I use ableton live for my solo ambient projects, but my new combo Mithril are 2 vocals and myself on acoustic, so I wanted a simple, practical looper option. I had previously used a line 6 M13 (too big/limited) and an M9 (which I broke while trying to replace the micro-switches!). Finally, I persuaded myself (and my wife) that a Line 6 HX effects would fit the bill. After shopping around, I found one at £358, well below the typical street price, so I bought one.
The pedal is quite amazing and really well thought through in terms of usability. Plus, it has midi control, which I’ve used to overcome the main limitation of a one-pedal looper, that of stopping by double click. It may be my age, but when I’m recording a live loop, I find double tapping throws my timing out. Or at least, I feel it does! Since I’m getting handy at building midi projects using the arduino chip, I built myself a small pedal to plug into the HX midi in socket.
Whilst I could assign any looper controls to a pedal (except, infuriatingly, a “clear loop” command), I kept it basic, with a pedal for “stop” and another for “play”. I added LEDs (colour matched to the pedal light!) and it works faultlessly. It’s powered via USB, so needs suitable power socket handy.
I then extended the code to that switching “play” on also switched FS3 on, set to add a little dirt for solos. Pressing stop switches off both the loop and the boost.
Here’s a fritzing of the layout
and here’s the arduino code, for those in the know 😉
// midi controller for line 6 M9 to control looper - solo OD
// apr 19
#include <MIDI.h>
#include <midi_Defs.h>
#include <midi_Message.h>
#include <midi_Namespace.h>
#include <midi_Settings.h>
MIDI_CREATE_DEFAULT_INSTANCE();
// Constants
#define SWITCH1 3 // play
#define SWITCH2 2 // stop
#define SWITCHES 2 // how many switches?
# define LED1 5 // channel 1
# define LED2 4 // channel 2
int thisLed = 0;
int switches[SWITCHES] = { SWITCH1, SWITCH2 };
int switchState[SWITCHES] = { LOW, LOW }; // Initial state of switch
int leds[SWITCHES] = { LED1, LED2 };
int currentSwitch = 0;
int play = 0; // state or recording
unsigned long SwitchMillis = 0; // when button was released
unsigned long DebounceMillis = 20; //
unsigned long CurrentMillis = 0;
void setup()
{
MIDI.begin(1);
// Setup Switches and activation LEDs
for ( currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++ )
{
pinMode( switches[currentSwitch], INPUT ); // Set pin for switch
digitalWrite( switches[currentSwitch], HIGH ); // Turn on internal pullup
pinMode( leds[currentSwitch], OUTPUT );
digitalWrite( leds[currentSwitch], HIGH );
}
intro();
}
void loop()
{
CurrentMillis = millis(); // get the time at the start of this loop()
if (CurrentMillis - SwitchMillis >= DebounceMillis) //is it time to check the switches?
{
SwitchMillis = millis(); //re-initilize Timer
for ( currentSwitch = 0; currentSwitch < SWITCHES; currentSwitch++ )
{
if ( (digitalRead(switches[currentSwitch]) != switchState[currentSwitch] ) && (switchState[currentSwitch] == HIGH) )
{
switch ( currentSwitch )
{
case 0: // play
{
MIDI.sendControlChange(61, 127, 1); // play
delay(200); // slow down commands so the HX doesn't crash!
MIDI.sendControlChange(51, 127, 1); // FS3
digitalWrite( leds[0], HIGH );
digitalWrite( leds[1], LOW );
play = 1;
}
break;
case 1: // stop
{
MIDI.sendControlChange(61, 0, 1); // stop
if (play)
{
delay(200); // slow down commands so the HX doesn't crash!
MIDI.sendControlChange(51, 127, 1); // FS3
play = 0;
}
digitalWrite( leds[1], HIGH );
digitalWrite( leds[0], LOW );
}
break;
}
} // end if changed
switchState[currentSwitch] = digitalRead( switches[currentSwitch] );
} // go thru switches
} // end check switches
} // end loop
void intro () // startup flashes
{
for ( int i = 0; i < 6; i++ ) // startup flashes
{
for ( thisLed = 0; thisLed < SWITCHES; thisLed++ )
{
digitalWrite( leds[thisLed], LOW );
delay(160);
digitalWrite( leds[thisLed], HIGH );
}
}
}