home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume37 / tclm / part03 < prev    next >
Encoding:
Text File  |  1993-05-15  |  61.1 KB  |  2,204 lines

  1. Newsgroups: comp.sources.misc
  2. From: durian@advtech.uswest.com (Mike Durian)
  3. Subject: v37i045:  tclm - TCL extensions for MIDI file manipulation, Part03/05
  4. Message-ID: <1993May10.215145.3932@sparky.imd.sterling.com>
  5. X-Md4-Signature: 865dd15b90efa71a5aacfe0acb278560
  6. Date: Mon, 10 May 1993 21:51:45 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: durian@advtech.uswest.com (Mike Durian)
  10. Posting-number: Volume 37, Issue 45
  11. Archive-name: tclm/part03
  12. Environment: BSD/386, Esix SV4, SunOS, TCL 6.x
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  tclm-1.0/doc/midiget.3 tclm-1.0/doc/midiput.3
  19. #   tclm-1.0/doc/mseq.1 tclm-1.0/doc/tclm_interface.3 tclm-1.0/infom
  20. #   tclm-1.0/main.c tclm-1.0/minfo tclm-1.0/mlib/Makefile
  21. #   tclm-1.0/mlib/mutil.h tclm-1.0/mrecord tclm-1.0/tclm.h
  22. # Wrapped by kent@sparky on Mon May 10 09:43:33 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 3 (of 5)."'
  26. if test -f 'tclm-1.0/doc/midiget.3' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'tclm-1.0/doc/midiget.3'\"
  28. else
  29.   echo shar: Extracting \"'tclm-1.0/doc/midiget.3'\" \(5857 characters\)
  30.   sed "s/^X//" >'tclm-1.0/doc/midiget.3' <<'END_OF_FILE'
  31. X.Dt MIDIGET 3
  32. X.Os TCLM
  33. X.Dd April 7, 1993
  34. X.Sh NAME
  35. X.Nm midiget
  36. X.Nd "tclm command to get one event from a track in a Standard MIDI File"
  37. X.Sh SYNOPSIS
  38. X.Nm
  39. X.Ar mfileId
  40. X.Ar track
  41. X.Sh DESCRIPTION
  42. X.Nm
  43. Xis a
  44. X.Xr tclm 3
  45. Xcommand that
  46. Xgets one event from the specified track
  47. Xof a
  48. XStandard
  49. X.Tn MIDI
  50. XFile.
  51. XThe first argument specifies the Standard
  52. X.Tn MIDI
  53. XFile
  54. Xand should be a value returned by either
  55. X.Xr midiread 3
  56. Xor
  57. X.Xr midimake 3 .
  58. XThe second argument specifies the
  59. Xtrack from which to get the event.
  60. XSuccessive calls to
  61. X.Nm
  62. Xon the same track
  63. Xwill get successive events from
  64. Xthat track.
  65. X.Xr midirewind 3
  66. Xcan be used to
  67. Xreturn to the beginning of the track.
  68. X.Sh RETURN VALUES
  69. X.Nm
  70. Xreturns the event in a form that can
  71. Xbe used by
  72. X.Xr midiput 3 .
  73. XIf no more events are available in the track
  74. X.Dq EOT
  75. Xis returned.
  76. X.Pp
  77. XThe return values for the non-meta events are
  78. Xas follows:
  79. X.Bl -tag -width "channelpressure" -offset indent
  80. X.It Nm channelpressure Ar channel value
  81. XThis
  82. X.Tn MIDI
  83. Xevent changes the pressure parameter for
  84. Xan entire channel.
  85. XIt has two arguments.
  86. XThe first the the channel number
  87. Xand the second is the pressure value.
  88. X.It Nm keypressure Ar channel key value
  89. XThis event changes the pressure for one key.
  90. XIt has three arguments.
  91. XThe first is the channel number, the second the
  92. Xkey value and the last the pressure value.
  93. X.It Nm noteoff Ar channel pitch velocity
  94. XThis event turns a note off.
  95. XIt has three arguments.
  96. XThe first argument is the channel, the second
  97. Xis the pitch and the third is the velocity.
  98. X.It Nm noteon Ar channel pitch velocity
  99. XThis event turns a note on.
  100. XIt takes three arguments.
  101. XThe first arguments is the channel, the
  102. Xsecond is the pitch and the third is the
  103. Xvelocity.
  104. X.It Nm parameter Ar channel param_number setting
  105. XThis event sets a parameter value.
  106. XIt has three arguments.
  107. XThe first is the channel, the second
  108. Xis the parameter number and the third
  109. Xis the setting.
  110. X.It Nm pitchwheel Ar channel setting
  111. XThis event sets the pitchwheel.
  112. XIt has two arguments.
  113. XThe first is the channel and the second
  114. Xis the setting.
  115. X.Nm
  116. Xtakes care of converting to two
  117. X7 bit values to one integer value.
  118. XThis integer value is returned in
  119. Xthe setting field.
  120. X.It Nm program Ar channel setting
  121. XThis event changes the program for a channel.
  122. XIt has two arguments.
  123. XThe first argument is the channel and
  124. Xthe second is the setting.
  125. X.It Nm sysex Ar [cont] {byte_list}
  126. XThis event is used to transfer implementation
  127. Xspecific information over
  128. X.Tn MIDI .
  129. XIt has one or two arguments.
  130. XIf the first argument is the string
  131. X.Dq cont ,
  132. Xthen
  133. Xthe sysex message which follows
  134. Xwas a continued sysex message
  135. X(ie it began with a 0xf7).
  136. XIf
  137. X.Dq cont
  138. Xis not specified, then the message
  139. Xis a normal sysex message (ie it
  140. Xbegan with a 0xf0).
  141. XThe last argument is the data.
  142. XIt is a list in which each element
  143. Xis one byte of the message.
  144. X.El
  145. X.Pp
  146. XThe return values for the meta events are:
  147. X.Bl -tag -width "metachanprefix" -offset indent
  148. X.It Nm metachanprefix Ar {byte_list}
  149. XI really don't know what this event does, so I had to
  150. Xguess on the format.
  151. XIt has one argument, which is a list of bytes.
  152. X.It Nm metacpy Ar copyright
  153. XThis event is a text event that is used for
  154. Xcopyrights.
  155. XIt has one argument which is the copyright.
  156. X.It Nm metacue Ar cue
  157. XThis event is a text event that is used for
  158. Xcue information.
  159. XIt has one argument which is the cue.
  160. X.It Nm metaeot
  161. XThis event marks the end of a track.
  162. XAll tracks must have one.
  163. XIt has no arguments
  164. X.It Nm metainstname Ar name
  165. XThis event is a text event used for instrument
  166. Xinformation.
  167. XIt has one argument which is the instrument data.
  168. X.It Nm metakey Ar key_name key_type
  169. XThis event is used to specify a key signature.
  170. XIt has two arguments.
  171. XThe first is one of the following strings:
  172. X.Dq C flat ,
  173. X.Dq G flat ,
  174. X.Dq D flat ,
  175. X.Dq A flat ,
  176. X.Dq E flat ,
  177. X.Dq B flat ,
  178. X.Dq F ,
  179. X.Dq C ,
  180. X.Dq G ,
  181. X.Dq D ,
  182. X.Dq A ,
  183. X.Dq E ,
  184. X.Dq B ,
  185. X.Dq F sharp
  186. Xor
  187. X.Dq C sharp 
  188. X(I hope I got those right - it should 7 flats to 7 sharps).
  189. XThe second argument is either:
  190. X.Dq major
  191. Xor
  192. X.Dq minor .
  193. X.It Nm metalyric Ar lyric
  194. XThis event is a text event used for lyrics.
  195. XIt has one argument which is the lyric.
  196. X.It Nm metamarker Ar marker
  197. XThis event is a text event used for marker
  198. Xinformation.
  199. XIt has one argument which is the marker data.
  200. X.It Nm metaseqname Ar name
  201. XThis event is a text event used for naming
  202. Xsequences.
  203. XIt has one argument which is the sequence
  204. Xname.
  205. X.It Nm metaseqnum Ar number
  206. XThis event is used for numbering sequences.
  207. XIt has one argument which is the sequence
  208. Xnumber.
  209. X.It Nm metaseqspec
  210. XI don't know anything about this event, and
  211. Xit is not currently implemented.
  212. X.It Nm metasmpte Ar hour minute second frame fractional_frame
  213. XThis event is used for supplying
  214. X.Tn SMPTE
  215. Xinformation.
  216. XIt has five arguments.
  217. XThis first argument is the hour position,
  218. Xthe second is the minute position
  219. Xand the third the second position.
  220. XThe fourth argument is the frame number
  221. Xand the fifth the fractional frame number.
  222. X.It Nm metatempo Ar tempo
  223. XThis event is used to specify a tempo,
  224. Xand has one argument.
  225. XUnlike
  226. X.Xr midiput 3
  227. Xwhich can take the argument as either
  228. Xbeats per minute or microseconds per
  229. Xquarter-note,
  230. X.Nm
  231. Xalways uses beats per minute.
  232. X.It Nm metatext Ar text
  233. XThis event is a generic text event.
  234. XIt has one argument which is a string.
  235. X.It Nm metatime Ar numerator denominator clocks 32nds
  236. XThis event is used for specifying the
  237. Xtime signature.
  238. XIt has four arguments.
  239. XThe first is the numerator of
  240. Xthe time signature
  241. Xand the second is the denominator.
  242. XThe third argument is how many clocks per
  243. Xmetronome beat and the fourth is
  244. Xhow many 32nd notes per quarter note.
  245. X.Nm
  246. Xtakes care of converting the denominator
  247. Xfrom a negative power of two, which is the
  248. Xform specified by Standard
  249. X.Tn MIDI
  250. Xfiles
  251. Xto the integer value.
  252. X.El
  253. X.Sh SEE ALSO
  254. X.Xr tclm 1 ,
  255. X.Xr midiread 3 ,
  256. X.Xr midimake 3 ,
  257. X.Xr midirewind 3 ,
  258. X.Xr midiput 3
  259. X.Sh AUTHORS
  260. XMike Durian - durian@advtech.uswest.com
  261. END_OF_FILE
  262.   if test 5857 -ne `wc -c <'tclm-1.0/doc/midiget.3'`; then
  263.     echo shar: \"'tclm-1.0/doc/midiget.3'\" unpacked with wrong size!
  264.   fi
  265.   # end of 'tclm-1.0/doc/midiget.3'
  266. fi
  267. if test -f 'tclm-1.0/doc/midiput.3' -a "${1}" != "-c" ; then 
  268.   echo shar: Will not clobber existing file \"'tclm-1.0/doc/midiput.3'\"
  269. else
  270.   echo shar: Extracting \"'tclm-1.0/doc/midiput.3'\" \(7802 characters\)
  271.   sed "s/^X//" >'tclm-1.0/doc/midiput.3' <<'END_OF_FILE'
  272. X.Dt MIDIPUT 3
  273. X.Os TCLM
  274. X.Dd April 7, 1993
  275. X.Sh NAME
  276. X.Nm midiput
  277. X.Nd "tclm command to append an event to a track of a Standard MIDI File"
  278. X.Sh SYNOPSIS
  279. X.Nm
  280. X.Ar mfileId
  281. X.Ar track
  282. X.Ar timing
  283. X.Ar event
  284. X.Op Ar arg ...
  285. X.Sh DESCRIPTION
  286. X.Nm
  287. Xis a tclm command that
  288. Xappends an event to a specified
  289. Xtrack in a
  290. XStandard
  291. X.Tn MIDI
  292. XFile.
  293. XThe first argument specifies the Standard
  294. X.Tn MIDI
  295. XFile
  296. Xand should be a value returned by either
  297. X.Xr midiread 3
  298. Xor
  299. X.Xr midimake 3 .
  300. XThe second argument specifies the
  301. Xtrack in which to put the event,
  302. Xand the third argument is the time in clocks since
  303. Xthe previous event in the track.
  304. XIf the timing argument is not a list, then it is
  305. Xinterpreted as a fixed length value.
  306. XIf it is a list of more than on value, then it is treated
  307. Xas a variable length value as used in Standard
  308. X.Tn MIDI
  309. XFiles.
  310. XTiming values specified as fixed length values are
  311. Xconverted to variable length values by
  312. X.Nm
  313. Xinternally.
  314. XThe next argument to
  315. X.Nm
  316. Xis the event name.
  317. XThe remaining optional arguments are dependent on the
  318. Xevent type.
  319. XThe non-meta event names, their descriptions and their arguments
  320. Xare as follows:
  321. X.Bl -tag -width "channelpressure" -offset indent
  322. X.It Nm channelpressure Ar channel value
  323. XThis
  324. X.Tn MIDI
  325. Xevent changes the pressure parameter for
  326. Xan entire channel.
  327. XIt takes two arguments.
  328. XThe first the the channel number
  329. Xand the second is the pressure value.
  330. XBoth values should be less than 128.
  331. X.It Nm keypressure Ar channel key value
  332. XThis event changes the pressure for one key.
  333. XIt takes three arguments.
  334. XThe first is the channel number, the second the
  335. Xkey value and the last the pressure value.
  336. XAll values should be less than 128.
  337. X.It Nm noteoff Ar channel pitch velocity
  338. XThis event turns a note off.
  339. XIt takes two arguments with an optional third.
  340. XThe first argument is the channel and the second
  341. Xis the pitch.
  342. XIf a third argument is specified, it is the
  343. Xvelocity for the note off.
  344. XIf it is not specified, then a velocity of
  345. Xzero is assumed.
  346. XIf a velocity of zero is used, either through
  347. Xassumption or as specified, then a note
  348. Xon event with a velocity of zero will be substituted.
  349. XThis is to take advantage of the running status,
  350. Xsince most
  351. X.Tn MIDI
  352. Xevents are note on and
  353. Xnote off events.
  354. XAll arguments should have values of 127 or less.
  355. X.It Nm noteon Ar channel pitch velocity
  356. XThis event turns a note on.
  357. XIt takes three arguments.
  358. XThe first argument is the channel, the
  359. Xsecond is the pitch and the third is the
  360. Xvelocity.
  361. XAll values should be less than 128.
  362. X.It Nm parameter Ar channel param_number setting
  363. XThis event sets a parameter value.
  364. XIt takes three arguments.
  365. XThe first is the channel, the second
  366. Xis the parameter number and the third
  367. Xis the setting.
  368. XAll values should be 127 or less.
  369. X.It Nm pitchwheel Ar channel setting
  370. XThis event sets the pitchwheel.
  371. XIt takes two arguments.
  372. XThe first is the channel and the second
  373. Xis the setting.
  374. XTclm takes care of converting the pitchwheel
  375. Xsetting to the proper
  376. X.Tn MIDI
  377. Xevent
  378. Xform (eg two 7 bit values).
  379. XThe channel should be less than 128 and
  380. Xthe setting should be less than 0x4000.
  381. X.It Nm program Ar channel setting
  382. XThis event changes the program for a channel.
  383. XIt takes two arguments.
  384. XThe first argument is the channel, and
  385. Xthe second is the setting.
  386. XBoth should be less than 128.
  387. X.It Nm sysex Ar [cont] {byte_list}
  388. XThis event is used to transfer implementation
  389. Xspecific information over
  390. X.Tn MIDI .
  391. XIt takes one or two arguments.
  392. XIf the first argument is the string
  393. X.Dq cont ,
  394. Xthen
  395. X.Nm
  396. Xwill generate a sysex message in
  397. Xthe continuation form.
  398. XThe second argument is then treated
  399. Xas the data.
  400. XIf there is only one argument, then
  401. Xit is treated as the
  402. Xdata.
  403. XThe data should be in a standard tcl
  404. Xlist with each element being a byte
  405. Xof the sysex message.
  406. XThe data need not specify the initial
  407. X0xf0 or 0xf7 byte as
  408. X.Nm
  409. Xincludes the proper value depending
  410. Xon if the
  411. X.Dq cont
  412. Xstring was an argument.
  413. XIt is up to the user to make sure
  414. Xall sysex messages are properly
  415. Xterminated.
  416. XAll data in the sysex message should
  417. Xbe less than 128.
  418. X.El
  419. X.Pp
  420. XAll non-meta events except sysex take advantage
  421. Xof the running status feature of Standard
  422. X.Tn MIDI
  423. XFiles.
  424. XThat is, if one event immediately follows an event
  425. Xof the same track on the same channel, then the
  426. Xevent type need not be explicitly stated and is
  427. Xassumed to be the same as the previous value.
  428. X.Pp
  429. XIn addition to the events listed above,
  430. X.Nm
  431. Xcan also be used with meta events.
  432. XTheir names, descriptions and parameters are:
  433. X.Bl -tag -width "metachanprefix" -offset indent
  434. X.It Nm metachanprefix Ar {byte_list}
  435. XI really don't know what this event does, so I had to
  436. Xguess on the format.
  437. XIt takes one argument, which is a list of bytes.
  438. X.It Nm metacpy Ar copyright
  439. XThis event is a text event that is used for
  440. Xcopyrights.
  441. XIt takes one argument which should be the copyright
  442. Xas a string.
  443. X.It Nm metacue Ar cue
  444. XThis event is a text event that is used for
  445. Xcue information.
  446. XIt takes one argument which should be the cue
  447. Xas a string.
  448. X.It Nm metaeot
  449. XThis event marks the end of a track.
  450. XAll tracks must have one.
  451. XIt takes no arguments.
  452. X.It Nm metainstname Ar name
  453. XThis event is a text event used for instrument
  454. Xinformation.
  455. XIt takes one arguments which should be the instrument
  456. Xdata as a string.
  457. X.It Nm metakey Ar key_name key_type
  458. XThis event is used to specify a key signature.
  459. XIt takes two arguments.
  460. XThe first should be one of the following strings:
  461. X.Dq C flat ,
  462. X.Dq G flat ,
  463. X.Dq D flat ,
  464. X.Dq A flat ,
  465. X.Dq E flat ,
  466. X.Dq B flat ,
  467. X.Dq F ,
  468. X.Dq C ,
  469. X.Dq G ,
  470. X.Dq D ,
  471. X.Dq A ,
  472. X.Dq E ,
  473. X.Dq B ,
  474. X.Dq F sharp
  475. Xor
  476. X.Dq C sharp 
  477. X(I hope I got those right - it should 7 flats to 7 sharps).
  478. XThe second argument should be either:
  479. X.Dq major
  480. Xor
  481. X.Dq minor .
  482. X.It Nm metalyric Ar lyric
  483. XThis event is a text event used for lyrics.
  484. XIt takes one argument which is the lyric
  485. Xin string form.
  486. X.It Nm metamarker Ar marker
  487. XThis event is a text event used for marker
  488. Xinformation.
  489. XIt takes one argument which is the marker
  490. Xdata as a string.
  491. X.It Nm metaseqname Ar name
  492. XThis event is a text event used for naming
  493. Xsequences.
  494. XIt takes one argument which is the sequence
  495. Xname as a string.
  496. X.It Nm metaseqnum Ar number
  497. XThis event is used for numbering sequences.
  498. XIt takes one argument which is the sequence
  499. Xnumber.
  500. X.Nm
  501. Xconverts the number to the proper two
  502. Xbyte form.
  503. X.It Nm metaseqspec
  504. XI don't know anything about this event, and
  505. Xit is not currently implemented.
  506. X.It Nm metasmpte Ar hour minute second frame fractional_frame
  507. XThis event is used for supplying
  508. X.Tn SMPTE
  509. Xinformation.
  510. XIt takes five arguments.
  511. XThe first argument is the hour position,
  512. Xthe second is the minute position
  513. Xand the third the second position.
  514. XThe fourth argument is the frame number
  515. Xand the fifth the fractional frame number.
  516. X.It Nm metatempo Ar tempo
  517. XThis event is used to specify a tempo.
  518. XIt takes one argument.
  519. XThe argument should be an integer.
  520. XIf the number has a
  521. X.Sq u
  522. Xcharacter at
  523. Xthe end it is treated as if it
  524. Xrepresents microseconds per quarter-note.
  525. XIf it does not have a
  526. X.Sq u
  527. Xcharacter then
  528. Xit is treated as if it represents
  529. Xbeats per minute.
  530. X.It Nm metatext Ar text
  531. XThis event is a generic text event.
  532. XIt take one argument which is a string.
  533. X.It Nm metatime Ar numerator denominator clocks 32nds
  534. XThis event is used for specifying the
  535. Xtime signature.
  536. XIt takes four arguments.
  537. XThe first is the numerator of
  538. Xthe time signature
  539. Xand the second is the denominator.
  540. XThe third argument is the number of clocks per
  541. Xmetronome beat and the fourth is
  542. Xthe number of 32nd notes per quarter note.
  543. X.Nm
  544. Xtakes care of converting the denominator
  545. Xto a negative power of two, which is the
  546. Xform specified by Standard
  547. X.Tn MIDI
  548. XFiles.
  549. X.El
  550. X.Sh RETURN VALUES
  551. X.Nm
  552. Xreturns nothing.
  553. X.Sh BUGS
  554. X.Nm
  555. Xshould be rewritten to handle
  556. Xinserting events in the middle
  557. Xof a track.
  558. X.Sh SEE ALSO
  559. X.Xr tclm 1 ,
  560. X.Xr midiread 3 ,
  561. X.Xr midimake 3 ,
  562. X.Xr midiget 3
  563. X.Sh AUTHORS
  564. XMike Durian - durian@advtech.uswest.com
  565. END_OF_FILE
  566.   if test 7802 -ne `wc -c <'tclm-1.0/doc/midiput.3'`; then
  567.     echo shar: \"'tclm-1.0/doc/midiput.3'\" unpacked with wrong size!
  568.   fi
  569.   # end of 'tclm-1.0/doc/midiput.3'
  570. fi
  571. if test -f 'tclm-1.0/doc/mseq.1' -a "${1}" != "-c" ; then 
  572.   echo shar: Will not clobber existing file \"'tclm-1.0/doc/mseq.1'\"
  573. else
  574.   echo shar: Extracting \"'tclm-1.0/doc/mseq.1'\" \(6593 characters\)
  575.   sed "s/^X//" >'tclm-1.0/doc/mseq.1' <<'END_OF_FILE'
  576. X.Dt MSEQ 1
  577. X.Os TCLM
  578. X.Dd April 7, 1993
  579. X.Sh NAME
  580. X.Nm mseq
  581. X.Nd "a tclm script to sequence MIDI files according to a simple language"
  582. X.Sh SYNOPSIS
  583. X.Nm
  584. X.Op sequence_file Op midi_file
  585. X.Sh DESCRIPTION
  586. X.Nm
  587. Xis a
  588. X.Xr tclm 1
  589. Xscript that sequences Standard
  590. X.Tn MIDI
  591. Xfiles according to a simple
  592. Xlanguage.
  593. XThe sequenced result is placed in a new
  594. X.Tn MIDI
  595. Xfile.
  596. X.Pp
  597. XIf an output
  598. X.Tn MIDI
  599. Xfile is not specified, then
  600. Xoutput is sent to
  601. X.Em stdout .
  602. XIf an input sequence file is not specified then
  603. Xinput is read from
  604. X.Em stdin .
  605. X.Pp
  606. XThe purpose of
  607. X.Nm
  608. Xis to generate more complicated
  609. X.Tn MIDI
  610. Xfiles from
  611. Xsmaller
  612. X.Tn MIDI
  613. Xfile components.
  614. X.Ss SEQUENCING LANGUAGE
  615. XThe language 
  616. X.Nm
  617. Xuses is
  618. X.Dq spartan
  619. Xat best, but does provide
  620. Xuseful functionality.
  621. XIt allows one to play parts in parallel
  622. Xby specifying information for different
  623. Xtracks, group phrases into blocks
  624. Xand repeat blocks.
  625. X.Pp
  626. XThe
  627. X.Tn BNF ,
  628. Xor
  629. X.No quasi- Ns Tn BNF
  630. Xas I don't quite
  631. Xremember the true form, looks like this:
  632. X.sp
  633. X.Bl -item -compact -offset indent
  634. X.It
  635. Xmseq_file :== section+
  636. X.It
  637. Xsection :== 
  638. X.Em track
  639. Xstatement+
  640. X.It
  641. Xstatement :== labeled sequence | filename | command | comment
  642. X.It
  643. Xlabeled sequence :== label sequence
  644. X.It
  645. Xlabel :==
  646. X.Pf name Em \:
  647. X.It
  648. Xsequence :== block | filename
  649. X.It
  650. Xblock :==
  651. X.Em {
  652. Xsequence+
  653. X.Em }
  654. X.It
  655. Xcommand :==
  656. X.Em repeat
  657. Xlabel |
  658. X.Em repeat
  659. Xlabel multiplier
  660. X.It
  661. Xmultiplier :== number
  662. X.It
  663. Xcomment :==
  664. X.Em #
  665. Xanything to end-of-line
  666. X.El
  667. X.sp
  668. XThe results look like this (though this isn't
  669. Xa very practical example):
  670. X.sp
  671. X.Bd -literal -compact -offset indent
  672. Xtrack
  673. X# This is track 1
  674. Xpat1.mid
  675. Xpat2.mid
  676. XA: {
  677. X    pat3.mid
  678. X    B: { # block B:
  679. X        pat4.mid
  680. X        pat5.mid
  681. X    }
  682. X    pat6.mid
  683. X    repeat B: 3
  684. X}
  685. Xpat7.mid
  686. Xpat8.mid # pattern 8
  687. X
  688. X# This is track 2
  689. Xtrack
  690. Xpat1.mid
  691. Xpat2.mid
  692. XA: {
  693. X    pat3.mid
  694. X    pat4.mid
  695. X    B: pat5.mid
  696. X    pat6.mid
  697. X    repeat B: 6
  698. X}
  699. Xpat7.mid
  700. Xrepeat A:
  701. X.Ed
  702. X.Pp
  703. XThere are six main parts to a sequence
  704. Xfile.
  705. XThere are
  706. X.Em tracks ,
  707. X.Em blocks ,
  708. X.Em repeats ,
  709. X.Em comments ,
  710. Xand
  711. X.Em files .
  712. XThe tracks are different sections of the sequence
  713. Xthat should play in parallel and should
  714. Xbelong to separate tracks in the output
  715. X.Tn MIDI
  716. Xfile.
  717. XEach track will start at time 0, the beginning
  718. Xof the sequence.
  719. XEvery sequence must have at least one track.
  720. XTracks are designated by the word
  721. X.Em track .
  722. XThis is a simple example of using tracks,
  723. X.sp
  724. X.Bd -literal -compact -offset indent
  725. Xtrack
  726. Xpart1.mid
  727. Xpart2.mid
  728. Xpart3.mid
  729. X
  730. Xtrack
  731. XpartA.mid
  732. XpartB.mid
  733. XpartC.mid
  734. X.Ed
  735. X.sp
  736. XIn this case two tracks will be created and, assuming
  737. Xall the parts are the same length, part1.mid will be
  738. Xplayed the same time partA.mid is played, part2.mid
  739. Xwill be played the same time partB.mid is played, etc.
  740. X.Pp
  741. XBlocks are groups of one or more files or other
  742. Xblocks.
  743. XEach block has a label, which is designated by
  744. Xending in a
  745. X.So : Sc .
  746. XIf a block is to consist of only on file, then
  747. Xit may be labeled directly like,
  748. X.sp
  749. X.Bd -literal -compact -offset indent
  750. XShortBlock: part1.mid
  751. X.Ed
  752. X.sp
  753. XOtherwise the block should be enclosed in
  754. Xcurly braces like,
  755. X.sp
  756. X.Bd -literal -compact -offset indent
  757. XLongerBlock: {
  758. X    part1.mid
  759. X    part2.mid
  760. X    part3.mid
  761. X}
  762. X.Ed
  763. X.sp
  764. XBlocks may even contain other blocks like,
  765. X.sp
  766. X.Bd -literal -compact -offset indent
  767. XOutterBlock: {
  768. X    part1.mid
  769. X    InnerBlock: {
  770. X        part2.mid
  771. X        part3.mid
  772. X    }
  773. X    part4.mid
  774. X}
  775. X.Ed
  776. X.sp
  777. XIn this case
  778. X.Em InnerBlock:
  779. Xcontains
  780. X.Em part2.mid
  781. Xand
  782. X.Em part3.mid ,
  783. Xwhile
  784. X.Em OutterBlock:
  785. Xcontains
  786. X.Em part1.mid , part2.mid , part3.mid
  787. X.Em part4.mid .
  788. X.Pp
  789. XRepeats provide a way of re-sequencing previously
  790. Xdefined blocks.
  791. XRepeats consist of the string
  792. X.Em repeat
  793. Xfollowed by a block name, including the colon,
  794. Xand an optional number.
  795. XThe optional number specifies the number of times
  796. Xthe block should be repeated.
  797. XIf no number is specified, the block is only
  798. Xrepeated once.
  799. XA simple example of a repeat looks like,
  800. X.sp
  801. X.Bd -literal -compact -offset indent
  802. XABlock: part1.mid
  803. Xrepeat ABlock: 3
  804. X.Ed
  805. X.sp
  806. XThe sequence generated by this
  807. Xfragment would contain,
  808. X.Em part1.mid , part1.mid , part1.mid
  809. Xand
  810. X.Em part1.mid .
  811. XA more complicated example might look like,
  812. X.sp
  813. X.Bd -literal -compact -offset indent
  814. XBlock1: {
  815. X    part1.mid
  816. X    part2.mid
  817. X    Block2: {
  818. X        part3.mid
  819. X        part4.mid
  820. X    }
  821. X    repeat Block2: 2
  822. X}
  823. Xpart5.mid
  824. Xrepeat Block1:
  825. X.Ed
  826. X.sp
  827. XThis sequence generates,
  828. X.Em part1.mid , part2.mid , part3.mid ,
  829. X.Em part4.mid , part3.mid , part4.mid ,
  830. X.Em part3.mid , part4.mid , part5.mid ,
  831. X.Em part1.mid , part2.mid , part3.mid ,
  832. X.Em part4.mid , part3.mid , part4.mid ,
  833. X.Em part3.mid
  834. Xand
  835. X.Em part4.mid .
  836. X.Pp
  837. XComments begin with a
  838. X.Sq #
  839. Xand continue to the
  840. Xend of a line.
  841. X.Nm
  842. Xcompletely ignores anything in a comment.
  843. XThis is an example of a few comments,
  844. X.sp
  845. X.Bd -literal -compact -offset indent
  846. Xtrack
  847. X# This track is for the drum part
  848. Xbackbeat: pat1.mid
  849. Xrepeat pat1.mid 7
  850. Xpat2.mid   # here's a turn around fill
  851. X.Ed
  852. X.sp
  853. X.Pp
  854. XThe final part of a sequence file is the
  855. Xmost important.
  856. XIt is the filenames of the smaller
  857. X.Tn MIDI
  858. Xfiles that are to be
  859. Xsequenced.
  860. XEach filename specifies one
  861. X.Tn MIDI
  862. Xfile
  863. Xand is read into the sequence as they are
  864. Xencountered in the sequence file.
  865. XThey are also read in when blocks containing
  866. Xthem are repeated.
  867. XCurrently, only
  868. X.Tn MIDI
  869. Xfiles of format
  870. X1 are accepted.
  871. X.Pp
  872. XThough there is not much complexity in the sequencing
  873. Xlanguage, it should be rich enough
  874. Xto allow the easy creation of sophisticated
  875. X.Tn MIDI
  876. Xfiles.
  877. X.Ss OUTPUT MIDI FILE
  878. XThe final output
  879. X.Tn MIDI
  880. Xfile created from
  881. Xthe sequence is in the Standard
  882. X.Tn MIDI
  883. XFormat,
  884. Xand is a format type 1 file.
  885. XAll the meta events from each sequenced
  886. X.Tn MIDI
  887. Xare merged together and put in track 0 at their
  888. Xproper relative times.
  889. XFor instance, a
  890. X.Em metaseqname
  891. Xevent occurring at time
  892. X10 in the first track will be at time 10 in the output
  893. Xfile as will a
  894. X.Em metaseqname
  895. Xevent occurring at time
  896. X10 in the third track.
  897. XBe aware of potential conflicts between
  898. X.Em metatempo
  899. Xevents in different tracks.
  900. X.Pp
  901. XThe remaining tracks in the output
  902. X.Tn MIDI
  903. Xfile
  904. Xwill correspond to the
  905. X.Em tracks
  906. Xin the sequence file.
  907. XThese tracks are created by collapsing each smaller
  908. X.Tn MIDI
  909. Xfile listed in the sequence file to
  910. Xjust two tracks, track 0 which remains unchanged, and
  911. Xtrack 1 which is created by merging all the other
  912. Xtracks in the file.
  913. XThese collapsed files are then concatenated together
  914. Xto form one long
  915. X.Tn MIDI
  916. Xfile for each track.
  917. XAs mentioned above, the track 0's from each sequence
  918. X.Em track
  919. Xare then merged to form one new track 0 while the other tracks
  920. Xare kept separate in the final output.
  921. X.Pp
  922. XThe resulting
  923. X.Tn MIDI
  924. Xfile can then be manipulated
  925. Xjust like any other
  926. X.Tn MIDI
  927. Xfile.
  928. X.Sh SEE ALSO
  929. X.Xr tclm 1 ,
  930. X.Xr midimerge 3 ,
  931. X.Xr midiget 3
  932. X.Sh AUTHORS
  933. XMike Durian - durian@advtech.uswest.com
  934. END_OF_FILE
  935.   if test 6593 -ne `wc -c <'tclm-1.0/doc/mseq.1'`; then
  936.     echo shar: \"'tclm-1.0/doc/mseq.1'\" unpacked with wrong size!
  937.   fi
  938.   # end of 'tclm-1.0/doc/mseq.1'
  939. fi
  940. if test -f 'tclm-1.0/doc/tclm_interface.3' -a "${1}" != "-c" ; then 
  941.   echo shar: Will not clobber existing file \"'tclm-1.0/doc/tclm_interface.3'\"
  942. else
  943.   echo shar: Extracting \"'tclm-1.0/doc/tclm_interface.3'\" \(4457 characters\)
  944.   sed "s/^X//" >'tclm-1.0/doc/tclm_interface.3' <<'END_OF_FILE'
  945. X.Dt TCLM_INTERFACE 3
  946. X.Os TCLM
  947. X.Dd April 20, 1993
  948. X.Sh NAME
  949. X.Nm tclm_interface
  950. X.Nd "function hooks to interface tclm to a MIDI device"
  951. X.Sh SYNOPSIS
  952. X.Fd #include <mdevice.h>
  953. X.Fd typedef enum {PLAY, RECORD, PLAYRECORD} PlayMode
  954. X.Ft int
  955. X.Fn play_tracks "int dev" "TCHUNK *tracks" "int *indices" "int num" "int repeat"
  956. X.Ft int
  957. X.Fn record_tracks "int dev" "TCHUNK *p_tracks" "int *indices" "int p_num" "TCHUNK *r_track" "int repeat"
  958. X.Ft int
  959. X.Fn stop_processing "int dev"
  960. X.Ft int
  961. X.Fn open_midi_device "PlayMode mode"
  962. X.Ft int
  963. X.Fn init_midi_device "int dev" "HCHUNK *hd" "double reltempo"
  964. X.Ft int
  965. X.Fn start_midi_device "int dev" "PlayMode mode"
  966. X.Ft int
  967. X.Fn stop_midi_device "int dev" "PlayMode mode"
  968. X.Ft int
  969. X.Fn close_midi_device "int dev"
  970. X.Sh DESCRIPTION
  971. X.Ss play_tracks
  972. X.Fn play_tracks
  973. Xprovides the functionality to convert events in
  974. XStandard
  975. X.Tn MIDI
  976. XFile
  977. X.No ( Tn SMF Ns No )
  978. Xform to a form
  979. Xthe
  980. X.Tn MIDI
  981. Xdevice wants, and to send the converted
  982. Xevents to the device to be played.
  983. X.Pp
  984. XThe
  985. X.Ar dev
  986. Xargument specifies the
  987. X.Tn MIDI
  988. Xdevice that the
  989. Xevents will be sent to.
  990. XThis value is what was returned from
  991. X.Fn open_midi_device .
  992. XThe second argument,
  993. X.Ar tracks ,
  994. Xis a pointer to a list of
  995. X.Tn SMF
  996. Xtracks as
  997. Xfound in
  998. X.Tn MIDI
  999. Xfiles.
  1000. X.Ar indices
  1001. Xis a pointer to a list of indices to the
  1002. X.Ar tracks .
  1003. XEach index is the index number of a track
  1004. Xthat should be played.
  1005. XThe fourth argument,
  1006. X.Ar num ,
  1007. Xis the number of indices pointed to by
  1008. X.Ar indices .
  1009. XIt is also the number of tracks to play.
  1010. X.Ar repeat ,
  1011. Xthe final argument is a boolean value.
  1012. XIf it is true it signifies that the tracks
  1013. Xshould be replayed when they reach their
  1014. Xend.
  1015. X.Pp
  1016. X.Fn play_tracks
  1017. Xdoes not send the actual commands
  1018. Xto start and stop playing.
  1019. XIt only processes and sends the
  1020. Xevents.
  1021. X.Ss record_tracks
  1022. X.Fn record_tracks
  1023. Xis very similar to
  1024. X.Fn play_tracks
  1025. Xand only differs in one argument.
  1026. XIt provides the functionality
  1027. Xto play
  1028. X.Em and
  1029. Xrecord
  1030. X.Tn SMF
  1031. Xfiles.
  1032. XIf
  1033. X.Ar p_tracks
  1034. Xis NULL, or
  1035. X.Ar p_num
  1036. Xis 0, then nothing will be played
  1037. Xwhile recording.
  1038. X.Pp
  1039. XThe only argument that differs from
  1040. X.Fn play_tracks
  1041. Xis the
  1042. X.Ar r_track
  1043. Xargument.
  1044. XThis argument specifies
  1045. Xthe track where the recorded
  1046. Xevents should be placed.
  1047. X.Ss stop_processing
  1048. X.Fn stop_processing
  1049. Xprovides the ability to abort
  1050. Xfrom a
  1051. X.Fn play_tracks
  1052. Xcall or a
  1053. X.Fn record_tracks
  1054. Xcall.
  1055. XWhen called,
  1056. X.Fn stop_processing ,
  1057. Xforces the two routines
  1058. Xto exit with success.
  1059. X.Fn stop_processing
  1060. Xis designed for use in
  1061. Xprocesses playing or recording in
  1062. Xthe background.
  1063. XIt takes one argument, the device
  1064. Xdescriptor and returns 1 on success
  1065. Xand 0 on failure.
  1066. X.Ss open_midi_device
  1067. X.Fn open_midi_device
  1068. Xopens the appropriate
  1069. X.Tn MIDI
  1070. Xdevice for use by the
  1071. Xother functions.
  1072. XIt takes one argument which is the
  1073. Xplay mode.
  1074. XThe play mode will be one of either
  1075. X.Tn PLAY , RECORD
  1076. Xor
  1077. X.Tn PLAYRECORD .
  1078. XIt returns the descriptor for
  1079. Xthat device.
  1080. X.Ss init_midi_device
  1081. X.Fn init_midi_device
  1082. Xtakes care of any initial
  1083. Xset up the device needs.
  1084. X.Ar dev
  1085. Xis the device descriptor as
  1086. Xreturned by
  1087. X.Fn open_midi_device .
  1088. XThe
  1089. X.Ar hd
  1090. Xargument contains the
  1091. Xheader chunk information
  1092. Xfor the file to be processed.
  1093. XThe division information in the header chunk might
  1094. Xbe especially useful.
  1095. XThe
  1096. X.Ar reltempo
  1097. Xargument contains a tempo
  1098. Xscaling factor.
  1099. XIf possible any tempos
  1100. Xfound in the playing files should
  1101. Xbe multiplied by this value.
  1102. XIf that is not possible, this argument
  1103. Xmay be ignored.
  1104. X.Ss start_midi_device
  1105. X.Fn start_midi_device
  1106. Xstarts the
  1107. X.Tn MIDI
  1108. Xdevice
  1109. Xspecified by
  1110. X.Ar dev
  1111. Xplaying or recording or both.
  1112. XThe
  1113. X.Ar mode
  1114. Xargument determines which should occur.
  1115. XIt will be one of
  1116. X.Tn PLAY , RECORD
  1117. Xor
  1118. X.Tn PLAYRECORD .
  1119. X.Ss stop_midi_device
  1120. X.Fn stop_midi_device
  1121. Xstops the
  1122. X.Tn MIDI
  1123. Xdevice
  1124. Xfrom further playing or recording.
  1125. XIt differs from
  1126. X.Fn stop_processing
  1127. Xin that it switches the device
  1128. Xoff rather than stopping the
  1129. Xflow of data to the device.
  1130. XThe argument
  1131. X.Ar dev
  1132. Xcontains the descriptor for
  1133. Xthe device as returned by
  1134. X.Fn open_midi_device .
  1135. X.Ar mode
  1136. Xcontains the same value that was used
  1137. Xin
  1138. X.Fn start_midi_device .
  1139. X.Ss close_midi_device
  1140. X.Fn close_midi_device
  1141. Xdoes any clean up necessary for the
  1142. X.tn MIDI
  1143. Xdevice and closes the
  1144. Xdescriptor.
  1145. X.Ar dev
  1146. Xis the descriptor for the device
  1147. Xas returned by
  1148. X.Fn open_midi_device .
  1149. X.Sh RETURN VALUES
  1150. XAll functions with the exception of
  1151. X.Fn open_midi_device ,
  1152. Xwhich returns the descriptor number,
  1153. Xreturn 1 on success and 0 otherwise.
  1154. X.Fn open_midi_device
  1155. Xreturns -1 on error.
  1156. X.Sh SEE ALSO
  1157. X.Xr tclm 1
  1158. X.Sh AUTHORS
  1159. XMike Durian - durian@advtech.uswest.com
  1160. END_OF_FILE
  1161.   if test 4457 -ne `wc -c <'tclm-1.0/doc/tclm_interface.3'`; then
  1162.     echo shar: \"'tclm-1.0/doc/tclm_interface.3'\" unpacked with wrong size!
  1163.   fi
  1164.   # end of 'tclm-1.0/doc/tclm_interface.3'
  1165. fi
  1166. if test -f 'tclm-1.0/infom' -a "${1}" != "-c" ; then 
  1167.   echo shar: Will not clobber existing file \"'tclm-1.0/infom'\"
  1168. else
  1169.   echo shar: Extracting \"'tclm-1.0/infom'\" \(6958 characters\)
  1170.   sed "s/^X//" >'tclm-1.0/infom' <<'END_OF_FILE'
  1171. X#!/usr/local/bin/tclm -f
  1172. X#
  1173. X# Copyright (c) 1993 Michael B. Durian.  All rights reserved.
  1174. X#
  1175. X# Redistribution and use in source and binary forms, with or without
  1176. X# modification, are permitted provided that the following conditions
  1177. X# are met:
  1178. X# 1. Redistributions of source code must retain the above copyright
  1179. X#    notice, this list of conditions and the following disclaimer.
  1180. X# 2. Redistributions in binary form must reproduce the above copyright
  1181. X#    notice, this list of conditions and the following disclaimer in the
  1182. X#    documentation and/or other materials provided with the distribution.
  1183. X# 3. All advertising materials mentioning features or use of this software
  1184. X#    must display the following acknowledgement:
  1185. X#    This product includes software developed by Michael B. Durian.
  1186. X# 4. The name of the the Author may be used to endorse or promote 
  1187. X#    products derived from this software without specific prior written 
  1188. X#    permission.
  1189. X#
  1190. X# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  1191. X# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1192. X# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
  1193. X# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  1194. X# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1195. X# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1196. X# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1197. X# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1198. X# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1199. X# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1200. X# SUCH DAMAGE.
  1201. X#
  1202. X
  1203. X# infom,v 1.2 1993/05/06 21:42:20 durian Exp
  1204. X
  1205. X# get filename arg
  1206. Xif {[string compare [lindex $argv 0] "-f"] == 0} {
  1207. X    incr argc -2
  1208. X    set argv [lrange $argv 2 end]
  1209. X}
  1210. X
  1211. Xcase $argc in {
  1212. X    0 {
  1213. X        set infile_name stdin
  1214. X        set outfile_name stdout
  1215. X    } 1 {
  1216. X        set infile_name [lindex $argv 0]
  1217. X        set outfile_name stdout
  1218. X    } 2 {
  1219. X        set infile_name [lindex $argv 0]
  1220. X        set outfile_name [lindex $argv 1]
  1221. X    } default {
  1222. X        puts stderr "Usage: infom [info_file [midi_file]]"
  1223. X        exit 1
  1224. X    }
  1225. X}
  1226. X
  1227. Xproc PutEvent {event mfile track_num last_timing} {
  1228. X
  1229. X    # get the timing part of the event
  1230. X    set timing [lindex $event 0]
  1231. X    # minus :
  1232. X    set timing [string trimright $timing :]
  1233. X
  1234. X    #determine time since last event
  1235. X    set delta [expr {$timing - $last_timing}]
  1236. X
  1237. X    case [lindex $event 1] in {
  1238. X    NOTEOFF {
  1239. X        set chan [lindex $event 3]
  1240. X        set pitch [lindex $event 5]
  1241. X        set vel [lindex $event 7]
  1242. X        midiput $mfile $track_num $delta noteoff $chan $pitch $vel
  1243. X    } NOTEON {
  1244. X        set chan [lindex $event 3]
  1245. X        set pitch [lindex $event 5]
  1246. X        set vel [lindex $event 7]
  1247. X        midiput $mfile $track_num $delta noteon $chan $pitch $vel
  1248. X    } KEY {
  1249. X        set chan [lindex $event 4]
  1250. X        set pitch [lindex $event 6]
  1251. X        set pres [lindex $event 8]
  1252. X        midiput $mfile $track_num $delta keypressure $chan $pitch $pres
  1253. X    } PARAMETER {
  1254. X        set chan [lindex $event 3]
  1255. X        set param [lindex $event 5]
  1256. X        set set [lindex $event 7]
  1257. X        midiput $mfile $track_num $delta parameter $chan $param $set
  1258. X    } PROGRAM {
  1259. X        set chan [lindex $event 3]
  1260. X        set prog [lindex $event 5]
  1261. X        midiput $mfile $track_num $delta program $chan $prog
  1262. X    } CHANNEL {
  1263. X        set chan [lindex $event 4]
  1264. X        set pres [lindex $event 6]
  1265. X        midiput $mfile $track_num $delta channelpressure $chan $pres
  1266. X    } PITCH {
  1267. X        set chan [lindex $event 4]
  1268. X        set val [lindex $event 6]
  1269. X        midiput $mfile $track_num $delta pitchwheel $chan $val
  1270. X    } METACHANPREFIX {
  1271. X        midiput $mfile $track_num $delta metachanprefix \
  1272. X            [lrange $event 2 end]
  1273. X    } METACPY {
  1274. X        midiput $mfile $track_num $delta metacpy [lrange $event 2 end]
  1275. X    } METACUE {
  1276. X        midiput $mfile $track_num $delta metacue [lrange $event 2 end]
  1277. X    } METAEOT {
  1278. X        midiput $mfile $track_num $delta metaeot
  1279. X    } METAINSTNAME {
  1280. X        midiput $mfile $track_num $delta metainstname \
  1281. X            [lrange $event 2 end]
  1282. X    } METAKEY {
  1283. X        midiput $mfile $track_num $delta metakey [lindex $event 2] \
  1284. X            [lindex $event 3]
  1285. X    } METALYRIC {
  1286. X        midiput $mfile $track_num $delta metalyric \
  1287. X            [lrange $event 2 end]
  1288. X    } METAMARKER {
  1289. X        midiput $mfile $track_num $delta metamarker \
  1290. X            [lrange $event 2 end]
  1291. X    } METASEQNAME {
  1292. X        midiput $mfile $track_num $delta metaseqname \
  1293. X            [lrange $event 2 end]
  1294. X    } METASEQNUM {
  1295. X        midiput $mfile $track_num $delta metaseqnum [lindex $event 2]
  1296. X    } METASEQSPEC {
  1297. X        # no idea, so we skip it
  1298. X        return $last_timing
  1299. X    } METASMPTE {
  1300. X        set hr [string trimright [lindex $event 3] ,]
  1301. X        set mi [string trimright [lindex $event 5] ,]
  1302. X        set se [string trimright [lindex $event 7] ,]
  1303. X        set fr [string trimright [lindex $event 9] ,]
  1304. X        set ff [lindex $event 12]
  1305. X        midiput $mfile $track_num $delta metasmpte $hr $mi $se $fr $ff
  1306. X    } METATEMPO {
  1307. X        midiput $mfile $track_num $delta metatempo [lindex $event 2]
  1308. X    } METATEXT {
  1309. X        midiput $mfile $track_num $delta metatext [lrange $event 2 end]
  1310. X    } METATIME {
  1311. X        set fraction [split [lindex $event 2] /]
  1312. X        set num [lindex $fraction 0]
  1313. X        set den [lindex $fraction 1]
  1314. X        set cpm [lindex $event 3]
  1315. X        set _32 [lindex $event 8]
  1316. X        midiput $mfile $track_num $delta metatime $num $den $cpm $_32
  1317. X    } SYSEX {
  1318. X        if {[string compare [lindex $event 2] cont] == 0} {
  1319. X            midiput $mfile $track_num $delta sysex cont \
  1320. X                [lrange $event 3 end]
  1321. X        } else {
  1322. X            midiput $mfile $track_num $delta sysex \
  1323. X                [lrange $event 2 end]
  1324. X        }
  1325. X    }
  1326. X    }
  1327. X
  1328. X    return $timing
  1329. X}
  1330. X
  1331. Xif {[string compare $infile_name stdin] == 0} {
  1332. X    set infile stdin
  1333. X} else {
  1334. X    if {![file exists $infile_name]} then {
  1335. X        puts stderr "Bad file name: $infile_name"
  1336. X        exit 1
  1337. X    } else {
  1338. X        set infile [open $infile_name "r"]
  1339. X    }
  1340. X}
  1341. X
  1342. Xif {[string compare $outfile_name stdout] == 0} {
  1343. X    set outfile stdout
  1344. X} else {
  1345. X    # check to see if the specified file exists and open it
  1346. X    if {[catch {open $outfile_name "w"} outfile]} {
  1347. X        puts stderr "Couldn't open $midi_file_name for writing"
  1348. X        puts stderr $outfile
  1349. X    }
  1350. X}
  1351. X
  1352. X# make an empty mfile
  1353. Xset mfile [midimake]
  1354. X
  1355. X# skip over filename since we use the command line
  1356. Xif {[gets $infile line] == -1} {
  1357. X    puts stderr "bad input line: $junk"
  1358. X    exit 1
  1359. X}
  1360. X
  1361. X# get format
  1362. Xif {[gets $infile line] == -1} {
  1363. X    puts stderr "bad input line: $junk"
  1364. X    exit 1
  1365. X}
  1366. Xset format [lindex $line 2]
  1367. Xmidiconfig $mfile format $format
  1368. X
  1369. X# get division
  1370. Xif {[gets $infile line] == -1} {
  1371. X    puts stderr "bad input line: $junk"
  1372. X    exit 1
  1373. X}
  1374. Xset division [lindex $line 2]
  1375. Xmidiconfig $mfile division $division
  1376. X
  1377. X# get num_trks
  1378. Xif {[gets $infile line] == -1} {
  1379. X    puts stderr "bad input line: $junk"
  1380. X    exit 1
  1381. X}
  1382. Xset num_trks [lindex $line 4]
  1383. Xmidiconfig $mfile tracks $num_trks
  1384. X
  1385. X# generate all the tracks
  1386. Xset track 0
  1387. Xwhile {1} {
  1388. X    if {[gets $infile line] == -1} {
  1389. X        if {[expr {$num_trks - 1}] != $track} {
  1390. X            puts stderr "bad input line: $junk"
  1391. X            exit 1
  1392. X        } else {
  1393. X            break
  1394. X        }
  1395. X    }
  1396. X    if {[string compare [lindex $line 0] Track] == 0} {
  1397. X        set timing 0
  1398. X        set track [lindex $line 1]
  1399. X        continue
  1400. X    }
  1401. X    if {[string length $line] == 0} {
  1402. X        continue
  1403. X    }
  1404. X    set timing [PutEvent $line $mfile $track $timing]
  1405. X}
  1406. Xmidiwrite $mfile $outfile
  1407. Xmidifree $mfile
  1408. Xclose $outfile
  1409. Xclose $infile
  1410. Xexit 0
  1411. END_OF_FILE
  1412.   if test 6958 -ne `wc -c <'tclm-1.0/infom'`; then
  1413.     echo shar: \"'tclm-1.0/infom'\" unpacked with wrong size!
  1414.   fi
  1415.   chmod +x 'tclm-1.0/infom'
  1416.   # end of 'tclm-1.0/infom'
  1417. fi
  1418. if test -f 'tclm-1.0/main.c' -a "${1}" != "-c" ; then 
  1419.   echo shar: Will not clobber existing file \"'tclm-1.0/main.c'\"
  1420. else
  1421.   echo shar: Extracting \"'tclm-1.0/main.c'\" \(3578 characters\)
  1422.   sed "s/^X//" >'tclm-1.0/main.c' <<'END_OF_FILE'
  1423. X/*-
  1424. X * Copyright (c) 1993 Michael B. Durian.  All rights reserved.
  1425. X *
  1426. X * Redistribution and use in source and binary forms, with or without
  1427. X * modification, are permitted provided that the following conditions
  1428. X * are met:
  1429. X * 1. Redistributions of source code must retain the above copyright
  1430. X *    notice, this list of conditions and the following disclaimer.
  1431. X * 2. Redistributions in binary form must reproduce the above copyright
  1432. X *    notice, this list of conditions and the following disclaimer in the
  1433. X *    documentation and/or other materials provided with the distribution.
  1434. X * 3. All advertising materials mentioning features or use of this software
  1435. X *    must display the following acknowledgement:
  1436. X *    This product includes software developed by Michael B. Durian.
  1437. X * 4. The name of the the Author may be used to endorse or promote 
  1438. X *    products derived from this software without specific prior written 
  1439. X *    permission.
  1440. X *
  1441. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  1442. X * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1443. X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
  1444. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  1445. X * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1446. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1447. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1448. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1449. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1450. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1451. X * SUCH DAMAGE.
  1452. X */
  1453. X/*
  1454. X * main.c,v 1.4 1993/05/07 17:45:03 durian Exp
  1455. X */
  1456. X
  1457. Xstatic char cvsid[] = "main.c,v 1.4 1993/05/07 17:45:03 durian Exp";
  1458. X
  1459. X#include "tclInt.h"
  1460. X#include "mutil.h"
  1461. X#include "tclm.h"
  1462. X
  1463. X/*
  1464. X * Declarations for library procedures:
  1465. X */
  1466. X
  1467. Xextern int isatty();
  1468. X
  1469. XTcl_Interp *interp;
  1470. XTcl_CmdBuf buffer;
  1471. Xint tty;
  1472. X
  1473. Xvoid usage _ANSI_ARGS_(());
  1474. Xextern char *optarg;
  1475. X
  1476. X    /* ARGSUSED */
  1477. Xint
  1478. Xmain(argc, argv)
  1479. X    int argc;
  1480. X    char **argv;
  1481. X{
  1482. X    static int gotPartial = 0;
  1483. X    int result;
  1484. X    FILE *file;
  1485. X    char *args;
  1486. X    char *cmd;
  1487. X    int have_f;
  1488. X    char buf[20];
  1489. X    char line[200];
  1490. X    char opt;
  1491. X
  1492. X    have_f = 0;
  1493. X    file = stdin;
  1494. X
  1495. X    /*
  1496. X     * we want to stop parsing args when we get a -f, so the
  1497. X     * script can get the args it wants
  1498. X     */
  1499. X    while (!have_f && (opt = getopt(argc, argv, "f:")) != -1) {
  1500. X        switch (opt) {
  1501. X        case 'f':
  1502. X            if ((file = fopen(optarg, "r")) == NULL) {
  1503. X                fprintf(stderr, "Couldn't open %s\n", optarg);
  1504. X                exit(1);
  1505. X            }
  1506. X            have_f = 1;
  1507. X            break;
  1508. X        case '?':
  1509. X            usage();
  1510. X            exit(1);
  1511. X        }
  1512. X    }
  1513. X
  1514. X    interp = Tcl_CreateInterp();
  1515. X    args = Tcl_Merge(argc-1, argv+1);
  1516. X    Tcl_SetVar(interp, "argv", args, TCL_GLOBAL_ONLY);
  1517. X    ckfree(args);
  1518. X    sprintf(buf, "%d", argc - 1);
  1519. X    Tcl_SetVar(interp, "argc", buf, TCL_GLOBAL_ONLY);
  1520. X    Tclm_InitMidi(interp);
  1521. X    buffer = Tcl_CreateCmdBuf();
  1522. X    tty = isatty(0);
  1523. X
  1524. X    for (;;) {
  1525. X        if (file == stdin && tty)
  1526. X            printf("tclm: ");
  1527. X
  1528. X        if (fgets(line, 200, file) == NULL)
  1529. X            break;
  1530. X        cmd = Tcl_AssembleCmd(buffer, line);
  1531. X        if (cmd == NULL) {
  1532. X            gotPartial = 1;
  1533. X            continue;
  1534. X        }
  1535. X        gotPartial = 0;
  1536. X        result = Tcl_RecordAndEval(interp, cmd, 0);
  1537. X        if (*interp->result != 0) {
  1538. X            if (result != TCL_OK) {
  1539. X                printf("%s\n", Tcl_GetVar(interp, "errorInfo",
  1540. X                    0));
  1541. X                if (file !=stdin || !tty)
  1542. X                    break;
  1543. X            } else if (file == stdin && tty) {
  1544. X                printf("%s\n", interp->result);
  1545. X            }
  1546. X        }
  1547. X    }
  1548. X
  1549. X    Tcl_DeleteInterp(interp);
  1550. X    Tcl_DeleteCmdBuf(buffer);
  1551. X    exit(0);
  1552. X}
  1553. X
  1554. Xvoid
  1555. Xusage()
  1556. X{
  1557. X
  1558. X    (void) fprintf(stderr, "Usage: tclm [ -f filename ]\n");
  1559. X}
  1560. END_OF_FILE
  1561.   if test 3578 -ne `wc -c <'tclm-1.0/main.c'`; then
  1562.     echo shar: \"'tclm-1.0/main.c'\" unpacked with wrong size!
  1563.   fi
  1564.   # end of 'tclm-1.0/main.c'
  1565. fi
  1566. if test -f 'tclm-1.0/minfo' -a "${1}" != "-c" ; then 
  1567.   echo shar: Will not clobber existing file \"'tclm-1.0/minfo'\"
  1568. else
  1569.   echo shar: Extracting \"'tclm-1.0/minfo'\" \(5581 characters\)
  1570.   sed "s/^X//" >'tclm-1.0/minfo' <<'END_OF_FILE'
  1571. X#!/usr/local/bin/tclm -f
  1572. X#
  1573. X# Copyright (c) 1993 Michael B. Durian.  All rights reserved.
  1574. X#
  1575. X# Redistribution and use in source and binary forms, with or without
  1576. X# modification, are permitted provided that the following conditions
  1577. X# are met:
  1578. X# 1. Redistributions of source code must retain the above copyright
  1579. X#    notice, this list of conditions and the following disclaimer.
  1580. X# 2. Redistributions in binary form must reproduce the above copyright
  1581. X#    notice, this list of conditions and the following disclaimer in the
  1582. X#    documentation and/or other materials provided with the distribution.
  1583. X# 3. All advertising materials mentioning features or use of this software
  1584. X#    must display the following acknowledgement:
  1585. X#    This product includes software developed by Michael B. Durian.
  1586. X# 4. The name of the the Author may be used to endorse or promote 
  1587. X#    products derived from this software without specific prior written 
  1588. X#    permission.
  1589. X#
  1590. X# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  1591. X# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1592. X# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
  1593. X# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  1594. X# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1595. X# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1596. X# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1597. X# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1598. X# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1599. X# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1600. X# SUCH DAMAGE.
  1601. X#
  1602. X
  1603. X# minfo,v 1.6 1993/04/08 04:16:01 durian Exp
  1604. X
  1605. X# get filename arg
  1606. Xif {[string compare [lindex $argv 0] "-f"] == 0} {
  1607. X    set midi_file_name [lindex $argv 2]
  1608. X} else {
  1609. X    set midi_file_name [lindex $argv 0]
  1610. X}
  1611. X
  1612. Xproc FormatEvent {event} {
  1613. X    global pos
  1614. X
  1615. X    # get the timing part of the event
  1616. X    set timing [lindex $event 0]
  1617. X
  1618. X    # determine offset from start of track
  1619. X    set pos [expr {$timing + $pos}]
  1620. X    set out [format "%6d: " $pos]
  1621. X
  1622. X    case [lindex $event 1] in {
  1623. X    noteoff {
  1624. X        set chan [lindex $event 2]
  1625. X        set pitch [lindex $event 3]
  1626. X        set vel [lindex $event 4]
  1627. X        append out "NOTEOFF channel $chan pitch $pitch velocity $vel"
  1628. X    } noteon {
  1629. X        set chan [lindex $event 2]
  1630. X        set pitch [lindex $event 3]
  1631. X        set vel [lindex $event 4]
  1632. X        append out "NOTEON channel $chan pitch $pitch velocity $vel"
  1633. X    } keypressure {
  1634. X        set chan [lindex $event 2]
  1635. X        set pitch [lindex $event 3]
  1636. X        set pres [lindex $event 4]
  1637. X        append out \
  1638. X            "KEY PRESSURE channel $chan pitch $pitch pressure $pres"
  1639. X    } parameter {
  1640. X        set chan [lindex $event 2]
  1641. X        set param [lindex $event 3]
  1642. X        set set [lindex $event 4]
  1643. X        append out \
  1644. X            "PARAMETER channel $chan parameter $param setting $set"
  1645. X    } program {
  1646. X        set chan [lindex $event 2]
  1647. X        set prog [lindex $event 3]
  1648. X        append out "PROGRAM channel $chan program $prog"
  1649. X    } channelpressure {
  1650. X        set chan [lindex $event 2]
  1651. X        set pres [lindex $event 3]
  1652. X        append out "CHANNEL PRESSURE channel $chan pressure $pres"
  1653. X    } pitchwheel {
  1654. X        set chan [lindex $event 2]
  1655. X        set val [lindex $event 3]
  1656. X        append out "PITCH WHEEL channel $chan value $val"
  1657. X    } metachanprefix {
  1658. X        append out "METACHANPREFIX [lindex $event 2]"
  1659. X    } metacpy {
  1660. X        append out "METACPY [lindex $event 2]"
  1661. X    } metacue {
  1662. X        append out "METACUE [lindex $event 2]"
  1663. X    } metaeot {
  1664. X        append out "METAEOT"
  1665. X    } metainstname {
  1666. X        append out "METAINSTNAME [lindex $event 2]"
  1667. X    } metakey {
  1668. X        append out "METAKEY [lindex $event 2] [lindex $event 3]"
  1669. X    } metalyric {
  1670. X        append out "METALYRIC [lindex $event 2]"
  1671. X    } metamarker {
  1672. X        append out "METAMARKER [lindex $event 2]"
  1673. X    } metaseqname {
  1674. X        append out "METASEQNAME [lindex $event 2]"
  1675. X    } metaseqnum {
  1676. X        append out "METASEQNUM [lindex $event 2]"
  1677. X    } metaseqspec {
  1678. X        append out "METASEQSPEC"
  1679. X    } metasmpte {
  1680. X        set hr [lindex $event 2]
  1681. X        set mi [lindex $event 3]
  1682. X        set se [lindex $event 4]
  1683. X        set fr [lindex $event 5]
  1684. X        set ff [lindex $event 6]
  1685. X        append out \
  1686. X            "METASMPTE Hour $hr, Min. $mi, Sec. $se, Frame $fr, Frac. Frame $ff"
  1687. X    } metatempo {
  1688. X        append out "METATEMPO [lindex $event 2] BPM"
  1689. X    } metatext {
  1690. X        append out "METATEXT [lindex $event 2]"
  1691. X    } metatime {
  1692. X        set num [lindex $event 2]
  1693. X        set den [lindex $event 3]
  1694. X        set cpm [lindex $event 4]
  1695. X        set _32 [lindex $event 5]
  1696. X        append out \
  1697. X            "METATIME $num/$den, $cpm clocks per met. beat, $_32 32nd notes per 1/4 note"
  1698. X    } sysex {
  1699. X        append out "SYSEX [lindex $event 2]"
  1700. X        if {[llength $event] > 3} {
  1701. X            append out " [lindex $event 3]"
  1702. X        }
  1703. X    }
  1704. X    }
  1705. X
  1706. X    return $out
  1707. X}
  1708. X
  1709. Xif {[string length $midi_file_name] == 0} {
  1710. X    # if no filename is specified use stdin
  1711. X    set midi_file stdin
  1712. X    set midi_file_name stdin
  1713. X} else {
  1714. X    # check to see if the specified file exists and open it
  1715. X    if {![file exists $midi_file_name]} then {
  1716. X        puts stderr "Bad file name: $midi_file_name"
  1717. X        exit 1
  1718. X    } else {
  1719. X        set midi_file [open $midi_file_name]
  1720. X    }
  1721. X}
  1722. X
  1723. X# read the midi file
  1724. X# print out error if there is one
  1725. Xif {[catch {midiread $midi_file} mfile]} {
  1726. X    puts stderr $mfile
  1727. X    exit 1
  1728. X}
  1729. Xputs stdout [format "%-16s = %s" "file name" $midi_file_name]
  1730. Xputs stdout [format "%-16s = %s" "format" [midiconfig $mfile format]]
  1731. Xputs stdout [format "%-16s = %s" "division" [midiconfig $mfile division]]
  1732. Xset num_trks [midiconfig $mfile tracks]
  1733. Xputs stdout [format "%-16s = %s" "number of tracks" $num_trks]
  1734. X
  1735. X# print out all the tracks
  1736. Xfor {set track 0} {$track < $num_trks} {incr track} {
  1737. X    puts stdout "\nTrack $track"
  1738. X    set pos 0
  1739. X    while {[string compare [set event [midiget $mfile $track]] EOT] != 0} {
  1740. X        set out [FormatEvent $event]
  1741. X        puts stdout $out
  1742. X    }
  1743. X}
  1744. Xexit 0
  1745. END_OF_FILE
  1746.   if test 5581 -ne `wc -c <'tclm-1.0/minfo'`; then
  1747.     echo shar: \"'tclm-1.0/minfo'\" unpacked with wrong size!
  1748.   fi
  1749.   chmod +x 'tclm-1.0/minfo'
  1750.   # end of 'tclm-1.0/minfo'
  1751. fi
  1752. if test -f 'tclm-1.0/mlib/Makefile' -a "${1}" != "-c" ; then 
  1753.   echo shar: Will not clobber existing file \"'tclm-1.0/mlib/Makefile'\"
  1754. else
  1755.   echo shar: Extracting \"'tclm-1.0/mlib/Makefile'\" \(1433 characters\)
  1756.   sed "s/^X//" >'tclm-1.0/mlib/Makefile' <<'END_OF_FILE'
  1757. X# add -DMIDIPLAY to defines if you wish to compile in the ability to
  1758. X# play standard MIDI files.  This will only work on systems
  1759. X# equipped with a MIDI interface and systems with an interface
  1760. X# between tclm and the MIDI device.  Currently this is
  1761. X# only BSD/386 with a MPU-401 compatible and the new midi
  1762. X# driver.
  1763. XDEFS =
  1764. X# DEFS = -DMIDIPLAY
  1765. X
  1766. X# add driver type.  This only matters if PLAYMIDI is defined
  1767. X# current choices are:
  1768. X# mpu_bsd386.o
  1769. X# DRIVER = mpu_bsd386.o
  1770. XDRIVER = 
  1771. X
  1772. X# set RANLIB to ranlib if your system has it - otherwise set it to
  1773. X# true
  1774. X# RANLIB = true
  1775. XRANLIB = ranlib
  1776. X
  1777. X# set INSTALL to be your install program
  1778. X# INSTALL = cp
  1779. XINSTALL = install
  1780. X
  1781. X# set INSTALLEXECFLAG to be flags needed when installing
  1782. X# executables
  1783. XINSTALLEXECFLAG = -c -m 755
  1784. X
  1785. X# set INSTALLTEXTFLAG to be flags needed when installing
  1786. X# text files
  1787. XINSTALLTEXTFLAG = -c -m 644
  1788. X
  1789. X# set LIBDIR to the place where libmutil.a should go
  1790. XLIBDIR = /usr/local/lib
  1791. X
  1792. X# set INCDIR to the place where the .h files should go
  1793. XINCDIR = /usr/local/include
  1794. X
  1795. XMIDILIBOBJS = mfileutil.o $(DRIVER)
  1796. XMIDILIB = libmutil.a
  1797. X
  1798. XCFLAGS = $(DEFS) -O -I.
  1799. XCC = cc
  1800. X
  1801. Xall: $(MIDILIB)
  1802. X
  1803. X$(MIDILIB): $(MIDILIBOBJS)
  1804. X    rm -f $(MIDILIB)
  1805. X    ar cr $(MIDILIB) $(MIDILIBOBJS)
  1806. X    $(RANLIB) $(MIDILIB)
  1807. X
  1808. Xinstall: $(MIDILIB)
  1809. X    $(INSTALL) $(INSTALLTEXTFLAG) $(MIDILIB) $(LIBDIR)
  1810. X    $(RANLIB) $(LIBDIR)/$(MIDILIB)
  1811. X    $(INSTALL) $(INSTALLTEXTFLAG) mutil.h mdevice.h $(INCDIR)
  1812. X
  1813. Xclean:
  1814. X    rm -f $(MIDILIB) $(MIDILIBOBJS)
  1815. END_OF_FILE
  1816.   if test 1433 -ne `wc -c <'tclm-1.0/mlib/Makefile'`; then
  1817.     echo shar: \"'tclm-1.0/mlib/Makefile'\" unpacked with wrong size!
  1818.   fi
  1819.   # end of 'tclm-1.0/mlib/Makefile'
  1820. fi
  1821. if test -f 'tclm-1.0/mlib/mutil.h' -a "${1}" != "-c" ; then 
  1822.   echo shar: Will not clobber existing file \"'tclm-1.0/mlib/mutil.h'\"
  1823. else
  1824.   echo shar: Extracting \"'tclm-1.0/mlib/mutil.h'\" \(4343 characters\)
  1825.   sed "s/^X//" >'tclm-1.0/mlib/mutil.h' <<'END_OF_FILE'
  1826. X/*-
  1827. X * Copyright (c) 1993 Michael B. Durian.  All rights reserved.
  1828. X *
  1829. X * Redistribution and use in source and binary forms, with or without
  1830. X * modification, are permitted provided that the following conditions
  1831. X * are met:
  1832. X * 1. Redistributions of source code must retain the above copyright
  1833. X *    notice, this list of conditions and the following disclaimer.
  1834. X * 2. Redistributions in binary form must reproduce the above copyright
  1835. X *    notice, this list of conditions and the following disclaimer in the
  1836. X *    documentation and/or other materials provided with the distribution.
  1837. X * 3. All advertising materials mentioning features or use of this software
  1838. X *    must display the following acknowledgement:
  1839. X *    This product includes software developed by Michael B. Durian.
  1840. X * 4. The name of the the Author may be used to endorse or promote 
  1841. X *    products derived from this software without specific prior written 
  1842. X *    permission.
  1843. X *
  1844. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  1845. X * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1846. X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
  1847. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  1848. X * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1849. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1850. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1851. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1852. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1853. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1854. X * SUCH DAMAGE.
  1855. X */
  1856. X/*
  1857. X * mutil.h,v 1.6 1993/05/06 21:44:06 durian Exp
  1858. X */
  1859. X#ifndef MUTIL_H
  1860. X#define MUTIL_H
  1861. X#if defined(i386) || defined(vax)
  1862. X#    define mtohl(l) ((((l) << 24) & 0xff000000L) | (((l) << 8) & \
  1863. X        0x00ff0000L) | (((l) >> 8) & 0x0000ff00L) | (((l) >> 24) & \
  1864. X        0x000000ffL))
  1865. X#    define htoml(l) ((((l) << 24) & 0xff000000L) | (((l) << 8) & \
  1866. X        0x00ff0000L) | (((l) >> 8) & 0x0000ff00L) | (((l) >> 24) & \
  1867. X        0x000000ffL))
  1868. X#    define mtohs(s) ((((s) << 8) & 0xff00) | (((s) >> 8) & 0x00ff))
  1869. X#    define htoms(s) ((((s) << 8) & 0xff00) | (((s) >> 8) & 0x00ff))
  1870. X#else
  1871. X#    define mtohl(l) l
  1872. X#    define mtohs(s) s
  1873. X#    define htoml(l) l
  1874. X#    define htoms(s) s
  1875. X#endif
  1876. X
  1877. Xtypedef enum {NORMAL = 0xff, SYSEX = 0xf0, METASEQNUM = 0x00, METATEXT = 0x01,
  1878. X    METACPY = 0x02, METASEQNAME = 0x03, METAINSTNAME = 0x04, METALYRIC = 0x05,
  1879. X    METAMARKER = 0x06, METACUE = 0x07, METACHANPREFIX = 0x20, METAEOT = 0x2f,
  1880. X    METATEMPO = 0x51, METASMPTE = 0x54, METATIME = 0x58, METAKEY = 0x59,
  1881. X    METASEQSPEC = 0x7f} EVENT_TYPE;
  1882. X
  1883. Xtypedef struct {
  1884. X        char str[4];
  1885. X        long length;
  1886. X        short format;
  1887. X        short num_trks;
  1888. X        short division;
  1889. X} HCHUNK;
  1890. X
  1891. Xtypedef struct {
  1892. X        char str[4];
  1893. X        long pos;
  1894. X        long length;
  1895. X    long msize;
  1896. X        unsigned char *events;
  1897. X        unsigned char *event_start;
  1898. X    unsigned char read_rs;
  1899. X    unsigned char write_rs;
  1900. X} TCHUNK;
  1901. X
  1902. X/* hack to tell us when reading from stdin if there is anymore data */
  1903. Xextern int MidiEof;
  1904. Xextern char MidiError[];
  1905. X
  1906. X/* function prototypes */
  1907. X#ifdef __STDC__
  1908. X#    define _ANSI_ARGS_(x) x
  1909. X#else
  1910. X#    define _ANSI_ARGS_(x) ()
  1911. X#endif
  1912. X
  1913. Xextern unsigned char get_running_state _ANSI_ARGS_((TCHUNK *));
  1914. Xextern int get_smf_event _ANSI_ARGS_((TCHUNK *, unsigned char *, EVENT_TYPE *));
  1915. Xextern int put_smf_event _ANSI_ARGS_((TCHUNK *, unsigned char *, int));
  1916. Xextern int read_header_chunk _ANSI_ARGS_((int, HCHUNK *));
  1917. Xextern int read_track_chunk _ANSI_ARGS_((int, TCHUNK *));
  1918. Xextern int skip_track_chunk _ANSI_ARGS_((int));
  1919. Xextern void rewind_track _ANSI_ARGS_((TCHUNK *));
  1920. Xextern void reset_track _ANSI_ARGS_((TCHUNK *));
  1921. Xextern int write_header_chunk _ANSI_ARGS_((int, HCHUNK *));
  1922. Xextern int write_track_chunk _ANSI_ARGS_((int, TCHUNK *));
  1923. Xextern int merge_tracks _ANSI_ARGS_((TCHUNK *, TCHUNK **, int *, int, int));
  1924. Xextern int split_type_zero _ANSI_ARGS_((TCHUNK *));
  1925. Xextern int fix2var _ANSI_ARGS_((long, unsigned char *));
  1926. Xextern long var2fix _ANSI_ARGS_((unsigned char *, int *));
  1927. Xextern void free_track _ANSI_ARGS_((TCHUNK *));
  1928. Xextern void init_track _ANSI_ARGS_((TCHUNK *));
  1929. Xextern int mread _ANSI_ARGS_((int, char *, int));
  1930. Xextern int mwrite _ANSI_ARGS_((int, char *, int));
  1931. Xextern int more_memory _ANSI_ARGS_((char **, int));
  1932. X#endif
  1933. END_OF_FILE
  1934.   if test 4343 -ne `wc -c <'tclm-1.0/mlib/mutil.h'`; then
  1935.     echo shar: \"'tclm-1.0/mlib/mutil.h'\" unpacked with wrong size!
  1936.   fi
  1937.   # end of 'tclm-1.0/mlib/mutil.h'
  1938. fi
  1939. if test -f 'tclm-1.0/mrecord' -a "${1}" != "-c" ; then 
  1940.   echo shar: Will not clobber existing file \"'tclm-1.0/mrecord'\"
  1941. else
  1942.   echo shar: Extracting \"'tclm-1.0/mrecord'\" \(4102 characters\)
  1943.   sed "s/^X//" >'tclm-1.0/mrecord' <<'END_OF_FILE'
  1944. X#!/usr/local/bin/tclm -f
  1945. X#
  1946. X# Copyright (c) 1993 Michael B. Durian.  All rights reserved.
  1947. X#
  1948. X# Redistribution and use in source and binary forms, with or without
  1949. X# modification, are permitted provided that the following conditions
  1950. X# are met:
  1951. X# 1. Redistributions of source code must retain the above copyright
  1952. X#    notice, this list of conditions and the following disclaimer.
  1953. X# 2. Redistributions in binary form must reproduce the above copyright
  1954. X#    notice, this list of conditions and the following disclaimer in the
  1955. X#    documentation and/or other materials provided with the distribution.
  1956. X# 3. All advertising materials mentioning features or use of this software
  1957. X#    must display the following acknowledgement:
  1958. X#    This product includes software developed by Michael B. Durian.
  1959. X# 4. The name of the the Author may be used to endorse or promote 
  1960. X#    products derived from this software without specific prior written 
  1961. X#    permission.
  1962. X#
  1963. X# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  1964. X# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1965. X# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
  1966. X# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  1967. X# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1968. X# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1969. X# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1970. X# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1971. X# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1972. X# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1973. X# SUCH DAMAGE.
  1974. X
  1975. X# mrecord,v 1.1 1993/05/06 02:51:08 durian Exp
  1976. X
  1977. Xif {! [midiplayable]} {
  1978. X    puts stderr [concat "Cannot record.  Tclm was not compiled with the " \
  1979. X        "record functionality turned on."]
  1980. X    exit 1
  1981. X}
  1982. X
  1983. Xset repeat {}
  1984. Xset tracks {}
  1985. Xset speed {}
  1986. Xset play ""
  1987. Xset reltempo ""
  1988. Xset rec_file_name ""
  1989. Xset play_file_name ""
  1990. X
  1991. Xproc parse_arg {args} {
  1992. X    global repeat
  1993. X    global tracks
  1994. X    global speed
  1995. X    global play_file_name
  1996. X    global rec_file_name
  1997. X
  1998. X    # strip away extra {}'s
  1999. X    set argv [lindex $args 0]
  2000. X    set argc [llength $argv]
  2001. X    if {$argc > 1 && [string compare [lindex $argv 0] "-f"] == 0} {
  2002. X        incr argc -2
  2003. X        set argv [lrange $argv 2 end]
  2004. X    }
  2005. X    for {set i 0} {$i < $argc} {incr i} {
  2006. X
  2007. X        set arg [lindex $argv $i]
  2008. X        case $arg in \
  2009. X        -repeat {
  2010. X            set repeat repeat
  2011. X        } -tracks {
  2012. X            set tracks [lindex $argv [incr i]]
  2013. X        } -speed {
  2014. X            set speed [lindex $argv [incr i]]
  2015. X        } -pfile {
  2016. X            set play_file_name [lindex $argv [incr i]]
  2017. X        } default {
  2018. X            if {[string length $rec_file_name] != 0} {
  2019. X                Usage
  2020. X            } else {
  2021. X                set rec_file_name [lindex $argv $i]
  2022. X            }
  2023. X        }
  2024. X    }
  2025. X}
  2026. X
  2027. Xproc Usage {} {
  2028. X    puts stderr {Usage: mrecord [-pfile play_file [-repeat] \
  2029. X[-tracks track_list] [-speed speed]] record_file}
  2030. X    exit 1
  2031. X}
  2032. X
  2033. Xparse_arg $argv
  2034. X
  2035. Xset background ""
  2036. Xset rmfile [midimake]
  2037. Xmidiconfig $rmfile format 0
  2038. Xmidiconfig $rmfile tracks 1
  2039. X
  2040. Xif {[string length $play_file_name] == 0} {
  2041. X    if {[string length $repeat] != 0} {
  2042. X        Usage
  2043. X    }
  2044. X    if {[string length $tracks] != 0} {
  2045. X        Usage
  2046. X    }
  2047. X    if {[string length $speed] != 0} {
  2048. X        Usage
  2049. X    }
  2050. X    set pfile ""
  2051. X    set pmfile ""
  2052. X    set background background
  2053. X} else {
  2054. X    if {[string length $repeat] != 0} {
  2055. X        set background background
  2056. X    }
  2057. X
  2058. X    if {[llength $tracks] != 0} {
  2059. X        set tracks "tracks \"$tracks\""
  2060. X    } else {
  2061. X        set tracks ""
  2062. X    }
  2063. X
  2064. X    if {[string length $speed] != 0} {
  2065. X        set reltempo "reltempo $speed"
  2066. X    } else {
  2067. X        set reltempo ""
  2068. X    }
  2069. X    set pfile [open $play_file_name "r"]
  2070. X    set pmfile [midiread $pfile]
  2071. X    close $pfile
  2072. X
  2073. X    set play "play $pmfile"
  2074. X
  2075. X    midiconfig $rmfile division [midiconfig $pmfile division]
  2076. X}
  2077. X
  2078. Xif {[string length $background] == 0} {
  2079. X    eval "midirecord $background $play $repeat $tracks $reltempo $rmfile"
  2080. X} else {
  2081. X    set pid [eval \
  2082. X        "midirecord $background $play $repeat $tracks $reltempo $rmfile"]
  2083. X    puts stdout "Press return to stop recording"
  2084. X    gets stdin
  2085. X    midistop $pid $rmfile
  2086. X}
  2087. X
  2088. Xmidiput $rmfile 0 0 metaeot
  2089. X
  2090. Xset rfile [open $rec_file_name "w"]
  2091. Xmidiwrite $rmfile $rfile
  2092. Xclose $rfile
  2093. Xif {[string length $pmfile] != 0} {
  2094. X    midifree $pmfile
  2095. X}
  2096. Xmidifree $rmfile
  2097. Xexit 0
  2098. END_OF_FILE
  2099.   if test 4102 -ne `wc -c <'tclm-1.0/mrecord'`; then
  2100.     echo shar: \"'tclm-1.0/mrecord'\" unpacked with wrong size!
  2101.   fi
  2102.   chmod +x 'tclm-1.0/mrecord'
  2103.   # end of 'tclm-1.0/mrecord'
  2104. fi
  2105. if test -f 'tclm-1.0/tclm.h' -a "${1}" != "-c" ; then 
  2106.   echo shar: Will not clobber existing file \"'tclm-1.0/tclm.h'\"
  2107. else
  2108.   echo shar: Extracting \"'tclm-1.0/tclm.h'\" \(3432 characters\)
  2109.   sed "s/^X//" >'tclm-1.0/tclm.h' <<'END_OF_FILE'
  2110. X/*-
  2111. X * Copyright (c) 1993 Michael B. Durian.  All rights reserved.
  2112. X *
  2113. X * Redistribution and use in source and binary forms, with or without
  2114. X * modification, are permitted provided that the following conditions
  2115. X * are met:
  2116. X * 1. Redistributions of source code must retain the above copyright
  2117. X *    notice, this list of conditions and the following disclaimer.
  2118. X * 2. Redistributions in binary form must reproduce the above copyright
  2119. X *    notice, this list of conditions and the following disclaimer in the
  2120. X *    documentation and/or other materials provided with the distribution.
  2121. X * 3. All advertising materials mentioning features or use of this software
  2122. X *    must display the following acknowledgement:
  2123. X *    This product includes software developed by Michael B. Durian.
  2124. X * 4. The name of the the Author may be used to endorse or promote 
  2125. X *    products derived from this software without specific prior written 
  2126. X *    permission.
  2127. X *
  2128. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  2129. X * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  2130. X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
  2131. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  2132. X * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  2133. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  2134. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  2135. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  2136. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  2137. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  2138. X * SUCH DAMAGE.
  2139. X */
  2140. X/*
  2141. X * tclm.h,v 1.7 1993/05/06 02:51:12 durian Exp
  2142. X */
  2143. X#ifndef TCLM_H
  2144. X#define TCLM_H
  2145. Xtypedef struct {
  2146. X    HCHUNK    hchunk;
  2147. X    TCHUNK    *tchunks;
  2148. X} MIDI_FILE;
  2149. X
  2150. X#define MAX_EVENT_SIZE 256
  2151. X
  2152. Xextern int Tclm_MidiConfig _ANSI_ARGS_((ClientData, Tcl_Interp *, int,
  2153. X    char **));
  2154. Xextern int Tclm_Division _ANSI_ARGS_((Tcl_Interp *, int, char **));
  2155. Xextern int Tclm_MidiFixToVar _ANSI_ARGS_((ClientData, Tcl_Interp *, int,
  2156. X    char **));
  2157. Xextern int Tclm_Format _ANSI_ARGS_((Tcl_Interp *, int, char **));
  2158. Xextern int Tclm_MidiFree _ANSI_ARGS_((ClientData, Tcl_Interp *, int, char **));
  2159. Xextern int Tclm_MidiGet _ANSI_ARGS_((ClientData, Tcl_Interp *, int, char **));
  2160. Xextern int Tclm_MidiPut _ANSI_ARGS_((ClientData, Tcl_Interp *, int, char **));
  2161. Xextern int Tclm_GetMFile _ANSI_ARGS_((Tcl_Interp *, char *, MIDI_FILE **));
  2162. Xextern void Tclm_InitMidi _ANSI_ARGS_((Tcl_Interp *));
  2163. Xextern int Tclm_MidiMake _ANSI_ARGS_((ClientData, Tcl_Interp *, int, char **));
  2164. Xextern int Tclm_MidiMerge _ANSI_ARGS_((ClientData, Tcl_Interp *, int, char **));
  2165. Xextern int Tclm_NumTracks _ANSI_ARGS_((Tcl_Interp *, int, char **));
  2166. Xextern int Tclm_MidiRead _ANSI_ARGS_((ClientData, Tcl_Interp *, int, char **));
  2167. Xextern int Tclm_MidiRewind _ANSI_ARGS_((ClientData, Tcl_Interp *, int,
  2168. X    char **));
  2169. Xextern int Tclm_SetMFile _ANSI_ARGS_((Tcl_Interp *, char *, MIDI_FILE *));
  2170. Xextern int Tclm_MidiTiming _ANSI_ARGS_((ClientData, Tcl_Interp *, int,
  2171. X    char **));
  2172. Xextern int Tclm_MidiVarToFix _ANSI_ARGS_((ClientData, Tcl_Interp *, int,
  2173. X    char **));
  2174. Xextern int Tclm_MidiWrite _ANSI_ARGS_((ClientData, Tcl_Interp *, int,
  2175. X    char **));
  2176. Xextern int Tclm_MidiPlayable _ANSI_ARGS_((ClientData, Tcl_Interp *, int,
  2177. X    char **));
  2178. Xextern int Tclm_TclmVersion _ANSI_ARGS_((ClientData, Tcl_Interp *, int,
  2179. X    char **));
  2180. X#endif
  2181. END_OF_FILE
  2182.   if test 3432 -ne `wc -c <'tclm-1.0/tclm.h'`; then
  2183.     echo shar: \"'tclm-1.0/tclm.h'\" unpacked with wrong size!
  2184.   fi
  2185.   # end of 'tclm-1.0/tclm.h'
  2186. fi
  2187. echo shar: End of archive 3 \(of 5\).
  2188. cp /dev/null ark3isdone
  2189. MISSING=""
  2190. for I in 1 2 3 4 5 ; do
  2191.     if test ! -f ark${I}isdone ; then
  2192.     MISSING="${MISSING} ${I}"
  2193.     fi
  2194. done
  2195. if test "${MISSING}" = "" ; then
  2196.     echo You have unpacked all 5 archives.
  2197.     rm -f ark[1-9]isdone
  2198. else
  2199.     echo You still must unpack the following archives:
  2200.     echo "        " ${MISSING}
  2201. fi
  2202. exit 0
  2203. exit 0 # Just in case...
  2204.