How to: Initialize XAudio2

You initialize XAudio2 for audio playback by creating an instance of the XAudio2 engine, and then creating a mastering voice.

  1. First, you need to have initialized COM. If you're using C++/WinRT, then it's taken care of. If you're not certain that your environment has already initialized COM, then you can call CoInitializeEx as long as you check the return value.

    HRESULT hr = ::CoInitializeEx(nullptr, COINIT_MULTITHREADED);
    if (FAILED(hr)) return hr;
    
  2. To create an instance of the XAudio2 engine, call the XAudio2Create function. That will give you a pointer to an IXAudio2 interface, and it's a good idea to store that in a class data member. In this snippet we're using a C++/WinRT smart pointer, but you could use a raw pointer if necessary.

    winrt::com_ptr<IXAudio2> m_xAudio2{};
    ...
    winrt::check_hresult(::XAudio2Create(m_xAudio2.put(), 0, XAUDIO2_DEFAULT_PROCESSOR));
    
  3. Next, to create what's known as a mastering voice, call the IXAudio2::CreateMasteringVoice method. That will give you a pointer to an IXAudio2MasteringVoice interface. A mastering voices encapsulates an audio device. It's the ultimate destination for all audio that passes through an audio graph.

    IXAudio2MasteringVoice* m_pXAudio2MasteringVoice{};
    ...
    winrt::check_hresult(xAudio2->CreateMasteringVoice(&m_pXAudio2MasteringVoice));
    

Smart pointers

For safety and convenience, you can use a smart pointer for the IXAudio2 interface. But the voice interfaces (such as IXAudio2MasteringVoice) don't have a Release method, so you'll see a build error if you try to use a smart pointer for those. In these code snippets we use a smart pointer where possible, and a raw pointer where necessary.