Meter Delta is a tool to help musicians improvise together in dynamic time signatures, chosen at random by the computer. Meter Delta itself is just a library to take care of the timings and time signature selection but I also provide a default UI that you can use directly, or as inspiration for your own project.
- Demo
- Meter Delta on GitHub (for source and docs)
Or, read on for the full story.
A bit of history
History is boring, give me the new stuff.
Back when I was at university I was in a band called Askuba. We played a lot of gigs for events in our college as well as various other balls and suchlike around Durham. It goes without saying we were the best band ever. One thing we used to do to spice up playing jazz standards was something we called "chord shouting" which entailed our pianist/singer (the inimitable) Theo Jackson picking chords at random and shouting them to the band as we improvised. A lot of the time this ended up sounding a bit weird but from time to time (especially after a bit of practice) we'd play something that sounded great, albeit unconventional.
I really enjoyed chord shouting but I've always been particularly interested in the rhythms in music and I wondered what the equivalent would be for time signatures in place of chords. At the time I had just embarked on my journey to become a programmer (by teaching myself a little PHP and JavaScript) and I decided to try and build an interface to enable this kind of rhythmic improvisation. There are three main requirements for such a tool:
- keep the group in time
- choose time signatures
- display the current and next time signature clearly
The first two points could be handled manually (you could imagine a conductor taking care of it) but I decided to write something to take care of all three points automatically.
I built a JavaScript tool to achieve it but I was let down by a mix of olden-days JavaScript timing and (mainly) my terrible programming. The resulting tool would quickly drift out of time and the experiment was a failure.
One day, years later, I was studying the code to an animation framework when I spotted something that hadn't occurred to me back when I was first grappling with programming. Rather than just delaying the next beat by some number of milliseconds it's far more reliable to target the exact millisecond that the beat is expected, using the actual current time. This is a technique that is used a lot and armed with this revelation I knew it would now be possible to create a dynamic time signature improvisation tool in JavaScript. Inevitably I didn't get around to doing so but now, spurred on by the excitement of having a new website and with my enthusiasm directed back towards music by @vihart's incredible twelve tones video (if you've read this far you should definitely watch that video), I decided the time had come.
Meter Delta
Meter Delta is a fairly simple piece of JavaScript that will run a timer in your browser and keep track of all the state required to handle the time signatures. Unless you're a web developer Meter Delta itself isn't very useful so I've included a basic user interface as well. This interface is just the bits and pieces I threw together for the demo page, but they'll serve as a good starting point for your own work if you do plan to integrate Meter Delta into your own work. For some people the demo page will be all you need, which is great! Just point your browser at it, maybe zoom the page in a bit to make it clearer, and get improvising.
The GitHub project is the best place to go to see the source and read the documentation on how to use the library but I guess I might as well chat about some of the pieces in it here.
Accurate timings
I mentioned that the first time I tried to build this it didn't work
because it kept coming out of time - the solution is incredibly
simple. Animations also require accurate timings (to keep the
animation consistent all the way through so it feels fluid and
realistic). Typically they solve it by targeting the next frame at
a specific time, rather than just saying the frame rate is x
and
thus the next frame must be y
milliseconds away.
Here's the relevant line:
var msToNextBeat = startTime + (beatCount * beatMs) - (+new Date);
When Meter Delta gets kicked off it stores the precise start time (all
the times are measured in milliseconds). It then keeps track of how
many beats we've had so far. Since we know the amount of time required
for each beat (from the tempo, which is given in beats per minute) we
can add the amount of time required to get to the next beat by
multiplying those two numbers. We then subtract the current date
(+new Date
is a shorthand for new Date().getTime()
which gets the
current time in milliseconds). This is our answer - the difference
between now and the time the next beat should occur. I'm better
with pictures than words:
start time now
| . . . .| .
->| |<- ^
1 beat's time next beat
----| <- start time
|----|----|----|----|----| <- start time + time for each beat
-----------------------------| <- so this is target time for next beat
-------------------------| <- time now
|---| <- target time - time now
Now you can clearly see that the answer we're after is the difference between the time now and the target time for the next beat.
Some TODOs
The main thing on my list is to actually use it with a group. I think with a bit of practice and some tweaking to get the settings just right, it could generate some really interesting music.
In terms of the programming, there are a few things I'd like to add:
- better metronome
- more flexibility with the time signatures
- consider beat groupings?
- switch the callbacks for events
Ideally the UI's metronome would be a bit more customisable, for example in allowing different sounds for new bars and new beats.
At the moment you can pass in your own time signatures so the second point is arguably already covered. It'd be nice to include this in the UI and ideally make it a little less clunky.
Beat groupings is a tricky one. Meter Delta deliberately doesn't make any assumptions about the beat groupings you'll be using (it doesn't click every 4 semiquavers in the x/16 bars, for example). The only way around this would be to include the groupings with the list of eligible time signatures. I think it would be worth building, but it'd make it rather more complex so perhaps I can make it an optional feature. On the other hand it would make the metronome a lot more useful. At the moment it can only do every beat or every bar. For x/16 bars clicking on every beat is impractical (since they happen quickly) so it's forced to only click on the bar changes. Clicking every beat on x/8 bars just about works at the default tempo but if this were increased it will begin to run into the same problem.
One for the programmers, I'd like to switch the callback style that
Meter Delta uses for a more flexible event approach. One problem with
the callbacks is that only one function can be registered at a time
for each action. By exposing an addEvent
interface developers using
Meter Delta are given a lot more freedom.
Thanks for reading this far!
If you try it out and find it useful, I'd love to hear about it. Holler at me on Twitter.
Once again,
- Working demo of Meter Delta
- Meter Delta on GitHub (for source and docs)