前段時間,在嘗試音樂節拍數的提取時,終於有了突破性的進展,效果基本上比市面上的許多商業軟件還要好,在作節拍數檢測時,高頻信息作用不大,
通過重采樣減小運算量。重采樣讓我想起了在學校里面做的變速變調算法,在這里順便回顧一下。
OLA(Overlap-and-Add, OLA)重疊疊加算法是音頻變速算法中最簡單的時域方法,它是后續時域算法(SOLA, SOLA-FS, TD-PSOLA, WSOLA)的基礎。
OLA分為分解與合成兩個部分,公式看起來很復雜,所以不貼出了,基本思路從圖中更能清晰的表現出來。
分解階段:語音首先分幀,幀長為N,假設幀移為Sa。
合成階段:分解出來的語音幀,以幀移為Ss的間隔重新合成起來,得到變速之后的音頻。
Rate = Ss/ Sa,如果Sa=Ss,則原速;Ss<Sa時,加速;Ss>Sa時,減速。
功能性代碼:
function [ RSound ] = OLA(Speech, Fs, Rate)
%OLA Summary of this function goes here
% Detailed explanation goes here
frame_ms = 25;
frame_len = frame_ms * Fs /1000;
window = hanning(frame_len);
Sa = 1/2 * frame_len;
AnalysisSplice = enframe(Speech, window, Sa);
AnalysisSplice = AnalysisSplice';%each column corresponding to each frame data
Ss = Rate*Sa;
RSound = Synthesis(AnalysisSplice, Ss);
end
function RSound = Synthesis(AnalysisSplice, Ss)
[frame_len, nframes] = size(AnalysisSplice);
N = Ss*(nframes - 1) + frame_len;
RSound = zeros(1, N);
for q = 1:nframes
RSound(1 + (q-1)* Ss : frame_len + (q-1)*Ss) = RSound(1 + (q-1)* Ss : frame_len + (q-1)*Ss) + AnalysisSplice(:,q)';
end
end
Script執行代碼:
clc;
clear;
close all;
Path = 'D:\Experiment\OLA\';
file = [Path, 'test.wav'];
faster = [Path, 'faster.wav'];
[Speech, Fs] = wavread(file);
Rate = 0.7;
%wavread wavwrite enframe function comes from voicebox tools
RSound = OLA(Speech,Fs,Rate);
wavwrite(RSound,Fs,faster);
figure;
subplot(2,1,1);
plot(Speech);
title('original');
axis([1 length(Speech) -0.5 0.5]);
subplot(2,1,2);
plot(RSound);
title('0.7 faster');
axis([1 length(Speech) -0.5 0.5]);
變速前后的時域波形對比圖
OLA算法在重疊部分會造成基頻斷裂,甚至語音失真。所以后期許多算法基於此缺點進行了相關的改進。
測試文件:
http://pan.baidu.com/s/1hq4540G
來自:http://www.cnblogs.com/welen
http://blog.csdn.net/weiqiwu1986