29 #define RDFT_BITS_MIN 4 
   30 #define RDFT_BITS_MAX 16 
   54 #define NB_GAIN_ENTRY_MAX 4096 
  113 #define OFFSET(x) offsetof(FIREqualizerContext, x) 
  114 #define FLAGS AV_OPT_FLAG_AUDIO_PARAM|AV_OPT_FLAG_FILTERING_PARAM 
  214     if (nsamples <= s->nsamples_max) {
 
  215         float *
buf = conv_buf + idx->buf_idx * s->rdft_len;
 
  216         float *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx;
 
  217         int center = s->fir_len/2;
 
  220         memset(buf, 0, center * 
sizeof(*data));
 
  221         memcpy(buf + center, data, nsamples * 
sizeof(*data));
 
  222         memset(buf + center + nsamples, 0, (s->rdft_len - nsamples - center) * 
sizeof(*data));
 
  225         buf[0] *= kernel_buf[0];
 
  226         buf[1] *= kernel_buf[s->rdft_len/2];
 
  227         for (k = 1; k < s->rdft_len/2; k++) {
 
  228             buf[2*k] *= kernel_buf[k];
 
  229             buf[2*k+1] *= kernel_buf[k];
 
  233         for (k = 0; k < s->rdft_len - idx->overlap_idx; k++)
 
  235         memcpy(data, buf, nsamples * 
sizeof(*data));
 
  236         idx->buf_idx = !idx->buf_idx;
 
  237         idx->overlap_idx = nsamples;
 
  239         while (nsamples > s->nsamples_max * 2) {
 
  240             fast_convolute(s, kernel_buf, conv_buf, idx, data, s->nsamples_max);
 
  241             data += s->nsamples_max;
 
  242             nsamples -= s->nsamples_max;
 
  245         fast_convolute(s, kernel_buf, conv_buf, idx, data + nsamples/2, nsamples - nsamples/2);
 
  250                                      float *av_restrict conv_buf, 
OverlapIndex *av_restrict idx,
 
  251                                      float *av_restrict 
data, 
int nsamples)
 
  253     if (nsamples <= s->nsamples_max) {
 
  254         float *
buf = conv_buf + idx->buf_idx * s->rdft_len;
 
  255         float *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx;
 
  258         memcpy(buf, data, nsamples * 
sizeof(*data));
 
  259         memset(buf + nsamples, 0, (s->rdft_len - nsamples) * 
sizeof(*data));
 
  262         buf[0] *= kernel_buf[0];
 
  263         buf[1] *= kernel_buf[1];
 
  264         for (k = 2; k < s->rdft_len; k += 2) {
 
  266             re = buf[k] * kernel_buf[k] - buf[k+1] * kernel_buf[k+1];
 
  267             im = buf[k] * kernel_buf[k+1] + buf[k+1] * kernel_buf[k];
 
  273         for (k = 0; k < s->rdft_len - idx->overlap_idx; k++)
 
  275         memcpy(data, buf, nsamples * 
sizeof(*data));
 
  276         idx->buf_idx = !idx->buf_idx;
 
  277         idx->overlap_idx = nsamples;
 
  279         while (nsamples > s->nsamples_max * 2) {
 
  281             data += s->nsamples_max;
 
  282             nsamples -= s->nsamples_max;
 
  290                             OverlapIndex *av_restrict idx, 
float *av_restrict data0, 
float *av_restrict data1, 
int nsamples)
 
  292     if (nsamples <= s->nsamples_max) {
 
  294         FFTComplex *obuf = conv_buf + !idx->buf_idx * s->rdft_len + idx->overlap_idx;
 
  295         int center = s->fir_len/2;
 
  299         memset(buf, 0, center * 
sizeof(*buf));
 
  300         for (k = 0; k < nsamples; k++) {
 
  301             buf[center+k].
re = data0[k];
 
  302             buf[center+k].
im = data1[k];
 
  304         memset(buf + center + nsamples, 0, (s->rdft_len - nsamples - center) * 
sizeof(*buf));
 
  311         buf[0].
re = 0.5f * kernel_buf[0] * buf[0].
im;
 
  312         buf[0].
im = 0.5f * kernel_buf[0] * 
tmp;
 
  313         for (k = 1; k < s->rdft_len/2; k++) {
 
  314             int m = s->rdft_len - k;
 
  316             buf[k].
re = 0.5f * kernel_buf[k] * buf[k].
im;
 
  317             buf[k].
im = 0.5f * kernel_buf[k] * 
tmp;
 
  319             buf[m].
re = 0.5f * kernel_buf[k] * buf[m].
im;
 
  320             buf[m].
im = 0.5f * kernel_buf[k] * 
tmp;
 
  323         buf[k].
re = 0.5f * kernel_buf[k] * buf[k].
im;
 
  324         buf[k].
im = 0.5f * kernel_buf[k] * 
tmp;
 
  329         for (k = 0; k < s->rdft_len - idx->overlap_idx; k++) {
 
  330             buf[k].
re += obuf[k].
re;
 
  331             buf[k].
im += obuf[k].
im;
 
  335         for (k = 0; k < nsamples; k++) {
 
  336             data0[k] = buf[k].
im;
 
  337             data1[k] = buf[k].
re;
 
  339         idx->buf_idx = !idx->buf_idx;
 
  340         idx->overlap_idx = nsamples;
 
  342         while (nsamples > s->nsamples_max * 2) {
 
  343             fast_convolute2(s, kernel_buf, conv_buf, idx, data0, data1, s->nsamples_max);
 
  344             data0 += s->nsamples_max;
 
  345             data1 += s->nsamples_max;
 
  346             nsamples -= s->nsamples_max;
 
  348         fast_convolute2(s, kernel_buf, conv_buf, idx, data0, data1, nsamples/2);
 
  349         fast_convolute2(s, kernel_buf, conv_buf, idx, data0 + nsamples/2, data1 + nsamples/2, nsamples - nsamples/2);
 
  361     double delay = s->
zero_phase ? 0.0 : (double) center / rate;
 
  366         for (x = 1; x <= center; x++) {
 
  371         for (x = 0; x < s->
fir_len; x++)
 
  378     fprintf(fp, 
"# time[%d] (time amplitude)\n", ch);
 
  381     for (x = center; x > 0; x--)
 
  384     for (x = 0; x <= center; x++)
 
  385         fprintf(fp, 
"%15.10f %15.10f\n", delay + (
double)x / rate , (
double) s->
analysis_buf[x]);
 
  387         for (x = 0; x < s->
fir_len; x++)
 
  388             fprintf(fp, 
"%15.10f %15.10f\n", (
double)x / rate, (
double) s->
analysis_buf[x]);
 
  393     fprintf(fp, 
"\n\n# freq[%d] (frequency desired_gain actual_gain)\n", ch);
 
  405             ya = 20.0 * log10(fabs(ya));
 
  406             yb = 20.0 * log10(fabs(yb));
 
  408         fprintf(fp, 
"%17.10f %17.10f %17.10f\n", vx, ya, yb);
 
  443     const double *freq = 
key;
 
  446     if (*freq < entry[0].freq)
 
  448     if (*freq > entry[1].freq)
 
  466     if (freq <= s->gain_entry_tbl[0].freq)
 
  476     d0 = freq - res[0].
freq;
 
  477     d1 = res[1].
freq - freq;
 
  480         return (d0 * res[1].gain + d1 * res[0].gain) / d;
 
  495     double m0, m1, m2, msum, unit;
 
  500     if (freq <= s->gain_entry_tbl[0].freq)
 
  511          unit * (res[0].
gain - res[-1].
gain) / (res[0].freq - res[-1].freq) : 0;
 
  514          unit * (res[2].
gain - res[1].
gain) / (res[2].freq - res[1].freq) : 0;
 
  516     msum = fabs(m0) + fabs(m1);
 
  517     m0 = msum > 0 ? (fabs(m0) * m1 + fabs(m1) * m0) / msum : 0;
 
  518     msum = fabs(m1) + fabs(m2);
 
  519     m1 = msum > 0 ? (fabs(m1) * m2 + fabs(m2) * m1) / msum : 0;
 
  523     b = 3 * res[1].
gain - m1 - 2 * c - 3 * d;
 
  524     a = res[1].
gain - b - c - d;
 
  526     x = (freq - res[0].
freq) / unit;
 
  530     return a * x3 + b * x2 + c * x + d;
 
  556     double norm = 2.0 / cepstrum_len;
 
  557     double minval = 1e-7 / rdft_len;
 
  560     memcpy(s->
cepstrum_buf, rdft_buf, rdft_len/2 * 
sizeof(*rdft_buf));
 
  561     memcpy(s->
cepstrum_buf + cepstrum_len - rdft_len/2, rdft_buf + rdft_len/2, rdft_len/2  * 
sizeof(*rdft_buf));
 
  568     for (k = 2; k < cepstrum_len; k += 2) {
 
  576     for (k = 1; k < cepstrum_len/2; k++)
 
  583     for (k = 2; k < cepstrum_len; k += 2) {
 
  591     memset(rdft_buf, 0, s->
rdft_len * 
sizeof(*rdft_buf));
 
  605     const char *gain_entry_func_names[] = { 
"entry", 
NULL };
 
  606     const char *gain_func_names[] = { 
"gain_interpolate", 
"cubic_interpolate", 
NULL };
 
  607     double (*gain_entry_funcs[])(
void *, double, double) = { 
entry_func, 
NULL };
 
  611     int ret, k, center, 
ch;
 
  614     FILE *dump_fp = 
NULL;
 
  621                                      gain_entry_func_names, gain_entry_funcs, ctx, 0, ctx);
 
  631                         gain_func_names, gain_funcs, 
NULL, 
NULL, 0, ctx);
 
  641     for (ch = 0; ch < inlink->
channels; ch++) {
 
  650         s->
analysis_buf[0] = ylog ? pow(10.0, 0.05 * result) : result;
 
  656         s->
analysis_buf[1] = ylog ? pow(10.0, 0.05 * result) : result;
 
  673         for (k = 0; k <= center; k++) {
 
  674             double u = k * (
M_PI/center);
 
  681                 win = 0.5 + 0.5 * cos(u);
 
  684                 win = 0.53836 + 0.46164 * cos(u);
 
  687                 win = 0.42 + 0.5 * cos(u) + 0.08 * cos(2*u);
 
  690                 win = 0.40897 + 0.5 * cos(u) + 0.09103 * cos(2*u);
 
  693                 win = 0.4243801 + 0.4973406 * cos(u) + 0.0782793 * cos(2*u);
 
  696                 win = 0.355768 + 0.487396 * cos(u) + 0.144232 * cos(2*u) + 0.012604 * cos(3*u);
 
  699                 win = 0.3635819 + 0.4891775 * cos(u) + 0.1365995 * cos(2*u) + 0.0106411 * cos(3*u);
 
  702                 win = 0.35875 + 0.48829 * cos(u) + 0.14128 * cos(2*u) + 0.01168 * cos(3*u);
 
  705                 win = (u <= 0.5 * 
M_PI) ? 1.0 : (0.5 + 0.5 * cos(2*u - 
M_PI));
 
  723             if (
isnan(rdft_buf[k]) || 
isinf(rdft_buf[k])) {
 
  733             rdft_buf[s->
rdft_len-1] = rdft_buf[1];
 
  735                 rdft_buf[k] = rdft_buf[2*k];
 
  753 #define SELECT_GAIN(s) (s->gain_cmd ? s->gain_cmd : s->gain) 
  754 #define SELECT_GAIN_ENTRY(s) (s->gain_entry_cmd ? s->gain_entry_cmd : s->gain_entry) 
  789         int cepstrum_bits = rdft_bits + 2;
 
  834     av_log(ctx, 
AV_LOG_DEBUG, 
"sample_rate = %d, channels = %d, analysis_rdft_len = %d, rdft_len = %d, fir_len = %d, nsamples_max = %d.\n",
 
  856         for ( ; ch < inlink->
channels; ch++) {
 
  862         for (ch = 0; ch < inlink->
channels; ch++) {
 
  902                            char *res, 
int res_len, 
int flags)
 
  907     if (!strcmp(cmd, 
"gain")) {
 
  926     } 
else if (!strcmp(cmd, 
"gain_entry")) {
 
  927         char *gain_entry_cmd;
 
  971     .
name               = 
"firequalizer",
 
  977     .
inputs             = firequalizer_inputs,
 
  978     .
outputs            = firequalizer_outputs,
 
  979     .priv_class         = &firequalizer_class,
 
This structure describes decoded (raw) audio or video data. 
ptrdiff_t const GLvoid * data
av_cold void av_fft_end(FFTContext *s)
#define AV_LOG_WARNING
Something somehow does not look correct. 
static void common_uninit(FIREqualizerContext *s)
Main libavfilter public API header. 
static float win(SuperEqualizerContext *s, float n, int N)
int max_samples
Maximum number of samples to filter at once. 
static void generate_min_phase_kernel(FIREqualizerContext *s, float *rdft_buf)
static double gain_interpolate_func(void *p, double freq)
static int request_frame(AVFilterLink *outlink)
void av_fft_permute(FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling ff_fft_calc(). 
static int config_input(AVFilterLink *inlink)
int av_expr_parse(AVExpr **expr, const char *s, const char *const *const_names, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), int log_offset, void *log_ctx)
Parse an expression. 
#define SELECT_GAIN_ENTRY(s)
void * av_calloc(size_t nmemb, size_t size)
Non-inlined equivalent of av_mallocz_array(). 
#define NB_GAIN_ENTRY_MAX
static const AVFilterPad firequalizer_outputs[]
const char * name
Pad name. 
AVFilterLink ** inputs
array of pointers to input links 
#define av_assert0(cond)
assert() equivalent, that is always enabled. 
int ff_filter_frame(AVFilterLink *link, AVFrame *frame)
Send a frame of data to the next filter. 
static double cubic_interpolate_func(void *p, double freq)
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user). 
#define u(width, name, range_min, range_max)
static const char *const var_names[]
#define AVERROR_EOF
End of file. 
A filter pad used for either input or output. 
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers. 
A link between two filters. 
int av_expr_parse_and_eval(double *d, const char *s, const char *const *const_names, const double *const_values, const char *const *func1_names, double(*const *funcs1)(void *, double), const char *const *func2_names, double(*const *funcs2)(void *, double, double), void *opaque, int log_offset, void *log_ctx)
Parse and evaluate an expression. 
#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. 
int min_samples
Minimum number of samples to filter at once. 
int sample_rate
samples per second 
AVFrame * ff_get_audio_buffer(AVFilterLink *link, int nb_samples)
Request an audio samples buffer with a specific set of permissions. 
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
AVFILTER_DEFINE_CLASS(firequalizer)
RDFTContext * cepstrum_rdft
void * priv
private data for use by the filter 
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers. 
AVRational time_base
Define the time base used by the PTS of the frames/samples which will pass through this link...
simple assert() macros that are a bit more flexible than ISO C assert(). 
FFTContext * av_fft_init(int nbits, int inverse)
Set up a complex FFT. 
RDFTContext * cepstrum_irdft
RDFTContext * analysis_irdft
static av_cold void uninit(AVFilterContext *ctx)
static const AVOption firequalizer_options[]
void av_rdft_calc(RDFTContext *s, FFTSample *data)
static const AVFilterPad firequalizer_inputs[]
static void fast_convolute2(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, FFTComplex *av_restrict conv_buf, OverlapIndex *av_restrict idx, float *av_restrict data0, float *av_restrict data1, int nsamples)
static void fast_convolute_nonlinear(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, float *av_restrict conv_buf, OverlapIndex *av_restrict idx, float *av_restrict data, int nsamples)
void av_rdft_end(RDFTContext *s)
AVFilterContext * src
source filter 
RDFTContext * av_rdft_init(int nbits, enum RDFTransformType trans)
Set up a real FFT. 
int partial_buf_size
Size of the partial buffer to allocate. 
static const AVFilterPad inputs[]
static const AVFilterPad outputs[]
A list of supported channel layouts. 
static double entry_func(void *p, double freq, double gain)
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
static const uint8_t vars[2][12]
char * av_strdup(const char *s)
Duplicate a string. 
AVSampleFormat
Audio sample formats. 
void av_expr_free(AVExpr *e)
Free a parsed expression previously created with av_expr_parse(). 
AVFilter ff_af_firequalizer
static AVRational av_make_q(int num, int den)
Create an AVRational. 
static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags)
static void fast_convolute(FIREqualizerContext *av_restrict s, const float *av_restrict kernel_buf, float *av_restrict conv_buf, OverlapIndex *av_restrict idx, float *av_restrict data, int nsamples)
Describe the class of an AVClass context structure. 
GainEntry gain_entry_tbl[NB_GAIN_ENTRY_MAX]
const char * name
Filter name. 
AVFilterLink ** outputs
array of pointers to output links 
enum MovChannelLayoutTag * layouts
static void dump_fir(AVFilterContext *ctx, FILE *fp, int ch)
RDFTContext * analysis_rdft
uint64_t av_channel_layout_extract_channel(uint64_t channel_layout, int index)
Get the channel with the given index in channel_layout. 
static int query_formats(AVFilterContext *ctx)
static int generate_kernel(AVFilterContext *ctx, const char *gain, const char *gain_entry)
uint64_t channel_layout
channel layout of current buffer (see libavutil/channel_layout.h) 
int channels
Number of channels. 
double av_expr_eval(AVExpr *e, const double *const_values, void *opaque)
Evaluate a previously parsed expression. 
AVFilterContext * dst
dest filter 
static int filter_frame(AVFilterLink *inlink, AVFrame *frame)
static enum AVSampleFormat sample_fmts[]
#define av_malloc_array(a, b)
static int gain_entry_compare(const void *key, const void *memb)
int ff_request_frame(AVFilterLink *link)
Request an input frame from the filter at the other end of the link. 
uint8_t ** extended_data
pointers to the data planes/channels. 
void av_fft_calc(FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in av_fft_init(). 
int nb_samples
number of audio samples (per channel) described by this frame 
#define AV_NOPTS_VALUE
Undefined timestamp value. 
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
simple arithmetic expression evaluator