95#define OFFSET(x) offsetof(AudioDRCContext, x)
96#define FLAGS AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_FILTERING_PARAM | AV_OPT_FLAG_RUNTIME_PARAM
110 for (
int i = 0;
i <
size;
i++) {
126 s->overlap =
s->fft_size / 4;
142 if (!
s->in_buffer || !
s->in_frame || !
s->target_gain ||
143 !
s->out_dist_frame || !
s->windowed_frame || !
s->envelope ||
144 !
s->drc_frame || !
s->spectrum_buf || !
s->energy || !
s->factors)
152 s->itx_ctx =
av_calloc(
s->channels,
sizeof(*
s->itx_ctx));
153 if (!
s->tx_ctx || !
s->itx_ctx)
156 for (
int ch = 0; ch <
s->channels; ch++) {
157 scale = 1.f /
s->fft_size;
176 const float *in_frame,
float *out_frame,
const int add_to_out_frame)
178 const float *
window =
s->window;
179 const int fft_size =
s->fft_size;
181 if (add_to_out_frame) {
182 for (
int i = 0;
i < fft_size;
i++)
185 for (
int i = 0;
i < fft_size;
i++)
198 const float *spectral)
200 for (
int n = 0; n <
len; n++) {
201 energy[n] = 10.f *
log10f(
sqrf(spectral[2 * n]) +
sqrf(spectral[2 * n + 1]));
202 if (!isnormal(energy[n]))
212 float fx,
int bypass)
217 memcpy(gain, energy,
sizeof(*gain) *
len);
221 for (
int n = 0; n <
len; n++) {
222 const float Xg = energy[n];
224 var_values[
VAR_P] = Xg;
225 var_values[
VAR_F] = n * fx;
238 const float release =
s->release;
239 const float attack =
s->attack;
241 for (
int n = 0; n <
len; n++) {
242 const float Bg = gain[n] - energy[n];
246 envelope[n] = attack * Vg + (1.f - attack) * Bg;
247 }
else if (Bg <= Vg) {
248 envelope[n] = release * Vg + (1.f - release) * Bg;
260 for (
int n = 0; n <
len; n++)
267 const float *factors)
269 for (
int n = 0; n <
len; n++) {
270 spectrum[2*n+0] *= factors[n];
271 spectrum[2*n+1] *= factors[n];
276 const float *in_samples,
float *out_samples,
277 float *in_frame,
float *out_dist_frame,
278 float *windowed_frame,
float *drc_frame,
279 float *spectrum_buf,
float *energy,
280 float *target_gain,
float *
envelope,
285 const int fft_size =
s->fft_size;
286 const int nb_coeffs =
s->fft_size / 2 + 1;
287 const int overlap =
s->overlap;
291 memcpy(var_values,
s->var_values,
sizeof(var_values));
296 memmove(in_frame, in_frame + overlap, (fft_size - overlap) *
sizeof(*in_frame));
297 memmove(out_dist_frame, out_dist_frame + overlap, (fft_size - overlap) *
sizeof(*out_dist_frame));
299 memcpy(in_frame + fft_size - overlap, in_samples,
sizeof(*in_frame) * overlap);
300 memset(out_dist_frame + fft_size - overlap, 0,
sizeof(*out_dist_frame) * overlap);
303 s->tx_fn(
s->tx_ctx[ch], spectrum_buf, windowed_frame,
sizeof(
float));
316 if (!
ctx->is_disabled) {
317 for (
int i = 0;
i < overlap;
i++)
318 out_samples[
i] = out_dist_frame[
i] / 1.5f;
320 memcpy(out_samples, in_frame,
sizeof(*out_samples) * overlap);
328 float *in_buffer = (
float *)
s->in_buffer->extended_data[ch];
329 float *
dst = (
float *)
out->extended_data[ch];
331 memcpy(in_buffer,
src,
sizeof(*in_buffer) *
s->overlap);
334 (
float *)(
s->in_frame->extended_data[ch]),
335 (
float *)(
s->out_dist_frame->extended_data[ch]),
336 (
float *)(
s->windowed_frame->extended_data[ch]),
337 (
float *)(
s->drc_frame->extended_data[ch]),
338 (
float *)(
s->spectrum_buf->extended_data[ch]),
339 (
float *)(
s->energy->extended_data[ch]),
340 (
float *)(
s->target_gain->extended_data[ch]),
341 (
float *)(
s->envelope->extended_data[ch]),
342 (
float *)(
s->factors->extended_data[ch]));
352 const int start =
ff_slice_pos(
out->ch_layout.nb_channels, jobnr, nb_jobs);
353 const int end =
ff_slice_pos(
out->ch_layout.nb_channels, jobnr + 1, nb_jobs);
355 for (
int ch = start; ch < end; ch++)
390 return ret < 0 ? ret : 0;
405 if (strcmp(
s->channels_to_filter,
"all"))
454 for (
int ch = 0; ch <
s->channels; ch++) {
466 char *res,
int res_len,
int flags)
473 if (ret >= 0 && strcmp(old_expr_str,
s->expr_str)) {
492 .p.priv_class = &adrc_class,
static void(*const apply_window[4])(AVFloatDSPContext *fdsp, SingleChannelElement *sce, const float *audio)
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
static const AVFilterPad inputs[]
static int config_input(AVFilterLink *inlink)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
const FFFilter ff_af_adrc
static void get_energy(AVFilterContext *ctx, int len, float *energy, const float *spectral)
static int drc_channel(AVFilterContext *ctx, AVFrame *in, AVFrame *out, int ch)
static void generate_hann_window(float *window, int size)
static void get_envelope(AVFilterContext *ctx, int len, float *envelope, const float *energy, const float *gain)
static int config_input(AVFilterLink *inlink)
static float sqrf(float x)
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
static void get_factors(AVFilterContext *ctx, int len, float *factors, const float *envelope)
static void apply_factors(AVFilterContext *ctx, int len, float *spectrum, const float *factors)
static int drc_channels(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static int activate(AVFilterContext *ctx)
static av_cold void uninit(AVFilterContext *ctx)
static void get_target_gain(AVFilterContext *ctx, int len, float *gain, const float *energy, double *var_values, float fx, int bypass)
static void feed(AVFilterContext *ctx, int ch, const float *in_samples, float *out_samples, float *in_frame, float *out_dist_frame, float *windowed_frame, float *drc_frame, float *spectrum_buf, float *energy, float *target_gain, float *envelope, float *factors)
static const AVOption adrc_options[]
const AVFilterPad ff_audio_default_filterpad[1]
An AVFilterPad array whose only entry has name "default" and is of type AVMEDIA_TYPE_AUDIO.
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.
int ff_filter_process_command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Generic processing of user supplied commands that are set in the same way as the filter options.
int ff_filter_execute(AVFilterContext *ctx, avfilter_action_func *func, void *arg, int *ret, int nb_jobs)
int ff_inlink_consume_samples(AVFilterLink *link, unsigned min, unsigned max, AVFrame **rframe)
Take samples from the link's FIFO and update the link's stats.
int ff_filter_get_nb_threads(AVFilterContext *ctx)
Get number of threads for current filter instance.
void ff_filter_set_ready(AVFilterContext *filter, unsigned priority)
Mark a filter ready and schedule it for activation.
int ff_inlink_queued_samples(AVFilterLink *link)
void ff_inlink_request_frame(AVFilterLink *link)
Mark that a frame is wanted on the link.
Main libavfilter public API header.
#define flags(name, subs,...)
#define i(width, name, range_min, range_max)
static __device__ float sqrtf(float a)
channel
Use these values when setting the channel map with ebur128_set_channel().
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse().
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression.
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression.
simple arithmetic expression evaluator
internal math functions header
static av_always_inline float ff_exp10f(float x)
static SDL_Window * window
@ AV_OPT_TYPE_DOUBLE
Underlying C type is double.
@ AV_OPT_TYPE_STRING
Underlying C type is a uint8_t* that is either NULL or points to a C string allocated with the av_mal...
#define AVFILTER_FLAG_SLICE_THREADS
The filter supports multithreading by splitting frames into multiple parts and processing them concur...
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
int av_channel_layout_from_string(AVChannelLayout *channel_layout, const char *str)
Initialize a channel layout from a given string description.
int av_channel_layout_index_from_channel(const AVChannelLayout *channel_layout, enum AVChannel channel)
Get the index of a given channel in a channel layout.
enum AVChannel av_channel_layout_channel_from_index(const AVChannelLayout *channel_layout, unsigned int idx)
Get the channel with the given index in a channel layout.
void av_channel_layout_uninit(AVChannelLayout *channel_layout)
Free any allocated data in the channel layout and reset the channel count to 0.
int av_channel_layout_copy(AVChannelLayout *dst, const AVChannelLayout *src)
Make a copy of a channel layout.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
Copy only "metadata" fields from src to dst.
@ AV_SAMPLE_FMT_FLTP
float, planar
static void scale(int *out, const int *in, const int w, const int h, const int shift)
static av_cold void uninit(AVBitStreamFilterContext *ctx)
static int activate(AVBitStreamFilterContext *ctx)
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
static int ff_slice_pos(int total, int jobnr, int nb_jobs)
Compute the boundary index for a slice when work of size total is split into nb_jobs slices.
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 FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink)
Forward the status on an output link to an input link.
static FilterLink * ff_filter_link(AVFilterLink *link)
#define FILTER_SINGLE_SAMPLEFMT(sample_fmt_)
#define AVFILTER_DEFINE_CLASS(fname)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
void * av_calloc(size_t nmemb, size_t size)
Memory handling functions.
static const char *const var_names[]
An AVChannelLayout holds information about the channel layout of audio data.
int nb_channels
Number of channels in this layout.
Describe the class of an AVClass context structure.
A link between two filters.
int sample_rate
samples per second
AVChannelLayout ch_layout
channel layout of current buffer (see libavutil/channel_layout.h)
AVFilterContext * dst
dest filter
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
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
uint8_t ** extended_data
pointers to the data planes/channels.
double var_values[VAR_VARS_NB]
AVChannelLayout ch_layout
char * channels_to_filter
Link properties exposed to filter code, but not external callers.
int64_t sample_count_in
Number of past samples sent through the link.
static AVFormatContext * ctx
av_cold void av_tx_uninit(AVTXContext **ctx)
Frees a context and sets *ctx to NULL, does nothing when *ctx == NULL.
av_cold int av_tx_init(AVTXContext **ctx, av_tx_fn *tx, enum AVTXType type, int inv, int len, const void *scale, uint64_t flags)
Initialize a transform context with the given configuration (i)MDCTs with an odd length are currently...
@ AV_TX_FLOAT_RDFT
Real to complex and complex to real DFTs.
void(* av_tx_fn)(AVTXContext *s, void *out, void *in, ptrdiff_t stride)
Function pointer to a function to perform the transform.
static float envelope(const float x)