FFmpeg
Loading...
Searching...
No Matches
af_atempo.c File Reference

tempo scaling audio filter – an implementation of WSOLA algorithm More...

#include <float.h>
#include "libavutil/avassert.h"
#include "libavutil/channel_layout.h"
#include "libavutil/mem.h"
#include "libavutil/opt.h"
#include "libavutil/samplefmt.h"
#include "libavutil/tx.h"
#include "avfilter.h"
#include "audio.h"
#include "filters.h"

Go to the source code of this file.

Data Structures

struct  AudioFragment
 A fragment of audio waveform. More...
 
struct  ATempoContext
 Filter state machine. More...
 

Macros

#define YAE_ATEMPO_MIN   0.5
 
#define YAE_ATEMPO_MAX   100.0
 
#define OFFSET(x)
 
#define yae_init_xdat(scalar_type, scalar_max)
 A helper macro for initializing complex data buffer with scalar data of a given type.
 
#define yae_blend(scalar_type)
 A helper macro for blending the overlap region of previous and current audio fragment.
 

Enumerations

enum  FilterState {
  YAE_LOAD_FRAGMENT , YAE_ADJUST_POSITION , YAE_RELOAD_FRAGMENT , YAE_OUTPUT_OVERLAP_ADD ,
  YAE_FLUSH_OUTPUT
}
 Filter state machine states. More...
 

Functions

 AVFILTER_DEFINE_CLASS (atempo)
 
static AudioFragmentyae_curr_frag (ATempoContext *atempo)
 
static AudioFragmentyae_prev_frag (ATempoContext *atempo)
 
static void yae_clear (ATempoContext *atempo)
 Reset filter to initial state, do not deallocate existing local buffers.
 
static void yae_release_buffers (ATempoContext *atempo)
 Reset filter to initial state and deallocate all buffers.
 
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 int yae_update (AVFilterContext *ctx)
 
static void yae_downmix (ATempoContext *atempo, AudioFragment *frag)
 Initialize complex data buffer of a given audio fragment with down-mixed mono data of appropriate scalar type.
 
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.
 
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_advance_to_next_frag (ATempoContext *atempo)
 Prepare for loading next audio fragment.
 
static void yae_xcorr_via_rdft (float *xcorr_in, float *xcorr, AVTXContext *complex_to_real, av_tx_fn c2r_fn, const AVComplexFloat *xa, const AVComplexFloat *xb, const int window)
 Calculate cross-correlation via rDFT.
 
static int yae_align (AudioFragment *frag, const AudioFragment *prev, const int window, const int delta_max, const int drift, float *correlation_in, float *correlation, AVTXContext *complex_to_real, av_tx_fn c2r_fn)
 Calculate alignment offset for given fragment relative to the previous fragment.
 
static int yae_adjust_position (ATempoContext *atempo)
 Adjust current fragment position for better alignment with 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 destination buffer.
 
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 destination buffer as it is able to produce or store.
 
static int yae_flush (ATempoContext *atempo, uint8_t **dst_ref, uint8_t *dst_end)
 Flush any buffered data from the filter.
 
static av_cold int init (AVFilterContext *ctx)
 
static av_cold void uninit (AVFilterContext *ctx)
 
static int config_props (AVFilterLink *inlink)
 
static int push_samples (ATempoContext *atempo, AVFilterLink *outlink, int n_out)
 
static int filter_frame (AVFilterLink *inlink, AVFrame *src_buffer)
 
static int request_frame (AVFilterLink *outlink)
 
