Source Code (Use browser search to find items of interest.)

Class Index

kdelibs'MidiMapper (./kdelibs/libkmid/midimapper.h:56)

class MidiMapper
{
  private:
    class MidiMapperPrivate;
    MidiMapperPrivate *d;

    /**
     * @internal
     * Internal definition for Keymaps
     */
    struct Keymap
    {
      char name[30];
      uchar key[128];
      struct Keymap *next;
    };

    int	_ok;

    uchar	channelmap[16]; 
    /**
     * @internal
     * It's a pointer to the Keymap to use for a channel
     * This variable is used to get faster a given Keymap
     * The index is the real channel (after mapping it)
     */
    Keymap *channelKeymap[16]; 

    /**
     * @internal
     * It's -1 if the channel doesn't have a forced patch,
     * else indicates the patch to force in the channel.
     */
    int	channelPatchForced[16]; 

    uchar	patchmap[128];

    /**
     * @internal
     * Same as channelKeymap
     */ 
    Keymap *patchKeymap[128];

    /**
     * @internal
     * Real linked list of keymaps used around the class.
     */
    Keymap *keymaps; 

    /**
     * @internal
     * Stores the name of the file from which the map was loaded
     */
    char *_filename; 

    /**
     * @internal
     * Simulate expression events with volume events
     */
    int mapExpressionToVolumeEvents; 

    /**
     * @internal
     * Map or not the Pitch Bender using @ref #pitchBenderRatio()
     */
    int mapPitchBender;

    /**
     * @internal
     * Indicates the ratio between the standard and the synthesizer's pitch
     * bender engine. The number sent to the synth is multiplied by this
     * and dividied by 4096. Thus if PitchBenderRatio is 4096, the synth's
     * pitch bender works as the standard one
     */
    int pitchBenderRatio; 

    void getValue(char *s,char *v);
    void removeSpaces(char *s);
    int  countWords(char *s);
    void getWord(char *t,char *s,int w); 
    // get from s the word in position  w and store it in t

    void deallocateMaps(void);
    Keymap *createKeymap(char *name,uchar use_same_note=0,uchar note=0);
    void readPatchmap(FILE *fh);
    void readKeymap(FILE *fh,char *first_line);
    void readChannelmap(FILE *fh);
    void readOptions(FILE *fh);

    void addKeymap(Keymap *newkm);
    Keymap *keymap(char *n);

  public:
    /**
     * Constructor. Loads a MIDI Mapper definition from a file.
     * @see #filename()
     */
    MidiMapper(const char *name);

    /**
     * Destructor.
     */
    ~MidiMapper();

    /**
     * Loads a MIDI Mapper definition file (you don't need to use this if you
     * used a correct filename in constructor). 
     */
    void loadFile(const char *name);	

    /**
     * Returns the status of the object.
     */
    int  ok(void) { return _ok; };

    /** 
     * Returns the channel which chn should be mapped to.
     */ 
    uchar channel(uchar chn) { return channelmap[chn];};

    /** 
     * Returns the patch which pgm used on channel chn should be mapped to.
     */ 
    uchar patch(uchar chn,uchar pgm);

    /** 
     * Returns the key that key note playing a pgm patch on channel chn should
     * be mapped to.
     */ 
    uchar key(uchar chn,uchar pgm, uchar note);

    /**
     * Returns the value which the pitch bender on channel chn should be
     * mapped to.
     */
    void  pitchBender(uchar chn,uchar &lsb,uchar &msb);

    /**
     * Returns the value which a given controller and its value should
     * be mapped to when played on channel chn.
     */ 
    void  controller(uchar chn,uchar &ctl,uchar &v);

    /**
     * Returns the path and name of the file which the object loaded the
     * mapper from.
     */
    char *filename(void);

};

kdelibs'MidiMapper::MidiMapper() (./kdelibs/libkmid/midimapper.cc:34)

MidiMapper::MidiMapper(const char *name)
{
  _ok=1;
  keymaps=NULL;
  _filename=NULL;
  mapPitchBender=0;
  mapExpressionToVolumeEvents=0;
  if ((name==NULL)||(name[0]==0))
  {
    deallocateMaps();    
    int i;
    for (i=0;i<16;i++) 
    {
      channelmap[i]=i;
      channelPatchForced[i]=-1;
    }
    for (i=0;i<128;i++) patchmap[i]=i;
  }
  else
    loadFile(name);
}


