如何在Qt中混合音频输入设备

How to mix audio input devices in Qt

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

据我所知,我必须首先为所有需要的设备获得特定的 QAudioDeviceInfo - 以及相应的 QAudioFormat 对象 - 并将其与 QAudioInput 一起使用。然后我简单地为每个创建的 QAudioInput 对象调用 start() 并用 readLine().

读出待处理的字节

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

我不确定是否有任何特定于 Qt 的方法/class 可以执行此操作。不过自己动手也很简单。

最基本的方法(假设你使用的是 PCM),你可以简单地将两个 streams/buffers 逐字相加(如果我记得它们是 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% 的动态范围(称之为全音量,超过这个音量就会失真),然后当你将它们加在一起时你会得到数字 over运行(即 16 位最大为 65535所以 50000 + 50000 将超过 运行).

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

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

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

编辑

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