gpt4 book ai didi

c# - 混合来自 MP3 文件的两个音频样本

转载 作者:太空狗 更新时间:2023-10-29 20:09:43 39 4
gpt4 key购买 nike

我在通过简单地添加两个音频样本的字节将两个不同的音频样本混合成一个时遇到问题。

在以下过程之后,当我尝试在媒体播放器中打开 mixed.mp3 文件时,它说:

Windows Media Player encountered a problem while playing the file.

这是我用来混合音频文件的代码:

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

注意:我尝试混合两个相同的文件并且成功了,也就是说,媒体播放器没有抛出任何错误并正确播放。

最佳答案

这很可能是因为您不是 decoding MP3 文件你混合它们之前。 并且您只是将样本“相加”在一起,这将导致 clipping ;你应该首先使用 library将 MP3 文件解码为 PCM,然后您可以将它们混合。

要正确混合 sample ,您应该这样做:

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

否则您的计算将会溢出(此外,我通常建议在处理音频之前将您的音频规范化为float)。还应该注意的是,您正在混合 MP3 文件中的所有字节,即,您弄乱了 header (因此 WMP 拒绝播放您的“混合”文件)。您应该只混合文件的实际音频数据(样本),而不是整个文件。

我提供了一个(注释的)工作示例1 使用 NAudio 库(它将混合音频导出到 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);
}
}

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

关于c# - 混合来自 MP3 文件的两个音频样本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32937664/

39 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com