mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
API for device name lists and timer enhancements
- new snd_names_list and snd_names_list_free functions - added snd_timer_ginfo related functions to the timer API
This commit is contained in:
parent
f658e3e148
commit
a022bc1fbc
6 changed files with 388 additions and 2 deletions
|
|
@ -170,6 +170,19 @@ int snd_config_get_bool(const snd_config_t *conf);
|
||||||
int snd_config_get_ctl_iface_ascii(const char *ascii);
|
int snd_config_get_ctl_iface_ascii(const char *ascii);
|
||||||
int snd_config_get_ctl_iface(const snd_config_t *conf);
|
int snd_config_get_ctl_iface(const snd_config_t *conf);
|
||||||
|
|
||||||
|
/* Names functions */
|
||||||
|
|
||||||
|
typedef struct snd_devname snd_devname_t;
|
||||||
|
|
||||||
|
struct snd_devname {
|
||||||
|
char *name;
|
||||||
|
char *comment;
|
||||||
|
snd_devname_t *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
int snd_names_list(const char *interface, snd_devname_t **list);
|
||||||
|
void snd_names_list_free(snd_devname_t *list);
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -177,4 +190,3 @@ int snd_config_get_ctl_iface(const snd_config_t *conf);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* __ALSA_CONF_H */
|
#endif /* __ALSA_CONF_H */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -173,6 +173,24 @@ int snd_timer_id_get_device(snd_timer_id_t *id);
|
||||||
void snd_timer_id_set_subdevice(snd_timer_id_t *id, int subdevice);
|
void snd_timer_id_set_subdevice(snd_timer_id_t *id, int subdevice);
|
||||||
int snd_timer_id_get_subdevice(snd_timer_id_t *id);
|
int snd_timer_id_get_subdevice(snd_timer_id_t *id);
|
||||||
|
|
||||||
|
size_t snd_timer_ginfo_sizeof(void);
|
||||||
|
/** allocate #snd_timer_ginfo_t container on stack */
|
||||||
|
#define snd_timer_ginfo_alloca(ptr) do { assert(ptr); *ptr = (snd_timer_ginfo_t *) alloca(snd_timer_ginfo_sizeof()); memset(*ptr, 0, snd_timer_ginfo_sizeof()); } while (0)
|
||||||
|
int snd_timer_ginfo_malloc(snd_timer_ginfo_t **ptr);
|
||||||
|
void snd_timer_ginfo_free(snd_timer_ginfo_t *obj);
|
||||||
|
void snd_timer_ginfo_copy(snd_timer_ginfo_t *dst, const snd_timer_ginfo_t *src);
|
||||||
|
|
||||||
|
int snd_timer_ginfo_set_tid(snd_timer_ginfo_t *obj, snd_timer_id_t *tid);
|
||||||
|
snd_timer_id_t *snd_timer_ginfo_get_tid(snd_timer_ginfo_t *obj);
|
||||||
|
unsigned int snd_timer_ginfo_get_flags(snd_timer_ginfo_t *obj);
|
||||||
|
int snd_timer_ginfo_get_card(snd_timer_ginfo_t *obj);
|
||||||
|
char *snd_timer_ginfo_get_id(snd_timer_ginfo_t *obj);
|
||||||
|
char *snd_timer_ginfo_get_name(snd_timer_ginfo_t *obj);
|
||||||
|
unsigned long snd_timer_ginfo_get_resolution(snd_timer_ginfo_t *obj);
|
||||||
|
unsigned long snd_timer_ginfo_get_resolution_min(snd_timer_ginfo_t *obj);
|
||||||
|
unsigned long snd_timer_ginfo_get_resolution_max(snd_timer_ginfo_t *obj);
|
||||||
|
unsigned int snd_timer_ginfo_get_clients(snd_timer_ginfo_t *obj);
|
||||||
|
|
||||||
size_t snd_timer_info_sizeof(void);
|
size_t snd_timer_info_sizeof(void);
|
||||||
/** allocate #snd_timer_info_t container on stack */
|
/** allocate #snd_timer_info_t container on stack */
|
||||||
#define snd_timer_info_alloca(ptr) do { assert(ptr); *ptr = (snd_timer_info_t *) alloca(snd_timer_info_sizeof()); memset(*ptr, 0, snd_timer_info_sizeof()); } while (0)
|
#define snd_timer_info_alloca(ptr) do { assert(ptr); *ptr = (snd_timer_info_t *) alloca(snd_timer_info_sizeof()); memset(*ptr, 0, snd_timer_info_sizeof()); } while (0)
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ VSYMS =
|
||||||
endif
|
endif
|
||||||
|
|
||||||
lib_LTLIBRARIES = libasound.la
|
lib_LTLIBRARIES = libasound.la
|
||||||
libasound_la_SOURCES = conf.c confmisc.c input.c output.c async.c error.c dlmisc.c socket.c shmarea.c userfile.c
|
libasound_la_SOURCES = conf.c confmisc.c input.c output.c async.c error.c dlmisc.c socket.c shmarea.c userfile.c names.c
|
||||||
libasound_la_LIBADD = control/libcontrol.la \
|
libasound_la_LIBADD = control/libcontrol.la \
|
||||||
mixer/libmixer.la ordinary_mixer/libordinarymixer.la \
|
mixer/libmixer.la ordinary_mixer/libordinarymixer.la \
|
||||||
pcm/libpcm.la ordinary_pcm/libordinarypcm.la \
|
pcm/libpcm.la ordinary_pcm/libordinarypcm.la \
|
||||||
|
|
|
||||||
18
src/Versions
18
src/Versions
|
|
@ -174,6 +174,9 @@ ALSA_1.0.8 {
|
||||||
ALSA_1.0.9 {
|
ALSA_1.0.9 {
|
||||||
global:
|
global:
|
||||||
|
|
||||||
|
snd_names_list;
|
||||||
|
snd_names_list_free;
|
||||||
|
|
||||||
snd_pcm_hw_params_set_rate_resample;
|
snd_pcm_hw_params_set_rate_resample;
|
||||||
snd_pcm_hw_params_get_rate_resample;
|
snd_pcm_hw_params_get_rate_resample;
|
||||||
|
|
||||||
|
|
@ -194,4 +197,19 @@ ALSA_1.0.9 {
|
||||||
|
|
||||||
snd_pcm_parse_control_id;
|
snd_pcm_parse_control_id;
|
||||||
|
|
||||||
|
snd_timer_ginfo_sizeof;
|
||||||
|
snd_timer_ginfo_malloc;
|
||||||
|
snd_timer_ginfo_free;
|
||||||
|
snd_timer_ginfo_copy;
|
||||||
|
snd_timer_ginfo_set_tid;
|
||||||
|
snd_timer_ginfo_get_tid;
|
||||||
|
snd_timer_ginfo_get_flags;
|
||||||
|
snd_timer_ginfo_get_card;
|
||||||
|
snd_timer_ginfo_get_id;
|
||||||
|
snd_timer_ginfo_get_name;
|
||||||
|
snd_timer_ginfo_get_resolution;
|
||||||
|
snd_timer_ginfo_get_resolution_min;
|
||||||
|
snd_timer_ginfo_get_resolution_max;
|
||||||
|
snd_timer_ginfo_get_clients;
|
||||||
|
|
||||||
} ALSA_1.0.5;
|
} ALSA_1.0.5;
|
||||||
|
|
|
||||||
187
src/names.c
Normal file
187
src/names.c
Normal file
|
|
@ -0,0 +1,187 @@
|
||||||
|
/**
|
||||||
|
* \file names.c
|
||||||
|
* \ingroup Configuration
|
||||||
|
* \brief Configuration helper functions - device names
|
||||||
|
* \author Jaroslav Kysela <perex@suse.cz>
|
||||||
|
* \date 2005
|
||||||
|
*
|
||||||
|
* Provide a list of device names for applications.
|
||||||
|
*
|
||||||
|
* See the \ref conf page for more details.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Configuration helper functions - device names
|
||||||
|
* Copyright (c) 2005 by Jaroslav Kysela <perex@suse.cz>
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <wordexp.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include "local.h"
|
||||||
|
|
||||||
|
#define ALSA_NAMES_ENV "ALSA_NAMES_FILE"
|
||||||
|
#define ALSA_NAMES_PATH1 "/etc/asound.names"
|
||||||
|
#define ALSA_NAMES_PATH2 "~/.asoundnm"
|
||||||
|
|
||||||
|
static int names_parse(snd_config_t *top, const char *interface, snd_devname_t **list)
|
||||||
|
{
|
||||||
|
snd_config_iterator_t i, next;
|
||||||
|
snd_config_iterator_t j, jnext;
|
||||||
|
char *name, *comment;
|
||||||
|
const char *id;
|
||||||
|
snd_devname_t *dn, *last = NULL;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = snd_config_search(top, interface, &top);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
snd_config_for_each(i, next, top) {
|
||||||
|
snd_config_t *n = snd_config_iterator_entry(i);
|
||||||
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
|
continue;
|
||||||
|
name = comment = NULL;
|
||||||
|
snd_config_for_each(j, jnext, n) {
|
||||||
|
snd_config_t *m = snd_config_iterator_entry(j);
|
||||||
|
if (snd_config_get_id(m, &id) < 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(id, "name") == 0) {
|
||||||
|
err = snd_config_get_string(m, (const char **)&name);
|
||||||
|
if (err < 0)
|
||||||
|
continue;
|
||||||
|
name = strdup(name);
|
||||||
|
if (name == NULL) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strcmp(id, "comment") == 0) {
|
||||||
|
err = snd_config_get_string(m, (const char **)&comment);
|
||||||
|
if (err < 0)
|
||||||
|
continue;
|
||||||
|
comment = strdup(comment);
|
||||||
|
if (name == NULL) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (name != NULL) {
|
||||||
|
dn = malloc(sizeof(*dn));
|
||||||
|
if (dn == NULL) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto _err;
|
||||||
|
}
|
||||||
|
dn->name = name;
|
||||||
|
dn->comment = comment;
|
||||||
|
dn->next = NULL;
|
||||||
|
if (last == NULL) {
|
||||||
|
*list = dn;
|
||||||
|
} else {
|
||||||
|
last->next = dn;
|
||||||
|
}
|
||||||
|
last = dn;
|
||||||
|
} else {
|
||||||
|
if (comment != NULL)
|
||||||
|
free(comment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
_err:
|
||||||
|
if (name)
|
||||||
|
free(name);
|
||||||
|
if (comment)
|
||||||
|
free(comment);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Give a list of device names and associated comments for selected interface
|
||||||
|
* \param interface a string identifying interface ("pcm", "ctl", "seq", "rawmidi")
|
||||||
|
* \param list result - a pointer to list
|
||||||
|
* \return A non-negative value if successful, otherwise a negative error code.
|
||||||
|
*
|
||||||
|
* The global configuration files are specified in the environment variable
|
||||||
|
* \c ALSA_NAMES_FILE.
|
||||||
|
*/
|
||||||
|
int snd_names_list(const char *interface, snd_devname_t **list)
|
||||||
|
{
|
||||||
|
char *file;
|
||||||
|
snd_config_t *top;
|
||||||
|
snd_input_t *in;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
assert(interface);
|
||||||
|
assert(list);
|
||||||
|
*list = NULL;
|
||||||
|
file = getenv(ALSA_NAMES_ENV);
|
||||||
|
if (file) {
|
||||||
|
file = strdup(file);
|
||||||
|
if (file == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
} else {
|
||||||
|
err = snd_user_file(ALSA_NAMES_PATH2, &file);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
if (access(file, R_OK)) {
|
||||||
|
file = strdup(ALSA_NAMES_PATH1);
|
||||||
|
if (file == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = snd_config_top(&top);
|
||||||
|
if (err >= 0)
|
||||||
|
err = snd_input_stdio_open(&in, file, "r");
|
||||||
|
if (err >= 0) {
|
||||||
|
err = snd_config_load(top, in);
|
||||||
|
snd_input_close(in);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("%s may be old or corrupted: consider to remove or fix it", file);
|
||||||
|
} else {
|
||||||
|
err = names_parse(top, interface, list);
|
||||||
|
if (err < 0) {
|
||||||
|
snd_names_list_free(*list);
|
||||||
|
*list = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SNDERR("cannot access file %s", file);
|
||||||
|
}
|
||||||
|
snd_config_delete(top);
|
||||||
|
return err >= 0 ? 0 : err;
|
||||||
|
}
|
||||||
|
|
||||||
|
void snd_names_list_free(snd_devname_t *list)
|
||||||
|
{
|
||||||
|
snd_devname_t *next;
|
||||||
|
|
||||||
|
while (list != NULL) {
|
||||||
|
next = list->next;
|
||||||
|
if (list->name)
|
||||||
|
free(list->name);
|
||||||
|
if (list->comment)
|
||||||
|
free(list->comment);
|
||||||
|
free(list);
|
||||||
|
list = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -220,6 +220,157 @@ int snd_timer_query_next_device(snd_timer_query_t *timer, snd_timer_id_t *tid)
|
||||||
return timer->ops->next_device(timer, tid);
|
return timer->ops->next_device(timer, tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get size of the snd_timer_ginfo_t structure in bytes
|
||||||
|
* \return size of the snd_timer_ginfo_t structure in bytes
|
||||||
|
*/
|
||||||
|
size_t snd_timer_ginfo_sizeof(void)
|
||||||
|
{
|
||||||
|
return sizeof(snd_timer_ginfo_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief allocate a new snd_timer_ginfo_t structure
|
||||||
|
* \param ptr returned pointer
|
||||||
|
* \return 0 on success otherwise a negative error code if fails
|
||||||
|
*
|
||||||
|
* Allocates a new snd_timer_info_t structure using the standard
|
||||||
|
* malloc C library function.
|
||||||
|
*/
|
||||||
|
int snd_timer_ginfo_malloc(snd_timer_ginfo_t **info)
|
||||||
|
{
|
||||||
|
assert(info);
|
||||||
|
*info = calloc(1, sizeof(snd_timer_ginfo_t));
|
||||||
|
if (!*info)
|
||||||
|
return -ENOMEM;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief frees the snd_timer_ginfo_t structure
|
||||||
|
* \param info pointer to the snd_timer_ginfo_t structure to free
|
||||||
|
*
|
||||||
|
* Frees the given snd_timer_info_t structure using the standard
|
||||||
|
* free C library function.
|
||||||
|
*/
|
||||||
|
void snd_timer_ginfo_free(snd_timer_ginfo_t *info)
|
||||||
|
{
|
||||||
|
assert(info);
|
||||||
|
free(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief copy one snd_timer_info_t structure to another
|
||||||
|
* \param dst destination snd_timer_info_t structure
|
||||||
|
* \param src source snd_timer_info_t structure
|
||||||
|
*/
|
||||||
|
void snd_timer_ginfo_copy(snd_timer_ginfo_t *dst, const snd_timer_ginfo_t *src)
|
||||||
|
{
|
||||||
|
assert(dst && src);
|
||||||
|
*dst = *src;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief set timer identification
|
||||||
|
* \param obj pointer to #snd_timer_ginfo_t structure
|
||||||
|
* \return zero on success otherwise a negative error number
|
||||||
|
*/
|
||||||
|
int snd_timer_ginfo_set_tid(snd_timer_ginfo_t *obj, snd_timer_id_t *tid)
|
||||||
|
{
|
||||||
|
obj->tid = *((snd_timer_id_t *)tid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get timer identification
|
||||||
|
* \param obj pointer to #snd_timer_ginfo_t structure
|
||||||
|
* \return pointer to snd_timer_id_t
|
||||||
|
*/
|
||||||
|
snd_timer_id_t *snd_timer_ginfo_get_tid(snd_timer_ginfo_t *obj)
|
||||||
|
{
|
||||||
|
return (snd_timer_id_t *)&obj->tid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get timer flags
|
||||||
|
* \param obj pointer to #snd_timer_ginfo_t structure
|
||||||
|
* \return timer flags
|
||||||
|
*/
|
||||||
|
unsigned int snd_timer_ginfo_get_flags(snd_timer_ginfo_t *obj)
|
||||||
|
{
|
||||||
|
return obj->flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get associated card with timer
|
||||||
|
* \param obj pointer to #snd_timer_ginfo_t structure
|
||||||
|
* \return associated card
|
||||||
|
*/
|
||||||
|
int snd_timer_ginfo_get_card(snd_timer_ginfo_t *obj)
|
||||||
|
{
|
||||||
|
return obj->card;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get timer identification
|
||||||
|
* \param obj pointer to #snd_timer_ginfo_t structure
|
||||||
|
* \return timer identification
|
||||||
|
*/
|
||||||
|
char *snd_timer_ginfo_get_id(snd_timer_ginfo_t *obj)
|
||||||
|
{
|
||||||
|
return obj->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get timer name
|
||||||
|
* \param obj pointer to #snd_timer_ginfo_t structure
|
||||||
|
* \return timer name
|
||||||
|
*/
|
||||||
|
char *snd_timer_ginfo_get_name(snd_timer_ginfo_t *obj)
|
||||||
|
{
|
||||||
|
return obj->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get timer resolution in ns
|
||||||
|
* \param obj pointer to #snd_timer_ginfo_t structure
|
||||||
|
* \return timer resolution in ns
|
||||||
|
*/
|
||||||
|
unsigned long snd_timer_ginfo_get_resolution(snd_timer_ginfo_t *obj)
|
||||||
|
{
|
||||||
|
return obj->resolution;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get timer minimal resolution in ns
|
||||||
|
* \param obj pointer to #snd_timer_ginfo_t structure
|
||||||
|
* \return timer minimal resolution in ns
|
||||||
|
*/
|
||||||
|
unsigned long snd_timer_ginfo_get_resolution_min(snd_timer_ginfo_t *obj)
|
||||||
|
{
|
||||||
|
return obj->resolution_min;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get timer maximal resolution in ns
|
||||||
|
* \param obj pointer to #snd_timer_ginfo_t structure
|
||||||
|
* \return timer maximal resolution in ns
|
||||||
|
*/
|
||||||
|
unsigned long snd_timer_ginfo_get_resolution_max(snd_timer_ginfo_t *obj)
|
||||||
|
{
|
||||||
|
return obj->resolution_max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief get current timer clients
|
||||||
|
* \param obj pointer to #snd_timer_ginfo_t structure
|
||||||
|
* \return current timer clients
|
||||||
|
*/
|
||||||
|
unsigned int snd_timer_ginfo_get_clients(snd_timer_ginfo_t *obj)
|
||||||
|
{
|
||||||
|
return obj->clients;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief obtain the timer global information
|
* \brief obtain the timer global information
|
||||||
* \param timer timer handle
|
* \param timer timer handle
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue