mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Documented input, output and conf
This commit is contained in:
parent
ddc9a186cf
commit
4bee8c5678
8 changed files with 587 additions and 301 deletions
|
|
@ -1,23 +1,19 @@
|
|||
|
||||
enum _snd_config_type {
|
||||
/** Config node type */
|
||||
typedef enum _snd_config_type {
|
||||
/** Integer number */
|
||||
SND_CONFIG_TYPE_INTEGER,
|
||||
/** Real number */
|
||||
SND_CONFIG_TYPE_REAL,
|
||||
/** Character string */
|
||||
SND_CONFIG_TYPE_STRING,
|
||||
/** Compound */
|
||||
SND_CONFIG_TYPE_COMPOUND,
|
||||
};
|
||||
|
||||
#ifdef SND_ENUM_TYPECHECK
|
||||
typedef struct __snd_config_type *snd_config_type_t;
|
||||
#else
|
||||
typedef enum _snd_config_type snd_config_type_t;
|
||||
#endif
|
||||
|
||||
#define SND_CONFIG_TYPE_INTEGER ((snd_config_type_t) SND_CONFIG_TYPE_INTEGER)
|
||||
#define SND_CONFIG_TYPE_REAL ((snd_config_type_t) SND_CONFIG_TYPE_REAL)
|
||||
#define SND_CONFIG_TYPE_STRING ((snd_config_type_t) SND_CONFIG_TYPE_STRING)
|
||||
#define SND_CONFIG_TYPE_COMPOUND ((snd_config_type_t) SND_CONFIG_TYPE_COMPOUND)
|
||||
} snd_config_type_t;
|
||||
|
||||
/** Config node handle */
|
||||
typedef struct _snd_config snd_config_t;
|
||||
/** Config compound iterator */
|
||||
typedef struct _snd_config_iterator *snd_config_iterator_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -62,6 +58,13 @@ snd_config_iterator_t snd_config_iterator_next(snd_config_iterator_t iterator);
|
|||
snd_config_iterator_t snd_config_iterator_end(snd_config_t *node);
|
||||
snd_config_t *snd_config_iterator_entry(snd_config_iterator_t iterator);
|
||||
|
||||
/** Helper for compound config node leaves traversal
|
||||
* \param pos Current node iterator
|
||||
* \param next Next node iterator
|
||||
* \param node Compound config node
|
||||
*
|
||||
* This macro is designed to permit the removal of current node.
|
||||
*/
|
||||
#define snd_config_for_each(pos, next, node) \
|
||||
for (pos = snd_config_iterator_first(node), next = snd_config_iterator_next(pos); pos != snd_config_iterator_end(node); pos = next, next = snd_config_iterator_next(pos))
|
||||
|
||||
|
|
|
|||
|
|
@ -1,19 +1,14 @@
|
|||
|
||||
/** Input handle */
|
||||
typedef struct _snd_input snd_input_t;
|
||||
|
||||
enum _snd_input_type {
|
||||
/** Input type */
|
||||
typedef enum _snd_input_type {
|
||||
/** Input from a stdio stream */
|
||||
SND_INPUT_STDIO,
|
||||
/** Input from a memory buffer */
|
||||
SND_INPUT_BUFFER,
|
||||
};
|
||||
|
||||
#ifdef SND_ENUM_TYPECHECK
|
||||
typedef struct __snd_input_type *snd_input_type_t;
|
||||
#else
|
||||
typedef enum _snd_input_type snd_input_type_t;
|
||||
#endif
|
||||
|
||||
#define SND_INPUT_STDIO ((snd_input_type_t) SND_INPUT_STDIO)
|
||||
#define SND_INPUT_BUFFER ((snd_input_type_t) SND_INPUT_BUFFER)
|
||||
} snd_input_type_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
|||
|
|
@ -1,20 +1,14 @@
|
|||
|
||||
/** Output handle */
|
||||
typedef struct _snd_output snd_output_t;
|
||||
|
||||
enum _snd_output_type {
|
||||
/** Output type */
|
||||
typedef enum _snd_output_type {
|
||||
/** Output to a stdio stream */
|
||||
SND_OUTPUT_STDIO,
|
||||
/** Output to a memory buffer */
|
||||
SND_OUTPUT_BUFFER,
|
||||
};
|
||||
|
||||
#ifdef SND_ENUM_TYPECHECK
|
||||
typedef struct __snd_output_type *snd_output_type_t;
|
||||
#else
|
||||
typedef enum _snd_output_type snd_output_type_t;
|
||||
#endif
|
||||
|
||||
#define SND_OUTPUT_STDIO ((snd_output_type_t) SND_OUTPUT_STDIO)
|
||||
#define SND_OUTPUT_BUFFER ((snd_output_type_t) SND_OUTPUT_BUFFER)
|
||||
|
||||
} snd_output_type_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
|
|||
628
src/conf.c
628
src/conf.c
|
|
@ -19,6 +19,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
#define _snd_config_iterator list_head
|
||||
|
||||
#include <stdarg.h>
|
||||
|
|
@ -42,9 +43,6 @@ struct _snd_config {
|
|||
snd_config_t *father;
|
||||
};
|
||||
|
||||
#define SYS_ASOUNDRC "/etc/asound.conf"
|
||||
#define USR_ASOUNDRC ".asoundrc"
|
||||
|
||||
struct filedesc {
|
||||
char *name;
|
||||
snd_input_t *in;
|
||||
|
|
@ -337,16 +335,6 @@ static int get_string(char **string, int id, input_t *input)
|
|||
}
|
||||
}
|
||||
|
||||
snd_config_type_t snd_config_get_type(snd_config_t *config)
|
||||
{
|
||||
return config->type;
|
||||
}
|
||||
|
||||
const char *snd_config_get_id(snd_config_t *config)
|
||||
{
|
||||
return config->id;
|
||||
}
|
||||
|
||||
static int _snd_config_make(snd_config_t **config, char *id,
|
||||
snd_config_type_t type)
|
||||
{
|
||||
|
|
@ -593,216 +581,6 @@ static int parse_defs(snd_config_t *father, input_t *input)
|
|||
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;
|
||||
}
|
||||
SNDERR("%s:%d:%d:%s", fd->name ? fd->name : "",
|
||||
fd->line, fd->column, str);
|
||||
}
|
||||
snd_config_delete(config);
|
||||
goto _end;
|
||||
}
|
||||
if (get_char(&input) != EOF) {
|
||||
SNDERR("%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, next;
|
||||
assert(father && leaf);
|
||||
snd_config_for_each(i, next, father) {
|
||||
snd_config_t *n = snd_config_iterator_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 (snd_enum_to_int(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_iterator_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, const 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_make_integer(snd_config_t **config, const char *id)
|
||||
{
|
||||
return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER);
|
||||
}
|
||||
|
||||
int snd_config_make_real(snd_config_t **config, const char *id)
|
||||
{
|
||||
return snd_config_make(config, id, SND_CONFIG_TYPE_REAL);
|
||||
}
|
||||
|
||||
int snd_config_make_string(snd_config_t **config, const char *id)
|
||||
{
|
||||
return snd_config_make(config, id, SND_CONFIG_TYPE_STRING);
|
||||
}
|
||||
|
||||
int snd_config_make_compound(snd_config_t **config, const 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_set_integer(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_set_real(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_set_string(snd_config_t *config, const 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_get_integer(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_get_real(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_get_string(snd_config_t *config, const char **ptr)
|
||||
{
|
||||
assert(config && ptr);
|
||||
if (config->type != SND_CONFIG_TYPE_STRING)
|
||||
return -EINVAL;
|
||||
*ptr = config->u.string;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void string_print(char *str, int id, snd_output_t *out)
|
||||
{
|
||||
unsigned char *p = str;
|
||||
|
|
@ -963,13 +741,348 @@ static int _snd_config_save_leaves(snd_config_t *config, snd_output_t *out, unsi
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* \brief Return type of a config node
|
||||
* \param config Config node handle
|
||||
* \return node type
|
||||
*/
|
||||
snd_config_type_t snd_config_get_type(snd_config_t *config)
|
||||
{
|
||||
return config->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return id of a config node
|
||||
* \param config Config node handle
|
||||
* \return node id
|
||||
*/
|
||||
const char *snd_config_get_id(snd_config_t *config)
|
||||
{
|
||||
return config->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Build a top level config node
|
||||
* \param configp Returned config node handle pointer
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_top(snd_config_t **configp)
|
||||
{
|
||||
assert(configp);
|
||||
return _snd_config_make(configp, 0, SND_CONFIG_TYPE_COMPOUND);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Load a config tree
|
||||
* \param config Config top node handle
|
||||
* \param in Input handle
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
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;
|
||||
}
|
||||
SNDERR("%s:%d:%d:%s", fd->name ? fd->name : "",
|
||||
fd->line, fd->column, str);
|
||||
}
|
||||
snd_config_delete(config);
|
||||
goto _end;
|
||||
}
|
||||
if (get_char(&input) != EOF) {
|
||||
SNDERR("%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;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Add a leaf to a config compound node
|
||||
* \param father Config compound node handle
|
||||
* \param leaf Leaf config node handle
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_add(snd_config_t *father, snd_config_t *leaf)
|
||||
{
|
||||
snd_config_iterator_t i, next;
|
||||
assert(father && leaf);
|
||||
snd_config_for_each(i, next, father) {
|
||||
snd_config_t *n = snd_config_iterator_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Remove a leaf config node (freeing all the related resources)
|
||||
* \param config Config node handle
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_delete(snd_config_t *config)
|
||||
{
|
||||
assert(config);
|
||||
switch (snd_enum_to_int(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_iterator_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Build a config node
|
||||
* \param configp Returned config node handle pointer
|
||||
* \param id Node id
|
||||
* \param type Node type
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_make(snd_config_t **config, const 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Build an integer config node
|
||||
* \param configp Returned config node handle pointer
|
||||
* \param id Node id
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_make_integer(snd_config_t **config, const char *id)
|
||||
{
|
||||
return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Build a real config node
|
||||
* \param configp Returned config node handle pointer
|
||||
* \param id Node id
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_make_real(snd_config_t **config, const char *id)
|
||||
{
|
||||
return snd_config_make(config, id, SND_CONFIG_TYPE_REAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Build a string config node
|
||||
* \param configp Returned config node handle pointer
|
||||
* \param id Node id
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_make_string(snd_config_t **config, const char *id)
|
||||
{
|
||||
return snd_config_make(config, id, SND_CONFIG_TYPE_STRING);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Build an empty compound config node
|
||||
* \param configp Returned config node handle pointer
|
||||
* \param id Node id
|
||||
* \param join Join flag (checked in snd_config_save to change look)
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_make_compound(snd_config_t **config, const 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Change the value of an integer config node
|
||||
* \param config Config node handle
|
||||
* \param value Value
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_set_integer(snd_config_t *config, long value)
|
||||
{
|
||||
assert(config);
|
||||
if (config->type != SND_CONFIG_TYPE_INTEGER)
|
||||
return -EINVAL;
|
||||
config->u.integer = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Change the value of a real config node
|
||||
* \param config Config node handle
|
||||
* \param value Value
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_set_real(snd_config_t *config, double value)
|
||||
{
|
||||
assert(config);
|
||||
if (config->type != SND_CONFIG_TYPE_REAL)
|
||||
return -EINVAL;
|
||||
config->u.real = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Change the value of a string config node
|
||||
* \param config Config node handle
|
||||
* \param value Value
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_set_string(snd_config_t *config, const 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the value of an integer config node
|
||||
* \param config Config node handle
|
||||
* \param ptr Returned value pointer
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_get_integer(snd_config_t *config, long *ptr)
|
||||
{
|
||||
assert(config && ptr);
|
||||
if (config->type != SND_CONFIG_TYPE_INTEGER)
|
||||
return -EINVAL;
|
||||
*ptr = config->u.integer;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the value of a real config node
|
||||
* \param config Config node handle
|
||||
* \param ptr Returned value pointer
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_get_real(snd_config_t *config, double *ptr)
|
||||
{
|
||||
assert(config && ptr);
|
||||
if (config->type != SND_CONFIG_TYPE_REAL)
|
||||
return -EINVAL;
|
||||
*ptr = config->u.real;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the value of a string config node
|
||||
* \param config Config node handle
|
||||
* \param ptr Returned value pointer
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_get_string(snd_config_t *config, const char **ptr)
|
||||
{
|
||||
assert(config && ptr);
|
||||
if (config->type != SND_CONFIG_TYPE_STRING)
|
||||
return -EINVAL;
|
||||
*ptr = config->u.string;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Dump a config tree contents
|
||||
* \param config Config node handle
|
||||
* \param out Output handle
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_save(snd_config_t *config, snd_output_t *out)
|
||||
{
|
||||
assert(config && out);
|
||||
return _snd_config_save_leaves(config, out, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Search a node inside a config tree
|
||||
* \param config Config node handle
|
||||
* \param key Dot separated search key
|
||||
* \param result Pointer to found node
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_search(snd_config_t *config, const char *key, snd_config_t **result)
|
||||
{
|
||||
assert(config && key && result);
|
||||
|
|
@ -990,6 +1103,13 @@ int snd_config_search(snd_config_t *config, const char *key, snd_config_t **resu
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Search a node inside a config tree
|
||||
* \param config Config node handle
|
||||
* \param result Pointer to found node
|
||||
* \param ... one or more concatenated dot separated search key
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_config_searchv(snd_config_t *config,
|
||||
snd_config_t **result, ...)
|
||||
{
|
||||
|
|
@ -1014,6 +1134,17 @@ int snd_config_searchv(snd_config_t *config,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Search a node inside a config tree using alias
|
||||
* \param config Config node handle
|
||||
* \param base Key base
|
||||
* \param key Key suffix
|
||||
* \param result Pointer to found node
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*
|
||||
* If base.key is found and it's a string the value found is recursively
|
||||
* tried instead of suffix.
|
||||
*/
|
||||
int snd_config_search_alias(snd_config_t *config,
|
||||
const char *base, const char *key,
|
||||
snd_config_t **result)
|
||||
|
|
@ -1029,16 +1160,29 @@ int snd_config_search_alias(snd_config_t *config,
|
|||
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;
|
||||
|
||||
/** File used for system wide ALSA configuration */
|
||||
#define SYS_ASOUNDRC "/etc/asound.conf"
|
||||
/** File resident in home directory used for user specific ALSA configuration */
|
||||
#define USR_ASOUNDRC ".asoundrc"
|
||||
|
||||
/** Config top node */
|
||||
snd_config_t *snd_config = NULL;
|
||||
|
||||
/**
|
||||
* \brief Update #snd_config rereading if needed #SYS_ASOUNDRC and #USR_ASOUNDRC
|
||||
* \return 0 if no action is needed, 1 if tree has been rebuilt otherwise a negative error code
|
||||
*
|
||||
* Warning: If config tree is reread all the string pointer and config
|
||||
* node handle previously obtained from this tree become invalid
|
||||
*/
|
||||
int snd_config_update()
|
||||
{
|
||||
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 err;
|
||||
char *usr_asoundrc = NULL;
|
||||
char *home = getenv("HOME");
|
||||
|
|
@ -1102,26 +1246,46 @@ int snd_config_update()
|
|||
usr_asoundrc_inode = usr_st.st_ino;
|
||||
usr_asoundrc_mtime = usr_st.st_mtime;
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return an iterator pointing to first leaf of a compound config node
|
||||
* \param node Config node handle
|
||||
* \return iterator value for first leaf
|
||||
*/
|
||||
snd_config_iterator_t snd_config_iterator_first(snd_config_t *node)
|
||||
{
|
||||
assert(node->type == SND_CONFIG_TYPE_COMPOUND);
|
||||
return node->u.compound.fields.next;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return an iterator pointing to next leaf
|
||||
* \param iterator Config node iterator
|
||||
* \return iterator value for next leaf
|
||||
*/
|
||||
snd_config_iterator_t snd_config_iterator_next(snd_config_iterator_t iterator)
|
||||
{
|
||||
return iterator->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return an iterator pointing past the last leaf of a compound config node
|
||||
* \param node Config node handle
|
||||
* \return iterator value for end
|
||||
*/
|
||||
snd_config_iterator_t snd_config_iterator_end(snd_config_t *node)
|
||||
{
|
||||
assert(node->type == SND_CONFIG_TYPE_COMPOUND);
|
||||
return &node->u.compound.fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Return the node handle pointed by iterator
|
||||
* \param iterator Config node iterator
|
||||
* \return config node handle
|
||||
*/
|
||||
snd_config_t *snd_config_iterator_entry(snd_config_iterator_t iterator)
|
||||
{
|
||||
return list_entry(iterator, snd_config_t, list);
|
||||
|
|
|
|||
88
src/input.c
88
src/input.c
|
|
@ -1,3 +1,10 @@
|
|||
/**
|
||||
* \file input.c
|
||||
* \author Abramo Bagnara <abramo@alsa-project.org>
|
||||
* \date 2000
|
||||
*
|
||||
* Generic stdio-like input interface
|
||||
*/
|
||||
/*
|
||||
* Input object
|
||||
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
|
||||
|
|
@ -19,6 +26,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -38,7 +46,13 @@ struct _snd_input {
|
|||
snd_input_ops_t *ops;
|
||||
void *private_data;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief close input handle
|
||||
* \param input Input handle
|
||||
* \return zero on success otherwise a negative error code
|
||||
*/
|
||||
int snd_input_close(snd_input_t *input)
|
||||
{
|
||||
int err = input->ops->close(input);
|
||||
|
|
@ -46,6 +60,13 @@ int snd_input_close(snd_input_t *input)
|
|||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief fscanf(3) like on an input handle
|
||||
* \param input Input handle
|
||||
* \param format fscanf format
|
||||
* \param ... other fscanf arguments
|
||||
* \return number of input itmes assigned or a negative error code
|
||||
*/
|
||||
int snd_input_scanf(snd_input_t *input, const char *format, ...)
|
||||
{
|
||||
int result;
|
||||
|
|
@ -56,27 +77,46 @@ int snd_input_scanf(snd_input_t *input, const char *format, ...)
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief fgets(3) like on an input handle
|
||||
* \param input Input handle
|
||||
* \param str Destination buffer pointer
|
||||
* \param size Buffer size
|
||||
* \return Pointer to buffer or NULL on error
|
||||
*/
|
||||
char *snd_input_gets(snd_input_t *input, char *str, size_t size)
|
||||
{
|
||||
return input->ops->gets(input, str, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief fgetc(3) like on an input handle
|
||||
* \param input Input handle
|
||||
* \return character read or EOF on end of file or error
|
||||
*/
|
||||
int snd_input_getc(snd_input_t *input)
|
||||
{
|
||||
return input->ops->getch(input);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief ungetc(3) like on an input handle
|
||||
* \param input Input handle
|
||||
* \param c Char to push back
|
||||
* \return character pushed back or EOF on error
|
||||
*/
|
||||
int snd_input_ungetc(snd_input_t *input, int c)
|
||||
{
|
||||
return input->ops->ungetch(input, c);
|
||||
}
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
typedef struct _snd_input_stdio {
|
||||
int close;
|
||||
FILE *fp;
|
||||
} snd_input_stdio_t;
|
||||
|
||||
int snd_input_stdio_close(snd_input_t *input ATTRIBUTE_UNUSED)
|
||||
static int snd_input_stdio_close(snd_input_t *input ATTRIBUTE_UNUSED)
|
||||
{
|
||||
snd_input_stdio_t *stdio = input->private_data;
|
||||
if (close)
|
||||
|
|
@ -85,39 +125,47 @@ int snd_input_stdio_close(snd_input_t *input ATTRIBUTE_UNUSED)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_input_stdio_scanf(snd_input_t *input, const char *format, va_list args)
|
||||
static int snd_input_stdio_scanf(snd_input_t *input, const char *format, va_list args)
|
||||
{
|
||||
snd_input_stdio_t *stdio = input->private_data;
|
||||
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)
|
||||
static char *snd_input_stdio_gets(snd_input_t *input, char *str, size_t size)
|
||||
{
|
||||
snd_input_stdio_t *stdio = input->private_data;
|
||||
return fgets(str, size, stdio->fp);
|
||||
}
|
||||
|
||||
int snd_input_stdio_getc(snd_input_t *input)
|
||||
static int snd_input_stdio_getc(snd_input_t *input)
|
||||
{
|
||||
snd_input_stdio_t *stdio = input->private_data;
|
||||
return getc(stdio->fp);
|
||||
}
|
||||
|
||||
int snd_input_stdio_ungetc(snd_input_t *input, int c)
|
||||
static int snd_input_stdio_ungetc(snd_input_t *input, int c)
|
||||
{
|
||||
snd_input_stdio_t *stdio = input->private_data;
|
||||
return ungetc(c, stdio->fp);
|
||||
}
|
||||
|
||||
snd_input_ops_t snd_input_stdio_ops = {
|
||||
static 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,
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Create a new input using an existing stdio FILE pointer
|
||||
* \param inputp Pointer to returned input handle
|
||||
* \param fp FILE pointer
|
||||
* \param close Close flag (1 if FILE is fclose'd when input handle is closed)
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_input_stdio_attach(snd_input_t **inputp, FILE *fp, int close)
|
||||
{
|
||||
snd_input_t *input;
|
||||
|
|
@ -140,6 +188,12 @@ int snd_input_stdio_attach(snd_input_t **inputp, FILE *fp, int close)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Open a new input from a file
|
||||
* \param inputp Pointer to returned input handle
|
||||
* \param file File name
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_input_stdio_open(snd_input_t **inputp, const char *file)
|
||||
{
|
||||
int err;
|
||||
|
|
@ -154,13 +208,15 @@ int snd_input_stdio_open(snd_input_t **inputp, const char *file)
|
|||
return err;
|
||||
}
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
|
||||
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)
|
||||
static int snd_input_buffer_close(snd_input_t *input)
|
||||
{
|
||||
snd_input_buffer_t *buffer = input->private_data;
|
||||
free(buffer->buf);
|
||||
|
|
@ -168,7 +224,7 @@ int snd_input_buffer_close(snd_input_t *input)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_input_buffer_scanf(snd_input_t *input, const char *format, va_list args)
|
||||
static int snd_input_buffer_scanf(snd_input_t *input, const char *format, va_list args)
|
||||
{
|
||||
snd_input_buffer_t *buffer = input->private_data;
|
||||
extern int vsscanf(const char *buf, const char *format, va_list args);
|
||||
|
|
@ -177,7 +233,7 @@ int snd_input_buffer_scanf(snd_input_t *input, const char *format, va_list args)
|
|||
return vsscanf(buffer->ptr, format, args);
|
||||
}
|
||||
|
||||
char *snd_input_buffer_gets(snd_input_t *input, char *str, size_t size)
|
||||
static char *snd_input_buffer_gets(snd_input_t *input, char *str, size_t size)
|
||||
{
|
||||
snd_input_buffer_t *buffer = input->private_data;
|
||||
size_t bsize = buffer->size;
|
||||
|
|
@ -195,7 +251,7 @@ char *snd_input_buffer_gets(snd_input_t *input, char *str, size_t size)
|
|||
return str;
|
||||
}
|
||||
|
||||
int snd_input_buffer_getc(snd_input_t *input)
|
||||
static int snd_input_buffer_getc(snd_input_t *input)
|
||||
{
|
||||
snd_input_buffer_t *buffer = input->private_data;
|
||||
if (buffer->size == 0)
|
||||
|
|
@ -204,7 +260,7 @@ int snd_input_buffer_getc(snd_input_t *input)
|
|||
return *buffer->ptr++;
|
||||
}
|
||||
|
||||
int snd_input_buffer_ungetc(snd_input_t *input, int c)
|
||||
static int snd_input_buffer_ungetc(snd_input_t *input, int c)
|
||||
{
|
||||
snd_input_buffer_t *buffer = input->private_data;
|
||||
if (buffer->ptr == buffer->buf)
|
||||
|
|
@ -215,14 +271,22 @@ int snd_input_buffer_ungetc(snd_input_t *input, int c)
|
|||
return c;
|
||||
}
|
||||
|
||||
snd_input_ops_t snd_input_buffer_ops = {
|
||||
static 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,
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Open a new input from a memory buffer
|
||||
* \param inputp Pointer to returned input handle
|
||||
* \param buf Buffer pointer
|
||||
* \param size Buffer size
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_input_buffer_open(snd_input_t **inputp, const char *buf, int size)
|
||||
{
|
||||
snd_input_t *input;
|
||||
|
|
|
|||
102
src/output.c
102
src/output.c
|
|
@ -1,3 +1,10 @@
|
|||
/**
|
||||
* \file output.c
|
||||
* \author Abramo Bagnara <abramo@alsa-project.org>
|
||||
* \date 2000
|
||||
*
|
||||
* Generic stdio-like output interface
|
||||
*/
|
||||
/*
|
||||
* Output object
|
||||
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
|
||||
|
|
@ -19,6 +26,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -38,7 +46,13 @@ struct _snd_output {
|
|||
snd_output_ops_t *ops;
|
||||
void *private_data;
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief close output handle
|
||||
* \param output Output handle
|
||||
* \return zero on success otherwise a negative error code
|
||||
*/
|
||||
int snd_output_close(snd_output_t *output)
|
||||
{
|
||||
int err = output->ops->close(output);
|
||||
|
|
@ -46,6 +60,13 @@ int snd_output_close(snd_output_t *output)
|
|||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief fprintf(3) like on an output handle
|
||||
* \param output Output handle
|
||||
* \param format fprintf format
|
||||
* \param ... other fprintf arguments
|
||||
* \return number of characters written or a negative error code
|
||||
*/
|
||||
int snd_output_printf(snd_output_t *output, const char *format, ...)
|
||||
{
|
||||
int result;
|
||||
|
|
@ -56,27 +77,45 @@ int snd_output_printf(snd_output_t *output, const char *format, ...)
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief fputs(3) like on an output handle
|
||||
* \param output Output handle
|
||||
* \param str Buffer pointer
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_output_puts(snd_output_t *output, const char *str)
|
||||
{
|
||||
return output->ops->puts(output, str);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief fputs(3) like on an output handle
|
||||
* \param output Output handle
|
||||
* \param str Source buffer pointer
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_output_putc(snd_output_t *output, int c)
|
||||
{
|
||||
return output->ops->putch(output, c);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief fflush(3) like on an output handle
|
||||
* \param output Output handle
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_output_flush(snd_output_t *output)
|
||||
{
|
||||
return output->ops->flush(output);
|
||||
}
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
typedef struct _snd_output_stdio {
|
||||
int close;
|
||||
FILE *fp;
|
||||
} snd_output_stdio_t;
|
||||
|
||||
int snd_output_stdio_close(snd_output_t *output ATTRIBUTE_UNUSED)
|
||||
static int snd_output_stdio_close(snd_output_t *output ATTRIBUTE_UNUSED)
|
||||
{
|
||||
snd_output_stdio_t *stdio = output->private_data;
|
||||
if (close)
|
||||
|
|
@ -85,31 +124,31 @@ int snd_output_stdio_close(snd_output_t *output ATTRIBUTE_UNUSED)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_output_stdio_printf(snd_output_t *output, const char *format, va_list args)
|
||||
static int snd_output_stdio_printf(snd_output_t *output, const char *format, va_list args)
|
||||
{
|
||||
snd_output_stdio_t *stdio = output->private_data;
|
||||
return vfprintf(stdio->fp, format, args);
|
||||
}
|
||||
|
||||
int snd_output_stdio_puts(snd_output_t *output, const char *str)
|
||||
static int snd_output_stdio_puts(snd_output_t *output, const char *str)
|
||||
{
|
||||
snd_output_stdio_t *stdio = output->private_data;
|
||||
return fputs(str, stdio->fp);
|
||||
}
|
||||
|
||||
int snd_output_stdio_putc(snd_output_t *output, int c)
|
||||
static int snd_output_stdio_putc(snd_output_t *output, int c)
|
||||
{
|
||||
snd_output_stdio_t *stdio = output->private_data;
|
||||
return putc(c, stdio->fp);
|
||||
}
|
||||
|
||||
int snd_output_stdio_flush(snd_output_t *output)
|
||||
static int snd_output_stdio_flush(snd_output_t *output)
|
||||
{
|
||||
snd_output_stdio_t *stdio = output->private_data;
|
||||
return fflush(stdio->fp);
|
||||
}
|
||||
|
||||
snd_output_ops_t snd_output_stdio_ops = {
|
||||
static snd_output_ops_t snd_output_stdio_ops = {
|
||||
close: snd_output_stdio_close,
|
||||
printf: snd_output_stdio_printf,
|
||||
puts: snd_output_stdio_puts,
|
||||
|
|
@ -117,6 +156,15 @@ snd_output_ops_t snd_output_stdio_ops = {
|
|||
flush: snd_output_stdio_flush,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Create a new output using an existing stdio FILE pointer
|
||||
* \param outputp Pointer to returned output handle
|
||||
* \param fp FILE pointer
|
||||
* \param close Close flag (1 if FILE is fclose'd when output handle is closed)
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int close)
|
||||
{
|
||||
snd_output_t *output;
|
||||
|
|
@ -153,13 +201,15 @@ int snd_output_stdio_open(snd_output_t **outputp, const char *file)
|
|||
return err;
|
||||
}
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
|
||||
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)
|
||||
static int snd_output_buffer_close(snd_output_t *output ATTRIBUTE_UNUSED)
|
||||
{
|
||||
snd_output_buffer_t *buffer = output->private_data;
|
||||
free(buffer->buf);
|
||||
|
|
@ -167,7 +217,7 @@ int snd_output_buffer_close(snd_output_t *output ATTRIBUTE_UNUSED)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_output_buffer_need(snd_output_t *output, size_t size)
|
||||
static int snd_output_buffer_need(snd_output_t *output, size_t size)
|
||||
{
|
||||
snd_output_buffer_t *buffer = output->private_data;
|
||||
size_t free = buffer->alloc - buffer->size;
|
||||
|
|
@ -185,7 +235,7 @@ int snd_output_buffer_need(snd_output_t *output, size_t size)
|
|||
return buffer->alloc - buffer->size;
|
||||
}
|
||||
|
||||
int snd_output_buffer_printf(snd_output_t *output, const char *format, va_list args)
|
||||
static int snd_output_buffer_printf(snd_output_t *output, const char *format, va_list args)
|
||||
{
|
||||
snd_output_buffer_t *buffer = output->private_data;
|
||||
size_t size = 256;
|
||||
|
|
@ -208,7 +258,7 @@ int snd_output_buffer_printf(snd_output_t *output, const char *format, va_list a
|
|||
return result;
|
||||
}
|
||||
|
||||
int snd_output_buffer_puts(snd_output_t *output, const char *str)
|
||||
static int snd_output_buffer_puts(snd_output_t *output, const char *str)
|
||||
{
|
||||
snd_output_buffer_t *buffer = output->private_data;
|
||||
size_t size = strlen(str);
|
||||
|
|
@ -221,7 +271,7 @@ int snd_output_buffer_puts(snd_output_t *output, const char *str)
|
|||
return size;
|
||||
}
|
||||
|
||||
int snd_output_buffer_putc(snd_output_t *output, int c)
|
||||
static int snd_output_buffer_putc(snd_output_t *output, int c)
|
||||
{
|
||||
snd_output_buffer_t *buffer = output->private_data;
|
||||
int err;
|
||||
|
|
@ -232,13 +282,28 @@ int snd_output_buffer_putc(snd_output_t *output, int c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int snd_output_buffer_flush(snd_output_t *output ATTRIBUTE_UNUSED)
|
||||
static int snd_output_buffer_flush(snd_output_t *output ATTRIBUTE_UNUSED)
|
||||
{
|
||||
snd_output_buffer_t *buffer = output->private_data;
|
||||
buffer->size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static 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,
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Return buffer info for a #SND_OUTPUT_TYPE_BUFFER output handle
|
||||
* \param output Output handle
|
||||
* \param buf Pointer to returned buffer
|
||||
* \return size of data in buffer
|
||||
*/
|
||||
size_t snd_output_buffer_string(snd_output_t *output, char **buf)
|
||||
{
|
||||
snd_output_buffer_t *buffer = output->private_data;
|
||||
|
|
@ -246,14 +311,11 @@ size_t snd_output_buffer_string(snd_output_t *output, char **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,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Open a new output to an auto extended memory buffer
|
||||
* \param outputp Pointer to returned output handle
|
||||
* \return 0 on success otherwise a negative error code
|
||||
*/
|
||||
int snd_output_buffer_open(snd_output_t **outputp)
|
||||
{
|
||||
snd_output_t *output;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef DOC_HIDDEN
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
|
@ -45,6 +46,7 @@
|
|||
#include <dlfcn.h>
|
||||
#include "pcm_local.h"
|
||||
#include "list.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief get identifier of PCM handle
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
* \file pcm/pcm_meter.c
|
||||
* \author Abramo Bagnara <abramo@alsa-project.org>
|
||||
* \date 2001
|
||||
*
|
||||
* Helper functions for #SND_PCM_TYPE_METER PCM scopes
|
||||
*/
|
||||
/*
|
||||
* PCM - Meter plugin
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue