Skip to content

Commit f3fd6d2

Browse files
new release. added better error messages and code documentation
1 parent 15822f2 commit f3fd6d2

19 files changed

+433
-366
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ x64
44
*.ipdb
55
*.ipdb
66
*.pdb
7+
*.vspx
78
*.vcxproj.filters
89
*.zip
910
\[stuff\]/

AudioDevice.cpp

Lines changed: 68 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
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() {
2828
void 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

4343
AudioDevice::AudioDevice() {
44-
init();
44+
initDefault();
4545
HRESULT hr = _pEnumerator->GetDefaultAudioEndpoint(eRender, eConsole, &_pDevice);
46-
assertHrResult(hr);
46+
assertHresult(hr);
4747
init(_pDevice);
4848
}
4949

5050
AudioDevice::AudioDevice(const std::string &id) : AudioDevice(std::wstring(id.begin(), id.end())) {
5151
}
5252

5353
AudioDevice::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

6060
AudioDevice::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

7488
void 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

115137
const 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 {
159181
UINT32 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

Comments
 (0)