67 #define OFFSET(x) offsetof(AudioFIRSourceContext, x)
68 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
81 {
"nb_samples",
"set the number of samples per requested frame",
OFFSET(nb_samples),
AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX,
FLAGS },
82 {
"n",
"set the number of samples per requested frame",
OFFSET(nb_samples),
AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX,
FLAGS },
94 if (!(
s->nb_taps & 1)) {
136 static int parse_string(
char *str,
float **items,
int *nb_items,
int *items_size)
151 (*items)[(*nb_items)++] =
av_strtod(tail, &tail);
152 new_items =
av_fast_realloc(*items, items_size, (*nb_items + 2) *
sizeof(
float));
158 }
while (tail && *tail);
165 const float *magnitude,
169 for (
int i = 0;
i < minterp;
i++) {
170 for (
int j = 1; j < m; j++) {
171 const float x =
i / (
float)minterp;
174 const float mg = (x - freq[j-1]) / (freq[j] - freq[j-1]) * (magnitude[j] - magnitude[j-1]) + magnitude[j-1];
175 const float ph = (x - freq[j-1]) / (freq[j] - freq[j-1]) * (phase[j] - phase[j-1]) + phase[j-1];
189 float overlap,
scale = 1.f, compensation;
190 int fft_size, middle,
ret;
192 s->nb_freq =
s->nb_magnitude =
s->nb_phase = 0;
206 if (
s->nb_freq !=
s->nb_magnitude &&
s->nb_freq !=
s->nb_phase &&
s->nb_freq >= 2) {
211 for (
int i = 0;
i <
s->nb_freq;
i++) {
212 if (
i == 0 &&
s->freq[
i] != 0.f) {
217 if (
i ==
s->nb_freq - 1 &&
s->freq[
i] != 1.f) {
222 if (
i &&
s->freq[
i] <
s->freq[
i-1]) {
228 fft_size = 1 << (
av_log2(
s->nb_taps) + 1);
229 s->complexf =
av_calloc(fft_size * 2,
sizeof(*
s->complexf));
247 lininterp(
s->complexf,
s->freq,
s->magnitude,
s->phase,
s->nb_freq, fft_size / 2);
249 s->tx_fn(
s->tx_ctx,
s->complexf + fft_size,
s->complexf,
sizeof(*
s->complexf));
251 compensation = 2.f / fft_size;
252 middle =
s->nb_taps / 2;
254 for (
int i = 0;
i <= middle;
i++) {
255 s->taps[
i] =
s->complexf[fft_size + middle -
i].re * compensation *
s->win[
i];
256 s->taps[middle +
i] =
s->complexf[fft_size +
i].re * compensation *
s->win[middle +
i];
274 nb_samples =
FFMIN(
s->nb_samples,
s->nb_taps -
s->pts);
275 if (nb_samples <= 0) {
283 memcpy(
frame->
data[0],
s->taps +
s->pts, nb_samples *
sizeof(
float));
286 s->pts += nb_samples;
308 .priv_class = &afirsrc_class,
311 #define DEFAULT_BANDS "25 40 63 100 160 250 400 630 1000 1600 2500 4000 6300 10000 16000 24000"
319 {
"flat", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
320 {
"acoustic", { 5.0, 4.5, 4.0, 3.5, 1.5, 1.0, 1.5, 1.5, 2.0, 3.0, 3.5, 4.0, 3.7, 3.0, 3.0 } },
321 {
"bass", { 10.0, 8.8, 8.5, 6.5, 2.5, 1.5, 0, 0, 0, 0, 0, 0, 0, 0, 0 } },
322 {
"beats", { -5.5, -5.0, -4.5, -4.2, -3.5, -3.0, -1.9, 0, 0, 0, 0, 0, 0, 0, 0 } },
323 {
"classic", { -0.3, 0.3, -3.5, -9.0, -1.0, 0.0, 1.8, 2.1, 0.0, 0.0, 0.0, 4.4, 9.0, 9.0, 9.0 } },
324 {
"clear", { 3.5, 5.5, 6.5, 9.5, 8.0, 6.5, 3.5, 2.5, 1.3, 5.0, 7.0, 9.0, 10.0, 11.0, 9.0 } },
325 {
"deep bass", { 12.0, 8.0, 0.0, -6.7, -12.0, -9.0, -3.5, -3.5, -6.1, 0.0, -3.0, -5.0, 0.0, 1.2, 3.0 } },
326 {
"dubstep", { 12.0, 10.0, 0.5, -1.0, -3.0, -5.0, -5.0, -4.8, -4.5, -2.5, -1.0, 0.0, -2.5, -2.5, 0.0 } },
327 {
"electronic", { 4.0, 4.0, 3.5, 1.0, 0.0, -0.5, -2.0, 0.0, 2.0, 0.0, 0.0, 1.0, 3.0, 4.0, 4.5 } },
328 {
"hardstyle", { 6.1, 7.0, 12.0, 6.1, -5.0, -12.0, -2.5, 3.0, 6.5, 0.0, -2.2, -4.5, -6.1, -9.2, -10.0 } },
329 {
"hip-hop", { 4.5, 4.3, 4.0, 2.5, 1.5, 3.0, -1.0, -1.5, -1.5, 1.5, 0.0, -1.0, 0.0, 1.5, 3.0 } },
330 {
"jazz", { 0.0, 0.0, 0.0, 2.0, 4.0, 5.9, -5.9, -4.5, -2.5, 2.5, 1.0, -0.8, -0.8, -0.8, -0.8 } },
331 {
"metal", { 10.5, 10.5, 7.5, 0.0, 2.0, 5.5, 0.0, 0.0, 0.0, 6.1, 0.0, 0.0, 6.1, 10.0, 12.0 } },
332 {
"movie", { 3.0, 3.0, 6.1, 8.5, 9.0, 7.0, 6.1, 6.1, 5.0, 8.0, 3.5, 3.5, 8.0, 10.0, 8.0 } },
333 {
"pop", { 0.0, 0.0, 0.0, 0.0, 0.0, 1.3, 2.0, 2.5, 5.0, -1.5, -2.0, -3.0, -3.0, -3.0, -3.0 } },
334 {
"r&b", { 3.0, 3.0, 7.0, 6.1, 4.5, 1.5, -1.5, -2.0, -1.5, 2.0, 2.5, 3.0, 3.5, 3.8, 4.0 } },
335 {
"rock", { 0.0, 0.0, 0.0, 3.0, 3.0, -10.0, -4.0, -1.0, 0.8, 3.0, 3.0, 3.0, 3.0, 3.0, 3.0 } },
336 {
"vocal booster", { -1.5, -2.0, -3.0, -3.0, -0.5, 1.5, 3.5, 3.5, 3.5, 3.0, 2.0, 1.5, 0.0, 0.0, -1.5 } },
369 {
"nb_samples",
"set the number of samples per requested frame",
OFFSET(nb_samples),
AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX,
FLAGS },
370 {
"n",
"set the number of samples per requested frame",
OFFSET(nb_samples),
AV_OPT_TYPE_INT, {.i64 = 1024}, 1, INT_MAX,
FLAGS },
386 const float *magnitude,
387 int m,
int interp,
int minterp,
390 for (
int i = 0;
i < minterp;
i++) {
391 for (
int j = 0; j < m; j++) {
394 if (x <= freq[j+1]) {
398 const float d = freq[j+1] - freq[j];
399 const float d0 = x - freq[j];
400 const float d1 = freq[j+1] - x;
401 const float g0 = magnitude[j];
402 const float g1 = magnitude[j+1];
405 g = (d0 * g1 + d1 * g0) /
d;
417 float m0, m1, m2, msum;
418 const float unit = freq[j+1] - freq[j];
420 m0 = j != 0 ? unit * (magnitude[j] - magnitude[j-1]) / (freq[j] - freq[j-1]) : 0;
421 m1 = magnitude[j+1] - magnitude[j];
422 m2 = j != minterp - 1 ? unit * (magnitude[j+2] - magnitude[j+1]) / (freq[j+2] - freq[j+1]) : 0;
425 m0 = msum > 0.f ? (
fabsf(m0) * m1 +
fabsf(m1) * m0) / msum : 0.
f;
427 m1 = msum > 0.f ? (
fabsf(m1) * m2 +
fabsf(m2) * m1) / msum : 0.
f;
431 b = 3.f * magnitude[j+1] - m1 - 2.f *
c - 3.f *
d;
432 a = magnitude[j+1] -
b -
c -
d;
434 x1 = (x - freq[j]) / unit;
438 g =
a * x3 +
b * x2 +
c * x1 +
d;
444 complexf[minterp * 2 -
i - 1].
re =
g;
445 complexf[minterp * 2 -
i - 1].
im = 0;
457 int fft_size, middle, asize,
ret;
460 s->nb_freq =
s->nb_magnitude = 0;
483 s->magnitude =
av_calloc(
s->nb_magnitude + 1,
sizeof(*
s->magnitude));
486 memcpy(
s->magnitude,
eq_presets[
s->preset].
gains,
sizeof(*
s->magnitude) *
s->nb_magnitude);
489 if (
s->nb_freq !=
s->nb_magnitude ||
s->nb_freq < 2) {
495 s->magnitude[
s->nb_freq] =
s->magnitude[
s->nb_freq-1];
497 fft_size =
s->nb_taps * 2;
500 s->complexf =
av_calloc(asize * 2,
sizeof(*
s->complexf));
515 for (
int i = 0;
i < fft_size;
i++)
519 const float threshold =
powf(10.
f, -100.
f / 20.
f);
520 const float logt = logf(threshold);
527 for (
int i = 0;
i < fft_size;
i++)
528 s->complexf[
i].re =
s->complexf[
i].re < threshold ? logt : logf(
s->complexf[
i].re);
530 s->itx_fn(
s->itx_ctx,
s->complexf + asize,
s->complexf,
sizeof(
float));
531 for (
int i = 0;
i < fft_size;
i++) {
532 s->complexf[
i + asize].re /= fft_size;
533 s->complexf[
i + asize].im /= fft_size;
536 for (
int i = 1;
i <
s->nb_taps;
i++) {
537 s->complexf[asize +
i].re +=
s->complexf[asize + fft_size -
i].re;
538 s->complexf[asize +
i].im -=
s->complexf[asize + fft_size -
i].im;
539 s->complexf[asize + fft_size -
i].re = 0.f;
540 s->complexf[asize + fft_size -
i].im = 0.f;
542 s->complexf[asize +
s->nb_taps - 1].im *= -1.f;
544 s->tx_fn(
s->tx_ctx,
s->complexf,
s->complexf + asize,
sizeof(
float));
546 for (
int i = 0;
i < fft_size;
i++) {
547 float eR =
expf(
s->complexf[
i].re);
549 s->complexf[
i].re = eR *
cosf(
s->complexf[
i].im);
550 s->complexf[
i].im = eR *
sinf(
s->complexf[
i].im);
553 s->itx_fn(
s->itx_ctx,
s->complexf + asize,
s->complexf,
sizeof(
float));
555 for (
int i = 0;
i <
s->nb_taps;
i++)
556 s->taps[
i] =
s->complexf[
i + asize].re / fft_size;
558 s->itx_fn(
s->itx_ctx,
s->complexf + asize,
s->complexf,
sizeof(
float));
560 middle =
s->nb_taps / 2;
561 for (
int i = 0;
i < middle;
i++) {
562 s->taps[middle -
i] =
s->complexf[
i + asize].re / fft_size;
563 s->taps[middle +
i] =
s->complexf[
i + asize].re / fft_size;
589 .priv_class = &afireqsrc_class,