(:damion @world-state)

freelance software architect. artist. radio ham.


Setting the T-Rex Replica's Delay Tempo


categories:   clojure guitar audioengineering

Intro

I was doing some tracking with a guitarist in my home studio the other day and we were laying down some overdubs using the T-Rex Replica delay pedal. He wanted to sync the tempo to a subdivision of the songs BPM, but had to do this manually. I noticed a MIDI in port on the side of the pedal, and thought surely there must be a way to set the tempo programatically.

It turns out that the pedal doesn’t listen to MIDI clock, but just acts as another source for a tap tempo. Luckily, this is quite easy to implement in software, so I created a simple command line utility where you can specify a tempo in BPM and it will sync the Replica by sending two taps.

Code

The full code can be found on my GitHub page for the trex-replica-tempo project.

The program is pretty simple. We’re just using javax.sound.midi classes to grab all Midi devices, and then create a CONTROL_CHANGE message on CC20, as specified in the T-Rex documentation.

The get-midi-devices provides a name to map mapping of Midi devices. The :device key in the map contains the useful javax.sound.midi.MidiDevice class for sending CC messages.

(defn get-midi-devices
  "Returns a list of hashes with info about the midi devices available."
  []
  (reduce
    (fn [m device]
      (assoc m (.getName device)
               {:name        (.getName device)
                :vendor      (.getVendor device)
                :version     (.getVersion device)
                :description (.getDescription device)
                :device      (. MidiSystem getMidiDevice device)}))
    {}
    (. MidiSystem getMidiDeviceInfo)))

The program boils down to merely sending two CONTROL_CHANGE messages to our selected device, with a timed delay:

(.send (.getReceiver device) (ShortMessage. ShortMessage/CONTROL_CHANGE 0 20 0) -1)
(Thread/sleep (bpm-sleep bpm))
(.send (.getReceiver device) (ShortMessage. ShortMessage/CONTROL_CHANGE 0 20 0) -1)

The bpm-sleep function provides the number of milliseconds between beats for the specified BPM:

(defn bpm-sleep
  "Returns how many ms to sleep between beats given `bpm`."
  [bpm]
  (/ 1000 (/ bpm 60)))

Running

Just in case a non Clojurian would happen to be interested in running this utility, and to make my life easier during future tracking sessions, I used clojure.tools.cli uberjar to make it easy to run anywhere Java is installed.

You can download a pre-packaged jar file here:

replica-bpm.jar

Command line help options:

java -jar replica-bpm.jar -h
T-Rex Tap Tempo over MIDI

Usage: java -jar replica-bpm.jar [options]

Example:
java -jar replica-bpm.jar -d MIDI -b 120

Options:
  -l, --list                List MIDI devices
  -d, --device DEVICE       Device name
  -b, --bpm BPM        120  Beats per minute
  -h, --help

List the Midi devices available:

java -jar replica-bpm.jar -l
The following MIDI devices are available:

Gervill : Software MIDI Synthesizer
MIDI : Pro40 MIDI
Real Time Sequencer : Software sequencer

Set the BPM to 146 using the Sapphire Pro 40 MIDI out:

java -jar target/replica-bpm.jar -d MIDI -b 146
Setting T-Rex Replica to 146 BPM.

I hope someone finds this utility useful! Either way, it was fun solving a simple, but real problem using Clojure!