/* -*- mode: C; compile-command: "cc drumseq.c -odrumseq"; -*-  */


/* Simple test of /dev/sequencer, plays four drum patterns
  in a loop */


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/soundcard.h>


#define NUM_INSTR 9
#define CHN 10

#define BDRM  35
#define SDRM  40
#define CLHH  44
#define OPHH  46
#define HTOM  48
#define MTOM  45
#define LTOM  41
#define CLPS  39
#define CRSH  49


char midibyte,vel,channel;
int seqfd,i,j;

int note_on (char c, char n, char v);
int note_off (char c, char n);


char pattern[4][16*NUM_INSTR];

SEQ_DEFINEBUF(4096);

main(int argc, char **argv)
{
       FILE *patf;
       int buf_offs, dtime, bytesread, curpat = 0, pat, playpat[4], beat;
       char sbuf[81];

       if(argc != 2) {
               printf("usage: drumseq <delta time>\n\n");
               exit(1);
       }

       dtime = atoi(argv[1]);

       channel = 10;
       vel = 127;

       if((patf = fopen("patterns","r")) == NULL) {
               printf("Error opening pattern file!\n");
               exit(1);
       }

       beat = 0;
       pat = 0;
       buf_offs = 0;

       fgets(sbuf,80,patf);
       playpat[0] = sbuf[0]-0x30-1;
       playpat[1] = sbuf[1]-0x30-1;
       playpat[2] = sbuf[2]-0x30-1;
       playpat[3] = sbuf[3]-0x30-1;

       while( fgets(sbuf,80,patf)) {
               if((sbuf[0] != '#') && (strlen(sbuf) > 7)) {
                       for(i = 0; i < 9; i++)
                               pattern[pat][buf_offs++] = sbuf[i]-0x30;

                       beat++;
                       if(beat == 16) {
                               pat++;
                               buf_offs = 0;
                               beat = 0;
                       }
               }
       }
       fclose(patf);

       if ((seqfd = open ("/dev/sequencer",O_WRONLY))== -1 ) {
               printf("Error opening MIDI sequencer device!\n");
               exit(1);
       }

       printf ("Playing...\n");

       SEQ_START_TIMER();

       curpat = 0;
       buf_offs = 0;

       while(1) {
               for(beat=0; beat<16; beat++) {
                       buf_offs = beat * 9;

                       if(pattern[playpat[curpat]][buf_offs])
                               note_on(CHN, BDRM, 127);
                       if(pattern[playpat[curpat]][buf_offs+1])
                               note_on(CHN, SDRM, 127);
                       if(pattern[playpat[curpat]][buf_offs+2])
                               note_on(CHN, CLHH, 127);
                       if(pattern[playpat[curpat]][buf_offs+3])
                               note_on(CHN, OPHH, 127);
                       if(pattern[playpat[curpat]][buf_offs+4])
                               note_on(CHN, HTOM, 127);
                       if(pattern[playpat[curpat]][buf_offs+5])
                               note_on(CHN, MTOM, 127);
                       if(pattern[playpat[curpat]][buf_offs+6])
                               note_on(CHN, LTOM, 127);
                       if(pattern[playpat[curpat]][buf_offs+7])
                               note_on(CHN, CLPS, 127);
                       if(pattern[playpat[curpat]][buf_offs+8])
                               note_on(CHN, CRSH, 127);

                       SEQ_DELTA_TIME(dtime);
               }

               curpat++;
               if(curpat == 4)
                       curpat = 0;
       }

       SEQ_DUMPBUF();
       close(seqfd);
}


void
seqbuf_dump(void)
{
       if(_seqbufptr)
               if( write(seqfd, _seqbuf, _seqbufptr) == -1) {
                       perror("write /dev/sequencer");
                       exit (-1);
               }

       _seqbufptr = 0;
}


note_on(char c, char n, char v)
{
       SEQ_MIDIOUT(0, 0x90 + c - 1);
       SEQ_MIDIOUT(0, n);
       SEQ_MIDIOUT(0, v);
}

note_off(char c, char n)
{
       SEQ_MIDIOUT(0, 0x90 + c - 1);
       SEQ_MIDIOUT(0, n);
       SEQ_MIDIOUT(0, 0);
}