This project has moved. For the latest updates, please go here.

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

Oct 18, 2010 at 12:27 AM

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 9: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 10:19 AM

 

did you find a solution to filter noise ? 

Sep 15, 2011 at 7: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 7: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