This project has moved and is read-only. For the latest updates, please go here.

Combining 2 mono wavestreams to 1 stereo wavestream

Aug 9, 2013 at 2:30 AM
I want to create a stereo wav out of 2 mono wavs (from a soundfont file). I can get it to combine into a waveprovider, but I need to be able to show the waveform using WaveViewer.

This is what I have now:
RawSourceWaveStream leftChannel = new RawSourceWaveStream(new MemoryStream(sf.SampleData, (int)sf.SampleHeaders[left].Start * 2, (int)((sf.SampleHeaders[left].End - sf.SampleHeaders[left].Start) * 2)), new WaveFormat(44100, 1));
RawSourceWaveStream rightChannel = new RawSourceWaveStream(new MemoryStream(sf.SampleData, (int)sf.SampleHeaders[right].Start * 2, (int)((sf.SampleHeaders[right].End - sf.SampleHeaders[right].Start) * 2)), new WaveFormat(44100, 1));
MultiplexingWaveProvider stereoWave = new MultiplexingWaveProvider(new IWaveProvider[] { leftChannel, rightChannel }, 2);
I'm not even sure if this does the right thing (combine left and right channels properly), but even if it does it ends up being a WaveProvider (that does not have a length).

My WaveViewerEx control needs the total length of the wave to be able to fit the waveview in the control.

Of course I can do it manually, but combining 2 mono streams into a single stereo stream seems to be such a common task that I think I must be missing something obvious.

Can this be done using NAudio, or should I combine the 2 channels manually?
Aug 21, 2013 at 3:19 PM
the length will be the longer of the two input streams,
Aug 21, 2013 at 11:13 PM
I've created my own implementation. I did try to use the Buffer helper functions, but am getting strange memory corruptions (due to the trick with mapping floats over bytes etc) so I ended up just using byte arrays and mixing like that. Works perfect now, just wanted to let you know that the Buffer helper classes don't work correctly in all cases. I can show you some code so you can verify I did it right if you want.
Sep 9, 2013 at 3:27 PM
If you can provide a failing unit test with WaveBuffer, I'd be interested. It's proved itself reliable over 6 years now, so I'm fairly confident it can be trusted. You do need to make sure you don't overwrite the end of the underlying buffer though. Only the Length of the byte array can be trusted. Also, don't use it with Array.Copy as it uses reflection to find the underlying array type and therefore pays no attention to whether you passed in the float[] instead of the byte[]