[squeak-dev] Sound playing can break in odd manner

tim Rowledge tim at rowledge.org
Fri Dec 5 03:11:35 UTC 2014

(Stephane added explicitly since the code has his initials)

This is  bit puzzling. I’ve just had a case of sound failing on a Pi that looks like it shouldn’t be possible. So far the best I can up with is a thread-safety violation.

The stacktrace shows that it was the FMSound>organ1 sound being played and that whilst handling #doControl (method that deals with the envelopes) we had a case where VolumeEnvelope>computeSlopeAtMSecs: hit a problem right at the end -
	nextRecomputeTime := (mSecs + mSecsForChange) min: loopEndMSecs.
At this point the loopEndMSecs value was nil, which isn’t going to make for a happy execution of #min:.

The only method I can find that sets loopEndMSecs is Envelope>sustainEnd: and it does A Funny Thing. Initially the ivar is set to nil, then some work is done, including #computeValueAtMSecs: before the ivar is actually set to the value needed. Looking at Enveleope>computeValueAtMSecs: it seems that loopEndMSecs gets set to nil in order to fake out the testing for ‘decay phase’ at the beginning of the code.

Now it happens that #sustainEnd: is only meaningfully used by Envelope>duration: and that happens to be used by AbstractSound>stopGracefully which in turn is used by the Scratch stuff to stop a sound. So my suspicion is that we just managed to hit a tick where the SoundPlayer was triggered to Do Its Thing precisely where #sustainEnd: was between setting loopEndMSecs to nil and setting it ‘correctly’. Not likely to happen terribly often but I think we have evidence that happen it can.

I know we’ve got a lot of stuff in the image that is not thread safe but SoundPlayer is one of the cases that has a pretty good chance of being hit. I’m honestly not sure what the best way to fix this would be; probably one should argue that a sound being played and simultaneously altered requires that semaphores get involved. I can also see that probably a fairly simple change to Envelope>computeValueAtMSecs: to add a flag for ‘ignore decay phase code’ would solve this particular case.

What do you think Steph? Anyone?

tim Rowledge; tim at rowledge.org; http://www.rowledge.org/tim
Common sense – so rare it’s a goddam superpower

More information about the Squeak-dev mailing list