FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
af_superequalizer.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2002 Naoki Shibata
3  * Copyright (c) 2017 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 #include "libavutil/opt.h"
23 
24 #include "libavcodec/avfft.h"
25 
26 #include "audio.h"
27 #include "avfilter.h"
28 #include "internal.h"
29 
30 #define NBANDS 17
31 #define M 15
32 
33 typedef struct EqParameter {
34  float lower, upper, gain;
35 } EqParameter;
36 
37 typedef struct SuperEqualizerContext {
38  const AVClass *class;
39 
41 
42  float gains[NBANDS + 1];
43 
44  float fact[M + 1];
45  float aa;
46  float iza;
47  float *ires, *irest;
48  float *fsamples;
50 
54 
55 static const float bands[] = {
56  65.406392, 92.498606, 130.81278, 184.99721, 261.62557, 369.99442, 523.25113, 739.9884, 1046.5023,
57  1479.9768, 2093.0045, 2959.9536, 4186.0091, 5919.9072, 8372.0181, 11839.814, 16744.036
58 };
59 
60 static float izero(SuperEqualizerContext *s, float x)
61 {
62  float ret = 1;
63  int m;
64 
65  for (m = 1; m <= M; m++) {
66  float t;
67 
68  t = pow(x / 2, m) / s->fact[m];
69  ret += t*t;
70  }
71 
72  return ret;
73 }
74 
75 static float hn_lpf(int n, float f, float fs)
76 {
77  float t = 1 / fs;
78  float omega = 2 * M_PI * f;
79 
80  if (n * omega * t == 0)
81  return 2 * f * t;
82  return 2 * f * t * sinf(n * omega * t) / (n * omega * t);
83 }
84 
85 static float hn_imp(int n)
86 {
87  return n == 0 ? 1.f : 0.f;
88 }
89 
90 static float hn(int n, EqParameter *param, float fs)
91 {
92  float ret, lhn;
93  int i;
94 
95  lhn = hn_lpf(n, param[0].upper, fs);
96  ret = param[0].gain*lhn;
97 
98  for (i = 1; i < NBANDS + 1 && param[i].upper < fs / 2; i++) {
99  float lhn2 = hn_lpf(n, param[i].upper, fs);
100  ret += param[i].gain * (lhn2 - lhn);
101  lhn = lhn2;
102  }
103 
104  ret += param[i].gain * (hn_imp(n) - lhn);
105 
106  return ret;
107 }
108 
109 static float alpha(float a)
110 {
111  if (a <= 21)
112  return 0;
113  if (a <= 50)
114  return .5842f * pow(a - 21, 0.4f) + 0.07886f * (a - 21);
115  return .1102f * (a - 8.7f);
116 }
117 
118 static float win(SuperEqualizerContext *s, float n, int N)
119 {
120  return izero(s, alpha(s->aa) * sqrtf(1 - 4 * n * n / ((N - 1) * (N - 1)))) / s->iza;
121 }
122 
123 static void process_param(float *bc, EqParameter *param, float fs)
124 {
125  int i;
126 
127  for (i = 0; i <= NBANDS; i++) {
128  param[i].lower = i == 0 ? 0 : bands[i - 1];
129  param[i].upper = i == NBANDS ? fs : bands[i];
130  param[i].gain = bc[i];
131  }
132 }
133 
134 static int equ_init(SuperEqualizerContext *s, int wb)
135 {
136  int i,j;
137 
138  s->rdft = av_rdft_init(wb, DFT_R2C);
139  s->irdft = av_rdft_init(wb, IDFT_C2R);
140  if (!s->rdft || !s->irdft)
141  return AVERROR(ENOMEM);
142 
143  s->aa = 96;
144  s->winlen = (1 << (wb-1))-1;
145  s->tabsize = 1 << wb;
146 
147  s->ires = av_calloc(s->tabsize, sizeof(float));
148  s->irest = av_calloc(s->tabsize, sizeof(float));
149  s->fsamples = av_calloc(s->tabsize, sizeof(float));
150 
151  for (i = 0; i <= M; i++) {
152  s->fact[i] = 1;
153  for (j = 1; j <= i; j++)
154  s->fact[i] *= j;
155  }
156 
157  s->iza = izero(s, alpha(s->aa));
158 
159  return 0;
160 }
161 
162 static void make_fir(SuperEqualizerContext *s, float *lbc, float *rbc, EqParameter *param, float fs)
163 {
164  const int winlen = s->winlen;
165  const int tabsize = s->tabsize;
166  float *nires;
167  int i;
168 
169  if (fs <= 0)
170  return;
171 
172  process_param(lbc, param, fs);
173  for (i = 0; i < winlen; i++)
174  s->irest[i] = hn(i - winlen / 2, param, fs) * win(s, i - winlen / 2, winlen);
175  for (; i < tabsize; i++)
176  s->irest[i] = 0;
177 
178  av_rdft_calc(s->rdft, s->irest);
179  nires = s->ires;
180  for (i = 0; i < tabsize; i++)
181  nires[i] = s->irest[i];
182 }
183 
184 static int filter_frame(AVFilterLink *inlink, AVFrame *in)
185 {
186  AVFilterContext *ctx = inlink->dst;
187  SuperEqualizerContext *s = ctx->priv;
188  AVFilterLink *outlink = ctx->outputs[0];
189  const float *ires = s->ires;
190  float *fsamples = s->fsamples;
191  int ch, i;
192 
193  AVFrame *out = ff_get_audio_buffer(outlink, s->winlen);
194  float *src, *dst, *ptr;
195 
196  if (!out) {
197  av_frame_free(&in);
198  return AVERROR(ENOMEM);
199  }
200 
201  for (ch = 0; ch < in->channels; ch++) {
202  ptr = (float *)out->extended_data[ch];
203  dst = (float *)s->out->extended_data[ch];
204  src = (float *)in->extended_data[ch];
205 
206  for (i = 0; i < s->winlen; i++)
207  fsamples[i] = src[i];
208  for (; i < s->tabsize; i++)
209  fsamples[i] = 0;
210 
211  av_rdft_calc(s->rdft, fsamples);
212 
213  fsamples[0] = ires[0] * fsamples[0];
214  fsamples[1] = ires[1] * fsamples[1];
215  for (i = 1; i < s->tabsize / 2; i++) {
216  float re, im;
217 
218  re = ires[i*2 ] * fsamples[i*2] - ires[i*2+1] * fsamples[i*2+1];
219  im = ires[i*2+1] * fsamples[i*2] + ires[i*2 ] * fsamples[i*2+1];
220 
221  fsamples[i*2 ] = re;
222  fsamples[i*2+1] = im;
223  }
224 
225  av_rdft_calc(s->irdft, fsamples);
226 
227  for (i = 0; i < s->winlen; i++)
228  dst[i] += fsamples[i] / s->tabsize * 2;
229  for (i = s->winlen; i < s->tabsize; i++)
230  dst[i] = fsamples[i] / s->tabsize * 2;
231  for (i = 0; i < s->winlen; i++)
232  ptr[i] = dst[i];
233  for (i = 0; i < s->winlen; i++)
234  dst[i] = dst[i+s->winlen];
235  }
236 
237  out->pts = in->pts;
238  av_frame_free(&in);
239 
240  return ff_filter_frame(outlink, out);
241 }
242 
244 {
245  SuperEqualizerContext *s = ctx->priv;
246 
247  return equ_init(s, 14);
248 }
249 
251 {
254  static const enum AVSampleFormat sample_fmts[] = {
257  };
258  int ret;
259 
260  layouts = ff_all_channel_counts();
261  if (!layouts)
262  return AVERROR(ENOMEM);
263  ret = ff_set_common_channel_layouts(ctx, layouts);
264  if (ret < 0)
265  return ret;
266 
267  formats = ff_make_format_list(sample_fmts);
268  if ((ret = ff_set_common_formats(ctx, formats)) < 0)
269  return ret;
270 
271  formats = ff_all_samplerates();
272  return ff_set_common_samplerates(ctx, formats);
273 }
274 
275 static int config_input(AVFilterLink *inlink)
276 {
277  AVFilterContext *ctx = inlink->dst;
278  SuperEqualizerContext *s = ctx->priv;
279 
280  inlink->partial_buf_size =
281  inlink->min_samples =
282  inlink->max_samples = s->winlen;
283 
284  s->out = ff_get_audio_buffer(inlink, s->tabsize);
285  if (!s->out)
286  return AVERROR(ENOMEM);
287 
288  return 0;
289 }
290 
291 static int config_output(AVFilterLink *outlink)
292 {
293  AVFilterContext *ctx = outlink->src;
294  SuperEqualizerContext *s = ctx->priv;
295 
296  make_fir(s, s->gains, s->gains, s->params, outlink->sample_rate);
297 
298  return 0;
299 }
300 
302 {
303  SuperEqualizerContext *s = ctx->priv;
304 
305  av_frame_free(&s->out);
306  av_freep(&s->irest);
307  av_freep(&s->ires);
308  av_freep(&s->fsamples);
309  av_rdft_end(s->rdft);
310  av_rdft_end(s->irdft);
311 }
312 
314  {
315  .name = "default",
316  .type = AVMEDIA_TYPE_AUDIO,
317  .filter_frame = filter_frame,
318  .config_props = config_input,
319  },
320  { NULL }
321 };
322 
324  {
325  .name = "default",
326  .type = AVMEDIA_TYPE_AUDIO,
327  .config_props = config_output,
328  },
329  { NULL }
330 };
331 
332 #define AF AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
333 #define OFFSET(x) offsetof(SuperEqualizerContext, x)
334 
336  { "1b", "set 65Hz band gain", OFFSET(gains [0]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
337  { "2b", "set 92Hz band gain", OFFSET(gains [1]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
338  { "3b", "set 131Hz band gain", OFFSET(gains [2]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
339  { "4b", "set 185Hz band gain", OFFSET(gains [3]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
340  { "5b", "set 262Hz band gain", OFFSET(gains [4]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
341  { "6b", "set 370Hz band gain", OFFSET(gains [5]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
342  { "7b", "set 523Hz band gain", OFFSET(gains [6]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
343  { "8b", "set 740Hz band gain", OFFSET(gains [7]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
344  { "9b", "set 1047Hz band gain", OFFSET(gains [8]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
345  { "10b", "set 1480Hz band gain", OFFSET(gains [9]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
346  { "11b", "set 2093Hz band gain", OFFSET(gains[10]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
347  { "12b", "set 2960Hz band gain", OFFSET(gains[11]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
348  { "13b", "set 4186Hz band gain", OFFSET(gains[12]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
349  { "14b", "set 5920Hz band gain", OFFSET(gains[13]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
350  { "15b", "set 8372Hz band gain", OFFSET(gains[14]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
351  { "16b", "set 11840Hz band gain", OFFSET(gains[15]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
352  { "17b", "set 16744Hz band gain", OFFSET(gains[16]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
353  { "18b", "set 20000Hz band gain", OFFSET(gains[17]), AV_OPT_TYPE_FLOAT, {.dbl=1}, 0, 20, AF },
354  { NULL }
355 };
356 
357 AVFILTER_DEFINE_CLASS(superequalizer);
358 
360  .name = "superequalizer",
361  .description = NULL_IF_CONFIG_SMALL("Apply 18 band equalization filter."),
362  .priv_size = sizeof(SuperEqualizerContext),
363  .priv_class = &superequalizer_class,
365  .init = init,
366  .uninit = uninit,
367  .inputs = superequalizer_inputs,
368  .outputs = superequalizer_outputs,
369 };
float, planar
Definition: samplefmt.h:69
#define NULL
Definition: coverity.c:32
int ff_set_common_channel_layouts(AVFilterContext *ctx, AVFilterChannelLayouts *layouts)
A helper for query_formats() which sets all links to the same list of channel layouts/sample rates...
Definition: formats.c:549
static float alpha(float a)
This structure describes decoded (raw) audio or video data.
Definition: frame.h:226
static int query_formats(AVFilterContext *ctx)
static const AVFilterPad superequalizer_outputs[]
AVOption.
Definition: opt.h:246
static const AVOption superequalizer_options[]
float re
Definition: fft.c:82
#define NBANDS
Main libavfilter public API header.
static float win(SuperEqualizerContext *s, float n, int N)
#define src
Definition: vp8dsp.c:254
EqParameter params[NBANDS+1]
#define N
Definition: af_mcompand.c:54
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array().
Definition: mem.c:244
AVFilterFormats * ff_make_format_list(const int *fmts)
Create a list of supported formats.
Definition: formats.c:283
const char * name
Pad name.
Definition: internal.h:60
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter.
Definition: avfilter.c:1080
static float hn_imp(int n)
#define av_cold
Definition: attributes.h:82
#define fs(width, name, subs,...)
Definition: cbs_vp9.c:259
AVOptions.
static int equ_init(SuperEqualizerContext *s, int wb)
#define f(width, name)
Definition: cbs_vp9.c:255
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:319
static float hn(int n, EqParameter *param, float fs)
static int config_output(AVFilterLink *outlink)
A filter pad used for either input or output.
Definition: internal.h:54
static float hn_lpf(int n, float f, float fs)
int ff_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats)
A helper for query_formats() which sets all links to the same list of formats.
Definition: formats.c:568
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions.
Definition: audio.c:86
#define AVERROR(e)
Definition: error.h:43
static const AVFilterPad superequalizer_inputs[]
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void * priv
private data for use by the filter
Definition: avfilter.h:353
static float izero(SuperEqualizerContext *s, float x)
GLenum GLint * params
Definition: opengl_enc.c:114
Definition: avfft.h:73
#define OFFSET(x)
void av_rdft_calc(RDFTContext *s, FFTSample *data)
int channels
number of audio channels, only used for audio.
Definition: frame.h:531
#define AF
AVFormatContext * ctx
Definition: movenc.c:48
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
#define s(width, name)
Definition: cbs_vp9.c:257
Definition: avfft.h:72
void av_rdft_end(RDFTContext *s)
int n
Definition: avisynth_c.h:684
RDFTContext * av_rdft_init(int nbits, enum RDFTransformType trans)
Set up a real FFT.
static const AVFilterPad inputs[]
Definition: af_acontrast.c:193
static const AVFilterPad outputs[]
Definition: af_acontrast.c:203
A list of supported channel layouts.
Definition: formats.h:85
AVFilter ff_af_superequalizer
#define sinf(x)
Definition: libm.h:419
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
FFT functions.
static const float bands[]
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_log(ac->avr, AV_LOG_TRACE,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
Describe the class of an AVClass context structure.
Definition: log.h:67
Filter definition.
Definition: avfilter.h:144
float im
Definition: fft.c:82
const char * name
Filter name.
Definition: avfilter.h:148
static void process_param(float *bc, EqParameter *param, float fs)
AVFilterLink ** outputs
array of pointers to output links
Definition: avfilter.h:350
enum MovChannelLayoutTag * layouts
Definition: mov_chan.c:434
AVFilterFormats * ff_all_samplerates(void)
Definition: formats.c:395
AVFILTER_DEFINE_CLASS(superequalizer)
static void make_fir(SuperEqualizerContext *s, float *lbc, float *rbc, EqParameter *param, float fs)
A list of supported formats for one end of a filter link.
Definition: formats.h:64
static av_cold void uninit(AVFilterContext *ctx)
An instance of a filter.
Definition: avfilter.h:338
static enum AVSampleFormat sample_fmts[]
Definition: adpcmenc.c:701
FILE * out
Definition: movenc.c:54
#define av_freep(p)
#define M_PI
Definition: mathematics.h:52
static int config_input(AVFilterLink *inlink)
formats
Definition: signature.h:48
internal API functions
AVFilterChannelLayouts * ff_all_channel_counts(void)
Construct an AVFilterChannelLayouts coding for any channel layout, with known or unknown disposition...
Definition: formats.c:410
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:273
#define M
static av_cold int init(AVFilterContext *ctx)
for(j=16;j >0;--j)
int ff_set_common_samplerates(AVFilterContext *ctx, AVFilterFormats *samplerates)
Definition: formats.c:556
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(constuint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(constint16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(constint32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(constint64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(constint64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(constfloat *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(constdouble *) pi *(INT64_C(1)<< 63)))#defineFMT_PAIR_FUNC(out, in) staticconv_func_type *constfmt_pair_to_conv_functions[AV_SAMPLE_FMT_NB *AV_SAMPLE_FMT_NB]={FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_U8), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S16), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S32), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_FLT), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_DBL), FMT_PAIR_FUNC(AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_DBL, AV_SAMPLE_FMT_S64), FMT_PAIR_FUNC(AV_SAMPLE_FMT_S64, AV_SAMPLE_FMT_S64),};staticvoidcpy1(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, len);}staticvoidcpy2(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 2 *len);}staticvoidcpy4(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 4 *len);}staticvoidcpy8(uint8_t **dst, constuint8_t **src, intlen){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, constint *ch_map, intflags){AudioConvert *ctx;conv_func_type *f=fmt_pair_to_conv_functions[av_get_packed_sample_fmt(out_fmt)+AV_SAMPLE_FMT_NB *av_get_packed_sample_fmt(in_fmt)];if(!f) returnNULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) returnNULL;if(channels==1){in_fmt=av_get_planar_sample_fmt(in_fmt);out_fmt=av_get_planar_sample_fmt(out_fmt);}ctx->channels=channels;ctx->conv_f=f;ctx->ch_map=ch_map;if(in_fmt==AV_SAMPLE_FMT_U8||in_fmt==AV_SAMPLE_FMT_U8P) memset(ctx->silence, 0x80, sizeof(ctx->silence));if(out_fmt==in_fmt &&!ch_map){switch(av_get_bytes_per_sample(in_fmt)){case1:ctx->simd_f=cpy1;break;case2:ctx->simd_f=cpy2;break;case4:ctx->simd_f=cpy4;break;case8:ctx->simd_f=cpy8;break;}}if(HAVE_X86ASM &&1) swri_audio_convert_init_x86(ctx, out_fmt, in_fmt, channels);if(ARCH_ARM) swri_audio_convert_init_arm(ctx, out_fmt, in_fmt, channels);if(ARCH_AARCH64) swri_audio_convert_init_aarch64(ctx, out_fmt, in_fmt, channels);returnctx;}voidswri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}intswri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, intlen){intch;intoff=0;constintos=(out->planar?1:out->ch_count)*out->bps;unsignedmisaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){intplanes=in->planar?in->ch_count:1;unsignedm=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) in->ch[ch];misaligned|=m &ctx->in_simd_align_mask;}if(ctx->out_simd_align_mask){intplanes=out->planar?out->ch_count:1;unsignedm=0;for(ch=0;ch< planes;ch++) m|=(intptr_t) out->ch[ch];misaligned|=m &ctx->out_simd_align_mask;}if(ctx->simd_f &&!ctx->ch_map &&!misaligned){off=len &~15;av_assert1(off >=0);av_assert1(off<=len);av_assert2(ctx->channels==SWR_CH_MAX||!in->ch[ctx->channels]);if(off >0){if(out->planar==in->planar){intplanes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56