Shifting sound pitch on the fly?

What's the best performing way to do a continuous sound that rises and falls in realtime, changing every frame in response to player actions?

No details needed, just the basics: a) Should it be a sample or a synth? And b) what API method is recommended?

(My ultimate aim is to have not just 1 but 3 or 4 tones that will come in and out of harmony as the player acts. But I don't want to slow down the visuals which are already taxing the CPU! If realtime pitch shifts can't be done efficiently, I have other ideas.)

TIA!

3 Likes

A basic way to do this is with a synth. You can then play any note with synth:playNote(n) (n just being a number value). Here’s a simple program that changes the note with the crank:

local synth = playdate.sound.synth.new(playdate.sound.kWaveSquare)
local n = 1

function play()
	synth:stop()
	synth:playNote(n)
end

function playdate.update()
end

function playdate.cranked()
	n = math.floor(playdate.getCrankPosition())
	play()
end
1 Like

As for samples vs synths, my hunch is that there won't be much difference (and above a threshold frequency, synths switch from the generator algorithm to a wavetable [i.e., sample] to avoid aliasing). Both should be pretty efficient. The MIDI Player demo uses synths and samples, playing maybe a dozen sounds simultaneously, and I don't think its CPU usage is very high.

1 Like

Thanks! What about changing the pitch of an already-playing sound every frame? I don't want to keep re-triggering a new note, but rather a smooth rise and fall of a sound that just keeps going.

But all mentions of "pitch" in the Lua SDK docs seem to be about playing a single note. Is there an approach to do this?

I think you're looking for sampleplayer:setRate() and fileplayer:setRate(). From my own testing, the higher you set the sample rate the bigger the performance impact will be. You can kind of get around this by importing a higher pitched sample to begin with, and then use a lower range of values for setRate(). Also using mono samples will have much less impact on performance than stereo samples.

1 Like

That should do it, thanks! And a low bitrate will be just fine for the low-fi "radio" sound I'm going for.

(Is there an equivalent for synth sounds? Just to know my options...)