2000 /* FMMOD FM MIDI Sound Module, plays the fm chip with MIDI messages from MIDI IN */ /* With Built-in editor */ /* Last revision: 941017 */ #include #include #include #include #include #include #include #include #include #include #define SbProID 100 #define KeyUp 0x80 int edpatch; int opr; int Loaded_before; char curr_cmf[80]; char cmfname[80]; unsigned char out_cnvrt(int i,int param); unsigned char in_runstatus,out_runstatus; 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; unsigned char old_note,velocity,octave,program; int editmode; int playmode; main(int argc,char **argv) { unsigned char midibyte,note,velocity,channel,program; long midiin; int event_flags; if(init(argc,argv[1])) { while(1) { if (midiin=sbmidi_get()) { midibyte=(unsigned char)midiin; if(midibyte >= NoteOff1) { if(midibyte == SysEx) sysex_rcv(); else if(midibyte <= EOX) /* Ignore System Realtime Msgs */ in_runstatus = midibyte; } else { channel = in_runstatus & 0xF; if((in_runstatus >= NoteOn1) && (in_runstatus <= NoteOn16)) { do while(!(midiin=sbmidi_get())); while((velocity=(unsigned char)midiin) > 127); /* Ignore Non-Data msgs */ if(channel_on[channel]) fmplay(channel,midibyte,velocity); } else if((in_runstatus >= ProgramChange1) && (in_runstatus <= ProgramChange16)) { program = midibyte; sbfd_program_change(channel,program); } } } if(playmode) process_playkey(); else if(kbhit()) process_key(); } } } int init(int argc,char *argstr) { int i,j; FILE* f; /* if(argc > 0) { */ if ( ! GetEnvSetting() ) { if (sbc_check_card() & 4) { if (sbc_test_int()) { sbfd_init(); sbfd_setmode(1); sbfd_program_change(15,15); sbmidi_init(ct_int_num); velocity = 64; octave = 5; program = 0; editmode = 0; playmode = 0; edpatch = 0; 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(f=fopen("fmmod.cfg","rb")) get_config_settings(f); if(f=fopen("default.set","rb")) { fclose(f); loadpatches2("default.set"); } 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); /* } else { printf("FMMOD FM MIDI Sound Module v1.0\n"); printf("usage: fmmod \n"); return(0); } */ } quit() { int k; gotoxy(1,22); printf("Do you really want to quit (Y\\n)?"); k = 0; while(1) if(kbhit()) break; if(kbhit()) k = (bioskey(0) >> 8) & 0xff; if( k == 28 || k == 21 ) { sbmidi_exit(); sbfd_music_off(); sbfd_reset(); showcur(); clrscr(); exit(0); } draw_screen(); } get_config_settings(FILE* cfgf) { fread(&channel_on[0],1,16,cfgf); fread(&velocity,1,1,cfgf); fclose(cfgf); } save_config_settings() { FILE* cfgf; cfgf = fopen("fmmod.cfg","wb"); fwrite(&channel_on[0],1,16,cfgf); fwrite(&velocity,1,1,cfgf); fclose(cfgf); } draw_screen() { int i; clrscr(); printf("*** FM MIDI Sound Module v1.0 *** Current Program: %-3u\n\n",program); printf("Alt-V Set Velocity Alt-O All notes off Alt-Y FM Editor Alt-Z List Files\n\n"); printf("Alt-P Load Patch Alt-L Load 128-patch set Alt-S Save 128-patch set\n\n"); printf("Alt-W Save Settings Alt-U SysEx Xmit\n\n"); printf("P Play Keyboard Quit\n\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]); } process_key() { int scan,modifiers; scan = (bioskey(0) >> 8) & 0xFF; modifiers = bioskey(2); if(modifiers & 8) { switch(scan) { case 47 : setveloc();break; /* Alt-V */ case 24 : all_notes_off();break; /* Alt-O */ case 25 : loadpatch();break; /* Alt-P */ case 38 : loadpatches();break; /* Alt-L */ case 31 : savepatches();break; /* Alt-S */ case 44 : listfiles();break; /* Alt-Z */ case 17 : save_config_settings();break; /* Alt-W */ case 21 : fm_edit();break; /* Alt-Y */ case 22 : sysex_xmit();break; /* Alt-U */ 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 25 : goto_playmode(); break; case 1 : quit(); } } } unsigned char old_key,old_release; process_playkey() { unsigned char key; key=get_mkbrk_code(); if(key != old_key) { if(key >= KeyUp) { if((key-0x80) == old_key) { stop_note(); old_key = key; } } else { if(old_key < KeyUp) stop_note(); switch(key) { 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; case 73 : change_program(key,0); break; case 81 : change_program(key,0);break; /* PgDwn */ case 1 : exit_playmode(); } old_key = key; } } } goto_pla 2000 ymode() { init_mkbrk(); playmode = 1; gotoxy(1,22); printf("Keyboard Play mode"); } exit_playmode() { while(get_mkbrk_code() != 0x81); exit_mkbrk(); playmode = 0; gotoxy(1,22); printf(" "); } loadpatch() { FILE* f; char patchname[80],patchnumstr[10]; clrscr(); showcur(); printf("Name of single patch to load: "); gets(patchname); if (strlen(patchname) != 0) { 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); sbfd_program_change(0,atoi(patchnumstr)); } else { printf("Couldn't find %s!\n",patchname); delay(1000); } } if(editmode) draw_editscreen(); else draw_screen(); } loadpatches() { char patchsetname[80]; clrscr(); showcur(); printf("Name of patch set to load: "); gets(patchsetname); loadpatches2(patchsetname); if(editmode) draw_editscreen(); else 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(); showcur(); 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); if(editmode) draw_editscreen(); else draw_screen(); } listfiles() { struct ffblk ffblk; int done; clrscr(); system("dir /w /p /on"); printf("\nPress any key to return to FMMOD...\n"); getch(); if(editmode) draw_editscreen(); else 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); } setveloc() { char velocstr[10]; showcur(); gotoxy(1,22); printf("\nSet velocity (0-127): "); gets(velocstr); velocity = atoi(velocstr); hidecur(); } all_notes_off() { sbfd_music_off(); } playnote(unsigned char offs) { unsigned char note; note = (octave*12)+offs; if(out_runstatus != 0x90) { out_runstatus = 0x90; sbmidi_put(0x90); /* Note On channel 1 */ } sbmidi_put(note); sbmidi_put(velocity); old_note = note; } stop_note() { if(out_runstatus != 0x90) { out_runstatus = 0x90; sbmidi_put(0x90); } sbmidi_put(old_note); sbmidi_put(0); } change_program(int scan,int button) { if(! button) { switch(scan){ case 73 : { if(program < 127) program++; }break; case 81 : { if(program > 0) program--; }break; } gotoxy(65,1);printf("%-3u",program); gotoxy(65,1); } else { /* switch(button){ case 1 : chg_while_pressed(1,0,&program,65,1,"%-3u"); break; case 2 : chg_while_pressed(2,127,&program,65,1,"%-3u"); } */ } if(out_runstatus != ProgramChange1) { out_runstatus = ProgramChange1; sbmidi_put(ProgramChange1); } sbmidi_put(program); } sysex_rcv() { unsigned char param,val; int i,j,offs; long midiin; unsigned int size,segp; unsigned char sysdata[6700],sysexbyte; offs=0; while(1) { if(midiin=sbmidi_get()) { sysexbyte=(unsigned char)midiin; sysdata[offs++]=sysexbyte; } if(sysexbyte == EOX) break; } offs=0; gotoxy(1,22); if(sysdata[offs++] == SbProID) /* Check for SBPro ID */ { switch(sysdata[offs++]){ /* get mode */ case 0 : /* All patches */ { for(i=0;i<128;i++) { for(j=0;j<26;j++) { param=sysdata[offs++]; val=sysdata[offs++]; setFMparam(i,param,val); } } } break; case 1 : /* single patch */ { for(i=0;i<26;i++) { param=sysdata[offs++]; val=sysdata[offs++]; setFMparam(program,param,val); } sbfd_program_change(0,0); } break; case 2 : /* Single parameter */ { param=sysdata[offs++]; val=sysdata[offs++]; setFMparam(program,param,val); sbfd_program_change(0,0); } } if(sysdata[offs] != EOX){ printf("\nError on SysEx receive!\n"); delay(1000); draw_screen(); } } else { printf("\nError: not SbPro ID!\n"); delay(1000); draw_screen(); } } sysex_xmit() { int scan,i,j; char patchstr[20]; int patch; clrscr(); showcur(); printf("Dump All or Single patch? (A/S)"); do scan=(bioskey(0) >> 8) & 0xff; while( (scan != 30) && (scan != 31) ); sbmidi_put(SysEx); sbmidi_put(SbProID); /* SbPro ID */ switch(scan){ case 30 : /* All */ { sbmidi_put(0); for(i=0;i<128;i++) for(j=0;j<26;j++) { sbmidi_put(j); sbmidi_put(out_cnvrt(i,j)); } }break; case 31 : /* Single patch */ { printf("\nSelect patch to dump (0-127): "); gets(patchstr); patch = atoi(patchstr); sbmidi_put(1); for(i=0;i<26;i++) { sbmidi_put(i); sbmidi_put(out_cnvrt(patch,i)); } } } sbmidi_put(EOX); printf("\n\nTransmission completed.\n"); delay(1000); draw_screen(); } unsigned char out_cnvrt(int i,int param) { unsigned char temp,outval; switch(param){ case 0 : outval = (InstrBuf[i][0] & 128) >> 7; break; case 1 : outval = (InstrBuf[i][0] & 64) >> 6; break; case 2 : outval = (InstrBuf[i][0] & 32) >> 5; break; case 3 : outval = (InstrBuf[i][0] & 16) >> 4; break; case 4 : outval = InstrBuf[i][0] & 0x0F; break; case 5 : outval = (InstrBuf[i][1] & 128) >> 7; break; case 6 : outval = (InstrBuf[i][1] & 64) >> 6; break; case 7 : outval = (InstrBuf[i][1] & 32) >> 5; break; case 8 : outval = (InstrBuf[i][1] & 16) >> 4; break; case 9 : outval = InstrBuf[i][1] & 0x0F; break; case 10 : { temp = InstrBuf[i][2] & 0xC0; switch(temp){ case 0 : temp = 0;break; case 0x80 : temp = 1;break; case 0x40 : temp = 2;break; case 0xC0 : temp = 3; } outval = temp; } break; case 11 : outval = InstrBuf[i][2] & 0x3F; break; case 12 : { temp = InstrBuf[i][3] & 0xC0; switch(temp){ case 0 : temp = 0;break; case 0x80 : temp = 1;break; case 0x40 : temp = 2;break; case 0xC0 : temp = 3; } outval = temp; }break; case 13 : outval = InstrBuf[i][3] & 0x3F; break; case 14 : outval = (InstrBuf[i][4] & 0xF0) >> 4; break; case 15 : outval = (InstrBuf[i][4] & 0x0F); break; case 16 : outval = (InstrBuf[i][5] & 0xF0) >> 4; break; case 17 : outval = (InstrBuf[i][5] & 0x0F); break; case 18 : outval = (InstrBuf[i][6] & 0xF0) >> 4; break; case 19 : outval = InstrBuf[edpatch][6] & 0x0F; break; case 20 : outval = (InstrBuf[i][7] & 0xF0) >> 4; break; case 21 : outval = InstrBuf[edpatch][7] & 0x0F; break; case 22 : outval = InstrBuf[i][8]; break; case 23 : outval = InstrBuf[i][9]; break; case 24 : outval = (InstrBuf[i][10] & 0xE) >> 1; break; case 25 : outval = InstrBuf[i][10] & 1; break; } return(outval); } /* chg_while_pressed(int button,unsigned char limit,unsigned char *chgvar,int x,int y,char *format) { if(button == 1) { if((*chgvar) > limit) (*chgvar)--; gotoxy(x,y);printf(format,*chgvar); gotoxy(x,y); delay(250); while(get_button_status() == button) { if((*chgvar) > limit) { (*chgvar)--; gotoxy(x,y);printf(format,*chgvar); gotoxy(x,y); delay(35); } } } else { if((*chgvar) < limit) (*chgvar)++; gotoxy(x,y);printf(format,*chgvar); gotoxy(x,y); delay(250); 2000 while(get_button_status() == button) { if((*chgvar) < limit) { (*chgvar)++; gotoxy(x,y);printf(format,*chgvar); gotoxy(x,y); delay(35); } } } } */ /*********************************************************************/ /************************* FM editor functions ********************/ /*********************************************************************/ unsigned char undo_buf[16],compare_buf[16]; int compare; void ReadVal(int *v, int llim, int ulim, int len, int x, int y) { char str[80]; str[0] = len+1; do{ while (! kbhit()); if((bioskey(1) & 0xFF) == 13) break; gotoxy(x,y); printf(" "); gotoxy(x,y); *v = atoi(gets(str)); gotoxy(x,y); printf(" "); gotoxy(x,y); } while((*v < llim) || (*v > ulim)); } Edit_Play() { unsigned char key; init_mkbrk(); gotoxy(65,1); printf("PLAY MODE "); do { key=get_mkbrk_code(); if(key != old_key) { if(key >= KeyUp) { if((key-0x80) == old_key) { edit_stopnote(); old_key = key; } } else { if(old_key < KeyUp) edit_stopnote(); switch(key) { case 44 : edit_playnote(0);break; /* z */ case 31 : edit_playnote(1);break; /* s */ case 45 : edit_playnote(2);break; /* x */ case 32 : edit_playnote(3);break; /* d */ case 46 : edit_playnote(4);break; /* c */ case 47 : edit_playnote(5);break; /* v */ case 34 : edit_playnote(6);break; /* g */ case 48 : edit_playnote(7);break; /* b */ case 35 : edit_playnote(8);break; /* h */ case 49 : edit_playnote(9);break; /* n */ case 36 : edit_playnote(10);break; /* j */ case 50 : edit_playnote(11);break; /* m */ case 51 : edit_playnote(12);break; /* , */ case 16 : edit_playnote(12);break; /* q */ case 3 : edit_playnote(13);break; /* 2 */ case 17 : edit_playnote(14);break; /* w */ case 4 : edit_playnote(15);break; /* 3 */ case 18 : edit_playnote(16);break; /* e */ case 19 : edit_playnote(17);break; /* f */ case 6 : edit_playnote(18);break; /* 5 */ case 20 : edit_playnote(19);break; /* t */ case 7 : edit_playnote(20);break; /* 6 */ case 21 : edit_playnote(21);break; /* y */ case 8 : edit_playnote(22);break; /* 7 */ case 22 : edit_playnote(23);break; /* u */ case 23 : edit_playnote(24);break; /* i */ case 78 : if(octave < 7) octave++; break; case 74 : if(octave > 2) octave--; break; } old_key = key; } } } while( key != 1 ); while(get_mkbrk_code() != 0x81); exit_mkbrk(); sbfd_note_off(0,old_note,0); gotoxy(65,1);printf(" "); } edit_playnote(int offs) { unsigned char note; note = (octave*12)+offs; sbfd_note_on(0,note,127); old_note = note; } edit_stopnote() { sbfd_note_off(0,old_note,0); } void modop_msg(int x, int y) { int k; k = 0; gotoxy(x,y); printf("1: Modulator 2: Carrier: "); ReadVal(&k,1,2,1,x+25,y); gotoxy(x,y); printf(" "); opr = (char)k; } void AM() { int k; showcur(); modop_msg(25,6); k = 0; gotoxy(25,6); printf("(1) On (0) Off: "); printf("%d",(InstrBuf[edpatch][opr-1] & 128) >> 7); ReadVal(&k,0,1,1,41,6); gotoxy(25,6); printf(" "); switch(opr){ case 1: setFMparam(edpatch,0,k);break; case 2: setFMparam(edpatch,5,k); } sbfd_program_change(0,edpatch); } void Vib() { int k; showcur(); modop_msg(25,7); k = 0; gotoxy(25,7); printf("(1) On (0) Off: "); printf("%d",(InstrBuf[edpatch][opr-1] & 64) >> 6); ReadVal(&k,0,1,1,41,7); gotoxy(25,7); printf(" "); switch(opr){ case 1: setFMparam(edpatch,1,k); break; case 2: setFMparam(edpatch,6,k); } sbfd_program_change(0,edpatch); } void EG() { int k; showcur(); modop_msg(25,8); k = 0; gotoxy(25,8); printf("(1) Continuing (0) Diminishing: "); printf("%d",(InstrBuf[edpatch][opr-1] & 32) >> 5); ReadVal(&k,0,1,1,57,8); gotoxy(25,8); printf(" "); switch(opr){ case 1: setFMparam(edpatch,2,k); break; case 2: setFMparam(edpatch,7,k); } sbfd_program_change(0,edpatch); } void KSR() { int k; showcur(); modop_msg(25,9); k = 0; gotoxy(25,9); printf("(1) On (0) Off: "); printf("%d",(InstrBuf[edpatch][opr-1] & 16) >> 4); ReadVal(&k,0,1,1,41,9); gotoxy(25,9); printf(" "); switch(opr){ case 1: setFMparam(edpatch,3,k); break; case 2: setFMparam(edpatch,8,k); } sbfd_program_change(0,edpatch); } void Multiple() { int val; showcur(); modop_msg(25,10); showcur(); gotoxy(25,10); printf("Multiple (0-15): "); printf("%d",InstrBuf[edpatch][opr-1] & 0x0F); ReadVal(&val,0,15,2,42,10); gotoxy(25,10); printf(" "); switch(opr){ case 1 : setFMparam(edpatch,4,val); break; case 2 : setFMparam(edpatch,9,val); } sbfd_program_change(0,edpatch); } void KSL() { int val; int temp; showcur(); modop_msg(25,11); showcur(); gotoxy(25,11); printf("KSL value (0-3): "); temp = InstrBuf[edpatch][2+(opr-1)] & 0xC0; switch(temp){ case 0 : printf("%d",0);break; case 0x80 : printf("%d",1);break; case 0x40 : printf("%d",2);break; case 0xC0 : printf("%d",3); } ReadVal(&val,0,3,1,42,11); gotoxy(25,11); printf(" "); switch(opr){ case 1: setFMparam(edpatch,10,val); break; case 2: setFMparam(edpatch,12,val); } sbfd_program_change(0,edpatch); } void TotLev() { int val; showcur(); modop_msg(25,12); showcur(); gotoxy(25,12); printf("Total Level (0-63): "); printf("%d", InstrBuf[edpatch][2+(opr-1)] & 0x3F); ReadVal(&val,0,63,2,45,12); gotoxy(25,12); printf(" "); switch(opr){ case 1 : setFMparam(edpatch,11,val); break; case 2 : setFMparam(edpatch,13,val); } sbfd_program_change(0,edpatch); } void Attack() { int val; showcur(); modop_msg(25,13); showcur(); gotoxy(25,13); printf("Attack (0-15): "); printf("%d",(InstrBuf[edpatch][4+(opr-1)] & 0xF0) >> 4); ReadVal(&val,0,15,2,40,13); gotoxy(25,13); printf(" "); switch(opr){ case 1 : setFMparam(edpatch,14,val); break; case 2 : setFMparam(edpatch,16,val); } sbfd_program_change(0,edpatch); } void Decay() { int val; showcur(); modop_msg(25,14); showcur(); gotoxy(25,14); printf("Decay (0-15): "); printf("%d", InstrBuf[edpatch][4+(opr-1)] & 0x0F); ReadVal(&val,0,15,2,39,14); gotoxy(25,14); printf(" "); switch(opr){ case 1 : setFMparam(edpatch,15,val); break; case 2 : setFMparam(edpatch,17,val); } sbfd_program_change(0,edpatch); } void Sustain() { int val; showcur(); modop_msg(25,15); showcur(); gotoxy(25,15); printf("Sustain Level (0-15): "); printf("%d",(InstrBuf[edpatch][6+(opr-1)] & 0xF0) >> 4); ReadVal(&val,0,15,2,47,15); gotoxy(25,15); printf(" "); switch(opr){ case 1 : setFMparam(edpatch,18,val); break; case 2 : setFMparam(edpatch,20,val); } sbfd_program_change(0,edpatch); } void Release() { int val; showcur(); modop_msg(25,16); showcur(); gotoxy(25,16); printf("Release (0-15): "); printf("%d", InstrBuf[edpatch][6+(opr-1)] & 0x0F); ReadVal(&val,0,15,2,41,16); gotoxy(25,16); printf(" "); switch(opr){ case 1: setFMparam(edpatch,19,val); break; case 2: setFMparam(edpatch,21,val); } sbfd_program_ch 2000 ange(0,edpatch); } void Wave() { int val; showcur(); modop_msg(25,17); val = 0; gotoxy(25,17); printf("Wave (0-4): "); printf("%d", InstrBuf[edpatch][8+(opr-1)]); ReadVal(&val,0,4,1,37,17); gotoxy(25,17); printf(" "); switch(opr){ case 1 : setFMparam(edpatch,22,val);break; case 2 : setFMparam(edpatch,23,val); } sbfd_program_change(0,edpatch); } void Feedback() { int val; val = 0; showcur(); gotoxy(25,18); printf("Feedback (0-7): "); printf("%d",(InstrBuf[edpatch][10] & 0xE) >> 1); ReadVal(&val,0,7,1,41,18); gotoxy(25,18); printf(" "); setFMparam(edpatch,24,val); sbfd_program_change(0,edpatch); } void Connection() { int val; showcur(); val = 0; gotoxy(25,19); printf("Connection (0,1): "); printf("%d",InstrBuf[edpatch][10] & 1); ReadVal(&val,0,1,1,43,19); gotoxy(25,19); printf(" "); setFMparam(edpatch,25,val); sbfd_program_change(0,edpatch); } void savepatch() { FILE* f; char scr_buf[4096]; char patchname[80]; int i,j; gettext(1,1,80,25,scr_buf); clrscr(); showcur(); printf("Patch file to save to: "); gets(patchname); if (f = fopen(patchname,"wb")) { fwrite(&InstrBuf[edpatch][0],1,16,f); fclose(f); } else { printf("\nError opening file"); delay(2000); } puttext(1,1,80,25,scr_buf); } Select_Patch() { char str[20]; clrscr(); showcur(); printf("Patch to edit (0-127): "); gets(str); edpatch = atoi(str); compare=0; sbfd_program_change(0,edpatch); save_undo_settings(edpatch); draw_editscreen(); } draw_editscreen() { hidecur(); clrscr(); printf("Patch currently selected: %d\n\n",edpatch); printf("Parameters\n"); printf("----------\n\n"); printf("1: AM On/Off\n"); printf("2: Vib On/Off\n"); printf("3: EG\n"); printf("4: KSR\n"); printf("5: Multiple\n"); printf("6: KSL\n"); printf("7: Total Level\n"); printf("8: Attack\n"); printf("9: Decay\n"); printf("A: Sustain\n"); printf("B: Release\n"); printf("C: Wave\n"); printf("D: Feedback Alt-F: List Files\n"); printf("E: Connection L: Load Patch Set\n"); printf("N: Select Patch to edit S: Save Patch Set\n"); printf("P: Play Keyboard Alt-L: Load Patch\n"); printf("U: Undo changes to patch Alt-S: Save Patch\n"); printf("X: Compare\n"); } fm_edit() { int k,mod; editmode = 1; compare=0; sbfd_program_change(0,edpatch); save_undo_settings(); textcolor(GREEN); draw_editscreen(); while((k & 0xff) != 27) { hidecur(); while(! bioskey(1)); mod = bioskey(2); k = bioskey(0); switch((k >> 8) & 0xFF) { case 0x02: AM(); break; case 0x03: Vib(); break; case 0x04: EG(); break; case 0x05: KSR(); break; case 0x06: Multiple(); break; case 0x07: KSL(); break; case 0x08: TotLev(); break; case 0x09: Attack(); break; case 0x0A: Decay(); break; case 0x1E: Sustain(); break; case 0x30: Release(); break; case 0x2e: Wave(); break; case 0x20: Feedback(); break; case 0x12: Connection(); break; case 0x21: if(mod & 8) listfiles(); break; case 0x26: if(mod & 8) loadpatch(); else loadpatches(); break; case 0x1F: if(mod & 8) savepatch(); else savepatches(); break; case 0x31: Select_Patch(); break; case 0x19: Edit_Play(); break; case 0x16: Undo(); break; case 0x2d: Compare(); break; } } showcur(); editmode = 0; textcolor(LIGHTGRAY); draw_screen(); } save_undo_settings() { int i; for(i=0;i<16;i++) undo_buf[i] = InstrBuf[edpatch][i]; } Compare() { int i; compare = compare ^ 1; if(compare) { for(i=0;i<16;i++) compare_buf[i]=InstrBuf[edpatch][i]; for(i=0;i<16;i++) InstrBuf[edpatch][i]=undo_buf[i]; gotoxy(46,3);printf("Compare, now original patch"); } else { for(i=0;i<16;i++) InstrBuf[edpatch][i]=compare_buf[i]; gotoxy(46,3);printf(" "); } sbfd_program_change(0,edpatch); } Undo() { int i; for(i=0;i<16;i++) InstrBuf[edpatch][i] = undo_buf[i]; sbfd_program_change(0,edpatch); } setFMparam(int edpatch,int param,int val) { switch(param){ case 0 : /* AM Modulator */ { switch(val){ case 1: InstrBuf[edpatch][0] = InstrBuf[edpatch][0] | 0x80; break; case 0: InstrBuf[edpatch][0] = InstrBuf[edpatch][0] & 0x7F; } }break; case 1 : /* VIB Modulator */ { switch(val){ case 1: InstrBuf[edpatch][0] = InstrBuf[edpatch][0] | 0x40; break; case 0: InstrBuf[edpatch][0] = InstrBuf[edpatch][0] & 0xBF; } }break; case 2 : /* EG modulator */ { switch(val){ case 1: InstrBuf[edpatch][0] = InstrBuf[edpatch][0] | 0x20; break; case 0: InstrBuf[edpatch][0] = InstrBuf[edpatch][0] & 0xDF; } }break; case 3 : /* KSR modulator */ { switch(val){ case 1: InstrBuf[edpatch][0] = InstrBuf[edpatch][0] | 0x10; break; case 0: InstrBuf[edpatch][0] = InstrBuf[edpatch][0] & 0xEF; } } break; case 4 : /* Multiple modulator */ { InstrBuf[edpatch][0] = InstrBuf[edpatch][0] & 0xF0; InstrBuf[edpatch][0] = InstrBuf[edpatch][0] | val; } break; case 5 : /* AM Carrier */ { switch(val){ case 1: InstrBuf[edpatch][1] = InstrBuf[edpatch][1] | 0x80; break; case 0: InstrBuf[edpatch][1] = InstrBuf[edpatch][1] & 0x7F; } } break; case 6 : /* VIB Carrier */ { switch(val){ case 1: InstrBuf[edpatch][1] = InstrBuf[edpatch][1] | 0x40; break; case 0: InstrBuf[edpatch][1] = InstrBuf[edpatch][1] & 0xBF; } } break; case 7 : /* EG Carrier */ { switch(val){ case 1: InstrBuf[edpatch][1] = InstrBuf[edpatch][1] | 0x20; break; case 0: InstrBuf[edpatch][1] = InstrBuf[edpatch][1] & 0xDF; } } break; case 8 : /* KSR Carrier */ { switch(val){ case 1: InstrBuf[edpatch][1] = InstrBuf[edpatch][1] | 0x10; break; case 0: InstrBuf[edpatch][1] = InstrBuf[edpatch][1] & 0xEF; } } break; case 9 : /* Multiple Carrier */ { InstrBuf[edpatch][1] = InstrBuf[edpatch][1] & 0xF0; InstrBuf[edpatch][1] = InstrBuf[edpatch][1] | val; } break; case 10 : /* KSL Modulator */ { switch(val){ case 0: val = 0; break; case 1: val = 0x80; break; case 2: val = 0x40; break; case 3: val = 0xC0; break; } InstrBuf[edpatch][2] = InstrBuf[edpatch][2] & 0x3F; InstrBuf[edpatch][2] = InstrBuf[edpatch][2] | val; } break; case 11 : /* TL Modulator */ { InstrBuf[edpatch][2] = InstrBuf[edpatch][2] & 0xC0; InstrBuf[edpatch][2] = InstrBuf[edpatch][2] | val; } break; case 12 : /* KSL Carrier */ { switch(val){ case 0: val = 0; break; case 1: val = 0x80; break; case 2: val = 0x40; break; case 3: val = 0xC0; break; } InstrBuf[edpatch][3] = InstrBuf[edpatch][3] & 0x3F; InstrBuf[edpatch][3] = InstrBuf[edpatch][3] | val; } break; case 13 : /* TL Carrier */ { InstrBuf[edpatch][3] = InstrBuf[edpatch][3] & 0xC0; InstrBuf[edpatch][3] = InstrBuf[edpatch][3] | val; } break; case 14 : /* Attack Modulator */ { InstrBuf[edpatch][4] = InstrBuf[edpatch][4] & 0x0F; InstrBuf[edpatch][4] = InstrBuf[edpatch][4] | (val << 4); } break; case 15 : /* Decay Modulator */ { InstrBuf[edpatch][4] = InstrBuf[edpatch][4] & 0xF0; InstrBuf[edpatch][4] = InstrBuf[edpatch][4] | val; } break; case 16 : /* Attack Carrier */ 65e { InstrBuf[edpatch][5] = InstrBuf[edpatch][5] & 0x0F; InstrBuf[edpatch][5] = InstrBuf[edpatch][5] | (val << 4); } break; case 17 : /* Decay Carrier */ { InstrBuf[edpatch][5] = InstrBuf[edpatch][5] & 0xF0; InstrBuf[edpatch][5] = InstrBuf[edpatch][5] | val; } break; case 18 : /* Sustain Level Modulator */ { InstrBuf[edpatch][6] = InstrBuf[edpatch][6] & 0x0F; InstrBuf[edpatch][6] = InstrBuf[edpatch][6] | (val << 4); } break; case 19 : /* Release rate Modulator */ { InstrBuf[edpatch][6] = InstrBuf[edpatch][6] & 0xF0; InstrBuf[edpatch][6] = InstrBuf[edpatch][6] | val; } break; case 20 : /* Sustain Level Carrier */ { InstrBuf[edpatch][7] = InstrBuf[edpatch][7] & 0x0F; InstrBuf[edpatch][7] = InstrBuf[edpatch][7] | (val << 4); } break; case 21 : /* Release rate Carrier */ { InstrBuf[edpatch][7] = InstrBuf[edpatch][7] & 0xF0; InstrBuf[edpatch][7] = InstrBuf[edpatch][7] | val; } break; case 22 : /* Wave Select Modulator */ { InstrBuf[edpatch][8] = val; } break; case 23 : /* Wave Select Carrier */ { InstrBuf[edpatch][9] = val; } break; case 24 : /* Feedback */ { InstrBuf[edpatch][10] = InstrBuf[edpatch][10] & 0xF1; InstrBuf[edpatch][10] = InstrBuf[edpatch][10] | ( ((char)val) << 1); } break; case 25 : /* Connection */ { InstrBuf[edpatch][10] = InstrBuf[edpatch][10] & 0xFE; InstrBuf[edpatch][10] = InstrBuf[edpatch][10] | val; } break; } } . 0