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
Paused
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:
Paused
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
Over-ride the default ~/midiloop/ Directory (and also the environment variable $MIDILOOP_DIR, if that's set).
Connect the Input from ALSA-MIDI client Keyst:1
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.
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
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.
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.
Because the user-interface of midiloop uses the midi-keyboard, it can also be controlled by computer-generated midi files. This allows loops to be composed using eg: muscript. The -m option makes this easier.
midiloop -m -k 88 or midiloop -m -k 49 output a set of variable-definitions for use as a header within muscript files, see www.pjb.com.au/muscript/variables.html
If a filename is given after the -m then its contents are output after the header. Eg:
midiloop -m /tmp/myloop | muscript -midi | aplaymidi -p midiloop -
$CMD
is the ModeChangeKey, which toggles in and out
of Command-Mode
Within Command-Mode, the main commands are: $PAUSE
$REC
$NEWMUTES
$NEWLOOPS
$GOTOLOOPS
$SAVE
and $QUIT
The numbers 0..15 are: $K0
$K1
$K2
$K3
$K4
$K5
$K6
$K7
$K8
$K9
$K10
$K11
$K12
$K13
$K14
and $K15
The binary keys are: $YES
and $NO
See
www.pjb.com.au/midi/free/loop_1
and
www.pjb.com.au/midi/free/rubycon_1_390s
for examples of such a file.
The author tends to keep these files in
~/midiloop/src/
Remember the commands $CMD
and $PAUSE
are
toggles. Unlike a real human, muscript can't see what the
screen is saying, so when working in muscript don't lose
track of which mode it's in ! Also other commands have a dialogue
which changes with circumstances; for example $GOTOLOOPS
will not ask "Go to which Loopset" if there's only
one other Loopset.
Remember also that only one channel can be Recorded at one time, so
muscript resources such as cha1+2
will not work
as intended.
To diagnose such problems it helps to play your file at much-reduced speed
so you have time to follow the dialogue, and see at what point it goes wrong.
midiloop is available at www.pjb.com.au/midi/free/midiloop
It uses the MIDI::ALSA module which is available at search.cpan.org/perldoc?MIDI::ALSA
muscript is available at www.pjb.com.au/muscript/muscript
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
Peter J Billam, http://www.pjb.com.au/comp/contact.html
www.pjb.com.au/
www.pjb.com.au/midi/
www.pjb.com.au/midi/midiloop.html
search.cpan.org/perldoc?MIDI::ALSA
www.pjb.com.au/comp/lua/midialsa.html#input
www.pjb.com.au/muscript/index.html
www.pjb.com.au/muscript/variables.html
Midiloop with rabbit and mt2, as well as just cycle.
Midiloop with a "this is the ending" Loopset,
which doesn't loop
A Loopset might also display comments, even if they have to be set
by vi ~/midiloop/whatever.dump