static int process_command (AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
 

Variables

static const AVOption atempo_options []
 
static enum AVSampleFormat sample_fmts []
 
static const AVFilterPad atempo_inputs []
 
static const AVFilterPad atempo_outputs []
 
const FFFilter ff_af_atempo
 

Detailed Description

tempo scaling audio filter – an implementation of WSOLA algorithm

Based on MIT licensed yaeAudioTempoFilter.h and yaeAudioFragment.h from Apprentice Video player by Pavel Koshevoy. https://sourceforge.net/projects/apprenticevideo/

An explanation of SOLA algorithm is available at http://www.surina.net/article/time-and-pitch-scaling.html

WSOLA is very similar to SOLA, only one major difference exists between these algorithms. SOLA shifts audio fragments along the output stream, where as WSOLA shifts audio fragments along the input stream.

The advantage of WSOLA algorithm is that the overlap region size is always the same, therefore the blending function is constant and can be precomputed.

Definition in file af_atempo.c.

Macro Definition Documentation

◆ YAE_ATEMPO_MIN

#define YAE_ATEMPO_MIN   0.5

Definition at line 157 of file af_atempo.c.

◆ YAE_ATEMPO_MAX

#define YAE_ATEMPO_MAX   100.0

Definition at line 158 of file af_atempo.c.

◆ OFFSET

#define OFFSET ( x)
Value:
offsetof(ATempoContext, x)
Filter state machine.
Definition af_atempo.c:87

Definition at line 160 of file af_atempo.c.

◆ yae_init_xdat

#define yae_init_xdat ( scalar_type,
scalar_max )

A helper macro for initializing complex data buffer with scalar data of a given type.

Definition at line 353 of file af_atempo.c.

Referenced by yae_downmix().

◆ yae_blend

#define yae_blend ( scalar_type)
Value:
do { \
const scalar_type *aaa = (const scalar_type *)a; \
const scalar_type *bbb = (const scalar_type *)b; \
\
scalar_type *out = (scalar_type *)dst; \
scalar_type *out_end = (scalar_type *)dst_end; \
\
for (i = 0; i < overlap && out < out_end; \
i++, atempo->position[1]++, wa++, wb++) { \
float w0 = *wa; \
float w1 = *wb; \
int j; \
\
for (j = 0; j < atempo->channels; \
j++, aaa++, bbb++, out++) { \
float t0 = (float)*aaa; \
float t1 = (float)*bbb; \
\
*out = \
frag->position[0] + i < 0 ? \
*aaa : \
(scalar_type)(t0 * w0 + t1 * w1); \
} \
} \
dst = (uint8_t *)out; \
} while (0)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
long long int64_t
Definition coverity.c:34
int a
#define b
Definition input.c:43
static FILE * out
Definition movenc.c:55

A helper macro for blending the overlap region of previous and current audio fragment.

Definition at line 732 of file af_atempo.c.

Referenced by yae_overlap_add().

Enumeration Type Documentation

◆ FilterState

Filter state machine states.

Enumerator
YAE_LOAD_FRAGMENT 
YAE_ADJUST_POSITION 
YAE_RELOAD_FRAGMENT 
YAE_OUTPUT_OVERLAP_ADD 
YAE_FLUSH_OUTPUT 

Definition at line 76 of file af_atempo.c.

Function Documentation

◆ AVFILTER_DEFINE_CLASS()

AVFILTER_DEFINE_CLASS ( atempo )

◆ yae_curr_frag()

static AudioFragment * yae_curr_frag ( ATempoContext * atempo)
inlinestatic

◆ yae_prev_frag()

static AudioFragment * yae_prev_frag ( ATempoContext * atempo)
inlinestatic

◆ yae_clear()

static void yae_clear ( ATempoContext * atempo)
static

Reset filter to initial state, do not deallocate existing local buffers.

Definition at line 186 of file af_atempo.c.

Referenced by yae_release_buffers().

◆ yae_release_buffers()

static void yae_release_buffers ( ATempoContext * atempo)
static

Reset filter to initial state and deallocate all buffers.

Definition at line 227 of file af_atempo.c.

Referenced by uninit(), and yae_reset().

◆ yae_reset()

static int yae_reset ( ATempoContext * atempo,
enum AVSampleFormat format,
int sample_rate,
int channels )
static

Prepare filter for processing audio data of given format, sample rate and number of channels.

Definition at line 251 of file af_atempo.c.

Referenced by config_props().

◆ yae_update()

static int yae_update ( AVFilterContext * ctx)
static

Definition at line 338 of file af_atempo.c.

Referenced by process_command().

◆ yae_downmix()

static void yae_downmix ( ATempoContext * atempo,
AudioFragment * frag )
static

