/* -*- mode: C; compile-command: "cc fmtest.c -ofmtest"; -*-  */


/* Simple test of /dev/music */


#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 0

#define NOTE_C  0
#define NOTE_CISS 1
#define NOTE_D  2
#define NOTE_DISS 3
#define NOTE_E  4
#define NOTE_F  5
#define NOTE_FISS 6
#define NOTE_G  7
#define NOTE_GISS 8
#define NOTE_A  9
#define NOTE_B  10
#define NOTE_H  11
#define NOTE_C1 12

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

int sb_noteon(char c, char n, char v);
int sb_noteoff(char c, char n);
int midi_noteon (char c, char n, char v);
int midi_noteoff (char c, char n);


char pattern[4][16*NUM_INSTR];
char octave[4];


struct sbi_instrument inst;


SEQ_DEFINEBUF(4096);

main(int argc, char **argv)
{
       FILE *patf;
       int dtime, tempo, ctrlrate, timebase, instrument[4], dummy, nrsynths;
       char instfile[80];

       strcpy(instfile,argv[1]);
       instrument[0] = atoi(argv[2]);
       instrument[1] = atoi(argv[3]);
       instrument[2] = atoi(argv[4]);
       instrument[3] = atoi(argv[5]);
       dtime = atoi(argv[6]);


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

/* ioctl(seqfd,SNDCTL_FM_4OP_ENABLE,&dummy); */

       sbfd = open(instfile,O_RDONLY);

       for(i=0; i<128; i++) {
               inst.key = FM_PATCH;
/*    inst.key = OPL3_PATCH; */
               inst.device = 0;
               inst.channel = i;
               lseek(sbfd,(off_t)(52*i+36),SEEK_SET);
/*    lseek(sbfd,(off_t)(60*i+36),SEEK_SET); */
               read(sbfd,inst.operators,11);
/*    read(sbfd,inst.operators,22); */
               SEQ_WRPATCH(&inst, sizeof(inst));
       }
       close(sbfd);

       SEQ_SET_PATCH(0,0,instrument[0]);
       SEQ_SET_PATCH(0,1,instrument[1]);
       SEQ_SET_PATCH(0,2,instrument[2]);
       SEQ_SET_PATCH(0,3,instrument[3]);

       octave[0] = 3;
       octave[1] = 6;
       octave[2] = 6;
       octave[3] = 6;

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

       tempo = 120;
       ioctl(seqfd, SNDCTL_TMR_TEMPO, &tempo);
       printf("Tempo: %d\n", tempo);
/*
       timebase = 768;
       ioctl(seqfd, SNDCTL_TMR_TIMEBASE, &timebase);
       printf("Timebase: %d\n", timebase);

       ctrlrate = 0;
       ioctl(seqfd, SNDCTL_SEQ_CTRLRATE, &ctrlrate);
       printf("Ctrl rate: %d\n", ctrlrate);
*/

       SEQ_START_TIMER();

       while(1) {
               sb_noteon(0, NOTE_C, 127);
               sb_noteon(1, NOTE_C, 127);
               sb_noteon(1, NOTE_DISS, 127);
               sb_noteon(1, NOTE_G, 127);
               midi_noteon(9, 44, 127);
               midi_noteon(9, 35, 127);
               SEQ_DELTA_TIME(dtime);


               sb_noteoff(0, NOTE_C);
               SEQ_DELTA_TIME(dtime);


               sb_noteon(0,NOTE_C,80);
               midi_noteon(9,44,127);
               SEQ_DELTA_TIME(dtime);


               sb_noteoff(0,NOTE_C);
               SEQ_DELTA_TIME(dtime);


               sb_noteon(0,NOTE_DISS,127);
               midi_noteon(9,40,127);
               midi_noteon(9,44,127);
               SEQ_DELTA_TIME(dtime);


               sb_noteoff(0,NOTE_DISS);
               SEQ_DELTA_TIME(dtime);



               sb_noteon(0,NOTE_DISS,80);
               midi_noteon(9,44,127);
               SEQ_DELTA_TIME(dtime);




               sb_noteoff(0,NOTE_DISS);
               SEQ_DELTA_TIME(dtime);



               sb_noteon(0,NOTE_F,127);
               midi_noteon(9,35,127);
               midi_noteon(9,44,127);
               SEQ_DELTA_TIME(dtime);


               sb_noteoff(0,NOTE_F);
               SEQ_DELTA_TIME(dtime);


               sb_noteon(0,NOTE_F,80);
               midi_noteon(9,44,127);
               SEQ_DELTA_TIME(dtime);


               sb_noteoff(0,NOTE_F);
               SEQ_DELTA_TIME(dtime);


               sb_noteon(0,NOTE_G,127);
               midi_noteon(9,40,127);
               midi_noteon(9,44,127);
               SEQ_DELTA_TIME(dtime);


               sb_noteoff(0,NOTE_G);
               SEQ_DELTA_TIME(dtime);


               sb_noteon(0,NOTE_G,80);
               midi_noteon(9,46,127);
               SEQ_DELTA_TIME(dtime);


               sb_noteoff(0,NOTE_G);
               SEQ_DELTA_TIME(dtime);


       }

       SEQ_DUMPBUF();
       close(seqfd);
}


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

       _seqbufptr = 0;
}


sb_noteon(char c, char n, char v)
{
       SEQ_START_NOTE(0, c, (12*octave[c])+n, v);
}

sb_noteoff(char c, char n)
{
       SEQ_START_NOTE(0, c, (12*octave[c])+n, 0);
}

midi_noteon(char c, char n, char v)
{
       SEQ_START_NOTE(1, c, n, v);
}

midi_noteoff(char c, char n)
{
       SEQ_START_NOTE(1, c-1, n, 0);
}