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

Levente Uzonyi leves at caesar.elte.hu
Sat Sep 19 11:47:08 UTC 2020


Hi Eliot,

On Fri, 18 Sep 2020, Eliot Miranda wrote:

> 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;

If you replace the above line with

> add: sound copy pan: 0.75;

then the produced sound should be okay. Sound objects have state, and if 
you pass the same object twice, the state will be messed up.


Levente

> 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
> 
>


More information about the Squeak-dev mailing list