fastest/most accurate way to trigger sounds (drum sequencer)

Hi All,

I’m looking to make a drum machine app on the ipad 2.
I’m triggering drum hits (wav files under 20k) in a sequence using timer.performWithDelay but am experiencing inconsistent timing on the actual device (timing is perfect in the simulator).

My understanding is that audio.loadSound will fully load the sample into memory thus enabling immediate playback when needed.

I’m guessing the audio trigger is causing the irregular lag but could it be that the timer itself varies in speed? is it framerate or system timer dependent?

I’m wondering if there are any tricks for a super stable timer or a way to trigger audio faster.

Here is a simplified version of the code I’m currently using:

[code]kick = audio.loadSound(“bd.wav”)

local sequencer = function(event)

if(play==1) then
Channel,BD = audio.play(kick, {channel=1,loops = 0})
end
end

seqTimer = timer.performWithDelay(100,sequencer ,-1)
[/code]

Thanks in advance for any tips!
Alex [import]uid: 66618 topic_id: 20420 reply_id: 320420[/import]

On iOS, the code you have should be pretty fast and there isn’t really much you can do to make it faster. My suspicion is that the timer is drifting. I don’t think the timer system is terribly accurate and is related to the framerate as you suggested.

I don’t really have any good suggestions for you, but perhaps other users may have some ideas. My only idea is you might use enterFrame and try to track the current time directly to see if it is time to play (within a margin of error).
[import]uid: 7563 topic_id: 20420 reply_id: 79996[/import]

Hi Ewing,

I tried every approach I could come up with ranging from reading the system clock on frame entry to looping prerecorded sequences of drum hits and modulating the volume to imitate re-triggering but the lag persists. It’s definitely a timer issue.

After further research it seems that even experienced programmers are having the same problem using the NStimer in pure Xcode.:

http://stackoverflow.com/questions/907137/how-to-program-a-real-time-accurate-audio-sequencer-on-the-iphone

The solution seems to be running the audio sequencing in a separate processing thread which sounds a little involved. Does corona enable this? maybe something for the road map?

Quoted:
"NSTimer has absolutely no guarantees on when it fires. It schedules itself for a fire time on the runloop, and when the runloop gets around to timers, it sees if any of the timers are past-due. If so, it runs their selectors. Excellent for a wide variety of tasks; useless for this one.

Step one here is that you need to move audio processing to its own thread and get off the UI thread. For timing, you can build your own timing engine using normal C approaches, but I’d start by looking at CAAnimation and especially CAMediaTiming."

Cheers
Alex

[import]uid: 66618 topic_id: 20420 reply_id: 80071[/import]

I’ve been trying to create a rhythm game with the SDK and so far these are some of my findings and deductions.

Assuming the timer delay is an enterframe runtime listener that checks the amount of time passed each time a frame is processed, the only way it could trigger a listener is to check which timer has expired and execute as required. Due to unreliable device frame rates, there is a possibility of one frame taking up more time than the next.

In fact if you were to print the amount of time that has passed in the simulator using an enterframe listener, you’d realise they vary between 24ms to 40. So you are working with a minute error of roughly 15-20ms.

Now if we were to implement this on an actual device, I expect the frame rates to vary on a more frequent basis. I’ve managed to get pretty consistent timings by declaring all my timer delays at the same time which means the time trigger will be executed only relative to the time of declaration.Occasional frame glitches do kill the rhythm but it’s become less of a problem.

Now if we were to consider your code which is to have a timer loop every 100ms. I am not sure how the actual SDK code is done but I presume it declares a new timer right after the current one expires. So each of your subsequent beat is executed relative to the previous timing, which could easily create a snowball error effect.

Just some of my thoughts, hope it helped. [import]uid: 108204 topic_id: 20420 reply_id: 80148[/import]

Just a quick note to share my experience making a rhythm based game: I found it impossible to create rock solid timing with Corona. Interestingly, some temps work better than others, which probably has to do with the 30fps or 60fps nature of Corona and the way it’s event architecture works. [import]uid: 70134 topic_id: 20420 reply_id: 80166[/import]

Thanks for your tips and insight!
I might Have to try lowering the beat resolution to 8ths instead of 16ths - less noticeable drifting.
It might be an idea to run at a lower framerate to give the processor some headroom
I ll let you know how that works

Cheers
Alex [import]uid: 66618 topic_id: 20420 reply_id: 80282[/import]

Hi Gary,

Thanks for the insightful post, I can’t wait to try this.
Good to know there are others on the same boat with a need to time accuracy.

It would certainly revive a lot of projects I have sitting in the attic

Cheers
Alex [import]uid: 66618 topic_id: 20420 reply_id: 85308[/import]

Alex, see my thread here on anchoring to a perfect pulse provided by calculating with float point math off of the system timer value at the point the beat sequence started. The trick is to keep calculating off the original timer value at sequence start, using float point math- which Lua uses without us even asking :slight_smile: Then we wait for the calculated time of the next beat to pass, and trigger it.

Here is some test code that demonstrates this: http://developer.anscamobile.com/forum/2011/08/15/drum-toy-0#comment-84062

The sad part is, although the pulse we are trying to anchor each beat to is now rock solid-- as solid as the processor clock itself-- and will never waver… the beats themselves often trigger a few milliseconds late in varying amounts: it’s a bit like having wavering bait tied in perfectly spaced intervals to a fishing line with atomic precision. If you can see what I mean :wink:

It would be nice if we could trigger simple audio and simple video events at the highest stable granularity. 60fps, or every 16.7 milliseconds, is not high enough granularity for music-based apps. This should be especially possible when not much else display- or listener-wise is going on, as would be the case in metronome and beat sequencer type apps.

Thanks for your consideration!

I have a slick metronome app right now with some groundbreaking features, but the issue of the wavering beats anchored to the perfect pulse is really getting me down :frowning:

Please, Ansca , throw all of us a bone that need precision for music apps!

Cheers,

Gary [import]uid: 106887 topic_id: 20420 reply_id: 85249[/import]

You are most welcome Alex!

As I mention here in my reply to Peach on the Drum Toy thread, http://developer.anscamobile.com/forum/2011/08/15/drum-toy-0#comment-85323 it would be super if we could just schedule the mix-in of our samples into a 44100 samples per second audio buffer at a specific sample value.

E.g. say the tempo we want is 97bpm. To have a sound trigger exactly 6 beats after the audio buffer begins playing, we could ask the system to schedule to mix our audio sample into the stream at sample number 44100*60 / 97 (which gives us a beat length of 27278.350515463917525773195876289 samples) TIMES six.

So we’d simply schedule the mix in of our audio sample at sample number 163670 (the previous float point number TIMES six, then rounded down to the nearest integer). And so on. The trick is to keep using the float point math to calculate forwards from sample 0 to know exactly where to place the beats in the audio stream. Then voila, we’d have what some metronomic products call sub-sample accurate tempo (due to our clever math).

Anyhow… I really hope that Ansca pays attention to this stuff. Because some very cool things could happen with some very cool music apps if they do. And we all know that high quality music apps generate a lot of money in the App Store. What do you think, Carlos?

Cheers,

Gary [import]uid: 106887 topic_id: 20420 reply_id: 85329[/import]

In my experience, low quality music apps can generate a moderate amount of money too :smiley: [import]uid: 66618 topic_id: 20420 reply_id: 85337[/import]

FYI, I posted a response in the other thread:
http://developer.anscamobile.com/forum/2011/08/15/drum-toy-0#comment-85700 [import]uid: 7563 topic_id: 20420 reply_id: 85740[/import]