Skip to content
Buffer definition; audio buffer abstraction for sound synthesis systems.
Common Lisp
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
LICENSE
README.org
bdef.asd
bdef.lisp
cl-collider.lisp
cl-patterns.lisp
package.lisp
splits.lisp

README.org

bdef

“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.

Features

Can be re-evaluated without loading a new buffer:

Compare:

(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!

versus:

(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 bdef again.

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:

(bdef "/my-file.ogg")

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 bdef’s 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.

Integration with cl-collider:

(cl-collider:bufnum (bdef :sound)) ;; returns the buffer number.

(cl-collider:synth :playbuf :bufnum (bdef :sound)) ;; plays the buffer.

Load the bdef/cl-collider system to enable this.

Integration with cl-patterns:

(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.

Load the bdef/cl-patterns system to enable this.

Designed to work with multiple backends:

At the moment, SuperCollider/cl-collider is the main one. Support for Incudine is planned.

Enable the cl-collider backend like so:

(ql:quickload :bdef/cl-collider)

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 remove-auto-metadata function.

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)

Integration with the Aubio audio analysis library if installed:

(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!

Future

  • Right now, cl-collider is the only supported backend. In the future, Incudine should work as well.
  • Support for configurable pathname shortcuts. (i.e. set foo as a shortcut to /a/long/path/name/, then provide ~”foo/bar.wav”~ instead of ~”/a/long/path/name/bar.wav”~.)
  • Loading with num-channels set to 1 loads only the first channel. Might make more sense to mix all channels down to mono, perhaps as an option.
You can’t perform that action at this time.