Initialize complex data buffer of a given audio fragment with down-mixed mono data of appropriate scalar type.

Definition at line 403 of file af_atempo.c.

Referenced by yae_apply(), and yae_flush().

◆ yae_load_data()

static int yae_load_data ( ATempoContext * atempo,
const uint8_t ** src_ref,
const uint8_t * src_end,
int64_t stop_here )
static

Populate the internal data buffer on as-needed basis.

Returns
0 if requested data was already available or was successfully loaded, AVERROR(EAGAIN) if more input data is required.

Definition at line 431 of file af_atempo.c.

Referenced by yae_load_frag().

◆ yae_load_frag()

static int yae_load_frag ( ATempoContext * atempo,
const uint8_t ** src_ref,
const uint8_t * src_end )
static

Populate current audio fragment data buffer.

Returns
0 when the fragment is ready, AVERROR(EAGAIN) if more input data is required.

Definition at line 506 of file af_atempo.c.

Referenced by yae_apply(), and yae_flush().

◆ yae_advance_to_next_frag()

static void yae_advance_to_next_frag ( ATempoContext * atempo)
static

Prepare for loading next audio fragment.

Definition at line 586 of file af_atempo.c.

Referenced by yae_apply(), and yae_flush().

◆ yae_xcorr_via_rdft()

static void yae_xcorr_via_rdft ( float * xcorr_in,
float * xcorr,
AVTXContext * complex_to_real,
av_tx_fn c2r_fn,
const AVComplexFloat * xa,
const AVComplexFloat * xb,
const int window )
static

Calculate cross-correlation via rDFT.

Multiply two vectors of complex numbers (result of real_to_complex rDFT) and transform back via complex_to_real rDFT.

Definition at line 608 of file af_atempo.c.

Referenced by yae_align().

◆ yae_align()

static int yae_align ( AudioFragment * frag,
const AudioFragment * prev,
const int window,
const int delta_max,
const int drift,
float * correlation_in,
float * correlation,
AVTXContext * complex_to_real,
av_tx_fn c2r_fn )
static

Calculate alignment offset for given fragment relative to the previous fragment.

Returns
alignment offset of current fragment relative to previous.

Definition at line 634 of file af_atempo.c.

Referenced by yae_adjust_position().

◆ yae_adjust_position()

static int yae_adjust_position ( ATempoContext * atempo)
static

Adjust current fragment position for better alignment with previous fragment.

Returns
alignment correction.

Definition at line 692 of file af_atempo.c.

Referenced by yae_apply(), and yae_flush().

◆ yae_overlap_add()

static int yae_overlap_add ( ATempoContext * atempo,
uint8_t ** dst_ref,
uint8_t * dst_end )
static

Blend the overlap region of previous and current audio fragment and output the results to the given destination buffer.

Returns
0 if the overlap region was completely stored in the dst buffer, AVERROR(EAGAIN) if more destination buffer space is required.

Definition at line 769 of file af_atempo.c.

Referenced by yae_apply(), and yae_flush().

◆ yae_apply()

static void yae_apply ( ATempoContext * atempo,
const uint8_t ** src_ref,
const uint8_t * src_end,
uint8_t ** dst_ref,
uint8_t * dst_end )
static

Feed as much data to the filter as it is able to consume and receive as much processed data in the destination buffer as it is able to produce or store.

Definition at line 824 of file af_atempo.c.

Referenced by filter_frame().

◆ yae_flush()

static int yae_flush ( ATempoContext * atempo,
uint8_t ** dst_ref,
uint8_t * dst_end )
static

Flush any buffered data from the filter.

Returns
0 if all data was completely stored in the dst buffer, AVERROR(EAGAIN) if more destination buffer space is required.

Definition at line 898 of file af_atempo.c.

Referenced by request_frame().

◆ init()

static av_cold int init ( AVFilterContext * ctx)
static

Definition at line 987 of file af_atempo.c.

◆ uninit()

static av_cold void uninit ( AVFilterContext * ctx)
static

Definition at line 995 of file af_atempo.c.

◆ config_props()

static int config_props ( AVFilterLink * inlink)
static

