歌曲《忘塵谷》基于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?

四、調試與優化建議

  1. 多音分離:引入和弦分析或機器學習模型(如CNN)提升復雜音樂的檢測精度。

  2. 調式判定:結合音階分布概率模型,區分大調與關系小調。

  3. 實時處理:通過滑動窗口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博客

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/80540.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/80540.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/80540.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大某麥演唱會門票如何自動搶

引言 僅供學習研究&#xff0c;歡迎交流 搶票難&#xff0c;難于上青天&#xff01;無論是演唱會、話劇還是體育賽事&#xff0c;大麥網的票總是秒光。大麥網是國內知名的票務平臺&#xff0c;熱門演出票往往一票難求。手動搶票不僅耗時&#xff0c;還容易錯過機會。作為一名…

1.3.3 tinyalsa詳細介紹

一、TinyALSA 的背景與設計目標 1. 誕生背景 Android 音頻需求的演變&#xff1a;早期 Android 系統使用標準 ALSA&#xff08;Advanced Linux Sound Architecture&#xff09;的用戶空間庫 alsa-lib&#xff0c;但因其復雜性&#xff08;代碼龐大、依賴較多&#xff09;和資…

超越合并速度(merge speed):AI如何重塑開發者協作

李升偉 編譯 AI 關于現代開發的討論通常圍繞著單一指標&#xff1a;合并速度&#xff08;merge speed&#xff09;。但在這一表面測量之下&#xff0c;隱藏著開發團隊工作方式的一種更深刻的變革。讓我們探討開發者協作的微妙演變方式以及為什么傳統生產力指標只講述了一部分故…

如何找正常運行虛擬機

1.新建虛擬機。Linux centos7&#xff0c;給虛擬機改個名字不要放在c盤 2.安裝操作系統。cd/dvd->2009.iso 啟動虛擬機

深度學習:系統性學習策略(二)

深度學習的系統性學習策略 基于《認知覺醒》與《認知驅動》的核心方法論,結合深度學習的研究實踐,從認知與技能雙重維度總結以下系統性學習策略: 一、認知覺醒:構建深度學習的思維操作系統 三重腦區協同法則 遵循**本能腦(舒適區)-情緒腦(拉伸區)-理智腦(困難區)**的…

如何使用CSS解決一行有三個元素,前兩個元素靠左排列,第三個元素靠右排列的問題

如圖所示&#xff0c;我要把左邊的場館和區域信息靠左排列&#xff0c;價格信息靠右排列。如何使用CSS實現這種效果&#xff1f; 在這里&#xff0c;我使用了flexbox彈性布局&#xff0c;以下是我的實現代碼 .name-info {display: flex;gap: 2px;justify-content: space-betwee…

USB傳輸模式

USB有四種傳輸模式: 控制傳輸, 中斷傳輸, 同步傳輸, 批量傳輸 1. 中斷傳輸 中斷傳輸一般用于小批量, 非連續的傳輸. 對實時性要求較高. 常見的使用此傳輸模式的設備有: 鼠標, 鍵盤等. 要注意的是, 這里的 “中斷” 和我們常見的中斷概念有差異. Linux中的中斷是設備主動發起的…

【Python 變量類型】

Python 是一種動態類型語言&#xff0c;變量類型在運行時自動確定&#xff0c;無需顯式聲明。以下是 Python 中核心變量類型的分類與用法詳解&#xff1a; 一、基本數據類型 1. 數值類型 整數 (int) 支持正負數、零和二進制/八進制/十六進制表示&#xff1a; a 42 b 0o52 #…

Python基礎:類的深拷貝與淺拷貝-->with語句的使用及三個庫:matplotlib基本畫圖-->pandas之Series創建

一.類的深拷貝與淺拷貝 class CPU():pass class Disk():passclass Computer():#計算機由CPU和硬盤組成def __init__(self):self.cpu CPU()self.disk Disk()cpu CPU()#創建一個CPU對象 disk Disk()#創建一個硬盤對象#創建一個計算機對象 com Computer(cpu,disk) #變量&…

【SSM-SpringMVC(二)】Spring接入Web環境!本篇開始研究SpringMVC的使用!SpringMVC數據響應和獲取請求數據

SpringMVC的數據響應方式 頁面跳轉 直接返回字符串通過ModelAndView對象返回 回寫數據 直接返回字符串返回對象或集合 頁面跳轉&#xff1a; 返回字符串方式 直接返回字符串&#xff1a;此種方式會將返回的字符串與視圖解析器的前后綴拼接后跳轉 RequestMapping("/con&…

