> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Use XAudio2 to play a sound

> Use XAudio2 to play a sound

Use `XAudio2` to load and play a .wav file on XBOX One.

The following sections describe how to use `XAudio2` to load and play a sound on the XBOX One Development Kit.

* [Important XAudio2 data types](#ID4ELB)
* [Initializing XAudio2](#ID4EXC)
* [Loading a .wav file](#ID4E1D)
* [Setting a file path to a .wav file](#ID4E2H)
* [Playing a .wav file](#ID4EAF)
* [Terminating a .wav file](#ID4E2F)

For a working `XAudio2` sample, download the SimplePlaySound sample from the Microsoft Game Development Kit (GDK) samples.

<a id="ID4ELB" />

## Important XAudio2 data types

`XAudio2` provides several data types to help you play sound effects on XBOX One. To play a .wav file, you need at least the following data types.

* `IXAudio2`: This is the interface for the `XAudio2` object that manages all Audio Engine states, the audio processing thread, the voice graph, and more.

* `IXAudio2SourceVoice`: Use a source voice to submit audio data to the `XAudio2` processing pipeline. To be heard, voice data must be sent to a mastering voice.

* `IXAudio2MasteringVoice`: Use this data type to represent the audio output device. Data buffers can't be submitted directly to mastering voices. However, to be heard, data submitted to other types of voices must be directed to a mastering voice.

In addition, you might find the following data types useful.

* `PlaySoundVoiceContext`: Use this data type to free up the audio buffer after processing.

* `IXAudio2VoiceCallback`: This data type contains methods that notify the client when certain events happen in a specific `IXAudio2SourceVoice`.

<a id="ID4EXC" />

## Initializing XAudio2

`CoInitializeEx()` initializes the Component Object Model (COM) for use by the current thread. Set the first parameter to `NULL`. Set the second parameter to `COINIT_MULTITHREADED`.

`XAudio2Create()` creates a new `XAudio2` object and returns a pointer to its `IXAudio2` interface. Ensure that `XAUDIO2_PROCESSOR` is set to a valid value. The value `XAUDIO2_USE_DEFAULT_PROCESSOR` is recommended to let the OS choose the ideal processor based on the hardware platform.

`IXAudio2::CreateMasteringVoice()` creates and configures a mastering voice and points to it with the user-provided pointer.

#### C++

```cpp theme={null}
CoInitializeEx( NULL, COINIT_MULTITHREADED );

// Create an XAudio2 device.
DX::ThrowIfFailed( XAudio2Create( &m_pXAudio2, 0, XAUDIO2_USE_DEFAULT_PROCESSOR, NULL ) );

// Create an XAudio2 mastering voice, and store the result.
DX::ThrowIfFailed( m_pXAudio2->CreateMasteringVoice( &m_pMasteringVoice ) );  
```

<a id="ID4E1D" />

## Loading a .wav file

To access the audio file, use an instance of the `WaveFile` class.

* To open a .wav file and retrieve some information stored in the file's header, call `WaveFile::Open(LPCWSTR strFileName)`.
* To determine the format of the .wav file, call `WaveFile::GetFormat()`.
* To determine the number of bytes and samples in the .wav file, call `WaveFile::GetDuration()`.
* To read the sample data into memory, call `WaveFile::ReadSample()`.

#### C++

```cpp theme={null}
// Read the .wav file.
WaveFile WaveFile;

// Append the file name and location to the end of the installation location.
WCHAR FilenameAndLocation[ 1024 ];
_snwprintf_s( FilenameAndLocation, _countof( FilenameAndLocation ), _TRUNCATE, L"%s%s", g_strCommonFileRoot, szFilename );

DX::ThrowIfFailed( WaveFile.Open( FilenameAndLocation ) );

// Read the format header.
BYTE header[64];
WAVEFORMATEX* pbWfx = reinterpret_cast<WAVEFORMATEX*>(header);

DX::ThrowIfFailed( WaveFile.GetFormat( pbWfx, sizeof(header) ) );

// Calculate the number of bytes and samples in the .wav file. 
DWORD cbWaveSize = WaveFile.GetDuration();

// Read the sample data into memory.
BYTE* pbWaveData = new BYTE[ cbWaveSize ];
DX::ThrowIfFailed( WaveFile.ReadSample( 0, pbWaveData, cbWaveSize, &cbWaveSize ) );  
```

<a id="ID4E2H" />

## Setting a file path to a .wav file

To load and use audio files, use the following code to find the installation location of your project on the local device. Store the installation location in a string. Append the location of the audio file to the end of the installation location string.

#### C++

```cpp theme={null}
std::wstring installFolder = Windows::ApplicationModel::Package::Current->InstalledLocation->Path->Data();  
```

<a id="ID4EAF" />

## Playing a .wav file

Create an `IXAudio2::CreateSourceVoice()` class, and then use it to submit audio data to the `XAudio2` processing pipeline. For voice data to be heard, you must send it to a mastering voice directly or through intermediate submix voices. To store the details of the audio file, create an `XAUDIO2_BUFFER`.

After you create and initialize the `XAudio2` buffer and source voice, call `IXAudio2SourceVoice::SubmitSourceBuffer()` to add the audio buffer to the voice input queue. Note that the audio data pointed to by `XAUDIO2_BUFFER::pAudioData` must remain valid until `XAudio2` has finished playing the contents of the buffer.

After the voice input queue is populated, call `IXAudio2SourceVoice::Start()` to play the next sound in the queue.

#### C++

```cpp theme={null}
// Play the .wav file by using a new XAudio2SourceVoice.
// Create the source voice.
DX::ThrowIfFailed( pXaudio2->CreateSourceVoice( &m_pSourceVoice, pbWfx, 0, XAUDIO2_DEFAULT_FREQ_RATIO, &m_VoiceContext ) );

// Submit the .wav sample data by using an XAUDIO2_BUFFER structure.
XAUDIO2_BUFFER buffer = {0};
buffer.pAudioData     = pbWaveData;
buffer.Flags          = XAUDIO2_END_OF_STREAM;
buffer.AudioBytes     = cbWaveSize;
buffer.pContext       = pbWaveData;

// Add the audio buffer to the voice input queue.
DX::ThrowIfFailed( m_pSourceVoice->SubmitSourceBuffer( &buffer ) );

// Play the next audio buffer in the queue.
DX::ThrowIfFailed( m_pSourceVoice->Start( 0 ) );  
```

<a id="ID4E2F" />

## Terminating a .wav file

To determine whether a .wav file has been played to completion, you'll need the current state of the source voice. Create an `XAUDIO2_VOICE_STATE` struct, and then call `IXAudio2SourceVoice::GetState()`. If the audio has been played to completion, call `IXAudio2SourceVoice::DestroyVoice()`.

#### C++

```cpp theme={null}
// Determine whether the sound effect has been played to completion, and handle an appropriate termination.
XAUDIO2_VOICE_STATE state;
m_pSourceVoice->GetState( &state, XAUDIO2_VOICE_NOSAMPLESPLAYED );
if( state.BuffersQueued == 0 )
{
  // Destroy the current sound effect.
  m_pSourceVoice->DestroyVoice();
}  
```

## See also

[Overview of XAudio2](/build/console-features/audio/overviews/xaudio2-overview)
[Overview of ADPCM](/build/console-features/audio/overviews/adpcm-overview)
[ADPCM command-line encoder](/build/console-features/audio/tools/adpcmencoder-tools)


## Related topics

- [Overview of ADPCM](/build/console-features/audio/overviews/adpcm-overview.md)
- [ADPCM command-line encoder](/build/console-features/audio/tools/adpcmencoder-tools.md)
- [Overview of xWMA](/build/console-features/audio/overviews/xwma-overview.md)
- [XAudio2CreateWithSharedContexts](/reference/audio/xaudio2xbox/functions/xaudio2createwithsharedcontexts.md)
- [Audio](/build/console-features/audio/gc-audio-toc.md)
