libkmid Library API Documentation

midimapper.cc

00001 /************************************************************************** 00002 00003 midimapper.cc - The midi mapper object 00004 This file is part of LibKMid 0.9.5 00005 Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez 00006 LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libkmid.html 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Library General Public 00010 License as published by the Free Software Foundation; either 00011 version 2 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Library General Public License for more details. 00017 00018 You should have received a copy of the GNU Library General Public License 00019 along with this library; see the file COPYING.LIB. If not, write to 00020 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00021 Boston, MA 02111-1307, USA. 00022 00023 Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org> 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]; /* Longer than t and 'AllKeysTo' */ 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 }
KDE Logo
This file is part of the documentation for libkmid Library Version 3.2.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 20 09:49:47 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003