Skip to content

Instantly share code, notes, and snippets.

@georgejwright
Last active May 27, 2022 22:01
Show Gist options
  • Save georgejwright/3e2442fc9231a6d30e42f9eb75ea4793 to your computer and use it in GitHub Desktop.
Save georgejwright/3e2442fc9231a6d30e42f9eb75ea4793 to your computer and use it in GitHub Desktop.
Experiments with extempore audiobuffers
;; piano_3_notes_in_assets.xtm
;; Some experiments with audiobuffers in which I attempt to:
;; Load audio buffers. Print buffer component values. Play buffers.
;; Externally from the dsp, change the note played.
;; Concatenate two buffers. Concatenate three buffers.
;; Mix two buffers to sound together.
;; Using a different file from assets:
;; Some experiments with AudioBuffer_read_interp
;; and
;; AudioBuffer_read_interp_pw
;; George Wright
;; Melbourne Richmond
;; 28/May/2022
(sys:load "libs/core/audiobuffer.xtm")
;; Create audio buffers from three sample files in
;; extempore/assets/samples/salamander-piano/ff/
(bind-val pianoC6 AudioBuffer* (AudioBuffer "assets/samples/salamander-piano/ff/C6-ff.wav"))
(bind-val pianoDsh6 AudioBuffer* (AudioBuffer "assets/samples/salamander-piano/ff/D#6-ff.wav"))
(bind-val pianoFsh6 AudioBuffer* (AudioBuffer "assets/samples/salamander-piano/ff/F#6-ff.wav"))
;; Print buffer component values.
($ (println pianoC6)) ; two channels and 272,926 frames
($ (println pianoDsh6)) ; two channels and 284,676 frames
($ (println pianoFsh6)) ; two channels and 263,761 frames
;; Setup the dsp to play one of the audio buffers
(bind-func dsp:DSP
(let ((ab pianoDsh6))
(AudioBuffer_set_phase ab 0.)
(AudioBuffer_set_playhead ab 0)
(lambda (in time chan dat)
(AudioBuffer_read ab chan))))
;; The note will sound for about 6 seconds
(dsp:set! dsp)
;; This version will loop repeatedly
(bind-func dsp:DSP
(let ((ab pianoC6))
(AudioBuffer_set_phase ab 0.)
(AudioBuffer_set_playhead ab 0)
(lambda (in time chan dat)
(AudioBuffer_read_looped ab chan))))
;; Changing the note played.
;; Note that the file plays for up to 6 seconds. The timing of re-evaluation of the group
;; makes a difference. Sometimes the new buffer does not sound! ???
;; Play different notes. pianoFsh6
;; Evaluate just the third line of the group.
;; But may be more reliable if you evaluate as a group of three.
;; Play pianoFsh6
($ (AudioBuffer_set_phase pianoFsh6 0.))
($ (AudioBuffer_set_playhead pianoFsh6 0))
($ (dsp.ab pianoFsh6))
;; Play different notes. pianoDsh6
($ (AudioBuffer_set_phase pianoDsh6 0.))
($ (AudioBuffer_set_playhead pianoDsh6 0))
($ (dsp.ab pianoDsh6))
;; Play different notes. pianoC6
($ (AudioBuffer_set_phase pianoC6 0.))
($ (AudioBuffer_set_playhead pianoC6 0))
($ (dsp.ab pianoC6))
;; AudioBuffer_concat
;; This version will create a buffer containing two samples.
;; Plays two notes in sequence.
;; Concat two buffers
(bind-func dsp:DSP
(let ((ab (AudioBuffer_concat pianoDsh6 pianoFsh6)))
(lambda (in time chan dat)
(AudioBuffer_read_looped ab chan)))) ;; seems not to require reset phase
;; Concat three buffers
(bind-func dsp:DSP
(let ((ab (AudioBuffer_concat pianoC6 (AudioBuffer_concat pianoDsh6 pianoFsh6))))
(lambda (in time chan dat)
(AudioBuffer_read ab chan)))) ;; seems not to require reset phase
;; AudioBuffer_read_interp_mix
;; Mixing two buffers to sound together.
;; This version mixes the second buffer, ab2 in with the first buffer ab1
;; In the final line changing the midi 60 frequency from 264.3 Hz will shift the output frequency.
;; Changing the 0.5 value alters the mix ratio of ab1/ab2
;; I found it is important to reset the phase to zero on each re-evaluation.
(bind-func dsp:DSP
(let ((ab1 pianoC6) ;; pianoFsh6 pianoC6 pianoDsh6
(ab2 pianoFsh6))
(AudioBuffer_set_phase ab1 0.) ;; set the phase of ab1 to zero !!
(lambda (in time chan dat)
(AudioBuffer_read_interp_mix ab1 ab2 (* 1.3 264.3) chan 0.5)))) ;; altering the mix value (a float) emphasises one or other buffer
;; Without phase reset the output will play the first time and only once!
;; To show this, comment out the phase line and print the ab1 components
($ (println pianoC6))
;; Notice the PHASE number for the ab1 buffer is non zero.
;; Need to set_phase to zero on each re-evaluation.
;; Not sure if the non-zero phase was intentional. ??
;; It took me a long time to figure out why the thing would run only once despite re-evaluations.
($ (println pianoC6))
($ (println pianoDsh6))
($ (println pianoFsh6))
;; Playhead reset to zero behaves differently from reset phase.
;; Printout shows playhead set to somewhere in file but resetting to zero maybe is done automatically.
;; Comment out the playhead reset does not seem to cause a problem.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Some experiments with AudioBuffer_read_interp
;; and
;; AudioBuffer_read_interp_pw
;; Load an new AudioBuffer with data also from extempore/assets/samples
(bind-val ab_xmas AudioBuffer* (AudioBuffer "assets/samples/xmas_carol.wav"))
($ (println ab_xmas)) ;; Stereo with 1312108 samples
;; Play the tune
(bind-func dsp:DSP
(let ((ab ab_xmas))
(AudioBuffer_set_phase ab 0.)
(AudioBuffer_set_playhead ab 0)
(lambda (in time chan dat)
(AudioBuffer_read ab chan))))
;; Then try AudioBuffer_read_interp
;; Try changing loop_start and/or loop_frames
;; Try altering the pitch multiplier in the last line
(bind-func dsp:DSP
(let ((ab ab_xmas)) ;;
;; loop_frames = looplgth.
;; segments = frames/looplgth
(lambda (in time chan dat)
(AudioBuffer_set_loop_start ab 312108) ;; start looping from a position
(AudioBuffer_set_loop_frames ab (* 1 100000)) ;; loop_frames = looplgth.
(AudioBuffer_read_interp ab (* 1.0 261.3) chan)))) ;; Hear a mix of two parts of the file?
;; Next try AudioBuffer_read_interp_pw
;; Changing the pw variable will shift positions sampled from the buffer
(bind-func dsp:DSP
(let ((ab ab_xmas)) ;;
;; loop_frames = looplgth.
;; segments = frames/looplgth
(AudioBuffer_set_phase ab 0.0)
(lambda (in time chan dat)
; (AudioBuffer_set_loop_start ab 0) ;; seems to have no effect?
(AudioBuffer_set_loop_frames ab (* 5 100000)) ;; loop_frames = looplgth.
(AudioBuffer_read_interp_pw ab (* 1.0 261.3) chan 0.95)))) ;; There's a mix going on - may be hard to hear?
;; You may be able to make more sense of what's going on
;; in the previous two 'interp' versions of AudioBuffer_read
;; if you choose a file on your own device with more contrast/variation between sections.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment