hardware 1.13.1 (affected)
Mac OS simulator 1.13.1 (NOT affected)
Tried this using both a WaveSynth and SampleSynth. Both affected.
Creating a sequence from a midi and creating instruments works fine before playing the sequence.
Now, while the sequence is playing, I might want to change the instrument for a track. This also works fine as long as no note is playing for that track.
If there is a note playing, however there is a high chance of a crash on device, with the error
SoundSource 0x<address> doesn't have a lua wrapper
I have isolated this to the setInstrument call; creation of the instrument in itself does not cause the crash.
When removing the sequence:play() call, the crash does not occur immediately, but the track goes silent. It might then crash when the sequence:play() call is invoked at a later time.
local s = snd.synth.new(trackProps.instrument.id or snd.kWaveSawtooth)
s:setVolume(trackProps.volume or defaultWaveVolume)
trackProps.attack or defaultWaveAttack,
trackProps.decay or defaultWaveDecay,
trackProps.sustain or defaultWaveSustain,
trackProps.release or defaultWaveRelease
local inst = snd.instrument.new()
for _= 1, polyphony do
local track = self:getTrack(trackNum)
track:setInstrument(inst) -- when commenting this line, crash does not occur
--while the sequence is already playing, calling :play() notifies it of the changes
Thanks for the demo! I think when I saw the first post I didn't see an easy way for me to put the code together to try and reproduce the issue so I put it on the "look at this later" stack and moved on. That stack is growing way too fast these days.
I also get the crash in the simulator, which makes it a lot easier to debug. Looks like the problem is there's a missing reference to the synth, so the synth gets cleaned up between the time it calls the finish callback--which, for synths created in Lua, is a shim that passes the message from the audio task to the main task--and when the main task picks it up. Ah! There's no reference because the playing is done in lower-level code out of sight of Lua. I'll have to add a way for sequences to notify when notes start (and stop, for symmetry's sake). If you track the synth lifespan manually by adding them to a table after creating them then removing them when they've been replaced you should be able to avoid this bug. The trick is to store the reference in on the key side of the table so you get fast lookups:
activeSynths[synth] = true -- adds a reference so synth doesn't scope out
activeSynths[synth] = nil -- clears the reference, allowing it to be collected
As for the problem of instruments not working right when you replace them in a playing sequence, the general issue there is I hadn't expected anyone would do that. But specifically, instruments are only added to their sound channels when you call sequence:play(). I was going to say that you could manage this manually by adding the instruments to a separate channel then removing them, but in the Lua code we delay adding sources to channels until you call play()/playNote() on them. And we're stuck again with the problem that Lua never sees those calls when triggered by a sequence.
I've filed a handful of issues for this. Thank you so much for digging these up, and especially for the demo. Having a reproducible test case that shows exactly what the issue is and that I can run in the debugger makes a world of difference.