]> git.alsa-project.org Git - alsa-lib.git/commitdiff
More changes to the ordinary mixer API
authorJaroslav Kysela <perex@perex.cz>
Mon, 13 Oct 2003 12:06:45 +0000 (12:06 +0000)
committerJaroslav Kysela <perex@perex.cz>
Mon, 13 Oct 2003 12:06:45 +0000 (12:06 +0000)
include/control.h
include/mixer_ordinary.h
src/Versions
src/alisp/alisp.c
src/alisp/alisp_snd.c
src/conf/sndo-mixer.alisp
src/control/hcontrol.c
src/ordinary_mixer/ordinary_mixer.c
test/omixer.c

index a40c125ea07c240782796be4d17c45d084f7e012..73c10b36a462dedab79a8cccbdaf0785e4a69309 100644 (file)
@@ -455,6 +455,7 @@ int snd_hctl_close(snd_hctl_t *hctl);
 int snd_hctl_nonblock(snd_hctl_t *hctl, int nonblock);
 int snd_hctl_poll_descriptors_count(snd_hctl_t *hctl);
 int snd_hctl_poll_descriptors(snd_hctl_t *hctl, struct pollfd *pfds, unsigned int space);
+int snd_hctl_poll_descriptors_revents(snd_hctl_t *ctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
 unsigned int snd_hctl_get_count(snd_hctl_t *hctl);
 int snd_hctl_set_compare(snd_hctl_t *hctl, snd_hctl_compare_t hsort);
 snd_hctl_elem_t *snd_hctl_first_elem(snd_hctl_t *hctl);
index eebce24fb84c6764ffcdec682991e07c116e7152..0c25dc20b7a2c1a5a17deda9002d48aa7a3fb761 100644 (file)
 
 #include <alsa/asoundlib.h>
 
+/*
+ * Abbreviations:
+ *
+ * FLVOL    - Front Left Volume (0-1000)
+ * FCLVOL   - Front Center Left Volume (0-1000)
+ * FCVOL    - Front Center Volume (0-1000)
+ * FCRVOL   - Front Center Right Volume (0-1000)
+ * FRVOL    - Front Right Volume (0-1000)
+ * FSLVOL   - Front Side Left Volume (0-1000)
+ * FSRVOL   - Front Side Right Volume (0-1000)
+ * RSLVOL   - Rear Side Left Volume (0-1000)
+ * RSRVOL   - Rear Side Right Volume (0-1000)
+ * RLVOL    - Rear Left Volume (0-1000)
+ * RCVOL    - Rear Center Volume (0-1000)
+ * RRVOL    - Rear Right Volume (0-1000)
+ * LFEVOL   - Low Frequency Effects (Subwoofer) Volume (0-1000)
+ * OVRVOL   - Overhead Volume (0-1000)
+ */
+
 /** Ordinary Mixer I/O type */
 enum sndo_mixer_io_type {
 
@@ -36,158 +55,131 @@ enum sndo_mixer_io_type {
         *  playback section
         */
 
-       /** Master volume - left (0-1000) */
-       SNDO_MIO_MASTER_LVOL = 0,
-       /** Master volume - right (0-1000) */
-       SNDO_MIO_MASTER_RVOL,
-       /** 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) */
+       /* Master */
+       SNDO_MIO_MASTER_FLVOL = 0 * 0x40,
+       SNDO_MIO_MASTER_FCLVOL,
+       SNDO_MIO_MASTER_FCVOL,
+       SNDO_MIO_MASTER_FCRVOL,
+       SNDO_MIO_MASTER_FRVOL,
+       SNDO_MIO_MASTER_FSLVOL,
+       SNDO_MIO_MASTER_FSRVOL,
+       SNDO_MIO_MASTER_RSLVOL,
+       SNDO_MIO_MASTER_RSRVOL,
+       SNDO_MIO_MASTER_RLVOL,
+       SNDO_MIO_MASTER_RCVOL,
+       SNDO_MIO_MASTER_RRVOL,
        SNDO_MIO_MASTER_LFEVOL,
-       /** Master volume - left mute (0 = off, 1 = on) */
-       SNDO_MIO_MASTER_LMUTE,
-       /** Master volume - right mute (0 = off, 1 = on) */
-       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) */
-       SNDO_MIO_PCM_LVOL = 0,
-       /** PCM volume - right (0-1000) */
-       SNDO_MIO_PCM_RVOL,
-       /** PCM volume - left surround (0-1000) */
-       SNDO_MIO_PCM_LSVOL = 0,
-       /** PCM volume - right surround (0-1000) */
-       SNDO_MIO_PCM_RSVOL,
-       /** PCM volume - center (0-1000) */
-       SNDO_MIO_PCM_CVOL = 0,
-       /** PCM volume - LFE (0-1000) */
+       SNDO_MIO_MASTER_OVRVOL,
+
+       /* PCM */
+       SNDO_MIO_PCM_FLVOL = 1 * 0x40,
+       SNDO_MIO_PCM_FCLVOL,
+       SNDO_MIO_PCM_FCVOL,
+       SNDO_MIO_PCM_FCRVOL,
+       SNDO_MIO_PCM_FRVOL,
+       SNDO_MIO_PCM_FSLVOL,
+       SNDO_MIO_PCM_FSRVOL,
+       SNDO_MIO_PCM_RSLVOL,
+       SNDO_MIO_PCM_RSRVOL,
+       SNDO_MIO_PCM_RLVOL,
+       SNDO_MIO_PCM_RCVOL,
+       SNDO_MIO_PCM_RRVOL,
        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_PCM_OVRVOL,
+
+       /* LINE */
+       SNDO_MIO_LINE_FLVOL = 2 * 0x40,
+       SNDO_MIO_LINE_FCLVOL,
+       SNDO_MIO_LINE_FCVOL,
+       SNDO_MIO_LINE_FCRVOL,
+       SNDO_MIO_LINE_FRVOL,
+       SNDO_MIO_LINE_FSLVOL,
+       SNDO_MIO_LINE_FSRVOL,
+       SNDO_MIO_LINE_RSLVOL,
+       SNDO_MIO_LINE_RSRVOL,
+       SNDO_MIO_LINE_RLVOL,
+       SNDO_MIO_LINE_RCVOL,
+       SNDO_MIO_LINE_RRVOL,
        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_LINE_OVRVOL,
+
+       /* MIC */
+       SNDO_MIO_MIC_FLVOL = 3 * 0x40,
+       SNDO_MIO_MIC_FCLVOL,
+       SNDO_MIO_MIC_FCVOL,
+       SNDO_MIO_MIC_FCRVOL,
+       SNDO_MIO_MIC_FRVOL,
+       SNDO_MIO_MIC_FSLVOL,
+       SNDO_MIO_MIC_FSRVOL,
+       SNDO_MIO_MIC_RSLVOL,
+       SNDO_MIO_MIC_RSRVOL,
+       SNDO_MIO_MIC_RLVOL,
+       SNDO_MIO_MIC_RCVOL,
+       SNDO_MIO_MIC_RRVOL,
        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) */
-       SNDO_MIO_CD_LVOL = 0,
-       /** CD volume - right (0-1000) */
-       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_MIC_OVRVOL,
+
+       /* CD */
+       SNDO_MIO_CD_FLVOL = 4 * 0x40,
+       SNDO_MIO_CD_FCLVOL,
+       SNDO_MIO_CD_FCVOL,
+       SNDO_MIO_CD_FCRVOL,
+       SNDO_MIO_CD_FRVOL,
+       SNDO_MIO_CD_FSLVOL,
+       SNDO_MIO_CD_FSRVOL,
+       SNDO_MIO_CD_RSLVOL,
+       SNDO_MIO_CD_RSRVOL,
+       SNDO_MIO_CD_RLVOL,
+       SNDO_MIO_CD_RCVOL,
+       SNDO_MIO_CD_RRVOL,
        SNDO_MIO_CD_LFEVOL,
-       /** CD volume - left mute (0 = off, 1 = on) */
-       SNDO_MIO_CD_LMUTE,
-       /** CD volume - right mute (0 = off, 1 = on) */
-       SNDO_MIO_CD_RMUTE,
-       /** CD volume - left surround mute (0 = off, 1 = on) */
-       SNDO_MIO_CD_LSMUTE,
-       /** CD volume - right surround mute (0 = off, 1 = on) */
-       SNDO_MIO_CD_RSMUTE,
-       /** CD volume - center mute (0 = off, 1 = on) */
-       SNDO_MIO_CD_CMUTE,
-       /** CD volume - LFE mute (0 = off, 1 = on) */
-       SNDO_MIO_CD_LFEMUTE,
+       SNDO_MIO_CD_OVRVOL,
+
+       /* AUX */
+       SNDO_MIO_AUX_FLVOL = 5 * 0x40,
+       SNDO_MIO_AUX_FCLVOL,
+       SNDO_MIO_AUX_FCVOL,
+       SNDO_MIO_AUX_FCRVOL,
+       SNDO_MIO_AUX_FRVOL,
+       SNDO_MIO_AUX_FSLVOL,
+       SNDO_MIO_AUX_FSRVOL,
+       SNDO_MIO_AUX_RSLVOL,
+       SNDO_MIO_AUX_RSRVOL,
+       SNDO_MIO_AUX_RLVOL,
+       SNDO_MIO_AUX_RCVOL,
+       SNDO_MIO_AUX_RRVOL,
+       SNDO_MIO_AUX_LFEVOL,
+       SNDO_MIO_AUX_OVRVOL,
 
        /*
         *  capture section
         */
 
-       /** capture gain - left (0-1000) */
-       SNDO_MIO_CGAIN_LVOL = 0x1000,
-       /** capture gain - right (0-1000) */
-       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) */
-       SNDO_MIO_CSOURCE_MIC = 0x1100,
-       /** capture source - LINE exclusive switch (0 = off, 1 = on) */
+       /* capture gain */
+       SNDO_MIO_CGAIN_FL = 0x8000,
+       SNDO_MIO_CGAIN_FCL,
+       SNDO_MIO_CGAIN_FC,
+       SNDO_MIO_CGAIN_FCR,
+       SNDO_MIO_CGAIN_FR,
+       SNDO_MIO_CGAIN_FSL,
+       SNDO_MIO_CGAIN_FSR,
+       SNDO_MIO_CGAIN_RSL,
+       SNDO_MIO_CGAIN_RSR,
+       SNDO_MIO_CGAIN_RL,
+       SNDO_MIO_CGAIN_RC,
+       SNDO_MIO_CGAIN_RR,
+       SNDO_MIO_CGAIN_LFE,
+       SNDO_MIO_CGAIN_OVR,
+
+       /* capture source (0 = off, 1 = on) */
+       SNDO_MIO_CSOURCE_MIC = 0x8100,
        SNDO_MIO_CSOURCE_LINE,
-       /** capture source - CD exclusive switch (0 = off, 1 = on) */
        SNDO_MIO_CSOURCE_CD,
-       /** capture source - AUX exclusive switch (0 = off, 1 = on) */
        SNDO_MIO_CSOURCE_AUX,
-       /** capture source - MIX exclusive switch (0 = off, 1 = on) */
-       SNDO_MIO_CSOURCE_MIX
+       SNDO_MIO_CSOURCE_MIX,
+
+       /* misc */
+       SNDO_MIO_STEREO = 0x8200,       /* (0 = off, 1 = on) standard stereo source, might be converted to use all outputs */
 };
 
 typedef struct sndo_mixer sndo_mixer_t;
@@ -208,8 +200,13 @@ int sndo_mixer_close(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_revents(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
+int sndo_mixer_io_get_name(enum sndo_mixer_io_type type, char **name);
 int sndo_mixer_io_get(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val);
-int sndo_mixer_io_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int val);
+int sndo_mixer_io_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val);
+int sndo_mixer_io_try_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val);
+int sndo_mixer_io_get_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val);
+int sndo_mixer_io_set_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val);
+int sndo_mixer_io_try_set_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val);
 int sndo_mixer_io_change(sndo_mixer_t *mixer, enum sndo_mixer_io_type *changed, int changed_array_size);
 
 /** \} */
