home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #1 / NN_1993_1.iso / spool / comp / lang / tcl / 2357 < prev    next >
Encoding:
Text File  |  1993-01-12  |  27.8 KB  |  962 lines

  1. Newsgroups: comp.lang.tcl
  2. Path: sparky!uunet!paladin.american.edu!howland.reston.ans.net!zaphod.mps.ohio-state.edu!magnus.acs.ohio-state.edu!usenet.ins.cwru.edu!agate!boulder!csn!cherokee!durian
  3. From: durian@advtech.uswest.com (Mike Durian)
  4. Subject: tclm0.1 - tcl with MIDI extensions (5/7)
  5. Message-ID: <1993Jan12.203010.20008@advtech.uswest.com>
  6. Sender: news@advtech.uswest.com (Radio Free Boulder)
  7. Nntp-Posting-Host: mongo.advtech.uswest.com
  8. Organization: U S WEST Advanced Technologies
  9. Date: Tue, 12 Jan 1993 20:30:10 GMT
  10. Lines: 950
  11.  
  12. # This is a shell archive.  Save it in a file, remove anything before
  13. # this line, and then unpack it by entering "sh file".  Note, it may
  14. # create directories; files and directories will be owned by you and
  15. # have default permissions.
  16. #
  17. # This archive contains:
  18. #
  19. #    tclm0.1/doc
  20. #    tclm0.1/doc/README
  21. #    tclm0.1/doc/minfo.1
  22. #    tclm0.1/doc/mplay.1
  23. #    tclm0.1/doc/tclm.1
  24. #    tclm0.1/mlib
  25. #    tclm0.1/mlib/mpu401.c
  26. #    tclm0.1/mlib/mplayutil.h
  27. #    tclm0.1/mlib/mpu401.h
  28. #    tclm0.1/mlib/mutil.h
  29. #
  30. echo c - tclm0.1/doc
  31. mkdir tclm0.1/doc > /dev/null 2>&1
  32. echo x - tclm0.1/doc/README
  33. sed 's/^X//' >tclm0.1/doc/README << 'END-of-tclm0.1/doc/README'
  34. X  These man pages want to use the mdoc macro package.  This is the
  35. Xnew Berkeley man page formatter.  It can be found with groff.
  36. END-of-tclm0.1/doc/README
  37. echo x - tclm0.1/doc/minfo.1
  38. sed 's/^X//' >tclm0.1/doc/minfo.1 << 'END-of-tclm0.1/doc/minfo.1'
  39. XMINFO(1)                     BSD Reference Manual                     MINFO(1)
  40. X
  41. XNNAAMMEE
  42. X     mmiinnffoo - a tcl script to print a Standard MIDI File in human readable form
  43. X
  44. XSSYYNNOOPPSSIISS
  45. X     mmiinnffoo [file]
  46. X
  47. XDDEESSCCRRIIPPTTIIOONN
  48. X     mmiinnffoo is a ttccll script that reads a Standard MIDI File and prints the data
  49. X     in human readable form.  If a file is not specified on the command line
  50. X     mmiinnffoo will read from _s_t_d_i_n.
  51. X
  52. XSSEEEE AALLSSOO
  53. X     tclm(3TCLM)
  54. X
  55. XAAUUTTHHOORRSS
  56. X     Mike Durian - durian@advtech.uswest.com
  57. X
  58. X TCLM                            Jan 10, 1993                                1
  59. X
  60. X
  61. X
  62. X
  63. X
  64. X
  65. X
  66. X
  67. X
  68. X
  69. X
  70. X
  71. X
  72. X
  73. X
  74. X
  75. X
  76. X
  77. X
  78. X
  79. X
  80. X
  81. X
  82. X
  83. X
  84. X
  85. X
  86. X
  87. X
  88. X
  89. X
  90. X
  91. X
  92. X
  93. X
  94. X
  95. X
  96. X
  97. X
  98. X
  99. X
  100. X
  101. X
  102. X
  103. X
  104. X
  105. END-of-tclm0.1/doc/minfo.1
  106. echo x - tclm0.1/doc/mplay.1
  107. sed 's/^X//' >tclm0.1/doc/mplay.1 << 'END-of-tclm0.1/doc/mplay.1'
  108. XMPLAY(1)                     BSD Reference Manual                     MPLAY(1)
  109. X
  110. XNNAAMMEE
  111. X     mmppllaayy - a tcl script to play Standard MIDI Files
  112. X
  113. XSSYYNNOOPPSSIISS
  114. X     mmppllaayy [--rr] [--tt _t_r_a_c_k_s] [--ss _s_p_e_e_d] [file ...]
  115. X
  116. XDDEESSCCRRIIPPTTIIOONN
  117. X     mmppllaayy is a ttccll script that plays Standard MIDI Files.  Multiple files may
  118. X     be specified on the command line, or files can be read from _s_t_d_i_n. The
  119. X     options are as follows:
  120. X
  121. X           --rr       Play the first file repeatedly.  The playing will continue
  122. X                    until the process is killed.
  123. X
  124. X           --tt       Specifies a list of tracks to be played instead of the de-
  125. X                    fault all.  This option has an argument that lists the
  126. X                    tracks.  The argument needs to be treated as one argument
  127. X                    instead of multiple values, and thus should be enclosed in
  128. X                    double or single quotes.
  129. X
  130. X           --ss       Specifies a tempo modifier.  The argument to this option
  131. X                    is a float value in the range 0 to 4 that acts as a multi-
  132. X                    pler for the tempo values found in the Standard MIDI
  133. X                    Files.
  134. X
  135. X     Since mmppllaayy makes use of the mmiiddiippllaayy ttccllmm command, this program will on-
  136. X     ly work on BSD/386 systems equiped with a MPU-401 compatible MIDI card.
  137. X     An error message is printed to stderr if the script is run by a ttccllmm in-
  138. X     terpreter without the MPU-401 extensions.
  139. X
  140. XSSEEEE AALLSSOO
  141. X     tclm(3TCLM)
  142. X
  143. XAAUUTTHHOORRSS
  144. X     Mike Durian - durian@advtech.uswest.com
  145. X
  146. X TCLM                            Jan 10, 1993                                1
  147. X
  148. X
  149. X
  150. X
  151. X
  152. X
  153. X
  154. X
  155. X
  156. X
  157. X
  158. X
  159. X
  160. X
  161. X
  162. X
  163. X
  164. X
  165. X
  166. X
  167. X
  168. X
  169. X
  170. X
  171. X
  172. X
  173. X
  174. END-of-tclm0.1/doc/mplay.1
  175. echo x - tclm0.1/doc/tclm.1
  176. sed 's/^X//' >tclm0.1/doc/tclm.1 << 'END-of-tclm0.1/doc/tclm.1'
  177. XTCLM(1)                      BSD Reference Manual                      TCLM(1)
  178. X
  179. XNNAAMMEE
  180. X     ttccllmm - a tcl interpreter with MIDI extensions
  181. X
  182. XSSYYNNOOPPSSIISS
  183. X     ttccllmm [--ff [_f_i_l_e_n_a_m_e]]
  184. X
  185. XDDEESSCCRRIIPPTTIIOONN
  186. X     ttccllmm is a ttccll interpreter with MIDI extensions allowing it to manipulate
  187. X     Standard MIDI Files and in some cases play Standard MIDI Files.  TTccll is a
  188. X     Tool Command Language written by John Ousterhout.
  189. X
  190. X     ttccllmm has only one option:
  191. X
  192. X           --ff          This option has one optional argument that specifies
  193. X                       the name of a file containing tclm commands.  These
  194. X                       commands are executed in place of reading from stdin.
  195. X                       Without the optional argument commands are read from
  196. X                       _s_t_d_i_n.
  197. X     Without the --ff option ttccllmm displays a ``tclm:'' prompt and reads commands
  198. X     from _s_t_d_i_n.
  199. X
  200. X   TTCCLLMM EEXXTTEENNSSIIOONN
  201. X     ttccllmm has a few extensions which aid in the manipulation of Standard MIDI
  202. X     Files (SMF).  They are:
  203. X
  204. X           mmiiddiiccoonnffiigg    Changes configuration values in a SMF.
  205. X
  206. X           mmiiddiiffiixxttoovvaarr  Converts fixed length integers to SMF variable length
  207. X                         values.
  208. X
  209. X           mmiiddiiffrreeee      Frees the space used by SMF's.
  210. X
  211. X           mmiiddiiggeett       Gets one event from a track in a SMF.
  212. X
  213. X           mmiiddiimmaakkee      Creates an empty SMF.
  214. X
  215. X           mmiiddiimmppuu       Checks to see if the MPU-401 extensions are avail-
  216. X                         able.
  217. X
  218. X           mmiiddiippuutt       Puts an event in a track in a SMF.
  219. X
  220. X           mmiiddiirreeaadd      Reads a SMF from an open file descriptor.
  221. X
  222. X           mmiiddiirreewwiinndd    Resets a SMF to its beginning.
  223. X
  224. X           mmiiddiittiimmiinngg    Gets the timing portion of a SMF event.
  225. X
  226. X           mmiiddiivvaarrttooffiixx  Converts a SMF variable length value to a fixed
  227. X                         length integer.
  228. X
  229. X           mmiiddiiwwrriittee     Writes a SMF to an open file descriptor.
  230. X
  231. X     There are also two commands available for playing SMF.  Since they use
  232. X     BSDI's MPU-401 device driver, they are only available for BSD/386 ma-
  233. X     chines with an MPU-401 card.  The mmiiddiimmppuu command can be used to selec-
  234. X     tively enable or disable MPU-401 specific commands in scripts meant to
  235. X     run on BSD/386 as well as other machines.  These commands are:
  236. X
  237. X           mmiiddiippllaayy  Play a SMF.
  238. X
  239. X           mmiiddiissttoopp  Stop a SMF that is currently playing in the background.
  240. X
  241. XSSEEEE AALLSSOO
  242. X     midiconfig(3TCLM),  midifixtovar(3TCLM),  midifree(3TCLM),
  243. X     midiget(3TCLM),  midimake(3TCLM),  midimpu(3TCLM),  midiplay(3TCLM),
  244. X     midiput(3TCLM),  midiread(3TCLM),  midirewind(3TCLM),  midistop(3TCLM),
  245. X     miditiming(3TCLM),  midivartofix(3TCLM),  midiwrite(3TCLM)
  246. X
  247. XAAUUTTHHOORRSS
  248. X     John Ousterhout - ouster@cs.berkely.edu for the TCL stuff
  249. X     Mike Durian - durian@advtech.uswest.com for the MIDI stuff
  250. X
  251. X TCLM                            Jan 10, 1993                                2
  252. X
  253. X
  254. X
  255. X
  256. X
  257. X
  258. X
  259. X
  260. X
  261. X
  262. X
  263. X
  264. X
  265. X
  266. X
  267. X
  268. X
  269. X
  270. X
  271. X
  272. X
  273. X
  274. X
  275. X
  276. X
  277. X
  278. X
  279. X
  280. X
  281. X
  282. X
  283. X
  284. X
  285. X
  286. X
  287. X
  288. X
  289. X
  290. X
  291. X
  292. X
  293. X
  294. X
  295. X
  296. X
  297. X
  298. X
  299. X
  300. X
  301. X
  302. X
  303. X
  304. X
  305. X
  306. X
  307. X
  308. X
  309. END-of-tclm0.1/doc/tclm.1
  310. echo c - tclm0.1/mlib
  311. mkdir tclm0.1/mlib > /dev/null 2>&1
  312. echo x - tclm0.1/mlib/mpu401.c
  313. sed 's/^X//' >tclm0.1/mlib/mpu401.c << 'END-of-tclm0.1/mlib/mpu401.c'
  314. X/* mpu401.c,v 1.3 1993/01/12 19:23:47 durian Exp */
  315. X/*
  316. X * Copyright (c) 1993 Michael B. Durian.  All rights reserved.
  317. X *
  318. X * Redistribution and use in source and binary forms, with or without
  319. X * modification, are permitted provided that the following conditions
  320. X * are met:
  321. X * 1. Redistributions of source code must retain the above copyright
  322. X *    notice, this list of conditions and the following disclaimer.
  323. X * 2. Redistributions in binary form must reproduce the above copyright
  324. X *    notice, this list of conditions and the following disclaimer in the
  325. X *    documentation and/or other materials provided with the distribution.
  326. X * 3. All advertising materials mentioning features or use of this software
  327. X *    must display the following acknowledgement:
  328. X *    This product includes software developed by Michael B. Durian.
  329. X * 4. The name of the the Author may be used to endorse or promote 
  330. X *    products derived from this software without specific prior written 
  331. X *    permission.
  332. X *
  333. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  334. X * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  335. X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
  336. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  337. X * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  338. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  339. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  340. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  341. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  342. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  343. X * SUCH DAMAGE.
  344. X */
  345. X#ifdef MPU
  346. X#include <stdio.h>
  347. X#include <stdlib.h>
  348. X#include <unistd.h>
  349. X#include <string.h>
  350. X#include <sys/fcntl.h>
  351. X#include <sys/ioctl.h>
  352. X#include <i386/isa/midiioctl.h>
  353. X#include "mpu401.h"
  354. X
  355. X#define        MAX_TIME    0xef
  356. X
  357. Xint
  358. Xget_board_event(events_data, events_size, event_data, event_size)
  359. X    unsigned char *events_data;
  360. X    int events_size;
  361. X    unsigned char *event_data;
  362. X    int *event_size;
  363. X{
  364. X    MESS_STATE state;
  365. X    int delta;
  366. X    int parsed;
  367. X    static unsigned char r_state;
  368. X
  369. X    *event_size = 0;
  370. X    parsed = 0;
  371. X    delta = 0;
  372. X    state = START;
  373. X    while (!parsed) {
  374. X        if (delta >= events_size)
  375. X            return (-1);
  376. X        switch (state) {
  377. X        case START:
  378. X            if (*events_data < 0xf0) {
  379. X                state = TIMEDEVENT;
  380. X                *event_data++ = *events_data++;
  381. X                (*event_size)++;
  382. X                delta++;
  383. X                break;
  384. X            }
  385. X            switch (*events_data) {
  386. X            case 0xf8:        /* timer overflow */
  387. X                *event_data++ = *events_data++;
  388. X                (*event_size)++;
  389. X                delta++;
  390. X                parsed = 1;
  391. X                break;
  392. X            case 0xfc:        /* all play tracks ended */
  393. X            case 0xfd:        /* clock to PC message */
  394. X                *event_data++ = *events_data++;
  395. X                (*event_size)++;
  396. X                delta++;
  397. X                parsed = 1;
  398. X                break;
  399. X            case 0xf9:
  400. X                /* conductor track request - should never see */
  401. X                *event_data++ = *events_data++;
  402. X                (*event_size)++;
  403. X                delta++;
  404. X                parsed = 1;
  405. X                break;
  406. X            case 0xff:
  407. X                /* system message */
  408. X                *event_data++ = *events_data++;
  409. X                (*event_size)++;
  410. X                delta++;
  411. X                state = SYSMSG;
  412. X                break;
  413. X            case 0xfe:
  414. X                /* command acknowledge - should never see */
  415. X                *event_data++ = *events_data++;
  416. X                (*event_size)++;
  417. X                delta++;
  418. X                parsed = 1;
  419. X                break;
  420. X            case 0xf0:
  421. X            case 0xf1:
  422. X            case 0xf2:
  423. X            case 0xf3:
  424. X            case 0xf4:
  425. X            case 0xf5:
  426. X            case 0xf6:
  427. X            case 0xf7:
  428. X                /* track requests - should never see */
  429. X                *event_data++ = *events_data++;
  430. X                (*event_size)++;
  431. X                delta++;
  432. X                parsed = 1;
  433. X                break;
  434. X            }
  435. X            break;
  436. X        case TIMEDEVENT:
  437. X            if (*events_data < 0xf0) {
  438. X                /* midi channel/voice message */
  439. X                if (*events_data & 0x80) {
  440. X                    /* new running status */
  441. X                    r_state = (*events_data >> 4) & 0x0f;
  442. X                    state = NEWSTATUS;
  443. X                    *event_data++ = *events_data++;
  444. X                    (*event_size)++;
  445. X                    delta++;
  446. X                    break;
  447. X                } else {
  448. X                    /* midi data byte */
  449. X                    /*
  450. X                     * if timed messaged are off then
  451. X                     * this 1st data byte is actually the
  452. X                     * the second
  453. X                     * Only when midi not playing, data
  454. X                     * transfer is stopped state is active
  455. X                     * and timing byte on switch is off
  456. X                     */
  457. X                    /*
  458. X                     * Since we can't know these things
  459. X                     * here, we'll assume how this routine
  460. X                     * will be used (oh Ghads!), and
  461. X                     * pretrend that the the timing byte
  462. X                     * is on when we the event was
  463. X                     * generated.  Why would they want
  464. X                     * to put events in a Standard Midi
  465. X                     * file if this wasn't the case
  466. X                     */
  467. X                    *event_data++ = *events_data++;
  468. X                    (*event_size)++;
  469. X                    delta++;
  470. X                    state = MIDIDATA;
  471. X                    break;
  472. X                }
  473. X            } else {
  474. X                /* mcc timed event */
  475. X                if (*events_data == 0xf9) {
  476. X                    /* measure end message */
  477. X                    *event_data++ = *events_data++;
  478. X                    (*event_size)++;
  479. X                    delta++;
  480. X                    parsed = 1;
  481. X                    break;
  482. X                } else if (*events_data == 0xfc) {
  483. X                    *event_data++ = *events_data++;
  484. X                    (*event_size)++;
  485. X                    delta++;
  486. X                    parsed = 1;
  487. X                    break;
  488. X                } else {
  489. X                    *event_data++ = *events_data++;
  490. X                    (*event_size)++;
  491. X                    delta++;
  492. X                    parsed = 1;
  493. X                    break;
  494. X                }
  495. X            }
  496. X        case NEWSTATUS:
  497. X            /* first nonstatus byte of a midi message */
  498. X            /*
  499. X             * if timed messaged are off then this 1st data byte is
  500. X             * actually the the second.
  501. X             * Only when midi not playing, data transfer is stopped
  502. X             * state is active and timing byte on switch is off.
  503. X             * We're not doing this.  See explaination (cop-out)
  504. X             * above
  505. X             */
  506. X            *event_data++ = *events_data++;
  507. X            (*event_size)++;
  508. X            delta++;
  509. X            switch (r_state) {
  510. X            case 0x08:
  511. X            case 0x09:
  512. X            case 0x0a:
  513. X            case 0x0b:
  514. X            case 0x0e:
  515. X                state = MIDIDATA;
  516. X                break;
  517. X            default:
  518. X                parsed = 1;
  519. X                break;
  520. X            }
  521. X            break;
  522. X        case MIDIDATA:
  523. X            /* second data byte of a midi message */
  524. X            *event_data++ = *events_data++;
  525. X            (*event_size)++;
  526. X            delta++;
  527. X            parsed = 1;
  528. X            break;
  529. X        case SYSMSG:
  530. X            /* first byte of a system message. */
  531. X            if (*events_data == 0xf0)
  532. X                /* system exclusive */
  533. X                state = SYSX;
  534. X            else {
  535. X                /* real time message */
  536. X                parsed = 1;
  537. X            }
  538. X            *event_data++ = *events_data++;
  539. X            (*event_size)++;
  540. X            delta++;
  541. X            break;
  542. X        case SYSX:
  543. X            /* system exclusive message */
  544. X            /*
  545. X             * Supposedly the 0xf7 is optional as a terminator.
  546. X             * Since all bytes in the SYSX message are data bytes,
  547. X             * we should be able to tell when it is over by looking
  548. X             * for any byte with high bit set.  Of course this is
  549. X             * the first byte of the next message.
  550. X             */
  551. X            if (*events_data & 0x80) {
  552. X                switch (*events_data) {
  553. X                case 0xf7:
  554. X                    *event_data++ = *events_data++;
  555. X                    (*event_size)++;
  556. X                    delta++;
  557. X                    parsed = 1;
  558. X                    break;
  559. X                case 0xf8:
  560. X                case 0xfc:
  561. X                case 0xfd:
  562. X                case 0xf9:
  563. X                case 0xff:
  564. X                case 0xfe:
  565. X                case 0xf0:
  566. X                case 0xf1:
  567. X                case 0xf2:
  568. X                case 0xf3:
  569. X                case 0xf4:
  570. X                case 0xf5:
  571. X                case 0xf6:
  572. X                    /*
  573. X                     * abnormal terminators
  574. X                     * We'll save these for next go
  575. X                     * around and add a terminator
  576. X                     */
  577. X                    *event_data++ = 0xf7;
  578. X                    (*event_size)++;
  579. X                    parsed = 1;
  580. X                    break;
  581. X                default:
  582. X                    /*
  583. X                     * we already grabbed the timing
  584. X                     * byte.  This the the event byte.
  585. X                     * since we went on too far we'll
  586. X                     * have to decrement the delta.
  587. X                     * also cover up that extra byte
  588. X                     * with a terminator.
  589. X                     */
  590. X                    *--event_data = 0x7f;
  591. X                    delta--;
  592. X                    parsed = 1;
  593. X                    break;
  594. X                }
  595. X            } else {
  596. X                *event_data++ = *events_data++;
  597. X                (*event_size)++;
  598. X                delta++;
  599. X            }
  600. X            break;
  601. X        }
  602. X    }
  603. X    return (delta);
  604. X}
  605. X
  606. Xvoid
  607. Xboard2smf(board_event, board_length, smf_event, smf_length)
  608. X    unsigned char *board_event;
  609. X    int board_length;
  610. X    unsigned char *smf_event;
  611. X    int *smf_length;
  612. X{
  613. X    static long elapsed = 0;
  614. X    int delta;
  615. X    int i;
  616. X
  617. X
  618. X    *smf_length = 0;
  619. X
  620. X    if (*board_event == 0xf8)
  621. X        elapsed += 240;
  622. X    else {
  623. X        delta = fix2var((long)(*board_event + elapsed), smf_event);
  624. X        elapsed = 0;
  625. X        *smf_length += delta;
  626. X        smf_event += delta;
  627. X        board_event++;
  628. X        for (i = 1; i < board_length; i++) {
  629. X            *smf_event++ = *board_event++;
  630. X            (*smf_length)++;
  631. X        }
  632. X    }
  633. X
  634. X    return;
  635. X}
  636. X
  637. X
  638. Xint
  639. Xsmf2board(track_num, smf_event, smf_size, board_event, t_scalar,
  640. X    need_new_event, event_type)
  641. X    int track_num;
  642. X    unsigned char *smf_event;
  643. X    int smf_size;
  644. X    unsigned char *board_event;
  645. X    int t_scalar;
  646. X    int *need_new_event;
  647. X    EVENT_TYPE *event_type;
  648. X{
  649. X    static long time_left[MAX_TRAX] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  650. X        0, 0, 0, 0, 0};
  651. X    static int fraction[MAX_TRAX] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  652. X        0, 0, 0, 0};
  653. X    static EVENT_TYPE e_type[MAX_TRAX];
  654. X    static int s_size[MAX_TRAX];
  655. X    static int s_pos[MAX_TRAX];
  656. X    static unsigned char s_data[MAX_TRAX][256];
  657. X    static unsigned char *s_event[MAX_TRAX];
  658. X    int delta;
  659. X    int size;
  660. X
  661. X    *need_new_event = 0;
  662. X    size = 0;
  663. X    if (smf_event != NULL) {
  664. X        memcpy(s_data[track_num], smf_event, smf_size);
  665. X        s_event[track_num] = s_data[track_num];
  666. X        s_pos[track_num] = 0;
  667. X        s_size[track_num] = smf_size;
  668. X        e_type[track_num] = *event_type;
  669. X
  670. X        time_left[track_num] = var2fix(s_event[track_num], &delta);
  671. X        fraction[track_num] +=  time_left[track_num] % t_scalar;
  672. X        time_left[track_num] /= t_scalar;
  673. X        if (fraction[track_num] >= t_scalar) {
  674. X            time_left[track_num] += fraction[track_num] / t_scalar;
  675. X            fraction[track_num] %= t_scalar;
  676. X        }
  677. X        s_pos[track_num] += delta;
  678. X        s_event[track_num] += delta;
  679. X    }
  680. X    if (time_left[track_num] >= MAX_TIME) {
  681. X        *board_event++ = 0xf8;
  682. X        size += 1;
  683. X        time_left[track_num] -= MAX_TIME + 1;
  684. X        *event_type = NORMAL;
  685. X        return (size);
  686. X    } else {
  687. X        *board_event++ = (unsigned char) time_left[track_num];
  688. X        size++;
  689. X        time_left[track_num] = 0;
  690. X        *event_type = e_type[track_num];
  691. X    }
  692. X        
  693. X    while (s_pos[track_num]++ < s_size[track_num]) {
  694. X        *board_event++ = *s_event[track_num]++;
  695. X        size++;
  696. X    }
  697. X
  698. X    *need_new_event = 1;
  699. X
  700. X    return (size);
  701. X}
  702. X
  703. Xunsigned char
  704. Xdouble2tempo(d)
  705. X    double d;
  706. X{
  707. X    double bit_vals[] = {2.0, 1.0, 0.5, 0.25, 0.125, 0.0625,
  708. X        0.03125, 0.015625};
  709. X    int i;
  710. X    unsigned char tempo_scalar;
  711. X
  712. X    for (i = 0; i < 8; i++) {
  713. X        if (d < bit_vals[i])
  714. X            tempo_scalar = (tempo_scalar << 1) & ~1;
  715. X        else {
  716. X            tempo_scalar = (tempo_scalar << 1) | 1;
  717. X            d -= bit_vals[i];
  718. X        }
  719. X    }
  720. X    return(tempo_scalar);
  721. X}
  722. X
  723. Xint
  724. Xadjust_division(division, div_ioctl, tempo_scalar)
  725. X    int division;
  726. X    long *div_ioctl;
  727. X    int *tempo_scalar;
  728. X{
  729. X    long ioctls[] = {MRES192, MRES168, MRES144, MRES120, MRES96,
  730. X        MRES72, MRES48};
  731. X    int divs[] = {192, 168, 144, 120, 96, 72, 48};
  732. X    int i;
  733. X    int ret_val;
  734. X
  735. X    ret_val = 0;
  736. X    for (i = 0; i < sizeof(divs) / sizeof(divs[0]); i++) {
  737. X        if (division % divs[i] == 0) {
  738. X            *div_ioctl = ioctls[i];
  739. X            *tempo_scalar = division / divs[i];
  740. X            ret_val = 1;
  741. X            break;
  742. X        }
  743. X    }
  744. X    return (ret_val);
  745. X}
  746. X#endif
  747. END-of-tclm0.1/mlib/mpu401.c
  748. echo x - tclm0.1/mlib/mplayutil.h
  749. sed 's/^X//' >tclm0.1/mlib/mplayutil.h << 'END-of-tclm0.1/mlib/mplayutil.h'
  750. X/* mplayutil.h,v 1.3 1993/01/12 19:23:44 durian Exp */
  751. X/*
  752. X * Copyright (c) 1993 Michael B. Durian.  All rights reserved.
  753. X *
  754. X * Redistribution and use in source and binary forms, with or without
  755. X * modification, are permitted provided that the following conditions
  756. X * are met:
  757. X * 1. Redistributions of source code must retain the above copyright
  758. X *    notice, this list of conditions and the following disclaimer.
  759. X * 2. Redistributions in binary form must reproduce the above copyright
  760. X *    notice, this list of conditions and the following disclaimer in the
  761. X *    documentation and/or other materials provided with the distribution.
  762. X * 3. All advertising materials mentioning features or use of this software
  763. X *    must display the following acknowledgement:
  764. X *    This product includes software developed by Michael B. Durian.
  765. X * 4. The name of the the Author may be used to endorse or promote 
  766. X *    products derived from this software without specific prior written 
  767. X *    permission.
  768. X *
  769. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  770. X * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  771. X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
  772. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  773. X * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  774. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  775. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  776. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  777. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  778. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  779. X * SUCH DAMAGE.
  780. X */
  781. X#ifndef MPLAYUTIL_H
  782. X#define MPLAYUTIL_H
  783. X
  784. Xextern int play_tracks(TCHUNK *, int *, int, int, int);
  785. Xextern int record_tracks(TCHUNK *, int *, int, TCHUNK *, int, int, int);
  786. Xextern int process_play_event(int, TCHUNK *, int, int *, int *, int);
  787. Xextern int process_record_event(int, TCHUNK *);
  788. Xextern void flush_event(TCHUNK *);
  789. Xextern void stop_recording(void);
  790. Xextern SEND_VAL send_event(int, unsigned char *, int, EVENT_TYPE, int);
  791. Xextern int open_midi_devices(HCHUNK *, TRKS *, int *, int *, unsigned char *);
  792. Xextern void set_midi_verbose(int);
  793. X#endif
  794. END-of-tclm0.1/mlib/mplayutil.h
  795. echo x - tclm0.1/mlib/mpu401.h
  796. sed 's/^X//' >tclm0.1/mlib/mpu401.h << 'END-of-tclm0.1/mlib/mpu401.h'
  797. X/* mpu401.h,v 1.3 1993/01/12 19:23:49 durian Exp */
  798. X/*
  799. X * Copyright (c) 1993 Michael B. Durian.  All rights reserved.
  800. X *
  801. X * Redistribution and use in source and binary forms, with or without
  802. X * modification, are permitted provided that the following conditions
  803. X * are met:
  804. X * 1. Redistributions of source code must retain the above copyright
  805. X *    notice, this list of conditions and the following disclaimer.
  806. X * 2. Redistributions in binary form must reproduce the above copyright
  807. X *    notice, this list of conditions and the following disclaimer in the
  808. X *    documentation and/or other materials provided with the distribution.
  809. X * 3. All advertising materials mentioning features or use of this software
  810. X *    must display the following acknowledgement:
  811. X *    This product includes software developed by Michael B. Durian.
  812. X * 4. The name of the the Author may be used to endorse or promote 
  813. X *    products derived from this software without specific prior written 
  814. X *    permission.
  815. X *
  816. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  817. X * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  818. X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
  819. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  820. X * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  821. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  822. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  823. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  824. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  825. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  826. X * SUCH DAMAGE.
  827. X */
  828. X#ifndef MPU401_H
  829. X#define MPU401_H
  830. X
  831. X#include "mutil.h"
  832. X
  833. Xtypedef enum {START, TIMEDEVENT, NEWSTATUS, MIDIDATA, SYSMSG, SYSX} MESS_STATE;
  834. X
  835. Xtypedef enum {SEND_ERROR, SEND_VALID, SEND_INVALID, SEND_DONE} SEND_VAL;
  836. X
  837. X#ifndef NUM_TRKS
  838. X#define NUM_TRKS 8
  839. X#endif
  840. X
  841. X#define MAX_TRAX 18
  842. X
  843. Xextern int get_board_event(unsigned char *, int, unsigned char *, int *);
  844. Xextern void board2smf(unsigned char *, int, unsigned char *, int *);
  845. Xextern int smf2board(int, unsigned char *, int, unsigned char *, int, int *,
  846. X    EVENT_TYPE *);
  847. Xextern unsigned char double2tempo(double);
  848. Xextern int adjust_division(int, long *, int *);
  849. X#endif
  850. END-of-tclm0.1/mlib/mpu401.h
  851. echo x - tclm0.1/mlib/mutil.h
  852. sed 's/^X//' >tclm0.1/mlib/mutil.h << 'END-of-tclm0.1/mlib/mutil.h'
  853. X/* mutil.h,v 1.3 1993/01/12 19:23:51 durian Exp */
  854. X/*
  855. X * Copyright (c) 1993 Michael B. Durian.  All rights reserved.
  856. X *
  857. X * Redistribution and use in source and binary forms, with or without
  858. X * modification, are permitted provided that the following conditions
  859. X * are met:
  860. X * 1. Redistributions of source code must retain the above copyright
  861. X *    notice, this list of conditions and the following disclaimer.
  862. X * 2. Redistributions in binary form must reproduce the above copyright
  863. X *    notice, this list of conditions and the following disclaimer in the
  864. X *    documentation and/or other materials provided with the distribution.
  865. X * 3. All advertising materials mentioning features or use of this software
  866. X *    must display the following acknowledgement:
  867. X *    This product includes software developed by Michael B. Durian.
  868. X * 4. The name of the the Author may be used to endorse or promote 
  869. X *    products derived from this software without specific prior written 
  870. X *    permission.
  871. X *
  872. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 
  873. X * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  874. X * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
  875. X * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
  876. X * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  877. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  878. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  879. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  880. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  881. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  882. X * SUCH DAMAGE.
  883. X */
  884. X#ifndef MUTIL_H
  885. X#define MUTIL_H
  886. X#if defined(i386) || defined(vax)
  887. X#    define mtohl(l) ((((l) << 24) & 0xff000000L) | (((l) << 8) & \
  888. X        0x00ff0000L) | (((l) >> 8) & 0x0000ff00L) | (((l) >> 24) & \
  889. X        0x000000ffL))
  890. X#    define htoml(l) ((((l) << 24) & 0xff000000L) | (((l) << 8) & \
  891. X        0x00ff0000L) | (((l) >> 8) & 0x0000ff00L) | (((l) >> 24) & \
  892. X        0x000000ffL))
  893. X#    define mtohs(s) ((((s) << 8) & 0xff00) | (((s) >> 8) & 0x00ff))
  894. X#    define htoms(s) ((((s) << 8) & 0xff00) | (((s) >> 8) & 0x00ff))
  895. X#else
  896. X#    define mtohl(l) l
  897. X#    define mtohs(s) s
  898. X#    define htoml(l) l
  899. X#    define htoms(s) s
  900. X#endif
  901. X
  902. Xtypedef enum {NORMAL = 0xff, SYSEX = 0xf0, METASEQNUM = 0x00, METATEXT = 0x01,
  903. X    METACPY = 0x02, METASEQNAME = 0x03, METAINSTNAME = 0x04, METALYRIC = 0x05,
  904. X    METAMARKER = 0x06, METACUE = 0x07, METACHANPREFIX = 0x20, METAEOT = 0x2f,
  905. X    METATEMPO = 0x51, METASMPTE = 0x54, METATIME = 0x58, METAKEY = 0x59,
  906. X    METASEQSPEC = 0x7f} EVENT_TYPE;
  907. X
  908. Xtypedef struct {
  909. X        char str[4];
  910. X        long length;
  911. X        short format;
  912. X        short num_trks;
  913. X        short division;
  914. X} HCHUNK;
  915. X
  916. Xtypedef struct {
  917. X        char str[4];
  918. X        long pos;
  919. X        long length;
  920. X    long msize;
  921. X        unsigned char *events;
  922. X        unsigned char *event_start;
  923. X} TCHUNK;
  924. X
  925. Xtypedef struct {
  926. X    int num_tracks;
  927. X    int tracks[50];
  928. X} TRKS;
  929. X
  930. X/* hack to tell us when reading from stdin if there is anymore data */
  931. Xextern int MidiEof;
  932. Xextern char MidiError[];
  933. X
  934. X/* function prototypes */
  935. X#ifdef __STDC__
  936. X#    define _ANSI_ARGS_(x) x
  937. X#else
  938. X#    define _ANSI_ARGS_(x) ()
  939. X#endif
  940. X
  941. Xextern int get_smf_event _ANSI_ARGS_((TCHUNK *, unsigned char *, EVENT_TYPE *));
  942. Xextern int put_smf_event _ANSI_ARGS_((TCHUNK *, unsigned char *, int));
  943. Xextern int read_header_chunk _ANSI_ARGS_((int, HCHUNK *));
  944. Xextern int read_track_chunk _ANSI_ARGS_((int, TCHUNK *));
  945. Xextern int skip_track_chunk _ANSI_ARGS_((int));
  946. Xextern void rewind_track _ANSI_ARGS_((TCHUNK *));
  947. Xextern void reset_track _ANSI_ARGS_((TCHUNK *));
  948. Xextern int write_header_chunk _ANSI_ARGS_((int, HCHUNK *));
  949. Xextern int write_track_chunk _ANSI_ARGS_((int, TCHUNK *));
  950. Xextern int load_tracks _ANSI_ARGS_((int, HCHUNK *, TCHUNK **, TRKS *));
  951. Xextern int split_type_zero _ANSI_ARGS_((TCHUNK *));
  952. Xextern int fix2var _ANSI_ARGS_((long, unsigned char *));
  953. Xextern long var2fix _ANSI_ARGS_((unsigned char *, int *));
  954. Xextern void free_track _ANSI_ARGS_((TCHUNK *));
  955. Xextern int mread _ANSI_ARGS_((int, char *, int));
  956. Xextern int mwrite _ANSI_ARGS_((int, char *, int));
  957. Xextern int more_memory _ANSI_ARGS_((char **, int));
  958. X#endif
  959. END-of-tclm0.1/mlib/mutil.h
  960. exit
  961.  
  962.