MP3 playback breaks moving from 1.3 release to change set 64823

Jan 9, 2011 at 10:21 PM

First of all, let me say that this is an awesome project!  It's saving me months of work!

I had built an application using the V 1.3 release of naudio and it was working very well.  I updated to changeset 64823 and mp3 playback stopped working.  I'm getting a "Not a supported encoding" exception from the DmoMediaType::SetWaveFormat method. 

Based on the change log and the demo app, I removed any PCM conversions and calls to BlockAlignReductionStream.  I even tried putting them back to see if that would make a difference, but no-joy. 

I'm creating the input stream like this:

 

                    Dim mp3Reader As WaveStream = New Mp3FileReader(fileName)
                                       inputStream = New WaveChannel32(mp3Reader)

Starting the playback like this:

                If waveOutDevice Is Nothing Then
                    CreateWaveOut()
                End If

                waveOutDevice.Init(inputStream)
                
                timer1.Interval = 1000
                timer1.AutoReset = True
                AddHandler timer1.Elapsed, AddressOf TimerHandler
                waveOutDevice.Play()
                timer1.Start()
The CreateWaveOut method looks like this:
            Private Sub CreateWaveOut()
                waveOutDevice = New WasapiOut(AudioClientShareMode.Shared, True, 100)
            End Sub
Again, this worked great using the 1.3 release, just not now with the latest change set.
Any help would be appreciated.
-John
Coordinator
Jan 10, 2011 at 6:31 AM

that's very strange, because the WaveFormat of the input stream should be exactly the same as before (probably 44.1KHz IEEE float stereo). Can you double check what it is? Wasapi is much more fussy than WaveOut; you have to be playing at exactly the right frequency.

Mark

Jan 10, 2011 at 11:55 PM

Okay.  I did some before and after breakpoints to get the formats you asked for.  Right where I invoke the waveoutdevice.init method I checked the format under V1.3.  I get the following:

  • Encoding:  IeeeFloat {3}
  • Channels:  2
  • SampleRate:  44100

 

I then replaced naudio with the latest change set and get the exact same thing.  So that looks normal.  However, I put a break just before the "Not a supported encoding" exception in DmoMediaType::SetWaveFormat to take a look at the parameter "waveFormat".  It shows the following:

  • Encoding:  Extensible
  • Channels: 2
  • SampleRate: 48000

 

 

Here's the method where the exception is being thrown:

  /// <summary>
        /// Sets this object up to point to a wave format
        /// </summary>
        /// <param name="waveFormat">Wave format structure</param>
        public void SetWaveFormat(WaveFormat waveFormat)
        {
            majortype = MediaTypes.MEDIATYPE_Audio;
            switch (waveFormat.Encoding)
            {
                case WaveFormatEncoding.Pcm:
                    subtype = AudioMediaSubtypes.MEDIASUBTYPE_PCM;
                    bFixedSizeSamples = true;
                    break;
                case WaveFormatEncoding.IeeeFloat:
                    subtype = AudioMediaSubtypes.MEDIASUBTYPE_IEEE_FLOAT;
                    bFixedSizeSamples = true;
                    break;
                case WaveFormatEncoding.MpegLayer3:
                    subtype = AudioMediaSubtypes.WMMEDIASUBTYPE_MP3;
                    break;
                default:
                    throw new ArgumentException("Not a supported encoding");
            }
            formattype = DmoMediaTypeGuids.FORMAT_WaveFormatEx;
            if (cbFormat < Marshal.SizeOf(waveFormat))
                throw new InvalidOperationException("Not enough memory assigned for a WaveFormat structure");
            //Debug.Assert(cbFormat >= ,"Not enough space");
            Marshal.StructureToPtr(waveFormat, pbFormat, false);
        }

 

 

 

Somewhere along the line something is changing.  I don't see where that's happening in my code.

 

Thanks for your help,

 

-John

 

 

 

 

Coordinator
Jan 11, 2011 at 8:54 AM

what is the WaveFormat of inputstream? Wasapi playback often has the 44.1/48kHz issue as it doesn't do SRC for you, and if you (say) play a DVD, your soundcard can switch to 48kHz, breaking 44.1kHz playback

 

Jan 11, 2011 at 4:53 PM

It's an mp3 file and I'm using the mp3Reader class.  Remember, it works under the 1.3 release, just not under the latest change set. 

Somewhere along the line, the encoding is changing from IEEE to "Extensible".  Is that normal?  As far as I know, I'm not doing it in my code. 

 

Thanks again,

 

-John

 

Coordinator
Jan 11, 2011 at 4:55 PM

what is the WaveFormat of inputstream?

what decoder is being used - ACM or DMO?

 

Coordinator
Jan 11, 2011 at 4:56 PM

also, can you play MP3 with WASAPI using the NAudioDemo app?

Coordinator
Jan 11, 2011 at 5:00 PM

assuming you are using the ACM frame decompressor - the WaveFormat you are seeing is likely coming from the AcmFormatSuggest function:

http://naudio.codeplex.com/SourceControl/changeset/view/64823#1678310

what ACM codecs do you have installed that can decompress MP3?

Jan 11, 2011 at 5:02 PM

Sorry Mark.  I know I'm being thick.  I guess I'm not sure what you're asking.  I don't believe I'm explicitly selecting a decoder in my code.  Is there something I can look at in the debugger to get you that? 

 

Good idea on checking the demo app from the new change set.  I should have thought of that before bugging you :)

I'll do that and get back to you.

 

Thanks,

-John

 

Jan 11, 2011 at 5:04 PM

Looks like we both posted at the same time.  I'll also look at the available codecs.

Thanks

Jan 11, 2011 at 9:31 PM
Edited Jan 11, 2011 at 9:33 PM

The demo application fails with the same error.  A window titled "Error initializing output" with a message saying "Not a supported encoding" pops up.  I've tried this with multiple mp3's and I get the same error.

I also set a breakpoint at the DmoMediaType::SetWaveFormat method while running the demo app to see if I can get some more info.  Turns out it is called three times.  Twice with the IEEE encoding, the third time with the extensible encoding. 

Again, while running the demo app, I also set a breakpoint in the Ac3Mp3Decompressor class you mentioned to see what AcmFormatSuggest returns.  It returns "16 bit PCM 44 kHz 2 Channels".  I think that also confirms it's attempting to use the AcmMp3Frame decompressor.

I've got the following codecs available on my machine:

ACM Microsoft IMA ADPCM CODEC 0011 imaadp32.acm 6.1.7600.16385
ACM Microsoft CCITT G.711 A-Law and u-Law CODEC 0007 msg711.acm 6.1.7600.16385
ACM Microsoft GSM 6.10 Audio CODEC 0031 msgsm32.acm 6.1.7600.16385
ACM Microsoft ADPCM CODEC 0002 msadp32.acm 6.1.7600.16385
ACM Fraunhofer IIS MPEG Layer-3 Codec (decode only) 0055 l3codeca.acm 1.9.0.401
ACM Decode AC3 and DTS audio 2001    
ACM LAME MP3 Codec v0.9.2 - 3.98.2 0001 LameACM.acm 0.9.1.0
ACM Microsoft PCM Converter 0001 LameACM.acm 0.9.1.0
DMO WMAudio Decoder DMO 0160, 0161, 0162, 0163 WMADMOD.DLL 6.1.7600.16385
DMO WMAPro over S/PDIF DMO 0162 WMADMOD.DLL 6.1.7600.16385
DMO WMSpeech Decoder DMO 000A, 000B WMSPDMOD.DLL 6.1.7600.16385
DMO MP3 Decoder DMO 0055 mp3dmod.dll 6.1.7600.16385

 

Thanks again for the help.

 

Regards,

 

John

 

Jan 11, 2011 at 10:06 PM

I think I may have found the problem.

I went into the Sound control panel and looked at the default output device settings.  The default format was set to 48 kHz 24 bits.  I changed it to 44 kHz and the demo app started working!  I'll re-integrate the latest change-set into my app and see what happens.   How can I programatically deal with this sort of scenario?  Also, is there a way to select from multiple sound cards on a machine using WASAPI.  I know it can be done with the other output drivers, but the property to select the device doesn't exist in the WasapiOut class.

Thanks again for the help and the hard work you've done on this project.  It is truly an awesome piece of work!

 

-John

 

 

Coordinator
Jan 12, 2011 at 4:08 PM

Yes, it is very frustrating that WASAPI doesn't offer any sample rate / bit depth conversion for you like WaveOut does, making it less than useful for general purpose audio playback. Off the top of my head, I can't remember what the way to query available WASAPI devices is, but there should be a way, and there are wrappers in NAudio for most of the API now.

Mark