オーディオエフェクト:フランジャーとコーラス

はじめに

今日は、フランジャーとコーラスの2つの音響効果について説明しますが、これらもディレイに基づいて実装されており、実装と原理には多くの類似点があります。

私たちはまだ古いルールです。最初にこれら2つの音響効果の特定の効果を紹介し、それらの実装の詳細を分析し、最後に2つの音響効果の類似点と相違点を示します。

フランジャー

1つはフランジャーで、中国語では「フランジ」に変換されます。これは、もともとオープンリールレコーダーのエッジを意味していました。

フランジャーサウンドエフェクトを生成するために、2つのオープンテープレコーダーを使用して、同じテープを同時に再生できます。2つのレコーダーがまったく同じように再生される場合、出力オーディオは元のオーディオを強化するだけです。フランジャーエフェクトを生成するために、2つのオーディオ間の時間にわずかな差を生じさせることに加えて、レコーダーの1つをゆっくりと押して再生レートを下げ、ピッチを下げることができます。圧力を解除すると、元の音色と時間差が徐々に消えると同時に、別のレコーダーを軽く押すことでサイクルが繰り返され、フランジャー効果音が発生します。

フランジャーは「飛行」効果音とも呼ばれ、空を飛んでいるジェット機のように、汽笛のように聞こえるので、聞いてみましょう。フランジャーの音が頭上を飛行機が浮かんでいるように聞こえます。

生の音声

フランジャー

それはフランジャーの結果の原則に来るとき、私たちは言及しなければならない建設的干渉(建設的干渉)破壊的干渉(破壊的干渉を)

簡単に言えば、正弦信号があり、それが遅延によって元のオーディオに追加されると仮定します。2つの信号が完全に同相の場合、出力オーディオの振幅は入力の2倍になり、建設的な干渉になります。2つの信号が位相が相殺されるだけで、ミュート信号が出力されます。これは破壊的な干渉です。

通常、オーディオには多数の周波数があります。遅延して元の信号に追加すると、一部の周波数が互いにキャンセルされ(周波数応答が「谷」として表示され)、一部の周波数が互いに強調されます(周波数応答が「ピーク」として表示されます)。 。LFOの影響で「波頭」と「波谷」が移動して変化し、最終的にフランジャー効果音が発生します。このプロセスは、オープニングレコーダーのフランジャーの操作と併せて理解できます。レコーダーを繰り返したたくサイクルは、実際にはLFOと一致する周期的な遅延を生成するプロセスです。

基本フランジャー

基本的なフランジャーの差分方程式とブロック図は次のとおりです

y [n] = x [n] + gx [n-M [n]]

基本的なフランジャー

どこに

  • g フィードバック、深さとも呼ばれます
  • M [n]LFOによって制御される遅延用

基本的なフランジャー構造も呼ばれるフィードフォワードコムフィルタを、それは櫛のようなスペクトル応答であるので、。伝達方程式で説明できます。

\ begin {aligned} Y(z)&= X(z)+ gz ^ {-M [n]} X(z)\\ H(z)&= \ frac {Y(z)} {X(z) } = 1 + gz ^ {-M [n]} \ end {aligned}

次数z = e ^ {j \ omega}\ omega \ in [0、\ pi]振幅応答が得られる場所

\ begin {aligned} H(e ^ {j \ omega})&= 1 + ge ^ {-j \ omega M [n]} \\ \ vert H(e ^ {j \ omega})\ vert&= \ sqrt {1 + 2g \ cos(\ omega M [n])+ g ^ 2} \ end {aligned}

振幅応答があることが分かる\ vert H(e ^ {j \ omega})\ vertで、周期関数のcosである\ omega \ in [0、\ pi]M / 22、「ピーク」と「谷」

「波紋」の場所は次のとおりです。

\ omega_p = 2 \ pi p / M

「Pogu」は次の場所にあります。

\ omega_n =(2n + 1)\ pi / M

「波のピーク」と「波のピーク」、「波の谷」、「波の谷」の周波数間隔は f_s / M

したがって、櫛のような振幅応答ルックス、など、例えば、これに続いてM [n] = 6振幅応答:

