From e283a3f6428331c2bbd48ce9ddd062d3bb1c2331 Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Wed, 17 Jan 2001 11:00:32 +0000 Subject: [PATCH] Added I/O classes --- configure.in | 2 +- include/Makefile.am | 4 +- include/conf.h | 25 +- include/input.h | 15 + include/output.h | 17 + include/pcm.h | 16 +- src/Makefile.am | 9 +- src/conf.c | 1100 +++++++++++++++++++++++++++++++++++++ src/conf/Makefile.am | 8 - src/control/control_shm.c | 4 +- src/input.c | 261 +++++++++ src/instr/iwffff.c | 4 +- src/output.c | 283 ++++++++++ src/pcm/interval.c | 18 +- src/pcm/interval.h | 2 +- src/pcm/pcm.c | 78 +-- src/pcm/pcm_adpcm.c | 12 +- src/pcm/pcm_alaw.c | 12 +- src/pcm/pcm_copy.c | 12 +- src/pcm/pcm_file.c | 14 +- src/pcm/pcm_hw.c | 8 +- src/pcm/pcm_linear.c | 12 +- src/pcm/pcm_local.h | 2 +- src/pcm/pcm_mulaw.c | 12 +- src/pcm/pcm_multi.c | 16 +- src/pcm/pcm_null.c | 8 +- src/pcm/pcm_params.c | 66 +-- src/pcm/pcm_plug.c | 20 +- src/pcm/pcm_rate.c | 14 +- src/pcm/pcm_route.c | 26 +- src/pcm/pcm_share.c | 16 +- src/pcm/pcm_shm.c | 12 +- 32 files changed, 1882 insertions(+), 226 deletions(-) create mode 100644 include/input.h create mode 100644 include/output.h create mode 100644 src/conf.c delete mode 100644 src/conf/Makefile.am create mode 100644 src/input.c create mode 100644 src/output.c diff --git a/configure.in b/configure.in index e4509775..1e6306c9 100644 --- a/configure.in +++ b/configure.in @@ -53,6 +53,6 @@ AC_OUTPUT(Makefile doc/Makefile include/Makefile src/Makefile \ src/control/Makefile src/mixer/Makefile src/pcm/Makefile \ src/rawmidi/Makefile src/timer/Makefile \ src/hwdep/Makefile src/seq/Makefile src/instr/Makefile \ - src/compat/Makefile src/conf/Makefile aserver/Makefile \ + src/compat/Makefile aserver/Makefile \ test/Makefile utils/Makefile \ utils/alsa-lib.spec) diff --git a/include/Makefile.am b/include/Makefile.am index 06315574..7308f8c4 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -3,8 +3,8 @@ sysinclude_HEADERS = asoundlib.h # This is the order they will be concatenated into asoundlib.h! # -header_files=header.h version.h global.h error.h control.h mixer.h pcm.h \ - rawmidi.h timer.h hwdep.h seq.h seqmid.h seq_midi_event.h \ +header_files=header.h version.h global.h input.h output.h error.h control.h mixer.h \ + pcm.h rawmidi.h timer.h hwdep.h seq.h seqmid.h seq_midi_event.h \ conv.h instr.h conf.h footer.h noinst_HEADERS=$(header_files) search.h list.h aserver.h local.h diff --git a/include/conf.h b/include/conf.h index 00ae6f99..5b1091bc 100644 --- a/include/conf.h +++ b/include/conf.h @@ -24,10 +24,20 @@ struct _snd_config { snd_config_t *father; }; +static inline snd_config_type_t snd_config_type(snd_config_t *config) +{ + return config->type; +} + +static inline char *snd_config_id(snd_config_t *config) +{ + return config->id; +} + int snd_config_top(snd_config_t **config); -int snd_config_load(snd_config_t *config, FILE *fp); -int snd_config_save(snd_config_t *config, FILE *fp); +int snd_config_load(snd_config_t *config, snd_input_t *in); +int snd_config_save(snd_config_t *config, snd_output_t *out); int snd_config_search(snd_config_t *config, char *key, snd_config_t **result); int snd_config_searchv(snd_config_t *config, @@ -62,15 +72,8 @@ typedef struct list_head *snd_config_iterator_t; #define snd_config_entry(iterator) list_entry(iterator, snd_config_t, list) -static inline snd_config_type_t snd_config_type(snd_config_t *config) -{ - return config->type; -} - -static inline char *snd_config_id(snd_config_t *config) -{ - return config->id; -} +snd_config_type_t snd_config_type(snd_config_t *config); +char *snd_config_id(snd_config_t *config); extern snd_config_t *snd_config; int snd_config_update(); diff --git a/include/input.h b/include/input.h new file mode 100644 index 00000000..2f4c2426 --- /dev/null +++ b/include/input.h @@ -0,0 +1,15 @@ + +typedef struct _snd_input snd_input_t; + +typedef enum _snd_input_type { + SND_INPUT_STDIO, + SND_INPUT_BUFFER, +} snd_input_type_t; + +int snd_input_stdio_open(snd_input_t **inputp, const char *file); +int snd_input_stdio_attach(snd_input_t **inputp, FILE *fp, int close); +int snd_input_buffer_open(snd_input_t **inputp, const char *buffer, int size); +int snd_input_close(snd_input_t *input); +int snd_input_scanf(snd_input_t *input, const char *format, ...) __attribute__ ((format (scanf, 2, 3))); +char *snd_input_gets(snd_input_t *input, char *str, size_t size); +int snd_input_getc(snd_input_t *input); diff --git a/include/output.h b/include/output.h new file mode 100644 index 00000000..dd50f9db --- /dev/null +++ b/include/output.h @@ -0,0 +1,17 @@ + +typedef struct _snd_output snd_output_t; + +typedef enum _snd_output_type { + SND_OUTPUT_STDIO, + SND_OUTPUT_BUFFER, +} snd_output_type_t; + +int snd_output_stdio_open(snd_output_t **outputp, const char *file); +int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int close); +int snd_output_buffer_open(snd_output_t **outputp); +size_t snd_output_buffer_string(snd_output_t *output, char **buf); +int snd_output_close(snd_output_t *output); +int snd_output_printf(snd_output_t *output, const char *format, ...) __attribute__ ((format (printf, 2, 3))); +int snd_output_puts(snd_output_t *output, const char *str); +int snd_output_putc(snd_output_t *output, int c); +int snd_output_flush(snd_output_t *output); diff --git a/include/pcm.h b/include/pcm.h index 6b958a47..96849fee 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -76,11 +76,11 @@ snd_pcm_sframes_t snd_pcm_readi(snd_pcm_t *pcm, void *buffer, snd_pcm_uframes_t snd_pcm_sframes_t snd_pcm_writen(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); snd_pcm_sframes_t snd_pcm_readn(snd_pcm_t *pcm, void **bufs, snd_pcm_uframes_t size); -int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, FILE *fp); -int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, FILE *fp); -int snd_pcm_dump_setup(snd_pcm_t *pcm, FILE *fp); -int snd_pcm_dump(snd_pcm_t *pcm, FILE *fp); -int snd_pcm_status_dump(snd_pcm_status_t *status, FILE *fp); +int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out); +int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out); +int snd_pcm_dump_setup(snd_pcm_t *pcm, snd_output_t *out); +int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out); +int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out); int snd_pcm_link(snd_pcm_t *pcm1, snd_pcm_t *pcm2); int snd_pcm_unlink(snd_pcm_t *pcm); @@ -158,7 +158,7 @@ int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm, snd_pcm_hw_params_t *fail, snd_pcm_hw_params_t *success, unsigned int depth, - FILE *fp); + snd_output_t *out); int snd_pcm_hw_params_info_rate(const snd_pcm_hw_params_t *params, unsigned int *rate_num, @@ -167,7 +167,7 @@ int snd_pcm_hw_params_info_msbits(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_info_flags(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_info_fifo_size(const snd_pcm_hw_params_t *params); int snd_pcm_hw_params_info_dig_groups(const snd_pcm_hw_params_t *params); -int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, FILE *fp); +int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out); typedef struct _snd_pcm_hw_strategy snd_pcm_hw_strategy_t; @@ -212,7 +212,7 @@ int snd_pcm_sw_params_current(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); int snd_pcm_sw_param_set(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var, unsigned int val); int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var, unsigned int val); int snd_pcm_sw_param_value(snd_pcm_sw_params_t *params, snd_pcm_sw_param_t var); -int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, FILE *fp); +int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out); /* mmap */ const snd_pcm_channel_area_t *snd_pcm_mmap_areas(snd_pcm_t *pcm); diff --git a/src/Makefile.am b/src/Makefile.am index ab991741..7dc09e37 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,12 +1,12 @@ -SUBDIRS=control mixer pcm rawmidi timer hwdep seq instr compat conf +SUBDIRS=control mixer pcm rawmidi timer hwdep seq instr compat COMPATNUM=@LIBTOOL_VERSION_INFO@ lib_LTLIBRARIES = libasound.la -libasound_la_SOURCES = error.c +libasound_la_SOURCES = conf.c input.c output.c error.c libasound_la_LIBADD = control/libcontrol.la mixer/libmixer.la pcm/libpcm.la \ rawmidi/librawmidi.la timer/libtimer.la \ hwdep/libhwdep.la seq/libseq.la instr/libinstr.la \ - compat/libcompat.la conf/libconf.la -lm -ldl -lpthread + compat/libcompat.la -lm -ldl -lpthread libasound_la_LDFLAGS = -version-info $(COMPATNUM) @@ -37,7 +37,4 @@ instr/libinstr.la: compat/libcompat.la: $(MAKE) -C compat libcompat.la -conf/libconf.la: - $(MAKE) -C conf libconf.la - INCLUDES=-I$(top_srcdir)/include diff --git a/src/conf.c b/src/conf.c new file mode 100644 index 00000000..17e5daac --- /dev/null +++ b/src/conf.c @@ -0,0 +1,1100 @@ +/* + * Configuration helper functions + * Copyright (c) 2000 by Abramo Bagnara + * + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include "asoundlib.h" +#include "local.h" +#include "list.h" + +#define SYS_ASOUNDRC "/etc/asound.conf" +#define USR_ASOUNDRC ".asoundrc" + +struct filedesc { + char *name; + snd_input_t *in; + unsigned int line, column; + struct filedesc *next; +}; + +typedef struct { + struct filedesc *current; + int unget; + int ch; + enum { + UNTERMINATED_STRING = -1, + UNTERMINATED_QUOTE = -2, + UNEXPECTED_CHAR = -3, + UNEXPECTED_EOF = -4, + } error; +} input_t; + +static int get_char(input_t *input) +{ + int c; + struct filedesc *fd; + if (input->unget) { + input->unget = 0; + return input->ch; + } + again: + fd = input->current; + c = snd_input_getc(fd->in); + switch (c) { + case '\n': + fd->column = 0; + fd->line++; + break; + case '\t': + fd->column += 8 - fd->column % 8; + break; + case EOF: + if (fd->next) { + snd_input_close(fd->in); + free(fd->name); + input->current = fd->next; + free(fd); + goto again; + } + break; + default: + fd->column++; + break; + } + return c; +} + +static void unget_char(int c, input_t *input) +{ + assert(!input->unget); + input->ch = c; + input->unget = 1; +} + +static int get_delimstring(char **string, int delim, input_t *input); + +static int get_char_skip_comments(input_t *input) +{ + int c; + while (1) { + c = get_char(input); + if (c == '<') { + char *file; + snd_input_t *in; + struct filedesc *fd; + int err = get_delimstring(&file, '>', input); + if (err < 0) + return err; + err = snd_input_stdio_open(&in, file); + if (err < 0) + return err; + fd = malloc(sizeof(*fd)); + fd->name = file; + fd->in = in; + fd->next = input->current; + fd->line = 1; + fd->column = 0; + input->current = fd; + continue; + } + if (c != '#') + break; + while (1) { + c = get_char(input); + if (c == EOF) + return c; + if (c == '\n') + break; + } + } + + return c; +} + + +static int get_nonwhite(input_t *input) +{ + int c; + while (1) { + c = get_char_skip_comments(input); + switch (c) { + case ' ': + case '\f': + case '\t': + case '\n': + case '\r': + break; + default: + return c; + } + } +} + +static int get_quotedchar(input_t *input) +{ + int c; + c = get_char(input); + switch (c) { + case 'n': + return '\n'; + case 't': + return '\t'; + case 'v': + return '\v'; + case 'b': + return '\b'; + case 'r': + return '\r'; + case 'f': + return '\f'; + case '0' ... '7': + { + int num = c - '0'; + int i = 1; + do { + c = get_char(input); + if (c < '0' || c > '7') { + unget_char(c, input); + break; + } + num = num * 8 + c - '0'; + i++; + } while (i < 3); + return num; + } + default: + return c; + } +} + +static int get_freestring(char **string, int id, input_t *input) +{ + const size_t bufsize = 256; + char _buf[bufsize]; + char *buf = _buf; + size_t alloc = bufsize; + size_t idx = 0; + int c; + while (1) { + c = get_char(input); + switch (c) { + case '.': + if (!id) + break; + case ' ': + case '\f': + case '\t': + case '\n': + case '\r': + case EOF: + case '=': + case '{': + case '}': + case ',': + case ';': + case '\'': + case '"': + case '\\': + case '#': + { + char *s = malloc(idx + 1); + unget_char(c, input); + memcpy(s, buf, idx); + s[idx] = '\0'; + *string = s; + return 0; + } + default: + break; + } + if (idx >= alloc) { + size_t old_alloc = alloc; + alloc += bufsize; + if (old_alloc == bufsize) { + buf = malloc(alloc); + memcpy(buf, _buf, old_alloc); + } else + buf = realloc(buf, alloc); + } + buf[idx++] = c; + } + return 0; +} + +static int get_delimstring(char **string, int delim, input_t *input) +{ + const size_t bufsize = 256; + char _buf[bufsize]; + char *buf = _buf; + size_t alloc = bufsize; + size_t idx = 0; + int c; + while (1) { + c = get_char(input); + switch (c) { + case EOF: + input->error = UNTERMINATED_STRING; + return -EINVAL; + case '\\': + c = get_quotedchar(input); + if (c < 0) { + input->error = UNTERMINATED_QUOTE; + return -EINVAL; + } + break; + default: + if (c == delim) { + char *s = malloc(idx + 1); + memcpy(s, buf, idx); + s[idx] = '\0'; + *string = s; + return 0; + } + } + if (idx >= alloc) { + size_t old_alloc = alloc; + alloc += bufsize; + if (old_alloc == bufsize) { + buf = malloc(alloc); + memcpy(buf, _buf, old_alloc); + } else + buf = realloc(buf, alloc); + } + buf[idx++] = c; + } + return 0; +} + +/* Return 0 for free string, 1 for delimited string */ +static int get_string(char **string, int id, input_t *input) +{ + int c = get_nonwhite(input); + int err; + switch (c) { + case EOF: + input->error = UNEXPECTED_EOF; + return -EINVAL; + case '=': +#if 0 + /* I'm not sure to want unnamed fields */ + *string = 0; + return 0; +#endif + case '.': + case '{': + case '}': + case ',': + case ';': + input->error = UNEXPECTED_CHAR; + return -EINVAL; + case '\'': + case '"': + err = get_delimstring(string, c, input); + if (err < 0) + return err; + return 1; + default: + unget_char(c, input); + err = get_freestring(string, id, input); + if (err < 0) + return err; + return 0; + } +} + +static int _snd_config_make(snd_config_t **config, char *id, + snd_config_type_t type) +{ + snd_config_t *n; + n = calloc(1, sizeof(*n)); + if (n == NULL) { + if (id) + free(id); + return -ENOMEM; + } + n->id = id; + n->type = type; + if (type == SND_CONFIG_TYPE_COMPOUND) + INIT_LIST_HEAD(&n->u.compound.fields); + *config = n; + return 0; +} + + +static int _snd_config_make_add(snd_config_t **config, char *id, + snd_config_type_t type, snd_config_t *father) +{ + snd_config_t *n; + int err; + assert(father->type == SND_CONFIG_TYPE_COMPOUND); + err = _snd_config_make(&n, id, type); + if (err < 0) + return err; + n->father = father; + list_add_tail(&n->list, &father->u.compound.fields); + *config = n; + return 0; +} + +static int _snd_config_search(snd_config_t *config, char *id, int len, snd_config_t **result) +{ + snd_config_iterator_t i; + snd_config_foreach(i, config) { + snd_config_t *n = snd_config_entry(i); + if (len < 0) { + if (strcmp(n->id, id) == 0) { + *result = n; + return 0; + } + } else { + if (strlen(n->id) != (size_t) len) + continue; + if (memcmp(n->id, id, len) == 0) { + *result = n; + return 0; + } + } + } + return -ENOENT; +} + +static int parse_defs(snd_config_t *father, input_t *input); + +static int parse_def(snd_config_t *father, input_t *input) +{ + char *id; + int c; + int err; + snd_config_t *n; + enum {MERGE, NOCREATE, REMOVE} mode; + while (1) { +#if 0 + c = get_nonwhite(input); + switch (c) { + case '?': + mode = NOCREATE; + break; + case '!': + mode = REMOVE; + break; + default: + mode = MERGE; + unget_char(c, input); + } +#else + mode = MERGE; +#endif + err = get_string(&id, 1, input); + if (err < 0) + return err; + c = get_nonwhite(input); + if (c != '.') + break; + if (_snd_config_search(father, id, -1, &n) == 0) { + if (mode != REMOVE) { + if (n->type != SND_CONFIG_TYPE_COMPOUND) { + ERR("%s is not a compound", id); + return -EINVAL; + } + n->u.compound.join = 1; + father = n; + free(id); + continue; + } + snd_config_delete(n); + } + if (mode == NOCREATE) { + ERR("%s does not exists", id); + free(id); + return -ENOENT; + } + err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_COMPOUND, father); + if (err < 0) + return err; + n->u.compound.join = 1; + father = n; + } + if (c == '=' ) + c = get_nonwhite(input); + if (_snd_config_search(father, id, -1, &n) == 0) { + if (mode == REMOVE) { + snd_config_delete(n); + n = NULL; + } + else + free(id); + } else { + n = NULL; + if (mode == NOCREATE) { + ERR("%s does not exists", id); + free(id); + return -ENOENT; + } + } + switch (c) { + case '{': + { + if (n) { + if (n->type != SND_CONFIG_TYPE_COMPOUND) { + ERR("%s is not a compound", id); + return -EINVAL; + } + } else { + err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_COMPOUND, father); + if (err < 0) + return err; + } + err = parse_defs(n, input); + if (err < 0) { + snd_config_delete(n); + return err; + } + c = get_nonwhite(input); + if (c != '}') { + snd_config_delete(n); + input->error = (c == EOF ? UNEXPECTED_EOF : UNEXPECTED_CHAR); + return -EINVAL; + } + break; + } + default: + { + char *s; + unget_char(c, input); + err = get_string(&s, 0, input); + if (err < 0) + return err; + if (!err && ((s[0] >= '0' && s[0] <= '9') || s[0] == '-')) { + char *ptr; + long i; + errno = 0; + i = strtol(s, &ptr, 0); + if (*ptr == '.' || errno != 0) { + double r; + errno = 0; + r = strtod(s, &ptr); + if (errno == 0) { + free(s); + if (n) { + if (n->type != SND_CONFIG_TYPE_REAL) { + ERR("%s is not a real", id); + return -EINVAL; + } + } else { + err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_REAL, father); + if (err < 0) + return err; + } + n->u.real = r; + break; + } + } else if (*ptr == '\0') { + free(s); + if (n) { + if (n->type != SND_CONFIG_TYPE_INTEGER) { + ERR("%s is not an integer", id); + return -EINVAL; + } + } else { + err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_INTEGER, father); + if (err < 0) + return err; + } + n->u.integer = i; + break; + } + } + if (n) { + if (n->type != SND_CONFIG_TYPE_STRING) { + ERR("%s is not a string", id); + free(s); + return -EINVAL; + } + } else { + err = _snd_config_make_add(&n, id, SND_CONFIG_TYPE_STRING, father); + if (err < 0) + return err; + } + if (n->u.string) + free(n->u.string); + n->u.string = s; + } + } + c = get_nonwhite(input); + switch (c) { + case ';': + case ',': + break; + default: + unget_char(c, input); + } + return err; +} + +static int parse_defs(snd_config_t *father, input_t *input) +{ + while (1) { + int c = get_nonwhite(input); + int err; + if (c == EOF) + return 0; + unget_char(c, input); + if (c == '}') + return 0; + err = parse_def(father, input); + if (err < 0) + return err; + } + return 0; +} + +int snd_config_top(snd_config_t **config) +{ + assert(config); + return _snd_config_make(config, 0, SND_CONFIG_TYPE_COMPOUND); +} + +int snd_config_load(snd_config_t *config, snd_input_t *in) +{ + int err; + input_t input; + struct filedesc *fd; + assert(config && in); + fd = malloc(sizeof(*fd)); + fd->name = NULL; + fd->in = in; + fd->line = 1; + fd->column = 0; + fd->next = NULL; + input.current = fd; + input.unget = 0; + input.error = 0; + err = parse_defs(config, &input); + fd = input.current; + if (err < 0) { + if (input.error < 0) { + char *str; + switch (input.error) { + case UNTERMINATED_STRING: + str = "Unterminated string"; + break; + case UNTERMINATED_QUOTE: + str = "Unterminated quote"; + break; + case UNEXPECTED_CHAR: + str = "Unexpected char"; + break; + case UNEXPECTED_EOF: + str = "Unexpected end of file"; + break; + default: + assert(0); + break; + } + ERR("%s:%d:%d:%s", fd->name ? fd->name : "", + fd->line, fd->column, str); + } + snd_config_delete(config); + goto _end; + } + if (get_char(&input) != EOF) { + ERR("%s:%d:%d:Unexpected }", fd->name ? fd->name : "", + fd->line, fd->column); + snd_config_delete(config); + err = -EINVAL; + goto _end; + } + _end: + while (fd->next) { + snd_input_close(fd->in); + free(fd->name); + free(fd); + fd = fd->next; + } + free(fd); + return err; +} + +int snd_config_add(snd_config_t *father, snd_config_t *leaf) +{ + snd_config_iterator_t i; + assert(father && leaf); + snd_config_foreach(i, father) { + snd_config_t *n = snd_config_entry(i); + if (strcmp(leaf->id, n->id) == 0) + return -EEXIST; + } + leaf->father = father; + list_add_tail(&leaf->list, &father->u.compound.fields); + return 0; +} + +int snd_config_delete(snd_config_t *config) +{ + assert(config); + switch (config->type) { + case SND_CONFIG_TYPE_COMPOUND: + { + int err; + struct list_head *i; + i = config->u.compound.fields.next; + while (i != &config->u.compound.fields) { + struct list_head *nexti = i->next; + snd_config_t *leaf = snd_config_entry(i); + err = snd_config_delete(leaf); + if (err < 0) + return err; + i = nexti; + } + break; + } + case SND_CONFIG_TYPE_STRING: + if (config->u.string) + free(config->u.string); + break; + default: + break; + } + if (config->father) + list_del(&config->list); + return 0; +} + +int snd_config_make(snd_config_t **config, char *id, + snd_config_type_t type) +{ + char *id1; + assert(config); + if (id) { + id1 = strdup(id); + if (!id1) + return -ENOMEM; + } else + id1 = NULL; + return _snd_config_make(config, id1, type); +} + +int snd_config_integer_make(snd_config_t **config, char *id) +{ + return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER); +} + +int snd_config_real_make(snd_config_t **config, char *id) +{ + return snd_config_make(config, id, SND_CONFIG_TYPE_REAL); +} + +int snd_config_string_make(snd_config_t **config, char *id) +{ + return snd_config_make(config, id, SND_CONFIG_TYPE_STRING); +} + +int snd_config_compound_make(snd_config_t **config, char *id, + int join) +{ + int err; + err = snd_config_make(config, id, SND_CONFIG_TYPE_COMPOUND); + if (err < 0) + return err; + (*config)->u.compound.join = join; + return 0; +} + +int snd_config_integer_set(snd_config_t *config, long value) +{ + assert(config); + if (config->type != SND_CONFIG_TYPE_INTEGER) + return -EINVAL; + config->u.integer = value; + return 0; +} + +int snd_config_real_set(snd_config_t *config, double value) +{ + assert(config); + if (config->type != SND_CONFIG_TYPE_REAL) + return -EINVAL; + config->u.real = value; + return 0; +} + +int snd_config_string_set(snd_config_t *config, char *value) +{ + assert(config); + if (config->type != SND_CONFIG_TYPE_STRING) + return -EINVAL; + if (config->u.string) + free(config->u.string); + config->u.string = strdup(value); + if (!config->u.string) + return -ENOMEM; + return 0; +} + +int snd_config_set(snd_config_t *config, ...) +{ + va_list arg; + va_start(arg, config); + assert(config); + switch (config->type) { + case SND_CONFIG_TYPE_INTEGER: + config->u.integer = va_arg(arg, long); + break; + case SND_CONFIG_TYPE_REAL: + config->u.real = va_arg(arg, double); + break; + case SND_CONFIG_TYPE_STRING: + config->u.string = va_arg(arg, char *); + break; + default: + assert(0); + return -EINVAL; + } + va_end(arg); + return 0; +} + +int snd_config_integer_get(snd_config_t *config, long *ptr) +{ + assert(config && ptr); + if (config->type != SND_CONFIG_TYPE_INTEGER) + return -EINVAL; + *ptr = config->u.integer; + return 0; +} + +int snd_config_real_get(snd_config_t *config, double *ptr) +{ + assert(config && ptr); + if (config->type != SND_CONFIG_TYPE_REAL) + return -EINVAL; + *ptr = config->u.real; + return 0; +} + +int snd_config_string_get(snd_config_t *config, char **ptr) +{ + assert(config && ptr); + if (config->type != SND_CONFIG_TYPE_STRING) + return -EINVAL; + *ptr = config->u.string; + return 0; +} + +int snd_config_get(snd_config_t *config, void *ptr) +{ + assert(config && ptr); + switch (config->type) { + case SND_CONFIG_TYPE_INTEGER: + * (long*) ptr = config->u.integer; + break; + case SND_CONFIG_TYPE_REAL: + * (double*) ptr = config->u.real; + break; + case SND_CONFIG_TYPE_STRING: + * (char **) ptr = config->u.string; + break; + default: + assert(0); + return -EINVAL; + } + return 0; +} + +void string_print(char *str, int id, snd_output_t *out) +{ + unsigned char *p = str; + if (!id) { + switch (*p) { + case '0' ... '9': + case '-': + goto quoted; + } + } + loop: + switch (*p) { + case 0: + goto nonquoted; + case 1 ... 31: + case 127 ... 255: + case ' ': + case '=': + case '.': + case '{': + case '}': + case ';': + case ',': + case '\'': + case '"': + goto quoted; + default: + p++; + goto loop; + } + nonquoted: + snd_output_puts(out, str); + return; + quoted: + snd_output_putc(out, '\''); + p = str; + while (*p) { + int c; + c = *p; + switch (c) { + case '\n': + snd_output_putc(out, '\\'); + snd_output_putc(out, 'n'); + break; + case '\t': + snd_output_putc(out, '\\'); + snd_output_putc(out, 't'); + break; + case '\v': + snd_output_putc(out, '\\'); + snd_output_putc(out, 'v'); + break; + case '\b': + snd_output_putc(out, '\\'); + snd_output_putc(out, 'b'); + break; + case '\r': + snd_output_putc(out, '\\'); + snd_output_putc(out, 'r'); + break; + case '\f': + snd_output_putc(out, '\\'); + snd_output_putc(out, 'f'); + break; + case '\'': + snd_output_putc(out, '\\'); + snd_output_putc(out, c); + break; + case 32 ... '\'' - 1: + case '\'' + 1 ... 126: + snd_output_putc(out, c); + break; + default: + snd_output_printf(out, "\\%04o", c); + break; + } + p++; + } + snd_output_putc(out, '\''); +} + +static int _snd_config_save_leaves(snd_config_t *config, snd_output_t *out, unsigned int level, unsigned int joins); + +static int _snd_config_save_leaf(snd_config_t *n, snd_output_t *out, + unsigned int level) +{ + int err; + unsigned int k; + switch (n->type) { + case SND_CONFIG_TYPE_INTEGER: + snd_output_printf(out, "%ld", n->u.integer); + break; + case SND_CONFIG_TYPE_REAL: + snd_output_printf(out, "%16g", n->u.real); + break; + case SND_CONFIG_TYPE_STRING: + string_print(n->u.string, 0, out); + break; + case SND_CONFIG_TYPE_COMPOUND: + snd_output_putc(out, '{'); + snd_output_putc(out, '\n'); + err = _snd_config_save_leaves(n, out, level + 1, 0); + if (err < 0) + return err; + for (k = 0; k < level; ++k) { + snd_output_putc(out, '\t'); + } + snd_output_putc(out, '}'); + break; + } + return 0; +} + +static void id_print(snd_config_t *n, snd_output_t *out, unsigned int joins) +{ + if (joins > 0) { + assert(n->father); + id_print(n->father, out, joins - 1); + snd_output_putc(out, '.'); + } + string_print(n->id, 1, out); +} + +static int _snd_config_save_leaves(snd_config_t *config, snd_output_t *out, unsigned int level, unsigned int joins) +{ + unsigned int k; + int err; + snd_config_iterator_t i; + assert(config && out); + snd_config_foreach(i, config) { + snd_config_t *n = snd_config_entry(i); + if (n->type == SND_CONFIG_TYPE_COMPOUND && + n->u.compound.join) { + err = _snd_config_save_leaves(n, out, level, joins + 1); + if (err < 0) + return err; + continue; + } + for (k = 0; k < level; ++k) { + snd_output_putc(out, '\t'); + } + id_print(n, out, joins); + snd_output_putc(out, ' '); + snd_output_putc(out, '='); + snd_output_putc(out, ' '); + err = _snd_config_save_leaf(n, out, level); + if (err < 0) + return err; + snd_output_putc(out, ';'); + snd_output_putc(out, '\n'); + } + return 0; +} + +int snd_config_save(snd_config_t *config, snd_output_t *out) +{ + assert(config && out); + return _snd_config_save_leaves(config, out, 0, 0); +} + +int snd_config_search(snd_config_t *config, char *key, snd_config_t **result) +{ + assert(config && key && result); + while (1) { + snd_config_t *n; + int err; + char *p = strchr(key, '.'); + if (config->type != SND_CONFIG_TYPE_COMPOUND) + return -ENOENT; + if (p) { + err = _snd_config_search(config, key, p - key, &n); + if (err < 0) + return err; + config = n; + key = p + 1; + } else + return _snd_config_search(config, key, -1, result); + } +} + +int snd_config_searchv(snd_config_t *config, + snd_config_t **result, ...) +{ + snd_config_t *n; + va_list arg; + assert(config && result); + va_start(arg, result); + while (1) { + char *k = va_arg(arg, char *); + int err; + if (!k) + break; + if (config->type != SND_CONFIG_TYPE_COMPOUND) + return -ENOENT; + err = _snd_config_search(config, k, -1, &n); + if (err < 0) + return err; + config = n; + } + va_end(arg); + *result = n; + return 0; +} + +snd_config_t *snd_config = 0; +static dev_t sys_asoundrc_device; +static ino_t sys_asoundrc_inode; +static time_t sys_asoundrc_mtime; +static dev_t usr_asoundrc_device; +static ino_t usr_asoundrc_inode; +static time_t usr_asoundrc_mtime; + +int snd_config_update() +{ + int err; + char *usr_asoundrc = NULL; + char *home = getenv("HOME"); + struct stat usr_st, sys_st; + int reload; + snd_input_t *in; + if (home) { + size_t len = strlen(home); + size_t len1 = strlen(USR_ASOUNDRC); + usr_asoundrc = alloca(len + len1 + 2); + memcpy(usr_asoundrc, home, len); + usr_asoundrc[len] = '/'; + memcpy(usr_asoundrc + len + 1, USR_ASOUNDRC, len1); + usr_asoundrc[len + 1 + len1] = '\0'; + } + reload = (snd_config == NULL); + if (stat(SYS_ASOUNDRC, &sys_st) == 0 && + (sys_st.st_dev != sys_asoundrc_device || + sys_st.st_ino != sys_asoundrc_inode || + sys_st.st_mtime != sys_asoundrc_mtime)) + reload = 1; + if (stat(usr_asoundrc, &usr_st) == 0 && + (usr_st.st_dev != usr_asoundrc_device || + usr_st.st_ino != usr_asoundrc_inode || + usr_st.st_mtime != usr_asoundrc_mtime)) + reload = 1; + if (!reload) + return 0; + if (snd_config) { + err = snd_config_delete(snd_config); + if (err < 0) + return err; + snd_config = 0; + } + err = snd_config_top(&snd_config); + if (err < 0) + return err; + err = snd_input_stdio_open(&in, SYS_ASOUNDRC); + if (err >= 0) { + err = snd_config_load(snd_config, in); + snd_input_close(in); + if (err < 0) { + snd_config = NULL; + return err; + } + sys_asoundrc_device = sys_st.st_dev; + sys_asoundrc_inode = sys_st.st_ino; + sys_asoundrc_mtime = sys_st.st_mtime; + } + err = snd_input_stdio_open(&in, usr_asoundrc); + if (err >= 0) { + err = snd_config_load(snd_config, in); + snd_input_close(in); + if (err < 0) { + snd_config = NULL; + return err; + } + usr_asoundrc_device = usr_st.st_dev; + usr_asoundrc_inode = usr_st.st_ino; + usr_asoundrc_mtime = usr_st.st_mtime; + } + return 0; +} diff --git a/src/conf/Makefile.am b/src/conf/Makefile.am deleted file mode 100644 index 113d747c..00000000 --- a/src/conf/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -EXTRA_LTLIBRARIES = libconf.la - -libconf_la_SOURCES = conf.c - -all: libconf.la - - -INCLUDES=-I$(top_srcdir)/include diff --git a/src/control/control_shm.c b/src/control/control_shm.c index b718252e..d61ad8eb 100644 --- a/src/control/control_shm.c +++ b/src/control/control_shm.c @@ -57,7 +57,7 @@ static int snd_ctl_shm_action(snd_ctl_t *ctl) if (err != 1) return -EBADFD; if (ctrl->cmd) { - fprintf(stderr, "Server has not done the cmd\n"); + ERR("Server has not done the cmd"); return -EBADFD; } return ctrl->result; @@ -76,7 +76,7 @@ static int snd_ctl_shm_action_fd(snd_ctl_t *ctl, int *fd) if (err != 1) return -EBADFD; if (ctrl->cmd) { - fprintf(stderr, "Server has not done the cmd\n"); + ERR("Server has not done the cmd"); return -EBADFD; } return ctrl->result; diff --git a/src/input.c b/src/input.c new file mode 100644 index 00000000..1199b089 --- /dev/null +++ b/src/input.c @@ -0,0 +1,261 @@ +/* + * Input object + * Copyright (c) 2000 by Abramo Bagnara + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "local.h" +#include "asoundlib.h" + +typedef struct _snd_input_ops { + int (*close)(snd_input_t *input); + int (*scanf)(snd_input_t *input, const char *format, va_list args); + char *(*gets)(snd_input_t *input, char *str, size_t size); + int (*getch)(snd_input_t *input); + int (*ungetch)(snd_input_t *input, int c); +} snd_input_ops_t; + +struct _snd_input { + snd_input_type_t type; + snd_input_ops_t *ops; + void *private; +}; + +int snd_input_close(snd_input_t *input) +{ + int err = input->ops->close(input); + free(input); + return err; +} + +int snd_input_scanf(snd_input_t *input, const char *format, ...) +{ + int result; + va_list args; + va_start(args, format); + result = input->ops->scanf(input, format, args); + va_end(args); + return result; +} + +char *snd_input_gets(snd_input_t *input, char *str, size_t size) +{ + return input->ops->gets(input, str, size); +} + +int snd_input_getc(snd_input_t *input) +{ + return input->ops->getch(input); +} + +int snd_input_ungetc(snd_input_t *input, int c) +{ + return input->ops->ungetch(input, c); +} + +typedef struct _snd_input_stdio { + int close; + FILE *fp; +} snd_input_stdio_t; + +int snd_input_stdio_close(snd_input_t *input ATTRIBUTE_UNUSED) +{ + snd_input_stdio_t *stdio = input->private; + if (close) + fclose(stdio->fp); + free(stdio); + return 0; +} + +int snd_input_stdio_scanf(snd_input_t *input, const char *format, va_list args) +{ + snd_input_stdio_t *stdio = input->private; + extern int vfscanf(FILE *fp, const char *format, va_list args); + return vfscanf(stdio->fp, format, args); +} + +char *snd_input_stdio_gets(snd_input_t *input, char *str, size_t size) +{ + snd_input_stdio_t *stdio = input->private; + return fgets(str, size, stdio->fp); +} + +int snd_input_stdio_getc(snd_input_t *input) +{ + snd_input_stdio_t *stdio = input->private; + return getc(stdio->fp); +} + +int snd_input_stdio_ungetc(snd_input_t *input, int c) +{ + snd_input_stdio_t *stdio = input->private; + return ungetc(c, stdio->fp); +} + +snd_input_ops_t snd_input_stdio_ops = { + close: snd_input_stdio_close, + scanf: snd_input_stdio_scanf, + gets: snd_input_stdio_gets, + getch: snd_input_stdio_getc, + ungetch: snd_input_stdio_ungetc, +}; + +int snd_input_stdio_attach(snd_input_t **inputp, FILE *fp, int close) +{ + snd_input_t *input; + snd_input_stdio_t *stdio; + assert(inputp && fp); + stdio = calloc(1, sizeof(*stdio)); + if (!stdio) + return -ENOMEM; + input = calloc(1, sizeof(*input)); + if (!input) { + free(stdio); + return -ENOMEM; + } + stdio->fp = fp; + stdio->close = close; + input->type = SND_INPUT_STDIO; + input->ops = &snd_input_stdio_ops; + input->private = stdio; + *inputp = input; + return 0; +} + +int snd_input_stdio_open(snd_input_t **inputp, const char *file) +{ + int err; + FILE *fp = fopen(file, "r"); + if (!fp) { + SYSERR("fopen"); + return -errno; + } + err = snd_input_stdio_attach(inputp, fp, 1); + if (err < 0) + fclose(fp); + return err; +} + +typedef struct _snd_input_buffer { + unsigned char *buf; + unsigned char *ptr; + size_t size; +} snd_input_buffer_t; + +int snd_input_buffer_close(snd_input_t *input) +{ + snd_input_buffer_t *buffer = input->private; + free(buffer->buf); + free(buffer); + return 0; +} + +int snd_input_buffer_scanf(snd_input_t *input, const char *format, va_list args) +{ + snd_input_buffer_t *buffer = input->private; + extern int vsscanf(const char *buf, const char *format, va_list args); + /* FIXME: how can I obtain consumed chars count? */ + assert(0); + return vsscanf(buffer->ptr, format, args); +} + +char *snd_input_buffer_gets(snd_input_t *input, char *str, size_t size) +{ + snd_input_buffer_t *buffer = input->private; + size_t bsize = buffer->size; + while (--size > 0 && bsize > 0) { + unsigned char c = *buffer->ptr++; + bsize--; + *str++ = c; + if (c == '\n') + break; + } + if (bsize == buffer->size) + return NULL; + buffer->size = bsize; + *str = '\0'; + return str; +} + +int snd_input_buffer_getc(snd_input_t *input) +{ + snd_input_buffer_t *buffer = input->private; + if (buffer->size == 0) + return EOF; + buffer->size--; + return *buffer->ptr++; +} + +int snd_input_buffer_ungetc(snd_input_t *input, int c) +{ + snd_input_buffer_t *buffer = input->private; + if (buffer->ptr == buffer->buf) + return EOF; + buffer->ptr--; + assert(*buffer->ptr == (unsigned char) c); + buffer->size++; + return c; +} + +snd_input_ops_t snd_input_buffer_ops = { + close: snd_input_buffer_close, + scanf: snd_input_buffer_scanf, + gets: snd_input_buffer_gets, + getch: snd_input_buffer_getc, + ungetch: snd_input_buffer_ungetc, +}; + +int snd_input_buffer_open(snd_input_t **inputp, const char *buf, int size) +{ + snd_input_t *input; + snd_input_buffer_t *buffer; + assert(inputp); + buffer = calloc(1, sizeof(*buffer)); + if (!buffer) + return -ENOMEM; + input = calloc(1, sizeof(*input)); + if (!input) { + free(buffer); + return -ENOMEM; + } + if (size < 0) + size = strlen(buf); + buffer->buf = malloc(size+1); + if (!buffer->buf) { + free(input); + free(buffer); + return -ENOMEM; + } + memcpy(buffer->buf, buf, size); + buffer->buf[size] = 0; + buffer->ptr = buffer->buf; + buffer->size = size; + input->type = SND_INPUT_BUFFER; + input->ops = &snd_input_buffer_ops; + input->private = buffer; + *inputp = input; + return 0; +} + diff --git a/src/instr/iwffff.c b/src/instr/iwffff.c index 383b40ac..9b3c179f 100644 --- a/src/instr/iwffff.c +++ b/src/instr/iwffff.c @@ -278,7 +278,7 @@ int snd_instr_iwffff_open_rom(snd_iwffff_handle_t **handle, int card, int bank, next_ffff = lseek(fd, 0, SEEK_CUR) + ffff.length; if (file == index) { #ifdef IW_ROM_DEBUG - fprintf(stderr, "file header at 0x%x size 0x%x\n", rom_pos - sizeof(ffff), ffff.length); + ERR("file header at 0x%x size 0x%x\n", rom_pos - sizeof(ffff), ffff.length); #endif iwf = malloc(sizeof(*iwf)); if (iwf == NULL) { @@ -505,7 +505,7 @@ static int load_iw_patch(snd_iwffff_handle_t *iwf, iwffff_instrument_t *instr, unsigned char *current; #ifdef IW_ROM_DEBUG - fprintf(stderr, "load_iw_patch - nlayers = %i\n", snd_LE_to_host_16(*(((unsigned short *)patch) + 8/2)); + ERR("load_iw_patch - nlayers = %i\n", snd_LE_to_host_16(*(((unsigned short *)patch) + 8/2)); #endif instr->layer_type = patch[6]; instr->exclusion = patch[7]; diff --git a/src/output.c b/src/output.c new file mode 100644 index 00000000..6634538e --- /dev/null +++ b/src/output.c @@ -0,0 +1,283 @@ +/* + * Output object + * Copyright (c) 2000 by Abramo Bagnara + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "local.h" +#include "asoundlib.h" + +typedef struct _snd_output_ops { + int (*close)(snd_output_t *output); + int (*printf)(snd_output_t *output, const char *format, va_list args); + int (*puts)(snd_output_t *output, const char *str); + int (*putch)(snd_output_t *output, int c); + int (*flush)(snd_output_t *output); +} snd_output_ops_t; + +struct _snd_output { + snd_output_type_t type; + snd_output_ops_t *ops; + void *private; +}; + +int snd_output_close(snd_output_t *output) +{ + int err = output->ops->close(output); + free(output); + return err; +} + +int snd_output_printf(snd_output_t *output, const char *format, ...) +{ + int result; + va_list args; + va_start(args, format); + result = output->ops->printf(output, format, args); + va_end(args); + return result; +} + +int snd_output_puts(snd_output_t *output, const char *str) +{ + return output->ops->puts(output, str); +} + +int snd_output_putc(snd_output_t *output, int c) +{ + return output->ops->putch(output, c); +} + +int snd_output_flush(snd_output_t *output) +{ + return output->ops->flush(output); +} + +typedef struct _snd_output_stdio { + int close; + FILE *fp; +} snd_output_stdio_t; + +int snd_output_stdio_close(snd_output_t *output ATTRIBUTE_UNUSED) +{ + snd_output_stdio_t *stdio = output->private; + if (close) + fclose(stdio->fp); + free(stdio); + return 0; +} + +int snd_output_stdio_printf(snd_output_t *output, const char *format, va_list args) +{ + snd_output_stdio_t *stdio = output->private; + return vfprintf(stdio->fp, format, args); +} + +int snd_output_stdio_puts(snd_output_t *output, const char *str) +{ + snd_output_stdio_t *stdio = output->private; + return fputs(str, stdio->fp); +} + +int snd_output_stdio_putc(snd_output_t *output, int c) +{ + snd_output_stdio_t *stdio = output->private; + return putc(c, stdio->fp); +} + +int snd_output_stdio_flush(snd_output_t *output) +{ + snd_output_stdio_t *stdio = output->private; + return fflush(stdio->fp); +} + +snd_output_ops_t snd_output_stdio_ops = { + close: snd_output_stdio_close, + printf: snd_output_stdio_printf, + puts: snd_output_stdio_puts, + putch: snd_output_stdio_putc, + flush: snd_output_stdio_flush, +}; + +int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int close) +{ + snd_output_t *output; + snd_output_stdio_t *stdio; + assert(outputp && fp); + stdio = calloc(1, sizeof(*stdio)); + if (!stdio) + return -ENOMEM; + output = calloc(1, sizeof(*output)); + if (!output) { + free(stdio); + return -ENOMEM; + } + stdio->fp = fp; + stdio->close = close; + output->type = SND_OUTPUT_STDIO; + output->ops = &snd_output_stdio_ops; + output->private = stdio; + *outputp = output; + return 0; +} + +int snd_output_stdio_open(snd_output_t **outputp, const char *file) +{ + int err; + FILE *fp = fopen(file, "w"); + if (!fp) { + SYSERR("fopen"); + return -errno; + } + err = snd_output_stdio_attach(outputp, fp, 1); + if (err < 0) + fclose(fp); + return err; +} + +typedef struct _snd_output_buffer { + unsigned char *buf; + size_t alloc; + size_t size; +} snd_output_buffer_t; + +int snd_output_buffer_close(snd_output_t *output ATTRIBUTE_UNUSED) +{ + snd_output_buffer_t *buffer = output->private; + free(buffer->buf); + free(buffer); + return 0; +} + +int snd_output_buffer_need(snd_output_t *output, size_t size) +{ + snd_output_buffer_t *buffer = output->private; + size_t free = buffer->alloc - buffer->size; + size_t alloc; + if (free >= size) + return free; + if (buffer->alloc == 0) + alloc = 256; + else + alloc = buffer->alloc * 2; + buffer->buf = realloc(buffer->buf, alloc); + if (!buffer->buf) + return -ENOMEM; + buffer->alloc = alloc; + return buffer->alloc - buffer->size; +} + +int snd_output_buffer_printf(snd_output_t *output, const char *format, va_list args) +{ + snd_output_buffer_t *buffer = output->private; + size_t size = 256; + int result; + result = snd_output_buffer_need(output, size); + if (result < 0) + return result; + result = vsnprintf(buffer->buf + buffer->size, size, format, args); + assert(result >= 0); + if ((size_t)result <= size) { + buffer->size += result; + return result; + } + size = result; + result = snd_output_buffer_need(output, size); + if (result < 0) + return result; + result = vsprintf(buffer->buf + buffer->size, format, args); + assert(result == (int)size); + return result; +} + +int snd_output_buffer_puts(snd_output_t *output, const char *str) +{ + snd_output_buffer_t *buffer = output->private; + size_t size = strlen(str); + int err; + err = snd_output_buffer_need(output, size); + if (err < 0) + return err; + memcpy(buffer->buf + buffer->size, str, size); + buffer->size += size; + return size; +} + +int snd_output_buffer_putc(snd_output_t *output, int c) +{ + snd_output_buffer_t *buffer = output->private; + int err; + err = snd_output_buffer_need(output, 1); + if (err < 0) + return err; + buffer->buf[buffer->size++] = c; + return 0; +} + +int snd_output_buffer_flush(snd_output_t *output ATTRIBUTE_UNUSED) +{ + snd_output_buffer_t *buffer = output->private; + buffer->size = 0; + return 0; +} + +size_t snd_output_buffer_string(snd_output_t *output, char **buf) +{ + snd_output_buffer_t *buffer = output->private; + *buf = buffer->buf; + return buffer->size; +} + +snd_output_ops_t snd_output_buffer_ops = { + close: snd_output_buffer_close, + printf: snd_output_buffer_printf, + puts: snd_output_buffer_puts, + putch: snd_output_buffer_putc, + flush: snd_output_buffer_flush, +}; + +int snd_output_buffer_open(snd_output_t **outputp) +{ + snd_output_t *output; + snd_output_buffer_t *buffer; + assert(outputp); + buffer = calloc(1, sizeof(*buffer)); + if (!buffer) + return -ENOMEM; + output = calloc(1, sizeof(*output)); + if (!output) { + free(buffer); + return -ENOMEM; + } + buffer->buf = NULL; + buffer->alloc = 0; + buffer->size = 0; + output->type = SND_OUTPUT_BUFFER; + output->ops = &snd_output_buffer_ops; + output->private = buffer; + *outputp = output; + return 0; +} + diff --git a/src/pcm/interval.c b/src/pcm/interval.c index 0e2793b9..fb39af3d 100644 --- a/src/pcm/interval.c +++ b/src/pcm/interval.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include "asoundlib.h" #include "interval.h" static inline void div64_32(u_int64_t *n, u_int32_t div, u_int32_t *rem) @@ -352,18 +352,18 @@ void interval_mulkdiv(const interval_t *a, unsigned int k, c->integer = 0; } -void interval_print(const interval_t *i, FILE *fp) +void interval_print(const interval_t *i, snd_output_t *out) { if (interval_empty(i)) - fprintf(fp, "NONE"); + snd_output_printf(out, "NONE"); else if (i->min == 0 && i->openmin == 0 && i->max == UINT_MAX && i->openmax == 0) - fprintf(fp, "ALL"); + snd_output_printf(out, "ALL"); else if (interval_single(i)) - fprintf(fp, "%u", interval_value(i)); + snd_output_printf(out, "%u", interval_value(i)); else - fprintf(fp, "%c%u %u%c", - i->openmin ? '(' : '[', - i->min, i->max, - i->openmax ? ')' : ']'); + snd_output_printf(out, "%c%u %u%c", + i->openmin ? '(' : '[', + i->min, i->max, + i->openmax ? ')' : ']'); } diff --git a/src/pcm/interval.h b/src/pcm/interval.h index 2f549b42..751cd11d 100644 --- a/src/pcm/interval.h +++ b/src/pcm/interval.h @@ -49,7 +49,7 @@ void interval_muldivk(const interval_t *a, const interval_t *b, unsigned int k, interval_t *c); void interval_mulkdiv(const interval_t *a, unsigned int k, const interval_t *b, interval_t *c); -void interval_print(const interval_t *i, FILE *fp); +void interval_print(const interval_t *i, snd_output_t *out); int interval_refine_min(interval_t *i, unsigned int min, int openmin); int interval_refine_max(interval_t *i, unsigned int max, int openmax); int interval_refine(interval_t *i, const interval_t *v); diff --git a/src/pcm/pcm.c b/src/pcm/pcm.c index 1a364077..9457511e 100644 --- a/src/pcm/pcm.c +++ b/src/pcm/pcm.c @@ -501,70 +501,70 @@ const char *snd_pcm_state_name(snd_pcm_state_t state) return snd_pcm_state_names[state]; } -int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, FILE *fp) +int snd_pcm_dump_hw_setup(snd_pcm_t *pcm, snd_output_t *out) { assert(pcm); - assert(fp); + assert(out); assert(pcm->setup); - fprintf(fp, "stream : %s\n", snd_pcm_stream_name(pcm->stream)); - fprintf(fp, "access : %s\n", snd_pcm_access_name(pcm->access)); - fprintf(fp, "format : %s\n", snd_pcm_format_name(pcm->format)); - fprintf(fp, "subformat : %s\n", snd_pcm_subformat_name(pcm->subformat)); - fprintf(fp, "channels : %u\n", pcm->channels); - fprintf(fp, "rate : %u\n", pcm->rate); - fprintf(fp, "exact rate : %g (%u/%u)\n", (double) pcm->rate_num / pcm->rate_den, pcm->rate_num, pcm->rate_den); - fprintf(fp, "msbits : %u\n", pcm->msbits); - fprintf(fp, "buffer_size : %lu\n", pcm->buffer_size); - fprintf(fp, "period_size : %lu\n", pcm->period_size); - fprintf(fp, "period_time : %u\n", pcm->period_time); - fprintf(fp, "tick_time : %u\n", pcm->tick_time); + snd_output_printf(out, "stream : %s\n", snd_pcm_stream_name(pcm->stream)); + snd_output_printf(out, "access : %s\n", snd_pcm_access_name(pcm->access)); + snd_output_printf(out, "format : %s\n", snd_pcm_format_name(pcm->format)); + snd_output_printf(out, "subformat : %s\n", snd_pcm_subformat_name(pcm->subformat)); + snd_output_printf(out, "channels : %u\n", pcm->channels); + snd_output_printf(out, "rate : %u\n", pcm->rate); + snd_output_printf(out, "exact rate : %g (%u/%u)\n", (double) pcm->rate_num / pcm->rate_den, pcm->rate_num, pcm->rate_den); + snd_output_printf(out, "msbits : %u\n", pcm->msbits); + snd_output_printf(out, "buffer_size : %lu\n", pcm->buffer_size); + snd_output_printf(out, "period_size : %lu\n", pcm->period_size); + snd_output_printf(out, "period_time : %u\n", pcm->period_time); + snd_output_printf(out, "tick_time : %u\n", pcm->tick_time); return 0; } -int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, FILE *fp) +int snd_pcm_dump_sw_setup(snd_pcm_t *pcm, snd_output_t *out) { assert(pcm); - assert(fp); + assert(out); assert(pcm->setup); - fprintf(fp, "start_mode : %s\n", snd_pcm_start_mode_name(pcm->start_mode)); - fprintf(fp, "xrun_mode : %s\n", snd_pcm_xrun_mode_name(pcm->xrun_mode)); - fprintf(fp, "tstamp_mode : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode)); - fprintf(fp, "period_step : %ld\n", (long)pcm->period_step); - fprintf(fp, "sleep_min : %ld\n", (long)pcm->sleep_min); - fprintf(fp, "avail_min : %ld\n", (long)pcm->avail_min); - fprintf(fp, "xfer_align : %ld\n", (long)pcm->xfer_align); - fprintf(fp, "silence_threshold: %ld\n", (long)pcm->silence_threshold); - fprintf(fp, "silence_size : %ld\n", (long)pcm->silence_size); - fprintf(fp, "boundary : %ld\n", (long)pcm->boundary); + snd_output_printf(out, "start_mode : %s\n", snd_pcm_start_mode_name(pcm->start_mode)); + snd_output_printf(out, "xrun_mode : %s\n", snd_pcm_xrun_mode_name(pcm->xrun_mode)); + snd_output_printf(out, "tstamp_mode : %s\n", snd_pcm_tstamp_mode_name(pcm->tstamp_mode)); + snd_output_printf(out, "period_step : %ld\n", (long)pcm->period_step); + snd_output_printf(out, "sleep_min : %ld\n", (long)pcm->sleep_min); + snd_output_printf(out, "avail_min : %ld\n", (long)pcm->avail_min); + snd_output_printf(out, "xfer_align : %ld\n", (long)pcm->xfer_align); + snd_output_printf(out, "silence_threshold: %ld\n", (long)pcm->silence_threshold); + snd_output_printf(out, "silence_size : %ld\n", (long)pcm->silence_size); + snd_output_printf(out, "boundary : %ld\n", (long)pcm->boundary); return 0; } -int snd_pcm_dump_setup(snd_pcm_t *pcm, FILE *fp) +int snd_pcm_dump_setup(snd_pcm_t *pcm, snd_output_t *out) { - snd_pcm_dump_hw_setup(pcm, fp); - snd_pcm_dump_sw_setup(pcm, fp); + snd_pcm_dump_hw_setup(pcm, out); + snd_pcm_dump_sw_setup(pcm, out); return 0; } -int snd_pcm_status_dump(snd_pcm_status_t *status, FILE *fp) +int snd_pcm_status_dump(snd_pcm_status_t *status, snd_output_t *out) { assert(status); - fprintf(fp, "state : %s\n", snd_pcm_state_name(status->state)); - fprintf(fp, "trigger_time: %ld.%06ld\n", + snd_output_printf(out, "state : %s\n", snd_pcm_state_name(status->state)); + snd_output_printf(out, "trigger_time: %ld.%06ld\n", status->trigger_time.tv_sec, status->trigger_time.tv_usec); - fprintf(fp, "tstamp : %ld.%06ld\n", + snd_output_printf(out, "tstamp : %ld.%06ld\n", status->tstamp.tv_sec, status->tstamp.tv_usec); - fprintf(fp, "delay : %ld\n", (long)status->delay); - fprintf(fp, "avail : %ld\n", (long)status->avail); - fprintf(fp, "avail_max : %ld\n", (long)status->avail_max); + snd_output_printf(out, "delay : %ld\n", (long)status->delay); + snd_output_printf(out, "avail : %ld\n", (long)status->avail); + snd_output_printf(out, "avail_max : %ld\n", (long)status->avail_max); return 0; } -int snd_pcm_dump(snd_pcm_t *pcm, FILE *fp) +int snd_pcm_dump(snd_pcm_t *pcm, snd_output_t *out) { assert(pcm); - assert(fp); - pcm->ops->dump(pcm->op_arg, fp); + assert(out); + pcm->ops->dump(pcm->op_arg, out); return 0; } diff --git a/src/pcm/pcm_adpcm.c b/src/pcm/pcm_adpcm.c index d31170e3..0e56a856 100644 --- a/src/pcm/pcm_adpcm.c +++ b/src/pcm/pcm_adpcm.c @@ -530,17 +530,17 @@ static snd_pcm_sframes_t snd_pcm_adpcm_read_areas(snd_pcm_t *pcm, return err; } -static void snd_pcm_adpcm_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_adpcm_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_adpcm_t *adpcm = pcm->private; - fprintf(fp, "Ima-ADPCM conversion PCM (%s)\n", + snd_output_printf(out, "Ima-ADPCM conversion PCM (%s)\n", snd_pcm_format_name(adpcm->sformat)); if (pcm->setup) { - fprintf(fp, "Its setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "Its setup is:\n"); + snd_pcm_dump_setup(pcm, out); } - fprintf(fp, "Slave: "); - snd_pcm_dump(adpcm->plug.slave, fp); + snd_output_printf(out, "Slave: "); + snd_pcm_dump(adpcm->plug.slave, out); } snd_pcm_ops_t snd_pcm_adpcm_ops = { diff --git a/src/pcm/pcm_alaw.c b/src/pcm/pcm_alaw.c index a4167a60..df11d7c6 100644 --- a/src/pcm/pcm_alaw.c +++ b/src/pcm/pcm_alaw.c @@ -398,17 +398,17 @@ static snd_pcm_sframes_t snd_pcm_alaw_read_areas(snd_pcm_t *pcm, return err; } -static void snd_pcm_alaw_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_alaw_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_alaw_t *alaw = pcm->private; - fprintf(fp, "A-Law conversion PCM (%s)\n", + snd_output_printf(out, "A-Law conversion PCM (%s)\n", snd_pcm_format_name(alaw->sformat)); if (pcm->setup) { - fprintf(fp, "Its setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "Its setup is:\n"); + snd_pcm_dump_setup(pcm, out); } - fprintf(fp, "Slave: "); - snd_pcm_dump(alaw->plug.slave, fp); + snd_output_printf(out, "Slave: "); + snd_pcm_dump(alaw->plug.slave, out); } snd_pcm_ops_t snd_pcm_alaw_ops = { diff --git a/src/pcm/pcm_copy.c b/src/pcm/pcm_copy.c index d5773dce..f04cbb9a 100644 --- a/src/pcm/pcm_copy.c +++ b/src/pcm/pcm_copy.c @@ -155,16 +155,16 @@ static snd_pcm_sframes_t snd_pcm_copy_read_areas(snd_pcm_t *pcm, return err; } -static void snd_pcm_copy_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_copy_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_copy_t *copy = pcm->private; - fprintf(fp, "Copy conversion PCM\n"); + snd_output_printf(out, "Copy conversion PCM\n"); if (pcm->setup) { - fprintf(fp, "Its setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "Its setup is:\n"); + snd_pcm_dump_setup(pcm, out); } - fprintf(fp, "Slave: "); - snd_pcm_dump(copy->plug.slave, fp); + snd_output_printf(out, "Slave: "); + snd_pcm_dump(copy->plug.slave, out); } snd_pcm_ops_t snd_pcm_copy_ops = { diff --git a/src/pcm/pcm_file.c b/src/pcm/pcm_file.c index 3da9043f..d5cb5885 100644 --- a/src/pcm/pcm_file.c +++ b/src/pcm/pcm_file.c @@ -357,19 +357,19 @@ static int snd_pcm_file_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) return 0; } -static void snd_pcm_file_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_file_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_file_t *file = pcm->private; if (file->fname) - fprintf(fp, "File PCM (file=%s)\n", file->fname); + snd_output_printf(out, "File PCM (file=%s)\n", file->fname); else - fprintf(fp, "File PCM (fd=%d)\n", file->fd); + snd_output_printf(out, "File PCM (fd=%d)\n", file->fd); if (pcm->setup) { - fprintf(fp, "Its setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "Its setup is:\n"); + snd_pcm_dump_setup(pcm, out); } - fprintf(fp, "Slave: "); - snd_pcm_dump(file->slave, fp); + snd_output_printf(out, "Slave: "); + snd_pcm_dump(file->slave, out); } snd_pcm_ops_t snd_pcm_file_ops = { diff --git a/src/pcm/pcm_hw.c b/src/pcm/pcm_hw.c index f64e037f..51701127 100644 --- a/src/pcm/pcm_hw.c +++ b/src/pcm/pcm_hw.c @@ -488,17 +488,17 @@ static snd_pcm_sframes_t snd_pcm_hw_avail_update(snd_pcm_t *pcm) return avail; } -static void snd_pcm_hw_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_hw_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_hw_t *hw = pcm->private; char *name = "Unknown"; snd_card_get_name(hw->card, &name); - fprintf(fp, "Hardware PCM card %d '%s' device %d subdevice %d\n", + snd_output_printf(out, "Hardware PCM card %d '%s' device %d subdevice %d\n", hw->card, name, hw->device, hw->subdevice); free(name); if (pcm->setup) { - fprintf(fp, "\nIts setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "\nIts setup is:\n"); + snd_pcm_dump_setup(pcm, out); } } diff --git a/src/pcm/pcm_linear.c b/src/pcm/pcm_linear.c index 1d331338..ca028bcd 100644 --- a/src/pcm/pcm_linear.c +++ b/src/pcm/pcm_linear.c @@ -237,17 +237,17 @@ static snd_pcm_sframes_t snd_pcm_linear_read_areas(snd_pcm_t *pcm, return err; } -static void snd_pcm_linear_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_linear_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_linear_t *linear = pcm->private; - fprintf(fp, "Linear conversion PCM (%s)\n", + snd_output_printf(out, "Linear conversion PCM (%s)\n", snd_pcm_format_name(linear->sformat)); if (pcm->setup) { - fprintf(fp, "Its setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "Its setup is:\n"); + snd_pcm_dump_setup(pcm, out); } - fprintf(fp, "Slave: "); - snd_pcm_dump(linear->plug.slave, fp); + snd_output_printf(out, "Slave: "); + snd_pcm_dump(linear->plug.slave, out); } snd_pcm_ops_t snd_pcm_linear_ops = { diff --git a/src/pcm/pcm_local.h b/src/pcm/pcm_local.h index 5338b8a3..6ffc08e8 100644 --- a/src/pcm/pcm_local.h +++ b/src/pcm/pcm_local.h @@ -57,7 +57,7 @@ typedef struct { int (*hw_params)(snd_pcm_t *pcm, snd_pcm_hw_params_t *params); int (*sw_params)(snd_pcm_t *pcm, snd_pcm_sw_params_t *params); int (*channel_info)(snd_pcm_t *pcm, snd_pcm_channel_info_t *info); - void (*dump)(snd_pcm_t *pcm, FILE *fp); + void (*dump)(snd_pcm_t *pcm, snd_output_t *out); int (*mmap)(snd_pcm_t *pcm); int (*munmap)(snd_pcm_t *pcm); } snd_pcm_ops_t; diff --git a/src/pcm/pcm_mulaw.c b/src/pcm/pcm_mulaw.c index 5904c5ae..c1a7ccb8 100644 --- a/src/pcm/pcm_mulaw.c +++ b/src/pcm/pcm_mulaw.c @@ -415,17 +415,17 @@ static snd_pcm_sframes_t snd_pcm_mulaw_read_areas(snd_pcm_t *pcm, return err; } -static void snd_pcm_mulaw_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_mulaw_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_mulaw_t *mulaw = pcm->private; - fprintf(fp, "Mu-Law conversion PCM (%s)\n", + snd_output_printf(out, "Mu-Law conversion PCM (%s)\n", snd_pcm_format_name(mulaw->sformat)); if (pcm->setup) { - fprintf(fp, "Its setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "Its setup is:\n"); + snd_pcm_dump_setup(pcm, out); } - fprintf(fp, "Slave: "); - snd_pcm_dump(mulaw->plug.slave, fp); + snd_output_printf(out, "Slave: "); + snd_pcm_dump(mulaw->plug.slave, out); } snd_pcm_ops_t snd_pcm_mulaw_ops = { diff --git a/src/pcm/pcm_multi.c b/src/pcm/pcm_multi.c index a6be1e4c..e5018f34 100644 --- a/src/pcm/pcm_multi.c +++ b/src/pcm/pcm_multi.c @@ -383,26 +383,26 @@ int snd_pcm_multi_poll_descriptor(snd_pcm_t *pcm) return snd_pcm_poll_descriptor(slave); } -static void snd_pcm_multi_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_multi_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_multi_t *multi = pcm->private; unsigned int k; - fprintf(fp, "Multi PCM\n"); - fprintf(fp, "\nChannel bindings:\n"); + snd_output_printf(out, "Multi PCM\n"); + snd_output_printf(out, "\nChannel bindings:\n"); for (k = 0; k < multi->channels_count; ++k) { snd_pcm_multi_channel_t *c = &multi->channels[k]; if (c->slave_idx < 0) continue; - fprintf(fp, "%d: slave %d, channel %d\n", + snd_output_printf(out, "%d: slave %d, channel %d\n", k, c->slave_idx, c->slave_channel); } if (pcm->setup) { - fprintf(fp, "\nIts setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "\nIts setup is:\n"); + snd_pcm_dump_setup(pcm, out); } for (k = 0; k < multi->slaves_count; ++k) { - fprintf(fp, "\nSlave #%d: ", k); - snd_pcm_dump(multi->slaves[k].pcm, fp); + snd_output_printf(out, "\nSlave #%d: ", k); + snd_pcm_dump(multi->slaves[k].pcm, out); } } diff --git a/src/pcm/pcm_null.c b/src/pcm/pcm_null.c index f2e6e148..1007a9d0 100644 --- a/src/pcm/pcm_null.c +++ b/src/pcm/pcm_null.c @@ -271,12 +271,12 @@ static int snd_pcm_null_munmap(snd_pcm_t *pcm) return 0; } -static void snd_pcm_null_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_null_dump(snd_pcm_t *pcm, snd_output_t *out) { - fprintf(fp, "Null PCM\n"); + snd_output_printf(out, "Null PCM\n"); if (pcm->setup) { - fprintf(fp, "Its setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "Its setup is:\n"); + snd_pcm_dump_setup(pcm, out); } } diff --git a/src/pcm/pcm_params.c b/src/pcm/pcm_params.c index 90a7920d..7bbcab75 100644 --- a/src/pcm/pcm_params.c +++ b/src/pcm/pcm_params.c @@ -1117,7 +1117,7 @@ void snd_pcm_hw_param_copy(snd_pcm_hw_params_t *params, snd_pcm_hw_param_t var, } void snd_pcm_hw_param_dump(const snd_pcm_hw_params_t *params, - snd_pcm_hw_param_t var, FILE *fp) + snd_pcm_hw_param_t var, snd_output_t *out) { static const char *(*funcs[])(unsigned int k) = { [SND_PCM_HW_PARAM_ACCESS] = snd_pcm_access_name, @@ -1127,9 +1127,9 @@ void snd_pcm_hw_param_dump(const snd_pcm_hw_params_t *params, if (hw_is_mask(var)) { const mask_t *mask = hw_param_mask_c(params, var); if (mask_empty(mask)) - fputs(" NONE", fp); + snd_output_puts(out, " NONE"); else if (mask_full(mask)) - fputs(" ALL", fp); + snd_output_puts(out, " ALL"); else { unsigned int k; const char *(*f)(unsigned int k); @@ -1138,27 +1138,27 @@ void snd_pcm_hw_param_dump(const snd_pcm_hw_params_t *params, assert(f); for (k = 0; k <= MASK_MAX; ++k) { if (mask_test(mask, k)) { - putc(' ', fp); - fputs(f(k), fp); + snd_output_putc(out, ' '); + snd_output_puts(out, f(k)); } } } return; } if (hw_is_interval(var)) { - interval_print(hw_param_interval_c(params, var), fp); + interval_print(hw_param_interval_c(params, var), out); return; } assert(0); } -int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, FILE *fp) +int snd_pcm_hw_params_dump(snd_pcm_hw_params_t *params, snd_output_t *out) { unsigned int k; for (k = 0; k <= SND_PCM_HW_PARAM_LAST; k++) { - fprintf(fp, "%s: ", snd_pcm_hw_param_name(k)); - snd_pcm_hw_param_dump(params, k, fp); - putc('\n', fp); + snd_output_printf(out, "%s: ", snd_pcm_hw_param_name(k)); + snd_pcm_hw_param_dump(params, k, out); + snd_output_putc(out, '\n'); } return 0; } @@ -1466,7 +1466,7 @@ int snd_pcm_hw_params_try_explain_failure1(snd_pcm_t *pcm, snd_pcm_hw_params_t *fail, snd_pcm_hw_params_t *success, unsigned int depth, - FILE *fp) + snd_output_t *out) { snd_pcm_hw_param_t var; snd_pcm_hw_params_t i; @@ -1478,11 +1478,11 @@ int snd_pcm_hw_params_try_explain_failure1(snd_pcm_t *pcm, snd_pcm_hw_param_copy(&i, var, fail); err = snd_pcm_hw_refine(pcm, &i); if (err == 0 && - snd_pcm_hw_params_try_explain_failure1(pcm, fail, &i, depth - 1, fp) < 0) + snd_pcm_hw_params_try_explain_failure1(pcm, fail, &i, depth - 1, out) < 0) continue; - fprintf(fp, "%s: ", snd_pcm_hw_param_name(var)); - snd_pcm_hw_param_dump(fail, var, fp); - putc('\n', fp); + snd_output_printf(out, "%s: ", snd_pcm_hw_param_name(var)); + snd_pcm_hw_param_dump(fail, var, out); + snd_output_putc(out, '\n'); return 0; } return -ENOENT; @@ -1492,7 +1492,7 @@ int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm, snd_pcm_hw_params_t *fail, snd_pcm_hw_params_t *success, unsigned int depth, - FILE *fp) + snd_output_t *out) { snd_pcm_hw_params_t i, any; int err; @@ -1502,7 +1502,7 @@ int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm, for (var = 0; var <= SND_PCM_HW_PARAM_LAST; var++) { if (!snd_pcm_hw_param_empty(fail, var)) continue; - fprintf(fp, "%s is empty\n", snd_pcm_hw_param_name(var)); + snd_output_printf(out, "%s is empty\n", snd_pcm_hw_param_name(var)); done = 1; } if (done) @@ -1510,14 +1510,14 @@ int snd_pcm_hw_params_try_explain_failure(snd_pcm_t *pcm, i = *fail; err = snd_pcm_hw_refine(pcm, &i); if (err == 0) { - fprintf(fp, "Configuration is virtually correct\n"); + snd_output_printf(out, "Configuration is virtually correct\n"); return 0; } if (!success) { snd_pcm_hw_params_any(pcm, &any); success = &any; } - return snd_pcm_hw_params_try_explain_failure1(pcm, fail, success, depth, fp); + return snd_pcm_hw_params_try_explain_failure1(pcm, fail, success, depth, out); } typedef struct _snd_pcm_hw_rule snd_pcm_hw_rule_t; @@ -2151,48 +2151,48 @@ int snd_pcm_sw_param_near(snd_pcm_t *pcm, snd_pcm_sw_params_t *params, } void snd_pcm_sw_param_dump(const snd_pcm_sw_params_t *params, - snd_pcm_sw_param_t var, FILE *fp) + snd_pcm_sw_param_t var, snd_output_t *out) { switch (var) { case SND_PCM_SW_PARAM_START_MODE: - fputs(snd_pcm_start_mode_name(params->start_mode), fp); + snd_output_puts(out, snd_pcm_start_mode_name(params->start_mode)); break; case SND_PCM_SW_PARAM_XRUN_MODE: - fputs(snd_pcm_xrun_mode_name(params->xrun_mode), fp); + snd_output_puts(out, snd_pcm_xrun_mode_name(params->xrun_mode)); break; case SND_PCM_SW_PARAM_TSTAMP_MODE: - fputs(snd_pcm_tstamp_mode_name(params->tstamp_mode), fp); + snd_output_puts(out, snd_pcm_tstamp_mode_name(params->tstamp_mode)); break; case SND_PCM_SW_PARAM_PERIOD_STEP: - fprintf(fp, "%d", params->period_step); + snd_output_printf(out, "%d", params->period_step); break; case SND_PCM_SW_PARAM_SLEEP_MIN: - fprintf(fp, "%d", params->sleep_min); + snd_output_printf(out, "%d", params->sleep_min); break; case SND_PCM_SW_PARAM_AVAIL_MIN: - fprintf(fp, "%ld", (long) params->avail_min); + snd_output_printf(out, "%ld", (long) params->avail_min); break; case SND_PCM_SW_PARAM_XFER_ALIGN: - fprintf(fp, "%ld", (long) params->xfer_align); + snd_output_printf(out, "%ld", (long) params->xfer_align); break; case SND_PCM_SW_PARAM_SILENCE_THRESHOLD: - fprintf(fp, "%ld", (long) params->silence_threshold); + snd_output_printf(out, "%ld", (long) params->silence_threshold); break; case SND_PCM_SW_PARAM_SILENCE_SIZE: - fprintf(fp, "%ld", (long) params->silence_size); + snd_output_printf(out, "%ld", (long) params->silence_size); break; default: assert(0); } } -int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, FILE *fp) +int snd_pcm_sw_params_dump(snd_pcm_sw_params_t *params, snd_output_t *out) { unsigned int k; for (k = 0; k <= SND_PCM_SW_PARAM_LAST; k++) { - fprintf(fp, "%s: ", snd_pcm_sw_param_name(k)); - snd_pcm_sw_param_dump(params, k, fp); - putc('\n', fp); + snd_output_printf(out, "%s: ", snd_pcm_sw_param_name(k)); + snd_pcm_sw_param_dump(params, k, out); + snd_output_putc(out, '\n'); } return 0; } diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index 4fb45f6b..9c6bc2fb 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -365,19 +365,7 @@ static int snd_pcm_plug_hw_refine1(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, static int snd_pcm_plug_hw_refine(snd_pcm_t *pcm, snd_pcm_hw_params_t *params) { snd_pcm_hw_params_t sparams; - int err; -#if 0 - fprintf(stderr, "Enter: client =\n"); - snd_pcm_hw_params_dump(params, stderr); -#endif - err = snd_pcm_plug_hw_refine1(pcm, params, &sparams); -#if 0 - fprintf(stderr, "Exit: client =\n"); - snd_pcm_hw_params_dump(params, stderr); - fprintf(stderr, "Exit: slave =\n"); - snd_pcm_hw_params_dump(&sparams, stderr); -#endif - return err; + return snd_pcm_plug_hw_refine1(pcm, params, &sparams); } static void snd_pcm_plug_clear(snd_pcm_t *pcm) @@ -670,11 +658,11 @@ static int snd_pcm_plug_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) return 0; } -static void snd_pcm_plug_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_plug_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_plug_t *plug = pcm->private; - fprintf(fp, "Plug PCM: "); - snd_pcm_dump(plug->slave, fp); + snd_output_printf(out, "Plug PCM: "); + snd_pcm_dump(plug->slave, out); } snd_pcm_ops_t snd_pcm_plug_ops = { diff --git a/src/pcm/pcm_rate.c b/src/pcm/pcm_rate.c index 23be3f4e..aacdf344 100644 --- a/src/pcm/pcm_rate.c +++ b/src/pcm/pcm_rate.c @@ -531,22 +531,22 @@ snd_pcm_sframes_t snd_pcm_rate_slave_frames(snd_pcm_t *pcm, snd_pcm_sframes_t fr return muldiv_down(frames, DIV, rate->pitch); } -static void snd_pcm_rate_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_rate_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_rate_t *rate = pcm->private; if (rate->sformat < 0) - fprintf(fp, "Rate conversion PCM (%d)\n", + snd_output_printf(out, "Rate conversion PCM (%d)\n", rate->srate); else - fprintf(fp, "Rate conversion PCM (%d, sformat=%s)\n", + snd_output_printf(out, "Rate conversion PCM (%d, sformat=%s)\n", rate->srate, snd_pcm_format_name(rate->sformat)); if (pcm->setup) { - fprintf(fp, "Its setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "Its setup is:\n"); + snd_pcm_dump_setup(pcm, out); } - fprintf(fp, "Slave: "); - snd_pcm_dump(rate->plug.slave, fp); + snd_output_printf(out, "Slave: "); + snd_pcm_dump(rate->plug.slave, out); } snd_pcm_ops_t snd_pcm_rate_ops = { diff --git a/src/pcm/pcm_route.c b/src/pcm/pcm_route.c index 761cb82a..01b209ed 100644 --- a/src/pcm/pcm_route.c +++ b/src/pcm/pcm_route.c @@ -633,42 +633,42 @@ static snd_pcm_sframes_t snd_pcm_route_read_areas(snd_pcm_t *pcm, return err; } -static void snd_pcm_route_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_route_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_route_t *route = pcm->private; unsigned int dst; if (route->sformat < 0) - fprintf(fp, "Route conversion PCM\n"); + snd_output_printf(out, "Route conversion PCM\n"); else - fprintf(fp, "Route conversion PCM (sformat=%s)\n", + snd_output_printf(out, "Route conversion PCM (sformat=%s)\n", snd_pcm_format_name(route->sformat)); - fputs("Transformation table:\n", fp); + snd_output_puts(out, "Transformation table:\n"); for (dst = 0; dst < route->params.ndsts; dst++) { ttable_dst_t *d = &route->params.dsts[dst]; unsigned int src; if (d->nsrcs == 0) continue; - fprintf(fp, "%d <- ", dst); + snd_output_printf(out, "%d <- ", dst); src = 0; while (1) { ttable_src_t *s = &d->srcs[src]; if (d->att) - fprintf(fp, "%d*%g", s->channel, s->as_float); + snd_output_printf(out, "%d*%g", s->channel, s->as_float); else - fprintf(fp, "%d", s->channel); + snd_output_printf(out, "%d", s->channel); src++; if (src == d->nsrcs) break; - fputs(" + ", fp); + snd_output_puts(out, " + "); } - putc('\n', fp); + snd_output_putc(out, '\n'); } if (pcm->setup) { - fprintf(fp, "Its setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "Its setup is:\n"); + snd_pcm_dump_setup(pcm, out); } - fprintf(fp, "Slave: "); - snd_pcm_dump(route->plug.slave, fp); + snd_output_printf(out, "Slave: "); + snd_pcm_dump(route->plug.slave, out); } snd_pcm_ops_t snd_pcm_route_ops = { diff --git a/src/pcm/pcm_share.c b/src/pcm/pcm_share.c index 99fa5b71..eb67950c 100644 --- a/src/pcm/pcm_share.c +++ b/src/pcm/pcm_share.c @@ -1071,21 +1071,21 @@ static int snd_pcm_share_munmap(snd_pcm_t *pcm ATTRIBUTE_UNUSED) return 0; } -static void snd_pcm_share_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_share_dump(snd_pcm_t *pcm, snd_output_t *out) { snd_pcm_share_t *share = pcm->private; snd_pcm_share_slave_t *slave = share->slave; unsigned int k; - fprintf(fp, "Share PCM\n"); - fprintf(fp, "\nChannel bindings:\n"); + snd_output_printf(out, "Share PCM\n"); + snd_output_printf(out, "\nChannel bindings:\n"); for (k = 0; k < share->channels_count; ++k) - fprintf(fp, "%d: %d\n", k, share->slave_channels[k]); + snd_output_printf(out, "%d: %d\n", k, share->slave_channels[k]); if (pcm->setup) { - fprintf(fp, "\nIts setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "\nIts setup is:\n"); + snd_pcm_dump_setup(pcm, out); } - fprintf(fp, "Slave: "); - snd_pcm_dump(slave->pcm, fp); + snd_output_printf(out, "Slave: "); + snd_pcm_dump(slave->pcm, out); } snd_pcm_ops_t snd_pcm_share_ops = { diff --git a/src/pcm/pcm_shm.c b/src/pcm/pcm_shm.c index 1da7f338..65e4e6f8 100644 --- a/src/pcm/pcm_shm.c +++ b/src/pcm/pcm_shm.c @@ -91,7 +91,7 @@ static int snd_pcm_shm_action(snd_pcm_t *pcm) if (err != 1) return -EBADFD; if (ctrl->cmd) { - fprintf(stderr, "Server has not done the cmd\n"); + ERR("Server has not done the cmd"); return -EBADFD; } return ctrl->result; @@ -110,7 +110,7 @@ static int snd_pcm_shm_action_fd(snd_pcm_t *pcm, int *fd) if (err != 1) return -EBADFD; if (ctrl->cmd) { - fprintf(stderr, "Server has not done the cmd\n"); + ERR("Server has not done the cmd"); return -EBADFD; } return ctrl->result; @@ -463,12 +463,12 @@ static int snd_pcm_shm_close(snd_pcm_t *pcm) return result; } -static void snd_pcm_shm_dump(snd_pcm_t *pcm, FILE *fp) +static void snd_pcm_shm_dump(snd_pcm_t *pcm, snd_output_t *out) { - fprintf(fp, "Shm PCM\n"); + snd_output_printf(out, "Shm PCM\n"); if (pcm->setup) { - fprintf(fp, "\nIts setup is:\n"); - snd_pcm_dump_setup(pcm, fp); + snd_output_printf(out, "\nIts setup is:\n"); + snd_pcm_dump_setup(pcm, out); } } -- 2.47.1