13

オーディオ コンピューティングの世界の皆さん、こんにちは。

録音を表すサンプルの配列があります。44100Hzで5秒としましょう。ピッチを上げてこれを再生するにはどうすればよいですか? また、ピッチを動的に増減することは可能ですか? ピッチをゆっくり上げて速度を 2 倍にしてから下げるようにします。

言い換えれば、DJ によって「スクラッチ」されているかのように、録音して再生したいのです。

疑似コードは常に歓迎されます。これをCで書きます。

ありがとう、


編集1

私の意図をはっきりさせてください。再生を 44100Hz に保ちたいので、再生前にサンプルを操作する必要があります。これは、ピッチを上げたオーディオと通常の速度で実行されているオーディオをミックスしたいからでもあります。

別の言い方をすれば、どうにかして同じサンプル数でオーディオを縮小する必要があるのでしょうか? そうすれば再生すると速くなるのでは?


編集2

また、これは自分でやりたいと思っています。ライブラリは使用しないでください (コードを調べて興味深いものを見つけることができると思わない限り)。


編集3

2 つの引数 (サンプルの配列とピッチ係数) を取り、新しいオーディオの配列を返す C で書かれたサンプル コードは素晴らしいでしょう!


PS私は、すでに与えられた答えが有効ではないとは思わないからではなく、これについて報奨金を開始しました。このテーマについてもっと多くのフィードバックを得ることができれば良いと思いました。



報奨金の授与

正直なところ、非常に役立つと思った回答がかなり多かったので、いくつかの異なる回答に報奨金を分配できればと思います。いくつかのコードを渡してくれた Daniel と、そのような詳細な応答を提供してくれた AShelly と Hotpaw2 に特別な感謝の意を表します。

最終的には、datageist によって参照された別の SO の質問からの回答を使用したため、賞は彼に与えられます。

みんなありがとう!

4

6 に答える 6

11

これに対する Nosredna の回答 (非常によく似た) の「象」の論文を見てください

サンプルの実装は 37 ページから提供されています。参考までに、AShelly の回答は線形補間 (同じページ) に対応しています。少し調整するだけで、この論文の他の式をそのフレームワークに組み込むことができます。

特定の補間方法の品質を評価する (および「より安価な」スキームを使用する際の潜在的な問題を理解する) には、次のページをご覧ください。

http://www.discodsp.com/highlife/aliasing/

おそらく (ソース コードを使用して) 扱いたいと思うよりも多くの理論については、これも良いリファレンスです。

https://ccrma.stanford.edu/~jos/resample/

于 2011-03-19T12:21:33.310 に答える
8

1つの方法は、浮動小数点インデックスを元の波に保持し、補間されたサンプルを出力波に混合することです。

//Simulate scratching of `inwave`: 
// `rate` is the speedup/slowdown factor. 
// result mixed into `outwave`
// "Sample" is a typedef for the raw audio type.
void ScratchMix(Sample* outwave, Sample* inwave, float rate)
{
   float index = 0;
   while (index < inputLen)
   {
      int i = (int)index;          
      float frac = index-i;      //will be between 0 and 1
      Sample s1 = inwave[i];
      Sample s2 = inwave[i+1];
      *outwave++ += s1 + (s2-s1)*frac;   //do clipping here if needed
      index+=rate;
   }

}

その場で変更したい場合rateは、それも可能です。

レート>1のときにノイズの多いアーティファクトが発生する場合は*outwave++ += s1 + (s2-s1)*frac;、この手法に置き換えてみてください(この質問から

*outwave++ = InterpolateHermite4pt3oX(inwave+i-1,frac);

どこ

public static float InterpolateHermite4pt3oX(Sample* x, float t)
{
    float c0 = x[1];
    float c1 = .5F * (x[2] - x[0]);
    float c2 = x[0] - (2.5F * x[1]) + (2 * x[2]) - (.5F * x[3]);
    float c3 = (.5F * (x[3] - x[0])) + (1.5F * (x[1] - x[2]));
    return (((((c3 * t) + c2) * t) + c1) * t) + c0;
}

「WindowsStartup.wav」で係数1.1の線形補間手法を使用した例。オリジナルが上にあり、高速化されたバージョンが下にあります。

数学的には完璧ではないかもしれませんが、そうあるべきであり、OPのニーズに合わせて正常に機能するはずです。

于 2011-03-01T20:48:22.333 に答える
3

はい、可能です。

しかし、これは少量の擬似コードではありません。あなたはタイムピッチ修正アルゴリズムを求めています。これは、まともな結果を得るためのかなり大きくて複雑な量のDSPコードです。

これがDSPDimensionsのタイムピッチストレッチの概要です。フェーズボコーダーアルゴリズムをGoogleで検索することもできます。

追加した:

DJが物理的なターンテーブルのLPで行うように、「スクラッチ」したい場合は、タイムピッチを変更する必要はありません。スクラッチは、ピッチとプレイの速度を同じ量だけ変更します(タイムピッチの変更が必要になるため、独立してではありません)。

そして、結果として得られる配列は同じ長さではありませんが、ピッチ/速度の変化によって短くなったり長くなったりします。

適切にフィルタリングされた補間を使用して信号をリサンプリングするだけで、ピッチを変更したり、同じ比率でサウンドの再生を速くしたり遅くしたりできます。必要なレート変更による浮動小数点の追加によって、1.0ではなく各サンプルポイントを移動し、そのポイントでデータをフィルタリングおよび補間するだけです。ウィンドウ化されたSinc補間カーネルを使用した補間は、ローパスフィルターの遷移周波数が元の補間されたローカルサンプルレートの低い方よりも低く、かなりうまく機能します。Webで「ウィンドウ化されたSinc補間」を検索すると、多くの適切な結果が返されます。

ローパスフィルターを含む内挿法が必要です。そうしないと、ひどいエイリアシングノイズが聞こえます。(これの例外は、元のサウンドファイルがサンプルレートより10年以上下ですでに厳しくローパスフィルター処理されている場合です。)

于 2011-03-02T00:51:18.610 に答える
3

これを簡単に実行したい場合は、AShelly の提案[編集: 実際のところ、とにかく最初に試してください] を参照してください。良い品質が必要な場合は、基本的にフェーズボコーダーが必要です。

位相ボコーダーの非常に基本的な考え方は、サウンドを構成する周波数を見つけ、必要に応じてそれらの周波数を変更し、サウンドを再合成することです。したがって、残忍な単純化は次のようになります。

  1. FFTを実行する
  2. すべての周波数を係数で変更する
  3. 逆FFTを実行する

これを自分で実装する場合は、位相ボコーダーの仕組みに関する完全な説明を読む必要があります。このアルゴリズムには、上記の 3 ステップの単純化よりも多くの考慮事項が必要です。

もちろん、既製の実装は存在しますが、私が集めた質問から、あなたはこれを自分でやりたいと思っています。

于 2011-03-24T11:47:35.737 に答える
0

これは、反対側から見ただけで同じことを再サンプリングするのに役立ちました。

コードが見つからない場合は、私に ping してください。このための優れた C ルーチンがあります。

于 2011-03-01T19:46:00.803 に答える
0

ピッチを増減するには、サンプルを 44.1kHz より低いレートまたは高いレートで再生するのと同じくらい簡単です。これにより、より遅い/より速いレコード サウンドが生成されますが、実際のレコードの「スクラッチ感」を追加する必要があります。

于 2011-03-01T15:12:13.083 に答える