Combfilter

ときにM [n]LFOを変える、「ピーク」と「谷」の制御は、音声フランジャーを生成し、変化しています

フィードバック付きフランジャー

フィードバック付きフランジャーのブロック図によると、差分方程式は次のように書くことができます。

y [n] = x [n] + g_ {ff} d [n] \ quad \ text {where} \ quad d [n] = x [nM] + g_ {fb} d [nM]

だけで変換と[n]し、x [n]に関連する方程式の違い:

\ begin {aligned} y [nM]&= x [nM] + g_ {ff} d [nM] \\ d [n]&= x [nM] + \ frac {g_ {fb}} {g_ {ff} }(y [nM]-x [nM])\\ y [n]&= x [n] + g_ {fb} y [nM] +(g_ {ff} -g_ {fb})x [nM] \ end {aligned}

flanger_with_feedback

伝達方程式は次のとおりです。

H(z)= \ frac {Y(z)} {X(z)} = \ frac {z ^ M + g_ {ff} -g_ {fb}} {z ^ {M} -g_ {fb}}

それは次のように見ることができg_ {fb} = 0、その伝達式は、基本的なフランジャーと一致しています、。場合はg_ {fb} <1単位円内の全ての極は、安定しています。

次に、特定の実装コードを直接実装します

void Flanger::processBlock(AudioBuffer<float> &buffer)
{
    const int num_channels = buffer.getNumChannels();
    const int num_samples = buffer.getNumSamples();
    float phase = 0.0f;
    float channel0EndPhase = phase_;

    assert(static_cast<size_t>(num_channels) <= dlines_.getNumLines());

    for(int c = 0; c < num_channels; ++c)
    {
        phase = phase_;
        if(stereo != 0 && c != 0)
        {
            phase = fmodf(phase + 0.25f, 1.0f);
        }

        float* channel_data = buffer.getWritePointer(c);
        auto* dline = dlines_.getDelayLine(c);

        for(int i = 0; i < num_samples; ++i)
        {
            const float in = channel_data[i];

            // get delay from lfo
            float delay_second = min_delay + sweep_width*lfo_.lfo(phase, LFO::WaveformType::kWaveformSine);
            float delay_sample = delay_second * static_cast<float>(getSampleRate());

            // get interpolation delay value
            float interpolation_val = dline->getInterpolation(delay_sample);
            channel_data[i] = in + depth * interpolation_val;

            // push input to delay line
            dline->push(in + (interpolation_val * feedback));

            // update phase
            phase += lfo_freq*invert_sample_rate_;
            if(phase >= 1.0f)
            {
                phase -= 1.0f;
            }
        }

        // use channel 0 only keep the phase in sync between call processBlock()
        if(c == 0)
        {
            channel0EndPhase = phase;
        }
    }

    phase_ = channel0EndPhase;
}
复制代码

説明が必要な詳細が1つあります。それはステレオモードです。

ステレオモードがオンになっている場合は、疑似ステレオ効果を作成します。いわゆる「疑似ステレオ」とは、左チャネルと右チャネルに違いがあることを意味しますが、リスナーはその方向を明確に区別できません。ステレオ音の理由:音と左右の耳の時間差、周波数差、音量差。私たちの実装では、LFOの位相に左チャネルと右チャネルの違いがあり、結果として遅延の違いが生じ、結果として疑似ステレオサウンドになります。

コーラスサウンド

次に紹介するのは、コーラスコーラスサウンドエフェクトです。フランジャーとコーラスはディレイベースのサウンドエフェクトであり、実装はほぼ同じです。

2つの最大の違いは、遅延の長さです。コーラスで使用される遅延は長く、通常は20〜30ミリ秒以上、フラグは通常10ミリ秒未満であり、人間のエコーの制限(約50〜70ミリ秒)をはるかに下回ります。

