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

How to get rid of the NAudio.MmException

Dec 30, 2011 at 1:39 AM
Edited Dec 30, 2011 at 1:41 AM

I'm experimenting on how to play mp3 using Naudio. My simple app has one windows form and one button to play/pause the music. The app however has two major problem:

  1. While it was intended that if the music is playing and the play button is pressed, the app should stop playing. Instead when the button is re-pressed, the app restart the music and then (sometime) throw an exception
  2. If the button is pressed two or three times (and  without any delay) ,the app throw a NAudio.MmException (Message=InvalidParameter calling acmStreamClose)

Can someone tell me what's wrong with my code? Below is my code: 

 

using System;
using System.Windows.Forms;
namespace NaudioTesting
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private NAudio.Wave.BlockAlignReductionStream stream = null;

        private NAudio.Wave.DirectSoundOut output = null;

       
        public void LoadFile(string filePath)
        {
            DisposeWave();

            if (filePath.EndsWith(".mp3"))
            {
                NAudio.Wave.WaveStream pcm =
                    NAudio.Wave.WaveFormatConversionStream.CreatePcmStream(new NAudio.Wave.Mp3FileReader(filePath));
                stream = new NAudio.Wave.BlockAlignReductionStream(pcm);
            }
            else if (filePath.EndsWith(".wav"))
            {
                NAudio.Wave.WaveStream pcm = new NAudio.Wave.WaveChannel32(new NAudio.Wave.WaveFileReader(filePath));
                stream = new NAudio.Wave.BlockAlignReductionStream(pcm);
            }
            else throw new InvalidOperationException("Not a correct audio file type.");

            output = new NAudio.Wave.DirectSoundOut();
            output.Init(stream);
            output.Play();
        }

        private void playPauseButton_Click(object sender, EventArgs e)
        {
            string filePath = "GetLoud.mp3";
            LoadFile(filePath);
            if (output != null)
            {
                if (output.PlaybackState == NAudio.Wave.PlaybackState.Playing) output.Pause();
                else if (output.PlaybackState == NAudio.Wave.PlaybackState.Paused) output.Play();
            }
        }

        private void DisposeWave()
        {
            try
            {
                if (output != null)
                {
                    if (output.PlaybackState == NAudio.Wave.PlaybackState.Playing) output.Stop();
                    output.Dispose();
                    output = null;
                }
                if (stream != null)
                {
                    stream.Dispose();
                    stream = null;
                }
            }
            catch (NAudio.MmException)
            {
                throw;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            DisposeWave();
        }
    }
}


Dec 30, 2011 at 8:38 AM

what version of NAudio are you using? You shouldn't need the BlockAlignmentReductionStream or the WaveFormatConversionStream with the latest version.

Dec 30, 2011 at 11:47 AM

@markheath: Thanks for your reply. I just fixed the problem in my app. It seems I needed to check if the output is not null before I call the loadFile function. Anyways, speaking of the Naudio version, I am using the latest version. As you mentioned, I "e BlockAlignmentReductionStream or the WaveFormatConversionStream with the latest version". What is that and how is that supposed to easy my burden. Even though now things worked out well, I would love to improve my code.

Dec 30, 2011 at 12:19 PM

it is just that the latest NAudio's Mp3FileReader already converts to PCM, and already copes with non-block aligned reposition requests, making it more robust and easy to use out of the box.