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.

362 lines
11KB

  1. /*
  2. * Copyright (C) 2001-2010 Krzysztof Foltman, Markus Schmidt, Thor Harald Johansen and others
  3. * Copyright (c) 2015 Paul B Mahol
  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. * @file
  23. * Lookahead limiter filter
  24. */
  25. #include "libavutil/avassert.h"
  26. #include "libavutil/channel_layout.h"
  27. #include "libavutil/common.h"
  28. #include "libavutil/opt.h"
  29. #include "audio.h"
  30. #include "avfilter.h"
  31. #include "formats.h"
  32. #include "internal.h"
  33. typedef struct AudioLimiterContext {
  34. const AVClass *class;
  35. double limit;
  36. double attack;
  37. double release;
  38. double att;
  39. int auto_release;
  40. double asc;
  41. int asc_c;
  42. int asc_pos;
  43. double asc_coeff;
  44. double *buffer;
  45. int buffer_size;
  46. int pos;
  47. int *nextpos;
  48. double *nextdelta;
  49. double delta;
  50. int nextiter;
  51. int nextlen;
  52. int asc_changed;
  53. } AudioLimiterContext;
  54. #define OFFSET(x) offsetof(AudioLimiterContext, x)
  55. #define A AV_OPT_FLAG_AUDIO_PARAM
  56. #define F AV_OPT_FLAG_FILTERING_PARAM
  57. static const AVOption alimiter_options[] = {
  58. { "limit", "set limit", OFFSET(limit), AV_OPT_TYPE_DOUBLE, {.dbl=1}, 0.0625, 1, A|F },
  59. { "attack", "set attack", OFFSET(attack), AV_OPT_TYPE_DOUBLE, {.dbl=5}, 0.1, 80, A|F },
  60. { "release", "set release", OFFSET(release), AV_OPT_TYPE_DOUBLE, {.dbl=50}, 1, 8000, A|F },
  61. { "asc", "enable asc", OFFSET(auto_release), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, A|F },
  62. { "asc_level", "set asc level", OFFSET(asc_coeff), AV_OPT_TYPE_DOUBLE, {.dbl=0.5}, 0, 1, A|F },
  63. { NULL }
  64. };
  65. AVFILTER_DEFINE_CLASS(alimiter);
  66. static av_cold int init(AVFilterContext *ctx)
  67. {
  68. AudioLimiterContext *s = ctx->priv;
  69. s->attack /= 1000.;
  70. s->release /= 1000.;
  71. s->att = 1.;
  72. s->asc_pos = -1;
  73. s->asc_coeff = pow(0.5, s->asc_coeff - 0.5) * 2 * -1;
  74. return 0;
  75. }
  76. static double get_rdelta(AudioLimiterContext *s, double release, int sample_rate,
  77. double peak, double limit, double patt, int asc)
  78. {
  79. double rdelta = (1.0 - patt) / (sample_rate * release);
  80. if (asc && s->auto_release && s->asc_c > 0) {
  81. double a_att = limit / (s->asc_coeff * s->asc) * (double)s->asc_c;
  82. if (a_att > patt) {
  83. double delta = FFMAX((a_att - patt) / (sample_rate * release), rdelta / 10);
  84. if (delta < rdelta)
  85. rdelta = delta;
  86. }
  87. }
  88. return rdelta;
  89. }
  90. static int filter_frame(AVFilterLink *inlink, AVFrame *in)
  91. {
  92. AVFilterContext *ctx = inlink->dst;
  93. AudioLimiterContext *s = ctx->priv;
  94. AVFilterLink *outlink = ctx->outputs[0];
  95. const double *src = (const double *)in->data[0];
  96. const int channels = inlink->channels;
  97. const int buffer_size = s->buffer_size;
  98. double *dst, *buffer = s->buffer;
  99. const double release = s->release;
  100. const double limit = s->limit;
  101. double *nextdelta = s->nextdelta;
  102. int *nextpos = s->nextpos;
  103. AVFrame *out;
  104. double *buf;
  105. int n, c, i;
  106. if (av_frame_is_writable(in)) {
  107. out = in;
  108. } else {
  109. out = ff_get_audio_buffer(inlink, in->nb_samples);
  110. if (!out) {
  111. av_frame_free(&in);
  112. return AVERROR(ENOMEM);
  113. }
  114. av_frame_copy_props(out, in);
  115. }
  116. dst = (double *)out->data[0];
  117. for (n = 0; n < in->nb_samples; n++) {
  118. double peak = 0;
  119. for (c = 0; c < channels; c++) {
  120. double sample = src[c];
  121. buffer[s->pos + c] = sample;
  122. peak = FFMAX(peak, fabs(sample));
  123. }
  124. if (s->auto_release && peak > limit) {
  125. s->asc += peak;
  126. s->asc_c++;
  127. }
  128. if (peak > limit) {
  129. double patt = FFMIN(limit / peak, 1.);
  130. double rdelta = get_rdelta(s, release, inlink->sample_rate,
  131. peak, limit, patt, 0);
  132. double delta = (limit / peak - s->att) / buffer_size * channels;
  133. int found = 0;
  134. if (delta < s->delta) {
  135. s->delta = delta;
  136. nextpos[0] = s->pos;
  137. nextpos[1] = -1;
  138. nextdelta[0] = rdelta;
  139. s->nextlen = 1;
  140. s->nextiter= 0;
  141. } else {
  142. for (i = s->nextiter; i < s->nextiter + s->nextlen; i++) {
  143. int j = i % buffer_size;
  144. double ppeak, pdelta;
  145. ppeak = fabs(buffer[nextpos[j]]) > fabs(buffer[nextpos[j] + 1]) ?
  146. fabs(buffer[nextpos[j]]) : fabs(buffer[nextpos[j] + 1]);
  147. pdelta = (limit / peak - limit / ppeak) / (((buffer_size - nextpos[j] + s->pos) % buffer_size) / channels);
  148. if (pdelta < nextdelta[j]) {
  149. nextdelta[j] = pdelta;
  150. found = 1;
  151. break;
  152. }
  153. }
  154. if (found) {
  155. s->nextlen = i - s->nextiter + 1;
  156. nextpos[(s->nextiter + s->nextlen) % buffer_size] = s->pos;
  157. nextdelta[(s->nextiter + s->nextlen) % buffer_size] = rdelta;
  158. nextpos[(s->nextiter + s->nextlen + 1) % buffer_size] = -1;
  159. s->nextlen++;
  160. }
  161. }
  162. }
  163. buf = &s->buffer[(s->pos + channels) % buffer_size];
  164. peak = 0;
  165. for (c = 0; c < channels; c++) {
  166. double sample = buf[c];
  167. peak = FFMAX(peak, fabs(sample));
  168. }
  169. if (s->pos == s->asc_pos && !s->asc_changed)
  170. s->asc_pos = -1;
  171. if (s->auto_release && s->asc_pos == -1 && peak > limit) {
  172. s->asc -= peak;
  173. s->asc_c--;
  174. }
  175. s->att += s->delta;
  176. for (c = 0; c < channels; c++)
  177. dst[c] = buf[c] * s->att;
  178. if ((s->pos + channels) % buffer_size == nextpos[s->nextiter]) {
  179. if (s->auto_release) {
  180. s->delta = get_rdelta(s, release, inlink->sample_rate,
  181. peak, limit, s->att, 1);
  182. if (s->nextlen > 1) {
  183. int pnextpos = nextpos[(s->nextiter + 1) % buffer_size];
  184. double ppeak = fabs(buffer[pnextpos]) > fabs(buffer[pnextpos + 1]) ?
  185. fabs(buffer[pnextpos]) :
  186. fabs(buffer[pnextpos + 1]);
  187. double pdelta = (limit / ppeak - s->att) /
  188. (((buffer_size + pnextpos -
  189. ((s->pos + channels) % buffer_size)) %
  190. buffer_size) / channels);
  191. if (pdelta < s->delta)
  192. s->delta = pdelta;
  193. }
  194. } else {
  195. s->delta = nextdelta[s->nextiter];
  196. s->att = limit / peak;
  197. }
  198. s->nextlen -= 1;
  199. nextpos[s->nextiter] = -1;
  200. s->nextiter = (s->nextiter + 1) % buffer_size;
  201. }
  202. if (s->att > 1.) {
  203. s->att = 1.;
  204. s->delta = 0.;
  205. s->nextiter = 0;
  206. s->nextlen = 0;
  207. nextpos[0] = -1;
  208. }
  209. if (s->att <= 0.) {
  210. s->att = 0.0000000000001;
  211. s->delta = (1.0 - s->att) / (inlink->sample_rate * release);
  212. }
  213. if (s->att != 1. && (1. - s->att) < 0.0000000000001)
  214. s->att = 1.;
  215. if (s->delta != 0. && fabs(s->delta) < 0.00000000000001)
  216. s->delta = 0.;
  217. for (c = 0; c < channels; c++)
  218. dst[c] = av_clipd(dst[c], -limit, limit);
  219. s->pos = (s->pos + channels) % buffer_size;
  220. src += channels;
  221. dst += channels;
  222. }
  223. if (in != out)
  224. av_frame_free(&in);
  225. return ff_filter_frame(outlink, out);
  226. }
  227. static int query_formats(AVFilterContext *ctx)
  228. {
  229. AVFilterFormats *formats;
  230. AVFilterChannelLayouts *layouts;
  231. static const enum AVSampleFormat sample_fmts[] = {
  232. AV_SAMPLE_FMT_DBL,
  233. AV_SAMPLE_FMT_NONE
  234. };
  235. int ret;
  236. layouts = ff_all_channel_counts();
  237. if (!layouts)
  238. return AVERROR(ENOMEM);
  239. ret = ff_set_common_channel_layouts(ctx, layouts);
  240. if (ret < 0)
  241. return ret;
  242. formats = ff_make_format_list(sample_fmts);
  243. if (!formats)
  244. return AVERROR(ENOMEM);
  245. ret = ff_set_common_formats(ctx, formats);
  246. if (ret < 0)
  247. return ret;
  248. formats = ff_all_samplerates();
  249. if (!formats)
  250. return AVERROR(ENOMEM);
  251. return ff_set_common_samplerates(ctx, formats);
  252. }
  253. static int config_input(AVFilterLink *inlink)
  254. {
  255. AVFilterContext *ctx = inlink->dst;
  256. AudioLimiterContext *s = ctx->priv;
  257. int obuffer_size;
  258. obuffer_size = inlink->sample_rate * inlink->channels * 100 / 1000. + inlink->channels;
  259. if (obuffer_size < inlink->channels)
  260. return AVERROR(EINVAL);
  261. s->buffer = av_calloc(obuffer_size, sizeof(*s->buffer));
  262. s->nextdelta = av_calloc(obuffer_size, sizeof(*s->nextdelta));
  263. s->nextpos = av_malloc_array(obuffer_size, sizeof(*s->nextpos));
  264. if (!s->buffer || !s->nextdelta || !s->nextpos)
  265. return AVERROR(ENOMEM);
  266. memset(s->nextpos, -1, obuffer_size * sizeof(*s->nextpos));
  267. s->buffer_size = inlink->sample_rate * s->attack * inlink->channels;
  268. s->buffer_size -= s->buffer_size % inlink->channels;
  269. return 0;
  270. }
  271. static av_cold void uninit(AVFilterContext *ctx)
  272. {
  273. AudioLimiterContext *s = ctx->priv;
  274. av_freep(&s->buffer);
  275. av_freep(&s->nextdelta);
  276. av_freep(&s->nextpos);
  277. }
  278. static const AVFilterPad alimiter_inputs[] = {
  279. {
  280. .name = "main",
  281. .type = AVMEDIA_TYPE_AUDIO,
  282. .filter_frame = filter_frame,
  283. .config_props = config_input,
  284. },
  285. { NULL }
  286. };
  287. static const AVFilterPad alimiter_outputs[] = {
  288. {
  289. .name = "default",
  290. .type = AVMEDIA_TYPE_AUDIO,
  291. },
  292. { NULL }
  293. };
  294. AVFilter ff_af_alimiter = {
  295. .name = "alimiter",
  296. .description = NULL_IF_CONFIG_SMALL("Lookahead limiter."),
  297. .priv_size = sizeof(AudioLimiterContext),
  298. .priv_class = &alimiter_class,
  299. .init = init,
  300. .uninit = uninit,
  301. .query_formats = query_formats,
  302. .inputs = alimiter_inputs,
  303. .outputs = alimiter_outputs,
  304. };