74 if (ptr_align == 1 && samples_align == 1) {
82 snprintf(chan_str,
sizeof(chan_str),
"[%d to %d] ",
83 in_channels, out_channels);
85 snprintf(chan_str,
sizeof(chan_str),
"[%d to any] ",
87 }
else if (out_channels) {
88 snprintf(chan_str,
sizeof(chan_str),
"[any to %d] ",
91 snprintf(chan_str,
sizeof(chan_str),
"[any to any] ");
99 #define MIX_FUNC_NAME(fmt, cfmt) mix_any_ ## fmt ##_## cfmt ##_c 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) \ 106 stype temp[AVRESAMPLE_MAX_CHANNELS]; \ 107 for (i = 0; i < len; i++) { \ 108 for (out = 0; out < out_ch; out++) { \ 110 for (in = 0; in < in_ch; in++) \ 111 sum += samples[in][i] * matrix[out][in]; \ 114 for (out = 0; out < out_ch; out++) \ 115 samples[out][i] = temp[out]; \ 122 MIX_FUNC_GENERIC(S16P, Q8, int16_t, int16_t, int32_t, av_clip_int16(sum >> 8))
127 int out_ch,
int in_ch)
129 float *
src0 = samples[0];
130 float *
src1 = samples[1];
132 float m0 = matrix[0][0];
133 float m1 = matrix[0][1];
136 *dst++ = *src0++ * m0 + *src1++ * m1;
137 *dst++ = *src0++ * m0 + *src1++ * m1;
138 *dst++ = *src0++ * m0 + *src1++ * m1;
139 *dst++ = *src0++ * m0 + *src1++ * m1;
143 *dst++ = *src0++ * m0 + *src1++ * m1;
149 int out_ch,
int in_ch)
151 int16_t *
src0 = samples[0];
152 int16_t *
src1 = samples[1];
154 float m0 = matrix[0][0];
155 float m1 = matrix[0][1];
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));
165 *dst++ = av_clip_int16(
lrintf(*src0++ * m0 + *src1++ * m1));
171 int out_ch,
int in_ch)
173 int16_t *
src0 = samples[0];
174 int16_t *
src1 = samples[1];
176 int16_t m0 = matrix[0][0];
177 int16_t m1 = matrix[0][1];
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;
187 *dst++ = (*src0++ * m0 + *src1++ * m1) >> 8;
193 int out_ch,
int in_ch)
196 float *dst0 = samples[0];
197 float *dst1 = samples[1];
199 float m0 = matrix[0][0];
200 float m1 = matrix[1][0];
226 int out_ch,
int in_ch)
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];
237 float *m0 = matrix[0];
238 float *m1 = matrix[1];
243 *dst0++ = v0 * m0[0] +
249 *dst1++ = v0 * m1[0] +
260 int out_ch,
int in_ch)
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];
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];
311 2, 1, 1, 1,
"C", mix_2_to_1_fltp_flt_c);
374 sizeof(*matrix_dbl));
457 data0[j++] = src->
data[
i];
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); \ 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; \ 503 matrix[o * stride + i] = am->matrix_ ## suffix[o0][i0] * \ 505 if (!am->input_skip[i]) \ 508 if (!am->output_zero[o]) \ 544 if (matrix[o * stride + i] != 0.0) {
553 if (matrix[i * stride + o] != 0.0) {
562 if (o < am->in_channels)
579 if ((o != i && matrix[o * stride + i] != 0.0) ||
580 (o == i && matrix[o * stride +
i] != 1.0)) {
588 if (i0 != i && matrix[o * stride + i0] != 0.0) {
605 if (matrix[o * stride + i] != 0.0) {
627 if ((o != i && matrix[o * stride + i] != 0.0) ||
628 (o == i && matrix[o * stride +
i] != 1.0)) {
637 if (o0 != i && matrix[o0 * stride + i] != 0.0) {
655 int i, o, i0, o0,
ret;
656 char in_layout_name[128];
657 char out_layout_name[128];
675 #define CONVERT_MATRIX(type, expr) \ 676 am->matrix_## type[0] = av_mallocz(am->out_matrix_channels * \ 677 am->in_matrix_channels * \ 678 sizeof(*am->matrix_## type[0])); \ 679 if (!am->matrix_## type[0]) \ 680 return AVERROR(ENOMEM); \ 681 for (o = 0, o0 = 0; o < am->out_channels; o++) { \ 682 if (am->output_zero[o] || am->output_skip[o]) \ 685 am->matrix_## type[o0] = am->matrix_## type[o0 - 1] + \ 686 am->in_matrix_channels; \ 687 for (i = 0, i0 = 0; i < am->in_channels; i++) { \ 689 if (am->input_skip[i] || am->output_zero[i]) \ 691 v = matrix[o * stride + i]; \ 692 am->matrix_## type[o0][i0] = expr; \ 697 am->matrix = (void **)am->matrix_## type; 725 in_layout_name, out_layout_name);
#define MIX_FUNC_NAME(fmt, cfmt)
int in_channels
number of input channels
int output_skip[AVRESAMPLE_MAX_CHANNELS]
ptrdiff_t const GLvoid * data
Audio buffer used for intermediate storage between conversion phases.
double * mix_matrix
mix matrix only used if avresample_set_matrix() is called before avresample_open() ...
uint64_t out_channel_layout
output channel layout
static void mix_6_to_2_fltp_flt_c(float **samples, float **matrix, int len, int out_ch, int in_ch)
enum attribute_deprecated AVMixCoeffType
int16_t * matrix_q8[AVRESAMPLE_MAX_CHANNELS]
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
static void error(const char *err)
int ff_audio_mix(AudioMix *am, AudioData *src)
Apply channel mixing to audio data using the current mixing matrix.
int nb_samples
current number of samples
double surround_mix_level
surround mix level
enum AVMixCoeffType mix_coeff_type
mixing coefficient type
int out_channels
number of output channels
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
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.
static void mix_2_to_1_s16p_flt_c(int16_t **samples, float **matrix, int len, int out_ch, int in_ch)
int output_zero[AVRESAMPLE_MAX_CHANNELS]
int ff_audio_data_set_channels(AudioData *a, int channels)
enum AVMixCoeffType coeff_type
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
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.
double center_mix_level
center mix level
static void mix_1_to_2_fltp_flt_c(float **samples, float **matrix, int len, int out_ch, int in_ch)
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
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.
static const char *const coeff_type_names[]
uint64_t in_channel_layout
input channel layout
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 AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
void( mix_func)(uint8_t **src, void **matrix, int len, int out_ch, int in_ch)
AVSampleFormat
Audio sample formats.
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)
uint8_t * data[AVRESAMPLE_MAX_CHANNELS]
data plane pointers
void ff_audio_mix_init_x86(AudioMix *am)
#define AVRESAMPLE_MAX_CHANNELS
enum AVSampleFormat internal_sample_fmt
internal sample format
static void reduce_matrix(AudioMix *am, const double *matrix, int stride)
void ff_audio_mix_free(AudioMix **am_p)
Free an AudioMix context.
Replacements for frequently missing libm functions.
int32_t * matrix_q15[AVRESAMPLE_MAX_CHANNELS]
const char * func_descr_generic
float * matrix_flt[AVRESAMPLE_MAX_CHANNELS]
int input_skip[AVRESAMPLE_MAX_CHANNELS]
static av_cold int mix_function_init(AudioMix *am)
int samples_align
allocated samples alignment
GLint GLenum GLboolean GLsizei stride
#define GET_MATRIX_CONVERT(suffix, scale)
common internal and external API header
enum AVMatrixEncoding matrix_encoding
matrixed stereo encoding
AudioMix * ff_audio_mix_alloc(AVAudioResampleContext *avr)
Allocate and initialize an AudioMix context.
#define CONVERT_MATRIX(type, expr)
static void mix_2_to_1_s16p_q8_c(int16_t **samples, int16_t **matrix, int len, int out_ch, int in_ch)
static void mix_2_to_6_fltp_flt_c(float **samples, float **matrix, int len, int out_ch, int in_ch)
AV_MIX_COEFF_TYPE_FLT
32-bit 17.15 fixed-point
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.
Filter the word “frame” indicates either a video frame or a group of audio samples
int ptr_align
minimum data pointer alignment
AV_MIX_COEFF_TYPE_Q15
16-bit 8.8 fixed-point
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
double lfe_mix_level
lfe mix level
int ff_audio_mix_get_matrix(AudioMix *am, double *matrix, int stride)
Get the current mixing matrix.
#define MIX_FUNC_GENERIC(fmt, cfmt, stype, ctype, sumtype, expr)
AVAudioResampleContext * avr