熊輝 嚴國權 陳瑜斌
摘 ?要:鋼琴是一種傳統(tǒng)演奏樂器,距今已有幾百年的發(fā)展和使用歷史。我國自從改革開放以來,越來越多的家庭購買了鋼琴。但是鋼琴調音仍然處于人工調試階段,需要調音師的經驗和手藝來判斷鋼琴音色是否標準,調音效果千差萬別。隨著智能手機以及計算機技術發(fā)展,設計應用軟件通過語音識別技術對琴鍵頻率進行采集,采用傅里葉變換對接收到的音頻進行分析,得到真實的音鍵頻率,可以彌補人為因素對樂音調試的誤差;將分析得到的琴鍵頻率與標準樂音庫進行對比,將對比后的樂音信息通過可視化界面展示出來,便于人們更加快速準確地調音。
關鍵詞:Visual Studio;鋼琴調音;語音識別;傅里葉變換
中圖分類號:TN912.3 ? ? 文獻標識碼:A
Abstract:Piano is a traditional musical instrument,which has a history of development and use for hundreds of years. Since Chinese reform and opening up,more and more families have bought piano. However,the piano tuning is still in the stage of manual debugging,which requires the experience and skills of the tuner to judge whether the piano tone is standard,and the tuning effect is very different. With the development of smart phones and computer technology,the design application software collects the piano key frequency through speech recognition technology,analyzes the received music by using Fourier transform,and gets the sound key frequency approaching to the standard,which can completely make up for the error of human factors in music debugging;compares the piano key frequency obtained by analysis with the standard music library,and then compares it Through the visual interface,the music information is displayed,which is convenient for people to tune more quickly and accurately.
Key words:Visual Studio;Piano tuning;Speech Recognition;Fourier transform
一、項目背景
21世紀,人們更加注重于對精神的追求,鋼琴的發(fā)展和普及恰好可以為現(xiàn)代人們帶來精神上的快樂和滿足[1]。鋼琴的音質長期受到各種外在環(huán)境因素的影響,使得鋼琴發(fā)音不準,嚴重干擾鋼琴演奏的穩(wěn)定性和演奏效果,因此必須在鋼琴使用前進行準確的調音。近些年由于演奏鋼琴人數(shù)的增加,傳統(tǒng)的鋼琴調音過于復雜化和機械化,現(xiàn)有的調音模式始終滿足不了大眾的調音需求[2]。因此,需要一款方便、快捷、準確、實用的調音裝置或者軟件工具來幫助解決調音的音準問題。
設計一種鋼琴調音軟件,可以實現(xiàn)智能化精密測量,高效地協(xié)助調音師完成鋼琴調音工作,避免了人為調音的不足,滿足了實際工作的要求。調音軟件也適用于其他樂器的調音,使調音工作不再枯燥煩瑣。
二、技術方案
(一)音頻識別技術構建模型
將模擬的音頻信號進行采樣得到波形數(shù)據(jù)之后,要輸入到特征提取模塊,提取出合適的聲學特征參數(shù)供后續(xù)聲學模型訓練使用。好的聲學特征應當考慮以下三個方面的因素:第一,應當具有比較優(yōu)秀的區(qū)分特性,以使聲學模型不同的建模單元可以方便準確地建模;其次,特征提取也可以認為是音頻信息的壓縮編碼過程,既需要將信道、環(huán)境噪音的因素消除,保留與內容相關的信息,又需要在不損失過多有用信息的情況下使用盡量低的參數(shù)維度,便于高效準確地進行模型的訓練;最后,需要考慮魯棒性,即對環(huán)境噪聲的抗干擾能力[3-4]。
如今主流語音識別系統(tǒng)都采用隱馬爾科夫模型(HMM)作為聲學模型,這是因為HMM具有很多優(yōu)良特性。HMM的狀態(tài)跳轉模型很適合人類語音的短時平穩(wěn)特性,方便對不斷產生的觀測值(語音信號)進行統(tǒng)計建模;與HMM相伴生的動態(tài)規(guī)劃算法可以有效地實現(xiàn)對可變長度的時間序列進行分段和分類的功能;HMM的應用范圍廣泛,只要選擇不同的生成概率密度,離散分布或者連續(xù)分布,都可以使用HMM進行建模。其原理框架如下圖1中所示。
鋼琴鍵頻率是指鋼琴上琴鍵所產生的聲音頻率,以赫茲(Hz)為單位?,F(xiàn)代的鋼琴上共有88至108鍵。88鍵鋼琴的第49鍵,即第5個A(亦稱A4)一般被用作調音標準。現(xiàn)行的標準是440Hz,亦稱A440。鋼琴的琴鍵號和頻率對應關系如下表1。本項目對音頻信號建模,標準頻率模型即為該表。
(二) FFT(Fast Fourier Transform)算法原理
FFT是一種基于離散傅里葉變換(DFT)的高效傅里葉算法,被人們廣泛稱為快速傅里葉變換[5-6]。該方法主要基于Fourier的傅里葉函數(shù)變換,在時域上的任何傅里葉函數(shù)都必須是完全可以整數(shù)表示的,它可以構成由一個正交余弦陣列函數(shù)所組合構成的無窮數(shù)量級數(shù)。Fourier函數(shù)定義為:時域上的一個信號x(t)會對應于頻域f上的另外一個信號 X(f)。即X(f)=dt。
通過Fourier變換后,可以得出信號的離散頻譜,從而精確地求出信號的離散頻率。實際應用時,計算得到離散信號周期x(t)的離散采樣值,即x(nt),t代表離散采樣信號的周期。通過計算離散采樣的值x(nt),可以精確地計算出離散信號周期x(t)的離散頻譜。
麥克風記錄聲音時,只能獲取不同時刻的電壓變化值,這是多種聲音頻率的總和。利用傅里葉變換將多個不同頻率的音頻分別提取出來,將語音信號轉化為電腦可識別的數(shù)字信號,其中傅里葉變換還可將混合的復雜音波分別提取出單一的音頻信號。本項目通過快速傅里葉變換的算法獲取采樣音頻的能量值。
三、程序的實現(xiàn)
本項目運行環(huán)境為微軟公司的Visual Studio 2017(VS),采用C語言和Windows編程來實現(xiàn)鋼琴調音的基本功能。首先建立一個控制臺項目文件,新建項目完成后,將后綴名稱.cpp改為.c。為了更加方便地調試程序,手動添加一個FFT算法.c文件。完成總體框搭建以后,只需向項目文件中添加代碼即可,采用多文件聯(lián)合編程的思想,可以更加快速有效地實現(xiàn)程序的功能。
(一)整體思路
軟件的工作流程如下圖2所示。
頻率識別需要對外部聲音進行采集,添加導入winmm.lib庫,可以進行Windows多媒體編程。因為還需調用接口函數(shù)和添加mmsystem.h頭文件來實現(xiàn)聲音的輸入輸出。mmsystem.h中包含了多媒體的大多數(shù)接口,可以簡化程序。主程序包含了1個main函數(shù)和5個可調用函數(shù),將鋼琴音鍵和對應頻率值設為全局變量,定義為結構體數(shù)組。鋼琴各按鍵頻率,為測試方便,本項目定義了70個(可以在堆??臻g中開辟88個。)
struct MusicNote
{
char noteName[10];
double frequence;
}
note[VOLUMESIZE]={{“1”,27.5},{“2”, 29.1},{“3”, 30.8},{“4”, 32.7},{“5”, 34.6},{“6”, 36.7 7”, 38.8},{“8”, 41.2},{“9”, 43.6},{“10”,46.2},{“11”,48.9},{“12”, 51.9},{“13”, 55.0},{“14”, 58.2},{“15”, 61.7},{“16”, 65.4}, {“17”, 69.2}, {“18”, 73.4}, { “19”, 77.7}, {“20”, 82.4}, {“21”, 87.3},{“22”, 92.4}, {“23”, 97.9}, {“24”, 103.8},{“25”, 110.0},{“26”,116.5},{“27”,123.4},{“28”,130.8},{“29”,138.5},{“30”,146.8},{“31”,155.5},{“32”,164.8},{“33”,174.6},{“34”,184.9},{“35”,195.9},{“36”,207.6},{“37”,220.0},{“38”,233.0},{“39”,246.9},{“40”,261.6},{“41”,277.1},{“42”,293.6},{“43”,311.1},{“44”,329.6},{“45”, 349.2},{“46”, 369.9},{“47”, 391.9}, {“48”, 415.3}, {“49”, 440.0},{“50”,466.1},{“51”,493.8},{“52”,523.2},{“53”,554.3},{“54”,587.3},{“55”,622.2}, {“56”,659.2},{“57”,698.4},{“58”,739.9},{“59”,783.9},{“60”,830.6},{“61”,880.0},{“62”,932.3},{“63”,987.7},{“64”,1046.5},{“65”,1108.7},{“66”,1174.6},{“67”,1244.5},{“68”,1318.5},{“69”,1396.9}, {“70”, 1479.9}};
(二)設計過程
1.調用Record()函數(shù),實現(xiàn)PCM(脈沖編碼調制)聲音采集,將生成的錄音文件保存于D盤的根目錄下。保存的文件采用二進制進行存儲,讀取函數(shù)時也要進行相應的二進制讀取。定義音頻流格式的數(shù)據(jù)結構WAVEFORMATEX waveform和輸入設備HWAVEIN hWaveIn,輸入設備的初始值為0。采集音頻時,需要包含數(shù)據(jù)緩存結構體LPWAVEHDR pWaveHdr以及采集時的數(shù)據(jù)緩存PBYTE pBuffer,數(shù)據(jù)緩存的類型為PBYTE,數(shù)據(jù)定義格式均為Windows核心編程內容。
WAVEFORMATEX waveform; ? ? ? ?//采集音頻格式,結構體
HWAVEIN hWaveIn = 0; ? ? ? ? ?//輸入設備
LPWAVEHDR pWaveHdr = NULL; ? ?//采集音頻時,包含數(shù)據(jù)緩存結構體
PBYTE pBuffer = NULL; ? ? ? ? ?//采集音頻時的數(shù)據(jù)緩存
MMRESULT error = 0; ? ? ? ? ? //枚舉型數(shù)據(jù)變量
double i = 4000000000; ? ? //循環(huán)變量,用于錄音需要的一段時間
FILE *fp = NULL;
得到能量的返回值:
*(data + i) = pr[i];
4.調用getFrequence()函數(shù),計算出音頻的頻率值。
設置能量的頻率、坐標和能量最大值:
double locate = 0;
int i;
double frequence;
double max;
max = *data;
求出能量最大值對應的橫坐標:
for (i = 0; i < (DATASIZE / 2); i++)
{if (*(data + i) > max)
{max = *(data + i);
locate = i;}}
計算出其頻率值:
frequence = locate * (8000.0 / DATASIZE);
5.調用showVolume()函數(shù)。根據(jù)頻率,在音高頻率對照表中,查看對應的音符并顯示結果。
函數(shù)開始時打印出標準鋼琴70個鍵的參照表:
printf(“%s:%fHz\n”, note[i].noteName, note[i].frequence);
輸出當前音鍵的頻率值:
printf(“當前頻率值:%f\n”, fre);
輸入的音律太高或音律太低,提示出現(xiàn)錯誤,并重新進行下一輪的聲音讀取操作:
if (fre <= note[0].frequence)
{Low = note[0].frequence - fre;
printf(“音律太低,請重新錄入\n”);}
else if(fre >= note[69].frequence)
{Heigh = fre - note[69].frequence;
printf(“音律太高,請重新錄入\n”);}
如果頻率在相應合理的范圍,顯示出對應高出或低于標準頻率的頻率值,誤差在5Hz以內時,提示調音較為合理:
if (note[choose].frequence < fre)
{printf(“當前頻率高于標準頻率,高了%fHz\n”, fre - note[choose].frequence);
while ( fre - note[choose].frequence {printf(“誤差在0至5Hz之間,調音基本完成\n”); break;}} else {printf(“當前頻率低于標準頻率,低了%fHz\n”, note[choose].frequence - fre); while(note[choose].frequence-fre < Wucha) {printf(“誤差在0至5Hz之間,調音基本完成\n”); break;}} (三)測試案例 1.當在一個相對安靜的環(huán)境下時,接收到的聲音頻率為0,低于鋼琴所發(fā)出的最低頻率,則會出現(xiàn)相應提示如下,測試結果達到預期目標。 2.當在一個相對頻率較高的環(huán)境下時,接收到的頻率遠高于對照表中的數(shù)據(jù),則會出現(xiàn)相應提示如下,測試結果達到預期目標。 3.測試任意鋼琴的頻率按鍵。 (1)選擇52號琴鍵為低音鍵(一組7個音鍵中Do鍵),對應的標準頻率為523.2Hz,測試結果如下: 與標準頻率相差僅為0.23Hz,達到了預期調音目標。 (2)選擇63號高音鍵Xi,對應標準頻率為987.7Hz,測試結果如下: 與標準頻率僅相差0.58Hz,達到了預期效果。 (四)誤差分析 選取部分鋼琴琴鍵,測出調音后的頻率,與標準音頻值做比對,檢驗軟件準確度。測量結果如表2所示。52、54、56、57、59、61、63鍵號分別對應鋼琴鍵號中的C5、D5、E5、F5、G5、A5、B5。 從表2數(shù)據(jù)可以看出,測得誤差與標準值基本控制在1Hz左右,誤差百分比在0%~0.5%之間,測量精度相對較高,完全可以擔任調音工作。 調音中的誤差主要來源于以下幾個方面: 1.系統(tǒng)聲卡將聲音文件轉化為二進制文件進行保存時,聲音信號轉化為數(shù)字信號,會出現(xiàn)失真和數(shù)據(jù)丟失的情況;將二進制文件轉化為音頻文件時又會出現(xiàn)音質損失。 2.不存在絕對安靜的環(huán)境,環(huán)境因素會對頻率檢測出現(xiàn)影響,有一些雜音會通過麥克風進入聲卡,導致有時測量相對誤差較大。 四、總結 本項目通過Visual Studio平臺進行了整體項目搭建,對每一個重要功能函數(shù)進行了詳細分析和開發(fā)應用,根據(jù)程序測試案例進行分析數(shù)據(jù),最后對比分析出結果。通過快速離散傅里葉變換計算得出的頻率值與鋼琴調音時彈奏出的頻率值基本吻合,該軟件可以初步滿足對鋼琴調音的需求。 參考文獻: [1]林琳娜.淺談鋼琴中的“律”及“調試”[J].科技信息,2011(20):259. [2]崔笑.鋼琴調音儀的研究及實現(xiàn)[D].成都:電子科技大學,2014. [3]柯鑫.基于Web客戶端和語音識別的智能家居交互系統(tǒng)設計[D].武漢:華中科技大學,2019. [4]林圣曄.語音識別技術[J].數(shù)碼設計(下),2019(04):182-183. [5]徐健,李曉慧.一種基于FFT的高分辨率音頻頻率測量方法[J].電子質量,2020(02):11-14. [6]張嘉.基于ARM的鋼琴調校裝置的研發(fā)[D].哈爾濱:哈爾濱理工大學,2013.