Pattern Guide 01: Introduction:
Tutorials/A-Practical-Guide | Streams-Patterns-Events > A-Practical-Guide

Pattern Guide 01: Introduction

Fundamental concepts of patterns and streams

by H. James Harkins 1


Patterns are one of the most powerful elements of the SuperCollider language, but in some ways they can be difficult to approach using only the class-oriented help files. These documents seek to bridge the gap, explaining the conceptual background behind patterns, describing the usage of specific Pattern classes, and proceeding into examples of practical musical tasks written as patterns.


Pattern Guide 01: Introduction
Fundamental concepts of patterns and streams
Pattern Guide 02: Basic Vocabulary
Common patterns to generate streams of single values
Pattern Guide 03: What Is Pbind
Pattern-based musical sequencing with Pbind and cousins
Pattern Guide 04: Words to Phrases
Nesting patterns, arranging music in terms of phrases
Pattern Guide 05: Math on Patterns
Performing math and collection operations on patterns
Pattern Guide 060: Filter Patterns
Overview of patterns that modify the behavior of other patterns
Pattern Guide 06a: Repetition Constraint Patterns
Patterns that repeat values, or cut other patterns off early
Pattern Guide 06b: Time Based Patterns
Patterns using time as the basis for their evaluation
Pattern Guide 06c: Composition of Patterns
Making multiple event patterns act as one
Pattern Guide 06d: Parallel Patterns
Running multiple event patterns simultaneously
Pattern Guide 06e: Language Control
Patterns that mimic some language-side control structures
Pattern Guide 06f: Server Control
Patterns that manage server-side resources
Pattern Guide 06g: Data Sharing
Writing patterns to use information from other patterns
Pattern Guide 07: Value Conversions
Describes the default event's conversions for pitch, rhythm and amplitude
Pattern Guide 08: Event Types and Parameters
Describes the event types defined in the default event, and the parameters they expect

Pattern Cookbook

The pattern cookbook is a set of examples with explanations.

Pattern Guide Cookbook 01: Basic Sequencing
  • Playing a predefined note sequence
  • "Multichannel" expansion
  • Using custom SynthDefs (including unpitched SynthDefs)

Pattern Guide Cookbook 02: Manipulating Patterns
  • Merging (interleaving) independent streams
  • Reading an array forward or backward arbitrarily
  • Changing Pbind value patterns on the fly

Pattern Guide Cookbook 03: External Control
  • Control of parameters by MIDI or HID
  • Triggering patterns by external control

Pattern Guide Cookbook 04: Sending MIDI
  • Sending notes under pattern control to MIDI devices

Pattern Guide Cookbook 05: Using Samples
  • Playing a pattern in time with a sampled loop
  • Using audio samples to play pitched material

Pattern Guide Cookbook 06: Phrase Network
  • Building a more complicated melody using shorter phrase patterns
  • Also illustrates PmonoArtic for portamento with articulation

Pattern Guide Cookbook 07: Rhythmic Variations
  • An ever-changing drumbeat

Pattern Guide Cookbook 08: Swing
  • Emulating quantize-with-swing from conventional sequencers

Reference material

Pattern Guide Reference 01: Pattern Internals
Details of pattern implementation, with guidance on writing new pattern classes

Why patterns?

Patterns describe calculations without explicitly stating every step. They are a higher-level representation of a computational task. While patterns are not ideally suited for every type of calculation, when they are appropriate they free the user from worrying about every detail of the process. Using patterns, one writes what is supposed to happen, rather than how to accomplish it.

In SuperCollider, patterns are best for tasks that need to produce sequences, or streams, of information. Often these are numbers, but they don't have to be -- patterns can generate any kind of object.

For a simple example, let's count upward starting from 0. We don't know how high we will need to count; we just know that every time we ask for values, we should get a continually increasing series.

Writing everything out, it looks like this. Routine is used because this is a control structure that can interrupt what it's doing and remember where it was, so that it can pick up again at exactly that point. You can get some numbers out of it, and call it again later and it will keep counting from the last number returned. (This is an example of a Stream. You can find more about Streams in Understanding Streams, Patterns and Events - Part 1.)

SuperCollider's built-in control structures allow some simplification.

But wouldn't it be nice just to say, "Give me an infinite series of numbers starting with 0, increasing by 1"? With Pseries, you can. (Here, keyword addressing of the arguments is used for clarity, but start, step and length can be omitted.)

What are the advantages of the pattern representation?

What are some disadvantages?

Using patterns for sequencing might seem to be an advanced usage, but for many uses they are easier than the equivalent code written out step by step. They can serve as a bridge for new and advanced users alike, to represent a musical conception more directly with less connective tissue explicitly stated.

The first step in learning a new language is vocabulary, so the next chapter will concentrate on foundational patterns to generate data streams of nearly every sort.

Patterns versus Streams

Some context that is important to keep in mind throughout this discussion is the difference between patterns and streams. In the most general terms:

Patterns define behavior; streams execute it.

A pattern is like a blueprint for a building, showing how all the parts fit together. The building doesn't exist until the contractors go and do what the plans specify. When a stream is made from a pattern, it follows the plans laid out in the pattern's blueprint. Rendering the plans into a real-world result does not change the blueprint in any way, but to get the result, the stream has to go through different states.

A pattern is supposed to describe behavior, and in general, evaluating the pattern (by way of a stream) should not change anything in the Pattern object itself. In computer science terms, patterns are stateless; their definition does not change over time. The stream is what keeps track of where we are in the pattern's evaluation.

This explains an easy "gotcha" with patterns -- forgetting to turn the pattern into a stream doesn't get the expected result. Since a pattern doesn't have any concept of a current state, calling next on it is meaningless, so next does what it does for most objects: return the receiver object itself. The method asStream creates the stream conforming to the pattern's specification, and calling next on the stream advances to its next state and returns the new value.

There is a concrete benefit to this strict division of labor. Since the stream does not modify the original pattern, any number of streams can be made from the same blueprint. All of those streams maintain their own independent states, and they can operate concurrently without interfering with each other.

Bear these points in mind as we move to the next subject: getting basic types of data (deterministic and random) out of patterns.

Next: Pattern Guide 02: Basic Vocabulary

[1] - Documentation licensing

The initial version of these documents was written December-February 2009 by H. James Harkins. As part of the SuperCollider package, they are released under the Creative Commons CC-BY-SA license. As SuperCollider is an open source project, it is expected (and encouraged) that other users will contribute to the series. Dr. Harkins, however, wishes to retain exclusive rights to revise and republish the original body of work independently of the open-source copy. This excludes material contributed into svn by others. The work may be redistributed at no charge with proper attribution:

Harkins, Henry James. "A Practical Guide to Patterns." SuperCollider 3.3 Documentation, 2009.