[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)