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.

8 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.

1 Like

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

1 Like

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.