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; }
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; }
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; }