home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v941.tgz / icon.v941src.tar / icon.v941src / ipl / progs / midisig.icn < prev    next >
Text File  |  2000-07-29  |  4KB  |  141 lines

  1. ############################################################################
  2. #
  3. #    File:     midisig.icn
  4. #
  5. #    Subject:  Program to show signature of a MIDI file
  6. #
  7. #    Author:   Ralph E. Griswold
  8. #
  9. #    Date:     August 17, 1998
  10. #
  11. ############################################################################
  12. #
  13. #  This file is in the public domain.
  14. #
  15. ############################################################################
  16. #
  17. #  This program displays the signature of a MIDI file.
  18. #
  19. ############################################################################
  20. #
  21. #  Links:  bincvt, convert
  22. #
  23. ############################################################################
  24.  
  25. link bincvt
  26. link convert
  27.  
  28. procedure main()
  29.    local rest, track, tracks, width, track_segs, seg, byte, bytes, code
  30.    local meta_event, event, command, channel
  31.  
  32.    event := table()
  33.  
  34.    event["8"] := "note off"
  35.    event["9"] := "note on"
  36.    event["a"] := "key after-touch"
  37.    event["b"] := "control change"
  38.    event["c"] := "program change"
  39.    event["d"] := "channel after-touch"
  40.    event["e"] := "pitch wheel change"
  41.    event["f"] := "SysEx event"
  42.  
  43.    meta_event := table()
  44.  
  45.    meta_event["\x00"] := "track sequence number"
  46.    meta_event["\x01"] := "text"
  47.    meta_event["\x02"] := "copyright"
  48.    meta_event["\x03"] := "sequence or track name"
  49.    meta_event["\x04"] := "track instrument name"
  50.    meta_event["\x05"] := "lyric"
  51.    meta_event["\x06"] := "marker"
  52.    meta_event["\x07"] := "cue point"
  53.    meta_event["\x20"] := "channel marker"
  54.    meta_event["\x2f"] := "end of track"
  55.    meta_event["\x51"] := "tempo"
  56.    meta_event["\x54"] := "SMPTE offset"
  57.    meta_event["\x58"] := "time signature"
  58.    meta_event["\x59"] := "key signature"
  59.    meta_event["\x07"] := "sequencer-specific information"
  60.  
  61.    track_segs := []
  62.  
  63.    reads(, 100000) ? {
  64.       ="MThd" | stop("*** invalid header")
  65.       (unsigned(move(4)) = 6) | stop("*** invalid size")
  66.       write(
  67.          case unsigned(move(2)) of {
  68.             0        :  "single track"
  69.             1        :  "multi-track, synchronous"
  70.             2        :  "multi-track, asynchronous"
  71.             default  :  stop("*** invalid track information")
  72.             } | stop("*** invalid track information")
  73.          )
  74.       write(tracks := unsigned(move(2)), " tracks") |
  75.          stop("*** invalid track number information")
  76.       write(unsigned(move(2)), " delta-ticks per quarter note") |
  77.          stop("*** invalid delta-tick information")
  78.       width := *tracks + 1
  79.       every track := 1 to tracks do {
  80.          ="MTrk" | {
  81.             write(&errout, "*** short file")
  82.             break
  83.             }
  84.          rest := unsigned(move(4))
  85.          put(track_segs, move(rest))
  86.          }
  87.       }
  88.  
  89.    track := 0
  90.  
  91.    while seg := get(track_segs) do {
  92.       write()
  93.       track +:= 1
  94.       write("track", right(track, width), ": ", *seg, " bytes")
  95.       seg ? {
  96.          write("delta-time: ", get_time()) | stop("*** invalid delta-time")
  97.          byte := move(1)
  98.          if byte == "\xff" then {
  99.             write(
  100.                "meta-event: ",
  101.                \meta_event[code := move(1)] |
  102.                   ("unknown code " || image(code))
  103.                )
  104.             bytes := unsigned(move(1))
  105.             if 1 <= unsigned(code) <= 7 then write("   ", move(bytes))
  106.             }
  107.          else {                # event
  108.             byte := exbase10(ord(byte), 16)
  109.             write(
  110.                "event: ",
  111.                \event[byte[1]] | ("unknown command " || image(byte[1])),
  112.                ", channel ",
  113.                byte[2]
  114.                )
  115.             }
  116.          next            # THE NEXT THING TO DO IS GET DATA BYTES
  117.          }            # AND LOOP
  118.       }
  119.  
  120. end
  121.  
  122. # Decode delta-time.
  123.  
  124. procedure get_time()
  125.    local delta, byte
  126.  
  127.    delta := ""
  128.  
  129.    while byte := move(1) do {
  130.       if ord(byte) >= 128 then delta ||:= char(ord(byte) - 128)
  131.       else {
  132.          delta ||:= byte
  133.          return unsigned(delta)
  134.          }
  135.       }
  136.  
  137.    fail                        # short data
  138.  
  139. end
  140.           
  141.