MIDI hardware timing devices

List, Christopher Chris.List at sc.siemens.com
Tue Apr 20 21:39:15 CEST 1999


This is a common problem with software sequencers as well as your average OS
doesn't allow you to set interrupts at the uSec level, and even if it could,
you still wouldn't be able to set your sequencer accurately to .01 bpms. So
how's it done? 

Basically you use a FIXED timer interval for all BPMs. You then use a
counter that sort of maintains an average for the tick timing. One tick
might be a little fast, another a little slow, but over the long-term, they
all come out right. The way I do it is to pick some fixed "rollover value",
based on the number of ticks/beat you want, the frequency of your
interrupts, and the resolution of the BPMs you want. Then at each timer
interval, I add the BPM number (shifted left to make it a whole integer, so
136.08 bpm = 13608) to the counter. If the counter is above the rollover
value, I perform a "real" clock tick and at the same time, subtract the
rollover value from the counter.

For example, take the following code snippet where the BPM Resolution would
be 100 if I wanted .01 resolution and 10 if I want 0.1, and "PPQ" is "Parts
per quarternote", or midi ticks:

// 				(# of Milliseconds / Minute) *
BPM_RESOLUTION 
// ROLLOVER = 	---------------------------------------------
//				         TimerResolution(in ms) * PPQ

// ROLLOVER = (60000 * BPM_Res) / (Timer_Res * PPQ)

const UINT BPM_RES = 100;	 // Timing resolution in ms.
const UINT PPQ = 48;	 // Timing resolution in ms.
const UINT TIMER_RESOLUTION = 1;	 // Timing resolution in ms.

#define TIMER_ROLLOVER 125000	// Roll over value, when the accumulator
(that gets
					// incremented every RESOLUTION ms)
reaches this value,
					// we process a clock tick.

...Now, this will only work if my timer interrupt period is 1ms. Let's say
I've set my BPM to 133.50. My stored BPM is 13350. Everytime an interrupt
occurs (every ms) I add 13350 to an accumulator. On the 10th ms, the
accumulator will go from 120150 to 133500, so I issue a tick, and roll my
accumulator back to 8500 (subtract the rollover value). Now it'll only take
9ms before the next rollover, because we aren't starting from 0! Sometimes
it'll be every 9ms between ticks, sometimes 10. Note that in a perfect
world, at 133.5 bpm and 48ppq, a tick would occur every 9.363ms or so... 

Note that this scheme is not my own. Note also that it helps if the timerres
* PPQ divides evenly in 60000! 

- Hope that helps,
CList



> -----Original Message-----
> From:	Marc-Julien Objois [SMTP:marc.objois at home.com]
> Sent:	Monday, April 19, 1999 7:43 PM
> To:	synth-diy at mailhost.bpa.nl
> Subject:	MIDI hardware timing devices
> 
> Hi there.  I'm new to the list.  I posted this message to a less 'tech'
> mailing list and was informed of synth-diy.  I'm a recent Computer
> Engineering graduate from the University of Alberta, and I enjoy making
> a variety styles of Electronic music.  I'm interested in doing design
> (I've come to love microcontroller programming in assembler and C as
> well as UI design) for a living, but I haven't started dropping resumés
> yet.  But enough about me...
> 
> I need to talk to some gurus...  I was just wondering how timing is
> achieved in MIDI hardware.  For my step sequencer (microcontroller
> project course) I used the PIT (programmable interval timer) built into
> the MMC2001 microprocessor (based on Motorola's M.CORE RISC core).  The
> rate of the timer was 8192 clock cycles per second.  I had it
> interrupting at intervals of 32X per step, and decrementing "note off"
> counters to provide a reference for turning notes off (so you can set a
> gate time for a note, but the granularity is pretty big: 1/32 of a
> step!)
> 
> I think that sucks...  There's got to be a better way of providing
> timing.  The whole reason for using such a large granularity was because
> the useful range of PIT speeds was limited.  For the faster bpm's, I was
> setting the timer to values around 27, which give values like:
> 
> 26: 147.7 bpm
> 27: 142.2 bpm
> 28: 137.1 bpm
> 
> So going from one PIT value to another would produce relatively large
> jumps in bpm, and there was no way of setting it to accurate bpm
> values.  So how is timing achieved in _real_ hardware?  What does the
> A3k do to playback a sequence?  BTW, I never even _touched_ MIDI
> timecode.  And active sensing?  Well, I threw that out the window before
> it even got to my MIDI queue...  :)
> 
> Anyhow, anybody want to discuss this with me?  Thanks.



More information about the Synth-diy mailing list