Beispiel #1
0
/* be_midi_key_on:
 *  Triggers a specified voice.
 */
extern "C" void be_midi_key_on(int inst, int note, int bend, int vol, int pan)
{
   int voice;
   
   if (inst > 127) {
      /* percussion */
      
      /* hack to use channel 10 only */
      midi_beos.xmin = midi_beos.xmax = -1;
      voice = _midi_allocate_voice(10, 10);
      midi_beos.xmin = midi_beos.xmax = 10;
      
      if (voice < 0)
         return;
      cur_note[10] = inst - 128;
      cur_vol[10] = vol;
      be_midi_set_pan(voice, pan);
      _be_midisynth->NoteOn(10, inst - 128, vol, B_NOW);
   }
   else {
      /* normal instrument */
      voice = _midi_allocate_voice(1, 16);
      if (voice < 0)
         return;
      if (inst != cur_patch[voice]) {
         _be_midisynth->ProgramChange(voice, inst);
         cur_patch[voice] = inst;
      }
 
      cur_note[voice] = note;
      cur_vol[voice] = vol;
      be_midi_set_pitch(voice, note, bend);
      be_midi_set_pan(voice, pan);
      _be_midisynth->NoteOn(voice, note, vol, B_NOW);
   }
}
Beispiel #2
0
/* _awe32_do_note:
 *  Actually plays the note as described above; the above function just remaps
 *  the drums.
 */
static void _awe32_do_note(int inst, int note, int bend, int vol, int pan) {
 int voice;
 int i;
 envparms_t *env;
 int key,vel;
 int atten;
 int pan_pos;

 /* EMU8000 pan is back-to-front and twice the scale */
 pan = 0x100-2*pan;
 if (pan>0xff) pan = 0xff;
 if (pan<0x00) pan = 0x00;

 for (i=0;i<midi_preset[inst].num_splits;i++) {
  /* envelope for this split */
  env=midi_preset[inst].split[i];

  /* should we play this split? */
  if ((note>=env->minkey)&&(note<=env->maxkey)&&( vol>=env->minvel)&&( vol<=env->maxvel)) {

   /* get a voice (any voice) to play it on */
   voice = _midi_allocate_voice (-1,-1);

   /* did we get one? */
   if (voice>=0) {

    /* set the current envelope for this voice */
    voice_envelope[voice]=env;

    /* set pitch and velocity */
    key = note*0x1000+bend;
    vel = vol;

    /* override key and velocity if envelope says so */
    if ((env->key>=0)&&(env->key<=127)) key=env->key*0x1000;
    if ((env->vel>=0)&&(env->vel<=127)) vel=env->vel;

    /* check key and velocity numbers are within range */
    if (key>0x7ffff) key=0x7ffff;
    if (key<0) key=0;
    if (vel>127) vel=127;
    if (vel<0) vel=0;

    /* add one-off information to the envelope (these have no side-effects on the other voices using this envelope) */
    env->ip=env->ipbase+(env->ipscale*key)/1200;

    /* remap MIDI velocity to attenuation */
    if (vel)
     atten = env->atten + (-20/0.375*log(vel/127.0));
    else
     atten = 0xff;
    if (atten<0x00) atten = 0x00;
    if (atten>0xff) atten = 0xff;

    /* update it in the envelope */
    env->ifatn=env->filter+atten;

    /* modify pan with envelope's built-in pan */
    if (pan<0x80) {
     pan_pos = (pan*env->pan)/0x80;
    } else {
     pan_pos = env->pan + (pan-0x80)*(256-env->pan)/0x80;
    }
    if (pan_pos<0x00) pan_pos=0x00;
    if (pan_pos>0xff) pan_pos=0xff;

    /* update pan in the envelope */
    env->psst = (pan_pos<<24) + env->loopst;

    /* test exclusive class */
    exclusive_class_info[voice] = (inst << 8) + env->exc;

    if (env->exc) {
     int chan;
     for (chan = 0; chan < 32; chan++)
      if ((chan != voice) && (exclusive_class_info[chan] == exclusive_class_info[voice]))
       emu8k_terminatesound (chan);
    }

    /* start the note playing */
    emu8k_startsound(voice,env);

   }
  }
 }
}