Search code examples
c#audiomp3naudiopcm

Handle setting up WaveFormat for mp3 memory stream in NAudio


I'm trying to set up the WaveStream so that it uses the same format as the mp3 data passed in. I get the format by reading a frame, but when I try to actually create the new conversion stream using the new format I get an "AcmNotPossible calling AcmStreamOpen" exception.

Here's where I'm trying to set the new format:

Mp3Frame f = Mp3Frame.LoadFromStream(ms);
WaveFormat targetFormat = new Mp3WaveFormat(f.SampleRate, f.ChannelMode == ChannelMode.Mono ? 1 : 2, f.FrameLength, f.BitRate);
WaveFormatConversionStream conversionStream;
try
{
    using (WaveStream blockAlignedStream =
        new BlockAlignReductionStream(conversionStream = new WaveFormatConversionStream(targetFormat,
                new Mp3FileReader(ms))))
    {
        using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
        {
            waveOut.Init(blockAlignedStream);
            waveOut.Play();

I'm not sure if I even need to convert anything if I set up the wave stream to match the format of the mp3 data.

NOTE: I tried using WaveFormatStream.CreatePcmStream but I was getting 'static/white noise' for some mp3's. They appeared to be 16bit 44,100 stereo, but were being labeled as Version 1, Layer 1, as opposed to version 1, layer 3 which plays back correctly.


Solution

  • This code sample seems to have come from a long time back. You don;t need the BlockAlignReductionStream or the WaveFormatConversionStream, and you should stay away from function callbacks in WaveOut. This should be sufficient to play from a memory stream:

    var reader = new Mp3FileReader(ms)
    var waveOut = new WaveOutEvent();
    waveOut.Init(reader);
    waveOut.Play();