Exemple #1
0
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;
}
Exemple #2
0
static int filter_out(struct af_instance *af)
{
    struct priv *p = af->priv;

    while (rubberband_available(p->rubber) <= 0) {
        const float *dummy[MP_NUM_CHANNELS] = {0};
        const float **in_data = dummy;
        size_t in_samples = 0;
        if (p->pending) {
            if (!p->pending->samples)
                break;

            // recover from previous EOF
            if (p->needs_reset) {
                rubberband_reset(p->rubber);
                p->rubber_delay = 0;
            }
            p->needs_reset = false;

            size_t needs = rubberband_get_samples_required(p->rubber);
            in_data = (void *)&p->pending->planes;
            in_samples = MPMIN(p->pending->samples, needs);
        }

        if (p->needs_reset)
            break; // previous EOF
        p->needs_reset = !p->pending; // EOF

        rubberband_process(p->rubber, in_data, in_samples, p->needs_reset);
        p->rubber_delay += in_samples;

        if (!p->pending)
            break;
        mp_audio_skip_samples(p->pending, in_samples);
    }

    int out_samples = rubberband_available(p->rubber);
    if (out_samples > 0) {
        struct mp_audio *out =
            mp_audio_pool_get(af->out_pool, af->data, out_samples);
        if (!out)
            return -1;
        if (p->pending)
            mp_audio_copy_config(out, p->pending);

        float **out_data = (void *)&out->planes;
        out->samples = rubberband_retrieve(p->rubber, out_data, out->samples);
        p->rubber_delay -= out->samples * p->speed;

        af_add_output_frame(af, out);
    }

    int delay_samples = p->rubber_delay;
    if (p->pending)
        delay_samples += p->pending->samples;
    af->delay = delay_samples / (af->data->rate * p->speed);

    return 0;
}
Exemple #3
0
void alogg_seek_abs_msecs_ogg_ul(ALOGG_OGG *ogg, unsigned long msec) {
  /* convert msec to pcm sample position */
  double s = msec;
  s /= 1000;

  ov_time_seek(&(ogg->vf), s);
  if (ogg->time_stretch)
    rubberband_reset(ogg->time_stretch_state);
}
Exemple #4
0
void alogg_seek_abs_secs_ogg(ALOGG_OGG *ogg, int sec) {
  ov_time_seek(&(ogg->vf), sec);
  if (ogg->time_stretch)
    rubberband_reset(ogg->time_stretch_state);
}