home *** CD-ROM | disk | FTP | other *** search
- #include <curses.h>
-
- /*
- * The following source code is being placed in the public domain
- * with the sole restriction that if any of it is used in any manner,
- * proper acknowledgement will be given to the original author -
- * Eric Pettersen
- */
-
- #define Effect (!((Random() >> 3) % weirdness))
- #define sfunc(i,b) ((types[i][b] == 1) ? "high": ((types[i][b] == 2) ? \
- " mid": " low"))
- #define Get_roll(a) roll = get_roll(a)
- #define AND_CHAR 241
- #define OPTIONS 9
- #define EDIT_OPTIONS 8
- #define MAIN 0
- #define EDIT 1
- #define OK 0
- #undef NULL
- #define NULL -1
- #define ABORT -2
- #define BAD -3
-
- #define VOICES 1000
-
- /* either #define DX100 or CZ101 here */
- #ifdef DX100
- #define RANDOM_FILE "DX100.DTA"
- #define VOICE_FILE "DXVOICES.DTA"
- #define VOICE_SIZE 77
- #define TOTAL_SIZE 93
- #else
- #define RANDOM_FILE "CZ101.DTA"
- #define VOICE_FILE "CZVOICES.DTA"
- #define VOICE_SIZE 81
- #define TOTAL_SIZE 128
- #define VDT 0
- #define VRm 1
- #define VRl 2
- #define VD 3
- #define SLOTS 4
-
- char table[SLOTS][100]; /* the CZMIDI.DTA data file fits in this table */
- int dca_kf[10] = { 0, 8, 17, 26, 36, 47, 58, 69, 82, 95 };
- int dcw_kf[10] = { 0, 31, 44, 57, 70, 83, 96, 110, 146, 255 };
- #endif
-
- int weirdness;
- int ranges[VOICE_SIZE]; /* data from DX/CZDATA.DTA */
- int types[VOICE_SIZE][2]; /* is read into these */
- int tries[VOICE_SIZE][2]; /* arrays */
- char out[80], key_tbl[384]; /* data from KEYTAB.DTA goes in */
- /* key_tbl array */
- int cur_voice, load_ptr; /* cur_voice: points to where */
- /* next saved voice will go in */
- /* the voices array (and also, */
- /* therefore, how many voices */
- /* we have in the library) */
- /* load_ptr: which voice from */
- /* voices array was last loaded */
- /* into the synth */
- long cur_space; /* how much free space on disk */
- unsigned char voices[VOICES][TOTAL_SIZE]; /* actual voices */
- char v_names[VOICES+1][80]; /* associated voice names */
-
- /* main: Handle all main menu I/O and call any subroutines requested */
- main()
- {
- char key, ans;
- char voice[TOTAL_SIZE], v_name[80], search_str[80];
- int i, j, name_valid, load_voice, leng, found, init_rez;
-
- if ((init_rez = Getrez()) == 0) Setscreen(-1L, -1L, 1);
- init_curses();
- scr_func(CLEAR_SCR);
- printf("Getting old voices from file\n\r");
- get_voices(v_names, voices);
- load_ptr = -1;
- printf("Getting random voice weights from file\n\r");
- initialize();
- show_screen(MAIN);
- do {
- pos_cursor(8, 3+OPTIONS);
- scr_func(ERASE_TO_EOP);
- switch((int)(key = Crawcin())) {
- case 'n':
- case 'N':
- printf("n");
- printf("\n\rmaking voice");
- make_voice(voice);
- load_ptr = cur_voice;
- /* FALL THROUGH */
- case 'r':
- case 'R':
- if (key == 'r' || key == 'R'){
- printf("r");
- }
- if (load_ptr < 0)
- printf("\n\rno current voice\n\r");
- else {
- printf("\n\rsending voice\n\r");
- if (load_ptr == cur_voice)
- send_voice(voice);
- else
- send_voice(voices[load_ptr]);
- show_voice(load_ptr);
- }
- break;
- case 's':
- case 'S':
- printf("s");
- printf("\n\rreceiving voice\n\r");
- #ifndef DEBUG
- receive_voice(voice);
- #endif
- do {
- do {
- pos_cursor(0,5+OPTIONS);
- scr_func(CLEAR_TO_EOL);
- printf("enter voice name: \007");
- printf("\n\r[ESC to abort]");
- pos_cursor(18, 5+OPTIONS);
- leng = get_str(v_name);
- } while (leng == 0);
- if (leng < 0) break;
- name_valid = TRUE;
- for(i=0; i<leng; i++)
- if (v_name[i]<32 || v_name[i]>127) {
- printf("\n\rName has invalid ");
- printf("character in it - ");
- printf("re-try");
- name_valid = FALSE;
- break;
- }
- v_name[i] = '\0';
- if (name_valid)
- for(i=0; i<cur_voice; i++) {
- if(!strcmp(v_names[i],v_name))
- {
- printf("\n\rThere is al");
- printf("ready a voice");
- printf(" named '%s'",
- v_name);
- printf(" - re-try");
- name_valid = FALSE;
- break;
- }
- }
- } while(name_valid == FALSE);
- if (leng < 0) break;
- #ifdef DX100
- strncpy(voice+77, v_name, 10);
- for(i=strlen(v_name); i<10; i++) voice[77+i] = ' ';
- #endif
- pos_cursor(0,6+OPTIONS);
- scr_func(CLEAR_TO_EOL);
- for(i=0; i<TOTAL_SIZE; i++) voices[cur_voice][i] = voice[i];
- strcpy(v_names[cur_voice], v_name);
- printf("writing voice '%s' to file\n\r", v_name);
- write_voice(v_name, voice);
- cur_voice++;
- show_voice(load_ptr);
- break;
- case 'a':
- case 'A':
- printf("a");
- goto test;
- case 'l':
- case 'L':
- printf("l");
- test:
- if (cur_voice == 0) {
- warn("No voices to load");
- break;
- }
- if (key == 'a' || key == 'A') {
- load_ptr = (load_ptr + 1) % cur_voice;
- goto load_it;
- }
- load_voice = get_v_num(5+OPTIONS);
- if (load_voice == ABORT) break;
- load_ptr = load_voice;
- load_it:
- pos_cursor(0,6+OPTIONS);
- scr_func(CLEAR_TO_EOL);
- printf("Loading voice '%s'\n\r", v_names[load_ptr]);
- send_voice(voices[load_ptr]);
- show_voice(load_ptr);
- break;
- case 'w':
- case 'W':
- printf("w");
- do {
- pos_cursor(0, 5+OPTIONS);
- scr_func(CLEAR_TO_EOL);
- printf("New weirdness factor: ");
- leng = get_num();
- if (leng == BAD || leng == 0) {
- printf("\n\rInput 1 or higher ");
- printf("[ESC to abort]");
- }
- } while(leng == 0 || leng == BAD);
- if (leng > 0) {
- weirdness = leng;
- show_weirdness();
- }
- break;
- case 'e':
- case 'E':
- show_screen(EDIT);
- edit();
- show_screen(MAIN);
- break;
- case 'f':
- case 'F':
- printf("f");
- Keytbl(key_tbl, key_tbl+128, key_tbl+256);
- pos_cursor(0, 5+OPTIONS);
- printf("Enter string(s) to search for: \n\r");
- printf("[ESC to abort]");
- pos_cursor(32, 5+OPTIONS);
- leng = get_str(search_str);
- Bioskeys();
- if (leng <= 0) break;
- found = -1;
- pos_cursor(0, 8+OPTIONS);
- printf(" # name\n\r");
- printf("--- ----");
- do {
- found = search(search_str, found+1);
- if (found < cur_voice) {
- pos_cursor(0, 10+OPTIONS);
- scr_func(CLEAR_TO_EOL);
- printf("%03d '%s'", found,
- v_names[found]);
- pos_cursor(0, 6+OPTIONS);
- scr_func(CLEAR_TO_EOL);
- printf("Continue search (y/n)? \007");
- printf("%c", (ans = Crawcin()));
- }
- else {
- pos_cursor(0, 10+OPTIONS);
- scr_func(CLEAR_TO_EOL);
- printf("*** NONE");
- pos_cursor(0, 6+OPTIONS);
- scr_func(CLEAR_TO_EOL);
- printf("-- Hit any key to continue --");
- wait();
- }
- } while (found<cur_voice && (ans == 'y' || ans == 'Y'));
- break;
- case 'q':
- case 'Q':
- printf("q");
- break;
- default:
- printf("\007");
- printf("\n\rBad option '%c' - re-try", key);
- break;
- }
- } while (key != 'q' && key != 'Q');
- if (init_rez == 0) Setscreen(-1L, -1L, 0);
- curses_cleanup();
- }
-
- /* get_voices: read the standard voice library file and initialize the
- voices in memory */
- get_voices(names, voice_data)
- char names[][80], voice_data[][TOTAL_SIZE];
- {
- long result;
- int handle;
-
- check_disk();
- if (cur_space < 80 + TOTAL_SIZE) {
- warn(
- "WARNING: There is not enough space on the disk to store more voices");
- }
- result = Fsfirst(VOICE_FILE, 0);
- if (result == EFILNF) {
- printf("file '%s' not found -- attempting to create\n\r",
- VOICE_FILE);
- handle = Fcreate(VOICE_FILE, 0);
- if (handle < 0) {
- sprintf(out, "cannot create '%s'", VOICE_FILE);
- error(out);
- }
- else {
- printf("'%s' created\n\r", VOICE_FILE);
- Fclose(handle);
- result = E_OK;
- }
- }
- if (result == E_OK) {
- handle = Fopen(VOICE_FILE, READ);
- if (handle < 0) {
- sprintf(out, "cannot open '%s'", VOICE_FILE);
- error(out);
- }
- else {
- printf("file opened\n\r");
- }
- }
- else {
- sprintf(out, "cannot find '%s'", VOICE_FILE);
- error(out);
- }
- cur_voice = 0;
- printf("reading in voice data\n\r");
- while(TRUE) {
- if (scan_name(handle, names[cur_voice]) != OK) break;
- if (strlen(names[cur_voice]) > 0) {
- if (scan_voice(handle, voice_data[cur_voice]) != OK)
- break;
- cur_voice++;
- }
- else break;
- }
- Fclose(handle);
- }
-
- /* make_voice: create a random voice and put it in 'voice' */
- make_voice(voice)
- char voice[];
- {
- int i, roll, wave1, wave2, nmod, rmod, line, step, sustain;
- int rate, level;
-
- #ifdef DX100
- for (i=0; i<VOICE_SIZE; i++) {
- if (Effect) voice[i] = func(i,0);
- else voice[i] = func(i,1);
- }
- if (!((Random() >> 3) % 4)) voice[10] = 0; /* each operator */
- if (!((Random() >> 3) % 4)) voice[23] = 0; /* (except # 1) */
- if (!((Random() >> 3) % 4)) voice[36] = 0; /* given arbitrary */
- /* 25% chance of not */
- /* being used */
- if (!Effect) voice[11] = round(voice[11]); /* normal frequency */
- if (!Effect) voice[24] = round(voice[24]); /* ratios are */
- if (!Effect) voice[37] = round(voice[37]); /* rational multiples*/
- if (!Effect) voice[50] = round(voice[50]); /* of 1.0 */
- voice[49] = 99; /* max operator 1 output */
- voice[62] /= 12;
- voice[62] *= 12; /* make key change shift whole octaves */
- sprintf(voice+77, "RANDOM ");
- for(i=87; i<93; i++) voice[i] = 0;
- #else
- /* Do I want to explain how the code works for the CZ101? NOOO!!! *
- * I suggest you get a copy of CZ101 MIDI system exclusive specs *
- * and then examine the code closely. What makes this stuff so *
- * hard to understand is that the random values have to be put *
- * into specific *bit positions* in specific bytes, instead of *
- * being given bytes of their very own, i.e. several different *
- * values are stuffed into a specific byte. If there is something*
- * crucial that you cannot understand you can E-mail me. If you *
- * scrap the code and write your own, I suggest you retain CZMIDI.*
- * DTA because that is a pain to generate by hand. */
- Get_roll(0);
- roll = (roll - 1) % 3;
- voice[0] = 0 | (roll << 2) | (line = 3);
- /* Line select and Octave */
- voice[1] = (Random() >> 3) % 2;
- /* Detune + or - */
- Get_roll(1);
- voice[2] = (((10*roll)/151) << 4) + ((roll + roll/15 - 1) % 16);
- /* Fine Detune */
- Get_roll(2);
- voice[3] = roll;
- /* Octave and Note Detune */
- Get_roll(3);
- voice[4] = 8/(roll+1) + (roll == 3) * 28;
- /* Vibrato Waveform */
- Get_roll(4);
- voice[5] = roll;
- voice[6] = table[VDT][roll];
- voice[7] = (roll > 79) + (roll > 95);
- /* Vibrato Delay Time (3 bytes) */
- Get_roll(5);
- voice[8] = roll;
- voice[9] = table[VRl][roll];
- voice[10] = table[VRm][roll];
- /* Vibrato Rate (3 bytes) */
- Get_roll(6);
- voice[11] = roll;
- voice[12] = table[VD][roll];
- voice[13] = (roll > 78) + (roll > 94) + (roll > 98);
- /* Vibrato Depth (3 bytes) */
- for(i=0; i<2; i++) {
- Get_roll(7+i*37);
- wave1 = roll;
- Get_roll(8+i*37);
- if (roll) {
- Get_roll(9+i*37);
- wave2 = roll+1;
- if (wave1 > 4 && wave2 > 5) wave2 = 0;
- }
- else wave2 = 0;
- Get_roll(10+i*37);
- if (!(rmod = roll)) {
- Get_roll(11+i*37);
- nmod = roll;
- } else nmod = 0;
- if (i || line < 2) nmod = rmod = 0;
- voice[14+i*57] =
- ((wave1 < 3 ? wave1 : (wave1 > 4 ? 6 : wave1+1)) << 5)
- +(wave2>0)*((wave2<4 ? wave2-1:(wave2>5 ? 6:wave2))<<2)
- +((wave2 > 0) << 1);
- /* DCO waves */
- wave2--;
- voice[15+i*57] =
- ((max(wave1,wave2) > 4 ? max(wave1,wave2)-4 : 0) << 6)
- + (rmod << 5) + ((3*nmod) << 3);
- /* Modulation and DCO wave resonance */
- Get_roll(12+i*37);
- voice[16+i*57] = roll;
- voice[17+i*57] = dca_kf[roll];
- /* DCA Key Follow */
- Get_roll(13+i*37);
- voice[18+i*57] = roll;
- voice[19+i*57] = dcw_kf[roll];
- /* DCW Key Follow */
- Get_roll(14+i*37);
- if (!i && roll < 1) roll = 1;
- voice[20+i*57] = roll;
- /* DCA End Step */
- if (Effect) sustain = 8;
- else sustain = mid(voice[20+i*57], 3);
- if (sustain == voice[20+i*57]) sustain = 8;
- Get_roll(15+i*37);
- rate = roll;
- voice[21+i*57] = (119 * rate) / 99;
- /* DCA Attack Rate */
- Get_roll(16+i*37);
- level = roll;
- voice[22+i*57] = (sustain == 0 ? 128 : 0) +
- (level == 0 ? 0 : level+28);
- /* DCA Attack Level */
- for (step=1; step<voice[20+i*57]; step++) {
- if (sustain < 8) {
- if (step < sustain) {
- Get_roll(17+i*37);
- rate = roll;
- Get_roll(18+i*37);
- level = roll;
- }
- else if (step == sustain) {
- Get_roll(19+i*37);
- rate = roll;
- Get_roll(20+i*37);
- level = roll;
- }
- else {
- Get_roll(21+i*37);
- rate = roll;
- Get_roll(22+i*37);
- level = roll;
- }
- }
- else if (step < (voice[20+i*37]+1)/2) {
- Get_roll(17+i*37);
- rate = roll;
- Get_roll(18+i*37);
- level = roll;
- }
- else {
- Get_roll(21+i*37);
- rate = roll;
- Get_roll(22+i*37);
- level = roll;
- }
- voice[21+2*step+i*57] = (level < (voice[20+2*step+i*57]
- & 0x007F) ? 128 : 0) + ((119 * rate)/99);
- /* DCA intermediate rate */
- voice[22+2*step+i*57] = (sustain == step ? 128 : 0) +
- (level == 0 ? 0 : level+28);
- /* DCA intermediate level */
- }
- Get_roll(23+i*37);
- rate = roll;
- voice[21+2*step+i*57] = 128 + ((119 * rate)/99);
- /* DCA End Rate */
- voice[22+2*step+i*57] = 0;
- /* DCA End Level */
- for(step=step+1;step<8;step++) {
- voice[21+2*step+i*57] = (119*50)/99;
- voice[22+2*step+i*57] = 0;
- /* Envelope cleanup */
- }
- Get_roll(24+i*37);
- voice[37+i*57] = roll;
- /* DCW End Step */
- if (Effect) sustain = 8;
- else sustain = mid(voice[37+i*57], 3);
- if (sustain == voice[37+i*57]) sustain = 8;
- Get_roll(25+i*37);
- rate = roll;
- Get_roll(26+i*37);
- level = roll;
- voice[38+i*57] = (119 * rate) / 99;
- /* DCW Attack Rate */
- voice[39+i*57] = (127 * level) / 99;
- /* DCW Attack Level */
- for (step=1; step<voice[37+i*57]; step++) {
- if (sustain < 8) {
- if (step < sustain) {
- Get_roll(27+i*37);
- rate = roll;
- Get_roll(28+i*37);
- level = roll;
- }
- else if (step == sustain) {
- Get_roll(29+i*37);
- rate = roll;
- Get_roll(30+i*37);
- level = roll;
- }
- else {
- Get_roll(31+i*37);
- rate = roll;
- Get_roll(32+i*37);
- level = roll;
- }
- }
- else if (step < (voice[20+i*37]+1)/2) {
- Get_roll(27+i*37);
- rate = roll;
- Get_roll(28+i*37);
- level = roll;
- }
- else {
- Get_roll(31+i*37);
- rate = roll;
- Get_roll(32+i*37);
- level = roll;
- }
- voice[38+2*step+i*57] = (level < (voice[37+2*step+i*57]
- & 0x007F) ? 128 : 0) + ((119 * rate)/99);
- /* DCW intermediate rate */
- voice[39+2*step+i*57] = (sustain == step ? 128 : 0) +
- ((127 * level) / 99);
- /* DCW intermediate level */
- }
- Get_roll(33+i*37);
- rate = roll;
- voice[38+2*step+i*57] = 128 + ((119 * rate)/99);
- /* DCW End Rate */
- voice[39+2*step+i*57] = 0;
- /* DCW End Level */
- for(step=step+1;step<8;step++) {
- voice[38+2*step+i*57] = (119*50)/99;
- voice[39+2*step+i*57] = 0;
- /* Envelope cleanup */
- }
- Get_roll(34+i*37);
- voice[54+i*57] = roll;
- /* DCO End Step */
- if (Effect) sustain = 8;
- else sustain = mid(voice[54+i*57], 3);
- if (sustain == voice[54+i*57]) sustain = 8;
- Get_roll(35+i*37);
- rate = roll;
- Get_roll(36+i*37);
- level = roll;
- voice[55+i*57] = (127 * rate) / 99;
- /* DCO Attack Rate */
- voice[56+i*57] = (level < 64 ? level : level+4);
- /* DCO Attack Level */
- for (step=1; step<voice[54+i*57]; step++) {
- if (sustain < 8) {
- if (step < sustain) {
- Get_roll(37+i*37);
- rate = roll;
- Get_roll(38+i*37);
- level = roll;
- }
- else if (step == sustain) {
- Get_roll(39+i*37);
- rate = roll;
- Get_roll(40+i*37);
- level = roll;
- }
- else {
- Get_roll(41+i*37);
- rate = roll;
- Get_roll(42+i*37);
- level = roll;
- }
- }
- else if (step < (voice[20+i*37]+1)/2) {
- Get_roll(37+i*37);
- rate = roll;
- Get_roll(38+i*37);
- level = roll;
- }
- else {
- Get_roll(41+i*37);
- rate = roll;
- Get_roll(42+i*37);
- level = roll;
- }
- voice[55+2*step+i*57] = (level < (voice[54+2*step+i*57]
- & 0x007F) ? 128 : 0) + ((127 * rate)/99);
- /* DCO intermediate rate */
- voice[56+2*step+i*57] = (sustain == step ? 128 : 0) +
- (level < 64 ? level : level+4);
- /* DCO intermediate level */
- }
- Get_roll(43+i*37);
- rate = roll;
- voice[55+2*step+i*57] = 128 + ((127 * rate)/99);
- /* DCO End Rate */
- voice[56+2*step+i*57] = 0;
- /* DCO End Level */
- for(step=step+1;step<8;step++) {
- voice[55+2*step+i*57] = (127*50)/99;
- voice[56+2*step+i*57] = 0;
- /* Envelope cleanup */
- }
- }
- for (i=0; i<TOTAL_SIZE; i++)
- voice[i] = (voice[i] << 4) + (0x000F & (voice[i] >> 4));
- /* Casio sends nibbles in *reverse* order */
- #endif
- }
-
- /* send_voice: send a voice ('voice') to the synth */
- send_voice(voice)
- char voice[];
- {
- int i,j;
- char checksum;
-
- #ifdef CZ101
- retry:
- midi_flush();
- #endif
- send('\360');
- #ifdef DX100
- send('\103');
- send('\000');
- send('\003');
- send('\000');
- send('\135');
- checksum = 0;
- for(i=0;i<TOTAL_SIZE;i++) {
- send(voice[i]);
- checksum += ~voice[i] + 1;
- }
- checksum &= '\177';
- send(checksum);
- #else
- send('\104');
- send('\000');
- send('\000');
- send('\160');
- send('\040');
- send('\140');
- if(!handshake('\360')) goto retry;
- if(!handshake('\104')) goto retry;
- if(!handshake('\000')) goto retry;
- if(!handshake('\000')) goto retry;
- if(!handshake('\160')) goto retry;
- if(!handshake('\060')) goto retry;
- for(i=0; i<TOTAL_SIZE; i++) {
- send((char)(0x000F & (voice[i] >> 4)));
- send((char)(0x000F & voice[i]));
- }
- for (i=0; i<256 - 2*TOTAL_SIZE; i++) send('\000');
- #endif
- send('\367');
- #ifdef CZ101
- if(!handshake('\367')) goto retry;
- #endif
- }
-
- /* receive_voice: receive a voice from the synth and place it in 'voice' */
- receive_voice(voice)
- char voice[];
- {
- int i,j;
- #ifdef DX100
- char checksum, test;
- #else
- char high, low;
- #endif
-
- retry:
- midi_flush();
- send('\360');
- #ifdef DX100
- send('\103');
- send('\040');
- send('\003');
- send('\367');
- for(i=0;i<5;i++) {
- while((test=Bconin(3)) & '\200');
- }
- test = 0;
- for(i=0;i<TOTAL_SIZE;i++) {
- while((voice[i] = Bconin(3)) & '\200');
- test += ~voice[i] + 1;
- }
- test &= '\177';
- while((checksum = Bconin(3)) & '\200');
- if (test == checksum) {
- printf("good checksum\n\r");
- }
- else {
- printf("bad checksum -- re-trying\n\r");
- goto retry;
- }
- #else
- send('\104');
- send('\000');
- send('\000');
- send('\160');
- send('\020');
- send('\140');
- if (!handshake('\360')) goto retry;
- if (!handshake('\104')) goto retry;
- if (!handshake('\000')) goto retry;
- if (!handshake('\000')) goto retry;
- if (!handshake('\160')) goto retry;
- if (!handshake('\060')) goto retry;
- send('\160');
- send('\061');
- for(i=0;i<TOTAL_SIZE;i++) {
- while((high = Bconin(3)) & '\200');
- while((low = Bconin(3)) & '\200');
- voice[i] = (high << 4) + low;
- }
- send('\367');
- #endif
- }
-
- /* write_voice: write voice 'voice' with name 'name' to the standard
- library file */
- write_voice(name, voice)
- char name[], voice[];
- {
- int handle;
-
- if (cur_voice >= VOICES) {
- printf("At voice number limit [%d], to save current voice:\n\r",
- VOICES);
- printf(" (1) use 'quit' option to exit program.\n\r");
- printf(" (2) rename file %s to any other name.\n\r",
- VOICE_FILE);
- printf(" (3) restart program and save voice.\n\r");
- printf("Note: To access the voices stored in the old ");
- printf("%s it must be renamed back\n\rto %s ", VOICE_FILE,
- VOICE_FILE);
- printf("and the current %s named something else ", VOICE_FILE);
- printf("temporarily.\n\r");
- printf("-- hit any key to continue --");
- wait();
- return;
- }
- if (cur_space < 94 + strlen(name))
- error("Not enough free space on disk to store voice data");
- handle = Fopen(VOICE_FILE, READ_WRITE);
- if (handle < 0) {
- sprintf(out, "Cannot open '%s'", VOICE_FILE);
- error(out);
- }
- Fseek(0L, handle, 2);
- if (Fwrite(handle, (long)(strlen(name) + 1), name) < 0)
- error("Error while writing voice name to file");
- cur_space -= strlen(name)+1;
- if (Fwrite(handle, (long)TOTAL_SIZE, voice) < 0)
- error("Error while writing voice data to file");
- cur_space -= TOTAL_SIZE;
- Fclose(handle);
- if (cur_space < 80 + TOTAL_SIZE) {
- warn(
- "WARNING: there may not be enough space on the current disk for another voice");
- }
- if (cur_voice == VOICES-1) {
- printf("WARNING: voice number limit of %d reached\n\r", VOICES);
- printf("To save more voices:\n\r");
- printf(" (1) use 'quit' option to exit program.\n\r");
- printf(" (2) rename file %s to any other name.\n\r",
- VOICE_FILE);
- printf(" (3) restart program.\n\r");
- printf("Note: To access the voices stored in the old ");
- printf("%s it must be renamed back\n\rto %s ", VOICE_FILE,
- VOICE_FILE);
- printf("and the current %s named something else ", VOICE_FILE);
- printf("temporarily.\n\r");
- printf("-- hit any key to continue --");
- wait();
- }
- }
-
- /* scan_name: read a voice name from a file with handle 'handle' into 'name',
- returning the success of the operation */
- int
- scan_name(handle, name)
- int handle;
- char name[];
- {
- if (Fread(handle, 1L, name) == 0) {
- name[0] = '\0';
- }
- else do {
- name++;
- if (Fread(handle, 1L, name) == 0) {
- warn("unexpected end-of-file in voice file -- check voices");
- return(BAD);
- }
- } while(*name != '\0');
- return(OK);
- }
-
- /* scan_voice: read a voice from a file with handle 'handle' into 'voice',
- returning the success of the operation */
- int
- scan_voice(handle, voice)
- int handle;
- char voice[];
- {
- if (Fread(handle, (long)TOTAL_SIZE, voice) != TOTAL_SIZE) {
- warn("Unexpected end-of-file in voice file -- check voices");
- return(BAD);
- }
- return(OK);
- }
-
- /* error: print message 'message', wait, and terminate */
- error(message)
- char *message;
- {
- scr_func(CLEAR_SCR);
- printf("%s\n\r", message);
- printf("\n\r-- hit any key to exit --\n\r");
- wait();
- curses_cleanup();
- exit();
- }
-
- /* warn: print message 'message', wait, and continue */
- warn(message)
- char *message;
- {
- printf("\n\r%s\n\r", message);
- printf("-- hit any key to continue --\n\r");
- wait();
- }
-
- /* midi_flush: flush the MIDI input buffer */
- midi_flush()
- {
- while(Bconstat(3)) Bconin(3);
- }
-
- /* send: send the byte 'data' to MIDI out */
- send(data)
- char data;
- {
- while(!Bcostat(3));
- Bconout(3, data);
- }
-
- /* mid: find the median of 'rolls' numbers between zero and 'range' */
- mid(range, rolls)
- int range, rolls;
- {
- int i, lowest, place, j;
- int results[100];
-
- for(i=0; i<rolls; i++)
- results[i] = Random() % (range+1);
- for(i=0; i<rolls/2; i++) {
- lowest = range;
- for(j=0;j<rolls;j++)
- if(results[j] < lowest) {
- lowest = results[j];
- place = j;
- }
- results[place] = range;
- }
- lowest = range;
- for(j=0;j<rolls;j++)
- if(results[j] < lowest) {
- lowest = results[j];
- place = j;
- }
- return(lowest);
- }
-
- /* low: find the lowest of 'rolls' numbers in the range zero to 'range' */
- low(range, rolls)
- int range, rolls;
- {
- int i, lowest, roll;
-
- lowest = range;
- for(i=0; i<rolls; i++)
- if ((roll = Random() % (range+1)) < lowest) lowest = roll;
- return(lowest);
- }
-
- /* high: find the highest of 'rolls' numbers in the range zero to 'range' */
- high(range, rolls)
- int range, rolls;
- {
- int i, highest, roll;
-
- highest = 0;
- for(i=0; i<rolls; i++)
- if ((roll = Random() % (range+1)) > highest) highest = roll;
- return(highest);
- }
-
- /* initialize: initialize various tables and variables */
- initialize()
- {
- int i, handle, slot;
-
- if ((handle = Fopen("KEYTAB.DTA", READ)) < 0)
- error("Cannot open 'KEYTAB.DTA'");
- if (Fread(handle, 384L, key_tbl) < 384)
- error("Read error on 'KEYTAB.DTA'");
- Fclose(handle);
- handle = Fopen(RANDOM_FILE, READ);
- if (handle < 0)
- error("Cannot open random weight file");
- weirdness = 50;
- for (i=0; i<VOICE_SIZE; i++) ranges[i] = get_int(handle);
- for (i=0; i<VOICE_SIZE; i++) {
- types[i][0] = get_int(handle);
- types[i][1] = get_int(handle);
- }
- for (i=0; i<VOICE_SIZE; i++) {
- tries[i][0] = get_int(handle);
- tries[i][1] = get_int(handle);
- }
- Fclose(handle);
- #ifdef CZ101
- handle = Fopen("CZMIDI.DTA", READ);
- if (handle < 0) error("Cannot open MIDI table file");
- for (slot=0; slot<SLOTS; slot++) for(i=0; i<100; i++) {
- if (Fread(handle, 1L, &table[slot][i]) < 1)
- error("Unexpected EOF in 'CZMIDI.DTA'");
- }
- Fclose(handle);
- #endif
- }
-
- /* get_int: read an integer from the file pointed to by 'handle',
- ignoring non-numeric characters */
- int
- get_int(handle)
- int handle;
- {
- char data;
- int num, in_comment;
-
- in_comment = FALSE;
- do {
- if (Fread(handle, 1L, &data) < 1) {
- sprintf(out, "Unexpected EOF in '%s'", RANDOM_FILE);
- error(out);
- }
- if (data == '*') in_comment = !in_comment;
- } while(data < '0' || data > '9' || in_comment);
- num = data - '0';
- if (Fread(handle, 1L, &data) < 1) {
- sprintf(out, "Unexpected EOF in '%s'", RANDOM_FILE);
- error(out);
- }
- else if (data >= '0' && data <= '9')
- num = 10*num + data - '0';
- return(num);
- }
-
- /* get_num: read an integer from the keyboard and return it or an error code */
- int
- get_num()
- {
- int i, num, leng;
-
- if ((leng = get_str(out)) < 0) return(ABORT);
- else if (leng == 0) return(NULL);
- num = 0;
- for(i=0; i<leng; i++) {
- if (out[i] < '0' || out[i] > '9')
- return(BAD);
- else
- num = 10*num + out[i] - '0';
- }
- return(num);
- }
-
- /* handshake: wait for character 'verify' from the CZ101 */
- handshake(verify)
- char verify;
- {
- int received;
-
- while(!Bconstat(3));
- if ((received = (0x00FF & Bconin(3))) != (0x00FF & verify)) {
- warn("Bad handshaking from synth - Make sure MIDI channel = 1");
- sprintf(out, "Expecting %x but received %x", (int) verify,
- received);
- warn(out);
- sprintf(out, "Next byte = %x", (0x00FF & Bconin(3)));
- error(out);
- return(FALSE);
- }
- return(TRUE);
- }
-
- /* show_weirdness: display the weirdness factor on the screen */
- show_weirdness()
- {
- pos_cursor(40, 2);
- scr_func(CLEAR_TO_EOL);
- sprintf(out, "weirdness factor = 1 in %d", weirdness);
- pos_cursor(80 - strlen(out), 2);
- printf("%s", out);
- }
-
- /* show_voice: show the name and voice number of voice number 'voice'
- on the screen */
- show_voice(voice)
- {
- pos_cursor(77, 3);
- if (voice < 0) printf("---");
- else printf("%03d", voice);
- pos_cursor(40, 4);
- scr_func(CLEAR_TO_EOL);
- if (voice < 0) {
- pos_cursor(76, 4);
- printf("NONE");
- }
- else if (voice == cur_voice) {
- pos_cursor(74, 4);
- printf("RANDOM");
- }
- else {
- pos_cursor(max(78-strlen(v_names[voice]),40), 4);
- printf("'%s'", v_names[voice]);
- }
- }
-
- /* show_screen: if 'screen' equals MAIN, display the main menu,
- otherwise display the edit menu */
- show_screen(screen)
- int screen;
- {
- scr_func(CLEAR_SCR);
- if (screen == MAIN) {
- printf("OPTIONS\n\r");
- printf("-------\n\r");
- printf("n = generate and load new voice\n\r");
- printf("s = save currently loaded [and edited] voice\n\r");
- printf("r = reload current voice\n\r");
- printf("l = load previously saved voice\n\r");
- printf("a = audition next voice in library\n\r");
- printf("w = change weirdness factor\n\r");
- printf("e = edit voice library\n\r");
- printf("f = find voice by name\n\r");
- printf("q = quit\n\r");
- printf("\n\rOption? ");
- show_weirdness();
- sprintf(out, "current voice # ");
- pos_cursor(80 - strlen(out), 3);
- printf("%s", out);
- show_voice(load_ptr);
- }
- else {
- printf("EDIT OPTIONS\n\r");
- printf("---- -------\n\r");
- printf("c = change voice name\n\r");
- printf("d = delete voice\n\r");
- printf("D = delete range of voices\n\r");
- printf("m = move voice\n\r");
- printf("M = move range of voices\n\r");
- printf("r = read in and append voices from alternate file\n\r");
- printf("x = execute changes and return to main menu\n\r");
- printf("q = quit edit menu, abandoning changes\n\r");
- printf("\n\rOption? ");
- }
- }
-
- /* list_voices: list the voice names and numbers available in the library */
- list_voices()
- {
- int i,j;
-
- pos_cursor(0,14);
- scr_func(ERASE_TO_EOP);
- for(i=0; i<cur_voice; i+=10){
- for(j=0; j<10; j++) {
- pos_cursor(0, 14+j);
- scr_func(CLEAR_TO_EOL);
- if (i+j < cur_voice)
- printf("[%3d] %s", i+j, v_names[i+j]);
- }
- printf("\n\r -- hit any key to ");
- printf("continue or ESC to ");
- printf("quit listing --");
- if ((char)Crawcin() == 27)
- break;
- }
- pos_cursor(0,14);
- scr_func(ERASE_TO_EOP);
- }
-
- /* edit: handle edit screen I/O and call appropiate subroutines */
- edit()
- {
- int i, j, e_voice, e_max, leng, name_valid, changed, target;
- int last_slash, main_drive, start, f_handle;
- long drv_map;
- char key, voice[TOTAL_SIZE], v_name[80];
- char pfname[80], path[80], file[20], main_path[80];
-
- changed = FALSE;
- do {
- pos_cursor(8, 3+EDIT_OPTIONS);
- scr_func(ERASE_TO_EOP);
- switch((int)(key = Crawcin())) {
- case 'c':
- case 'C':
- printf("c\n\r");
- e_voice = get_v_num(5+EDIT_OPTIONS);
- if (e_voice == ABORT) break;
- do {
- do {
- pos_cursor(0,6+EDIT_OPTIONS);
- scr_func(CLEAR_TO_EOL);
- printf("enter voice name: \007");
- printf("\n\r[ESC to abort]");
- pos_cursor(18, 6+EDIT_OPTIONS);
- leng = get_str(v_name);
- } while (leng == 0);
- if (leng < 0) break;
- name_valid = TRUE;
- for(i=0; i<leng; i++)
- if (v_name[i]<32 || v_name[i]>127) {
- printf("\n\rName has invalid ");
- printf("character in it - ");
- printf("re-try");
- name_valid = FALSE;
- break;
- }
- if (name_valid)
- for(i=0; i<cur_voice; i++) {
- if(!strcmp(v_names[i],v_name))
- {
- printf("\n\rThere is al");
- printf("ready a voice");
- printf(" named '%s'",
- v_name);
- printf(" - re-try");
- name_valid = FALSE;
- break;
- }
- }
- } while(name_valid == FALSE);
- if (leng < 0) break;
- #ifdef DX100
- strncpy(voices[e_voice]+77, v_name, 10);
- for(i=strlen(v_name); i<10; i++)
- voices[e_voice][77+i] = ' ';
- #endif
- strcpy(v_names[e_voice], v_name);
- changed = TRUE;
- break;
- case 'd':
- case 'D':
- printf("%c\n\r", key);
- if (key == 'd')
- printf("Delete voice...\n\r");
- else
- printf("Delete from voice...\n\r");
- e_voice = get_v_num(6+EDIT_OPTIONS);
- if (e_voice < 0) break;
- if (key == 'D') {
- printf("\n\r");
- scr_func(CLEAR_TO_EOL);
- printf("up through voice...\n\r");
- do {
- e_max = get_v_num(8+EDIT_OPTIONS);
- if (e_max >= 0 && e_max < e_voice) {
- sprintf( out,
- "\n\rLast voice number must be greater than first voice number [%d]",
- e_voice);
- warn(out);
- }
- } while (e_max >= 0 && e_max < e_voice);
- if (e_max < 0) break;
- } else e_max = e_voice;
- for (i = e_max+1; i < cur_voice; i++) {
- strcpy(v_names[e_voice + i - (e_max+1)],
- v_names[i]);
- voice_copy(voices[e_voice + i - (e_max+1)],
- voices[i]);
- }
- cur_voice -= e_max+1 - e_voice;
- changed = TRUE;
- break;
- case 'm':
- case 'M':
- printf("%c\n\r", key);
- if (key == 'm')
- printf("Move voice...\n\r");
- else
- printf("First voice to move...\n\r");
- e_voice = get_v_num(6+EDIT_OPTIONS);
- if (e_voice < 0) break;
- if (key == 'M') {
- printf("\n\r");
- scr_func(CLEAR_TO_EOL);
- printf("up through voice...\n\r");
- do {
- e_max = get_v_num(8+EDIT_OPTIONS);
- if (e_max >= 0 && e_max < e_voice) {
- sprintf( out,
- "\n\rLast voice number must be greater than first voice number [%d]",
- e_voice);
- warn(out);
- }
- } while (e_max >= 0 && e_max < e_voice);
- if (e_max < 0) break;
- } else e_max = e_voice;
- do {
- pos_cursor(0, 5+EDIT_OPTIONS);
- scr_func(ERASE_TO_EOP);
- if (e_max == e_voice)
- printf("move voice %d in front of voice...",
- e_voice);
- else
- printf("move voices %d to %d in front of voice...",
- e_voice, e_max);
- printf("\n\r(End of file is position %d)",
- cur_voice);
- strcpy(v_names[cur_voice++], "END OF FILE");
- target = get_v_num(7+EDIT_OPTIONS);
- cur_voice--;
- if (target > cur_voice) {
- sprintf(out,
- "\n\r\n\rhighest legal position is %d",
- cur_voice);
- warn(out);
- } else if (target > e_voice && target <= e_max){
- printf(
- "\n\r\n\rblock cannot be moved inside itself!");
- sprintf(out,
- "\n\rLegal ranges are from 0 to %d and from %d to %d",
- e_voice, e_max+1, cur_voice);
- warn(out);
- }
- } while (target > cur_voice ||
- target > e_voice && target <= e_max);
- if (target < 0) break;
- printf("\n\rMoving voice(s)...");
- for (i = e_voice; i < e_max+1; i++) {
- if (target > e_max) {
- strcpy(v_name, v_names[e_voice]);
- voice_copy(voice, voices[e_voice]);
- for (j = e_voice+1; j < target; j++) {
- strcpy(v_names[j-1],v_names[j]);
- voice_copy(voices[j-1],
- voices[j]);
- }
- strcpy(v_names[target-1], v_name);
- voice_copy(voices[target-1], voice);
- } else {
- strcpy(v_name, v_names[i]);
- voice_copy(voice, voices[i]);
- for (j = i-1; j >= target+i - e_voice;
- j--) {
- strcpy(v_names[j+1],v_names[j]);
- voice_copy(voices[j+1],
- voices[j]);
- }
- strcpy(v_names[target + i - e_voice],
- v_name);
- voice_copy(voices[target + i - e_voice],
- voice);
- }
- }
- changed = TRUE;
- break;
- case 'r':
- printf("r\n\r");
- Dgetpath(main_path, 0);
- drv_map = Dsetdrv(main_drive = Dgetdrv());
- do {
- name_valid = !E_OK;
- warn("Enter disk if necessary");
- pos_cursor(0, 5+EDIT_OPTIONS);
- scr_func(ERASE_TO_EOP);
- printf("[Drive:] Path/File name: ");
- printf("\n\r[ESC to abort]");
- pos_cursor(25, 5+EDIT_OPTIONS);
- if ((leng = get_str(pfname)) < 0) break;
- printf("\n\r");
- if (pfname[1] == ':') {
- if (pfname[0] >= 'a'
- && pfname[0] <= 'z')
- pfname[0] += 'A' - 'a';
- if (pfname[0] < 'A' || pfname[0] > 'Z'){
- warn("Bad drive; Drive letter must be in the range A-Z... re-try");
- continue;
- }
- if (!((1L<<(pfname[0]-'A')) & drv_map)){
- sprintf(out,
- "Bad drive; Drive '%c' not installed... re-try",
- pfname[0]);
- warn(out);
- continue;
- }
- Dsetdrv(pfname[0] - 'A');
- strcpy(pfname, &pfname[2]);
- }
- if (pfname[0] == '\\') {
- last_slash = 0;
- for (i=1; i < leng; i++)
- if (pfname[i] == '\\')
- last_slash = i;
- for (i=0; i<last_slash; i++)
- path[i] = pfname[i];
- path[last_slash] = '\0';
- Dsetpath(path);
- strcpy(file, &pfname[last_slash+1]);
- }
- else strcpy(file, pfname);
- if ((name_valid = Fsfirst(file, 0)) != E_OK)
- printf("'%s' not found, re-try...\n\r",
- pfname);
- else printf("'%s' found...", pfname);
- } while (name_valid != E_OK);
- if (leng < 0) break;
- if ((f_handle = Fopen(file, READ)) < 0) {
- sprintf(out,
- "Cannot open '%s' for reading -- aborting...",
- pfname);
- warn(out);
- break;
- }
- printf("reading in voice data\n\r");
- while(TRUE) {
- if (cur_voice+1 >= VOICES) {
- sprintf(out,
- "voices number limit reached (%d) -- file read aborted",
- VOICES);
- warn(out);
- break;
- }
- if (scan_name(f_handle, v_names[cur_voice])
- != OK) break;
- if (strlen(v_names[cur_voice]) > 0) {
- if (scan_voice(f_handle,
- voices[cur_voice]) != OK) break;
- cur_voice++;
- }
- else break;
- }
- Fclose(f_handle);
- changed = TRUE;
- warn("Re-insert original disk if necessary");
- Dsetdrv(main_drive);
- Dsetpath(main_path);
- break;
- case 'x':
- case 'X':
- printf("x\n\r");
- if (changed && save_edit() < 0) break;
- else key = 'q';
- break;
- case 'q':
- case 'Q':
- printf("q\n\r");
- if (!changed) break;
- printf("Restoring library to pre-edit state from disk\n\r");
- get_voices(v_names, voices);
- break;
- default:
- printf("\007");
- printf("Bad option '%c' - re-try", key);
- break;
- }
- } while (key != 'q' && key != 'Q');
- }
-
- /* save_edit: save the edited voice library, returning a success/failure code */
- int
- save_edit()
- {
- long needed_space, lib_size(), *fsize;
- unsigned char response;
-
- needed_space = lib_size();
- while (Fsfirst(VOICE_FILE, 0) != E_OK) {
- printf("'%s' not found.\n\r", VOICE_FILE);
- warn("Please insert voice disk.");
- }
- fsize = Fgetdta() + 26;
- if (*fsize + cur_space >= needed_space) {
- return(dump_voices());
- }
- else {
- do {
- printf("\n\rNot enough room on disk to save ");
- printf("file\n\rDo you have a formatted disk ");
- printf("with at least %ld free bytes \n\r",
- needed_space);
- printf("\tavailable to insert (y/n)? ");
- if ((response = Crawcin()) == 'y') {
- printf("y\n\r");
- warn("Insert disk");
- check_disk();
- if (Fsfirst(VOICE_FILE, 0) == E_OK) {
- fsize = Fgetdta() + 26;
- } else {
- fsize = Fgetdta() + 26;
- *fsize = 0;
- }
- if (cur_space + *fsize > needed_space) {
- return(dump_voices());
- break;
- }
- } else {
- printf("n\n\r");
- printf("Aborting save...\n\r");
- printf("It is recommended that you ");
- printf("quit out of this program and ");
- printf("\n\rcreate enough space on a ");
- printf("disk to save the file as ");
- printf("desired\n\r");
- printf("Hit any key to continue...");
- wait();
- break;
- }
- } while ((response = Crawcin()) == 'y');
- }
- }
-
- /* lib_size: return the size of the voice library (in bytes) */
- long
- lib_size()
- {
- int i;
- long size;
-
- for (i=0, size=0; i < cur_voice; i++) {
- size += strlen(v_names[i]) + 1;
- size += TOTAL_SIZE;
- }
- return(size);
- }
-
- /* search: search the voice library names for a match with 's_str', handling
- special cases in 's_str', starting from voice 'from' */
- int
- search(s_str, from)
- char *s_str;
- int from;
- {
- int found, target_len;
- char ps_str[80], rs_str[80], ss_str[80], srs_str[80];
-
- if (extract(s_str, ps_str, rs_str) == NULL) return(from);
- for (found=from; found < cur_voice; found++) {
- if (substr(v_names[found], ps_str)) {
- strcpy(srs_str, rs_str);
- do {
- if (extract(srs_str, ss_str, srs_str) == NULL)
- return(found);
- } while (substr(v_names[found], ss_str));
- }
- }
- return(found);
- }
-
- /* extract: break string 'raw_str' into an initial search string ('fs_str')
- and a remnant string ('rs_str') returning NULL if 'raw_str' is empty,
- !NULL otherwise */
- int
- extract(raw_str, fs_str, rs_str)
- char *raw_str, *fs_str, *rs_str;
- {
- if (*raw_str == '\0') return(NULL);
- if (*raw_str == AND_CHAR) *raw_str++;
- while (*raw_str != '\0' && *raw_str != AND_CHAR)
- *fs_str++ = *raw_str++;
- *fs_str = '\0';
- while ((*rs_str++ = *raw_str++) != '\0');
- return(!NULL);
- }
-
- /* substr: determine if pattern 'pattern' exists in string 'field',
- returning TRUE if so, FALSE otherwise */
- int
- substr(field, pattern)
- char *field, *pattern;
- {
- int i, reps, leng;
-
- if ((leng = strlen(pattern)) == 0) return(TRUE);
- reps = strlen(field) - leng;
- for (i=0; i <= reps; i++)
- if (!strncmp(field+i, pattern, leng)) return(TRUE);
- return(FALSE);
- }
-
- /* check_disk: determine free space on disk */
- check_disk()
- {
- struct { long free_c, tot_c, sec_siz, sec_in_c; } disk_info;
-
- printf("checking disk usage\n\r");
- Dfree(&disk_info, 0);
- cur_space = disk_info.free_c * disk_info.sec_in_c * disk_info.sec_siz;
- }
-
- /* dump_voices: actually write the voice library to disk, an error *should*
- not be possible at this point. Nonetheless, a success/failure code
- is returned */
- int
- dump_voices()
- {
- int f_handle, i;
- long f_start_leng, offset, incr;
- char response;
-
- if (Fsfirst(VOICE_FILE, 0) != E_OK) f_start_leng = 0;
- else {
- f_start_leng = *(long *)(Fgetdta() + 26);
- Fdelete(VOICE_FILE);
- printf("'%s' deleted\n\r", VOICE_FILE);
- }
- do {
- if ((f_handle = Fcreate(VOICE_FILE, 0)) < 0) {
- printf("Cannot create voice file.\n\r");
- printf("Ensure disk is inserted and ");
- printf("not write protected.\n\r");
- printf("Re-try (y/n)? ");
- if ((response = Crawcin()) == 'y') {
- printf("y\n\r");
- continue;
- } else {
- printf("n\n\r");
- sprintf(out,
- "'%s' deleted/not found and current voices NOT saved!",
- VOICE_FILE);
- warn(out);
- return(BAD);
- }
- } else {
- printf("'%s' created.\n\r", VOICE_FILE);
- Fclose(f_handle);
- }
- } while (f_handle < 0);
- f_handle = Fopen(VOICE_FILE, READ_WRITE);
- if (f_handle < 0) {
- sprintf(out, "Cannot open '%s' -- Aborting save", VOICE_FILE);
- warn(out);
- return(BAD);
- }
- printf("'%s' opened for reading/writing...\n\r", VOICE_FILE);
- pos_cursor(0, 24);
- printf("Saving voice number ");
- for (i = 0, offset = 0; i < cur_voice; i++) {
- pos_cursor(20, 24);
- scr_func(CLEAR_TO_EOL);
- printf("%d", i);
- incr = strlen(v_names[i]) + 1;
- if (Fwrite(f_handle, incr, v_names[i]) < incr)
- error("Unknown write error on voice file - bye!");
- offset += incr;
- if (Fwrite(f_handle, (long) TOTAL_SIZE, voices[i]) < 0)
- error("Unknown write error on voice file - bye!");
- offset += TOTAL_SIZE;
- }
- cur_space += f_start_leng;
- cur_space -= offset;
- Fclose(f_handle);
- return(OK);
- }
-
- /* get_v_num: interact with the user to get a voice number and return it
- (putting prompts at screen line 'curs_y') */
- int
- get_v_num(curs_y)
- int curs_y;
- {
- int v_num;
-
- do {
- pos_cursor(0,curs_y);
- scr_func(CLEAR_TO_EOL);
- printf("enter voice number: \n\r");
- printf("[ESC to abort, RETURN to list, voices 0-%d available]",
- cur_voice-1);
- pos_cursor(20, curs_y);
- if ((v_num = get_num()) == NULL)
- list_voices();
- if (v_num == BAD)
- printf("\n\r\n\rBad input - re-try");
- } while (v_num != ABORT &&
- (v_num < 0 || v_num >= cur_voice));
- return(v_num);
- }
-
- /* func: call the appropiate voice parameter determining function and
- return its value */
- int
- func(i,b)
- int i,b;
- {
- switch(types[i][b]) {
- case 1:
- return(high(ranges[i], tries[i][b]));
- break;
- case 2:
- return(mid(ranges[i], tries[i][b]));
- break;
- case 3:
- default:
- return(low(ranges[i], tries[i][b]));
- break;
- }
- }
-
- /* get_roll: determine whether func should be called with a normal or
- weird value and return what func returns */
- int
- get_roll(a)
- int a;
- {
- if (Effect) return(func(a,0));
- else return(func(a,1));
- }
-
- /* voice_copy: copy voice 'v2' into voice 'v1' */
- voice_copy(v1, v2)
- char *v1, *v2;
- {
- int i;
-
- for (i=0; i<TOTAL_SIZE; i++) *v1++ = *v2++;
- }
-
- #ifdef DX100
- /* round: return the nearest integral frequency ratio to ratio 'freq' */
- int
- round(freq)
- int freq;
- {
- if (freq < 2) return(0);
- if (freq < 6) return(4);
- if (freq < 9) return(8);
- if (freq < 12) return(10);
- if (freq < 15) return(13);
- if (freq < 18) return(16);
- if (freq < 21) return(19);
- if (freq < 24) return(22);
- if (freq < 27) return(25);
- if (freq < 30) return(28);
- if (freq < 33) return(31);
- if (freq < 36) return(34);
- if (freq < 38) return(36);
- if (freq < 41) return(40);
- if (freq < 45) return(42);
- if (freq < 64) return(45);
- return(4);
- }
- #endif
- ə