tempomap

A MIDI sequencer program is the commonest way of working on standard midifiles, but it has limitations when you have a freely-recorded piece where notes don't line up with beats and bars on the screen. If you have a habit of recording live midi without the aid of a metronome, this little command-line utility may be a great help towards tidying it up in a sequencer afterward. It provides a convenient way of adjusting beat and tempo to clean up roughness in the original.

The idea is that you start with a freely-recorded multitrack ('format 1') midifile, and add a 'click track' that corresponds to the actual beats in the recording, rather than any rhythm either you or the sequencer think ought to be there. You then run the enhanced file through tempomap, and the result will have event timing adjusted so that the clicks exactly match beats and bars shown by a sequencer (or a program that processes the file in other ways such as 'midi2abc'). The file won't sound any different when played back, because tempo changes have been added to compensate for the adjusted event ticks, but you can then delete or modify the tempo events as necessary to smooth the output to your liking.

Exactly how you generate the click track is up to you. You might do it directly in the sequencer, by finding the notes that correspond to beats and adding clicks at those points, or by copying the melody track, say, and deleting all notes not on a beat (the program only looks for note-on events, and doesn't care about pitch or velocity, so anything will do as a 'click'). This is likely to be a very tedious — even impossible — method, though, if the piece is at all complex.

Much more simply, but a bit less accurately, you can just add the clicks with your MIDI keyboard (or drumkit, or...) as you play back the piece. Probably the best approach is a combination: record the clicks first, and then edit them in the sequencer to match the actual notes.

By default, tempomap expects one click per quarter-note beat, but this may be hard to achieve if you're using the live input approach. However you can use any other steady rhythm that's convenient, such as one click every two beats, or even one beat per bar. Precision is reduced, but will be perfectly good for most purposes.

Details

The program is invoked from the command-line, and expects as an argument a format-1 standard midifile with an included extra 'click-track'. Some option arguments precede this to control its exact behaviour. (See the section below for these.)

The click-track should contain note events that match, as closely as possible, the actual beat points in the recorded piece, however irregular these are. No other note events should be present in the track. By default, the clicks should occur on every (quarter-note) beat, but you can use any other regular interval (2, 3, 4, etc. beats per click) and set the 'beats-per-click' command line option appropriately.

The output of the program is a midifile equivalent to the input — containing all the original events — but with the tick-count assigned to each event adjusted so every click falls exactly on a beat division. With appropriate command-line options, they will match up to the bar lines shown by a sequencer as well. Tempo events are simultaneously inserted to compensate for the changes in ticks, so it will sound exactly like the original when played back.

With this file back in your sequencer, you can remove all or some of these added tempo changes, or adjust them, to fix the rhythm to your liking. Removing all tempo events — except the first, of course — will give you a clockwork-steady rhythm (at least as far as the clicks are concerned!). As bar lines should now match the intended rhythm, it should also be easier to tweak individual notes in the other tracks to their proper place. As a final step, no doubt, you will want to remove the click track again for the end product.

More specifically, tempos are assigned as follows. The interval between the first two clicks is used to calculate the initial tempo, which is inserted at time zero and maintained until the moment of the second click. A new tempo for this point is then computed from the second/third click interval, and so on. If clicks end before the piece does, the last tempo is maintained for the rest of the file. There should be no interruption within the sequence of clicks, though, or tempo assignments will go very wrong.

Tick counts are computed for each event after all the tempo events have been inserted. The first click will be forced onto a bar line (given correct option settings), and all subsequent events will be suitably moved to maintain their alignment. Channel events before the first click will be moved the same amount to keep their timing relative to the click, but non-channel events (system and meta) that are in the file before the first channel event found will not be advanced, because the sequencer may be using them for setup. If they appear after that point, they are assumed to be linked to other events (lyrics perhaps) and are moved in the same way.

The program numbers the tracks in a midifile from zero, even if your sequencer labels them starting from one. Remember that conventionally a Format-1 midifile uses the first ("Conductor" or "Master") track — "track 0" here — for all tempo events, and for other global 'events' such as the time signature setting. The track is normally never used for any note or other performance events; this is not enforced, but a sequencer is likely to expect it. tempomap actually doesn't care; it will always insert tempo events into track 0, but doesn't interfere with any other events that happen to be there (except to adjust their ticks), so you could even use it for the click track if there was some reason to.

Provided that you have used the right 'beats-per-tick' and beats-in-bar' command options (see below), the first click will be aligned on a bar line. If the click is not originally at tick 0, at least one 'lead-in' bar will be inserted before it so that there is space for any preceding notes in other tracks.

Command Line

The basic command line form (using a keyword-type argument) is:

tempomap --click-track <n> [<options>] <filename.mid>
The last argument — the name of the file to be processed, of course — and the click-track are required, but the latter may also be given in short form as "-cn". Other arguments are optional, in either keyword or short form, but either an output filename or replacement must be present.

Available option arguments (shown as "--keyword-form|-short-form") are:

--click-track|-c n
Specify the track n in the file (starting from 0) where the clicks will be found. [Required]
--out|-o filename
Specify the file to which the adjusted events will be written. [Either this or the next option must be present]
--replace|-r
Specify that the input file is to be overwritten. (Not reversible! Don't use it unless you're sure...) [Either this or the previous option must be present]
--beats-per-click|-b n
The number of quarter-note beats in each click period. The default is one beat per click if this option is not given.
--beats-in-bar|-n n
The number of quarter-note beats in a bar. It is used to determine the alignment of the first bar and click, and should be set to match the time signature of the piece. The actual time signature in the file, though, is neither read nor modified by the program. The default setting is 4 if the option is not present.

As an example, suppose you have a freely-recorded midifile in 3/4 time, "roughwaltz.mid", with four tracks — one master-track 0 and music tracks 1..3. You play this through your sequencer while using your MIDI keyboard to add clicks to a further track ('4'), one per bar, on the downbeat. [As much as possible!] You might then want to fiddle with the clicks so that they are better aligned with the actual melody. Once you are satisfied, feed it to tempomap with a command like:

tempomap -c4 -b3 -n3 -o waltzwithbeats.mid roughwaltz.mid
So that it reads click-track 4, with 3 beats per click, and 3 beats per bar. When you bring the new file into the sequencer, the clicks will be on the sequencer's bar lines, and you can more clearly see the music's structure. Then edit away, removing tempo changes to smooth the rhythm, shifting notes to the correct place in the bar, and so on.

History

This application was originally conceived and written by "Div" (David) Slobin. (Its original name was "Tempo-map"; I have removed the hyphen for brevity.) He states that it was "Inspired by the "fit to improvisation" feature in Cakewalk". It actually is part of a suite of command-line applications for MIDI, but the others were not so useful to me, so they aren't included here. See the link below if you are interested in them.

I found his version invaluable in sorting out an ancient early attempt at multitrack recording (on the Amiga!) that I rather liked despite its flaws. It did, however, lack some features that I would have liked to have (such as not having clicks always equivalent to quarter-notes), so I embarked on this enhanced version.

I also made minor changes to Div's original basic MIDI-handling library. I fixed one small bug (if you referenced a track that didn't exist, it might 'wrap around' rather than creating a new one) and added output of running status by default. The revised source is included here.

None of the code uses any platform-specific features, so it should compile and run under any OS.

Related Links

You can find all Div's original utilities on his website.

Original author: dgslomin (at) alumni (dot) princeton (dot) edu

Extensions by Pete Goodeve (pete (dot) goodeve (at) computer (dot) org)

Licence

This utility is free and open source, provided under terms of the BSD licence. Specifically:

© Copyright 1998-2006 David G. Slomin, all rights reserved.
Extensions © Copyright 2010 Peter J. Goodeve.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.