How to seamlessly change music?

I have 2 musics that are basically the same song but with different instrumentation. I want to switch between them depending on the action.

To do this, I tried to create 2 FilePlayers and to synchronize their offset when I want to change track:

void switchToMainLoop(GameScene * _Nonnull self) {
    const struct playdate_sound_fileplayer *filePlayerAPI = playdate->sound->fileplayer;
    const float offset = filePlayerAPI->getOffset(self->tutorialLoopPlayer);
    filePlayerAPI->play(self->mainLoopPlayer, 0);
    filePlayerAPI->setOffset(self->mainLoop, offset);

However, it doesn't sound good. There is always a slight delay. Is there a better way to do this?

I'm using the Lua APIs, but I've had good luck with using animators or timers to automate volume of FilePlayers for smooth fades between playing sounds. The end effect is slightly lowering the volume of one player each frame and slightly increasing the volume of the other player. Maybe something similar would work for you? Either fade out and then fade in, or fade both opposite directions for a cross-fade.


This is exactly what I do in Ball und Panzer. I have two tracks playing at the same time, in lock step, and fade their relative volume levels to make dynamic music.

The trickiest part was creating two identical (sample-level) ADPCM files. My approach here was to combine two mono tracks as a single stereo track and edit them together as a WAV. Only at the final step do I export each channel as a mono WAV and convert to ADPCM using adpcm-xq


Thank you @briandorsey and @matt, I will try to do a crossfade. I have an other problem thought, my second track is longer.

EDIT: I was able to solve the duration problem with playdate->sound->fileplayer->setLoopRange(...) . It works! Thanks.

@matt: Shouldn't both track have the same number of sample if the sample rate and the duration are the same ?

1 Like

Yes! Exactly.

I just found it easier to make sure of that by working on them in the same file.

1 Like