Example #1
0
static int control(struct af_instance *af, int cmd, void *arg)
{
    struct priv *s = af->priv;

    switch (cmd) {
    case AF_CONTROL_REINIT: {
        struct mp_audio *in = arg;

        mp_audio_copy_config(af->data, in);
        mp_audio_force_interleaved_format(af->data);

        if (s->fast && af_fmt_from_planar(in->format) != AF_FORMAT_FLOAT) {
            mp_audio_set_format(af->data, AF_FORMAT_S16);
        } else {
            mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
        }
        if (af_fmt_is_planar(in->format))
            mp_audio_set_format(af->data, af_fmt_to_planar(af->data->format));
        return af_test_output(af, in);
    }
    case AF_CONTROL_SET_VOLUME:
        s->level = *(float *)arg;
        return AF_OK;
    case AF_CONTROL_GET_VOLUME:
        *(float *)arg = s->level;
        return AF_OK;
    }
    return AF_UNKNOWN;
}
Example #2
0
// Initialization and runtime control
static int control(struct af_instance* 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++)
      free(s->q[i]);

    mp_audio_copy_config(af->data, (struct mp_audio*)arg);
    mp_audio_force_interleaved_format(af->data);

    // 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])
	mp_msg(MSGT_AFILTER, MSGL_FATAL, "[delay] Out of memory\n");
    }

    if(AF_OK != af_from_ms(AF_NCH, s->d, s->wi, af->data->rate, 0.0, 1000.0))
      return AF_ERROR;
    s->ri = 0;
    for(i=0;i<AF_NCH;i++){
      mp_msg(MSGT_AFILTER, MSGL_DBG2, "[delay] Channel %i delayed by %0.3fms\n",
             i,MPCLAMP(s->d[i],0.0,1000.0));
      mp_msg(MSGT_AFILTER, MSGL_DBG3, "[delay] Channel %i delayed by %i samples\n",
             i,s->wi[i]);
    }
    return AF_OK;
  }
  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;
  }
  }
  return AF_UNKNOWN;
}
Example #3
0
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
  switch(cmd){
  case AF_CONTROL_REINIT:
    // Sanity check
    if(!arg) return AF_ERROR;

    mp_audio_force_interleaved_format((struct mp_audio*)arg);
    mp_audio_copy_config(af->data, (struct mp_audio*)arg);

    if(((struct mp_audio*)arg)->format != (AF_FORMAT_S16)){
      mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
    }
    return af_test_output(af,(struct mp_audio*)arg);
  }
  return AF_UNKNOWN;
}
Example #4
0
File: af_delay.c Project: agiz/mpv
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
  af_delay_t* s = af->priv;
  switch(cmd){
  case AF_CONTROL_REINIT:{
    int i;
    struct mp_audio *in = arg;

    if (in->bps != 1 && in->bps != 2 && in->bps != 4) {
      mp_msg(MSGT_AFILTER, MSGL_FATAL, "[delay] Sample format not supported\n");
      return AF_ERROR;
    }

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

    mp_audio_force_interleaved_format(in);
    mp_audio_copy_config(af->data, in);

    // 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])
	mp_msg(MSGT_AFILTER, MSGL_FATAL, "[delay] Out of memory\n");
    }

    if(AF_OK != af_from_ms(AF_NCH, s->d, s->wi, af->data->rate, 0.0, 1000.0))
      return AF_ERROR;
    s->ri = 0;
    for(i=0;i<AF_NCH;i++){
      mp_msg(MSGT_AFILTER, MSGL_DBG2, "[delay] Channel %i delayed by %0.3fms\n",
             i,MPCLAMP(s->d[i],0.0,1000.0));
      mp_msg(MSGT_AFILTER, MSGL_DBG3, "[delay] Channel %i delayed by %i samples\n",
             i,s->wi[i]);
    }
    return AF_OK;
  }
  }
  return AF_UNKNOWN;
}
Example #5
0
// Initialization and runtime control
static int control(struct af_instance* af, int cmd, void* arg)
{
  af_channels_t* s = af->priv;
  switch(cmd){
  case AF_CONTROL_REINIT: ;

    struct mp_chmap chmap;
    mp_chmap_set_unknown(&chmap, s->nch);
    mp_audio_set_channels(af->data, &chmap);

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

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

    af->data->rate   = ((struct mp_audio*)arg)->rate;
    mp_audio_force_interleaved_format((struct mp_audio*)arg);
    mp_audio_set_format(af->data, ((struct mp_audio*)arg)->format);
    return check_routes(af,((struct mp_audio*)arg)->nch,af->data->nch);
  }
  return AF_UNKNOWN;
}
Example #6
0
// Initialization and runtime control
static int control(struct af_instance *af, int cmd, void *arg)
{
    af_scaletempo_t *s = af->priv;
    switch (cmd) {
    case AF_CONTROL_REINIT: {
        struct mp_audio *data = (struct mp_audio *)arg;
        float srate = data->rate / 1000;
        int nch = data->nch;
        int use_int = 0;

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

        mp_audio_force_interleaved_format(data);
        mp_audio_copy_config(af->data, data);

        if (s->scale == 1.0) {
            if (s->speed_tempo && s->speed_pitch)
                return AF_DETACH;
            af->delay = 0;
            af->mul = 1;
            return af_test_output(af, data);
        }

        if (data->format == AF_FORMAT_S16) {
            use_int = 1;
        } else {
            mp_audio_set_format(af->data, AF_FORMAT_FLOAT);
        }
        int bps = af->data->bps;

        s->frames_stride        = srate * s->ms_stride;
        s->bytes_stride         = s->frames_stride * bps * nch;
        s->frames_stride_scaled = s->scale * s->frames_stride;
        s->frames_stride_error  = 0;
        af->mul = 1.0 / s->scale;
        af->delay = 0;

        int frames_overlap = s->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;
            s->bytes_overlap    = 0;
        } 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) {
                mp_msg(MSGT_AFILTER, MSGL_FATAL, "[scaletempo] Out of memory\n");
                return AF_ERROR;
            }
            memset(s->buf_overlap, 0, s->bytes_overlap);
            if (use_int) {
                int32_t *pb = s->table_blend;
                int64_t blend = 0;
                for (int i = 0; i < frames_overlap; i++) {
                    int32_t v = blend / frames_overlap;
                    for (int j = 0; j < nch; j++)
                        *pb++ = v;
                    blend += 65536; // 2^16
                }
                s->output_overlap = output_overlap_s16;
            } else {
                float *pb = s->table_blend;
                for (int i = 0; i < frames_overlap; i++) {
                    float v = i / (float)frames_overlap;
                    for (int 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
                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) {
                    mp_msg(MSGT_AFILTER, MSGL_FATAL, "[scaletempo] Out of memory\n");
                    return AF_ERROR;
                }
                memset((char *)s->buf_pre_corr + s->bytes_overlap * 2, 0,
                       UNROLL_PADDING);
                int32_t *pw = s->table_window;
                for (int i = 1; i < frames_overlap; i++) {
                    int32_t v = (i * (t - i) * n) >> 15;
                    for (int j = 0; j < nch; j++)
                        *pw++ = v;
                }
                s->best_overlap_offset = best_overlap_offset_s16;
            } else {
                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) {
                    mp_msg(MSGT_AFILTER, MSGL_FATAL,
                           "[scaletempo] Out of memory\n");
                    return AF_ERROR;
                }
                float *pw = s->table_window;
                for (int i = 1; i < frames_overlap; i++) {
                    float v = i * (frames_overlap - i);
                    for (int 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 + s->frames_stride + frames_overlap)
                         * bps * nch;
        s->buf_queue = realloc(s->buf_queue, s->bytes_queue + UNROLL_PADDING);
        if (!s->buf_queue) {
            mp_msg(MSGT_AFILTER, MSGL_FATAL, "[scaletempo] Out of memory\n");
            return AF_ERROR;
        }

        s->bytes_queued = 0;
        s->bytes_to_slide = 0;

        mp_msg(MSGT_AFILTER, MSGL_DBG2, "[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, (struct mp_audio *)arg);
    }
    case AF_CONTROL_SET_PLAYBACK_SPEED: {
        if (s->speed_tempo) {
            if (s->speed_pitch)
                break;
            s->speed = *(double *)arg;
            s->scale = s->speed * s->scale_nominal;
        } else {
            if (s->speed_pitch) {
                s->speed = 1 / *(double *)arg;
                s->scale = s->speed * s->scale_nominal;
                break;
            }
        }
        return AF_OK;
    }
    case AF_CONTROL_RESET:
        s->bytes_queued = 0;
        s->bytes_to_slide = 0;
        s->frames_stride_error = 0;
        memset(s->buf_overlap, 0, s->bytes_overlap);
    }