'=========================================================================== ' Subject: SCAN MIDI FILE STRUCTURES Date: 01-06-96 (01:27) ' Author: Joe Shay Code: QB, QBasic, PDS ' Origin: FidoNet QUIK_BAS Echo Packet: SOUND.ABC '=========================================================================== 'MIDI001.BAS By Joe Shay 'Released to the Public Domain, January 1996 '(presently intended) 'A program ^ to - scan the MIDI file structure. ' - identify MIDI Format, Tempo, Key, ' Track name, instrument name ' - generally display file contents ' 'Note: I have directed the program to examine a ' .MID file included with Windows. ' ' This code is 'AS IS' so if anyone can improve my 'methods to accomplish the above stated I would 'appreciate it. My thanx to Chad Beck for directing me 'towards the correct ball park. ' DEFINT A-Z DECLARE FUNCTION Int2Hex$ (Dec%) DECLARE FUNCTION KeeOTune$ (sfnum$, minum%) TYPE midi headchunk AS STRING * 4 headsize AS STRING * 4 f4mat AS STRING * 2 totrax AS STRING * 2 deltatix AS STRING * 2 END TYPE TYPE midigutz trakchunx AS STRING * 4 chunklen AS STRING * 4 END TYPE DIM midfylhead AS midi DIM miditrax(1 TO 100) AS midigutz WIDTH 80, 50 CLS OPEN "c:\sb16\playmidi\minuet.mid" FOR BINARY AS #1 GET 1, , midfylhead IF midfylhead.headchunk <> "MThd" THEN CLOSE PRINT "Non .MID file or corrupted file" END END IF COLOR 0, 2 PRINT " File Format = "; ASC(RIGHT$(midfylhead.f4mat, 1)); IF ASC(RIGHT$(midfylhead.f4mat, 1)) > 0 THEN PRINT "[Multi Trax]" ELSE PRINT "[Single Trax]" COLOR 0, 3 ttrx = ASC(LEFT$(midfylhead.totrax, 1)) + ASC(RIGHT$(midfylhead.totrax, 1)) PRINT " Total Tracks = "; ttrx - 1; 'PRINT " Delta Ticks / PPQ = "; ASC(RIGHT$(midfylhead.deltatix, 1)); PRINT COLOR 3, 0 Tempo$ = SPACE$(8) timsig$ = SPACE$(5) keysig$ = SPACE$(3) a$ = SPACE$(1) B$ = SPACE$(1) DO UNTIL EOF(1) GET 1, , a$ SELECT CASE a$ CASE CHR$(255) '&HFF meta event marker GET 1, , B$ bb$ = HEX$(ASC(B$)) IF LEN(bb$) < 2 THEN bb$ = "0" + bb$ SELECT CASE bb$ CASE "01", "02", "03", "04", "05", "06", "07" GET 1, , B$ tot = ASC(B$) GOSUB grabyte CASE "20" cc$ = "MIDI Ch. Prefix.." CASE "2F" cc$ = "-=End Trk=-" + CHR$(13) CASE "51" cc$ = "Set tempo" GET 1, , Tempo$ Byte1 = VAL(HEX$(ASC(MID$(Tempo$, 3, 2)))) Byte2 = VAL(HEX$(ASC(MID$(Tempo$, 5, 2)))) Byte3 = VAL(HEX$(ASC(MID$(Tempo$, 7, 2)))) Tempo& = Byte1 + (Byte2 * 256&) + (Byte3 * 65537) PRINT Tempo& CASE "58" cc$ = "Time Sig.." GET 1, , timsig$ num = ASC(MID$(timsig$, 2, 1)) den = ASC(MID$(timsig$, 3, 1)) den = 2 ^ den COLOR 15, 3 LOCATE 1, 42: PRINT num; "/"; den CASE "59" cc$ = "Key Sig.." GET 1, , keysig$ sf = ASC(MID$(keysig$, 2, 1)) mi = ASC(MID$(keysig$, 3, 1)) IF sf > 7 THEN '='='convert to negative sf = sf - 256 END IF sf$ = LTRIM$(RTRIM$(STR$(sf))) ' PRINT sf 'temp for tests COLOR 15, 3 LOCATE 1, 65: PRINT KeeOTune$(sf$, mi) CASE ELSE cc$ = "====" END SELECT PRINT bb$; " "; cc$ CASE ELSE END SELECT LOOP CLOSE END grabyte: COLOR 1, 15 FOR i = 1 TO tot a$ = INPUT$(1, #1) IF a$ <> CHR$(0) OR a$ <> CHR$(12) THEN PRINT a$; END IF NEXT COLOR 3, 0 RETURN DEFSNG A-Z FUNCTION Int2Hex$ (Dec%) IF Dec% = 0 THEN t2Hex$ = "00" ELSE t2Hex$ = HEX$(Dec%) IF LEN(t2Hex$) < 2 THEN t2Hex$ = "0" + t2Hex$ END IF Int2Hex$ = t2Hex$ END FUNCTION DEFINT A-Z ' FUNCTION KeeOTune$ (sfnum$, minum%) keyz$ = "Bb-5DbF -4AbC -3EbG -2BbD -1F A 0 C E +1G B +2D F#+3A C#+4E G#+5B D#+6F#" scan1 = INSTR(keyz$, sfnum$) IF minum% = 0 THEN scan1 = scan1 + 2 mm$ = " Major" ELSE scan1 = scan1 - 2 mm$ = " Minor" END IF tunekee$ = MID$(keyz$, scan1, 2) KeeOTune$ = tunekee$ + mm$ END FUNCTION