Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Drum Toy
Started by robbykilgore Aug 15 2011 08:49 AM

24 replies to this topic
[TOPIC CONTROLS]
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

robbykilgore

[GLOBAL: userInfoPane.html]
robbykilgore
  • Observer

  • 9 posts
  • Corona SDK











Yay! - I just submitted my latest app to the iTunes App Store. I was going to call it iGadd, but I thought that would be a little presumptuous. So in the end, I went for the more straight forward: Drum Toy 1.0
Drum Toy uses an admittedly weird drum machine architecture and concept. You create basic loops using Drum Toy's Every and Offset knobs, and then feather in the secret ingredient: Probability!

www.youtube.com/v/SXsLtHXegH8

In a way, Drum Toy 'thinks' the way drummers do. Find the pocket, lay down the main groove and sprinkle lightly with a few tasty fills or variations here and there to keep things fresh. Drum Toy is set up to force certain beats while leaving others to just the right amount of chance. This simple mechanism yields a surprising array of personality.

Drum Toy - the world's funkiest practice metronome. Coming soon to the iTunes App Store.
uid: 56133 topic_id: 13881 reply_id: 313881


[TOPIC: post.html]
#2

peach pellen

[GLOBAL: userInfoPane.html]
peach pellen
  • Corona Geek

  • 8,866 posts
  • Alumni

Really impressive stuff :D

I love seeing all the great games Corona users make but it's awesome to see non-game apps as well; it's great to remind everyone that we don't just make games ;)

Peach

PS - Nicely polished look, too!
uid: 52491 topic_id: 13881 reply_id: 51103


[TOPIC: post.html]
#3

robbykilgore

[GLOBAL: userInfoPane.html]
robbykilgore
  • Observer

  • 9 posts
  • Corona SDK

Thanks Peach. Nice of you to say.
Next version, I want to add alternate sounds and convert the channel strips to a class module so I can easily create patches with more than three sounds.
uid: 56133 topic_id: 13881 reply_id: 51184


[TOPIC: post.html]
#4

jmp909

[GLOBAL: userInfoPane.html]
jmp909
  • Corona Geek

  • 1,328 posts
  • Corona SDK

Hi,

good stuff! the timing on your demo seems quite tight. are you doing anything special to keep the audio in sync other than "audio.play" on a timer?

thanks
j
uid: 6645 topic_id: 13881 reply_id: 52322


[TOPIC: post.html]
#5

robbykilgore

[GLOBAL: userInfoPane.html]
robbykilgore
  • Observer

  • 9 posts
  • Corona SDK

I'm use an a listener on enterFrame(event). I compare (system time - the last frame's system time), and if it's greater than the number of ticks in a sixteenth, then I play the audio. Otherwise, I prepare the material for the next sixteenth.

The problem with Corona in this regard is the max frame resolution is 60fps, so there's a limit. I haven't figured out a way to get every tempo, only certain ones where the sixteenth value falls within a fifteen tick range. So you'll notice that the tempo goes from 94, 98, 102, 108...(I'm making these up, but you get the idea) I haven't figured out a way to get better tempo resolutions.

But Corona is so fast to code in, and I wanted something I could play along with that would do this, so it was a quick and dirty hack that turned out to be very usable and useful.

I'm hoping in the future Ansca will provide a midi API so i can control other devices and perhaps tighter access to the audio buffers or clock cycles so I can improve the resolution without having to recode everything in objC.

Of course - If anyone knows any tricks that I can use to optimize the algorithm, that would also be greatly appreciated.
uid: 56133 topic_id: 13881 reply_id: 52525


[TOPIC: post.html]
#6

brasstech

[GLOBAL: userInfoPane.html]
brasstech
  • Observer

  • 15 posts
  • Guests

great thanks for the reply.

i've discussed this sort of thing here http://developer.anscamobile.com/forum/2010/12/21/timing-trouble and I think i put in a feature request somewhere, but I don't think it would happen for a while, especially given android audio issues

j
uid: 10744 topic_id: 13881 reply_id: 52530


[TOPIC: post.html]
#7

Sven.Lua

[GLOBAL: userInfoPane.html]
Sven.Lua
  • Contributor

  • 145 posts
  • Corona SDK

maybe the timers have better resolution than 1/60 second!?
could you provide some promo codes?
uid: 70114 topic_id: 13881 reply_id: 52532


[TOPIC: post.html]
#8

peach pellen

[GLOBAL: userInfoPane.html]
peach pellen
  • Corona Geek

  • 8,866 posts
  • Alumni

That's a freaking essay!

As it's almost 6am I'm not even going to attempt reading it tonight but I did have a skim and look forward to a proper read tomorrow.

Clearly a huge amount of effort went into it, I'm very impressed :)
uid: 52491 topic_id: 13881 reply_id: 85284


[TOPIC: post.html]
#9

Gary Duke

[GLOBAL: userInfoPane.html]
Gary Duke
  • Enthusiast

  • 37 posts
  • Corona SDK

I have a solution to your problem!

This allows you to play in sync with any tempo-- even fractional tempos. I've used the technique on much less powerful hardware and it's worked perfectly with no drift of tempo (tempo never goes out of phase to use a more technical terminology).

What you were doing "wrong" was to compare the current system time to the timestamp of the last beat. This is because the last beat will always be a little "off" for several big reasons I can go into in another post.

Instead, you should be always calculating forward, with high precision floating point math, from the system time at which the play button was originally pressed and triggering the code for the next beat when the current system time passes the value of the system time when play button was pressed PLUS tempo_in_milliseconds TIMES beat_number.

So you'll need some variables (lua will automatically type float point variables where they are needed, so don't worry about this):

1. one to store when the play button was pressed, we'll call this "time_started".

2. the other variable we'll use to calculate the system time we have to wait for to play the next beat at, lets call it "next_beat"

3. to keep track of which beat number we're on we can introduce a third variable, "counter" that counts the beats and initialize it to "1"

4, and finally we'll need a variable that stores the tempo in milliseconds between beats, "tempoMS", which we'll initialize to 600000/tempo
where tempo is whatever bpm value you wish, e.g. 97

Now after calulating tempoMS by the formula 600000/tempo what we'd have as a formula for the system time value of the any given beat is:

next_beat=time_started+(counter*tempoMS)

when that time has passed, we simply increment the counter and wait til the next beat.

Using the time_started value as our perfect anchor point (not the stamp of the last beat played which will be an imperfect anchor point), and using that to calculate forward in the way I just described your tempo will stay in phase and remain in perfect phase til the battery runs dead or the floating point math precision weakens by a tiny amount over time.

Now, the caveat with this method is that you need to check that some hiccup in the OS or program hasn't introduced a period of time which puts us behind by more than a beat... see the comment "--integrity check" in the code sample.

Now, to illustrate what I've been saying, try this code out that outputs to the console... first set the config.lua to output at 60fps:

application =
  {
      content =
      {
          fps = 60,
      },
  }


Now save this audio file I have on Dropbox.com, tick_44.wav, http://db.tt/5qkdbPQO to your project directory.

try this code in main.lua:


local tempo=95.5 -- a pretty wierd tempo, to illustrate my point :)
local tempoMS=60000/tempo/4 -- for 16ths at 95.5bpm we'll divide by 4... for normal quarter-note beats, remove the "/4" from the end of the line
 
local click = audio.loadSound("tick_44.wav")
local timestarted=system.getTimer()
local next_beat=timestarted+tempoMS

print ("tempoMS (beat length): "..tempoMS.."\n")
 
local counter=1;
 
local function checkBeat()
   local thetime = system.getTimer()
   if thetime>next_beat then
      audio.play(click)
      print ("only off target ticks by "..math.floor(thetime-next_beat).. "ms") --this is the amount of milliseconds we are off the perfect system time target that will never go out of phase
      print ("timestarted: "..timestarted.." thetime: "..thetime.." next_beat:"..next_beat.."\n")

      --Begin playback integrity check
      if thetime>next_beat+tempoMS then -- i.e. we are behind two beats because of some kind of overload
        print("OH NO! Tempo has gone out of phase due to an interruption in the runtime or perhaps the audio engine, etc")
        --playback could be halted here, too
      end 
      --End playback integrity check
 
      counter=counter+1
      next_beat=next_beat+tempoMS
      --the above line could also be expressed as next_beat=timestarted+(counter*tempoMS) to find the timing for a specific beat number, the number of which is represented here by "counter"
   end
end
 
 
Runtime:addEventListener("enterFrame",checkBeat) 
 
--timer.performWithDelay(1,checkBeat,0)  
--this should work better in theory, but doesn't. comment out the Runtime:... line above if you try this method over the enterFrame 
 

Outputs this to simulator:

Windows simulator build date: Dec  9 2011 @ 14:01:29
Copyright (C) 2009-2011  A n s c a ,  I n c .
        Version: 2.0.0
        Build: 2011.704
tempoMS (beat length): 157.06806282723

only off target ticks by 14ms
timestarted: 78 thetime: 250 next_beat:235.06806282723

only off target ticks by 13ms
timestarted: 78 thetime: 406 next_beat:392.13612565445

only off target ticks by 12ms
timestarted: 78 thetime: 562 next_beat:549.20418848168

only off target ticks by 11ms
timestarted: 78 thetime: 718 next_beat:706.2722513089

only off target ticks by 11ms
timestarted: 78 thetime: 875 next_beat:863.34031413613

only off target ticks by 10ms
timestarted: 78 thetime: 1031 next_beat:1020.4083769634

only off target ticks by 9ms
timestarted: 78 thetime: 1187 next_beat:1177.4764397906

only off target ticks by 8ms
timestarted: 78 thetime: 1343 next_beat:1334.5445026178

only off target ticks by 8ms
timestarted: 78 thetime: 1500 next_beat:1491.612565445

only off target ticks by 7ms
timestarted: 78 thetime: 1656 next_beat:1648.6806282723

only off target ticks by 6ms
timestarted: 78 thetime: 1812 next_beat:1805.7486910995

only off target ticks by 5ms
timestarted: 78 thetime: 1968 next_beat:1962.8167539267

only off target ticks by 5ms
timestarted: 78 thetime: 2125 next_beat:2119.8848167539

only off target ticks by 4ms
timestarted: 78 thetime: 2281 next_beat:2276.9528795812

only off target ticks by 2ms
timestarted: 78 thetime: 2437 next_beat:2434.0209424084

only off target ticks by 1ms
timestarted: 78 thetime: 2593 next_beat:2591.0890052356

only off target ticks by 1ms
timestarted: 78 thetime: 2750 next_beat:2748.1570680628

only off target ticks by 0ms
timestarted: 78 thetime: 2906 next_beat:2905.2251308901

only off target ticks by 15ms
timestarted: 78 thetime: 3078 next_beat:3062.2931937173

only off target ticks by 14ms
timestarted: 78 thetime: 3234 next_beat:3219.3612565445

only off target ticks by 13ms
timestarted: 78 thetime: 3390 next_beat:3376.4293193717

only off target ticks by 13ms
timestarted: 78 thetime: 3547 next_beat:3533.497382199

only off target ticks by 12ms
timestarted: 78 thetime: 3703 next_beat:3690.5654450262

only off target ticks by 11ms
timestarted: 78 thetime: 3859 next_beat:3847.6335078534
and so on.... there really isn't a problem with any tempo from 120.0 bpm to wierd tempos like 95.5 bpm... or even 134.563 bpm.

And the reference beat time value, next_beat at which we trigger the next beat will never go out of phase with the pulse of the ideal tempo any more than the processor hardware and floating precision math of corona will allow.

Each discrete beat could be off from this perfect target ticks value by 16.7 milliseconds (1000 ticks per second/60fps) or less. This is still an issue. Carlos: Can Corona please be given the ability to trigger audio and perhaps some simple display events at a much higher granularity? Especially when not much else is going on?

In spite of a minor delay of each beat from approx 0 to 16.7 milliseconds, with this method at least the tempo pulse itself from which each beat is triggered will be rock solid. Always!

Hope this helps!

I look forward to your reply/replies!
uid: 106887 topic_id: 13881 reply_id: 84062


[TOPIC: post.html]
#10

Gary Duke

[GLOBAL: userInfoPane.html]
Gary Duke
  • Enthusiast

  • 37 posts
  • Corona SDK

Thanks Peach,

See my additional comments here on this related thread by another developer wanting to make a music app. http://developer.anscamobile.com/forum/2012/01/14/fastestmost-accurate-way-trigger-sounds-drum-sequencer#comment-85249

I hope something can be done by Ansca to help all of us who are making music-based apps to improve the granularity at which we can trigger audio events.

Another solution would be to enable us to write to the audio buffer and schedule the "mix-in" of sound samples at a specific sample number along a continuous audio stream of 44100 samples a second. That would be awesome. Can it be done?

Thanks for replying to my thread Peach!

Cheers to all at Ansca!

Gary
uid: 106887 topic_id: 13881 reply_id: 85323


[TOPIC: post.html]
#11

spideri

[GLOBAL: userInfoPane.html]
spideri
  • Contributor

  • 106 posts
  • Corona SDK

Great stuff. Thanks Gary.
uid: 29093 topic_id: 13881 reply_id: 85661


[TOPIC: post.html]
#12

ewing

[GLOBAL: userInfoPane.html]
ewing
  • Corona Geek

  • 1,138 posts
  • Alumni

I'm curious if you have any specific recommendations or performance (Instruments) traces that would point to areas we could reasonably optimize.

The kind of precision timing you ask for is very hard to do in general, let alone be cross-platform. Typically, for very precise audio timing, it would often be suggested that on iOS or Mac, you deal directly in C and the lowest level Core Audio APIs because even Objective-C would be too slow/unreliable.

In Corona, on Mac/iOS, the event system is fairly tied to Cocoa/Obj-C (as with just about all Mac/iOS apps). So even though your app might not be doing anything, Cocoa may actually be doing things with the event loop which still take minor, but additional amounts of time. And because some services live on separate threads, there is also thread switching going on behind the scenes which also leads to unpredictable times. And because you are going through Lua, that is yet another layer which will incur minor, but additional overhead.

Apple does provide some low-level callbacks on special high priority threads for things that need very precise timings, but there are a lot of limitations and rules about using these. And because these do not live on the main thread, there are additional complications/restrictions as well. In Corona, we always make Lua callback on the same thread. This protects you from concurrency problems which can be very complicated. And requiring us to lock the Lua VM on every operation would also incur more overhead.

That is just the Apple side. On Android, I would say you are SOL for now.
As for your for 17ms margin of error you show above. Here's one idea (which might be bad so use carefully). When you enter your callback with 17ms or less time to your next beat, create a busy loop that blocks execution until you get closer to your timed event, e.g.

local system_getTimer = system.getTimer -- make a local variable for faster access since we are in a time critical loop
busy_wait = true
while busy_wait do
	local new_time = system_getTimer()
	if new_time > ready_time then
		busy_wait=false
	end
end

