UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
wasapi.cpp File Reference
#include <audiosessiontypes.h>
#include <audioclient.h>
#include <basetsd.h>
#include <cctype>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <combaseapi.h>
#include <guiddef.h>
#include <iomanip>
#include <iostream>
#include <ksmedia.h>
#include <mediaobj.h>
#include <mmeapi.h>
#include <mmdeviceapi.h>
#include <mmreg.h>
#include <objbase.h>
#include <propidl.h>
#include <propsys.h>
#include <sstream>
#include <string>
#include <synchapi.h>
#include <winerror.h>
#include "audio/audio_capture.h"
#include "audio/types.h"
#include "debug.h"
#include "host.h"
#include "lib_common.h"
#include "types.h"
#include "ug_runtime_error.hpp"
#include "utils/color_out.h"
#include "utils/macros.h"
#include "utils/windows.h"
Include dependency graph for wasapi.cpp:

Go to the source code of this file.

Classes

struct  state_acap_wasapi
 

Macros

#define FAIL_IF_NOT(cmd)
 
#define MOD_NAME   "[WASAPI cap.] "
 
#define REFTIMES_PER_MILLISEC   10000
 
#define REFTIMES_PER_SEC   10000000
 
#define SAFE_RELEASE(u)
 
#define THROW_IF_FAILED(cmd)
 

Functions

static void audio_cap_wasapi_done (void *state)
 
static void * audio_cap_wasapi_init (struct module *parent, const char *cfg)
 
static void audio_cap_wasapi_probe (struct device_info **available_devices, int *dev_count, void(**deleter)(void *))
 
static struct audio_frame * audio_cap_wasapi_read (void *state)
 
static string get_name (IMMDevice *pDevice)
 
 REGISTER_MODULE (wasapi, &acap_wasapi_info, LIBRARY_CLASS_AUDIO_CAPTURE, AUDIO_CAPTURE_ABI_VERSION)
 
static void show_help ()
 
string wasapi_get_default_device_id (EDataFlow dataFlow, IMMDeviceEnumerator *enumerator)
 

Variables

static const struct audio_capture_info acap_wasapi_info
 
static const GUID IDevice_FriendlyName = { 0xa45c254e, 0xdf1c, 0x4efd, { 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0 } }
 
const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient)
 
const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT }
 
const GUID KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM }
 
static const PROPERTYKEY PKEY_Device_FriendlyName = { IDevice_FriendlyName, 14 }
 

Detailed Description

Author
Martin Pulec marti.nosp@m.n.pu.nosp@m.lec@c.nosp@m.esne.nosp@m.t.cz
Todo
Probe and help are almost similar - consolide common code.

Definition in file wasapi.cpp.

Macro Definition Documentation

◆ FAIL_IF_NOT

