зеркало из https://github.com/mozilla/cubeb.git
Add enumerate_devices API
No backends support this yet.
This commit is contained in:
Родитель
8d27b7e03b
Коммит
65fee6d192
|
@ -45,6 +45,8 @@ test/test_sanity
|
|||
test/test_sanity.exe
|
||||
test/test_tone
|
||||
test/test_tone.exe
|
||||
test/test_devices
|
||||
test/test_devices.exe
|
||||
include/cubeb/cubeb-stdint.h
|
||||
test-suite.log
|
||||
test/test_sanity.log
|
||||
|
|
15
Makefile.am
15
Makefile.am
|
@ -64,17 +64,23 @@ src_libcubeb_la_SOURCES += src/cubeb_resampler.cpp src/speex/resample.c
|
|||
endif
|
||||
|
||||
EXTRA_src_libcubeb_la_SOURCES = \
|
||||
src/cubeb.c \
|
||||
src/cubeb.c \
|
||||
src/cubeb_jack.cpp \
|
||||
src/cubeb_alsa.c src/cubeb_pulse.c \
|
||||
src/cubeb_audiounit.c src/cubeb_audioqueue.c \
|
||||
src/cubeb_sndio.c src/cubeb_directsound.cpp \
|
||||
src/cubeb_winmm.c src/cubeb_wasapi.cpp src/speex/resample.c \
|
||||
src/cubeb_opensl.c src/cubeb_audiotrack.c
|
||||
src/cubeb_opensl.c src/cubeb_audiotrack.c \
|
||||
$(NULL)
|
||||
|
||||
src_libcubeb_la_LDFLAGS = -export-symbols-regex '^cubeb_' $(platform_lib) -no-undefined
|
||||
|
||||
check_PROGRAMS = test/test_sanity test/test_tone test/test_audio test/test_latency
|
||||
check_PROGRAMS = test/test_sanity \
|
||||
test/test_tone \
|
||||
test/test_audio \
|
||||
test/test_latency \
|
||||
test/test_devices \
|
||||
$(NULL)
|
||||
|
||||
test_test_sanity_SOURCES = test/test_sanity.cpp
|
||||
test_test_sanity_LDADD = -lm src/libcubeb.la $(platform_lib)
|
||||
|
@ -88,6 +94,9 @@ test_test_audio_LDADD = -lm src/libcubeb.la $(platform_lib)
|
|||
test_test_latency_SOURCES = test/test_latency.cpp
|
||||
test_test_latency_LDADD = -lm src/libcubeb.la $(platform_lib)
|
||||
|
||||
test_test_devices_SOURCES = test/test_devices.cpp
|
||||
test_test_devices_LDADD = -lm src/libcubeb.la $(platform_lib)
|
||||
|
||||
TESTS = test/test_sanity
|
||||
|
||||
DISTCLEANFILES = include/cubeb/cubeb-stdint.h
|
||||
|
|
|
@ -152,6 +152,74 @@ enum {
|
|||
CUBEB_ERROR_NOT_SUPPORTED = -4 /**< Optional function not implemented in current backend. */
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
CUBEB_DEVICE_TYPE_UNKNOWN,
|
||||
CUBEB_DEVICE_TYPE_INPUT,
|
||||
CUBEB_DEVICE_TYPE_OUTPUT
|
||||
} cubeb_device_type;
|
||||
|
||||
typedef enum {
|
||||
CUBEB_DEVICE_STATE_DISABLED,
|
||||
CUBEB_DEVICE_STATE_UNPLUGGED,
|
||||
CUBEB_DEVICE_STATE_ENABLED
|
||||
} cubeb_device_state;
|
||||
|
||||
typedef void * cubeb_devid;
|
||||
|
||||
typedef enum {
|
||||
CUBEB_DEVICE_FMT_S16LE = 0x0010,
|
||||
CUBEB_DEVICE_FMT_S16BE = 0x0020,
|
||||
CUBEB_DEVICE_FMT_F32LE = 0x1000,
|
||||
CUBEB_DEVICE_FMT_F32BE = 0x2000
|
||||
} cubeb_device_fmt;
|
||||
|
||||
#if defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__)
|
||||
#define CUBEB_DEVICE_FMT_S16NE CUBEB_DEVICE_FMT_S16BE
|
||||
#define CUBEB_DEVICE_FMT_F32NE CUBEB_DEVICE_FMT_F32BE
|
||||
#else
|
||||
#define CUBEB_DEVICE_FMT_S16NE CUBEB_DEVICE_FMT_S16LE
|
||||
#define CUBEB_DEVICE_FMT_F32NE CUBEB_DEVICE_FMT_F32LE
|
||||
#endif
|
||||
#define CUBEB_DEVICE_FMT_S16_MASK (CUBEB_DEVICE_FMT_S16LE | CUBEB_DEVICE_FMT_S16BE)
|
||||
#define CUBEB_DEVICE_FMT_F32_MASK (CUBEB_DEVICE_FMT_F32LE | CUBEB_DEVICE_FMT_F32BE)
|
||||
#define CUBEB_DEVICE_FMT_ALL (CUBEB_DEVICE_FMT_S16_MASK | CUBEB_DEVICE_FMT_F32_MASK)
|
||||
|
||||
typedef enum {
|
||||
CUBEB_DEVICE_PREF_NONE = 0x00,
|
||||
CUBEB_DEVICE_PREF_MULTIMEDIA = 0x01,
|
||||
CUBEB_DEVICE_PREF_VOICE = 0x02,
|
||||
CUBEB_DEVICE_PREF_NOTIFICATION = 0x04,
|
||||
CUBEB_DEVICE_PREF_ALL = 0x0F
|
||||
} cubeb_device_pref;
|
||||
|
||||
typedef struct {
|
||||
cubeb_devid device_id; /* Device identifier */
|
||||
char * friendly_name; /* Friendly device name which might be presented in a UI */
|
||||
char * group_id; /* Two devices have the same group identifier if they belong to the same physical device; for example a headset and microphone. */
|
||||
char * vendor_name; /* Optional vendor name, may be NULL */
|
||||
|
||||
cubeb_device_type type; /* Type of device (Input/Output) */
|
||||
cubeb_device_state state; /* State of device disabled/enabled/unplugged */
|
||||
cubeb_device_pref preferred;/* Preferred device */
|
||||
|
||||
cubeb_device_fmt format; /* Sample format supported */
|
||||
cubeb_device_fmt default_format;
|
||||
unsigned int max_channels; /* Channels */
|
||||
unsigned int default_rate; /* Default/Preferred sample rate */
|
||||
unsigned int max_rate; /* Maximum sample rate supported */
|
||||
unsigned int min_rate; /* Minimum sample rate supported */
|
||||
|
||||
unsigned int latency_lo_ms; /* Lowest possible latency in milliseconds */
|
||||
unsigned int latency_hi_ms; /* Higest possible latency in milliseconds */
|
||||
} cubeb_device_info;
|
||||
|
||||
typedef struct _cubeb_device_entry cubeb_device_entry;
|
||||
struct _cubeb_device_entry {
|
||||
cubeb_device_info device;
|
||||
cubeb_device_entry * next;
|
||||
};
|
||||
typedef struct _cubeb_device_entry cubeb_device_list;
|
||||
|
||||
/** User supplied data callback.
|
||||
@param stream
|
||||
@param user_ptr
|
||||
|
@ -179,6 +247,12 @@ typedef void (* cubeb_state_callback)(cubeb_stream * stream,
|
|||
* @param user */
|
||||
typedef void (* cubeb_device_changed_callback)(void * user_ptr);
|
||||
|
||||
/**
|
||||
* User supplied callback called when the underlying device list changed.
|
||||
* @param context
|
||||
* @param user_ptr */
|
||||
typedef void (* cubeb_device_list_changed_callback)(cubeb * context, void * user_ptr);
|
||||
|
||||
/** Initialize an application context. This will perform any library or
|
||||
application scoped initialization.
|
||||
@param context
|
||||
|
@ -337,6 +411,52 @@ int cubeb_stream_device_destroy(cubeb_stream * stream,
|
|||
int cubeb_stream_register_device_changed_callback(cubeb_stream * stream,
|
||||
cubeb_device_changed_callback device_changed_callback);
|
||||
|
||||
/** Returns enumerated devices.
|
||||
@param context
|
||||
@param devtype device type to include
|
||||
@param list output list. Must be destroyed with cubeb_device_list_destroy
|
||||
@param count optional parameter which will return number of devices in list
|
||||
@retval CUBEB_OK in case of success
|
||||
@retval CUBEB_ERROR_INVALID_PARAMETER if list is an invalid pointer
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
int cubeb_enumerate_devices(cubeb * context,
|
||||
cubeb_device_type devtype,
|
||||
cubeb_device_list ** list,
|
||||
uint32_t * count);
|
||||
|
||||
/** Destroy a cubeb_device_list list.
|
||||
The whole list is destroyed.
|
||||
@param context
|
||||
@param list list to destroy
|
||||
@retval CUBEB_OK */
|
||||
int cubeb_device_list_destroy(cubeb * context, cubeb_device_list * list);
|
||||
|
||||
/** Retrieves the device id as string.
|
||||
The string must be free()ed by the caller.
|
||||
@param context
|
||||
@param devid device id
|
||||
@param str pointer to string
|
||||
@retval CUBEB_OK */
|
||||
int cubeb_device_id_to_str(cubeb * context, const cubeb_devid devid, char ** str);
|
||||
|
||||
/** Registers a callback which is called when device list changes..
|
||||
@param context
|
||||
@param callback
|
||||
@param user_ptr
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
int cubeb_register_device_list_changed(cubeb * context,
|
||||
cubeb_device_list_changed_callback callback,
|
||||
void * user_ptr);
|
||||
|
||||
/** Removes a already registered callback/user_ptr pair.
|
||||
@param context
|
||||
@param callback
|
||||
@param user_ptr
|
||||
@retval CUBEB_ERROR_NOT_SUPPORTED */
|
||||
int cubeb_deregister_device_list_changed(cubeb * context,
|
||||
cubeb_device_list_changed_callback callback,
|
||||
void * user_ptr);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#define CUBEB_INTERNAL_0eb56756_4e20_4404_a76d_42bf88cd15a5
|
||||
|
||||
#include "cubeb/cubeb.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
struct cubeb_ops {
|
||||
int (* init)(cubeb ** context, char const * context_name);
|
||||
|
@ -17,6 +19,10 @@ struct cubeb_ops {
|
|||
cubeb_stream_params params,
|
||||
uint32_t * latency_ms);
|
||||
int (* get_preferred_sample_rate)(cubeb * context, uint32_t * rate);
|
||||
int (* enumerate_devices)(cubeb * context, cubeb_device_type type,
|
||||
cubeb_device_list ** devices, uint32_t * count);
|
||||
int (* device_info_destroy)(cubeb * context, cubeb_device_info * info);
|
||||
int (* device_id_to_str)(cubeb * context, const cubeb_devid devid, char ** str);
|
||||
void (* destroy)(cubeb * context);
|
||||
int (* stream_init)(cubeb * context, cubeb_stream ** stream, char const * stream_name,
|
||||
cubeb_stream_params stream_params, unsigned int latency,
|
||||
|
@ -36,7 +42,6 @@ struct cubeb_ops {
|
|||
cubeb_device * device);
|
||||
int (* stream_register_device_changed_callback)(cubeb_stream * stream,
|
||||
cubeb_device_changed_callback device_changed_callback);
|
||||
|
||||
};
|
||||
|
||||
#define XASSERT(expr) do { \
|
||||
|
@ -47,4 +52,50 @@ struct cubeb_ops {
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
static inline int
|
||||
cubeb_device_info_destroy (cubeb * context, cubeb_device_info * info)
|
||||
{
|
||||
free(info->device_id);
|
||||
free(info->friendly_name);
|
||||
free(info->group_id);
|
||||
free(info->vendor_name);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static inline int
|
||||
cubeb_device_info_destroy_no_devid (cubeb * context, cubeb_device_info * info)
|
||||
{
|
||||
free(info->friendly_name);
|
||||
free(info->group_id);
|
||||
free(info->vendor_name);
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static inline int
|
||||
cubeb_device_id_str (cubeb * context, cubeb_devid devid, char ** str)
|
||||
{
|
||||
size_t size = strlen((const char *)devid);
|
||||
*str = (char *)malloc(size + 1);
|
||||
strncpy(*str, (const char *)devid, size);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static inline int
|
||||
cubeb_device_id_idx (cubeb * context, cubeb_devid devid, char ** str)
|
||||
{
|
||||
*str = (char *)malloc(sizeof(char)*16);
|
||||
snprintf(*str, 16, "%u", (unsigned int)(size_t)devid);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static inline int
|
||||
cubeb_device_id_ptr (cubeb * context, cubeb_devid devid, char ** str)
|
||||
{
|
||||
*str = (char *)malloc(sizeof(char)*16);
|
||||
snprintf(*str, 16, "%p", (const char *)devid);
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
#endif /* CUBEB_INTERNAL_0eb56756_4e20_4404_a76d_42bf88cd15a5 */
|
||||
|
|
56
src/cubeb.c
56
src/cubeb.c
|
@ -7,6 +7,7 @@
|
|||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(HAVE_CONFIG_H)
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
@ -362,3 +363,58 @@ int cubeb_stream_register_device_changed_callback(cubeb_stream * stream,
|
|||
|
||||
return stream->context->ops->stream_register_device_changed_callback(stream, device_changed_callback);
|
||||
}
|
||||
|
||||
int cubeb_enumerate_devices(cubeb * context,
|
||||
cubeb_device_type devtype,
|
||||
cubeb_device_list ** list,
|
||||
uint32_t * count)
|
||||
{
|
||||
if ((devtype & (CUBEB_DEVICE_TYPE_INPUT | CUBEB_DEVICE_TYPE_OUTPUT)) == 0)
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
if (list == NULL)
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
if (!context->ops->enumerate_devices)
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
|
||||
return context->ops->enumerate_devices(context, devtype, list, count);
|
||||
}
|
||||
|
||||
int cubeb_device_list_destroy(cubeb * context, cubeb_device_list * list)
|
||||
{
|
||||
cubeb_device_list * cur;
|
||||
|
||||
if (context == NULL)
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
|
||||
while (list != NULL) {
|
||||
cur = list;
|
||||
list = list->next;
|
||||
context->ops->device_info_destroy(context, &cur->device);
|
||||
free(cur);
|
||||
}
|
||||
|
||||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
int cubeb_device_id_to_str(cubeb * context, const cubeb_devid devid, char ** str)
|
||||
{
|
||||
if (context == NULL || str == NULL)
|
||||
return CUBEB_ERROR_INVALID_PARAMETER;
|
||||
|
||||
return context->ops->device_id_to_str(context, devid, str);
|
||||
}
|
||||
|
||||
int cubeb_register_device_list_changed(cubeb * context,
|
||||
cubeb_device_list_changed_callback callback,
|
||||
void * user_ptr)
|
||||
{
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int cubeb_deregister_device_list_changed(cubeb * context,
|
||||
cubeb_device_list_changed_callback callback,
|
||||
void * user_ptr)
|
||||
{
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -1116,6 +1116,9 @@ static struct cubeb_ops const alsa_ops = {
|
|||
.get_max_channel_count = alsa_get_max_channel_count,
|
||||
.get_min_latency = alsa_get_min_latency,
|
||||
.get_preferred_sample_rate = alsa_get_preferred_sample_rate,
|
||||
.enumerate_devices = NULL,
|
||||
.device_info_destroy = NULL,
|
||||
.device_id_to_str = NULL,
|
||||
.destroy = alsa_destroy,
|
||||
.stream_init = alsa_stream_init,
|
||||
.stream_destroy = alsa_stream_destroy,
|
||||
|
|
|
@ -489,6 +489,9 @@ static struct cubeb_ops const audiotrack_ops = {
|
|||
.get_max_channel_count = audiotrack_get_max_channel_count,
|
||||
.get_min_latency = audiotrack_get_min_latency,
|
||||
.get_preferred_sample_rate = audiotrack_get_preferred_sample_rate,
|
||||
.enumerate_devices = NULL,
|
||||
.device_info_destroy = NULL,
|
||||
.device_id_to_str = NULL,
|
||||
.destroy = audiotrack_destroy,
|
||||
.stream_init = audiotrack_stream_init,
|
||||
.stream_destroy = audiotrack_stream_destroy,
|
||||
|
|
|
@ -1005,6 +1005,9 @@ static struct cubeb_ops const audiounit_ops = {
|
|||
.get_max_channel_count = audiounit_get_max_channel_count,
|
||||
.get_min_latency = audiounit_get_min_latency,
|
||||
.get_preferred_sample_rate = audiounit_get_preferred_sample_rate,
|
||||
.enumerate_devices = NULL,
|
||||
.device_info_destroy = NULL,
|
||||
.device_id_to_str = NULL,
|
||||
.destroy = audiounit_destroy,
|
||||
.stream_init = audiounit_stream_init,
|
||||
.stream_destroy = audiounit_stream_destroy,
|
||||
|
|
|
@ -132,6 +132,9 @@ static struct cubeb_ops const cbjack_ops = {
|
|||
.get_max_channel_count = cbjack_get_max_channel_count,
|
||||
.get_min_latency = cbjack_get_min_latency,
|
||||
.get_preferred_sample_rate = cbjack_get_preferred_sample_rate,
|
||||
.enumerate_devices = NULL,
|
||||
.device_info_destroy = NULL,
|
||||
.device_id_to_str = NULL,
|
||||
.destroy = cbjack_destroy,
|
||||
.stream_init = cbjack_stream_init,
|
||||
.stream_destroy = cbjack_stream_destroy,
|
||||
|
|
|
@ -270,6 +270,21 @@ kai_get_preferred_sample_rate(cubeb * ctx, uint32_t * rate)
|
|||
return CUBEB_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
kai_enumerate_devices(cubeb * context, cubeb_device_type type,
|
||||
cubeb_device_list ** devices, uint32_t * count)
|
||||
{
|
||||
(void)context;
|
||||
(void)type;
|
||||
|
||||
*devices = NULL;
|
||||
if (count != NULL)
|
||||
*count = 0;
|
||||
|
||||
return CUBEB_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
kai_stream_start(cubeb_stream * stm)
|
||||
{
|
||||
|
@ -329,6 +344,9 @@ static struct cubeb_ops const kai_ops = {
|
|||
/*.get_max_channel_count=*/ kai_get_max_channel_count,
|
||||
/*.get_min_latency=*/ kai_get_min_latency,
|
||||
/*.get_preferred_sample_rate =*/ kai_get_preferred_sample_rate,
|
||||
/*.enumerate_devices =*/ kai_enumerate_devices,
|
||||
/*.device_info_destroy =*/ cubeb_device_info_destroy_no_devid,
|
||||
/*.device_id_to_str =*/ cubeb_device_id_idx,
|
||||
/*.destroy =*/ kai_destroy,
|
||||
/*.stream_init =*/ kai_stream_init,
|
||||
/*.stream_destroy =*/ kai_stream_destroy,
|
||||
|
|
|
@ -814,6 +814,9 @@ static struct cubeb_ops const opensl_ops = {
|
|||
.get_max_channel_count = opensl_get_max_channel_count,
|
||||
.get_min_latency = opensl_get_min_latency,
|
||||
.get_preferred_sample_rate = opensl_get_preferred_sample_rate,
|
||||
.enumerate_devices = NULL,
|
||||
.device_info_destroy = NULL,
|
||||
.device_id_to_str = NULL,
|
||||
.destroy = opensl_destroy,
|
||||
.stream_init = opensl_stream_init,
|
||||
.stream_destroy = opensl_stream_destroy,
|
||||
|
|
|
@ -730,6 +730,9 @@ static struct cubeb_ops const pulse_ops = {
|
|||
.get_max_channel_count = pulse_get_max_channel_count,
|
||||
.get_min_latency = pulse_get_min_latency,
|
||||
.get_preferred_sample_rate = pulse_get_preferred_sample_rate,
|
||||
.enumerate_devices = NULL,
|
||||
.device_info_destroy = NULL,
|
||||
.device_id_to_str = NULL,
|
||||
.destroy = pulse_destroy,
|
||||
.stream_init = pulse_stream_init,
|
||||
.stream_destroy = pulse_stream_destroy,
|
||||
|
|
|
@ -356,6 +356,9 @@ static struct cubeb_ops const sndio_ops = {
|
|||
.get_max_channel_count = sndio_get_max_channel_count,
|
||||
.get_min_latency = sndio_get_min_latency,
|
||||
.get_preferred_sample_rate = sndio_get_preferred_sample_rate,
|
||||
.enumerate_devices = NULL,
|
||||
.device_info_destroy = NULL,
|
||||
.device_id_to_str = NULL,
|
||||
.destroy = sndio_destroy,
|
||||
.stream_init = sndio_stream_init,
|
||||
.stream_destroy = sndio_stream_destroy,
|
||||
|
|
|
@ -1431,6 +1431,9 @@ cubeb_ops const wasapi_ops = {
|
|||
/*.get_max_channel_count =*/ wasapi_get_max_channel_count,
|
||||
/*.get_min_latency =*/ wasapi_get_min_latency,
|
||||
/*.get_preferred_sample_rate =*/ wasapi_get_preferred_sample_rate,
|
||||
/*.enumerate_devices =*/ NULL,
|
||||
/*.device_info_destroy */= NULL,
|
||||
/*.device_id_to_str */= NULL,
|
||||
/*.destroy =*/ wasapi_destroy,
|
||||
/*.stream_init =*/ wasapi_stream_init,
|
||||
/*.stream_destroy =*/ wasapi_stream_destroy,
|
||||
|
|
|
@ -677,6 +677,9 @@ static struct cubeb_ops const winmm_ops = {
|
|||
/*.get_max_channel_count=*/ winmm_get_max_channel_count,
|
||||
/*.get_min_latency=*/ winmm_get_min_latency,
|
||||
/*.get_preferred_sample_rate =*/ winmm_get_preferred_sample_rate,
|
||||
/*.enumerate_devices =*/ NULL,
|
||||
/*.device_info_destroy */= NULL,
|
||||
/*.device_id_to_str */= NULL,
|
||||
/*.destroy =*/ winmm_destroy,
|
||||
/*.stream_init =*/ winmm_stream_init,
|
||||
/*.stream_destroy =*/ winmm_stream_destroy,
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright © 2015 Haakon Sporsheim <haakon.sporsheim@telenordigital.com>
|
||||
*
|
||||
* This program is made available under an ISC-style license. See the
|
||||
* accompanying file LICENSE for details.
|
||||
*/
|
||||
|
||||
/* libcubeb enumerate device test/example.
|
||||
* Prints out a list of devices enumerated. */
|
||||
#ifdef NDEBUG
|
||||
#undef NDEBUG
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cubeb/cubeb.h"
|
||||
|
||||
|
||||
static void
|
||||
print_device_list(cubeb * context, cubeb_device_list * devices, FILE * f)
|
||||
{
|
||||
char * devid = NULL, devfmts[64] = "";
|
||||
const char * devtype, * devstate, * devdeffmt;
|
||||
|
||||
if (devices == NULL)
|
||||
return;
|
||||
|
||||
cubeb_device_id_to_str(context, devices->device.device_id, &devid);
|
||||
|
||||
switch (devices->device.type) {
|
||||
case CUBEB_DEVICE_TYPE_INPUT:
|
||||
devtype = "input";
|
||||
break;
|
||||
case CUBEB_DEVICE_TYPE_OUTPUT:
|
||||
devtype = "output";
|
||||
break;
|
||||
case CUBEB_DEVICE_TYPE_UNKNOWN:
|
||||
default:
|
||||
devtype = "unknown?";
|
||||
break;
|
||||
};
|
||||
|
||||
switch (devices->device.state) {
|
||||
case CUBEB_DEVICE_STATE_DISABLED:
|
||||
devstate = "disabled";
|
||||
break;
|
||||
case CUBEB_DEVICE_STATE_UNPLUGGED:
|
||||
devstate = "unplugged";
|
||||
break;
|
||||
case CUBEB_DEVICE_STATE_ENABLED:
|
||||
devstate = "enabled";
|
||||
break;
|
||||
default:
|
||||
devstate = "unknown?";
|
||||
break;
|
||||
};
|
||||
|
||||
switch (devices->device.default_format) {
|
||||
case CUBEB_DEVICE_FMT_S16LE:
|
||||
devdeffmt = "S16LE";
|
||||
break;
|
||||
case CUBEB_DEVICE_FMT_S16BE:
|
||||
devdeffmt = "S16BE";
|
||||
break;
|
||||
case CUBEB_DEVICE_FMT_F32LE:
|
||||
devdeffmt = "F32LE";
|
||||
break;
|
||||
case CUBEB_DEVICE_FMT_F32BE:
|
||||
devdeffmt = "F32BE";
|
||||
break;
|
||||
default:
|
||||
devdeffmt = "unknown?";
|
||||
break;
|
||||
};
|
||||
|
||||
if (devices->device.format & CUBEB_DEVICE_FMT_S16LE)
|
||||
strcat(devfmts, " S16LE");
|
||||
if (devices->device.format & CUBEB_DEVICE_FMT_S16BE)
|
||||
strcat(devfmts, " S16BE");
|
||||
if (devices->device.format & CUBEB_DEVICE_FMT_F32LE)
|
||||
strcat(devfmts, " F32LE");
|
||||
if (devices->device.format & CUBEB_DEVICE_FMT_F32BE)
|
||||
strcat(devfmts, " F32BE");
|
||||
|
||||
fprintf(f,
|
||||
"dev: \"%s\"%s\n"
|
||||
"\tName: \"%s\"\n"
|
||||
"\tGroup: \"%s\"\n"
|
||||
"\tVendor: \"%s\"\n"
|
||||
"\tType: %s\n"
|
||||
"\tState: %s\n"
|
||||
"\tCh: %u\n"
|
||||
"\tFormat: %s (0x%x) (default: %s)\n"
|
||||
"\tRate: %u - %u (default: %u)\n"
|
||||
"\tLatency: lo %ums, hi %ums\n",
|
||||
devid, devices->device.preferred ? " (PREFERRED)" : "",
|
||||
devices->device.friendly_name, devices->device.group_id,
|
||||
devices->device.vendor_name, devtype, devstate,
|
||||
devices->device.max_channels,
|
||||
(devfmts[0] == ' ') ? &devfmts[1] : devfmts,
|
||||
(unsigned int)devices->device.format, devdeffmt,
|
||||
devices->device.min_rate, devices->device.max_rate,
|
||||
devices->device.default_rate,
|
||||
devices->device.latency_lo_ms, devices->device.latency_hi_ms);
|
||||
|
||||
free(devid);
|
||||
|
||||
print_device_list(context, devices->next, f);
|
||||
}
|
||||
|
||||
static int
|
||||
run_enumerate_devices(void)
|
||||
{
|
||||
int r = CUBEB_OK;
|
||||
cubeb * ctx = NULL;
|
||||
cubeb_device_list * devices = NULL;
|
||||
uint32_t count = 0;
|
||||
|
||||
r = cubeb_init(&ctx, "Cubeb audio test");
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error initializing cubeb library\n");
|
||||
return r;
|
||||
}
|
||||
|
||||
fprintf(stdout, "Enumerating input devices for backend %s\n",
|
||||
cubeb_get_backend_id (ctx));
|
||||
|
||||
r = cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_INPUT, &devices, &count);
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error enumerating devices %d\n", r);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fprintf(stdout, "Found %u input devices\n", count);
|
||||
print_device_list (ctx, devices, stdout);
|
||||
cubeb_device_list_destroy (ctx, devices);
|
||||
|
||||
fprintf(stdout, "Enumerating output devices for backend %s\n",
|
||||
cubeb_get_backend_id (ctx));
|
||||
|
||||
r = cubeb_enumerate_devices(ctx, CUBEB_DEVICE_TYPE_OUTPUT, &devices, &count);
|
||||
if (r != CUBEB_OK) {
|
||||
fprintf(stderr, "Error enumerating devices %d\n", r);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fprintf(stdout, "Found %u output devices\n", count);
|
||||
print_device_list (ctx, devices, stdout);
|
||||
cubeb_device_list_destroy (ctx, devices);
|
||||
|
||||
cleanup:
|
||||
cubeb_destroy(ctx);
|
||||
return r;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = run_enumerate_devices();
|
||||
|
||||
return ret;
|
||||
}
|
Загрузка…
Ссылка в новой задаче