• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • libtdemid
 

libtdemid

  • libtdemid
midimapper.cpp
1 /**************************************************************************
2 
3  midimapper.cpp - The midi mapper object
4  This file is part of LibKMid 0.9.5
5  Copyright (C) 1997,98,99,2000 Antonio Larrosa Jimenez
6  LibKMid's homepage : http://www.arrakis.es/~rlarrosa/libtdemid.html
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Library General Public
10  License as published by the Free Software Foundation; either
11  version 2 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  Library General Public License for more details.
17 
18  You should have received a copy of the GNU Library General Public License
19  along with this library; see the file COPYING.LIB. If not, write to
20  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21  Boston, MA 02110-1301, USA.
22 
23  Send comments and bug fixes to Antonio Larrosa <larrosa@kde.org>
24 
25 ***************************************************************************/
26 #include "midimapper.h"
27 #include <stdio.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 MidiMapper::MidiMapper(const char *name)
35 {
36  _ok=1;
37  keymaps=NULL;
38  _filename=NULL;
39  mapPitchBender=0;
40  mapExpressionToVolumeEvents=0;
41  if ((name==NULL)||(name[0]==0))
42  {
43  deallocateMaps();
44  int i;
45  for (i=0;i<16;i++)
46  {
47  channelmap[i]=i;
48  channelPatchForced[i]=-1;
49  }
50  for (i=0;i<128;i++) patchmap[i]=i;
51  }
52  else
53  loadFile(name);
54 }
55 
56 MidiMapper::~MidiMapper()
57 {
58  if (_filename) free(_filename);
59  deallocateMaps();
60 }
61 
62 void MidiMapper::deallocateMaps(void)
63 {
64  int i;
65  for (i=0;i<16;i++) channelKeymap[i]=NULL;
66  for (i=0;i<128;i++) patchKeymap[i]=NULL;
67  Keymap *km;
68  while (keymaps!=NULL)
69  {
70  km=keymaps->next;
71  delete keymaps;
72  keymaps=km;
73  }
74 }
75 
76 void MidiMapper::getValue(char *s,char *v)
77 {
78  char *c=s;
79  while ((*c!=0)&&(*c!='=')) c++;
80  if (*c==0) v[0]=0;
81  else
82  {
83  c++;
84  while (*c!=0)
85  {
86  *v=*c;
87  c++;v++;
88  }
89  *v=0;
90  }
91 }
92 
93 void MidiMapper::removeSpaces(char *s)
94 {
95  char *a=s;
96  while ((*a!=0)&&(*a==' ')) a++;
97  if (*a==0) {*s=0;return;};
98  while (*a!=0)
99  {
100  while ((*a!=0)&&(*a!=' ')&&(*a!=10)&&(*a!=13))
101  {
102  *s=*a;
103  s++;
104  a++;
105  }
106  while ((*a!=0)&&((*a==' ')||(*a==10)||(*a==13))) a++;
107  *s=' ';s++;
108  if (*a==0) {*s=0;return;};
109  }
110  *s=0;
111 
112 }
113 
114 int MidiMapper::countWords(char *s)
115 {
116  int c=0;
117  while (*s!=0)
118  {
119  if (*s==' ') c++;
120  s++;
121  }
122  return c;
123 }
124 
125 void MidiMapper::getWord(char *t,char *s,int w)
126 {
127  int i=0;
128  *t=0;
129  while ((*s!=0)&&(i<w))
130  {
131  if (*s==' ') i++;
132  s++;
133  }
134  while ((*s!=0)&&(*s!=' ')&&(*s!=10)&&(*s!=13))
135  {
136  *t=*s;
137  t++;s++;
138  }
139  *t=0;
140 }
141 
142 
143 void MidiMapper::loadFile(const char *name)
144 {
145  _ok=1;
146  FILE *fh = fopen(name,"rt");
147  if ( fh == NULL ) { _ok = -1; return; };
148  char s[101];
149  s[0] = 0;
150  if ( _filename != NULL ) free(_filename);
151  _filename = strdup(name);
152 #ifdef MIDIMAPPERDEBUG
153  printf("Loading mapper ...\n");
154 #endif
155  while (!feof(fh))
156  {
157  s[0]=0;
158  while ((!feof(fh))&&((s[0]==0)||(s[0]=='#'))) fgets(s,100,fh);
159  if (strncmp(s,"DEFINE",6)==0)
160  {
161  if (strncmp(&s[7],"PATCHMAP",8)==0) readPatchmap(fh);
162  else
163  if (strncmp(&s[7],"KEYMAP",6)==0) readKeymap(fh,s);
164  else
165  if (strncmp(&s[7],"CHANNELMAP",10)==0) readChannelmap(fh);
166  else
167  {
168  printf("ERROR: Unknown DEFINE line in map file\n");
169  _ok=0;
170  }
171  if (_ok==0)
172  {
173  printf("The midi map file will be ignored\n");
174  fclose(fh);
175  return;
176  }
177  }
178  else if (strncmp(s,"OPTIONS",7)==0) readOptions(fh);
179  }
180  fclose(fh);
181 }
182 
183 MidiMapper::Keymap *MidiMapper::createKeymap(char *name,uchar use_same_note,uchar note)
184 {
185  Keymap *km=new Keymap;
186  strncpy(km->name, name, KM_NAME_SIZE);
187  km->name[KM_NAME_SIZE - 1] = 0;
188 
189  int i;
190  if (use_same_note==1)
191  {
192  for (i=0;i<128;i++)
193  km->key[i]=note;
194  }
195  else
196  {
197  for (i=0;i<128;i++)
198  km->key[i]=i;
199  }
200  addKeymap(km);
201  return km;
202 }
203 
204 void MidiMapper::addKeymap(Keymap *newkm)
205 {
206  Keymap *km=keymaps;
207  if (keymaps==NULL)
208  {
209  keymaps=newkm;
210  newkm->next=NULL;
211  return;
212  }
213  while (km->next!=NULL) km=km->next;
214  km->next=newkm;
215  newkm->next=NULL;
216  return;
217 }
218 
219 MidiMapper::Keymap *MidiMapper::keymap(char *n)
220 {
221  Keymap *km=keymaps;
222  while ((km!=NULL)&&(strcmp(km->name,n)!=0)) km=km->next;
223  return km;
224 }
225 
226 void MidiMapper::readOptions(FILE *fh)
227 {
228 #ifdef MIDIMAPPERDEBUG
229  printf("Loading Options ... \n");
230 #endif
231  char s[101];
232  char v[101];
233  char t[101];
234  int fin=0;
235  mapPitchBender=0;
236  while (!fin)
237  {
238  s[0]=0;
239  while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh);
240  if (strncmp(s,"PitchBenderRatio",16)==0)
241  {
242  getValue(s,v);
243  removeSpaces(v);
244  getWord(t,v,0);
245  mapPitchBender=1;
246  pitchBenderRatio=atoi(t);
247  }
248  else if (strncmp(s,"MapExpressionToVolumeEvents",27)==0) mapExpressionToVolumeEvents=1;
249  else if (strncmp(s,"END",3)==0)
250  {
251  fin=1;
252  }
253  else
254  {
255  printf("ERROR: Invalid option in OPTIONS section of map file : (%s)\n",s);
256  _ok=0;
257  return;
258  }
259  }
260 }
261 
262 void MidiMapper::readPatchmap(FILE *fh)
263 {
264  char s[101];
265  char v[101];
266  char t[101];
267  char name[256]; /* Longer than t and 'AllKeysTo' */
268  int i=0;
269  int j,w;
270 #ifdef MIDIMAPPERDEBUG
271  printf("Loading Patch map ... \n");
272 #endif
273  while (i<128)
274  {
275  s[0]=0;
276  while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh);
277  getValue(s,v);
278  removeSpaces(v);
279  w=countWords(v);
280  j=0;
281  patchKeymap[i]=NULL;
282  patchmap[i]=i;
283  while (j<w)
284  {
285  getWord(t,v,j);
286  if (strcmp(t,"AllKeysTo")==0)
287  {
288  j++;
289  if (j>=w)
290  {
291  printf("ERROR: Invalid option in PATCHMAP section of map file\n");
292  _ok=0;
293  return;
294  }
295  getWord(t,v,j);
296  sprintf(name,"AllKeysTo%s",t);
297  patchKeymap[i]=createKeymap(name,1,atoi(t));
298  }
299  else
300  {
301  patchmap[i]=atoi(t);
302  }
303  j++;
304  }
305  i++;
306  }
307  s[0]=0;
308  while ((s[0]==0)||(s[0]=='#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh);
309  if (strncmp(s,"END",3)!=0)
310  {
311  printf("ERROR: End of section not found in map file\n");
312  _ok=0;
313  return;
314  }
315 }
316 
317 void MidiMapper::readKeymap(FILE *fh,char *first_line)
318 {
319  char s[101];
320  char v[101];
321 #ifdef MIDIMAPPERDEBUG
322  printf("Loading Key map ... %s",first_line);
323 #endif
324  removeSpaces(first_line);
325  getWord(v,first_line,2);
326  Keymap *km=new Keymap;
327  strncpy(km->name, v, KM_NAME_SIZE);
328  km->name[KM_NAME_SIZE - 1] = 0;
329 
330  int i=0;
331  while (i<128)
332  {
333  s[0]=0;
334  while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh);
335  getValue(s,v);
336  removeSpaces(v);
337  km->key[i]=atoi(v);
338  i++;
339  }
340  s[0]=0;
341  while ((s[0]==0)||(s[0]=='#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh);
342  if (strncmp(s,"END",3)!=0)
343  {
344  printf("ERROR: End of section not found in map file\n");
345  _ok=0;
346  return;
347  }
348  addKeymap(km);
349 }
350 
351 void MidiMapper::readChannelmap(FILE *fh)
352 {
353  char s[101];
354  char v[101];
355  char t[101];
356  int i=0;
357  int w,j;
358 #ifdef MIDIMAPPERDEBUG
359  printf("Loading Channel map ... \n");
360 #endif
361  while (i<16)
362  {
363  s[0]=0;
364  while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh);
365  getValue(s,v);
366  removeSpaces(v);
367  w=countWords(v);
368  j=0;
369  channelKeymap[i]=NULL;
370  channelPatchForced[i]=-1;
371  channelmap[i]=i;
372  while (j<w)
373  {
374  getWord(t,v,j);
375  if (strcmp(t,"Keymap")==0)
376  {
377  j++;
378  if (j>=w)
379  {
380  printf("ERROR: Invalid option in CHANNELMAP section of map file\n");
381  _ok=0;
382  return;
383  }
384  getWord(t,v,j);
385  channelKeymap[i]=keymap(t);
386  }
387  else if (strcmp(t,"ForcePatch")==0)
388  {
389  j++;
390  if (j>=w)
391  {
392  printf("ERROR: Invalid option in CHANNELMAP section of map file\n");
393  _ok=0;
394  return;
395  }
396  getWord(t,v,j);
397  channelPatchForced[i]=atoi(t);
398  }
399  else
400  {
401  channelmap[i]=atoi(t);
402  }
403  j++;
404  }
405  i++;
406  }
407  s[0]=0;
408  while ((s[0]==0)||(s[0]=='#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh);
409  if (strncmp(s,"END",3)!=0)
410  {
411  printf("END of section not found in map file\n");
412  _ok=0;
413  return;
414  }
415 
416 }
417 
418 const char *MidiMapper::filename(void)
419 {
420  return (_filename)? _filename : "";
421 }
422 
423 uchar MidiMapper::key(uchar chn,uchar pgm, uchar note)
424 {
425  uchar notemapped=note;
426  if (patchKeymap[pgm]!=NULL) notemapped=patchKeymap[pgm]->key[note];
427  if (channelKeymap[chn]!=NULL) notemapped=channelKeymap[chn]->key[note];
428  return notemapped;
429 }
430 
431 uchar MidiMapper::patch(uchar chn,uchar pgm)
432 {
433  return (channelPatchForced[chn] == -1) ?
434  patchmap[pgm] : (uchar)channelPatchForced[chn] ;
435 }
436 
437 void MidiMapper::pitchBender(uchar ,uchar &lsb,uchar &msb)
438 {
439  if (mapPitchBender)
440  {
441  short pbs=((short)msb<<7) | (lsb & 0x7F);
442  pbs=pbs-0x2000;
443  short pbs2=(((long)pbs*pitchBenderRatio)/4096);
444 #ifdef MIDIMAPPERDEBUG
445  printf("Pitch Bender (%d): %d -> %d \n",chn,pbs,pbs2);
446 #endif
447  pbs2=pbs2+0x2000;
448  lsb=pbs2 & 0x7F;
449  msb=(pbs2 >> 7)&0x7F;
450  }
451 }
452 
453 void MidiMapper::controller(uchar ,uchar &ctl, uchar &)
454 {
455  if ((mapExpressionToVolumeEvents)&&(ctl==11)) ctl=7;
456 }
MidiMapper::MidiMapper
MidiMapper(const char *name)
Constructor.
Definition: midimapper.cpp:34
MidiMapper::controller
void controller(uchar chn, uchar &ctl, uchar &v)
Returns the value which a given controller and its value should be mapped to when played on channel c...
Definition: midimapper.cpp:453
MidiMapper::patch
uchar patch(uchar chn, uchar pgm)
Returns the patch which pgm used on channel chn should be mapped to.
Definition: midimapper.cpp:431
MidiMapper::key
uchar key(uchar chn, uchar pgm, uchar note)
Returns the key that key note playing a pgm patch on channel chn should be mapped to.
Definition: midimapper.cpp:423
MidiMapper::loadFile
void loadFile(const char *name)
Loads a MIDI Mapper definition file (you don't need to use this if you used a correct filename in con...
Definition: midimapper.cpp:143
MidiMapper::filename
const char * filename(void)
Returns the path and name of the file which the object loaded the mapper from.
Definition: midimapper.cpp:418
MidiMapper::pitchBender
void pitchBender(uchar chn, uchar &lsb, uchar &msb)
Returns the value which the pitch bender on channel chn should be mapped to.
Definition: midimapper.cpp:437
MidiMapper::~MidiMapper
~MidiMapper()
Destructor.
Definition: midimapper.cpp:56
TDEStdAccel::name
TQString name(StdAccel id)

libtdemid

Skip menu "libtdemid"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

libtdemid

Skip menu "libtdemid"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for libtdemid by doxygen 1.9.1
This website is maintained by Timothy Pearson.