2015-10-04 54 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); 
    } 
} 

输入文件必须具有相同的采样率,位深度和通道数才能正常工作。