[squeak-dev] The Trunk: Sound-eem.74.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Sep 19 16:11:42 UTC 2020


Eliot Miranda uploaded a new version of Sound to project The Trunk:
http://source.squeak.org/trunk/Sound-eem.74.mcz

==================== Summary ====================

Name: Sound-eem.74
Author: eem
Time: 19 September 2020, 9:11:40.666386 am
UUID: 42a3c2d9-0bed-4310-bcf1-cbe0f3d0653b
Ancestors: Sound-eem.73

Oops! stopPlayerProcess *must* stop the sound system when sent from startPlayerProcessBufferSize:rate:stereo:sound:.  Spo refactor a bit, renaming stopPlayerProcess to stopPlayerProcess: to take a hardStop boolean.  When quitting the argument is false.

Add a 64-bit specific, integer-overflow agnostic version of mixSampleCount:into:startingAt:leftVol:rightVol:, for creating a simpler inline primitive in the 64-bit VM.

=============== Diff against Sound-eem.73 ===============

Item was changed:
  ----- Method: AbstractSound class>>translatedPrimitives (in category 'primitive generation') -----
  translatedPrimitives
  	^#(
  		(FMSound mixSampleCount:into:startingAt:leftVol:rightVol:)
  		(PluckedSound mixSampleCount:into:startingAt:leftVol:rightVol:)
  		(LoopedSampledSound mixSampleCount:into:startingAt:leftVol:rightVol:)
  		(SampledSound mixSampleCount:into:startingAt:leftVol:rightVol:)
+ 		(SampledSound _64bitMixSampleCount:into:startingAt:leftVol:rightVol:)
  		(ReverbSound applyReverbTo:startingAt:count:)
  	).
  !

