我是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。

关于c++ - 如何在Qt中混合音频输入设备,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34618069/

10-14 15:57