Mixing two audio from MP3 files

I'm having a problem mixing two different audio recordings into one, just adding bytes of both audio samples.

After that, when I try to open the mixed.mp3 file in the media player, it says:

Windows Media Player encountered a problem while playing a file.

Here is the code I use to mix audio files:

byte[] bytes1,bytes2,final; int length1,length2,max; // Getting byte[] of audio file using ( BinaryReader b = new BinaryReader(File.Open("background.mp3" , FileMode.Open)) ) { length1 = (int)b.BaseStream.Length; bytes1 = b.ReadBytes(length1); } using ( BinaryReader b = new BinaryReader(File.Open("voice.mp3" , FileMode.Open)) ) { length2 = (int)b.BaseStream.Length; bytes2 = b.ReadBytes(length2); } // Getting max length if(length1 > length2){ max = length1; }else{ max = length2; } // Initializing output byte[] of max length final = new byte[max]; // Adding byte1 and byte2 and copying into final for (int i=0;i<max;i++) { byte b1 , b2; if(i < length1){ b1 = bytes1[i]; }else{ b1 = 0; } if ( i < length2 ){ b2 = bytes2[i]; } else{ b2 = 0; } final[i] = (byte)(b1 + b2); } // Writing final[] as an mp3 file File.WriteAllBytes("mixed.mp3" , final); 

Note. I tried to mix two identical files, and it worked, that is, the media player did not produce errors and did not play them correctly.

+7
c # audio
source share
1 answer

This is most likely due to the fact that you are not decoding MP3 files before mixing them. And you just add samples together, which will result in clipping ; you must first use the library to decode MP3 files in PCM, which allows you to mix them.

To mix the samples that you have to make correctly:

 final[i] = (byte)(b1 / 2 + b2 / 2); 

Otherwise, your calculations will be overwhelmed (I would also recommend normalizing your sound to float before manipulating them). It should also be noted that you mix all the bytes in the MP3 files, i.e. You mess with the headers (therefore, WMP refuses to play your β€œmixed” file). You should only mix the actual audio data (samples) of the files, not the entire file.

I provided (comment) a working example 1 using the NAudio library (it exports mixed sound to a wav file to avoid further complications):

 // You can get the library via NuGet if preferred. using NAudio.Wave; ... var fileA = new AudioFileReader("Input path 1"); // Calculate our buffer size, since we're normalizing our samples to floats // we'll need to account for that by dividing the file audio byte count // by its bit depth / 8. var bufferA = new float[fileA.Length / (fileA.WaveFormat.BitsPerSample / 8)]; // Now let populate our buffer with samples. fileA.Read(bufferA, 0, bufferA.Length); // Do it all over again for the other file. var fileB = new AudioFileReader("Input path 2"); var bufferB = new float[fileB.Length / (fileB.WaveFormat.BitsPerSample / 8)]; fileB.Read(bufferB, 0, bufferB.Length); // Calculate the largest file (simpler than using an 'if'). var maxLen = (long)Math.Max(bufferA.Length, bufferB.Length); var final = new byte[maxLen]; // For now, we'll just save our mixed data to a wav file. // (Things can get a little complicated when encoding to MP3.) using (var writer = new WaveFileWriter("Output path", fileA.WaveFormat)) { for (var i = 0; i < maxLen; i++) { float a, b; if (i < bufferA.Length) { // Reduce the amplitude of the sample by 2 // to avoid clipping. a = bufferA[i] / 2; } else { a = 0; } if (i < bufferB.Length) { b = bufferB[i] / 2; } else { b = 0; } writer.WriteSample(a + b); } } 

1 Input files must have the same sampling rate, bit depth and number of channels for it to work correctly.

+8
source share

All Articles