summaryrefslogtreecommitdiff
path: root/ipl/progs/midisig.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/progs/midisig.icn')
-rw-r--r--ipl/progs/midisig.icn140
1 files changed, 140 insertions, 0 deletions
diff --git a/ipl/progs/midisig.icn b/ipl/progs/midisig.icn
new file mode 100644
index 0000000..8aee48d
--- /dev/null
+++ b/ipl/progs/midisig.icn
@@ -0,0 +1,140 @@
+############################################################################
+#
+# File: midisig.icn
+#
+# Subject: Program to show signature of a MIDI file
+#
+# Author: Ralph E. Griswold
+#
+# Date: August 17, 1998
+#
+############################################################################
+#
+# This file is in the public domain.
+#
+############################################################################
+#
+# This program displays the signature of a MIDI file.
+#
+############################################################################
+#
+# Links: bincvt, convert
+#
+############################################################################
+
+link bincvt
+link convert
+
+procedure main()
+ local rest, track, tracks, width, track_segs, seg, byte, bytes, code
+ local meta_event, event, command, channel
+
+ event := table()
+
+ event["8"] := "note off"
+ event["9"] := "note on"
+ event["a"] := "key after-touch"
+ event["b"] := "control change"
+ event["c"] := "program change"
+ event["d"] := "channel after-touch"
+ event["e"] := "pitch wheel change"
+ event["f"] := "SysEx event"
+
+ meta_event := table()
+
+ meta_event["\x00"] := "track sequence number"
+ meta_event["\x01"] := "text"
+ meta_event["\x02"] := "copyright"
+ meta_event["\x03"] := "sequence or track name"
+ meta_event["\x04"] := "track instrument name"
+ meta_event["\x05"] := "lyric"
+ meta_event["\x06"] := "marker"
+ meta_event["\x07"] := "cue point"
+ meta_event["\x20"] := "channel marker"
+ meta_event["\x2f"] := "end of track"
+ meta_event["\x51"] := "tempo"
+ meta_event["\x54"] := "SMPTE offset"
+ meta_event["\x58"] := "time signature"
+ meta_event["\x59"] := "key signature"
+ meta_event["\x07"] := "sequencer-specific information"
+
+ track_segs := []
+
+ reads(, 100000) ? {
+ ="MThd" | stop("*** invalid header")
+ (unsigned(move(4)) = 6) | stop("*** invalid size")
+ write(
+ case unsigned(move(2)) of {
+ 0 : "single track"
+ 1 : "multi-track, synchronous"
+ 2 : "multi-track, asynchronous"
+ default : stop("*** invalid track information")
+ } | stop("*** invalid track information")
+ )
+ write(tracks := unsigned(move(2)), " tracks") |
+ stop("*** invalid track number information")
+ write(unsigned(move(2)), " delta-ticks per quarter note") |
+ stop("*** invalid delta-tick information")
+ width := *tracks + 1
+ every track := 1 to tracks do {
+ ="MTrk" | {
+ write(&errout, "*** short file")
+ break
+ }
+ rest := unsigned(move(4))
+ put(track_segs, move(rest))
+ }
+ }
+
+ track := 0
+
+ while seg := get(track_segs) do {
+ write()
+ track +:= 1
+ write("track", right(track, width), ": ", *seg, " bytes")
+ seg ? {
+ write("delta-time: ", get_time()) | stop("*** invalid delta-time")
+ byte := move(1)
+ if byte == "\xff" then {
+ write(
+ "meta-event: ",
+ \meta_event[code := move(1)] |
+ ("unknown code " || image(code))
+ )
+ bytes := unsigned(move(1))
+ if 1 <= unsigned(code) <= 7 then write(" ", move(bytes))
+ }
+ else { # event
+ byte := exbase10(ord(byte), 16)
+ write(
+ "event: ",
+ \event[byte[1]] | ("unknown command " || image(byte[1])),
+ ", channel ",
+ byte[2]
+ )
+ }
+ next # THE NEXT THING TO DO IS GET DATA BYTES
+ } # AND LOOP
+ }
+
+end
+
+# Decode delta-time.
+
+procedure get_time()
+ local delta, byte
+
+ delta := ""
+
+ while byte := move(1) do {
+ if ord(byte) >= 128 then delta ||:= char(ord(byte) - 128)
+ else {
+ delta ||:= byte
+ return unsigned(delta)
+ }
+ }
+
+ fail # short data
+
+end
+