FFmpeg
dither.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
3  *
4  * Triangular with Noise Shaping is based on opusfile.
5  * Copyright (c) 1994-2012 by the Xiph.Org Foundation and contributors
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 /**
25  * @file
26  * Dithered Audio Sample Quantization
27  *
28  * Converts from dbl, flt, or s32 to s16 using dithering.
29  */
30 
31 #include <math.h>
32 #include <stdint.h>
33 
34 #include "libavutil/attributes.h"
35 #include "libavutil/common.h"
36 #include "libavutil/lfg.h"
37 #include "libavutil/mem.h"
38 #include "libavutil/samplefmt.h"
39 #include "audio_convert.h"
40 #include "dither.h"
41 #include "internal.h"
42 
43 typedef struct DitherState {
44  int mute;
45  unsigned int seed;
47  float *noise_buf;
50  float dither_a[4];
51  float dither_b[4];
52 } DitherState;
53 
54 struct DitherContext {
57  int apply_map;
59 
60  int mute_dither_threshold; // threshold for disabling dither
61  int mute_reset_threshold; // threshold for resetting noise shaping
62  const float *ns_coef_b; // noise shaping coeffs
63  const float *ns_coef_a; // noise shaping coeffs
64 
65  int channels;
66  DitherState *state; // dither states for each channel
67 
68  AudioData *flt_data; // input data in fltp
69  AudioData *s16_data; // dithered output in s16p
70  AudioConvert *ac_in; // converter for input to fltp
71  AudioConvert *ac_out; // converter for s16p to s16 (if needed)
72 
73  void (*quantize)(int16_t *dst, const float *src, float *dither, int len);
75 };
76 
77 /* mute threshold, in seconds */
78 #define MUTE_THRESHOLD_SEC 0.000333
79 
80 /* scale factor for 16-bit output.
81  The signal is attenuated slightly to avoid clipping */
82 #define S16_SCALE 32753.0f
83 
84 /* scale to convert lfg from INT_MIN/INT_MAX to -0.5/0.5 */
85 #define LFG_SCALE (1.0f / (2.0f * INT32_MAX))
86 
87 /* noise shaping coefficients */
88 
89 static const float ns_48_coef_b[4] = {
90  2.2374f, -0.7339f, -0.1251f, -0.6033f
91 };
92 
93 static const float ns_48_coef_a[4] = {
94  0.9030f, 0.0116f, -0.5853f, -0.2571f
95 };
96 
97 static const float ns_44_coef_b[4] = {
98  2.2061f, -0.4707f, -0.2534f, -0.6213f
99 };
100 
101 static const float ns_44_coef_a[4] = {
102  1.0587f, 0.0676f, -0.6054f, -0.2738f
103 };
104 
105 static void dither_int_to_float_rectangular_c(float *dst, int *src, int len)
106 {
107  int i;
108  for (i = 0; i < len; i++)
109  dst[i] = src[i] * LFG_SCALE;
110 }
111 
112 static void dither_int_to_float_triangular_c(float *dst, int *src0, int len)
113 {
114  int i;
115  int *src1 = src0 + len;
116 
117  for (i = 0; i < len; i++) {
118  float r = src0[i] * LFG_SCALE;
119  r += src1[i] * LFG_SCALE;
120  dst[i] = r;
121  }
122 }
123 
124 static void quantize_c(int16_t *dst, const float *src, float *dither, int len)
125 {
126  int i;
127  for (i = 0; i < len; i++)
128  dst[i] = av_clip_int16(lrintf(src[i] * S16_SCALE + dither[i]));
129 }
130 
131 #define SQRT_1_6 0.40824829046386301723f
132 
133 static void dither_highpass_filter(float *src, int len)
134 {
135  int i;
136 
137  /* filter is from libswresample in FFmpeg */
138  for (i = 0; i < len - 2; i++)
139  src[i] = (-src[i] + 2 * src[i + 1] - src[i + 2]) * SQRT_1_6;
140 }
141 
143  int min_samples)
144 {
145  int i;
146  int nb_samples = FFALIGN(min_samples, 16) + 16;
147  int buf_samples = nb_samples *
148  (c->method == AV_RESAMPLE_DITHER_RECTANGULAR ? 1 : 2);
149  unsigned int *noise_buf_ui;
150 
151  av_freep(&state->noise_buf);
152  state->noise_buf_size = state->noise_buf_ptr = 0;
153 
154  state->noise_buf = av_malloc(buf_samples * sizeof(*state->noise_buf));
155  if (!state->noise_buf)
156  return AVERROR(ENOMEM);
157  state->noise_buf_size = FFALIGN(min_samples, 16);
158  noise_buf_ui = (unsigned int *)state->noise_buf;
159 
160  av_lfg_init(&state->lfg, state->seed);
161  for (i = 0; i < buf_samples; i++)
162  noise_buf_ui[i] = av_lfg_get(&state->lfg);
163 
164  c->ddsp.dither_int_to_float(state->noise_buf, noise_buf_ui, nb_samples);
165 
167  dither_highpass_filter(state->noise_buf, nb_samples);
168 
169  return 0;
170 }
171 
173  int16_t *dst, const float *src,
174  int nb_samples)
175 {
176  int i, j;
177  float *dither = &state->noise_buf[state->noise_buf_ptr];
178 
179  if (state->mute > c->mute_reset_threshold)
180  memset(state->dither_a, 0, sizeof(state->dither_a));
181 
182  for (i = 0; i < nb_samples; i++) {
183  float err = 0;
184  float sample = src[i] * S16_SCALE;
185 
186  for (j = 0; j < 4; j++) {
187  err += c->ns_coef_b[j] * state->dither_b[j] -
188  c->ns_coef_a[j] * state->dither_a[j];
189  }
190  for (j = 3; j > 0; j--) {
191  state->dither_a[j] = state->dither_a[j - 1];
192  state->dither_b[j] = state->dither_b[j - 1];
193  }
194  state->dither_a[0] = err;
195  sample -= err;
196 
197  if (state->mute > c->mute_dither_threshold) {
198  dst[i] = av_clip_int16(lrintf(sample));
199  state->dither_b[0] = 0;
200  } else {
201  dst[i] = av_clip_int16(lrintf(sample + dither[i]));
202  state->dither_b[0] = av_clipf(dst[i] - sample, -1.5f, 1.5f);
203  }
204 
205  state->mute++;
206  if (src[i])
207  state->mute = 0;
208  }
209 }
210 
211 static int convert_samples(DitherContext *c, int16_t **dst, float * const *src,
212  int channels, int nb_samples)
213 {
214  int ch, ret;
215  int aligned_samples = FFALIGN(nb_samples, 16);
216 
217  for (ch = 0; ch < channels; ch++) {
218  DitherState *state = &c->state[ch];
219 
220  if (state->noise_buf_size < aligned_samples) {
221  ret = generate_dither_noise(c, state, nb_samples);
222  if (ret < 0)
223  return ret;
224  } else if (state->noise_buf_size - state->noise_buf_ptr < aligned_samples) {
225  state->noise_buf_ptr = 0;
226  }
227 
229  quantize_triangular_ns(c, state, dst[ch], src[ch], nb_samples);
230  } else {
231  c->quantize(dst[ch], src[ch],
232  &state->noise_buf[state->noise_buf_ptr],
233  FFALIGN(nb_samples, c->samples_align));
234  }
235 
236  state->noise_buf_ptr += aligned_samples;
237  }
238 
239  return 0;
240 }
241 
243 {
244  int ret;
245  AudioData *flt_data;
246 
247  /* output directly to dst if it is planar */
248  if (dst->sample_fmt == AV_SAMPLE_FMT_S16P)
249  c->s16_data = dst;
250  else {
251  /* make sure s16_data is large enough for the output */
252  ret = ff_audio_data_realloc(c->s16_data, src->nb_samples);
253  if (ret < 0)
254  return ret;
255  }
256 
257  if (src->sample_fmt != AV_SAMPLE_FMT_FLTP || c->apply_map) {
258  /* make sure flt_data is large enough for the input */
259  ret = ff_audio_data_realloc(c->flt_data, src->nb_samples);
260  if (ret < 0)
261  return ret;
262  flt_data = c->flt_data;
263  }
264 
265  if (src->sample_fmt != AV_SAMPLE_FMT_FLTP) {
266  /* convert input samples to fltp and scale to s16 range */
267  ret = ff_audio_convert(c->ac_in, flt_data, src);
268  if (ret < 0)
269  return ret;
270  } else if (c->apply_map) {
271  ret = ff_audio_data_copy(flt_data, src, c->ch_map_info);
272  if (ret < 0)
273  return ret;
274  } else {
275  flt_data = src;
276  }
277 
278  /* check alignment and padding constraints */
280  int ptr_align = FFMIN(flt_data->ptr_align, c->s16_data->ptr_align);
281  int samples_align = FFMIN(flt_data->samples_align, c->s16_data->samples_align);
282  int aligned_len = FFALIGN(src->nb_samples, c->ddsp.samples_align);
283 
284  if (!(ptr_align % c->ddsp.ptr_align) && samples_align >= aligned_len) {
285  c->quantize = c->ddsp.quantize;
287  } else {
288  c->quantize = quantize_c;
289  c->samples_align = 1;
290  }
291  }
292 
293  ret = convert_samples(c, (int16_t **)c->s16_data->data,
294  (float * const *)flt_data->data, src->channels,
295  src->nb_samples);
296  if (ret < 0)
297  return ret;
298 
299  c->s16_data->nb_samples = src->nb_samples;
300 
301  /* interleave output to dst if needed */
302  if (dst->sample_fmt == AV_SAMPLE_FMT_S16) {
303  ret = ff_audio_convert(c->ac_out, dst, c->s16_data);
304  if (ret < 0)
305  return ret;
306  } else
307  c->s16_data = NULL;
308 
309  return 0;
310 }
311 
313 {
314  DitherContext *c = *cp;
315  int ch;
316 
317  if (!c)
318  return;
323  for (ch = 0; ch < c->channels; ch++)
324  av_free(c->state[ch].noise_buf);
325  av_free(c->state);
326  av_freep(cp);
327 }
328 
330  enum AVResampleDitherMethod method)
331 {
332  ddsp->quantize = quantize_c;
333  ddsp->ptr_align = 1;
334  ddsp->samples_align = 1;
335 
336  if (method == AV_RESAMPLE_DITHER_RECTANGULAR)
338  else
340 
341  if (ARCH_X86)
342  ff_dither_init_x86(ddsp, method);
343 }
344 
346  enum AVSampleFormat out_fmt,
347  enum AVSampleFormat in_fmt,
348  int channels, int sample_rate, int apply_map)
349 {
350  AVLFG seed_gen;
351  DitherContext *c;
352  int ch;
353 
355  av_get_bytes_per_sample(in_fmt) <= 2) {
356  av_log(avr, AV_LOG_ERROR, "dithering %s to %s is not supported\n",
358  return NULL;
359  }
360 
361  c = av_mallocz(sizeof(*c));
362  if (!c)
363  return NULL;
364 
365  c->apply_map = apply_map;
366  if (apply_map)
367  c->ch_map_info = &avr->ch_map_info;
368 
370  sample_rate != 48000 && sample_rate != 44100) {
371  av_log(avr, AV_LOG_WARNING, "sample rate must be 48000 or 44100 Hz "
372  "for triangular_ns dither. using triangular_hp instead.\n");
374  }
375  c->method = avr->dither_method;
376  dither_init(&c->ddsp, c->method);
377 
379  if (sample_rate == 48000) {
380  c->ns_coef_b = ns_48_coef_b;
381  c->ns_coef_a = ns_48_coef_a;
382  } else {
383  c->ns_coef_b = ns_44_coef_b;
384  c->ns_coef_a = ns_44_coef_a;
385  }
386  }
387 
388  /* Either s16 or s16p output format is allowed, but s16p is used
389  internally, so we need to use a temp buffer and interleave if the output
390  format is s16 */
391  if (out_fmt != AV_SAMPLE_FMT_S16P) {
392  c->s16_data = ff_audio_data_alloc(channels, 1024, AV_SAMPLE_FMT_S16P,
393  "dither s16 buffer");
394  if (!c->s16_data)
395  goto fail;
396 
398  channels, sample_rate, 0);
399  if (!c->ac_out)
400  goto fail;
401  }
402 
403  if (in_fmt != AV_SAMPLE_FMT_FLTP || c->apply_map) {
404  c->flt_data = ff_audio_data_alloc(channels, 1024, AV_SAMPLE_FMT_FLTP,
405  "dither flt buffer");
406  if (!c->flt_data)
407  goto fail;
408  }
409  if (in_fmt != AV_SAMPLE_FMT_FLTP) {
411  channels, sample_rate, c->apply_map);
412  if (!c->ac_in)
413  goto fail;
414  }
415 
416  c->state = av_mallocz(channels * sizeof(*c->state));
417  if (!c->state)
418  goto fail;
419  c->channels = channels;
420 
421  /* calculate thresholds for turning off dithering during periods of
422  silence to avoid replacing digital silence with quiet dither noise */
423  c->mute_dither_threshold = lrintf(sample_rate * MUTE_THRESHOLD_SEC);
425 
426  /* initialize dither states */
427  av_lfg_init(&seed_gen, 0xC0FFEE);
428  for (ch = 0; ch < channels; ch++) {
429  DitherState *state = &c->state[ch];
430  state->mute = c->mute_reset_threshold + 1;
431  state->seed = av_lfg_get(&seed_gen);
432  generate_dither_noise(c, state, FFMAX(32768, sample_rate / 2));
433  }
434 
435  return c;
436 
437 fail:
438  ff_dither_free(&c);
439  return NULL;
440 }
float * noise_buf
Definition: dither.c:47
AV_RESAMPLE_DITHER_TRIANGULAR_HP
Triangular Dither with High Pass.
Definition: avresample.h:133
Definition: lfg.h:27
float, planar
Definition: samplefmt.h:69
#define NULL
Definition: coverity.c:32
int mute
Definition: dither.c:44
void ff_dither_free(DitherContext **cp)
Free a DitherContext.
Definition: dither.c:312
int ff_audio_data_realloc(AudioData *a, int nb_samples)
Reallocate AudioData.
Definition: audio_data.c:162
static const float ns_48_coef_b[4]
Definition: dither.c:89
Audio buffer used for intermediate storage between conversion phases.
Definition: audio_data.h:37
static int generate_dither_noise(DitherContext *c, DitherState *state, int min_samples)
Definition: dither.c:142
AudioData * flt_data
Definition: dither.c:68
enum AVResampleDitherMethod method
Definition: dither.c:56
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:182
Memory handling functions.
AudioData * ff_audio_data_alloc(int channels, int nb_samples, enum AVSampleFormat sample_fmt, const char *name)
Allocate AudioData.
Definition: audio_data.c:119
#define LFG_SCALE
Definition: dither.c:85
channels
Definition: aptx.c:30
uint8_t pi<< 24) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_U8,(uint64_t)((*(const uint8_t *) pi-0x80U))<< 56) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8,(*(const uint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16,(*(const int16_t *) pi >>8)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S16,(uint64_t)(*(const int16_t *) pi)<< 48) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16,*(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32,(*(const int32_t *) pi >>24)+0x80) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_S32,(uint64_t)(*(const int32_t *) pi)<< 32) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32,*(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S64,(*(const int64_t *) pi >>56)+0x80) CONV_FUNC(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0f/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S64,*(const int64_t *) pi *(1.0/(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_FLT, llrintf(*(const float *) pi *(INT64_C(1)<< 63))) CONV_FUNC(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) CONV_FUNC(AV_SAMPLE_FMT_S64, int64_t, AV_SAMPLE_FMT_DBL, llrint(*(const double *) pi *(INT64_C(1)<< 63)))#define FMT_PAIR_FUNC(out, in) static conv_func_type *const fmt_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),};static void cpy1(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, len);}static void cpy2(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 2 *len);}static void cpy4(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 4 *len);}static void cpy8(uint8_t **dst, const uint8_t **src, int len){memcpy(*dst,*src, 8 *len);}AudioConvert *swri_audio_convert_alloc(enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, const int *ch_map, int flags){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) return NULL;ctx=av_mallocz(sizeof(*ctx));if(!ctx) return NULL;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)){case 1:ctx->simd_f=cpy1;break;case 2:ctx->simd_f=cpy2;break;case 4:ctx->simd_f=cpy4;break;case 8: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);return ctx;}void swri_audio_convert_free(AudioConvert **ctx){av_freep(ctx);}int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len){int ch;int off=0;const int os=(out->planar?1:out->ch_count)*out->bps;unsigned misaligned=0;av_assert0(ctx->channels==out->ch_count);if(ctx->in_simd_align_mask){int planes=in->planar?in->ch_count:1;unsigned m=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){int planes=out->planar?out->ch_count:1;unsigned m=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){int planes=out->planar?out->ch_count:1;for(ch=0;ch< planes;ch++){ctx->simd_f(out-> ch ch
Definition: audioconvert.c:56
static const float ns_44_coef_a[4]
Definition: dither.c:101
int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in)
Convert audio data from one sample format to another.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
#define src
Definition: vp8dsp.c:254
#define sample
unsigned int seed
Definition: dither.c:45
AudioConvert * ac_out
Definition: dither.c:71
void(* quantize)(int16_t *dst, const float *src, float *dither, int len)
Definition: dither.c:73
Macro definitions for various function/variable attributes.
static struct @315 state
int nb_samples
current number of samples
Definition: audio_data.h:43
#define SQRT_1_6
Definition: dither.c:131
#define av_cold
Definition: attributes.h:82
#define av_malloc(s)
#define S16_SCALE
Definition: dither.c:82
DitherState * state
Definition: dither.c:66
static void dither_int_to_float_rectangular_c(float *dst, int *src, int len)
Definition: dither.c:105
#define f(width, name)
Definition: cbs_vp9.c:255
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
void(* quantize)(int16_t *dst, const float *src, float *dither, int len)
Convert samples from flt to s16 with added dither noise.
Definition: dither.h:38
const float * ns_coef_a
Definition: dither.c:63
#define lrintf(x)
Definition: libm_mips.h:70
int samples_align
Definition: dither.c:74
AudioConvert * ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map)
Allocate and initialize AudioConvert context for sample format conversion.
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
static int convert_samples(DitherContext *c, int16_t **dst, float *const *src, int channels, int nb_samples)
Definition: dither.c:211
static void quantize_c(int16_t *dst, const float *src, float *dither, int len)
Definition: dither.c:124
AV_RESAMPLE_DITHER_TRIANGULAR_NS
Triangular Dither with Noise Shaping.
Definition: avresample.h:133
enum AVResampleDitherMethod dither_method
dither method
Definition: internal.h:75
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int noise_buf_size
Definition: dither.c:48
int mute_reset_threshold
Definition: dither.c:61
int ptr_align
src and dst constraints for quantize()
Definition: dither.h:40
int channels
channel count
Definition: audio_data.h:45
const char * r
Definition: vf_curves.c:114
static const uint8_t dither[8][8]
Definition: vf_fspp.c:57
int noise_buf_ptr
Definition: dither.c:49
void(* dither_int_to_float)(float *dst, int *src0, int len)
Convert dither noise from int to float with triangular distribution.
Definition: dither.h:54
void ff_audio_convert_free(AudioConvert **ac)
Free AudioConvert.
const char * av_get_sample_fmt_name(enum AVSampleFormat sample_fmt)
Return the name of sample_fmt, or NULL if sample_fmt is not recognized.
Definition: samplefmt.c:49
#define FFMAX(a, b)
Definition: common.h:94
DitherContext * ff_dither_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map)
Allocate and initialize a DitherContext.
Definition: dither.c:345
#define fail()
Definition: checkasm.h:121
int channels
Definition: dither.c:65
AudioConvert * ac_in
Definition: dither.c:70
DitherDSPContext ddsp
Definition: dither.c:55
#define FFMIN(a, b)
Definition: common.h:96
int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src)
Convert audio sample format with dithering.
Definition: dither.c:242
typedef void(APIENTRY *FF_PFNGLACTIVETEXTUREPROC)(GLenum texture)
ChannelMapInfo ch_map_info
Definition: internal.h:107
const float * ns_coef_b
Definition: dither.c:62
static const float ns_48_coef_a[4]
Definition: dither.c:93
static const float ns_44_coef_b[4]
Definition: dither.c:97
int samples_align
len constraints for quantize()
Definition: dither.h:41
int mute_dither_threshold
Definition: dither.c:60
#define src1
Definition: h264pred.c:139
sample_rate
AVSampleFormat
Audio sample formats.
Definition: samplefmt.h:58
AVLFG lfg
Definition: dither.c:46
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
Definition: audio_data.h:39
static void dither_highpass_filter(float *src, int len)
Definition: dither.c:133
enum attribute_deprecated AVResampleDitherMethod
Definition: avresample.h:132
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition: lfg.h:47
static void quantize_triangular_ns(DitherContext *c, DitherState *state, int16_t *dst, const float *src, int nb_samples)
Definition: dither.c:172
#define src0
Definition: h264pred.c:138
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:32
static void dither_int_to_float_triangular_c(float *dst, int *src0, int len)
Definition: dither.c:112
int av_get_bytes_per_sample(enum AVSampleFormat sample_fmt)
Return number of bytes per sample.
Definition: samplefmt.c:106
int samples_align
allocated samples alignment
Definition: audio_data.h:54
int ff_audio_data_copy(AudioData *dst, AudioData *src, ChannelMapInfo *map)
Copy data from one AudioData to another.
Definition: audio_data.c:225
static av_cold void dither_init(DitherDSPContext *ddsp, enum AVResampleDitherMethod method)
Definition: dither.c:329
common internal and external API header
enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt)
Get the packed alternative form of the given sample format.
Definition: samplefmt.c:75
AudioData * s16_data
Definition: dither.c:69
signed 16 bits
Definition: samplefmt.h:61
float dither_a[4]
Definition: dither.c:50
AV_RESAMPLE_DITHER_RECTANGULAR
Rectangular Dither.
Definition: avresample.h:133
int apply_map
Definition: dither.c:57
static int quantize(CinepakEncContext *s, int h, uint8_t *data[4], int linesize[4], int v1mode, strip_info *info, mb_encoding encoding)
Definition: cinepakenc.c:714
#define av_free(p)
int len
enum AVSampleFormat sample_fmt
sample format
Definition: audio_data.h:44
#define av_freep(p)
void ff_audio_data_free(AudioData **a)
Free AudioData.
Definition: audio_data.c:217
signed 16 bits, planar
Definition: samplefmt.h:67
void ff_dither_init_x86(DitherDSPContext *ddsp, enum AVResampleDitherMethod method)
Definition: dither_init.c:34
int ptr_align
minimum data pointer alignment
Definition: audio_data.h:53
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
ChannelMapInfo * ch_map_info
Definition: dither.c:58
float dither_b[4]
Definition: dither.c:51
#define MUTE_THRESHOLD_SEC
Definition: dither.c:78