/ Examples / Control / Tidal

Projects .. AudioIO .. Control
NoteStreams .. Instruments
Filters .. Effects .. LiCK Effects
Plot .. Utility .. Pure ChucK


Wherein we explore the Tidal node for live-coding and algo-raving with Strudel.

For more on Strudel/Fiddle integration see Strudel Panel and our scripting cheatsheet.
Also check out Strudel's online tutorial.

Right-click to copy this example-pack to your workspace.

Strudel+Fiddle Operation

Strudel is an online website so its ability to save your work is constrained. In Fiddle, we are free from these contraints. We rely on the combination of the Workspace Panel and the Code Editor to make Strudel scripting easy and efficient.

✓ Open the Strudel script in Code Editor. See tests/ and tunes/ after copying this example to your workspace.

✓ Select-all and copy the text from your file.

✓ Select-all and paste the script into the Strudel panel.

✓ Make sure ChucK is operating on your desired Fiddle graph (.chg). Since most of the "juice" is in the Strudel script you'll find that a single .chg goes a long way.

✓ Press play in Strudel.

✓ Play! Tweak your script, tweak the Fiddle nodes.

The Tidal Node

The Tidal Node is the hub of all Strudel/Tidal activites in the Fiddle+ChucK environment. In order for the Tidal node to have any effect, the Strudel Panel must be visible and active. You can have multiple Tidal nodes in a single session, each attending to Tidal events on a single orbit or midichan. Typically a single node is sufficient.

You can use the Tidal node in two distinct ways.

Internal Synthesis: the Tidal node receives Tidal Events and synthesizes sound that closely approximates the sound of Strudel's WebAudio synth pipeline.

External Synthesis: the Tidal node receives Tidal Events and distributes them to downstream instruments and effects.

We provide a diverse set of example .chg and .js files with this example packet. We'll discuss some of them below.

Tidal's Parameters

Synth - check this box to enable internal synthesis. When not checked, notes are delivered to the downstream instruments and effects via its Ctrl port. When checked, the outlet port must be connected to a downstream audio channel or effect.

Orbit - respond to Tidal events from a single orbit. The default of -1 means respond to all orbits. Tidal orbits embody unique global effects configurations. If you want to use an external synth, each with different effects chains create multiple Tidal+Player configurations with different orbit settings.

MidiChan - respond to Tidal events on one or more MIDI channels. The default of -1 means respond to all channels. Tidal's MIDI channels are controlled via its midichan control with indices starting at zero. MIDI channel 1 is expressed: midichan(0). MIDI channel 10 is reserved for percussion and is expressed: midichan(9). To respond to a single MIDI channel, enter its 0-indexed value here. To respond to all MIDI channels except the reserved percussion channel, enter -9.

EmitCCs - when routing Tidal traffic to an external synth this knob controls whether to include Tidal control values as CC messages. When checked, we emit Tidal fields like pan, gain, room, delay, etc to nodes downstream from our Ctrl port connections. NB: to rename outgoing CC names, define Aliases through the CCAliases port. In all the examples herein, we include a single CCAliases node to perform the renaming operation.

SampMgrs - when used in internal-synthesis mode, upstream SampleMgr connections assign sample filenames to Tidal's sound references. For example, s("bd sd") specifies two different sounds 'bd' and 'sd' and the Tidal's internal synth needs to convert these reference to sample files available on your local filesystem. The SampleMgr Node is a nifty solution to this problem and automates the downloading and pitch-shifting of internet-hosted audio samples. Each upstream node has one or more sample references and these are currently resolved in connection order.

Gain - a linear multiplier for the internally synthesized audio output.

CCAliases - connection one or more Alias nodes to this port. See below for a typical setup.

Port - the UDP socket we listen to for Strudel events. You shouldn't need to change this value.

Example 1 (Internal Synthesis)

To run this example you'll need several free MBs of disk space for sample files.

Internal synthesis is enabled when Synth is checked. This is the default mode for Tidal node because it's the simplest way to get going with Strudel+ChucK.

Here is an overview of Tidal's internal synth pipeline:

Sin/Sqr/Tri/SawOSC   => sig
SamplePlayer         => sig

sig => adsr => gain
       => lpf => hpf => bpf => vowel
       => coarse => crush => shape
       => pan => lastgain => orbit (delay, reverb)

Each of these pipeline stages has its own Tidal controls described here. We've provided concise examples of these in the tests subdirectory.

Let turn our focus to the following graph. As mentioned above, this graph should work for any Strudel script. Most of its complexity is present to provide a mapping between a Strudel sound-reference, eg. s("bd") and a local sample file (in .wav, .mp3, .flac format).

