From 38f712d96d12b75deea192846f1969f28fb73f07 Mon Sep 17 00:00:00 2001 From: wm4 Date: Sun, 21 Jul 2013 21:35:29 +0200 Subject: ao_portaudio: use new option API This basically serves as example. All other AOs should be ported as well. --- audio/out/ao_portaudio.c | 67 +++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/audio/out/ao_portaudio.c b/audio/out/ao_portaudio.c index d51d01ed9b..d695a16550 100644 --- a/audio/out/ao_portaudio.c +++ b/audio/out/ao_portaudio.c @@ -26,7 +26,7 @@ #include #include "config.h" -#include "core/subopt-helper.h" +#include "core/m_option.h" #include "audio/format.h" #include "core/mp_msg.h" #include "core/mp_ring.h" @@ -44,6 +44,9 @@ struct priv { // 0 is N/A (0 is not a valid PA time value) int play_silence; // play this many bytes of silence, before real data bool play_remaining;// play what's left in the buffer, then stop stream + + // Options + char *cfg_device; }; struct format_map { @@ -62,18 +65,6 @@ static const struct format_map format_maps[] = { {AF_FORMAT_UNKNOWN, 0} }; -static void print_help(void) -{ - mp_msg(MSGT_AO, MSGL_FATAL, - "\n-ao portaudio commandline help:\n" - "Example: mpv -ao portaudio:device=subdevice\n" - "\nOptions:\n" - " device=subdevice\n" - " Audio device PortAudio should use. Devices can be listed\n" - " with -ao portaudio:device=help\n" - " The subdevice can be passed as index, or as complete name.\n"); -} - static bool check_pa_ret(int ret) { if (ret < 0) { @@ -102,12 +93,14 @@ static int to_int(const char *s, int return_on_error) return (s[0] && !endptr[0]) ? res : return_on_error; } -static int find_device(struct ao *ao, const char *name) +static int find_device(const char *name) { + int found = paNoDevice; + if (!name) + return found; int help = strcmp(name, "help") == 0; int count = Pa_GetDeviceCount(); check_pa_ret(count); - int found = paNoDevice; int index = to_int(name, -1); if (help) mp_msg(MSGT_AO, MSGL_INFO, "PortAudio devices:\n"); @@ -128,11 +121,27 @@ static int find_device(struct ao *ao, const char *name) } } if (found == paNoDevice && !help) - mp_msg(MSGT_AO, MSGL_FATAL, "[portaudio] Device '%s' not found!\n", + mp_msg(MSGT_AO, MSGL_WARN, "[portaudio] Device '%s' not found!\n", name); return found; } +static int validate_device_opt(const m_option_t *opt, struct bstr name, + struct bstr param) +{ + // Note: we do not check whether the device actually exist, because this + // might break elaborate configs with several AOs trying several + // devices. We do it merely for making "help" special. + if (bstr_equals0(param, "help")) { + if (!check_pa_ret(Pa_Initialize())) + return M_OPT_EXIT; + find_device("help"); + Pa_Terminate(); + return M_OPT_EXIT - 1; + } + return 0; +} + static void fill_silence(unsigned char *ptr, int len) { memset(ptr, 0, len); @@ -207,27 +216,16 @@ static void uninit(struct ao *ao, bool cut_audio) static int init(struct ao *ao, char *params) { - struct priv *priv = talloc_zero(ao, struct priv); - ao->priv = priv; + struct priv *priv = ao->priv; if (!check_pa_ret(Pa_Initialize())) return -1; pthread_mutex_init(&priv->ring_mutex, NULL); - char *device = NULL; - const opt_t subopts[] = { - {"device", OPT_ARG_MSTRZ, &device, NULL}, - {NULL} - }; - if (subopt_parse(params, subopts) != 0) { - print_help(); - goto error_exit; - } - int pa_device = Pa_GetDefaultOutputDevice(); - if (device) - pa_device = find_device(ao, device); + if (priv->cfg_device && priv->cfg_device[0]) + pa_device = find_device(priv->cfg_device); if (pa_device == paNoDevice) goto error_exit; @@ -274,12 +272,10 @@ static int init(struct ao *ao, char *params) priv->ring = mp_ring_new(priv, seconds_to_bytes(ao, 0.5)); - free(device); return 0; error_exit: uninit(ao, true); - free(device); return -1; } @@ -374,6 +370,8 @@ static void resume(struct ao *ao) check_pa_ret(Pa_StartStream(priv->stream)); } +#define OPT_BASE_STRUCT struct priv + const struct ao_driver audio_out_portaudio = { .info = &(const struct ao_info) { "PortAudio", @@ -389,4 +387,9 @@ const struct ao_driver audio_out_portaudio = { .get_delay = get_delay, .pause = pause, .resume = resume, + .priv_size = sizeof(struct priv), + .options = (const struct m_option[]) { + OPT_STRING_VALIDATE("device", cfg_device, 0, validate_device_opt), + {0} + }, }; -- cgit v1.2.3