home *** CD-ROM | disk | FTP | other *** search
/ Millennium Time Capsule / AC2000.BIN / disks / ac11disk / midiseq / midiseq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-06-10  |  3.1 KB  |  132 lines

  1. /*
  2.  *    Atari Computing MIDI programming in C tutorial
  3.  *    ©1998 by Danny McAleer
  4.  *    this code is freeware - use and tamper with as you please!
  5.  *    
  6.  *    With any luck, this progrma will illustrate how easy it is
  7.  *    to write a simple monophonic MIDI sequencer, and also the
  8.  *    ease in which note data can be manipulated!
  9.  *
  10.  *
  11.  *    compiled and written using Lattice C
  12.  *    
  13.  *    file     : MIDISEQ.C
  14.  *    routines : event loop, start-up code, and MIDI input analyser    
  15.  *
  16.  */
  17.  
  18. #include "globals.h"
  19.  
  20. TRACK trk;
  21.  
  22. void main(void)
  23. {
  24.     setup_parameters();
  25.     draw_menu();
  26.     evnt_loop();
  27.     all_notes_off();
  28.     exit(1);
  29. }
  30.  
  31. void setup_parameters(void)
  32. {
  33.     trk.tempo        = 120;
  34.     trk.playmode     = 1;
  35.     trk.transpose    = 0;
  36.     trk.channel        = 0;
  37.     trk.patch         = 0;
  38. }
  39.  
  40. void evnt_loop(void)
  41. {
  42.     BYTE             m, n_off=0;
  43.     char            k;
  44.     unsigned long    timer = clock_timer();
  45.     unsigned long    step;
  46.     int                ctr = 0;
  47.  
  48.     while(1)
  49.     {
  50.         /*
  51.          *    first check for any input from the Atari keyboard
  52.          */
  53.         if(poll_kbd()!=0){
  54.             k = check_kbd();
  55.             if(!keybd_input(k, ctr))    break;
  56.         }
  57.         /*
  58.          *    next, check the MIDI ports, and if something's there, 
  59.          *    and it's not active sensing ($fe), go see if it's a note...
  60.          */
  61.         if(poll_midi()!=0){
  62.             m = midi_in();
  63.             if(m!=0xfe)
  64.                 process_midi_msg(m, ctr);
  65.         }
  66.  
  67.  
  68.         /* calculate 'step rate' based on tempo and system clock */
  69.         step = (200.0 / ((float)trk.tempo/60.0)) / 4.0;
  70.  
  71.         /* 
  72.           *    the sequencer will only play if bit '0' of the 
  73.          *    playmode variable is set to 0 (or OFF), since in the
  74.          *    sequencer this is play mode off!
  75.           */
  76.         if((trk.playmode&0x01)==OFF)
  77.         {    
  78.             /* if time has passed, play the next note... */
  79.             if((timer + step) <= clock_timer())
  80.             {
  81.                 if(n_off!=0)    note_off(trk.channel, n_off);
  82.  
  83.                 /* 
  84.                  *    if there's a valid note value (greater than 0)
  85.                  *    play the note, then copy it with transposition
  86.                  *    to the note off variable (so next time around
  87.                  *    we can switch it off, even if the value in the 
  88.                  *    array has been over-written...
  89.                  */
  90.                 if(trk.note[ctr] > 0){
  91.                     note_on(trk.channel, trk.note[ctr]+trk.transpose, trk.vel[ctr]);
  92.                     n_off = trk.note[ctr] + trk.transpose;
  93.                 }
  94.                 /* delete existing cursor...    */
  95.                 move_cursor(13, ctr*4 + 4);    
  96.                 printf(" ");
  97.                 if(trk.playmode==0x04){ if(--ctr<0)    ctr=7;    }
  98.                 else if(trk.playmode==0x02){     if(++ctr>7)    ctr=0;    }
  99.                 else ctr = rand()%8;
  100.                 /* ...and redraw it in the new position! */
  101.                 move_cursor(13, ctr*4 + 4);    
  102.                 printf("^");
  103.                 /* re-sample the system clock once a note has been played */
  104.                 timer = clock_timer();
  105.             }
  106.         }
  107.     }
  108. }
  109.  
  110.  
  111. int process_midi_msg(BYTE m, int ctr)
  112. {
  113.     BYTE msg[2];
  114.  
  115.     /* if it's not a note-on, ignore it! */
  116.     if(m!=0x90+trk.channel)    return 0;
  117.     
  118.     msg[0] = midi_in();
  119.     msg[1] = midi_in();
  120.     /* 
  121.      *    a note on with a velocity value of 0
  122.      *    is also a note off, so we don't want these either...
  123.      */
  124.     if(!msg[1])    return 0;
  125.  
  126.     trk.note[ctr] = msg[0];
  127.     trk.vel[ctr]  = msg[1];
  128.     /* print new MIDI note to sequencer position on screen */
  129.     move_cursor(12, ctr*4 + 1);
  130.     printf(" %3d ", trk.note[ctr]);
  131.     return 1;
  132. }