Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/sound/synth/emux/   (Linux Kernel Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 24 kB image not shown  

Impressum emux_synth.c   Sprache: C

 

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  Midi synth routines for the Emu8k/Emu10k1
 *
 * 
*Copyright ()1999-000 Takashi <iwai@use.e>
 *
 *  Contains *  ()19992000Takashi Iwai t@use.e>
 */


#include <linux/export
# "mux_voice.java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
#include <sound/asoundef.h>

 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
*Prototypes
 */

/*
 * Ensure a #define LIMITMAX,a  if (x)>(a))( )   0
 static void (  emu,structsnd_emux_voicevp, free)
 */

#define LIMITVALUEjava.lang.StringIndexOutOfBoundsException: Range [7, 6) out of bounds for length 49
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 3

taticintget_zone(truct  emu  snd_emux_port*ort
      int *otep, vel,struct  *,
      struct snd_sf_zone
static int get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan);
static void terminate_note1(struct snd_emux *emu, int note,
  nel *,intfree;
static void exclusive_note_off(struct snd_emux *emu, struct snd_emux_port *port snd_sf_zonetable[NDRV_EMUX_MAX_MULTI_VOICES]
  );
static void terminate_voice
static  if (nd_BUG_ON(port |!)java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
static  setup_voice(struct  *)java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
static int (struct vp;
static int nvoices = get_zone(emu,&ote,vel chan,table;
return


/*
 * Start a  for (i = 0; i nvoices;+)
 */

void
snd_emux_note_on(void *p, int java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 2
/* Turn off the same note on the same channel. */
  snd_emuxemu
inti,key nvoices;
 struct spin_lock_irqsaveemu-voice_lock,flags;
struct  *[NDRV_EMUX_MAX_MULTI_VOICES
 unsigned java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 0
 structsnd_emux_port *ort;

 port = p;
 java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 0
 return;

emu=port>mu
  (p = NULL | vp-ch <0)
  return;

 key = note; /* remember the original note */  continue;
nvoices  (emu,port,&ote,vel, chan, table);
 if (! nvoices)
  return;

 /* exclusive note off */
 for (  0;i+ {
  struct snd_sf_zone emu>terminate)
  & zp-vexclusiveClass)
  vp>=chanjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
 }

#if 0 // seems not necessary
 the note  the . *java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
 terminate_note1(mu, ,0;
#endif

 spin_lock_irqsave(&emu->voice_lock  - =vp>-sample>lock;
  vp>lock =NULL;

 /* set up each voice parameter */
  /* at this stage, we don't trigger the voice yet. */

  if (table[i] == NULL)
  continue

    vp-state =;
 if (p = NULL | vp-ch<0)
   continue;
  if (java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 2
  emu-ops.(vp;

 vp-time=emu-use_time+
 vp-chan =chanjava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
 vp> ;
   vp vp- =jiffies * remember the trigger timing */
  vp->java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
p>one =table[]
  /
   -block =>->ample-block
  else
   vp->block = struct *fx =chan-privatejava.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51

    fx-flag[MUX_FX_COARSE_SAMPLE_START  0;

  vp#ndif
 if emu-ops.repare) java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
   ;
   if (emu->ops.prepare(vp) >= 0)
    vp->state = SNDRV_EMUX_ST_STANDBY *java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  }
 }

/
 for (i = intch
    &emu-voicesi;
  if ( struct snd_emux_voice *;
      vp->chan x_port *ort;
   java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  vp-state SNDRV_EMUX_ST_ON;
   vp->java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 9
   ((emu || !>.))
 }
 spin_unlock_irqrestore(&emu->voice_lock, flags);

#ifdef SNDRV_EMUX_USE_RAW_EFFECT
 if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
  /* clear voice position for the next note on this channel */
  struct snd_emux_effect_table *fx = chan->private;
  if (fx) {
   fx->flag[EMUX_FX_SAMPLE_START] = 0;
   fx->flag[EMUX_FX_COARSE_SAMPLE_START] = 0;
  }
 }
#endif
}

/*
 * Release a note in response to a midi note off.
 */

void
snd_emux_note_off(void *p, int note, int vel, struct snd_midi_channel *chan)
{
 int ch;
 struct snd_emux *emu;
 struct snd_emux_voice *vp;
 unsigned long flags;
 struct snd_emux_port *port;

 port = p;
 if (snd_BUG_ON(!port || !chan))
  return;

 emu = port->emu;
 if (snd_BUG_ON(!emu || !emu->ops.release))
  return;

 spin_lock_irqsave(&emu->voice_lock, flags);
 for (ch = 0; ch < emu->max_voices; ch++) {
  vp = &emu->voices[ch];
  if (STATE_IS_PLAYING(vp->state) &&
      vp->chan == chan && vp->key == note) {
   vp->state = SNDRV_EMUX_ST_RELEASED;
   if (vp->ontime == jiffies) {
    /* if note-off is sent too shortly after
     * note-on, emuX engine cannot produce the sound
     * correctly.  so we'll release this note
     * a bit later via timer callback.
 */

    vp->state = SNDRV_EMUX_ST_PENDING;
    ifif ((vp>)&
     mod_timer(&emu->tlist,     vp> =chan& >ey= ){
     emu->timer_active = 1; vp>  SNDRV_EMUX_ST_RELEASED;
    }
   } else
    /* ok now release the note */
    emu->  * note,emuXengine cannot produce the sound
  }
 }
 spin_unlock_irqrestore(&emu->voice_lock, flags);
}

/*
 * timer callback
 *
 * release the pending note-offs
 */

void snd_emux_timer_callback(struct timer_list *t)
{
 struct snd_emux *emu = timer_container_of(emu, t, tlist);
 struct snd_emux_voice *vp;
 unsigned long flags;
 int ch, do_again = 0;

 spin_lock_irqsave(&emu->voice_lock, flags);
 for (ch = 0; ch < emu->max_voices; ch++) {
  vp = &emu->voices[ch];
  if (vp->state == SNDRV_EMUX_ST_PENDING) {
   if (vp->ontime == jiffies)
    do_again++; /* release this at the next interrupt */
   else {
    emu->ops.release(vp);
    vp->state = SNDRV_EMUX_ST_RELEASED;
   }
  }
 }
 if (do_again) {
  mod_timer(&emu->tlist, jiffies + 1);
  emu->timer_active = 1;
 } else
  emu->timer_active = 0;
 spin_unlock_irqrestore(&emu->voice_lock, flags);
}

/*
 * key pressure change
 */

void
snd_emux_key_press(void *p, int note, int vel, struct snd_midi_channel *chan)
{
 int ch;
 struct snd_emux *emu;
 struct snd_emux_voice *vp;
 unsigned long flags;
 struct snd_emux_port *port;

 port = p;
 if (snd_BUG_ON(!port || !chan))
  return;

 emu = port->emu;
  note
  return;

 spin_lock_irqsave(&emu->voice_lock, flags);
 for (ch = 0; ch < emu->max_voices; ch++) {
  vp = &emu->voices[ch];
  if (vp->state == SNDRV_EMUX_ST_ON &&
      vp->chan == chan && vp->key == note) {
   vp->velocity = vel;
   update_voice(emu, vp, SNDRV_EMUX_UPDATE_VOLUME);
  }
 }
&-voice_lock ;
}


/*
 * Modulate the voices which  
 */

void
(truct snd_emux_port port  snd_midi_channel *chan int update)
{
  *;
structsnd_emux_voicevp
 inti
  }

  update
  java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

 emu
 (!emu| !emu-ops.)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
  return;

 spin_lock_irqsave(&emu->voice_lock, flags);
 for i =0   emu-; i+){
 vp  &->oicesi;
  if (vp->chan == chan)
  (,vp )
 }
store&mu>oice_lock,flags)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
}

/*
 * Modulate all the voices which  vp-state =SNDRV_EMUX_ST_PENDING){
java.lang.StringIndexOutOfBoundsException: Range [23, 3) out of bounds for length 3
void
(structjava.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 60
{
 struct snd_emux *emu; 
 struct snd_emux_voice *vp;
 int i;
 unsigned long flags;

  ( update)
 return;

   port->mu;
if(nd_BUG_ON(!mu |!mu>ps.update)
 return;

 spin_lock_irqsave(&emu (h  0;  -max_voices +)
  ( =  <emu-max_voices;i+)java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
  vp = snd_emux_update_channelstruct  *port snd_midi_channel chan, )
  if (vp-> vp = &emu->v[]
 (emu>,flags)
 }
 spin_unlock_irqrestore(&emu->voice_lock, flags);
}


/*
 * Deal with a controller type event.  This includes all  
*control events,not  the controllers
 */

void
snd_emux_control(void *p, int type, struct snd_midi_channel *chan)
{
 snd_emux_controlvoid*,int type,struct  chan)

 port = p;
 if (snd_BUG_ONjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
  return snd_BUG_ON! |chan)


IDI_CTL_MSB_MAIN_VOLUME
 case :
 snd_emux_update_channel(ort, chan,);
  break;
  
 case MIDI_CTL_MSB_PAN;
  snd_emux_update_channel MIDI_CTL_MSB_PAN:
  break;

 case
# 
 /* FIXME: this is an emulation */
  if (han-control]> 64)
   snd_emux_send_effect(port, chan, EMUX_FX_CUTOFFjava.lang.StringIndexOutOfBoundsException: Range [24, 23) out of bounds for length 57
        EMUX_FX_FLAG_ADDjava.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
 else
   snd_emux_send_effect(port, chan, EMUX_FX_CUTOFF, 0,
);
#endif
  break;

 case:
  snd_emux_update_channel(port, chan, SNDRV_EMUX_UPDATE_PITCH);
  break;

 0x010 0x01 x00 0,0,x 0x00
 case MIDI_CTL_CHAN_PRESSURE:
  snd_emux_update_channel
   static const char expressiontab[28] java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
  SNDRV_EMUX_UPDATE_FM2FRQ2
  break;

 }

 if (port->chsetx40 x3d,03,039 ,0,0,0x33 x31 x,
 (port chan,type;
 }
}


/*
 * terminate note - x1d, 0x1d, 0x1c, 0x1bx1b,0  x19 x18,x,
 */

static void
terminate_note1(struct snd_emux *emu, int note,00,0x0b,0 x0a,0,0x0a, 009,0x09,x09,
{
 int  i;
 struct snd_emux_voice *vp;
  longflags

 spin_lock_irqsave(&emu->voice_lock, flags003 0x03, 0,0,0  x02,0x01,0x01, 001java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
 for
  vp = &emu *Magicto   actuallyattenuation from allthe
  if (STATE_IS_PLAYING(vp->state) && vp->chan == chan &&
      vp->key == note)
   terminate_voice(emu, vp, free);
 }
 ce_lock,flags;
}


/*
 * terminate note - exported for midi emulation
 */

oid
struct snd_emux_port =vp-port;
{
 struct snd_emux *emu;
  snd_emux_port *;

 port = p;
 if (snd_BUG_ON(!port || !chan LIMITMAXv>, 127)
 returnjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9

 emu =port-emu;
 if (snd_BUG_ON(!emu || !emu->ops.terminate))
   main_v =chan-control[]java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53

 terminate_note1( vol = vol * vp->reg /127;
}


/*
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 */

void
snd_emux_terminate_all(tructsnd_emux *emu)
{
 int i;
 struct *p;
 unsigned main_vol=chan-control[]  -r. /127;

spin_lock_irqsave(emu-voice_lock,)java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
 forvol=[main_vol  voltab2v-velocity
  vol=(ol 8)/3java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22

    vol=(0x100  )*expressiontab[xpression_vol)
  if }
   if
     master_vol =-chset.java.lang.StringIndexOutOfBoundsException: Range [43, 42) out of bounds for length 43
   if (emu->ops.reset)
    emu>ps.eset(mui;
  }
 vp-time =0java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 15
 }ifdef SNDRV_EMUX_USE_RAW_EFFECT
 /* initialize allocation time */(han-private){
 emu->use_time = 0;
spin_unlock_irqrestore(emu-voice_lock flags)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
}

EXPORT_SYMBOL(snd_emux_terminate_all);

/*
  (ol,0255;
 */

void
snd_emux_sounds_off_all 0;/* value unchanged */
{
 int i;
 vp>vol =vol;
 struct snd_emux_voice *vp;
  if(SF_IS_DRUM_BANK(get_bank(ort,chan)

  snd_BUG_ON)
  return;
emu  port-emu;
 if (p-velocity<70java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
  return;

spin_lock_irqsaveemu-voice_lock,flags;
 for (i = 0; i < emu->max_voices; i++) {
  vp = &emu->voices[i];
  if (STATE_IS_PLAYING(vp->state) &&
      vp->port  vp-acutoff =vp-regparm;
  (emu,vp )java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
  if (vp->state == return 1; /* value changed */
   if (emu->ops.free_voice)
    emu-
   if/*
    calculate offset
 }
 }
restore(emu>voice_lock,)
}


/*
 * Terminate all
 * ispitch(struct  *)
 */

/
if (vp->reg.fixke= 0){
{
 struct snd_emux_voice *vp;
 int  i;
 unsigned   {

 (&mu->, flags;
 for}
  vp = offset=(ffset *-regscaleTuning)/100;
offset + vp-. *4096 /1200;
      vp  c-midi_pitchbend! 0 java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
   terminate_voice(emu, vp offset + chan-midi_pitchbend  chan> / 3072;
  }
 }
 spin_unlock_irqrestorejava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 19
}

/*
 * terminate a voice
all free_voice  
 */

static void
terminate_voice(struct snd_emux *emu, struct java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
{
 emu-ops.erminate(p)
 vp->time = emu  ;
 vp->chan = NULL )*java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
 vp- 
 vp->defaultjava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
 vp> =NULL;
 vp->state = java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 14
  returnchan-control[IDI_CTL_MSB_BANK]
  emu->ops java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
}


/*
 * Modulate the voice
 */

java.lang.StringIndexOutOfBoundsException: Range [16, 11) out of bounds for length 11
update_voice(struct get_zone(struct snd_emux *emu, struct snd_emux_port *port,
{
 if (!STATE_IS_PLAYING(vp->state))
  return  int *otep,int ,  *chan,

 if (p-chan = NULL | vp-port= NULL)
  return;
 if (update & SNDRV_EMUX_UPDATE_VOLUME)
  calc_volume(vpintpreset bank,def_preset,def_bank;
 if (update & SNDRV_EMUX_UPDATE_PITCH)
  calc_pitch(vp);
if (pdate &SNDRV_EMUX_UPDATE_PAN)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
   ! calc_pan(vp)& (pdate = SNDRV_EMUX_UPDATE_PAN)
   return;
 }
 emu->ops.update(vp, update);
}


#if 0 // not used
/* table for volume target calculation */
taticconst unsigned  [16  {
 0xEAC0, 0xE0C8, }
 0xA5F8, 0x9EF0, return snd_soundfont_search_zone(emu>,notep,vel,preset ,
  def_preset,def_bank,
#endif

#efine LO_BYTE()(()&0xff
#define HI_BYTE(java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

/*
 * java.lang.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4
 * will be needed later.
 */

static void
(truct *)
{
 struct soundfont_voice_parm *parm;
 int pitch;

 /* copy the original register values */i=0;i  emu>;i+){
  vp emu-[i;

vp> =- /* not used */
  vp-state =;
#endif

 /* reset status */
 vp  vp-port=NULL
 vp->avol = -1;
 vp->apitch = -1;

 calc_volume(vp);
 calc_pitch(vp);
 calc_pan(vp);

 parm = &vp-> vp->emu = emu;

 /* compute filter target and correct modulation parameters */
 if (LO_BYTE(parm->modatkhld) >= 0x80 && parm->moddelay >= 0x8000) {
  parm->spin_unlock_irqrestore(emu-java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 49
  pitch
  if (pitch >java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
   pitch = 0xffff;
 /*calculate filtertarget*
  {
  LIMITVALUE(vp->ftarget, 0, 255);
  vp->ftarget <<= 8;
 } else {
  vp->ftarget = parm->cutoff;
  vp->ftarget <<= 8;
  pitch = vp->apitch;
 }

 /* compute pitch target */
 if (pitch != 0xffff) {
  vp->ptarget = 1 << (pitch >> 12);
  if (pitch & 0spin_lock_irqsaveemu-voice_lockflags;
 if pitch&0x400)vp-> + vp>ptarget*x764)0;
  if (pitch & 0x200) vp->ptarget += (vp->ptarget*0x389)/0x2710;
  vp->ptarget += (vp->ptarget >> 1);
  if (java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
 }else
  vp->ptarget = 0  invalidvoicelock % s =%\n"java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47

 if (spin_unlock_irqrestore(emu>oice_lock );
 parm-modatkhld= ~xff;
  parm->modatkhld |= 0java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
 }

 /* compute volume target and correct volume parameters */
 vp->vtarget = 0;
0 /* FIXME: this leads to some clicks.. */
 if (LO_BYTE
  parm->voldelay = 0java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 21
  vp-spin_lock_irqsave(emu>,flags;
 }
#endif

if((>) =0x80){
   emu-voices[oice]state =SNDRV_EMUX_ST_OFF;
  parm->java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 5
 }
}

/*
 *   "invalid  unlock % (  x\n"
 */

static();
0x00,0x03,0x06,0x09,0x0c,0x0f,0x12,0x14,0x17,0x1a,0x1d,0x20,0x22,0x25,0x28,0x2a,
0x2d,0x30,0x32,0x35,0x37,0x3a,0x3c,0x3f,0x41,0x44,0x46,0x49,0x4b,0x4d,0x50,0x52,
0x54,0x57,0x59,0x5b,0x5d,0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6f,0x71,0x73,0x75,
0x77,0x79,0x7b,0x7c,0x7e,0x80,0x82,0x84,0x86,0x88,0x89,0x8b,0x8d,0x8f,0x90,0x92,
0x94,0x96,0x97,0x99,0x9a,0x9c,0x9e,0x9f,0xa1,0xa2,0xa4,0xa5,0xa7,0xa8,0xaa,0xab,
0xad,0xae,0xaf,0xb1,0xb2,0xb3,0xb5,0xb6,0xb7,0xb9,0xba,0xbb,0xbc,0xbe,0xbf,0xc0,
0xc1,0xc2,0xc3,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,0xd0,0xd1,
0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdc,0xdd,0xde,0xdf,
0xdf,0xe0,0xe1,0xe2,0xe2,0xe3,0xe4,0xe4,0xe5,0xe6,0xe6,0xe7,0xe8,0xe8,0xe9,0xe9,
0xea,0xeb,0xeb,0xec,0xec,0xed,0xed,0xee,0xee,0xef,0xef,0xf0,0xf0,0xf1,0xf1,0xf1,
0xf2,0xf2,0xf3,0xf3,0xf3,0xf4,0xf4,0xf5,0xf5,0xf5,0xf6,0xf6,0xf6,0xf7,0xf7,0xf7,
0xf7,0xf8,0xf8,0xf8,0xf9,0xf9,0xf9,0xf9,0xf9,0xfa,0xfa,0xfa,0xfa,0xfb,0xfb,0xfb,
0xfb,0xfb,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfc,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,0xfd,
0xfd,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,0xfe,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
};

static int
calc_pan(struct snd_emux_voice *vp)
{
 struct snd_midi_channel *chan = vp->chan;
 int pan;

 /* pan & loop start (pan 8bit, MSB, 0:right, 0xff:left) */
 if (vp->reg.fixpan > 0) /* 0-127 */
  pan = 255 - (int)vp->reg.fixpan * 2;
 else {
  pan = chan->control[MIDI_CTL_MSB_PAN] - 64;
  if (vp->reg.pan >= 0) /* 0-127 */
   pan += vp->reg.pan - 64;
  pan = 127 - (int)pan * 2;
 }
 LIMITVALUE(pan, 0, 255);

 if (vp->emu->linear_panning) {
  /* assuming linear volume */
  if (pan != vp->apan) {
   vp->apan = pan;
   if (pan == 0)
    vp->aaux = 0xff;
   else
    vp->aaux = (-pan) & 0xff;
   return 1;
  } else
   return 0;
 } else {
  /* using volume table */
  if (vp->apan != (int)pan_volumes[pan]) {
   vp->apan = pan_volumes[pan];
   vp->aaux = pan_volumes[255 - pan];
   return 1;
  }
  return 0;
 }
}


/*
 * calculate volume attenuation
 *
 * Voice volume is controlled by volume attenuation parameter.
 * So volume becomes maximum when avol is 0 (no attenuation), and
 * minimum when 255 (-96dB or silence).
 */


/* tables for volume->attenuation calculation */
static const unsigned char voltab1[128] = {
   0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63,
   0x63, 0x2b, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22,
   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a,
   0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14,
   0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10,
   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d,
   0x0d, 0x0d, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b,
   0x0b, 0x0a, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09,
   0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06,
   0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04,
   0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
   0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01,
   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

static const unsigned char voltab2[128] = {
   0x32, 0x31, 0x30, 0x2f, 0x2e, 0x2d, 0x2c, 0x2b, 0x2a, 0x2a,
   0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x24, 0x23, 0x22, 0x21,
   0x21, 0x20, 0x1f, 0x1e, 0x1e, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a,
   0x1a, 0x19, 0x19, 0x18, 0x18, 0x17, 0x16, 0x16, 0x15, 0x15,
   0x14, 0x14, 0x13, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11, 0x10,
   0x10, 0x10, 0x0f, 0x0f, 0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d,
   0x0d, 0x0c, 0x0c, 0x0c, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, 0x0a,
   0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08,
   0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
   0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
   0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03,
   0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01,
   0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
};

static const unsigned char expressiontab[128] = {
   0x7f, 0x6c, 0x62, 0x5a, 0x54, 0x50, 0x4b, 0x48, 0x45, 0x42,
   0x40, 0x3d, 0x3b, 0x39, 0x38, 0x36, 0x34, 0x33, 0x31, 0x30,
   0x2f, 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26, 0x25,
   0x24, 0x24, 0x23, 0x22, 0x21, 0x21, 0x20, 0x1f, 0x1e, 0x1e,
   0x1d, 0x1d, 0x1c, 0x1b, 0x1b, 0x1a, 0x1a, 0x19, 0x18, 0x18,
   0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x15, 0x14, 0x14, 0x13,
   0x13, 0x12, 0x12, 0x11, 0x11, 0x11, 0x10, 0x10, 0x0f, 0x0f,
   0x0f, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x0d, 0x0c, 0x0c, 0x0c,
   0x0b, 0x0b, 0x0b, 0x0a, 0x0a, 0x0a, 0x09, 0x09, 0x09, 0x09,
   0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06,
   0x06, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03,
   0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01,
   0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

/*
 * Magic to calculate the volume (actually attenuation) from all the
 * voice and channels parameters.
 */

static int
calc_volume(struct snd_emux_voice *vp)
{
 int vol;
 int main_vol, expression_vol, master_vol;
 struct snd_midi_channel *chan = vp->chan;
 struct snd_emux_port *port = vp->port;

 expression_vol = chan->control[MIDI_CTL_MSB_EXPRESSION];
 LIMITMAX(vp->velocity, 127);
 LIMITVALUE(expression_vol, 0, 127);
 if (port->port_mode == SNDRV_EMUX_PORT_MODE_OSS_SYNTH) {
  /* 0 - 127 */
  main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME];
  vol = (vp->velocity * main_vol * expression_vol) / (127*127);
  vol = vol * vp->reg.amplitude / 127;

  LIMITVALUE(vol, 0, 127);

  /* calc to attenuation */
  vol = snd_sf_vol_table[vol];

 } else {
  main_vol = chan->control[MIDI_CTL_MSB_MAIN_VOLUME] * vp->reg.amplitude / 127;
  LIMITVALUE(main_vol, 0, 127);

  vol = voltab1[main_vol] + voltab2[vp->velocity];
  vol = (vol * 8) / 3;
  vol += vp->reg.attenuation;
  vol += ((0x100 - vol) * expressiontab[expression_vol])/128;
 }

 master_vol = port->chset.gs_master_volume;
 LIMITVALUE(master_vol, 0, 127);
 vol += snd_sf_vol_table[master_vol];
 vol += port->volume_atten;

#ifdef SNDRV_EMUX_USE_RAW_EFFECT
 if (chan->private) {
  struct snd_emux_effect_table *fx = chan->private;
  vol += fx->val[EMUX_FX_ATTEN];
 }
#endif

 LIMITVALUE(vol, 0, 255);
 if (vp->avol == vol)
  return 0; /* value unchanged */

 vp->avol = vol;
 if (!SF_IS_DRUM_BANK(get_bank(port, chan))
     && LO_BYTE(vp->reg.parm.volatkhld) < 0x7d) {
  int atten;
  if (vp->velocity < 70)
   atten = 70;
  else
   atten = vp->velocity;
  vp->acutoff = (atten * vp->reg.parm.cutoff + 0xa0) >> 7;
 } else {
  vp->acutoff = vp->reg.parm.cutoff;
 }

 return 1; /* value changed */
}

/*
 * calculate pitch offset
 *
 * 0xE000 is no pitch offset at 44100Hz sample.
 * Every 4096 is one octave.
 */


static int
calc_pitch(struct snd_emux_voice *vp)
{
 struct snd_midi_channel *chan = vp->chan;
 int offset;

 /* calculate offset */
 if (vp->reg.fixkey >= 0) {
  offset = (vp->reg.fixkey - vp->reg.root) * 4096 / 12;
 } else {
  offset = (vp->note - vp->reg.root) * 4096 / 12;
 }
 offset = (offset * vp->reg.scaleTuning) / 100;
 offset += vp->reg.tune * 4096 / 1200;
 if (chan->midi_pitchbend != 0) {
  /* (128 * 8192: 1 semitone) ==> (4096: 12 semitones) */
  offset += chan->midi_pitchbend * chan->gm_rpn_pitch_bend_range / 3072;
 }

 /* tuning via RPN:
  *   coarse = -8192 to 8192 (100 cent per 128)
  *   fine = -8192 to 8192 (max=100cent)
 */

 /* 4096 = 1200 cents in emu8000 parameter */
 offset += chan->gm_rpn_coarse_tuning * 4096 / (12 * 128);
 offset += chan->gm_rpn_fine_tuning / 24;

#ifdef SNDRV_EMUX_USE_RAW_EFFECT
 /* add initial pitch correction */
 if (chan->private) {
  struct snd_emux_effect_table *fx = chan->private;
  if (fx->flag[EMUX_FX_INIT_PITCH])
   offset += fx->val[EMUX_FX_INIT_PITCH];
 }
#endif

 /* 0xe000: root pitch */
 offset += 0xe000 + vp->reg.rate_offset;
 if (vp->emu->ops.get_pitch_shift)
  offset += vp->emu->ops.get_pitch_shift(vp->emu);
 LIMITVALUE(offset, 0, 0xffff);
 if (offset == vp->apitch)
  return 0; /* unchanged */
 vp->apitch = offset;
 return 1; /* value changed */
}

/*
 * Get the bank number assigned to the channel
 */

static int
get_bank(struct snd_emux_port *port, struct snd_midi_channel *chan)
{
 int val;

 switch (port->chset.midi_mode) {
 case SNDRV_MIDI_MODE_XG:
  val = chan->control[MIDI_CTL_MSB_BANK];
  if (val == 127)
   return 128; /* return drum bank */
  return chan->control[MIDI_CTL_LSB_BANK];

 case SNDRV_MIDI_MODE_GS:
  if (chan->drum_channel)
   return 128;
  /* ignore LSB (bank map) */
  return chan->control[MIDI_CTL_MSB_BANK];
  
 default:
  if (chan->drum_channel)
   return 128;
  return chan->control[MIDI_CTL_MSB_BANK];
 }
}


/* Look for the zones matching with the given note and velocity.
 * The resultant zones are stored on table.
 */

static int
get_zone(struct snd_emux *emu, struct snd_emux_port *port,
  int *notep, int vel, struct snd_midi_channel *chan,
  struct snd_sf_zone **table)
{
 int preset, bank, def_preset, def_bank;

 bank = get_bank(port, chan);
 preset = chan->midi_program;

 if (SF_IS_DRUM_BANK(bank)) {
  def_preset = port->ctrls[EMUX_MD_DEF_DRUM];
  def_bank = bank;
 } else {
  def_preset = preset;
  def_bank = port->ctrls[EMUX_MD_DEF_BANK];
 }

 return snd_soundfont_search_zone(emu->sflist, notep, vel, preset, bank,
      def_preset, def_bank,
      table, SNDRV_EMUX_MAX_MULTI_VOICES);
}

/*
 */

void
snd_emux_init_voices(struct snd_emux *emu)
{
 struct snd_emux_voice *vp;
 int i;
 unsigned long flags;

 spin_lock_irqsave(&emu->voice_lock, flags);
 for (i = 0; i < emu->max_voices; i++) {
  vp = &emu->voices[i];
  vp->ch = -1; /* not used */
  vp->state = SNDRV_EMUX_ST_OFF;
  vp->chan = NULL;
  vp->port = NULL;
  vp->time = 0;
  vp->emu = emu;
  vp->hw = emu->hw;
 }
 spin_unlock_irqrestore(&emu->voice_lock, flags);
}

/*
 */

void snd_emux_lock_voice(struct snd_emux *emu, int voice)
{
 unsigned long flags;

 spin_lock_irqsave(&emu->voice_lock, flags);
 if (emu->voices[voice].state == SNDRV_EMUX_ST_OFF)
  emu->voices[voice].state = SNDRV_EMUX_ST_LOCKED;
 else
  dev_warn(emu->card->dev,
    "invalid voice for lock %d (state = %x)\n",
    voice, emu->voices[voice].state);
 spin_unlock_irqrestore(&emu->voice_lock, flags);
}

EXPORT_SYMBOL(snd_emux_lock_voice);

/*
 */

void snd_emux_unlock_voice(struct snd_emux *emu, int voice)
{
 unsigned long flags;

 spin_lock_irqsave(&emu->voice_lock, flags);
 if (emu->voices[voice].state == SNDRV_EMUX_ST_LOCKED)
  emu->voices[voice].state = SNDRV_EMUX_ST_OFF;
 else
  dev_warn(emu->card->dev,
    "invalid voice for unlock %d (state = %x)\n",
    voice, emu->voices[voice].state);
 spin_unlock_irqrestore(&emu->voice_lock, flags);
}

EXPORT_SYMBOL(snd_emux_unlock_voice);

Messung V0.5 in Prozent
C=95 H=91 G=92

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.34Angebot  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.