Beispiel #1
0
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  af_sub_t* s   = 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    = max(s->ch+1,((af_data_t*)arg)->nch);
    af->data->format = AF_FORMAT_FLOAT_NE;
    af->data->bps    = 4;

    // Design low-pass filter
    s->k = 1.0;
    if((-1 == af_filter_szxform(sp[0].a, sp[0].b, Q, s->fc,
       (float)af->data->rate, &s->k, s->w[0])) ||
       (-1 == af_filter_szxform(sp[1].a, sp[1].b, Q, s->fc,
       (float)af->data->rate, &s->k, s->w[1])))
      return AF_ERROR;
    return af_test_output(af,(af_data_t*)arg);
  }
  case AF_CONTROL_COMMAND_LINE:{
    int   ch=5;
    float fc=60.0;
    sscanf(arg,"%f:%i", &fc , &ch);
    if(AF_OK != control(af,AF_CONTROL_SUB_CH | AF_CONTROL_SET, &ch))
      return AF_ERROR;
    return control(af,AF_CONTROL_SUB_FC | AF_CONTROL_SET, &fc);
  }
  case AF_CONTROL_SUB_CH | AF_CONTROL_SET: // Requires reinit
    // Sanity check
    if((*(int*)arg >= AF_NCH) || (*(int*)arg < 0)){
      af_msg(AF_MSG_ERROR,"[sub] Subwoofer channel number must be between "
	     " 0 and %i current value is %i\n", AF_NCH-1, *(int*)arg);
      return AF_ERROR;
    }
    s->ch = *(int*)arg;
    return AF_OK;
  case AF_CONTROL_SUB_CH | AF_CONTROL_GET:
    *(int*)arg = s->ch;
    return AF_OK;
  case AF_CONTROL_SUB_FC | AF_CONTROL_SET: // Requires reinit
    // Sanity check
    if((*(float*)arg > 300) || (*(float*)arg < 20)){
      af_msg(AF_MSG_ERROR,"[sub] Cutoff frequency must be between 20Hz and"
	     " 300Hz current value is %0.2f",*(float*)arg);
      return AF_ERROR;
    }
    // Set cutoff frequency
    s->fc = *(float*)arg;
    return AF_OK;
  case AF_CONTROL_SUB_FC | AF_CONTROL_GET:
    *(float*)arg = s->fc;
    return AF_OK;
  }
  return AF_UNKNOWN;
}
// Filter data through filter
static af_data_t* play(struct af_instance_s* af, af_data_t* data)
{
    // Do something necessary to get rid of annoying warning during compile
    if(!af)
        af_msg(AF_MSG_ERROR,"EEEK: Argument af == NULL in af_dummy.c play().");
    return data;
}
// Filter data through filter
static af_data_t* play_s16(struct af_instance_s* af, af_data_t* data)
{
  af_sinesuppress_t *s = af->setup;
  register int i = 0;
  int16_t *a = (int16_t*)data->audio;	// Audio data
  int len = data->len/2;		// Number of samples
  
  for (i = 0; i < len; i++)
  {
    double co= cos(s->pos);
    double si= sin(s->pos);

    s->real += co * a[i];
    s->imag += si * a[i];
    s->ref  += co * co;

    a[i] -= (s->real * co + s->imag * si) / s->ref;

    s->real -= s->real * s->decay;
    s->imag -= s->imag * s->decay;
    s->ref  -= s->ref  * s->decay;

    s->pos += 2 * M_PI * s->freq / data->rate;
  }

   af_msg(AF_MSG_VERBOSE,"[sinesuppress] f:%8.2f: amp:%8.2f\n", s->freq, sqrt(s->real*s->real + s->imag*s->imag) / s->ref);

  return data;
}
Beispiel #4
0
// Make sure the routes are sane
static int check_routes(af_channels_t* s, int nin, int nout)
{
  int i;
  if((s->nr < 1) || (s->nr > AF_NCH)){
    af_msg(AF_MSG_ERROR,"[channels] The number of routing pairs must be" 
	   " between 1 and %i. Current value is %i\n",AF_NCH,s->nr);
    return AF_ERROR;
  }
	
  for(i=0;i<s->nr;i++){
    if((s->route[i][FR] >= nin) || (s->route[i][TO] >= nout)){
      af_msg(AF_MSG_ERROR,"[channels] Invalid routing in pair nr. %i.\n", i);
      return AF_ERROR;
    }
  }
  return AF_OK;
}
Beispiel #5
0
// Sanity check for bytes per sample
static int check_bps(int bps)
{
  if(bps != 4 && bps != 3 && bps != 2 && bps != 1){
    af_msg(AF_MSG_ERROR,"[format] The number of bytes per sample" 
	   " must be 1, 2, 3 or 4. Current value is %i \n",bps);
    return AF_ERROR;
  }
  return AF_OK;
}
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
    switch(cmd) {
    case AF_CONTROL_REINIT:
        memcpy(af->data,(af_data_t*)arg,sizeof(af_data_t));
        af_msg(AF_MSG_VERBOSE,"[dummy] Was reinitialized: %iHz/%ich/%s\n",
               af->data->rate,af->data->nch,af_fmt2str_short(af->data->format));
        return AF_OK;
    }
    return AF_UNKNOWN;
}
Beispiel #7
0
// Check for unsupported formats
static int check_format(int format)
{
  char buf[256];
  switch(format & AF_FORMAT_SPECIAL_MASK){
  case(AF_FORMAT_IMA_ADPCM): 
  case(AF_FORMAT_MPEG2): 
  case(AF_FORMAT_AC3):
    af_msg(AF_MSG_ERROR,"[format] Sample format %s not yet supported \n",
	 af_fmt2str(format,buf,256)); 
    return AF_ERROR;
  }
  return AF_OK;
}
Beispiel #8
0
// Local function for copying data
static void copy(void* in, void* out, int ins, int inos,int outs, int outos, int len, int bps)
{
  switch(bps){
  case 1:{
    int8_t* tin  = (int8_t*)in;
    int8_t* tout = (int8_t*)out;
    tin  += inos;
    tout += outos;
    len = len/ins;
    while(len--){
      *tout=*tin;
      tin +=ins;
      tout+=outs;
    }
    break;
  }
  case 2:{
    int16_t* tin  = (int16_t*)in;
    int16_t* tout = (int16_t*)out;
    tin  += inos;
    tout += outos;
    len = len/(2*ins);
    while(len--){
      *tout=*tin;
      tin +=ins;
      tout+=outs;
    }
    break;
  }
  case 3:{
    int8_t* tin  = (int8_t*)in;
    int8_t* tout = (int8_t*)out;
    tin  += 3 * inos;
    tout += 3 * outos;
    len = len / ( 3 * ins);
    while (len--) {
      tout[0] = tin[0];
      tout[1] = tin[1];
      tout[2] = tin[2];
      tin += 3 * ins;
      tout += 3 * outs;
    }
    break;
  }
  case 4:{
    int32_t* tin  = (int32_t*)in;
    int32_t* tout = (int32_t*)out;
    tin  += inos;
    tout += outos;
    len = len/(4*ins);
    while(len--){
      *tout=*tin;
      tin +=ins;
      tout+=outs;
    }
    break;
  }
  case 8:{
    int64_t* tin  = (int64_t*)in;
    int64_t* tout = (int64_t*)out;
    tin  += inos;
    tout += outos;
    len = len/(8*ins);
    while(len--){
      *tout=*tin;
      tin +=ins;
      tout+=outs;
    }
    break;
  }
  default:
    af_msg(AF_MSG_ERROR,"[channels] Unsupported number of bytes/sample: %i" 
	   " please report this error on the MPlayer mailing list. \n",bps);
  }
}
Beispiel #9
0
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  af_channels_t* s = af->setup;
  switch(cmd){
  case AF_CONTROL_REINIT:

    // Set default channel assignment
    if(!s->router){
      int i;
      // Make sure this filter isn't redundant 
      if(af->data->nch == ((af_data_t*)arg)->nch)
	return AF_DETACH;

      // If mono: fake stereo
      if(((af_data_t*)arg)->nch == 1){
	s->nr = min(af->data->nch,2);
	for(i=0;i<s->nr;i++){
	  s->route[i][FR] = 0;
	  s->route[i][TO] = i;
	}
      }
      else{
	s->nr = min(af->data->nch, ((af_data_t*)arg)->nch);
	for(i=0;i<s->nr;i++){
	  s->route[i][FR] = i;
	  s->route[i][TO] = i;
	}
      }
    }

    af->data->rate   = ((af_data_t*)arg)->rate;
    af->data->format = ((af_data_t*)arg)->format;
    af->data->bps    = ((af_data_t*)arg)->bps;
    af->mul.n        = af->data->nch;
    af->mul.d	     = ((af_data_t*)arg)->nch;
    af_frac_cancel(&af->mul);
    return check_routes(s,((af_data_t*)arg)->nch,af->data->nch);
  case AF_CONTROL_COMMAND_LINE:{
    int nch = 0;
    int n = 0;
    // Check number of channels and number of routing pairs
    sscanf(arg, "%i:%i%n", &nch, &s->nr, &n);

    // If router scan commandline for routing pairs
    if(s->nr){
      char* cp = &((char*)arg)[n];
      int ch = 0;
      // Sanity check
      if((s->nr < 1) || (s->nr > AF_NCH)){
	af_msg(AF_MSG_ERROR,"[channels] The number of routing pairs must be" 
	     " between 1 and %i. Current value is %i\n",AF_NCH,s->nr);
      }	
      s->router = 1;
      // Scan for pairs on commandline
      while((*cp == ':') && (ch < s->nr)){
	sscanf(cp, ":%i:%i%n" ,&s->route[ch][FR], &s->route[ch][TO], &n);
	af_msg(AF_MSG_VERBOSE,"[channels] Routing from channel %i to" 
	       " channel %i\n",s->route[ch][FR],s->route[ch][TO]);
	cp = &cp[n];
	ch++;
      }
    }

    if(AF_OK != af->control(af,AF_CONTROL_CHANNELS | AF_CONTROL_SET ,&nch))
      return AF_ERROR;
    return AF_OK;
  }    
  case AF_CONTROL_CHANNELS | AF_CONTROL_SET: 
    // Reinit must be called after this function has been called
    
    // Sanity check
    if(((int*)arg)[0] <= 0 || ((int*)arg)[0] > AF_NCH){
      af_msg(AF_MSG_ERROR,"[channels] The number of output channels must be" 
	     " between 1 and %i. Current value is %i\n",AF_NCH,((int*)arg)[0]);
      return AF_ERROR;
    }

    af->data->nch=((int*)arg)[0]; 
    if(!s->router)
      af_msg(AF_MSG_VERBOSE,"[channels] Changing number of channels" 
	     " to %i\n",af->data->nch);
    return AF_OK;
  case AF_CONTROL_CHANNELS | AF_CONTROL_GET:
    *(int*)arg = af->data->nch;
    return AF_OK;
  case AF_CONTROL_CHANNELS_ROUTING | AF_CONTROL_SET:{
    int ch = ((af_control_ext_t*)arg)->ch;
    int* route = ((af_control_ext_t*)arg)->arg;
    s->route[ch][FR] = route[FR];
    s->route[ch][TO] = route[TO];
    return AF_OK;
  }
  case AF_CONTROL_CHANNELS_ROUTING | AF_CONTROL_GET:{
    int ch = ((af_control_ext_t*)arg)->ch;
    int* route = ((af_control_ext_t*)arg)->arg;
    route[FR] = s->route[ch][FR];
    route[TO] = s->route[ch][TO];
    return AF_OK;
  }
  case AF_CONTROL_CHANNELS_NR | AF_CONTROL_SET:
    s->nr = *(int*)arg;
    return AF_OK;
  case AF_CONTROL_CHANNELS_NR | AF_CONTROL_GET:
    *(int*)arg = s->nr;
    return AF_OK;
  case AF_CONTROL_CHANNELS_ROUTER | AF_CONTROL_SET:
    s->router = *(int*)arg;
    return AF_OK;
  case AF_CONTROL_CHANNELS_ROUTER | AF_CONTROL_GET:
    *(int*)arg = s->router;
    return AF_OK;
  }
  return AF_UNKNOWN;
}
Beispiel #10
0
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  af_delay_t* s = af->setup;
  switch(cmd){
  case AF_CONTROL_REINIT:{
    int i;

    // Free prevous delay queues
    for(i=0;i<af->data->nch;i++){
      if(s->q[i])
	free(s->q[i]);
    }

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

    // Allocate new delay queues
    for(i=0;i<af->data->nch;i++){
      s->q[i] = calloc(L,af->data->bps);
      if(NULL == s->q[i])
	af_msg(AF_MSG_FATAL,"[delay] Out of memory\n");
    }

    return control(af,AF_CONTROL_DELAY_LEN | AF_CONTROL_SET,s->d);
  }
  case AF_CONTROL_COMMAND_LINE:{
    int n = 1;
    int i = 0;
    char* cl = arg;
    while(n && i < AF_NCH ){
      sscanf(cl,"%f:%n",&s->d[i],&n);
      if(n==0 || cl[n-1] == '\0')
	break;
      cl=&cl[n];
      i++;
    }
    return AF_OK;
  }
  case AF_CONTROL_DELAY_LEN | AF_CONTROL_SET:{
    int i;
    if(AF_OK != af_from_ms(AF_NCH, arg, s->wi, af->data->rate, 0.0, 1000.0))
      return AF_ERROR;
    s->ri = 0;
    for(i=0;i<AF_NCH;i++){
      af_msg(AF_MSG_DEBUG0,"[delay] Channel %i delayed by %0.3fms\n",
	     i,clamp(s->d[i],0.0,1000.0));
      af_msg(AF_MSG_DEBUG1,"[delay] Channel %i delayed by %i samples\n",
	     i,s->wi[i]);
    }
    return AF_OK;
  }
  case AF_CONTROL_DELAY_LEN | AF_CONTROL_GET:{
    int i;
    for(i=0;i<AF_NCH;i++){
      if(s->ri > s->wi[i])
	s->wi[i] = L - (s->ri - s->wi[i]);
      else
	s->wi[i] = s->wi[i] - s->ri;
    }
    return af_to_ms(AF_NCH, s->wi, arg, af->data->rate);
  }
  }
  return AF_UNKNOWN;
}
Beispiel #11
0
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  af_scaletempo_t* s = af->setup;
  switch(cmd){
  case AF_CONTROL_REINIT:{
    af_data_t* data = (af_data_t*)arg;
    float srate = data->rate / 1000;
    int nch = data->nch;
    int bps;
    int use_int = 0;
    int frames_stride, frames_overlap;
    int i, j;

    af_msg(AF_MSG_VERBOSE,
           "[scaletempo] %.3f speed * %.3f scale_nominal = %.3f\n",
           s->speed, s->scale_nominal, s->scale);

    if (s->scale == 1.0) {
      if (s->speed_tempo && s->speed_pitch)
        return AF_DETACH;
      memcpy(af->data, data, sizeof(af_data_t));
      return af_test_output(af, data);
    }

    af->data->rate = data->rate;
    af->data->nch  = data->nch;
    if ( data->format == AF_FORMAT_S16_LE
         || data->format == AF_FORMAT_S16_BE ) {
      use_int = 1;
      af->data->format  = AF_FORMAT_S16_NE;
      af->data->bps     = bps = 2;
    } else {
      af->data->format = AF_FORMAT_FLOAT_NE;
      af->data->bps    = bps = 4;
    }

    frames_stride           = srate * s->ms_stride;
    s->bytes_stride         = frames_stride * bps * nch;
    s->bytes_stride_scaled  = s->scale * s->bytes_stride;
    s->frames_stride_scaled = s->scale * frames_stride;
    s->frames_stride_error  = 0;
    af->mul = (double)s->bytes_stride / s->bytes_stride_scaled;

    frames_overlap = frames_stride * s->percent_overlap;
    if (frames_overlap <= 0) {
      s->bytes_standing   = s->bytes_stride;
      s->samples_standing = s->bytes_standing / bps;
      s->output_overlap   = NULL;
    } else {
      s->samples_overlap  = frames_overlap * nch;
      s->bytes_overlap    = frames_overlap * nch * bps;
      s->bytes_standing   = s->bytes_stride - s->bytes_overlap;
      s->samples_standing = s->bytes_standing / bps;
      s->buf_overlap      = realloc(s->buf_overlap, s->bytes_overlap);
      s->table_blend      = realloc(s->table_blend, s->bytes_overlap * 4);
      if(!s->buf_overlap || !s->table_blend) {
        af_msg(AF_MSG_FATAL, "[scaletempo] Out of memory\n");
        return AF_ERROR;
      }
      bzero(s->buf_overlap, s->bytes_overlap);
      if (use_int) {
        int32_t* pb = s->table_blend;
        int64_t blend = 0;
        for (i=0; i<frames_overlap; i++) {
          int32_t v = blend / frames_overlap;
          for (j=0; j<nch; j++) {
            *pb++ = v;
          }
          blend += 65536;  // 2^16
        }
        s->output_overlap = output_overlap_s16;
      } else {
        float* pb = s->table_blend;
        for (i=0; i<frames_overlap; i++) {
          float v = i / (float)frames_overlap;
          for (j=0; j<nch; j++) {
            *pb++ = v;
          }
        }
        s->output_overlap = output_overlap_float;
      }
    }

    s->frames_search = (frames_overlap > 1) ? srate * s->ms_search : 0;
    if (s->frames_search <= 0) {
      s->best_overlap_offset = NULL;
    } else {
      if (use_int) {
        int64_t t = frames_overlap;
        int32_t n = 8589934588LL / (t * t);  // 4 * (2^31 - 1) / t^2
        int32_t* pw;
        s->buf_pre_corr = realloc(s->buf_pre_corr, s->bytes_overlap * 2 + UNROLL_PADDING);
        s->table_window = realloc(s->table_window, s->bytes_overlap * 2 - nch * bps * 2);
        if(!s->buf_pre_corr || !s->table_window) {
          af_msg(AF_MSG_FATAL, "[scaletempo] Out of memory\n");
          return AF_ERROR;
        }
        memset((char *)s->buf_pre_corr + s->bytes_overlap * 2, 0, UNROLL_PADDING);
        pw = s->table_window;
        for (i=1; i<frames_overlap; i++) {
          int32_t v = ( i * (t - i) * n ) >> 15;
          for (j=0; j<nch; j++) {
            *pw++ = v;
          }
        }
        s->best_overlap_offset = best_overlap_offset_s16;
      } else {
        float* pw;
        s->buf_pre_corr = realloc(s->buf_pre_corr, s->bytes_overlap);
        s->table_window = realloc(s->table_window, s->bytes_overlap - nch * bps);
        if(!s->buf_pre_corr || !s->table_window) {
          af_msg(AF_MSG_FATAL, "[scaletempo] Out of memory\n");
          return AF_ERROR;
        }
        pw = s->table_window;
        for (i=1; i<frames_overlap; i++) {
          float v = i * (frames_overlap - i);
          for (j=0; j<nch; j++) {
            *pw++ = v;
          }
        }
        s->best_overlap_offset = best_overlap_offset_float;
      }
    }

    s->bytes_per_frame = bps * nch;
    s->num_channels    = nch;

    s->bytes_queue
      = (s->frames_search + frames_stride + frames_overlap) * bps * nch;
    s->buf_queue = realloc(s->buf_queue, s->bytes_queue + UNROLL_PADDING);
    if(!s->buf_queue) {
      af_msg(AF_MSG_FATAL, "[scaletempo] Out of memory\n");
      return AF_ERROR;
    }

    af_msg (AF_MSG_DEBUG0, "[scaletempo] "
            "%.2f stride_in, %i stride_out, %i standing, "
            "%i overlap, %i search, %i queue, %s mode\n",
            s->frames_stride_scaled,
            (int)(s->bytes_stride / nch / bps),
            (int)(s->bytes_standing / nch / bps),
            (int)(s->bytes_overlap / nch / bps),
            s->frames_search,
            (int)(s->bytes_queue / nch / bps),
            (use_int?"s16":"float"));

    return af_test_output(af, (af_data_t*)arg);
  }
  case AF_CONTROL_PLAYBACK_SPEED | AF_CONTROL_SET:{
    if (s->speed_tempo) {
      if (s->speed_pitch) {
        break;
      }
      s->speed = *(float*)arg;
      s->scale = s->speed * s->scale_nominal;
    } else {
      if (s->speed_pitch) {
        s->speed = 1 / *(float*)arg;
        s->scale = s->speed * s->scale_nominal;
        break;
      }
    }
    return AF_OK;
  }
  case AF_CONTROL_SCALETEMPO_AMOUNT | AF_CONTROL_SET:{
    s->scale = *(float*)arg;
    s->scale = s->speed * s->scale_nominal;
    return AF_OK;
  }
  case AF_CONTROL_SCALETEMPO_AMOUNT | AF_CONTROL_GET:
    *(float*)arg = s->scale;
    return AF_OK;
  case AF_CONTROL_COMMAND_LINE:{
    strarg_t speed = {};
    opt_t subopts[] = {
      {"scale",   OPT_ARG_FLOAT, &s->scale_nominal, NULL},
      {"stride",  OPT_ARG_FLOAT, &s->ms_stride, NULL},
      {"overlap", OPT_ARG_FLOAT, &s->percent_overlap, NULL},
      {"search",  OPT_ARG_FLOAT, &s->ms_search, NULL},
      {"speed",   OPT_ARG_STR,   &speed, NULL},
      {NULL},
    };
    if (subopt_parse(arg, subopts) != 0) {
      return AF_ERROR;
    }
    if (s->scale_nominal <= 0) {
      af_msg(AF_MSG_ERROR, "[scaletempo] "
             MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
             ": scale > 0\n");
      return AF_ERROR;
    }
    if (s->ms_stride <= 0) {
      af_msg(AF_MSG_ERROR, "[scaletempo] "
             MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
             ": stride > 0\n");
      return AF_ERROR;
    }
    if (s->percent_overlap < 0 || s->percent_overlap > 1) {
      af_msg(AF_MSG_ERROR, "[scaletempo] "
             MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
             ": 0 <= overlap <= 1\n");
      return AF_ERROR;
    }
    if (s->ms_search < 0) {
      af_msg(AF_MSG_ERROR, "[scaletempo] "
             MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
             ": search >= 0\n");
      return AF_ERROR;
    }
    if (speed.len > 0) {
      if (strcmp(speed.str, "pitch") == 0) {
        s->speed_tempo = 0;
        s->speed_pitch = 1;
      } else if (strcmp(speed.str, "tempo") == 0) {
        s->speed_tempo = 1;
        s->speed_pitch = 0;
      } else if (strcmp(speed.str, "none") == 0) {
        s->speed_tempo = 0;
        s->speed_pitch = 0;
      } else if (strcmp(speed.str, "both") == 0) {
        s->speed_tempo = 1;
        s->speed_pitch = 1;
      } else {
        af_msg(AF_MSG_ERROR, "[scaletempo] "
               MSGTR_ErrorParsingCommandLine ": " MSGTR_AF_ValueOutOfRange
               ": speed=[pitch|tempo|none|both]\n");
        return AF_ERROR;
      }
    }
    s->scale = s->speed * s->scale_nominal;
    af_msg(AF_MSG_DEBUG0, "[scaletempo] %6.3f scale, %6.2f stride, %6.2f overlap, %6.2f search, speed = %s\n", s->scale_nominal, s->ms_stride, s->percent_overlap, s->ms_search, (s->speed_tempo?(s->speed_pitch?"tempo and speed":"tempo"):(s->speed_pitch?"pitch":"none")));
    return AF_OK;
  }
  }
