Launch a sound (sampleplayer or fileplayer) at rate 1
then use setRate(0.5) and you will hear both sounds (rate 1 and rate 0.5). Same thing happens when you start with play(1,1) and then stop() + play(1,0.5).
Also getRate gives always 1 with sampleplayer if you change the rate through play method (but it is correctly updated when using setRate).
Expected result:
changing rate should change the rate of the current sample and not launch another one
sampleplayer:getRate should give the correct rate
Code Sample (put in update loop). Test by pressing A then B:
if playdate.buttonIsPressed( playdate.kButtonA ) then
fp = playdate.sound.sampleplayer.new( "sounds/Drumming Sticks" )
fp:play(1,0.5)
end
if playdate.buttonIsPressed(playdate.kButtonB) then
fp:stop()
fp:play(1,1) -- you can hear both sound at rate 0.5 and at rate 1
end
if fp then
gfx.drawText("speed: " .. fp:getRate(), 5, 5) -- display always 1 (but it should display 0.5 when pressing A)
end
You're using buttonIsPressed(), which means you're creating a new sampleplayer on each frame that the A button is held down — and this can be several frames even for a quick tap. Then you assign them all to the same variable (fp), so you're only calling stop() on the most recent player.
I would try using buttonJustPressed() instead, because it's guaranteed to return true at most once per button press.
I believe that's as designed — you can either set a default rate for the player using setRate(), or you can pass one to play() to override the default just for that playback. Passing a rate to play() doesn't change the player's default rate, which is what's returned by getRate().
Ok I understand. Thanks for your explanation. Maybe that deserves better explanation in the documentation because there is no mention of default rate and current rate for current play.
Ah, nope, that's a bug. If you use player:setRate() it correctly stores the value for subsequent getRate() calls, but if you give the rate argument in play() it doesn't. It's an easy fix, though! I'll push that now, hopefully get that into 1.13
Oh, I didn't quite grok what Dan was talking about there, thankfully he clarified in the issue I filed. setRate() sets the rate that gets played when you call play() without the rate argument. So if you do player:setRate(0.5) then player:play(1,2.0), player:getRate() should return 2.0 while the sample is playing (at 2x speed) and then 0.5 after it's done. There's a lot more going on here than I'd expected! Let me know if that jibes with what you're expecting and I'll make it work that way.