playcanvas / playcanvas/engine
Overlapping sound slot doesn't play tracks that are not preloaded
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 16.8k
- Forks
- 2k
- Avg merge
- 4h 32m
- Merged PRs (30d)
- 222
Description
I think I found some unintended behaviour in the sound slot class when playing overlapping sounds. When you play multiple sound tracks in short succession sometimes the early sounds are "canceled" while the later sound is being played at a higher volume. In this test project you can hear this issue. When you start the scene, you will only hear 1 sound track instead of both at the same time.
The steps important to reproduce this issue:
- create a sound slot and set it to allow overlaping sounds
- use 2 different sound asset and set both of them to NOT preload
- play both of them in the same frame in the same sound slot. I do this by setting the asset property on the sound slot and then calling play.
I think I also found the reason why this is happening. When SoundSlot.play() is being called, the slot checks whether it first needs to load the asset. If it does, it calls SoundSlot.load() and subscribes to the assets' load event. Once that is finished, it is executing SoundSlot._onAssetLoad, which executes SoundSlot.load() again, which then basically starts playing the asset in this slot.
The issue here is that in the subsequent call of SoundSlot.load() the method never references the currently loaded asset that it had to wait for. It will use the last asset that was set. This means that if I were to play 5 different audio tracks at the same time and they all need to be loaded, the slot will only play the fifth asset five times simultaneously.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the SoundSlot.play(), load(), and _onAssetLoad() flow described in the issue, then reproduce the behavior in the linked test project. Verify overlapping playback with two different non-preloaded assets assigned and played in the same frame. Done means each requested track plays concurrently rather than the latest asset playing repeatedly.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100