00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include "midimapper.h"
00027
#include <stdio.h>
00028
#include <string.h>
00029
#include <stdlib.h>
00030
#ifdef HAVE_CONFIG_H
00031
#include <config.h>
00032
#endif
00033
00034 MidiMapper::MidiMapper(
const char *name)
00035 {
00036 _ok=1;
00037 keymaps=NULL;
00038 _filename=NULL;
00039 mapPitchBender=0;
00040 mapExpressionToVolumeEvents=0;
00041
if ((name==NULL)||(name[0]==0))
00042 {
00043 deallocateMaps();
00044
int i;
00045
for (i=0;i<16;i++)
00046 {
00047 channelmap[i]=i;
00048 channelPatchForced[i]=-1;
00049 }
00050
for (i=0;i<128;i++) patchmap[i]=i;
00051 }
00052
else
00053
loadFile(name);
00054 }
00055
00056 MidiMapper::~MidiMapper()
00057 {
00058
if (_filename) free(_filename);
00059 deallocateMaps();
00060 }
00061
00062
void MidiMapper::deallocateMaps(
void)
00063 {
00064
int i;
00065
for (i=0;i<16;i++) channelKeymap[i]=NULL;
00066
for (i=0;i<128;i++) patchKeymap[i]=NULL;
00067 Keymap *km;
00068
while (keymaps!=NULL)
00069 {
00070 km=keymaps->next;
00071
delete keymaps;
00072 keymaps=km;
00073 }
00074 }
00075
00076
void MidiMapper::getValue(
char *s,
char *v)
00077 {
00078
char *c=s;
00079
while ((*c!=0)&&(*c!=
'=')) c++;
00080
if (*c==0) v[0]=0;
00081
else
00082 {
00083 c++;
00084
while (*c!=0)
00085 {
00086 *v=*c;
00087 c++;v++;
00088 }
00089 *v=0;
00090 }
00091 }
00092
00093
void MidiMapper::removeSpaces(
char *s)
00094 {
00095
char *a=s;
00096
while ((*a!=0)&&(*a==
' ')) a++;
00097
if (*a==0) {*s=0;
return;};
00098
while (*a!=0)
00099 {
00100
while ((*a!=0)&&(*a!=
' ')&&(*a!=10)&&(*a!=13))
00101 {
00102 *s=*a;
00103 s++;
00104 a++;
00105 }
00106
while ((*a!=0)&&((*a==
' ')||(*a==10)||(*a==13))) a++;
00107 *s=
' ';s++;
00108
if (*a==0) {*s=0;
return;};
00109 }
00110 *s=0;
00111
00112 }
00113
00114
int MidiMapper::countWords(
char *s)
00115 {
00116
int c=0;
00117
while (*s!=0)
00118 {
00119
if (*s==
' ') c++;
00120 s++;
00121 }
00122
return c;
00123 }
00124
00125
void MidiMapper::getWord(
char *t,
char *s,
int w)
00126 {
00127
int i=0;
00128 *t=0;
00129
while ((*s!=0)&&(i<w))
00130 {
00131
if (*s==
' ') i++;
00132 s++;
00133 }
00134
while ((*s!=0)&&(*s!=
' ')&&(*s!=10)&&(*s!=13))
00135 {
00136 *t=*s;
00137 t++;s++;
00138 }
00139 *t=0;
00140 }
00141
00142
00143 void MidiMapper::loadFile(
const char *name)
00144 {
00145 _ok=1;
00146 FILE *fh = fopen(name,
"rt");
00147
if ( fh == NULL ) { _ok = -1;
return; };
00148
char s[101];
00149 s[0] = 0;
00150
if ( _filename != NULL ) free(_filename);
00151 _filename = strdup(name);
00152
#ifdef MIDIMAPPERDEBUG
00153
printf(
"Loading mapper ...\n");
00154
#endif
00155
while (!feof(fh))
00156 {
00157 s[0]=0;
00158
while ((!feof(fh))&&((s[0]==0)||(s[0]==
'#'))) fgets(s,100,fh);
00159
if (strncmp(s,
"DEFINE",6)==0)
00160 {
00161
if (strncmp(&s[7],
"PATCHMAP",8)==0) readPatchmap(fh);
00162
else
00163
if (strncmp(&s[7],
"KEYMAP",6)==0) readKeymap(fh,s);
00164
else
00165
if (strncmp(&s[7],
"CHANNELMAP",10)==0) readChannelmap(fh);
00166
else
00167 {
00168 printf(
"ERROR: Unknown DEFINE line in map file\n");
00169 _ok=0;
00170 }
00171
if (_ok==0)
00172 {
00173 printf(
"The midi map file will be ignored\n");
00174 fclose(fh);
00175
return;
00176 }
00177 }
00178
else if (strncmp(s,
"OPTIONS",7)==0) readOptions(fh);
00179 }
00180 fclose(fh);
00181 }
00182
00183 MidiMapper::Keymap *MidiMapper::createKeymap(
char *name,uchar use_same_note,uchar note)
00184 {
00185 Keymap *km=
new Keymap;
00186 strncpy(km->name, name, KM_NAME_SIZE);
00187 km->name[KM_NAME_SIZE - 1] = 0;
00188
00189
int i;
00190
if (use_same_note==1)
00191 {
00192
for (i=0;i<128;i++)
00193 km->key[i]=note;
00194 }
00195
else
00196 {
00197
for (i=0;i<128;i++)
00198 km->key[i]=i;
00199 }
00200 addKeymap(km);
00201
return km;
00202 }
00203
00204
void MidiMapper::addKeymap(Keymap *newkm)
00205 {
00206 Keymap *km=keymaps;
00207
if (keymaps==NULL)
00208 {
00209 keymaps=newkm;
00210 newkm->next=NULL;
00211
return;
00212 }
00213
while (km->next!=NULL) km=km->next;
00214 km->next=newkm;
00215 newkm->next=NULL;
00216
return;
00217 }
00218
00219 MidiMapper::Keymap *MidiMapper::keymap(
char *n)
00220 {
00221 Keymap *km=keymaps;
00222
while ((km!=NULL)&&(strcmp(km->name,n)!=0)) km=km->next;
00223
return km;
00224 }
00225
00226
void MidiMapper::readOptions(FILE *fh)
00227 {
00228
#ifdef MIDIMAPPERDEBUG
00229
printf(
"Loading Options ... \n");
00230
#endif
00231
char s[101];
00232
char v[101];
00233
char t[101];
00234
int fin=0;
00235 mapPitchBender=0;
00236
while (!fin)
00237 {
00238 s[0]=0;
00239
while ((s[0]==0)||(s[0]==
'#')) fgets(s,100,fh);
00240
if (strncmp(s,
"PitchBenderRatio",16)==0)
00241 {
00242 getValue(s,v);
00243 removeSpaces(v);
00244 getWord(t,v,0);
00245 mapPitchBender=1;
00246 pitchBenderRatio=atoi(t);
00247 }
00248
else if (strncmp(s,
"MapExpressionToVolumeEvents",27)==0) mapExpressionToVolumeEvents=1;
00249
else if (strncmp(s,
"END",3)==0)
00250 {
00251 fin=1;
00252 }
00253
else
00254 {
00255 printf(
"ERROR: Invalid option in OPTIONS section of map file : (%s)\n",s);
00256 _ok=0;
00257
return;
00258 }
00259 }
00260 }
00261
00262
void MidiMapper::readPatchmap(FILE *fh)
00263 {
00264
char s[101];
00265
char v[101];
00266
char t[101];
00267
char name[256];
00268
int i=0;
00269
int j,w;
00270
#ifdef MIDIMAPPERDEBUG
00271
printf(
"Loading Patch map ... \n");
00272
#endif
00273
while (i<128)
00274 {
00275 s[0]=0;
00276
while ((s[0]==0)||(s[0]==
'#')) fgets(s,100,fh);
00277 getValue(s,v);
00278 removeSpaces(v);
00279 w=countWords(v);
00280 j=0;
00281 patchKeymap[i]=NULL;
00282 patchmap[i]=i;
00283
while (j<w)
00284 {
00285 getWord(t,v,j);
00286
if (strcmp(t,
"AllKeysTo")==0)
00287 {
00288 j++;
00289
if (j>=w)
00290 {
00291 printf(
"ERROR: Invalid option in PATCHMAP section of map file\n");
00292 _ok=0;
00293
return;
00294 }
00295 getWord(t,v,j);
00296 sprintf(name,
"AllKeysTo%s",t);
00297 patchKeymap[i]=createKeymap(name,1,atoi(t));
00298 }
00299
else
00300 {
00301 patchmap[i]=atoi(t);
00302 }
00303 j++;
00304 }
00305 i++;
00306 }
00307 s[0]=0;
00308
while ((s[0]==0)||(s[0]==
'#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh);
00309
if (strncmp(s,
"END",3)!=0)
00310 {
00311 printf(
"ERROR: End of section not found in map file\n");
00312 _ok=0;
00313
return;
00314 }
00315 }
00316
00317
void MidiMapper::readKeymap(FILE *fh,
char *first_line)
00318 {
00319
char s[101];
00320
char v[101];
00321
#ifdef MIDIMAPPERDEBUG
00322
printf(
"Loading Key map ... %s",first_line);
00323
#endif
00324
removeSpaces(first_line);
00325 getWord(v,first_line,2);
00326 Keymap *km=
new Keymap;
00327 strncpy(km->name, v, KM_NAME_SIZE);
00328 km->name[KM_NAME_SIZE - 1] = 0;
00329
00330
int i=0;
00331
while (i<128)
00332 {
00333 s[0]=0;
00334
while ((s[0]==0)||(s[0]==
'#')) fgets(s,100,fh);
00335 getValue(s,v);
00336 removeSpaces(v);
00337 km->key[i]=atoi(v);
00338 i++;
00339 }
00340 s[0]=0;
00341
while ((s[0]==0)||(s[0]==
'#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh);
00342
if (strncmp(s,
"END",3)!=0)
00343 {
00344 printf(
"ERROR: End of section not found in map file\n");
00345 _ok=0;
00346
return;
00347 }
00348 addKeymap(km);
00349 }
00350
00351
void MidiMapper::readChannelmap(FILE *fh)
00352 {
00353
char s[101];
00354
char v[101];
00355
char t[101];
00356
int i=0;
00357
int w,j;
00358
#ifdef MIDIMAPPERDEBUG
00359
printf(
"Loading Channel map ... \n");
00360
#endif
00361
while (i<16)
00362 {
00363 s[0]=0;
00364
while ((s[0]==0)||(s[0]==
'#')) fgets(s,100,fh);
00365 getValue(s,v);
00366 removeSpaces(v);
00367 w=countWords(v);
00368 j=0;
00369 channelKeymap[i]=NULL;
00370 channelPatchForced[i]=-1;
00371 channelmap[i]=i;
00372
while (j<w)
00373 {
00374 getWord(t,v,j);
00375
if (strcmp(t,
"Keymap")==0)
00376 {
00377 j++;
00378
if (j>=w)
00379 {
00380 printf(
"ERROR: Invalid option in CHANNELMAP section of map file\n");
00381 _ok=0;
00382
return;
00383 }
00384 getWord(t,v,j);
00385 channelKeymap[i]=keymap(t);
00386 }
00387
else if (strcmp(t,
"ForcePatch")==0)
00388 {
00389 j++;
00390
if (j>=w)
00391 {
00392 printf(
"ERROR: Invalid option in CHANNELMAP section of map file\n");
00393 _ok=0;
00394
return;
00395 }
00396 getWord(t,v,j);
00397 channelPatchForced[i]=atoi(t);
00398 }
00399
else
00400 {
00401 channelmap[i]=atoi(t);
00402 }
00403 j++;
00404 }
00405 i++;
00406 }
00407 s[0]=0;
00408
while ((s[0]==0)||(s[0]==
'#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh);
00409
if (strncmp(s,
"END",3)!=0)
00410 {
00411 printf(
"END of section not found in map file\n");
00412 _ok=0;
00413
return;
00414 }
00415
00416 }
00417
00418 const char *
MidiMapper::filename(
void)
00419 {
00420
return (_filename)? _filename :
"";
00421 }
00422
00423 uchar
MidiMapper::key(uchar chn,uchar pgm, uchar note)
00424 {
00425 uchar notemapped=note;
00426
if (patchKeymap[pgm]!=NULL) notemapped=patchKeymap[pgm]->key[note];
00427
if (channelKeymap[chn]!=NULL) notemapped=channelKeymap[chn]->key[note];
00428
return notemapped;
00429 }
00430
00431 uchar
MidiMapper::patch(uchar chn,uchar pgm)
00432 {
00433
return (channelPatchForced[chn] == -1) ?
00434 patchmap[pgm] : (uchar)channelPatchForced[chn] ;
00435 }
00436
00437 void MidiMapper::pitchBender(uchar ,uchar &lsb,uchar &msb)
00438 {
00439
if (mapPitchBender)
00440 {
00441
short pbs=((
short)msb<<7) | (lsb & 0x7F);
00442 pbs=pbs-0x2000;
00443
short pbs2=(((
long)pbs*pitchBenderRatio)/4096);
00444
#ifdef MIDIMAPPERDEBUG
00445
printf(
"Pitch Bender (%d): %d -> %d \n",chn,pbs,pbs2);
00446
#endif
00447
pbs2=pbs2+0x2000;
00448 lsb=pbs2 & 0x7F;
00449 msb=(pbs2 >> 7)&0x7F;
00450 }
00451 }
00452
00453 void MidiMapper::controller(uchar ,uchar &ctl, uchar &)
00454 {
00455
if ((mapExpressionToVolumeEvents)&&(ctl==11)) ctl=7;
00456 }