[Pkg] 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 Packages
mailing list