avfilter/af_sofalizer: add fltp sample format support
authorPaul B Mahol <onemda@gmail.com>
Tue, 25 Dec 2018 21:32:05 +0000 (22:32 +0100)
committerPaul B Mahol <onemda@gmail.com>
Wed, 26 Dec 2018 09:01:06 +0000 (10:01 +0100)
libavfilter/af_sofalizer.c

index b09c6e0..3b60969 100644 (file)
@@ -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;