Definition at line 1016 of file af_atempo.c.

◆ push_samples()

static int push_samples ( ATempoContext * atempo,
AVFilterLink * outlink,
int n_out )
static

Definition at line 1027 of file af_atempo.c.

Referenced by filter_frame(), and request_frame().

◆ filter_frame()

static int filter_frame ( AVFilterLink * inlink,
AVFrame * src_buffer )
static

Definition at line 1053 of file af_atempo.c.

◆ request_frame()

static int request_frame ( AVFilterLink * outlink)
static

Definition at line 1101 of file af_atempo.c.

◆ process_command()

static int process_command ( AVFilterContext * ctx,
const char * cmd,
const char * arg,
char * res,
int res_len,
int flags )
static

Definition at line 1147 of file af_atempo.c.

Variable Documentation

◆ atempo_options

const AVOption atempo_options[]
static
Initial value:
= {
{ "tempo", "set tempo scale factor",
OFFSET(tempo), AV_OPT_TYPE_DOUBLE, { .dbl = 1.0 },
{ NULL }
}
#define YAE_ATEMPO_MAX
Definition af_atempo.c:158
#define YAE_ATEMPO_MIN
Definition af_atempo.c:157
#define NULL
Definition coverity.c:32
#define OFFSET(x)
#define AV_OPT_FLAG_FILTERING_PARAM
A generic parameter which can be set by the user for filtering.
Definition opt.h:380
#define AV_OPT_FLAG_AUDIO_PARAM
Definition opt.h:356
#define AV_OPT_FLAG_RUNTIME_PARAM
A generic parameter which can be set by the user at runtime.
Definition opt.h:376
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
Definition opt.h:266

Definition at line 162 of file af_atempo.c.

◆ sample_fmts

enum AVSampleFormat sample_fmts[]
static
Initial value:
= {
}
@ AV_SAMPLE_FMT_FLT
float
Definition samplefmt.h:60
@ AV_SAMPLE_FMT_S32
signed 32 bits
Definition samplefmt.h:59
@ AV_SAMPLE_FMT_NONE
Definition samplefmt.h:56
@ AV_SAMPLE_FMT_U8
unsigned 8 bits
Definition samplefmt.h:57
@ AV_SAMPLE_FMT_DBL
double
Definition samplefmt.h:61
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition samplefmt.h:58

Definition at line 1007 of file af_atempo.c.

◆ atempo_inputs

const AVFilterPad atempo_inputs[]
static
Initial value:
= {
{
.name = "default",
.filter_frame = filter_frame,
.config_props = config_props,
},
}
static int filter_frame(DBEDecodeContext *s, AVFrame *frame)
Definition dolby_e.c:1067
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
static int config_props(AVBitStreamFilterLink *link)
Definition source.c:181

Definition at line 1162 of file af_atempo.c.

◆ atempo_outputs

const AVFilterPad atempo_outputs[]
static
Initial value:
= {
{
.name = "default",
.request_frame = request_frame,
},
}
static int request_frame(AVFilterLink *outlink)
Definition af_aecho.c:272

Definition at line 1171 of file af_atempo.c.

◆ ff_af_atempo

const FFFilter ff_af_atempo
Initial value:
= {
.p.name = "atempo",
.p.description = NULL_IF_CONFIG_SMALL("Adjust audio tempo."),
.p.priv_class = &atempo_class,
.init = init,
.uninit = uninit,
.process_command = process_command,
.priv_size = sizeof(ATempoContext),
}
static enum AVSampleFormat sample_fmts[]
Definition adpcmenc.c:933
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static const AVFilterPad atempo_inputs[]
Definition af_atempo.c:1162
static const AVFilterPad atempo_outputs[]
Definition af_atempo.c:1171
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static av_cold void uninit(AVBitStreamFilterContext *ctx)
#define FILTER_INPUTS(array)
Definition filters.h:264
#define FILTER_SAMPLEFMTS_ARRAY(array)
Definition filters.h:247
#define FILTER_OUTPUTS(array)
Definition filters.h:265
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88

Definition at line 1179 of file af_atempo.c.