;; This is the main script for the pcm-dispatch tool ;; last main-arg nominates the configuration file (signal 1 (fn (x) (exit 0))) (signal 2 (fn (x) (exit 0))) (signal 15 (fn (x) (exit 0))) (load "misc.lsp") ; load contexts libasound and ALSA (load "libasound.lsp") (unless (> (length (main-args)) 1) (die 1 "Usage: ")) (context libc) (import LIB "dup2" "int" "int" ; int oldfd "int" ; int newfd ) (context MAIN) (setf CONFIGFILE (main-args -1) CONFIGTEXT (read-file CONFIGFILE) CONFIG (read-expr CONFIGTEXT) PCM-LIST (rest (assoc "PCM-LIST" CONFIG)) ) (define (open-pcm PCM) (ALSA:snd_pcm_open PCM libasound:SND_PCM_STREAM_PLAYBACK 0 )) (define (setup-pcm PCM) (libasound:snd_pcm_set_params PCM libasound:SND_PCM_FORMAT_S16_LE libasound:SND_PCM_ACCESS_RW_INTERLEAVED 2 ; channels 48000 ; rate 1 ; soft resample (0/1) 10000 ; latency (microseconds) )) ;(! (format "ls -l /proc/%d/fd" (sys-info 7))) (let ((REDIR (open "/dev/null" "append"))) ; "/tmp/test1" (when (< REDIR) (exit 1)) (when (< (libc:dup2 REDIR 2)) (exit 1)) (when (< (libc:dup2 REDIR 1)) (exit 1)) (close REDIR) ) ;; Change ALSA configuration for this process (setf KEY "pcm.out1.device" VALUE "20:74:CF:C0:22:81") (when (!= (setf E (ALSA:set_config_string KEY VALUE))) (die 1 "set_config_string " E)) ;; Find first usable PCM (setf PCM (unless (dolist (PCM PCM-LIST (open-pcm PCM))) (die 1 "No PCM available"))) (define (ready PCM) (dotimes (x 1000 (!= -32 (libasound:snd_pcm_wait PCM -1))) (sleep 10))) (when (!= (setf E (setup-pcm PCM))) (libasound:snd_pcm_close PCM) (die 1 "set params" E)) ;;(die nil "status" (libasound:snd_pcm_start PCM)) (setf N 0 x 0 E 0 i 0) ;(define BUFFER:BUFFER (dup "\000" 1000008)) (setf CACHE nil) (while (> (or (setf N (read 0 BUFFER 20000000)) 0)) ;(println "reading " N) (setf CACHE BUFFER) (while (> N) (ready PCM) (when (< (setf E (libasound:snd_pcm_writei PCM CACHE (/ N 4)))) (libasound:snd_pcm_close PCM) (die 1 "writing" E N)) (setf E (* E 4)) (setf CACHE (E CACHE)) ;(println "wrote " E) (dec N E) ) ) (libasound:snd_pcm_wait PCM -1) (libasound:snd_pcm_drain PCM) (libasound:snd_pcm_close PCM)