Bug 1027713 - Part 2 - Add a cubeb API to query the name of the audio output device in use. r=kinetik

--HG--
extra : rebase_source : fed39350db9e7c56c003a288e040fd6f901088d2
This commit is contained in:
Paul Adenot 2014-07-24 17:05:23 +02:00
parent 876688d0d4
commit 208b4e5f48
12 changed files with 149 additions and 8 deletions

View File

@ -137,6 +137,8 @@ cubeb_stream_stop
cubeb_stream_get_latency
cubeb_stream_set_volume
cubeb_stream_set_panning
cubeb_stream_get_current_output_device
cubeb_stream_output_device_destroy
th_comment_clear
th_comment_init
th_decode_alloc

View File

@ -129,6 +129,11 @@ typedef struct {
#endif
} cubeb_stream_params;
/** Output device description */
typedef struct {
char * name; /**< The name of the output device */
} cubeb_output_device;
/** Stream states signaled via state_callback. */
typedef enum {
CUBEB_STATE_STARTED, /**< Stream started. */
@ -285,6 +290,27 @@ int cubeb_stream_set_volume(cubeb_stream * stream, float volume);
*/
int cubeb_stream_set_panning(cubeb_stream * stream, float panning);
/**
* Get the current output device for this stream.
* @param stm the stream for which to query the current output device
* @param device a pointer in which the current output device will be stored.
* @return CUBEB_OK in case of success
* @return CUBEB_ERROR_INVALID_PARAMETER if either stm, device or count are
* invalid pointers
*/
int cubeb_stream_get_current_output_device(cubeb_stream * stm,
cubeb_output_device ** const device);
/**
* Destroy a cubeb_output_device structure.
* @param stream the stream passed in cubeb_stream_get_current_output_device
* @param devices the devices to destroy
* @return CUBEB_OK in case of success
* @return CUBEB_ERROR_INVALID_PARAMETER if devices is an invalid pointer
*/
int cubeb_stream_output_device_destroy(cubeb_stream * stream,
cubeb_output_device * devices);
#if defined(__cplusplus)
}
#endif

View File

@ -30,6 +30,11 @@ struct cubeb_ops {
int (* stream_get_latency)(cubeb_stream * stream, uint32_t * latency);
int (* stream_set_volume)(cubeb_stream * stream, float volumes);
int (* stream_set_panning)(cubeb_stream * stream, float panning);
int (* stream_get_current_output_device)(cubeb_stream * stream,
cubeb_output_device ** const device);
int (* stream_output_device_destroy)(cubeb_stream * stream,
cubeb_output_device * device);
};
#endif /* CUBEB_INTERNAL_0eb56756_4e20_4404_a76d_42bf88cd15a5 */

View File

@ -277,3 +277,36 @@ int cubeb_stream_set_panning(cubeb_stream * stream, float panning)
return stream->context->ops->stream_set_panning(stream, panning);
}
int cubeb_stream_get_current_output_device(cubeb_stream * stream,
cubeb_output_device ** const device)
{
if (!stream || !device) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
// If we find an implementation, call the function, it might not be available
// on some platforms.
if (stream->context->ops->stream_get_current_output_device) {
return stream->context->ops->stream_get_current_output_device(stream,
device);
}
return CUBEB_ERROR;
}
int cubeb_stream_output_device_destroy(cubeb_stream * stream,
cubeb_output_device * device)
{
if (!stream || !device) {
return CUBEB_ERROR_INVALID_PARAMETER;
}
// If we find an implementation, call the function, it might not be available
// on some platforms.
if (stream->context->ops->stream_output_device_destroy) {
return stream->context->ops->stream_output_device_destroy(stream, device);
}
return CUBEB_ERROR;
}

View File

@ -1130,5 +1130,7 @@ static struct cubeb_ops const alsa_ops = {
.stream_get_position = alsa_stream_get_position,
.stream_get_latency = alsa_stream_get_latency,
.stream_set_volume = alsa_stream_set_volume,
.stream_set_panning = alsa_stream_set_panning
.stream_set_panning = alsa_stream_set_panning,
.stream_get_current_output_device = NULL,
.stream_output_device_destroy = NULL
};

View File

@ -504,5 +504,7 @@ static struct cubeb_ops const audiotrack_ops = {
.stream_get_position = audiotrack_stream_get_position,
.stream_get_latency = audiotrack_stream_get_latency,
.stream_set_volume = audiotrack_stream_set_volume,
.stream_set_panning = audiotrack_stream_set_panning
.stream_set_panning = audiotrack_stream_set_panning,
.stream_get_current_output_device = NULL,
.stream_output_device_destroy = NULL
};

View File

