Crash on Fileplayer:setFinishCallback() with second arg

SDK 1.12 on Mac.
I'm trying to have a fileplayer call a function when playback completes, using setFinishCallback(). Since it's being handled by an object, i am trying to pass the object as the second arg then use that in the callback function. (I've tried this both with and without that second arg)

When playback completes, the simulator completely crashes out.

Maybe I'm holding it wrong, and that's fine, but the docs make it seem like this should work...

Here is the complete source code to reproduce the issue:


import "CoreLibs/utilities/where"

import 'CoreLibs/animator'
import "CoreLibs/object"
import "CoreLibs/graphics"
import "CoreLibs/sprites"
import "CoreLibs/timer"
import "CoreLibs/animator"
import "CoreLibs/ui"

---------------------
local gfx <const> = playdate.graphics

---------------------------------------------

class( 'PlayerTest' ).extends( 'Object' )

function PlayerTest:init()
    PlayerTest.super.init( self )

    -- get a new fileplayer with a 1 second buffer
    self.thePlayer = playdate.sound.fileplayer.new( 1 )
    self:Go()
end

function PlayerTest:describe()

    local pcnt = 0

    if self.thePlayer:isPlaying() then
        local offs = self.thePlayer:getOffset()
        local len = self.thePlayer:getLength()

        return  string.format( "%01.1f / %01.1f", offs, len )
    end

    return "-"
end


function finishedPlaying( ply, obj )
    -- this crashes?
    print( '---1---' )
    printTable( ply )
    print( '---2---' )
    printTable( obj )
    --obj:Go()
end


function PlayerTest:Go()
    -- load in this short mp3 and play it
    self.thePlayer:load( 'conet_numbers.mp3' )
    self.thePlayer:play()

    -- set the finish callback with a second parameter
    self.thePlayer:setFinishCallback( finishedPlaying, self )
end



local pt = PlayerTest()

function playdate.update()
    gfx.clear(gfx.kColorWhite)
    playdate.drawFPS( 20, 20 )
    gfx.drawText( pt:describe(), 20, 80 )
end

This 415k zip contains the code, the mp3 that I was testing with and the crash dump: https://umlautllama.com/tmp/playdate.TestFileplayer.zip

(note: the mp3 used in the zip is from the Conet Project, snagged from archive.org... it's a 21 second long mp3 file.)

Okay some more info.

  • I thought it might be because I was calling setFinishCallback() after the load() and play(), so i moved it before, and that made no difference.
  • Then I was getting annoyed that I had to wait 21 seconds to find out if my changes worked, so on a button press, i had it seek to 19 seconds and then it stopped crashing.

Long story short, I can work around the issue by changing the code above to:

self.thePlayer:load( 'conet_numbers.mp3' )
self.thePlayer:play()
self.thePlayer:setOffset(0)

the setOffset(0) will let it play as expexcted, and call the callback at the end, as expected.

So something isn't getting set properly on a new file when you only call play(), that IS getting set up properly when setOffset() is called on the fileplayer.

I hope this helps y'all track it down! :smiley: Cheers!

Windows, simulator 1.12.3, seeing similar issues (and 'setOffset(0)' doesn't seem to help):

I had a need to try 'sampleplayer:setFinishCallback' this morning... writing a minigame that has lots of little robots on the screen, the player is zapping away at them... when a robot is hit, there are various phrases they can speak and I didn't like how the phrases stepped all over each other when they were being mowed down, so needed a way to detect when a phrase had completed without doing a 'isPlaying' poll every update cycle - 'setFinishCallback' seemed perfect for this.

tl;dr: 'setFinishCallback' just isn't reliable... it works some times, doesn't other times, it's just iffy as heck. Will roll a different solution, but it would be nice if the callback worked reliably.