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 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/
andtunes/
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 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.
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.
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.
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.