11#include " AudioDevice.h"
2- #include " Functiondiscoverykeys_devpkey.h"
2+ #include " Functiondiscoverykeys_devpkey.h" // PKEY_Device_FriendlyName
33
44#define SAFE_RELEASE (punk ) if ((punk) != NULL ) { (punk)->Release (); (punk) = NULL ; }
55
@@ -10,16 +10,16 @@ std::vector<AudioDevice*> AudioDevice::getDevices() {
1010 initStatic ();
1111 IMMDeviceCollection *pCollection;
1212 HRESULT hr = _pEnumerator->EnumAudioEndpoints (eRender, DEVICE_STATE_ACTIVE, &pCollection);
13- assertHrResult (hr);
13+ assertHresult (hr);
1414 UINT count;
1515 hr = pCollection->GetCount (&count);
16- assertHrResult (hr);
16+ assertHresult (hr);
1717 std::vector<AudioDevice*> devices;
1818 for (ULONG i = 0 ; i < count; i++) {
1919 IMMDevice *pDevice;
2020 hr = pCollection->Item (i, &pDevice);
2121 devices.push_back (new AudioDevice (pDevice));
22- assertHrResult (hr);
22+ assertHresult (hr);
2323 }
2424 SAFE_RELEASE (pCollection);
2525 return devices;
@@ -28,9 +28,9 @@ std::vector<AudioDevice*> AudioDevice::getDevices() {
2828void AudioDevice::initStatic () {
2929 if (!_initStatic) {
3030 HRESULT hr = CoInitialize (nullptr );
31- assertHrResult (hr);
31+ assertHresult (hr);
3232 hr = CoCreateInstance (__uuidof (MMDeviceEnumerator), NULL , CLSCTX_ALL, __uuidof (IMMDeviceEnumerator), (void **)&_pEnumerator);
33- assertHrResult (hr);
33+ assertHresult (hr);
3434 _initStatic = true ;
3535 }
3636}
@@ -41,82 +41,104 @@ void AudioDevice::destroyStatic() {
4141}
4242
4343AudioDevice::AudioDevice () {
44- init ();
44+ initDefault ();
4545 HRESULT hr = _pEnumerator->GetDefaultAudioEndpoint (eRender, eConsole, &_pDevice);
46- assertHrResult (hr);
46+ assertHresult (hr);
4747 init (_pDevice);
4848}
4949
5050AudioDevice::AudioDevice (const std::string &id) : AudioDevice(std::wstring(id.begin(), id.end())) {
5151}
5252
5353AudioDevice::AudioDevice (const std::wstring &id) {
54- init ();
54+ initDefault ();
5555 HRESULT hr = _pEnumerator->GetDevice (id.c_str (), &_pDevice);
56- assertHrResult (hr);
56+ assertHresult (hr);
5757 init (_pDevice);
5858}
5959
6060AudioDevice::AudioDevice (IMMDevice *pDevice) {
61+ initDefault ();
6162 init (pDevice);
6263}
6364
64- void AudioDevice::init () {
65+ AudioDevice::~AudioDevice () {
66+ // Stop service;
67+ _pAudioClient->Stop ();
68+ // Free resources
69+ CoTaskMemFree (_pFormat);
70+ SAFE_RELEASE (_pDevice);
71+ SAFE_RELEASE (_pAudioClient);
72+ SAFE_RELEASE (_pCaptureClient);
73+ SAFE_RELEASE (_pRenderClient);
74+ SAFE_RELEASE (_pSimpleVolume);
75+ }
76+
77+ void AudioDevice::initDefault () {
6578 initStatic ();
6679 _pFormat = nullptr ;
6780 _pDevice = nullptr ;
6881 _pAudioClient = nullptr ;
6982 _pCaptureClient = nullptr ;
7083 _pRenderClient = nullptr ;
7184 _pSimpleVolume = nullptr ;
85+ _bufferFrameCount = 0 ;
7286}
7387
7488void AudioDevice::init (IMMDevice *pDevice) {
7589 _pDevice = pDevice;
76-
7790 HRESULT hr = _pDevice->Activate (__uuidof (IAudioClient), CLSCTX_ALL, NULL , (void **)&_pAudioClient);
78- assertHrResult (hr);
79-
91+ assertHresult (hr);
8092 hr = _pAudioClient->GetMixFormat (&_pFormat);
81- assertHrResult (hr);
93+ assertHresult (hr);
94+ }
8295
83- _initMode = false ;
84- _bufferFrameCount = - 1 ;
96+ void AudioDevice::startCaptureService () {
97+ startService ( true ) ;
8598}
8699
87- void AudioDevice::initMode (const bool capture) {
88- if (!_initMode) {
89- HRESULT hr;
90- if (capture) {
91- hr = _pAudioClient->Initialize (AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_LOOPBACK, 0 , 0 , _pFormat, 0 );
92- }
93- else {
94- hr = _pAudioClient->Initialize (AUDCLNT_SHAREMODE_SHARED, 0 , 0 , 0 , _pFormat, 0 );
95- }
96- assertHrResult (hr);
100+ void AudioDevice::startRenderService () {
101+ startService (false );
102+ }
97103
98- // Get the size of the allocated buffer.
99- hr = _pAudioClient->GetBufferSize (&_bufferFrameCount);
100- assertHrResult (hr);
104+ void AudioDevice::startService (const bool capture) {
105+ HRESULT hr;
106+ if (capture) {
107+ hr = _pAudioClient->Initialize (AUDCLNT_SHAREMODE_SHARED, AUDCLNT_STREAMFLAGS_LOOPBACK, 0 , 0 , _pFormat, 0 );
108+ assertHresult (hr);
109+ hr = _pAudioClient->GetService (__uuidof (IAudioCaptureClient), (void **)&_pCaptureClient);
110+ assertHresult (hr);
111+ }
112+ else {
113+ hr = _pAudioClient->Initialize (AUDCLNT_SHAREMODE_SHARED, 0 , 0 , 0 , _pFormat, 0 );
114+ assertHresult (hr);
115+ hr = _pAudioClient->GetService (__uuidof (IAudioRenderClient), (void **)&_pRenderClient);
116+ assertHresult (hr);
117+ }
101118
102- _initMode = true ;
119+ // Get the size of the allocated buffer.
120+ hr = _pAudioClient->GetBufferSize (&_bufferFrameCount);
121+ assertHresult (hr);
122+
123+ if (!capture) {
124+ // Get and release render buffer first time. Needed to not get audio glitches
125+ BYTE *pRenderBuffer;
126+ hr = _pRenderClient->GetBuffer (_bufferFrameCount, &pRenderBuffer);
127+ assertHresult (hr);
128+ hr = _pRenderClient->ReleaseBuffer (_bufferFrameCount, AUDCLNT_BUFFERFLAGS_SILENT);
129+ assertHresult (hr);
103130 }
104- }
105131
106- AudioDevice::~AudioDevice () {
107- CoTaskMemFree (_pFormat);
108- SAFE_RELEASE (_pDevice);
109- SAFE_RELEASE (_pAudioClient);
110- SAFE_RELEASE (_pCaptureClient);
111- SAFE_RELEASE (_pRenderClient);
112- SAFE_RELEASE (_pSimpleVolume);
132+ // Start aduio service on device.
133+ hr = _pAudioClient->Start ();
134+ assertHresult (hr);
113135}
114136
115137const std::string AudioDevice::getId () {
116138 if (!_id.size ()) {
117139 LPWSTR id;
118140 HRESULT hr = _pDevice->GetId (&id);
119- assertHrResult (hr);
141+ assertHresult (hr);
120142 std::wstring tmp (id);
121143 _id = std::string (tmp.begin (), tmp.end ());
122144 CoTaskMemFree (id);
@@ -129,15 +151,15 @@ const std::string AudioDevice::getName() {
129151 IPropertyStore *pProps = NULL ;
130152
131153 HRESULT hr = _pDevice->OpenPropertyStore (STGM_READ, &pProps);
132- assertHrResult (hr);
154+ assertHresult (hr);
133155
134156 // Initialize container for property value.
135157 PROPVARIANT varName;
136158 PropVariantInit (&varName);
137159
138160 // Get the endpoint's friendly-name property.
139161 hr = pProps->GetValue (PKEY_Device_FriendlyName, &varName);
140- assertHrResult (hr);
162+ assertHresult (hr);
141163
142164 std::wstring tmp (varName.pwszVal );
143165 _name = std::string (tmp.begin (), tmp.end ());
@@ -159,59 +181,14 @@ UINT32 AudioDevice::getBufferFrameCount() const {
159181UINT32 AudioDevice::getBufferFrameCountAvailable () const {
160182 UINT32 numFramesPadding;
161183 HRESULT hr = _pAudioClient->GetCurrentPadding (&numFramesPadding);
162- assertHrResult (hr);
184+ assertHresult (hr);
163185 return _bufferFrameCount - numFramesPadding;
164186}
165187
166- IAudioCaptureClient* AudioDevice::getCaptureClient () {
167- if (!_pCaptureClient) {
168- initMode (true );
169- HRESULT hr = _pAudioClient->GetService (__uuidof (IAudioCaptureClient), (void **)&_pCaptureClient);
170- assertHrResult (hr);
171- }
172- return _pCaptureClient;
173- }
174-
175- IAudioRenderClient* AudioDevice::getRenderClient () {
176- if (!_pRenderClient) {
177- initMode (false );
178- HRESULT hr = _pAudioClient->GetService (__uuidof (IAudioRenderClient), (void **)&_pRenderClient);
179- assertHrResult (hr);
180- }
181- return _pRenderClient;
182- }
183-
184- ISimpleAudioVolume* AudioDevice::getVolume () {
188+ ISimpleAudioVolume* AudioDevice::getVolumeControl () {
185189 if (!_pSimpleVolume) {
186190 HRESULT hr = _pAudioClient->GetService (__uuidof (ISimpleAudioVolume), (void **)&_pSimpleVolume);
187- assertHrResult (hr);
191+ assertHresult (hr);
188192 }
189193 return _pSimpleVolume;
190- }
191-
192- void AudioDevice::start () {
193- HRESULT hr = _pAudioClient->Start ();
194- assertHrResult (hr);
195- }
196-
197- void AudioDevice::stop () {
198- HRESULT hr = _pAudioClient->Stop ();
199- assertHrResult (hr);
200- }
201-
202- void AudioDevice::printInfo () {
203- printf (" %s '%s'\n " , getName ().c_str (), getId ().c_str ());
204- }
205-
206-
207-
208- // _pFormat->wFormatTag = WAVE_FORMAT_PCM;
209- // _pFormat->nChannels = 2;
210- // _pFormat->wBitsPerSample = 16;
211- // _pFormat->nSamplesPerSec = 44100;
212- // _pFormat->nBlockAlign = _pFormat->nChannels * _pFormat->wBitsPerSample / 8;
213- // _pFormat->nAvgBytesPerSec = _pFormat->nSamplesPerSec * _pFormat->nBlockAlign;
214- // _pFormat->cbSize = 0;
215- // hr = _pAudioClient->IsFormatSupported(AUDCLNT_SHAREMODE_EXCLUSIVE, _pFormat, 0);
216- // AUDCLNT_E_UNSUPPORTED_FORMAT
217- // hr = _pAudioClient->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE, 0, 0, 0, _pFormat, 0);
194+ }
0 commit comments