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.
Or, read on for the full story.
A bit of history
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.
- 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 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.
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 first 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.