@ -654,6 +654,65 @@ int audiounit_stream_set_panning(cubeb_stream * stm, float panning)
return CUBEB_OK;
}
int audiounit_stream_get_current_output_device(cubeb_stream * stm,
cubeb_output_device ** const device)
{
OSStatus r;
uint32_t size;
UInt32 data;
char strdata[4];
AudioDeviceID output_device_id;
AudioObjectPropertyAddress datasource_address = {
kAudioDevicePropertyDataSource,
kAudioDevicePropertyScopeOutput,
kAudioObjectPropertyElementMaster
};
*device = NULL;
if (audiounit_get_output_device_id(&output_device_id) != CUBEB_OK) {
return CUBEB_ERROR;
}
size = sizeof(UInt32);
/* This fails with some USB headset, so simply return an empty string. */
r = AudioObjectGetPropertyData(output_device_id, &datasource_address, 0, NULL, &size, &data);
if (r != noErr) {
size = 0;
data = 0;
}
*device = malloc(sizeof(cubeb_output_device));
if (!*device) {
return CUBEB_ERROR;
}
(*device)->name = malloc(size + 1);
if (!(*device)->name) {
return CUBEB_ERROR;
}
// Turn the four chars packed into a uint32 into a string
strdata[0] = (char)(data >> 24);
strdata[1] = (char)(data >> 16);
strdata[2] = (char)(data >> 8);
strdata[3] = (char)(data);
memcpy((*device)->name, strdata, size);
(*device)->name[size] = '\0';
return CUBEB_OK;
}
int audiounit_stream_output_device_destroy(cubeb_stream * stream,
cubeb_output_device * device)
{
free(device->name);
free(device);
return CUBEB_OK;
}
static struct cubeb_ops const audiounit_ops = {
.init = audiounit_init,
.get_backend_id = audiounit_get_backend_id,
@ -668,5 +727,7 @@ static struct cubeb_ops const audiounit_ops = {
.stream_get_position = audiounit_stream_get_position,
.stream_get_latency = audiounit_stream_get_latency,
.stream_set_volume = audiounit_stream_set_volume,
.stream_set_panning = audiounit_stream_set_panning
.stream_set_panning = audiounit_stream_set_panning,
.stream_get_current_output_device = audiounit_stream_get_current_output_device,
.stream_output_device_destroy = audiounit_stream_output_device_destroy
};

View File

@ -787,5 +787,7 @@ static struct cubeb_ops const opensl_ops = {
.stream_get_position = opensl_stream_get_position,
.stream_get_latency = opensl_stream_get_latency,
.stream_set_volume = opensl_stream_set_volume,
.stream_set_panning = opensl_stream_set_panning
.stream_set_panning = opensl_stream_set_panning,
.stream_get_current_output_device = NULL,
.stream_output_device_destroy = NULL
};

View File

@ -748,5 +748,7 @@ static struct cubeb_ops const pulse_ops = {
.stream_get_position = pulse_stream_get_position,
.stream_get_latency = pulse_stream_get_latency,
.stream_set_volume = pulse_stream_set_volume,
.stream_set_panning = pulse_stream_set_panning
.stream_set_panning = pulse_stream_set_panning,
.stream_get_current_output_device = NULL,
.stream_output_device_destroy = NULL
};

View File

@ -361,5 +361,7 @@ static struct cubeb_ops const sndio_ops = {
.stream_get_position = sndio_stream_get_position,
.stream_get_latency = sndio_stream_get_latency,
.stream_set_volume = sndio_stream_set_volume,
.stream_set_panning = sndio_stream_set_panning
.stream_set_panning = sndio_stream_set_panning,
.stream_get_current_output_device = NULL,
.stream_output_device_destroy = NULL
};

View File

@ -939,7 +939,9 @@ cubeb_ops const wasapi_ops = {
/*.stream_get_position =*/ wasapi_stream_get_position,
/*.stream_get_latency =*/ wasapi_stream_get_latency,
/*.stream_set_volume =*/ wasapi_stream_set_volume,
/*.stream_set_panning =*/ wasapi_stream_set_panning
/*.stream_set_panning =*/ wasapi_stream_set_panning,
/*.stream_get_current_output_device =*/ NULL,
/*.stream_output_device_destroy =*/ NULL
};
} // namespace anonymous

View File

@ -714,5 +714,7 @@ static struct cubeb_ops const winmm_ops = {
/*.stream_get_position =*/ winmm_stream_get_position,
/*.stream_get_latency = */ winmm_stream_get_latency,
/*.stream_set_volume =*/ winmm_stream_set_volume,
/*.stream_set_panning =*/ winmm_stream_set_panning
/*.stream_set_panning =*/ winmm_stream_set_panning,
/*.stream_get_current_output_device =*/ NULL,
/*.stream_output_device_destroy =*/ NULL
};