added snd_hctl_ctl() function

ordinary mixer:
  - revised Ordinary Mixer I/O type
  - sndo_mixer_open() take PCMs rather than strings to pass
    the real relationship
  - an initial version of toplevel alisp script
more alisp development:
  - renamed a* functions to A* functions (acall -> Acall etc.)
  - many improvements (unset*, exfun, Acall pcm_info, Asnderr, Asyserr)
This commit is contained in:
Jaroslav Kysela 2003-09-09 19:24:35 +00:00
parent 668a300229
commit 60585e25fc
16 changed files with 535 additions and 165 deletions

View file

@ -1,26 +1,26 @@
(setq card (acall 'card_next -1)) (setq card (Acall 'card_next -1))
(setq card (aresult card)) (setq card (Aresult card))
(while (>= card 0) (while (>= card 0)
(progn (progn
(princ "found card: " card "\n") (princ "found card: " card "\n")
(princ " name : " (aresult (acall 'card_get_name card)) "\n") (princ " name : " (Aresult (Acall 'card_get_name card)) "\n")
(princ " longname: " (aresult (acall 'card_get_longname card)) "\n") (princ " longname: " (Aresult (Acall 'card_get_longname card)) "\n")
(setq card (acall 'card_next card)) (setq card (Acall 'card_next card))
(setq card (aresult card)) (setq card (Aresult card))
) )
) )
(unsetq card) (unsetq card)
(princ "card_get_index test (SI7018): " (acall 'card_get_index "SI7018") "\n") (princ "card_get_index test (SI7018): " (Acall 'card_get_index "SI7018") "\n")
(princ "card_get_index test (ABCD): " (acall 'card_get_index "ABCD") "\n") (princ "card_get_index test (ABCD): " (Acall 'card_get_index "ABCD") "\n")
(setq hctl (acall 'hctl_open 'default nil)) (setq hctl (Acall 'hctl_open 'default nil))
(if (= (aerror hctl) 0) (if (= (Aerror hctl) 0)
(progn (progn
(princ "open success: " hctl "\n") (princ "open success: " hctl "\n")
(setq hctl (ahandle hctl)) (setq hctl (Ahandle hctl))
(princ "open hctl: " hctl "\n") (princ "open hctl: " hctl "\n")
(setq hctl (acall 'hctl_close hctl)) (setq hctl (Acall 'hctl_close hctl))
(if (= hctl 0) (if (= hctl 0)
(princ "close success\n") (princ "close success\n")
(princ "close failed: " hctl "\n") (princ "close failed: " hctl "\n")
@ -32,42 +32,42 @@
) )
(unsetq hctl) (unsetq hctl)
(setq ctl (acall 'ctl_open 'default nil)) (setq ctl (Acall 'ctl_open 'default nil))
(if (= (aerror ctl) 0) (if (= (Aerror ctl) 0)
(progn (progn
(princ "ctl open success: " ctl "\n") (princ "ctl open success: " ctl "\n")
(setq ctl (ahandle ctl)) (setq ctl (Ahandle ctl))
(setq info (aresult (acall 'ctl_card_info ctl))) (setq info (Aresult (Acall 'ctl_card_info ctl)))
(princ "ctl card info: " info "\n") (princ "ctl card info: " info "\n")
(princ "ctl card info (mixername): " (cdr (assq "mixername" info)) "\n") (princ "ctl card info (mixername): " (cdr (assq "mixername" info)) "\n")
(unsetq info) (unsetq info)
(setq hctl (acall 'hctl_open_ctl ctl)) (setq hctl (Acall 'hctl_open_ctl ctl))
(if (= (aerror hctl) 0) (if (= (Aerror hctl) 0)
(progn (progn
(princ "hctl open success: " hctl "\n") (princ "hctl open success: " hctl "\n")
(setq hctl (ahandle hctl)) (setq hctl (Ahandle hctl))
(princ "open hctl: " hctl "\n") (princ "open hctl: " hctl "\n")
(princ "load hctl: " (acall 'hctl_load hctl) "\n") (princ "load hctl: " (Acall 'hctl_load hctl) "\n")
(princ "first : " (acall 'hctl_first_elem hctl) "\n") (princ "first : " (Acall 'hctl_first_elem hctl) "\n")
(princ "last : " (acall 'hctl_last_elem hctl) "\n") (princ "last : " (Acall 'hctl_last_elem hctl) "\n")
(princ "next (first): " (acall 'hctl_elem_next (acall 'hctl_first_elem hctl)) "\n") (princ "next (first): " (Acall 'hctl_elem_next (Acall 'hctl_first_elem hctl)) "\n")
(princ "prev (last) : " (acall 'hctl_elem_prev (acall 'hctl_last_elem hctl)) "\n") (princ "prev (last) : " (Acall 'hctl_elem_prev (Acall 'hctl_last_elem hctl)) "\n")
(setq elem (acall 'hctl_first_elem hctl)) (setq elem (Acall 'hctl_first_elem hctl))
(while elem (while elem
(progn (progn
(setq info (acall 'hctl_elem_info elem)) (setq info (Acall 'hctl_elem_info elem))
(princ info "\n") (princ info "\n")
(setq value (acall 'hctl_elem_read elem)) (setq value (Acall 'hctl_elem_read elem))
(princ value "\n") (princ value "\n")
(when (equal (cdr (assq "name" (car (cdr (assq "id" (aresult info)))))) "Master Playback Volume") (when (equal (cdr (assq "name" (car (cdr (assq "id" (Aresult info)))))) "Master Playback Volume")
(princ "write Master: " (acall 'hctl_elem_write elem (20 20)) "\n") (princ "write Master: " (Acall 'hctl_elem_write elem (20 20)) "\n")
) )
(unsetq info value) (unsetq info value)
(gc) (gc)
(setq elem (acall 'hctl_elem_next elem)) (setq elem (Acall 'hctl_elem_next elem))
) )
) )
(setq hctl (acall 'hctl_close hctl)) (setq hctl (Acall 'hctl_close hctl))
(if (= hctl 0) (if (= hctl 0)
(princ "hctl close success\n") (princ "hctl close success\n")
(princ "hctl close failed: " hctl "\n") (princ "hctl close failed: " hctl "\n")
@ -75,7 +75,7 @@
) )
(progn (progn
(princ "hctl open failed: " hctl "\n") (princ "hctl open failed: " hctl "\n")
(acall 'ctl_close ctl) (Acall 'ctl_close ctl)
) )
) )
(unsetq hctl) (unsetq hctl)
@ -88,8 +88,3 @@
(&stat-memory) (&stat-memory)
(&dump-memory "memory.dump") (&dump-memory "memory.dump")
(defun autotest () (princ "abcd\n"))
(setq auto-exec 'autotest)
(princ (path 'data) "\n")

View file

@ -176,6 +176,7 @@ AC_OUTPUT(Makefile doc/Makefile doc/pictures/Makefile include/Makefile
src/rawmidi/Makefile src/timer/Makefile \ src/rawmidi/Makefile src/timer/Makefile \
src/hwdep/Makefile src/seq/Makefile src/instr/Makefile \ src/hwdep/Makefile src/seq/Makefile src/instr/Makefile \
src/compat/Makefile src/alisp/Makefile src/conf/Makefile \ src/compat/Makefile src/alisp/Makefile src/conf/Makefile \
src/conf/cards/Makefile src/conf/pcm/Makefile \ src/conf/cards/Makefile \
src/conf/pcm/Makefile \
alsalisp/Makefile aserver/Makefile test/Makefile utils/Makefile \ alsalisp/Makefile aserver/Makefile test/Makefile utils/Makefile \
utils/alsa-lib.spec utils/alsa.pc) utils/alsa-lib.spec utils/alsa.pc)

View file

@ -468,6 +468,7 @@ int snd_hctl_free(snd_hctl_t *hctl);
int snd_hctl_handle_events(snd_hctl_t *hctl); int snd_hctl_handle_events(snd_hctl_t *hctl);
const char *snd_hctl_name(snd_hctl_t *hctl); const char *snd_hctl_name(snd_hctl_t *hctl);
int snd_hctl_wait(snd_hctl_t *hctl, int timeout); int snd_hctl_wait(snd_hctl_t *hctl, int timeout);
snd_ctl_t *snd_hctl_ctl(snd_hctl_t *hctl);
snd_hctl_elem_t *snd_hctl_elem_next(snd_hctl_elem_t *elem); snd_hctl_elem_t *snd_hctl_elem_next(snd_hctl_elem_t *elem);
snd_hctl_elem_t *snd_hctl_elem_prev(snd_hctl_elem_t *elem); snd_hctl_elem_t *snd_hctl_elem_prev(snd_hctl_elem_t *elem);

View file

@ -29,48 +29,137 @@
#include <alsa/asoundlib.h> #include <alsa/asoundlib.h>
/** Ordinary Mixer latency type */ /** Ordinary Mixer I/O type */
enum sndo_mixer_io_type { enum sndo_mixer_io_type {
/* /*
* playback section * playback section
*/ */
/** master volume - left (0-1000) */ /** Master volume - left (0-1000) */
SNDO_MIO_MASTER_LVOL = 0, SNDO_MIO_MASTER_LVOL = 0,
/** master volume - right (0-1000) */ /** Master volume - right (0-1000) */
SNDO_MIO_MASTER_RVOL, SNDO_MIO_MASTER_RVOL,
/** master volume - left mute (0 = off, 1 = on) */ /** Master volume - left surround (0-1000) */
SNDO_MIO_MASTER_LSVOL = 0,
/** Master volume - right surround (0-1000) */
SNDO_MIO_MASTER_RSVOL,
/** Master volume - center (0-1000) */
SNDO_MIO_MASTER_CVOL = 0,
/** Master volume - LFE (0-1000) */
SNDO_MIO_MASTER_LFEVOL,
/** Master volume - left mute (0 = off, 1 = on) */
SNDO_MIO_MASTER_LMUTE, SNDO_MIO_MASTER_LMUTE,
/** master volume - right mute (0 = off, 1 = on) */ /** Master volume - right mute (0 = off, 1 = on) */
SNDO_MIO_MASTER_RMUTE, SNDO_MIO_MASTER_RMUTE,
/** Master volume - left surround mute (0 = off, 1 = on) */
SNDO_MIO_MASTER_LSMUTE,
/** Master volume - right surround mute (0 = off, 1 = on) */
SNDO_MIO_MASTER_RSMUTE,
/** Master volume - center mute (0 = off, 1 = on) */
SNDO_MIO_MASTER_CMUTE,
/** Master volume - LFE mute (0 = off, 1 = on) */
SNDO_MIO_MASTER_LFEMUTE,
/** pcm volume - left (0-1000) */ /** PCM volume - left (0-1000) */
SNDO_MIO_Mixer_LVOL, SNDO_MIO_PCM_LVOL = 0,
/** pcm volume - right (0-1000) */ /** PCM volume - right (0-1000) */
SNDO_MIO_Mixer_RVOL, SNDO_MIO_PCM_RVOL,
/** pcm volume - left mute (0 = off, 1 = on) */ /** PCM volume - left surround (0-1000) */
SNDO_MIO_Mixer_LMUTE, SNDO_MIO_PCM_LSVOL = 0,
/** pcm volume - right mute (0 = off, 1 = on) */ /** PCM volume - right surround (0-1000) */
SNDO_MIO_Mixer_RMUTE, SNDO_MIO_PCM_RSVOL,
/** PCM volume - center (0-1000) */
SNDO_MIO_PCM_CVOL = 0,
/** PCM volume - LFE (0-1000) */
SNDO_MIO_PCM_LFEVOL,
/** PCM volume - left mute (0 = off, 1 = on) */
SNDO_MIO_PCM_LMUTE,
/** PCM volume - right mute (0 = off, 1 = on) */
SNDO_MIO_PCM_RMUTE,
/** PCM volume - left surround mute (0 = off, 1 = on) */
SNDO_MIO_PCM_LSMUTE,
/** PCM volume - right surround mute (0 = off, 1 = on) */
SNDO_MIO_PCM_RSMUTE,
/** PCM volume - center mute (0 = off, 1 = on) */
SNDO_MIO_PCM_CMUTE,
/** PCM volume - LFE mute (0 = off, 1 = on) */
SNDO_MIO_PCM_LFEMUTE,
/** LINE volume - left (0-1000) */
SNDO_MIO_LINE_LVOL = 0,
/** LINE volume - right (0-1000) */
SNDO_MIO_LINE_RVOL,
/** LINE volume - left surround (0-1000) */
SNDO_MIO_LINE_LSVOL = 0,
/** LINE volume - right surround (0-1000) */
SNDO_MIO_LINE_RSVOL,
/** LINE volume - center (0-1000) */
SNDO_MIO_LINE_CVOL = 0,
/** LINE volume - LFE (0-1000) */
SNDO_MIO_LINE_LFEVOL,
/** LINE volume - left mute (0 = off, 1 = on) */
SNDO_MIO_LINE_LMUTE,
/** LINE volume - right mute (0 = off, 1 = on) */
SNDO_MIO_LINE_RMUTE,
/** LINE volume - left surround mute (0 = off, 1 = on) */
SNDO_MIO_LINE_LSMUTE,
/** LINE volume - right surround mute (0 = off, 1 = on) */
SNDO_MIO_LINE_RSMUTE,
/** LINE volume - center mute (0 = off, 1 = on) */
SNDO_MIO_LINE_CMUTE,
/** LINE volume - LFE mute (0 = off, 1 = on) */
SNDO_MIO_LINE_LFEMUTE,
/** MIC volume - left (0-1000) */
SNDO_MIO_MIC_LVOL = 0,
/** MIC volume - right (0-1000) */
SNDO_MIO_MIC_RVOL,
/** MIC volume - left surround (0-1000) */
SNDO_MIO_MIC_LSVOL = 0,
/** MIC volume - right surround (0-1000) */
SNDO_MIO_MIC_RSVOL,
/** MIC volume - center (0-1000) */
SNDO_MIO_MIC_CVOL = 0,
/** MIC volume - LFE (0-1000) */
SNDO_MIO_MIC_LFEVOL,
/** MIC volume - left mute (0 = off, 1 = on) */
SNDO_MIO_MIC_LMUTE,
/** MIC volume - right mute (0 = off, 1 = on) */
SNDO_MIO_MIC_RMUTE,
/** MIC volume - left surround mute (0 = off, 1 = on) */
SNDO_MIO_MIC_LSMUTE,
/** MIC volume - right surround mute (0 = off, 1 = on) */
SNDO_MIO_MIC_RSMUTE,
/** MIC volume - center mute (0 = off, 1 = on) */
SNDO_MIO_MIC_CMUTE,
/** MIC volume - LFE mute (0 = off, 1 = on) */
SNDO_MIO_MIC_LFEMUTE,
/** CD volume - left (0-1000) */ /** CD volume - left (0-1000) */
SNDO_MIO_CD_LVOL, SNDO_MIO_CD_LVOL = 0,
/** CD volume - right (0-1000) */ /** CD volume - right (0-1000) */
SNDO_MIO_CD_RVOL, SNDO_MIO_CD_RVOL,
/** CD volume - left surround (0-1000) */
SNDO_MIO_CD_LSVOL = 0,
/** CD volume - right surround (0-1000) */
SNDO_MIO_CD_RSVOL,
/** CD volume - center (0-1000) */
SNDO_MIO_CD_CVOL = 0,
/** CD volume - LFE (0-1000) */
SNDO_MIO_CD_LFEVOL,
/** CD volume - left mute (0 = off, 1 = on) */ /** CD volume - left mute (0 = off, 1 = on) */
SNDO_MIO_CD_LMUTE, SNDO_MIO_CD_LMUTE,
/** CD volume - right mute (0 = off, 1 = on) */ /** CD volume - right mute (0 = off, 1 = on) */
SNDO_MIO_CD_RMUTE, SNDO_MIO_CD_RMUTE,
/** CD volume - left surround mute (0 = off, 1 = on) */
/** AUX volume - left (0-1000) */ SNDO_MIO_CD_LSMUTE,
SNDO_MIO_AUX_LVOL, /** CD volume - right surround mute (0 = off, 1 = on) */
/** CD volume - right (0-1000) */ SNDO_MIO_CD_RSMUTE,
SNDO_MIO_AUX_RVOL, /** CD volume - center mute (0 = off, 1 = on) */
/** CD volume - left mute (0 = off, 1 = on) */ SNDO_MIO_CD_CMUTE,
SNDO_MIO_AUX_LMUTE, /** CD volume - LFE mute (0 = off, 1 = on) */
/** CD volume - right mute (0 = off, 1 = on) */ SNDO_MIO_CD_LFEMUTE,
SNDO_MIO_AUX_RMUTE,
/* /*
* capture section * capture section
@ -80,17 +169,24 @@ enum sndo_mixer_io_type {
SNDO_MIO_CGAIN_LVOL = 0x1000, SNDO_MIO_CGAIN_LVOL = 0x1000,
/** capture gain - right (0-1000) */ /** capture gain - right (0-1000) */
SNDO_MIO_CGAIN_RVOL, SNDO_MIO_CGAIN_RVOL,
/** capture gain - left surround (0-1000) */
SNDO_MIO_CGAIN_LSVOL,
/** capture gain - right surround (0-1000) */
SNDO_MIO_CGAIN_RSVOL,
/** capture gain - center (0-1000) */
SNDO_MIO_CGAIN_CVOL,
/** capture gain - LFE (0-1000) */
SNDO_MIO_CGAIN_LFEVOL,
/** capture source - MIC exclusive switch (0 = off, 1 = on) */
/** capture source - mic switch (0 = off, 1 = on) */
SNDO_MIO_CSOURCE_MIC = 0x1100, SNDO_MIO_CSOURCE_MIC = 0x1100,
/** capture source - line switch (0 = off, 1 = on)*/ /** capture source - LINE exclusive switch (0 = off, 1 = on) */
SNDO_MIO_CSOURCE_LINE, SNDO_MIO_CSOURCE_LINE,
/** capture source - CD switch (0 = off, 1 = on) */ /** capture source - CD exclusive switch (0 = off, 1 = on) */
SNDO_MIO_CSOURCE_CD, SNDO_MIO_CSOURCE_CD,
/** capture source - AUX switch (0 = off, 1 = on) */ /** capture source - AUX exclusive switch (0 = off, 1 = on) */
SNDO_MIO_CSOURCE_AUX, SNDO_MIO_CSOURCE_AUX,
/** capture source - mix switch (0 = off, 1 = on) */ /** capture source - MIX exclusive switch (0 = off, 1 = on) */
SNDO_MIO_CSOURCE_MIX SNDO_MIO_CSOURCE_MIX
}; };
@ -107,7 +203,7 @@ extern "C" {
* \{ * \{
*/ */
int sndo_mixer_open(sndo_mixer_t **pmixer, const char *playback_name, const char *capture_name, struct alisp_cfg *lconf); int sndo_mixer_open(sndo_mixer_t **pmixer, snd_pcm_t *playback_pcm, snd_pcm_t *capture_pcm, struct alisp_cfg *lconf);
int sndo_mixer_close(sndo_mixer_t *mixer); int sndo_mixer_close(sndo_mixer_t *mixer);
int sndo_mixer_poll_descriptors_count(sndo_mixer_t *mixer); int sndo_mixer_poll_descriptors_count(sndo_mixer_t *mixer);
int sndo_mixer_poll_descriptors(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int space); int sndo_mixer_poll_descriptors(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int space);

View file

@ -131,6 +131,7 @@ ALSA_0.9.7 {
global: global:
snd_user_file; snd_user_file;
snd_hctl_ctl;
sndo_*; sndo_*;
alsa_lisp_*; alsa_lisp_*;
} ALSA_0.9.6; } ALSA_0.9.6;

View file

@ -309,6 +309,24 @@ static struct alisp_object * new_pointer(struct alisp_instance *instance, const
return obj; return obj;
} }
static struct alisp_object * new_cons_pointer(struct alisp_instance * instance, const char *ptr_id, void *ptr)
{
struct alisp_object * lexpr;
if (ptr == NULL)
return &alsa_lisp_nil;
lexpr = new_object(instance, ALISP_OBJ_CONS);
if (lexpr == NULL)
return NULL;
lexpr->value.c.car = new_string(instance, ptr_id);
if (lexpr->value.c.car == NULL)
return NULL;
lexpr->value.c.cdr = new_pointer(instance, ptr);
if (lexpr->value.c.cdr == NULL)
return NULL;
return lexpr;
}
void alsa_lisp_init_objects(void) __attribute__ ((constructor)); void alsa_lisp_init_objects(void) __attribute__ ((constructor));
void alsa_lisp_init_objects(void) void alsa_lisp_init_objects(void)
@ -563,10 +581,13 @@ static struct alisp_object * parse_form(struct alisp_instance *instance)
return first; return first;
} }
static struct alisp_object * parse_quote(struct alisp_instance *instance) static struct alisp_object * quote_object(struct alisp_instance *instance, struct alisp_object * obj)
{ {
struct alisp_object * p; struct alisp_object * p;
if (obj == NULL)
return NULL;
p = new_object(instance, ALISP_OBJ_CONS); p = new_object(instance, ALISP_OBJ_CONS);
if (p == NULL) if (p == NULL)
return NULL; return NULL;
@ -577,13 +598,16 @@ static struct alisp_object * parse_quote(struct alisp_instance *instance)
p->value.c.cdr = new_object(instance, ALISP_OBJ_CONS); p->value.c.cdr = new_object(instance, ALISP_OBJ_CONS);
if (p->value.c.cdr == NULL) if (p->value.c.cdr == NULL)
return NULL; return NULL;
p->value.c.cdr->value.c.car = parse_object(instance, 0);
if (p->value.c.cdr->value.c.car == NULL)
return NULL;
p->value.c.cdr->value.c.car = obj;
return p; return p;
} }
static inline struct alisp_object * parse_quote(struct alisp_instance *instance)
{
return quote_object(instance, parse_object(instance, 0));
}
static struct alisp_object * parse_object(struct alisp_instance *instance, int havetoken) static struct alisp_object * parse_object(struct alisp_instance *instance, int havetoken)
{ {
int thistoken; int thistoken;
@ -662,8 +686,9 @@ static struct alisp_object_pair * set_object(struct alisp_instance *instance, st
return p; return p;
} }
static void unset_object1(struct alisp_instance *instance, const char *id) static struct alisp_object * unset_object1(struct alisp_instance *instance, const char *id)
{ {
struct alisp_object * res;
struct alisp_object_pair *p, *p1; struct alisp_object_pair *p, *p1;
for (p = instance->setobjs_list, p1 = NULL; p != NULL; p1 = p, p = p->next) { for (p = instance->setobjs_list, p1 = NULL; p != NULL; p1 = p, p = p->next) {
@ -673,13 +698,16 @@ static void unset_object1(struct alisp_instance *instance, const char *id)
p1->next = p->next; p1->next = p->next;
else else
instance->setobjs_list = p->next; instance->setobjs_list = p->next;
res = p->value;
free(p); free(p);
return; return res;
} }
} }
return &alsa_lisp_nil;
} }
static inline void unset_object(struct alisp_instance *instance, struct alisp_object * name) static inline struct alisp_object * unset_object(struct alisp_instance *instance, struct alisp_object * name)
{ {
return unset_object1(instance, name->value.id); return unset_object1(instance, name->value.id);
} }
@ -688,10 +716,11 @@ static struct alisp_object * get_object1(struct alisp_instance *instance, const
{ {
struct alisp_object_pair *p; struct alisp_object_pair *p;
for (p = instance->setobjs_list; p != NULL; p = p->next) for (p = instance->setobjs_list; p != NULL; p = p->next) {
if (p->name->value.id != NULL && if (p->name->value.id != NULL &&
!strcmp(id, p->name->value.id)) !strcmp(id, p->name->value.id))
return p->value; return p->value;
}
return &alsa_lisp_nil; return &alsa_lisp_nil;
} }
@ -956,18 +985,22 @@ static struct alisp_object * F_add(struct alisp_instance *instance, struct alisp
} else { } else {
return new_float(instance, f); return new_float(instance, f);
} }
} else if (p1->type == ALISP_OBJ_STRING || p1->type == ALISP_OBJ_IDENTIFIER) { } else if (p1->type == ALISP_OBJ_STRING) {
char *str = NULL, *str1; char *str = NULL, *str1;
for (;;) { for (;;) {
if (p1->type == ALISP_OBJ_STRING || p1->type == ALISP_OBJ_IDENTIFIER) { if (p1->type == ALISP_OBJ_STRING) {
str1 = realloc(str, strlen(str) + strlen(p1->value.s) + 1); str1 = realloc(str, (str ? strlen(str) : 0) + strlen(p1->value.s) + 1);
if (str1 == NULL) { if (str1 == NULL) {
nomem(); nomem();
if (str) if (str)
free(str); free(str);
return NULL; return NULL;
} }
strcat(str, p1->value.s); if (str == NULL)
strcpy(str1, p1->value.s);
else
strcat(str1, p1->value.s);
str = str1;
} else { } else {
lisp_warn(instance, "concat with a non string or identifier operand"); lisp_warn(instance, "concat with a non string or identifier operand");
} }
@ -1292,6 +1325,27 @@ static struct alisp_object * F_numeq(struct alisp_instance *instance, struct ali
return &alsa_lisp_nil; return &alsa_lisp_nil;
} }
/*
* Syntax: (exfun name)
* Test, if a function exists
*/
static struct alisp_object * F_exfun(struct alisp_instance *instance, struct alisp_object * args)
{
struct alisp_object * p1, * p2;
p1 = car(args);
if (p1->type != ALISP_OBJ_STRING && p1->type != ALISP_OBJ_IDENTIFIER)
return &alsa_lisp_nil;
p2 = get_object(instance, p1);
if (p2 == &alsa_lisp_nil)
return &alsa_lisp_nil;
p2 = car(p2);
if (p2->type == ALISP_OBJ_IDENTIFIER && !strcmp(p2->value.id, "lambda"))
return &alsa_lisp_t;
return &alsa_lisp_nil;
}
static void princ_string(snd_output_t *out, char *s) static void princ_string(snd_output_t *out, char *s)
{ {
char *p; char *p;
@ -1448,31 +1502,27 @@ static inline int eq(struct alisp_object * p1, struct alisp_object * p2)
static int equal(struct alisp_object * p1, struct alisp_object * p2) static int equal(struct alisp_object * p1, struct alisp_object * p2)
{ {
int type1, type2;
if (eq(p1, p2)) if (eq(p1, p2))
return 1; return 1;
if (p1->type == ALISP_OBJ_CONS || p2->type == ALISP_OBJ_CONS) type1 = p1->type;
type2 = p2->type;
if (type1 == ALISP_OBJ_CONS || type2 == ALISP_OBJ_CONS)
return 0; return 0;
if (p1->type == p2->type) if (type1 == type2) {
switch (p1->type) { switch (type1) {
case ALISP_OBJ_IDENTIFIER:
if (!strcmp(p1->value.id, p2->value.id))
return 1;
return 0;
case ALISP_OBJ_STRING: case ALISP_OBJ_STRING:
if (!strcmp(p1->value.s, p2->value.s)) return !strcmp(p1->value.s, p2->value.s);
return 1;
return 0;
case ALISP_OBJ_INTEGER: case ALISP_OBJ_INTEGER:
if (p1->value.i == p2->value.i) return p1->value.i == p2->value.i;
return 1;
return 0;
case ALISP_OBJ_FLOAT: case ALISP_OBJ_FLOAT:
if (p1->value.i == p2->value.i) return p1->value.i == p2->value.i;
return 1;
return 0;
} }
}
return 0; return 0;
} }
@ -1727,7 +1777,7 @@ static struct alisp_object * F_unset(struct alisp_instance *instance, struct ali
struct alisp_object * p1 = eval(instance, car(args)); struct alisp_object * p1 = eval(instance, car(args));
unset_object(instance, p1); unset_object(instance, p1);
return &alsa_lisp_nil; return p1;
} }
/* /*
@ -1757,15 +1807,15 @@ static struct alisp_object * F_setq(struct alisp_instance *instance, struct alis
*/ */
static struct alisp_object * F_unsetq(struct alisp_instance *instance, struct alisp_object * args) static struct alisp_object * F_unsetq(struct alisp_instance *instance, struct alisp_object * args)
{ {
struct alisp_object * p = args, * p1; struct alisp_object * p = args, * p1, * res;
do { do {
p1 = car(p); p1 = car(p);
unset_object(instance, p1); res = unset_object(instance, p1);
p = cdr(p); p = cdr(p);
} while (p != &alsa_lisp_nil); } while (p != &alsa_lisp_nil);
return &alsa_lisp_nil; return res;
} }
/* /*
@ -1885,7 +1935,7 @@ struct alisp_object * F_path(struct alisp_instance *instance, struct alisp_objec
struct alisp_object * p = args, * p1; struct alisp_object * p = args, * p1;
p1 = eval(instance, car(p)); p1 = eval(instance, car(p));
if (p1->type != ALISP_STRING && p1->type != ALISP_IDENTIFIER) if (p1->type != ALISP_OBJ_STRING)
return &alsa_lisp_nil; return &alsa_lisp_nil;
if (!strcmp(p1->value.s, "data")) if (!strcmp(p1->value.s, "data"))
return new_string(instance, DATADIR); return new_string(instance, DATADIR);
@ -1898,15 +1948,16 @@ struct alisp_object * F_path(struct alisp_instance *instance, struct alisp_objec
struct alisp_object * F_include(struct alisp_instance *instance, struct alisp_object * args) struct alisp_object * F_include(struct alisp_instance *instance, struct alisp_object * args)
{ {
struct alisp_object * p = args, * p1; struct alisp_object * p = args, * p1;
int res = -ENOENT;
do { do {
p1 = eval(instance, car(p)); p1 = eval(instance, car(p));
if (p1->type == ALISP_STRING && p1->type == ALISP_IDENTIFIER) if (p1->type == ALISP_OBJ_STRING)
alisp_include_file(instance, p1->value.s); res = alisp_include_file(instance, p1->value.s);
p = cdr(p); p = cdr(p);
} while (p != &alsa_lisp_nil); } while (p != &alsa_lisp_nil);
return p1; return new_integer(instance, res);
} }
/* /*
@ -2140,12 +2191,13 @@ static struct intrinsic intrinsics[] = {
{ "eq", F_eq }, { "eq", F_eq },
{ "equal", F_equal }, { "equal", F_equal },
{ "eval", F_eval }, { "eval", F_eval },
{ "exfun", F_exfun },
{ "float", F_float }, { "float", F_float },
{ "garbage-collect", F_gc }, { "garbage-collect", F_gc },
{ "gc", F_gc }, { "gc", F_gc },
{ "if", F_if }, { "if", F_if },
{ "int", F_int },
{ "include", F_include }, { "include", F_include },
{ "int", F_int },
{ "list", F_list }, { "list", F_list },
{ "not", F_not }, { "not", F_not },
{ "nth", F_nth }, { "nth", F_nth },
@ -2219,7 +2271,9 @@ static struct alisp_object * eval(struct alisp_instance *instance, struct alisp_
case ALISP_OBJ_IDENTIFIER: case ALISP_OBJ_IDENTIFIER:
return get_object(instance, p); return get_object(instance, p);
case ALISP_OBJ_INTEGER: case ALISP_OBJ_INTEGER:
case ALISP_OBJ_FLOAT:
case ALISP_OBJ_STRING: case ALISP_OBJ_STRING:
case ALISP_OBJ_POINTER:
return p; return p;
case ALISP_OBJ_CONS: case ALISP_OBJ_CONS:
return eval_cons(instance, p); return eval_cons(instance, p);
@ -2385,23 +2439,6 @@ int alsa_lisp(struct alisp_cfg *cfg, struct alisp_instance **_instance)
unset_object(instance, omain); unset_object(instance, omain);
for (;;) {
p = get_object1(instance, "auto-exec");
if (p == &alsa_lisp_nil)
break;
p = get_object(instance, p);
if (p == &alsa_lisp_nil)
break;
unset_object1(instance, "auto-exec");
p1 = eval_func(instance, p, &alsa_lisp_nil);
if (p1 == NULL) {
retval = -ENOMEM;
break;
}
garbage_collect(instance);
}
done_lex(instance);
if (_instance) if (_instance)
*_instance = instance; *_instance = instance;
else else
@ -2414,6 +2451,7 @@ void alsa_lisp_free(struct alisp_instance *instance)
{ {
if (instance == NULL) if (instance == NULL)
return; return;
done_lex(instance);
free_objects(instance); free_objects(instance);
free(instance); free(instance);
} }
@ -2458,11 +2496,11 @@ int alsa_lisp_function(struct alisp_instance *instance, struct alisp_seq_iterato
const char *id, const char *args, ...) const char *id, const char *args, ...)
{ {
int err = 0; int err = 0;
struct alisp_object *aargs = NULL, *p3, *res; struct alisp_object *aargs = NULL, *obj, *res;
if (args && *args != 'n') { if (args && *args != 'n') {
va_list ap; va_list ap;
struct alisp_object *p, *obj; struct alisp_object *p;
p = NULL; p = NULL;
va_start(ap, args); va_start(ap, args);
while (*args) { while (*args) {
@ -2490,6 +2528,20 @@ int alsa_lisp_function(struct alisp_instance *instance, struct alisp_seq_iterato
case 'd': case 'd':
obj = new_integer(instance, va_arg(ap, double)); obj = new_integer(instance, va_arg(ap, double));
break; break;
case 'p': {
char _ptrid[24];
char *ptrid = _ptrid;
while (*args && *args != '%')
*ptrid++ = *args++;
*ptrid = 0;
if (ptrid == _ptrid) {
err = -EINVAL;
break;
}
obj = new_cons_pointer(instance, _ptrid, va_arg(ap, void *));
obj = quote_object(instance, obj);
break;
}
default: default:
err = -EINVAL; err = -EINVAL;
break; break;
@ -2526,8 +2578,8 @@ int alsa_lisp_function(struct alisp_instance *instance, struct alisp_seq_iterato
err = -ENOENT; err = -ENOENT;
if (aargs == NULL) if (aargs == NULL)
aargs = &alsa_lisp_nil; aargs = &alsa_lisp_nil;
if ((p3 = get_object1(instance, id)) != &alsa_lisp_nil) { if ((obj = get_object1(instance, id)) != &alsa_lisp_nil) {
res = eval_func(instance, p3, aargs); res = eval_func(instance, obj, aargs);
err = 0; err = 0;
} else { } else {
struct intrinsic key, *item; struct intrinsic key, *item;
@ -2607,7 +2659,7 @@ int alsa_lisp_seq_pointer(struct alisp_seq_iterator *seq, const char *ptr_id, vo
seq = seq->value.c.cdr; seq = seq->value.c.cdr;
if (seq->type == ALISP_OBJ_CONS) { if (seq->type == ALISP_OBJ_CONS) {
p2 = seq->value.c.car; p2 = seq->value.c.car;
if (p2->type != ALISP_OBJ_STRING && p2->type != ALISP_OBJ_IDENTIFIER) if (p2->type != ALISP_OBJ_STRING)
return -EINVAL; return -EINVAL;
if (strcmp(p2->value.s, ptr_id)) if (strcmp(p2->value.s, ptr_id))
return -EINVAL; return -EINVAL;

View file

@ -243,24 +243,6 @@ static struct alisp_object * new_result3(struct alisp_instance * instance, int e
return lexpr; return lexpr;
} }
static struct alisp_object * new_result4(struct alisp_instance * instance, const char *ptr_id, void *ptr)
{
struct alisp_object * lexpr;
if (ptr == NULL)
return &alsa_lisp_nil;
lexpr = new_object(instance, ALISP_OBJ_CONS);
if (lexpr == NULL)
return NULL;
lexpr->value.c.car = new_string(instance, ptr_id);
if (lexpr->value.c.car == NULL)
return NULL;
lexpr->value.c.cdr = new_pointer(instance, ptr);
if (lexpr->value.c.cdr == NULL)
return NULL;
return lexpr;
}
/* /*
* macros * macros
*/ */
@ -326,6 +308,8 @@ static struct alisp_object * FA_p_p(struct alisp_instance * instance, struct aca
item->xfunc == &snd_hctl_elem_next || item->xfunc == &snd_hctl_elem_next ||
item->xfunc == &snd_hctl_elem_prev) item->xfunc == &snd_hctl_elem_prev)
prefix1 = "hctl_elem"; prefix1 = "hctl_elem";
else if (item->xfunc == &snd_hctl_ctl)
prefix1 = "ctl";
else else
return &alsa_lisp_nil; return &alsa_lisp_nil;
args = eval(instance, car(args)); args = eval(instance, car(args));
@ -333,7 +317,7 @@ static struct alisp_object * FA_p_p(struct alisp_instance * instance, struct aca
if (handle == NULL) if (handle == NULL)
return &alsa_lisp_nil; return &alsa_lisp_nil;
handle = ((snd_p_p_t)item->xfunc)(handle); handle = ((snd_p_p_t)item->xfunc)(handle);
return new_result4(instance, prefix1, handle); return new_cons_pointer(instance, prefix1, handle);
} }
static struct alisp_object * FA_int_p(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args) static struct alisp_object * FA_int_p(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
@ -466,7 +450,7 @@ static struct alisp_object * FA_hctl_find_elem(struct alisp_instance * instance,
snd_ctl_elem_id_alloca(&id); snd_ctl_elem_id_alloca(&id);
if (parse_ctl_elem_id(eval(instance, car(cdr(args))), id) < 0) if (parse_ctl_elem_id(eval(instance, car(cdr(args))), id) < 0)
return &alsa_lisp_nil; return &alsa_lisp_nil;
return new_result4(instance, "hctl_elem", snd_hctl_find_elem(handle, id)); return new_cons_pointer(instance, "hctl_elem", snd_hctl_find_elem(handle, id));
} }
static struct alisp_object * FA_hctl_elem_info(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args) static struct alisp_object * FA_hctl_elem_info(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
@ -660,6 +644,36 @@ static struct alisp_object * FA_hctl_elem_write(struct alisp_instance * instance
return new_result(instance, err); return new_result(instance, err);
} }
static struct alisp_object * FA_pcm_info(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
{
snd_pcm_t *handle;
struct alisp_object * lexpr, * p1;
snd_pcm_info_t *info;
int err;
args = eval(instance, car(args));
handle = (snd_pcm_t *)get_ptr(args, item->prefix);
if (handle == NULL)
return &alsa_lisp_nil;
snd_pcm_info_alloca(&info);
err = snd_pcm_info(handle, info);
lexpr = new_lexpr(instance, err);
if (err < 0)
return lexpr;
p1 = add_cons(instance, lexpr->value.c.cdr, 0, "card", new_integer(instance, snd_pcm_info_get_card(info)));
p1 = add_cons(instance, p1, 1, "device", new_integer(instance, snd_pcm_info_get_device(info)));
p1 = add_cons(instance, p1, 1, "subdevice", new_integer(instance, snd_pcm_info_get_subdevice(info)));
p1 = add_cons(instance, p1, 1, "id", new_string(instance, snd_pcm_info_get_id(info)));
p1 = add_cons(instance, p1, 1, "name", new_string(instance, snd_pcm_info_get_name(info)));
p1 = add_cons(instance, p1, 1, "subdevice_name", new_string(instance, snd_pcm_info_get_subdevice_name(info)));
p1 = add_cons(instance, p1, 1, "class", new_integer(instance, snd_pcm_info_get_class(info)));
p1 = add_cons(instance, p1, 1, "subclass", new_integer(instance, snd_pcm_info_get_subclass(info)));
p1 = add_cons(instance, p1, 1, "subdevices_count", new_integer(instance, snd_pcm_info_get_subdevices_count(info)));
p1 = add_cons(instance, p1, 1, "subdevices_avail", new_integer(instance, snd_pcm_info_get_subdevices_avail(info)));
//p1 = add_cons(instance, p1, 1, "sync", new_string(instance, snd_pcm_info_get_sync(info)));
return lexpr;
}
/* /*
* main code * main code
*/ */
@ -673,6 +687,7 @@ static struct acall_table acall_table[] = {
{ "ctl_close", &FA_int_p, (void *)&snd_ctl_close, "ctl" }, { "ctl_close", &FA_int_p, (void *)&snd_ctl_close, "ctl" },
{ "ctl_open", &FA_int_pp_strp_int, (void *)&snd_ctl_open, "ctl" }, { "ctl_open", &FA_int_pp_strp_int, (void *)&snd_ctl_open, "ctl" },
{ "hctl_close", &FA_int_p, (void *)&snd_hctl_close, "hctl" }, { "hctl_close", &FA_int_p, (void *)&snd_hctl_close, "hctl" },
{ "hctl_ctl", &FA_p_p, (void *)&snd_hctl_ctl, "hctl" },
{ "hctl_elem_info", &FA_hctl_elem_info, (void *)&snd_hctl_elem_info, "hctl_elem" }, { "hctl_elem_info", &FA_hctl_elem_info, (void *)&snd_hctl_elem_info, "hctl_elem" },
{ "hctl_elem_next", &FA_p_p, (void *)&snd_hctl_elem_next, "hctl_elem" }, { "hctl_elem_next", &FA_p_p, (void *)&snd_hctl_elem_next, "hctl_elem" },
{ "hctl_elem_prev", &FA_p_p, (void *)&snd_hctl_elem_prev, "hctl_elem" }, { "hctl_elem_prev", &FA_p_p, (void *)&snd_hctl_elem_prev, "hctl_elem" },
@ -685,6 +700,7 @@ static struct acall_table acall_table[] = {
{ "hctl_load", &FA_int_p, (void *)&snd_hctl_load, "hctl" }, { "hctl_load", &FA_int_p, (void *)&snd_hctl_load, "hctl" },
{ "hctl_open", &FA_int_pp_strp_int, (void *)&snd_hctl_open, "hctl" }, { "hctl_open", &FA_int_pp_strp_int, (void *)&snd_hctl_open, "hctl" },
{ "hctl_open_ctl", &FA_int_pp_p, (void *)&snd_hctl_open_ctl, "hctl" }, { "hctl_open_ctl", &FA_int_pp_p, (void *)&snd_hctl_open_ctl, "hctl" },
{ "pcm_info", &FA_pcm_info, NULL, "pcm" },
}; };
static int acall_compar(const void *p1, const void *p2) static int acall_compar(const void *p1, const void *p2)
@ -724,9 +740,60 @@ static struct alisp_object * F_aerror(struct alisp_instance *instance, struct al
return args; return args;
} }
static int common_error(snd_output_t **rout, struct alisp_instance *instance, struct alisp_object * args)
{
struct alisp_object * p = args, * p1;
snd_output_t *out;
int err;
err = snd_output_buffer_open(&out);
if (err < 0)
return err;
do {
p1 = eval(instance, car(p));
if (p1->type == ALISP_OBJ_STRING)
snd_output_printf(out, "%s", p1->value.s);
else
princ_object(out, p1);
p = cdr(p);
} while (p != &alsa_lisp_nil);
*rout = out;
return 0;
}
static struct alisp_object * F_snderr(struct alisp_instance *instance, struct alisp_object * args)
{
snd_output_t *out;
char *str;
if (common_error(&out, instance, args) < 0)
return &alsa_lisp_nil;
snd_output_buffer_string(out, &str);
SNDERR(str);
snd_output_close(out);
return &alsa_lisp_t;
}
static struct alisp_object * F_syserr(struct alisp_instance *instance, struct alisp_object * args)
{
snd_output_t *out;
char *str;
if (common_error(&out, instance, args) < 0)
return &alsa_lisp_nil;
snd_output_buffer_string(out, &str);
SYSERR(str);
snd_output_close(out);
return &alsa_lisp_t;
}
static struct intrinsic snd_intrinsics[] = { static struct intrinsic snd_intrinsics[] = {
{ "acall", F_acall }, { "Acall", F_acall },
{ "aerror", F_aerror }, { "Aerror", F_aerror },
{ "ahandle", F_ahandle }, { "Ahandle", F_ahandle },
{ "aresult", F_ahandle }, { "Aresult", F_ahandle },
{ "Asnderr", F_snderr },
{ "Asyserr", F_syserr }
}; };

View file

@ -1,6 +1,7 @@
SUBDIRS=cards pcm SUBDIRS=cards pcm
cfg_files = alsa.conf cfg_files = alsa.conf \
sndo-mixer.alisp
EXTRA_DIST = $(cfg_files) EXTRA_DIST = $(cfg_files)

View file

@ -23,7 +23,18 @@ cfg_files = aliases.conf \
VIA8233A.conf \ VIA8233A.conf \
VX222.conf \ VX222.conf \
VXPocket.conf \ VXPocket.conf \
VXPocket440.conf VXPocket440.conf \
\
aliases.alisp
EXTRA_DIST = $(cfg_files)
alsa_DATA = $(cfg_files) alsa_DATA = $(cfg_files)
SI7018dir = $(datadir)/alsa/cards/SI7018
SI7018_files = \
SI7018/sndoc-mixer.alisp \
SI7018/sndop-mixer.alisp
SI7018_DATA = $(SI7018_files)
EXTRA_DIST =
$(cfg_files) \
$(SI7018_files)

View file

@ -0,0 +1,4 @@
(defun sndoc_mixer_open (hctl)
(princ "sndoc_mixer_open\n")
0
)

View file

@ -0,0 +1,4 @@
(defun sndop_mixer_open (hctl)
(princ "sndop_mixer_open\n")
0
)

View file

@ -0,0 +1,25 @@
(setq snd_card_aliases_array
(
("YMF724" . "YMF744")
("YMF724F" . "YMF744")
("YMF740" . "YMF744")
("YMF740C" . "YMF744")
("YMF754" . "YMF744")
("CMIPCI" . "CMI8338")
("CMI8738" . "CMI8338")
("CMI8738-MC4" . "CMI8738-MC6")
("E-mu APS" . "EMU10K1")
("GUS Max" . "GUS")
("GUS ACE" . "GUS")
("GUS Extreme" . "GUS")
("AMD InterWave" . "GUS")
("Dynasonic 3-D" . "GUS")
("InterWave STB" . "GUS")
)
)
(defun snd_card_alias (cardname)
(setq r (assq cardname snd_card_aliases_array))
(setq r (if (null r) cardname r))
(unsetq r)
)

82
src/conf/sndo-mixer.alisp Normal file
View file

@ -0,0 +1,82 @@
(defun sndo_include (hctl stream)
(setq info (Acall "ctl_card_info" (Acall "hctl_ctl" hctl)))
(if (= (Aerror info) 0)
(progn
(setq info (Aresult info))
(setq driver (cdr (assq "driver" (unsetq info))))
(setq file (+ (path "data") "/alsa/cards/" (snd_card_alias driver) "/sndo" stream "-mixer.alisp"))
(setq r (include file))
(when (= r -2) (Asyserr "unable to find file " file))
(unsetq driver file r)
)
(setq r (Aerror info))
(unsetq info r)
)
)
(defun sndo_mixer_open1 (pcm stream)
(setq info (Acall "pcm_info" pcm))
(setq r (Aerror info))
(when (= r 0)
(progn
(setq info (Aresult info))
(setq card (cdr (assq "card" info)))
(setq r
(if (< card 0)
(+ (Acall "pcm_name" pcm) stream)
(+ "hw:" (str card))
)
)
(unsetq card)
)
)
(unsetq info r)
)
(defun sndo_mixer_open (ppcm cpcm)
(setq pname (sndo_mixer_open1 ppcm "p"))
(setq cname (sndo_mixer_open1 cpcm "c"))
(setq phctl (Acall "hctl_open" pname nil))
(if (= (Aerror phctl) 0)
(progn
(setq phctl (Aresult phctl))
(setq chctl (Acall "hctl_open" cname nil))
(if (= (Aerror chctl) 0)
(progn
(setq chctl (Aresult chctl))
(setq hctls (cons phctl (cons chctl)))
(setq r (sndo_include phctl "p"))
(when (= r 0) (setq r (sndo_include chctl "c")))
(when (= r 0) (setq r (if (exfun sndop_mixer_open) (sndop_mixer_open phctl) 0)))
(when (= r 0)
(progn
(setq r (if (exfun sndoc_mixer_open) (sndoc_mixer_open chctl) 0))
(unless (= r 0) (sndop_close phctl))
)
)
(unless (= r 0) (sndo_close))
(unsetq phctl chctl)
(gc)
(unsetq r)
)
(progn
(Acall "hctl_close" (Aresult phctl))
(setq r (Aerror chctl))
(unsetq r)
)
)
)
(setq r (Aerror phctl))
(unsetq r)
)
)
(defun sndo_mixer_close nil
(cond (exfun sndop_close) (sndop_close (nth 0 hctls)))
(cond (exfun sndoc_close) (sndoc_close (nth 1 hctls)))
(Acall "hctl_close" (nth 0 hctls))
(Acall "hctl_close" (nth 1 hctls))
(unsetq hctls)
)
(include (+ (path "data") "/alsa/cards/aliases.alisp"))

View file

@ -89,7 +89,6 @@ int snd_hctl_open(snd_hctl_t **hctlp, const char *name, int mode)
int snd_hctl_open_ctl(snd_hctl_t **hctlp, snd_ctl_t *ctl) int snd_hctl_open_ctl(snd_hctl_t **hctlp, snd_ctl_t *ctl)
{ {
snd_hctl_t *hctl; snd_hctl_t *hctl;
int err;
assert(hctlp); assert(hctlp);
*hctlp = NULL; *hctlp = NULL;
@ -649,6 +648,16 @@ int snd_hctl_wait(snd_hctl_t *hctl, int timeout)
return 0; return 0;
} }
/**
* \brief Get a ctl handle associated to the given hctl handle
* \param hctl HCTL handle
* \return a ctl handle otherwise NULL
*/
snd_ctl_t *snd_hctl_ctl(snd_hctl_t *hctl)
{
return hctl->ctl;
}
static int snd_hctl_handle_event(snd_hctl_t *hctl, snd_ctl_event_t *event) static int snd_hctl_handle_event(snd_hctl_t *hctl, snd_ctl_event_t *event)
{ {
snd_hctl_elem_t *elem; snd_hctl_elem_t *elem;

View file

@ -70,14 +70,14 @@ struct sndo_mixer {
/** /**
* \brief Opens a ordinary mixer instance * \brief Opens a ordinary mixer instance
* \param pmixer Returned ordinary mixer handle * \param pmixer Returned ordinary mixer handle
* \param playback_name ASCII identifier of the ordinary mixer handle (playback controls) * \param playback_pcm handle of the playback PCM
* \param capture_name ASCII identifier of the ordinary mixer handle (capture controls) * \param capture_pcm handle of the capture PCM
* \param lconf Local configuration (might be NULL - use global configuration) * \param lconf Local configuration (might be NULL - use global configuration)
* \return 0 on success otherwise a negative error code * \return 0 on success otherwise a negative error code
*/ */
int sndo_mixer_open(sndo_mixer_t **pmixer, int sndo_mixer_open(sndo_mixer_t **pmixer,
const char *playback_name, snd_pcm_t *playback_pcm,
const char *capture_name, snd_pcm_t *capture_pcm,
struct alisp_cfg *lconf) struct alisp_cfg *lconf)
{ {
struct alisp_cfg *cfg = lconf; struct alisp_cfg *cfg = lconf;
@ -105,7 +105,7 @@ int sndo_mixer_open(sndo_mixer_t **pmixer,
err = alsa_lisp(cfg, &alisp); err = alsa_lisp(cfg, &alisp);
if (err < 0) if (err < 0)
goto __error; goto __error;
err = alsa_lisp_function(alisp, &iterator, "open", "%s%s", playback_name, capture_name); err = alsa_lisp_function(alisp, &iterator, "sndo_mixer_open", "%ppcm%ppcm", playback_pcm, capture_pcm);
if (err < 0) { if (err < 0) {
alsa_lisp_free(alisp); alsa_lisp_free(alisp);
goto __error; goto __error;
@ -161,7 +161,7 @@ int sndo_mixer_close(sndo_mixer_t *mixer)
{ {
int res; int res;
res = alsa_lisp_function(mixer->alisp, NULL, "close", "n"); res = alsa_lisp_function(mixer->alisp, NULL, "sndo_mixer_close", "n");
alsa_lisp_free(mixer->alisp); alsa_lisp_free(mixer->alisp);
if (mixer->_free_cfg) if (mixer->_free_cfg)
alsa_lisp_default_cfg_free(mixer->cfg); alsa_lisp_default_cfg_free(mixer->cfg);
@ -188,7 +188,7 @@ int sndo_mixer_poll_descriptors_count(sndo_mixer_t *mixer)
} else { } else {
struct alisp_seq_iterator *result; struct alisp_seq_iterator *result;
long val; long val;
err = alsa_lisp_function(mixer->alisp, &result, "poll_descriptors_count", "n"); err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_poll_descriptors_count", "n");
if (err < 0) if (err < 0)
return err; return err;
err = alsa_lisp_seq_integer(result, &val); err = alsa_lisp_seq_integer(result, &val);

View file

@ -13,8 +13,8 @@ static void help(void)
printf( printf(
"Usage: omixer [OPTION]...\n" "Usage: omixer [OPTION]...\n"
"-h,--help help\n" "-h,--help help\n"
"-P,--pname playback device\n" "-P,--pname playback PCM device\n"
"-C,--cname capture device\n" "-C,--cname capture PCM device\n"
"\n"); "\n");
} }
@ -29,6 +29,7 @@ int main(int argc, char *argv[])
}; };
int err, morehelp; int err, morehelp;
char *pname = "default", *cname = "default"; char *pname = "default", *cname = "default";
snd_pcm_t *phandle = NULL, *chandle = NULL;
sndo_mixer_t *handle; sndo_mixer_t *handle;
morehelp = 0; morehelp = 0;
@ -54,11 +55,31 @@ int main(int argc, char *argv[])
return 0; return 0;
} }
err = sndo_mixer_open(&handle, pname, cname, NULL); if (strcmp(pname, "-")) {
err = snd_pcm_open(&phandle, pname, SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
fprintf(stderr, "Playback PCM open error: %s\n", snd_strerror(err));
return EXIT_FAILURE;
}
}
if (strcmp(cname, "-")) {
err = snd_pcm_open(&chandle, cname, SND_PCM_STREAM_CAPTURE, 0);
if (err < 0) {
if (phandle)
snd_pcm_close(phandle);
fprintf(stderr, "Capture PCM open error: %s\n", snd_strerror(err));
return EXIT_FAILURE;
}
}
err = sndo_mixer_open(&handle, phandle, chandle, NULL);
if (err < 0) { if (err < 0) {
fprintf(stderr, "mixer open error: %s\n", snd_strerror(err)); fprintf(stderr, "mixer open error: %s\n", snd_strerror(err));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
sndo_mixer_close(handle); sndo_mixer_close(handle);
snd_pcm_close(chandle);
snd_pcm_close(phandle);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }