如何在 C++ 中只用一个扬声器播放声音?

Posted

技术标签:

【中文标题】如何在 C++ 中只用一个扬声器播放声音?【英文标题】:How can I play sound out of just one speaker in C++? 【发布时间】:2011-01-02 04:01:20 【问题描述】:

我有一张支持多个扬声器的声卡 (Creative SB X-Fi)。我想做的是用 C++(Windows 7 环境,Visual Studio IDE)编写一个程序,它将向我连接的 4 个扬声器之一播放给定的单声道 wav 文件。关于将实现这一目标的具体功能,任何人都可以为我指出正确的方向吗?我尝试用谷歌搜索解决方案并没有取得成果。谢谢。

【问题讨论】:

【参考方案1】:

您可以使用 DirectSound 通过一组环绕声扬声器播放声音。请参阅MSDN page "Sounds in 3-D"。

【讨论】:

我曾想过使用 OpenAL(另一个 3D 音频库)来做类似的事情,但我想不出一种方法让声音只从一个(或主要是一个)扬声器发出。 略读 OpenAL 指南,我看到一个关于“多通道缓冲区”的部分,看起来您可以独立控制每个扬声器。你已经试过了吗? 来自公开邮件列表的这条消息看起来可能会有所帮助:opensource.creative.com/pipermail/openal/2009-April/011586.html @Ben:我是一名程序员,而不是职业,所以我经常发现自己在游刃有余。这是一个这样的案例。我还没有看到那个部分,我现在正在检查它。如果您知道可以在 DirectSound 中完成此任务的特定功能,我也可以。让程序运行起来比我坚持任何特定的实现更重要。 我可能不得不提出另一个问题;但我被困在'ALshort monodata [samples];'在 OpenAL 中,缓冲区似乎都由 ID 寻址,所以我不确定如何进入原始 WAV 样本以便按照邮件列表消息中的讨论重新分配它们。【参考方案2】:

我建议先尝试 Ben Voigt 的答案,因为如果成功,它可能会更容易、更灵活。

但如果由于某种原因没有,另一种选择如下。

基本上,当您想从特定扬声器播放单声道 .wav 时,将其转换为 6 声道 .wav,在其中五个声道上无声,但包含来自声道上单声道 .wav 的数据您希望它播放的扬声器。

这应该很容易做到,因为 .wav 文件格式非常简单。基本思想是单声道 .wav 文件中的声音数据将由(通常)每个音频样本的两字节对组成,例如:

1234 2ab3 def0 ce18 ....

要将数据转换为多通道,您需要为其他通道插入静音(零)。例如,对于通道 0(左前),您可以使用:

1234 0000 0000 0000 0000 0000 2ab3 0000 0000 0000 0000 0000 def0 0000 0000 0000 0000 0000 (etc)

而你会使用右前方:

0000 1234 0000 0000 0000 0000 0000 2ab3 0000 0000 0000 0000 0000 def0 0000 0000 0000 0000 (etc)

(有关订单请咨询此list of speaker assignments。)

你还需要处理文件头,但是wave file header format很简单;您需要将 NumChannels 从 1 更改为 6,ByteRate 从任何值更改为相同的值乘以 6,BlockAlignSubchunk2Size 类似。

请注意,我实际上并没有测试过以上任何一个,但它不应该花费太多时间来进行实验。如果它不起作用,可能需要将较新的 WAVE_FORMAT_EXTENSIBLE 数据添加到文件中 - 更繁琐但仍然不太难;这是useful page describing these extensions to the .wav format。

【讨论】:

是的,这个和我链接的邮件列表中的思路基本一样,只有你的扩展多通道后写回文件,我找到的那个发到声卡而是。【参考方案3】:

你尝试过 BASS 库吗?

http://www.un4seen.com/

多个输出 同时使用多个声卡,并在它们之间移动通道

【讨论】:

以上是关于如何在 C++ 中只用一个扬声器播放声音?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 中的简单声音

如何同时在多个设备中播放声音

如何在 vb.Net 中通过外部扬声器播放声音?

免提通话期间通过电话扬声器播放声音

如何在通话期间以编程方式在 iPhone 的两个扬声器上播放声音

如何从一组双重创建声音并在扬声器上播放