Object subclass: #DataChunk instanceVariableNames: 'id dataSize positionOfDataSize ' classVariableNames: '' poolDictionaries: '' category: 'Music-WaveFile'! !DataChunk commentStamp: 'tf 8/4/2002 15:35' prior: 0! dataChunk contains ID - 'data' data size - 4 bytes. actual data is not contained in this object.! !DataChunk methodsFor: 'initialize' stamp: 'tf 7/25/2002 12:40'! initialize id _ 'data' asByteArray. dataSize _ 0. ! ! !DataChunk methodsFor: 'accessing' stamp: 'tf 7/24/2002 17:36'! chunkSize ^dataSize.! ! !DataChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:41'! dataSize ^dataSize ! ! !DataChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:42'! dataSize:aDataSize dataSize _ aDataSize. ! ! !DataChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:42'! dataSizeSize ^4 ! ! !DataChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:41'! id ^id. ! ! !DataChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:41'! idSize ^4. ! ! !DataChunk methodsFor: 'accessing' stamp: 'tf 7/25/2002 15:14'! writeDataChunkSize:dataChunkSize to:aStream aStream position:positionOfDataSize. RiffFileHelper writeSize:dataChunkSize with:(self dataSizeSize) to:aStream. ! ! !DataChunk methodsFor: 'file I/O' stamp: 'tf 7/25/2002 14:14'! readFrom:aStream | tmp | tmp _ RiffFileHelper setId:self size:#idSize from:aStream. (tmp = id) ifFalse:[ self error:'dataChunk invalid'. ^nil. ]. positionOfDataSize _ aStream position. dataSize _ RiffFileHelper setSize:self size:#dataSizeSize from:aStream. ! ! !DataChunk methodsFor: 'file I/O' stamp: 'tf 7/25/2002 15:02'! writeDataChunkSizeTo:aStream aStream position:positionOfDataSize. RiffFileHelper writeSize:dataSize with:(self dataSizeSize) to:aStream. ! ! !DataChunk methodsFor: 'file I/O' stamp: 'tf 7/25/2002 14:11'! writeTo:aStream aStream nextPutAll:id. positionOfDataSize _ aStream position. dataSize _ 0. RiffFileHelper writeSize:dataSize with:(self dataSizeSize) to:aStream. ! ! Object subclass: #FmtChunk instanceVariableNames: 'id fmtSize fmtData fmtDataSize positionOfFmtDataSize ' classVariableNames: '' poolDictionaries: '' category: 'Music-WaveFile'! !FmtChunk commentStamp: 'tf 8/4/2002 15:34' prior: 0! fmtChunk contains id - 'fmt ' fmtChunk size - 4 bytes bits per sample 8, 16, 24 byteAlignment 1 - 6 bytePerSecond - sampling bytes channels 1 or 2 sampling rate 44100, 22050 etc. ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:37'! bitsPerSample ^fmtData at:6.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 15:58'! bitsPerSample:bitsPerSample fmtData at:6 put:bitsPerSample! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:37'! bitsPerSampleSize ^fmtDataSize at:6.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:36'! byteAlignment ^fmtData at:5.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 15:58'! byteAlignment:byteAlignment fmtData at:5 put:byteAlignment! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:36'! byteAlignmentSize ^fmtDataSize at:5.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/23/2002 16:36'! bytePerSecond ^fmtData at:4.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 15:58'! bytePerSecond:bytePerSecond fmtData at:4 put:bytePerSecond! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:35'! bytePerSecondSize ^fmtDataSize at:4.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 15:49'! channels ^fmtData at:2.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 15:50'! channels:channels ^fmtData at:2 put:channels! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/23/2002 15:08'! channelsSize ^fmtDataSize at:2.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/24/2002 17:35'! chunkSize ^fmtSize.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/24/2002 16:47'! fmtSizeSize ^4.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 15:54'! formatTag ^fmtData at:1.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 15:57'! formatTag:tag fmtData at:1 put:tag.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/22/2002 15:54'! formatTagSize ^fmtDataSize at:1.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/24/2002 17:27'! id ^id. ! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/24/2002 17:27'! idSize ^4. ! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/24/2002 15:36'! samplingBit ^self bitsPerSample. ! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/24/2002 15:36'! samplingBit:aSamplingBit self bitsPerSample:aSamplingBit.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/24/2002 15:25'! samplingRate ^fmtData at:3.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/24/2002 15:25'! samplingRate:sampling fmtData at:3 put:sampling.! ! !FmtChunk methodsFor: 'accessing' stamp: 'tf 7/24/2002 15:25'! samplingRateSize ^fmtDataSize at:3.! ! !FmtChunk methodsFor: 'initialize' stamp: 'tf 8/3/2002 00:35'! initialize | bytePerSecond | id _ 'fmt ' asByteArray. "PCM:1 channels samplingRate byteAlignment samplingBit " fmtData _ #( 1 2 44100 0 4 16). bytePerSecond _ 44100 * 2 * 2. "sampling X 16bits X 2channels" fmtData at:4 put:bytePerSecond. fmtDataSize _ #(2 2 4 4 2 2). fmtSize _ 0.! ! !FmtChunk methodsFor: 'file I/O' stamp: 'tf 7/24/2002 17:30'! readFrom:aStream | tmp | tmp _ RiffFileHelper setId:self size:#idSize from:aStream. (tmp = id) ifFalse:[ self error:'fmtChunk invalid'. ^nil. ]. fmtSize _ RiffFileHelper setSize:self size:#fmtSizeSize from:aStream. tmp _ RiffFileHelper setSize:self size:#formatTagSize from:aStream. (tmp = 1) ifFalse:[ self error:'Only PCM is supported'. ^nil. ]. self formatTag:tmp. RiffFileHelper setSize:self size:#channelsSize setter:#channels: from:aStream. RiffFileHelper setSize:self size:#samplingRateSize setter:#samplingRate: from:aStream. RiffFileHelper setSize:self size:#bytePerSecondSize setter:#bytePerSecond: from:aStream. RiffFileHelper setSize:self size:#byteAlignmentSize setter:#byteAlignment: from:aStream. RiffFileHelper setSize:self size:#bitsPerSampleSize setter:#bitsPerSample: from:aStream. "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! tmp _ fmtSize - (self formatTagSize + self channelsSize + self samplingRateSize + self byteAlignmentSize + self bitsPerSampleSize). tmp timesRepeat:[ aStream next. ]. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" ! ! !FmtChunk methodsFor: 'file I/O' stamp: 'tf 7/24/2002 16:47'! writeTo:aStream aStream nextPutAll:id. positionOfFmtDataSize _ aStream position. fmtSize _ 0. 1 to:(fmtDataSize size) do:[ :i | fmtSize _ fmtSize + (fmtDataSize at:i). ]. RiffFileHelper writeSize:fmtSize with:(self fmtSizeSize) to:aStream. 1 to:(fmtData size) do:[ :i | RiffFileHelper writeSize:(fmtData at:i) with:(fmtDataSize at:i) to:aStream. ]. ! ! Object subclass: #RiffData instanceVariableNames: 'id fmtChunk dataChunk ' classVariableNames: '' poolDictionaries: '' category: 'Music-WaveFile'! !RiffData commentStamp: 'tf 8/4/2002 15:32' prior: 0! RiffData controlls fmtChunk and dataChunk. It also has file ID. ID - 'WAVE'! !RiffData methodsFor: 'initialize' stamp: 'tf 7/25/2002 12:39'! initialize id _ 'WAVE' asByteArray. fmtChunk _ FmtChunk new initialize. dataChunk _ DataChunk new initialize. ! ! !RiffData methodsFor: 'file I/O' stamp: 'tf 7/23/2002 15:18'! readFrom:aStream | tmp | tmp _ RiffFileHelper setId:self size:#idSize from:aStream. (tmp = id) ifFalse:[ self error:'RIFF Data Header is invalid'. ^nil. ]. Transcript show:'RIFF DATA: ', tmp; cr. fmtChunk readFrom:aStream. dataChunk readFrom:aStream. ! ! !RiffData methodsFor: 'file I/O' stamp: 'tf 7/24/2002 16:34'! writeTo:aStream aStream nextPutAll:id. fmtChunk writeTo:aStream. dataChunk writeTo:aStream. ! ! !RiffData methodsFor: 'accessing' stamp: 'tf 7/24/2002 15:07'! dataChunk ^dataChunk! ! !RiffData methodsFor: 'accessing' stamp: 'tf 7/24/2002 15:06'! fmtChunk ^fmtChunk! ! !RiffData methodsFor: 'accessing' stamp: 'tf 7/23/2002 14:36'! id ^id! ! !RiffData methodsFor: 'accessing' stamp: 'tf 7/23/2002 14:35'! idSize ^4. ! ! !RiffData methodsFor: 'accessing' stamp: 'tf 7/24/2002 14:40'! totalSampleSize ^((dataChunk dataSize) / (fmtChunk byteAlignment) / (fmtChunk channels)). ! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! RiffData class instanceVariableNames: ''! !RiffData class methodsFor: 'instance creation' stamp: 'tf 7/22/2002 14:17'! new | tmp | tmp _ super new. tmp initialize. ^tmp.! ! Object subclass: #RiffFileHelper instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Music-WaveFile'! !RiffFileHelper commentStamp: 'tf 8/4/2002 15:31' prior: 0! RiffFileHelper provides useful function to access wave file. read/write ID (string) read/write size (4 byte integer). ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! RiffFileHelper class instanceVariableNames: ''! !RiffFileHelper class methodsFor: 'as yet unclassified' stamp: 'tf 7/25/2002 12:42'! setId:model size:sizeSelector from:stream | id size | size _ model perform:sizeSelector. id _ ByteArray new:size. 1 to:size do:[ :i | id at:i put:(stream next). ]. ^id.! ! !RiffFileHelper class methodsFor: 'as yet unclassified' stamp: 'tf 7/23/2002 15:00'! setId:model size:sizeSelector setter:setSelector from:stream | id | id _ self setId:model size:sizeSelector from:stream. model perform:setSelector with:id.! ! !RiffFileHelper class methodsFor: 'as yet unclassified' stamp: 'tf 7/25/2002 12:43'! setSize:model size:sizeSelector from:stream | length size byte | size _ model perform:sizeSelector. byte _ ByteArray new:size. 1 to:size do:[ :i | byte at:i put:(stream next). ]. length _ 0. 1 to:size do:[ :i | length _ length * 256 + (byte at:(size - i + 1)). ]. ^length.! ! !RiffFileHelper class methodsFor: 'as yet unclassified' stamp: 'tf 7/23/2002 14:59'! setSize:model size:sizeSelector setter:setSelector from:stream | length | length _ self setSize:model size:sizeSelector from:stream. model perform:setSelector with:length.! ! !RiffFileHelper class methodsFor: 'as yet unclassified' stamp: 'tf 7/25/2002 16:06'! writeSize:value with:bytes to:aStream (bytes = 1) ifTrue:[ aStream nextPut:value. ] ifFalse:[ (bytes = 2) ifTrue:[ aStream nextPut:(value \\ 256). aStream nextPut:(value // 256). ] ifFalse:[ (bytes = 4) ifTrue:[ aStream nextPut:(value \\ 256). aStream nextPut:(value // 256 \\ 256). aStream nextPut:(value // 256 // 256 \\ 256). aStream nextPut:(value // 256 // 256 //256). ] ifFalse:[ self error:'does not support ', bytes printString, ' bytes write!!'. ^nil. ]. ]. ]. ! ! Object subclass: #RiffHeader instanceVariableNames: 'riff riffSize positionOfRiffSize ' classVariableNames: '' poolDictionaries: '' category: 'Music-WaveFile'! !RiffHeader commentStamp: 'tf 8/4/2002 15:29' prior: 0! Control Riff Header of Wave file. Riff Header contains, ID - 'RIFF' File Size - 4 bytes. ! !RiffHeader methodsFor: 'initialize' stamp: 'tf 7/25/2002 12:39'! initialize riff _ 'RIFF' asByteArray. riffSize _ 4. ! ! !RiffHeader methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:46'! id ^riff.! ! !RiffHeader methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:46'! idSize ^4.! ! !RiffHeader methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:05'! riffSize ^riffSize.! ! !RiffHeader methodsFor: 'accessing' stamp: 'tf 7/22/2002 14:47'! riffSizeSize ^4.! ! !RiffHeader methodsFor: 'file I/O' stamp: 'tf 7/23/2002 15:18'! readFrom:aStream | temp | temp _ RiffFileHelper setId:self size:#idSize from:aStream. (riff = temp) ifFalse:[ self error:'Riff Header format error'. ^nil. ]. riffSize _ RiffFileHelper setSize:self size:#riffSizeSize from:aStream. Transcript show:'HEADER - ', temp, ' ', riffSize printString; cr. ! ! !RiffHeader methodsFor: 'file I/O' stamp: 'tf 7/25/2002 15:56'! writeHeaderSize:dataSize to:aStream aStream position:positionOfRiffSize. RiffFileHelper writeSize:(dataSize + 36) with:(self riffSizeSize) to:aStream. ! ! !RiffHeader methodsFor: 'file I/O' stamp: 'tf 7/24/2002 16:33'! writeTo:aStream aStream nextPutAll:riff. positionOfRiffSize _ aStream position. RiffFileHelper writeSize:0 with:(self riffSizeSize) to:aStream. ! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! RiffHeader class instanceVariableNames: ''! !RiffHeader class methodsFor: 'instance creation' stamp: 'tf 7/22/2002 14:06'! new | tmp | tmp _ super new. tmp initialize. ^tmp. ! ! StandardFileStream subclass: #WaveFileStream instanceVariableNames: 'riffHeader riffData forWrite byteCount writtenWaveCount ' classVariableNames: '' poolDictionaries: '' category: 'Music-WaveFile'! !WaveFileStream commentStamp: 'tf 8/4/2002 15:28' prior: 0! Read/Write Wave File To read a wave file, WaveFileStream readOnlyFileNamed:'test.wav'. nextWave will read the sequencial wave data. To write a wav file, WaveFileStream newFileNamed''test.wav'. nextWave:#(dataRight dataLeft) to write wave data. After writing all data, send 'writeCompleteHeader' to complete the file and 'close' it. examples WaveFileStream example1 WaveFileStream example2 WaveFileStream example3 WaveFileStream example4 ! !WaveFileStream methodsFor: 'open/close' stamp: 'tf 7/24/2002 18:09'! open:fileName forWrite:writeMode super open:fileName forWrite:writeMode. self binary. (writeMode) ifTrue:[ riffHeader _ RiffHeader new initialize. riffData _ RiffData new initialize. ] ifFalse:[ riffHeader _ RiffHeader new initialize. riffData _ RiffData new initialize. ]. forWrite _ writeMode.! ! !WaveFileStream methodsFor: 'access' stamp: 'tf 7/25/2002 14:44'! nextWave | data tmp wave channels bytePerChannel samplingBit byte | channels _ riffData fmtChunk channels. bytePerChannel _(riffData fmtChunk byteAlignment) / channels. samplingBit _ riffData fmtChunk samplingBit. data _ Array new:channels. tmp _ ByteArray new:bytePerChannel. 1 to:channels do:[ :i | 1 to:bytePerChannel do:[ :j | byte _ self next. tmp at:j put:byte. ]. wave _ 0. 1 to:bytePerChannel do:[ :j | wave _ wave * 256 + (tmp at:(bytePerChannel - j + 1)). ]. (samplingBit = 8) ifTrue:[ (wave > 127) ifTrue:[ wave _ (wave bitXor:16rFF) * -1 - 1. ]. ]. (samplingBit = 16) ifTrue:[ (wave > 32767) ifTrue:[ wave _ (wave bitXor:16rFFFF) * -1 - 1. ]. ]. (samplingBit = 24) ifTrue:[ (wave > 8388607) ifTrue:[ wave _ (wave bitXor:16rFFFFFF) * -1 - 1. ]. ]. data at:i put:wave. ]. ^data.! ! !WaveFileStream methodsFor: 'access' stamp: 'tf 7/25/2002 16:21'! nextWave:wave | data tmp channels bytePerChannel samplingBit | channels _ riffData fmtChunk channels. bytePerChannel _(riffData fmtChunk byteAlignment) / channels. samplingBit _ riffData fmtChunk samplingBit. tmp _ ByteArray new:bytePerChannel. (writtenWaveCount isNil) ifTrue:[ writtenWaveCount _ 0 ]. 1 to:channels do:[ :i | data _ wave at:i. (samplingBit = 8) ifTrue:[ (data < 0) ifTrue:[ data _ 256 + data. ]. tmp at:1 put:(data bitAnd:16rFF). ]. (samplingBit = 16) ifTrue:[ (data < 0) ifTrue:[ data _ (256 * 256) + data. ]. tmp at:1 put:(data bitAnd:16rFF). tmp at:2 put:((data // 256) bitAnd:16rFF). ]. (samplingBit = 24) ifTrue:[ (data < 0) ifTrue:[ data _ (256 * 256 * 256 * 256) + data. ]. tmp at:1 put:(data bitAnd:16rFF). tmp at:2 put:((data // 256) bitAnd:16rFF). tmp at:3 put:((data // (256 * 256)) bitAnd:16rFF). tmp at:4 put:((data // (256 * 256 * 256)) bitAnd:16rFF). ]. 1 to:bytePerChannel do:[ :j | self nextPut:(tmp at:j). ]. ]. writtenWaveCount _ writtenWaveCount + 1.! ! !WaveFileStream methodsFor: 'access' stamp: 'tf 7/24/2002 15:34'! readAll | channels samplingBit byteAlignment | riffHeader readFrom:self. riffData readFrom:self. samplingBit _ riffData fmtChunk samplingBit. channels _ riffData fmtChunk channels. byteAlignment _ (riffData fmtChunk byteAlignment) / channels. ((channels < 1) or:[channels > 2]) ifTrue:[ self error:(channels printString), ' channels is not supported'. ^nil. ]. ((samplingBit = 8) or:[(samplingBit = 16) or:[samplingBit = 24]]) ifFalse:[ self error:'sampling ', samplingBit printString, ' bits is not supported'. ^nil. ]. ! ! !WaveFileStream methodsFor: 'access' stamp: 'tf 7/25/2002 15:57'! writeCompleteHeader riffHeader writeHeaderSize:(writtenWaveCount * riffData fmtChunk byteAlignment) to:self. riffData dataChunk writeDataChunkSize:(writtenWaveCount * riffData fmtChunk byteAlignment) to:self.! ! !WaveFileStream methodsFor: 'access' stamp: 'tf 7/25/2002 16:22'! writeTemporaryHeader riffHeader writeTo:self. riffData writeTo:self.! ! !WaveFileStream methodsFor: 'creation' stamp: 'tf 7/24/2002 15:08'! bitsPerSample:bitsPerSample riffData fmtChunk bitsPerSample:bitsPerSample.! ! !WaveFileStream methodsFor: 'creation' stamp: 'tf 7/24/2002 15:30'! byteAlignment:aByteAlign riffData fmtChunk byteAlignment:aByteAlign.! ! !WaveFileStream methodsFor: 'creation' stamp: 'tf 7/24/2002 15:10'! bytePerSecond:bytePerSecond riffData fmtChunk bytePerSecond:bytePerSecond.! ! !WaveFileStream methodsFor: 'creation' stamp: 'tf 7/24/2002 15:11'! channels:aChannels riffData fmtChunk channels:aChannels.! ! !WaveFileStream methodsFor: 'creation' stamp: 'tf 7/24/2002 15:26'! samplingRate:aSampling riffData fmtChunk samplingRate:aSampling.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 15:38'! bitsPerSample ^riffData fmtChunk bitsPerSample! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 15:39'! byteAlignment ^riffData fmtChunk byteAlignment.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 15:39'! bytePerSecond ^riffData fmtChunk bytePerSecond! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 15:40'! channels ^riffData fmtChunk channels.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 17:38'! dataChunkSize ^riffData dataChunk chunkSize.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 17:37'! dataId ^riffData dataChunk id.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 17:35'! fmtChunkSize ^riffData fmtChunk chunkSize.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 17:32'! fmtId ^riffData fmtChunk id.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/25/2002 14:50'! numberOfData | dataSize | dataSize _ riffData dataChunk dataSize. ^dataSize / riffData fmtChunk byteAlignment.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 16:57'! riffDataId ^riffData id.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 16:56'! riffHeaderId ^riffHeader id.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 16:56'! riffHeaderSize ^riffHeader riffSize.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 15:38'! samplingBit ^riffData fmtChunk samplingBit.! ! !WaveFileStream methodsFor: 'information access' stamp: 'tf 7/24/2002 15:38'! samplingRate ^riffData fmtChunk samplingRate.! ! !WaveFileStream methodsFor: 'private' stamp: 'tf 7/25/2002 15:36'! forWrite:bool forWrite _ bool.! ! !WaveFileStream methodsFor: 'private' stamp: 'tf 7/25/2002 14:30'! next "Just for Test, it is OK to delete this method" | c | c _ super next. (byteCount isNil) ifTrue:[ byteCount _ 0 ]. byteCount _ byteCount + 1. ^c. ! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! WaveFileStream class instanceVariableNames: ''! !WaveFileStream class methodsFor: 'instance creation' stamp: 'tf 7/25/2002 15:54'! newFileNamed:fileName | f | f _ super fileNamed:fileName. f forWrite:true. (f isNil) ifFalse:[ f writeTemporaryHeader. ]. ^f.! ! !WaveFileStream class methodsFor: 'instance creation' stamp: 'tf 7/25/2002 15:43'! readOnlyFileNamed:fileName | f | f _ super readOnlyFileNamed:fileName. (f isNil) ifFalse:[ ((f readAll) isNil) ifTrue:[ f _ nil. ]. ]. ^f.! ! !WaveFileStream class methodsFor: 'examples' stamp: 'tf 7/24/2002 15:33'! example1 | f data count | f _ WaveFileStream readOnlyFileNamed:'chimes.wav'. Transcript show:'Channels:', f channels printString; show:' SamplingRate:', f samplingRate printString; show:' SamplingBit:', f samplingBit printString; cr. count _ 0. [f atEnd] whileFalse:[ data _ f nextWave. (count < 100) ifTrue:[ Transcript show:(data printString); cr. ]. count _ count + 1. ]. f close. ! ! !WaveFileStream class methodsFor: 'examples' stamp: 'tf 7/25/2002 14:49'! example2 | f data filename collection dataSize | filename _ StandardFileMenu oldFileStream name. f _ WaveFileStream readOnlyFileNamed:filename. Transcript show:'Channels:', f channels printString; show:' SamplingRate:', f samplingRate printString; show:' SamplingBit:', f samplingBit printString; cr. collection _ OrderedCollection new. dataSize _ f numberOfData. dataSize timesRepeat:[ data _ f nextWave. collection add:(data at:1). ]. "----------------------- Following include garbage of last portion of the file ----------------------- [f atEnd] whileFalse:[ data _ f nextWave. collection add:(data at:1). ]. -------------------------" f close. WaveEditor openOn:collection. ! ! !WaveFileStream class methodsFor: 'examples' stamp: 'tf 7/25/2002 15:37'! example3 | in out data filename | filename _ StandardFileMenu oldFileStream name. in _ WaveFileStream readOnlyFileNamed:filename. out _ WaveFileStream newFileNamed:'test.wav'. out bitsPerSample:(in bitsPerSample); byteAlignment:(in byteAlignment); bytePerSecond:(in bytePerSecond); channels:(in channels); samplingRate:(in samplingRate). (in numberOfData) timesRepeat:[ data _ in nextWave. out nextWave:data. ]. out writeCompleteHeader. in close. out close. ! ! !WaveFileStream class methodsFor: 'examples' stamp: 'tf 8/3/2002 11:22'! example4 | f count | f _ WaveFileStream readOnlyFileNamed:'1.wav'. Transcript show:'Channels:', f channels printString; show:' SamplingRate:', f samplingRate printString; show:' SamplingBit:', f samplingBit printString; show:' ByteAlignment:', f byteAlignment printString; show:' BytePerSecond:', f bytePerSecond printString; cr; show:'RIFF id:', f riffHeaderId; show:' RIFF header size:', f riffHeaderSize printString; show:' RIFF data id:', f riffDataId; cr; show:'FMT id:', f fmtId; show:' FMT data size:', f fmtChunkSize printString; cr; show:'DATA id:', f dataId; show:' DATA data size:', f dataChunkSize printString; cr. count _ 0. [f atEnd] whileFalse:[ f nextWave. count _ count + 1. ]. f close. Transcript show:'Data:', count asString, ' samples.'; cr. ! !