[Pkg] The Trunk: Sound-ul.29.mcz
commits at source.squeak.org
commits at source.squeak.org
Sat Jun 18 08:57:27 UTC 2011
Levente Uzonyi uploaded a new version of Sound to project The Trunk:
http://source.squeak.org/trunk/Sound-ul.29.mcz
==================== Summary ====================
Name: Sound-ul.29
Author: ul
Time: 17 June 2011, 4:46:36.573 pm
UUID: 144555d5-76b9-a143-a11f-aead01847127
Ancestors: Sound-nice.28
- Don't add a delay to SoundRecorder >> #recordLoop if the VM is not unix.
- Use #repeat instead of [ true ] whileTrue and friends.
- Use #displayProgressFrom:to:during: instead of #displayProgressAt:from:to:during:.
=============== Diff against Sound-nice.28 ===============
Item was changed:
----- Method: AbstractSound>>storeSampleCount:bigEndian:on: (in category 'file i/o') -----
storeSampleCount: samplesToStore bigEndian: bigEndianFlag on: aBinaryStream
"Store my samples on the given stream at the current SoundPlayer sampling rate. If bigFlag is true, then each 16-bit sample is stored most-significant byte first (AIFF files), otherwise it is stored least-significant byte first (WAV files). If self isStereo is true, both channels are stored, creating a stereo file. Otherwise, only the left channel is stored, creating a mono file."
| bufSize stereoBuffer reverseBytes |
self reset.
bufSize := (2 * self samplingRate rounded) min: samplesToStore. "two second buffer"
stereoBuffer := SoundBuffer newStereoSampleCount: bufSize.
reverseBytes := bigEndianFlag ~= (SmalltalkImage current isBigEndian).
'Storing audio...'
+ displayProgressFrom: 0 to: samplesToStore during: [:bar | | remaining out |
- displayProgressAt: Sensor cursorPoint
- from: 0 to: samplesToStore during: [:bar | | remaining out |
remaining := samplesToStore.
[remaining > 0] whileTrue: [
bar value: samplesToStore - remaining.
stereoBuffer primFill: 0. "clear the buffer"
self playSampleCount: (bufSize min: remaining) into: stereoBuffer startingAt: 1.
out := self isStereo
ifTrue: [stereoBuffer]
ifFalse: [stereoBuffer extractLeftChannel].
reverseBytes ifTrue: [out reverseEndianness].
(aBinaryStream isKindOf: StandardFileStream)
ifTrue: [ "optimization for files: write sound buffer directly to file"
aBinaryStream next: (out size // 2) putAll: out startingAt: 1] "size in words"
ifFalse: [ "for non-file streams:"
1 to: out monoSampleCount do: [:i | aBinaryStream int16: (out at: i)]].
remaining := remaining - bufSize]].
!
Item was changed:
----- Method: SoundPlayer class>>oldStylePlayLoop (in category 'player process') -----
oldStylePlayLoop
"This version of the play loop is used if the VM does not yet support sound primitives that signal a semaphore when a sound buffer becomes available."
| bytesPerSlice count |
bytesPerSlice := Stereo ifTrue: [4] ifFalse: [2].
+ [
- [true] whileTrue: [
[(count := self primSoundAvailableBytes // bytesPerSlice) > 100]
whileFalse: [(Delay forMilliseconds: 1) 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.
Buffer primFill: 0.
+ SoundJustStarted := nil]] repeat
- SoundJustStarted := nil]].
!
Item was changed:
----- Method: SoundPlayer class>>playLoop (in category 'player process') -----
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] ] repeat
- willStop ifTrue:[^self].
- ].
!
Item was changed:
----- Method: SoundRecorder>>recordLoop (in category 'private') -----
recordLoop
"Record process loop that records samples."
+ | n sampleCount linuxWorkaroundBlock |
- | n sampleCount |
n := 0.
+ linuxWorkaroundBlock := Smalltalk os platformName = 'unix'
+ ifTrue: [ [ (Delay forMilliseconds: 20) wait ] ]
+ ifFalse: [ nil ].
+ [
- [true] whileTrue: [
n = 0 ifTrue: [bufferAvailableSema wait].
paused
ifTrue: [
n := self primRecordSamplesInto: meteringBuffer startingAt: 1.
self meterFrom: 1 count: n in: meteringBuffer]
ifFalse: [
n := self primRecordSamplesInto: currentBuffer startingAt: nextIndex.
self meterFrom: nextIndex count: n in: currentBuffer.
nextIndex := nextIndex + n.
stereo
ifTrue: [sampleCount := currentBuffer stereoSampleCount]
ifFalse: [sampleCount := currentBuffer monoSampleCount].
nextIndex > sampleCount
ifTrue: [
self emitBuffer: currentBuffer.
self allocateBuffer]].
"workaround for OSS emulation on top on ALSA (on Linux environments)"
+ linuxWorkaroundBlock ifNotNil: [ linuxWorkaroundBlock value ] ] repeat
- (Delay forMilliseconds: 20) wait.
- ].
!
Item was changed:
----- Method: StreamingMonoSound>>storeSunAudioOn:compressionType: (in category 'converting') -----
storeSunAudioOn: aBinaryStream compressionType: compressionName
"Store myself on the given stream as a monophonic sound compressed with the given type of compression. The sampling rate is reduced to 22050 samples/second if it is higher."
| fmt inBufSize samplesPerFrame outCodec compressed outSamplingRate audioWriter |
self pause; reset. "stop playing and return to beginning"
fmt := SunAudioFileWriter formatCodeForCompressionType: compressionName.
inBufSize := 64000.
samplesPerFrame := 1.
outCodec := SunAudioFileWriter codecForFormatCode: fmt.
outCodec ifNotNil: [
samplesPerFrame := outCodec samplesPerFrame.
inBufSize := inBufSize roundUpTo: (2 * samplesPerFrame).
compressed := ByteArray new:
(inBufSize // samplesPerFrame) * outCodec bytesPerEncodedFrame].
outSamplingRate := streamSamplingRate.
streamSamplingRate > 22050 ifTrue: [
streamSamplingRate = 44100 ifFalse: [self error: 'unexpected MP3 sampling rate'].
outSamplingRate := 22050].
"write audio header"
audioWriter := SunAudioFileWriter onStream: aBinaryStream.
audioWriter writeHeaderSamplingRate: outSamplingRate format: fmt.
"convert and write sound data"
+ 'Storing audio...'
+ displayProgressFrom: 0 to: totalSamples during: [:bar | | outBuf counts inBuf samplesRemaining byteCount |
- 'Storing audio...' displayProgressAt: Sensor cursorPoint
- from: 0 to: totalSamples during: [:bar | | outBuf counts inBuf samplesRemaining byteCount |
samplesRemaining := totalSamples.
[samplesRemaining > 0] whileTrue: [
bar value: totalSamples - samplesRemaining.
self loadBuffersForSampleCount: (inBufSize min: samplesRemaining).
inBuf := mixer sounds first samples.
outSamplingRate < streamSamplingRate
ifTrue: [outBuf := inBuf downSampledLowPassFiltering: true]
ifFalse: [outBuf := inBuf].
outCodec
ifNil: [audioWriter appendSamples: outBuf]
ifNotNil: [
counts := outCodec
encodeFrames: (outBuf size // samplesPerFrame)
from: outBuf at: 1
into: compressed at: 1.
byteCount := counts last.
byteCount = compressed size
ifTrue: [audioWriter appendBytes: compressed]
ifFalse: [audioWriter appendBytes: (compressed copyFrom: 1 to: byteCount)]].
samplesRemaining := samplesRemaining - inBuf monoSampleCount]].
"update audio header"
audioWriter updateHeaderDataSize.
!
More information about the Packages
mailing list