Please consider a donation to the Higher Intellect project. See https://preterhuman.net/donate.php or the Donate to Higher Intellect page for more info. |
SEQ.C
Jump to navigation
Jump to search
/* fmsynt plays the fm chip with MIDI messages from MIDI IN */ /* With Built-in FM editor */ /* now with MOUSE support!!!! */ #include <stdio.h> #include <sbc.h> #include <sbcmusic.h> #include <bios.h> #include <conio.h> #include <dos.h> #include <dir.h> #include <cursor.c> #include <alloc.h> #include <midi.h> #include <mkbrk.h> #define SbProID 100 #define KeyUp 0x80 typedef unsigned long ulong; struct MIDIpacket { unsigned char track; ulong msec; unsigned char midbyte1; unsigned char midbyte2; unsigned char midbyte3; struct MIDIpacket *next,*before; } *point, *sequence_start, *sequence_end; static struct MIDIpacket *last_pos; unsigned long ms,old_ms; unsigned char status,kanel,nn,vl; unsigned char trk; int solo; 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, playmode, recmode; main(int argc,char **argv) { if(init(argc,argv[1])) { while(1) { if(playmode && (point != NULL)) process_recorded(); if(playmode) process_playkey(); else if(kbhit()) process_key(); } } } 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 46 : clr_sequence();break; case 20 : select_track();break; case 45 : set_solo();break; /* case 120 : trk = 1; break; case 121 : trk = 2; break; case 122 : trk = 3; break; case 123 : trk = 4; break; case 124 : trk = 5; break; case 125 : trk = 6; break; case 126 : trk = 7; break; case 127 : trk = 8; break; case 128 : trk = 9; break; case 129 : trk = 0; break; case 30 : trk = 10; break; case 48 : trk = 11; break; case 46 : trk = 12; break; case 32 : trk = 13; break; case 18 : trk = 14; break; case 33 : trk = 15; break; */ } draw_screen(); } else { switch(scan){ case 25 : rec_play(0); break; case 19 : rec_play(1);break; case 1 : quit(0); } } } 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; } } } process_recorded() { if(miditicks-ms >= point->msec) { if(solo && (point->track != trk)) { point = point->next; return; } status = point->midbyte1; kanel = status & 0xF; switch(status & 0xF0){ case 0x90 : { nn = point->midbyte2; vl = point->midbyte3; if(vl) sbfd_note_on(kanel,nn,vl); else sbfd_note_off(kanel,nn,0); } break; case 0x80 : { nn = point->midbyte2; vl = point->midbyte3; sbfd_note_off(kanel,nn,0); } break; case 0xC0 : sbfd_program_change(kanel,point->midbyte2); } point = point->next; } } select_track() { unsigned char ts[10]; gotoxy(1,22); printf("Select track (1-16): \n"); gets(ts); trk = (unsigned char)(atoi(ts) - 1); gotoxy(1,22); printf(" "); } set_solo() { unsigned char *mode[2] = {"Off","On"}; solo ^= 1; gotoxy(1,22); printf("Solo %s\n",mode[solo]); delay(1000); gotoxy(1,22); printf(" "); } rec_play(int mode) { if(mode == 1) recmode = 1; else recmode = 0; ms = miditicks; point = sequence_start; goto_playmode(); } clr_sequence() { point = sequence_start; /* f”rsta block i gruppen */ do { farfree(point); /* g”r fri nuvarande block */ point = point->next; /* peka till n„sta */ } while (point->next != NULL); /* sluta n„r next „r NULL */ sequence_start = sequence_end = NULL; last_pos = sequence_start; gotoxy(1,22); printf("Sequence Cleared!\n"); delay(1000); gotoxy(1,22); printf(" "); } goto_playmode() { 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(" "); } 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(recmode) add_packet(trk,miditicks-ms,0x90 | trk,note,velocity); sbfd_note_on(trk,note,velocity); old_note = note; } stop_note() { if(recmode) add_packet(trk,miditicks-ms,0x90 | trk,old_note,0); sbfd_note_off(trk,old_note,0); } change_program(int scan,int button) { switch(scan){ case 73 : { if(program < 127) program++; }break; case 81 : { if(program > 0) program--; }break; } if(recmode) add_packet(trk,miditicks-ms,0xC0 | trk,program,0); sbfd_program_change(trk,program); gotoxy(65,1);printf("%-3u",program); } add_packet(trk,tstamp,c1,c2,c3) unsigned long tstamp; unsigned char c1,c2,c3; { struct MIDIpacket *scratch,*insert_pt,*get_insert_point(); scratch = (struct MIDIpacket *) farmalloc(16); if(scratch == NULL) { fprintf(stderr,"Sorry, out of memory!\n"); delay(1000); quit(1); } scratch->track = trk; scratch->msec = tstamp; scratch->midbyte1 = c1; scratch->midbyte2 = c2; scratch->midbyte3 = c3; /* Where in the linked list should this packet go? */ if(sequence_start == NULL) /* the list is empty */ { sequence_start = sequence_end = scratch; scratch->before = NULL; scratch->next = NULL; } else { insert_pt = get_insert_point(sequence_start,sequence_end,tstamp); scratch->track = trk; if(insert_pt == NULL) /* insert the new bottom record */ { sequence_end->next = scratch; scratch->before = sequence_end; scratch->next = NULL; sequence_end = scratch; } else if(insert_pt == sequence_start) /* insert the new top record */ { sequence_start->before = scratch; scratch->before = NULL; scratch->next = sequence_start; sequence_start = scratch; } else /* insert before the insert pointer */ { scratch->next = insert_pt; scratch->before = insert_pt->before; insert_pt->before = scratch; (scratch->before)->next = scratch; } } } /* end of add_packet() */ struct MIDIpacket *get_insert_point(top,bottom,tstamp) struct MIDIpacket *top,*bottom; unsigned long tstamp; { if(tstamp > bottom->msec) return(NULL); /* tack onto end of list */ if(tstamp < top->msec) return(top); /* insert as the new first record */ if(tstamp >= (last_pos->before)->msec) { while(tstamp > last_pos->msec) last_pos = last_pos->next; return(last_pos); } else { last_pos = sequence_start; /* Apparently a new track */ while(tstamp > last_pos->msec) last_pos = last_pos->next; return(last_pos); } } /* ================== Initialization and other routines =============== */ int init(int argc,char *patchfile) { int i,j; FILE* f; if ( ! GetEnvSetting() ) { if (sbc_check_card() & 4) { if (sbc_test_int()) { sbfd_init(); init_midi(); velocity = 64; octave = 5; program = 0; editmode = 0; playmode = 0; edpatch = 0; sequence_start = sequence_end = NULL; last_pos = sequence_start; trk = 0; solo = 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("fmsynt.cfg","rb")) get_config_settings(f); if(argc > 1) loadpatches2(patchfile); else 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); } quit(mode) { int k, butstat; if(!mode) { gotoxy(1,22); printf("Do you really want to quit (Y\\n)?"); k = (bioskey(0) >> 8) & 0xff; }else k = 28; if(k == 28 || k == 21) { point = sequence_start; /* f”rsta block i gruppen */ do { farfree(point); /* g”r fri nuvarande block */ point = point->next; /* peka till n„sta */ } while (point->next !=NULL); /* sluta n„r next „r NULL */ sbfd_music_off(); exit_midi(); 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("fmsynt.cfg","wb"); fwrite(&channel_on[0],1,16,cfgf); fwrite(&velocity,1,1,cfgf); fclose(cfgf); } draw_screen() { int i; clrscr(); printf("*** THE Sequencer! *** Current Program: %-3u\n\n",program); printf("^V Set Velocity ^O All notes off ^Y FM Editor ^Z List Files ^P Load Patch\n\n"); printf("^L Load 128-patch set ^S Save 128-patch set ^W Save Settings ^C Clear seq\n\n"); printf("^T Select Track ^X Solo (R)ecord (P)lay (Q)uit\n\n\n"); printf("Current Track: %d\n",trk+1); } 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); } 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(); done = findfirst("*.*",&ffblk,0); while (!done) { printf("%16s", ffblk.ff_name); done = findnext(&ffblk); } printf("\n\nPress any key..."); getch(); if(editmode) draw_editscreen(); else draw_screen(); } #include "fmedit.c"