“Buffer definition”; abstraction of audio buffers for Lisp sound synthesis systems.
Basically, this simplifies buffer management in cl-collider, making them easier to use.
Note: Previously at the URL for this repository was Bdef for SuperCollider. That repository has since moved here.
Can be re-evaluated without loading a new buffer:
(defparameter *buf* (cl-collider:buffer-read "/buffer.wav")) (defparameter *buf* (cl-collider:buffer-read "/buffer.wav")) ;; the same variable, and same file! (length (remove-if #'null (slot-value *s* 'cl-collider::buffers))) ;; => 2 -- duplicate buffers!
(bdef :buf "/buffer.wav") ;; here we give it the name :buf (bdef :foo "/buffer.wav") ;; same file, different "name"... (length (remove-if #'null (slot-value *s* 'cl-collider::buffers))) ;; => 1 -- no duplicate buffers :D
…To force a file to be reloaded, simply call
bdef-free on it, then call
Automatically converts files unsupported by the backend if you have ffmpeg installed:
(bdef :bar "/blah.mp3") ;; works!
It does this by storing them in a temporary directory (
/tmp/bdef/ by default on linux and mac).
No additional name needed if loading from a file:
Supports pathname abbreviations:
(bdef "~/cool-sound.wav") ;; will find a cool sound in your home directory
Loads mono files as stereo by default.
For consistency. To load as mono, supply 1 for
num-channels keyword argument.
Supports loading in wavetable format:
(bdef "~/wilhelm.wav" :wavetable t) ;; load the Wilhelm scream as a wavetable
Supports loading envelopes as buffers:
Either as wavetables, or standard.
(cl-collider:bufnum (bdef :sound)) ;; returns the buffer number. (cl-collider:synth :playbuf :bufnum (bdef :sound)) ;; plays the buffer.
bdef/cl-collider system to enable this.
(cl-patterns:play (bdef :sound)) ;; plays the buffer using the *cl-collider-buffer-preview-synth* set in cl-patterns. (cl-patterns:play (cl-patterns:event :instrument :playbuf :bufnum (bdef :sound))) ;; automatically converts bdef to the buffer number.
bdef/cl-patterns system to enable this.
Designed to work with multiple backends:
Enable the cl-collider backend like so:
Allows metadata about the buffer to be stored:
(setf (bdef-metadata (bdef :snd) :tempo) (/ 99 60)) ;; set :snd's tempo to 99 BPM. (bdef-metadata (bdef :snd) :tempo) ;; get the stored tempo value.
Automatically gets various metadata for a file when available:
(bdef-metadata (bdef "~/my-file-128bpm.wav") :tempo) ;; => 32/15 (128bpm in beats per second)
You can also add your own auto-metadata keys with the
define-auto-metadata macro or
set-auto-metadata function, or remove them with the
Additional metadata is loaded asynchronously in background threads using futures from the eager-future2 library. If a requested metadatum is still being generated,
bdef-metadata will block until the result is available.
“Splits” functionality to define split points or regions in buffers:
(make-splits (list 0 0.25 0.5 0.75) :bdef (bdef :foo)) ;; splits at the start, 25%, 50%, and 75% into the file. (splits-from-audacity-labels "/path/to/label.txt") ;; make a splits object from an Audacity labels file. (setf (bdef-splits :my-bdef) *) ;; set the :my-bdef bdef's :splits metadatum to the splits object generated from the above. (splits-point :my-bdef 3 :start :second) ;; get the start of :my-bdef's fourth split in seconds.
Splits integration with cl-patterns:
(pbind :instrument :playbuf :bufnum (bdef :my-bdef) :split (pwhite 0 (1- (splits-length :my-bdef))) ;; pick a random split :embed (psplits) ;; the psplits pattern yields events with :start, :end, and :dur keys to play the split specified by :split from the :splits metadatum of the bdef specified as :bufnum. :dur 1)
Aubio audio analysis library if installed:Integration with the
(bdef::splits-from-aubio-onsets "/path/to/audio/file.wav") (bdef :pee "/path/to/pee.wav") ;; since no BPM is listed in the filename, aubio is used to detect it (if installed)... (bdef-metadata :pee :tempo) ;; ...and it is stored in the bdef's :tempo metadatum! nice!
- Right now,
cl-collideris the only supported backend. In the future, Incudine should work as well.
- Support for configurable pathname shortcuts. (i.e. set
fooas a shortcut to
/a/long/path/name/, then provide ~”foo/bar.wav”~ instead of ~”/a/long/path/name/bar.wav”~.)
- Loading with
num-channelsset to 1 loads only the first channel. Might make more sense to mix all channels down to mono, perhaps as an option.