mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
More changes to the ordinary mixer API
This commit is contained in:
parent
72c814db2a
commit
ab61b62cb4
9 changed files with 576 additions and 234 deletions
|
|
@ -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_nonblock(snd_hctl_t *hctl, int nonblock);
|
||||||
int snd_hctl_poll_descriptors_count(snd_hctl_t *hctl);
|
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(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);
|
unsigned int snd_hctl_get_count(snd_hctl_t *hctl);
|
||||||
int snd_hctl_set_compare(snd_hctl_t *hctl, snd_hctl_compare_t hsort);
|
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);
|
snd_hctl_elem_t *snd_hctl_first_elem(snd_hctl_t *hctl);
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,25 @@
|
||||||
|
|
||||||
#include <alsa/asoundlib.h>
|
#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 */
|
/** Ordinary Mixer I/O type */
|
||||||
enum sndo_mixer_io_type {
|
enum sndo_mixer_io_type {
|
||||||
|
|
||||||
|
|
@ -36,158 +55,131 @@ enum sndo_mixer_io_type {
|
||||||
* playback section
|
* playback section
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** Master volume - left (0-1000) */
|
/* Master */
|
||||||
SNDO_MIO_MASTER_LVOL = 0,
|
SNDO_MIO_MASTER_FLVOL = 0 * 0x40,
|
||||||
/** Master volume - right (0-1000) */
|
SNDO_MIO_MASTER_FCLVOL,
|
||||||
SNDO_MIO_MASTER_RVOL,
|
SNDO_MIO_MASTER_FCVOL,
|
||||||
/** Master volume - left surround (0-1000) */
|
SNDO_MIO_MASTER_FCRVOL,
|
||||||
SNDO_MIO_MASTER_LSVOL = 0,
|
SNDO_MIO_MASTER_FRVOL,
|
||||||
/** Master volume - right surround (0-1000) */
|
SNDO_MIO_MASTER_FSLVOL,
|
||||||
SNDO_MIO_MASTER_RSVOL,
|
SNDO_MIO_MASTER_FSRVOL,
|
||||||
/** Master volume - center (0-1000) */
|
SNDO_MIO_MASTER_RSLVOL,
|
||||||
SNDO_MIO_MASTER_CVOL = 0,
|
SNDO_MIO_MASTER_RSRVOL,
|
||||||
/** Master volume - LFE (0-1000) */
|
SNDO_MIO_MASTER_RLVOL,
|
||||||
|
SNDO_MIO_MASTER_RCVOL,
|
||||||
|
SNDO_MIO_MASTER_RRVOL,
|
||||||
SNDO_MIO_MASTER_LFEVOL,
|
SNDO_MIO_MASTER_LFEVOL,
|
||||||
/** Master volume - left mute (0 = off, 1 = on) */
|
SNDO_MIO_MASTER_OVRVOL,
|
||||||
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) */
|
/* PCM */
|
||||||
SNDO_MIO_PCM_LVOL = 0,
|
SNDO_MIO_PCM_FLVOL = 1 * 0x40,
|
||||||
/** PCM volume - right (0-1000) */
|
SNDO_MIO_PCM_FCLVOL,
|
||||||
SNDO_MIO_PCM_RVOL,
|
SNDO_MIO_PCM_FCVOL,
|
||||||
/** PCM volume - left surround (0-1000) */
|
SNDO_MIO_PCM_FCRVOL,
|
||||||
SNDO_MIO_PCM_LSVOL = 0,
|
SNDO_MIO_PCM_FRVOL,
|
||||||
/** PCM volume - right surround (0-1000) */
|
SNDO_MIO_PCM_FSLVOL,
|
||||||
SNDO_MIO_PCM_RSVOL,
|
SNDO_MIO_PCM_FSRVOL,
|
||||||
/** PCM volume - center (0-1000) */
|
SNDO_MIO_PCM_RSLVOL,
|
||||||
SNDO_MIO_PCM_CVOL = 0,
|
SNDO_MIO_PCM_RSRVOL,
|
||||||
/** PCM volume - LFE (0-1000) */
|
SNDO_MIO_PCM_RLVOL,
|
||||||
|
SNDO_MIO_PCM_RCVOL,
|
||||||
|
SNDO_MIO_PCM_RRVOL,
|
||||||
SNDO_MIO_PCM_LFEVOL,
|
SNDO_MIO_PCM_LFEVOL,
|
||||||
/** PCM volume - left mute (0 = off, 1 = on) */
|
SNDO_MIO_PCM_OVRVOL,
|
||||||
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) */
|
/* LINE */
|
||||||
SNDO_MIO_LINE_LVOL = 0,
|
SNDO_MIO_LINE_FLVOL = 2 * 0x40,
|
||||||
/** LINE volume - right (0-1000) */
|
SNDO_MIO_LINE_FCLVOL,
|
||||||
SNDO_MIO_LINE_RVOL,
|
SNDO_MIO_LINE_FCVOL,
|
||||||
/** LINE volume - left surround (0-1000) */
|
SNDO_MIO_LINE_FCRVOL,
|
||||||
SNDO_MIO_LINE_LSVOL = 0,
|
SNDO_MIO_LINE_FRVOL,
|
||||||
/** LINE volume - right surround (0-1000) */
|
SNDO_MIO_LINE_FSLVOL,
|
||||||
SNDO_MIO_LINE_RSVOL,
|
SNDO_MIO_LINE_FSRVOL,
|
||||||
/** LINE volume - center (0-1000) */
|
SNDO_MIO_LINE_RSLVOL,
|
||||||
SNDO_MIO_LINE_CVOL = 0,
|
SNDO_MIO_LINE_RSRVOL,
|
||||||
/** LINE volume - LFE (0-1000) */
|
SNDO_MIO_LINE_RLVOL,
|
||||||
|
SNDO_MIO_LINE_RCVOL,
|
||||||
|
SNDO_MIO_LINE_RRVOL,
|
||||||
SNDO_MIO_LINE_LFEVOL,
|
SNDO_MIO_LINE_LFEVOL,
|
||||||
/** LINE volume - left mute (0 = off, 1 = on) */
|
SNDO_MIO_LINE_OVRVOL,
|
||||||
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) */
|
/* MIC */
|
||||||
SNDO_MIO_MIC_LVOL = 0,
|
SNDO_MIO_MIC_FLVOL = 3 * 0x40,
|
||||||
/** MIC volume - right (0-1000) */
|
SNDO_MIO_MIC_FCLVOL,
|
||||||
SNDO_MIO_MIC_RVOL,
|
SNDO_MIO_MIC_FCVOL,
|
||||||
/** MIC volume - left surround (0-1000) */
|
SNDO_MIO_MIC_FCRVOL,
|
||||||
SNDO_MIO_MIC_LSVOL = 0,
|
SNDO_MIO_MIC_FRVOL,
|
||||||
/** MIC volume - right surround (0-1000) */
|
SNDO_MIO_MIC_FSLVOL,
|
||||||
SNDO_MIO_MIC_RSVOL,
|
SNDO_MIO_MIC_FSRVOL,
|
||||||
/** MIC volume - center (0-1000) */
|
SNDO_MIO_MIC_RSLVOL,
|
||||||
SNDO_MIO_MIC_CVOL = 0,
|
SNDO_MIO_MIC_RSRVOL,
|
||||||
/** MIC volume - LFE (0-1000) */
|
SNDO_MIO_MIC_RLVOL,
|
||||||
|
SNDO_MIO_MIC_RCVOL,
|
||||||
|
SNDO_MIO_MIC_RRVOL,
|
||||||
SNDO_MIO_MIC_LFEVOL,
|
SNDO_MIO_MIC_LFEVOL,
|
||||||
/** MIC volume - left mute (0 = off, 1 = on) */
|
SNDO_MIO_MIC_OVRVOL,
|
||||||
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 */
|
||||||
SNDO_MIO_CD_LVOL = 0,
|
SNDO_MIO_CD_FLVOL = 4 * 0x40,
|
||||||
/** CD volume - right (0-1000) */
|
SNDO_MIO_CD_FCLVOL,
|
||||||
SNDO_MIO_CD_RVOL,
|
SNDO_MIO_CD_FCVOL,
|
||||||
/** CD volume - left surround (0-1000) */
|
SNDO_MIO_CD_FCRVOL,
|
||||||
SNDO_MIO_CD_LSVOL = 0,
|
SNDO_MIO_CD_FRVOL,
|
||||||
/** CD volume - right surround (0-1000) */
|
SNDO_MIO_CD_FSLVOL,
|
||||||
SNDO_MIO_CD_RSVOL,
|
SNDO_MIO_CD_FSRVOL,
|
||||||
/** CD volume - center (0-1000) */
|
SNDO_MIO_CD_RSLVOL,
|
||||||
SNDO_MIO_CD_CVOL = 0,
|
SNDO_MIO_CD_RSRVOL,
|
||||||
/** CD volume - LFE (0-1000) */
|
SNDO_MIO_CD_RLVOL,
|
||||||
|
SNDO_MIO_CD_RCVOL,
|
||||||
|
SNDO_MIO_CD_RRVOL,
|
||||||
SNDO_MIO_CD_LFEVOL,
|
SNDO_MIO_CD_LFEVOL,
|
||||||
/** CD volume - left mute (0 = off, 1 = on) */
|
SNDO_MIO_CD_OVRVOL,
|
||||||
SNDO_MIO_CD_LMUTE,
|
|
||||||
/** CD volume - right mute (0 = off, 1 = on) */
|
/* AUX */
|
||||||
SNDO_MIO_CD_RMUTE,
|
SNDO_MIO_AUX_FLVOL = 5 * 0x40,
|
||||||
/** CD volume - left surround mute (0 = off, 1 = on) */
|
SNDO_MIO_AUX_FCLVOL,
|
||||||
SNDO_MIO_CD_LSMUTE,
|
SNDO_MIO_AUX_FCVOL,
|
||||||
/** CD volume - right surround mute (0 = off, 1 = on) */
|
SNDO_MIO_AUX_FCRVOL,
|
||||||
SNDO_MIO_CD_RSMUTE,
|
SNDO_MIO_AUX_FRVOL,
|
||||||
/** CD volume - center mute (0 = off, 1 = on) */
|
SNDO_MIO_AUX_FSLVOL,
|
||||||
SNDO_MIO_CD_CMUTE,
|
SNDO_MIO_AUX_FSRVOL,
|
||||||
/** CD volume - LFE mute (0 = off, 1 = on) */
|
SNDO_MIO_AUX_RSLVOL,
|
||||||
SNDO_MIO_CD_LFEMUTE,
|
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 section
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** capture gain - left (0-1000) */
|
/* capture gain */
|
||||||
SNDO_MIO_CGAIN_LVOL = 0x1000,
|
SNDO_MIO_CGAIN_FL = 0x8000,
|
||||||
/** capture gain - right (0-1000) */
|
SNDO_MIO_CGAIN_FCL,
|
||||||
SNDO_MIO_CGAIN_RVOL,
|
SNDO_MIO_CGAIN_FC,
|
||||||
/** capture gain - left surround (0-1000) */
|
SNDO_MIO_CGAIN_FCR,
|
||||||
SNDO_MIO_CGAIN_LSVOL,
|
SNDO_MIO_CGAIN_FR,
|
||||||
/** capture gain - right surround (0-1000) */
|
SNDO_MIO_CGAIN_FSL,
|
||||||
SNDO_MIO_CGAIN_RSVOL,
|
SNDO_MIO_CGAIN_FSR,
|
||||||
/** capture gain - center (0-1000) */
|
SNDO_MIO_CGAIN_RSL,
|
||||||
SNDO_MIO_CGAIN_CVOL,
|
SNDO_MIO_CGAIN_RSR,
|
||||||
/** capture gain - LFE (0-1000) */
|
SNDO_MIO_CGAIN_RL,
|
||||||
SNDO_MIO_CGAIN_LFEVOL,
|
SNDO_MIO_CGAIN_RC,
|
||||||
|
SNDO_MIO_CGAIN_RR,
|
||||||
|
SNDO_MIO_CGAIN_LFE,
|
||||||
|
SNDO_MIO_CGAIN_OVR,
|
||||||
|
|
||||||
/** capture source - MIC exclusive switch (0 = off, 1 = on) */
|
/* capture source (0 = off, 1 = on) */
|
||||||
SNDO_MIO_CSOURCE_MIC = 0x1100,
|
SNDO_MIO_CSOURCE_MIC = 0x8100,
|
||||||
/** capture source - LINE exclusive switch (0 = off, 1 = on) */
|
|
||||||
SNDO_MIO_CSOURCE_LINE,
|
SNDO_MIO_CSOURCE_LINE,
|
||||||
/** capture source - CD exclusive switch (0 = off, 1 = on) */
|
|
||||||
SNDO_MIO_CSOURCE_CD,
|
SNDO_MIO_CSOURCE_CD,
|
||||||
/** capture source - AUX exclusive switch (0 = off, 1 = on) */
|
|
||||||
SNDO_MIO_CSOURCE_AUX,
|
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;
|
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_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);
|
||||||
int sndo_mixer_poll_descriptors_revents(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int nfds, unsigned short *revents);
|
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_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);
|
int sndo_mixer_io_change(sndo_mixer_t *mixer, enum sndo_mixer_io_type *changed, int changed_array_size);
|
||||||
|
|
||||||
/** \} */
|
/** \} */
|
||||||
|
|
|
||||||
|
|
@ -135,3 +135,9 @@ ALSA_0.9.7 {
|
||||||
sndo_*;
|
sndo_*;
|
||||||
alsa_lisp_*;
|
alsa_lisp_*;
|
||||||
} ALSA_0.9.6;
|
} ALSA_0.9.6;
|
||||||
|
|
||||||
|
ALSA_0.9.8 {
|
||||||
|
global:
|
||||||
|
|
||||||
|
snd_hctl_poll_descriptors_revents;
|
||||||
|
} ALSA_0.9.7;
|
||||||
|
|
|
||||||
|
|
@ -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_cons(snd_output_t *out, struct alisp_object * p);
|
||||||
static void princ_object(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(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 */
|
/* functions */
|
||||||
static struct alisp_object *F_eval(struct alisp_instance *instance, struct alisp_object *);
|
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;
|
return instance->thistoken;
|
||||||
|
|
||||||
got_id:
|
got_id:
|
||||||
case '_': case '+': case '*': case '/': 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 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||||
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
|
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 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
|
||||||
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
|
||||||
case 'Y': case 'Z':
|
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;
|
p = instance->token_buffer;
|
||||||
do {
|
do {
|
||||||
if (p - instance->token_buffer >= instance->token_buffer_max) {
|
if (p - instance->token_buffer >= instance->token_buffer_max) {
|
||||||
|
|
@ -489,7 +490,7 @@ static int gettoken(struct alisp_instance *instance)
|
||||||
}
|
}
|
||||||
*p++ = c;
|
*p++ = c;
|
||||||
c = xgetc(instance);
|
c = xgetc(instance);
|
||||||
} while (isalnum(c) || strchr("_-+*/%<>=&", c) != NULL);
|
} while (isalnum(c) || strchr("!_-+*/%<>=&", c) != NULL);
|
||||||
xungetc(instance, c);
|
xungetc(instance, c);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
return instance->thistoken = ALISP_IDENTIFIER;
|
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;
|
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)
|
* Syntax: (exfun name)
|
||||||
* Test, if a function exists
|
* 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;
|
struct alisp_object * p1, * p2;
|
||||||
|
|
||||||
p1 = car(args);
|
p1 = eval(instance, car(args));
|
||||||
if (p1->type != ALISP_OBJ_STRING && p1->type != ALISP_OBJ_IDENTIFIER)
|
if (p1->type != ALISP_OBJ_STRING && p1->type != ALISP_OBJ_IDENTIFIER)
|
||||||
return &alsa_lisp_nil;
|
return &alsa_lisp_nil;
|
||||||
p2 = get_object(instance, p1);
|
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);
|
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)
|
* Syntax: (int value)
|
||||||
* 'value' can be integer or float type
|
* '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));
|
struct alisp_object * p = eval(instance, car(args));
|
||||||
|
|
||||||
if (p->type == ALISP_INTEGER)
|
if (p->type == ALISP_OBJ_INTEGER)
|
||||||
return p;
|
return p;
|
||||||
if (p->type == ALISP_FLOAT)
|
if (p->type == ALISP_OBJ_FLOAT)
|
||||||
return new_integer(instance, floor(p->value.f));
|
return new_integer(instance, floor(p->value.f));
|
||||||
|
|
||||||
lisp_warn(instance, "expected an integer or float for integer conversion");
|
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));
|
struct alisp_object * p = eval(instance, car(args));
|
||||||
|
|
||||||
if (p->type == ALISP_FLOAT)
|
if (p->type == ALISP_OBJ_FLOAT)
|
||||||
return p;
|
return p;
|
||||||
if (p->type == ALISP_INTEGER)
|
if (p->type == ALISP_OBJ_INTEGER)
|
||||||
return new_float(instance, p->value.i);
|
return new_float(instance, p->value.i);
|
||||||
|
|
||||||
lisp_warn(instance, "expected an integer or float for integer conversion");
|
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));
|
struct alisp_object * p = eval(instance, car(args));
|
||||||
|
|
||||||
if (p->type == ALISP_STRING)
|
if (p->type == ALISP_OBJ_STRING)
|
||||||
return p;
|
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];
|
char buf[64];
|
||||||
if (p->type == ALISP_INTEGER) {
|
if (p->type == ALISP_INTEGER) {
|
||||||
snprintf(buf, sizeof(buf), "%ld", p->value.i);
|
snprintf(buf, sizeof(buf), "%ld", p->value.i);
|
||||||
|
|
@ -2166,6 +2194,7 @@ struct intrinsic {
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct intrinsic intrinsics[] = {
|
static struct intrinsic intrinsics[] = {
|
||||||
|
{ "!=", F_numneq },
|
||||||
{ "%", F_mod },
|
{ "%", F_mod },
|
||||||
{ "&dump-memory", F_dump_memory },
|
{ "&dump-memory", F_dump_memory },
|
||||||
{ "&dump-objects", F_dump_objects },
|
{ "&dump-objects", F_dump_objects },
|
||||||
|
|
@ -2183,6 +2212,7 @@ static struct intrinsic intrinsics[] = {
|
||||||
{ "assoc", F_assoc },
|
{ "assoc", F_assoc },
|
||||||
{ "assq", F_assq },
|
{ "assq", F_assq },
|
||||||
{ "atom", F_atom },
|
{ "atom", F_atom },
|
||||||
|
{ "call", F_call },
|
||||||
{ "car", F_car },
|
{ "car", F_car },
|
||||||
{ "cdr", F_cdr },
|
{ "cdr", F_cdr },
|
||||||
{ "cond", F_cond },
|
{ "cond", F_cond },
|
||||||
|
|
@ -2233,33 +2263,41 @@ static int compar(const void *p1, const void *p2)
|
||||||
((struct intrinsic *)p2)->name);
|
((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;
|
||||||
|
|
||||||
|
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 ((item = bsearch(&key, snd_intrinsics,
|
||||||
|
sizeof snd_intrinsics / sizeof snd_intrinsics[0],
|
||||||
|
sizeof snd_intrinsics[0], compar)) != NULL)
|
||||||
|
return item->func(instance, p2);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
return &alsa_lisp_nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct alisp_object * eval_cons(struct alisp_instance *instance, struct alisp_object * p)
|
||||||
|
{
|
||||||
|
struct alisp_object * p1 = car(p);
|
||||||
|
|
||||||
if (p1 != &alsa_lisp_nil && p1->type == ALISP_OBJ_IDENTIFIER) {
|
if (p1 != &alsa_lisp_nil && p1->type == ALISP_OBJ_IDENTIFIER) {
|
||||||
struct intrinsic key, *item;
|
|
||||||
|
|
||||||
if (!strcmp(p1->value.id, "lambda"))
|
if (!strcmp(p1->value.id, "lambda"))
|
||||||
return p;
|
return p;
|
||||||
|
|
||||||
auto_garbage_collect(instance);
|
auto_garbage_collect(instance);
|
||||||
|
|
||||||
key.name = p1->value.id;
|
return eval_cons1(instance, p1, cdr(p));
|
||||||
if ((item = bsearch(&key, intrinsics,
|
|
||||||
sizeof intrinsics / sizeof intrinsics[0],
|
|
||||||
sizeof intrinsics[0], compar)) != NULL)
|
|
||||||
return item->func(instance, p2);
|
|
||||||
|
|
||||||
if ((item = bsearch(&key, snd_intrinsics,
|
|
||||||
sizeof snd_intrinsics / sizeof snd_intrinsics[0],
|
|
||||||
sizeof snd_intrinsics[0], compar)) != NULL)
|
|
||||||
return item->func(instance, p2);
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &alsa_lisp_nil;
|
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;
|
struct alisp_object * p2;
|
||||||
|
|
||||||
if (seq->type == ALISP_OBJ_CONS && seq->value.c.cdr->type == ALISP_OBJ_CONS)
|
if (seq->type == ALISP_OBJ_CONS && seq->value.c.car->type == ALISP_OBJ_CONS)
|
||||||
seq = seq->value.c.cdr;
|
seq = seq->value.c.car;
|
||||||
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)
|
if (p2->type != ALISP_OBJ_STRING)
|
||||||
|
|
|
||||||
|
|
@ -188,11 +188,6 @@ static struct alisp_object * add_cons2(struct alisp_instance * instance, struct
|
||||||
return lexpr;
|
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)
|
static struct alisp_object * new_result1(struct alisp_instance * instance, int err, const char *ptr_id, void *ptr)
|
||||||
{
|
{
|
||||||
struct alisp_object * lexpr, * p1;
|
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_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_pp_p_t)(void **rctl, void *handle);
|
||||||
typedef int (*snd_int_p_t)(void *rctl);
|
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_intp_t)(int *val);
|
||||||
typedef int (*snd_int_str_t)(const char *str);
|
typedef int (*snd_int_str_t)(const char *str);
|
||||||
typedef int (*snd_int_int_strp_t)(int val, 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);
|
handle = (void *)get_ptr(args, item->prefix);
|
||||||
if (handle == NULL)
|
if (handle == NULL)
|
||||||
return &alsa_lisp_nil;
|
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)
|
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)
|
if (args->type != ALISP_OBJ_STRING && args->type != ALISP_OBJ_IDENTIFIER)
|
||||||
return &alsa_lisp_nil;
|
return &alsa_lisp_nil;
|
||||||
err = ((snd_int_str_t)item->xfunc)(args->value.s);
|
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)
|
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);
|
snd_ctl_elem_value_alloca(&value);
|
||||||
err = snd_hctl_elem_info(handle, info);
|
err = snd_hctl_elem_info(handle, info);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return new_result(instance, err);
|
return new_integer(instance, err);
|
||||||
type = snd_ctl_elem_info_get_type(info);
|
type = snd_ctl_elem_info_get_type(info);
|
||||||
count = snd_ctl_elem_info_get_count(info);
|
count = snd_ctl_elem_info_get_count(info);
|
||||||
if (type == SND_CTL_ELEM_TYPE_IEC958) {
|
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);
|
p1 = cdr(p1);
|
||||||
} while (p1 != &alsa_lisp_nil);
|
} while (p1 != &alsa_lisp_nil);
|
||||||
err = snd_hctl_elem_write(handle, value);
|
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)
|
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", &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" },
|
{ "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)
|
static int acall_compar(const void *p1, const void *p2)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
|
;
|
||||||
|
; Toplevel configuration for the ALSA Ordinary Mixer Interface
|
||||||
|
;
|
||||||
|
|
||||||
(defun sndo_include (hctl stream)
|
(defun sndo_include (hctl stream)
|
||||||
(setq info (Acall "ctl_card_info" (Acall "hctl_ctl" hctl)))
|
(setq info (Acall "ctl_card_info" (Acall "hctl_ctl" hctl)))
|
||||||
(if (= (Aerror info) 0)
|
(if (= (Aerror info) 0)
|
||||||
|
|
@ -7,75 +11,78 @@
|
||||||
(setq file (+ (path "data") "/alsa/cards/" (snd_card_alias driver) "/sndo" stream "-mixer.alisp"))
|
(setq file (+ (path "data") "/alsa/cards/" (snd_card_alias driver) "/sndo" stream "-mixer.alisp"))
|
||||||
(setq r (include file))
|
(setq r (include file))
|
||||||
(when (= r -2) (Asyserr "unable to find file " file))
|
(when (= r -2) (Asyserr "unable to find file " file))
|
||||||
(unsetq driver file r)
|
|
||||||
)
|
)
|
||||||
(setq r (Aerror info))
|
(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)
|
(defun sndo_mixer_open1 (pcm stream)
|
||||||
(setq info (Acall "pcm_info" pcm))
|
(setq info (Acall "pcm_info" pcm))
|
||||||
(setq r (Aerror info))
|
(setq r (Aerror info))
|
||||||
(when (= r 0)
|
(when (= r 0)
|
||||||
(progn
|
(setq info (Aresult info))
|
||||||
(setq info (Aresult info))
|
(setq card (cdr (assq "card" info)))
|
||||||
(setq card (cdr (assq "card" info)))
|
(setq r
|
||||||
(setq r
|
(if (< card 0)
|
||||||
(if (< card 0)
|
(sndo_mixer_open_virtual pcm stream)
|
||||||
(+ (Acall "pcm_name" pcm) stream)
|
(sndo_mixer_open_hctl card stream)
|
||||||
(+ "hw:" (str card))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
(unsetq card)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(unsetq info r)
|
(unsetq info card r)
|
||||||
)
|
)
|
||||||
|
|
||||||
(defun sndo_mixer_open (ppcm cpcm)
|
(defun sndo_mixer_open (ppcm cpcm)
|
||||||
(setq pname (sndo_mixer_open1 ppcm "p"))
|
(setq r (sndo_mixer_open1 ppcm "p"))
|
||||||
(setq cname (sndo_mixer_open1 cpcm "c"))
|
(when (= r 0) (setq r (sndo_mixer_open1 cpcm "c")))
|
||||||
(setq phctl (Acall "hctl_open" pname nil))
|
(when (!= r 0) (sndo_mixer_close))
|
||||||
(if (= (Aerror phctl) 0)
|
(unsetq r)
|
||||||
|
)
|
||||||
|
|
||||||
|
(defun sndo_mixer_close1 (hctl stream)
|
||||||
|
(when hctl
|
||||||
(progn
|
(progn
|
||||||
(setq phctl (Aresult phctl))
|
(setq fcn (+ "sndo" stream "_mixer_close"))
|
||||||
(setq chctl (Acall "hctl_open" cname nil))
|
(when (exfun fcn) (call fcn hctl))
|
||||||
(if (= (Aerror chctl) 0)
|
(unsetq fcn)
|
||||||
(progn
|
(Acall "hctl_close" hctl)
|
||||||
(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
|
(defun sndo_mixer_close nil
|
||||||
(cond (exfun sndop_close) (sndop_close (nth 0 hctls)))
|
(sndo_mixer_close1 (nth 1 hctls) "c")
|
||||||
(cond (exfun sndoc_close) (sndoc_close (nth 1 hctls)))
|
(sndo_mixer_close1 (nth 0 hctls) "p")
|
||||||
(Acall "hctl_close" (nth 0 hctls))
|
|
||||||
(Acall "hctl_close" (nth 1 hctls))
|
|
||||||
(unsetq hctls)
|
(unsetq hctls)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
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,
|
static int snd_hctl_throw_event(snd_hctl_t *hctl, unsigned int mask,
|
||||||
snd_hctl_elem_t *elem)
|
snd_hctl_elem_t *elem)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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)
|
int sndo_mixer_poll_descriptors(sndo_mixer_t *mixer, struct pollfd *pfds, unsigned int space)
|
||||||
{
|
{
|
||||||
//return snd_mixer_poll_descriptors(mixer->mixer, pfds, space);
|
int err, idx, res;
|
||||||
return -ENODEV;
|
|
||||||
|
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)
|
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);
|
int err, idx, count, res;
|
||||||
return -ENODEV;
|
|
||||||
|
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)
|
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
|
* \param val desired value
|
||||||
* \return zero if success, otherwise a negative error code
|
* \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)
|
||||||
{
|
{
|
||||||
return -ENODEV;
|
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)
|
||||||
|
{
|
||||||
|
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)
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,11 @@
|
||||||
static void help(void)
|
static void help(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"Usage: omixer [OPTION]...\n"
|
"Usage: omixer [OPTION]...\n\n"
|
||||||
"-h,--help help\n"
|
"-h,--help help\n"
|
||||||
"-P,--pname playback PCM device\n"
|
"-P,--pname playback PCM device\n"
|
||||||
"-C,--cname capture PCM device\n"
|
"-C,--cname capture PCM device\n"
|
||||||
"\n");
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue