home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / audio / synthia / rdmf.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  9.9 KB  |  516 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  * Copyright (C) 1991, Silicon Graphics, Inc.
  19.  * All Rights Reserved.
  20.  */
  21.  
  22.     /*
  23.      *  rdmf  -  Read a MIDI file
  24.      *
  25.      *  Jim Bennett
  26.      *  1991
  27.      *
  28.      *  Contains the routines:
  29.      *    mf_read_hd (file, header)
  30.      *    mf_read_trk (file, resolution)
  31.      */
  32.  
  33. #include <stdio.h>
  34. #include "midif.h"
  35.  
  36. extern    int    maxfinger;
  37.  
  38. #ifdef    DEBUG
  39.  
  40. static    int    col = 0;
  41.  
  42. #else
  43.  
  44. #define    GETC    getc
  45.  
  46. #endif
  47.  
  48.     /*
  49.      *  mf_read_hd  -  Read in MIDI file header
  50.      *
  51.      *    Returns -1 if not a MIDI file
  52.      */
  53.  
  54. mf_read_hd (midifile, mf_header)
  55.  
  56.     FILE    *midifile;
  57.     struct    s_mfhd    *mf_header;
  58.  
  59.     {
  60.     int    c, n;
  61.     char    buf[8];
  62.     long    x;
  63.  
  64. /* Check header of file    */
  65.  
  66.     for (n=0; n<4; n++)
  67.         {
  68.         c = GETC (midifile);
  69.         if (c == EOF) return (-1);
  70.         buf [n] = c;
  71.         }
  72.     buf [n] = 0;
  73.     if (strcmp (buf, MF_header) != 0) return (-1);
  74.  
  75. /* Read in header    */
  76.  
  77.     for (x=0, n=0; n<4; n++)
  78.         {
  79.         c = GETC (midifile);
  80.         if (c == EOF) return (-1);
  81.         x = (x << 8) + c;
  82.         }
  83.     if (x != 6) return (-1);    /* Header length must be 6    */
  84.  
  85.     for (x=0, n=0; n<2; n++)
  86.         {
  87.         c = GETC (midifile);
  88.         if (c == EOF) return (-1);
  89.         x = (x << 8) + c;
  90.         }
  91.     mf_header->format = x;
  92.  
  93.     for (x=0, n=0; n<2; n++)
  94.         {
  95.         c = GETC (midifile);
  96.         if (c == EOF) return (-1);
  97.         x = (x << 8) + c;
  98.         }
  99.     mf_header->ntrks = x;
  100.  
  101.     for (x=0, n=0; n<2; n++)
  102.         {
  103.         c = GETC (midifile);
  104.         if (c == EOF) return (-1);
  105.         x = (x << 8) + c;
  106.         }
  107.     mf_header->division = x;
  108.  
  109.     return (0);
  110.     }
  111.  
  112.     /*
  113.      *  mf_read_trk  -  Read in a single track
  114.      *
  115.      *    Returns an array of events (struct s_mfevent)
  116.      *    Return negative error code if not a valid track
  117.      *    Sets the global variable maxfinger
  118.      */
  119.  
  120. struct s_mfevent *mf_read_trk (midifile, resolution)
  121.  
  122.     FILE    *midifile;
  123.     int    resolution;
  124.  
  125.     {
  126.     int    c, n;
  127.     char    buf[8];
  128.     long    trklen, trkcnt;
  129.     struct    s_mfevent    *mfv_base;
  130.     struct    s_mfevent    *mfv;
  131.     int    evcnt, pitch, velocity;
  132.     float    mf_time;
  133.     int    last_status;
  134.     int    midi_event;
  135.     int    finger;
  136.     int    programs[16];
  137.     int    channels[16];
  138.     int    fingertab[16];
  139.  
  140.     last_status = -1;
  141.     for (n=0; n<16; n++) programs[n] = n;
  142.     for (n=0; n<16; n++) channels[n] = 0;
  143.     for (n=0; n<16; n++) fingertab[n] = 0;
  144.  
  145. /* Check for valid track    */
  146.  
  147.     for (n=0; n<4; n++)
  148.         {
  149.         c = GETC (midifile);
  150.         if (c == EOF) return ((struct s_mfevent *)-1);
  151.         buf [n] = c;
  152.         }
  153.     buf [n] = 0;
  154.     if (strcmp (buf, MF_track) != 0) return ((struct s_mfevent *)-2);
  155.  
  156. /* Get length of track, and allocate an event buffer    */
  157.  
  158.     for (trklen=0, n=0; n<4; n++)
  159.         {
  160.         c = GETC (midifile);
  161.         if (c == EOF) return ((struct s_mfevent *)-3);
  162.         trklen = (trklen << 8) + c;
  163.         }
  164.  
  165.     mfv_base = (struct s_mfevent *)malloc
  166.             (10000 * sizeof (struct s_mfevent));
  167.     mfv = mfv_base;
  168.  
  169. /* Process the track into events    */
  170.  
  171.     finger = 0;
  172.     maxfinger = 0;
  173.     evcnt = 0;
  174.     trkcnt = 0;
  175.     mf_time = 0.0;
  176.     while (1)
  177.         {
  178.  
  179.     /* Per event:  Get track relative time of event    */
  180.  
  181.         for (n=0, c=0x80; c&0x80; )
  182.             {
  183.             c = GETC (midifile);
  184.             if (c == EOF) return ((struct s_mfevent *)-4);
  185.             trkcnt++;
  186.             if (trkcnt > trklen) return ((struct s_mfevent *)-5);
  187.  
  188.             n = (n << 7) + (c & 0x7f);
  189.             }
  190.         mf_time = mf_time + (float)n / (float)resolution;
  191.  
  192.     /* Next classify event    */
  193.  
  194.         c = GETC (midifile);
  195.         if (c == EOF) return ((struct s_mfevent *)-6);
  196.         trkcnt++;
  197.         if (trkcnt > trklen) return ((struct s_mfevent *)-7);
  198.  
  199.     /* Check for end of track event    */
  200.  
  201. next_event:
  202.         if (c == META_EVENT)
  203.             {
  204.             c = GETC (midifile);
  205.             if (c == EOF) return ((struct s_mfevent *)-8);
  206.             trkcnt++;
  207.             if (trkcnt > trklen) return ((struct s_mfevent *)-9);
  208.  
  209.             if (c != END_TRACK) goto skip_event;
  210.  
  211.             c = GETC (midifile);
  212.             if (c == EOF) return ((struct s_mfevent *)-10);
  213.             trkcnt++;
  214.  
  215.             if (c != 0) return ((struct s_mfevent *)-11);
  216.             if (trkcnt != trklen) return ((struct s_mfevent *)-12);
  217.             goto end_of_track;
  218.             }
  219.  
  220.     /* Skip over SYSEX events    */
  221.  
  222.         if ((c == SYSEX_EVENT) || (c == SYSEX_EVENTA))
  223.             {
  224.             c = GETC (midifile);
  225.             if (c == EOF) return ((struct s_mfevent *)-13);
  226.             trkcnt++;
  227.             if (trkcnt > trklen) return ((struct s_mfevent *)-14);
  228.  
  229.             goto skip_event;
  230.             }
  231.  
  232.     /* Process normal MIDI events    */
  233.  
  234.         midi_event = c;
  235.  
  236.         if (c >= 0x80)
  237.             {
  238.             c = GETC (midifile);
  239.             if (c == EOF) return ((struct s_mfevent *)-15);
  240.             trkcnt++;
  241.             if (trkcnt > trklen)
  242.                 return ((struct s_mfevent *)-16);
  243.  
  244. #ifdef    DEBUG
  245.             if (c >= 0x80)
  246.                 {
  247.                 printf ("\nInterrupt 1\n");
  248.                 goto next_event;
  249.                 }
  250. #endif
  251.             }
  252.  
  253. event_switch:
  254.         switch (midi_event & 0xf0)
  255.             {
  256.             case NOTE_OFF:
  257.                 last_status = midi_event;
  258.                 pitch = c;
  259.  
  260.                 c = GETC (midifile);
  261.                 if (c == EOF) return ((struct s_mfevent *)-17);
  262.                 trkcnt++;
  263.                 if (trkcnt > trklen)
  264.                     return ((struct s_mfevent *)-18);
  265.  
  266. #ifdef    DEBUG
  267.         if (c >= 0x80)
  268.             {
  269.             printf ("\nInterrupt 2\n");
  270.             goto next_event;
  271.             }
  272. #endif
  273.  
  274.                 velocity = c;
  275.  
  276.                 channels[midi_event&0x0f] = 1;
  277.                 for (n=0; n<16; n++)
  278.                     if (fingertab[n] == pitch) break;
  279.                 finger = n;
  280.                 if (finger >= 16)
  281.                     {
  282.                     fprintf (stderr,
  283.                         "finger underflow!\n");
  284.                     }
  285.                 else
  286.                     {
  287.                     fingertab[finger] = 0;
  288.                     mfv->time = mf_time;
  289.                     mfv->event =
  290.                       (finger << 28) +
  291.                        (programs[midi_event&0x0f] << 24) +
  292.                        (NOTE_OFF << 16) +
  293.                       (velocity << 8) +
  294.                       pitch;
  295.                     mfv++;
  296.                     evcnt++;
  297.                     if (evcnt >= 10000)
  298.                         {
  299.                         fprintf (stderr, "Too many events!\n");
  300.                         return ((struct s_mfevent *)-20);
  301.                         }
  302.                     }
  303.                 break;
  304.  
  305.             case NOTE_ON:
  306.                 last_status = midi_event;
  307.                 pitch = c;
  308.  
  309.                 c = GETC (midifile);
  310.                 if (c == EOF) return ((struct s_mfevent *)-21);
  311.                 trkcnt++;
  312.                 if (trkcnt > trklen)
  313.                     return ((struct s_mfevent *)-22);
  314.  
  315. #ifdef    DEBUG
  316.         if (c >= 0x80)
  317.             {
  318.             printf ("\nInterrupt 3\n");
  319.             goto next_event;
  320.             }
  321. #endif
  322.  
  323.                 velocity = c;
  324.  
  325.                 channels[midi_event&0x0f] = 1;
  326.                 if (velocity == 0)
  327.                     {
  328.                     for (n=0; n<16; n++)
  329.                         if (fingertab[n] == pitch) break;
  330.                     finger = n;
  331.                     if (finger >= 16)
  332.                         {
  333.                         fprintf (stderr,
  334.                             "finger underflow!\n");
  335.                         }
  336.                     else
  337.                         {
  338.                         fingertab[finger] = 0;
  339.                         mfv->time = mf_time;
  340.                         mfv->event =
  341.                       (finger << 28) +
  342.                       (programs[midi_event&0x0f] << 24) +
  343.                       (NOTE_OFF << 16) +
  344.                       (velocity << 8) +
  345.                       pitch;
  346.                         mfv++;
  347.                         evcnt++;
  348.                         if (evcnt >= 10000)
  349.                             {
  350.                             fprintf (stderr, "Too many events!\n");
  351.                             return ((struct s_mfevent *)-25);
  352.                             }
  353.                         }
  354.                     }
  355.                 else
  356.                     {
  357.                     for (n=0; n<16; n++)
  358.                         if (fingertab[n] == 0) break;
  359.                     finger = n;
  360.                     if (finger >= 16)
  361.                         {
  362.                         fprintf (stderr,
  363.                             "finger overflow!\n");
  364.                         return ((struct s_mfevent *)-24);
  365.                         }
  366.                     fingertab[finger] = pitch;
  367.                     mfv->time = mf_time;
  368.                     mfv->event =
  369.                       (finger << 28) +
  370.                       (programs[midi_event&0x0f] << 24) +
  371.                       (NOTE_ON << 16) +
  372.                       (velocity << 8) +
  373.                       pitch;
  374.                     mfv++;
  375.                     evcnt++;
  376.                     if (evcnt >= 10000)
  377.                         {
  378.                         fprintf (stderr, "Too many events!\n");
  379.                         return ((struct s_mfevent *)-25);
  380.                         }
  381.                     finger++;
  382.                     if (finger > maxfinger)
  383.                         maxfinger = finger;
  384.                     }
  385.                 break;
  386.  
  387.             case KEY_PRESSURE:
  388.                 last_status = midi_event;
  389.                 goto skip_two;
  390.  
  391.             case PARAMETER:
  392.                 last_status = midi_event;
  393.                 goto skip_two;
  394.  
  395.             case PROGRAM:
  396. #ifdef    DEBUG
  397.                 printf ("\nProgram change\n");
  398. #endif
  399.                 last_status = midi_event;
  400.                     /* Set program for this channel    */
  401.                 programs[midi_event&0x0f] = c&0x0f;
  402.                 break;
  403.  
  404.             case CHAN_PRESSURE:
  405.                 last_status = midi_event;
  406.                 goto skip_one;
  407.  
  408.             case PITCH_WHEEL:
  409.                 last_status = midi_event;
  410.                 goto skip_two;
  411.  
  412.             default:
  413.                 if ((last_status > 0) && (midi_event <= 0x7f))
  414.                     {
  415.                     c = midi_event;
  416.                     midi_event = last_status;
  417.                     goto event_switch;
  418.                     }
  419.                 else
  420.                     return ((struct s_mfevent *)-26);
  421.             }
  422.         continue;
  423.  
  424.     /* skip_one, skip_two:  skip one or two bytes    */
  425.  
  426. skip_two:
  427.         c = GETC (midifile);
  428.         if (c == EOF) return ((struct s_mfevent *)-27);
  429.         trkcnt++;
  430.         if (trkcnt > trklen) return ((struct s_mfevent *)-28);
  431.  
  432. #ifdef    DEBUG
  433.         if (c >= 0x80)
  434.             {
  435.             printf ("\nInterrupt 4\n");
  436.             goto next_event;
  437.             }
  438. #endif
  439.  
  440. skip_one:
  441.         continue;
  442.  
  443.     /* skip_event:  read event length and skip that many bytes    */
  444.  
  445. skip_event:
  446.         for (n=0, c=0x80; c&0x80; )
  447.             {
  448.             c = GETC (midifile);
  449.             if (c == EOF) return ((struct s_mfevent *)-29);
  450.             trkcnt++;
  451.             if (trkcnt > trklen) return ((struct s_mfevent *)-30);
  452.  
  453.             n = (n << 7) + (c & 0x7f);
  454.             }
  455.  
  456.         while (n-- > 0)
  457.             {
  458.             c = GETC (midifile);
  459.             if (c == EOF) return ((struct s_mfevent *)-31);
  460.             trkcnt++;
  461.             if (trkcnt > trklen) return ((struct s_mfevent *)-32);
  462.             }
  463.         }
  464.  
  465. end_of_track:
  466.     for (n=0; n<16; n++)
  467.         if (fingertab[n] != 0) break;
  468.     if (n < 16)
  469.         {
  470.         printf ("Too many fingers!\n");
  471.         return ((struct s_mfevent *)-33);
  472.         }
  473. #ifdef DEBUG
  474.     printf ("%d events in this track\n", evcnt);
  475.     printf ("%d fingers used in this track\n", maxfinger);
  476.     printf ("Channels: %d %d %d %d %d %d %d %d\n",
  477.         channels[0], channels[1], channels[2], channels[3],
  478.         channels[4], channels[5], channels[6], channels[7]);
  479.     printf ("          %d %d %d %d %d %d %d %d\n",
  480.         channels[8],  channels[9],  channels[10], channels[11],
  481.         channels[12], channels[13], channels[14], channels[15]);
  482. #endif
  483.     mfv->time = END_TIME;
  484.     return (mfv_base);
  485.     }
  486.  
  487. #ifdef DEBUG
  488.     /*
  489.      *  GETC  -  Input character and echo as hex byte
  490.      */
  491.  
  492. int GETC (f)
  493.  
  494.     FILE    *f;
  495.  
  496.     {
  497.     char    buf[4];
  498.     int    ret;
  499.  
  500.     ret = read (fileno(f), buf, 1);
  501.     if (ret == 1)
  502.         ret = (buf[0])&0xff;
  503.     else
  504.         ret = EOF;
  505.  
  506.     col++;
  507.     printf ("%2.2x", ret);
  508.     if ((col & 0x0f) == 0)
  509.         printf ("\n");
  510.     else
  511.         printf (" ");
  512.  
  513.     return (ret);
  514.     }
  515. #endif
  516.