cl-patterns comes by default with several backends. The “primary” backend that usually gets the most development time and testing is the SuperCollider/cl-collider backend, however full functionality is planned for the other included backends as well. If you want to use functionality that seems broken or missing in one of them, don’t hesitate to file a bug so it’s known what should be prioritized in development.
The following is a list of the backends included with cl-patterns, as well as all other known Lisp systems that include backends of their own (or integrate in other ways).
Of course, if you want to control something that cl-patterns doesn’t already have a backend for, in theory all you need to do is define a few methods… However, pre-1.0, cl-patterns’ API for doing so is not guaranteed to be stable, so do so at your own risk. Information about implementing a backend is included at the end of this document. See the SuperCollider backend for an example.
The following is a table giving information on the various known backends as well as the status of the implementation of various cl-patterns features. Obviously, the information here might lag a bit behind the actual code.
feature | SC | INC | AMIDI | DEBUG | EMACS | RN | CLP | WORM | BDEF |
basic sequencing | ✅ | ✅ | ✅ | ✅ | 🚫 | ❌ | ❌ | ❌ | ✅ |
standard backend methods | ✅ | 🟡 | 🟡 | ✅ | ❌ | ❌ | ✅ | ||
clock sync | ❌ | ❌ | ❌ | 🚫 | 🟡 | ❌ | 🚫 | 🚫 | |
play/stop/etc | ✅ | 🟡 | ❌ | 🚫 | 🚫 | ❌ | 🚫 | ||
backend’s own methods | ✅ | ❌ | ✅ | ||||||
multichannel expansion | ✅ | 🟡 | ❌ | 🚫 | |||||
pattern import | ❌ | ❌ | 🚫 | 🚫 | 🚫 | ||||
pattern export | ❌ | ❌ | 🚫 | 🚫 | |||||
rendering | ❌ | ❌ | ❌ | 🚫 | |||||
other (backend-specific) |
- SC = SuperCollider/cl-collider
- INC = Incudine
- AMIDI = ALSA MIDI
- RN = Renoise
- CLP = cl-patterns
- BDEF = bdef
- ✅ = 75-100% implemented
- 🟡 = 25-75% implemented
- ❌ = 0-25% implemented
- 🚫 = not applicable
- blank = unknown
Basic sequencing, in which cl-patterns’ own clock triggers events.
Basic methods like make-backend
, backend-start
, etc.
Synchronize the backend’s own clock with the cl-patterns clock.
Allows cl-patterns’ play
, stop
, launch
, end
, etc, methods to control the backend’s objects. For example to play
an Incudine DSP, stop
a SuperCollider node, etc.
If the backend has its own generics, cl-patterns may define methods on them so you can use them to control its objects. For example, cl-collider’s free
has a method to act like stop
when used on a cl-patterns pattern.
cl-patterns will multi-channel expand for the backend.
The ability to convert from a backend’s sequence format(s) into a cl-patterns pattern. For example, for the Renoise backend, this would be the ability for cl-patterns to read a project file and convert its sequences into patterns.
The ability to convert from a cl-patterns pattern into a sequence format supported by the backend. For example, SuperCollider’s score format, which scsynth can use to perform non-realtime (NRT) rendering.
Functionality to render a pattern or event as an audio file or buffer via the backend.
It’s possible some backends may have additional functionality we may want to support. If that is found to be the case, they will be noted here.
The SuperCollider backend is the “main” backend that cl-patterns is developed and tested against the most. Any backend-agnostic functionality will most likely be implemented in this one first.
Note that cl-patterns doesn’t control SuperCollider directly; instead it does so via cl-collider. I try to keep cl-patterns’ functionality consistent with cl-collider and make it easy to use both libraries in tandem. For example, generics like play
, stop
, etc, should work just as well on cl-collider objects as they do on cl-patterns.
The Incudine backend is cl-patterns’ other main synthesis backend. Incudine is unique in that it is designed from the start to be used with Lisp. It is also unique in that it supports the concept of “virtual ugens” or “VUGs” which make it simpler to write synthesis routines at a lower level than SuperCollider.
At the moment, the Incudine backend may lag a bit behind the SuperCollider one, mostly because I am not as familiar with it yet. However it is very interesting for the reasons listed above and I definitely want to make it as good as the SuperCollider backend!
Note that this is subject to change, and that the information below may not reflect the current state of the code - feel free to ask questions or submit bug reports if you’re interested.
The following is a list of some of the generic functions defined by cl-patterns. The list is roughly ordered from most to least important for implementing a backend.
peek
next
events-in-range
ended-p
as-pstream
- ?last-output
- ?
backend-start
backend-stop
backend-play-event
backend-tempo-change-at
backend-task-removed
backend-instrument-controls
backend-instrument-args-list
backend-all-nodes
backend-node-p
backend-panic
- Forwards to(stop (backend-all-nodes BACKEND))
if undefined for a backend.backend-timestamps-for-event
backend-proxys-node
backend-control-node-at
backend-convert-object
*dictionary-lookup-functions*
- A list of functions thatplay
,stop
, etc check when called with a symbol as their argument. For example,(play :foo)
will check the functions in this list and the first non-nil result will be used as the object to play. You will likely want to include a function that can be added to this list, i.e. a function mapping symbols to playable/stoppable objects.play
stop
launch
- Forwards toplay
if undefined for a class.end
- Forwards tostop
if undefined for a class.tempo
beat
play-quant
end-quant
playing-p
- Allows functions likeplay-or-stop
andplay-or-end
to work when defined.loop-p
render