#define FAIL_IF_NOT ( cmd)
Value:
do {HRESULT hr = cmd; if (hr != S_OK) { LOG(LOG_LEVEL_ERROR) << MOD_NAME << #cmd << ": " << hresult_to_str(hr) << "\n"; return nullptr;}} while(0)
#define MOD_NAME
Definition wasapi.cpp:64
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
#define LOG(level)
Definition debug.h:313

Definition at line 384 of file wasapi.cpp.

Referenced by audio_cap_wasapi_read().

◆ MOD_NAME

#define MOD_NAME   "[WASAPI cap.] "

Definition at line 64 of file wasapi.cpp.

Referenced by audio_cap_wasapi_init(), audio_cap_wasapi_probe(), and show_help().

◆ REFTIMES_PER_MILLISEC

#define REFTIMES_PER_MILLISEC   10000

Definition at line 66 of file wasapi.cpp.

◆ REFTIMES_PER_SEC

#define REFTIMES_PER_SEC   10000000

Definition at line 65 of file wasapi.cpp.

Referenced by audio_cap_wasapi_init().

◆ SAFE_RELEASE

#define SAFE_RELEASE ( u)
Value:
do { if ((u) != NULL) (u)->Release(); (u) = NULL; } while(0)

Definition at line 100 of file wasapi.cpp.

100#define SAFE_RELEASE(u) \
101 do { if ((u) != NULL) (u)->Release(); (u) = NULL; } while(0)

Referenced by audio_cap_wasapi_init(), audio_cap_wasapi_probe(), get_name(), show_help(), and wasapi_get_default_device_id().

◆ THROW_IF_FAILED

#define THROW_IF_FAILED ( cmd)
Value:
do { HRESULT hr = cmd; if (!SUCCEEDED(hr)) { ostringstream oss; oss << #cmd << ": " << hresult_to_str(hr); throw ug_runtime_error(oss.str()); } } while(0)

Definition at line 103 of file wasapi.cpp.

Referenced by audio_cap_wasapi_init(), audio_cap_wasapi_probe(), and show_help().

Function Documentation

◆ audio_cap_wasapi_done()

static void audio_cap_wasapi_done ( void * state)
static

Definition at line 378 of file wasapi.cpp.

379{
380 CoUninitialize();
381 delete static_cast<state_acap_wasapi *>(state);
382}
void ** state

References state.

◆ audio_cap_wasapi_init()

static void * audio_cap_wasapi_init ( struct module * parent,
const char * cfg )
static

Definition at line 234 of file wasapi.cpp.

235{
236 UNUSED(parent);
237 wchar_t deviceID[1024] = L"";
238 WAVEFORMATEX *pwfx = NULL;
239 enum { IDX_LOOP = -2, IDX_DFL = -1 };
240 int index = IDX_DFL;
241 if (strlen(cfg) > 0) {
242 if (strcmp(cfg, "help") == 0) {
243 show_help();
244 return INIT_NOERR;
245 }
246 if (isdigit(cfg[0])) {
247 index = atoi(cfg);
248 } else if (strcmp(cfg, "loopback") == 0) {
249 index = IDX_LOOP;
250 } else {
251 mbtowc(deviceID, cfg, (sizeof deviceID / 2) - 1);
252 }
253 }
254 auto s = new state_acap_wasapi();
255 if (!com_initialize(&s->com_initialized, MOD_NAME)) {
256 delete s;
257 return nullptr;
258 }
259 IMMDeviceEnumerator *enumerator = nullptr;
260 try {
261
262 THROW_IF_FAILED(CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator,
263 (void **) &enumerator));
264 if (wcslen(deviceID) > 0) {
265 THROW_IF_FAILED(enumerator->GetDevice(deviceID, &s->pDevice));
266 } else if (index >= 0) {
267 IMMDeviceCollection *pEndpoints = nullptr;
268 try {
269 THROW_IF_FAILED(enumerator->EnumAudioEndpoints(eCapture, DEVICE_STATEMASK_ALL, &pEndpoints));
270 UINT count;
271 THROW_IF_FAILED(pEndpoints->GetCount(&count));
272 for (UINT i = 0; i < count; ++i) {
273 if (i == (UINT) index) {
274 THROW_IF_FAILED(pEndpoints->Item(i, &s->pDevice));
275 break;
276 }
277 }
278 } catch (ug_runtime_error &e) { // just continue with the next
279 LOG(LOG_LEVEL_WARNING) << MOD_NAME << e.what() << "\n";
280 }
281 SAFE_RELEASE(pEndpoints);
282 } else {// default device
283 THROW_IF_FAILED(enumerator->GetDefaultAudioEndpoint(
284 index == IDX_DFL ? eCapture : eRender, eConsole,
285 &s->pDevice));
286 }
287 if (!s->pDevice) {
288 throw ug_runtime_error("Device not found!");
289 }
290 THROW_IF_FAILED(s->pDevice->Activate(IID_IAudioClient, CLSCTX_ALL, NULL,
291 (void **)&s->pAudioClient));
292
293 auto friendlyName = get_name(s->pDevice);
294 if (!friendlyName.empty()) {
295 LOG(LOG_LEVEL_NOTICE) << MOD_NAME << "Using device: "
296 << friendlyName << "\n";
297 }
298
299 REFERENCE_TIME hnsRequestedDuration = REFTIMES_PER_SEC;
300 // get the mixer format
301 THROW_IF_FAILED(s->pAudioClient->GetMixFormat(&pwfx));
302 // set our preferences
303 if (audio_capture_channels != 0) {
304 pwfx->nChannels = audio_capture_channels;
305 }
307 pwfx->nSamplesPerSec = audio_capture_sample_rate;
308 }
309 pwfx->wBitsPerSample = 16;
310 if (audio_capture_bps) {
311 pwfx->wBitsPerSample = audio_capture_bps * 8;
312 }
313 // coerce the format
314 // taken from https://github.com/Riateche/SoundStreamer/blob/master/SoundStreamer/SoundStreamer.cpp
315 switch (pwfx->wFormatTag) {
316 case WAVE_FORMAT_IEEE_FLOAT:
317 pwfx->wFormatTag = WAVE_FORMAT_PCM;
318 pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
319 pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
320 break;
321
322 case WAVE_FORMAT_EXTENSIBLE:
323 {
324 // naked scope for case-local variable
325 PWAVEFORMATEXTENSIBLE waveFormatEx = reinterpret_cast<PWAVEFORMATEXTENSIBLE>(pwfx);
326 if (IsEqualGUID(KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, waveFormatEx->SubFormat)) {
327 waveFormatEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
328 waveFormatEx->Samples.wValidBitsPerSample =
329 pwfx->wBitsPerSample;
330 pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8;
331 pwfx->nAvgBytesPerSec = pwfx->nBlockAlign * pwfx->nSamplesPerSec;
332 } else {
333 throw ug_runtime_error("Don't know how to coerce mix format to int-16");
334 }
335 }
336 break;
337
338 default:
339 ostringstream oss;
340 oss << "Don't know how to coerce WAVEFORMATEX with wFormatTag = 0x" << setw(8) << setfill('0') << " to PCM";
341 throw ug_runtime_error(oss.str());
342 }
343
344 THROW_IF_FAILED(s->pAudioClient->Initialize(
345 AUDCLNT_SHAREMODE_SHARED,
346 index == IDX_LOOP ? AUDCLNT_STREAMFLAGS_LOOPBACK : 0,
347 hnsRequestedDuration,
348 0,
349 pwfx,
350 NULL));
351
352 UINT32 bufferFrameCount;
353 THROW_IF_FAILED(s->pAudioClient->GetBufferSize(&bufferFrameCount));
354 s->frame.bps = pwfx->wBitsPerSample / 8;
355 s->frame.sample_rate = pwfx->nSamplesPerSec;
356 s->frame.ch_count = pwfx->nChannels;
357 s->frame.max_size = bufferFrameCount * s->frame.bps * s->frame.ch_count;
358 s->frame.data = (char *) malloc(s->frame.max_size);
359
360 THROW_IF_FAILED(s->pAudioClient->GetService(IID_IAudioCaptureClient, (void **) &s->pCaptureClient));
361 THROW_IF_FAILED(s->pAudioClient->Start());
362
363 } catch (ug_runtime_error &e) {
364 LOG(LOG_LEVEL_ERROR) << MOD_NAME << e.what() << "\n";
365 if (audio_capture_channels != 0) {
366 LOG(LOG_LEVEL_WARNING) << MOD_NAME << "Maybe wrong number of channels? Try using default.";
367 }
368 CoUninitialize();
369 delete s;
370 s = nullptr;
371 }
372
373 SAFE_RELEASE(enumerator);
374 CoTaskMemFree(pwfx);
375 return s;
376}
#define UNUSED(x)
#define THROW_IF_FAILED(cmd)
Definition wasapi.cpp:103
#define SAFE_RELEASE(u)
Definition wasapi.cpp:100
static void show_help()
Definition wasapi.cpp:193
const IID IID_IAudioCaptureClient
Definition wasapi.cpp:71
#define REFTIMES_PER_SEC
Definition wasapi.cpp:65
const GUID KSDATAFORMAT_SUBTYPE_PCM
Definition wasapi.cpp:76
const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT
Definition wasapi.cpp:77
static string get_name(IMMDevice *pDevice)
Definition wasapi.cpp:157
u32 UINT
Definition cuda_dxt.cu:13
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
int count
Definition hd-rum.c:44
unsigned int audio_capture_bps
Definition host.cpp:164
unsigned int audio_capture_sample_rate
Definition host.cpp:165
unsigned int audio_capture_channels
Definition host.cpp:163
#define INIT_NOERR
Definition host.h:73
const CLSID CLSID_MMDeviceEnumerator
Definition wasapi.cpp:68
const IID IID_IAudioClient
Definition wasapi.cpp:70
const IID IID_IMMDeviceEnumerator
Definition wasapi.cpp:69
const char * parent
Definition settings.cpp:198
bool com_initialize(bool *com_initialized, const char *err_prefix)
Definition windows.c:65

References audio_capture_bps, audio_capture_channels, audio_capture_sample_rate, CLSID_MMDeviceEnumerator, com_initialize(), count, get_name(), IID_IAudioCaptureClient, IID_IAudioClient, IID_IMMDeviceEnumerator, INIT_NOERR, KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, KSDATAFORMAT_SUBTYPE_PCM, LOG, LOG_LEVEL_ERROR, LOG_LEVEL_NOTICE, LOG_LEVEL_WARNING, MOD_NAME, parent, REFTIMES_PER_SEC, SAFE_RELEASE, show_help(), THROW_IF_FAILED, and UNUSED.

Here is the call graph for this function:

◆ audio_cap_wasapi_probe()

static void audio_cap_wasapi_probe ( struct device_info ** available_devices,
int * dev_count,
void(** deleter )(void *) )
static

<

Todo
This may be rather id than index

Definition at line 104 of file wasapi.cpp.

105{
106 *deleter = free;
107 *available_devices = nullptr;
108 *dev_count = 0;
109 bool com_initialized = false;
110
111 if (!com_initialize(&com_initialized, MOD_NAME)) {
112 return;
113 }
114 IMMDeviceEnumerator *enumerator = nullptr;
115 IMMDeviceCollection *pEndpoints = nullptr;
116
117 try {
118 THROW_IF_FAILED(CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator,
119 (void **) &enumerator));
120
121 THROW_IF_FAILED(enumerator->EnumAudioEndpoints(eCapture, DEVICE_STATEMASK_ALL, &pEndpoints));
122 UINT count;
123 THROW_IF_FAILED(pEndpoints->GetCount(&count));
124 for (UINT i = 0; i < count; ++i) {
125 IMMDevice *pDevice = nullptr;
126 LPWSTR pwszID = NULL;
127 try {
128 THROW_IF_FAILED(pEndpoints->Item(i, &pDevice));
129 THROW_IF_FAILED(pDevice->GetId(&pwszID));
130 *available_devices = (struct device_info *) realloc(*available_devices, (*dev_count + 1) * sizeof(struct device_info));
131 memset(&(*available_devices)[*dev_count], 0, sizeof(struct device_info));
132 snprintf((*available_devices)[*dev_count].dev, sizeof (*available_devices)[*dev_count].dev, ":%u", i);
133 snprintf((*available_devices)[*dev_count].name, sizeof (*available_devices)[*dev_count].name, "WASAPI %s", get_name(pDevice).c_str());
134 ++*dev_count;
135 } catch (ug_runtime_error &e) {
136 LOG(LOG_LEVEL_WARNING) << MOD_NAME << "Device " << i << ": " << e.what() << "\n";
137 }
138 SAFE_RELEASE(pDevice);
139 CoTaskMemFree(pwszID);
140 }
141 } catch (...) {
142 }
143 SAFE_RELEASE(enumerator);
144 SAFE_RELEASE(pEndpoints);
145 com_uninitialize(&com_initialized);
146 // add looopback
147 *available_devices = (struct device_info *)realloc(
148 *available_devices, (*dev_count + 1) * sizeof(struct device_info));
149 memset(&(*available_devices)[*dev_count], 0,
150 sizeof(struct device_info));
151 snprintf_ch((*available_devices)[*dev_count].dev, ":loopback");
152 snprintf_ch((*available_devices)[*dev_count].name,
153 "WASAPI computer audio output");
154 *dev_count += 1;
155}
int void(** deleter)(void *))
#define snprintf_ch(str,...)
shortcut for snprintf(var, sizeof var...), var must be a char array
Definition macros.h:101
const char * name
Definition settings.cpp:193
char dev[1024]
Definition types.h:383
void com_uninitialize(bool *com_initialized)
Definition windows.c:94

