Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411646 Posts in 69395 Topics- by 58451 Members - Latest Member: Monkey Nuts

May 15, 2024, 08:52:39 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Sound Latency in Flash
Pages: [1]
Print
Author Topic: Sound Latency in Flash  (Read 2534 times)
Kunal
Level 1
*


is feeling Bit.Core.Trippy


View Profile WWW
« on: March 05, 2010, 08:18:38 AM »

I've got a simple drum sound that is about 0.3 seconds long. I'm trying to play this sound every 1 second.

I'm tracing the time (using flash.utils.getTimer()) between consecutive sound.play() calls, and the gap seems accurate enough (usually within 10-20 ms of 1 second). But the time taken for the sound to play just seems way off on a few occasions. I haven't measured it but its definitely more than 100ms.

I've tried doing the two things suggested in this thread (http://stackoverflow.com/questions/227674/latency-in-playing-short-sounds-in-flash-9-actionscript-3) i.e. embedding the sound into the swf, and playing a silent sound on loop continuously. Doesn't seem to help things.

The worst thing is that this delay is just random. Sometimes I'll notice it after 50 beats, another time after 15 beats. I've got nothing else going on in the SWF, and I even turned off most of the other programs on my PC.

I'm using the Flex 4-Beta 2 SDK (Gumbo) along with FlashDevelop. This is being tested in the latest debug flash player. Would appreciate if anyone had some advice to offer.
« Last Edit: March 05, 2010, 06:00:05 PM by kvjoshi » Logged

Draknek
Level 6
*


"Alan Hazelden" for short


View Profile WWW
« Reply #1 on: March 05, 2010, 09:42:25 AM »

Have you checked that the sound file doesn't have any silence at the start of the file?

Very often when you convert a wav to an mp3 it adds a noticeable amount of silence as part of the encoding.
Logged

Kunal
Level 1
*


is feeling Bit.Core.Trippy


View Profile WWW
« Reply #2 on: March 05, 2010, 11:13:39 AM »

Have you checked that the sound file doesn't have any silence at the start of the file?

Very often when you convert a wav to an mp3 it adds a noticeable amount of silence as part of the encoding.

Thanks for the reply
If there was some silence my guess is that the delay would be constant ? The sound plays with no delay on some calls to sound.play(), then there's a small delay on one call (randomly), then it'll be back on track for the next few calls and so on.
Logged

increpare
Guest
« Reply #3 on: March 05, 2010, 12:16:31 PM »

Flash isn't very good with sound latency from my experience - I don't think there's any way around it, and I don't think it's mp3 related.
Logged
Martin 2BAM
Level 10
*****


@iam2bam


View Profile WWW
« Reply #4 on: March 05, 2010, 01:41:44 PM »

Very often when you convert a wav to an mp3 it adds a noticeable amount of silence as part of the encoding.
Flash isn't very good with sound latency from my experience
My thoughts exactly.
Logged

Working on HeliBrawl
st33d
Guest
« Reply #5 on: March 05, 2010, 02:52:38 PM »

I don't have the code to hand, but here's how we did it in Pixel Pop:

You can increase the accuracy by running at a high framerate (say 120fps) and when you are close to the exact time you want to play the sound, you use a while loop to stall the Flash player.

That's right - you wait till just right moment and then make Flash spaz out in a while loop till you get just close enough to the right millisecond value - then BAM, play that sound.

If you're doing it in time to music, play the music and note the current value from getTimer(). If you ask Flash what millisecond value the music is at IT WILL LIE TO YOU! As far as I can guess, the Flash player plays media files in a separate thread to the actionscript code thread - hence the massive synchronisation issues. Use the millisecond reading from getTimer and work out how far the music is in by inference - you will have to add an onComplete method if you want the music to loop so you can track the time accurately.

Use a while loop stall we got close enough to the actual timing of the track to notice a slight phasing effect.

This means that anyone with an exceptionally good ear will suck at your game, but the rest of the proles should be fine.
Logged
st33d
Guest
« Reply #6 on: March 05, 2010, 02:56:50 PM »

Oh, and you can deal with the mp3 compression dead air by experimenting with where to start the sound. You can specify how many milliseconds in to play a sound. Generally on a given compression rate the dead air gap will be the same - but you should be editing these sounds in something like Audacity to examine the waveform anyway. That's if you want to do a proper job of it.
Logged
Rob Lach
Level 10
*****



View Profile WWW
« Reply #7 on: March 05, 2010, 03:24:22 PM »

You might want to contact the guys who made punk-o-matic since their timing is pretty good.
Logged

Kunal
Level 1
*


is feeling Bit.Core.Trippy


View Profile WWW
« Reply #8 on: March 05, 2010, 05:51:21 PM »

@st33d Thanks - will try that out.
@Pierog I tried Punk-O-Matic out and it seems perfect. After spending an evening in frustration over this issue, listening to non-laggy sound seems magical Smiley.

Incidentally I tried the SWF out on a friends machine which does not have the debug player installed (mine does) and it seemed fine there.
Logged

Glaiel-Gamer
Guest
« Reply #9 on: March 05, 2010, 06:17:09 PM »

how are you doing the timing? in a timer event or something else?

If you have a sound embedded in the fla and set to stream (can only do this in the .fla i believe, no way to invoke the frame-synced streaming elsewhere), flash will skip rendering frames to keep the audio in sync with the framerate. You can do that with a silent sound, and as long as your sounds are invoked on frames (ENTER_FRAME), they will be in sync
Logged
Kunal
Level 1
*


is feeling Bit.Core.Trippy


View Profile WWW
« Reply #10 on: March 05, 2010, 06:45:09 PM »

@Glaiel-Gamer

The timing is done using the flash.utils.getTimer() function, _not_ the TimerEvent.

Essentially, for each ENTER_FRAME, I dispatch a custom event. This custom event has a property that contains the time between each ENTER_FRAME. This value is calculated based on flash.utils.getTimer().

The drums 'class' is listening for this event and has a counter that keeps track of the total time elapsed. Once this value crosses 1000 ms it plays the sound and sets the counter back to zero

Code:
public function playDrum (ev:TickEvent):void
{
    counter += ev.elapsed;
    if (counter >= 1000 )
    {
        trace(getTimer());
drum1.play(0, 0);
counter = 0;
    }
}

drum1 is a 0.3s mp3 that has been embedded.

Based on the output of flash.utils.getTimer() then the time between calls to drum1.play() are always fine.  But for a few random calls it just seems that drum1.play() itself takes a very noticeable amount of time to get going.
Logged

raigan
Level 5
*****


View Profile
« Reply #11 on: March 06, 2010, 03:55:15 AM »

Two ideas:

1) Maybe stupid: if your problem isn't simplified/hypothetical (i.e you literally want a drum sound that plays once a second) why not just pad the sound file with silence so that it's 1sec long, and then set it to loop? This way there should only be latency when you start the loop, from then on the timing will be good.

2) Maybe over-complex: you could try directly managing the sound buffers, AFAIK in AS3 you can write the binary data directly to the sound buffer rather than using the higher-level "play sound" API. I would guess that this is how e.g http://www.hobnox.com/audiotool works, which definitely has no issues with sync'ing and shows that it's possible *somehow*..
Logged
Kunal
Level 1
*


is feeling Bit.Core.Trippy


View Profile WWW
« Reply #12 on: March 06, 2010, 06:32:53 AM »

@raigan - Thanks. Unfortunately this is just the start. Got some things planned that don't fit into a simple loop scenario. I'll look into writing directly to the buffer, although I've heard there are issues with that as well.
Logged

Glaiel-Gamer
Guest
« Reply #13 on: March 06, 2010, 12:02:38 PM »

@raigan - Thanks. Unfortunately this is just the start. Got some things planned that don't fit into a simple loop scenario. I'll look into writing directly to the buffer, although I've heard there are issues with that as well.

The issue with this is flash is a bit slow. You'd get your timing right (assuming 44.1kHz samples) if you could determine the exact moment the sound starts playing, but since you need to calculate 44100 samples per second, and flash isn't exactly the fastest language out there. In tetraform I was able to get ~7 dynamic sounds playing at once before it became an issue though
Logged
st33d
Guest
« Reply #14 on: March 06, 2010, 05:11:31 PM »

This is why the while loop method works. Although Flash wants to do its own thing, Flash wants to do its own thing. It likes being stalled. Try to use this.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic