# HG changeset patch # User Claus Gittinger # Date 974999293 -3600 # Node ID 9675c5ea14df18157a567ca1ba038231dfe12782 # Parent 527262f8f026badd03a7a81948b0cebc2b148e16 refactored RIFF- and AVIReader for general use RIFFReader is no longer tied to the ImageReader hierarchy. diff -r 527262f8f026 -r 9675c5ea14df RIFFReader.st --- a/RIFFReader.st Wed Nov 22 15:54:00 2000 +0100 +++ b/RIFFReader.st Thu Nov 23 18:08:13 2000 +0100 @@ -10,11 +10,13 @@ hereby transferred. " -ImageReader subclass:#RIFFReader - instanceVariableNames:'chunkSize streamTypes' +"{ Package: 'stx:libview2' }" + +Object subclass:#RIFFReader + instanceVariableNames:'inStream chunkSize streamTypes client' classVariableNames:'UnsupportedFormatErrorSignal' poolDictionaries:'' - category:'Graphics-Images-Support' + category:'System-Support-FileFormats' ! !RIFFReader class methodsFor:'documentation'! @@ -36,6 +38,15 @@ documentation " Abstract helper class to read RIFF files. See concrete subclasses for details. + RIFF is the abstract base-format used for a whole bunch of concrete file formats: + WAV, AVI, AIF etc. + Concrete formats must be parsed by concrete readers. + + Use: + define your own concrete reader, with methods getChunk_FOO:, + for each chunk type FOO you want to parse there. + Define your reader as a client to this reader, and let it processChunks. + See AVIReader for a concrete example. This is in an experimental state and not yet finished. The protocol may change. @@ -78,29 +89,53 @@ " RIFFReader isRIFFFile:'bitmaps/magtape.xpm' RIFFReader isRIFFFile:'/home2/pd_stuff/movies/avi/drlair.avi' + RIFFReader isRIFFFile: '/usr/share/sounds/alsa/test.wav' " "Created: 4.4.1997 / 22:35:52 / cg" "Modified: 5.4.1997 / 16:12:16 / cg" ! ! +!RIFFReader methodsFor:'accessing'! + +addStream:type + streamTypes add:type +! + +client + "return the value of the instance variable 'client' (automatically generated)" + + ^ client +! + +client:something + "set the value of the instance variable 'client' (automatically generated)" + + client := something. +! + +streamTypes:something + "set the value of the instance variable 'streamTypes' (automatically generated)" + + streamTypes := something. +! ! + !RIFFReader methodsFor:'reading from stream'! fromStream:aStream "read RIFF chunks from aStream. Process chunks in getChunkXXX methods (usually redefined in concrete reader classes." - inStream := aStream. - inStream binary. - - [inStream atEnd] whileFalse:[ - self getChunk - ]. - ^ nil + client := self. + self processStream:aStream " - RIFFReader fromFile:'/home2/pd_stuff/movies/avi/hangldm.avi' - RIFFReader fromFile:'/home2/cg/AFsp-V2R0/test/audiofiles/jg00b1ss.wav' + RIFFReader fromFile:'/phys/exept/home/pd_stuff/movies/avi/hangldm.avi' + RIFFReader fromFile:'/phys/exept/opt/office52/share/gallery/sounds/gong.wav' + + AVIReader fromFile:'/phys/exept/home/pd_stuff/movies/avi/hangldm.avi' + WAVFileReader fromFile:'/phys/exept/opt/office52/share/gallery/sounds/gong.wav' + AIFFFileReader fromFile:'/phys/exept/opt/office52/share/gallery/sounds/gong.wav' " "Modified: 17.4.1997 / 03:25:08 / cg" @@ -109,7 +144,7 @@ getChunk "get a single chunk" - |id s sel streamNr streamType| + |id sel sTyp| 'getChunk -> ' infoPrint. @@ -117,36 +152,68 @@ inStream nextBytes:4 into:id startingAt:1. chunkSize := inStream nextLongMSB:false. - (id at:4) == Character space ifTrue:[ - id := id copyTo:3 - ]. + (id at:1) == $0 ifTrue:[ + sTyp := '_Unknown'. + streamTypes notNil ifTrue:[ + sTyp := streamTypes at:((id at:2) digitValue + 1) ifAbsent:nil. + ]. + sel := 'getChunk_' , sTyp , '_' , (id copyFrom:3), ':'. - (id at:1) isDigit ifTrue:[ - streamNr := Number readFrom:(id copyTo:2). - streamTypes notNil ifTrue:[ - streamType := streamTypes at:(streamNr + 1). - s := 'getChunk_' , streamType , '_' , (id copyFrom:3). - ] ifFalse:[ - s := 'getChunk_' , id. +"/id infoPrint. ' -> ' infoPrint. sel infoPrintCR. + sel := sel asSymbolIfInterned. + (sel isNil or:[(self respondsTo:sel) not]) ifTrue:[ + sel := 'getChunk_' , sTyp , '_Unknown:'. +"/' ' infoPrint. id infoPrint. ' -> ' infoPrint. sel infoPrintCR. + sel := sel asSymbolIfInterned. + (sel isNil or:[(self respondsTo:sel) not]) ifTrue:[ + '[' infoPrint. ('getChunk_' , sTyp , '_' , (id copyFrom:3)) infoPrint. '] ' infoPrint. + sel := #'getChunk_Unknown:'. +"/' ' infoPrint. id infoPrint. ' -> ' infoPrint. sel infoPrintCR. + ]. ] ] ifFalse:[ - s := 'getChunk_' , id. - ]. - sel := s asSymbolIfInterned. - (sel isNil or:[(self respondsTo:sel) not]) ifTrue:[ - '[' infoPrint. s infoPrint. '] ' infoPrint. - sel := #'getChunk_Unknown' + (id at:4) == Character space ifTrue:[ + id := id copyTo:3 + ]. + sel := ('getChunk_' , id , ':') asSymbolIfInterned. + (sel isNil or:[(self respondsTo:sel) not]) ifTrue:[ + '[' infoPrint. ('getChunk_' , id) infoPrint. '] ' infoPrint. + sel := #'getChunk_Unknown:' + ]. +"/id infoPrint. ' -> ' infoPrint. sel infoPrintCR. ]. - self perform:sel. - + client perform:sel with:chunkSize ifNotUnderstood:[self perform:sel with:chunkSize]. '' infoPrintCR. - "Created: 5.4.1997 / 16:29:40 / cg" - "Modified: 17.4.1997 / 03:24:48 / cg" + " + RIFFReader fromFile:'/phys/exept/home/pd_stuff/movies/avi/hangldm.avi' + AVIReader fromFile:'/phys/exept/home/pd_stuff/movies/avi/hangldm.avi' + " + + "Created: 4.4.1997 / 22:50:13 / cg" + "Modified: 5.4.1997 / 15:47:48 / cg" ! -getChunk_LIST +getChunk_DISP:chunkSize + "process (ignore) a DISP chunk" + + 'getChunk_DISP -> ' infoPrint. + + self skipChunk:chunkSize + + "Created: 5.4.1997 / 15:19:10 / cg" +! + +getChunk_JUNK:chunkSize + "ignore JUNK chunk" + + 'getChunk_JUNK -> ' infoPrint. + + self skipChunk:chunkSize +! + +getChunk_LIST:chunkSize "process a LIST chunk" 'getChunk_LIST' infoPrint. @@ -163,37 +230,43 @@ "Modified: 17.4.1997 / 03:22:15 / cg" ! -getChunk_RIFF +getChunk_RIFF:chunkSize "process a RIFF chunk" 'getChunk_RIFF' infoPrint. inStream skip:4. - - " - AVIReader fromFile:'/home2/pd_stuff/movies/avi/hangldm.avi' - " - - "Created: 4.4.1997 / 23:18:08 / cg" - "Modified: 5.4.1997 / 16:12:16 / cg" ! -getChunk_Unknown +getChunk_Unknown:chunkSize "ignore any other chunk" 'getChunk_Unknown -> ' infoPrint. - self skipChunk + self skipChunk:chunkSize +! + +processStream:aStream + "read RIFF chunks from aStream. Process chunks in getChunkXXX methods + (usually redefined in concrete reader classes." + + inStream := aStream. + inStream binary. + + [inStream atEnd] whileFalse:[ + client perform:#getChunk ifNotUnderstood:[self getChunk]. + ]. + ^ nil " - AVIReader fromFile:'/home2/pd_stuff/movies/avi/hangldm.avi' + RIFFReader fromFile:'/home2/pd_stuff/movies/avi/hangldm.avi' + RIFFReader fromFile:'/home2/cg/AFsp-V2R0/test/audiofiles/jg00b1ss.wav' " - "Created: 5.4.1997 / 00:03:43 / cg" - "Modified: 5.4.1997 / 16:12:16 / cg" + "Modified: 17.4.1997 / 03:25:08 / cg" ! -skipChunk +skipChunk:chunkSize "skip a chunk" |sz| @@ -206,18 +279,11 @@ ]. inStream skip:sz. - - " - AVIReader fromFile:'/home2/pd_stuff/movies/avi/hangldm.avi' - " - - "Created: 5.4.1997 / 14:13:43 / cg" - "Modified: 5.4.1997 / 16:12:16 / cg" ! ! !RIFFReader class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libview2/RIFFReader.st,v 1.3 1997-04-17 01:32:11 cg Exp $' + ^ '$Header: /cvs/stx/stx/libview2/RIFFReader.st,v 1.4 2000-11-23 17:08:13 cg Exp $' ! ! RIFFReader initialize!