How To Mix two bytes[] audio Chunk with NAudio to retrieve one mixed byte[]

86 Views Asked by At

I’m new with NAudio and I need to achieve following:

I have a sip Event that return to me an uint rtp buffer that I convert in byte[] Chunk with following code:

rtpChunk = new byte[buflen];
Marshal.Copy(buf, rtpChunk, 0, buflen);

I have one other bytes[] chunk of background music.

var backChunk = new byte[buflen];
Array.Copy(bot.BackgroundBuffer, bot.BackgroundBufferIndex, backChunk, 0, buflen);

I need to mix together and retrieve the mixed chunk in byte[] and send back as uint rtp packet with following code:

Marshal.Copy(mixedChunk, 0, buf, buflen);

So how can I achieve with NAudio:

byte[] mixedChunk = MixChunks(rtpChunk, backChunk);

P.S: The sample Rate, Bits, Channel are equals for bought chunks:

8000, 16, 1

Thank you for help, Piercarlo

1

There are 1 best solutions below

0
Piercarlo On BEST ANSWER

Dears, thanking for suggestions, I searched and I adapted some source code found on NAudio github repository to achieve my goal, so I post the solution that is working, may be will be usefull for some other else.

I premise that this code is handling only Raw Audio bytes, if you want to save the result on a ".wav" file you need to add the Header.

Method is the following:

public static byte[] MixBuffers(int count, params byte[][] bSources)
{
    byte[] buffer = new byte[count];
    int offset = 0;
    byte[] sourceBuffer = new byte[count];
    List<Stream> sources = new();
    foreach (var chunk in bSources)
        sources.Add(new MemoryStream(chunk));
    int outputSamples = 0;
    sourceBuffer = BufferHelpers.Ensure(sourceBuffer, count);
    lock (sources)
    {
        int index = sources.Count - 1;
        while (index >= 0)
        {
            var source = sources[index];
            int samplesRead = source.Read(sourceBuffer, 0, count);
            int outIndex = offset;
            for (int n = 0; n < samplesRead; n++)
                if (n >= outputSamples)
                    buffer[outIndex++] = sourceBuffer[n];
                else
                    buffer[outIndex++] += sourceBuffer[n];
            outputSamples = Math.Max(samplesRead, outputSamples);
            index--;
        }
    }
    foreach (var source in sources)
        source.Dispose();
    return buffer;
}