You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

802 lines
35KB

  1. /*
  2. * Copyright (c) 2013 Paul B Mahol
  3. * Copyright (c) 2006-2008 Rob Sykes <robs@users.sourceforge.net>
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /*
  22. * 2-pole filters designed by Robert Bristow-Johnson <rbj@audioimagination.com>
  23. * see http://www.musicdsp.org/files/Audio-EQ-Cookbook.txt
  24. *
  25. * 1-pole filters based on code (c) 2000 Chris Bagwell <cbagwell@sprynet.com>
  26. * Algorithms: Recursive single pole low/high pass filter
  27. * Reference: The Scientist and Engineer's Guide to Digital Signal Processing
  28. *
  29. * low-pass: output[N] = input[N] * A + output[N-1] * B
  30. * X = exp(-2.0 * pi * Fc)
  31. * A = 1 - X
  32. * B = X
  33. * Fc = cutoff freq / sample rate
  34. *
  35. * Mimics an RC low-pass filter:
  36. *
  37. * ---/\/\/\/\----------->
  38. * |
  39. * --- C
  40. * ---
  41. * |
  42. * |
  43. * V
  44. *
  45. * high-pass: output[N] = A0 * input[N] + A1 * input[N-1] + B1 * output[N-1]
  46. * X = exp(-2.0 * pi * Fc)
  47. * A0 = (1 + X) / 2
  48. * A1 = -(1 + X) / 2
  49. * B1 = X
  50. * Fc = cutoff freq / sample rate
  51. *
  52. * Mimics an RC high-pass filter:
  53. *
  54. * || C
  55. * ----||--------->
  56. * || |
  57. * <
  58. * > R
  59. * <
  60. * |
  61. * V
  62. */
  63. #include "libavutil/avassert.h"
  64. #include "libavutil/opt.h"
  65. #include "audio.h"
  66. #include "avfilter.h"
  67. #include "internal.h"
  68. enum FilterType {
  69. biquad,
  70. equalizer,
  71. bass,
  72. treble,
  73. bandpass,
  74. bandreject,
  75. allpass,
  76. highpass,
  77. lowpass,
  78. };
  79. enum WidthType {
  80. NONE,
  81. HERTZ,
  82. OCTAVE,
  83. QFACTOR,
  84. SLOPE,
  85. KHERTZ,
  86. NB_WTYPE,
  87. };
  88. typedef struct ChanCache {
  89. double i1, i2;
  90. double o1, o2;
  91. } ChanCache;
  92. typedef struct BiquadsContext {
  93. const AVClass *class;
  94. enum FilterType filter_type;
  95. int width_type;
  96. int poles;
  97. int csg;
  98. double gain;
  99. double frequency;
  100. double width;
  101. uint64_t channels;
  102. double a0, a1, a2;
  103. double b0, b1, b2;
  104. ChanCache *cache;
  105. int clippings;
  106. int block_align;
  107. void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len,
  108. double *i1, double *i2, double *o1, double *o2,
  109. double b0, double b1, double b2, double a1, double a2);
  110. } BiquadsContext;
  111. static av_cold int init(AVFilterContext *ctx)
  112. {
  113. BiquadsContext *s = ctx->priv;
  114. if (s->filter_type != biquad) {
  115. if (s->frequency <= 0 || s->width <= 0) {
  116. av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n",
  117. s->frequency, s->width);
  118. return AVERROR(EINVAL);
  119. }
  120. }
  121. return 0;
  122. }
  123. static int query_formats(AVFilterContext *ctx)
  124. {
  125. AVFilterFormats *formats;
  126. AVFilterChannelLayouts *layouts;
  127. static const enum AVSampleFormat sample_fmts[] = {
  128. AV_SAMPLE_FMT_S16P,
  129. AV_SAMPLE_FMT_S32P,
  130. AV_SAMPLE_FMT_FLTP,
  131. AV_SAMPLE_FMT_DBLP,
  132. AV_SAMPLE_FMT_NONE
  133. };
  134. int ret;
  135. layouts = ff_all_channel_counts();
  136. if (!layouts)
  137. return AVERROR(ENOMEM);
  138. ret = ff_set_common_channel_layouts(ctx, layouts);
  139. if (ret < 0)
  140. return ret;
  141. formats = ff_make_format_list(sample_fmts);
  142. if (!formats)
  143. return AVERROR(ENOMEM);
  144. ret = ff_set_common_formats(ctx, formats);
  145. if (ret < 0)
  146. return ret;
  147. formats = ff_all_samplerates();
  148. if (!formats)
  149. return AVERROR(ENOMEM);
  150. return ff_set_common_samplerates(ctx, formats);
  151. }
  152. #define BIQUAD_FILTER(name, type, min, max, need_clipping) \
  153. static void biquad_## name (BiquadsContext *s, \
  154. const void *input, void *output, int len, \
  155. double *in1, double *in2, \
  156. double *out1, double *out2, \
  157. double b0, double b1, double b2, \
  158. double a1, double a2) \
  159. { \
  160. const type *ibuf = input; \
  161. type *obuf = output; \
  162. double i1 = *in1; \
  163. double i2 = *in2; \
  164. double o1 = *out1; \
  165. double o2 = *out2; \
  166. int i; \
  167. a1 = -a1; \
  168. a2 = -a2; \
  169. \
  170. for (i = 0; i+1 < len; i++) { \
  171. o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \
  172. i2 = ibuf[i]; \
  173. if (need_clipping && o2 < min) { \
  174. s->clippings++; \
  175. obuf[i] = min; \
  176. } else if (need_clipping && o2 > max) { \
  177. s->clippings++; \
  178. obuf[i] = max; \
  179. } else { \
  180. obuf[i] = o2; \
  181. } \
  182. i++; \
  183. o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \
  184. i1 = ibuf[i]; \
  185. if (need_clipping && o1 < min) { \
  186. s->clippings++; \
  187. obuf[i] = min; \
  188. } else if (need_clipping && o1 > max) { \
  189. s->clippings++; \
  190. obuf[i] = max; \
  191. } else { \
  192. obuf[i] = o1; \
  193. } \
  194. } \
  195. if (i < len) { \
  196. double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
  197. i2 = i1; \
  198. i1 = ibuf[i]; \
  199. o2 = o1; \
  200. o1 = o0; \
  201. if (need_clipping && o0 < min) { \
  202. s->clippings++; \
  203. obuf[i] = min; \
  204. } else if (need_clipping && o0 > max) { \
  205. s->clippings++; \
  206. obuf[i] = max; \
  207. } else { \
  208. obuf[i] = o0; \
  209. } \
  210. } \
  211. *in1 = i1; \
  212. *in2 = i2; \
  213. *out1 = o1; \
  214. *out2 = o2; \
  215. }
  216. BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
  217. BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
  218. BIQUAD_FILTER(flt, float, -1., 1., 0)
  219. BIQUAD_FILTER(dbl, double, -1., 1., 0)
  220. static int config_filter(AVFilterLink *outlink, int reset)
  221. {
  222. AVFilterContext *ctx = outlink->src;
  223. BiquadsContext *s = ctx->priv;
  224. AVFilterLink *inlink = ctx->inputs[0];
  225. double A = exp(s->gain / 40 * log(10.));
  226. double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
  227. double alpha;
  228. if (w0 > M_PI) {
  229. av_log(ctx, AV_LOG_ERROR,
  230. "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
  231. s->frequency, inlink->sample_rate);
  232. return AVERROR(EINVAL);
  233. }
  234. switch (s->width_type) {
  235. case NONE:
  236. alpha = 0.0;
  237. break;
  238. case HERTZ:
  239. alpha = sin(w0) / (2 * s->frequency / s->width);
  240. break;
  241. case KHERTZ:
  242. alpha = sin(w0) / (2 * s->frequency / (s->width * 1000));
  243. break;
  244. case OCTAVE:
  245. alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
  246. break;
  247. case QFACTOR:
  248. alpha = sin(w0) / (2 * s->width);
  249. break;
  250. case SLOPE:
  251. alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
  252. break;
  253. default:
  254. av_assert0(0);
  255. }
  256. switch (s->filter_type) {
  257. case biquad:
  258. break;
  259. case equalizer:
  260. s->a0 = 1 + alpha / A;
  261. s->a1 = -2 * cos(w0);
  262. s->a2 = 1 - alpha / A;
  263. s->b0 = 1 + alpha * A;
  264. s->b1 = -2 * cos(w0);
  265. s->b2 = 1 - alpha * A;
  266. break;
  267. case bass:
  268. s->a0 = (A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
  269. s->a1 = -2 * ((A - 1) + (A + 1) * cos(w0));
  270. s->a2 = (A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
  271. s->b0 = A * ((A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
  272. s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
  273. s->b2 = A * ((A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
  274. break;
  275. case treble:
  276. s->a0 = (A + 1) - (A - 1) * cos(w0) + 2 * sqrt(A) * alpha;
  277. s->a1 = 2 * ((A - 1) - (A + 1) * cos(w0));
  278. s->a2 = (A + 1) - (A - 1) * cos(w0) - 2 * sqrt(A) * alpha;
  279. s->b0 = A * ((A + 1) + (A - 1) * cos(w0) + 2 * sqrt(A) * alpha);
  280. s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
  281. s->b2 = A * ((A + 1) + (A - 1) * cos(w0) - 2 * sqrt(A) * alpha);
  282. break;
  283. case bandpass:
  284. if (s->csg) {
  285. s->a0 = 1 + alpha;
  286. s->a1 = -2 * cos(w0);
  287. s->a2 = 1 - alpha;
  288. s->b0 = sin(w0) / 2;
  289. s->b1 = 0;
  290. s->b2 = -sin(w0) / 2;
  291. } else {
  292. s->a0 = 1 + alpha;
  293. s->a1 = -2 * cos(w0);
  294. s->a2 = 1 - alpha;
  295. s->b0 = alpha;
  296. s->b1 = 0;
  297. s->b2 = -alpha;
  298. }
  299. break;
  300. case bandreject:
  301. s->a0 = 1 + alpha;
  302. s->a1 = -2 * cos(w0);
  303. s->a2 = 1 - alpha;
  304. s->b0 = 1;
  305. s->b1 = -2 * cos(w0);
  306. s->b2 = 1;
  307. break;
  308. case lowpass:
  309. if (s->poles == 1) {
  310. s->a0 = 1;
  311. s->a1 = -exp(-w0);
  312. s->a2 = 0;
  313. s->b0 = 1 + s->a1;
  314. s->b1 = 0;
  315. s->b2 = 0;
  316. } else {
  317. s->a0 = 1 + alpha;
  318. s->a1 = -2 * cos(w0);
  319. s->a2 = 1 - alpha;
  320. s->b0 = (1 - cos(w0)) / 2;
  321. s->b1 = 1 - cos(w0);
  322. s->b2 = (1 - cos(w0)) / 2;
  323. }
  324. break;
  325. case highpass:
  326. if (s->poles == 1) {
  327. s->a0 = 1;
  328. s->a1 = -exp(-w0);
  329. s->a2 = 0;
  330. s->b0 = (1 - s->a1) / 2;
  331. s->b1 = -s->b0;
  332. s->b2 = 0;
  333. } else {
  334. s->a0 = 1 + alpha;
  335. s->a1 = -2 * cos(w0);
  336. s->a2 = 1 - alpha;
  337. s->b0 = (1 + cos(w0)) / 2;
  338. s->b1 = -(1 + cos(w0));
  339. s->b2 = (1 + cos(w0)) / 2;
  340. }
  341. break;
  342. case allpass:
  343. s->a0 = 1 + alpha;
  344. s->a1 = -2 * cos(w0);
  345. s->a2 = 1 - alpha;
  346. s->b0 = 1 - alpha;
  347. s->b1 = -2 * cos(w0);
  348. s->b2 = 1 + alpha;
  349. break;
  350. default:
  351. av_assert0(0);
  352. }
  353. av_log(ctx, AV_LOG_VERBOSE, "a=%lf %lf %lf:b=%lf %lf %lf\n", s->a0, s->a1, s->a2, s->b0, s->b1, s->b2);
  354. s->a1 /= s->a0;
  355. s->a2 /= s->a0;
  356. s->b0 /= s->a0;
  357. s->b1 /= s->a0;
  358. s->b2 /= s->a0;
  359. s->a0 /= s->a0;
  360. s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
  361. if (!s->cache)
  362. return AVERROR(ENOMEM);
  363. if (reset)
  364. memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
  365. switch (inlink->format) {
  366. case AV_SAMPLE_FMT_S16P: s->filter = biquad_s16; break;
  367. case AV_SAMPLE_FMT_S32P: s->filter = biquad_s32; break;
  368. case AV_SAMPLE_FMT_FLTP: s->filter = biquad_flt; break;
  369. case AV_SAMPLE_FMT_DBLP: s->filter = biquad_dbl; break;
  370. default: av_assert0(0);
  371. }
  372. s->block_align = av_get_bytes_per_sample(inlink->format);
  373. return 0;
  374. }
  375. static int config_output(AVFilterLink *outlink)
  376. {
  377. return config_filter(outlink, 1);
  378. }
  379. static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
  380. {
  381. AVFilterContext *ctx = inlink->dst;
  382. BiquadsContext *s = ctx->priv;
  383. AVFilterLink *outlink = ctx->outputs[0];
  384. AVFrame *out_buf;
  385. int nb_samples = buf->nb_samples;
  386. int ch;
  387. if (av_frame_is_writable(buf)) {
  388. out_buf = buf;
  389. } else {
  390. out_buf = ff_get_audio_buffer(outlink, nb_samples);
  391. if (!out_buf) {
  392. av_frame_free(&buf);
  393. return AVERROR(ENOMEM);
  394. }
  395. av_frame_copy_props(out_buf, buf);
  396. }
  397. for (ch = 0; ch < buf->channels; ch++) {
  398. if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
  399. if (buf != out_buf)
  400. memcpy(out_buf->extended_data[ch], buf->extended_data[ch], nb_samples * s->block_align);
  401. continue;
  402. }
  403. s->filter(s, buf->extended_data[ch],
  404. out_buf->extended_data[ch], nb_samples,
  405. &s->cache[ch].i1, &s->cache[ch].i2,
  406. &s->cache[ch].o1, &s->cache[ch].o2,
  407. s->b0, s->b1, s->b2, s->a1, s->a2);
  408. }
  409. if (s->clippings > 0)
  410. av_log(ctx, AV_LOG_WARNING, "clipping %d times. Please reduce gain.\n", s->clippings);
  411. s->clippings = 0;
  412. if (buf != out_buf)
  413. av_frame_free(&buf);
  414. return ff_filter_frame(outlink, out_buf);
  415. }
  416. static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
  417. char *res, int res_len, int flags)
  418. {
  419. BiquadsContext *s = ctx->priv;
  420. AVFilterLink *outlink = ctx->outputs[0];
  421. if ((!strcmp(cmd, "frequency") || !strcmp(cmd, "f")) &&
  422. (s->filter_type == equalizer ||
  423. s->filter_type == bass ||
  424. s->filter_type == treble ||
  425. s->filter_type == bandpass ||
  426. s->filter_type == bandreject||
  427. s->filter_type == lowpass ||
  428. s->filter_type == highpass ||
  429. s->filter_type == allpass)) {
  430. double freq;
  431. if (sscanf(args, "%lf", &freq) != 1) {
  432. av_log(ctx, AV_LOG_ERROR, "Invalid frequency value.\n");
  433. return AVERROR(EINVAL);
  434. }
  435. s->frequency = freq;
  436. } else if ((!strcmp(cmd, "gain") || !strcmp(cmd, "g")) &&
  437. (s->filter_type == equalizer ||
  438. s->filter_type == bass ||
  439. s->filter_type == treble)) {
  440. double gain;
  441. if (sscanf(args, "%lf", &gain) != 1) {
  442. av_log(ctx, AV_LOG_ERROR, "Invalid gain value.\n");
  443. return AVERROR(EINVAL);
  444. }
  445. s->gain = gain;
  446. } else if ((!strcmp(cmd, "width") || !strcmp(cmd, "w")) &&
  447. (s->filter_type == equalizer ||
  448. s->filter_type == bass ||
  449. s->filter_type == treble ||
  450. s->filter_type == bandpass ||
  451. s->filter_type == bandreject||
  452. s->filter_type == lowpass ||
  453. s->filter_type == highpass ||
  454. s->filter_type == allpass)) {
  455. double width;
  456. if (sscanf(args, "%lf", &width) != 1) {
  457. av_log(ctx, AV_LOG_ERROR, "Invalid width value.\n");
  458. return AVERROR(EINVAL);
  459. }
  460. s->width = width;
  461. } else if ((!strcmp(cmd, "width_type") || !strcmp(cmd, "t")) &&
  462. (s->filter_type == equalizer ||
  463. s->filter_type == bass ||
  464. s->filter_type == treble ||
  465. s->filter_type == bandpass ||
  466. s->filter_type == bandreject||
  467. s->filter_type == lowpass ||
  468. s->filter_type == highpass ||
  469. s->filter_type == allpass)) {
  470. char width_type;
  471. if (sscanf(args, "%c", &width_type) != 1) {
  472. av_log(ctx, AV_LOG_ERROR, "Invalid width_type value.\n");
  473. return AVERROR(EINVAL);
  474. }
  475. switch (width_type) {
  476. case 'h': width_type = HERTZ; break;
  477. case 'q': width_type = QFACTOR; break;
  478. case 'o': width_type = OCTAVE; break;
  479. case 's': width_type = SLOPE; break;
  480. case 'k': width_type = KHERTZ; break;
  481. default:
  482. av_log(ctx, AV_LOG_ERROR, "Invalid width_type value: %c\n", width_type);
  483. return AVERROR(EINVAL);
  484. }
  485. s->width_type = width_type;
  486. } else if ((!strcmp(cmd, "a0") ||
  487. !strcmp(cmd, "a1") ||
  488. !strcmp(cmd, "a2") ||
  489. !strcmp(cmd, "b0") ||
  490. !strcmp(cmd, "b1") ||
  491. !strcmp(cmd, "b2")) &&
  492. s->filter_type == biquad) {
  493. double value;
  494. if (sscanf(args, "%lf", &value) != 1) {
  495. av_log(ctx, AV_LOG_ERROR, "Invalid biquad value.\n");
  496. return AVERROR(EINVAL);
  497. }
  498. if (!strcmp(cmd, "a0"))
  499. s->a0 = value;
  500. else if (!strcmp(cmd, "a1"))
  501. s->a1 = value;
  502. else if (!strcmp(cmd, "a2"))
  503. s->a2 = value;
  504. else if (!strcmp(cmd, "b0"))
  505. s->b0 = value;
  506. else if (!strcmp(cmd, "b1"))
  507. s->b1 = value;
  508. else if (!strcmp(cmd, "b2"))
  509. s->b2 = value;
  510. }
  511. return config_filter(outlink, 0);
  512. }
  513. static av_cold void uninit(AVFilterContext *ctx)
  514. {
  515. BiquadsContext *s = ctx->priv;
  516. av_freep(&s->cache);
  517. }
  518. static const AVFilterPad inputs[] = {
  519. {
  520. .name = "default",
  521. .type = AVMEDIA_TYPE_AUDIO,
  522. .filter_frame = filter_frame,
  523. },
  524. { NULL }
  525. };
  526. static const AVFilterPad outputs[] = {
  527. {
  528. .name = "default",
  529. .type = AVMEDIA_TYPE_AUDIO,
  530. .config_props = config_output,
  531. },
  532. { NULL }
  533. };
  534. #define OFFSET(x) offsetof(BiquadsContext, x)
  535. #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
  536. #define DEFINE_BIQUAD_FILTER(name_, description_) \
  537. AVFILTER_DEFINE_CLASS(name_); \
  538. static av_cold int name_##_init(AVFilterContext *ctx) \
  539. { \
  540. BiquadsContext *s = ctx->priv; \
  541. s->class = &name_##_class; \
  542. s->filter_type = name_; \
  543. return init(ctx); \
  544. } \
  545. \
  546. AVFilter ff_af_##name_ = { \
  547. .name = #name_, \
  548. .description = NULL_IF_CONFIG_SMALL(description_), \
  549. .priv_size = sizeof(BiquadsContext), \
  550. .init = name_##_init, \
  551. .uninit = uninit, \
  552. .query_formats = query_formats, \
  553. .inputs = inputs, \
  554. .outputs = outputs, \
  555. .priv_class = &name_##_class, \
  556. .process_command = process_command, \
  557. }
  558. #if CONFIG_EQUALIZER_FILTER
  559. static const AVOption equalizer_options[] = {
  560. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
  561. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
  562. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  563. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  564. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  565. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  566. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  567. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  568. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  569. {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
  570. {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
  571. {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  572. {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  573. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  574. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  575. {NULL}
  576. };
  577. DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
  578. #endif /* CONFIG_EQUALIZER_FILTER */
  579. #if CONFIG_BASS_FILTER
  580. static const AVOption bass_options[] = {
  581. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
  582. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
  583. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  584. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  585. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  586. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  587. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  588. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  589. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  590. {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  591. {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  592. {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  593. {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  594. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  595. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  596. {NULL}
  597. };
  598. DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
  599. #endif /* CONFIG_BASS_FILTER */
  600. #if CONFIG_TREBLE_FILTER
  601. static const AVOption treble_options[] = {
  602. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  603. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  604. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  605. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  606. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  607. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  608. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  609. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  610. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  611. {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  612. {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  613. {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  614. {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  615. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  616. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  617. {NULL}
  618. };
  619. DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
  620. #endif /* CONFIG_TREBLE_FILTER */
  621. #if CONFIG_BANDPASS_FILTER
  622. static const AVOption bandpass_options[] = {
  623. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  624. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  625. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  626. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  627. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  628. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  629. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  630. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  631. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  632. {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  633. {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  634. {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
  635. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  636. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  637. {NULL}
  638. };
  639. DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
  640. #endif /* CONFIG_BANDPASS_FILTER */
  641. #if CONFIG_BANDREJECT_FILTER
  642. static const AVOption bandreject_options[] = {
  643. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  644. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  645. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  646. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  647. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  648. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  649. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  650. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  651. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  652. {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  653. {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  654. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  655. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  656. {NULL}
  657. };
  658. DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
  659. #endif /* CONFIG_BANDREJECT_FILTER */
  660. #if CONFIG_LOWPASS_FILTER
  661. static const AVOption lowpass_options[] = {
  662. {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
  663. {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
  664. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  665. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  666. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  667. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  668. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  669. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  670. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  671. {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  672. {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  673. {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  674. {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  675. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  676. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  677. {NULL}
  678. };
  679. DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
  680. #endif /* CONFIG_LOWPASS_FILTER */
  681. #if CONFIG_HIGHPASS_FILTER
  682. static const AVOption highpass_options[] = {
  683. {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  684. {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  685. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  686. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  687. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  688. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  689. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  690. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  691. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  692. {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  693. {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  694. {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  695. {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  696. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  697. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  698. {NULL}
  699. };
  700. DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
  701. #endif /* CONFIG_HIGHPASS_FILTER */
  702. #if CONFIG_ALLPASS_FILTER
  703. static const AVOption allpass_options[] = {
  704. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  705. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  706. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  707. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  708. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  709. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  710. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  711. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  712. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  713. {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
  714. {"w", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
  715. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  716. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  717. {NULL}
  718. };
  719. DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
  720. #endif /* CONFIG_ALLPASS_FILTER */
  721. #if CONFIG_BIQUAD_FILTER
  722. static const AVOption biquad_options[] = {
  723. {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
  724. {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
  725. {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
  726. {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
  727. {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
  728. {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
  729. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  730. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  731. {NULL}
  732. };
  733. DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
  734. #endif /* CONFIG_BIQUAD_FILTER */