Attached.
- Tommi
--
Kotisivu / Homepage: http://www.iki.fi/tohoyn/
Sähköposti / E-Mail: [email protected]
GPG-sormenjälki / GPG fingerprint:
55F4 2477 7155 3528 5CB2 2B7A BB86 1FDE 4046 0F83
FT, Debian-ylläpitäjä / PhD, Debian Maintainer
;; test-render-envelope.scm
;;
;; Integration test for guile-fluidsynth:
;; - loads a SoundFont
;; - renders audio offline
;; - verifies note attack produces signal
;; - verifies note-off causes decay
;; - verifies polyphony accounting
;;
;; This is intentionally not a trivial smoke test.
(use-modules
(srfi srfi-64)
(ice-9 binary-ports)
(nyacc foreign cdata)
(f-synth)
(f-synth ffi settings)
(f-synth ffi synth))
(test-begin "fluidsynth-render-envelope")
(define SAMPLE-RATE 44100)
(define BLOCK-SIZE 64)
;; Utility ------------------------------------------------------------
(define (buffer-rms buffer)
(let* ((n (f32vector-length buffer))
(sum 0.0))
(do ((i 0 (+ i 1)))
((>= i n) (/ sum n))
(let ((x (f32vector-ref buffer i)))
(set! sum (+ sum (* x x)))))
(sqrt (/ sum n))))
(define ctype-float (cbase 'float))
(define (render-block synth frames)
(let ((left (make-cdata (carray ctype-float frames)))
(right (make-cdata (carray ctype-float frames))))
;; Offline rendering into buffers
(fluid_synth_write_float synth
frames
left 0 1
right 0 1)
(values left right)))
(define (render-rms synth frames)
(call-with-values
(lambda () (render-block synth frames))
(lambda (l r)
(/ (+ (buffer-rms (cdata-ref l))
(buffer-rms (cdata-ref r)))
2.0))))
;; Setup --------------------------------------------------------------
(define synth (make <synth>))
(define settings (!settings synth))
(fluid_settings_setnum settings "synth.sample-rate" SAMPLE-RATE)
(fluid_settings_setint settings "synth.polyphony" 16)
;; Disable realtime drivers for deterministic CI behavior
(fluid_settings_setstr settings "audio.driver" "file")
;; You should replace this path with a test fixture.
(define sfid
(sfload synth
"example.sf2"
1))
(test-assert "soundfont loaded"
(>= sfid 0))
(program-select synth
0 ; channel
0 ; bank
0 ; preset
sfid)
;; Attack test --------------------------------------------------------
(noteon synth 0 60 100)
(define attack-rms
(render-rms (!synth synth) 4096))
(test-assert "note-on produces audible signal"
(> attack-rms 0.001))
;; Polyphony test -----------------------------------------------------
(noteon synth 0 61 100)
(noteon synth 0 62 100)
(test-assert "polyphony increases after multiple notes"
(>= (fluid_synth_get_active_voice_count (!synth synth)) 3))
;; Release test -------------------------------------------------------
(noteoff synth 0 60)
(noteoff synth 0 61)
(noteoff synth 0 62)
;; Render enough frames for release envelope to decay
(define release-rms
(begin
(render-rms (!synth synth) (* SAMPLE-RATE 2))))
(test-assert "signal decays after note-off"
(< release-rms (* attack-rms 0.2)))
(test-end "fluidsynth-render-envelope")