Tidaling on Elektron Machines

I know that some of you are already making use of some Elektron machines in their sets and music. I'm still in the process of discovering my Digitakt and thought about opening a topic to gather some tips about their usage and inclusion in a live-coding setup.

To start the discussion with something, here is a "mostly" complete mapping of the Digitakt:

let parameter pat value = ccn (inhabit [
                                -- trig parameters
                                ("mute", 94), ("track-level", 95), 
                                ("note", 3), ("velocity", 4), 
                                ("length", 5), ("filter-trig", 13), 
                                ("LFO-trig", 14), 
                                -- source parameters
                                ("tune", 16), ("play-mode", 17), 
                                ("bit-reduction", 18), ("sample-slot", 19), 
                                ("start", 20), ("length", 21), 
                                ("loop-position", 22), ("sample-level", 23), 
                                -- filter parameters
                                ("filter-freq", 74), ("resonance", 75), 
                                ("filter-type", 76), ("filter-attack", 70), 
                                ("filter-decay", 71), ("filter-sustain)", 72), 
                                ("filter-release)", 73), ("filter-env-depth", 77), 
                                ("filter-env-delay", 86), ("filter-base", 84), 
                                ("filter-width", 85), 
                                -- amp parameters
                                ("attack", 78), ("hold", 79), 
                                ("decay", 80), ("overdrive", 81), 
                                ("delay", 82), ("reverb", 83), 
                                ("pan", 10), ("volume", 7), 
                                -- lfo 1 parameters
                                ("lfo-speed", 102), ("lfo-multiplier", 103),
                                ("lfo-fade", 104), ("lfo-destination", 105),
                                ("lfo-waveform", 106), ("lfo-start-phase", 107),
                                ("lfo-trig-mode", 108), ("lfo-depth", 109),
                                -- lfo 2 parameters
                                ("lfo2-speed", 112), ("lfo2-multiplier", 113),
                                ("lfo2-fade", 114), ("lfo2-destination", 115),
                                ("lfo2-waveform", 116), ("lfo2-start-phase", 117),
                                ("lfo2-trig-mode", 118), ("lfo2-depth", 119),
                                -- fx parameters (delay)
                                ("delay-time", 85), ("pingpong", 86),
                                ("delay-stereo-width", 87), ("delay-feedback", 88),
                                ("delay-highpass-filter", 89), ("delay-lowpass-filter)", 90),
                                ("delay-reverb)", 91), ("delay-mix", 92),
                                -- fx parameters (reverb)
                                ("reverb-predelay", 24), ("reverb-decay", 25),
                                ("reverb-shelving-freq", 26), ("reverb-shelving-gain", 27),
                                ("reverb-highpass-filter", 28), ("reverb-lowpass-filter", 29),
                                ("reverb-comp", 30), ("reverb-mix", 31),
                                -- fx parameters (compressor)
                                ("comp-threshold", 111), ("comp-attack", 112),
                                ("comp-releas", 113), ("comp-makeup", 114),
                                ("comp-volume", 119), ("comp-ratio", 115),
                                ("comp-sidechain-source", 116), ("comp-sidechain-filter", 117),
                                ("comp-mix", 118)] pat) # ccv value


-- demo pattern
d3 
    $ fast 4
    $ cat [n "0(2,4)",  n "0(3,4)"]
    # s "digitakt" # midichan 0
    # stack [parameter "sample-slot" (irand 40),
             parameter "tune" (irand 127),
             parameter "reverb" 127,
             parameter "filter-freq" (irand 120)]

I'm having fun switching between different patterns and sculpting kits this way. Each pattern using its own sounds or a variation of the previous kit/pattern. Tidal for sequencing purposes only.

EDIT: actually, the MIDI implementation is much more complex than I thought at first. There are some MIDI CC MSB/LSB details to take into consideration to do a proper mapping of the Digi- family and I suppose that it is the same for all the Elektron machines.

9 Likes

Digitakt - Tidal user here. A thing I've been meaning to get around to! Thank you for doing the work! Looking forward to playing with this later.

1 Like

we should start a topic about mapping tidal to various MIDI devices. it would be cool to add something like that to the documentation. it would encourage more people to experiment w/ it. maybe we should also have some consensus about the naming of the parameters ? or maybe just keeping them as similar as the MIDI device as possible.

3 Likes

yes, absolutely, in the last days I was tickling a Roland TR505 and a Boss DR550, had some hard time trying to figure out what n or drum value were needed. Maybe something like external modules to be included as need?

I agree. We can open a topic if you want and list all the machines currently mapped by the community. I have planned to map the Digitone this evening if I can find time for that. It should be pretty much the same thing. I can also map the Minilogue XD and some Korg boxes. Some synths doesn't have any internal CC mapping (Neutron being an example).

I think that it will not be possible for many things outside of simple substractive synthesis or drum processors. Some envelopes, filters and parameters only make sense in their relation to another part of the hardware architecture. I prefer to stick to "as written in the manual" in order to make everything as explicit as possible.

It can look cumbersome to write long parameter names but there are some advantages:

  • I will forget what an alias really do 5 minutes after writing it down.
  • you can always use auto-completion for summoning things with long names.
  • readability when opening a file 6 months later.
  • people will always alias on their side if they can / want.
1 Like

What is inhabit? Don't find it in tidalcyces.org. Found something via hoogle. Is that it?

hey! i store my tidal -> rytm related files in this repo:

it is midi only though, as i've replaced superdirt & supercollider with a separate tidalrytm program to send midi out. but perhaps it could run alongside SC..?

i haven't tried it with other hardware but i think the tidalrytm program is pretty device-agnostic, as all of the midi mapping happens in BootTidal.hs.

3 Likes

