'From Squeak3.3alpha of 24 January 2002 [latest update: #4657] on 25 January 2002 at 4:23:31 pm'! "Change Set: SndPlayerFeeback-ar Date: 25 January 2002 Author: Andreas Raab Published in Squeak 3.3a as 4659SndPlayerFeeback-ar.cs Allow feedback from the SoundPlayer to use by other applications (e.g., spectrum analyzers etc)."! Object subclass: #SoundPlayer instanceVariableNames: '' classVariableNames: 'ActiveSounds Buffer BufferIndex BufferMSecs LastBuffer PlayerProcess PlayerSemaphore ReadyForBuffer ReverbState SamplingRate SoundJustStarted SoundSupported Stereo UseReadySemaphore UseReverb ' poolDictionaries: '' category: 'Sound-Synthesis'! !SoundPlayer class methodsFor: 'initialization' stamp: 'ar 1/24/2002 18:40'! useLastBuffer ^LastBuffer notNil! ! !SoundPlayer class methodsFor: 'initialization' stamp: 'ar 1/24/2002 18:47'! useLastBuffer: aBool Buffer ifNil:[^self]. aBool ifTrue:[LastBuffer _ SoundBuffer basicNew: Buffer basicSize] ifFalse:[LastBuffer _ nil] ! ! !SoundPlayer class methodsFor: 'player process' stamp: 'ar 1/24/2002 18:41'! lastPlayBuffer ^LastBuffer! ! !SoundPlayer class methodsFor: 'player process' stamp: 'ar 1/24/2002 15:49'! playLoop "The sound player process loop." | bytesPerSlice count willStop mayStop | mayStop _ Preferences soundStopWhenDone. bytesPerSlice _ Stereo ifTrue: [4] ifFalse: [2]. [true] whileTrue: [ [(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]. 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. ]. willStop ifTrue:[self shutDown. PlayerProcess _ nil] ifFalse:[Buffer primFill: 0]. SoundJustStarted _ nil]. willStop ifTrue:[^self]. ]. ! ! !SoundPlayer class methodsFor: 'player process' stamp: 'ar 1/24/2002 18:42'! 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. aSound ifNil:[ActiveSounds _ OrderedCollection new] ifNotNil:[ActiveSounds _ OrderedCollection with: aSound]. Buffer _ SoundBuffer newStereoSampleCount: (bufferSize // 4) * 4. LastBuffer ifNotNil:[LastBuffer _ SoundBuffer basicNew: Buffer basicSize]. PlayerSemaphore _ Semaphore forMutualExclusion. SamplingRate _ samplesPerSecond. Stereo _ stereoFlag. ReadyForBuffer _ Semaphore new. SoundSupported _ true. "Assume so" UseReadySemaphore _ true. "set to false if ready semaphore not supported by VM" self primSoundStartBufferSize: Buffer stereoSampleCount rate: samplesPerSecond stereo: Stereo semaIndex: (Smalltalk registerExternalObject: ReadyForBuffer). "Check if sound start prim was successful" SoundSupported ifFalse:[^self]. UseReadySemaphore ifTrue: [PlayerProcess _ [SoundPlayer playLoop] newProcess] ifFalse: [PlayerProcess _ [SoundPlayer oldStylePlayLoop] newProcess]. UseReverb ifTrue: [self startReverb]. PlayerProcess priority: Processor userInterruptPriority. PlayerProcess resume.! !