1

我是 Qt 多媒体库的新手,在我的应用程序中,我想混合来自多个输入设备(例如麦克风)的音频,以便通过 TCP 流式传输它。

据我所知,我必须首先获取QAudioDeviceInfo所有需要设备的特定信息 - 连同相应的QAudioFormat对象 - 并将其与QAudioInput. 然后我只需调用start()每个创建的QAudioInput对象并用readLine().

但是如何将多个设备的音频数据混合到一个缓冲区?

4

1 回答 1

3

我不确定是否有任何 Qt 特定的方法/类来执行此操作。然而,自己做这件事很简单。

最基本的方法(假设您使用的是 PCM),您可以简单地将两个流/缓冲区逐字添加(如果我记得它们是 16 位 PCM 字)。

因此,如果您有两个输入缓冲区:

int16 buff1[10];
int16 buff2[10];
int16 mixBuff[10];

// Fill them...
//... code goes here to read from the buffers ....

// Add them (effectively mix them)

for (int i = 0; i < 10; i++)
{
   mixBuff[i] = buff1[i] + buff2[i];
}

现在,这是非常粗略的,没有考虑任何缩放。所以想象一下 buff1 和 buff2 都使用了 80% 的动态范围(称之为全音量,超过它会出现失真),然后当你将它们加在一起时,你会得到数字溢出(即 16 位最大值为 65535,因此 50000 + 50000 将被超越)。

每次混合时,您实际上需要两个输入的一半(因此 65535 / 2 + 65535 / 2 = 65535 ... 即当您将它们相加时,您不能超出)。所以你的混合代码是这样的:

for (int i = 0; i < 10; i++)
{
   mixBuff[i] = (buff1[i] >> 1) + (buff2[i] >> 1);
}

你可以做更多的事情(去除噪音等......),但随后数学开始变得有点毛茸茸。这很简单。如果需要,您可以在之后使用移位来增加/减少音量作为简单的音量控制。

编辑

需要注意的一件事......您正在使用 readline() (文档说它将数据作为 ASCII 读取)。我总是使用 read() 它没有说明它读出的“格式”,但我假设是二进制的。因此,如果您使用 readline(),此代码可能无法正常工作,但我从未尝试过。它适用于 read(),如果你想操作数据,你真的不想在 ASCII 中工作。

于 2016-01-06T12:05:15.343 回答