48#define MEAN_SUM(suffix, type, zero) \
49static type mean_sum_##suffix(const type *in, \
52 type mean_sum = zero; \
54 for (int i = 0; i < size; i++) \
63#define SQUARE_SUM(suffix, type, zero) \
64static type square_sum_##suffix(const type *x, \
68 type square_sum = zero; \
70 for (int i = 0; i < size; i++) \
71 square_sum += x[i] * y[i]; \
79#define XCORRELATE(suffix, type, zero, small, sqrtfun)\
80static type xcorrelate_##suffix(const type *x, \
83 type sumy, int size) \
85 const type xm = sumx / size, ym = sumy / size; \
86 type num = zero, den, den0 = zero, den1 = zero; \
88 for (int i = 0; i < size; i++) { \
89 type xd = x[i] - xm; \
90 type yd = y[i] - ym; \
98 den = sqrtfun((den0 * den1) / size / size); \
100 return den <= small ? zero : num / den; \
106#define XCORRELATE_SLOW(suffix, type) \
107static int xcorrelate_slow_##suffix(AVFilterContext *ctx, \
108 AVFrame *out, int available) \
110 AudioXCorrelateContext *s = ctx->priv; \
111 const int size = s->size; \
114 for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) { \
115 const type *x = (const type *)s->cache[0]->extended_data[ch]; \
116 const type *y = (const type *)s->cache[1]->extended_data[ch]; \
117 type *sumx = (type *)s->mean_sum[0]->extended_data[ch]; \
118 type *sumy = (type *)s->mean_sum[1]->extended_data[ch]; \
119 type *dst = (type *)out->extended_data[ch]; \
123 sumx[0] = mean_sum_##suffix(x, size); \
124 sumy[0] = mean_sum_##suffix(y, size); \
128 for (int n = 0; n < out->nb_samples; n++) { \
129 const int idx = n + size; \
131 dst[n] = xcorrelate_##suffix(x + n, y + n, \
148#define clipf(x) (av_clipf(x, -1.f, 1.f))
149#define clipd(x) (av_clipd(x, -1.0, 1.0))
151#define XCORRELATE_FAST(suffix, type, zero, small, sqrtfun, CLIP) \
152static int xcorrelate_fast_##suffix(AVFilterContext *ctx, AVFrame *out, \
155 AudioXCorrelateContext *s = ctx->priv; \
156 const int size = s->size; \
159 for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) { \
160 const type *x = (const type *)s->cache[0]->extended_data[ch]; \
161 const type *y = (const type *)s->cache[1]->extended_data[ch]; \
162 type *num_sum = (type *)s->num_sum->extended_data[ch]; \
163 type *den_sumx = (type *)s->den_sum[0]->extended_data[ch]; \
164 type *den_sumy = (type *)s->den_sum[1]->extended_data[ch]; \
165 type *dst = (type *)out->extended_data[ch]; \
169 num_sum[0] = square_sum_##suffix(x, y, size); \
170 den_sumx[0] = square_sum_##suffix(x, x, size); \
171 den_sumy[0] = square_sum_##suffix(y, y, size); \
175 for (int n = 0; n < out->nb_samples; n++) { \
176 const int idx = n + size; \
179 num = num_sum[0] / size; \
180 den = sqrtfun((den_sumx[0] * den_sumy[0]) / size / size); \
182 dst[n] = den <= small ? zero : CLIP(num / den); \
184 num_sum[0] -= x[n] * y[n]; \
185 num_sum[0] += x[idx] * y[idx]; \
186 den_sumx[0] -= x[n] * x[n]; \
187 den_sumx[0] += x[idx] * x[idx]; \
188 den_sumx[0] = FFMAX(den_sumx[0], zero); \
189 den_sumy[0] -= y[n] * y[n]; \
190 den_sumy[0] += y[idx] * y[idx]; \
191 den_sumy[0] = FFMAX(den_sumy[0], zero); \
201#define XCORRELATE_BEST(suffix, type, zero, small, sqrtfun, FMAX, CLIP) \
202static int xcorrelate_best_##suffix(AVFilterContext *ctx, AVFrame *out, \
205 AudioXCorrelateContext *s = ctx->priv; \
206 const int size = s->size; \
209 for (int ch = 0; ch < out->ch_layout.nb_channels; ch++) { \
210 const type *x = (const type *)s->cache[0]->extended_data[ch]; \
211 const type *y = (const type *)s->cache[1]->extended_data[ch]; \
212 type *mean_sumx = (type *)s->mean_sum[0]->extended_data[ch]; \
213 type *mean_sumy = (type *)s->mean_sum[1]->extended_data[ch]; \
214 type *num_sum = (type *)s->num_sum->extended_data[ch]; \
215 type *den_sumx = (type *)s->den_sum[0]->extended_data[ch]; \
216 type *den_sumy = (type *)s->den_sum[1]->extended_data[ch]; \
217 type *dst = (type *)out->extended_data[ch]; \
221 num_sum[0] = square_sum_##suffix(x, y, size); \
222 den_sumx[0] = square_sum_##suffix(x, x, size); \
223 den_sumy[0] = square_sum_##suffix(y, y, size); \
224 mean_sumx[0] = mean_sum_##suffix(x, size); \
225 mean_sumy[0] = mean_sum_##suffix(y, size); \
229 for (int n = 0; n < out->nb_samples; n++) { \
230 const int idx = n + size; \
231 type num, den, xm, ym; \
233 xm = mean_sumx[0] / size; \
234 ym = mean_sumy[0] / size; \
235 num = num_sum[0] - size * xm * ym; \
236 den = sqrtfun(FMAX(den_sumx[0] - size * xm * xm, zero)) * \
237 sqrtfun(FMAX(den_sumy[0] - size * ym * ym, zero)); \
239 dst[n] = den <= small ? zero : CLIP(num / den); \
241 mean_sumx[0]-= x[n]; \
242 mean_sumx[0]+= x[idx]; \
243 mean_sumy[0]-= y[n]; \
244 mean_sumy[0]+= y[idx]; \
245 num_sum[0] -= x[n] * y[n]; \
246 num_sum[0] += x[idx] * y[idx]; \
247 den_sumx[0] -= x[n] * x[n]; \
248 den_sumx[0] += x[idx] * x[idx]; \
249 den_sumx[0] = FMAX(den_sumx[0], zero); \
250 den_sumy[0] -= y[n] * y[n]; \
251 den_sumy[0] += y[idx] * y[idx]; \
252 den_sumy[0] = FMAX(den_sumy[0], zero); \
273 for (
int i = 0;
i < 2 && !
s->eof;
i++) {
287 if (available >
s->size) {
288 const int out_samples = available -
s->size;
291 if (!
s->cache[0] ||
s->cache[0]->nb_samples < available) {
298 if (!
s->cache[1] ||
s->cache[1]->nb_samples < available) {
317 s->used =
s->xcorrelate(
ctx,
out, available);
320 s->pts += out_samples;
328 for (
int i = 0;
i < 2 && !
s->eof;
i++) {
360 for (
int i = 0;
i < 2;
i++) {
380 if (!
s->fifo[0] || !
s->fifo[1])
388 if (!
s->mean_sum[0] || !
s->mean_sum[1] || !
s->num_sum ||
389 !
s->den_sum[0] || !
s->den_sum[1])
393 case 0:
s->xcorrelate = xcorrelate_slow_f;
break;
394 case 1:
s->xcorrelate = xcorrelate_fast_f;
break;
395 case 2:
s->xcorrelate = xcorrelate_best_f;
break;
400 case 0:
s->xcorrelate = xcorrelate_slow_d;
break;
401 case 1:
s->xcorrelate = xcorrelate_fast_d;
break;
402 case 2:
s->xcorrelate = xcorrelate_best_d;
break;
426 .name =
"axcorrelate0",
430 .name =
"axcorrelate1",
443#define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
444#define OFFSET(x) offsetof(AudioXCorrelateContext, x)
458 .p.name =
"axcorrelate",
460 .p.priv_class = &axcorrelate_class,
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
#define XCORRELATE(suffix, type, zero, small, sqrtfun)
#define MEAN_SUM(suffix, type, zero)
#define XCORRELATE_FAST(suffix, type, zero, small, sqrtfun, CLIP)
#define XCORRELATE_BEST(suffix, type, zero, small, sqrtfun, FMAX, CLIP)
#define XCORRELATE_SLOW(suffix, type)
#define SQUARE_SUM(suffix, type, zero)
static av_cold void uninit(AVFilterContext *ctx)
static const AVOption axcorrelate_options[]
const FFFilter ff_af_axcorrelate
static int config_output(AVFilterLink *outlink)
static AVFormatContext * ctx
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
int ff_inlink_acknowledge_status(AVFilterLink *link, int *rstatus, int64_t *rpts)
Test and acknowledge the change of status on the link.
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
int ff_outlink_frame_wanted(AVFilterLink *link)
Test if a frame is wanted on an output link.
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
int ff_inlink_consume_frame(AVFilterLink *link, AVFrame **rframe)
Take a frame from the link's FIFO and update the link's stats.
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Main libavfilter public API header.
#define i(width, name, range_min, range_max)
Public libavutil channel layout APIs header.
common internal and external API header
static __device__ float sqrtf(float a)
double fmax(double, double)
float fmaxf(float, float)
@ AV_OPT_TYPE_CONST
Special option type for declaring named constants.
@ AV_OPT_TYPE_INT
Underlying C type is int.
int av_audio_fifo_peek(const AVAudioFifo *af, void *const *data, int nb_samples)
Peek data from an AVAudioFifo.
AVAudioFifo * av_audio_fifo_alloc(enum AVSampleFormat sample_fmt, int channels, int nb_samples)
Allocate an AVAudioFifo.
int av_audio_fifo_write(AVAudioFifo *af, void *const *data, int nb_samples)
Write data to an AVAudioFifo.
void av_audio_fifo_free(AVAudioFifo *af)
Free an AVAudioFifo.
int av_audio_fifo_size(AVAudioFifo *af)
Get the current number of samples in the AVAudioFifo available for reading.
int av_audio_fifo_drain(AVAudioFifo *af, int nb_samples)
Drain data from an AVAudioFifo.
#define AVERROR_EOF
End of file.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
@ AV_SAMPLE_FMT_FLTP
float, planar
@ AV_SAMPLE_FMT_DBLP
double, planar
#define AV_NOPTS_VALUE
Undefined timestamp value.
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
static int config_output(AVBitStreamFilterLink *outlink)
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
#define FILTER_SAMPLEFMTS(...)
static void ff_outlink_set_status(AVFilterLink *link, int status, int64_t pts)
Set the status field of a link from the source filter.
#define FFERROR_NOT_READY
Filters implementation helper functions and internal structures.
#define FF_FILTER_FORWARD_STATUS_BACK_ALL(outlink, filter)
Forward the status on an output link to all input links.
#define AVFILTER_DEFINE_CLASS(fname)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Context for an Audio FIFO Buffer.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
A link between two filters.
AVFilterContext * src
source filter
AVChannelLayout ch_layout
channel layout of current buffer (see libavutil/channel_layout.h)
int format
agreed upon media format
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
int nb_samples
number of audio samples (per channel) described by this frame
uint8_t ** extended_data
pointers to the data planes/channels.
int(* xcorrelate)(AVFilterContext *ctx, AVFrame *out, int available)