[squeak-dev] Sound mixing makes nasty noises

Herbert König herbertkoenig at gmx.net
Tue Dec 29 18:52:54 UTC 2020

I changed playLoop to just copy the current SoundBuffer into a
collection. I got some 11 seconds sound (2 below)
Each buffer I differentiated and took the abs value. (see attached st)
Of those I took the max. In case of wraparound that would be close to 64k.
The zeroes in these buffers are the clippings. (3 below) Again I took
the max. (4 below).

I can't email screenshots from the Pi but I did it on a Pi too. I used
Tim's first snippet. I found a lot of clipping inside Squeak and not a
single wraparound in several attempts.

Same observation id waggling the Keyboard or playing my 6 voiced C major
while waggling the keyboard morph.

On the Pi3 I still lost buffers (getting 7 seconds worth of buffers from
10+ seconds of Audio). I would not search in the Squeak Smalltalk code
for the problem but would suspect the primitive where Squeak hands the
output to Raspbian.

That said clipping still makes for horrible sound (SCNR :-).



Am 29.12.2020 um 12:38 schrieb Herbert König:
> Am 28.12.2020 um 22:48 schrieb tim Rowledge:
>>> On 2020-12-28, at 10:36 AM, Herbert <herbertkoenig at gmx.net> wrote:
>>> Inside Squeak I saw a lot of clipping as expected, outside I saw
>>> wrapping whenever it clipped inside.
>> That would be an interesting thing to prove conclusively. It's not
>> unimagineable that there could be a bug in a unix sound library.
> I'd suspect the Squeak primitive that hands the buffers to the OS before
> looking into OS code.
> Would it be conclusive to record the outside for a minute or so, read
> that file and count wrapping
> (sample(n) = +fullscale and sample(n+1) = -fullscale) or (sample(n) =
> -fullscale and sample(n+1) = +fullscale)
> and do the same for all SoundBuffers we get hold of inside Squeak during
> the recording? (repeatedly checking SoundBuffer allInstances)
>> Maybe if we make a crafted sound buffer with a clean waveform that we
>> know never gets clipped but does hit the maxval/minval and play it
>> directly with no mixing related calls (because the mixer code does
>> volume scaling etc and internal clipping) we might see what comes out
>> of pulseaudio and indeed alsa.
> AbstractSound or the like has a class var Sine with that but I feel
> that's directed at finding a bug in the OS and discards the possibility
> of Squeak messing it up. And the organ sounds used are predictable
> enough re clipping but I hope the individual envelopes add some
> randomness to cover more cases.
> Cheers,
> Herbert

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20201229/86d9c110/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hnbcejajmlkkicge.png
Type: image/png
Size: 234140 bytes
Desc: not available
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20201229/86d9c110/attachment-0001.png>
-------------- next part --------------
'From Squeak5.3alpha of 4 October 2019 [latest update: #19044] on 29 December 2020 at 4:32:13 pm'!

!SoundBuffer methodsFor: 'utilities' stamp: 'hk 12/29/2020 16:17'!
	"return n Array consisting of the differntiated (n - n+1st samples)
	hackish unoptimized"

	| leftSamples absDiff |
	leftSamples := self splitStereo first.
	absDiff := Array new: leftSamples size -1.
	1 to: leftSamples size - 1 do: [:i | 
		absDiff at: i put: ((leftSamples at: i) - (leftSamples at: i+1)) abs].
	^absDiff! !
-------------- next part --------------
'From Squeak5.3alpha of 4 October 2019 [latest update: #19044] on 29 December 2020 at 4:01:54 pm'!

!SoundPlayer class methodsFor: 'player process' stamp: 'hk 12/29/2020 15:59'!
	"The sound player process loop."
	| bytesPerSlice count willStop mayStop buffers|
	buffers := OrderedCollection new.
	mayStop := self stopSoundWhenDone.
	bytesPerSlice := Stereo ifTrue: [4] ifFalse: [2].
		[(count := self primSoundAvailableBytes // bytesPerSlice) > 100]
			whileFalse: [ReadyForBuffer wait].

		count := count min: Buffer stereoSampleCount.
		PlayerSemaphore critical: [
			ActiveSounds := ActiveSounds select: [:snd | snd samplesRemaining > 0].
			ActiveSounds do: [:snd |
				snd ~~ SoundJustStarted ifTrue: [
					snd playSampleCount: count into: Buffer startingAt: 1]].
			ReverbState == nil ifFalse: [
				ReverbState applyReverbTo: Buffer startingAt: 1 count: count].
			buffers add: Buffer copy.
			self primSoundPlaySamples: count from: Buffer startingAt: 1.
			willStop := mayStop and:[
						(ActiveSounds size = 0) and:[
							self isAllSilence: Buffer size: count]].
			LastBuffer ifNotNil:[
				LastBuffer replaceFrom: 1 to: LastBuffer size with: Buffer startingAt: 1.
				ifTrue:[self shutDown: true. PlayerProcess := nil]
				ifFalse:[Buffer primFill: 0].
			SoundJustStarted := nil].
		willStop ifTrue:[buffers explore. ^self] ] repeat
! !

More information about the Squeak-dev mailing list