midisox - a SoX-like workalike, for handling MIDI files
> midisox [global-options] \ [format-options] infile1 [[format-options] infile2] ... \ [format-options] outfile \ [effect [effect-options]] ... > sox chorus.wav chorus.wav mid8.wav chorus.wav out.wav > play out.wav > midisox chorus.mid chorus.mid mid8.mid chorus.mid out.mid > aplaymidi out.mid > midisox -M bass.mid pno.mid -v 1.1 horns.mid soar.mid verse.mid > midisox -M bass.mid pno.mid voice.mid - | aplaymidi - > midisox -M http://mid.com/drms.mid pno.mid voice.mid -d > muscript -midi chords | midisox -M - bass.mid -d > muscript -midi chords | midisox - -n stat > midisox -M "|midisox chords.mid - pitch -200" solo.mid out.mid > midisox impro.mid riff.mid trim 37.2 3.4 > midisox --help ; midisox --help-effect=all
Midisox is a tool for working on MIDI files, with a calling interface modelled, as far as possible, on that of SoX, which is a well-established tool for working on audio files.
Midisox standardises all its files to a tick-rate of 1000 ticks/sec. This makes it possible to mix them together. But it does make it hard to load them into music-typesetting software afterwards and have the beats recognised. . .
Midisox is available in three versions, one in Python3, one in Perl and one in Lua.
Show version number and Helpful usage information
Show usage information on the specified effect (or "all").
Prompt before overwriting an existing file.
Select the input file combining method; -m means mix, -M merge. If the mix combining method is selected (with -m) then two or more input files must be given and will all be mixed together into one MIDI-track. A mixed file cannot be un-mixed.
If the merge combining method is selected (with -M), then the merged file contains all of the MIDI-tracks from all of the input files; un-merging is possible using multiple invocations of midisox with the mixer effect. The merging process attempts to avoid channel-conflicts by renumbering channels in the later files as necessary (however, a total of only fifteen MIDI-channels is available).
The default is sequence.
Displays the version number.
There is only one file-format-option available:
Adjusts the volume (specifically, the velocity parameter of all the notes) by a factor of FACTOR. A factor less than 1 decreases the volume; greater than 1 increases it.
Adjusts the velocity of all notes closer to (or away from) 100.
If the gradient parameter is
0 every note gets volume 100,
if it is
1.0 there is no effect,
if it is greater than 1.0 there is expansion,
and if it is negative the loud notes become soft and the soft notes loud.
The default value is
Individual channels can be given individual gradients.
The syntax of this effect is not the same as its SoX equivalent.
Adds echoing to the audio. Each delay decay pair gives the
delay in milliseconds and the decay of that echo. Gain-in
and gain-out are ignored, they are there for compatibilty with SoX.
The echo effect triples the number of channels in the MIDI, so
doesn't work well if there are more than 5 channels initially.
echo 1 1 240 0.6 450 0.3
For a more elaborately configurable echo effect, see midiecho
Adds a fade effect to the beginning, end, or both of the MIDI. Fade-ins start from the beginning and ramp the volume (specifically, the velocity parameter of all the notes) from zero to full, over fade-in-length seconds. Specify 0 seconds if no fade-in is wanted.
For fade-outs, the MIDI will be truncated at stop-time, and the volume will be ramped from full down to zero starting at fade-out-length seconds before the stop-time. If fade-out-length is not specified, it defaults to the same value as fade-in-length. No fade-out is performed if stop-time is not specified. If the stop-time is specified as 0, it will be set to the end of the MIDI. Times are specified in seconds: ss.frac
Changes the key (i.e. pitch but not tempo). This is just an alias for the pitch effect.
Reduces the number of MIDI channels, by selecting just some of them
and combining these (if necessary) into one track.
The channel parameters are the channel-numbers 0 ... 15,
mixer 9 selects just the drumkit.
If an optional to_channel is specified, the selected
channel will be remapped to the to_channel; for example,
will select just channel 3 and renumber it to channel 1.
If a channel number begins with a minus (including
then that channel will be suppressed, and the others transmitted.
The syntax of this effect is not the same as its SoX equivalent.
Pads the MIDI with silence, at the beginning, the end, or at specified
points within the file. Both length and position are specified in
seconds. length is the amount of silence to insert,
and position the position at which to insert it.
Any number of lengths and positions may be specified, provided
that each specified position is not less that the previous one.
position is optional for the first and last lengths specified,
and if omitted they correspond to the beginning and end respectively.
pad 2 2 adds two seconds of
silence at each end, whilst
inserts 2.5 seconds of silence 3 minutes into the MIDI.
If silence is wanted only at the end, specify a zero-length pad at the start.
Pans all the MIDI-channels from one side to another. The direction is a value from -1 to 1; -1 represents far-left and 1 represents far-right.
Changes the pitch (i.e. key but not tempo). shift gives the pitch-shift, as positive or negative "cents" (i.e. 100ths of a semitone). However, currently all pitch-shifts get rounded to the nearest 100 cents, i.e. to the nearest semitone. Individual channels (0..15) can be given individual shifts.
Adjusts the beginnings of all the notes to be a multiple of
length seconds since the previous note.
If the length is greater than
30 then it is considered
to be in milliseconds.
Channels for which length is zero do not get quantised.
quantise and quantize are synonyms.
This is a MIDI-related effect, and is not present in Sox.
Repeat the entire MIDI count times. Note that repeating one time doubles the length: the original MIDI plus the one repeat.
Does a statistical check on the MIDI, and prints results on stderr.
This sox-compatible behaviour means if you want to grep the output, you redirect stderr, e.g.:
midisox mix3.mid -n stat 2>&1 | grep patch_changes_by_track
midisox mix3.mid -n stat 2>&1 | grep nticks
The MIDI is passed unmodified through the processing chain.
The -freq option calculates the input's MIDI-pitch-spectrum (60 = middle-C) and prints it to stderr before the rest of the stats.
Changes the tempo (but not the pitch). factor gives the ratio of new tempo to the old tempo. So if factor > 1.0, then the MIDI will be speeded up.
Outputs only the segment of the file starting at start seconds, and ending length seconds later, or at the end if length is not specified. To preserve instruments, however, the latest patch-setting event in each channel is preserved, even if it occurred before the start of the segment.
Adjusts the volume (velocity) of all notes by a fixed increment. If increment is -15 every note has its velocity reduced by fifteen, if it is 0 there is no effect, if it is +10 the velocity is increased by ten. Individual channels can be given individual adjustments. The syntax of this effect is not the same as its SoX equivalent.
The current version of midisox_py is available by http at
To install midisox, save it to disc, move it into your $PATH, make it executable, and if necessary edit the first line to reflect where python3 is installed on your system. You will also need to install the MIDI.py and TermClui.py modules in your $PYTHONPATH.
The current version of midisox_pl is available by http at
To install it, save it to disc, rename it midisox, move it into your $PATH, make it executable, and if necessary edit the first line to reflect where perl is installed on your system. You will also need to install the MIDI-Perl and Term::Clui and LWP::Simple CPAN modules.
The current version of midisox_lua is available by http at
To install it, save it to disc, rename it midisox, move it into your $PATH, make it executable, and if necessary edit the first line to reflect where lua is installed on your system. You will also need to install the MIDI.lua module and the luaposix module. Fetching URLs as input files is believed to work either with the freepops-luacurl module, or with the luacurl module. The Lua version runs considerably faster than the Python or Perl versions.
These files are all on gitlab and can be downloaded by:
git clone https://gitlab.com/peterbillam/miditools
5.6, 20170917, Lua version: fix missing table.maxn in lua5.3
5.5, 20130507, All versions: in the quantise effect channels can be given individual lengths
5.4, 20130321, All versions: bug fixed in the quantise effect
5.3, 20120626, All versions: compand effect default_gradient is 0.5 not 0.0
5.2, 20111224, All versions: in the pitch effect channels can be given individual shifts
5.1, 20111219, All versions: the vol effect is introduced
5.0, 20111201, All versions: the compand effect and the quantise effect are introduced, and the mixer effect will accept negative channels
4.9, 20110922, All versions: fade with stop_time == 0 fades at end of file
4.8, 20110910, Lua version fixes reading from pipes
4.7, 20110710, Perl version opus2score() interprets note_on with vol=0 as a note_off and terminates unended notes at the end of the track
4.6, 20110111, Lua version fixes an emtpy-string-is-true bug in gm_on_already
4.5, 20101026, Lua version stat -freq works
4.4, 20101021, Lua version function wget() uses luacurl to get URLs
4.3, 20100926, Python3 version bug fixed appending to tuple in mixer()
4.2, 20100910, Python3 version fade effect handles absent params
4.1, 20100802, bug fixed in the Python3 midisox, in the mixer effect
4.0, 20100306, bug fixed in the pan effect
3.9, 20100203, the pitch effect as synonym for key
3.8, 20091128, fetches any valid URL as an input file
3.7, 20091127, "|cmd" pipe-style input files
3.6, 20091113, -d pseudo-output-file plays through aplaymidi
3.5, 20091112, pad shifts from 0 ticks, and stat output tidied
3.4, 20091107, the mixer effect does channel-remapping e.g. 3:1
3.3, 20091021, warns about mixing GM on and GM off or bank-select
3.2, 20091018, stat -freq detects the screen width
3.1, 20091018, does the pan effect
3.0, 20091018, stat effect gets the -freq option
2.9, 20091015, does the mixer effect
2.8, 20091014, echo channels are panned alternately right and left
2.7, 20091014, does the echo effect
2.6, 20091013, does the key effect
2.5, 20091013, midi2ms_score not opus2ms_score
2.4, 20091012, uses midi2ms_score
2.3, 20091011, fixed infinite loop in pad() at the end
2.2, 20091010, to_millisecs() must now be called on the opus
2.1, 20091010, stat effect sorted, and more complete
2.0, 20091010, vol_mul() improves defensiveness and clarity
1.9, 20091010, the fade effect fades-out correctly
1.8, 20091010, does the fade effect, and trim works with one arg
1.7, 20091009, will read from - (i.e. stdin)
1.6, 20091009, does the repeat effect
1.5, 20091008, does -h, --help and --help-effect=NAME
1.4, 20091007, does the pad effect
1.3, 20091007, does the tempo effect
1.2, 20091007, will write to - (i.e. stdout), and does trim
1.1, 20091006, does sequence, concatenate and stat
1.0, 20091003, first working version, does merge and mix
Peter J Billam www.pjb.com.au/comp/contact.html
search.cpan.org/perldoc?LWP::Simple (in the libwww-perl package)