This is generally bad because you are blocking the main loop and preventing the app and OS from doing useful things (and Apple's watchdog process will kill your app if you block for too long). However, for very short amount of times, this may acceptable and give you slightly more timing precision.

uid: 7563 topic_id: 13881 reply_id: 85700


[TOPIC: post.html]
#13

Gary Duke

[GLOBAL: userInfoPane.html]
Gary Duke
  • Enthusiast

  • 37 posts
  • Corona SDK

Ewing,

A whole-hearted thank you for this response!

I have to say I did tinker with that very idea of hogging cycles in a busy loop but didn't because I thought it would do more harm than good. Still may try it and let you know how it goes.

That said it would really be nice if performWithDelay could trigger non-display-updating functions at a higher frequency than 16 ms... down to every ms or at least every 4ms would help a lot. 10ms would be a nice compromise too! Can we make this happen? It is really odd that performWithDelay takes the argument of 1ms, but only triggers at 60fps/16ms.

Cheers,

Gary
uid: 106887 topic_id: 13881 reply_id: 85720


[TOPIC: post.html]
#14

alanfalcon

[GLOBAL: userInfoPane.html]
alanfalcon
  • Enthusiast

  • 41 posts
  • Corona SDK

I've been chatting with Gary in part about my music/rhythm game "Beat Boxes" and whether I learned anything from making that game that could help with some of the precision audio timings discussed here. In fact, I measured out all of the "beats" in my game exactly as Gary described in his essay of a post, always calculating forward from the start of the track instead of from the previous beat, which would quickly get out of sync if you deviated from the subset of possible beat timings that robby used.

In the case of working within the 60FPS limitations of Corona, I think it should be possible in theory to create multiple sound files with short periods of silence in front of them, ranging from 0-15ms, and then choose the correct sound file based on the calculated delay before the next beat should sound. This would theoretically give you perfect ms granularity without any changes to the SDK from Corona (though it's a kind of hacky workaround, and of course it would be nice if we could access real ms-precise timings directly in Corona).

Gary suggested that my idea could be taken a step further (and save a lot of time building different sound files in the process!) by having a single sound file with 16ms of silence in the front of the file, and then just "seek" to the right part of the track based on how many ms it would be until the next beat should sound. Then you still only need one sound file, and you can be sure that the sound plays exactly when it should, even if a frame refresh doesn't occur in that exact moment.

A huge word of caution to anyone dealing with precise timings like this though: the iPhone screen actually refreshes every 16.6666667ms, giving it a precise 60FPS update cycle. The Corona simulator, on the other hand (at least on my system) actually updates frames every 16ms exactly, which is close to but not exactly 60FPS (if you're running at 30FPS the same caveat applies, except the numbers are 33.33333ms and 32ms). So make sure you're testing everything on your device, you'll save a lot of potential headache. (Trust me, I've been there).
uid: 14598 topic_id: 13881 reply_id: 86716


[TOPIC: post.html]
#15

spideri

[GLOBAL: userInfoPane.html]
spideri
  • Contributor

  • 106 posts
  • Corona SDK

Well done, great creative problem solving guys.

Can I ask though, did you try the single padded track + seek method discussed above? Seems a lot better than having 17 different versions of the same sound so I'm guessing you tried and it failed.
uid: 29093 topic_id: 13881 reply_id: 86836


[TOPIC: post.html]
#16

Gary Duke

[GLOBAL: userInfoPane.html]
Gary Duke
  • Enthusiast

  • 37 posts
  • Corona SDK

Thanks, spideri!

And thanks again to Alan.

And, thanks to Ancsa's staff for showing an interest in this thread.

At some point down the road I will definitely test the seek solution I proposed. But, I'm sticking with the multiple files method for now because it worked beautifully at a reasonable cost of 23KB for the 16 extra "tick" audio files and bears the advantages of requiring fewer lines of code and no extra function calls to complete (e.g. seek and channel-related) before the file plays.

It's also a simpler solution (doesn't require a black box seek function to work as expected at a high level of granularity, reliably across multiple devices).

I will experiment with seek at a later date, but right now I have much more need to getting back to refining the user interface.

That said, I would certainly welcome data from anyone testing the accuracy of the seek method vs the multiple audio files method. Here is an archive of my 17 tick audio files http://db.tt/GSCANdVc

Cheers!

Gary
uid: 106887 topic_id: 13881 reply_id: 86898


[TOPIC: post.html]
#17

Gary Duke

[GLOBAL: userInfoPane.html]
Gary Duke
  • Enthusiast

  • 37 posts
  • Corona SDK

Yes!! It works! It totally smooths out the audio***. Now, I've got a pulse going at virtually any tempo, including 97.5 or any other tempo... I ended up using 17 different files for my "tick" sound: one with no delay, and 16 other files with from 1 to 16 milliseconds delay.

I loaded them up into a table variable, and I find the index number i want to play (which corresponds to the number of milliseconds I need padded) with this line in my checkbeat function which I call every enterframe.

local index=math.max(0,16-(math.floor(thetime-next_beat)))

where next_beat is the time in float milliseconds I'm waiting for the system time (stored in thetime) to pass.

I actually pad each beat so each beat sounds as close to exactly 20ms late past the target time that I can. The result is that all my audio is now way more evenly spaced. It's amazing how much difference eliminating (really compensating for) 16 or less milliseconds of error makes...

Works great. And I can finally concentrate on rest of my UI work for my app.

Awesome. I love the feeling of support here in the Corona forums. There are a lot of inspired and creative minds here!

Cheers,

Gary

***UPDATE... see my second post from Feb 14.
uid: 106887 topic_id: 13881 reply_id: 86764


[TOPIC: post.html]
#18

ewing

[GLOBAL: userInfoPane.html]
ewing
  • Corona Geek

  • 1,138 posts
  • Alumni

Thanks for sharing your results. That is very impressive. It's wonderful to see that you were able to one-up a native app using Corona.

I would be interested in hearing your seek results if you do them.
uid: 7563 topic_id: 13881 reply_id: 87142


[TOPIC: post.html]
#19

Gary Duke

[GLOBAL: userInfoPane.html]
Gary Duke
  • Enthusiast

  • 37 posts
  • Corona SDK

***Update:

My musician's ear could hear it was smoother. But I just did a test in an audio editor using recorded output from my old app version and the new version with the different offset tick wav files.

The result is that in the old version each tick plays up to 17 milliseconds early or late from the perfect pulse. In the new version, the tick plays up to 10.5 milliseconds early/late.

This is a 38% improvement, which I am very happy with.

I guess what this means is that for various reasons, probably code execution speed differences and/or latency in the interface to the audio engine itself accounts for latency beyond any control.

The main and most important part still is that the tempo pulse against which each beat is triggered is rock solid thanks to the tempo pulse calculation algorithm I presented in my "essay" in my initial post to this thread.

UPDATE #2: In fact, the tempo pulse for my metronome matches and might exceed that of the most accurate metronome I've seen for any mobile platform thus far, which I respectfully won't name here, because though the beats are super-evenly spaced it does drift very slightly-- it drifted 6 ms after 3mins 27secs.

I was amused that a recently released and highly publicized metronome on the app store made an audacious and false claim in their app description that "No other metronomes on the app store surpass our accuracy." Well, using a waveform editor to examine the output, I noticed that after 3 minutes at 97BPM (a tempo value that requires float precision, sub-sample accuracy), the tempo pulse of this well publicized metronome app had drifted out by 22 milliseconds, while the pulse of the former app was at least less off, and my app in development though with a jittery beat trigger, has a pulse that should remain spot-on while the other apps drift gradually away from the ideal pulse.

What's confusing is that both of these other apps are native apps that write directly to the audio buffer using very low level audio APIs. Yet they are both still off (even though one is more 'on' than the other, as mentioned). Could it be that the the os+hardware combination that processes the audio buffer in the iPhones, is not perfect timing-wise!? Crazy... if this is the case, then samples in the audio buffer on my iPhone 3GS can't be relied on to reconcile against the system clock. Integrity checks against the system clock might be needed to maintain accuracy!

That just goes to show that using the low-level audio API doesn't mean their app is going to be the most accurate. Careful and insightful programming is going to be more important.

This probably applies to many other areas in debates over using low level frameworks versus corona: it often amounts to how intelligent the business logic and problem solving in your analysis and implementation is, and not so much how low level you go, or for that matter, what framework or SDK you use!

Cheers!
uid: 106887 topic_id: 13881 reply_id: 86927


[TOPIC: post.html]
#20

alexsmith944

[GLOBAL: userInfoPane.html]
alexsmith944
  • Enthusiast

  • 41 posts
  • Corona SDK

Hi Gary,

What an exciting read! Thanks so much for posting your progress! I will definitely try the seek method and report back. Corona Drum Sequencer ahoy!
Cheers
Alex
uid: 66618 topic_id: 13881 reply_id: 93414


[TOPIC: post.html]
#21

alexsmith944

[GLOBAL: userInfoPane.html]
alexsmith944
  • Enthusiast

  • 41 posts
  • Corona SDK

Hi Gary, Alan,

I just tried the SEEK idea and while it's not bad, it's not perfect. I can't really tell if it's helping or not.

Here is the project folder, including the 16ms delayed audio hihat:

http://www.alkex.com/wp-content/uploads/BPM-TEST.zip

Maybe you can have a look in case I did something wrong?

Thanks so much for getting us this far! We're already accurate enough for a lot of audio applications

Cheers
Alex

EDIT: I also tried the 17 audio file technique and it doesn't appear to be any better than the SEEK.Maybe I'm doing something wrong?

Here is my folder for that approach:
http://www.alkex.com/wp-content/uploads/BPM-TEST-17files.zip

Thanks!!!
uid: 66618 topic_id: 13881 reply_id: 93653


[TOPIC: post.html]
#22

Gary Duke

[GLOBAL: userInfoPane.html]
Gary Duke
  • Enthusiast

  • 37 posts
  • Corona SDK

Alex, thanks for trying. I already published my results and there is no doubt the multiple files method worked for me. I have kind of forgotten about this thread as my problem is solved for my purposes.

However, yes, there are several things I can see you are doing wrong. To help others I'll list them a bit.

**But** I don't want this thread to become a conversation about all the things you were doing wrong.. so *please* if you would like further clarification please contact me directly. Thanks!

a) You are playing the audio and then seeking in the next line, which is the wrong order. You would seek first, then play. Right?
b) Your files are 48 kHz they should be 44.1 to match the audio system. You are creating extra work for the system by making it convert to 44.1 which is the default. You could try adding "audioPlayFrequency = 48000" to config.lua to try to tell openAL to use that sample rate, but I'd just stick to 44.1 and define audioPlayFrequency as 44100 in your config.lua as well for sake of completeness.
c) In your audio files, after the Hi Hat sound there are a lot of samples worth of trailing silence. You should trim all the silence off from the sound file so you don't needlessly tax the audio system... although I guess there isn't going to be mixing going on because you have the sounds playing on the same channel which will cut the currently playing sound off and start again (it won't layer/overlap the sounds)

Also, you didn't use my sounds.. (you could have used the 16 ms of padding tick sound I had for a 1:1 comparison between my method and the seek method). It may also be that an extremely short 10ms tick sound like mine-- which doesn't tax the audio system much in terms of having to mix overlapping sounds from different channels-- may have something to do with my success.

And, aside from using 44.1 kHz sounds you may also want to consider using mono sounds instead of stereo further efficiency.

You didn't mention as well the method you are using to measure the performance difference. Are you recording the sound output of your app into to a sequencer?

Also, for the multiple files example, you are using 16 if then end statements to play the right file, and they aren't even arranged as if elseif elseif end, they are all separate ifs, one after the other which is worse and might itself insert a tiny amount of time.

Instead you should have put all the audio files as elements 0 to 16 in an array called click so you can just execute one line, e.g.

audio.play(click[index])

Again, I don't want this thread to become a discussion of what you were doing wrong, so please contact me directly, and then if you have later success post here again :)

I should also mention that I don't have much time to spend on this research these days, as I am concentrating on the other logic in my app...

Cheers,

Gary
uid: 106887 topic_id: 13881 reply_id: 93802


[TOPIC: post.html]
#23

alexsmith944

[GLOBAL: userInfoPane.html]
alexsmith944
  • Enthusiast

  • 41 posts
  • Corona SDK

Thanks, Gary

Couldn't figure out how to write to you personally but you've given me plenty to sink my teeth into.
The url to your clicks seems to be dead but I can certainly fix my audios.

Once again i really appreciate the time you put into explaining this.
All the best
Alex
uid: 66618 topic_id: 13881 reply_id: 93856


[TOPIC: post.html]
#24

robbykilgore

[GLOBAL: userInfoPane.html]
robbykilgore
  • Observer

  • 9 posts
  • Corona SDK

Wowza! I haven't stopped by in a while due to a crushingly massive project at work. (Sadly not involving Corona). Anyhow, what a fascinating read. I'm thrilled and inspired by all the great convo and ideas this thread has collected. Massive shoutout to you all for your generosity! Looking forward to a time when I might actually have the cycles to dive back into implementation. - Robby

http://www.youtube.com/user/RobbyKilgore
uid: 56133 topic_id: 13881 reply_id: 105429


[TOPIC: post.html]
#25

Beloudest

[GLOBAL: userInfoPane.html]
Beloudest
  • Contributor

  • 189 posts
  • Corona SDK

Just read this thread top to toe, great stuff gary. Your method was exactly how someone else years back crushed flashes audio latency issues, they were much worse than corona's.

I tried to make a drum machine on it, i could probably get better results now Im better at OOP.

Check it out here if interested:

http://www.newgrounds.com/portal/view/464751

I appropriately named it rusty drummer. I never finished as it was not worth the battle.

I will be using your info to assist with audio based app im planning on working on.

Many thanks.
uid: 118379 topic_id: 13881 reply_id: 110260



[topic_controls]
[/topic_controls]