[squeak-dev] MixedSound (& consequently stereo) is badly broken in both 32-bit and 64-bit versions

Eliot Miranda eliot.miranda at gmail.com
Sat Sep 19 02:34:18 UTC 2020


Hi All,

     the SampledSound>>#mixSampleCount:into:startingAt:leftVol:rightVol:
method looks to be badly broken.  I don't understand the index scaling
(yet) so I thought I'd throw this out there and see if anyone can spot when
and why this broke.

Here's a simple example that generates a second long A below middle C
(220Hz), smoothing start and stop, and then plays it, so far so good:

| samples sineTable sound |
"1 second of A below middle C (220Hz). 16000 / 220 is 72.72 recurring"
sineTable := SoundPlayer sineTable: 73.
sineTable doWithIndex: "And let's not deafen anyone..."
[:sample :index| sineTable at: index put: sample // 4].
samples := SoundBuffer new: 16000.
1 to: samples size by: sineTable size do:
[:i| samples replaceFrom: i to: (i + sineTable size - 1 min: 16000) with:
sineTable startingAt: 1].
1 to: 146 do: "smooth start and end of the sound"
[:i|
samples at: i put: ((samples at: i) * i / 146) asInteger.
samples at: 16001 - i put: ((samples at: 16001 - i) * i / 146) asInteger].
(SampledSound samples: samples samplingRate: 16000) play

Now let's create a stereo sound image and try and play that:

| samples sineTable sound |
"1 second of A below middle C (220Hz). 16000 / 220 is 72.72 recurring"
sineTable := SoundPlayer sineTable: 73.
sineTable doWithIndex:
[:sample :index| sineTable at: index put: sample // 4].
samples := SoundBuffer new: 16000.
1 to: samples size by: sineTable size do:
[:i| samples replaceFrom: i to: (i + sineTable size - 1 min: 16000) with:
sineTable startingAt: 1].
1 to: 146 do:
[:i|
samples at: i put: ((samples at: i) * i / 146) asInteger.
samples at: 16001 - i put: ((samples at: 16001 - i) * i / 146) asInteger].
sound := SampledSound samples: samples samplingRate: 16000.
sound := MixedSound new
add: sound pan: 0.25;
add: sound pan: 0.75;
yourself.
sound play

Eek!!

You can examine the mixing without hurting your ears by replacing
    "sound play"
with
    "sound computeSamplesForSeconds: sound duration"
which invokes the mixing directly.

Any help making sense of this gratefully received.  Some comments around the

scaledIndex := scaledIndex + scaledIncrement.
scaledIndex >= ScaledIndexOverflow ifTrue: [
overflow := scaledIndex >> IncrementFractionBits.
indexHighBits := indexHighBits + overflow.
scaledIndex := scaledIndex - (overflow << IncrementFractionBits)].

in SampledSound>>#mixSampleCount:into:startingAt:leftVol:rightVol: would be
most welcome.

And if you simply comment out the primitive teh Smaklltalk code produces
garbage also, so the problem does not seem to be Slang but the algorithm
itself.

_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200918/3b37df52/attachment.html>


More information about the Squeak-dev mailing list