音楽では、ピッチや音色が似た音をいくつか独立して演奏すると、コーラス効果音が出ます。この種の効果音は非常に一般的です。たとえば、同じ曲を歌ったり、同時にバイオリンを演奏したりする人々のグループは、一斉に演奏していても、常にピッチや時間にわずかな違いを示します。これらの微妙な変更により、サウンドはより豊かで明るくなり、大きな弦楽オーケストラの演奏が非常に衝撃的に聞こえる理由の1つです。コーラス効果音は、これらの時間とピッチの違いをシミュレートし、1つの楽器の音源でも、複数の楽器が一緒に演奏しているように聞こえます。

コーラス効果音を聞いてみよう

生の音声

コーラス

基本合唱

基本的なコーラスの差分方程式とブロック図は次のとおりです

y [n] = x [n] + gx [n-M [n]]

基本合唱

基本的なコーラスと基本的なフランジャーの構造は同じであることがわかります。これらの主な違いは、遅延の長さです。コーラスの遅延の長さは通常20〜30ミリ秒で、フラグは通常10ミリ秒未満です。

基本的なコーラスは基本的なフランジャーと同じで、その振幅応答は櫛のようなものです。

\ begin {aligned} \ vert H(e ^ {j \ omega})\ vert&= \ sqrt {1 + 2g \ cos(\ omega M [n])+ g ^ 2} \ end {aligned}

コーラスの遅延を30ミリ秒、サンプリングレートを48 kHzとすると、M = 14402つのピークの間隔はf_s / M = 33.3 Hz、つまり、33.3 Hzごとにピークが現れると仮定します。私たちの補聴器では、33.3 Hzでの周波数差は小さすぎて解決できません。

コードのすぐ下

void Chorus::processBlock(AudioBuffer<float> &buffer)
{
    const auto num_channels = buffer.getNumChannels();
    const auto num_samples = buffer.getNumSamples();

    float ph = 0.0f;

    for(size_t c = 0; c < num_channels; ++c)
    {
        auto* channel_data = buffer.getWritePointer(c);
        auto* dline = dlines_.getDelayLine(c);

        ph = phase_;

        for(size_t i = 0; i < num_samples; ++i)
        {
            const float in = channel_data[i];
            float weight = 0.0f;
            float phase_offset = 0.0f;

            for(int j  = 0; j < num_voices - 1; ++j)
            {
                if(stereo != 0 && num_voices > 2)
                {
                    weight = (float)(j) / (float)(num_voices-2);

                    if(c != 0)
                    {
                        weight = 1.0f - weight;
                    }

                } else
                {
                    weight = 1.0f;
                }

                if(weight != 0.0f)
                {
                    // get delay from lfo
                    float delay_second = min_delay + sweep_width*lfo_.lfo(fmodf(ph+phase_offset,1.0f), LFO::WaveformType::kWaveformSine);
                    float delay_sample = delay_second * static_cast<float>(getSampleRate());

                    // get interpolation value
                    float interpolation_val = dline->getInterpolation(delay_sample);
                    channel_data[i] = in + weight * depth * interpolation_val;
                }

                if(num_voices < 3)
                {
                    phase_offset += 0.25f;
                } else
                {
                    phase_offset += 1.0f / (float)(num_voices - 1);
                }
            }

            dline->push(in);

            // update phase
            ph += lfo_freq*invert_sample_rate_;
            if(ph >= 1.0f)
            {
                ph -= 1.0f;
            }
        }
    }

    phase_ = ph;
}

复制代码

より複雑な部分は疑似ステレオ部分であり、この実装部分では周波数差と音量差が含まれ、その中で周波数差と音量差がphase_offset制御されweightます。

まとめ

コーラスとフランジャーは基本的に同じ構造です。主な違いはパラメーターの選択にあります。コーラスはフランジャーよりも長いディレイを使用し、通常はスイープ幅が大きくなります。これらのパラメーターを組み合わせると、元のサウンドと遅延コピーの間の分離感とピッチモジュレーションが大きくなります。

もう1つの構造上の違いは、フランジャーがフィードバックを使用して、コーラスにはほとんどない、より強いエフェクトを生成できることです。一方、コーラスは複数の遅延コピーを使用しますが、フランジャーは通常1つのコピーのみを使用します。

おすすめ

転載: juejin.im/post/5e9e5616e51d4546ca30c439