2、判斷音訊資料是否是雙聲道,如果是雙聲道則保留一個聲道的資料,用calsample.m檔案的函式完成此功能,檔案內容如下: function sample = calsample(sampledata,FS) temp_sample = resample(sampledata,1,FS/11025); [m,n] = size(temp_sample); if (n == 2) sample = temp_sample(:,1); else sample = temp_sample; end end
3、對音訊資料進行快速傅立葉變換得到頻譜圖,並選取scope區域內的能量最大並且能量增幅最大的點作為峰值點,進行特徵提取,keypoint.m檔案內容如下: function point = keypoint(sample,scope) %對音訊資料進行快速傅立葉變換,得到變換後的資料為b,頻率為f,時間為t [b,f,t] = specgram(sample,1024,11025,hanning(1024),256); specgram(sample,1024,11025,hanning(1024),256);%繪製頻譜圖 hold on; energy = abs(b);%根據快速傅立葉變換後的資料進行能量計算 %energy = sample; diffenergy = caldiffenergy(energy);%計算能量差分 [m,n] = size(energy);%獲取能量矩陣的大小 %f = (0:4); %t = (0:4); f_unit = max(f)/(length(f)-1);%根據頻率點個數計算頻率單位長度 t_unit = max(t)/(length(t)-1);%根據時間點個數計算時間單位長度 k = 1; l = 1; p = 1; num = 1; point.t = 0; point.f = 0;%point結構體陣列用來儲存峰值點 temp.t = 0; temp.f = 0;%temp結構體陣列用來儲存計算中的臨時點 count = 0;%count為零表示在當前scope中未找到峰值點 x_f=0; y_t=0; plot(x_f,y_t); hold on; for i = 1:m-scope+1 for j = 1:n-scope+1 %找出大小為scope的子矩陣中的最大元素的位置並儲存 [x_f,y_t] = find(energy(i:i+scope-1,j:j+scope-1)==max(max(energy(i:i+scope-1,j:j+scope-1)))); x_f = x_f + i - 1; y_t = y_t + j - 1; %找出大小為scope的子矩陣中的差分最大元素的位置並儲存 [diffx,diffy] = find(diffenergy(i:i+scope-1,j:j+scope-1)==max(max(diffenergy(i:i+scope-1,j:j+scope-1)))); diffx = diffx + i - 1; diffy = diffy + j - 1; count = 0; %如果最大元素和差分最大元素都為同一個位置則該點為峰值點,儲存在temp中 for k = 1:length(x_f) for l = 1:length(diffx) if (x_f(k) == diffx(l)) && (y_t(k) == diffy(l)) temp(num).f = x_f(k) * f_unit; temp(num).t = y_t(k) * t_unit; %plot(temp(num).t,temp(num).f,"."); num = num + 1; count = 1;%在scope中找到一個峰值點則不再記錄其它相同的點 break; end end if count == 1%scope中多個峰值點只保留第一個 break; end end end end %將temp中儲存的峰值點畫在圖上,多個scope中找到的相同峰值點只畫一次 len = 1; point(1).f = temp(1).f; point(1).t = temp(1).t; plot(point(1).t,point(1).f,"."); for i = 2:num - 1 for j = 1:len if (temp(i).f == point(j).f) && (temp(i).t == point(j).t) break; end end if j == len && (temp(i).f ~= point(j).f) && (temp(i).t ~= point(j).t) len = len + 1; point(len).f = temp(i).f; point(len).t = temp(i).t; plot(point(len).t,point(len).f,"."); end end hold off end 4、keypoint(sample,scope);函式中用到的caldiffenergy(energy);函式內容在caldiffenergy.m檔案中,內容如下: function diffenergy = caldiffenergy(energy) v = diff(energy"); [x,y] = size(v); for i = 1:y zero(i) = 0; end diffenergy = abs(([zero;v])"); end
1、用audioread("");函式讀取電腦中的音訊檔案,引數是音訊檔案的路徑: [sampledata,FS] = audioread("F:1.mp3"); sampledata儲存音訊訊號資料,FS是音訊取樣率,MP3格式的取樣率一般為44100;
2、判斷音訊資料是否是雙聲道,如果是雙聲道則保留一個聲道的資料,用calsample.m檔案的函式完成此功能,檔案內容如下: function sample = calsample(sampledata,FS) temp_sample = resample(sampledata,1,FS/11025); [m,n] = size(temp_sample); if (n == 2) sample = temp_sample(:,1); else sample = temp_sample; end end
3、對音訊資料進行快速傅立葉變換得到頻譜圖,並選取scope區域內的能量最大並且能量增幅最大的點作為峰值點,進行特徵提取,keypoint.m檔案內容如下: function point = keypoint(sample,scope) %對音訊資料進行快速傅立葉變換,得到變換後的資料為b,頻率為f,時間為t [b,f,t] = specgram(sample,1024,11025,hanning(1024),256); specgram(sample,1024,11025,hanning(1024),256);%繪製頻譜圖 hold on; energy = abs(b);%根據快速傅立葉變換後的資料進行能量計算 %energy = sample; diffenergy = caldiffenergy(energy);%計算能量差分 [m,n] = size(energy);%獲取能量矩陣的大小 %f = (0:4); %t = (0:4); f_unit = max(f)/(length(f)-1);%根據頻率點個數計算頻率單位長度 t_unit = max(t)/(length(t)-1);%根據時間點個數計算時間單位長度 k = 1; l = 1; p = 1; num = 1; point.t = 0; point.f = 0;%point結構體陣列用來儲存峰值點 temp.t = 0; temp.f = 0;%temp結構體陣列用來儲存計算中的臨時點 count = 0;%count為零表示在當前scope中未找到峰值點 x_f=0; y_t=0; plot(x_f,y_t); hold on; for i = 1:m-scope+1 for j = 1:n-scope+1 %找出大小為scope的子矩陣中的最大元素的位置並儲存 [x_f,y_t] = find(energy(i:i+scope-1,j:j+scope-1)==max(max(energy(i:i+scope-1,j:j+scope-1)))); x_f = x_f + i - 1; y_t = y_t + j - 1; %找出大小為scope的子矩陣中的差分最大元素的位置並儲存 [diffx,diffy] = find(diffenergy(i:i+scope-1,j:j+scope-1)==max(max(diffenergy(i:i+scope-1,j:j+scope-1)))); diffx = diffx + i - 1; diffy = diffy + j - 1; count = 0; %如果最大元素和差分最大元素都為同一個位置則該點為峰值點,儲存在temp中 for k = 1:length(x_f) for l = 1:length(diffx) if (x_f(k) == diffx(l)) && (y_t(k) == diffy(l)) temp(num).f = x_f(k) * f_unit; temp(num).t = y_t(k) * t_unit; %plot(temp(num).t,temp(num).f,"."); num = num + 1; count = 1;%在scope中找到一個峰值點則不再記錄其它相同的點 break; end end if count == 1%scope中多個峰值點只保留第一個 break; end end end end %將temp中儲存的峰值點畫在圖上,多個scope中找到的相同峰值點只畫一次 len = 1; point(1).f = temp(1).f; point(1).t = temp(1).t; plot(point(1).t,point(1).f,"."); for i = 2:num - 1 for j = 1:len if (temp(i).f == point(j).f) && (temp(i).t == point(j).t) break; end end if j == len && (temp(i).f ~= point(j).f) && (temp(i).t ~= point(j).t) len = len + 1; point(len).f = temp(i).f; point(len).t = temp(i).t; plot(point(len).t,point(len).f,"."); end end hold off end 4、keypoint(sample,scope);函式中用到的caldiffenergy(energy);函式內容在caldiffenergy.m檔案中,內容如下: function diffenergy = caldiffenergy(energy) v = diff(energy"); [x,y] = size(v); for i = 1:y zero(i) = 0; end diffenergy = abs(([zero;v])"); end