Monday, March 23, 2015

Note looper/recorder/player multiscript for Kontakt

This is probably pointless exercise, because it is what people use sequencers for, but I made an attempt at writing a script which would record and playback incoming note sequences in Kontakt. I was aiming at something that would allow me to record sequences while playing and then switch through them from keyboard. I took it to a point where I'm able to jam with it, e.g. trigger different drum loops and bass loops while playing another instrument. Feel free to try it out.

DOWNLOAD HERE
DOWNLOAD revision C
These are script preset files, they need to be uncompressed to multiscript preset folder (in my Windows it's "my documents\Native Instruments\Kontakt 4\presets\multiscripts"). This is multiscript, so you load it on top of some instruments. It has been written in Kontakt 4.2.4.

Update: revision C scripts should fix incompatibility with midi controllers, which use zero velocity note on command instead of note off command. Also midi learn function, may be a bit more bulletproof in this version and key cluster tape change automation functionality is fixed for reel 2. Rev C pack contains x2 and x4 versions.

It is an experiment and it is possible, it may have some bugs, so be cautious with it. I don't have the drive for bulletproof testing of this script, so take it as it is, maybe you will find it useful, but have in mind that it may go south at some point.

Note, if you re-save the preset, all recorded sequences will be saved within the preset, so you can easily make sequence sets.

A little guide to the script.

The script will memorize incoming note on and note off messages (no other MIDI data is processed) and then play back the sequence on request.
There are two versions of the script "x1" is a kind of one track recorder and "x2" has two tracks, so you can playback two sequences simultaneously.
Press record to start recording, which actually starts on first incoming note (the gap before pressing record button and receiving first note is ignored). When done press record again to stop the recording, or press play to stop recording and start playback right away. If loop switch is on, recorded sequence will play in a loop, else it will stop after last note. If auto rewind switch is on, the recorded sequence will start from beginning, when you press play button, else it will start from where it stopped.
There are 8 "tapes" per reel, so you can record up to 8 sequences which you can switch through while playing. If play button is on, tape will not change immediately, but it will be scheduled. After coming to the end of currently playing sequence, the machine will load selected sequence. This way you can switch loops "in advance". Each tape can store up to 2040 events, so a bit more than 1000 notes. If the limit is reached, the recording should stop automatically.
Play, record and tape change commands can be automated with midi keyboard. Note, that key used for automation will be unavailable for triggering notes. Tape change command has three automation modes, you can use CC message, a series of 8 keys, where pressing a key will load corresponding tape, or use one key to toggle through tapes. In last mode there is option named "select empty", when the switch is off, the machine will only toggle through recorded sequences, skipping empty tapes (as selecting empty tape will stop playback).
Snap is function, which will try to align recorded sequences to current tempo. When it's activated, the machine will wait for sync when starting to play the sequence, on play button or when restarting a loop. There is no synchronization in between, so this machine is not suitable to playback whole songs, better stick to 1-6 measure loops. So, e.g., if you pick snap resolution to whole note in 4/4 meter, have snap switches enabled and press play, the sequence will start at beginning of next measure.
Synchronize is function which will attempt to recalculate recorded times to fit a recording to different tempo. This is somewhat tricky, as the machine memorize events like this: note on, wait some thousands milliseconds, note off, etc. At the moment of recording, the quarter note length is stored, which is then being compared to current quarter note length and used to recalculate waiting times throughout the recording. Tempo changes while recording are not stored.
Key setting is simple transpose function, it will add key value to note numbers on playback.
Input port and channel settings can be used to pick a source of data, in case you have multiple controllers. "x2" version of the script has simple data router, so you can switch instruments while playing/recording. Changing channel/port can be automated with a key or CC.
There are somewhat limited "sequencing" options in Kontakt multiscript, so I made this script using "wait" command together with, $KSP_TIMER and $DISTANCE_BAR_START variables (first to detect event times, second to sync with tempo). The second variable is only being updated in Kontakt when transport is running, so synchronization will fail, if the play button is off in host. In standalone mode, it will always work, as Kontakt assumes transport is always on.

Feel free to write me, if you find it usable, yet limited or bugged in some aspect. I may look into it again.

11 comments:

  1. Hey, i love this script.

    I've been using the default NI Looper and MidiBits script too sometimes, but yours are far better! A lot more easy to configure for instant ideas while keeping a simple workflow.

    Some bug i've found: learn function don't works for Rec/Play keys setting, and when i set it by note number works but don't keeps Rec or Play button pressed, i need to keep it pressed all time.
    Otherwise i just press de GUI buttons with mouse. But using the midi controller would be good, you know.
    Maybe the problem are Kontakt 5, i read that it was writen for 4.2.4.

    ____
    Feature requests:

    Please make a x4(or more) Reel Script!!
    Now i'm loading a second script aside and works, but switching 1st and 2nd scripts while playing to manage loops it's a headache.
    A single GUI with 4 or more reels would be more easy.


    Another feature would be to be capable of set Play button with midi keys on same channel for different reels, independently.
    So you could play/record on one Reel/Midi Channel but start playing another Reels using keys on same channel.
    Now you can only push setted/learned(bugged) Play key on same Reel channel that plays and switch to another channel/Reel to Play another Reel. A lot of work that breaks the workflow.

    MidiBits script can do that. But it's difficult to work with.

    Your aproach are far more easy with this script.

    Thanks.

    ReplyDelete
    Replies
    1. Hi,

      I think you have one of these midi controllers which use note on message with zero velocity instead of a note off message. I didn't think of supporting them when writing the script (none of my controllers work this way, so I tend to forget about them). The script actually waits for a note off message in learn function, as I thought it would be more natural for it to react when releasing the key. So that would explain why it doesn't work for you. I'll try to fix it when I get time. Meanwhile I wrote a simple script which converts a zero velocity note on message to a note off message, if you insert it before reel script, it should fix learn function and you will not have to hold the key to keep a reel playing.

      here's the script:

      {----------}
      on init
      set_script_title("note on zero converter")
      message(" ")
      end on

      on midi_in
      if($MIDI_COMMAND = $MIDI_COMMAND_NOTE_ON and $MIDI_BYTE_1 = 0)
      ignore_midi
      set_midi($MIDI_CHANNEL,$MIDI_COMMAND_NOTE_OFF,$MIDI_BYTE_1,100)
      message("midi command converted")
      end if
      end on
      {----------}

      I wasn't able to test it, as I have no such controller, but it's so simple it should just work. It will message "midi command converted", if the problem is what I think it is.

      You should be able to "set Play button with midi keys on same channel for different reels", I am. Maybe it's the matter of configuring input channel settings? I'm not sure what is the nature of the problem. What you cannot do is to use the same key for two functions, eg. press play for both reels. I'll see if I can fix it.

      Delete
    2. Thanks for reply.

      I can't apply this new script, hangs red colour on 'on midi_in' and don't let me load it. :/

      __
      Yes, i was need to configure the Input Channel settings and now works, thanks. I didn't thought it before.

      But the problem of not 'latching'(aka keep pressed) the Rec/Play buttons stills.
      Only works using the mouse not the midi key (static switch vs trigger).

      Delete
    3. Uhm, and i did look on midi monitor and when releasing a key indicates: Note-Off - Velocity N/A.
      Don't know if it helps you. :)

      Delete
    4. The small script is multicript too, put it on top of instrument in a slot before reel script.

      Delete
    5. Ok, new script loaded, but doesn't works. :/
      Still same problem, won't learn, just muting the sound and that's it.
      Don't know if it's working, midi monitor after new script don't shows any change at all.

      Delete
    6. Being on the hurry never helps, sorry but indeed the small script is wrong too, it should of course look at MIDI byte 2...

      if($MIDI_COMMAND = $MIDI_COMMAND_NOTE_ON and $MIDI_BYTE_2 = 0)

      Which doesn't matter, as I rewrote parts of the 2x script, which should now be compatible with your controller. Here:
      http://www.fairlyconfusing.net/docs/midi_reel_x2B.zip

      I'll see, if I get time to compile 4x version.

      Delete
    7. Please add quantized 'Snap' Recording too. Now it's just for playback. But are difficult to start recording perfect some loops.

      Delete
    8. There's x4 version now, see downloads in the post. Also fixed key cluster automation.
      Quantizing live input would be difficult and confusing, it would require some kind of buffering and delaying incoming notes. I'm not up for it, not for this script.

      Delete
    9. OK. Thanks anyway. This is fantastic! :D

      Delete