Exemplo n.º 1
0
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  af_gate_t* s   = (af_gate_t*)af->setup; 
  switch(cmd){
  case AF_CONTROL_REINIT:
    // Sanity check
    if(!arg) return AF_ERROR;
    
    af->data->rate   = ((af_data_t*)arg)->rate;
    af->data->nch    = ((af_data_t*)arg)->nch;
    af->data->format = AF_FORMAT_FLOAT_NE;
    af->data->bps    = 4;

    // Time constant set to 0.1s
    //    s->alpha = (1.0/0.2)/(2.0*M_PI*(float)((af_data_t*)arg)->rate); 
    return af_test_output(af,(af_data_t*)arg);
  case AF_CONTROL_COMMAND_LINE:{
/*     float v=-10.0; */
/*     float vol[AF_NCH]; */
/*     float s=0.0; */
/*     float clipp[AF_NCH]; */
/*     int i; */
/*     sscanf((char*)arg,"%f:%f", &v, &s); */
/*     for(i=0;i<AF_NCH;i++){ */
/*       vol[i]=v; */
/*       clipp[i]=s; */
/*     } */
/*     if(AF_OK != control(af,AF_CONTROL_VOLUME_SOFTCLIP | AF_CONTROL_SET, clipp)) */
/*       return AF_ERROR; */
/*     return control(af,AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET, vol); */
  }

  case AF_CONTROL_GATE_ON_OFF | AF_CONTROL_SET:
    memcpy(s->enable,(int*)arg,AF_NCH*sizeof(int));
    return AF_OK; 
  case AF_CONTROL_GATE_ON_OFF | AF_CONTROL_GET:
    memcpy((int*)arg,s->enable,AF_NCH*sizeof(int));
    return AF_OK; 
  case AF_CONTROL_GATE_THRESH | AF_CONTROL_SET:
    return af_from_dB(AF_NCH,(float*)arg,s->tresh,20.0,-60.0,-1.0);
  case AF_CONTROL_GATE_THRESH | AF_CONTROL_GET:
    return af_to_dB(AF_NCH,s->tresh,(float*)arg,10.0);
  case AF_CONTROL_GATE_ATTACK | AF_CONTROL_SET:
    return af_from_ms(AF_NCH,(float*)arg,s->attack,af->data->rate,500.0,0.1);
  case AF_CONTROL_GATE_ATTACK | AF_CONTROL_GET:
    return af_to_ms(AF_NCH,s->attack,(float*)arg,af->data->rate);
  case AF_CONTROL_GATE_RELEASE | AF_CONTROL_SET:
    return af_from_ms(AF_NCH,(float*)arg,s->release,af->data->rate,3000.0,10.0);
  case AF_CONTROL_GATE_RELEASE | AF_CONTROL_GET:
    return af_to_ms(AF_NCH,s->release,(float*)arg,af->data->rate);
  case AF_CONTROL_GATE_RANGE | AF_CONTROL_SET:
    return af_from_dB(AF_NCH,(float*)arg,s->range,20.0,100.0,0.0);
  case AF_CONTROL_GATE_RANGE | AF_CONTROL_GET:
    return af_to_dB(AF_NCH,s->range,(float*)arg,10.0);
  }
  return AF_UNKNOWN;
}
Exemplo n.º 2
0
Arquivo: mixer.c Projeto: kax4/mpv
static void checkvolume(struct mixer *mixer)
{
    if (!mixer->ao)
        return;

    if (mixer->softvol == SOFTVOL_AUTO) {
        mixer->softvol = mixer->ao->per_application_mixer
                         ? SOFTVOL_NO : SOFTVOL_YES;
    }

    ao_control_vol_t vol;
    if (mixer->softvol || CONTROL_OK != ao_control(mixer->ao,
                                                AOCONTROL_GET_VOLUME, &vol)) {
        mixer->softvol = SOFTVOL_YES;
        if (!mixer->afilter)
            return;
        float db_vals[AF_NCH];
        if (!af_control_any_rev(mixer->afilter,
                        AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET, db_vals))
            db_vals[0] = db_vals[1] = 1.0;
        else
            af_from_dB(2, db_vals, db_vals, 20.0, -200.0, 60.0);
        vol.left = (db_vals[0] / (mixer->softvol_max / 100.0)) * 100.0;
        vol.right = (db_vals[1] / (mixer->softvol_max / 100.0)) * 100.0;
    }
    float l = mixer->vol_l;
    float r = mixer->vol_r;
    if (mixer->muted_using_volume)
        l = r = 0;
    /* Try to detect cases where the volume has been changed by some external
     * action (such as something else changing a shared system-wide volume).
     * We don't test for exact equality, as some AOs may round the value
     * we last set to some nearby supported value. 3 has been the default
     * volume step for increase/decrease keys, and is apparently big enough
     * to step to the next possible value in most setups.
     */
    if (FFABS(vol.left - l) >= 3 || FFABS(vol.right - r) >= 3) {
        mixer->vol_l = vol.left;
        mixer->vol_r = vol.right;
        if (mixer->muted_using_volume)
            mixer->muted = false;
    }
    if (!mixer->softvol)
        // Rely on the value not changing if the query is not supported
        ao_control(mixer->ao, AOCONTROL_GET_MUTE, &mixer->muted);
    mixer->muted_by_us &= mixer->muted;
    mixer->muted_using_volume &= mixer->muted;
}
Exemplo n.º 3
0
void mixer_getvolume(mixer_t *mixer, float *l, float *r)
{
  ao_control_vol_t vol;
  *l=0; *r=0;
  if(mixer->audio_out){
    if(soft_vol ||
        CONTROL_OK != mixer->audio_out->control(AOCONTROL_GET_VOLUME,&vol)) {
      if (!mixer->afilter)
        return;
      else {
        float db_vals[AF_NCH];
        if (!af_control_any_rev(mixer->afilter,
               AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET, db_vals))
          db_vals[0] = db_vals[1] = 1.0;
        else
        af_from_dB (2, db_vals, db_vals, 20.0, -200.0, 60.0);
        vol.left = (db_vals[0] / (soft_vol_max / 100.0)) * 100.0;
        vol.right = (db_vals[1] / (soft_vol_max / 100.0)) * 100.0;
      }
    }
    *r=vol.right;
    *l=vol.left;
  }
}
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  af_volume_t* s   = (af_volume_t*)af->setup;

  switch(cmd){
  case AF_CONTROL_REINIT:
    // Sanity check
    if(!arg) return AF_ERROR;

    af->data->rate   = ((af_data_t*)arg)->rate;
    af->data->nch    = ((af_data_t*)arg)->nch;

    if(s->fast && (((af_data_t*)arg)->format != (AF_FORMAT_FLOAT_NE))){
      af->data->format = AF_FORMAT_S16_NE;
      af->data->bps    = 2;
    }
    else{
      // Cutoff set to 10Hz for forgetting factor
      float x = 2.0*M_PI*15.0/(float)af->data->rate;
      float t = 2.0-cos(x);
      s->time = 1.0 - (t - sqrt(t*t - 1));
      mp_msg(MSGT_AFILTER, MSGL_DBG2, "[volume] Forgetting factor = %0.5f\n",s->time);
      af->data->format = AF_FORMAT_FLOAT_NE;
      af->data->bps    = 4;
    }
    return af_test_output(af,(af_data_t*)arg);
  case AF_CONTROL_COMMAND_LINE:{
    float v=0.0;
    float vol[AF_NCH];
    int   i;
    sscanf((char*)arg,"%f:%i", &v, &s->soft);
    for(i=0;i<AF_NCH;i++) vol[i]=v;
    return control(af,AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET, vol);
  }
  case AF_CONTROL_POST_CREATE:
    s->fast = ((((af_cfg_t*)arg)->force & AF_INIT_FORMAT_MASK) ==
      AF_INIT_FLOAT) ? 0 : 1;
    return AF_OK;
  case AF_CONTROL_VOLUME_ON_OFF | AF_CONTROL_SET:
    memcpy(s->enable,(int*)arg,AF_NCH*sizeof(int));
    return AF_OK;
  case AF_CONTROL_VOLUME_ON_OFF | AF_CONTROL_GET:
    memcpy((int*)arg,s->enable,AF_NCH*sizeof(int));
    return AF_OK;
  case AF_CONTROL_VOLUME_SOFTCLIP | AF_CONTROL_SET:
    s->soft = *(int*)arg;
    return AF_OK;
  case AF_CONTROL_VOLUME_SOFTCLIP | AF_CONTROL_GET:
    *(int*)arg = s->soft;
    return AF_OK;
  case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_SET:
    return af_from_dB(AF_NCH,(float*)arg,s->level,20.0,-200.0,60.0);
  case AF_CONTROL_VOLUME_LEVEL | AF_CONTROL_GET:
    return af_to_dB(AF_NCH,s->level,(float*)arg,20.0);
  case AF_CONTROL_VOLUME_PROBE | AF_CONTROL_GET:
    return af_to_dB(AF_NCH,s->pow,(float*)arg,10.0);
  case AF_CONTROL_VOLUME_PROBE_MAX | AF_CONTROL_GET:
    return af_to_dB(AF_NCH,s->max,(float*)arg,10.0);
  case AF_CONTROL_PRE_DESTROY:{
    float m = 0.0;
    int i;
    if(!s->fast){
      for(i=0;i<AF_NCH;i++)
	m=max(m,s->max[i]);
	af_to_dB(1, &m, &m, 10.0);
	mp_msg(MSGT_AFILTER, MSGL_INFO, "[volume] The maximum volume was %0.2fdB \n", m);
    }
    return AF_OK;
  }
  }
  return AF_UNKNOWN;
}