References CLSID_MMDeviceEnumerator, com_initialize(), com_uninitialize(), count, deleter, device_info::dev, get_name(), IID_IMMDeviceEnumerator, LOG, LOG_LEVEL_WARNING, MOD_NAME, name, SAFE_RELEASE, snprintf_ch, and THROW_IF_FAILED.

Here is the call graph for this function:

◆ audio_cap_wasapi_read()

static struct audio_frame * audio_cap_wasapi_read ( void * state)
static

Definition at line 385 of file wasapi.cpp.

386{
387 auto s = static_cast<state_acap_wasapi *>(state);
388
389 UINT32 packetLength = 0;
390 FAIL_IF_NOT(s->pCaptureClient->GetNextPacketSize(&packetLength));
391 if (packetLength == 0) {
392 Sleep(10);
393 }
394
395 FAIL_IF_NOT(s->pCaptureClient->GetNextPacketSize(&packetLength));
396
397 s->frame.data_len = 0;
398
399 while (packetLength != 0) {
400 UINT32 numFramesAvailable;
401 BYTE *pData;
402 DWORD flags;
403 // Get the available data in the shared buffer.
404 FAIL_IF_NOT(s->pCaptureClient->GetBuffer(
405 &pData,
406 &numFramesAvailable,
407 &flags, NULL, NULL));
408
409 //if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
410 //{
411 // pData = NULL; // Tell CopyData to write silence.
412 //}
413
414 // Copy the available capture data to the audio sink.
415 int count = numFramesAvailable * s->frame.bps * s->frame.ch_count;
416 if (s->frame.data_len + count > s->frame.max_size) {
417 count = s->frame.max_size - s->frame.data_len;
418 }
419 memcpy(s->frame.data + s->frame.data_len, pData, count);
420 //fprintf(stderr, "%d\n", count);
421 s->frame.data_len += count;
422 FAIL_IF_NOT(s->pCaptureClient->ReleaseBuffer(count / s->frame.ch_count / s->frame.bps));
423 if (s->frame.data_len == s->frame.max_size) {
424 return &s->frame;
425 }
426
427 FAIL_IF_NOT(s->pCaptureClient->GetNextPacketSize(&packetLength));
428 }
429 return &s->frame;
430}
const char unsigned int flags
#define FAIL_IF_NOT(cmd)
Definition wasapi.cpp:384
unsigned char BYTE
Definition crypt_aes.h:71

