単純な、またはコメント付きのリバーブアルゴリズムを探しています。疑似コードでも非常に役立ちます。
いくつか見つけましたが、コードはかなり難解で、追跡するのが難しい傾向があります。
これは、既存の配列にリバーブエフェクトを生成する「ディレイライン」の非常に単純な実装です(C#、buffer
is short[]
):
int delayMilliseconds = 500; // half a second
int delaySamples =
(int)((float)delayMilliseconds * 44.1f); // assumes 44100 Hz sample rate
float decay = 0.5f;
for (int i = 0; i < buffer.length - delaySamples; i++)
{
// WARNING: overflow potential
buffer[i + delaySamples] += (short)((float)buffer[i] * decay);
}
基本的には、各サンプルの値を取得し、それに減衰パラメーターを掛けて、結果をバッファーの値に追加しますdelaySamples
離れます。
これにより、各サウンドは振幅が減少しながら複数回聞こえるため、真の「リバーブ」エフェクトが生成されます。より単純なエコー効果(各サウンドが1回だけ繰り返される)を得るには、基本的に同じコードを使用し、for
ループを逆に実行するだけです。
pdate:このコンテキストの「リバーブ」という言葉には、2つの一般的な使用法があります。上記の私のコードサンプルは、漫画で一般的な古典的なリバーブエフェクトを生成しますが、音楽アプリケーションでは、この用語はリバーブ、より一般的には人工的な空間エフェクトの作成を意味するために使用されます。
残響に関する文献を理解するのが非常に難しい主な理由は、優れた空間効果を作成するには、ここでのサンプルメソッドよりもはるかに複雑なアルゴリズムが必要になるためです。ただし、ほとんどの電子空間効果は複数の遅延線を使用して構築されているため、このサンプルでは、何が起こっているかの基本を説明できると期待しています。本当に良いエフェクトを生成するには、FFTまたは単純なぼかしを使用してリバーブの出力を濁らせることもできます(またはすべきです)。
pdate 2:マルチディレイラインリバーブデザインのヒントをいくつか紹介します。
(波の意味で)お互いに積極的に干渉しない遅延値を選択します。たとえば、500msで1つの遅延があり、250msで2番目の遅延がある場合、両方のラインからのエコーを含むスポットが多くなり、非現実的な効果が生じます。この重複が起こらないようにするために、基本遅延に異なる素数を掛けることが一般的です。
(現実の世界の)広い部屋では、ノイズを発生させると、比較的歪みのない数秒間(数ミリ秒)の鋭いエコーが聞こえ、その後にエコーの大きな、かすかな "雲"が続きます。後方に走るいくつかの遅延ラインを使用して初期エコーを作成し、いくつかの完全なリバーブラインといくつかのぼかしを使用して「クラウド」を作成することにより、この効果を安価に実現できます。
絶対的なbestトリック(そして、私はこれを放棄したくないような気がしますが、地獄は何ですか)は、オーディオがステレオ。左右のチャンネル間でディレイラインのパラメーターをわずかに変えると(たとえば、左チャンネルが490ミリ秒、右チャンネルが513ミリ秒、または左チャンネルが.273ディケイ、右チャンネルが.2631)、非常に多くなります。よりリアルな響きのリバーブ。
デジタルリバーブには、通常2つの種類があります。
畳み込みリバーブ畳み込みインパルス応答 と入力信号。インパルス応答は、多くの場合、実際の部屋やその他の残響ソースの録音です。リバーブの特性は、インパルス応答によって定義されます。そのため、コンボリューションリバーブは通常、リバーブキャラクターを調整する手段が限られています。
アルゴリズムリバーブ遅延、フィルター、フィードバックのネットワークでリバーブを模倣します。異なるスキームは、これらの基本的なビルディングブロックを異なる方法で組み合わせます。技術の多くは、ネットワークを調整する方法を知ることです。アルゴリズムリバーブは通常、いくつかのパラメーターをエンドユーザーに公開するので、リバーブキャラクターを適切に調整できます。
EarLevelの リバーブについてのビット の投稿は、このテーマの優れた紹介です。コンボリューションリバーブとアルゴリズムリバーブの違いを説明し、それぞれの実装方法の詳細を示します。
Physical Audio Signal Processing by Julius O. Smithには、Freeverbアルゴリズムに特化したセクションを含む、リバーブアルゴリズムに関する章があります。いくつかのソースコードの例を検索するときに役立つかもしれません。
Sean Costelloの Valhalla ブログには興味深いリバーブのヒントが満載です。
必要なのは、モデリングまたはシミュレーションするルームまたはリバーブチャンバーのインパルス応答です。完全なインパルス応答には、すべてのマルチパスエコーとマルチパスエコーが含まれます。インパルス応答の長さは、インパルス音が可聴しきい値以下または所定のノイズフロア未満で完全に減衰するのにかかる時間(サンプル数)にほぼ等しくなります。
長さNのインパルスベクトルが与えられた場合、入力ベクトル(前のN-1入力サンプルと連結された現在のオーディオ入力サンプルで構成される)のベクトル乗算と適切なスケーリングを使用したインパルスベクトルによるオーディオ出力サンプルを生成できます。
一部の人々は、インパルス応答のほとんどのタップ(1を除くすべてのタップ)がゼロであると想定し、残りのエコーに対していくつかのスケーリングされた遅延線を使用して、出力に追加されることで、これを単純化します。
さらにリアルなリバーブを得るには、耳ごとに異なるインパルス応答を使用し、頭部の位置によって応答を少し変化させることができます。わずか1/4インチの頭の動きで、インパルス応答のピークの位置が1サンプル(44.1kレート)だけ変化する可能性があります。
GVerbを使用できます。 here からコードを取得します。GVerbはLADSPAプラグインです。LADSPAについて何か知りたい場合は、 here にアクセスしてください。
ここ はGVerbのwikiであり、パラメーターといくつかのインスタントリバーブ設定の説明が含まれています。
また、Objcで直接使用することもできます。
ty_gverb *_verb;
_verb = gverb_new(16000.f, 41.f, 40.0f, 7.0f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f);
AudioSampleType *samples = (AudioSampleType*)dataBuffer.mBuffers[0].mData;//Audio Data from AudioUnit Render or ExtAuidoFileReader
float lval,rval;
for (int i = 0; i< fileLengthFrames; i++) {
float value = (float)samples[i] / 32768.f;//from SInt16 to float
gverb_do(_verb, value, &lval, &rval);
samples[i] = (SInt16)(lval * 32767.f);//float to SInt16
}
GVerbはモノエフェクトですが、ステレオエフェクトが必要な場合は、各チャネルを個別にエフェクトに通してから、必要に応じて、処理済み信号をドライ信号とパンおよびミックスできます。