歌曲《忘尘谷》基于C语言的歌曲调性检测技术解析
引言
在音乐分析与数字信号处理领域,自动检测歌曲调性是一项基础且关键的任务。本文以C语言为核心,结合音频处理库(libsndfile
)和快速傅里叶变换库(FFTW
),探讨如何实现调性检测,并通过实际案例《忘尘谷》分析程序结果与简谱标记的差异。
一、技术实现流程
1. 音频输入与解码
-
支持格式:通过
libsndfile
库读取WAV等无损格式音频文件。 -
代码示例:
#include <sndfile.h> SNDFILE *file; SF_INFO info; file = sf_open("input.wav", SFM_READ, &info); float *buffer = malloc(info.frames * sizeof(float)); sf_read_float(file, buffer, info.frames); sf_close(file);
2. 频域分析与基频检测
-
傅里叶变换(FFT):使用FFTW库将时域信号转换为频域,提取频率峰值。
#include <fftw3.h> fftwf_complex *out = fftwf_malloc(sizeof(fftwf_complex) * N); fftwf_plan plan = fftwf_plan_dft_r2c_1d(N, buffer, out, FFTW_ESTIMATE); fftwf_execute(plan);
-
基频定位:通过频谱峰值或自相关算法(如YIN算法)确定主导频率。
3. 调性判定逻辑
-
频率到音名映射:基于十二平均律公式转换频率为音高:
double freq_to_midi(double freq) {return 69 + 12 * log2(freq / 440.0); }
-
调式匹配:统计音高分布,匹配大调或小调音阶特征(如D大调音阶:D-E-F♯-G-A-B-C♯)。
二、常见问题与解决方案
1. 编译错误处理
-
错误示例:
fftw3.h: No such file or directory
原因:未安装FFTW开发库。
解决:sudo apt install libfftw3-dev # Linux brew install fftw # macOS
-
链接库缺失:
undefined reference to 'sf_open'
解决:编译时添加-lsndfile
和-lfftw3
选项:gcc diao.c -o diao -lsndfile -lfftw3 -lm
2. 数据类型一致性
-
错误示例:
passing 'float*' to 'double*' parameter
原因:sf_read_float
与FFTW函数参数类型不匹配。
解决:统一使用单精度或双精度:// 单精度方案 float *buffer = malloc(...); sf_read_float(file, buffer, ...); fftwf_plan plan = fftwf_plan_dft_r2c_1d(...);
3. 调性检测误差分析
-
案例:程序检测《忘尘谷》主音为B,而简谱标记为1=D。
原因:-
关系大小调:D大调与B小调共享调号(两个升号),程序可能捕捉到B小调的主音。
-
算法局限性:基频检测易受和弦或伴奏干扰,需结合音阶分布优化逻辑。
-
三、音乐理论核心:D大调与B小调对比
维度 | D大调 | B小调 |
---|---|---|
主音 | D(频率293.66 Hz) | B(频率246.94 Hz,低小三度) |
音阶结构 | D-E-F♯-G-A-B-C♯(全全半全全全半) | B-C♯-D-E-F♯-G-A(全半全全半全全) |
情感色彩 | 明亮、欢快 | 忧郁、深沉 |
和弦功能 | 主和弦D-F♯-A,属和弦A-C♯-E | 主和弦B-D-F♯,属和弦F♯-A♯-C♯ |
四、调试与优化建议
-
多音分离:引入和弦分析或机器学习模型(如CNN)提升复杂音乐的检测精度。
-
调式判定:结合音阶分布概率模型,区分大调与关系小调。
-
实时处理:通过滑动窗口FFT实现流式音频分析。
五、结论
通过C语言结合信号处理库,可实现歌曲调性的自动化检测,但需兼顾技术细节与音乐理论。实际应用中,算法结果与乐谱标记的差异常源于调式复杂性或检测逻辑的局限性。未来可通过多算法融合和理论规则优化,进一步提升准确性和实用性。
附录
-
完整代码示例
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sndfile.h>
#include <fftw3.h>void detect_key(const char *filename) {// 读取音频文件SF_INFO info;SNDFILE *file = sf_open(filename, SFM_READ, &info);if (!file) {fprintf(stderr, "无法打开文件\n");return;}double *buffer = malloc(info.frames * info.channels *sizeof(double));sf_read_double(file, buffer, info.frames * info.channels);sf_close(file);// 执行FFTint N = info.frames;fftw_complex *out = fftw_malloc(sizeof(fftw_complex) * (N/2 + 1));fftw_plan plan = fftw_plan_dft_r2c_1d(N, buffer, out, FFTW_ESTIMATE);fftw_execute(plan);// 寻找峰值频率(简化示例)double max_magnitude = 0;int peak_bin = 0;for (int i = 0; i < N/2; i++) {double mag = sqrt(out[i][0]*out[i][0] + out[i][1]*out[i][1]);if (mag > max_magnitude) {max_magnitude = mag;peak_bin = i;}}double peak_freq = (double)peak_bin * info.samplerate / N;// 转换为音高并推测调性double midi_note = 69 + 12 * log2(peak_freq / 440.0);const char *notes[] = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};int note_index = (int)round(midi_note) % 12;printf("Dominant Note: %s\n", notes[note_index]);// 清理资源fftw_destroy_plan(plan);fftw_free(out);free(buffer);
}int main() {detect_key("w.ogg");return 0;
}
# gcc diao.c -o diao -lsndfile -lfftw3 -lm
# ./diao
Dominant Note: B
-
libsndfile文档
-
FFTW官方教程
相关链接:
使用 librosa 测量《忘尘谷》节拍速度-CSDN博客
相关文章:
歌曲《忘尘谷》基于C语言的歌曲调性检测技术解析
引言 在音乐分析与数字信号处理领域,自动检测歌曲调性是一项基础且关键的任务。本文以C语言为核心,结合音频处理库(libsndfile)和快速傅里叶变换库(FFTW),探讨如何实现调性检测,并通…...
Spring Boot 使用Itext绘制并导出PDF
最终效果 其实可以加分页,但是没有那么精细的需求,所以我最后就没有加,有兴趣的可以尝试下。 项目依赖 <!-- Spring Boot 版本有点老 --> <spring-boot.version>2.3.12.RELEASE</spring-boot.version><!-- 依…...
医学影像处理与可视化:从预处理到 3D 重建的技术实践
🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…...
用 openssl 测试 tls 连接
以 baidu 为例,命令行为: openssl s_client -tlsextdebug -connect baidu.com:443 得到的输出为: CONNECTED(00000003) TLS server extension "renegotiation info" (id65281), len1 0000 - 00 …...
Matlab 汽车制动纵向动力学模型和PID控制
1、内容简介 Matlab 228-汽车制动纵向动力学模型和PID控制 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 4、参考论文 略...
重塑JavaScript原生功底=>【构造函数篇】
概念:用于创建对象的函数称之为构造函数 作用:构造函数在 JavaScript 中是用来创建对象的最根本操作。 语法:当一个函数通过 new 关键字 来调用的话,那么这个函数就是一个构造函数。 场景:构造函数是专门用来创建对象…...
从0到1:Python机器学习实战全攻略(8/10)
摘要:通过本文的学习,我们深入探索了 Python 机器学习从入门到实战的精彩世界。从 Python 在机器学习领域的独特优势,到机器学习的核心概念,再到各种强大工具库的应用,以及实战项目的完整演练,我们逐步揭开…...
[计算机网络]网络层
文章目录 408考研大纲IPV4数据报格式协议: IPv4 地址DHCP协议IP组播 408考研大纲 IPV4数据报格式 协议: 1:ICMP IPv4 地址 特殊IP 网络号全1又称直接广播地址,32位全1又称受限广播地址 因为255.255.255.255只能在本网络内广播,路由器不许通过它&…...
华为行业认证是什么?如何考取华为行业认证?
据IDC预测,2027年全球数字化转型市场规模将突破3.4万亿美元,而中国将成为增长最快的市场之一。然而,85%的企业在转型中面临核心人才短缺的困境,尤其缺乏兼具技术能力与行业洞察的复合型人才! 讯方技术作为华为授权培训…...
Kotlin与Qt跨平台框架深度解析:业务逻辑共享与多语言集成
简介 Kotlin Multiplatform和Qt作为两大主流跨平台开发框架,各自在技术生态和应用场景上展现出独特优势。Kotlin Multiplatform专注于业务逻辑的跨平台共享,通过Kotlin语言的统一特性实现高达80%的代码复用率,特别适合移动应用和Web服务的业务逻辑开发。而Qt则凭借其强大的…...
基于LNMP架构的个人博客系统部署
一、项目概述 本项目旨在通过两台服务器(Server-Web和Server-NFS-DNS)搭建一个基于LNMP(Linux、Nginx、MySQL、PHP)架构的个人博客系统。通过域名访问自建网站,同时实现资源文件的共享和DNS解析功能。 二、服务器配置…...
Python训练打卡Day21
常见的降维算法: # 先运行预处理阶段的代码 import pandas as pd import pandas as pd #用于数据处理和分析,可处理表格数据。 import numpy as np #用于数值计算,提供了高效的数组操作。 import matplotlib.pyplot as plt #用于绘…...
PostgreSQL 序列(Sequence) 与 Oracle 序列对比
PostgreSQL 序列(Sequence) 与 Oracle 序列对比 PostgreSQL 和 Oracle 都提供了序列(Sequence)功能,但在实现细节和使用方式上存在一些重要差异。以下是两者的详细对比: 一 基本语法对比 1.1 创建序列 PostgreSQL: CREATE [ { TEMPORARY | TEMP } |…...
直播:怎样用Agentic AI搭建企业AI应用?5.24日,拆解新一代“智能客服系统”案例
2025 DeepSeek掀起了中国企业的AI落地浪潮! 随着应用的深入,AI的落地技术正在快速演化。 3月,Manus一夜爆火,让AI Agent更加引人关注。 从生成式AI,到Agentic AI(代理式AI)。 AI正在从只能生…...
《Asp.net Mvc 网站开发》复习试题
一.选择题(注:每题2分,共 54分,只能在下列表格中,填写每个题目相应的正确字母选项) 01: 02: 03: 04: 05: 06: 07: 08: 09: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: :27: 1. Mvc让软件…...
算法题(145):货仓选址
审题: 本题需要我们找出距离之和的最小值 思路: 方法一:贪心 贪心策略:将货仓建立在所有商店的中间可以达到距离之和最小 因为每家商店都需要接收一车商品,所以这里的距离之和指的是从货仓到每一家商店的路线的距离之和…...
✅ TensorRT Python 安装精简流程(适用于 Ubuntu 20.04+)
安装 TensorRT Python 轮子的步骤 确保 pip 和 wheel 模块已更新并安装: 参考链接 python3 -m pip install --upgrade pip python3 -m pip install wheel 1. 确认环境要求 Python:版本 3.8 - 3.13 OS:Ubuntu 20.04 或 Windows 10 CPU&a…...
MYSQL 全量,增量备份与恢复
目录 一 数据备份的重要性 1 数据备份的重要性 2 数据库备份类型 2.1 从物理与逻辑的角度分类 2.2. 从数据库的备份策略角度分类从数据库的备份策略角度,数据库的备份可分为完全备份、差异备份和增量备份。 3 常见的备份方法 3.1 物理冷备份 物理冷备份时需要在数据库处…...
10. Spring AI PromptTemplate:从模板到高级技巧
1、前言 如果学到了这里,相信大部分人对Prompt并不陌生了。 在 Spring AI 的世界里,与强大的语言模型进行交互的基石便是 Prompt(提示语)。它不仅仅是你输入给 AI 的一段文本,更是你与智能对话的桥梁,是你唤醒模型潜能的关键指令。理解 Prompt 的本质、构建原则以及在 …...
基于OpenCV的人脸识别:Haar级联分类器
文章目录 引言一、环境准备二、代码实现1. 图像加载与预处理2. 加载Haar级联分类器3. 人脸检测核心参数详解4. 结果显示与标注 三、效果优化建议四、完整代码五、总结 引言 本文将带你一步步实现一个简单但实用的人脸检测程序,使用Python和OpenCV库。 一、环境准备…...
Git安装教程及常用命令
1. 安装 Git Bash 下载 Git 安装包 首先,访问 Git 官方网站 下载适用于 Windows 的 Git 安装包。 安装步骤 启动安装程序:双击下载的 .exe 文件,启动安装程序。选择安装选项: 安装路径:可以选择默认路径࿰…...
【PmHub后端篇】Skywalking:性能监控与分布式追踪的利器
在微服务架构日益普及的当下,对系统的性能监控和分布式追踪显得尤为重要。本文将详细介绍在 PmHub 项目中,如何使用 Skywalking 实现对系统的性能监控和分布式追踪,以及在这过程中的一些关键技术点和实践经验。 1 分布式链路追踪概述 在微服…...
ChromeDriver 技术生态与应用场景深度解析
ChromeDriver 技术生态与应用场景深度解析 随着 Web 自动化测试、运维和数据采集需求的不断增长,ChromeDriver 及其相关技术栈在各行业中扮演着举足轻重的角色。本文将从技术选型、语言适配、典型场景、技术延伸等维度,结合最新行业趋势与实践经验&…...
链表面试题6之回文结构
经过前几道题的铺垫,那么我们也是来到了链表的第六关。这也是一道非常经典的题目。 目录 逆置法 数组法 那么对于这道题目,我们要判断回文结构,实际上就是判断链表对不对称。这种类型的题目我们好像在哪里见过,对了,…...
ASP.NET Core Identity框架使用指南
文章目录 前言一、核心功能二、核心组件三、使用1)创建项目2)安装必要 NuGet包3)配置数据库连接字符串4)用户与角色实体定义4)配置数据库上下文5) 注册服务6)数据库迁移与初始化7)用…...
Hugging Face推出了一款免费AI代理工具,它能像人类一样使用电脑
Hugging Face推出了一款免费AI代理工具,它能像人类一样使用电脑。 这款工具名为Open Computer Agent(开放计算机代理),可模拟真实的电脑操作。 无需安装,在浏览器中即可运行。 以下是一些信息: - Open C…...
一.Gitee基本操作
一.初始化 1.git init初始化仓库 git init 用于在当前目录下初始化一个本地 Git 仓库,让这个目录开始被 Git 跟踪和管理。 生成 .git 元数据目录,从而可以开始进行提交、回退、分支管理等操作。 2.git config user.name/user.email配置本地仓库 # 设置…...
24、DeepSeek-V3论文笔记
DeepSeek-V3论文笔记 **一、概述****二、核心架构与创新技术**0.汇总:1. **基础架构**2. **创新策略** 1.DeepSeekMoE无辅助损失负载均衡DeepSeekMoE基础架构无辅助损失负载均衡互补序列级辅助损失 2.多令牌预测(MTP)1.概念2、原理2.1BPD2.2M…...
神经网络初步学习——感知机
一、前言 神经网络,顾名思义,它与我们大脑生物学里面讲到的神经元有关联。前辈们在研究早期人工智能的时候,就开始过我们的“交叉融合”,他们思考能不能把我们的人工智能的学习模式改造成我们人脑中神经元之间的学习方式——于是乎…...
在Text-to-SQL任务中应用过程奖励模型
论文标题 Reward-SQL: Boosting Text-to-SQL via Stepwise Reasoning and Process-Supervised Rewards 论文地址 https://arxiv.org/pdf/2505.04671 代码地址 https://github.com/ruc-datalab/RewardSQL 作者背景 中国人民大学,香港科技大学广州,阿…...
Python的安装使用
一、下载Python安装包 下载python安装包,可以直接访问官网地址:https://www.python.org/downloads/ 通过页面咱们直接下载最新版本的python安装包即可,python3.13.3。在页面的下方也可下载安装之前的版本,目前咱们按最新版本安装…...
mapreduce-wordcount程序2
WordCount案例分析 给定一个路径,统计这个路径下所有的文件中的每一个单词的出现次数。 其中,需要我们去实现代码的部分是:map函数和reduce函数。它们各自的作用是: map函数的入参是kv结构,k是偏移量,v是一…...
Java 内存模型(JMM)与内存屏障:原理、实践与性能权衡
Java 内存模型(JMM)与内存屏障:原理、实践与性能权衡 在多线程高并发时代,Java 内存模型(JMM) 及其背后的内存屏障机制,是保障并发程序正确性与性能的基石。本文将系统梳理 JMM 的核心原理、内…...
1.6 偏导数
(铺垫)全导数与偏导数看似相似,实则对应不同维度的变化观察。理解它们的差异需要从"变量自由度"切入: (核心差异解剖) 维度偏导数全导数变量关系其他变量被强制锁定所有变量都通过中间变量关联…...
网络爬虫学习之正则表达式
开篇 本文整理自《python3 网络爬虫开发实战》的学习笔记。 笔记整理 match match是一种常用的匹配方法,向它传入要匹配的字符串以及正则表达式,就可以检测这个正则表达式是否和字符串相匹配。 match会尝试从字符串的起始位置开始匹配正则表达式&#x…...
Pytorch常用统计和矩阵运算
文章目录 常用统计函数torch.prod()求积torch.sum()求和torch.mean()求均值torch.max()求最值torch.var() 方差torch.std()标准差 常见矩阵运算矩阵乘法点积 (torch.dot)批量矩阵乘法 (torch.bmm)奇异值分解 (SVD)特征分解 (torch.eig)矩阵求逆 (torch.inverse)伪逆 (torch.pin…...
PyTorch Lightning实战 - 训练 MNIST 数据集
MNIST with PyTorch Lightning 利用 PyTorch Lightning 训练 MNIST 数据。验证梯度范数、学习率、优化器对训练的影响。 pip show lightning Version: 2.5.1.post0Fast dev run DATASET_DIR"/repos/datasets" python mnist_pl.py --output_grad_norm --fast_dev_run…...
内存泄漏系列专题分析之十一:高通相机CamX ION/dmabuf内存管理机制Camx ImageBuffer原理
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:内存泄漏系列专题分析之八:高通相机CamX内存泄漏&内存占用分析--通用ION(dmabuf)内存拆解 这一篇我们开始讲: 内存泄漏系列专题分析之十一:高通相机CamX ION/dmabuf内存管理机制Camx ImageBuf…...
MySQL-逻辑架构
MySQL服务器逻辑架构图 主要分层结构 1.连接层 功能:处理连接、安全认证、线程管理等 核心模块:连接器:支持不同语言(JDBC)与MySQL交互;线程连接池:管理线程连接,减少线程频繁创建…...
架构思维:通用架构模式_系统监控的设计
文章目录 引言什么是监控三大常见监控类型1. 次数监控2. 性能监控3. 可用率监控 落地监控1. 服务入口2. 服务内部3. 服务依赖 监控时间间隔的取舍小结 引言 架构思维:通用架构模式_从设计到代码构建稳如磐石的系统 架构思维:通用架构模式_稳如老狗的SDK…...
架构、构架、结构、框架之间有什么区别?|系统设计|系统建模
在技术与知识中,我们总是频繁地遇到一些高度抽象、看似类似、却又各自承载着不同思想重量的词汇。“架构”、“构架”、“结构”、“框架”即是其中最为常见又最为令人困惑的一组术语。它们既是工程师们日常工作的核心语言,也是学者们在探索系统、组织、…...
系统架构设计(五):构件
定义 构件(Component)是指一个具有明确边界和独立部署能力的模块化单元,能够封装实现细节,并通过接口与其他构件协作完成系统功能。 主要特性 特性说明可复用性构件可以在不同系统中被重复使用。可部署性构件可以独立部署&…...
【系统架构师】2025论文《基于架构的软件设计方法》【最新】
😊你好,我是小航,一个正在变秃、变强的文艺倾年。 🔔本文分享【系统架构师】2025论文《系统可靠性设计》,期待与你一同探索、学习、进步,一起卷起来叭! 目录 项目介绍背景介绍系统模块技术栈基于…...
MultiTTS 1.7.6 | 最强离线语音引擎,提供多音色无障碍朗读功能,附带语音包
MultiTTS是一款免费且支持离线使用的文本转语音(TTS)工具,旨在为用户提供丰富的语音包选项,实现多音色无障碍朗读功能。这款应用程序特别适合用于阅读软件中的离线听书体验,提供了多样化的语音选择,使得听书…...
Costmap代价地图
以下为ROS navigation导航工具包的move_base框架图。其中有两个关于代价地图的模块(红框所框),全局代价地图global_costmap和局部代价地图local_costmap,这两个代价地图实际上是调用的同一个功能包代码,通过配置不同的参数实例化为两个代价地…...
用生活例子通俗理解 Python OOP 四大特性
让我们用最生活化的方式,结合Python代码,来理解面向对象编程的四大特性。 1. 封装:像使用自动售货机 生活比喻: 你只需要投币、按按钮,就能拿到饮料 不需要知道机器内部如何计算找零、如何运送饮料 如果直接打开机…...
大规模容器集群怎么规划
规划大规模容器集群需要综合考虑多个方面,以下是一些关键的规划要点: 业务需求分析 应用类型和特点:明确容器集群上运行的应用类型,如 Web 应用、数据库、大数据处理等。不同类型的应用对资源的需求和性能要求各不相同。例如&am…...
机器学习第七讲:概率统计 → 预测可能性,下雨概率70%就是典型应用
机器学习第七讲:概率统计 → 预测可能性,下雨概率70%就是典型应用 资料取自《零基础学机器学习》。 查看总目录:学习大纲 关于DeepSeek本地部署指南可以看下我之前写的文章:DeepSeek R1本地与线上满血版部署:超详细手…...
蓝桥杯13届 卡牌
问题描述 这天, 小明在整理他的卡牌。 他一共有 n 种卡牌, 第 i 种卡牌上印有正整数数 i(i∈[1,n]), 且第 i 种卡牌 现有 ai 张。 而如果有 n 张卡牌, 其中每种卡牌各一张, 那么这 n 张卡牌可以被称为一 套牌。小明为了凑出尽可能多套牌, 拿出了 m 张空白牌, 他可以在上面…...
《Vue.js》阅读之响应式数据与副作用函数
Vue.js 《Vue.js设计与实现》(霍春阳) 适合:从零手写Vue3响应式系统,大厂面试源码题直接覆盖。重点章节:第4章(响应式)、第5章(渲染器)、第8章(编译器&…...