forked from microsoft/Xbox-ATG-Samples
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathISACRenderer.cpp
172 lines (141 loc) · 4.69 KB
/
ISACRenderer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//--------------------------------------------------------------------------------------
//
// ISACRenderer.cpp
//
// Advanced Technology Group (ATG)
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#include "pch.h"
#include "ISACRenderer.h"
using namespace Windows::Media::Devices;
using Microsoft::WRL::ComPtr;
//
// ISACRenderer()
//
ISACRenderer::ISACRenderer() :
m_SpatialAudioClient( nullptr ),
m_SpatialAudioStream( nullptr ),
m_ISACrenderstate( RenderState::Inactive ),
m_bufferCompletionEvent( NULL )
{
}
//
// ~ISACRenderer()
//
ISACRenderer::~ISACRenderer()
{
}
//
// InitializeAudioDeviceAsync()
//
// Activates the default audio renderer on a asynchronous callback thread. This needs
// to be called from the main UI thread.
//
HRESULT ISACRenderer::InitializeAudioDeviceAsync()
{
ComPtr<IActivateAudioInterfaceAsyncOperation> asyncOp;
HRESULT hr = S_OK;
// Get a string representing the Default Audio Device Renderer
m_DeviceIdString = MediaDevice::GetDefaultAudioRenderId( Windows::Media::Devices::AudioDeviceRole::Default );
EnableSpatialAudio();
// This call must be made on the main UI thread. Async operation will call back to
// IActivateAudioInterfaceCompletionHandler::ActivateCompleted, which must be an agile interface implementation
hr = ActivateAudioInterfaceAsync(m_DeviceIdString->Data(), __uuidof(ISpatialAudioClient), nullptr, this, &asyncOp);
if (FAILED( hr ))
{
m_ISACrenderstate = RenderState::Inactive;
}
return hr;
}
//
// ActivateCompleted()
//
// Callback implementation of ActivateAudioInterfaceAsync function. This will be called on MTA thread
// when results of the activation are available.
//
HRESULT ISACRenderer::ActivateCompleted( IActivateAudioInterfaceAsyncOperation *operation )
{
HRESULT hr = S_OK;
HRESULT hrActivateResult = S_OK;
ComPtr<IUnknown> punkAudioInterface = nullptr;
// Check for a successful activation result
hr = operation->GetActivateResult( &hrActivateResult, &punkAudioInterface );
if (SUCCEEDED( hr ) && SUCCEEDED( hrActivateResult ))
{
// Get the pointer for the Audio Client
punkAudioInterface.Get()->QueryInterface( IID_PPV_ARGS(&m_SpatialAudioClient) );
if( nullptr == m_SpatialAudioClient)
{
hr = E_FAIL;
goto exit;
}
// Check the available rendering formats
ComPtr<IAudioFormatEnumerator> audioObjectFormatEnumerator;
hr = m_SpatialAudioClient->GetSupportedAudioObjectFormatEnumerator(&audioObjectFormatEnumerator);
// WavFileIO is helper class to read WAV file
WAVEFORMATEX* objectFormat = nullptr;
UINT32 audioObjectFormatCount;
hr = audioObjectFormatEnumerator->GetCount(&audioObjectFormatCount); // There is at least one format that the API accept
if (audioObjectFormatCount == 0)
{
hr = E_FAIL;
goto exit;
}
// Select the most favorable format, first one
hr = audioObjectFormatEnumerator->GetFormat(0, &objectFormat);
// Create the event that will be used to signal the client for more data
m_bufferCompletionEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
// Define the object mask for the Spatial bed - in this case 7.1.4
AudioObjectType objectmask =
AudioObjectType_FrontLeft |
AudioObjectType_FrontRight |
AudioObjectType_FrontCenter |
AudioObjectType_LowFrequency |
AudioObjectType_SideLeft |
AudioObjectType_SideRight |
AudioObjectType_BackLeft |
AudioObjectType_BackRight |
AudioObjectType_TopFrontLeft |
AudioObjectType_TopFrontRight |
AudioObjectType_TopBackLeft |
AudioObjectType_TopBackRight;
// Set the activation parameters for the Spatial stream
SpatialAudioObjectRenderStreamActivationParams activationparams =
{
objectFormat,
objectmask,
0, //zero dynamic objects needed
0, //zero dynamic objects needed
AudioCategory_GameEffects,
m_bufferCompletionEvent,
nullptr
};
PROPVARIANT activateParams;
PropVariantInit(&activateParams);
activateParams.vt = VT_BLOB;
activateParams.blob.cbSize = sizeof(activationparams);
activateParams.blob.pBlobData = reinterpret_cast<BYTE*>(&activationparams);
// Activate the spatial stream
hr = m_SpatialAudioClient->ActivateSpatialAudioStream(&activateParams, __uuidof(m_SpatialAudioStream), &m_SpatialAudioStream);
if (FAILED(hr))
{
hr = E_FAIL;
goto exit;
}
// Start streaming / rendering
hr = m_SpatialAudioStream->Start();
if (FAILED(hr))
{
hr = E_FAIL;
goto exit;
}
m_ISACrenderstate = RenderState::Active;
}
exit:
if (FAILED( hr ))
{
m_ISACrenderstate = RenderState::Inactive;
}
// Need to return S_OK
return S_OK;
}