Search code examples
c#.netaudionaudiosample

NAudio converting samples buffer to wave buffer


My goal - to make processing and playback of audio data in real-time by NAudio. The application uses different formats: 8bit pcm, 16bit pcm, 24bit pcm. For playback, I use WaveOut and BufferedWaveProvider. The difficulty arises with the processing of individual samples in real time. To convert raw data into samples, I use the following code:

var vaweProviderIn = new BufferedWaveProvider(format);
vaweProviderIn.AddSamples(waveBuffer, 0, waveBuffer.Length);
var sampleProvider = vaweProviderIn.ToSampleProvider();
sampleProvider.Read(sampleBuffer, 0, sampleBufferSize);
//samples processing

The question is how to convert the samples buffer back to the wave buffer, to play it?


Solution

  • I wrote my own code to solve this problem.

        private enum BPS {PCM_16Bit = 16, PCM_24Bit = 24};
    
        /// <summary>
        /// Converting the Sample Buffer to the Byte Buffer
        /// </summary>
        /// <param name="samples"></param>
        /// <param name="format"></param>
        /// <returns></returns>
        private byte[] samplesToVawe(float[] samples, WaveFormat format)
        {
            Int32 intSample;
            UInt32 sample4Byte;
            byte[] byteBuffer = new byte[samples.Length * (format.BitsPerSample / 8)];
            uint byteBufIndex = 0;
    
            for (uint i = 0; i < samples.Length; i++)
            {
                //convert 1 sample into 4 byte integer
                intSample = (Int32)(samples[i] * Int32.MaxValue);
                sample4Byte = (UInt32)intSample;
    
                switch((BPS)format.BitsPerSample)
                {
                    case BPS.PCM_24Bit:
                        byteBuffer[byteBufIndex++] = (byte)(sample4Byte >> 8);
                        byteBuffer[byteBufIndex++] = (byte)(sample4Byte >> 16);
                        byteBuffer[byteBufIndex++] = (byte)(sample4Byte >> 24);
                        break;
    
                    case BPS.PCM_16Bit:
                        byteBuffer[byteBufIndex++] = (byte)(sample4Byte >> 16);
                        byteBuffer[byteBufIndex++] = (byte)(sample4Byte >> 24);
                        break;
                }                
            }
    
            return byteBuffer;
        }