Noise reduction and compression in streaming audio

hope you can help. I record sound from a microphone and broadcast it over the network. The quality of the samples is 11025 Hz, 8 bits, mono. Although there is a slight delay (1 second), it works great. I need help trying to implement noise reduction and compression to make the sound quieter and use less bandwidth. Audio samples are stored in a C # array with bytes [], which I send / receive using Socket.

Can anyone suggest how to implement compression and noise reduction in C #? I do not mind using a third-party library if it is free (LGPL license, etc.), and can be used with C #. However, I would prefer actual source code examples. Thank you in advance for any suggestion you have.

UPDATE:

I changed the bit size from 8-bit sound to 16-bit sound, and the interference problem was fixed. Apparently, the 8-bit microphone sound had a too low signal to noise ratio. The voice sounds great at 11 kHz, 16 bit mono.

The requirements of this project have changed since I posted this. We are also trying to add a video. I have a callback function that receives live images every 100 ms from a webcam. I need to encode audio and video, multiplex them, transfer them to my socket on the server, the server retransmits the stream to another client, which receives the stream, demultiplexes the stream and decodes the audio and video, displays the video in the image window and outputs the sound to the speaker.

I look at ffmpeg to help with (de | en) coding / [de] muxing, and I also see SharpFFmpeg as a C # library of interaction with ffmpeg.

I can not find good examples of this. I scoured the Internet all week without knowing any luck. Any help you can provide is greatly appreciated!

Here's some code, including my mic callback function:

  private const int AUDIO_FREQ = 11025;
         private const int CHANNELS = 1;
         private const int BITS = 16;
         private const int BYTES_PER_SEC = AUDIO_FREQ * CHANNELS * (BITS / 8);
         private const int BLOCKS_PER_SEC = 40;
         private const int BUFFER_SECS = 1;
         private const int BUF_SIZE = ((int) (BYTES_PER_SEC / BLOCKS_PER_SEC * BUFFER_SECS / 2)) * 2;  // rounded to nearest EVEN number

         private WaveLib.WaveOutPlayer m_Player;
         private WaveLib.WaveInRecorder m_Recorder;
         private WaveLib.FifoStream m_Fifo;

         WebCam MyWebCam;

         public void OnPickupHeadset ()
         {
             stopRingTone ();
             m_Fifo = new WaveLib.FifoStream ();

             WaveLib.WaveFormat fmt = new WaveLib.WaveFormat (AUDIO_FREQ, BITS, CHANNELS);
             m_Player = new WaveLib.WaveOutPlayer (-1, fmt, BUF_SIZE, BLOCKS_PER_SEC,
                             new WaveLib.BufferFillEventHandler (PlayerCB));
             m_Recorder = new WaveLib.WaveInRecorder (-1, fmt, BUF_SIZE, BLOCKS_PER_SEC,
                             new WaveLib.BufferDoneEventHandler (RecorderCB));

             MyWebCam = null;
             try
             {
                 MyWebCam = new WebCam ();                
                 MyWebCam.InitializeWebCam (ref pbMyPhoto, pbPhoto.Width, pbPhoto.Height);
                 MyWebCam.Start ();
             }
             catch {}

         }

         private byte [] m_PlayBuffer;
         private void PlayerCB (IntPtr data, int size)
         {
             try
             {
                 if (m_PlayBuffer == null || m_PlayBuffer.Length! = size)
                     m_PlayBuffer = new byte [size];

                 if (m_Fifo.Length> = size)
                 {
                     m_Fifo.Read (m_PlayBuffer, 0, size);
                 }
                 else
                 {
                     // Read what we can 
                     int fifoLength = (int) m_Fifo.Length;
                     m_Fifo.Read (m_PlayBuffer, 0, fifoLength);

                     // Zero out rest of buffer
                     for (int i = fifoLength; i <m_PlayBuffer.Length; i ++)
                         m_PlayBuffer [i] = 0;                        
                 }

                 // Return the play buffer
                 Marshal.Copy (m_PlayBuffer, 0, data, size);
             }
             catch {}
         }


         private byte [] m_RecBuffer;
         private void RecorderCB (IntPtr data, int size)
         {
             try
             {
                 if (m_RecBuffer == null || m_RecBuffer.Length! = size)
                     m_RecBuffer = new byte [size];
                 Marshal.Copy (data, m_RecBuffer, 0, size);

                 // HERE WHERE I WOULD ENCODE THE AUDIO IF I KNEW HOW

                 // Send data to server
                 if (theForm.CallClient! = null)
                 {
                     SocketAsyncEventArgs args = new SocketAsyncEventArgs ();
                     args.SetBuffer (m_RecBuffer, 0, m_RecBuffer.Length);
                     theForm.CallClient.SendAsync (args);
                 }
             }
             catch {}
         }

         // Called from network stack when data received from server (other client)
         public void PlayBuffer (byte [] buffer, int length)
         {
             try
             {
                 // HERE WHERE I WOULD DECODE THE AUDIO IF I KNEW HOW

                 m_Fifo.Write (buffer, 0, length); 
             }
             catch {}
         }

So where do I go?

+4
source share
2 answers

Your goals here are mutually exclusive. The reason your 11025Hz / 8bit / Mono WAV files sound noisy (with a huge amount of β€œhiss”) is due to their low sampling rate and resolution (44100 Hz / 16 bit / stereo is the standard for audio CD quality).

If you continue to record and stream at that speed, you will have a noisy sound period. The only way to eliminate (or simply mitigate) this noise will be to increase the audio sample to 44100 Hz / 16 bits, and then execute the noise reduction algorithm on it. This upsampling should be performed by the client application, since doing this on the server before streaming means that you will stream the audio 8 times more than your original (doing this on the server would also be completely pointless, since you would be better just record in a denser format first of all).

What you want to do is record the original sound in CD-quality format, and then compress it into a standard format, such as MP3 or Ogg Vorbis. See previous question:

What is the best audio compression library for .NET?

Update: I have not used this, but:

http://www.ohloh.net/p/OggVorbisDecoder

I think you need an encoder, but I could not find it for Ogg Vorbis. I think you can try WMV encoding:

http://www.discussweb.com/c-programming/1728-encoding-wmv-file-c-net.html

Update 2: Sorry, my level of knowledge of streaming is pretty low. If I did something like what you are doing, I would first create an (uncompressed) AVI file from audio and still images (using the avifil32.dll methods via PInvoke), and then compress it to MPEG (or any standard format - YouTube has a page where they talk about their preferred formats, and it's probably good to use one of them).

I'm not sure if this will do what you need, but this link:

http://csharpmagics.blogspot.com/

using this free player:

http://www.videolan.org/

can work.

+1
source

If you only want to compress the data to limit bandwidth usage, you can try using GZipStream.

0
source

Source: https://habr.com/ru/post/1312255/


All Articles