예제 #1
0
파일: af_rubberband.c 프로젝트: Ionic/mpv
static int control(struct af_instance *af, int cmd, void *arg)
{
    struct priv *p = af->priv;

    switch (cmd) {
    case AF_CONTROL_REINIT: {
        struct mp_audio *in = arg;
        struct mp_audio orig_in = *in;
        struct mp_audio *out = af->data;

        in->format = AF_FORMAT_FLOATP;
        mp_audio_copy_config(out, in);

        if (p->rubber)
            rubberband_delete(p->rubber);

        int opts = p->opt_transients | p->opt_detector | p->opt_phase |
                   p->opt_window | p->opt_smoothing | p->opt_formant |
                   p->opt_pitch | p-> opt_channels |
                   RubberBandOptionProcessRealTime;

        p->rubber = rubberband_new(in->rate, in->channels.num, opts, 1.0, 1.0);
        if (!p->rubber) {
            MP_FATAL(af, "librubberband initialization failed.\n");
            return AF_ERROR;
        }

        update_speed(af, p->speed);
        update_pitch(af, p->pitch);
        control(af, AF_CONTROL_RESET, NULL);

        return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
    }
    case AF_CONTROL_SET_PLAYBACK_SPEED: {
        update_speed(af, *(double *)arg);
        return AF_OK;
    }
    case AF_CONTROL_RESET:
        if (p->rubber)
            rubberband_reset(p->rubber);
        talloc_free(p->pending);
        p->pending = NULL;
        p->rubber_delay = 0;
        return AF_OK;
    case AF_CONTROL_COMMAND: {
        char **args = arg;
        if (!strcmp(args[0], "set-pitch")) {
            char *endptr;
            double pitch = strtod(args[1], &endptr);
            if (*endptr || pitch < 0.01 || pitch > 100.0)
                return CONTROL_ERROR;
            update_pitch(af, pitch);
            return CONTROL_OK;
        } else {
            return CONTROL_ERROR;
        }
    }
    }
    return AF_UNKNOWN;
}
예제 #2
0
int alogg_play_ogg_ts(ALOGG_OGG *ogg, int buffer_len, int vol, int pan, int speed) {
  int ret;

  /* start playing Ogg at normal speed */
  ret = alogg_play_ex_ogg(ogg, buffer_len, vol, pan, 1000, 0);
  if (ret != ALOGG_OK)
    return ret;

  /* don't set up time stretching if we are playing at normal speed */
  if (speed == 1000)
    return ALOGG_OK;

  ogg->time_stretch = 1;
  ogg->time_stretch_buffer_samples = (buffer_len / (ogg->stereo ? 2 : 1)) / 2;
  ogg->time_stretch_state = rubberband_new(ogg->freq, ogg->stereo ? 2 : 1, RubberBandOptionProcessRealTime |  RubberBandOptionThreadingNever, 1000.0 / (float)speed, 1.0);
  rubberband_set_max_process_size(ogg->time_stretch_state, ogg->time_stretch_buffer_samples);
  ogg->time_stretch_buffer[0] = malloc(sizeof(float) * ogg->time_stretch_buffer_samples);
  if (ogg->stereo)
    ogg->time_stretch_buffer[1] = malloc(sizeof(float) * ogg->time_stretch_buffer_samples);
  else
    ogg->time_stretch_buffer[1] = NULL;

  return ALOGG_OK;
}
예제 #3
0
static gint rubberband_init(DenemoPrefs *config) {
    rubberband = rubberband_new(sample_rate, 2 /* channels */, RubberBandOptionProcessRealTime | RubberBandOptionStretchPrecise,
    slowdown, 1.0);
    //rubberband_set_debug_level(rubberband, 3);
    return 0;
}