[squeak-dev] Sound mixing makes nasty noises

Herbert König herbertkoenig at gmx.net
Sat Dec 26 12:57:29 UTC 2020

Tim, thanks for the recording.

No idea if that happens inside Squeak but basically clipping is not
working. In the image instead of going from positive full-scale to
negative full-scale the signal should just stay at the resp. full-scale.
Instead of clipping 32767 + 1 to 32767  the code uses 32768 as being -
full-scale (wraparound).  See pulse1PosWrap.png. For negative full-scale
the symmetric thing happens. The signal should stay at full-scale there.

mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol:
leftVol rightVol: rightVol  seems to do the right thing:
         leftVol > 0 ifTrue: [
             i := (2 * outIndex) - 1.
             s := (aSoundBuffer at: i) + ((sample * leftVol) //
             s >  32767 ifTrue: [s :=  32767].  "clipping!"
             s < -32767 ifTrue: [s := -32767].  "clipping!"
             aSoundBuffer at: i put: s].
except we can go to 32767 and -32768 IIRC but that's no problem.

If you look at Pi4-pulse-1.wav second 5.2352 it seems there's multiple
wraparounds going on. See pulse1MultipleWrap.
For this I have no explanation because the signal if it were unclipped
looks like going to about 1.5 * full-scale.

pulse2ClipAndWrap shows that somewhere (red mark) the normal clipping is
going on (sounds bad if this strong, that's why I suggested a limiter)
and close to this the wrapping is going on. Maybe there are places where
the clipping is taking something >32767 as max.

Or (a wild idea):
SoundBuffer stores 16 bit unsigned quantities. So if a signal is first
put into a sound buffer w/o clipping and only the mixing does the
clipping and that happens in several places (several sounds generated
independently) that could explain the wrapping. That's why I gave up
when I saw that SoundBuffer only uses 16 bits.

Here Eliot's suggestion from Dec 18:

"But adding a signed 32-bit, or even a signed 64-bit collection for
mixing would be straight forward, except for ensuring it mixes down to
16 bits. A signed 32-bit collection would allow 32k 16-bit sources to be
additively mixed without clipping, right? So an underlying 64-bit
collection is unnecessary. So a MixedSound that adds into an underlying
32-bit signed sequence, and updates a count of added sounds, and does
interpolation when adding sounds of different sample rates, and outputs
16-bit samples derived by dividing the 32-bit sums by the count of added
sounds would be a solution right? "

could make sense. I'd suggest using 32 Bit Float. Seeing loudness being
0.0 to 1.0 and scale in Envelope having Float values > 1 (I see even 25)
I hope that this already happens. But looking at e.g. FMSound's class
var SineTable I see it is a SoundBuffer, on which we operate with float
operations and then we must go back to 16 Bit unsigned to store the
result. Lots of room for human error in this.

All audio precessing (incl. mixing) should be done in Float (usually
normalized to +-1.0) and then use a limiter and then go to 16 bit sound
buffers. Or better use 32 bit Float for output to the OS too. Usually AD
and DA conversion is done with 24 bit by moderately cheap audio cards so
I guess most OSses use 32 bit float. But that's just a guess.



Am 25.12.2020 um 23:39 schrieb tim Rowledge:
> I've managed to record some samples with parecord on the pulseaudio Pi. As usual, the man page for parecord etc was about as helpful as a chocolate teapot in a sauna, but some flailing around on google eventually found a page with something that worked.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pulse1PosWrap.png
Type: image/png
Size: 2464 bytes
Desc: not available
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20201226/fc996f17/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pulse1MultipleWrap.png
Type: image/png
Size: 2735 bytes
Desc: not available
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20201226/fc996f17/attachment-0001.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pulse2ClipAndWrap.png
Type: image/png
Size: 13553 bytes
Desc: not available
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20201226/fc996f17/attachment-0002.png>

More information about the Squeak-dev mailing list