Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

音声の LPC 解析と合成

この例では MATLAB® コマンド ラインで使用可能な DSP System Toolbox™ 機能を使用して、LPC (線形予測符号化) と呼ばれる音声圧縮手法を実装する方法を示します。

はじめに

この例では、音声信号の LPC 解析と合成 (LPC 符号化) を実装します。このプロセスは、解析と合成という 2 つの手順で構成されています。解析では信号から反射係数を抽出し、これを使用して残差信号を計算します。合成では残差信号と反射係数を使用して信号を復元します。残差信号と反射係数のコーディングに必要なビット数は、元の音声信号より少なくなります。

以下のブロック線図に、実装するシステムを示します。

このシミュレーションでは、音声信号が 3200 サンプルのサイズのフレームに分割され、そのうち 1600 サンプルがオーバーラップしています。各フレームはハミング ウィンドウで表示されます。12 次数の自己相関係数が検出されると、Levinson-Durbin アルゴリズムを使用して、自己相関係数から反射係数が計算されます。元の音声信号は解析フィルターに通されます。このフィルターは上記で取得した反射係数をもつすべての要素がゼロのフィルターです。このフィルターの出力が残差信号になります。この残差信号は、解析フィルターの逆である合成フィルターに通されます。この合成フィルターの出力が元の信号になります。

初期化

ここではフレーム サイズなどの変数の一部を初期化し、処理で使用する System object をインスタンス化します。これらのオブジェクトは必要な変数またはテーブルも事前に計算するため、ループ内で以降の呼び出しを効率よく処理できます。

変数を初期化します。

frameSize = 1600;
fftLen = 2048;

ここでオーディオ ファイルから読み取り、ファイルのオーディオ サンプリング レートを特定する System object を作成します。

audioReader = dsp.AudioFileReader('SamplesPerFrame', frameSize, ...
            'OutputDataType', 'double');

fileInfo = info(audioReader);
Fs = fileInfo.SampleRate;

プリエンファシスに使用する FIR デジタル フィルター System object を作成します。

preEmphasisFilter = dsp.FIRFilter(...
        'Numerator', [1 -0.95]);

バッファー System object を作成し、frameSize の 2 倍の長さで frameSize のオーバーラップ長をもつ出力が得られるようにプロパティを設定します。

signalBuffer = dsp.AsyncBuffer(2*frameSize);

ウィンドウの System object を作成します。ここでは、既定のウィンドウであるハミングを使用します。

hammingWindow = dsp.Window;

自己相関 System object を作成し、入力の長さでスケーリングされる、範囲 [0:12] のラグを計算するようにプロパティを設定します。

autoCorrelator = dsp.Autocorrelator( ...
            'MaximumLagSource', 'Property', ...
            'MaximumLag', 12, ...
            'Scaling', 'Biased');

レビンソン・ダービン再帰法を使用して自己相関関数から反射係数を計算する System object を作成します。多項式係数と反射係数の両方を出力するように設定します。多項式係数を使用して LPC スペクトルを計算およびプロットします。

levSolver = dsp.LevinsonSolver( ...
                'AOutputPort', true, ...
                'KOutputPort', true);

解析に使用する FIR デジタル フィルター System object を作成します。また、シンセシスおよびディエンファシスで使用される 2 つの全極デジタル フィルターの System object も作成します。

analysisFilter = dsp.FIRFilter(...
                    'Structure','Lattice MA',...
                    'ReflectionCoefficientsSource', 'Input port');

synthesisFilter = dsp.AllpoleFilter('Structure','Lattice AR');

deEmphasisFilter = dsp.AllpoleFilter('Denominator',[1 -0.95]);

結果として出力された音声を再生する System object を作成します。

audioWriter = audioDeviceWriter('SampleRate', Fs);

% Setup plots for visualization.
scope = dsp.SpectrumAnalyzer('SampleRate', Fs, ...
    'PlotAsTwoSidedSpectrum', false, 'YLimits', [-140, 0], ...
    'FrequencyResolutionMethod', 'WindowLength', 'WindowLength', fftLen,...
    'FFTLengthSource', 'Property', 'FFTLength', fftLen, ...
    'Title', 'Linear Prediction of Speech', ...
    'ShowLegend', true, 'ChannelNames', {'Signal', 'LPC'});

ストリーム処理ループ

ここではインスタンス化した System object を使用して入力オーディオ信号の LPC 解析と合成を行う処理ループを呼び出します。

ループは入力ファイルの末尾に達すると停止します。ファイルの末尾は AudioFileReader の System object によって検出されます。

while ~isDone(audioReader)
    % Read audio input
    sig = audioReader();

    % Analysis
    % Note that the filter coefficients are passed in as an argument to the
    % analysisFilter System object.
    sigpreem     = preEmphasisFilter(sig);
    write(signalBuffer,sigpreem);
    sigbuf       = read(signalBuffer,2*frameSize, frameSize);
    sigwin       = hammingWindow(sigbuf);
    sigacf       = autoCorrelator(sigwin);
    [sigA, sigK] = levSolver(sigacf); % Levinson-Durbin
    siglpc       = analysisFilter(sigpreem, sigK);

    % Synthesis
    synthesisFilter.ReflectionCoefficients = sigK.';
    sigsyn = synthesisFilter(siglpc);
    sigout = deEmphasisFilter(sigsyn);

    % Play output audio
    audioWriter(sigout);

    % Update plots
    sigA_padded = zeros(size(sigwin), 'like', sigA); % Zero-padded to plot
    sigA_padded(1:size(sigA,1), :) = sigA;
    scope([sigwin, sigA_padded]);
end

Release

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

release(audioReader);
pause(10*audioReader.SamplesPerFrame/audioReader.SampleRate); % Wait until audio finishes playing
release(audioWriter);
release(scope);

まとめ

ここでは線形予測符号化を使用した音声圧縮手法の実装を確認しました。この実装では、MATLAB コマンド ラインから使用できる DSP System Toolbox 機能を使用しました。コードでは、適切な入力引数を使用して連続した System object の呼び出しだけが行われます。MATLAB で Buffer を実装した場合のように、エラーが生じやすい手動の状態追跡は必要ありません。