我正在使用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;
}
}
}
答案 0 :(得分:2)
您似乎没有正确处理签名的音频样本。水平线应为音频信号的零电压。
如果您查看正电压音频样本,它们会正确地遵守您的等式(除了中心的峰值值)。负值被压缩,这让我觉得它们被视为小正电压而不是负电压。
换句话说,也许这些无符号整数应该是有符号整数,因此最高位表示电压极性,你可以在+127到-128范围内设置音频样本。
中心的那些峰值看起来像是以模数255包围,这将是音频的无符号字节表示的峰值。我不确定这会发生什么,但似乎与无符号vs签名信号有关。
也许您应该尝试Viktor在其文档中提供的其他公式:
Z = 2(A + B) - (AB / 128) - 256