閱文集團C++面試題及參考答案

目錄 能否不使用鎖保證多線程安全? 面向對象的三個特性是什么?請分別解釋。 構造函數和析構函數能否被繼承? C++ 中函數重載是如何實現的? C 語言中是否支持函數重載? 什么是左值和右值?請舉例說明。 C++ 中子類的構造和析構順序是怎樣的? C++ 中虛函數表的變化過…

【親測有效】如何清空但不刪除GitHub倉庫中的所有文件(main分支)

如何清空但不刪除GitHub倉庫中的所有文件&#xff08;main分支&#xff09; 在項目開發過程中&#xff0c;有時我們需要清空GitHub倉庫中的所有文件&#xff0c;同時保留倉庫本身。這種情況常見于項目重構、代碼重寫或者需要重新開始一個項目時。本文將介紹一種有效的方法來清…

前端EXCEL插件,智表ZCELL產品V3.0 版本發布,底層采用canvas全部重構,功能大幅擴展,性能極致提升,滿足千萬級單元格加載

本次更新是底層全部重構&#xff0c;按照現代瀏覽器要求&#xff0c;采用canvas方式進行了重構&#xff0c;預留了將來擴展空間&#xff0c;特別是在大數據量性能提升方面有了較大提升&#xff0c;可以滿足千萬級單元格加載&#xff0c;歡迎大家體驗使用。 體驗地址&#xff1…

3DGS-to-PC:3DGS模型一鍵絲滑轉 點云 or Mesh 【Ubuntu 20.04】【2025最新版!!】

一、引言 3D高斯潑濺(3DGS)是一種新興的三維場景表示方法&#xff0c;可以生成高質量的場景重建結果。然而&#xff0c;要查看這些重建場景&#xff0c;需要特殊的高斯渲染器。大多數3D處理軟件并不兼容3D高斯分布模型&#xff0c;但它們通常都兼容點云文件。 3DGS-to-PC項目提…

OpenHarmony 以太網卡熱插拔事件接口無效

目錄 1.背景 2.解決方案 1.背景 在OpenHarmony中調用以太網熱插拔時間,發現熱插拔沒有任何回調,如下接口 import { ethernet } from @kit.NetworkKit;ethernet.on(interfaceStateChange, (data: object) => {console.log(on interfaceSharingStateChange: + JSON.…

C++ 跨平臺開發挑戰與深度解決方案:從架構設計到實戰優化

C 憑借其高性能與底層控制能力&#xff0c;在游戲引擎、嵌入式系統、工業軟件等領域占據核心地位。然而&#xff0c;跨平臺開發過程中需應對硬件架構多樣性、操作系統差異性、編譯工具鏈碎片化等復雜問題。本文將從底層架構到上層應用&#xff0c;系統性剖析 C 跨平臺開發的核心…

什么是 ANR 如何避免它

一、什么是 ANR&#xff1f; ANR&#xff08;Application Not Responding&#xff09; 是 Android 系統在應用程序主線程&#xff08;UI 線程&#xff09;被阻塞超過一定時間后觸發的錯誤機制。此時系統會彈出一個對話框提示用戶“應用無響應”&#xff0c;用戶可以選擇等待或強…

數據結構(六)——樹和二叉樹

一、樹和二叉樹的定義與存儲 1.樹的定義 樹是一種非線性的數據結構&#xff0c;它是由n個有限結點組成有層次關系的集合 樹具有以下特點&#xff1a; &#xff08;1&#xff09;每個結點具有0個或多個子結點 &#xff08;2&#xff09;每個子結點只有一個父結點 &#xff…

DICOM 網絡服務實現:醫學影像傳輸與管理的技術實踐

?? 博主簡介:CSDN博客專家、CSDN平臺優質創作者,高級開發工程師,數學專業,10年以上C/C++, C#, Java等多種編程語言開發經驗,擁有高級工程師證書;擅長C/C++、C#等開發語言,熟悉Java常用開發技術,能熟練應用常用數據庫SQL server,Oracle,mysql,postgresql等進行開發應用…

TongWeb7.0常用-D參數說明

Web容器相關啟動參數配置 屬性 含義 -Dtongweb.restart.interval 設置宕機后重啟的時間間隔&#xff0c;以秒為單位。如果不設置這個參數&#xff0c;默認為1秒 -Dmonitor.abnormal.restart 設置服務器非正常狀態時是否重啟&#xff0c;如果不設置這個參數或者參數值不為…