midiloop - Makes multiple sets of multi-channel MIDI loops


 midiloop -i ProKeys -o MySynth  # use my 88-note keyboard,
 # on which 0..15 are mapped to notes treble D to e~ (midi 62 to 88)

 midiloop -i Keystation -k 49   # to use a 49-note keyboard, or
 midiloop -i Keystation -k 61   # to use a 61-note keyboard,
 # on which 0..15 are mapped to notes bass D to e~ (midi 38 to 64)

 midiloop -i Keystation -k 25   # use my 25-note keyboard,
 # on which 0..13 are mapped to notes bass c to treble B (midi 48 to 59)

 # Saved loopsets are expressed in Perl, the notes in MIDI::ALSA format
 midiloop -i Pro -l 201302_1452  # loads a previously saved loopset
 cd ~/midiloop ; ls -l           # inspect the saved loopsets
 perldoc MIDI::ALSA     # for the event format see the "input" function
 vi ~/midiloop/201502_1452.dump  # edit a loopset file (in Perl)

 # compose your loopsets in muscript:
 vi ~/mus/my_loop       # it's a muscript file
 midiloop -m ~/mus/my_loop | muscript -midi | aplaymidi -p midiloop -

 midiloop -v            # prints the version
 perldoc midiloop       # read the manual :-)


midiloop creates an ALSA-MIDI client, and records and replays sets of loops. There can be up to sixteen Loopsets. Each loopset can have up to sixteen midi-channels, each of which can be muted or unmuted.

Once midiloop is launched, all the user-interface is driven by the keys of the midi-keyboard (not the computer-keyboard). This leads to fast operation in a performance situation. The user-interface depends on the computer-screen being visible by the performer, because it tells you what the current status is and what your options are.

The top note of the keyboard switches you into and out of command-mode. All other data is entered using the numbers 0..15, which are mapped onto some of the white notes (see USER INTERFACE).

This also allows a whole set-up, with several loops and many channels, to be performed by notes in a standard midi-file (see the -m option).

Each loopset has a basic barlength in seconds, but each channel within that loopset can loop at an integer multiple (1..15) of that basic barlength. For example, the drums could loop at 1.8 seconds, but the bass could play a 3.6-second riff, and the organ could play a 7.2-second sequence.

All changes in what's being played (Play/Pause, Mute, Unmute, GotoMuting, GotoLoopset) take place not immediately but at the next barline. This means a midiloop performance never loses the beat.


The user-interface is built for speed during performance. Your data-input-device is the white keys on your midi-keyboard; midiloop's output-device is the computer-screen.

The top note on your (88-, 61-, 49- or 25-note) midi-keyboard toggles you into Command-mode. midiloop will respond immediately, telling you what the valid choices are, each choice having a number between 0 and 15.

The only other keys involved express those numbers 0 to 15. The mapping is the same as is used to express channel-numbers by (at least) M-Audio Keystation and ProKeys keyboards. (You may want to number those keys with little white-paper sticky labels.)

On an 88-note keyboard, 0..15 are treble D to e~ (midi 62 to 88)
On an 61-note or 49-note keyboard, 0..15 are bass D to e~ (midi 38 to 64). (The 61-note keyboard is assumed to have three treble octaves and two bass octaves, so that middle-C lies left-of-center.)
If you have to use a 25-note keyboard, the numbers 0..13 are mapped to white notes bass c to treble B (midi 48 to 59); that's all you need to enter the commands, but it restricts you to 0..13 in channels, loopsets and mutings.

Whenever you are asked for a number, midiloop displays a list of the available responses. Numbers not in this list will be ignored by midiloop. Whenever you are asked for confirmation, the numbers are (0,1), with 0 meaning No and 1 meaning Yes (as in C and Perl).

A couple of screenshots of midiloop's side of the dialogue:

 box8:tmp> midiloop -i Pro -o Rol -l hambone
 We are in Loopset 0  (we also have a Loopset 1)
 BarLength is 3.04 sec    We have Channels 0,1,2,3,9
 Mutings :  no mutings
   channel 0,   muted, 1 bars, patch 27 = Electric Guitar(clean)
   channel 1,   muted, 1 bars, patch 26 = Electric Guitar(jazz)
   channel 2, unmuted, 3 bars, patch 32 = Acoustic Bass
   channel 3,   muted, 2 bars, patch 18 = Rock Organ
   channel 9, unmuted, 5 bars, percussion

 Loaded file /home/pjb/midiloop/hambone.dump

 play treble c~~~ to enter command-mode

So then if we press c~~~ and enter command-mode, we get:

 We are in Loopset 0  (we also have a Loopset 1)
 BarLength is 3.04 sec    We have Channels 0,1,2,3,9
 Mutings :  no mutings
   channel 0,   muted, 1 bars, patch 27 = Electric Guitar(clean)
   channel 1,   muted, 1 bars, patch 26 = Electric Guitar(jazz)
   channel 2, unmuted, 3 bars, patch 32 = Acoustic Bass
   channel 3,   muted, 2 bars, patch 18 = Rock Organ
   channel 9, unmuted, 5 bars, percussion

  do what (0,1,2,3,4,6,9,10,11,12,13) ? 

 0=Pause,  1=Mute,  2=Unmute,  3=Record,  4=EraseChannel,  6=SaveMuting
 9=NewLoopset,  10=GotoLoopset,  11=SaveLoopsets,  12=LoadLoopsets,  13=Quit
 c~~~ to re-enter play-mode


-d ~/otherstuff/wierdgrooves/

Over-ride the default ~/midiloop/ Directory (and also the environment variable $MIDILOOP_DIR, if that's set).

-i Keyst:1

Connect the Input from ALSA-MIDI client Keyst:1

-k 49

Tells midiloop which size Keyboard you'll be using. The available values are 88, 61, 49 and 25. This affects the ModeChangeKey, which is the top note on the keyboard, and the keys entering the numbers 0 to 15, which on an 88-note keyboard are the white notes treble D to e~, and on an 49-note keyboard are two octaves lower, bass D to e~. These conventions are modelled on the Channel-entry keys used by M-Audio (counting channels 0..15 of course :-).

If no -k option is specified but a -i option has been provided, then midiloop checks if the number "49" occurs in its input-client name (eg: Keystation 49e), and if so sets up for a 49-note keyboard. Otherwise, the default is 88.

-l 20130214_1425

Loads the previously saved Loopset 20130214_1425.dump, probably from the user's ~/midiloop/ directory, though this can be over-ridden with the environment variable $MIDILOOP_DIR or with the -d option.

The Loopsets are saved in Perl Data::Dumper format, but with helpful added comments to tell you which Loopset, Channel and Bar you're in. The file can be edited with some care and a text-editor. As from version 3.5, the events are MIDI::Event events with times in milliseconds, as documented in perldoc MIDI::Event in the section on EVENTS.
(previously they were saved as MIDI::ALSA events, as documented in perldoc MIDI::ALSA in the section on the function input())

An example dump-file is: hambone.dump

-m muscriptfile.txt

This option does not start a midiloop. This option generates some header lines in Muscript format, prepended to muscriptfile.txt to allow it to be played into a running midiloop. If the filename is not present, just the header lines are output. See the USING MUSCRIPT section.

-o Syn

Connect the Output to ALSA-MIDI client Syn. The special value -o 0 tells midiloop not to connect to any other client. If the -o option is not specified, the default is the environment variable $ALSA_OUTPUT_PORTS


Print the Version



Invoked by the note (eg: D) corresponding to 0, this toggles between Pause-mode (which pauses all the channels) and Play-mode.


Invoked by the note (eg: E) corresponding to 1, this allows you to Mute any of the (currently unmuted) channels.


Invoked by the note (eg: F) corresponding to 2, this allows you to Unmute any of the (currently muted) channels.


Invoked by the note (eg: G) corresponding to 3, this allows you to Record a loop on the channel your MIDI-keyboard is currently set to. If that channel already exists, your new recording will overdub onto it; if that channel does not yet exist, the channel will be created.

If the current LoopSet still has no channels, you will be asked to choose a Barlength (in seconds). All channels in the LoopSet share this same Barlength. The choices are:
  0=1.00,   1=1.04,   2=1.08,   3=1.12,   4=1.16,   5=1.20,   6=1.26,   7=1.32,
  8=1.38,   9=1.44,   10=1.52,   11=1.60, 12=1.68,   13=1.76,   14=1.84,   15=1.92 seconds.
If you need a 2-second bar, you use two 1-second bars, and so on. (If you need finer graduations, you have to SaveLoopsets into a dump file, and edit it by hand.)

In any case, you will be asked to choose how many bars this channel's loop will last. (All channels in a LoopSet share a common BarLength, but their loops can last for different numbers of bars.) The choice 0 means a Free loop; the recording will terminate at the next barline after you press the ModeChangeKey.

You will be asked whether you want a Metronome. If it's a currently-empty LoopSet, you'll probably want to choose 1=Yes; but if there are already some recorded channels, you may want to choose 0=No. The Metronome is a guide only; it is not recorded.

Later, when you Mute or UnMute, or change LoopSets, the change will occur not instantly, but at the next barline. The Metronome will help you to lay down a loop which has its end-of-loop in a musically sensible place.


Invoked by the note (eg: A) corresponding to 4, this allows you to Erase any of the channels in the current LoopSet. Do this if, for example, you're not happy with what you just recorded. If there is more than one channel, you will be asked which channel. You will then be asked for confirmation.


Invoked by the note (eg: c) corresponding to 6, this creates a new Muting, and saves in it the current Muted/Unmuted state of all the channels. Each LoopSet can have up to 16 Mutings (0..15).


Invoked by the note (eg: d) corresponding to 7, this allows you to invoke any of your Mutings. The change takes place at the next Barline. If there is more than one other Muting, you will be asked which Muting.


Invoked by the note (eg: e) corresponding to 8, this allows you to Erase any of the Mutings (in in the current LoopSet). If there is more than one Muting, you will be asked which Muting.


Invoked by the note (eg: f) corresponding to 9, this creates a new, empty, LoopSet, then goes to it and enters Pause mode.


Invoked by the note (eg: g) corresponding to 10, this allows you to switch to any one of your LoopSets. If there is more than one other Loopset, you will be asked which Loopset.

GotoLoopset allows you change (at the next Barline) from one section of the piece (eg: the verse) to another (eg: the middle-8),


Invoked by the note (eg: a) corresponding to 11, this allows you to save all the LoopSets to a .dump file in ~/midiloop/

These files are in perl, and can be edited with your favourite text-editor and checked with perl -c

As from version 3.5, the data is in MIDI::Event format with times in milliseconds: see perldoc MIDI::Event in the section on EVENTS. (previously they were in MIDI::ALSA format: see perldoc MIDI::ALSA)

An example dump-file is: hambone.dump


Invoked by the note (eg: b) corresponding to 12, this gives you a choice of the most recent .dump files in ~/midiloop/

One .dump file can contain multiple LoopSets, each containing multiple Channels.

An example dump-file is: hambone.dump


Invoked by the note (eg: c~) corresponding to 13, this allows you to Quit from midiloop
You will be asked for confirmation with 1=Yes or 0=No.




 20150825 3.7 -o 0 option is respected as documented
 20150711 3.6 check for safe dumpfile syntax before executing
 20150707 3.5 Loopsets stored in scoreevent form, but loaded in either
 20150706 3.4 Recording with nbars = 0 means free-loop, terminates on CmdKey
 20150626 3.3 notes-off when exiting from Record; Muteset renamed Muting
 20150624 3.2 much finer choice of Barlengths
 20150623 3.1 Message disappears after 3 displays; various bugfixes
 20150622 3.0 SaveMuteset, GotoMuteset and EraseMuteset working
 20150621 2.9 61-key kbds as 49; 25-key ask_n uses white-notes 48 to 71
 20150618 2.8 LoadLoopsets only offered if dumpfiles exist
 20150618 2.7 LoadLoopsets command works
 20150617 2.6 introduced '-m filename'
 20150615 2.5 starts with no loopsets, needing a NewLoopset command
 20150614 2.4 many bugs fixed around NewLoopset and GotoLoopset
 20150608 2.3 autodetects detects 49-note keyboards
 20150605 2.2 handles -k 49; NOTEON vol=0 means OFF; EraseChannel; bugfixes
 20150604 2.1 Pedal no longer enters Command-mode; Erase Loopset bug fixed;
        NextLoopset entered immediately if Paused; screensaver disabled
 20130224 2.0 shorter varnames; @LoopChannels convenience-var eliminated
 20130223 1.9 each LoopChannel is a hashref
 20130222 1.8 each Loopset is a hashref
 20130221 1.7 LoadLoopsets corrects the channel if necessary
 20130209 1.6 Loopsets stored in NOTE-form; SaveLoopset much improved
 20130207 1.5 SaveLoopset works
 20130103 1.4 starting the change to Loopsets, BarLengths, NumBars
 20121024 1.3 overdubbing, muting, replacing any channel
 20120929 1.2 convert NOTEONs unterminated in the loop to NOTEs
 20120922 1.1 seems to respond correctly to the Pedal :-)
 20120909 1.0 forked from an old fade-based midiecho-like version