[CM] LADSPA implementation

e deleflie edeleflie@gmail.com
Thu, 21 Jun 2007 15:20:25 +1000


I've finally got a fully working script that can handle 3 or 4 channel
ambisonic files, re-samples them to 44100 automatically, passes them
through a LADSPA plugin, and spits out the result as 4 independent
channels.

... so thanks very much for the help learning SND... :) ... (I guess
mainly to Bill and Kjetil)

For posterity's sake ... I've included the script below ... might be
useful to someone googling for something along the way ...

Etienne
---------------------------------------------------------------------

#!/usr/local/bin/snd -b
!#
(use-modules (ice-9 format))
; set some global variables
(set! (ladspa-dir) "/usr/lib/ladspa")
(set! (sinc-width) 100);i set the sync width to very high to get the
smaple rate conversion as accurate as possible

(if (< (length (script-args)) 3) ;
        (display "usage: decode_to_square.sh file-name [insound-path]
[outfile-path] [decode set (0-10)]")
        ; if we get here then we have the right number of arguments
        (begin                ; define some args.
                (define name (list-ref (script-args) (+ (script-arg)
1)))                 (define inpath (if (> (length (script-args)) 3)
(list-ref (script-args) (+ (script-arg) 2))
"/home/ambisonicbootlegs/share/"  ))                (define outpath
(if (> (length (script-args)) 4) (list-ref (script-args) (+
(script-arg) 3)) "/home/ambisonicbootlegs/transcodes_DTS/"  ))
       (define version (if (> (length (script-args)) 5) (list-ref
(script-args) (+ (script-arg) 4)) 99 ))
                (define fullfilename (format #f "~a~a" inpath name))
                (display (format #f "Full File name is ~a \n" fullfilename))
                (display (format #f "OutPath is ~a \n" outpath))
         (display (format #f "Decode set is ~a \n" version))
                ;open the file and check out what its headers are
                (let*   ((outsound (new-sound "out.snd" :channels 4))
                      (insound (open-sound fullfilename)))
                        (display (format #f "header is ~a (or ~a) \n"
(header-type insound) (mus-header-type-name (header-type insound)) ))
                        (display (format #f "data-format is ~a (or ~a)
\n" (data-format insound) (mus-data-format-name (data-format insound)
) ))

                        ; check that we have 4 channels, if not then
create a 4th one
                        (display (format #f "Number of channels: ~a
\n" (channels insound)))

                        ; if number of channels is 3 .... otherwise

                        ; resample
                        (display (format #f "Resampling from ~D to
44100 \n" (srate insound)))
                        (src-sound (/ (srate insound) 44100) 1.0 insound 0)
                        (src-sound (/ (srate insound) 44100) 1.0 insound 1)
                        (src-sound (/ (srate insound) 44100) 1.0 insound 2)

                        (if (= (channels insound) 4) (src-sound (/
(srate insound) 44100) 1.0 insound 3))

                        (let ((readers
                                        (list   (make-sample-reader 0
insound 0)  ; W
                                                (make-sample-reader 0
insound 1)  ; X
                                                (make-sample-reader 0
insound 2)  ; Y
                                                (case (channels insound)
                                                        ((3) #f )  ; Z
                                                        ((4)
(make-sample-reader 0 insound 3))  ; Z
                                                )
                                        )))

                                ; apply LADSPA plugin that converts to
4 speaker feeds in a square
                                (apply-ladspa readers
                                        (case version
                              ((0) (list "ambisonic1"
"Ambisonics-11-square-decoder" 1 0 0.2 6 0 0.5) );   Bogus
                                   ((1) (list "ambisonic1"
"Ambisonics-11-square-decoder" 0 0 1.414 1.414 0 2.5) );   Energy
decode                                                ((2) (list
"ambisonic1" "Ambisonics-11-square-decoder" 0 1 0.8   1.2   380 2.5)
); Shelf, v.low gains
((4) (list "ambisonic1" "Ambisonics-11-square-decoder" 0 1 1.2   1.8
380 2.5) ); Shelf, low gains
     ((4) (list "ambisonic1" "Ambisonics-11-square-decoder" 0 0 1.0
1.0   0 2.5) );   Cardiod decode for large area
                        ((5) (list "ambisonic1"
"Ambisonics-11-square-decoder" 0 1 1.3   1.9   300 2.5) ); Low shelf,
lowered gains                                                ((6)
(list "ambisonic1" "Ambisonics-11-square-decoder" 0 1 1.414 2.0   380
2.5) ); classic decode
((7) (list "ambisonic1" "Ambisonics-11-square-decoder" 0 1 1.0   1.40
380 2.5) ); Shelf, lower gains
       ((8) (list "ambisonic1" "Ambisonics-11-square-decoder" 0 1
1.414 2     600 2.5) ); Shelf, v.high
              ((9) (list "ambisonic1" "Ambisonics-11-square-decoder" 0
1 1.414 2     500 2.5) ); Shelf, high
                                                ((10) (list
"ambisonic1" "Ambisonics-11-square-decoder" 0 1 1.414 2 380 2.5) )
                                           (else (list "ambisonic1"
"Ambisonics-11-square-decoder" 0 1 1.414 2 380 2.5) ); anticipated
best decode
                                        )
                                        (mus-sound-frames fullfilename)
                                        "ambisonic conversion to
square speaker layout"
                                        outsound 0)
                                (for-each (lambda (r) (if r
(free-sample-reader r))) readers))

                        ; now convert the 4 channels into 4 mono wav
files, and write to disk
                        (do ((i 0 (1+ i)))
                                   ((= i 4))
                                        (display (format #f "writing
channel ~D\n" i))
                                (save-sound-as (format #f "~a~a.~a" outpath name
                                                        (case i
                                                                ((0)
"LFront.wav")
                                                                ((1)
"RFront.wav")
                                                                ((2)
"RSurround.wav")
                                                                ((3)
"LSurround.wav")
                                                                (else "lost")
                                                        )
                                                )
                                                :sound outsound
                                                :header-type mus-riff
; (value= 3) RIFF header (for Microsoft WAVE)
                                                :data-format
mus-l24int ; (value= 16) 24 Bit little endian int
                          :srate 44100 ; the sound is already
resampled, so lets set the appropriate file header
                                                :channel i)
                        )
                        (close-sound insound)
                        (close-sound outsound)
                )
        )
)
(exit)