In trying to solve some latency issues related to sounds playing on a linux fmod system we started experimenting with the setDSPBufferSize, the experiment we ran on windows worked as expected, with bigger buffers having longer delays and really short (128,2) buffers having broken sounds.
However when this is done on the linux system the values seem to be ignored, no matter the changes in the DSPBufferSize the sounds play as if with the default values.
The only effective changes were buffer size = 0 or numbofbuffers < 2 where fmod would return an error.
Why does setDSPBufferSize seem to have no effect in the linux build?
Some extra information:
We are using output type: FMOD_OUTPUTTYPE_ALSA
FMOD version 44420
Slackware 14.0-x64 based, Linux kernel 3.4.33
Hardware: Intel HDA (snd_hda_intel model 3stack-6ch) + codec Realtek ALC887-VD.
amixer: ‘Channel Mode’ 6ch
Playing with DSP buffers, in Linux we hear difference in sound only if FMOD is initialized in 5.1 with 2 1byte-length DSP buffers.
- djlenny_3000 asked 4 years ago
Until now I haven’t had a chance to continue the investigation due to changed priorities.
a) I measured the delay on Windows. You can find the results in the updated report below. In short, there’s no difference between FmodEx+WAV vs. EventSystem+PCM-FSB. Meanwhile EventSystem+MP3-FSB shows ~10ms of extra latency/244 ms total, on Linux we had ~24ms/126 ms total.
It’s not quite fair to compare Windows and Linux results, because I used two significantly different machines. Unfortunately, we don’t have two identical ones with Windows and Linux installed. Anyway, the measured on Windows 7 total delay is as twice as long as it is on Linux, while the Windows machine is WAY more powerful. I think It could be explained considering that we run Linux in the console mode (no GUI no X Windows) and ALSA is used exclusively.
b) We haven’t tried playing FSB using Fmod Ex. Even if it demonstrates some sort of perfomance improvement we wouldn’t consider it as a practical solution.
c) Right now I have (I think I do a desent understanding of major factors affecting the latency. The only thing which I can’t explane is why an MP3-decompress-to-memory sound bank contributes to it. As I previously mentioned the contribution have been detected on both Windows and Linux. It might be too much to ask, but if you could make a similar test on your side (preferrably with my test sound banks) it would be really helpful.
Report can be found at: https://www.dropbox.com/s/cexpdyn63zalaf1/measurements.xlsx
Thank you for your support,
I’ve read through your report (quite detailed I might add) and I’ll comment where I can to further the discussion.
Yes, Linux will clamp the buffers based on the minimum the OS can handle.
Delay between FMOD Ex and FMOD Event System should be equal provided createSound / getEvent has been called prior to playback regardless of loading mode or compression format.
This surprises me, there should be no added latency from FSB MP3 vs PCM (.mp3 files I could understand perhaps). I notice you single out Linux as your test here, did you run this on Windows? I expect the results between the platforms to be equal. Did you try playing the FSB using FMOD Ex? i.e. createSound, then getSubSound to rule out anything in the event system (again I am surprised this would cause added latency).
4.There is no extra latency added by FMOD for multi-channel output, however there could be some added further down the signal chain. You could verify this by using the aplay ALSA Linux test tool and running the same test with stereo and 5.1 devices.
Thank you for your feedback and sorry for the delay in communication. We’ve made a very basic test application which plays a sound. When ‘S’ key is pressed it plays the test sound preloaded from a WAV file. When ‘E’ key is pressed it plays the same sound as an event.
We measured the delay between pressing the key and the sound being played in the speakers. The measurement technique description and the results could be found in the Excel file measurements.xlsx. Please find it in the archive along with the test application source code and the audio project.
1. Measurement results show that SetDSPBufferSize parameters make a difference on both Windows and Linux. The only difference is ALSA on Linux seems to clamp the parameters by the lower bound of 2×1024 (the delays for 2×1024 and 2×512 are the same).
The delays observed for sounds played using FMOD System and FMOD Event System are in fact the same. But ONLY if the bank type is "decompress into memory" (which is expected) and the bank compression is PCM (which is unexpected).
An MP3 compressed audio bank introduces (on our Linux test platform) an extra delay of approximately 23ms as compared against the same bank with PCM compression, despite the fact that in both cases the bank type is "decompress into memory".
Speaker configuration "5.1" introduces ~16ms as compared against the same test with configuration "Stereo".
Speaking of #3, according to the documentation after the events are loaded they should be in both cases decompressed and become in-memory PCMs. No streaming or on-the-fly decompression should occure. Meanwhile the delays are different.
This is what misled us in the first place. We were comparing a WAV sound played by FMOD System vs. an event with its wave data in a "decompress into memory"/MP3 bank. Since we didn’t expect the MP3 compression to affect the playback in this case we decided that the extra delay was introduced by the Event System.
Could you please comment on #3 and #4?
Please let me know if you need any more information. Thank you for your help.
Can you try linking with the logging version of FMOD?
We offer the user set DSP buffer size to ALSA, then ALSA will give us the closest supported size it can actually do.
This information is printed to the TTY during System::init. It might show ALSA requiring a larger buffer than you request.
We’ve done a few experiments with the logging version of FMOD. The results prove that ALSA clamps the requested parameters to their valid/sane ranges. The minimum buffer size ALSA could make was 64 bytes.
What is strange though is that the getDSPBufferSize() function returns exactly the same parameters setDSPBufferSiz() was called with. Even in the cases where the actual values were adjusted by ALSA.
- setDSPBufferSize(65536, 512) - EventSystem::init - the DSP buffer params silently clamped by ALSA - - -FMOD: OutputALSA::Start : Requested block size: 65536, Actual block size: 2720 - - -FMOD: OutputALSA::Start : Requested buffer size: 5440, Actual buffer size: 5440 - getDSPBufferSize() -> bufsize :65536, numbufs:512
Q1: Is it a bug or desired behavior?
We haven’t managed to decrease the latency playing with the size of the DSP buffer. Cutting it down to the minimal limit is no help:
– – -FMOD: OutputALSA::Start : Requested block size: 32, Actual block size: 32
– – -FMOD: OutputALSA::Start : Requested buffer size: 64, Actual buffer size: 64
This config results in ~170 ms delay* when sound is played using the FMOD Event System (bank settings WAV/decompress to memory) and ~130 ms when played using the lower level FMOD System.
We’ve made sure FMOD and the audio driver use the same sampling rate (48000). Playing the same sound using ALSA results in less than 40ms delay.
Q2: What else can we do? Or at least what’s the explanation for the observed delay?
Q3: Why does the FMOD Event System contributes ~40ms to the latency.
*The way we measure the delay is via recording the sound of a key being pressed and the playing sound coming from the speakers.
Q1. It’s not necessarily bug, in FMOD Ex we honor the requested buffer size (from our mixers perspective) but the underlying hardware buffer may be sized differently. In FMOD Studio calling getDSPBufferSize after System::init will give you the ALSA modified block size. The num buffers will remain the same in both cases because the value is only used during System::init as a hint to the overall hardware buffer size.
Q2. With an appropriately small buffer size you can calculate the exact latency between a call to System::playSound and the sound arriving at ALSA. If you are seeing 170ms end-to-end it appears something is adding to your latency. Can you confirm your sounds are loaded before playing? For the low level API ensure you have called System::createSound prior to playback, and for the EventSystem you have loaded your event data ahead of time (before calling getEvent). If you have done these things then that accounts for the latency inside FMOD, next is latency outside. If your Linux distro is using PulseAudio or some other sound library that has an ALSA plugin it is possible your audio is being routed through that adding latency, is this the case?
Q3. The EventSystem shouldn’t be adding any latency unless event loading is happening at playback time. If this is not the case could you provide your test code?
Please login first to submit.