OLA音頻變速算法的仿真與剖析


      前段時間,在嘗試音樂節拍數的提取時,終於有了突破性的進展,效果基本上比市面上的許多商業軟件還要好,在作節拍數檢測時,高頻信息作用不大,

通過重采樣減小運算量。重采樣讓我想起了在學校里面做的變速變調算法,在這里順便回顧一下。

      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 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM