3

C# と NAudio を使用して、それぞれが 3 つの入力ファイルの 1 つに対応する 3 つのチャネルを持つ単一の wave ファイルに結合したい 3 つの wave ファイルがあります。さらに、各ウェーブ ファイルのオーディオ クリップを、最終ストリームの異なるポイントから開始したいと考えています。たとえば、3 つの wave ファイルの長さが 3 秒の場合、5 秒です。それぞれ 2 秒、出力 Wave ファイルの長さは 10 秒になり、...

  • チャネル 1 には、ファイル 1 からの 3 秒間の音声と、それに続く 7 秒間の無音が含まれます。

  • チャンネル 2 には 3 秒間の無音、続いてファイル 2 からの 5 秒間の音声、その後 2 秒間の無音が含まれます。

  • チャンネル 3 には、8 秒間の無音と、それに続くファイル 3 からの 2 秒間の音声が含まれています。

ファイルごとに WaveChannel32 インスタンスを作成してから、WaveOffsetStream クラスを使用して実験してきましたが、この種のことは初めてで、あまり成功していません。

誰にも提案はありますか?

4

1 に答える 1

2

これを行うには、出力 WaveFormat に 3 つのチャネルがある独自のカスタム IWaveProvider/WaveStream を記述します。3 つの入力ファイルのそれぞれへの参照を保持します。次に、Read メソッドで、要求されたサンプル数を計算し、各ソース ファイルから適切な数を読み取ります。次に、サンプルをインターリーブする必要があります。最初のファイルから 1 つ、2 番目のファイルから 1 つ、3 番目のファイルから 1 つです。遅延するには、ゼロを入れるだけです。

さまざまなソース ファイル (すべて同じビット深度とサンプル レートである必要があります) からインターリーブする未テストのサンプル コードを次に示します。これにより、正しい方向に進むことが期待されます。

int Read(byte[] buffer, int offset, int bytesRequired)
{
    int bytesPerSample = this.WaveFormat.BitsPerSample / 8;
    int samplesRequired = bytesRequired / bytesPerSample;
    int channels = this.WaveFormat.Channels; // 3
    int samplesPerChannel = samplesRequired / channels;
    byte[] readBuffer = new byte[samplesPerChannel * bytesPerSample];
    for (int channel = 0; channel < channels; channel++)
    {
        int read = inputs[channel].Read(readBuffer, 0, samplesPerChannel * bytesPerSample);
        int outOffset = offset + channel * bytesPerSample;
        for (int i = 0; i < read; i += bytesPerSample)
        {
             Array.Copy(readBuffer, i, buffer, outOffset, bytesPerSample);
             outOffset += channels * bytesPerSample;
        } 
    }
}

コードが過度に複雑にならないようにするために、別の派生 IWaveProvider / WaveStream を作成し、その Read メソッドが適切な量の無音を返した後、入力ファイルから実際のデータを返すことによって、無音の挿入を行うことができます。これは、インターリーブする WaveStream への入力として使用できます。

于 2011-08-10T10:10:12.663 に答える