/* fmsynt plays the fm chip with MIDI messages from MIDI IN */ /* channel 10 goes directly to MIDI out */ #include #include #include #include #include #include extern void init_midi(void); extern void exit_midi(void); extern int get_midibyte(unsigned char * midiinbyte); extern void out_midibyte(unsigned char midioutbyte); const NoteOff1 = 128, NoteOff16 = 143, NoteOn1 = 144, NoteOn16 = 159, PolyPress1 = 160, PolyPress16 = 175, ControlChange1 = 176, ControlChange16 = 191, ProgramChange1 = 192, ProgramChange16 = 207, ChanPress1 = 208, ChanPress16 = 223, PitchWheel1 = 224, PitchWheel16 = 239, SysEx = 240, EOX = 247 ; unsigned char run_status_buf; char channel_on[16]; char default_instr[16] = { 0x021,0x011,0x04C,0x000,0x0F1,0x0F2,0x063,0x072, 0x000,0x000,0x004,0x000,0x000,0x000,0x000,0x000 }; char InstrBuf[128][16]; int numinstr; int notedur; unsigned char old_note,velocity,octave; int note_stopped; long far *ticks; long tick_cntr; main(int argc,char **argv) { unsigned char bMidiByte,note,channel,velocity,program_num; if(init(argc,argv[1])) { while(1) { if (get_midibyte(&bMidiByte)) { /* out_midibyte(bMidiByte); */ if(bMidiByte >= NoteOff1) run_status_buf = bMidiByte; else { channel = run_status_buf & 0xF; if((run_status_buf >= NoteOn1) && (run_status_buf <= NoteOn16)) { while(! get_midibyte(&velocity)); /* out_midibyte(velocity); */ if(channel_on[channel]) fmplay(channel,bMidiByte,velocity); } else { if((run_status_buf >= ProgramChange1) && (run_status_buf <= ProgramChange16)) sbfd_program_change(channel,bMidiByte); } } } if(! note_stopped) if(ticks[0]-tick_cntr > notedur) stop_note(); if(kbhit()) if(! process_key()) break; } sbfd_music_off(); exit_midi(); clrscr(); } } int init(int argc,char *patchfile) { int i,j; if ( ! GetEnvSetting() ) { if (sbc_check_card() & 4) { if (sbc_test_int()) { init_midi(); sbfd_init(); ticks = MK_FP(0,0x46c); note_stopped = 1; velocity = 64; notedur = 20; octave = 5; for(i=0;i<16;i++) channel_on[i] = 1; for(i=0;i<128;i++) for(j=0;j<16;j++) InstrBuf[i][j]=default_instr[j]; if(argc > 1) loadpatches2(patchfile); sbfd_instrument((char far*)InstrBuf); draw_screen(); } else { printf("Error on interrupt.\n"); return(0); } } else { printf("Sound Blaster Card not found or wrong I/O setting.\n") ; return(0); } } else { printf("BLASTER environment variable not set or incomplete or invalid.\n"); return(0); } return(1); } draw_screen() { int i; clrscr(); printf("*** FM MIDI Synth *** \n\n"); printf("Channels enabled/disabled\n"); printf("-------------------------\n\n"); printf("0 1 2 3 4 5 6 7 8 9 A B C D E F\n\n"); for(i=0;i<16;i++) printf("%X ",channel_on[i]); } int process_key() { int scan,modifiers; scan = (bioskey(0) >> 8) & 0xFF; modifiers = bioskey(2); if(scan == 1) return(0); if(modifiers & 8) { switch(scan) { case 45 : setduration();break; /* Alt-X */ case 47 : setveloc();break; /* Alt-V */ case 25 : loadpatch();break; /* Alt-P */ case 38 : loadpatches();break; /* Alt-L */ case 31 : savepatches();break; /* Alt-S */ case 120 : channel_on[1] = channel_on[1] ^ 1; break; case 121 : channel_on[2] = channel_on[2] ^ 1; break; case 122 : channel_on[3] = channel_on[3] ^ 1; break; case 123 : channel_on[4] = channel_on[4] ^ 1; break; case 124 : channel_on[5] = channel_on[5] ^ 1; break; case 125 : channel_on[6] = channel_on[6] ^ 1; break; case 126 : channel_on[7] = channel_on[7] ^ 1; break; case 127 : channel_on[8] = channel_on[8] ^ 1; break; case 128 : channel_on[9] = channel_on[9] ^ 1; break; case 129 : channel_on[0] = channel_on[0] ^ 1; break; case 30 : channel_on[10] = channel_on[10] ^ 1; break; case 48 : channel_on[11] = channel_on[11] ^ 1; break; case 46 : channel_on[12] = channel_on[12] ^ 1; break; case 32 : channel_on[13] = channel_on[13] ^ 1; break; case 18 : channel_on[14] = channel_on[14] ^ 1; break; case 33 : channel_on[15] = channel_on[15] ^ 1; break; } draw_screen(); } else { switch(scan) { case 44 : playnote(0);break; /* z */ case 31 : playnote(1);break; /* s */ case 45 : playnote(2);break; /* x */ case 32 : playnote(3);break; /* d */ case 46 : playnote(4);break; /* c */ case 47 : playnote(5);break; /* v */ case 34 : playnote(6);break; /* g */ case 48 : playnote(7);break; /* b */ case 35 : playnote(8);break; /* h */ case 49 : playnote(9);break; /* n */ case 36 : playnote(10);break; /* j */ case 50 : playnote(11);break; /* m */ case 51 : playnote(12);break; /* , */ case 16 : playnote(12);break; /* q */ case 3 : playnote(13);break; /* 2 */ case 17 : playnote(14);break; /* w */ case 4 : playnote(15);break; /* 3 */ case 18 : playnote(16);break; /* e */ case 19 : playnote(17);break; /* f */ case 6 : playnote(18);break; /* 5 */ case 20 : playnote(19);break; /* t */ case 7 : playnote(20);break; /* 6 */ case 21 : playnote(21);break; /* y */ case 8 : playnote(22);break; /* 7 */ case 22 : playnote(23);break; /* u */ case 23 : playnote(24);break; /* i */ case 78 : if(octave < 7) octave++;break; case 74 : if(octave > 2) octave--;break; } } return(1); } loadpatch() { FILE* f; char patchname[80],patchnumstr[10]; clrscr(); printf("Name of single patch to load: "); gets(patchname); printf("Patch number to load patch into (0-127): "); gets(patchnumstr); if(f=fopen(patchname,"rb")) { fread(&InstrBuf[atoi(patchnumstr)][0],16,1,f); fclose(f); } else { printf("Couldn't find %s!\n",patchname); delay(1000); } draw_screen(); } loadpatches() { char patchsetname[80]; clrscr(); printf("Name of patch set to load: "); gets(patchsetname); loadpatches2(patchsetname); draw_screen(); } loadpatches2(char *patchfile) { FILE* f; int i; if(f = fopen(patchfile,"rb")) { for(i=0;i<128;i++) /* read instruments */ fread(&InstrBuf[i][0],1,16,f); fclose(f); } else { printf("Couldn't find %s!\n",patchfile); delay(1000); } } savepatches() { FILE* f; int i; char patchsetname[80]; clrscr(); printf("Save patch set as: "); gets(patchsetname); f = fopen(patchsetname,"wb"); for(i=0;i<128;i++) fwrite(&InstrBuf[i][0],1,16,f); fclose(f); draw_screen(); } fmplay(unsigned char channel, unsigned char note, unsigned char velocity) { if(velocity != 0) sbfd_note_on(channel,note,velocity); else sbfd_note_off(channel,note,velocity); } setduration() { char notedurstr[10]; printf("\nSet note length (times 55 ms): "); gets(notedurstr); notedur = atoi(notedurstr); } setveloc() { char velocstr[10]; printf("\nSet velocity (0-127): "); gets(velocstr); velocity = atoi(velocstr); } playnote(unsigned char offs) { unsigned char note; if(! note_stopped) stop_note(); note = (octave*12)+offs; out_midibyte(0x90); /* Note On channel 1 */ out_midibyte(note); out_midibyte(velocity); tick_cntr = ticks[0]; old_note = note; note_stopped = 0; } stop_note() { out_midibyte(0x90); /* Note Off */ out_midibyte(old_note); out_midibyte(0); note_stopped = 1; } .