home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / sound / players / mp02_tar.z / mp02_tar / mp02 / phase2.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-02-08  |  26.3 KB  |  1,096 lines

  1. /* phase2.c -- this module plays notes compiled and sorted in phase1 or phasem */
  2.  
  3. #include <stdio.h>
  4. #include <ctype.h>
  5. #include <malloc.h>
  6. #include "cext.h"
  7. #include "adagio.h"
  8. #include "userio.h"
  9. #include "cmdline.h"
  10. #include "pitch.h"
  11. #include "midicode.h"
  12. #include "midi.h"
  13. #include "drum.h"
  14. #include <linux/soundcard.h>
  15. #include <fcntl.h>
  16.  
  17. #define MAXTIME 10000000
  18.  
  19. #ifndef XSELECT
  20. #define XSELECT 0
  21. #endif
  22. #ifndef PSELECT
  23. #define PSELECT 0x8200
  24. #endif
  25.  
  26. extern boolean verbose;
  27.  
  28. #define n_t_sw 2
  29. private char *t_switches[n_t_sw] = { "-t", "-trace" };
  30. #define n_m_sw 2
  31. private char *m_switches[n_m_sw] = { "-m", "-midi" };
  32. #define n_e_sw 2
  33. private char *e_switches[n_e_sw] = { "-e", "-external" };
  34. #define nmsw 2
  35. private char *msw[nmsw] = { "-i", "-init" };
  36. private boolean initflag = false;
  37. private boolean extflag = false;
  38. extern int percsel;
  39. extern boolean drum_mode;
  40. private boolean v_drum = true;
  41. private boolean use_damper = false;
  42.  
  43. private long time = 0;    /* time clock */
  44. private long lasttime = 0;    /* time clock */
  45. private boolean readable = false;
  46.  
  47. private int user_scale = false; /* true if user-defined scale */
  48. private int bend[num_voices];    /* current pitch bend on channel */
  49. private pitch_table pit_tab[128];    /* scale definition */
  50.  
  51. private char sblast = true;
  52. /****************************************************************************
  53. * Routines local to this module
  54. ****************************************************************************/
  55. private    void    off_init();
  56. private void    tuninginit();
  57. private void    read_tuning();
  58. private    boolean    note_offs();
  59. private long    next_off();
  60. private    void    off_schedule();
  61. private void    f_note();
  62. private void    f_touch();
  63. private void    f_program();
  64. private void    f_ctrl();
  65. private void    f_bend();
  66. /*private void    load_drums();*/
  67.  
  68.  
  69. static int sb;
  70. static unsigned char sbbuf[404];
  71. static int sbptr = 0;
  72. static int num_cells, perc_mode;
  73. struct synth_info fm_info;
  74.  
  75. void midisync(void);
  76. void fm_program(int,int,int);
  77. void fm_noteon(int,int,int,int);
  78. void fm_noteoff(int,int,int);
  79.  
  80. void sbflush(void)
  81. {
  82.     if (!sbptr) return;
  83.  
  84.     if (write(sb, sbbuf, sbptr) == -1) {
  85.         perror("write sb");
  86.         exit(-1);
  87.     }
  88.  
  89.     sbptr=0;
  90. }
  91.  
  92. void sbwrite(char *msg)
  93. {
  94.     if (sbptr>400) sbflush();
  95.  
  96.     memcpy(&sbbuf[sbptr], msg, 4);
  97.     sbptr +=4;
  98. }
  99.  
  100. void midich(char c)
  101. {
  102.     char buf[4];
  103.  
  104.     buf[0] = 5;
  105.     buf[1] = c;
  106.     sbwrite(buf);
  107. }
  108.  
  109.  
  110. extern struct sub_type{
  111.     char *vname;
  112.     char solo;
  113.     char newv;
  114.     char transpose;
  115. } sub_voice[];
  116.  
  117. #define EOX 0xf7
  118.  
  119. extern int ext_program[];
  120. extern int ext_chan[];
  121. extern int ext_pan[];
  122. private int main_volume[16] = { 90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90 };
  123. private int expression[16] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 };
  124.  
  125. #ifdef K1
  126. /* form of a multi patch on the Kawai K1 */
  127. struct patch_multi {
  128.     char name[10];
  129.     char volume;
  130.     char single[8];
  131.     char zonelow[8];
  132.     char zonehigh[8];
  133.     char poly[8];
  134.     char rcvchan[8];
  135.     char transpose[8];
  136.     char tune[8];
  137.     char level[8];
  138.     char checksum;
  139. } patch = {
  140.     'M','i','s','c',' ',' ',' ',' ',' ',' ',
  141.     99,
  142.     0,1,2,3,4,5,6,7,
  143.     0,0,0,0,0,0,0,0,
  144.     127,127,127,127,127,127,127,127,
  145.     0x00, 0x20, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
  146.     0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
  147.     24,24,24,24,24,24,24,24,
  148.     50,50,50,50,50,50,50,50,
  149.     100,100,100,100,100,100,100,100,
  150.     0x74
  151. };
  152.  
  153. /* send intro to K1 sysex command */
  154. void
  155. k1send1(function, voice)
  156. {
  157.     midich(0xf0);
  158.     midich(0x40);        /* Kawai id */
  159.     midich(0x00);        /* channel = 0 to 15 */
  160.     midich(function);    /* function */
  161.     midich(0x00);        /* group */
  162.     midich(0x03);        /* machine id number of K1 */
  163.     midich(0x00);        /* subcommand 1 = internal */
  164.     midich(voice);    /* subcommand 2 = voice/program */
  165. }
  166.  
  167. /* byte to K1 and update checksum */
  168. void
  169. mchk(c)
  170. int c;
  171. {
  172.     midich(c);
  173.     patch.checksum += c & 0x7f;
  174. }
  175.  
  176. /* k1msone - send a single voice to the K1 */
  177. void
  178. k1msone(iv)
  179. int iv;
  180. {
  181.     int n;
  182.  
  183.     k1send1(0x20, iv);
  184.     patch.checksum = 0xa5;
  185.  
  186.     for (n = 0; n < 10; n++) mchk(patch.name[n]);
  187.     mchk(patch.volume);
  188.     for (n = 0; n < 8; n++) mchk(patch.single[n]);
  189.     for (n = 0; n < 8; n++) mchk(patch.zonelow[n]);
  190.     for (n = 0; n < 8; n++) mchk(patch.zonehigh[n]);
  191.     for (n = 0; n < 8; n++) mchk(patch.poly[n]);
  192.     for (n = 0; n < 8; n++) mchk(patch.rcvchan[n]);
  193.     for (n = 0; n < 8; n++) mchk(patch.transpose[n]);
  194.     for (n = 0; n < 8; n++) mchk(patch.tune[n]);
  195.     for (n = 0; n < 8; n++) mchk(patch.level[n]);
  196.     midich(patch.checksum & 0x7f);
  197.     midich(EOX);
  198.  
  199. }
  200. #endif
  201.  
  202. /****************************************************************************
  203. *                    phase2
  204. * Inputs:
  205. *    event_type root: Root of play list
  206. * Effect: 
  207. *    Plays the music
  208. ****************************************************************************/
  209.  
  210. void phase2(score)
  211.     event_type score;
  212. {    
  213.     event_type event = score;    /* pointer to next note or control event */
  214.     short done = false;
  215.     long offtime = 0;        /* time  for next note off*/
  216.     int i;            /* index counter to initialize channels */
  217.     int n;
  218.  
  219.  
  220.     readable = (cl_nswitch(t_switches, n_t_sw) != NULL);
  221.     sblast = (cl_nswitch(m_switches, n_m_sw) == NULL);
  222.     if (!sblast) extflag = false;
  223.     else extflag = (cl_nswitch(e_switches, n_e_sw) == NULL);
  224.     if (extflag) sblast = true;
  225.     if (readable) sblast = false;
  226.     initflag = (cl_nswitch(msw, nmsw) == NULL);
  227.     if (cl_switch("-s")) use_damper = true;
  228.  
  229.     off_init();
  230.     tuninginit();  
  231.  
  232.     if (sblast) {
  233.     char buf[4];
  234.     if ((sb=open("/dev/sequencer", O_WRONLY, 0))==-1) {
  235.         perror("/dev/sequencer");
  236.         exit(-1);
  237.     }
  238.     /*if (drum_mode) load_drums();*/
  239.  
  240.     if (drum_mode)
  241.     if (ioctl(sb, SNDCTL_SEQ_PERCMODE, 1) == -1) {
  242.         perror("/dev/sequencer");
  243.         exit(-1);
  244.     }
  245.  
  246.     if (ioctl(sb, SNDCTL_SYNTH_INFO, &fm_info) == -1) {
  247.         perror("/dev/sequencer");
  248.         exit(-1);
  249.     }
  250.  
  251.     num_cells = fm_info.nr_voices;
  252.     perc_mode = fm_info.perc_mode;
  253.     /* and if card does not support drum mode, make sure not
  254.      * to use any percussion channels
  255.      */
  256.     if (drum_mode && !perc_mode) percsel = 0;
  257.  
  258.     if (verbose) printf("Nr. SB voices %d, %s percussion mode.\n",
  259.         num_cells, perc_mode? "using" : "no");
  260.     }
  261.  
  262.     for (n = 0; n < num_voices; n++) {
  263.     int v;
  264.     if (!extflag) ext_chan[n] = 0;
  265.     /* "ext_program" has the first program requested for each
  266.      * channel, or else -1 or 0 if there was no program request
  267.      * (0 if notes were played on the channel)
  268.      */
  269.     v = program[n] - 1;
  270.     /* if notes were played but there was no program request, use
  271.      * program 0, Ac. Gr. Piano, as default
  272.      */
  273.     if (v == -2 && program[n] == 0) v = 0;
  274.     if (PERCCHAN(n)) {
  275.         if (verbose) {
  276.             printf("  channel %2d: SB percussion", n+1);
  277.             if (program[n] > 0) printf(" (%s[%d] request ignored)",
  278.             sub_voice[program[n]-1].vname, program[n]-1);
  279.             printf(".\n");
  280.         }
  281.     }
  282. #ifdef K1
  283.     /* which channels shall we send out to the K1? none if the -e flag
  284.      * was given (extflag is 0), no more than the max (etot keeps track),
  285.      * and not for a timbre the K1 doesn't have (marked -1 in the array in
  286.      * vname.h)
  287.      */
  288.     else if (ext_chan[n]) {
  289.         static char *pan[3] = { "right", "center", "left" };
  290.         int etot = ext_chan[n] - 1;
  291.         int leftright = 1;
  292.         int solo = 0;
  293.         if (ext_pan[n] != -1) {
  294.             if (ext_pan[n] < 64) leftright = 2;
  295.             else if (ext_pan[n] > 64) leftright = 0;
  296.  
  297.         }
  298.         v = ext_program[etot] - 1;
  299.         if (sub_voice[v].solo) solo = 2;
  300.         patch.poly[etot] = (0x40&patch.poly[etot])
  301.                 | solo
  302.                 | (leftright << 4);
  303.         /* use transposition marked in vname.h */
  304.         patch.transpose[etot] = sub_voice[v].transpose + 24;
  305.         /* finally, the voice/timbre for the section */
  306.         patch.single[etot] = sub_voice[v].newv;
  307.         if (verbose) {
  308.             printf("  channel %2d: %s[%d] %s to K1 channel %d at %s.\n", n+1,
  309.                 sub_voice[v].vname, v, solo? "solo":"poly",
  310.                 etot+1, pan[leftright]);
  311.             if (v != program[n]-1) printf("   (also %s[%d], etc. to SB)\n",
  312.                 sub_voice[program[n]-1].vname, program[n]-1);
  313.         }
  314.     }
  315. #else
  316.     else if (ext_chan[n] && v >= 0) {
  317.         if (verbose) printf("  channel %2d: %s[%d] external.\n", n+1,
  318.             sub_voice[v].vname, v);
  319.     }
  320. #endif
  321.     else if (program[n] >= 0) {
  322.         if (verbose) {
  323.             printf("  channel %2d: is %s[%d] etc. on SB.\n", n+1,
  324.             sub_voice[program[n]-1].vname, program[n]-1);
  325.         }
  326.     }
  327.     }
  328. #ifdef K1
  329.     if (extflag) {
  330.     /* I have had a hell of a time getting the K1 to accept and use a patch;
  331.      * the following uses up so much time waiting that the SB sequencer has
  332.      * to be reset -- and it works only 9 times out of 10
  333.      */
  334.         char buf[4];
  335.         k1msone(64);
  336.         sbflush();
  337.         sleep(2);
  338.         midich(PROGRAM + 0);
  339.         midich(64);
  340.         sbflush();
  341.         sleep(4);
  342.         buf[0] = SEQ_SYNCTIMER;
  343.         sbwrite(buf);
  344.         sbflush();
  345.     }
  346. #endif
  347.  
  348.  
  349.     /* Initialize all midi channels with reasonable start values: */
  350.     for (i = 1; i <= num_voices; i++) {
  351.     int d = ext_chan[i-1];
  352.     program[i-1] = ext_program[i-1];
  353.     if (program[i-1] <= 0) ext_program[i-1] = program[i-1] = 1;
  354.     bend[i-1] = 1 << 13;
  355.     if (!initflag) continue;
  356.     f_program(d, i, program[i-1]);
  357.     f_bend(d, i, 1 << 13);
  358.     f_touch(d, i, 0);
  359.     f_ctrl(d, i, PORTARATE, 99);
  360.     f_ctrl(d, i, PORTASWITCH, 0);
  361.     f_ctrl(d, i, MODWHEEL, 0);
  362.     f_ctrl(d, i, FOOT, 99);
  363.     f_ctrl(d, i, VOLUME, 90);
  364.     if (d) continue;
  365.     f_program(0, i, program[i-1]);
  366.     f_bend(0, i, 1 << 13);
  367.     f_touch(0, i, 0);
  368.     f_ctrl(0, i, PORTARATE, 99);
  369.     f_ctrl(0, i, PORTASWITCH, 0);
  370.     f_ctrl(0, i, MODWHEEL, 0);
  371.     f_ctrl(0, i, FOOT, 99);
  372.     f_ctrl(0, i, VOLUME, 90);
  373.     }
  374.  
  375.     while (event != NULL) { /* play it, Sam */
  376.     int d = event->ndest;
  377.     if (!ext_chan[event->nvoice]) d = 0;
  378.     time = event->ntime;
  379.     note_offs(time);
  380.  
  381.     if (is_note(event)) { /* play a note */
  382.             /* check for correct program (preset) */
  383.             if (event->u.note.nprogram != program[event->nvoice]) {
  384.             f_program(d, event->nvoice+1, event->u.note.nprogram);
  385.              program[event->nvoice] = event->u.note.nprogram;
  386.             }
  387.             /* if it is a note (not a rest) play it */
  388.             if (event->u.note.npitch != NO_PITCH) {
  389.             f_note(d, event->nvoice+1, event->u.note.npitch,
  390.                   event->u.note.nloud);
  391.             off_schedule(d, event->ntime + event->u.note.ndur,
  392.                      event->nvoice, event->u.note.npitch);
  393.             }
  394.     } else {    /* send control info */
  395.             switch (vc_ctrl(event->nvoice)) {
  396.             case 1: f_ctrl(d, vc_voice(event->nvoice) + 1,
  397.                          PORTARATE,
  398.                          event->u.ctrl.value);
  399.                 break;
  400.             case 2: f_ctrl(d, vc_voice(event->nvoice) + 1,
  401.                          PORTASWITCH,
  402.                          event->u.ctrl.value);
  403.                 break;
  404.             case 3: f_ctrl(d, vc_voice(event->nvoice) + 1,
  405.                          MODWHEEL,
  406.                          event->u.ctrl.value);
  407.                 break;
  408.             case 4: f_touch(d, vc_voice(event->nvoice) + 1,
  409.                        event->u.ctrl.value);
  410.                 break;
  411.             case 5: if (use_damper) f_ctrl(d, vc_voice(event->nvoice) + 1,
  412.                          FOOT,
  413.                          event->u.ctrl.value);
  414.                 break;
  415.             case 6: f_bend(d, vc_voice(event->nvoice) + 1,
  416.                       event->u.ctrl.value << 6);
  417.                 break;
  418.             /* when d=0 should I also set volume external channel? */
  419.             case 7: f_ctrl(d, vc_voice(event->nvoice) + 1,
  420.                          VOLUME,
  421.                          event->u.ctrl.value);
  422.                 main_volume[vc_voice(event->nvoice)] =
  423.                          event->u.ctrl.value;
  424.                 break;
  425.             case 8: f_ctrl(d, vc_voice(event->nvoice) + 1,
  426.                          PAN,
  427.                          event->u.ctrl.value);
  428.                 break;
  429.             case 9: f_ctrl(d, vc_voice(event->nvoice) + 1,
  430.                          EXPRESSION,
  431.                          event->u.ctrl.value);
  432.                 expression[vc_voice(event->nvoice)] =
  433.                          event->u.ctrl.value;
  434.                 break;
  435.             /* pass through any other controls */
  436.             case 15: f_ctrl(d, vc_voice(event->nvoice) + 1,
  437.                          event->u.ctrl.control,
  438.                          event->u.ctrl.value);
  439.                 break;
  440.             default: break;
  441.             }
  442.     }
  443.  
  444.     event = event->next;
  445.     } /* play it, Sam */
  446.  
  447.     note_offs(MAXTIME);
  448.     if (sblast) sbflush();
  449. }
  450.  
  451.  
  452. /* noteoff.c -- this module keeps track of pending note offs for adagio */
  453.  
  454. /*****************************************************************************
  455. *        Change Log
  456. *  Date        | Change
  457. *-----------+-----------------------------------------------------------------
  458. * 31-Dec-85 | Created changelog
  459. * 31-Dec-85 | Add c:\ to include directives
  460. *  1-Jan-86 | Declare malloc char * for lint consistency
  461. * 21-Jan-86 | note_offs can now turn off more than one note per call
  462. *****************************************************************************/
  463.  
  464.  
  465. /* off_type is a structure containing note-off information */
  466.  
  467. typedef struct off_struct {
  468.     long when;
  469.     int voice;
  470.     int pitch;
  471.     int dest;
  472.     struct off_struct *next;
  473. } *off_type;
  474.  
  475. private off_type free_off;        /* free list of off_type structures */
  476. private off_type off_events = NULL;    /* active list */
  477.  
  478. /****************************************************************************
  479. *    Routines declared in this module
  480. ****************************************************************************/
  481.  
  482. private off_type    off_alloc();
  483. private void        off_free();
  484.  
  485. /****************************************************************************
  486. *                note_offs
  487. * Inputs:
  488. *    long time: the current time
  489. * Outputs:
  490. *    return true if off list has more notes 
  491. * Effect: turn off notes if it is time 
  492. * Assumes:
  493. * Implementation:
  494. *    Find scheduled note off events in off_events, compare with time
  495. ****************************************************************************/
  496.  
  497. private boolean note_offs(mtime)
  498. long mtime;
  499. {
  500.     off_type temp;
  501.     while (off_events != NULL && (time=off_events->when) <= mtime) {
  502.     f_note(off_events->dest, (off_events->voice) + 1, off_events->pitch, 0);
  503.     temp = off_events;
  504.     off_events = off_events->next;
  505.     off_free(temp);
  506.     }
  507.     if (mtime < MAXTIME) time = mtime;
  508.     return (off_events != NULL);
  509. }
  510.  
  511. /****************************************************************************
  512. *                off_alloc
  513. * Outputs:
  514. *    returns off_type: an allocated note off structure
  515. * Effect:
  516. *    allocates a structure using malloc
  517. ****************************************************************************/
  518.  
  519. private off_type off_alloc()
  520. {
  521.     return (off_type) malloc(sizeof(struct off_struct));
  522. }
  523.  
  524. /****************************************************************************
  525. *                off_free
  526. * Inputs:
  527. *    off_type off: a structure to deallocate
  528. * Effect: 
  529. *    returns off to freelist
  530. ****************************************************************************/
  531.  
  532. private void off_free(off)
  533.     off_type off;
  534. {
  535.     off->next = free_off;
  536.     free_off = off;
  537. }
  538.  
  539. /****************************************************************************
  540. *                off_init
  541. * Effect: initialize this module
  542. * Assumes:
  543. *    only called once, otherwise storage is leaked
  544. ****************************************************************************/
  545.  
  546. private void off_init()
  547. {
  548.     int i;
  549.     for (i = 0; i < 50; i++) off_free(off_alloc());
  550. }
  551.  
  552. /****************************************************************************
  553. *                off_schedule
  554. * Inputs:
  555. *    long offtime: time to turn note off
  556. *    int voice: the midi channel
  557. *    int pitch: the pitch
  558. * Effect: 
  559. *    schedules a note to be turned off
  560. * Assumes:
  561. *    note_offs will be called frequently to actually turn off notes
  562. ****************************************************************************/
  563.  
  564. private void off_schedule(dest, offtime, voice, pitch)
  565.     long offtime;
  566.     int dest, voice, pitch;
  567. {
  568.     off_type off, ptr, prv;
  569.     /* allocate off */
  570.     if ((off = free_off) == NULL) {
  571.     off = off_alloc();
  572.     } else free_off = off->next;
  573.  
  574.     if (off == NULL) {
  575.     fprintf(stderr, "out of space for note off events");
  576.     exit(1);
  577.     }
  578.  
  579.     off->when = offtime;
  580.     off->voice = voice;
  581.     off->pitch = pitch;
  582.     off->dest = dest;
  583.     /* insert into list of off events */
  584.     ptr = off_events;
  585.     if (ptr == NULL || offtime <= ptr->when) {
  586.     off->next = ptr;
  587.     off_events = off;
  588.     } else {
  589.     while (ptr != NULL && offtime > ptr->when) {
  590.         prv = ptr;
  591.         ptr = ptr->next;
  592.     }
  593.     prv->next = off;
  594.     off->next = ptr;
  595.     }
  596. /*
  597.  *    printf("off_schedule(%ld, %d, %d): \n", offtime, voice, pitch);
  598.  *    for (ptr = off_events; ptr != NULL; ptr = ptr->next) {
  599.  *    printf("    %ld: %d, %d\n", ptr->when, ptr->voice, ptr->pitch);
  600.  *    }
  601.  */
  602. }
  603.  
  604. AWriteVarLen (value)
  605. register long value;
  606. {
  607.     register long buffer;
  608.  
  609.     buffer = value & 0x7f;
  610.     while ((value >>= 7) > 0)
  611.     {
  612.         buffer <<= 8;
  613.         buffer |= 0x80;
  614.         buffer += (value & 0x7f);
  615.     }
  616.  
  617.     while (true)
  618.     {
  619.         putchar(buffer);
  620.         if (buffer & 0x80)
  621.             buffer >>= 8;
  622.         else
  623.             break;
  624.     } 
  625. }
  626.  
  627. deltatime()
  628. {
  629.     float csecs = (float)(time - lasttime);
  630.  
  631.     AWriteVarLen( (long)(((csecs * 10.0) / 4.0 * 96) / 120) );
  632.     lasttime = time;
  633. }
  634.  
  635. /****************************************************************************
  636. *                   f_note
  637. * Inputs:
  638. *    int channel: midi channel on which to send data
  639. *    int pitch: midi pitch code
  640. *    int velocity: velocity with which to sound it (0=> release)
  641. * Effect: 
  642. *    Prints a midi note-play request out
  643. ****************************************************************************/
  644.  
  645. private void f_note(d, channel, pitch, velocity)
  646.     int d, channel, pitch, velocity;
  647. {
  648.     if (readable)
  649.     printf("Time=%d  Note %s, chan=%d pitch=%d vol=%d\n",
  650.         time, velocity? "on":"off", channel, pitch, velocity);
  651.     else if (sblast) fm_noteon(d, channel-1, pitch+12, velocity);
  652.     else {
  653.     deltatime();
  654.     putchar(NOTEON + channel - 1);
  655.     putchar(pitch+12);
  656.     putchar(velocity);
  657.     }
  658.  
  659.     if (user_scale) {
  660.     /* check for correct pitch bend */
  661.     if ((pit_tab[pitch+12].pbend != bend[MIDI_CHANNEL(channel)]) &&
  662.         (velocity != 0)) {
  663.         f_bend(d, channel, pit_tab[pitch+12].pbend);
  664.         bend[channel] = pit_tab[pitch+12].pbend;
  665.     }
  666.     pitch = pit_tab[pitch+12].ppitch;
  667.     }
  668. }
  669.  
  670. /****************************************************************************
  671. *                   f_bend
  672. * Inputs:
  673. *    int channel: midi channel on which to send data
  674. *    int value: pitch bend value
  675. * Effect: 
  676. *    Prints a midi pitch bend message
  677. ****************************************************************************/
  678.  
  679. private void f_bend(d, channel, value)
  680.     int d, channel, value;
  681. {
  682.     if (readable)
  683.     printf("Time=%d  Pitchbend, chan=%d value=%d\n",
  684.         time, channel, value);
  685.     else if (sblast) {
  686.     if (d) {
  687.         midisync();
  688.         midich(PITCHBEND + d - 1);
  689.         midich(value & 0x7f);
  690.         midich((value>>7) & 0x7f);
  691.     }
  692.     }
  693.     else {
  694.     deltatime();
  695.     putchar(PITCHBEND + channel - 1);
  696. /* are these bytes in right order? */
  697.     putchar(value & 0x7f);
  698.     putchar((value>>7) & 0x7f);
  699.     }
  700.  
  701.     bend[MIDI_CHANNEL(channel)] = value;
  702. }
  703.  
  704. /****************************************************************************
  705. *                   f_ctrl
  706. * Inputs:
  707. *    int channel: midi channel on which to send data
  708. *    int control: control number
  709. *    int value: control value
  710. * Effect: 
  711. *    Prints a midi control change message
  712. ****************************************************************************/
  713.  
  714. private void f_ctrl(d, channel, control, value)
  715.     int d, channel, control, value;
  716. {
  717.     if (readable)
  718.     printf("Time=%d  Parameter, chan=%d ctrl=%d value=%d\n", 
  719.         time, channel, control, value);
  720.     else if (sblast) {
  721.     if (d) {
  722. #ifdef K1
  723. /* no expression controller for K1, so use volume */
  724.         if (control == EXPRESSION) {
  725.             float vol_factor = main_volume[channel-1]/127.0;
  726.             control = VOLUME;
  727.             value *= vol_factor;
  728.         }
  729. #endif
  730.         midisync();
  731.         midich(CONTROLLER + d - 1);
  732.         midich(control);
  733.         midich(value);
  734.     }
  735.     }
  736.     else {
  737.     deltatime();
  738.     putchar(CONTROLLER + channel - 1);
  739.     putchar(control);
  740.     putchar(value);
  741.     }
  742. }
  743.  
  744. /****************************************************************************
  745. *                 f_program
  746. * Inputs:
  747. *    int channel: Channel on which to send midi program change request
  748. *    int program: Program number to send (decremented by 1 before
  749. *            being sent as midi data)
  750. * Effect: 
  751. *    Prints a program change request out the channel
  752. ****************************************************************************/
  753.  
  754. private void f_program(d, channel, program)
  755.     int d;        /* destination */
  756.     int channel;    /* midi channel */
  757.     int program;    /* the program number */
  758. {
  759.     if (readable)
  760.     printf("Time=%d  Program, chan=%d program=%d\n",
  761.         time, channel, program);
  762.     else if (sblast) fm_program(d, channel-1, program-1);
  763.     else {
  764.     deltatime();
  765.     putchar(PROGRAM + channel - 1);
  766.     putchar(program - 1);
  767.     }
  768. }
  769.  
  770. /****************************************************************************
  771. *                   f_touch
  772. * Inputs:
  773. *    int channel: midi channel on which to send data
  774. *    int value: control value
  775. * Effect: 
  776. *    Prints a midi after touch message
  777. ****************************************************************************/
  778.  
  779. private void f_touch(d, channel, value)
  780.     int d, channel, value;
  781. {
  782.     if (readable)
  783.     printf("Time=%d  Channel pressure, chan=%d value=%d\n",
  784.         time, channel, value);
  785.     else if (sblast) {
  786.     if (d) {
  787.         midisync();
  788.         midich(CHANPRESSURE + d - 1);
  789.         midich(value);
  790.     }
  791.     }
  792.     else {
  793.     deltatime();
  794.     putchar(CHANPRESSURE + channel - 1);
  795.     putchar(value);
  796.     }
  797. }
  798.  
  799. /*****************************************************************
  800. *            set_pitch_default
  801. *****************************************************************/
  802. private void set_pitch_default()
  803. {
  804.     int i;
  805.  
  806.     for (i = 0; i < 128; i++) {
  807.     pit_tab[i].pbend = 8192;
  808.     pit_tab[i].ppitch = i;
  809.     }
  810. }
  811.  
  812. /*****************************************************************
  813. *            read_tuning
  814. *****************************************************************/
  815.  
  816. private void read_tuning(filename)
  817.     char *filename;
  818. {
  819.     int index, pit, lineno = 0;
  820.     float bend;
  821.     FILE *fpp;
  822.  
  823.     user_scale = true;
  824.     set_pitch_default();
  825.     fpp = fileopen(filename, "tun", "r", "Tuning definition file");
  826.     while ((fscanf(fpp, "%d %d %f\n", &index, &pit, &bend) > 2) &&
  827.        (lineno < 128)) {
  828.     lineno++;
  829.     if (index >= -12 && index <= 115) {
  830.         pit_tab[index+12].pbend = (int)(8192 * bend/100 + 8192);
  831.         pit_tab[index+12].ppitch = pit;
  832.     }
  833.     }
  834. }
  835.  
  836.  
  837. /****************************************************************************
  838. *                   tunginginit
  839. * Effect: 
  840. * Read tuning file
  841. ****************************************************************************/
  842.  
  843. private void tuninginit()
  844. {
  845.     int i;
  846.     char *filename;
  847.  
  848.     filename = cl_option("-tune");
  849.     if (filename != NULL) {
  850.         read_tuning(filename);
  851.     }
  852. /*
  853.     if (user_scale) {
  854.     for (i = 0; i < num_voices; i++) {
  855.         f_bend(0, i+1, 8192);
  856.         bend[i] = 8192;
  857.     }
  858.     }
  859. */
  860.  
  861. }
  862.  
  863. /*
  864.  * following code mostly stolen from:
  865.  * 
  866.  * fmplay by Hannu Savolainen (hsavolai@cs.helsinki.fi)
  867.  * Modifications, bugfixes, and ANSIfied by Rob Hooft (hooft@chem.ruu.nl)
  868.  *
  869.  */
  870. static int chn_pgm[16] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
  871. #define N_CELL        (20)
  872. static int cell_next[N_CELL]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,0};
  873. static int cell_chan[N_CELL]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
  874. static int cell_pitch[N_CELL]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
  875. static int cell_restarted[N_CELL]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  876. static int cell_pointer=0;
  877. static int cell_circled=0;
  878.  
  879. void fm_drumon(int drum, int vol)
  880. {
  881.     char buf[4];
  882.     if (!perc_mode) return;
  883.  
  884.     buf[0] = SEQ_DRUMON;
  885.     buf[1] = 0;
  886.     buf[2] = drum;
  887.     buf[3] = vol;
  888.     sbwrite(buf);
  889. }
  890.  
  891. void fm_drumoff(int drum, int vol)
  892. {
  893.     char buf[4];
  894.  
  895.     if (!perc_mode) return;
  896.     buf[0] = SEQ_DRUMOFF;
  897.     buf[1] = 0;
  898.     buf[2] = drum;
  899.     buf[3] = vol;
  900.     sbwrite(buf);
  901. }
  902.  
  903. void fm_noteon(int d, int chan,int pitch,int vol)
  904. {
  905.     char buf[4];
  906.     int cell, dv;
  907.     midisync();
  908.  
  909.  
  910.     if (d) {
  911.         midich(NOTEON + d - 1);
  912.         midich(pitch);
  913.         midich(vol);
  914.         return;
  915.     }
  916.  
  917.     if (vol && main_volume[chan] >= 0) {
  918.         float vol_factor = (float)main_volume[chan];
  919.         if (expression[chan] >= 0) vol_factor *=
  920.             ((float)expression[chan]/127.0);
  921.         vol = vol * (vol_factor/127.0);
  922.     }
  923.  
  924.     if (PERCCHAN(chan)) {
  925.         if (drum_mode) {
  926.             if (!vol) fm_drumoff(pitch, vol);
  927.             else fm_drumon(pitch, vol);
  928.             return;
  929.         }
  930.         else if (v_drum) {
  931.             if (pitch >= 35 && pitch <= 81) {
  932.                 dv = d_voice[pitch - 35].dv;
  933.                 pitch = d_voice[pitch - 35].dnote;
  934.             }
  935.             else {
  936.                 dv = 130;
  937.                 pitch = 50;
  938.             }
  939.         }
  940.     }
  941.  
  942.     if (!cell_circled) {
  943.         cell_next[num_cells-1] = 0;
  944.         cell_circled = 1;
  945.     }
  946.     if (!vol) {
  947.         fm_noteoff(chan,pitch,vol);
  948.         return;
  949.     }
  950.  
  951.     /* first determine: is this note already running ? */
  952.     cell=0; 
  953.     while (cell<num_cells && (cell_chan[cell]!=chn_pgm[chan] || cell_pitch[cell]!=pitch)) {
  954.         ++cell;
  955.     }
  956.     if (cell<num_cells) {
  957.         /* terminate identical running note first */
  958.         fm_noteoff(chan,pitch,vol);
  959.         /* And AFTER putting it to silence, mark it as 
  960.            restarted, such that it will not be stopped 
  961.            immediately.  */
  962.         cell_restarted[cell_pointer]=1;
  963.     }
  964.     /* now allocate the cell, and move the pointer */
  965.     cell=cell_pointer;
  966.     cell_pointer=cell_next[cell_pointer];
  967.     cell_pitch[cell]=pitch;
  968.     if (1) /*if (cell_chan[cell] != chn_pgm[chan])*/ {
  969.         buf[0] = SEQ_FMPGMCHANGE;
  970.         buf[1] = cell;
  971.         if (v_drum && PERCCHAN(chan)) buf[2] = dv;
  972.         else buf[2] = chn_pgm[chan];
  973.         sbwrite(buf);
  974.         cell_chan[cell]=chn_pgm[chan];
  975.     }
  976.     buf[0] = SEQ_FMNOTEON;
  977.     buf[1] = cell;
  978.     buf[2] = pitch;
  979.     buf[3] = vol;
  980.     sbwrite(buf);    
  981. }
  982.  
  983. void fm_noteoff(int chan,int pitch,int vol)
  984. {
  985.     char buf[4];
  986.     int cell,before,last;
  987.     midisync();
  988.  
  989.  
  990.     if (PERCCHAN(chan)) {
  991.            fm_drumoff(pitch, vol);
  992.        return;
  993.     }
  994.  
  995.            cell=0;
  996.     while (cell_chan[cell]!=chn_pgm[chan] || cell_pitch[cell]!=pitch) {
  997.         if (++cell>=num_cells) {
  998.             return;
  999.         }
  1000.     }
  1001.     if (cell_restarted[cell]) {
  1002.         return;
  1003.     }
  1004.     buf[0] = SEQ_FMNOTEOFF;
  1005.     buf[1] = cell;
  1006.     buf[2] = pitch;
  1007.     buf[3] = vol;
  1008.     sbwrite(buf);    
  1009.     if (cell!=cell_pointer) {
  1010.         before=0;
  1011.         while (cell_next[before]!=cell) { 
  1012.             if (++before>=num_cells) {
  1013.                 int nn;
  1014.                 fprintf(stderr,"Can not happen 1\n");
  1015.                 fprintf(stderr,"(cell %d, before %d, ptr %d) {",
  1016.                     cell, before, cell_pointer);
  1017.                 for (nn = 0; nn < num_cells; nn++)
  1018.                 fprintf(stderr," %d",cell_next[nn]);
  1019.                 fprintf(stderr," }\n");
  1020.                 return;
  1021.             }
  1022.         }
  1023.         last=0;
  1024.         while (cell_next[last]!=cell_pointer) { 
  1025.             if (++last>=num_cells) {
  1026.                 fprintf(stderr,"Can not happen 2\n");
  1027.                 return;
  1028.             }
  1029.         }
  1030.         if (last != cell) {
  1031.             cell_next[before]=cell_next[cell];
  1032.             cell_next[last]=cell;
  1033.                    cell_next[cell]=cell_pointer;
  1034.         }
  1035.         cell_pointer=cell;
  1036.         cell_pitch[cell]=-1;
  1037.     }
  1038. }
  1039.  
  1040.  
  1041. void fm_program(int d, int chan,int program)
  1042. {
  1043.     chn_pgm[chan] = program;
  1044. #ifndef K1
  1045. /* K1 can't remember channel programs */
  1046.     if (d) {
  1047.         midich(PROGRAM + d);
  1048.         midich(program);
  1049.         return;
  1050.     }
  1051. #endif
  1052. }
  1053.  
  1054. void midisync(void)
  1055. {
  1056.     unsigned jiffies;
  1057.  
  1058.     static int prevtime = 0;
  1059.     int i;
  1060.  
  1061.     jiffies = time;
  1062.     if (jiffies > prevtime)
  1063.     {
  1064.         prevtime = jiffies; 
  1065.         jiffies = (jiffies << 8) | SEQ_WAIT;
  1066.         sbwrite((char*)&jiffies);
  1067.         for (i=0;i<num_cells;i++) cell_restarted[i]=0;
  1068.     }
  1069. }
  1070.  
  1071. /* if other programs use the SB voices > 127, maybe should use this to
  1072. reload the percussion voices on startup ...
  1073. void load_drums()
  1074. {    int f, n, v;
  1075.     struct sbi_instrument instr;
  1076.     char buf[52];
  1077.  
  1078.     if ((f = open("drums.sb", O_RDONLY, 0)) == -1) {
  1079.         fprintf(stderr,"can't find drums.sb file\n");
  1080.         exit(1);
  1081.     }
  1082.     for (v = 0; v < 16; v++) {
  1083.         if (read(f, buf, 52) != 52) {
  1084.             fprintf(stderr,"short library file\n");
  1085.             exit(1);
  1086.         }
  1087.         instr.channel = v + 128;
  1088.         for (n = 0x24; n < 52; n++) instr.operators[n - 0x24] = buf[n];
  1089.         if (ioctl(sb, SNDCTL_FM_LOAD_INSTR, &instr) == -1) {
  1090.             fprintf(stderr,"can't load instrument %d\n", v);
  1091.             exit(1);
  1092.         }
  1093.     }
  1094. }
  1095. */
  1096.