Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
M
miniaudio
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
MyCard
miniaudio
Commits
c4099c86
Commit
c4099c86
authored
Nov 01, 2020
by
David Reid
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
PulseAudio: Add support for detecting default devices.
Public issue
https://github.com/mackron/miniaudio/issues/126
parent
c8444550
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
168 additions
and
81 deletions
+168
-81
miniaudio.h
miniaudio.h
+168
-81
No files found.
miniaudio.h
View file @
c4099c86
...
...
@@ -20719,12 +20719,144 @@ static ma_bool32 ma_context_is_device_id_equal__pulse(ma_context* pContext, cons
}
static void ma_device_sink_info_callback(ma_pa_context* pPulseContext, const ma_pa_sink_info* pInfo, int endOfList, void* pUserData)
{
ma_pa_sink_info* pInfoOut;
if (endOfList > 0) {
return;
}
pInfoOut = (ma_pa_sink_info*)pUserData;
MA_ASSERT(pInfoOut != NULL);
*pInfoOut = *pInfo;
(void)pPulseContext; /* Unused. */
}
static void ma_device_source_info_callback(ma_pa_context* pPulseContext, const ma_pa_source_info* pInfo, int endOfList, void* pUserData)
{
ma_pa_source_info* pInfoOut;
if (endOfList > 0) {
return;
}
pInfoOut = (ma_pa_source_info*)pUserData;
MA_ASSERT(pInfoOut != NULL);
*pInfoOut = *pInfo;
(void)pPulseContext; /* Unused. */
}
static void ma_device_sink_name_callback(ma_pa_context* pPulseContext, const ma_pa_sink_info* pInfo, int endOfList, void* pUserData)
{
ma_device* pDevice;
if (endOfList > 0) {
return;
}
pDevice = (ma_device*)pUserData;
MA_ASSERT(pDevice != NULL);
ma_strncpy_s(pDevice->playback.name, sizeof(pDevice->playback.name), pInfo->description, (size_t)-1);
(void)pPulseContext; /* Unused. */
}
static void ma_device_source_name_callback(ma_pa_context* pPulseContext, const ma_pa_source_info* pInfo, int endOfList, void* pUserData)
{
ma_device* pDevice;
if (endOfList > 0) {
return;
}
pDevice = (ma_device*)pUserData;
MA_ASSERT(pDevice != NULL);
ma_strncpy_s(pDevice->capture.name, sizeof(pDevice->capture.name), pInfo->description, (size_t)-1);
(void)pPulseContext; /* Unused. */
}
static ma_result ma_context_get_sink_info__pulse(ma_context* pContext, const char* pDeviceName, ma_pa_sink_info* pSinkInfo)
{
ma_pa_operation* pOP;
pOP = ((ma_pa_context_get_sink_info_by_name_proc)pContext->pulse.pa_context_get_sink_info_by_name)((ma_pa_context*)pContext->pulse.pPulseContext, pDeviceName, ma_device_sink_info_callback, pSinkInfo);
if (pOP == NULL) {
return MA_ERROR;
}
ma_wait_for_operation_and_unref__pulse(pContext, pOP);
return MA_SUCCESS;
}
static ma_result ma_context_get_source_info__pulse(ma_context* pContext, const char* pDeviceName, ma_pa_source_info* pSourceInfo)
{
ma_pa_operation* pOP;
pOP = ((ma_pa_context_get_source_info_by_name_proc)pContext->pulse.pa_context_get_source_info_by_name)((ma_pa_context*)pContext->pulse.pPulseContext, pDeviceName, ma_device_source_info_callback, pSourceInfo);
if (pOP == NULL) {
return MA_ERROR;
}
ma_wait_for_operation_and_unref__pulse(pContext, pOP);
return MA_SUCCESS;
}
static ma_result ma_context_get_default_device_index__pulse(ma_context* pContext, ma_device_type deviceType, ma_uint32* pIndex)
{
ma_result result;
MA_ASSERT(pContext != NULL);
MA_ASSERT(pIndex != NULL);
if (pIndex != NULL) {
*pIndex = (ma_uint32)-1;
}
if (deviceType == ma_device_type_playback) {
ma_pa_sink_info sinkInfo;
result = ma_context_get_sink_info__pulse(pContext, NULL, &sinkInfo);
if (result != MA_SUCCESS) {
return result;
}
if (pIndex != NULL) {
*pIndex = sinkInfo.index;
}
}
if (deviceType == ma_device_type_capture) {
ma_pa_source_info sourceInfo;
result = ma_context_get_source_info__pulse(pContext, NULL, &sourceInfo);
if (result != MA_SUCCESS) {
return result;
}
if (pIndex != NULL) {
*pIndex = sourceInfo.index;
}
}
return MA_SUCCESS;
}
typedef struct
{
ma_context* pContext;
ma_enum_devices_callback_proc callback;
void* pUserData;
ma_bool32 isTerminated;
ma_uint32 defaultDeviceIndexPlayback;
ma_uint32 defaultDeviceIndexCapture;
} ma_context_enumerate_devices_callback_data__pulse;
static void ma_context_enumerate_devices_sink_callback__pulse(ma_pa_context* pPulseContext, const ma_pa_sink_info* pSinkInfo, int endOfList, void* pUserData)
...
...
@@ -20750,12 +20882,16 @@ static void ma_context_enumerate_devices_sink_callback__pulse(ma_pa_context* pPu
ma_strncpy_s(deviceInfo.name, sizeof(deviceInfo.name), pSinkInfo->description, (size_t)-1);
}
if (pSinkInfo->index == pData->defaultDeviceIndexPlayback) {
deviceInfo._private.isDefault = MA_TRUE;
}
pData->isTerminated = !pData->callback(pData->pContext, ma_device_type_playback, &deviceInfo, pData->pUserData);
(void)pPulseContext; /* Unused. */
}
static void ma_context_enumerate_devices_source_callback__pulse(ma_pa_context* pPulseContext, const ma_pa_source_info* pS
ink
Info, int endOfList, void* pUserData)
static void ma_context_enumerate_devices_source_callback__pulse(ma_pa_context* pPulseContext, const ma_pa_source_info* pS
ource
Info, int endOfList, void* pUserData)
{
ma_context_enumerate_devices_callback_data__pulse* pData = (ma_context_enumerate_devices_callback_data__pulse*)pUserData;
ma_device_info deviceInfo;
...
...
@@ -20769,13 +20905,17 @@ static void ma_context_enumerate_devices_source_callback__pulse(ma_pa_context* p
MA_ZERO_OBJECT(&deviceInfo);
/* The name from PulseAudio is the ID for miniaudio. */
if (pS
ink
Info->name != NULL) {
ma_strncpy_s(deviceInfo.id.pulse, sizeof(deviceInfo.id.pulse), pS
ink
Info->name, (size_t)-1);
if (pS
ource
Info->name != NULL) {
ma_strncpy_s(deviceInfo.id.pulse, sizeof(deviceInfo.id.pulse), pS
ource
Info->name, (size_t)-1);
}
/* The description from PulseAudio is the name for miniaudio. */
if (pSinkInfo->description != NULL) {
ma_strncpy_s(deviceInfo.name, sizeof(deviceInfo.name), pSinkInfo->description, (size_t)-1);
if (pSourceInfo->description != NULL) {
ma_strncpy_s(deviceInfo.name, sizeof(deviceInfo.name), pSourceInfo->description, (size_t)-1);
}
if (pSourceInfo->index == pData->defaultDeviceIndexCapture) {
deviceInfo._private.isDefault = MA_TRUE;
}
pData->isTerminated = !pData->callback(pData->pContext, ma_device_type_capture, &deviceInfo, pData->pUserData);
...
...
@@ -20796,6 +20936,12 @@ static ma_result ma_context_enumerate_devices__pulse(ma_context* pContext, ma_en
callbackData.callback = callback;
callbackData.pUserData = pUserData;
callbackData.isTerminated = MA_FALSE;
callbackData.defaultDeviceIndexPlayback = (ma_uint32)-1;
callbackData.defaultDeviceIndexCapture = (ma_uint32)-1;
/* We need to get the index of the default devices. */
ma_context_get_default_device_index__pulse(pContext, ma_device_type_playback, &callbackData.defaultDeviceIndexPlayback);
ma_context_get_default_device_index__pulse(pContext, ma_device_type_capture, &callbackData.defaultDeviceIndexCapture);
/* Playback. */
if (!callbackData.isTerminated) {
...
...
@@ -20836,6 +20982,7 @@ done:
typedef struct
{
ma_device_info* pDeviceInfo;
ma_uint32 defaultDeviceIndex;
ma_bool32 foundDevice;
} ma_context_get_device_info_callback_data__pulse;
...
...
@@ -20865,6 +21012,10 @@ static void ma_context_get_device_info_sink_callback__pulse(ma_pa_context* pPuls
pData->pDeviceInfo->formatCount = 1;
pData->pDeviceInfo->formats[0] = ma_format_from_pulse(pInfo->sample_spec.format);
if (pData->defaultDeviceIndex == pInfo->index) {
pData->pDeviceInfo->_private.isDefault = MA_TRUE;
}
(void)pPulseContext; /* Unused. */
}
...
...
@@ -20894,6 +21045,10 @@ static void ma_context_get_device_info_source_callback__pulse(ma_pa_context* pPu
pData->pDeviceInfo->formatCount = 1;
pData->pDeviceInfo->formats[0] = ma_format_from_pulse(pInfo->sample_spec.format);
if (pData->defaultDeviceIndex == pInfo->index) {
pData->pDeviceInfo->_private.isDefault = MA_TRUE;
}
(void)pPulseContext; /* Unused. */
}
...
...
@@ -20912,6 +21067,8 @@ static ma_result ma_context_get_device_info__pulse(ma_context* pContext, ma_devi
callbackData.pDeviceInfo = pDeviceInfo;
callbackData.foundDevice = MA_FALSE;
result = ma_context_get_default_device_index__pulse(pContext, deviceType, &callbackData.defaultDeviceIndex);
if (deviceType == ma_device_type_playback) {
pOP = ((ma_pa_context_get_sink_info_by_name_proc)pContext->pulse.pa_context_get_sink_info_by_name)(pContext->pulse.pPulseContext, pDeviceID->pulse, ma_context_get_device_info_sink_callback__pulse, &callbackData);
...
...
@@ -20935,71 +21092,6 @@ done:
return result;
}
static void ma_device_sink_info_callback(ma_pa_context* pPulseContext, const ma_pa_sink_info* pInfo, int endOfList, void* pUserData)
{
ma_pa_sink_info* pInfoOut;
if (endOfList > 0) {
return;
}
pInfoOut = (ma_pa_sink_info*)pUserData;
MA_ASSERT(pInfoOut != NULL);
*pInfoOut = *pInfo;
(void)pPulseContext; /* Unused. */
}
static void ma_device_source_info_callback(ma_pa_context* pPulseContext, const ma_pa_source_info* pInfo, int endOfList, void* pUserData)
{
ma_pa_source_info* pInfoOut;
if (endOfList > 0) {
return;
}
pInfoOut = (ma_pa_source_info*)pUserData;
MA_ASSERT(pInfoOut != NULL);
*pInfoOut = *pInfo;
(void)pPulseContext; /* Unused. */
}
static void ma_device_sink_name_callback(ma_pa_context* pPulseContext, const ma_pa_sink_info* pInfo, int endOfList, void* pUserData)
{
ma_device* pDevice;
if (endOfList > 0) {
return;
}
pDevice = (ma_device*)pUserData;
MA_ASSERT(pDevice != NULL);
ma_strncpy_s(pDevice->playback.name, sizeof(pDevice->playback.name), pInfo->description, (size_t)-1);
(void)pPulseContext; /* Unused. */
}
static void ma_device_source_name_callback(ma_pa_context* pPulseContext, const ma_pa_source_info* pInfo, int endOfList, void* pUserData)
{
ma_device* pDevice;
if (endOfList > 0) {
return;
}
pDevice = (ma_device*)pUserData;
MA_ASSERT(pDevice != NULL);
ma_strncpy_s(pDevice->capture.name, sizeof(pDevice->capture.name), pInfo->description, (size_t)-1);
(void)pPulseContext; /* Unused. */
}
static void ma_device_uninit__pulse(ma_device* pDevice)
{
ma_context* pContext;
...
...
@@ -21214,7 +21306,6 @@ static ma_result ma_device_init__pulse(ma_context* pContext, const ma_device_con
ma_uint32 periodSizeInMilliseconds;
ma_pa_sink_info sinkInfo;
ma_pa_source_info sourceInfo;
ma_pa_operation* pOP = NULL;
ma_pa_sample_spec ss;
ma_pa_channel_map cmap;
ma_pa_buffer_attr attr;
...
...
@@ -21250,11 +21341,9 @@ static ma_result ma_device_init__pulse(ma_context* pContext, const ma_device_con
}
if (pConfig->deviceType == ma_device_type_capture || pConfig->deviceType == ma_device_type_duplex) {
pOP = ((ma_pa_context_get_source_info_by_name_proc)pContext->pulse.pa_context_get_source_info_by_name)((ma_pa_context*)pContext->pulse.pPulseContext, devCapture, ma_device_source_info_callback, &sourceInfo);
if (pOP != NULL) {
ma_wait_for_operation_and_unref__pulse(pContext, pOP);
} else {
result = ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to retrieve source info for capture device.", ma_result_from_pulse(error));
result = ma_context_get_source_info__pulse(pContext, devCapture, &sourceInfo);
if (result != MA_SUCCESS) {
ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to retrieve source info for capture device.", result);
goto on_error0;
}
...
...
@@ -21342,11 +21431,9 @@ static ma_result ma_device_init__pulse(ma_context* pContext, const ma_device_con
}
if (pConfig->deviceType == ma_device_type_playback || pConfig->deviceType == ma_device_type_duplex) {
pOP = ((ma_pa_context_get_sink_info_by_name_proc)pContext->pulse.pa_context_get_sink_info_by_name)((ma_pa_context*)pContext->pulse.pPulseContext, devPlayback, ma_device_sink_info_callback, &sinkInfo);
if (pOP != NULL) {
ma_wait_for_operation_and_unref__pulse(pContext, pOP);
} else {
result = ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to retrieve sink info for playback device.", ma_result_from_pulse(error));
result = ma_context_get_sink_info__pulse(pContext, devPlayback, &sinkInfo);
if (result != MA_SUCCESS) {
ma_post_error(pDevice, MA_LOG_LEVEL_ERROR, "[PulseAudio] Failed to retrieve sink info for playback device.", result);
goto on_error2;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment