I’m implementing an FMOD Designer soundtrack for a little Android pinball game, using the simple_event example code as a guide. I’ve got it working, but there’s a fairly large time gap between when the ball hits the bumper, and the sound is heard.
The latency also seems to be present in both the playsound (fmodex) and simple_event (fmodevent) code … the time from when you release the button, to when the sound starts playing, is noticeable. It’s kinda hard for me to get an accurate measurement without a high-speed camera, but i’m guessing it’s ~100ms?
Is the latency caused by JNI, or something about the Android platform? Is it something I need to live with, or is there a way to decrease the lag, maybe at the cost of CPU? (the game uses very little) … Or did I screw up somehow?
running a Nexus S, Android version 2.3.4, FMOD Designer / API 4.35.04
- pdx asked 5 years ago
You are correct that the tradeoff is performance, it will cost a little bit more to do a mix every 512 samples instead of every 1024 samples but shouldn’t be significant. The main downside is reduced tolerance to spikes in system load, but even at this reduced size the amount of tolerance is still quite high considering the sample rate is only 24KHz.
The number of DSP buffers is how many chunks of 512 samples we cache ahead of time to avoid stuttering, the concept is called ring buffering. This doesn’t dictate how many sounds can be played simultaneously, that is controlled by the maxchannels param in System::init and the System::setSoftwareChannels function.
success! i was missing the getSystemObject call <facepalm>
setting the buffer size to 512 samples reduces the latency significantly, thank you! now i’m curious: what is the tradeoff when using smaller buffers, increased CPU? and does number of buffers = number of sounds that can play simultaneously?
When using the EventSystem you still have access to the FMOD::System object underneath, you can get access to it via EventSystem::getSystemObject.
So you would do:
quite possibly i’m unclear on the concept, but setDSPBufferSize is a FMOD_SYSTEM method, and seems to have no effect on FMOD_EVENTSYSTEM?
i was able to use setDSPBufferSize with the playsound (fmodex) example code, and it did indeed have an effect on the latency, though again, without a highspeed camera, it’s hard to tell by exactly how much (but as a test, i set the sample size to 2048, and the latency definitely increased).
i also noticed that FMOD_EVENT_LOADINFO might be doing something similar (via loadfrommemory_length and sizeof_instancepool_simple??) for fmodevent, but try as i might, i can’t seem to get that to have any effect on the latency.
SO would it be possible to post a version of the "Java_org_fmod_simpleevent_Example_cBegin(JNIEnv *env, jobject thiz)" method from simple_event/jni/main.c that shows the correct way to configure the buffer size to reduce the latency??
The latency in FMOD is fully configurable via System::setDSPBufferSize.
By default the buffer size is 1024 samples, with 4 buffers, which means 4096 samples of latency.
Since by default FMOD for Android runs at 24KHz, that equals 170ms latency, which is probably what you are hearing.
You can simple change the buffer size to achieve better latency, perhaps 512 samples with 4 buffers to halve the latency?
We’ve had a couple of queries over this recently, I will look into changing the default to be more snappy, but for now it can easily be tweaked as needed for your application.
as a follow up test, i implemented the "bounce on score" sound using android’s SoundPool method (which i had previously used for my notepadd app [url:3ged2ix2]http://broadcast.oreilly.com/2011/02/generating-audio-ui-for-androi.html[/url:3ged2ix2] ) … and, hmm, works like a charm, no latency at all.
code for both tests can be downloaded here: [url:3ged2ix2]http://www.twittering.com/twittering/code/FMOD/FMODvsSoundpool.zip[/url:3ged2ix2]
Please login first to submit.