我是 Qt 多媒体库的新手,在我的应用程序中,我想混合来自多个输入设备(例如麦克风)的音频,以便通过 TCP 流式传输它。
据我所知,我必须首先获取QAudioDeviceInfo
所有需要设备的特定信息 - 连同相应的QAudioFormat
对象 - 并将其与QAudioInput
. 然后我只需调用start()
每个创建的QAudioInput
对象并用readLine()
.
但是如何将多个设备的音频数据混合到一个缓冲区?
我是 Qt 多媒体库的新手,在我的应用程序中,我想混合来自多个输入设备(例如麦克风)的音频,以便通过 TCP 流式传输它。
据我所知,我必须首先获取QAudioDeviceInfo
所有需要设备的特定信息 - 连同相应的QAudioFormat
对象 - 并将其与QAudioInput
. 然后我只需调用start()
每个创建的QAudioInput
对象并用readLine()
.
但是如何将多个设备的音频数据混合到一个缓冲区?
我不确定是否有任何 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 中工作。