/* Piano version 0.2.2 * * Author : Dave Hindle * Version Date : 01-03-1998 * * Changes since version 0.2.1 (07-11-1999) * - added input filter to ignore background -1s * * Changes since version 0.2 (02-11-1998) * - fixed pitchbend * * Changes since version 0.1 (01-11-1998) * - fixed bug in main control loop which had caused spurious notes * - added error reporting in initialisation function * */ #include #include #include #include #include #ifdef __FreeBSD__ # include # include #elif defined(linux) # include # include #endif #define SEQUENCER_DEV "/dev/sequencer" #define MIDI_DEV "/dev/midi" #define DFLT_BANK 0 #define DFLT_PATCH 0 #define DFLT_BEND 0x2000 /*----------------------------------------------------------------*/ static int seq_init(); static void seq_end(); static void playPrincipal(void); static void playSecondary(int); static int midiValue(void); static int setMod(void); static void setPatch(void); static int setPitch(void); SEQ_DEFINEBUF(512); int awe_dev; int seqfd; static int seq_opened = 0; FILE *midiIn; void seqbuf_dump() { if (_seqbufptr) if (write(seqfd, _seqbuf, _seqbufptr) == -1) { exit(-1); } _seqbufptr = 0; } static int seq_init() { int i; int nrsynths; struct synth_info card_info; if (seq_opened) return 1; if ((seqfd = open(SEQUENCER_DEV, O_WRONLY, 0)) < 0) { fprintf (stderr, "Piano: can't open %s\n", SEQUENCER_DEV); return 0; } if (ioctl(seqfd, SNDCTL_SEQ_NRSYNTHS, &nrsynths) == -1) { fprintf (stderr, "Piano: failed to get number of synth devices\n"); close(seqfd); return 0; } awe_dev = -1; for (i = 0; i < nrsynths; i++) { card_info.device = i; if (ioctl(seqfd, SNDCTL_SYNTH_INFO, &card_info) == -1) { fprintf (stderr, "Piano: failed to read synth info\n"); close(seqfd); return 0; } if (card_info.synth_type == SYNTH_TYPE_SAMPLE && card_info.synth_subtype == SAMPLE_TYPE_AWE32) awe_dev = i; } if (awe_dev < 0) { fprintf (stderr, "Piano: no AWE synth synth found\n"); close(seqfd); return 0; } /* use MIDI channel mode */ AWE_SET_CHANNEL_MODE(awe_dev, AWE_PLAY_MULTI); /* toggle drum flag if bank #128 is received */ AWE_MISC_MODE(awe_dev, AWE_MD_TOGGLE_DRUM_BANK, 1); SEQ_CONTROL(awe_dev, 0, CTL_BANK_SELECT, DFLT_BANK); SEQ_SET_PATCH(awe_dev, 0, DFLT_PATCH); SEQ_BENDER(awe_dev, 0, DFLT_BEND); seq_opened = 1; return 1; } static void seq_end() { if (seq_opened) { close(seqfd); seq_opened = 0; } } static int midiValue () { int value=(int)fgetc(midiIn); while (value == -1) value=(int)fgetc(midiIn); return (value); } static void playSecondary (int note) { int vel=midiValue(); if (vel == 0) { SEQ_STOP_NOTE (awe_dev, 0, note, vel); } else { SEQ_START_NOTE (awe_dev, 0, note, vel); } SEQ_DUMPBUF(); } static void playPrincipal () { playSecondary (midiValue()); } static int setMod () { int test = midiValue(); while (test > 0x00 && test < 0x80) { SEQ_CONTROL (awe_dev, 0, test, midiValue()); SEQ_DUMPBUF(); test = midiValue(); } if (test == CTL_BANK_SELECT) if ((test = midiValue()) == 0) if ((test = midiValue()) == 32) if ((test = midiValue()) == 0) test = midiValue(); return (test); } static void setPatch () { SEQ_SET_PATCH (awe_dev, 0, midiValue()); SEQ_DUMPBUF(); } static int setPitch () { int test = midiValue(); int seq_bend; while (test == 0 || test == 127) { seq_bend = midiValue()*129; SEQ_BENDER (awe_dev, 0, seq_bend); SEQ_DUMPBUF(); test = midiValue(); } return (test); } void main(int argc, char *argv []) { int signal; int signal2; int stop = 0; if (!seq_init()) exit(0); midiIn = fopen (MIDI_DEV, "r"); while (!stop) { signal = midiValue (); signal2 = -1; while (signal != signal2) { switch (signal) { case MIDI_NOTEON : playPrincipal(); break; case MIDI_CTL_CHANGE : signal2 = setMod (); break; case MIDI_PGM_CHANGE : setPatch(); break; case MIDI_PITCH_BEND : signal2 = setPitch(); break; case 0 : stop = 1; break; default : playSecondary(signal); break; } signal = signal2; signal2 = -1; } } seq_end(); }