#include <float.h>
#include "libavcodec/avfft.h"
#include "libavutil/audioconvert.h"
#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/eval.h"
#include "libavutil/opt.h"
#include "libavutil/samplefmt.h"
#include "avfilter.h"
#include "audio.h"
#include "internal.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... | |
Defines | |
#define | RE_MALLOC_OR_FAIL(field, field_size) |
#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 | |
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_set_tempo (AVFilterContext *ctx, const char *arg_tempo) |
static AudioFragment * | yae_curr_frag (ATempoContext *atempo) |
static AudioFragment * | yae_prev_frag (ATempoContext *atempo) |
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 (FFTSample *xcorr, RDFTContext *complex_to_real, const FFTComplex *xa, const FFTComplex *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, FFTSample *correlation, RDFTContext *complex_to_real) |
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, const char *args) |
static av_cold void | uninit (AVFilterContext *ctx) |
static int | query_formats (AVFilterContext *ctx) |
static int | config_props (AVFilterLink *inlink) |
static void | push_samples (ATempoContext *atempo, AVFilterLink *outlink, int n_out) |
static int | filter_samples (AVFilterLink *inlink, AVFilterBufferRef *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 | |
AVFilter | avfilter_af_atempo |
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.
#define RE_MALLOC_OR_FAIL | ( | field, | |||
field_size | ) |
Value:
do { \ av_freep(&field); \ field = av_malloc(field_size); \ if (!field) { \ yae_release_buffers(atempo); \ return AVERROR(ENOMEM); \ } \ } while (0)
Definition at line 214 of file af_atempo.c.
Referenced by yae_reset().
#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; \ int64_t i; \ \ 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)
Definition at line 708 of file af_atempo.c.
Referenced by yae_overlap_add().
#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 333 of file af_atempo.c.
Referenced by yae_downmix().
enum FilterState |
Filter state machine states.
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.
static int config_props | ( | AVFilterLink * | inlink | ) | [static] |
Definition at line 1011 of file af_atempo.c.
static int filter_samples | ( | AVFilterLink * | inlink, | |
AVFilterBufferRef * | src_buffer | |||
) | [static] |
Definition at line 1044 of file af_atempo.c.
static av_cold int init | ( | AVFilterContext * | ctx, | |
const char * | args | |||
) | [static] |
Definition at line 952 of file af_atempo.c.
static int process_command | ( | AVFilterContext * | ctx, | |
const char * | cmd, | |||
const char * | arg, | |||
char * | res, | |||
int | res_len, | |||
int | flags | |||
) | [static] |
Definition at line 1129 of file af_atempo.c.
static void push_samples | ( | ATempoContext * | atempo, | |
AVFilterLink * | outlink, | |||
int | n_out | |||
) | [static] |
Definition at line 1023 of file af_atempo.c.
static int query_formats | ( | AVFilterContext * | ctx | ) | [static] |
Definition at line 970 of file af_atempo.c.
static int request_frame | ( | AVFilterLink * | outlink | ) | [static] |
Definition at line 1081 of file af_atempo.c.
static av_cold void uninit | ( | AVFilterContext * | ctx | ) | [static] |
Definition at line 964 of file af_atempo.c.
static int yae_adjust_position | ( | ATempoContext * | atempo | ) | [static] |
Adjust current fragment position for better alignment with previous fragment.
Definition at line 676 of file af_atempo.c.
Referenced by yae_apply(), and yae_flush().
static void yae_advance_to_next_frag | ( | ATempoContext * | atempo | ) | [static] |
Prepare for loading next audio fragment.
Definition at line 566 of file af_atempo.c.
Referenced by yae_apply().
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 | |||
) | [static] |
Calculate alignment offset for given fragment relative to the previous fragment.
Definition at line 622 of file af_atempo.c.
Referenced by yae_adjust_position().
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 800 of file af_atempo.c.
Referenced by filter_samples().
static void yae_clear | ( | ATempoContext * | atempo | ) | [static] |
Reset filter to initial state, do not deallocate existing local buffers.
Definition at line 153 of file af_atempo.c.
Referenced by yae_release_buffers(), and yae_reset().
static AudioFragment* yae_curr_frag | ( | ATempoContext * | atempo | ) | [inline, static] |
Definition at line 319 of file af_atempo.c.
Referenced by yae_adjust_position(), yae_advance_to_next_frag(), yae_apply(), yae_flush(), yae_load_frag(), and yae_overlap_add().
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 383 of file af_atempo.c.
Referenced by yae_apply(), and yae_flush().
static int yae_flush | ( | ATempoContext * | atempo, | |
uint8_t ** | dst_ref, | |||
uint8_t * | dst_end | |||
) | [static] |
Flush any buffered data from the filter.
Definition at line 874 of file af_atempo.c.
Referenced by request_frame().
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.
Definition at line 411 of file af_atempo.c.
Referenced by 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.
Definition at line 486 of file af_atempo.c.
Referenced by yae_apply(), and yae_flush().
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.
Definition at line 745 of file af_atempo.c.
Referenced by yae_apply(), and yae_flush().
static AudioFragment* yae_prev_frag | ( | ATempoContext * | atempo | ) | [inline, static] |
Definition at line 324 of file af_atempo.c.
Referenced by yae_adjust_position(), yae_advance_to_next_frag(), and yae_overlap_add().
static void yae_release_buffers | ( | ATempoContext * | atempo | ) | [static] |
Reset filter to initial state and deallocate all buffers.
Definition at line 192 of file af_atempo.c.
Referenced by uninit(), and 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 228 of file af_atempo.c.
Referenced by config_props().
static int yae_set_tempo | ( | AVFilterContext * | ctx, | |
const char * | arg_tempo | |||
) | [static] |
static void yae_xcorr_via_rdft | ( | FFTSample * | xcorr, | |
RDFTContext * | complex_to_real, | |||
const FFTComplex * | xa, | |||
const FFTComplex * | 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 588 of file af_atempo.c.
Referenced by yae_align().
Initial value:
{ .name = "atempo", .description = NULL_IF_CONFIG_SMALL("Adjust audio tempo."), .init = init, .uninit = uninit, .query_formats = query_formats, .process_command = process_command, .priv_size = sizeof(ATempoContext), .inputs = (const AVFilterPad[]) { { .name = "default", .type = AVMEDIA_TYPE_AUDIO, .filter_samples = filter_samples, .config_props = config_props, .min_perms = AV_PERM_READ, }, { .name = NULL} }, .outputs = (const AVFilterPad[]) { { .name = "default", .request_frame = request_frame, .type = AVMEDIA_TYPE_AUDIO, }, { .name = NULL} }, }
Definition at line 1139 of file af_atempo.c.