www.pudn.com > gspmidi101src.zip > timidity.c
/* TiMidity -- Experimental MIDI to WAVE converter Copyright (C) 1995 Tuukka ToivonenThis program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /*<95GUI_MODIF_BEGIN>*/ /* 5 modifications performed on this file Nicolas Witczak juin 1996 */ /*<95GUI_MODIF_END>*/ #include #include #ifndef _WIN32_WCE #include #endif #ifdef RC_NONE /* the one */ #undef RC_NONE /* remove it before including controls.h */ #endif #include "config.h" #include "common.h" #include "instrum.h" #include "playmidi.h" #include "readmidi.h" #include "output.h" #include "tables.h" int free_instruments_afterwards=0; char def_instr_name[256]=""; static int set_channel_flag(int32 *flags, int32 i, char *name) { if (i==0) *flags=0; else if ((i<1 || i>16) && (i<-16 || i>-1)) { fprintf(stderr, "%s must be between 1 and 16, or between -1 and -16, or 0\n", name); return -1; } else { if (i>0) *flags |= (1<<(i-1)); else *flags &= ~ ((1<<(-1-i))); } return 0; } static int set_value(int32 *param, int32 i, int32 low, int32 high, char *name) { if (i high) { fprintf(stderr, "%s must be between %ld and %ld\n", name, low, high); return -1; } else *param=i; return 0; } static int set_play_mode(char *cp) { PlayMode *pmp, **pmpp=play_mode_list; while ((pmp=*pmpp++)) { if (pmp->id_character == *cp) { play_mode=pmp; while (*(++cp)) switch(*cp) { case 'U': pmp->encoding |= PE_ULAW; break; /* uLaw */ case 'l': pmp->encoding &= ~PE_ULAW; break; /* linear */ case '1': pmp->encoding |= PE_16BIT; break; /* 1 for 16-bit */ case '8': pmp->encoding &= ~PE_16BIT; break; case 'M': pmp->encoding |= PE_MONO; break; case 'S': pmp->encoding &= ~PE_MONO; break; /* stereo */ case 's': pmp->encoding |= PE_SIGNED; break; case 'u': pmp->encoding &= ~PE_SIGNED; break; case 'x': pmp->encoding ^= PE_BYTESWAP; break; /* toggle */ default: fprintf(stderr, "Unknown format modifier `%c'\n", *cp); return 1; } return 0; } } fprintf(stderr, "Playmode `%c' is not compiled in.\n", *cp); return 1; } #define MAXWORDS 10 int read_config_file(char *name) { FILE *fp; char tmp[1024], *w[MAXWORDS], *cp; ToneBank *bank=0; int i, j, k, line=0, words; static int rcf_count=0; if (rcf_count>50) { //fprintf(stderr, "Probable source loop in configuration files"); return (-1); } if (!(fp=open_file(name, 1, OF_VERBOSE))) return -1; while (fgets(tmp, sizeof(tmp), fp)) { line++; w[words=0]=strtok(tmp, " \t\r\n\240"); if (!w[0] || (*w[0]=='#')) continue; while (w[words] && (words < MAXWORDS)) w[++words]=strtok(0," \t\r\n\240"); if (!strcmp(w[0], "dir")) { if (words < 2) { fprintf(stderr, "%s: line %d: No directory given\n", name, line); return -2; } #if 1 tmp[0] = '\0'; for (i=1; i 127) { fprintf(stderr, "%s: line %d: Drum set must be between 0 and 127\n", name, line); return -2; } if (!drumset[i]) { drumset[i]=safe_malloc(sizeof(ToneBank)); memset(drumset[i], 0, sizeof(ToneBank)); } bank=drumset[i]; } else if (!strcmp(w[0], "bank")) { if (words < 2) { fprintf(stderr, "%s: line %d: No bank number given\n", name, line); return -2; } i=atoi(w[1]); if (i<0 || i>127) { fprintf(stderr, "%s: line %d: Tone bank must be between 0 and 127\n", name, line); return -2; } if (!tonebank[i]) { tonebank[i]=safe_malloc(sizeof(ToneBank)); memset(tonebank[i], 0, sizeof(ToneBank)); } bank=tonebank[i]; } else { if ((words < 2) || (*w[0] < '0' || *w[0] > '9')) { fprintf(stderr, "%s: line %d: syntax error\n", name, line); return -2; } i=atoi(w[0]); if (i<0 || i>127) { fprintf(stderr, "%s: line %d: Program must be between 0 and 127\n", name, line); return -2; } if (!bank) { fprintf(stderr, "%s: line %d: Must specify tone bank or drum set " "before assignment\n", name, line); return -2; } if (bank->tone[i].name) free(bank->tone[i].name); strcpy((bank->tone[i].name=safe_malloc(strlen(w[1])+1)),w[1]); bank->tone[i].note=bank->tone[i].amp=bank->tone[i].pan= bank->tone[i].strip_loop=bank->tone[i].strip_envelope= bank->tone[i].strip_tail=-1; for (j=2; j MAX_AMPLIFICATION) k = MAX_AMPLIFICATION; if ((k<0 || k>MAX_AMPLIFICATION) || (*cp < '0' || *cp > '9')) { fprintf(stderr, "%s: line %d: amplification must be between " "0 and %d\n", name, line, MAX_AMPLIFICATION); return -2; } bank->tone[i].amp=k; } else if (!strcmp(w[j], "note")) { k=atoi(cp); if ((k<0 || k>127) || (*cp < '0' || *cp > '9')) { fprintf(stderr, "%s: line %d: note must be between 0 and 127\n", name, line); return -2; } bank->tone[i].note=k; } else if (!strcmp(w[j], "pan")) { if (!strcmp(cp, "center")) k=64; else if (!strcmp(cp, "left")) k=0; else if (!strcmp(cp, "right")) k=127; else k=((atoi(cp)+100) * 100) / 157; if ((k<0 || k>127) || (k==0 && *cp!='-' && (*cp < '0' || *cp > '9'))) { fprintf(stderr, "%s: line %d: panning must be left, right, " "center, or between -100 and 100\n", name, line); return -2; } bank->tone[i].pan=k; } else if (!strcmp(w[j], "keep")) { if (!strcmp(cp, "env")) bank->tone[i].strip_envelope=0; else if (!strcmp(cp, "loop")) bank->tone[i].strip_loop=0; else { fprintf(stderr, "%s: line %d: keep must be env or loop\n", name, line); return -2; } } else if (!strcmp(w[j], "strip")) { if (!strcmp(cp, "env")) bank->tone[i].strip_envelope=1; else if (!strcmp(cp, "loop")) bank->tone[i].strip_loop=1; else if (!strcmp(cp, "tail")) bank->tone[i].strip_tail=1; else { fprintf(stderr, "%s: line %d: strip must be env, loop, or tail\n", name, line); return -2; } } else { fprintf(stderr, "%s: line %d: bad patch option %s\n", name, line, w[j]); return -2; } } } } if (ferror(fp)) { #if 0 fprintf(stderr, "Can't read %s: %s\n", name, sys_errlist[errno]); #else fprintf(stderr, "Can't read %s\n", name); #endif close_file(fp); return -2; } close_file(fp); return 0; }