Here's the graph for internalSynth.chg:

Lurking inside the seven SampleMgr nodes, we've provided a large vocabulary of soundfiles in order to increase the likelihood that a random Strudel script sounds okay. For this reason, you'll experience a longish delay the very first time you perform this graph. In the Log you'll see a message for each file as it's copied from the internet.

12:17 note [chuck] DbSampleMgr/0: cached https://raw.githubusercontent.com/ritchse/tidal-drum-machines/main/machines/RolandTR808/rolandtr808-sd/SD7575.WAV

By default, these files land below your Fiddle project directory at ~/Documents/Fiddle/_cache.

Once you get going with Tidal you will probably want to tailor your compositions to individual soundbanks. Then, this "kitchen-sink" approach may be overkill. At this point, you may want to learn about the banklist and toc files that make the SampleMgr tick. Or if you already have your favorite samples on your system, then the SampleMgr Files parameter allows you to point directly to them bypassing the auto-cache.

At this point you are ready to try out a number of Strudel tests and tunes. Restating the basic procedure:

✓ Open the Strudel script in Code Editor. Here's a simple script you can try.

// test adsr
stack(
  note("<g3 a3 b3>(8,11)")
   .pan("[0 .5 1]").attack(.1).fast(3),
  note("c4 c3 g2").s("sine")
    .attack(1).decay(1).pan("1 .5 0")
).slow(8).room("<0 .6>/8").roomsize(5)
.gain(2).osc()

✓ Select-all and copy the text from your file.

✓ Select-all and paste the script into the Strudel panel

✓ Press play in Strudel.

✓ Play! Tweak your script, tweak the Fiddle nodes.

If you want to load and tweak a random Strudel script from the internet.

✓ click on the Strudel REPL logo in the topleft corner of the Strudel panel. This opens a popup window with a few more controls. Make sure the base-panel is quiet, then press Strudel's shuffle button. Remember to add the .osc() line to send Tidal events to ChucK. Note that you may need to tweak various gain settings as well as nominate new samples to play the role required by the random script.

And one other note:

Some examples assume that delay and room are disabled but don't explicitly state that in the script with delay(-1) room(-1). When you question the current state of Tidal's internal synthesizer, a general workaround strategy is to quit-and-restart ChucK regularly.

Example 2 (External Synthesis)

On of the advantages of the Strudel+ChucK combination is that you aren't limited to the canned sounds of a specific sythesis pipeline. Instead you can build your own or even route to a ChucK-native synthesis engine.

The simplest example engines that can render Strudel events are Fluid Synth and DexedInst.

Let's focus on the use of Fluid to produce sounds for Strudel scripts. Comparing the graph below with the previous graph, the first thing to note is that there aren't any SampleMgr nodes. These aren't needed because FluidSynth has supports General MIDI which defines an assortment of percussion and instrument sounds.

When in external Synth mode (Synth unchecked), Tidal node automatically converts sound references like bd into an approximate match from the general MIDI percussion table.

Here's the graph for externalFluid.chg:

In this example, beyond producing note events for instruments, we route some important Strudel controls into ChucK effects nodes. This accounts for the wires between Tidal.Ctrl and DelayFB and NHHall. The remapping of Strudel names to arbitrary parameter names is accomplished by the Aliases node. At right you can see a typical setup.

For example, we map:

gain to Gain
roomsize to RevTime
midibend to PitchWheel

Now when you run some of the included Strudel scripts you can manually select a Fluid instrument to play the role. If you would like to control the choice of Fluid instrumet to associate with each layer in your script you can use Tidal's progNum control as seen here:

stack(
note("[C5,E5]@2 ~ ~")
//.progNum("4")
,
note("<[A2 B2@2 C3]@2 [B2 D3 C3@2]*2>") 
.progNum("<0 4 12 16 20>/6")
,
s("bd ~ sd cp")
)
.delay(-1).room(-1)
.osc();

Note that the Fluid project can respond to the percussion and instruments. Since Dexed doesn't implement the General MIDI standard your results for these sounds will be undefined. As stated at the outset, you can instantiate multiple Tidal nodes and set them up to be "tuned" to a MIDI channel or an orbit. It's easy to imagine all sorts of combinations to produce the orchestra of your choice.

One additional caveat for external synthesis. Each instrument has its own notions with respect to gain and stereo. For this reason it's impractical to provide a single example that works across multiple instruments with the same Strudel script. The only practical workflow entails constructing Strudel scripts tuned to particular instrument setups. It would be wise to note this in the comments of your scripts.


Right-click to copy this example-pack to your workspace.

home .. topics .. interface .. reference .. examples .. tipjar