References count, FAIL_IF_NOT, flags, and state.

◆ get_name()

static string get_name ( IMMDevice * pDevice)
static

Definition at line 157 of file wasapi.cpp.

157 {
158 wstring out;
159 IPropertyStore *pProps = NULL;
160 PROPVARIANT varName;
161 LPWSTR pwszID = NULL;
162 // Initialize container for property value.
163 PropVariantInit(&varName);
164 HRESULT hr = pDevice->OpenPropertyStore(STGM_READ, &pProps);
165 if (!FAILED(hr)) {
166 hr = pProps->GetValue(PKEY_Device_FriendlyName, &varName);
167 if (!FAILED(hr)) {
168 out = varName.pwszVal;
169 }
170 }
171 SAFE_RELEASE(pProps);
172 CoTaskMemFree(pwszID);
173 PropVariantClear(&varName);
174 return win_wstr_to_str(out.c_str());
175}
static const PROPERTYKEY PKEY_Device_FriendlyName
Definition wasapi.cpp:73
@ FAILED

References FAILED, PKEY_Device_FriendlyName, and SAFE_RELEASE.

Referenced by audio_cap_wasapi_init(), audio_cap_wasapi_probe(), and show_help().

◆ REGISTER_MODULE()

REGISTER_MODULE ( wasapi ,
& acap_wasapi_info,
LIBRARY_CLASS_AUDIO_CAPTURE ,
AUDIO_CAPTURE_ABI_VERSION  )

◆ show_help()

static void show_help ( void )
static

Definition at line 193 of file wasapi.cpp.

193 {
194 col() << "Usage:\n" <<
195 SBOLD(SRED("\t-s wasapi") << "[:<index>|:<ID>]") <<
196 "\n\nAvailable devices:\n";
197
198 IMMDeviceEnumerator *enumerator = nullptr;
199 IMMDeviceCollection *pEndpoints = nullptr;
200 bool com_initialized = false;
201 if (!com_initialize(&com_initialized, MOD_NAME)) {
202 return;
203 }
204
205 try {
206 THROW_IF_FAILED(CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_IMMDeviceEnumerator,
207 (void **) &enumerator));
208 string default_dev_id = wasapi_get_default_device_id(eCapture, enumerator);
209 THROW_IF_FAILED(enumerator->EnumAudioEndpoints(eCapture, DEVICE_STATEMASK_ALL, &pEndpoints));
210 UINT count;
211 THROW_IF_FAILED(pEndpoints->GetCount(&count));
212 for (UINT i = 0; i < count; ++i) {
213 IMMDevice *pDevice = nullptr;
214 LPWSTR pwszID = NULL;
215 try {
216 THROW_IF_FAILED(pEndpoints->Item(i, &pDevice));
217 THROW_IF_FAILED(pDevice->GetId(&pwszID));
218 string dev_id = win_wstr_to_str(pwszID);
219 col() << (dev_id == default_dev_id ? "(*)" : "") << "\t" << SBOLD(i) << ") " << SBOLD(get_name(pDevice)) << " (ID: " << dev_id << ")\n";
220 } catch (ug_runtime_error &e) {
221 LOG(LOG_LEVEL_WARNING) << MOD_NAME << "Device " << i << ": " << e.what() << "\n";
222 }
223 SAFE_RELEASE(pDevice);
224 CoTaskMemFree(pwszID);
225 }
226 } catch (...) {
227 }
228 SAFE_RELEASE(enumerator);
229 SAFE_RELEASE(pEndpoints);
230 com_uninitialize(&com_initialized);
231 col() << " " << SBOLD("loopback") << ") " << SBOLD("computer audio output") << " (ID: loopback)\n";
232}
string wasapi_get_default_device_id(EDataFlow dataFlow, IMMDeviceEnumerator *enumerator)
Definition wasapi.cpp:177
#define SRED(x)
Definition color_out.h:85
#define SBOLD(x)
Definition color_out.h:80

