加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 混合MP3文件中的两个音频样本

发布时间:2020-12-15 07:53:45 所属栏目:百科 来源:网络整理
导读:我有问题通过简单地添加两个音频样本的字节将两个不同的音频样本混合成一个. 在下面的过程中,当我尝试在媒体播放器中打开mixed.mp3文件时,它说: Windows Media Player encountered a problem while playing the file. 这是我用来混合音频文件的代码: byte[
我有问题通过简单地添加两个音频样本的字节将两个不同的音频样本混合成一个.

在下面的过程中,当我尝试在媒体播放器中打开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);

注意:我试图混合两个相同的文件,它工作,也就是说,媒体播放器没有抛出任何错误并正确播放.

解决方法

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

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

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

否则你的计算会溢出(另外,我通常建议在操作它们之前将音频标准化为浮点数).还应该注意的是,你正在混合MP3文件中的所有字节,即你正在弄乱标题(因此WMP拒绝播放你的“混合”文件).您应该只混合文件的实际音频数据(样本),而不是整个文件.

我已经使用NAudio库提供了一个(注释)工作示例1(它将混合音频导出到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,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,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输入文件必须具有相同的采样率,位深度和通道数,才能使其正常工作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读