DSP System Toolbox

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

位相ボコーダーを使用したピッチ シフトと時間伸長

この例では、オーディオ信号のタイム ストレッチとピッチ スケールを行う位相ボコーダーを実装する方法を示します。

はじめに

位相ボコーダーは、音声を周波数領域に変換して、タイム ストレッチとピッチ スケールを実行します。位相ボコーダーの実装に必要な演算を次のブロック線図に示します。

位相ボコーダーには、オーバーラップした短時間 FFT (ST-FFT) を実行する解析セクションと、オーバーラップした逆短時間 FFT (IST-FFT) を実行する合成セクションがあります。信号をタイム ストレッチするため、位相ボコーダーは合成セクションのオーバーラップ加算演算に解析セクションより大きいホップ サイズを使用します。ここでホップ サイズは一度に処理されるサンプルの数です。この結果、周波数成分は同じでも、出力時のサンプル数が入力時よりも多くなります。これで、より高いサンプルレートでこの信号を再生することによって、信号をピッチ スケールできます。これにより、音声の時間は元のままでピッチが高い信号が生成されます。

初期化

最適なパフォーマンスを達成するには、処理ループで使用する前に System object を作成して初期化しなければなりません。次のコード セクションを使用して必要な変数を初期化し、入力音声データを読み込みます。ファクター 90/64 で信号をストレッチするために、解析ホップ サイズを 64 に設定し、合成ホップ サイズを 90 に設定します。

作成した System object を設定する際に使用する一部の変数を初期化します。

WindowLen = 256;
AnalysisLen = 64;
SynthesisLen = 90;
Hopratio = SynthesisLen/AnalysisLen;

オーディオ ファイルから入力音声信号を読み取る System object を作成します。

hAudioSource = dsp.AudioFileReader(...
  which('speech_dft_8kHz.wav'), ...
  'SamplesPerFrame', AnalysisLen, ...
  'OutputDataType', 'double');

ST-FFT で使用されるバッファー System object を作成します。

hbuf = dsp.Buffer(WindowLen, WindowLen - AnalysisLen);

% Create a Window System object, which is used for the ST-FFT. This object
% applies a window to the buffered input data.
hwin = dsp.Window('Hanning', 'Sampling', 'Periodic');

ST-FFT で使用される FFT System object を作成します。

hfft = dsp.FFT;

% Create an IFFT System object, which is used for the IST-FFT.
hifft = dsp.IFFT('ConjugateSymmetricInput', true, ...
  'Normalize', false);

元の音声信号を再生する System object を作成します。

Fs = 8000;
hAudioOut = dsp.AudioPlayer('SampleRate', Fs);

% Create a System object to log your data.
hslg = dsp.SignalSink;

処理ループで使用される変数を初期化します。

yprevwin = zeros(WindowLen-SynthesisLen, 1);
gain = 1/(WindowLen*sum(hanning(WindowLen,'periodic').^2)/SynthesisLen);
unwrapdata = 2*pi*AnalysisLen*(0:WindowLen-1)'/WindowLen;
yangle = zeros(WindowLen, 1);
firsttime = true;

ストリーム処理ループ

System object をインスタンス化したので、入力信号でタイム ストレッチを実行する処理ループを作成できるようになりました。ループは入力ファイルの末尾に達すると停止します。末尾かどうかは、AudioFileReader System object によって検出されます。

while ~isDone(hAudioSource)
    y = step(hAudioSource);

    step(hAudioOut, y);    % Play back original audio

    % ST-FFT
    % FFT of a windowed buffered signal
    yfft = step(hfft, step(hwin, step(hbuf, y)));

    % Convert complex FFT data to magnitude and phase.
    ymag       = abs(yfft);
    yprevangle = yangle;
    yangle     = angle(yfft);

    % Synthesis Phase Calculation
    % The synthesis phase is calculated by computing the phase increments
    % between successive frequency transforms, unwrapping them, and scaling
    % them by the ratio between the analysis and synthesis hop sizes.
    yunwrap = (yangle - yprevangle) - unwrapdata;
    yunwrap = yunwrap - round(yunwrap/(2*pi))*2*pi;
    yunwrap = (yunwrap + unwrapdata) * Hopratio;
    if firsttime
        ysangle = yangle;
        firsttime = false;
    else
        ysangle = ysangle + yunwrap;
    end

    % Convert magnitude and phase to complex numbers.
    ys = ymag .* complex(cos(ysangle), sin(ysangle));

    % IST-FFT
    ywin  = step(hwin, step(hifft,ys));    % Windowed IFFT

    % Overlap-add operation
    olapadd  = [ywin(1:end-SynthesisLen,:) + yprevwin; ...
                ywin(end-SynthesisLen+1:end,:)];
    yistfft  = olapadd(1:SynthesisLen,:);
    yprevwin = olapadd(SynthesisLen+1:end,:);

    % Compensate for the scaling that was introduced by the overlap-add
    % operation
    yistfft = yistfft * gain;

    step(hslg, yistfft);     % Log signal
end

Release

ここでは System object に対して release メソッドを呼び出し、開いているファイルと装置を閉じます。

release(hAudioSource);
release(hAudioOut);

記録された音声信号の再生

loggedSpeech = hslg.Buffer(200:end)';
% Play time-stretched signal
p2 = audioplayer(loggedSpeech, Fs);
disp('Playing time-stretched signal...');
playblocking(p2);

% Play pitch-scaled signal
% The pitch-scaled signal is the time-stretched signal played at a higher
% sampling rate which produces a signal with a higher pitch.
Fs_new = Fs*(SynthesisLen/AnalysisLen);
p3 = audioplayer(loggedSpeech, Fs_new);
disp('Playing pitch-scaled signal...');
playblocking(p3);
Playing time-stretched signal...
Playing pitch-scaled signal...

まとめ

この例では、音声信号のタイム ストレッチとピッチ スケールを実行する位相ボコーダーを実装しました。例を実行すると、タイムストレッチおよびピッチスケールを行った信号を聞くことができます。

参考文献

A. D. Gotzen, N. Bernardini and D. Arfib, "Traditional Implementations of a Phase-Vocoder:The Tricks of the Trade," Proceedings of the COST G-6 Conference on Digital Audio Effects (DAFX-00), Verona, Italy, December 7-9, 2000.