References CLSID_MMDeviceEnumerator, com_initialize(), com_uninitialize(), count, get_name(), IID_IMMDeviceEnumerator, LOG, LOG_LEVEL_WARNING, MOD_NAME, SAFE_RELEASE, SBOLD, SRED, THROW_IF_FAILED, and wasapi_get_default_device_id().

Referenced by audio_cap_wasapi_init(), display_conference_init(), display_decklink_init(), display_sdl2_init(), main(), vidcap_dshow_init(), vidcap_ndi_init(), vidcap_rtsp_init(), vidcap_screen_win_init(), vidcap_testcard_init(), and vidcap_v4l2_init().

Here is the call graph for this function:

◆ wasapi_get_default_device_id()

string wasapi_get_default_device_id ( EDataFlow dataFlow,
IMMDeviceEnumerator * enumerator )

Definition at line 177 of file wasapi.cpp.

177 {
178 IMMDevice *pDevice = nullptr;
179 if (!SUCCEEDED(enumerator->GetDefaultAudioEndpoint(dataFlow, eConsole, &pDevice))) {
180 return {};
181 }
182 LPWSTR pwszID = nullptr;
183 if (!SUCCEEDED(pDevice->GetId(&pwszID))) {
184 SAFE_RELEASE(pDevice);
185 return {};
186 }
187 string ret = win_wstr_to_str(pwszID);
188 SAFE_RELEASE(pDevice);
189
190 return ret;
191}

References SAFE_RELEASE.

Referenced by audio_play_wasapi_help(), and show_help().

Variable Documentation

◆ acap_wasapi_info

const struct audio_capture_info acap_wasapi_info
static
Initial value:
= {
}
static void audio_cap_wasapi_done(void *state)
Definition wasapi.cpp:378
static void audio_cap_wasapi_probe(struct device_info **available_devices, int *dev_count, void(**deleter)(void *))
Definition wasapi.cpp:104
static struct audio_frame * audio_cap_wasapi_read(void *state)
Definition wasapi.cpp:385
static void * audio_cap_wasapi_init(struct module *parent, const char *cfg)
Definition wasapi.cpp:234

Definition at line 432 of file wasapi.cpp.

◆ IDevice_FriendlyName

const GUID IDevice_FriendlyName = { 0xa45c254e, 0xdf1c, 0x4efd, { 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0 } }
static

Definition at line 72 of file wasapi.cpp.

72{ 0xa45c254e, 0xdf1c, 0x4efd, { 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0 } };

◆ IID_IAudioCaptureClient

const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient)

Definition at line 71 of file wasapi.cpp.

Referenced by audio_cap_wasapi_init().

◆ KSDATAFORMAT_SUBTYPE_IEEE_FLOAT

const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT = { STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT }

Definition at line 77 of file wasapi.cpp.

77{ STATIC_KSDATAFORMAT_SUBTYPE_IEEE_FLOAT };

Referenced by audio_cap_wasapi_init().

◆ KSDATAFORMAT_SUBTYPE_PCM

const GUID KSDATAFORMAT_SUBTYPE_PCM = { STATIC_KSDATAFORMAT_SUBTYPE_PCM }

Definition at line 76 of file wasapi.cpp.

76{ STATIC_KSDATAFORMAT_SUBTYPE_PCM };

Referenced by audio_cap_wasapi_init().

◆ PKEY_Device_FriendlyName

const PROPERTYKEY PKEY_Device_FriendlyName = { IDevice_FriendlyName, 14 }
static

Definition at line 73 of file wasapi.cpp.

static const GUID IDevice_FriendlyName
Definition wasapi.cpp:72

Referenced by get_name().