Wow! That's really impressive. Very nice work, much better than my lazy midi mapping that doesn't take the details into account. I suppose that it is also really easy to tweak for the DT, DN and basically every other machine. I have a few questions for you:

  • Why have you chosen to reimplement your own MIDI backend?
  • Did you ever tried running it along regular Tidal and SuperDirt?

thanks! some of the stuff in BootTidal.hs is a little strange right now, i'm kind of figuring it out as i'm using it.

anyway as for your questions:

  • i couldn't really get the midi mapping to feel how i wanted it to. in my mind, a midi CC change should work the same way as effects do. the problem is that superdirt only expects one midi CCN & CCV pair per OSC message from tidal. i wanted to fork superdirt to try and change this, but it's kind of beyond me. there are some ways around the limit with stacks, but they're always quite verbose and get in the way of just writing code (at least the ways i explored were)! also, when i'm using the rytm i don't ever use superdirt to play samples, so i thought why not just replace it with something else. it's also a good excuse to try and make some software!

  • nope! but if you add whatever is in tidalrytm's BootTidal.hs to a regular one, and add give superdirt and tidalrytm separate osc streams it'll probably work

Hi all! Great thread. I own a Model:Cycles and I found these couple functions very useful:

  1. mc [...]: receives a list of patterns and sends them in order to the six M:C channels
  2. mamps [...]: sets the input gains of messages sent to these channels (again, in order).
    • ma/mamp <n> <value>: sets the input gain of messages sent to channel <n> to <value>
-- Model:Cycles
:{
let mc pats = p "cycles"
      $ stack
      $ zipWith (\idx pat -> pat # amp (cF 0.5 $ "m" ++ (show idx)++ "amp")) [0..]
      $ zipWith (\cycleschannel pat -> pat # s "mc" # midichan cycleschannel) [0, 1, 2, 3, 4, 5] pats
        cyclesDecayTime value = ccn 80 # ccv (value |* 125)
    cyclesColor     value = ccn 16 # ccv (value |* 125)
    cyclesShape     value = ccn 17 # ccv (value |* 125)
    cyclesSweep     value = ccn 18 # ccv (value |* 125)
    open = cyclesDecayTime
    mamp idx value = setF ("m" ++ (show idx) ++ "amp") value
    mamps amps = mapM_ (\(v,i) -> mamp i v) $ zip (take 6 $ amps ++ repeat 0) [0..5]
    mampall = mamp . repeat
    ma = mamp
:}

Alternatively, you can declare each channel as a different instrument as such:

:{
let mcTrack n time pat = xfadeIn ("cycles" ++ show n) time $ pat # s "mc" # midichan n
    m1' = mcTrack 0
    m2' = mcTrack 1
    m3' = mcTrack 2
    m4' = mcTrack 3
    m5' = mcTrack 4
    m6' = mcTrack 5
    m1 pat = do
      m1' 0.01 pat
      m1' 0.01 pat
    m2 pat = do
      m2' 0.01 pat
      m2' 0.01 pat
    m3 pat = do
      m3' 0.01 pat
      m3' 0.01 pat
    m4 pat = do
      m4' 0.01 pat
      m4' 0.01 pat
    m5 pat = do
      m5' 0.01 pat
      m5' 0.01 pat
    m6 pat = do
      m6' 0.01 pat
      m6' 0.01 pat
:}

Though I find the first option more convenient. I did implement some other stuff like receiving values from the cycles but I'll go through it later

2 Likes

On the Analog RYTM I think there is only one param that requires MSB and LSB to be sorted out. I've otherwise only had to deal with MSB for all the params I use.

Reopening the topic because I think that Elektron machines and Tidal are quite close in philosophy and design, and some ideas might easily be ported/reimplemented from one realm to the other. In particular, I would like to know if people were able to emulate/reproduce the behavior of live recording on the Octatrack, and I'm sure that some clever people here have done it already, maybe without knowing about it.

The idea is to have an audio buffer that can be written and read from in real time as a basis for live-looping quantized buffers of sound. It allows people to record quantized loops of external sources and mangle them live (repitching, slicing, per step effects and parameters), etc... As soon as the buffer is filled, you can start exploring applying pattern transformations to the sound, switch to another live buffer, etc...

Has anyone been able to reproduce something like this? I think it would be very fruitful for melodic improvisations on synths while keeping Tidal as a master clock and patterning mastermind. It could open the road for less rythmical and more sound design oriented performances on Tidal.

See "looper.scd" in the "hacks" directory of SuperDirt, it's from a few years ago but I think it still works.

2 Likes

Hello everybody!
Maybe someone can help me with the following problem.... I have been learning to use the Analog Rytm Mk2 with Tidal and so far I have been able to control all the parameters through midi CC (Thanks @kindohm Kingdohm for those wonderful tutorials) The only thing I can't get to work is controlling the velocity.... I see that on the machine the parameter moves but this does not affect the sound. It's probably a very simple solution but I've been trying for days. Thank you very much!!!

@diegonoguerab you mean you are controlling the velocity through MIDI CC to affect the track's Velocity parameter?

Instead, the RYTM should automatically handle the amp or gain param coming from Tidal, and you shouldn't have to change the RYTM's velocity control through MIDI CC.

d1 $ amp "0.25 0.5 0.75 1" # s "rytm" # midichan 0 # note "c3

If you are trying to change the track's velocity param through MIDI CC, I believe the specific note velocity coming from the amp or gain param would override it. And I believe Tidal will automatically send a default gain value on every note, so that might be why it doesn't appear to ever sound different (because Tidal is always setting the velocity per note).

Thank you very much for your reply.
Indeed with "amp" it works perfect. I saw in your tutorials that you used the "Gain" parameter to achieve this, but when I use it, there is no effect on the sound. Do you have any idea why "gain" may not work?
Thanks again.