kdelibs'MidiMapper::~MidiMapper() (./kdelibs/libkmid/midimapper.cc:56)

MidiMapper::~MidiMapper()
{
  if (_filename!=NULL) delete _filename;
  deallocateMaps();
}


kdelibs'MidiMapper::deallocateMaps() (./kdelibs/libkmid/midimapper.cc:62)

void MidiMapper::deallocateMaps(void)
{
  int i;
  for (i=0;i<16;i++) channelKeymap[i]=NULL;
  for (i=0;i<128;i++) patchKeymap[i]=NULL;
  Keymap *km;
  while (keymaps!=NULL)
  {
    km=keymaps->next;
    delete keymaps;
    keymaps=km;
  }
}


kdelibs'MidiMapper::getValue() (./kdelibs/libkmid/midimapper.cc:76)

void MidiMapper::getValue(char *s,char *v)
{
  char *c=s;
  while ((*c!=0)&&(*c!='=')) c++;
  if (c==0) v[0]=0;
  else
  {
    c++;
    while (*c!=0)
    {
      *v=*c;
      c++;v++;
    }
    *v=0;
  }
}


kdelibs'MidiMapper::removeSpaces() (./kdelibs/libkmid/midimapper.cc:93)

void MidiMapper::removeSpaces(char *s)
{
  char *a=s;
  while ((*a!=0)&&(*a==' ')) a++;
  if (*a==0) {*s=0;return;};
  while (*a!=0)
  {
    while ((*a!=0)&&(*a!=' ')&&(*a!=10)&&(*a!=13))    
    {
      *s=*a;
      s++;
      a++;
    }
    while ((*a!=0)&&((*a==' ')||(*a==10)||(*a==13))) a++;
    *s=' ';s++;
    if (*a==0) {*s=0;return;};
  }
  *s=0;

}


kdelibs'MidiMapper::countWords() (./kdelibs/libkmid/midimapper.cc:114)

int MidiMapper::countWords(char *s)
{
  int c=0;
  while (*s!=0)
  {
    if (*s==' ') c++;
    s++;
  }
  return c;
}


kdelibs'MidiMapper::getWord() (./kdelibs/libkmid/midimapper.cc:125)

void MidiMapper::getWord(char *t,char *s,int w)
{
  int i=0;
  *t=0;
  while ((*s!=0)&&(i<w))
  {
    if (*s==' ') i++;
    s++;
  }
  while ((*s!=0)&&(*s!=' ')&&(*s!=10)&&(*s!=13))
  {
    *t=*s;
    t++;s++;
  }
  *t=0;
}



kdelibs'MidiMapper::loadFile() (./kdelibs/libkmid/midimapper.cc:143)

void MidiMapper::loadFile(const char *name)
{
  _ok=1;
  FILE *fh = fopen(name,"rt");
  if ( fh == NULL ) { _ok = -1; return; };
  char s[101];
  s[0] = 0;
  if ( _filename != NULL ) delete _filename;
  _filename = new char[ strlen(name)+1 ];
  strcpy(_filename,name);
#ifdef MIDIMAPPERDEBUG
  printf("Loading mapper ...\n");
#endif
  while (!feof(fh))
  {
    s[0]=0;
    while ((!feof(fh))&&((s[0]==0)||(s[0]=='#'))) fgets(s,100,fh);
    if (strncmp(s,"DEFINE",6)==0)
    {
      if (strncmp(&s[7],"PATCHMAP",8)==0) readPatchmap(fh);
      else
	if (strncmp(&s[7],"KEYMAP",6)==0) readKeymap(fh,s);
	else
	  if (strncmp(&s[7],"CHANNELMAP",10)==0) readChannelmap(fh);
	  else
	  {
	    printf("ERROR: Unknown DEFINE line in map file\n");
	    _ok=0;
	  }
      if (_ok==0)
      {
	printf("The midi map file will be ignored\n");
	fclose(fh);
	return;
      }
    }
    else if (strncmp(s,"OPTIONS",7)==0) readOptions(fh);	
  }
  fclose(fh);
}

