Can the audio fileplayer and sampleplayer play at the same time?

I'm using the Lua 1.12.2 SDK. In my game, I have background music playing via the fileplayer api. I also want sound effects to occur during the game, but not stop the background music. On the Simulator this works fine and the sound mixes and plays back. However, on the actual device, as soon as the sampleplayer plays, the fileplayer stops. Is this a hardware limitation? I wasn't able to find information about the sound mixing capabilities of the device+SDK, so I'm not sure if I'm doing something wrong or if it's a platform limitation.

Thanks in advance!

1 Like

That's most likely due to buffer underrun on the fileplayer, and not because of you are playing multiple sounds. By default if a buffer underrun occurs, the sound will completely stop playing. If you want to disable this and allow it to continue playing, you can use fileplayer:setStopOnUnderrun(false), but may result in stutters. Another potentially better solution is to increase the buffer size when you create the fileplayer using fileplayer.new(path, [buffersize]). This will increase the latency of the fileplayer, but will avoid stutters and the sound stopping. Also, I don't know what kind of file you are playing, but I would avoid MP3 as they require a lot of processing which can make buffer underrun more likely.

5 Likes

Awesome! Thanks for the quick reply. Glad that I asked because I'm not sure I would have ever thought to do that. I'll give it a try and report back. Thanks!

That was it. Much appreciated! Thank you again.

I think I am facing the same issue. I am not sure I understand why this issue occur though. Does it mean the fileplayer does not stream the data fast enough from the disk?
In my case, there is no other disk access so wouldn't increasing the buffer size just delay the issue from occuring again?
Also, would anyone know what is the default value for [buffersize]?

The player can pull a lot of data off disk fairly quickly, but we can't guarantee how often it'll be able to do that. The smaller the buffer, the greater the chance that the player will run out of data before it has a chance to load more from disk.

The default buffer size is 1/4 second.

1 Like

I realized my issue occured when I was doing a lot of random calculations and populating a large table (generating the town for Mad City). In this instance, would you know what would be the bottleneck?

It would probably be useful for me to describe what's going on under the hood, wouldn't it? Sorry, I should have thought of that sooner.

The reason we have that buffer in the first place is because the audio render thread has very tight timing constraints--it runs every 256 samples, or 5.8 ms, and if it takes too long the game audio stutters. So, that code needs to be very lightweight, can't sit around waiting for disk i/o. The loading (and decoding, in the mp3 case) code runs on a separate lower-priority thread, which in this case is the same thread the game code runs on--that means slow-running game code will block fileplayer loading.

But it might not be necessary for those to share a thread any more? The old filesystem code wasn't thread safe, so we weren't allowed to access the disk from outside the game thread, but I think we have mutexes on the new filesystem code. If we move the loading to another thread it might just work! I'll give it a try, see what happens.

1 Like

Thanks Dave for the details, it makes a lot more sense now!
I don't really need enhancements for Mad City as the game is quite light in many aspects but I did end up increasing the buffer to 3 seconds (if I recall), which I assume is consuming quite a bit of memory for this one instance (generating the city). Of course, I could have put a workaround in place but if we have a more elegant solution that will eventually avoid this unnecessary memory usage, it is really a win-win!