mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
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:
parent
668a300229
commit
60585e25fc
16 changed files with 535 additions and 165 deletions
|
|
@ -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")
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 }
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
4
src/conf/cards/SI7018/sndoc-mixer.alisp
Normal file
4
src/conf/cards/SI7018/sndoc-mixer.alisp
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
(defun sndoc_mixer_open (hctl)
|
||||||
|
(princ "sndoc_mixer_open\n")
|
||||||
|
0
|
||||||
|
)
|
||||||
4
src/conf/cards/SI7018/sndop-mixer.alisp
Normal file
4
src/conf/cards/SI7018/sndop-mixer.alisp
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
(defun sndop_mixer_open (hctl)
|
||||||
|
(princ "sndop_mixer_open\n")
|
||||||
|
0
|
||||||
|
)
|
||||||
25
src/conf/cards/aliases.alisp
Normal file
25
src/conf/cards/aliases.alisp
Normal 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
82
src/conf/sndo-mixer.alisp
Normal 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"))
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue