Library for conveniently(?) writing patterns to generate or process (a)musical sequences of mathematically (un)related (non-)compound values in Lisp.
Switch branches/tags
Nothing to show
Clone or download

README.org

cl-patterns

A library for conveniently(?) writing patterns to generate or process (a)musical sequences of mathematically (un)related (non-)compound values in Lisp.

Heavily inspired by SuperCollider’s patterns system, with aims to implement much of it, but in a more robust, expressive, consistent, reflective, and lispy way:

  • robust: strongly prefer coercing values into something “correct” rather than failing or giving an error.
  • expressive: make writing music as easy and “natural” as possible, so that patterns can be built in real-time, in performance settings, without having to think so hard about how to bend the library to your will. i feel this is a weakness of SuperCollider.
  • consistent: edge cases minimized, arguments for the various functions in an intuitive order. pretty self-explanatory.
  • reflective: store more data about the stream state and more metadata about the patterns. make it easier for a pattern to access the values of another pattern, for patterns to affect other patterns, etc.
  • lispy: prefer lisp idioms rather than direct translations of the SuperCollider way of doing things (while still keeping things relatively similar so it’s not a huge adjustment for SC users to make).

In addition to emulating most of SuperCollider’s patterns system, another goal is to further extend it with more tools and more ways to write patterns/sequences. The most obvious example being a “drum sequence” notation like k - - - k - - - k - - - k - - - for a four-to-the-floor beat. The idea is that Lisp’s macros should make it possible to more expressively write music with code.

Intro

Make sure you have Quicklisp installed and working with your Lisp implementation, then load cl-patterns:

(ql:quickload :cl-patterns)
(in-package :cl-patterns)

Create a pattern like so:

(defparameter *pat* (pbind :foo (pseq '(1 2 3))
                           :bar (prand '(9 8 7) 5)))

Since patterns are basically “templates”, you need to turn them into pstream objects in order to actually get output from them:

(defparameter *pstream* (as-pstream *pat*))

Then, you can get results from the pstream one at a time with next, or many at a time with next-n or next-upto-n:

(defparameter *results* (next-n *pstream* 3))
results
;; => ((EVENT :FOO 1 :BAR 8) (EVENT :FOO 2 :BAR 9) (EVENT :FOO 3 :BAR 8))

To actually play events (and hear sound output), you’ll need to start an audio server. Right now, SuperCollider is the main audio server that cl-patterns is tested against, but there is also preliminary support for Incudine and for MIDI output through ALSA.

In order to be able to connect to SuperCollider, you need the cl-collider and scheduler libraries installed in your quicklisp local-projects directory so that they can be loaded. Then:

(ql:quickload :cl-patterns/supercollider)
;; code to start scsynth and define few example synths:
(load #P"/path/to/cl-patterns/doc/supercollider-example.lisp")

And finally we can play patterns and hear sound:

(play (pbind :instrument :kik :freq (pseq '(100 200 400 800) 1)))

From here, you can take a look at the code in the supercollider-example.lisp file for a short example of how to define your own synths. You may also be interested in my cl-collider tutorial for a more in-depth introduction to cl-collider.

For more information on how to use cl-patterns, refer to tutorial.org for an introduction.

You can get a list of all currently-defined patterns using (all-patterns). All patterns should have usage information and examples in their docstrings, which of course can be accessed using the standand describe or documentation functions.

Features

This library isn’t just a copy of SuperCollider’s patterns - I wanted to improve upon them as well. For a list of notable features in cl-patterns, see features.org.

If you’re familiar with SuperCollider, you may also want to look at sc-differences.org for a listing of differences between this library and SC’s patterns, or sc.org for a listing of patterns in SuperCollider and their equivalent (and implementation status) in cl-patterns.

Current Status

Right now, the library may be described as being in a “alpha” state, as major changes (which may break code you write) are still very likely to happen. However, these changes should be documented in commit messages, so check those if you have any issues after updating.

Despite that, lots of functionality is already written and the library should be stable enough for normal usage in most cases.

Many tests have already been written to help guard against regressions.

Much documentation is still being written, but there is already a good amount of information in the doc directory, and in the docstrings for the patterns, functions, etc.

The SuperCollider backend is the primary backend that cl-patterns is tested against so it should generally work the best and should be usable for most purposes.

The MIDI backend has some functionality complete and should be usable for basic tasks, but is still very much a work in progress.

The Incudine backend is a stub and has very limited (if any) functionality.

See TODO.org and roadmap.org for a listing of tasks that need to be completed and ideas for future features. The code itself is also littered with comments marked “FIX” noting various known issues and possible changes and optimizations that could be made.

Tour

doc

  • features.org - listing of notable features of cl-patterns.
  • other-libraries.org - listing of other libraries that have similar goals or may be useful in conjunction with cl-patterns.
  • roadmap.org - general overview of major goals for the future development of cl-patterns.
  • sc.org - a list of pattern classes in SuperCollider and their cl-patterns implementation status.
  • sc-differences.org - comprehensive description of things that differ between cl-patterns and SuperCollider.
  • special-keys.org - description of keys that have special effects when used in an event or pbind.
  • supercollider-example.lisp - short example of how to use cl-patterns with cl-collider.
  • TODO.org - a list of things and ideas that have not yet been implemented into cl-patterns, but may be in the future.
  • tutorial.org - explanation of the basic concepts of cl-patterns, meant for people who have never used SuperCollider’s patterns.
  • writing-your-own.org - information about how to write your own pattern classes.

src

  • utility.lisp - general utility functions and special variable definitions.
  • conversions.lisp - functions to convert between units (i.e. midinote to frequency, decibels to amplitude, etc.).
  • scales.lisp - musical pitch (scales/tuning) data and structs.
  • event.lisp - code to represent and deal with events. includes the event class, information about special keys (i.e. freq, amp…), etc.
  • backend.lisp - code to handle “backends”; i.e. how cl-patterns will actually “play” events.
  • clock.lisp - the scheduling functionality to make sure that each event is played at the proper time.
  • sugar.lisp - defines optional syntax sugar including a named-readtable. may be moved to a separate system in the future.
  • tests.lisp - test suite using FiveAM.

patterns

  • patterns.lisp - general pattern macros and functionality + the standard set of patterns; includes the pattern superclass, pbind, pseq, pk, etc.
  • bjorklund.lisp - Euclidean pattern functionality such as pbjorklund, etc.
  • cycles.lisp - TidalCycles-inspired patterns and notation, i.e. pcycles, etc.
  • tracker.lisp - tracker-inspired patterns and notation, i.e. ptracker and associated functions, macros, reader macros, etc.
  • sc-compatibility.lisp - patterns that are 100% compatible with SuperCollider’s patterns system.

backends

Community

As far as I’m aware there isn’t a huge community of people using this library to make music yet. However, if you need support or want to chat about it, the “official” room is on Matrix: #cl-patterns:struct.ws.

You can contact me (the primary author) on IRC as well; I’m usually idling on Freenode with the nick defaultxr.

Obviously, any bugs or feature requests can be submitted to the GitHub issue tracker.