audio_mix.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * Libav is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 #include <stdint.h>
22 
23 #include "libavutil/common.h"
24 #include "libavutil/libm.h"
25 #include "libavutil/samplefmt.h"
26 #include "avresample.h"
27 #include "internal.h"
28 #include "audio_data.h"
29 #include "audio_mix.h"
30 
31 static const char *coeff_type_names[] = { "q8", "q15", "flt" };
32 
33 struct AudioMix {
37  uint64_t in_layout;
38  uint64_t out_layout;
41 
42  int ptr_align;
45  const char *func_descr;
46  const char *func_descr_generic;
49 
58  void **matrix;
59 };
60 
63  int out_channels, int ptr_align, int samples_align,
64  const char *descr, void *mix_func)
65 {
66  if (fmt == am->fmt && coeff_type == am->coeff_type &&
67  ( in_channels == am->in_matrix_channels || in_channels == 0) &&
68  (out_channels == am->out_matrix_channels || out_channels == 0)) {
69  char chan_str[16];
70  am->mix = mix_func;
71  am->func_descr = descr;
72  am->ptr_align = ptr_align;
74  if (ptr_align == 1 && samples_align == 1) {
75  am->mix_generic = mix_func;
76  am->func_descr_generic = descr;
77  } else {
78  am->has_optimized_func = 1;
79  }
80  if (in_channels) {
81  if (out_channels)
82  snprintf(chan_str, sizeof(chan_str), "[%d to %d] ",
83  in_channels, out_channels);
84  else
85  snprintf(chan_str, sizeof(chan_str), "[%d to any] ",
86  in_channels);
87  } else if (out_channels) {
88  snprintf(chan_str, sizeof(chan_str), "[any to %d] ",
89  out_channels);
90  } else {
91  snprintf(chan_str, sizeof(chan_str), "[any to any] ");
92  }
93  av_log(am->avr, AV_LOG_DEBUG, "audio_mix: found function: [fmt=%s] "
94  "[c=%s] %s(%s)\n", av_get_sample_fmt_name(fmt),
95  coeff_type_names[coeff_type], chan_str, descr);
96  }
97 }
98 
99 #define MIX_FUNC_NAME(fmt, cfmt) mix_any_ ## fmt ##_## cfmt ##_c
100 
101 #define MIX_FUNC_GENERIC(fmt, cfmt, stype, ctype, sumtype, expr) \
102 static void MIX_FUNC_NAME(fmt, cfmt)(stype **samples, ctype **matrix, \
103  int len, int out_ch, int in_ch) \
104 { \
105  int i, in, out; \
106  stype temp[AVRESAMPLE_MAX_CHANNELS]; \
107  for (i = 0; i < len; i++) { \
108  for (out = 0; out < out_ch; out++) { \
109  sumtype sum = 0; \
110  for (in = 0; in < in_ch; in++) \
111  sum += samples[in][i] * matrix[out][in]; \
112  temp[out] = expr; \
113  } \
114  for (out = 0; out < out_ch; out++) \
115  samples[out][i] = temp[out]; \
116  } \
117 }
118 
119 MIX_FUNC_GENERIC(FLTP, FLT, float, float, float, sum)
120 MIX_FUNC_GENERIC(S16P, FLT, int16_t, float, float, av_clip_int16(lrintf(sum)))
121 MIX_FUNC_GENERIC(S16P, Q15, int16_t, int32_t, int64_t, av_clip_int16(sum >> 15))
122 MIX_FUNC_GENERIC(S16P, Q8, int16_t, int16_t, int32_t, av_clip_int16(sum >> 8))
123 
124 /* TODO: templatize the channel-specific C functions */
125 
126 static void mix_2_to_1_fltp_flt_c(float **samples, float **matrix, int len,
127  int out_ch, int in_ch)
128 {
129  float *src0 = samples[0];
130  float *src1 = samples[1];
131  float *dst = src0;
132  float m0 = matrix[0][0];
133  float m1 = matrix[0][1];
134 
135  while (len > 4) {
136  *dst++ = *src0++ * m0 + *src1++ * m1;
137  *dst++ = *src0++ * m0 + *src1++ * m1;
138  *dst++ = *src0++ * m0 + *src1++ * m1;
139  *dst++ = *src0++ * m0 + *src1++ * m1;
140  len -= 4;
141  }
142  while (len > 0) {
143  *dst++ = *src0++ * m0 + *src1++ * m1;
144  len--;
145  }
146 }
147 
148 static void mix_2_to_1_s16p_flt_c(int16_t **samples, float **matrix, int len,
149  int out_ch, int in_ch)
150 {
151  int16_t *src0 = samples[0];
152  int16_t *src1 = samples[1];
153  int16_t *dst = src0;
154  float m0 = matrix[0][0];
155  float m1 = matrix[0][1];
156 
157  while (len > 4) {
158  *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
159  *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
160  *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
161  *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
162  len -= 4;
163  }
164  while (len > 0) {
165  *dst++ = av_clip_int16(lrintf(*src0++ * m0 + *src1++ * m1));
166  len--;
167  }
168 }
169 
170 static void mix_2_to_1_s16p_q8_c(int16_t **samples, int16_t **matrix, int len,
171  int out_ch, int in_ch)
172 {
173  int16_t *src0 = samples[0];
174  int16_t *src1 = samples[1];
175  int16_t *dst = src0;
176  int16_t m0 = matrix[0][0];
177  int16_t m1 = matrix[0][1];
178 
179  while (len > 4) {
180  *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
181  *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
182  *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
183  *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
184  len -= 4;
185  }
186  while (len > 0) {
187  *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
188  len--;
189  }
190 }
191 
192 static void mix_1_to_2_fltp_flt_c(float **samples, float **matrix, int len,
193  int out_ch, int in_ch)
194 {
195  float v;
196  float *dst0 = samples[0];
197  float *dst1 = samples[1];
198  float *src = dst0;
199  float m0 = matrix[0][0];
200  float m1 = matrix[1][0];
201 
202  while (len > 4) {
203  v = *src++;
204  *dst0++ = v * m1;
205  *dst1++ = v * m0;
206  v = *src++;
207  *dst0++ = v * m1;
208  *dst1++ = v * m0;
209  v = *src++;
210  *dst0++ = v * m1;
211  *dst1++ = v * m0;
212  v = *src++;
213  *dst0++ = v * m1;
214  *dst1++ = v * m0;
215  len -= 4;
216  }
217  while (len > 0) {
218  v = *src++;
219  *dst0++ = v * m1;
220  *dst1++ = v * m0;
221  len--;
222  }
223 }
224 
225 static void mix_6_to_2_fltp_flt_c(float **samples, float **matrix, int len,
226  int out_ch, int in_ch)
227 {
228  float v0, v1;
229  float *src0 = samples[0];
230  float *src1 = samples[1];
231  float *src2 = samples[2];
232  float *src3 = samples[3];
233  float *src4 = samples[4];
234  float *src5 = samples[5];
235  float *dst0 = src0;
236  float *dst1 = src1;
237  float *m0 = matrix[0];
238  float *m1 = matrix[1];
239 
240  while (len > 0) {
241  v0 = *src0++;
242  v1 = *src1++;
243  *dst0++ = v0 * m0[0] +
244  v1 * m0[1] +
245  *src2 * m0[2] +
246  *src3 * m0[3] +
247  *src4 * m0[4] +
248  *src5 * m0[5];
249  *dst1++ = v0 * m1[0] +
250  v1 * m1[1] +
251  *src2++ * m1[2] +
252  *src3++ * m1[3] +
253  *src4++ * m1[4] +
254  *src5++ * m1[5];
255  len--;
256  }
257 }
258 
259 static void mix_2_to_6_fltp_flt_c(float **samples, float **matrix, int len,
260  int out_ch, int in_ch)
261 {
262  float v0, v1;
263  float *dst0 = samples[0];
264  float *dst1 = samples[1];
265  float *dst2 = samples[2];
266  float *dst3 = samples[3];
267  float *dst4 = samples[4];
268  float *dst5 = samples[5];
269  float *src0 = dst0;
270  float *src1 = dst1;
271 
272  while (len > 0) {
273  v0 = *src0++;
274  v1 = *src1++;
275  *dst0++ = v0 * matrix[0][0] + v1 * matrix[0][1];
276  *dst1++ = v0 * matrix[1][0] + v1 * matrix[1][1];
277  *dst2++ = v0 * matrix[2][0] + v1 * matrix[2][1];
278  *dst3++ = v0 * matrix[3][0] + v1 * matrix[3][1];
279  *dst4++ = v0 * matrix[4][0] + v1 * matrix[4][1];
280  *dst5++ = v0 * matrix[5][0] + v1 * matrix[5][1];
281  len--;
282  }
283 }
284 
286 {
287  am->func_descr = am->func_descr_generic = "n/a";
288  am->mix = am->mix_generic = NULL;
289 
290  /* no need to set a mix function when we're skipping mixing */
291  if (!am->in_matrix_channels || !am->out_matrix_channels)
292  return 0;
293 
294  /* any-to-any C versions */
295 
297  0, 0, 1, 1, "C", MIX_FUNC_NAME(FLTP, FLT));
298 
300  0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, FLT));
301 
303  0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q15));
304 
306  0, 0, 1, 1, "C", MIX_FUNC_NAME(S16P, Q8));
307 
308  /* channel-specific C versions */
309 
311  2, 1, 1, 1, "C", mix_2_to_1_fltp_flt_c);
312 
314  2, 1, 1, 1, "C", mix_2_to_1_s16p_flt_c);
315 
317  2, 1, 1, 1, "C", mix_2_to_1_s16p_q8_c);
318 
320  1, 2, 1, 1, "C", mix_1_to_2_fltp_flt_c);
321 
323  6, 2, 1, 1, "C", mix_6_to_2_fltp_flt_c);
324 
326  2, 6, 1, 1, "C", mix_2_to_6_fltp_flt_c);
327 
328  if (ARCH_X86)
330 
331  if (!am->mix) {
332  av_log(am->avr, AV_LOG_ERROR, "audio_mix: NO FUNCTION FOUND: [fmt=%s] "
333  "[c=%s] [%d to %d]\n", av_get_sample_fmt_name(am->fmt),
335  am->out_channels);
336  return AVERROR_PATCHWELCOME;
337  }
338  return 0;
339 }
340 
342 {
343  AudioMix *am;
344  int ret;
345 
346  am = av_mallocz(sizeof(*am));
347  if (!am)
348  return NULL;
349  am->avr = avr;
350 
353  av_log(avr, AV_LOG_ERROR, "Unsupported internal format for "
354  "mixing: %s\n",
356  goto error;
357  }
358 
359  am->fmt = avr->internal_sample_fmt;
360  am->coeff_type = avr->mix_coeff_type;
361  am->in_layout = avr->in_channel_layout;
362  am->out_layout = avr->out_channel_layout;
363  am->in_channels = avr->in_channels;
364  am->out_channels = avr->out_channels;
365 
366  /* build matrix if the user did not already set one */
367  if (avr->mix_matrix) {
368  ret = ff_audio_mix_set_matrix(am, avr->mix_matrix, avr->in_channels);
369  if (ret < 0)
370  goto error;
371  av_freep(&avr->mix_matrix);
372  } else {
373  double *matrix_dbl = av_mallocz(avr->out_channels * avr->in_channels *
374  sizeof(*matrix_dbl));
375  if (!matrix_dbl)
376  goto error;
377 
379  avr->out_channel_layout,
380  avr->center_mix_level,
381  avr->surround_mix_level,
382  avr->lfe_mix_level,
383  avr->normalize_mix_level,
384  matrix_dbl,
385  avr->in_channels,
386  avr->matrix_encoding);
387  if (ret < 0) {
388  av_free(matrix_dbl);
389  goto error;
390  }
391 
392  ret = ff_audio_mix_set_matrix(am, matrix_dbl, avr->in_channels);
393  if (ret < 0) {
394  av_log(avr, AV_LOG_ERROR, "error setting mix matrix\n");
395  av_free(matrix_dbl);
396  goto error;
397  }
398 
399  av_free(matrix_dbl);
400  }
401 
402  return am;
403 
404 error:
405  av_free(am);
406  return NULL;
407 }
408 
410 {
411  AudioMix *am;
412 
413  if (!*am_p)
414  return;
415  am = *am_p;
416 
417  if (am->matrix) {
418  av_free(am->matrix[0]);
419  am->matrix = NULL;
420  }
421  memset(am->matrix_q8, 0, sizeof(am->matrix_q8 ));
422  memset(am->matrix_q15, 0, sizeof(am->matrix_q15));
423  memset(am->matrix_flt, 0, sizeof(am->matrix_flt));
424 
425  av_freep(am_p);
426 }
427 
429 {
430  int use_generic = 1;
431  int len = src->nb_samples;
432  int i, j;
433 
434  /* determine whether to use the optimized function based on pointer and
435  samples alignment in both the input and output */
436  if (am->has_optimized_func) {
437  int aligned_len = FFALIGN(len, am->samples_align);
438  if (!(src->ptr_align % am->ptr_align) &&
439  src->samples_align >= aligned_len) {
440  len = aligned_len;
441  use_generic = 0;
442  }
443  }
444  av_dlog(am->avr, "audio_mix: %d samples - %d to %d channels (%s)\n",
445  src->nb_samples, am->in_channels, am->out_channels,
446  use_generic ? am->func_descr_generic : am->func_descr);
447 
448  if (am->in_matrix_channels && am->out_matrix_channels) {
449  uint8_t **data;
451 
452  if (am->out_matrix_channels < am->out_channels ||
453  am->in_matrix_channels < am->in_channels) {
454  for (i = 0, j = 0; i < FFMAX(am->in_channels, am->out_channels); i++) {
455  if (am->input_skip[i] || am->output_skip[i] || am->output_zero[i])
456  continue;
457  data0[j++] = src->data[i];
458  }
459  data = data0;
460  } else {
461  data = src->data;
462  }
463 
464  if (use_generic)
465  am->mix_generic(data, am->matrix, len, am->out_matrix_channels,
466  am->in_matrix_channels);
467  else
468  am->mix(data, am->matrix, len, am->out_matrix_channels,
469  am->in_matrix_channels);
470  }
471 
472  if (am->out_matrix_channels < am->out_channels) {
473  for (i = 0; i < am->out_channels; i++)
474  if (am->output_zero[i])
475  av_samples_set_silence(&src->data[i], 0, len, 1, am->fmt);
476  }
477 
479 
480  return 0;
481 }
482 
484 {
485  int i, o, i0, o0;
486 
487  if ( am->in_channels <= 0 || am->in_channels > AVRESAMPLE_MAX_CHANNELS ||
489  av_log(am->avr, AV_LOG_ERROR, "Invalid channel counts\n");
490  return AVERROR(EINVAL);
491  }
492 
493 #define GET_MATRIX_CONVERT(suffix, scale) \
494  if (!am->matrix_ ## suffix[0]) { \
495  av_log(am->avr, AV_LOG_ERROR, "matrix is not set\n"); \
496  return AVERROR(EINVAL); \
497  } \
498  for (o = 0, o0 = 0; o < am->out_channels; o++) { \
499  for (i = 0, i0 = 0; i < am->in_channels; i++) { \
500  if (am->input_skip[i] || am->output_zero[o]) \
501  matrix[o * stride + i] = 0.0; \
502  else \
503  matrix[o * stride + i] = am->matrix_ ## suffix[o0][i0] * \
504  (scale); \
505  if (!am->input_skip[i]) \
506  i0++; \
507  } \
508  if (!am->output_zero[o]) \
509  o0++; \
510  }
511 
512  switch (am->coeff_type) {
514  GET_MATRIX_CONVERT(q8, 1.0 / 256.0);
515  break;
517  GET_MATRIX_CONVERT(q15, 1.0 / 32768.0);
518  break;
520  GET_MATRIX_CONVERT(flt, 1.0);
521  break;
522  default:
523  av_log(am->avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
524  return AVERROR(EINVAL);
525  }
526 
527  return 0;
528 }
529 
530 static void reduce_matrix(AudioMix *am, const double *matrix, int stride)
531 {
532  int i, o;
533 
534  memset(am->output_zero, 0, sizeof(am->output_zero));
535  memset(am->input_skip, 0, sizeof(am->input_skip));
536  memset(am->output_skip, 0, sizeof(am->output_skip));
537 
538  /* exclude output channels if they can be zeroed instead of mixed */
539  for (o = 0; o < am->out_channels; o++) {
540  int zero = 1;
541 
542  /* check if the output is always silent */
543  for (i = 0; i < am->in_channels; i++) {
544  if (matrix[o * stride + i] != 0.0) {
545  zero = 0;
546  break;
547  }
548  }
549  /* check if the corresponding input channel makes a contribution to
550  any output channel */
551  if (o < am->in_channels) {
552  for (i = 0; i < am->out_channels; i++) {
553  if (matrix[i * stride + o] != 0.0) {
554  zero = 0;
555  break;
556  }
557  }
558  }
559  if (zero) {
560  am->output_zero[o] = 1;
561  am->out_matrix_channels--;
562  }
563  }
564  if (am->out_matrix_channels == 0) {
565  am->in_matrix_channels = 0;
566  return;
567  }
568 
569  /* skip input channels that contribute fully only to the corresponding
570  output channel */
571  for (i = 0; i < FFMIN(am->in_channels, am->out_channels); i++) {
572  int skip = 1;
573 
574  for (o = 0; o < am->out_channels; o++) {
575  int i0;
576  if ((o != i && matrix[o * stride + i] != 0.0) ||
577  (o == i && matrix[o * stride + i] != 1.0)) {
578  skip = 0;
579  break;
580  }
581  /* if the input contributes fully to the output, also check that no
582  other inputs contribute to this output */
583  if (o == i) {
584  for (i0 = 0; i0 < am->in_channels; i0++) {
585  if (i0 != i && matrix[o * stride + i0] != 0.0) {
586  skip = 0;
587  break;
588  }
589  }
590  }
591  }
592  if (skip) {
593  am->input_skip[i] = 1;
594  am->in_matrix_channels--;
595  }
596  }
597  /* skip input channels that do not contribute to any output channel */
598  for (; i < am->in_channels; i++) {
599  int contrib = 0;
600 
601  for (o = 0; o < am->out_channels; o++) {
602  if (matrix[o * stride + i] != 0.0) {
603  contrib = 1;
604  break;
605  }
606  }
607  if (!contrib) {
608  am->input_skip[i] = 1;
609  am->in_matrix_channels--;
610  }
611  }
612  if (am->in_matrix_channels == 0) {
613  am->out_matrix_channels = 0;
614  return;
615  }
616 
617  /* skip output channels that only get full contribution from the
618  corresponding input channel */
619  for (o = 0; o < FFMIN(am->in_channels, am->out_channels); o++) {
620  int skip = 1;
621  int o0;
622 
623  for (i = 0; i < am->in_channels; i++) {
624  if ((o != i && matrix[o * stride + i] != 0.0) ||
625  (o == i && matrix[o * stride + i] != 1.0)) {
626  skip = 0;
627  break;
628  }
629  }
630  /* check if the corresponding input channel makes a contribution to
631  any other output channel */
632  i = o;
633  for (o0 = 0; o0 < am->out_channels; o0++) {
634  if (o0 != i && matrix[o0 * stride + i] != 0.0) {
635  skip = 0;
636  break;
637  }
638  }
639  if (skip) {
640  am->output_skip[o] = 1;
641  am->out_matrix_channels--;
642  }
643  }
644  if (am->out_matrix_channels == 0) {
645  am->in_matrix_channels = 0;
646  return;
647  }
648 }
649 
650 int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
651 {
652  int i, o, i0, o0, ret;
653  char in_layout_name[128];
654  char out_layout_name[128];
655 
656  if ( am->in_channels <= 0 || am->in_channels > AVRESAMPLE_MAX_CHANNELS ||
658  av_log(am->avr, AV_LOG_ERROR, "Invalid channel counts\n");
659  return AVERROR(EINVAL);
660  }
661 
662  if (am->matrix) {
663  av_free(am->matrix[0]);
664  am->matrix = NULL;
665  }
666 
669 
670  reduce_matrix(am, matrix, stride);
671 
672 #define CONVERT_MATRIX(type, expr) \
673  am->matrix_## type[0] = av_mallocz(am->out_matrix_channels * \
674  am->in_matrix_channels * \
675  sizeof(*am->matrix_## type[0])); \
676  if (!am->matrix_## type[0]) \
677  return AVERROR(ENOMEM); \
678  for (o = 0, o0 = 0; o < am->out_channels; o++) { \
679  if (am->output_zero[o] || am->output_skip[o]) \
680  continue; \
681  if (o0 > 0) \
682  am->matrix_## type[o0] = am->matrix_## type[o0 - 1] + \
683  am->in_matrix_channels; \
684  for (i = 0, i0 = 0; i < am->in_channels; i++) { \
685  double v; \
686  if (am->input_skip[i]) \
687  continue; \
688  v = matrix[o * stride + i]; \
689  am->matrix_## type[o0][i0] = expr; \
690  i0++; \
691  } \
692  o0++; \
693  } \
694  am->matrix = (void **)am->matrix_## type;
695 
696  if (am->in_matrix_channels && am->out_matrix_channels) {
697  switch (am->coeff_type) {
699  CONVERT_MATRIX(q8, av_clip_int16(lrint(256.0 * v)))
700  break;
702  CONVERT_MATRIX(q15, av_clipl_int32(llrint(32768.0 * v)))
703  break;
705  CONVERT_MATRIX(flt, v)
706  break;
707  default:
708  av_log(am->avr, AV_LOG_ERROR, "Invalid mix coeff type\n");
709  return AVERROR(EINVAL);
710  }
711  }
712 
713  ret = mix_function_init(am);
714  if (ret < 0)
715  return ret;
716 
717  av_get_channel_layout_string(in_layout_name, sizeof(in_layout_name),
718  am->in_channels, am->in_layout);
719  av_get_channel_layout_string(out_layout_name, sizeof(out_layout_name),
720  am->out_channels, am->out_layout);
721  av_log(am->avr, AV_LOG_DEBUG, "audio_mix: %s to %s\n",
722  in_layout_name, out_layout_name);
723  av_log(am->avr, AV_LOG_DEBUG, "matrix size: %d x %d\n",
725  for (o = 0; o < am->out_channels; o++) {
726  for (i = 0; i < am->in_channels; i++) {
727  if (am->output_zero[o])
728  av_log(am->avr, AV_LOG_DEBUG, " (ZERO)");
729  else if (am->input_skip[i] || am->output_skip[o])
730  av_log(am->avr, AV_LOG_DEBUG, " (SKIP)");
731  else
732  av_log(am->avr, AV_LOG_DEBUG, " %0.3f ",
733  matrix[o * am->in_channels + i]);
734  }
735  av_log(am->avr, AV_LOG_DEBUG, "\n");
736  }
737 
738  return 0;
739 }
#define MIX_FUNC_NAME(fmt, cfmt)
Definition: audio_mix.c:99
int in_channels
number of input channels
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
float v
int output_skip[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:54
enum AVSampleFormat fmt
Definition: audio_mix.c:35
Audio buffer used for intermediate storage between conversion phases.
Definition: oss_audio.c:46
double * mix_matrix
mix matrix only used if avresample_set_matrix() is called before avresample_open() ...
uint64_t out_channel_layout
output channel layout
uint64_t out_layout
Definition: audio_mix.c:38
static void mix_6_to_2_fltp_flt_c(float **samples, float **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.c:225
int16_t * matrix_q8[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:55
av_dlog(ac->avr,"%d samples - audio_convert: %s to %s (%s)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic?ac->func_descr_generic:ac->func_descr)
int in_channels
Definition: audio_mix.c:39
32-bit 17.15 fixed-point
Definition: avresample.h:111
int stride
Definition: mace.c:144
int ff_audio_mix(AudioMix *am, AudioData *src)
Apply channel mixing to audio data using the current mixing matrix.
Definition: audio_mix.c:428
int in_matrix_channels
Definition: audio_mix.c:50
#define FFALIGN(x, a)
Definition: common.h:63
int nb_samples
current number of samples
Definition: audio_data.h:41
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
double surround_mix_level
surround mix level
enum AVMixCoeffType mix_coeff_type
mixing coefficient type
uint8_t
int out_channels
number of output channels
int normalize_mix_level
enable mix level normalization
int ff_audio_mix_set_matrix(AudioMix *am, const double *matrix, int stride)
Set the current mixing matrix.
Definition: audio_mix.c:650
static void mix_2_to_1_s16p_flt_c(int16_t **samples, float **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.c:148
int out_channels
Definition: audio_mix.c:40
int has_optimized_func
Definition: audio_mix.c:44
#define lrintf(x)
Definition: libm_mips.h:70
int avresample_build_matrix(uint64_t in_layout, uint64_t out_layout, double center_mix_level, double surround_mix_level, double lfe_mix_level, int normalize, double *matrix_out, int stride, enum AVMatrixEncoding matrix_encoding)
Generate a channel mixing matrix.
int output_zero[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:52
float, planar
Definition: samplefmt.h:60
int ff_audio_data_set_channels(AudioData *a, int channels)
Definition: audio_data.c:51
enum AVMixCoeffType coeff_type
Definition: audio_mix.c:36
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
double center_mix_level
center mix level
#define ARCH_X86
Definition: config.h:35
static void mix_1_to_2_fltp_flt_c(float **samples, float **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.c:192
Spectrum Plot time data
#define zero
Definition: regdef.h:64
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
#define FFMAX(a, b)
Definition: common.h:56
mix_func * mix_generic
Definition: audio_mix.c:48
external API header
#define FFMIN(a, b)
Definition: common.h:58
int av_samples_set_silence(uint8_t **audio_data, int offset, int nb_samples, int nb_channels, enum AVSampleFormat sample_fmt)
Fill an audio buffer with silence.
Definition: samplefmt.c:249
ret
Definition: avfilter.c:821
int32_t
uint64_t in_channel_layout
input channel layout
const char * func_descr
Definition: audio_mix.c:45
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:47
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:62
NULL
Definition: eval.c:55
void( mix_func)(uint8_t **src, void **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.h:31
mix_func * mix
Definition: audio_mix.c:47
AVS_Value src
Definition: avisynth_c.h:523
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
Definition: audio_data.h:37
void ff_audio_mix_init_x86(AudioMix *am)
#define AVRESAMPLE_MAX_CHANNELS
Definition: avresample.h:103
enum AVSampleFormat internal_sample_fmt
internal sample format
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
static void reduce_matrix(AudioMix *am, const double *matrix, int stride)
Definition: audio_mix.c:530
static const char * coeff_type_names[]
Definition: audio_mix.c:31
#define llrint(x)
Definition: libm.h:112
void ff_audio_mix_free(AudioMix **am_p)
Free an AudioMix context.
Definition: audio_mix.c:409
Replacements for frequently missing libm functions.
int32_t * matrix_q15[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:56
synthesis window for stochastic i
const char * func_descr_generic
Definition: audio_mix.c:46
float * matrix_flt[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:57
static av_always_inline av_const long int lrint(double x)
Definition: libm.h:148
#define snprintf
Definition: snprintf.h:34
int out_matrix_channels
Definition: audio_mix.c:51
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
int input_skip[AVRESAMPLE_MAX_CHANNELS]
Definition: audio_mix.c:53
int samples_align
allocated samples alignment
Definition: audio_data.h:52
#define v0
Definition: regdef.h:26
static int mix_function_init(AudioMix *am)
Definition: audio_mix.c:285
#define GET_MATRIX_CONVERT(suffix, scale)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:162
common internal and external API header
int samples_align
Definition: audio_mix.c:43
enum AVMatrixEncoding matrix_encoding
matrixed stereo encoding
16-bit 8.8 fixed-point
Definition: avresample.h:110
AVSampleFormat
Audio Sample Formats.
Definition: samplefmt.h:49
AudioMix * ff_audio_mix_alloc(AVAudioResampleContext *avr)
Allocate and initialize an AudioMix context.
Definition: audio_mix.c:341
#define CONVERT_MATRIX(type, expr)
int ptr_align
Definition: audio_mix.c:42
AVMixCoeffType
Mixing Coefficient Types.
Definition: avresample.h:108
int len
else dst[i][x+y *dst_stride[i]]
Definition: vf_mcdeint.c:160
static void mix_2_to_1_s16p_q8_c(int16_t **samples, int16_t **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.c:170
signed 16 bits, planar
Definition: samplefmt.h:58
static void mix_2_to_6_fltp_flt_c(float **samples, float **matrix, int len, int out_ch, int in_ch)
Definition: audio_mix.c:259
void ff_audio_mix_set_func(AudioMix *am, enum AVSampleFormat fmt, enum AVMixCoeffType coeff_type, int in_channels, int out_channels, int ptr_align, int samples_align, const char *descr, void *mix_func)
Set mixing function if the parameters match.
Definition: audio_mix.c:61
Filter the word “frame” indicates either a video frame or a group of audio samples
int ptr_align
minimum data pointer alignment
Definition: audio_data.h:51
uint64_t in_layout
Definition: audio_mix.c:37
double lfe_mix_level
lfe mix level
void ** matrix
Definition: audio_mix.c:58
int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
Get the current mixing matrix.
Definition: audio_mix.c:483
void av_get_channel_layout_string(char *buf, int buf_size, int nb_channels, uint64_t channel_layout)
Return a description of a channel layout.
#define MIX_FUNC_GENERIC(fmt, cfmt, stype, ctype, sumtype, expr)
Definition: audio_mix.c:101
AVAudioResampleContext * avr
Definition: audio_mix.c:34