【问题标题】:Mixing audio channels混合音频通道
【发布时间】:2018-07-10 16:25:09
【问题描述】:

我正在实现一个音频通道混合器并使用Viktor T. Toth's algorithm。试图混合两个音频通道流。

在代码中,quantization_ 是通道位深度的字节表示。我的mix 函数采用指向目标和源 uint8_t 缓冲区的指针,混合两个通道并写入目标缓冲区。因为我在 uint8_t 缓冲区中获取数据,执行加法、除法和乘法运算以获取实际的 8、16 或 24 位样本并将它们再次转换为 8 位。

通常,它会给出预期的输出样本值。但是,有些样本的值接近 0,因为当我在 Audacity 中查看输出时它们不应该是这样。在屏幕截图中,底部 2 个信号是两个单声道,顶部是混合通道。可以看出有一些非常低的值,尤其是中间。

下面是我的mix函数;

void audio_mixer::mix(uint8_t* dest, const uint8_t* source)
{
    uint64_t mixed_sample = 0;
    uint64_t dest_sample = 0;
    uint64_t source_sample = 0;
    uint64_t factor = 0;

    for (int i = 0; i < channel_size_; ++i)
    {
        dest_sample = 0;
        source_sample = 0;
        factor = 1;

        for (int j = 0; j < quantization_; ++j)
        {
            dest_sample += factor * static_cast<uint64_t>(*dest++);
            source_sample += factor * static_cast<uint64_t>(*source++);
            factor = factor * 256;
        }

        mixed_sample = (dest_sample + source_sample) - (dest_sample * source_sample / factor);

        dest -= quantization_;

        for (int k = 0; k < quantization_; ++k)
        {
            *dest++ = static_cast<uint8_t>(mixed_sample % 256);
            mixed_sample = mixed_sample / 256;
        }
    }
}

【问题讨论】:

    标签: c++ algorithm audio


    【解决方案1】:

    您似乎没有正确处理签名的音频样本。水平线应该是音频信号的零电压。

    如果您查看正电压音频样本,它们会正确地遵循您的方程式(中心的峰值除外)。负值被压缩,这让我觉得它们被视为小的正电压而不是负电压。

    换句话说,也许那些无符号整数应该是有符号整数,因此最高位指示电压极性,并且您可以在 +127 到 -128 范围内获得音频样本。

    中心的那些峰值似乎围绕模 255 进行环绕,这将是音频无符号字节表示的峰值。我不确定这会如何发生,但它似乎与无符号与有符号信号有关。

    也许你应该试试 Viktor 在他的文档中提供的另一个公式:

    Z = 2(A+B) - (AB/128) - 256

    【讨论】:

    • 谢谢大家的帮助,好像没看懂有符号数据和无符号数据的区别。如果我将数据视为已签名,我相信我会得到正确的输出。当我完全理解并纠正我的错误时,我会回来。
    • 是的,成功了!现在,我可以混合 8、16、24 位深度的频道了。
    • 问题与有符号-无符号混淆有关。
    猜你喜欢
    • 2011-06-01
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    • 2014-05-27
    • 2012-02-06
    • 1970-01-01
    • 2011-03-28
    • 1970-01-01
    相关资源
    最近更新 更多