index d9919cf5901f7597490d3214483720d9d15fe8cc..aedaff9a9031c6952d8160eb998070d1dc782761 100644 (file)
@@ -135,3 +135,9 @@ ALSA_0.9.7 {
     sndo_*;
     alsa_lisp_*;
 } ALSA_0.9.6;
+
+ALSA_0.9.8 {
+  global:
+
+    snd_hctl_poll_descriptors_revents;
+} ALSA_0.9.7;
index 4e8b2bf05a924eede4644c60d0bcda0186103c5f..0522a399edd500abd0c7dc52d75b8c704d0a169d 100644 (file)
@@ -51,6 +51,7 @@ static struct alisp_object * parse_object(struct alisp_instance *instance, int h
 static void princ_cons(snd_output_t *out, struct alisp_object * p);
 static void princ_object(snd_output_t *out, struct alisp_object * p);
 static struct alisp_object * eval(struct alisp_instance *instance, struct alisp_object * p);
+static struct alisp_object * eval_cons1(struct alisp_instance *instance, struct alisp_object * p1, struct alisp_object * p2);
 
 /* functions */
 static struct alisp_object *F_eval(struct alisp_instance *instance, struct alisp_object *);
@@ -467,7 +468,7 @@ static int gettoken(struct alisp_instance *instance)
                        return instance->thistoken;
 
                got_id:
-               case '_': case '+': case '*': case '/': case '%':
+               case '!': case '_': case '+': case '*': case '/': case '%':
                case '<': case '>': case '=': case '&':
                case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
                case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
@@ -479,7 +480,7 @@ static int gettoken(struct alisp_instance *instance)
                case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
                case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
                case 'Y': case 'Z':
-                       /* Identifier: [-/+*%<>=&a-zA-Z_][-/+*%<>=&a-zA-Z_0-9]* */
+                       /* Identifier: [!-/+*%<>=&a-zA-Z_][-/+*%<>=&a-zA-Z_0-9]* */
                        p = instance->token_buffer;
                        do {
                                if (p - instance->token_buffer >= instance->token_buffer_max) {
@@ -489,7 +490,7 @@ static int gettoken(struct alisp_instance *instance)
                                }
                                *p++ = c;
                                c = xgetc(instance);
-                       } while (isalnum(c) || strchr("_-+*/%<>=&", c) != NULL);
+                       } while (isalnum(c) || strchr("!_-+*/%<>=&", c) != NULL);
                        xungetc(instance, c);
                        *p = '\0';
                        return instance->thistoken = ALISP_IDENTIFIER;
@@ -1325,6 +1326,19 @@ static struct alisp_object * F_numeq(struct alisp_instance *instance, struct ali
        return &alsa_lisp_nil;
 }
 
