tidal-midi-0.9.9: MIDI support for tidal

Safe Haskell None Haskell98

Sound.Tidal.MIDI.Tetra

Description

Mapping and Abstractions for the analog four-voice synthesizer, TETR4 by Dave Smith Instruments.

Rather than being a tutorial on how to write your own mappings for your MIDI devices, this is more like the kitchen sink: it shows what is possible.

The DSI TETR4 has four separate voices that can (when set to multi-mode) be controlled via four different MIDI channels. Almost everything you can control directly on the device can be automated via MIDI messages.

Synopsis

# Documentation

The controller mapping for TETR4

To get the most out of this device with tidal, I chose to use the non-registered parameter (NRPN) variant to control it. This allows to use the full spectrum for controls like cutoff that allow more granular stepping than standard MIDI (164 instead of 128 steps).

Many parameters diverge from the default ranges of 0 to 127 and therefore this mapping uses the mapRange functionality for controls to allow you to always use double params, e.g.:

>>> t1 $n (run 4) # famt "0.5" # cutoff "0.3" # resonance "0.8"  while famt, cutoff and resonance all have different ranges of operation (0..254, 0..14 and 0..127 respectively) Some parameters are essentially mode switches and I chose to pass the values you enter into patterns directly through to the resulting control change. The method passThru on control specification simply skips the scaling of values (you can write your own scaler if you want). For very generic control I reused Tidal's own params, like cutoff, attack, gain, pan and release. Sometimes the defaults for Tidal do not make sense for MIDI. See (_, cutoff_p) below the actual controller shape for examples on how to deal with this. Abstractions Though not yet finished, these are some examples on how to combine multiple parameters into one single function you can use within your patterns. Since Tidal 0.7 you can use the grp method to allow things like: >>> t1$ n (run 4) # adsr "0.1:0.6:0.3:0.9 0.8:0.3:0.9:0.1"


which alternates between two filter envelope shapes, the first one with a sharp attack and a long decay/release and the latter with a long attack, high sustain and a short release.

lrate :: (Num b, Ord b, Functor f) => f b -> f b Source #

A hack to handle a param with completely different behavior for certain parts of the range:

lrate is limited from 0 to 150 and specifies values that will produce an lfo frequency

lstep however is essentially limited from 0 to 16 and specifies values that will produce rhythmic lfo based on the _sequence speed_. as taken from the manual:

0: 32 steps 1: 16 steps 2: 8 steps 3: 6 steps 4: 4 steps 5: 3 steps 6: 2 steps 7: 1.5 steps 8: 1 step 9: 2/3 steps 10: 1/2 step 11: 1/3 step 12: 1/4 step 13: 1/6 step 14: 1/8 step 15: 1/16 step

lstep :: (Num b, Ord b, Functor f) => f b -> f b Source #

Modulation

named sources and destinations to able to refer them for lfos, mods and also sequences.

Presets suck, but I constantly forget how to make drums with the TETR4, so here are some defaults (that can mostly be changed when using them) to make a snare and a kick.

Use the snare like this:

>>> t1 $n "0(3,8)" # snare  To make it shorter: >>> t1$ n "0(3,8)" # snare |-| release "0.1" |-| decay "0.1"


usage would be:

>>> t1 $n "0 [[0 1] 1]" # kick  you can change the defaults by applying merge operations for certain params: >>> t1$ n "0(3,8)" # kick |+| edcy "0.05"


will give the kick more resonance

>>> t1 \$ n "0(3,8)" # kick |-| edcy "0.15"


will make it really dry

Since the TETR4 lacks a high-pass filter, things like snares and especially cymbals are somewhat limited to filtered noise which sounds okish.

Therefore some presets for the different types of sounds you can get from the TETR4 can come in handy and can also be combined and modified with and through others:

A chip tune like sound, reminds me of gameboys