如何合并输入和输出音频以发送另一个会议者

Posted

技术标签:

【中文标题】如何合并输入和输出音频以发送另一个会议者【英文标题】:How to merge input and output audio to send another conferencer 【发布时间】:2019-06-15 18:00:27 【问题描述】:

我已经更改了我的问题信息...

我有两个 Java 音频流。我想要的是将这两个音频合并到一个 OutputStream 中。

我一直在搜索,如果你有两个音频格式相同的流,并且使用 PCM,你只需要对两个字节数组进行以下操作:

mixAudio[i] = (byte) ((audio1[i] + audio2[i]) >> 1);

但是,我将其写入文件,却得到一个没有任何音频的文件。

当我将音频放在两个流(不是两个音频文件)中时,有人知道如何合并两个音频吗?

提前谢谢你。

【问题讨论】:

你开发了??在哪里? 【参考方案1】:

质量不错的音频在每个通道的每个样本中消耗两个字节的数据,以使音频曲线具有 16 位的位深度,从而在对模拟音频曲线进行数字化时为您的音频曲线提供 2^16 个不同的值......知道这一点你做不到您在数据以字节形式存在时添加...因此,要将两个通道加在一起,您首先需要将音频从其字节中取出并转换为两个字节整数...然后您需要从每个两个字节整数中提取这两个字节一个接一个地存放到你的输出数组中

在伪代码中(这会将音频数组的两个连续字节放入一个整数中,代表音频曲线中的一个样本)

将最高有效字节的 16 位整数值赋值给

将此整数左移 8 位,例如 (myint = myint

位级别将您的第二个字节添加到此整数,这是您的最低有效字节

顶部提示:在您编写代码以从两个字节填充一个整数之后,然后执行相反的操作,即将一个多字节整数转换为某个数组中的两个字节...如果您绘制这些整数,则可以加分,这样您就可以可视化您的原始数据音频曲线

要执行上述操作,您必须知道您的字节序(您是在做小字节序还是大字节序),这将决定字节的顺序......特别是因为我们现在知道每个音频样本消耗两个字节(或者更多说是 24 位音频)字节 myarray[i] 和 myarray[i + 1] 是一个音频样本,但是只有在知道您的字节顺序之后,您才会意识到在填充上述 myint 时首先使用哪个数组元素......如果这些都没有意义,请投资花费时间和精力研究 PCM 格式的原始音频的概念

我强烈建议您在代码中至少执行一次以上所有操作,以了解可能会为您执行此操作的某些音频库中发生的事情

回到你的问题而不是简单地做

mixAudio[i] = (byte) ((audio1[i] + audio2[i]) >> 1);

你应该做这样的事情(未经测试,尤其是关于字节序)

twoByteAnswer = (byte) ((audio1[i] << 8) + audio1[i + 1]) + (audio2[i] << 8 + audio2[i + 1])) >> 1);

现在你需要将你的 twoByteAnswer 展开成两个字节的数组 mixAudio ...类似这样的东西(也未经测试)

mixAudio[i] =   twoByteAnswer >> 8  // throw away its least sig byte only using its most sig byte

mixAudio[i + 1] = twoByteAnswer && 0x0000FFFF // do a bit AND operator mask

【讨论】:

以上是关于如何合并输入和输出音频以发送另一个会议者的主要内容,如果未能解决你的问题,请参考以下文章

如何在为音频会议混合音频时自动增益控制 (AGC)

如何连接多个音频输出通道以与 PyAudio 一起使用?

将音频流读取到输出设备

覆盖 iOS 音频输出

合并两个音频 blob 记录

在 UWP 应用中使用 AudioGraph 将音频输出发送到两台设备