2015-10-04 52 views
7

我有兩個不同的音頻樣本混合在一起的問題,只需添加兩個音頻樣本的字節。從MP3文件混合兩個音頻樣本

以下過程後,當我嘗試打開媒體播放器mixed.mp3文件,它說:

Windows Media Player中遇到的問題,同時播放該文件。

這裏是我使用的混合音頻文件的代碼:

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); 

注:我試圖將兩種相同的文件和它的工作,那就是,媒體播放器沒有扔任何錯誤並正確播放。

+0

你的底部註釋是什麼意思?你的意思是現在的代碼有效? –

+5

這是不可能的。 Mp3不是行波數據。像這樣添加字節將100%損壞的數據。不知道它是如何工作的 –

+6

解碼它,做你的計算,記住作物(0..255),再次編碼。你現在所做的工作不能工作,因爲:mp3是壓縮的(除非它只包含幅度數據......我不是那裏的專家),你也必須考慮包含在文件級別工作時不應該改變的所有元數據的頭文件。 –

回答

8

這很可能是由於你不是decoding的MP3文件之前你混合它們。 你只是「將樣品加在一起,這將導致clipping;您應該首先使用library將MP3文件解碼爲PCM,然後再將它們混合使用。

要正確地搭配你應該做的樣品:

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

否則你的計算會溢出(也,我通常建議操作之前你的音頻正火float S)。還應該注意的是,你正在混合全部 MP3文件中的字節,即,你搞亂了標題(因此WMP拒絕播放你的「混合」文件)。您應該只混合文件的實際音頻數據(樣本),而不是整個文件。

我提供使用n音訊庫(其出口的混合音頻爲WAV文件,以避免進一步的併發症)一(註釋)工作示例:

// 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's audio byte count 
// by its bit depth/8. 
var bufferA = new float[fileA.Length/(fileA.WaveFormat.BitsPerSample/8)]; 

// Now let's 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); 
    } 
} 

輸入文件必須具有相同的採樣率,位深度和通道數才能正常工作。