MidiMapper::Keymap *MidiMapper::createKeymap(char *name,uchar use_same_note,uchar note)
{
  Keymap *km=new Keymap;
  strcpy(km->name,name);
  int i;
  if (use_same_note==1)
  {
    for (i=0;i<128;i++)
      km->key[i]=note;
  }
  else
  {
    for (i=0;i<128;i++)
      km->key[i]=i;
  }
  addKeymap(km);
  return km;
}


kdelibs'MidiMapper::addKeymap() (./kdelibs/libkmid/midimapper.cc:203)

void MidiMapper::addKeymap(Keymap *newkm)
{
  Keymap *km=keymaps;
  if (keymaps==NULL)
  {
    keymaps=newkm;
    newkm->next=NULL;
    return;
  }
  while (km->next!=NULL) km=km->next;
  km->next=newkm;
  newkm->next=NULL;
  return;
}

MidiMapper::Keymap *MidiMapper::keymap(char *n)
{
  Keymap *km=keymaps;
  while ((km!=NULL)&&(strcmp(km->name,n)!=0)) km=km->next;
  return km;
}


kdelibs'MidiMapper::readOptions() (./kdelibs/libkmid/midimapper.cc:225)

void MidiMapper::readOptions(FILE *fh)
{
#ifdef MIDIMAPPERDEBUG
  printf("Loading Options ... \n");
#endif
  char s[101];
  char v[101];
  char t[101];
  int fin=0;
  mapPitchBender=0;
  while (!fin)
  {
    s[0]=0;
    while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh);
    if (strncmp(s,"PitchBenderRatio",16)==0) 
    {
      getValue(s,v);
      removeSpaces(v);
      getWord(t,v,0);
      mapPitchBender=1;
      pitchBenderRatio=atoi(t);
    }
    else if (strncmp(s,"MapExpressionToVolumeEvents",27)==0) mapExpressionToVolumeEvents=1;
    else if (strncmp(s,"END",3)==0) 
    {
      fin=1;
    }
    else 
    {
      printf("ERROR: Invalid option in OPTIONS section of map file : (%s)\n",s);
      _ok=0;
      return;
    }
  }
}


kdelibs'MidiMapper::readPatchmap() (./kdelibs/libkmid/midimapper.cc:261)

