MIDI File Reader Patch

Andreas Raab raab at isgnw.cs.Uni-Magdeburg.DE
Tue Jan 27 16:41:03 UTC 1998


John,

enclosed is a patch for the MIDIFileReader to handle RMID files correctly.
If you don't know, RMID is M$ way of packing MIDI files in their
own chunk structure. If you haven't seen any of these yet, look into your
Windows\Media directory. There should be a couple of those (extension 
is ".rmi") .

Have fun,
  Andreas
-----------------------------------------------------------------------------

'From Squeak 1.3 of Jan 16, 1998 on 27 January 1998 at 5:27:45 pm'!

!MIDIFileReader methodsFor: 'chunk reading' stamp: 'ar 1/27/98 17:25'!
readHeaderChunk

	| chunkType chunkSize division |
	chunkType _ self readChunkType.
	"AR hack - support RMID files"
	chunkType = 'RIFF' ifTrue:[chunkType _ self riffSkipToMidiChunk].
        "AR endOfHack"
	chunkType = 'MThd' ifFalse: [^ self error: 'missing MIDI file header chunk'].
	chunkSize _ self readChunkSize.
	fileType _ self next16BitWord.
	trackCount _ self next16BitWord.
	division _ self next16BitWord.
	(division anyMask: 16r8000)
		ifTrue: [self error: 'SMPTE time formats are not yet supported']
		ifFalse: [ticksPerQuarter _ division].

	"sanity checks"
	chunkSize = 6
		ifFalse: [self report: 'unusual MIDI header size ', chunkSize printString].
	(#(0 1 2) includes: fileType)
		ifFalse: [self report: 'unusual MIDI file type ', fileType printString].

	Transcript
		show: 'Reading Type ', fileType printString, ' MIDI File (';
		show: trackCount printString, ' tracks, ';
		show: ticksPerQuarter printString, ' ticks per quarter note)';
		cr.
! !

!MIDIFileReader methodsFor: 'private' stamp: 'ar 1/27/98 17:27'!
next32BitWord: msbFirst
	"Read a 32-bit positive integer from the input stream."
	"Assume: Stream has at least four bytes left."

	| n |
	n _ stream next: 4.
	^msbFirst
		ifTrue:[((n at: 1) bitShift: 24) + ((n at: 2) bitShift: 16) + ((n at: 3) bitShift: 8) + (n at: 4)]
		ifFalse:[((n at: 4) bitShift: 24) + ((n at: 3) bitShift: 16) + ((n at: 2) bitShift: 8) + (n at: 1)]
! !

!MIDIFileReader methodsFor: 'private' stamp: 'ar 1/27/98 17:27'!
riffSkipToMidiChunk
	"The file is a RIFF file which may (or may not) contain a MIDI chunk"
	| dwLength fourcc |
	"Read length of all data"
	dwLength := self next32BitWord: false.
	"Get RIFF contents type "
	fourcc := self readChunkType.
	fourcc = 'RMID' ifFalse:[^fourcc]. "We can only read RMID files here"
	"Search for data"
	[[fourcc := self readChunkType.
	dwLength := self next32BitWord: false.
	fourcc = 'data'] whileFalse:[
		"Skip chunk - rounded to word boundary"
		stream skip: (dwLength + 1 bitAnd: 16rFFFFFFFE).
		stream atEnd ifTrue:[^'']].
	"Data chunk is raw - look into if it contains MIDI data and skip if not"
	fourcc := self readChunkType.
	fourcc = 'MThd'] whileFalse:[
		"Skip data (chunk - 4bytes) rounded to word boundary"
		stream skip: (dwLength - 3 bitAnd: 16rFFFFFFFE)].
	^fourcc! !


-----------------------------------------------------------------------------

-- 
Linear algebra is your friend - Trigonometry is your enemy.
+===== Andreas Raab ============= (raab at isg.cs.uni-magdeburg.de) =====+
I Department of Simulation and Graphics      Phone: +49 391 671 8065  I
I University of Magdeburg, Germany           Fax:   +49 391 671 1164  I
+=============< http://isgwww.cs.uni-magdeburg.de/~raab >=============+





More information about the Squeak-dev mailing list