[squeak-dev] The Inbox: Sound-HenrikSperreJohansen.28.mcz
Hannes Hirzel
hannes.hirzel at gmail.com
Fri Apr 15 17:26:17 UTC 2011
Henrik,
maybe you can explain a bit the ideas behind this change?
--Hannes
On Fri, 21 Jan 2011 19:11:23.897 0000, commits at source.squeak.org
<commits at source.squeak.org> wrote:
> A new version of Sound was added to project The Inbox:
> http://source.squeak.org/inbox/Sound-HenrikSperreJohansen.28.mcz
>
> ==================== Summary ====================
>
> Name: Sound-HenrikSperreJohansen.28
> Author: HenrikSperreJohansen
> Time: 21 January 2011, 8:11:33.349 pm
> UUID: 9292e731-70f3-674a-8e71-fc26c493d578
> Ancestors: Sound-ul.26
>
> Update to use pragma-based sound preferences
>
> =============== Diff against Sound-ul.26 ===============
>
> Item was changed:
> ----- Method: BaseSoundSystem>>beep (in category 'playing') -----
> beep
> "There is sound support, so we use the default
> sampled sound for a beep."
>
> + SoundService soundEnabled ifTrue: [
> - Preferences soundsEnabled ifTrue: [
> SampledSound beep]!
>
> Item was changed:
> ----- Method: BaseSoundSystem>>playSampledSound:rate: (in category
> 'playing') -----
> playSampledSound: samples rate: rate
>
> + SoundService soundEnabled ifTrue: [
> - Preferences soundsEnabled ifTrue: [
> (SampledSound samples: samples samplingRate: rate) play]!
>
> Item was changed:
> ----- Method: BaseSoundSystem>>playSoundNamed: (in category 'playing')
> -----
> playSoundNamed: soundName
> "There is sound support, so we play the given sound."
>
> + SoundService soundEnabled ifTrue: [
> - Preferences soundsEnabled ifTrue: [
> SampledSound playSoundNamed: soundName asString]!
>
> Item was changed:
> ----- Method: BaseSoundSystem>>playSoundNamed:ifAbsentReadFrom: (in
> category 'playing') -----
> playSoundNamed: soundName ifAbsentReadFrom: aifFileName
>
> + SoundService soundEnabled ifTrue: [
> - Preferences soundsEnabled ifTrue: [
> (SampledSound soundNames includes: soundName) ifFalse: [
> (FileDirectory default fileExists: aifFileName) ifTrue: [
> SampledSound
> addLibrarySoundNamed: soundName
> fromAIFFfileNamed: aifFileName]].
> (SampledSound soundNames includes: soundName) ifTrue: [
> SampledSound playSoundNamed: soundName]]!
>
> Item was changed:
> ----- Method: BaseSoundSystem>>playSoundNamedOrBeep: (in category
> 'playing') -----
> playSoundNamedOrBeep: soundName
> "There is sound support, so we play the given sound
> instead of beeping."
>
> + SoundService soundEnabled ifTrue: [
> - Preferences soundsEnabled ifTrue: [
> ^self playSoundNamed: soundName]!
>
> Item was changed:
> Object subclass: #SoundPlayer
> instanceVariableNames: ''
> + classVariableNames: 'ActiveSounds Buffer BufferIndex BufferMSecs
> LastBuffer PlayerProcess PlayerSemaphore ReadyForBuffer ReverbState
> SamplingRate SoundJustStarted SoundSupported SoundsShouldStartQuick
> SoundsStopWhenDone Stereo UseReadySemaphore UseReverb'
> - classVariableNames: 'ActiveSounds Buffer BufferIndex BufferMSecs
> LastBuffer PlayerProcess PlayerSemaphore ReadyForBuffer ReverbState
> SamplingRate SoundJustStarted SoundSupported Stereo UseReadySemaphore
> UseReverb'
> poolDictionaries: ''
> category: 'Sound-Synthesis'!
>
> Item was changed:
> ----- Method: SoundPlayer class>>canStartPlayer (in category 'playing')
> -----
> canStartPlayer
> "Some platforms do no support simultaneous record and play. If this is
> one of those platforms, return false if there is a running SoundRecorder."
>
> + ^SoundRecorder canRecordWhilePlaying
> + or: [ SoundRecorder anyActive not]
> +
> - Preferences canRecordWhilePlaying ifTrue: [^ true].
> - SoundRecorder anyActive ifTrue:[^false].
> - ^ true
> !
>
> Item was added:
> + ----- Method: SoundPlayer class>>defaultQuickStartForPlatform (in category
> 'preferences') -----
> + defaultQuickStartForPlatform
> +
> + ^ Smalltalk os platformName = 'Mac OS'.
> + !
>
> Item was added:
> + ----- Method: SoundPlayer class>>defaultStopSoundForPlatform (in category
> 'preferences') -----
> + defaultStopSoundForPlatform
> +
> + ^(Smalltalk os platformName = 'Mac OS') not
> + !
>
> Item was changed:
> ----- Method: SoundPlayer class>>playLoop (in category 'player process')
> -----
> playLoop
> "The sound player process loop."
>
> | bytesPerSlice count willStop mayStop |
> + mayStop := self stopSoundWhenDone.
> - 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].
> ].
> !
>
> Item was changed:
> ----- Method: SoundPlayer class>>resumePlaying:quickStart: (in category
> 'playing') -----
> resumePlaying: aSound quickStart: quickStart
> "Start playing the given sound without resetting it; it will resume
> playing from where it last stopped. If quickStart is true, then try to start
> playing the given sound immediately."
>
> | doQuickStart |
> + SoundService soundEnabled ifFalse: [^ self].
> - Preferences soundsEnabled ifFalse: [^ self].
> doQuickStart := quickStart.
> + self soundQuickStart ifFalse: [doQuickStart := false].
> - Preferences soundQuickStart ifFalse: [doQuickStart := false].
> PlayerProcess == nil ifTrue: [
> self canStartPlayer ifFalse: [^ self].
> ^self startUpWithSound: aSound].
>
> PlayerSemaphore critical: [
> (ActiveSounds includes: aSound)
> ifTrue: [doQuickStart := false]
> ifFalse: [
> doQuickStart ifFalse: [ActiveSounds add: aSound]]].
>
> "quick-start the given sound, unless the sound player has just started"
> doQuickStart ifTrue: [self startPlayingImmediately: aSound].
> !
>
> Item was added:
> + ----- Method: SoundPlayer class>>soundQuickStart (in category
> 'preferences') -----
> + soundQuickStart
> + <preference: 'Quickstart Sounds'
> + category: 'media'
> + description: 'If true, attempt to start playing sounds using option
> "quick start"'
> + type: #Boolean>
> +
> + ^SoundsShouldStartQuick ifNil: [self defaultQuickStartForPlatform]!
>
> Item was added:
> + ----- Method: SoundPlayer class>>soundQuickStart: (in category
> 'preferences') -----
> + soundQuickStart: aBoolean
> +
> +
> + SoundsShouldStartQuick := aBoolean!
>
> Item was added:
> + ----- Method: SoundPlayer class>>stopSoundWhenDone (in category
> 'preferences') -----
> + stopSoundWhenDone
> + <preference: 'Stop sounds when done'
> + category: 'media'
> + description: 'If true, the sound player is shut down after playing
> finished'
> + type: #Boolean>
> +
> + ^SoundsStopWhenDone ifNil: [self defaultStopSoundForPlatform]!
>
> Item was added:
> + ----- Method: SoundPlayer class>>stopSoundWhenDone: (in category
> 'preferences') -----
> + stopSoundWhenDone: aBoolean
> +
> + SoundsStopWhenDone := aBoolean!
>
> Item was changed:
> ----- Method: SoundRecorder class>>canRecordWhilePlaying (in category
> 'accessing') -----
> canRecordWhilePlaying
> "Return true if this platform supports simultaneous sound recording and
> playback."
> + <preference: 'Record while playing'
> + category: 'media'
> + description: 'If true, recording and playing sounds concurrently is
> permitted (platform dependent)'
> + type: #Boolean>
> + ^CanRecordWhilePlaying ifNil: [false].
> -
> - ^Preferences canRecordWhilePlaying. "now in preferences"
> !
>
> Item was added:
> + ----- Method: SoundRecorder class>>canRecordWhilePlaying: (in category
> 'accessing') -----
> + canRecordWhilePlaying: aBoolean
> +
> + CanRecordWhilePlaying := aBoolean
> + !
>
> Item was changed:
> ----- Method: SoundRecorder class>>initialize (in category 'class
> initialization') -----
> initialize
> "SoundRecorder initialize"
> "Details: Some computers cannot record and playback sound at the same
> time. If CanRecordWhilePlaying is false, then the SoundRecorder alternates
> between recording and playing. If it is true, sounds can be playing during
> recording."
>
> + CanRecordWhilePlaying := false.
> - CanRecordWhilePlaying := #ignoredNowInPreferences.
> !
>
> Item was changed:
> ----- Method: SoundRecorder>>pause (in category 'recording controls')
> -----
> pause
> "Go into pause mode. The record level continues to be updated, but no
> sound is recorded."
>
> paused := true.
> ((currentBuffer ~~ nil) and: [nextIndex > 1])
> ifTrue: [self emitPartialBuffer.
> self allocateBuffer].
>
> soundPlaying ifNotNil: [
> soundPlaying pause.
> soundPlaying := nil].
> "Note: there can be problems if canRecordWhilePlaying is true. Recorders
> which only pause will inhibit other recorders from recording. I chose to
> make #stopPlaying unconditional in a subclass. The same might be appropriate
> here at the expense of making recorders resumable"
>
> + CanRecordWhilePlaying ifFalse: [self stopRecording].
> - Preferences canRecordWhilePlaying ifFalse: [self stopRecording].
> !
>
> Item was changed:
> ----- Method: SoundRecorder>>resumeRecording (in category 'recording
> controls') -----
> resumeRecording
> "Continue recording from the point at which it was last paused."
>
> self flag: #bob.
> "Note: If canRecordWhilePlaying is true, then recordings may never get
> started (at least by this method). One possibility, used in a subclass, is
> to make the #startPlaying unconditional. Another would be to use
> #startPlaying instead of #resumePlaying in appropriate cases"
>
> + CanRecordWhilePlaying ifFalse: [self startRecording].
> - Preferences canRecordWhilePlaying ifFalse: [self startRecording].
> paused := false.
> !
>
> Item was changed:
> ----- Method: SoundRecorder>>startRecording (in category 'recording
> controls') -----
> startRecording
> "Turn of the sound input driver and start the recording process.
> Initially, recording is paused."
>
> | semaIndex |
> recordLevel ifNil: [recordLevel := 0.5]. "lazy initialization"
> + CanRecordWhilePlaying ifFalse: [SoundPlayer shutDown].
> - Preferences canRecordWhilePlaying ifFalse: [SoundPlayer shutDown].
> recordProcess ifNotNil: [self stopRecording].
> paused := true.
> meteringBuffer := SoundBuffer newMonoSampleCount: 1024.
> meterLevel := 0.
> self allocateBuffer.
> bufferAvailableSema := Semaphore new.
> semaIndex := Smalltalk registerExternalObject: bufferAvailableSema.
> self primStartRecordingDesiredSampleRate: samplingRate asInteger
> stereo: stereo
> semaIndex: semaIndex.
> RecorderActive := true.
> samplingRate := self primGetActualRecordingSampleRate.
> self primSetRecordLevel: (1000.0 * recordLevel) asInteger.
> recordProcess := [self recordLoop] newProcess.
> recordProcess priority: Processor userInterruptPriority.
> recordProcess resume.
> !
>
>
>
More information about the Squeak-dev
mailing list
|