+/*
+ * Syntax: (!= expr1 expr2)
+ */
+static struct alisp_object * F_numneq(struct alisp_instance *instance, struct alisp_object * args)
+{
+       struct alisp_object * p;
+       
+       p = F_numeq(instance, args);
+       if (p == &alsa_lisp_nil)
+               return &alsa_lisp_t;
+       return &alsa_lisp_nil;
+}
+
 /*
  * Syntax: (exfun name)
  * Test, if a function exists
@@ -1333,7 +1347,7 @@ static struct alisp_object * F_exfun(struct alisp_instance *instance, struct ali
 {
        struct alisp_object * p1, * p2;
 
-       p1 = car(args);
+       p1 = eval(instance, car(args));
        if (p1->type != ALISP_OBJ_STRING && p1->type != ALISP_OBJ_IDENTIFIER)
                return &alsa_lisp_nil;
        p2 = get_object(instance, p1);
@@ -1960,6 +1974,20 @@ struct alisp_object * F_include(struct alisp_instance *instance, struct alisp_ob
        return new_integer(instance, res);
 }
 
+/*
+ * Syntax: (call function args...)
+ */
+struct alisp_object * F_call(struct alisp_instance *instance, struct alisp_object * args)
+{
+       struct alisp_object * p = eval(instance, car(args));
+
+       if (p->type != ALISP_OBJ_IDENTIFIER && p->type != ALISP_OBJ_STRING) {
+               lisp_warn(instance, "expected an function name");
+               return &alsa_lisp_nil;
+       }
+       return eval_cons1(instance, p, cdr(args));
+}
+
 /*
  * Syntax: (int value)
  * 'value' can be integer or float type
@@ -1968,9 +1996,9 @@ struct alisp_object * F_int(struct alisp_instance *instance, struct alisp_object
 {
        struct alisp_object * p = eval(instance, car(args));
 
-       if (p->type == ALISP_INTEGER)
+       if (p->type == ALISP_OBJ_INTEGER)
                return p;
-       if (p->type == ALISP_FLOAT)
+       if (p->type == ALISP_OBJ_FLOAT)
                return new_integer(instance, floor(p->value.f));
 
        lisp_warn(instance, "expected an integer or float for integer conversion");
@@ -1985,9 +2013,9 @@ struct alisp_object * F_float(struct alisp_instance *instance, struct alisp_obje
 {
        struct alisp_object * p = eval(instance, car(args));
 
-       if (p->type == ALISP_FLOAT)
+       if (p->type == ALISP_OBJ_FLOAT)
                return p;
-       if (p->type == ALISP_INTEGER)
+       if (p->type == ALISP_OBJ_INTEGER)
                return new_float(instance, p->value.i);
 
        lisp_warn(instance, "expected an integer or float for integer conversion");
@@ -2002,9 +2030,9 @@ struct alisp_object * F_str(struct alisp_instance *instance, struct alisp_object
 {
        struct alisp_object * p = eval(instance, car(args));
 
-       if (p->type == ALISP_STRING)
+       if (p->type == ALISP_OBJ_STRING)
                return p;
-       if (p->type == ALISP_INTEGER || p->type == ALISP_FLOAT) {
+       if (p->type == ALISP_OBJ_INTEGER || p->type == ALISP_OBJ_FLOAT) {
                char buf[64];
                if (p->type == ALISP_INTEGER) {
                        snprintf(buf, sizeof(buf), "%ld", p->value.i);
@@ -2166,6 +2194,7 @@ struct intrinsic {
 };
 
 static struct intrinsic intrinsics[] = {
+       { "!=", F_numneq },
        { "%", F_mod },
        { "&dump-memory", F_dump_memory },
        { "&dump-objects", F_dump_objects },
@@ -2183,6 +2212,7 @@ static struct intrinsic intrinsics[] = {
        { "assoc", F_assoc },
        { "assq", F_assq },
        { "atom", F_atom },
+       { "call", F_call },
        { "car", F_car },
        { "cdr", F_cdr },
        { "cond", F_cond },
@@ -2233,33 +2263,41 @@ static int compar(const void *p1, const void *p2)
                      ((struct intrinsic *)p2)->name);
 }
 
-static struct alisp_object * eval_cons(struct alisp_instance *instance, struct alisp_object * p)
+static struct alisp_object * eval_cons1(struct alisp_instance *instance, struct alisp_object * p1, struct alisp_object * p2)
 {
-       struct alisp_object * p1 = car(p), * p2 = cdr(p), * p3;
+       struct alisp_object * p3;
+       struct intrinsic key, *item;
 
-       if (p1 != &alsa_lisp_nil && p1->type == ALISP_OBJ_IDENTIFIER) {
-               struct intrinsic key, *item;
+       key.name = p1->value.id;
+       if ((item = bsearch(&key, intrinsics,
+                           sizeof intrinsics / sizeof intrinsics[0],
+                           sizeof intrinsics[0], compar)) != NULL)
+                       return item->func(instance, p2);
 
-               if (!strcmp(p1->value.id, "lambda"))
-                       return p;
+       if ((item = bsearch(&key, snd_intrinsics,
+                           sizeof snd_intrinsics / sizeof snd_intrinsics[0],
+                           sizeof snd_intrinsics[0], compar)) != NULL)
+               return item->func(instance, p2);
 
-               auto_garbage_collect(instance);
+       if ((p3 = get_object(instance, p1)) != &alsa_lisp_nil)
+               return eval_func(instance, p3, p2);
+       else
+               lisp_warn(instance, "function `%s' is undefined", p1->value.id);
 
-               key.name = p1->value.id;
-               if ((item = bsearch(&key, intrinsics,
-                                   sizeof intrinsics / sizeof intrinsics[0],
-                                   sizeof intrinsics[0], compar)) != NULL)
-                       return item->func(instance, p2);
+       return &alsa_lisp_nil;
+}
 
-               if ((item = bsearch(&key, snd_intrinsics,
-                                   sizeof snd_intrinsics / sizeof snd_intrinsics[0],
-                                   sizeof snd_intrinsics[0], compar)) != NULL)
-                       return item->func(instance, p2);
+static inline struct alisp_object * eval_cons(struct alisp_instance *instance, struct alisp_object * p)
+{
+       struct alisp_object * p1 = car(p);
 
-               if ((p3 = get_object(instance, p1)) != &alsa_lisp_nil)
-                       return eval_func(instance, p3, p2);
-               else
-                       lisp_warn(instance, "function `%s' is undefined", p1->value.id);
+       if (p1 != &alsa_lisp_nil && p1->type == ALISP_OBJ_IDENTIFIER) {
+               if (!strcmp(p1->value.id, "lambda"))
+                       return p;
+
+               auto_garbage_collect(instance);
+               
+               return eval_cons1(instance, p1, cdr(p));
        }
 
        return &alsa_lisp_nil;
@@ -2655,8 +2693,8 @@ int alsa_lisp_seq_pointer(struct alisp_seq_iterator *seq, const char *ptr_id, vo
 {
        struct alisp_object * p2;
        
-       if (seq->type == ALISP_OBJ_CONS && seq->value.c.cdr->type == ALISP_OBJ_CONS)
-               seq = seq->value.c.cdr;
+       if (seq->type == ALISP_OBJ_CONS && seq->value.c.car->type == ALISP_OBJ_CONS)
+               seq = seq->value.c.car;
        if (seq->type == ALISP_OBJ_CONS) {
                p2 = seq->value.c.car;
                if (p2->type != ALISP_OBJ_STRING)
index 6c12c9cce2b23bc5becf850a164201efa2eda6d3..3bfe1c9c840e28df3c981616638ac054d07f5905 100644 (file)
@@ -188,11 +188,6 @@ static struct alisp_object * add_cons2(struct alisp_instance * instance, struct
        return lexpr;
 }
 
-static inline struct alisp_object * new_result(struct alisp_instance * instance, int err)
-{
-       return new_integer(instance, err);
-}
-
 static struct alisp_object * new_result1(struct alisp_instance * instance, int err, const char *ptr_id, void *ptr)
 {
        struct alisp_object * lexpr, * p1;
@@ -254,6 +249,7 @@ static struct alisp_object * new_result3(struct alisp_instance * instance, int e
 typedef int (*snd_int_pp_strp_int_t)(void **rctl, const char *name, int mode);
 typedef int (*snd_int_pp_p_t)(void **rctl, void *handle);
 typedef int (*snd_int_p_t)(void *rctl);
+typedef char * (*snd_str_p_t)(void *rctl);
 typedef int (*snd_int_intp_t)(int *val);
 typedef int (*snd_int_str_t)(const char *str);
 typedef int (*snd_int_int_strp_t)(int val, char **str);
@@ -328,7 +324,18 @@ static struct alisp_object * FA_int_p(struct alisp_instance * instance, struct a
        handle = (void *)get_ptr(args, item->prefix);
        if (handle == NULL)
                return &alsa_lisp_nil;
-       return new_result(instance, ((snd_int_p_t)item->xfunc)(handle));
+       return new_integer(instance, ((snd_int_p_t)item->xfunc)(handle));
+}
+
+static struct alisp_object * FA_str_p(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
+{
+       void *handle;
+
+       args = eval(instance, car(args));
+       handle = (void *)get_ptr(args, item->prefix);
+       if (handle == NULL)
+               return &alsa_lisp_nil;
+       return new_string(instance, ((snd_str_p_t)item->xfunc)(handle));
 }
 
 static struct alisp_object * FA_int_intp(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
@@ -351,7 +358,7 @@ static struct alisp_object * FA_int_str(struct alisp_instance * instance, struct
        if (args->type != ALISP_OBJ_STRING && args->type != ALISP_OBJ_IDENTIFIER)
                return &alsa_lisp_nil;
        err = ((snd_int_str_t)item->xfunc)(args->value.s);
-       return new_result(instance, err);
+       return new_integer(instance, err);
 }
 
 static struct alisp_object * FA_int_int_strp(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
@@ -606,7 +613,7 @@ static struct alisp_object * FA_hctl_elem_write(struct alisp_instance * instance
        snd_ctl_elem_value_alloca(&value);
        err = snd_hctl_elem_info(handle, info);
        if (err < 0)
-               return new_result(instance, err);
+               return new_integer(instance, err);
        type = snd_ctl_elem_info_get_type(info);
        count = snd_ctl_elem_info_get_count(info);
        if (type == SND_CTL_ELEM_TYPE_IEC958) {
@@ -641,7 +648,7 @@ static struct alisp_object * FA_hctl_elem_write(struct alisp_instance * instance
                p1 = cdr(p1);
        } while (p1 != &alsa_lisp_nil);
        err = snd_hctl_elem_write(handle, value);
-       return new_result(instance, err);
+       return new_integer(instance, err);
 }
 
 static struct alisp_object * FA_pcm_info(struct alisp_instance * instance, struct acall_table * item, struct alisp_object * args)
@@ -701,6 +708,7 @@ static struct acall_table acall_table[] = {
        { "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" },
        { "pcm_info", &FA_pcm_info, NULL, "pcm" },
+       { "pcm_name", &FA_str_p, (void *)&snd_pcm_name, "pcm" },
 };
 
 static int acall_compar(const void *p1, const void *p2)
index 8342ad05ce47ce6183bad6d48a7aa8327d851cfd..3b3ffdf3119e3251fd7ac0d7c6172ba2122cbd6a 100644 (file)
@@ -1,3 +1,7 @@
+;
+; Toplevel configuration for the ALSA Ordinary Mixer Interface
+;
+
 (defun sndo_include (hctl stream)
   (setq info (Acall "ctl_card_info" (Acall "hctl_ctl" hctl)))
   (if (= (Aerror info) 0)
       (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)
   )
+  (unsetq info driver file r)
+)
+
+(defun sndo_mixer_open_fcn (stream)
+  (setq fcn (+ "sndo" stream "_mixer_open"))
+  (setq r (if (exfun fcn) (call fcn hctl) 0))
+  (when (= r 0)
+    (setq hctls (if hctls (cons hctls (cons hctl)) hctl))
+  )
+  (unsetq fcn r)
+)
+
+(defun sndo_mixer_open_hctl (card stream)
+  (setq hctl (Acall "hctl_open" (+ "hw:" (str card)) nil))
+  (setq r (Aerror hctl))
+  (when (= r 0)
+    (setq hctl (Aresult hctl))
+    (setq r (sndo_include hctl stream))
+    (when (= r 0) (setq r (sndo_mixer_open_fcn stream)))
+  )
+  (unsetq hctl r)
+)
+
+(defun sndo_mixer_open_virtual (pcm stream)
+  (setq name (Acall "pcm_name" pcm))
+  (setq file (+ (path "data") "/alsa/virtual/" name "/sndo" stream "-mixer.alisp"))
+  (setq r (include file))
+  (when (= r -2) (Asyserr "unable to find file " file))
+  (when (= r 0) (setq r (sndo_mixer_open_fcn stream)))
+  (unsetq name file 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))
-        )
+    (setq info (Aresult info))
+    (setq card (cdr (assq "card" info)))
+    (setq r
+      (if (< card 0)
+       (sndo_mixer_open_virtual pcm stream)
+        (sndo_mixer_open_hctl card stream)
       )
-      (unsetq card)
     )
   )
-  (unsetq info r)
+  (unsetq info card 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)
+  (setq r (sndo_mixer_open1 ppcm "p"))
+  (when (= r 0) (setq r (sndo_mixer_open1 cpcm "c")))
+  (when (!= r 0) (sndo_mixer_close))
+  (unsetq r)
+)
+
+(defun sndo_mixer_close1 (hctl stream)
+  (when hctl
     (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 fcn (+ "sndo" stream "_mixer_close"))
+      (when (exfun fcn) (call fcn hctl))
+      (unsetq fcn)
+      (Acall "hctl_close" hctl)
     )
-    (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))
+  (sndo_mixer_close1 (nth 1 hctls) "c")
+  (sndo_mixer_close1 (nth 0 hctls) "p")
   (unsetq hctls)
 )
 
index b1d5ac427686595973beaa59d7e91e699381c985..3779fc80c123482b7e932e360f5b8480cbd692d5 100644 (file)
@@ -184,6 +184,20 @@ int snd_hctl_poll_descriptors(snd_hctl_t *hctl, struct pollfd *pfds, unsigned in
        return snd_ctl_poll_descriptors(hctl->ctl, pfds, space);
 }
 
+/**
+ * \brief get returned events from poll descriptors
+ * \param ctl HCTL handle
+ * \param pfds array of poll descriptors
+ * \param nfds count of poll descriptors
+ * \param revents returned events
+ * \return zero if success, otherwise a negative error code
+ */
+int snd_hctl_poll_descriptors_revents(snd_hctl_t *hctl, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
+{
+       assert(hctl);
+       return snd_ctl_poll_descriptors_revents(hctl->ctl, pfds, nfds, revents);
+}
+
 static int snd_hctl_throw_event(snd_hctl_t *hctl, unsigned int mask,
                         snd_hctl_elem_t *elem)
 {
index 630429239b28e0444cd082dfab3b39c440ddc461..9443a04a3a7bb4d577aa2460d992f9a779af606f 100644 (file)
@@ -206,8 +206,27 @@ 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)
 {
-       //return snd_mixer_poll_descriptors(mixer->mixer, pfds, space);
-       return -ENODEV;
+       int err, idx, res;
+
+       if (mixer->hctl_count > 0) {
+               for (idx = res = 0; idx < mixer->hctl_count && space > 0; idx++) {
+                       err = snd_hctl_poll_descriptors(mixer->hctl[idx], pfds, space);
+                       if (err < 0)
+                               return err;
+                       res += err;
+                       space -= err;
+               }
+               return res;
+       } else {
+               struct alisp_seq_iterator *result;
+               long val;
+               err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_poll_descriptors", "%i", space);
+               if (err < 0)
+                       return err;
+               assert(0);      /* FIXME: pass pfds to application */
+               err = alsa_lisp_seq_integer(result, &val);
+               return err < 0 ? err : val;
+       }
 }
 
 /**
@@ -220,8 +239,120 @@ int sndo_mixer_poll_descriptors(sndo_mixer_t *mixer, struct pollfd *pfds, unsign
  */ 
 int sndo_mixer_poll_descriptors_revents(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
 {
-       //return snd_mixer_poll_descriptors_revents(mixer->mixer, pfds, nfds, revents);
-       return -ENODEV;
+       int err, idx, count, res;
+
+       if (mixer->hctl_count > 0) {
+               for (idx = res = 0; idx < mixer->hctl_count && nfds > 0; idx++) {
+                       err = snd_hctl_poll_descriptors_count(mixer->hctl[idx]);
+                       if (err < 0)
+                               return err;
+                       count = err;
+                       if (nfds < (unsigned int)err)
+                               return -EINVAL;
+                       err = snd_hctl_poll_descriptors_revents(mixer->hctl[idx], pfds, count, revents);
+                       if (err < 0)
+                               return err;
+                       if (err != count)
+                               return -EINVAL;
+                       pfds += count;
+                       nfds -= err;
+                       revents += count;
+                       res += count;
+               }
+               return res;
+       } else {
+               struct alisp_seq_iterator *result;
+               long val, tmp;
+               
+               assert(0);      /* FIXME: pass pfds to alisp too */
+               err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_poll_descriptors_revents", "%i", nfds);
+               if (err < 0)
+                       return err;
+               err = alsa_lisp_seq_integer(result, &val);
+               if (err >= 0 && alsa_lisp_seq_count(result) > 1) {
+                       alsa_lisp_seq_next(&result);
+                       err = alsa_lisp_seq_integer(result, &tmp);
+                       *revents = tmp;
+               } else {
+                       *revents = 0;
+               }
+               return err < 0 ? err : val;
+       }
+}
+
+#define IOLINES 6
+
+static const char *name_table1[] = {
+       "Master",
+       "PCM",
+       "Line",
+       "Mic"
+       "CD",
+       "AUX"
+};
+
+#define SPEAKERS 14
+
+static const char *name_table2[] = {
+       "Front Left",
+       "Front Center Left",
+       "Front Center",
+       "Front Center Right",
+       "Front Right",
+       "Front Side Left",
+       "Front Side Right",
+       "Rear Side Left",
+       "Rear Side Right",
+       "Rear Left",
+       "Rear Center",
+       "Rear Right",
+       "LFE (Subwoofer)",
+       "Overhead"
+};
+
+#define CSOURCES 5
+
+static const char *name_table3[] = {
+       "Mic",
+       "Line",
+       "CD",
+       "AUX",
+       "Mix",
+};
+
+static int compose_string(char **result, const char *s1, const char *s2, const char *s3, const char *s4)
+{
+       int len = strlen(s1) + strlen(s2) + strlen(s3) + strlen(s4);
+       *result = malloc(len + 1);
+       if (*result == NULL)
+               return -ENOMEM;
+       strcpy(*result, s1);
+       strcat(*result, s2);
+       strcat(*result, s3);
+       strcat(*result, s4);
+       return 0;
+}
+
+/**
+ * \brief get ordinary mixer io control value
+ * \param mixer ordinary mixer handle
+ * \param type io type
+ * \param val returned value
+ * \return zero if success, otherwise a negative error code
+ */ 
+int sndo_mixer_io_get_name(enum sndo_mixer_io_type type, char **name)
+{
+       if (type < IOLINES * 0x40) {
+               int tmp = type / 0x40;
+               type %= 0x40;
+               if (type < SPEAKERS)
+                       return compose_string(name, name_table1[tmp], " ", name_table2[type], " Volume");
+       } else if (type >= SNDO_MIO_CGAIN_FL && type < SNDO_MIO_CGAIN_FL + SPEAKERS) {
+               return compose_string(name, "Capture Gain ", name_table2[type - SNDO_MIO_CGAIN_FL], "", "");
+       } else if (type >= SNDO_MIO_CSOURCE_MIC && type < SNDO_MIO_CSOURCE_MIC + CSOURCES) {
+               return compose_string(name, "Capture Source ", name_table3[type - SNDO_MIO_CSOURCE_MIC], "", "");
+       }
+       return -ENOENT;
 }
 
 /**
@@ -233,7 +364,18 @@ int sndo_mixer_poll_descriptors_revents(sndo_mixer_t *mixer, struct pollfd *pfds
  */ 
 int sndo_mixer_io_get(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val)
 {
-       return -ENODEV;
+       struct alisp_seq_iterator *result;
+       long val1;
+       int err;
+
+       err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_set", "%i", type);
+       if (err < 0)
+               return err;
+       err = alsa_lisp_seq_integer(result, &val1);
+       if (err < 0)
+               return err;
+       *val = val1;
+       return 0;
 }
 
 /**
@@ -243,9 +385,118 @@ int sndo_mixer_io_get(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *va
  * \param val desired value
  * \return zero if success, otherwise a negative error code
  */ 
-int sndo_mixer_io_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int val)
+int sndo_mixer_io_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val)
+{
+       struct alisp_seq_iterator *result;
+       long val1;
+       int err;
+
+       err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_set", "%i%i", type, *val);
+       if (err < 0)
+               return err;
+       err = alsa_lisp_seq_integer(result, &val1);
+       if (err < 0)
+               return err;
+       *val = val1;
+       return 0;
+}
+
+/**
+ * \brief try to set ordinary mixer io control value
+ * \param mixer ordinary mixer handle
+ * \param type io type
+ * \param val desired value
+ * \return zero if success, otherwise a negative error code
+ *
+ * This function does not update the value.
+ * It only returns the real value which will be set.
+ */ 
+int sndo_mixer_io_try_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val)
+{
+       struct alisp_seq_iterator *result;
+       long val1;
+       int err;
+
+       err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_try_set", "%i%i", type, *val);
+       if (err < 0)
+               return err;
+       err = alsa_lisp_seq_integer(result, &val1);
+       if (err < 0)
+               return err;
+       *val = val1;
+       return 0;
+}
+
+/**
+ * \brief get ordinary mixer io control value in dB (decibel units)
+ * \param mixer ordinary mixer handle
+ * \param type io type
+ * \param val returned value in dB
+ * \return zero if success, otherwise a negative error code
+ */ 
+int sndo_mixer_io_get_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val)
+{
+       struct alisp_seq_iterator *result;
+       long val1;
+       int err;
+
+       err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_set_dB", "%i", type);
+       if (err < 0)
+               return err;
+       err = alsa_lisp_seq_integer(result, &val1);
+       if (err < 0)
+               return err;
+       *val = val1;
+       return 0;
+}
+
+/**
+ * \brief set ordinary mixer io control value in dB (decibel units)
+ * \param mixer ordinary mixer handle
+ * \param type io type
+ * \param val desired value in dB
+ * \return zero if success, otherwise a negative error code
+ */ 
+int sndo_mixer_io_set_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val)
+{
+       struct alisp_seq_iterator *result;
+       long val1;
+       int err;
+
+       err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_set", "%i%i", type, *val);
+       if (err < 0)
+               return err;
+       err = alsa_lisp_seq_integer(result, &val1);
+       if (err < 0)
+               return err;
+       *val = val1;
+       return 0;
+}
+
+/**
+ * \brief try to set ordinary mixer io control value in dB (decibel units)
+ * \param mixer ordinary mixer handle
+ * \param type io type
+ * \param val desired and returned value in dB
+ * \return zero if success, otherwise a negative error code
+ *
+ * This function does not update the value.
+ * It only returns the real value which will be set.
+ */ 
+int sndo_mixer_io_try_set_dB(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int *val)
 {
-       return -ENODEV;
+       struct alisp_seq_iterator *result;
+       long val1;
+       int err;
+
+       err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_try_set", "%i%i", type, *val);
+       if (err < 0)
+               return err;
+       err = alsa_lisp_seq_integer(result, &val1);
+       if (err < 0)
+               return err;
+       *val = val1;
+       return 0;
 }
 
 /**
@@ -257,5 +508,25 @@ int sndo_mixer_io_set(sndo_mixer_t *mixer, enum sndo_mixer_io_type type, int val
  */ 
 int sndo_mixer_io_change(sndo_mixer_t *mixer, enum sndo_mixer_io_type *changed, int changed_array_size)
 {
-       return -ENODEV;
+       struct alisp_seq_iterator *result;
+       long val1;
+       int err;
+
+       err = alsa_lisp_function(mixer->alisp, &result, "sndo_mixer_io_change", "%i", changed_array_size);
+       if (err < 0)
+               return err;
+       err = alsa_lisp_seq_integer(result, &val1);
+       if (err < 0)
+               return err;
+       if (val1 < 0)
+               return val1;
+       while (changed_array_size-- > 0) {
+               *changed = val1;
+               if (!alsa_lisp_seq_next(&result))
+                       break;
+               err = alsa_lisp_seq_integer(result, &val1);
+               if (err < 0)
+                       return err;
+       }
+       return 0;
 }
index 0512b7ebff8e45d35d07f430d468db1895e71a7f..1f4b2e1cb75e28877c4796d305e400112ae19c16 100644 (file)
 static void help(void)
 {
        printf(
-"Usage: omixer [OPTION]...\n"
+"Usage: omixer [OPTION]...\n\n"
 "-h,--help      help\n"
 "-P,--pname     playback PCM device\n"
 "-C,--cname     capture PCM device\n"
-"\n");
+);
 }
 
 int main(int argc, char *argv[])