Metro Apps はWASAPI排他モードをサポートしないようだ

公開:2012-05-05 06:32
更新:2020-02-15 04:37
カテゴリ:wasapi,windows store apps,audio,windows,windows api

昨日今日とWASAPIの初期化コードを書いていた。排他モードで音を鳴らそうと思ったのだけれど、IsFormatSupportedでエラー:AUDCLNT_E_EXCLUSIVE_MODE_NOT_ALLOWEDとなってしまう。共有モードでは問題ない。


  void makeWaveFormat(WAVEFORMATEXTENSIBLE& format,
    int sample_rate = 44100,int channels = 2,int bits_per_sample = 16,int valid_bits_per_sample = 16,
    uint32_t type = WAVE_FORMAT_EXTENSIBLE,
    const GUID& sub_type = KSDATAFORMAT_SUBTYPE_PCM)
  {
    ZeroMemory(&format,sizeof(WAVEFORMATEXTENSIBLE));
    format.Format.wFormatTag = type;
    format.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
    format.SubFormat = sub_type;
    format.Format.nSamplesPerSec = sample_rate;
    format.Format.nChannels = channels;
    format.Format.wBitsPerSample = bits_per_sample;
    format.Format.nBlockAlign = (format.Format.wBitsPerSample / 8) * format.Format.nChannels;
    format.Format.nAvgBytesPerSec = format.Format.nSamplesPerSec  * format.Format.nBlockAlign;
    format.Samples.wValidBitsPerSample = valid_bits_per_sample;
    format.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
  }

SoundDriver::SoundDriver()
{
String^ deviceID = MediaDevice::GetDefaultAudioRenderId(AudioDeviceRole::Default);
ActivateAudioInterface(deviceID->Data(),__uuidof(IAudioClient2),&audioClient_);
WAVEFORMATEXTENSIBLE format;
makeWaveFormat(format);
sf::co_task_memory<WAVEFORMATEX>  alt_format;
HRESULT hr = audioClient_->IsFormatSupported(
    AUDCLNT_SHAREMODE_EXCLUSIVE,
    reinterpret_cast<WAVEFORMATEX*>(&format),
    reinterpret_cast<WAVEFORMATEX**>(&alt_format));
REFERENCE_TIME latency_;
audioClient_->GetStreamLatency(&latency_);
REFERENCE_TIME defaultDevicePeriod,minDevicePriod;
audioClient_->GetDevicePeriod(&defaultDevicePeriod,&minDevicePriod);
DX::ThrowIfFailed(
    audioClient_->Initialize(
        AUDCLNT_SHAREMODE_EXCLUSIVE,
        AUDCLNT_STREAMFLAGS_NOPERSIST | AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
        minDevicePriod,minDevicePriod,
        reinterpret_cast<WAVEFORMATEX*>(&format),NULL));
DX::ThrowIfFailed(audioClient_->GetService(__uuidof(IAudioRenderClient),&audioRenderClient_));
}

なんとなくMetro Styleでは排他モードのサポートはないのではないかなとググってみると下記を発見。

IAudioClient does not support Exclusive mode in Metro Apps?.

サポートしてないんだろうな。おそらく。

共有モードだとサンプルレートとかビット数がアプリ側で固定できないんだよね。設定値に応じて変換コードを入れるか、エラーでユーザーに変更を促すか、どちらかの対応が必要だ。