Beispiel #12
0
// Filter data through filter
static af_data_t* play(struct af_instance_s* af, af_data_t* data)
{
  af_scaletempo_t* s = af->setup;
  int offset_in;
  int max_bytes_out;
  int8_t* pout;

  if (s->scale == 1.0) {
    return data;
  }

  // RESIZE_LOCAL_BUFFER - can't use macro
  max_bytes_out = ((int)(data->len / s->bytes_stride_scaled) + 1) * s->bytes_stride;
  if (max_bytes_out > af->data->len) {
    af_msg(AF_MSG_VERBOSE, "[libaf] Reallocating memory in module %s, "
          "old len = %i, new len = %i\n",af->info->name,af->data->len,max_bytes_out);
    af->data->audio = realloc(af->data->audio, max_bytes_out);
    if (!af->data->audio) {
      af_msg(AF_MSG_FATAL, "[libaf] Could not allocate memory\n");
      return NULL;
    }
    af->data->len = max_bytes_out;
  }

  offset_in = fill_queue(af, data, 0);
  pout = af->data->audio;
  while (s->bytes_queued >= s->bytes_queue) {
    int ti;
    float tf;
    int bytes_off = 0;

    // output stride
    if (s->output_overlap) {
      if (s->best_overlap_offset)
        bytes_off = s->best_overlap_offset(s);
      s->output_overlap(s, pout, bytes_off);
    }
    memcpy(pout + s->bytes_overlap,
           s->buf_queue + bytes_off + s->bytes_overlap,
           s->bytes_standing);
    pout += s->bytes_stride;

    // input stride
    memcpy(s->buf_overlap,
           s->buf_queue + bytes_off + s->bytes_stride,
           s->bytes_overlap);
    tf = s->frames_stride_scaled + s->frames_stride_error;
    ti = (int)tf;
    s->frames_stride_error = tf - ti;
    s->bytes_to_slide = ti * s->bytes_per_frame;

    offset_in += fill_queue(af, data, offset_in);
  }

  // This filter can have a negative delay when scale > 1:
  // output corresponding to some length of input can be decided and written
  // after receiving only a part of that input.
  af->delay = s->bytes_queued - s->bytes_to_slide;

  data->audio = af->data->audio;
  data->len   = pout - (int8_t *)af->data->audio;
  return data;
}
Beispiel #13
0
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  af_surround_t *s = af->setup;
  switch(cmd){
  case AF_CONTROL_REINIT:{
    float fc;
    af->data->rate   = ((af_data_t*)arg)->rate;
    af->data->nch    = ((af_data_t*)arg)->nch*2;
    af->data->format = AF_FORMAT_FLOAT_NE;
    af->data->bps    = 4;

    if (af->data->nch != 4){
      af_msg(AF_MSG_ERROR,"[surround] Only stereo input is supported.\n");
      return AF_DETACH;
    }
    // Surround filer coefficients
    fc = 2.0 * 7000.0/(float)af->data->rate;
    if (-1 == af_filter_design_fir(L, s->w, &fc, LP|HAMMING, 0)){
      af_msg(AF_MSG_ERROR,"[surround] Unable to design low-pass filter.\n");
      return AF_ERROR;
    }

    // Free previous delay queues
    if(s->dl)
      free(s->dl);
    if(s->dr)
      free(s->dr);
    // Allocate new delay queues
    s->dl = calloc(LD,af->data->bps);
    s->dr = calloc(LD,af->data->bps);
    if((NULL == s->dl) || (NULL == s->dr))
      af_msg(AF_MSG_FATAL,"[delay] Out of memory\n");
    
    // Initialize delay queue index
    if(AF_OK != af_from_ms(1, &s->d, &s->wi, af->data->rate, 0.0, 1000.0))
      return AF_ERROR;
//    printf("%i\n",s->wi);
    s->ri = 0;

    if((af->data->format != ((af_data_t*)arg)->format) || 
       (af->data->bps    != ((af_data_t*)arg)->bps)){
      ((af_data_t*)arg)->format = af->data->format;
      ((af_data_t*)arg)->bps = af->data->bps;
      return AF_FALSE;
    }
    return AF_OK;
  }
  case AF_CONTROL_COMMAND_LINE:{
    float d = 0;
    sscanf((char*)arg,"%f",&d);
    if ((d < 0) || (d > 1000)){
      af_msg(AF_MSG_ERROR,"[surround] Invalid delay time, valid time values"
	     " are 0ms to 1000ms current value is %0.3f ms\n",d);
      return AF_ERROR;
    }
    s->d = d;
    return AF_OK;
  }
  }
  return AF_UNKNOWN;
}
/* Initialization and runtime control
   af audio filter instance
   cmd control command
   arg argument
*/
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  af_export_t* s = af->setup;
  switch (cmd){
  case AF_CONTROL_REINIT:{
    int i=0;
    int mapsize;

    // Free previous buffers
    if (s->buf && s->buf[0])
      free(s->buf[0]);

    // unmap previous area
    if(s->mmap_area)
      munmap(s->mmap_area, SIZE_HEADER + (af->data->bps*s->sz*af->data->nch));
    // close previous file descriptor
    if(s->fd)
      close(s->fd);	

    // Accept only int16_t as input format (which sucks)
    af->data->rate   = ((af_data_t*)arg)->rate;
    af->data->nch    = ((af_data_t*)arg)->nch;
    af->data->format = AF_FORMAT_S16_NE;
    af->data->bps    = 2;
	
    // If buffer length isn't set, set it to the default value
    if(s->sz == 0)
      s->sz = DEF_SZ;
	
    // Allocate new buffers (as one continuous block)
    s->buf[0] = calloc(s->sz*af->data->nch, af->data->bps);
    if(NULL == s->buf[0])
      af_msg(AF_MSG_FATAL, "[export] Out of memory\n");
    for(i = 1; i < af->data->nch; i++)
      s->buf[i] = s->buf[0] + i*s->sz*af->data->bps;
	
    // Init memory mapping
    s->fd = open(s->filename, O_RDWR | O_CREAT | O_TRUNC, 0640);
    af_msg(AF_MSG_INFO, "[export] Exporting to file: %s\n", s->filename);
    if(s->fd < 0)
      af_msg(AF_MSG_FATAL, "[export] Could not open/create file: %s\n", 
	     s->filename);
    
    // header + buffer
    mapsize = (SIZE_HEADER + (af->data->bps * s->sz * af->data->nch));
    
    // grow file to needed size
    for(i = 0; i < mapsize; i++){
      char null = 0;
      write(s->fd, (void*) &null, 1);
    }
	
    // mmap size
    s->mmap_area = mmap(0, mapsize, PROT_READ|PROT_WRITE,MAP_SHARED, s->fd, 0);
    if(s->mmap_area == NULL)
      af_msg(AF_MSG_FATAL, "[export] Could not mmap file %s\n", s->filename);
    af_msg(AF_MSG_INFO, "[export] Memory mapped to file: %s (%p)\n", 
	   s->filename, s->mmap_area);

    // Initialize header
    *((int*)s->mmap_area) = af->data->nch;
    *((int*)s->mmap_area + 1) = s->sz * af->data->bps * af->data->nch;
    msync(s->mmap_area, mapsize, MS_ASYNC);

    // Use test_output to return FALSE if necessary
    return af_test_output(af, (af_data_t*)arg);
  }
  case AF_CONTROL_COMMAND_LINE:{
    int i=0;
    char *str = arg;
    
    if (!str){
      if(s->filename) 
	free(s->filename);

      s->filename = get_path(SHARED_FILE);
      return AF_OK;
    }
	
    while((str[i]) && (str[i] != ':'))
      i++;

    if(s->filename)
      free(s->filename);

    s->filename = calloc(i + 1, 1);
    memcpy(s->filename, str, i);
    s->filename[i] = 0;
	
    sscanf(str + i + 1, "%d", &(s->sz));
  
    return af->control(af, AF_CONTROL_EXPORT_SZ | AF_CONTROL_SET, &s->sz);
  }
  case AF_CONTROL_EXPORT_SZ | AF_CONTROL_SET:
    s->sz = * (int *) arg;
    if((s->sz <= 0) || (s->sz > 2048))
      af_msg( AF_MSG_ERROR, "[export] Buffer size must be between"
	      " 1 and 2048\n" );

    return AF_OK;
  case AF_CONTROL_EXPORT_SZ | AF_CONTROL_GET:
    *(int*) arg = s->sz;
    return AF_OK;
      
  }
  return AF_UNKNOWN;
}
Beispiel #15
0
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  switch(cmd){
  case AF_CONTROL_REINIT:{
    char buf1[256];
    char buf2[256];
    af_data_t *data = arg;
    
    // Make sure this filter isn't redundant 
    if(af->data->format == data->format && 
       af->data->bps == data->bps)
      return AF_DETACH;

    // Check for errors in configuraton
    if((AF_OK != check_bps(data->bps)) ||
       (AF_OK != check_format(data->format)) ||
       (AF_OK != check_bps(af->data->bps)) ||
       (AF_OK != check_format(af->data->format)))
      return AF_ERROR;

    af_msg(AF_MSG_VERBOSE,"[format] Changing sample format from %s to %s\n",
	   af_fmt2str(data->format,buf1,256),
	   af_fmt2str(af->data->format,buf2,256));

    af->data->rate = data->rate;
    af->data->nch  = data->nch;
    af->mul.n      = af->data->bps;
    af->mul.d      = data->bps;
    af_frac_cancel(&af->mul);
    
    af->play = play; // set default
    
    // look whether only endianess differences are there
    if ((af->data->format & ~AF_FORMAT_END_MASK) ==
	(data->format & ~AF_FORMAT_END_MASK))
    {
	af_msg(AF_MSG_VERBOSE,"[format] Accelerated endianess conversion only\n");
	af->play = play_swapendian;
    }
    if ((data->format == AF_FORMAT_FLOAT_NE) &&
	(af->data->format == AF_FORMAT_S16_NE))
    {
	af_msg(AF_MSG_VERBOSE,"[format] Accelerated %s to %s conversion\n",
	   af_fmt2str(data->format,buf1,256),
	   af_fmt2str(af->data->format,buf2,256));
	af->play = play_float_s16;
    }
    if ((data->format == AF_FORMAT_S16_NE) &&
	(af->data->format == AF_FORMAT_FLOAT_NE))
    {
	af_msg(AF_MSG_VERBOSE,"[format] Accelerated %s to %s conversion\n",
	   af_fmt2str(data->format,buf1,256),
	   af_fmt2str(af->data->format,buf2,256));
	af->play = play_s16_float;
    }
    return AF_OK;
  }
  case AF_CONTROL_COMMAND_LINE:{
    int format = af_str2fmt_short(arg);
    if (format == -1) {
      af_msg(AF_MSG_ERROR, "[format] %s is not a valid format\n", (char *)arg);
      return AF_ERROR;
    }
    if(AF_OK != af->control(af,AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET,&format))
      return AF_ERROR;
    return AF_OK;
  }
  case AF_CONTROL_FORMAT_FMT | AF_CONTROL_SET:{
    // Check for errors in configuraton
    if(AF_OK != check_format(*(int*)arg))
      return AF_ERROR;

    af->data->format = *(int*)arg;
    af->data->bps = af_fmt2bits(af->data->format)/8;

    return AF_OK;
  }
  }
  return AF_UNKNOWN;
}
Beispiel #16
0
// Initialization and runtime control
static int control(struct af_instance_s* af, int cmd, void* arg)
{
  af_equalizer_t* s   = (af_equalizer_t*)af->setup; 

  switch(cmd){
  case AF_CONTROL_REINIT:{
    int k =0, i =0;
    float F[KM] = CF;
    
    s->gain_factor=0.0;

    // 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;
    
    // Calculate number of active filters
    s->K=KM;
    while(F[s->K-1] > (float)af->data->rate/2.2)
      s->K--;
    
    if(s->K != KM)
      af_msg(AF_MSG_INFO,"[equalizer] Limiting the number of filters to" 
	     " %i due to low sample rate.\n",s->K);

    // Generate filter taps
    for(k=0;k<s->K;k++)
      bp2(s->a[k],s->b[k],F[k]/((float)af->data->rate),Q);

    // Calculate how much this plugin adds to the overall time delay
    af->delay += 2000.0/((float)af->data->rate);
    
    // Calculate gain factor to prevent clipping at output
    for(k=0;k<AF_NCH;k++)
    {
        for(i=0;i<KM;i++)
        {
            if(s->gain_factor < s->g[k][i]) s->gain_factor=s->g[k][i];
        }
    }

    s->gain_factor=log10(s->gain_factor + 1.0) * 20.0;
	 
    if(s->gain_factor > 0.0)
    {
        s->gain_factor=0.1+(s->gain_factor/12.0);
    }else{
        s->gain_factor=1;
    }
	
    return af_test_output(af,arg);
  }
  case AF_CONTROL_COMMAND_LINE:{
    float g[10]={0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
    int i,j;
    sscanf((char*)arg,"%f:%f:%f:%f:%f:%f:%f:%f:%f:%f", &g[0], &g[1], 
	   &g[2], &g[3], &g[4], &g[5], &g[6], &g[7], &g[8] ,&g[9]);
    for(i=0;i<AF_NCH;i++){
      for(j=0;j<KM;j++){
	((af_equalizer_t*)af->setup)->g[i][j] = 
	  pow(10.0,clamp(g[j],G_MIN,G_MAX)/20.0)-1.0;
      }
    }
    return AF_OK;
  }
  case AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_SET:{
    float* gain = ((af_control_ext_t*)arg)->arg;
    int    ch   = ((af_control_ext_t*)arg)->ch;
    int    k;
    if(ch >= AF_NCH || ch < 0)
      return AF_ERROR;

    for(k = 0 ; k<KM ; k++)
      s->g[ch][k] = pow(10.0,clamp(gain[k],G_MIN,G_MAX)/20.0)-1.0;

    return AF_OK;
  }
  case AF_CONTROL_EQUALIZER_GAIN | AF_CONTROL_GET:{
    float* gain = ((af_control_ext_t*)arg)->arg;
    int    ch   = ((af_control_ext_t*)arg)->ch;
    int    k;
    if(ch >= AF_NCH || ch < 0)
      return AF_ERROR;

    for(k = 0 ; k<KM ; k++)
      gain[k] = log10(s->g[ch][k]+1.0) * 20.0;

    return AF_OK;
  }
  }
  return AF_UNKNOWN;
}