Streaming audio from computer mic generates continuous noise. Please help to make it correct

Oct 17, 2010 at 11:27 PM

Hello, 

I have the following code to get audio from mic and it sends byte array to network. On the other side when I capture it and play it, there is only continuous noice.

The following code sends byte[800] arrays to network (Please refer while loop). I capture these chunk of bytes and send it to overridden Read method of WaveStream. This first time I'm dealing with media devices. I know there must some serious issues with the following code. Please give me your feedback.

My Server code which generates data from computer mic (audio input device)

 

namespace MicroPhoneServer
{
    public class AudioService
    {
        #region Properties
            public string IpAddress { get; set; }
            public int Port { get; set; }
            public int DeviceNumber;
            public int BytesRecorded=0;
        #endregion

        NetworkStream netStr;
        TcpClient tcpClient;
        TcpListener tcpListener;
        bool tcpConnected = false;
        WaveIn waveIn = new WaveIn();
                
       
        MMDeviceCollection audioDeviceColl;
            

        public AudioService()
        { }

        public void Start() 
        {
            getVoice();

        }

        private void getVoice() 
        {
            openNetworkChannel();
            if (tcpConnected) 
            {
                setAudioInputDevice();
                waveIn.StartRecording();
            }
            
        }

        public void Stop() 
        {
            waveIn.StopRecording();
            waveIn.Dispose();
            tcpListener.Stop();
            tcpClient.Close();            
        }

        private void setAudioInputDevice() 
        {
            waveIn.DataAvailable += new EventHandler<WaveInEventArgs>(waveIn_DataAvailable);
            waveIn.RecordingStopped += new EventHandler(waveIn_RecordingStopped);
            MMDevice d = audioDeviceColl.ElementAt(DeviceNumber);
            //waveIn.DeviceNumber = 1;
            waveIn.WaveFormat = new WaveFormat(8000, 1);
        }

        void waveIn_RecordingStopped(object sender, EventArgs e)
        {
            waveIn.Dispose();
            waveIn = null;
            tcpClient.Close();
            tcpClient = null;
            netStr.Close();
            netStr = null;

        }

        void waveIn_DataAvailable(object sender, WaveInEventArgs e)
        {
            if (tcpConnected) 
            {
                netStr.Write(e.Buffer, 0,e.BytesRecorded);                               
            }
                        
        }
            
        public List<string> AudioInputDevices()
        {
            List<string> audioInputDevices = new List<string>();
            MMDeviceEnumerator audioDeviceEnum = new MMDeviceEnumerator();
            audioDeviceColl = audioDeviceEnum.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active);

            foreach (MMDevice d in audioDeviceColl) 
            {
                audioInputDevices.Add(d.FriendlyName);
            }

            return audioInputDevices;
        }

        private void openNetworkChannel() 
        {
            if (tcpListener == null) 
            {
                tcpListener = new TcpListener(System.Net.IPAddress.Parse(IpAddress), Port);
                tcpListener.Start();
            }
           
            if (tcpListener.Pending()) 
            {
                tcpConnected = true;
                tcpClient = tcpListener.AcceptTcpClient();
                netStr = tcpClient.GetStream();
            }
                        
        }
   
     }
}

 

My client code which subscribes byte[800] from network and plays it.

namespace MicroPhoneClient
{
    public class Subscriber
    {
        TcpClient client = null;
        NetworkStream netStr = null;
        Byte[] buffer;
        AudioSampleStream audioStrm = null;
        DirectSoundOut device;
        bool isPlaying = false;
        Queue<byte[]> bufferQueue = new Queue<byte[]>();

        public Subscriber() 
        {
            audioStrm = new AudioSampleStream(8000, 1);
            device = new DirectSoundOut();
            device.Init(audioStrm);
               
        }

        public void GetTCPClient() 
        {
            client = new TcpClient("192.168.1.3", 3345);
            netStr = client.GetStream();   
            
        }

        public void Seek() 
        {

            while (true) 
            {
                try 
                {
                    buffer = new byte[800];
                    netStr.Read(buffer, 0, 800);
                    if (buffer != null)
                    {
                        bufferQueue.Enqueue(buffer);
                    }
                    
                }
                
                catch{}

            }
            
        }

        public void Stop() 
        {
            device.Stop();
            audioStrm.Flush();
            audioStrm.Dispose();
            netStr.Dispose();
            
        }

        public void CloseTCPClient() 
        {
            client.Close();
            client = null;
        }

        public void Play() 
        {
            while (true) 
            {
                if (bufferQueue.Count != 0)
                {
                    audioStrm.AddAudioSamples(bufferQueue.Dequeue(), 0, 800);
                    if (!isPlaying)
                    {
                        device.Play();
                        isPlaying = true;
                    }   
                }

            }
                       
        }
    }

    class AudioSample
    {
        private byte[] audioBuffer;
        private int position;

        public AudioSample(byte[] buffer) 
        {
            audioBuffer = buffer;
            position = 0;
        }

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

        public byte[] AudioBuffer 
        {
            get 
            {
                return audioBuffer;
            }
        }
    }

    public class AudioSampleStream : WaveStream 
    {
        private WaveFormat waveFormat;
        private long position;
        private Queue<AudioSample> audioSampleQueue;

        public AudioSampleStream(int rate, int channels) 
        {
            waveFormat = new WaveFormat(rate, 1);
            position = 0;
            audioSampleQueue = new Queue<AudioSample>();
        }

        public void AddAudioSamples(byte[] buffer, int offset, int count) 
        {
            byte[] tempBuffer = new byte[count];
            Buffer.BlockCopy(buffer, offset, tempBuffer,0,count);

            lock (audioSampleQueue) 
            {
                audioSampleQueue.Enqueue(new AudioSample(tempBuffer));
            }

        }

        public override long Position
        {
            get
            {
                return position;
            }
            set
            {
                position = value;
            }
        }

        public override long Length
        {
            get { return 3500; }
        }

        public override WaveFormat WaveFormat
        {
            get { return waveFormat; }
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            int bytesToRead = 0;
            int required;
            while (bytesToRead < count)
            {
                required = count - bytesToRead;

                if (audioSampleQueue.Count == 0)
                {
                    //return emtpy sound
                    for (int i = 0; i < required; i++)
                    {
                        buffer[offset + i] = 0;
                    }

                    bytesToRead += required;

                }

                else 
                {
                    //read entire AudioSample
                    AudioSample sample = audioSampleQueue.Peek();
                    int bytesToReadInSample = sample.AudioBuffer.Length - sample.Position;

                    Buffer.BlockCopy(sample.AudioBuffer, sample.Position, buffer, offset + bytesToRead, bytesToReadInSample);
                    
                    audioSampleQueue.Dequeue();

                    bytesToRead = bytesToReadInSample ;

                 }

              }

            return bytesToRead;
            
        }

    }
    
}

Coordinator
Nov 8, 2010 at 8:46 AM

before adding a network into the equation, I would recommend recording and playing back on the same pc. You need to ensure the WaveFormat is the same for both record and playback as well.

Sep 14, 2011 at 9:19 AM

 

did you find a solution to filter noise ? 

Sep 15, 2011 at 6:47 PM

Hi skcr,

My updated code which works is on my local computer at home. I will send you that tomorrow.

Thanks.

Oct 7, 2011 at 6:29 AM
mbharodia wrote:

Hi skcr,

My updated code which works is on my local computer at home. I will send you that tomorrow.

Thanks.

 

Hi mbharodia

you forgot to send me your updated code ?

can you please send it

Thanks