Reason For MemoryAllocationError Exception

Nov 9, 2010 at 10:04 AM

Hi,
  while playing audio using NAudio library from a network stream, After playing the audio for about 1 minute i got the exception's in the line
waveOut.Init(new WaveOutStream(AudioRxvdStream));
The exceptions are either

1.NAudio.MmException: MemoryAllocationError calling waveOutOpen
   at NAudio.MmException.Try(MmResult result, String function)
   at NAudio.Wave.WaveOut.Init(IWaveProvider waveProvider)

or

2.NAudio.MmException: AlreadyAllocated calling waveOutOpen
   at NAudio.Wave.WaveOut.Init(IWaveProvider waveProvider)
                           
My code is

//For initialize thread

socket_Audio = new Socket(AddressFamily.InterNetworkV6, SocketType.Dgram, ProtocolType.Udp);

myAudioThread = new Thread(new ThreadStart(AudioListener));

myAudioThread.Start();

//******
private void AudioListener() { MemoryStream AudioRxvdStream; #region Its rxving audio From Network Continously socket_Audio.Bind(new IPEndPoint(IPAddress.IPv6Any, SoundPort)); byte[] byteData; while (true) { AudioRxvdStream = null; AudioRxvdStream = new MemoryStream(); byteData = new byte[1600]; if (socket_Audio != null) socket_Audio.Receive(byteData, SocketFlags.None); AudioRxvdStream.Write(byteData , 0, byteData .Length); if (AudioRxvdStream != null) { waveOut = null; waveOut = new WaveOut(); try { waveOut.Init(new WaveOutStream(AudioRxvdStream)); waveOut.Play(); } catch (Exception te) { ObjLog.Write("Exception-iNIT waveout" + te.ToString()); } } } #endregion }

The 2 derived classes used are ( code is from other discussions results )

public  class BufferedAudioStream
    {

        private byte[] _buffer;
        private int _position;

        public BufferedAudioStream(byte[] buffer)
        {
            _position = 0;
            _buffer = buffer;
        }

        public byte[] Buffer
        {
            get
            {
                return _buffer;
            }
        }

        public int Position
        {
            get
            {
                return _position;
            }
            set
            {
                _position = value;
            }
        }
    }

  public class WaveOutStream : WaveStream
    {
        private Queue<BufferedAudioStream> _sampQueue;
        private long _position;
      
        public override long Position
        {
            get
            {
                return _position;
            }
            set
            {
                _position = value;
            }
        }


        MemoryStream AudioRxvdStream;
        private bool Streaming=true;
        clsLog ObjLog = new clsLog();

        public WaveOutStream(MemoryStream _AudioRxvdStream)
        {
            try
            {
                AudioRxvdStream = _AudioRxvdStream;
                try
                {
                    _sampQueue.Clear();
                }
                catch
                {

                }

                _position = 0;
                _sampQueue = new Queue<BufferedAudioStream>();

                byte[] nbuffer = AudioRxvdStream.ToArray();
                lock (_sampQueue)
                {
                    _sampQueue.Enqueue(new BufferedAudioStream(nbuffer));
                }
            }             
            catch (Exception ex)
            {
                ObjLog.Write("-Exception at WaveOutStream()"+ex.Message);
            }
        }

   /// <summary>
   /// Reads sample data from queued samples, if queue is empty generates silence
   /// </summary>
   
        public override int Read(byte[] buffer, int offset, int count)
        {
            int read = 0;
            try
            {
                while (read < count)
                {
                    int required = count - read;
                    if (_sampQueue.Count == 0)
                    {
                        // Return a zero filled buffer
                        for (int n = 0; n < required; n++)
                            buffer[offset + n] = 0;

                        read += required;
                    }
                    else
                    {
                        BufferedAudioStream sblock = (BufferedAudioStream)_sampQueue.Peek();

                        int nread = sblock.Buffer.Length - sblock.Position;

                        // If this buffer must be read in it's entirety
                        if (nread <= required)
                        {
                            // Read entire buffer
                            Buffer.BlockCopy(sblock.Buffer, sblock.Position, buffer, offset + read, nread);
                            read += nread;

                            _sampQueue.Dequeue();

                        }
                        else // the number of bytes that can be read is greater than that required
                        {
                            Buffer.BlockCopy(sblock.Buffer, sblock.Position, buffer, offset + read, required);
                            sblock.Position += required;
                            read += required;
                        }
                    }
                }
                _position += read;
            }
            catch (Exception ex)
            {
                ObjLog.Write("-Exception at Read()" + ex.Message);

            }
            return read;
        }
          

        public override WaveFormat WaveFormat
        {
            get { return new WaveFormat(8000, 16, 2); }
        }

        public override long Length
        {
            get { return AudioRxvdStream.Length; }
        }

       
    }

Thanks,

JIbin

Coordinator
Nov 9, 2010 at 10:16 AM

there should only be one call to waveout.init and you need one master wave stream that returns received data from the network from its Read method. Have a look at BufferedWaveProvider in the latest NAudio source code (see the source code tab)

Mark

Nov 10, 2010 at 4:48 AM

Hi Mark,

*****  THANK YOU SO MUCH ***

The problem is solved now and i am able to do voice chat between 2 systems over internet  using NAudio Library without any errors..

Thanks

jibin

jibin.mn@hotmail.com