• 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
34MidiMapper::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
56MidiMapper::~MidiMapper()
57{
58 if (_filename) free(_filename);
59 deallocateMaps();
60}
61
62void 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
76void 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
93void 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
114int 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
125void 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
143void 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
183MidiMapper::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
204void 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
219MidiMapper::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
226void 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
262void 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
317void 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
351void 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
418const char *MidiMapper::filename(void)
419{
420 return (_filename)? _filename : "";
421}
422
423uchar 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
431uchar MidiMapper::patch(uchar chn,uchar pgm)
432{
433 return (channelPatchForced[chn] == -1) ?
434 patchmap[pgm] : (uchar)channelPatchForced[chn] ;
435}
436
437void 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
453void 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.4
This website is maintained by Timothy Pearson.