Last active
May 27, 2022 22:01
-
-
Save georgejwright/3e2442fc9231a6d30e42f9eb75ea4793 to your computer and use it in GitHub Desktop.
Experiments with extempore audiobuffers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; 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