How do I get music tracks playing sequentially?

Hello! Very new here, but I spent hours searching and trying to find a solution, hopefully it is simple! I'm primarily a producer and just now getting into dev, got the SDK running on my Mac environment well enough, and have already successfully compiled several small games with minor changes to them, and very simplistic POC's.

I'm trying to get audio tracks to play sequentially just so I can understand better, but I cannot get it to work. Here's what I've tried:

boing = pd.sound.fileplayer.new('music/audio')
boing2 = pd.sound.fileplayer.new('music/sandsea')
boing:setVolume(0.2, 1)
boing2:setVolume(0.2, 1)
boing:setStopOnUnderrun(false)
boing2:setStopOnUnderrun(false)
boing:play(2)
if boing:isPlaying() == false then
	boing2:play()
end

I'm also trying this but I'm unsure what steps I would need to check when the song is finished to start playing the next one:

player = playdate.sound.fileplayer.new()
function setup()
  player:load('music/audio')
  player:play(3);
end

Any suggestions would be much appreciated!

1 Like

Once you :play the file (which you would do once, not every frame) you need to check :isPlaying in your playdate.update() loop (which runs every frame).

Or:

In my game, I'm doing the same thing without checking :isPlaying in the update() loop, by setting a timer, something like this...

Do this at the start—not every frame:

local pd <const> = playdate

songs = {
	pd.sound.fileplayer.new("music/song1"),
	pd.sound.fileplayer.new("music/song2"
}
currentSong = 1
playNextSong()

And have a function like this:

function playNextSong()
	songs[currentSong]:play(1)

	if songTimer ~= nil then 
		songTimer:remove() --Prevent needless multiple timers
	end

	songTimer = pd.timer.new(1000 * songs[currentSong]:getLength(), playNextSong) --Milliseconds
	
	currentSong = 3 - currentSong --Alternate 1 and 2
end

(Also, when you :play(2) you're telling the sound to loop twice. If thats the intention, double the timer duration. My example plays once.)

Note that I put the songs into a {} Lua table so they can be referenced by number. That makes it easy to alternate 1 and 2 (by subtracting from 3) OR do other things, like cycle through a larger set of songs, or pick one using a random number, or reference particular songs by number in other variables (like within a table that defines a level).

This is just a shortcut:

local pd <const> = playdate

You can also shorten other things you use a lot, if you want:

local gfx <const> = pd.graphics
local snd <const> = pd.sound

And then it's just = snd.fileplayer.new etc.

2 Likes

check out playdate.sound.fileplayer:setFinishCallback(func, [arg])

https://sdk.play.date/inside-playdate/#m-sound.fileplayer.setFinishCallback

Then you can use a simple table of filenames.

With a little more work you can do cross-fades, etc.

2 Likes

Thank you! This is exactly what I was hoping for, it works perfectly :slight_smile:

1 Like

Thank you so much! I had a feeling this was the solution, or part of it, but I am so new I wasn't sure how to utilize this. I have a lot more learning to do with Lua, but thank you for the comment and the assist here!

1 Like