2016-06-11 42 views
0
でMixingSampleProviderを使用

私はチュートリアル(この素晴らしいユーティリティのためにあなたにマークをありがとう!)ここに書かれたよう でNAudioを使用して、「火とNAudioとオーディオ再生を忘れて」されています:私は管理 http://mark-dot-net.blogspot.nl/2014/02/fire-and-forget-audio-playback-with.htmlNAudio:正しくVolumeSampleProvider

MixingSampleProviderを入力として使用してVolumeSampleProviderを追加します。しかし、私は今すぐお互いの後に2つの音を再生すると、最初の音は、最初の音は常に最初の音が再生されていますが、2番目の音量を取得します。

私の質問は次のとおりです。サウンドごとに個別の音量でサウンドを追加するにはどうすればよいですか?

これは私が使用したものである:

 mixer = new MixingSampleProvider(waveformat); 
     mixer.ReadFully = true; 
     volumeProvider = new VolumeSampleProvider(mixer); 
     panProvider = new PanningSampleProvider(volumeProvider); 
     outputDevice.Init(panProvider); 
     outputDevice.Play(); 

答えて

1

私はあなたが求めているものの一定の100%ではないよ、あなたはすでにこれを解決した場合、私は知らないが、ここに私のテイクはこの上にあります。

ISampleProviderオブジェクトはRead()メソッドを使用してソースISampleProviderに「バック」ゲームを行います。最終的に、誰かがオーディオバイトの実際の読みをします。個々のISampleProviderクラスはバイトに何をしてもそれを行います。

MixingSampleProviderは、例えば、N個のオーディオソースを取ります。それらは混合されます。 Read()が呼び出されると、オーディオソースが反復され、それぞれからcountバイトが読み込まれます。 VolumeSampleProviderにそれを渡す

は、グループとして(これらのさまざまなソースからの)すべてのバイトを処理します...それは言う:軒並みバイトを調整するために起こって

buffer[offset+n] *= volume; 

...ので、すべてのバイトバッファ内で調整されます。volume乗数。

PanningSampleProviderは、ステレオオーディオに乗算器を提供し、それに応じてバイトを調整します。VolumeSampleProviderと同じ種類の処理を行います。

オーディオソースボリュームを個別に処理する場合は、MixingSampleProviderのアップストリームを処理する必要があります。基本的に、MixingSampleProviderに渡すものは、音量を個別に調整できる必要があります。

SampleChannelのオブジェクトをMixingSampleProviderに渡した場合、独立した音量調整を行うことができます。 Samplechannelクラスは、VolumeSampleProviderオブジェクトを組み込み、VolumeSampleProviderオブジェクトにボリュームを設定できるようにするプロパティーをVolumeに提供します。

SampleChannelはまた、所定の期間中の最大サンプル値の報告を提供するMeteringSampleProviderを組み込んでいる。チャンネルごとに1つの値が配列されたイベントが発生します。

+0

親愛なるマット、この回答をありがとうございました。私はそれを動作させることができるかどうかを調べるために、SampleChannelクラスを詳しく見ていく必要があります。私が最後にこのコードを編集してから1年以上経っていますので、すぐにわかるとは思いません。ご挨拶 – Paul

0

私は、この作業を行う唯一の方法は、ミキサーを単独で放置し、ミキサーに追加する前に、各CachedSoundのパンとボリュームを個別に調整することだと認識しました。したがって、追加の入力パラメータとしてパンとボリュームを使用して、CachedSoundSampleProviderを書き直す必要がありました。

これは新しいコンストラクタです:

public CachedSoundSampleProvider(CachedSound cachedSound, float volume = 1, float pan = 0) 
    { 
     this.cachedSound = cachedSound; 
     LeftVolume = volume * (0.5f - pan/2); 
     RightVolume = volume * (0.5f + pan/2); 
    } 

そして、これは新しい読む()関数です:

public int Read(float[] buffer, int offset, int count) 
    { 
     long availableSamples = cachedSound.AudioData.Length - position; 
     long samplesToCopy = Math.Min(availableSamples, count); 

     int destOffset = offset; 
     for (int sourceSample = 0; sourceSample < samplesToCopy; sourceSample += 2) 
     { 
      float outL = cachedSound.AudioData[position + sourceSample + 0]; 
      float outR = cachedSound.AudioData[position + sourceSample + 1]; 

      buffer[destOffset + 0] = outL * LeftVolume; 
      buffer[destOffset + 1] = outR * RightVolume; 
      destOffset += 2; 
     } 

     position += samplesToCopy; 
     return (int)samplesToCopy; 
    } 
関連する問題