A monolithic audio engine for live coding ported from C to Rust and then extended by BuboBubo. The initial project is called Dough and was designed by Felix Roos and al. Doux can run in a web browser via WebAssembly, or natively using an an OSC server and/or a REPL. Doux is an opinionated, fixed path, semi-modular synth that is remote-controlled via messages. It has been designed initially to be used with Strudel. This fork is a bit special: it adapts and specialize the engine for integration with Sova and Cagire, two live coding environments built with Rust.

This project is AGPL 3.0 licensed. We encourage you to support the development of the original version through the TidalCycles Open Collective. Consult the support page for more information.

License & Support

Getting Started

Click anywhere on the page to start the audio context. Then click inside a code block and press Ctrl+Enter to run it, or Escape to stop. You can also press the play button if you don't want to edit and just want to preview. The easiest way to start making sound with Doux is just to specify a sound to use:

You can set the pitch with the /note parameter (MIDI note numbers):

Or use frequency directly with /freq:

Omitting parameters

It is possible to omit pretty much all parameters or to under-specify the parameters a synthesis voice you wish to play. Doux has preconfigured defaults for most of the core parameters.

If no sound source is specified, the voice defaults to tri with sensible envelope defaults. If a sound name is not recognized, the voice is silently skipped.

Sound Sources

There are multiple sound sources you can use, detailed in the reference. You can also import your own audio samples or use a live input as a source.

Turn on your microphone (and beware of feedback!):

Envelopes

The amplitude envelope controls how the sound fades in and out. It uses the classic ADSR model: attack, decay, sustain, release.

/attack is the time (in seconds) to reach full volume.
/decay is the time to fall to the sustain level.
/sustain is the level held while the note is on (0-1).
/release is the time to fade to silence after note off.

Try changing each parameter to hear how it affects the sound.

Filters

Most of the default sources are producing rich timbres full of harmonics. Use filters to remove some components of the spectrum. Doux has all the basic filters you need:

All filters come with a control over resonance /..q:

Effects

Doux includes several effects. Here is a sound with reverb:

And another sound with delay:

If you stack up effects, it can become quite crazy:

Note that the order in which the effects are applied is fixed by default! You cannot re-order the synthesis chain.

Inline Modulation

Many parameters support inline modulation: instead of a static value, you write an expression with an operator that describes the motion between two values. In the reference, parameters marked with ~ support this syntax.

Oscillate ~

Cycle between two values forever. Syntax: min~max:period[shape]

  • 200~4000:2 β€” sine (default)
  • 200~4000:2t β€” triangle
  • 200~4000:2w β€” saw (ramp up, snap down)
  • 200~4000:2q β€” square (alternate min/max)

A lowpass filter sweeping from 200Hz to 4000Hz over 2 seconds:

Pan bouncing left to right with a triangle wave:

Transition >

Go from A to B, hold at B. Chain segments for multi-point envelopes. Syntax: start>target:duration[curve]

  • 200>4000:2 β€” linear (default)
  • 200>4000:2e β€” exponential
  • 200>4000:2s β€” smooth (ease in-out)

Multi-segment chains:

  • 200>4000:1>800:2 β€” up in 1s, down in 2s
  • 0>1:0.01>0:2 β€” percussive blip
  • 200>4000:1e>200:1.5s β€” exponential up, smooth down

Append ~ to the last duration to loop:

  • 200>4000:1>200:1~ β€” looping triangle-like sweep

FM index ramping up exponentially over 3 seconds:

Random ?

Wander stochastically within a range. Syntax: min?max:period[shape]

  • 200?4000:0.5 β€” sample-and-hold (default)
  • 200?4000:0.5s β€” smooth (cosine-interpolated)
  • 200?4000:0.1d β€” drunk walk (brownian)

Random pan jumps: