152 #define YAE_ATEMPO_MIN 0.5
153 #define YAE_ATEMPO_MAX 100.0
155 #define OFFSET(x) offsetof(ATempoContext, x)
158 {
"tempo",
"set tempo scale factor",
175 return &atempo->
frag[(atempo->
nfrag + 1) % 2];
243 #define RE_MALLOC_OR_FAIL(field, field_size) \
246 field = av_malloc(field_size); \
248 yae_release_buffers(atempo); \
249 return AVERROR(ENOMEM); \
263 uint32_t nlevels = 0;
272 atempo->
window = sample_rate / 24;
279 if (pot < atempo->window) {
317 for (i = 0; i < atempo->
window; i++) {
318 double t = (double)i / (
double)(atempo->
window - 1);
319 double h = 0.5 * (1.0 - cos(2.0 *
M_PI * t));
320 atempo->
hann[i] = (float)h;
332 double tempo =
av_strtod(arg_tempo, &tail);
348 atempo->
tempo = tempo;
356 #define yae_init_xdat(scalar_type, scalar_max) \
358 const uint8_t *src_end = src + \
359 frag->nsamples * atempo->channels * sizeof(scalar_type); \
361 FFTSample *xdat = frag->xdat; \
364 if (atempo->channels == 1) { \
365 for (; src < src_end; xdat++) { \
366 tmp = *(const scalar_type *)src; \
367 src += sizeof(scalar_type); \
369 *xdat = (FFTSample)tmp; \
372 FFTSample s, max, ti, si; \
375 for (; src < src_end; xdat++) { \
376 tmp = *(const scalar_type *)src; \
377 src += sizeof(scalar_type); \
379 max = (FFTSample)tmp; \
380 s = FFMIN((FFTSample)scalar_max, \
381 (FFTSample)fabsf(max)); \
383 for (i = 1; i < atempo->channels; i++) { \
384 tmp = *(const scalar_type *)src; \
385 src += sizeof(scalar_type); \
387 ti = (FFTSample)tmp; \
388 si = FFMIN((FFTSample)scalar_max, \
389 (FFTSample)fabsf(ti)); \
441 const int read_size = stop_here - atempo->
position[0];
443 if (stop_here <= atempo->position[0]) {
450 while (atempo->
position[0] < stop_here && src < src_end) {
451 int src_samples = (src_end -
src) / atempo->
stride;
454 int nsamples =
FFMIN(read_size, src_samples);
458 nsamples =
FFMIN(nsamples, atempo->
ring);
464 memcpy(a, src, na * atempo->
stride);
466 src += na * atempo->
stride;
479 memcpy(b, src, nb * atempo->
stride);
481 src += nb * atempo->
stride;
516 int64_t missing,
start, zeros;
519 int i0, i1, n0, n1, na, nb;
522 if (src_ref &&
yae_load_data(atempo, src_ref, src_end, stop_here) != 0) {
529 stop_here - atempo->
position[0] : 0;
532 missing < (int64_t)atempo->
window ?
533 (uint32_t)(atempo->
window - missing) : 0;
547 memset(dst, 0, zeros * atempo->
stride);
548 dst += zeros * atempo->
stride;
551 if (zeros == nsamples) {
569 i1 = i0 < na ? 0 : i0 - na;
571 n0 = i0 < na ?
FFMIN(na - i0, (
int)(nsamples - zeros)) : 0;
572 n1 = nsamples - zeros - n0;
575 memcpy(dst, a + i0 * atempo->
stride, n0 * atempo->
stride);
576 dst += n0 * atempo->
stride;
580 memcpy(dst, b + i1 * atempo->
stride, n1 * atempo->
stride);
591 const double fragment_step = atempo->
tempo * (double)(atempo->
window / 2);
630 for (i = 1; i <
window; i++, xa++, xb++, xc++) {
631 xc->
re = (xa->re * xb->re + xa->im * xb->im);
632 xc->
im = (xa->im * xb->re - xa->re * xb->im);
653 int best_offset = -drift;
668 i0 =
FFMAX(window / 2 - delta_max - drift, 0);
669 i0 =
FFMIN(i0, window);
671 i1 =
FFMIN(window / 2 + delta_max - drift, window - window / 16);
675 xcorr = correlation + i0;
677 for (i = i0; i < i1; i++, xcorr++) {
684 if (metric > best_metric) {
685 best_metric = metric;
686 best_offset = i - window / 2;
704 const double prev_output_position =
708 const double ideal_output_position =
711 const int drift = (
int)(prev_output_position - ideal_output_position);
713 const int delta_max = atempo->
window / 2;
737 #define yae_blend(scalar_type) \
739 const scalar_type *aaa = (const scalar_type *)a; \
740 const scalar_type *bbb = (const scalar_type *)b; \
742 scalar_type *out = (scalar_type *)dst; \
743 scalar_type *out_end = (scalar_type *)dst_end; \
746 for (i = 0; i < overlap && out < out_end; \
747 i++, atempo->position[1]++, wa++, wb++) { \
752 for (j = 0; j < atempo->channels; \
753 j++, aaa++, bbb++, out++) { \
754 float t0 = (float)*aaa; \
755 float t1 = (float)*bbb; \
758 frag->position[0] + i < 0 ? \
760 (scalar_type)(t0 * w0 + t1 * w1); \
763 dst = (uint8_t *)out; \
788 const int64_t overlap = stop_here - start_here;
790 const int64_t ia = start_here - prev->
position[1];
791 const int64_t ib = start_here - frag->
position[1];
793 const float *wa = atempo->
hann + ia;
794 const float *wb = atempo->
hann + ib;
803 overlap <= frag->nsamples);
849 if (!atempo->
nfrag) {
922 if (!atempo->
nfrag) {
956 while (atempo->
position[1] < overlap_end) {
971 offset = start_here - frag->
position[1];
972 av_assert0(start_here <= stop_here && frag->position[1] <= start_here);
977 src_size = (
int)(stop_here - start_here) * atempo->
stride;
978 dst_size = dst_end - dst;
979 nbytes =
FFMIN(src_size, dst_size);
981 memcpy(dst, src, nbytes);
1074 outlink->time_base);
1077 atempo->dst_buffer =
NULL;
1079 atempo->dst_end =
NULL;
1083 atempo->nsamples_out += n_out;
1095 int n_out = (
int)(0.5 + ((
double)n_in) / atempo->
tempo);
1100 while (src < src_end) {
1140 int n_max = atempo->
ring;
1144 while (err ==
AVERROR(EAGAIN)) {
1213 .priv_class = &atempo_class,
#define RE_MALLOC_OR_FAIL(field, field_size)
static int push_samples(ATempoContext *atempo, AVFilterLink *outlink, int n_out)
static const char * format[]
static void yae_xcorr_via_rdft(FFTSample *xcorr, RDFTContext *complex_to_real, const FFTComplex *xa, const FFTComplex *xb, const int window)
Calculate cross-correlation via rDFT.
This structure describes decoded (raw) audio or video data.
RDFTContext * complex_to_real
FilterState
Filter state machine states.
RDFTContext * real_to_complex
static int yae_set_tempo(AVFilterContext *ctx, const char *arg_tempo)
static int config_props(AVFilterLink *inlink)
Main libavfilter public API header.
enum AVSampleFormat format
#define AV_OPT_FLAG_AUDIO_PARAM
static void yae_apply(ATempoContext *atempo, const uint8_t **src_ref, const uint8_t *src_end, uint8_t **dst_ref, uint8_t *dst_end)
Feed as much data to the filter as it is able to consume and receive as much processed data in the de...
static const AVFilterPad atempo_outputs[]
static int request_frame(AVFilterLink *outlink)
AVFILTER_DEFINE_CLASS(atempo)
static void yae_advance_to_next_frag(ATempoContext *atempo)
Prepare for loading next audio fragment.
const char * name
Pad name.
AVFilterLink ** inputs
array of pointers to input links
static AudioFragment * yae_prev_frag(ATempoContext *atempo)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
static av_cold int end(AVCodecContext *avctx)
static AudioFragment * yae_curr_frag(ATempoContext *atempo)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
#define AVERROR_EOF
End of file.
static av_cold int init(AVFilterContext *ctx)
A filter pad used for either input or output.
static void yae_clear(ATempoContext *atempo)
Reset filter to initial state, do not deallocate existing local buffers.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
A link between two filters.
static int yae_load_data(ATempoContext *atempo, const uint8_t **src_ref, const uint8_t *src_end, int64_t stop_here)
Populate the internal data buffer on as-needed basis.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int sample_rate
samples per second
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
#define AV_OPT_FLAG_FILTERING_PARAM
a generic parameter which can be set by the user for filtering
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
A fragment of audio waveform.
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void * priv
private data for use by the filter
simple assert() macros that are a bit more flexible than ISO C assert().
static const uint8_t offset[127][2]
static int yae_flush(ATempoContext *atempo, uint8_t **dst_ref, uint8_t *dst_end)
Flush any buffered data from the filter.
void av_rdft_calc(RDFTContext *s, FFTSample *data)
static int yae_reset(ATempoContext *atempo, enum AVSampleFormat format, int sample_rate, int channels)
Prepare filter for processing audio data of given format, sample rate and number of channels...
static SDL_Window * window
static const AVFilterPad atempo_inputs[]
audio channel layout utility functions
static int yae_align(AudioFragment *frag, const AudioFragment *prev, const int window, const int delta_max, const int drift, FFTSample *correlation, RDFTContext *complex_to_real)
Calculate alignment offset for given fragment relative to the previous fragment.
static int yae_overlap_add(ATempoContext *atempo, uint8_t **dst_ref, uint8_t *dst_end)
Blend the overlap region of previous and current audio fragment and output the results to the given d...
void av_rdft_end(RDFTContext *s)
static int yae_adjust_position(ATempoContext *atempo)
Adjust current fragment position for better alignment with previous fragment.
AVFilterContext * src
source filter
RDFTContext * av_rdft_init(int nbits, enum RDFTransformType trans)
Set up a real FFT.
static int process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
static const AVFilterPad inputs[]
#define yae_blend(scalar_type)
A helper macro for blending the overlap region of previous and current audio fragment.
static const AVFilterPad outputs[]
int format
agreed upon media format
A list of supported channel layouts.
static int query_formats(AVFilterContext *ctx)
static void yae_release_buffers(ATempoContext *atempo)
Reset filter to initial state and deallocate all buffers.
double av_strtod(const char *numstr, char **tail)
Parse the string in numstr and return its value as a double.
AVSampleFormat
Audio sample formats.
static void correlation(int32_t *corr, int32_t *ener, int16_t *buffer, int16_t lag, int16_t blen, int16_t srange, int16_t scale)
static int filter_frame(AVFilterLink *inlink, AVFrame *src_buffer)
Describe the class of an AVClass context structure.
int sample_rate
Sample rate of the audio data.
Rational number (pair of numerator and denominator).
const char * name
Filter name.
AVFilterLink ** outputs
array of pointers to output links
enum MovChannelLayoutTag * layouts
#define yae_init_xdat(scalar_type, scalar_max)
A helper macro for initializing complex data buffer with scalar data of a given type.
#define flags(name, subs,...)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
int channels
Number of channels.
static av_cold void uninit(AVFilterContext *ctx)
AVFilterContext * dst
dest filter
static int yae_load_frag(ATempoContext *atempo, const uint8_t **src_ref, const uint8_t *src_end)
Populate current audio fragment data buffer.
static void yae_downmix(ATempoContext *atempo, AudioFragment *frag)
Initialize complex data buffer of a given audio fragment with down-mixed mono data of appropriate sca...
static enum AVSampleFormat sample_fmts[]
static const AVOption atempo_options[]
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link.
int nb_samples
number of audio samples (per channel) described by this frame
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
simple arithmetic expression evaluator