mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-02-21 14:26:59 +00:00
avfilter/af_sofalizer: add fltp sample format support
This commit is contained in:
parent
70c86deb8e
commit
530fc345ec
@ -340,8 +340,10 @@ static int sofalizer_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n
|
||||
float *temp_src = td->temp_src[jobnr];
|
||||
const int ir_samples = s->sofa.ir_samples; /* length of one IR */
|
||||
const int n_samples = s->sofa.n_samples;
|
||||
const float *src = (const float *)in->data[0]; /* get pointer to audio input buffer */
|
||||
float *dst = (float *)out->data[0]; /* get pointer to audio output buffer */
|
||||
const int planar = in->format == AV_SAMPLE_FMT_FLTP;
|
||||
const int mult = 1 + !planar;
|
||||
const float *src = (const float *)in->extended_data[0]; /* get pointer to audio input buffer */
|
||||
float *dst = (float *)out->extended_data[jobnr * planar]; /* get pointer to audio output buffer */
|
||||
const int in_channels = s->n_conv; /* number of input channels */
|
||||
/* ring buffer length is: longest IR plus max. delay -> next power of 2 */
|
||||
const int buffer_length = s->buffer_length;
|
||||
@ -352,7 +354,9 @@ static int sofalizer_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n
|
||||
int read;
|
||||
int i, l;
|
||||
|
||||
dst += offset;
|
||||
if (!planar)
|
||||
dst += offset;
|
||||
|
||||
for (l = 0; l < in_channels; l++) {
|
||||
/* get starting address of ringbuffer for each input channel */
|
||||
buffer[l] = ringbuffer + l * buffer_length;
|
||||
@ -362,9 +366,18 @@ static int sofalizer_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n
|
||||
const float *temp_ir = ir; /* using same set of IRs for each sample */
|
||||
|
||||
dst[0] = 0;
|
||||
for (l = 0; l < in_channels; l++) {
|
||||
/* write current input sample to ringbuffer (for each channel) */
|
||||
buffer[l][wr] = src[l];
|
||||
if (planar) {
|
||||
for (l = 0; l < in_channels; l++) {
|
||||
const float *srcp = (const float *)in->extended_data[l];
|
||||
|
||||
/* write current input sample to ringbuffer (for each channel) */
|
||||
buffer[l][wr] = srcp[i];
|
||||
}
|
||||
} else {
|
||||
for (l = 0; l < in_channels; l++) {
|
||||
/* write current input sample to ringbuffer (for each channel) */
|
||||
buffer[l][wr] = src[l];
|
||||
}
|
||||
}
|
||||
|
||||
/* loop goes through all channels to be convolved */
|
||||
@ -374,7 +387,7 @@ static int sofalizer_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n
|
||||
if (l == s->lfe_channel) {
|
||||
/* LFE is an input channel but requires no convolution */
|
||||
/* apply gain to LFE signal and add to output buffer */
|
||||
*dst += *(buffer[s->lfe_channel] + wr) * s->gain_lfe;
|
||||
dst[0] += *(buffer[s->lfe_channel] + wr) * s->gain_lfe;
|
||||
temp_ir += n_samples;
|
||||
continue;
|
||||
}
|
||||
@ -403,7 +416,7 @@ static int sofalizer_convolute(AVFilterContext *ctx, void *arg, int jobnr, int n
|
||||
n_clippings[0]++;
|
||||
|
||||
/* move output buffer pointer by +2 to get to next sample of processed channel: */
|
||||
dst += 2;
|
||||
dst += mult;
|
||||
src += in_channels;
|
||||
wr = (wr + 1) & modulo; /* update ringbuffer write position */
|
||||
}
|
||||
@ -424,8 +437,9 @@ static int sofalizer_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr,
|
||||
int *n_clippings = &td->n_clippings[jobnr];
|
||||
float *ringbuffer = td->ringbuffer[jobnr];
|
||||
const int n_samples = s->sofa.n_samples; /* length of one IR */
|
||||
const float *src = (const float *)in->data[0]; /* get pointer to audio input buffer */
|
||||
float *dst = (float *)out->data[0]; /* get pointer to audio output buffer */
|
||||
const int planar = in->format == AV_SAMPLE_FMT_FLTP;
|
||||
const int mult = 1 + !planar;
|
||||
float *dst = (float *)out->extended_data[jobnr * planar]; /* get pointer to audio output buffer */
|
||||
const int in_channels = s->n_conv; /* number of input channels */
|
||||
/* ring buffer length is: longest IR plus max. delay -> next power of 2 */
|
||||
const int buffer_length = s->buffer_length;
|
||||
@ -443,14 +457,15 @@ static int sofalizer_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr,
|
||||
int n_read;
|
||||
int i, j;
|
||||
|
||||
dst += offset;
|
||||
if (!planar)
|
||||
dst += offset;
|
||||
|
||||
/* find minimum between number of samples and output buffer length:
|
||||
* (important, if one IR is longer than the output buffer) */
|
||||
n_read = FFMIN(s->sofa.n_samples, in->nb_samples);
|
||||
for (j = 0; j < n_read; j++) {
|
||||
/* initialize output buf with saved signal from overflow buf */
|
||||
dst[2 * j] = ringbuffer[wr];
|
||||
dst[mult * j] = ringbuffer[wr];
|
||||
ringbuffer[wr] = 0.0; /* re-set read samples to zero */
|
||||
/* update ringbuffer read/write position */
|
||||
wr = (wr + 1) & modulo;
|
||||
@ -458,17 +473,26 @@ static int sofalizer_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr,
|
||||
|
||||
/* initialize rest of output buffer with 0 */
|
||||
for (j = n_read; j < in->nb_samples; j++) {
|
||||
dst[2 * j] = 0;
|
||||
dst[mult * j] = 0;
|
||||
}
|
||||
|
||||
/* fill FFT accumulation with 0 */
|
||||
memset(fft_acc, 0, sizeof(FFTComplex) * n_fft);
|
||||
|
||||
for (i = 0; i < n_conv; i++) {
|
||||
const float *src = (const float *)in->extended_data[i * planar]; /* get pointer to audio input buffer */
|
||||
|
||||
if (i == s->lfe_channel) { /* LFE */
|
||||
for (j = 0; j < in->nb_samples; j++) {
|
||||
/* apply gain to LFE signal and add to output buffer */
|
||||
dst[2 * j] += src[i + j * in_channels] * s->gain_lfe;
|
||||
if (in->format == AV_SAMPLE_FMT_FLT) {
|
||||
for (j = 0; j < in->nb_samples; j++) {
|
||||
/* apply gain to LFE signal and add to output buffer */
|
||||
dst[2 * j] += src[i + j * in_channels] * s->gain_lfe;
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < in->nb_samples; j++) {
|
||||
/* apply gain to LFE signal and add to output buffer */
|
||||
dst[j] += src[j] * s->gain_lfe;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@ -480,10 +504,18 @@ static int sofalizer_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr,
|
||||
/* fill FFT input with 0 (we want to zero-pad) */
|
||||
memset(fft_in, 0, sizeof(FFTComplex) * n_fft);
|
||||
|
||||
for (j = 0; j < in->nb_samples; j++) {
|
||||
/* prepare input for FFT */
|
||||
/* write all samples of current input channel to FFT input array */
|
||||
fft_in[j].re = src[j * in_channels + i];
|
||||
if (in->format == AV_SAMPLE_FMT_FLT) {
|
||||
for (j = 0; j < in->nb_samples; j++) {
|
||||
/* prepare input for FFT */
|
||||
/* write all samples of current input channel to FFT input array */
|
||||
fft_in[j].re = src[j * in_channels + i];
|
||||
}
|
||||
} else {
|
||||
for (j = 0; j < in->nb_samples; j++) {
|
||||
/* prepare input for FFT */
|
||||
/* write all samples of current input channel to FFT input array */
|
||||
fft_in[j].re = src[j];
|
||||
}
|
||||
}
|
||||
|
||||
/* transform input signal of current channel to frequency domain */
|
||||
@ -508,7 +540,7 @@ static int sofalizer_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr,
|
||||
|
||||
for (j = 0; j < in->nb_samples; j++) {
|
||||
/* write output signal of current channel to output buffer */
|
||||
dst[2 * j] += fft_acc[j].re * fft_scale;
|
||||
dst[mult * j] += fft_acc[j].re * fft_scale;
|
||||
}
|
||||
|
||||
for (j = 0; j < n_samples - 1; j++) { /* overflow length is IR length - 1 */
|
||||
@ -521,12 +553,9 @@ static int sofalizer_fast_convolute(AVFilterContext *ctx, void *arg, int jobnr,
|
||||
/* go through all samples of current output buffer: count clippings */
|
||||
for (i = 0; i < out->nb_samples; i++) {
|
||||
/* clippings counter */
|
||||
if (fabsf(dst[0]) > 1) { /* if current output sample > 1 */
|
||||
if (fabsf(dst[i * mult]) > 1) { /* if current output sample > 1 */
|
||||
n_clippings[0]++;
|
||||
}
|
||||
|
||||
/* move output buffer pointer by +2 to get to next sample of processed channel: */
|
||||
dst += 2;
|
||||
}
|
||||
|
||||
/* remember read/write position in ringbuffer for next call */
|
||||
@ -580,10 +609,14 @@ static int query_formats(AVFilterContext *ctx)
|
||||
AVFilterFormats *formats = NULL;
|
||||
AVFilterChannelLayouts *layouts = NULL;
|
||||
int ret, sample_rates[] = { 48000, -1 };
|
||||
static const enum AVSampleFormat sample_fmts[] = {
|
||||
AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP,
|
||||
AV_SAMPLE_FMT_NONE
|
||||
};
|
||||
|
||||
ret = ff_add_format(&formats, AV_SAMPLE_FMT_FLT);
|
||||
if (ret)
|
||||
return ret;
|
||||
formats = ff_make_format_list(sample_fmts);
|
||||
if (!formats)
|
||||
return AVERROR(ENOMEM);
|
||||
ret = ff_set_common_formats(ctx, formats);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user