Item was added:
+ ----- Method: SampledSound>>_64bitMixSampleCount:into:startingAt:leftVol:rightVol: (in category 'playing') -----
+ _64bitMixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
+ 	"Mix the given number of samples with the samples already in the given buffer starting at the given index.
+ 	 Assume that the buffer size is at least (index + count) - 1."
+ 
+ 	| lastIndex outIndex sampleIndex sample i s |
+ 	<inline: #always>
+ 	<var: #aSoundBuffer type: #'short int *'>
+ 	<var: #samples type: #'short int *'>
+ 
+ 	lastIndex := (startIndex + n) - 1.
+ 	outIndex := startIndex.    "index of next stereo output sample pair"
+ 	sampleIndex := indexHighBits + (scaledIndex >> IncrementFractionBits).
+ 	[(sampleIndex <= samplesSize) and: [outIndex <= lastIndex]] whileTrue:
+ 		[sample := ((samples at: sampleIndex) * scaledVol) // ScaleFactor.
+ 		leftVol > 0 ifTrue:
+ 			[i := (2 * outIndex) - 1.
+ 			s := (aSoundBuffer at: i) + ((sample * leftVol) // ScaleFactor).
+ 			s >  32767 ifTrue: [s :=  32767].  "clipping!!"
+ 			s < -32767 ifTrue: [s := -32767].  "clipping!!"
+ 			aSoundBuffer at: i put: s].
+ 		rightVol > 0 ifTrue:
+ 			[i := 2 * outIndex.
+ 			s := (aSoundBuffer at: i) + ((sample * rightVol) // ScaleFactor).
+ 			s >  32767 ifTrue: [s :=  32767].  "clipping!!"
+ 			s < -32767 ifTrue: [s := -32767].  "clipping!!"
+ 			aSoundBuffer at: i put: s].
+ 
+ 		scaledVolIncr ~= 0 ifTrue:
+ 			[scaledVol := scaledVol + scaledVolIncr.
+ 			((scaledVolIncr > 0 and: [scaledVol >= scaledVolLimit]) or:
+ 			 [scaledVolIncr < 0 and: [scaledVol <= scaledVolLimit]])
+ 				ifTrue:  "reached the limit; stop incrementing"
+ 					[scaledVol := scaledVolLimit.
+ 					scaledVolIncr := 0]].
+ 
+ 		scaledIndex := scaledIndex + scaledIncrement.
+ 
+ 		sampleIndex := indexHighBits + (scaledIndex >> IncrementFractionBits).
+ 		outIndex := outIndex + 1].
+ 	count := count - n
+ !

Item was changed:
  ----- Method: SampledSound>>mixSampleCount:into:startingAt:leftVol:rightVol: (in category 'playing') -----
  mixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol
+ 	"Mix the given number of samples with the samples already in the given buffer starting at the given index.
+ 	 Assume that the buffer size is at least (index + count) - 1."
- 	"Mix the given number of samples with the samples already in the given buffer starting at the given index. Assume that the buffer size is at least (index + count) - 1."
  
  	| lastIndex outIndex sampleIndex sample i s overflow |
+ 	<primitive:'primitiveMixSampledSound' module: 'SoundGenerationPlugin'>
+ 	<var: #aSoundBuffer type: #'short int *'>
+ 	<var: #samples type: #'short int *'>
- 	<primitive:'primitiveMixSampledSound' module:'SoundGenerationPlugin'>
- 	<var: #aSoundBuffer declareC: 'short int *aSoundBuffer'>
- 	<var: #samples declareC: 'short int *samples'>
  
+ 	SmallInteger maxVal > 16r3FFFFFFF ifTrue: "In 64-bits we don't have to worry about 2^15 * 2^15 overflow"
+ 		[^self _64bitMixSampleCount: n into: aSoundBuffer startingAt: startIndex leftVol: leftVol rightVol: rightVol].
  	lastIndex := (startIndex + n) - 1.
  	outIndex := startIndex.    "index of next stereo output sample pair"
  	sampleIndex := indexHighBits + (scaledIndex >> IncrementFractionBits).
  	[(sampleIndex <= samplesSize) and: [outIndex <= lastIndex]] whileTrue: [
  		sample := ((samples at: sampleIndex) * scaledVol) // ScaleFactor.
  		leftVol > 0 ifTrue: [
  			i := (2 * outIndex) - 1.
  			s := (aSoundBuffer at: i) + ((sample * leftVol) // ScaleFactor).
  			s >  32767 ifTrue: [s :=  32767].  "clipping!!"
  			s < -32767 ifTrue: [s := -32767].  "clipping!!"
  			aSoundBuffer at: i put: s].
  		rightVol > 0 ifTrue: [
  			i := 2 * outIndex.
  			s := (aSoundBuffer at: i) + ((sample * rightVol) // ScaleFactor).
  			s >  32767 ifTrue: [s :=  32767].  "clipping!!"
  			s < -32767 ifTrue: [s := -32767].  "clipping!!"
  			aSoundBuffer at: i put: s].
  
  		scaledVolIncr ~= 0 ifTrue: [
  			scaledVol := scaledVol + scaledVolIncr.
  			((scaledVolIncr > 0 and: [scaledVol >= scaledVolLimit]) or:
  			 [scaledVolIncr < 0 and: [scaledVol <= scaledVolLimit]])
  				ifTrue: [  "reached the limit; stop incrementing"
  					scaledVol := scaledVolLimit.
  					scaledVolIncr := 0]].
  
  		scaledIndex := scaledIndex + scaledIncrement.
  		scaledIndex >= ScaledIndexOverflow ifTrue: [
  			overflow := scaledIndex >> IncrementFractionBits.
  			indexHighBits := indexHighBits + overflow.
  			scaledIndex := scaledIndex - (overflow << IncrementFractionBits)].
  
  		sampleIndex := indexHighBits + (scaledIndex >> IncrementFractionBits).
  		outIndex := outIndex + 1].
+ 	count := count - n!
- 	count := count - n.
- !

Item was changed:
  ----- Method: SoundPlayer class>>shutDown: (in category 'snapshotting') -----
  shutDown: quitting
  	"Stop player process, for example before snapshotting."
  
+ 	quitting ifTrue:
+ 		[self stopPlayerProcess: false.
+ 		 ReverbState := nil]!
- 	quitting ifTrue: [
- 		self stopPlayerProcess.
- 		ReverbState := nil].!

Item was changed:
  ----- Method: SoundPlayer class>>startPlayerProcessBufferSize:rate:stereo:sound: (in category 'player process') -----
  startPlayerProcessBufferSize: bufferSize rate: samplesPerSecond stereo: stereoFlag sound: aSound
  	"Start the sound player process. Terminate the old process, if any."
  	"SoundPlayer startPlayerProcessBufferSize: 1000 rate: 11025 stereo: false"
  
+ 	self stopPlayerProcess: true.
+ 	aSound ifNotNil: "stopPlayerProcess: ensures ActiveSounds are empty..."
+ 		[ActiveSounds add: aSound].
- 	self stopPlayerProcess.
- 	aSound
- 		ifNil:[ActiveSounds := OrderedCollection new]
- 		ifNotNil:[ActiveSounds := OrderedCollection with: aSound].
  	Buffer := SoundBuffer newStereoSampleCount: (bufferSize // 4) * 4.
+ 	LastBuffer ifNotNil:
+ 		[LastBuffer := SoundBuffer basicNew: Buffer basicSize].
- 	LastBuffer ifNotNil:[LastBuffer := SoundBuffer basicNew: Buffer basicSize].
  	PlayerSemaphore := Semaphore forMutualExclusion.
  	SamplingRate := samplesPerSecond.
  	Stereo := stereoFlag.
  	SoundSupported := true. "Assume so"
  	UseReadySemaphore := true.  "set to false if ready semaphore not supported by VM"
  	Smalltalk newExternalSemaphoreDo: [ :semaphore :index |
  		ReadyForBuffer := semaphore.
  		self primSoundStartBufferSize: Buffer stereoSampleCount
  			rate: samplesPerSecond
  			stereo: Stereo
  			semaIndex: index ].
  	"Check if sound start prim was successful"
  	SoundSupported ifFalse:[
  		Smalltalk unregisterExternalObject: ReadyForBuffer.
  		ReadyForBuffer := nil.
  		^self ].
  	UseReadySemaphore
  		ifTrue: [PlayerProcess := [SoundPlayer playLoop] newProcess]
  		ifFalse: [PlayerProcess := [SoundPlayer oldStylePlayLoop] newProcess].
  	UseReverb ifTrue: [self startReverb].
  
  	PlayerProcess
  		name: 'Sound Player (', ActiveSounds size asString, ')';
  		priority: Processor userInterruptPriority;
  		resume!

Item was removed:
- ----- Method: SoundPlayer class>>stopPlayerProcess (in category 'player process') -----
- stopPlayerProcess
- 	"Stop the sound player process."
- 	"SoundPlayer stopPlayerProcess"
- 
- 	PlayerProcess ifNotNil:
- 		[PlayerProcess ~~ Processor activeProcess ifTrue:
- 			[PlayerProcess terminate].
- 		 PlayerProcess := nil].
- 	"Don't load the SoundPlugin if it is not in use..."
- 	self soundPluginActive ifTrue: [self primSoundStop].
- 	ActiveSounds isEmpty ifFalse:
- 		[ActiveSounds := OrderedCollection new].
- 	Buffer := nil.
- 	PlayerSemaphore isEmpty ifFalse:
- 		[PlayerSemaphore := Semaphore forMutualExclusion].
- 	ReadyForBuffer ifNotNil:
- 		[Smalltalk unregisterExternalObject: ReadyForBuffer.
- 		 ReadyForBuffer := nil]!

Item was added:
+ ----- Method: SoundPlayer class>>stopPlayerProcess: (in category 'player process') -----
+ stopPlayerProcess: hardStop
+ 	"Stop the sound player process."
+ 	"SoundPlayer stopPlayerProcess"
+ 
+ 	PlayerProcess ifNotNil:
+ 		[PlayerProcess ~~ Processor activeProcess ifTrue:
+ 			[PlayerProcess terminate].
+ 		 PlayerProcess := nil].
+ 	(hardStop or: [self soundPluginActive]) ifTrue: [self primSoundStop].
+ 	ActiveSounds isEmpty ifFalse:
+ 		[ActiveSounds := OrderedCollection new].
+ 	Buffer := nil.
+ 	PlayerSemaphore isEmpty ifFalse:
+ 		[PlayerSemaphore := Semaphore forMutualExclusion].
+ 	ReadyForBuffer ifNotNil:
+ 		[Smalltalk unregisterExternalObject: ReadyForBuffer.
+ 		 ReadyForBuffer := nil]!



More information about the Squeak-dev mailing list