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.

888 lines
40KB

  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. lowshelf,
  79. highshelf,
  80. };
  81. enum WidthType {
  82. NONE,
  83. HERTZ,
  84. OCTAVE,
  85. QFACTOR,
  86. SLOPE,
  87. KHERTZ,
  88. NB_WTYPE,
  89. };
  90. typedef struct ChanCache {
  91. double i1, i2;
  92. double o1, o2;
  93. int clippings;
  94. } ChanCache;
  95. typedef struct BiquadsContext {
  96. const AVClass *class;
  97. enum FilterType filter_type;
  98. int width_type;
  99. int poles;
  100. int csg;
  101. double gain;
  102. double frequency;
  103. double width;
  104. uint64_t channels;
  105. double a0, a1, a2;
  106. double b0, b1, b2;
  107. ChanCache *cache;
  108. int block_align;
  109. void (*filter)(struct BiquadsContext *s, const void *ibuf, void *obuf, int len,
  110. double *i1, double *i2, double *o1, double *o2,
  111. double b0, double b1, double b2, double a1, double a2, int *clippings);
  112. } BiquadsContext;
  113. static av_cold int init(AVFilterContext *ctx)
  114. {
  115. BiquadsContext *s = ctx->priv;
  116. if (s->filter_type != biquad) {
  117. if (s->frequency <= 0 || s->width <= 0) {
  118. av_log(ctx, AV_LOG_ERROR, "Invalid frequency %f and/or width %f <= 0\n",
  119. s->frequency, s->width);
  120. return AVERROR(EINVAL);
  121. }
  122. }
  123. return 0;
  124. }
  125. static int query_formats(AVFilterContext *ctx)
  126. {
  127. AVFilterFormats *formats;
  128. AVFilterChannelLayouts *layouts;
  129. static const enum AVSampleFormat sample_fmts[] = {
  130. AV_SAMPLE_FMT_S16P,
  131. AV_SAMPLE_FMT_S32P,
  132. AV_SAMPLE_FMT_FLTP,
  133. AV_SAMPLE_FMT_DBLP,
  134. AV_SAMPLE_FMT_NONE
  135. };
  136. int ret;
  137. layouts = ff_all_channel_counts();
  138. if (!layouts)
  139. return AVERROR(ENOMEM);
  140. ret = ff_set_common_channel_layouts(ctx, layouts);
  141. if (ret < 0)
  142. return ret;
  143. formats = ff_make_format_list(sample_fmts);
  144. if (!formats)
  145. return AVERROR(ENOMEM);
  146. ret = ff_set_common_formats(ctx, formats);
  147. if (ret < 0)
  148. return ret;
  149. formats = ff_all_samplerates();
  150. if (!formats)
  151. return AVERROR(ENOMEM);
  152. return ff_set_common_samplerates(ctx, formats);
  153. }
  154. #define BIQUAD_FILTER(name, type, min, max, need_clipping) \
  155. static void biquad_## name (BiquadsContext *s, \
  156. const void *input, void *output, int len, \
  157. double *in1, double *in2, \
  158. double *out1, double *out2, \
  159. double b0, double b1, double b2, \
  160. double a1, double a2, int *clippings) \
  161. { \
  162. const type *ibuf = input; \
  163. type *obuf = output; \
  164. double i1 = *in1; \
  165. double i2 = *in2; \
  166. double o1 = *out1; \
  167. double o2 = *out2; \
  168. int i; \
  169. a1 = -a1; \
  170. a2 = -a2; \
  171. \
  172. for (i = 0; i+1 < len; i++) { \
  173. o2 = i2 * b2 + i1 * b1 + ibuf[i] * b0 + o2 * a2 + o1 * a1; \
  174. i2 = ibuf[i]; \
  175. if (need_clipping && o2 < min) { \
  176. (*clippings)++; \
  177. obuf[i] = min; \
  178. } else if (need_clipping && o2 > max) { \
  179. (*clippings)++; \
  180. obuf[i] = max; \
  181. } else { \
  182. obuf[i] = o2; \
  183. } \
  184. i++; \
  185. o1 = i1 * b2 + i2 * b1 + ibuf[i] * b0 + o1 * a2 + o2 * a1; \
  186. i1 = ibuf[i]; \
  187. if (need_clipping && o1 < min) { \
  188. (*clippings)++; \
  189. obuf[i] = min; \
  190. } else if (need_clipping && o1 > max) { \
  191. (*clippings)++; \
  192. obuf[i] = max; \
  193. } else { \
  194. obuf[i] = o1; \
  195. } \
  196. } \
  197. if (i < len) { \
  198. double o0 = ibuf[i] * b0 + i1 * b1 + i2 * b2 + o1 * a1 + o2 * a2; \
  199. i2 = i1; \
  200. i1 = ibuf[i]; \
  201. o2 = o1; \
  202. o1 = o0; \
  203. if (need_clipping && o0 < min) { \
  204. (*clippings)++; \
  205. obuf[i] = min; \
  206. } else if (need_clipping && o0 > max) { \
  207. (*clippings)++; \
  208. obuf[i] = max; \
  209. } else { \
  210. obuf[i] = o0; \
  211. } \
  212. } \
  213. *in1 = i1; \
  214. *in2 = i2; \
  215. *out1 = o1; \
  216. *out2 = o2; \
  217. }
  218. BIQUAD_FILTER(s16, int16_t, INT16_MIN, INT16_MAX, 1)
  219. BIQUAD_FILTER(s32, int32_t, INT32_MIN, INT32_MAX, 1)
  220. BIQUAD_FILTER(flt, float, -1., 1., 0)
  221. BIQUAD_FILTER(dbl, double, -1., 1., 0)
  222. static int config_filter(AVFilterLink *outlink, int reset)
  223. {
  224. AVFilterContext *ctx = outlink->src;
  225. BiquadsContext *s = ctx->priv;
  226. AVFilterLink *inlink = ctx->inputs[0];
  227. double A = exp(s->gain / 40 * log(10.));
  228. double w0 = 2 * M_PI * s->frequency / inlink->sample_rate;
  229. double alpha, beta;
  230. if (w0 > M_PI) {
  231. av_log(ctx, AV_LOG_ERROR,
  232. "Invalid frequency %f. Frequency must be less than half the sample-rate %d.\n",
  233. s->frequency, inlink->sample_rate);
  234. return AVERROR(EINVAL);
  235. }
  236. switch (s->width_type) {
  237. case NONE:
  238. alpha = 0.0;
  239. break;
  240. case HERTZ:
  241. alpha = sin(w0) / (2 * s->frequency / s->width);
  242. break;
  243. case KHERTZ:
  244. alpha = sin(w0) / (2 * s->frequency / (s->width * 1000));
  245. break;
  246. case OCTAVE:
  247. alpha = sin(w0) * sinh(log(2.) / 2 * s->width * w0 / sin(w0));
  248. break;
  249. case QFACTOR:
  250. alpha = sin(w0) / (2 * s->width);
  251. break;
  252. case SLOPE:
  253. alpha = sin(w0) / 2 * sqrt((A + 1 / A) * (1 / s->width - 1) + 2);
  254. break;
  255. default:
  256. av_assert0(0);
  257. }
  258. beta = 2 * sqrt(A);
  259. switch (s->filter_type) {
  260. case biquad:
  261. break;
  262. case equalizer:
  263. s->a0 = 1 + alpha / A;
  264. s->a1 = -2 * cos(w0);
  265. s->a2 = 1 - alpha / A;
  266. s->b0 = 1 + alpha * A;
  267. s->b1 = -2 * cos(w0);
  268. s->b2 = 1 - alpha * A;
  269. break;
  270. case bass:
  271. beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
  272. case lowshelf:
  273. s->a0 = (A + 1) + (A - 1) * cos(w0) + beta * alpha;
  274. s->a1 = -2 * ((A - 1) + (A + 1) * cos(w0));
  275. s->a2 = (A + 1) + (A - 1) * cos(w0) - beta * alpha;
  276. s->b0 = A * ((A + 1) - (A - 1) * cos(w0) + beta * alpha);
  277. s->b1 = 2 * A * ((A - 1) - (A + 1) * cos(w0));
  278. s->b2 = A * ((A + 1) - (A - 1) * cos(w0) - beta * alpha);
  279. break;
  280. case treble:
  281. beta = sqrt((A * A + 1) - (A - 1) * (A - 1));
  282. case highshelf:
  283. s->a0 = (A + 1) - (A - 1) * cos(w0) + beta * alpha;
  284. s->a1 = 2 * ((A - 1) - (A + 1) * cos(w0));
  285. s->a2 = (A + 1) - (A - 1) * cos(w0) - beta * alpha;
  286. s->b0 = A * ((A + 1) + (A - 1) * cos(w0) + beta * alpha);
  287. s->b1 =-2 * A * ((A - 1) + (A + 1) * cos(w0));
  288. s->b2 = A * ((A + 1) + (A - 1) * cos(w0) - beta * alpha);
  289. break;
  290. case bandpass:
  291. if (s->csg) {
  292. s->a0 = 1 + alpha;
  293. s->a1 = -2 * cos(w0);
  294. s->a2 = 1 - alpha;
  295. s->b0 = sin(w0) / 2;
  296. s->b1 = 0;
  297. s->b2 = -sin(w0) / 2;
  298. } else {
  299. s->a0 = 1 + alpha;
  300. s->a1 = -2 * cos(w0);
  301. s->a2 = 1 - alpha;
  302. s->b0 = alpha;
  303. s->b1 = 0;
  304. s->b2 = -alpha;
  305. }
  306. break;
  307. case bandreject:
  308. s->a0 = 1 + alpha;
  309. s->a1 = -2 * cos(w0);
  310. s->a2 = 1 - alpha;
  311. s->b0 = 1;
  312. s->b1 = -2 * cos(w0);
  313. s->b2 = 1;
  314. break;
  315. case lowpass:
  316. if (s->poles == 1) {
  317. s->a0 = 1;
  318. s->a1 = -exp(-w0);
  319. s->a2 = 0;
  320. s->b0 = 1 + s->a1;
  321. s->b1 = 0;
  322. s->b2 = 0;
  323. } else {
  324. s->a0 = 1 + alpha;
  325. s->a1 = -2 * cos(w0);
  326. s->a2 = 1 - alpha;
  327. s->b0 = (1 - cos(w0)) / 2;
  328. s->b1 = 1 - cos(w0);
  329. s->b2 = (1 - cos(w0)) / 2;
  330. }
  331. break;
  332. case highpass:
  333. if (s->poles == 1) {
  334. s->a0 = 1;
  335. s->a1 = -exp(-w0);
  336. s->a2 = 0;
  337. s->b0 = (1 - s->a1) / 2;
  338. s->b1 = -s->b0;
  339. s->b2 = 0;
  340. } else {
  341. s->a0 = 1 + alpha;
  342. s->a1 = -2 * cos(w0);
  343. s->a2 = 1 - alpha;
  344. s->b0 = (1 + cos(w0)) / 2;
  345. s->b1 = -(1 + cos(w0));
  346. s->b2 = (1 + cos(w0)) / 2;
  347. }
  348. break;
  349. case allpass:
  350. s->a0 = 1 + alpha;
  351. s->a1 = -2 * cos(w0);
  352. s->a2 = 1 - alpha;
  353. s->b0 = 1 - alpha;
  354. s->b1 = -2 * cos(w0);
  355. s->b2 = 1 + alpha;
  356. break;
  357. default:
  358. av_assert0(0);
  359. }
  360. av_log(ctx, AV_LOG_VERBOSE, "a=%f %f %f:b=%f %f %f\n", s->a0, s->a1, s->a2, s->b0, s->b1, s->b2);
  361. s->a1 /= s->a0;
  362. s->a2 /= s->a0;
  363. s->b0 /= s->a0;
  364. s->b1 /= s->a0;
  365. s->b2 /= s->a0;
  366. s->a0 /= s->a0;
  367. s->cache = av_realloc_f(s->cache, sizeof(ChanCache), inlink->channels);
  368. if (!s->cache)
  369. return AVERROR(ENOMEM);
  370. if (reset)
  371. memset(s->cache, 0, sizeof(ChanCache) * inlink->channels);
  372. switch (inlink->format) {
  373. case AV_SAMPLE_FMT_S16P: s->filter = biquad_s16; break;
  374. case AV_SAMPLE_FMT_S32P: s->filter = biquad_s32; break;
  375. case AV_SAMPLE_FMT_FLTP: s->filter = biquad_flt; break;
  376. case AV_SAMPLE_FMT_DBLP: s->filter = biquad_dbl; break;
  377. default: av_assert0(0);
  378. }
  379. s->block_align = av_get_bytes_per_sample(inlink->format);
  380. return 0;
  381. }
  382. static int config_output(AVFilterLink *outlink)
  383. {
  384. return config_filter(outlink, 1);
  385. }
  386. typedef struct ThreadData {
  387. AVFrame *in, *out;
  388. } ThreadData;
  389. static int filter_channel(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs)
  390. {
  391. AVFilterLink *inlink = ctx->inputs[0];
  392. ThreadData *td = arg;
  393. AVFrame *buf = td->in;
  394. AVFrame *out_buf = td->out;
  395. BiquadsContext *s = ctx->priv;
  396. const int start = (buf->channels * jobnr) / nb_jobs;
  397. const int end = (buf->channels * (jobnr+1)) / nb_jobs;
  398. int ch;
  399. for (ch = start; ch < end; ch++) {
  400. if (!((av_channel_layout_extract_channel(inlink->channel_layout, ch) & s->channels))) {
  401. if (buf != out_buf)
  402. memcpy(out_buf->extended_data[ch], buf->extended_data[ch],
  403. buf->nb_samples * s->block_align);
  404. continue;
  405. }
  406. s->filter(s, buf->extended_data[ch], out_buf->extended_data[ch], buf->nb_samples,
  407. &s->cache[ch].i1, &s->cache[ch].i2, &s->cache[ch].o1, &s->cache[ch].o2,
  408. s->b0, s->b1, s->b2, s->a1, s->a2, &s->cache[ch].clippings);
  409. }
  410. return 0;
  411. }
  412. static int filter_frame(AVFilterLink *inlink, AVFrame *buf)
  413. {
  414. AVFilterContext *ctx = inlink->dst;
  415. BiquadsContext *s = ctx->priv;
  416. AVFilterLink *outlink = ctx->outputs[0];
  417. AVFrame *out_buf;
  418. ThreadData td;
  419. int ch;
  420. if (av_frame_is_writable(buf)) {
  421. out_buf = buf;
  422. } else {
  423. out_buf = ff_get_audio_buffer(outlink, buf->nb_samples);
  424. if (!out_buf) {
  425. av_frame_free(&buf);
  426. return AVERROR(ENOMEM);
  427. }
  428. av_frame_copy_props(out_buf, buf);
  429. }
  430. td.in = buf;
  431. td.out = out_buf;
  432. ctx->internal->execute(ctx, filter_channel, &td, NULL, FFMIN(outlink->channels, ff_filter_get_nb_threads(ctx)));
  433. for (ch = 0; ch < outlink->channels; ch++) {
  434. if (s->cache[ch].clippings > 0)
  435. av_log(ctx, AV_LOG_WARNING, "Channel %d clipping %d times. Please reduce gain.\n",
  436. ch, s->cache[ch].clippings);
  437. s->cache[ch].clippings = 0;
  438. }
  439. if (buf != out_buf)
  440. av_frame_free(&buf);
  441. return ff_filter_frame(outlink, out_buf);
  442. }
  443. static int process_command(AVFilterContext *ctx, const char *cmd, const char *args,
  444. char *res, int res_len, int flags)
  445. {
  446. BiquadsContext *s = ctx->priv;
  447. AVFilterLink *outlink = ctx->outputs[0];
  448. if ((!strcmp(cmd, "frequency") || !strcmp(cmd, "f")) &&
  449. (s->filter_type == equalizer ||
  450. s->filter_type == lowshelf ||
  451. s->filter_type == highshelf ||
  452. s->filter_type == bass ||
  453. s->filter_type == treble ||
  454. s->filter_type == bandpass ||
  455. s->filter_type == bandreject||
  456. s->filter_type == lowpass ||
  457. s->filter_type == highpass ||
  458. s->filter_type == allpass)) {
  459. double freq;
  460. if (sscanf(args, "%lf", &freq) != 1) {
  461. av_log(ctx, AV_LOG_ERROR, "Invalid frequency value.\n");
  462. return AVERROR(EINVAL);
  463. }
  464. s->frequency = freq;
  465. } else if ((!strcmp(cmd, "gain") || !strcmp(cmd, "g")) &&
  466. (s->filter_type == equalizer ||
  467. s->filter_type == lowshelf ||
  468. s->filter_type == highshelf ||
  469. s->filter_type == bass ||
  470. s->filter_type == treble)) {
  471. double gain;
  472. if (sscanf(args, "%lf", &gain) != 1) {
  473. av_log(ctx, AV_LOG_ERROR, "Invalid gain value.\n");
  474. return AVERROR(EINVAL);
  475. }
  476. s->gain = gain;
  477. } else if ((!strcmp(cmd, "width") || !strcmp(cmd, "w")) &&
  478. (s->filter_type == equalizer ||
  479. s->filter_type == lowshelf ||
  480. s->filter_type == highshelf ||
  481. s->filter_type == bass ||
  482. s->filter_type == treble ||
  483. s->filter_type == bandpass ||
  484. s->filter_type == bandreject||
  485. s->filter_type == lowpass ||
  486. s->filter_type == highpass ||
  487. s->filter_type == allpass)) {
  488. double width;
  489. if (sscanf(args, "%lf", &width) != 1) {
  490. av_log(ctx, AV_LOG_ERROR, "Invalid width value.\n");
  491. return AVERROR(EINVAL);
  492. }
  493. s->width = width;
  494. } else if ((!strcmp(cmd, "width_type") || !strcmp(cmd, "t")) &&
  495. (s->filter_type == equalizer ||
  496. s->filter_type == lowshelf ||
  497. s->filter_type == highshelf ||
  498. s->filter_type == bass ||
  499. s->filter_type == treble ||
  500. s->filter_type == bandpass ||
  501. s->filter_type == bandreject||
  502. s->filter_type == lowpass ||
  503. s->filter_type == highpass ||
  504. s->filter_type == allpass)) {
  505. char width_type;
  506. if (sscanf(args, "%c", &width_type) != 1) {
  507. av_log(ctx, AV_LOG_ERROR, "Invalid width_type value.\n");
  508. return AVERROR(EINVAL);
  509. }
  510. switch (width_type) {
  511. case 'h': width_type = HERTZ; break;
  512. case 'q': width_type = QFACTOR; break;
  513. case 'o': width_type = OCTAVE; break;
  514. case 's': width_type = SLOPE; break;
  515. case 'k': width_type = KHERTZ; break;
  516. default:
  517. av_log(ctx, AV_LOG_ERROR, "Invalid width_type value: %c\n", width_type);
  518. return AVERROR(EINVAL);
  519. }
  520. s->width_type = width_type;
  521. } else if ((!strcmp(cmd, "a0") ||
  522. !strcmp(cmd, "a1") ||
  523. !strcmp(cmd, "a2") ||
  524. !strcmp(cmd, "b0") ||
  525. !strcmp(cmd, "b1") ||
  526. !strcmp(cmd, "b2")) &&
  527. s->filter_type == biquad) {
  528. double value;
  529. if (sscanf(args, "%lf", &value) != 1) {
  530. av_log(ctx, AV_LOG_ERROR, "Invalid biquad value.\n");
  531. return AVERROR(EINVAL);
  532. }
  533. if (!strcmp(cmd, "a0"))
  534. s->a0 = value;
  535. else if (!strcmp(cmd, "a1"))
  536. s->a1 = value;
  537. else if (!strcmp(cmd, "a2"))
  538. s->a2 = value;
  539. else if (!strcmp(cmd, "b0"))
  540. s->b0 = value;
  541. else if (!strcmp(cmd, "b1"))
  542. s->b1 = value;
  543. else if (!strcmp(cmd, "b2"))
  544. s->b2 = value;
  545. }
  546. return config_filter(outlink, 0);
  547. }
  548. static av_cold void uninit(AVFilterContext *ctx)
  549. {
  550. BiquadsContext *s = ctx->priv;
  551. av_freep(&s->cache);
  552. }
  553. static const AVFilterPad inputs[] = {
  554. {
  555. .name = "default",
  556. .type = AVMEDIA_TYPE_AUDIO,
  557. .filter_frame = filter_frame,
  558. },
  559. { NULL }
  560. };
  561. static const AVFilterPad outputs[] = {
  562. {
  563. .name = "default",
  564. .type = AVMEDIA_TYPE_AUDIO,
  565. .config_props = config_output,
  566. },
  567. { NULL }
  568. };
  569. #define OFFSET(x) offsetof(BiquadsContext, x)
  570. #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
  571. #define DEFINE_BIQUAD_FILTER(name_, description_) \
  572. AVFILTER_DEFINE_CLASS(name_); \
  573. static av_cold int name_##_init(AVFilterContext *ctx) \
  574. { \
  575. BiquadsContext *s = ctx->priv; \
  576. s->class = &name_##_class; \
  577. s->filter_type = name_; \
  578. return init(ctx); \
  579. } \
  580. \
  581. AVFilter ff_af_##name_ = { \
  582. .name = #name_, \
  583. .description = NULL_IF_CONFIG_SMALL(description_), \
  584. .priv_size = sizeof(BiquadsContext), \
  585. .init = name_##_init, \
  586. .uninit = uninit, \
  587. .query_formats = query_formats, \
  588. .inputs = inputs, \
  589. .outputs = outputs, \
  590. .priv_class = &name_##_class, \
  591. .process_command = process_command, \
  592. .flags = AVFILTER_FLAG_SLICE_THREADS, \
  593. }
  594. #if CONFIG_EQUALIZER_FILTER
  595. static const AVOption equalizer_options[] = {
  596. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
  597. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=0}, 0, 999999, FLAGS},
  598. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  599. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  600. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  601. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  602. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  603. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  604. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  605. {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
  606. {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0, 99999, FLAGS},
  607. {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  608. {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  609. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  610. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  611. {NULL}
  612. };
  613. DEFINE_BIQUAD_FILTER(equalizer, "Apply two-pole peaking equalization (EQ) filter.");
  614. #endif /* CONFIG_EQUALIZER_FILTER */
  615. #if CONFIG_BASS_FILTER
  616. static const AVOption bass_options[] = {
  617. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
  618. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
  619. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  620. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  621. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  622. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  623. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  624. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  625. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  626. {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  627. {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  628. {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  629. {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  630. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  631. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  632. {NULL}
  633. };
  634. DEFINE_BIQUAD_FILTER(bass, "Boost or cut lower frequencies.");
  635. #endif /* CONFIG_BASS_FILTER */
  636. #if CONFIG_TREBLE_FILTER
  637. static const AVOption treble_options[] = {
  638. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  639. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  640. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  641. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  642. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  643. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  644. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  645. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  646. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  647. {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  648. {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  649. {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  650. {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  651. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  652. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  653. {NULL}
  654. };
  655. DEFINE_BIQUAD_FILTER(treble, "Boost or cut upper frequencies.");
  656. #endif /* CONFIG_TREBLE_FILTER */
  657. #if CONFIG_BANDPASS_FILTER
  658. static const AVOption bandpass_options[] = {
  659. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  660. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  661. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  662. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  663. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  664. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  665. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  666. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  667. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  668. {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  669. {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  670. {"csg", "use constant skirt gain", OFFSET(csg), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, FLAGS},
  671. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  672. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  673. {NULL}
  674. };
  675. DEFINE_BIQUAD_FILTER(bandpass, "Apply a two-pole Butterworth band-pass filter.");
  676. #endif /* CONFIG_BANDPASS_FILTER */
  677. #if CONFIG_BANDREJECT_FILTER
  678. static const AVOption bandreject_options[] = {
  679. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  680. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  681. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  682. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  683. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  684. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  685. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  686. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  687. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  688. {"width", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  689. {"w", "set band-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  690. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  691. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  692. {NULL}
  693. };
  694. DEFINE_BIQUAD_FILTER(bandreject, "Apply a two-pole Butterworth band-reject filter.");
  695. #endif /* CONFIG_BANDREJECT_FILTER */
  696. #if CONFIG_LOWPASS_FILTER
  697. static const AVOption lowpass_options[] = {
  698. {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
  699. {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=500}, 0, 999999, FLAGS},
  700. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  701. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  702. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  703. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  704. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  705. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  706. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  707. {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  708. {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  709. {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  710. {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  711. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  712. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  713. {NULL}
  714. };
  715. DEFINE_BIQUAD_FILTER(lowpass, "Apply a low-pass filter with 3dB point frequency.");
  716. #endif /* CONFIG_LOWPASS_FILTER */
  717. #if CONFIG_HIGHPASS_FILTER
  718. static const AVOption highpass_options[] = {
  719. {"frequency", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  720. {"f", "set frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  721. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  722. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  723. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  724. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  725. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  726. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  727. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  728. {"width", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  729. {"w", "set width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.707}, 0, 99999, FLAGS},
  730. {"poles", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  731. {"p", "set number of poles", OFFSET(poles), AV_OPT_TYPE_INT, {.i64=2}, 1, 2, FLAGS},
  732. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  733. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  734. {NULL}
  735. };
  736. DEFINE_BIQUAD_FILTER(highpass, "Apply a high-pass filter with 3dB point frequency.");
  737. #endif /* CONFIG_HIGHPASS_FILTER */
  738. #if CONFIG_ALLPASS_FILTER
  739. static const AVOption allpass_options[] = {
  740. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  741. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  742. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  743. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=HERTZ}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  744. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  745. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  746. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  747. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  748. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  749. {"width", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
  750. {"w", "set filter-width", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=707.1}, 0, 99999, FLAGS},
  751. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  752. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  753. {NULL}
  754. };
  755. DEFINE_BIQUAD_FILTER(allpass, "Apply a two-pole all-pass filter.");
  756. #endif /* CONFIG_ALLPASS_FILTER */
  757. #if CONFIG_LOWSHELF_FILTER
  758. static const AVOption lowshelf_options[] = {
  759. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
  760. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=100}, 0, 999999, FLAGS},
  761. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  762. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  763. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  764. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  765. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  766. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  767. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  768. {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  769. {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  770. {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  771. {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  772. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  773. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  774. {NULL}
  775. };
  776. DEFINE_BIQUAD_FILTER(lowshelf, "Apply a low shelf filter.");
  777. #endif /* CONFIG_LOWSHELF_FILTER */
  778. #if CONFIG_HIGHSHELF_FILTER
  779. static const AVOption highshelf_options[] = {
  780. {"frequency", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  781. {"f", "set central frequency", OFFSET(frequency), AV_OPT_TYPE_DOUBLE, {.dbl=3000}, 0, 999999, FLAGS},
  782. {"width_type", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  783. {"t", "set filter-width type", OFFSET(width_type), AV_OPT_TYPE_INT, {.i64=QFACTOR}, HERTZ, NB_WTYPE-1, FLAGS, "width_type"},
  784. {"h", "Hz", 0, AV_OPT_TYPE_CONST, {.i64=HERTZ}, 0, 0, FLAGS, "width_type"},
  785. {"q", "Q-Factor", 0, AV_OPT_TYPE_CONST, {.i64=QFACTOR}, 0, 0, FLAGS, "width_type"},
  786. {"o", "octave", 0, AV_OPT_TYPE_CONST, {.i64=OCTAVE}, 0, 0, FLAGS, "width_type"},
  787. {"s", "slope", 0, AV_OPT_TYPE_CONST, {.i64=SLOPE}, 0, 0, FLAGS, "width_type"},
  788. {"k", "kHz", 0, AV_OPT_TYPE_CONST, {.i64=KHERTZ}, 0, 0, FLAGS, "width_type"},
  789. {"width", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  790. {"w", "set shelf transition steep", OFFSET(width), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 99999, FLAGS},
  791. {"gain", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  792. {"g", "set gain", OFFSET(gain), AV_OPT_TYPE_DOUBLE, {.dbl=0}, -900, 900, FLAGS},
  793. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  794. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  795. {NULL}
  796. };
  797. DEFINE_BIQUAD_FILTER(highshelf, "Apply a high shelf filter.");
  798. #endif /* CONFIG_HIGHSHELF_FILTER */
  799. #if CONFIG_BIQUAD_FILTER
  800. static const AVOption biquad_options[] = {
  801. {"a0", NULL, OFFSET(a0), AV_OPT_TYPE_DOUBLE, {.dbl=1}, INT32_MIN, INT32_MAX, FLAGS},
  802. {"a1", NULL, OFFSET(a1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
  803. {"a2", NULL, OFFSET(a2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
  804. {"b0", NULL, OFFSET(b0), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
  805. {"b1", NULL, OFFSET(b1), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
  806. {"b2", NULL, OFFSET(b2), AV_OPT_TYPE_DOUBLE, {.dbl=0}, INT32_MIN, INT32_MAX, FLAGS},
  807. {"channels", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  808. {"c", "set channels to filter", OFFSET(channels), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=-1}, INT64_MIN, INT64_MAX, FLAGS},
  809. {NULL}
  810. };
  811. DEFINE_BIQUAD_FILTER(biquad, "Apply a biquad IIR filter with the given coefficients.");
  812. #endif /* CONFIG_BIQUAD_FILTER */