SkillAgentSearch skills...

Flocking

Flocking - Creative audio synthesis for the Web

Install / Use

/learn @lichen-community-systems/Flocking
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Flocking - Creative audio synthesis for the Web!

What is Flocking?

Flocking is a JavaScript audio synthesis framework designed for artists and musicians who are building creative and experimental Web-based sound projects. It supports Firefox, Chrome, Safari on Mac OS X, Windows, Linux, iOS, and Android.

Unlike comparable tools, Flocking is declarative. Its goal is to promote a uniquely community-minded approach to instrument design and composition. In Flocking, unit generators and synths are specified as JSON, making it easy to save, share, and manipulate your synthesis algorithms. Send your synths via Ajax, save them for later using HTML5 local data storage, or algorithmically produce new instruments on the fly.

Because it's just JSON, every instrument you build using Flocking can be easily modified and extended by others without forcing them to fork or cut and paste your code. This declarative approach will also help make it easier to create new authoring, performance, metaprogramming, and social tools on top of Flocking.

Flocking was inspired by the SuperCollider desktop synthesis environment. If you're familiar with SuperCollider, you'll feel at home with Flocking.

To learn more about Flocking's architecture and approach, please see:

Clark, C. and Tindale, Adam. "Flocking: A Framework for Declarative Music-Making on the Web" in Georgaki, A. and Kouroupetroglou (eds.). The Joint Proceedings of the ICMC and SMC, (2014). slides

Flocking does not currently support the Web Audio API's new AudioWorklet specification, which allows for JavaScript-based signal processing code to run in a separate, real-time thread. This means that Flocking is not currently well-suited to applications that involve a lot of graphics rendering or user interaction. Work is underway on a new core for Flocking, called Signaletic, which will provide full support for all Web Audio native nodes as well as the use of AudioWorklets.

Status and Roadmap

Flocking is no longer actively maintained, but it continues to be very important to me. I'll try to fix things if they're fixable. In most cases, I don't recommend using it, especially if you feel most comfortable following conventions and "best practices" from Big Tech.

Please note that Flocking might not work with your modern build toolchain unless you understand how your tools work and can ensure that Flocking is loaded as a classic JavaScript dependency in the timeless way of the <script> tag.

The Flocking project adheres to the Contributor Covenant guidelines, and is an open and welcoming community.

Documentation and Demos

Getting Started

See the Getting Started documentation for more details on how to install Flocking.

The latest stable release of Flocking can be installed using npm or your favourite JavaScript package manager. Add it as a dependency in your package.json run npm install. Installing Flocking will create concatenated and minified Flocking builds, suitable for development and production respectively, in the dist directory. Flocking can also be built manually using Grunt.

After installing it with npm, here's how to include Flocking's development file in your HTML page:

<!-- This includes Flocking and all its dependencies, including jQuery and Infusion -->
<script src="npm_modules/flocking/dist/flocking-all.js"></script>

For more information on using Flocking in a browser, read the Getting Started tutorial. If old-fashioned module loaders are your thing, Flocking also supports the CommonJS and AMD styles. Modern ES6 modules and build tools likely will require manual intervention to work correctly.

Using Flocking

Flocking consists of a handful of primary components that are configured using JSON specifications. These include: Unit Generators (ugens), Synths, Schedulers, and the Environment.

Unit Generators

Unit generators, or ugens for short, are the basic building blocks of synthesis; they do the work of generating or processing audio signals in Flocking. UGens have multiple inputs and a single output. Some unit generators support multiple input or output multiple channels.

A unit generator can be wired to other unit generators, supporting sophisticated signal processing graphs. Unit generators implement one primary method, <code>gen(numSamps)</code>, which is responsible for processing a block of audio samples.

Typically, however, you never need to interact with unit generator instances directly. Instead, you create declarative "unit generator definitions" (ugenDefs) objects, letting Flocking take care of creating the actual unit generator instances. UGenDefs are composed into trees called synthDefs. Here's an example of a ugenDef:

{
    id: "carrier",             // A unique ID used when updating this ugen's input values.

    ugen: "flock.ugen.sinOsc", // The fully-qualified name of the desired unit generator,
                               // specified as a "key path" (a dot-separated string).

    rate: "audio",             // The rate at which the unit generator should run.

    inputs: {                  // The input values for this unit generator. Each UGen has different inputs.
        freq: 440              // For convenience, these inputs don't need to be nested inside the "inputs"
    },                         // container, but you might want to for readability.

    options: {
        interpolation: "linear" // Other non-signal options such as interpolation rates, etc.
                                // Options are also specific to the type of unit generator.
    }
}

Synths

A Synth is a self-contained collection of unit generators that represents a synthesizer, instrument, or signal processor of some kind. Multiple synths can run at the same time, and they can be connected together using shared interconnect buses. For example, a mixing board Synth could be created to mix and process signals from several tone-generating Synths and effect Synths.

To create a synth, you specify a <code>synthDef</code> option, which is a declarative tree of unit generator definitions. Here's a simple example of a sine oscillator (named carrier) whose amplitude is modulate by another sine oscillator, mod:

{
    id: "carrier",                  // Name this unit generator "carrier," exposing it as an input to the synth.
    ugen: "flock.ugen.sinOsc",      // Sine oscillator ugen.
    freq: 440,                      // Give it a frequency of 440 Hz, or the A above middle C.
    mul: {                          // Modulate the amplitude of this ugen with another ugen.
        id: "mod",                      // Name this one "mod"
        ugen: "flock.ugen.sinOsc",      // Also of type Sine Oscillator
        freq: 1.0                       // Give it a frequency of 1 Hz, or one wobble per second.
    }
}

Synths can be updated in realtime by using the <code>get()</code> and <code>set()</code> methods. Any unit generator with an <code>id</code> property in its ugenDef will automatically be exposed as a named input to the synth. To update a unit generator, a key path is used to specify the desired input. Key paths are dot-delimited, path-like strings that allow you to address any part of the unit generator tree. Here's an example of a key path:

"carrier.freq.mul" // Refers to the amplitude (mul) of the carrier's frequency.

Getting Synth Inputs

An input can be retrieved from a synth by invoking the <code>get()</code> method with a key path. If the target of the path is a value unit generator, its value will be returned directly. If it is any other kind of input, its ugen instance will be returned instead.

var freq = synth.get("carrier.freq");

Setting Synth Inputs

Synth inputs can be set by calling the aptly-named <code>set()</code> method. Flocking's signal processing pipeline is dynamic, so unit generators can be added or replaced at any time. Behind the scenes, everything is a unit generator, even static values.

Updating a value:

synth.set("carrier.freq", 440);

Replacing the target unit generator with a new one:

synth.set("carrier.freq", {
    ugen: "flock.ugen.sinOsc",
    freq: 2
});

Updating multiple inputs at once:

synth.set({
    "carrier.freq": 440,
    "carrier.mul": 0.5,
    "modulator.freq": 123
});

Rates

To ensure reasonable performance on resource-constrained devices such as phones and low-power computers (e.g. Chromebooks, Raspberry Pi), Flocking uses a block-based architecture. By default, ugens and synths will produce 64 samples per block. This value is configurable by specifying the <code>blockSize</code> option when initializing Flocking.

There are three primary types of signal rates in Flocking: <code>audio</code>, <code>control</code>, and <code>constant</code>. Audio rate produces a full block of samples, control rate produces one sample per block, and constant rate will alway produce the same value. Synths also support two other rates, <code>demand</code> and <code>scheduled</code>. A demand rate synth will

View on GitHub
GitHub Stars709
CategoryDevelopment
Updated2d ago
Forks59

Languages

JavaScript

Security Score

95/100

Audited on Mar 29, 2026

No findings