void MidiMapper::readPatchmap(FILE *fh)
{
  char s[101];
  char v[101];
  char t[101];
  char name[101];
  int i=0;
  int j,w;
#ifdef MIDIMAPPERDEBUG
  printf("Loading Patch map ... \n");
#endif
  while (i<128)
  {
    s[0]=0;
    while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh);
    getValue(s,v);
    removeSpaces(v);
    w=countWords(v);
    j=0;
    patchKeymap[i]=NULL;
    patchmap[i]=i;
    while (j<w)
    {
      getWord(t,v,j);
      if (strcmp(t,"AllKeysTo")==0)
      {
	j++;
	if (j>=w) 
	{
	  printf("ERROR: Invalid option in PATCHMAP section of map file\n");
	  _ok=0;
	  return;
	}
	getWord(t,v,j);
	sprintf(name,"AllKeysTo%s",t);
	patchKeymap[i]=createKeymap(name,1,atoi(t));
      }
      else
      {
	patchmap[i]=atoi(t);
      }
      j++;
    }
    i++;
  }
  s[0]=0;
  while ((s[0]==0)||(s[0]=='#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh);
  if (strncmp(s,"END",3)!=0)
  {
    printf("ERROR: End of section not found in map file\n");
    _ok=0;
    return;
  }
}


kdelibs'MidiMapper::readKeymap() (./kdelibs/libkmid/midimapper.cc:316)

void MidiMapper::readKeymap(FILE *fh,char *first_line)
{
  char s[101];
  char v[101];
#ifdef MIDIMAPPERDEBUG
  printf("Loading Key map ... %s",first_line);
#endif
  removeSpaces(first_line);
  getWord(v,first_line,2);
  Keymap *km=new Keymap;
  strcpy(km->name,v);
  int i=0;
  while (i<128)
  {
    s[0]=0;
    while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh);
    getValue(s,v);
    removeSpaces(v);
    km->key[i]=atoi(v);
    i++;
  }
  s[0]=0;
  while ((s[0]==0)||(s[0]=='#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh);
  if (strncmp(s,"END",3)!=0)
  {
    printf("ERROR: End of section not found in map file\n");
    _ok=0;
    return;
  }
  addKeymap(km);
}


kdelibs'MidiMapper::readChannelmap() (./kdelibs/libkmid/midimapper.cc:348)

void MidiMapper::readChannelmap(FILE *fh)
{
  char s[101];
  char v[101];
  char t[101];
  int i=0;
  int w,j;
#ifdef MIDIMAPPERDEBUG
  printf("Loading Channel map ... \n");
#endif
  while (i<16)
  {
    s[0]=0;
    while ((s[0]==0)||(s[0]=='#')) fgets(s,100,fh);
    getValue(s,v);
    removeSpaces(v);
    w=countWords(v);
    j=0;
    channelKeymap[i]=NULL;
    channelPatchForced[i]=-1;
    channelmap[i]=i;
    while (j<w)
    {
      getWord(t,v,j);
      if (strcmp(t,"Keymap")==0)
      {
	j++;
	if (j>=w) 
	{
	  printf("ERROR: Invalid option in CHANNELMAP section of map file\n");
	  _ok=0;
	  return;
	}
	getWord(t,v,j);
	channelKeymap[i]=keymap(t); 
      }
      else if (strcmp(t,"ForcePatch")==0)
      {
	j++;
	if (j>=w) 
	{
	  printf("ERROR: Invalid option in CHANNELMAP section of map file\n");
	  _ok=0;
	  return;
	}
	getWord(t,v,j);
	channelPatchForced[i]=atoi(t); 
      }
      else
      {
	channelmap[i]=atoi(t); 
      }
      j++;
    }
    i++;
  }
  s[0]=0;
  while ((s[0]==0)||(s[0]=='#')||(s[0]==10)||(s[0]==13)) fgets(s,100,fh);
  if (strncmp(s,"END",3)!=0)
  {
    printf("END of section not found in map file\n");
    _ok=0;
    return;
  }

}


kdelibs'MidiMapper::filename() (./kdelibs/libkmid/midimapper.cc:415)

char *MidiMapper::filename(void)
{
  return (_filename!=NULL)? _filename : (char *)"";
}


kdelibs'MidiMapper::key() (./kdelibs/libkmid/midimapper.cc:420)

uchar MidiMapper::key(uchar chn,uchar pgm, uchar note)
{
  uchar notemapped=note;
  if (patchKeymap[pgm]!=NULL) notemapped=patchKeymap[pgm]->key[note];
  if (channelKeymap[chn]!=NULL) notemapped=channelKeymap[chn]->key[note];
  return notemapped;
}


kdelibs'MidiMapper::patch() (./kdelibs/libkmid/midimapper.cc:428)

uchar MidiMapper::patch(uchar chn,uchar pgm)
{
  return (channelPatchForced[chn] == -1) ? 
    patchmap[pgm] : (uchar)channelPatchForced[chn] ;
}


kdelibs'MidiMapper::pitchBender() (./kdelibs/libkmid/midimapper.cc:434)

void MidiMapper::pitchBender(uchar ,uchar &lsb,uchar &msb)
{
  if (mapPitchBender)
  {
    short pbs=((short)msb<<7) | (lsb & 0x7F);
    pbs=pbs-0x2000;
    short pbs2=(((long)pbs*pitchBenderRatio)/4096);
#ifdef MIDIMAPPERDEBUG
    printf("Pitch Bender (%d): %d -> %d \n",chn,pbs,pbs2);
#endif
    pbs2=pbs2+0x2000;
    lsb=pbs2 & 0x7F;
    msb=(pbs2 >> 7)&0x7F;  
  }
}


kdelibs'MidiMapper::controller() (./kdelibs/libkmid/midimapper.cc:450)

void MidiMapper::controller(uchar ,uchar &ctl, uchar &)
{
  if ((mapExpressionToVolumeEvents)&&(ctl==11)) ctl=7;
}