3

我正在为一个程序开发音频代码,该程序需要能够在各种设备上录制和播放,其中一些是高端设备,具有各种不同的 wav 和 AIFF 格式。我希望能够使用 WASAPI 库,但我遇到了一些重大问题。目前最大的问题是,据我所知,设备只允许播放格式完全匹配的流。

这就是我正在做的 - 我将设备(这里我只是获取默认控制台设备)设置为:

hr = pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &pPlaybackDevice);

我通过以下方式激活设备:

hr = pPlaybackDevice->Activate( __uuidof(IAudioClient), CLSCTX_ALL, NULL, (void**)&pTakeAudioClient);

然后我检查混合格式:

hr = pTakeAudioClient->GetMixFormat(&pWaveFormatEx);

但是,如果我在调用 Initialize 时使用不同的格式:

hr = pTakeAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,hnsRequestedDuration, 0, pAnotherWaveFormatEx,NULL);

我得到一个错误。似乎该文件绝对必须采用 GetMixFormat 返回的格式。如果我调用 IsFormatSupported 来了解我可以提交哪些格式:

hr = pTakeAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_SHARED, &waveFormatEx, &pAnotherWaveFormatEx);

我明白E_INVALIDARG了,即使两个结构完全相同。根据 WASAPI 文档,当“Parameter ShareMode is an value than AUDCLNT_SHAREMODE_SHAREDor AUDCLNT_SHAREMODE_EXCLUSIVE”时返回。我路过AUDCLNT_SHAREMODE_SHARED。这似乎是文档中的错误。

为了实验,我尝试:

hr = pTakeAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, &waveFormatEx, NULL);

错误返回是0x8889000e- 我无法找到对该错误的引用。您可以提供的任何帮助都将非常感激,即使它是“使用 MMSystem”。我会从 MMSystem 开始,只是我们需要能够在有多个设备时控制播放设备。

4

2 回答 2

1

0x8889000e= AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWEDHRESULT阅读实用程序),这几乎说明了原因:此格式不适用于独占模式音频客户端。而且您可能不需要它独占,共享模式可能就足够了。无论如何,要通过 WASAPI 录制和播放,您需要协商一种硬件支持的格式,这通常是 PCM 音频格式之一。

要在格式之间进行转换,您有几个 API(ACM、DirectShow、Media Foundation)。DirectShow 和 Media Foundation 等一些 API 既能够将播放的数据自动转换为支持的格式,也能够通过音频设备播放。

于 2012-11-18T17:40:33.007 回答
1

我知道这是一个非常古老的线程,但是这种情况显然已经得到改善,尽管在提出问题时该选项可能已经可用,但我不确定(并且文档,就像微软的大多数东西一样,通常不是非常有帮助)。

无论如何,根据我的经验,假设您想使用标准 PCM 音频,关键因素似乎是您要求的采样率。大多数声卡似乎不会接受在这方面与其“混合格式”中报告的内容不同的任何内容(这是用于共享音频模式)。因此,您可以接受卡的采样率,并以该采样率发送所有内容,如果这对您来说是一个可行的选择,或者您可以请求音频驱动程序根据需要在输出链中插入转换器。

最简单的方法是在发出呼叫时使用 AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM 标志Initialize(),这将按照我所说的进行,并将您请求的任何源音频格式转换为设备支持的格式。似乎甚至可以使用IAudioClockAdjustment::SetSampleRate即时更改 SR ,但我自己从未尝试过。请查看此页面中的不同标志以获取更多信息。

于 2017-06-21T19:44:47.297 回答