Corey-M/NAudio.Lame

Null reference exception on flush (or dispose)

Closed this issue · 1 comments

I've been trying to find and fix an issue where on some PC's, in some cases, a null-reference exception is thrown when stopping the recording. Not sure if it's actually me doing something wrong, or a possible bug

This is the error:

System.NullReferenceException: De objectverwijzing is niet op een exemplaar van een object ingesteld.
bij LameDLLWrap.NativeMethods.lame_encode_buffer(IntPtr context, Int16[] buffer_l, Int16[] buffer_r, Int32 nSamples, Byte[] mp3buf, Int32 mp3buf_size)
bij NAudio.Lame.LameMP3FileWriter.Encode_pcm_16_mono()
bij NAudio.Lame.LameMP3FileWriter.Encode()
bij NAudio.Lame.LameMP3FileWriter.Flush()
bij _DM.AudioRecorderSingle.StopRecording()
bij _DM.TestRecordDialog.OnRecordTimedEvent(Object source, ElapsedEventArgs e)

This is the class I use for the recorder:

namespace _DM
{
    public enum RecorderStatus { Preparing, Recording, Paused, Stopped};
    public class AudioRecorderSingle
    {
        WaveInEvent waveIn;
        LameMP3FileWriter mp3Writer;

        RecorderStatus status = RecorderStatus.Preparing;
        public RecorderStatus Status
        {
            get { return status;  }
        }

        System.Timers.Timer timer;

        public AudioRecorderSingle()
        {
            Model model = Program.mainForm.model;
            int deviceID = model.UserSettings.DeviceID;
            if (deviceID < 0) deviceID = 0;
            if (deviceID >= WaveIn.DeviceCount) deviceID = WaveIn.DeviceCount - 1;

            waveIn = new WaveInEvent();
            waveIn.WaveFormat = new WaveFormat(44100, 16, 1); //44.1Khz 16-bit, mono
            waveIn.DeviceNumber = deviceID;
            Console.WriteLine("Recording with device ID {0}", deviceID);
        }

        public bool StartRecording(string filename)
        {
            if (status != RecorderStatus.Preparing) return false;
            try
            {
                
                mp3Writer = new LameMP3FileWriter(filename, waveIn.WaveFormat, 256);
                status = RecorderStatus.Recording;
                waveIn.DataAvailable += WaveIn_DataAvailable;
                waveIn.StartRecording();
                while (waveIn.GetPosition() == 0) ;
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message, "Fout bij aanmaken geluidsbestand");
                status = RecorderStatus.Stopped;
                return false;
            }
        }

        private void WaveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            if (mp3Writer != null && status == RecorderStatus.Recording)
            {
                try
                {
                    mp3Writer.Write(e.Buffer, 0, e.BytesRecorded);
                }
                catch (Exception exception)
                {
                    MessageBox.Show(exception.Message, "Fout bij schrijven naar geluidsbestand");
                }
            }
        }


        public void PauseRecording()
        {
            Debug.Assert(status == RecorderStatus.Recording);

            if (status != RecorderStatus.Recording) return;

            if (timer != null) timer.Enabled = false;
            timer = new System.Timers.Timer(250); //pause only after .25 seconds so it has some time to save buffer
            timer.AutoReset = false;
            timer.Elapsed += (sender, args) => status = RecorderStatus.Paused;
            timer.Start();
            //waveIn.StopRecording();

        }

        public void ResumeRecording()
        {
            Debug.Assert(status == RecorderStatus.Paused);

            if (status != RecorderStatus.Paused) return;

            status = RecorderStatus.Recording;
        }

        public void StopRecording()
        {
            if (status != RecorderStatus.Recording && status != RecorderStatus.Paused) return;
            status = RecorderStatus.Stopped;
            try
            {
                waveIn?.StopRecording();
                mp3Writer?.Flush();
                waveIn?.Dispose();
                mp3Writer?.Dispose();
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
}

I really don't see what I'm doing wrong here, any clues?

Hope you solved this one - GitHub doesn't always tell me there are messages waiting.

Nothing in your code or the library seems to indicate what the problem might be. If you did solve it, can you let me know what the issue was?