filter-graph: remove a memcpy and some cleanups

We don't need to memcpy if we swap between 2 buffers for overlap.

Remove a duplicate variable.
This commit is contained in:
Wim Taymans 2025-06-05 11:35:32 +02:00
parent 7ef8dc4dee
commit e43324a186

View file

@ -19,14 +19,13 @@ struct convolver1 {
float **segments; float **segments;
float **segmentsIr; float **segmentsIr;
float *fft_buffer; float *fft_buffer[2];
void *fft; void *fft;
void *ifft; void *ifft;
float *pre_mult; float *pre_mult;
float *conv; float *conv;
float *overlap;
float *inputBuffer; float *inputBuffer;
int inputBufferFill; int inputBufferFill;
@ -48,7 +47,8 @@ static void convolver1_reset(struct spa_fga_dsp *dsp, struct convolver1 *conv)
int i; int i;
for (i = 0; i < conv->segCount; i++) for (i = 0; i < conv->segCount; i++)
spa_fga_dsp_fft_memclear(dsp, conv->segments[i], conv->fftComplexSize, false); spa_fga_dsp_fft_memclear(dsp, conv->segments[i], conv->fftComplexSize, false);
spa_fga_dsp_fft_memclear(dsp, conv->overlap, conv->blockSize, true); spa_fga_dsp_fft_memclear(dsp, conv->fft_buffer[0], conv->segSize, true);
spa_fga_dsp_fft_memclear(dsp, conv->fft_buffer[1], conv->segSize, true);
spa_fga_dsp_fft_memclear(dsp, conv->inputBuffer, conv->segSize, true); spa_fga_dsp_fft_memclear(dsp, conv->inputBuffer, conv->segSize, true);
spa_fga_dsp_fft_memclear(dsp, conv->pre_mult, conv->fftComplexSize, false); spa_fga_dsp_fft_memclear(dsp, conv->pre_mult, conv->fftComplexSize, false);
spa_fga_dsp_fft_memclear(dsp, conv->conv, conv->fftComplexSize, false); spa_fga_dsp_fft_memclear(dsp, conv->conv, conv->fftComplexSize, false);
@ -69,13 +69,14 @@ static void convolver1_free(struct spa_fga_dsp *dsp, struct convolver1 *conv)
spa_fga_dsp_fft_free(dsp, conv->fft); spa_fga_dsp_fft_free(dsp, conv->fft);
if (conv->ifft) if (conv->ifft)
spa_fga_dsp_fft_free(dsp, conv->ifft); spa_fga_dsp_fft_free(dsp, conv->ifft);
if (conv->fft_buffer) if (conv->fft_buffer[0])
spa_fga_dsp_fft_memfree(dsp, conv->fft_buffer); spa_fga_dsp_fft_memfree(dsp, conv->fft_buffer[0]);
if (conv->fft_buffer[1])
spa_fga_dsp_fft_memfree(dsp, conv->fft_buffer[1]);
free(conv->segments); free(conv->segments);
free(conv->segmentsIr); free(conv->segmentsIr);
spa_fga_dsp_fft_memfree(dsp, conv->pre_mult); spa_fga_dsp_fft_memfree(dsp, conv->pre_mult);
spa_fga_dsp_fft_memfree(dsp, conv->conv); spa_fga_dsp_fft_memfree(dsp, conv->conv);
spa_fga_dsp_fft_memfree(dsp, conv->overlap);
spa_fga_dsp_fft_memfree(dsp, conv->inputBuffer); spa_fga_dsp_fft_memfree(dsp, conv->inputBuffer);
free(conv); free(conv);
} }
@ -110,8 +111,9 @@ static struct convolver1 *convolver1_new(struct spa_fga_dsp *dsp, int block, con
if (conv->ifft == NULL) if (conv->ifft == NULL)
goto error; goto error;
conv->fft_buffer = spa_fga_dsp_fft_memalloc(dsp, conv->segSize, true); conv->fft_buffer[0] = spa_fga_dsp_fft_memalloc(dsp, conv->segSize, true);
if (conv->fft_buffer == NULL) conv->fft_buffer[1] = spa_fga_dsp_fft_memalloc(dsp, conv->segSize, true);
if (conv->fft_buffer[0] == NULL || conv->fft_buffer[1] == NULL)
goto error; goto error;
conv->segments = calloc(conv->segCount, sizeof(float*)); conv->segments = calloc(conv->segCount, sizeof(float*));
@ -128,18 +130,16 @@ static struct convolver1 *convolver1_new(struct spa_fga_dsp *dsp, int block, con
if (conv->segments[i] == NULL || conv->segmentsIr[i] == NULL) if (conv->segments[i] == NULL || conv->segmentsIr[i] == NULL)
goto error; goto error;
spa_fga_dsp_copy(dsp, conv->fft_buffer, &ir[i * conv->blockSize], copy); spa_fga_dsp_copy(dsp, conv->fft_buffer[0], &ir[i * conv->blockSize], copy);
if (copy < conv->segSize) if (copy < conv->segSize)
spa_fga_dsp_fft_memclear(dsp, conv->fft_buffer + copy, conv->segSize - copy, true); spa_fga_dsp_fft_memclear(dsp, conv->fft_buffer[0] + copy, conv->segSize - copy, true);
spa_fga_dsp_fft_run(dsp, conv->fft, 1, conv->fft_buffer, conv->segmentsIr[i]); spa_fga_dsp_fft_run(dsp, conv->fft, 1, conv->fft_buffer[0], conv->segmentsIr[i]);
} }
conv->pre_mult = spa_fga_dsp_fft_memalloc(dsp, conv->fftComplexSize, false); conv->pre_mult = spa_fga_dsp_fft_memalloc(dsp, conv->fftComplexSize, false);
conv->conv = spa_fga_dsp_fft_memalloc(dsp, conv->fftComplexSize, false); conv->conv = spa_fga_dsp_fft_memalloc(dsp, conv->fftComplexSize, false);
conv->overlap = spa_fga_dsp_fft_memalloc(dsp, conv->blockSize, true);
conv->inputBuffer = spa_fga_dsp_fft_memalloc(dsp, conv->segSize, true); conv->inputBuffer = spa_fga_dsp_fft_memalloc(dsp, conv->segSize, true);
if (conv->pre_mult == NULL || conv->conv == NULL || conv->overlap == NULL || if (conv->pre_mult == NULL || conv->conv == NULL || conv->inputBuffer == NULL)
conv->inputBuffer == NULL)
goto error; goto error;
conv->scale = 1.0f / conv->segSize; conv->scale = 1.0f / conv->segSize;
convolver1_reset(dsp, conv); convolver1_reset(dsp, conv);
@ -159,18 +159,18 @@ static int convolver1_run(struct spa_fga_dsp *dsp, struct convolver1 *conv, cons
return len; return len;
} }
int inputBufferFill = conv->inputBufferFill;
while (processed < len) { while (processed < len) {
const int processing = SPA_MIN(len - processed, conv->blockSize - conv->inputBufferFill); const int processing = SPA_MIN(len - processed, conv->blockSize - inputBufferFill);
const int inputBufferPos = conv->inputBufferFill;
spa_fga_dsp_copy(dsp, conv->inputBuffer + inputBufferPos, input + processed, processing);
if (inputBufferPos == 0 && processing < conv->blockSize)
spa_fga_dsp_fft_memclear(dsp, conv->inputBuffer + processing, conv->blockSize - processing, true);
spa_fga_dsp_copy(dsp, conv->inputBuffer + inputBufferFill, input + processed, processing);
if (inputBufferFill == 0 && processing < conv->blockSize)
spa_fga_dsp_fft_memclear(dsp, conv->inputBuffer + processing,
conv->blockSize - processing, true);
spa_fga_dsp_fft_run(dsp, conv->fft, 1, conv->inputBuffer, conv->segments[conv->current]); spa_fga_dsp_fft_run(dsp, conv->fft, 1, conv->inputBuffer, conv->segments[conv->current]);
if (conv->segCount > 1) { if (conv->segCount > 1) {
if (conv->inputBufferFill == 0) { if (inputBufferFill == 0) {
int indexAudio = (conv->current + 1) % conv->segCount; int indexAudio = (conv->current + 1) % conv->segCount;
spa_fga_dsp_fft_cmul(dsp, conv->fft, conv->pre_mult, spa_fga_dsp_fft_cmul(dsp, conv->fft, conv->pre_mult,
@ -203,22 +203,23 @@ static int convolver1_run(struct spa_fga_dsp *dsp, struct convolver1 *conv, cons
conv->fftComplexSize, conv->scale); conv->fftComplexSize, conv->scale);
} }
spa_fga_dsp_fft_run(dsp, conv->ifft, -1, conv->conv, conv->fft_buffer); spa_fga_dsp_fft_run(dsp, conv->ifft, -1, conv->conv, conv->fft_buffer[0]);
spa_fga_dsp_sum(dsp, output + processed, conv->fft_buffer + inputBufferPos, spa_fga_dsp_sum(dsp, output + processed, conv->fft_buffer[0] + inputBufferFill,
conv->overlap + inputBufferPos, processing); conv->fft_buffer[1] + conv->blockSize + inputBufferFill, processing);
conv->inputBufferFill += processing; inputBufferFill += processing;
if (conv->inputBufferFill == conv->blockSize) { if (inputBufferFill == conv->blockSize) {
conv->inputBufferFill = 0; inputBufferFill = 0;
spa_fga_dsp_copy(dsp, conv->overlap, conv->fft_buffer + conv->blockSize, conv->blockSize); SPA_SWAP(conv->fft_buffer[0], conv->fft_buffer[1]);
conv->current = (conv->current > 0) ? (conv->current - 1) : (conv->segCount - 1); conv->current = (conv->current > 0) ? (conv->current - 1) : (conv->segCount - 1);
} }
processed += processing; processed += processing;
} }
conv->inputBufferFill = inputBufferFill;
return len; return len;
} }
@ -236,7 +237,6 @@ struct convolver
float *tailPrecalculated; float *tailPrecalculated;
float *tailInput; float *tailInput;
int tailInputFill; int tailInputFill;
int precalculatedPos;
}; };
void convolver_reset(struct convolver *conv) void convolver_reset(struct convolver *conv)
@ -256,7 +256,6 @@ void convolver_reset(struct convolver *conv)
spa_fga_dsp_fft_memclear(dsp, conv->tailPrecalculated, conv->tailBlockSize, true); spa_fga_dsp_fft_memclear(dsp, conv->tailPrecalculated, conv->tailBlockSize, true);
} }
conv->tailInputFill = 0; conv->tailInputFill = 0;
conv->precalculatedPos = 0;
} }
struct convolver *convolver_new(struct spa_fga_dsp *dsp, int head_block, int tail_block, const float *ir, int irlen) struct convolver *convolver_new(struct spa_fga_dsp *dsp, int head_block, int tail_block, const float *ir, int irlen)
@ -358,13 +357,12 @@ int convolver_run(struct convolver *conv, const float *input, float *output, int
if (conv->tailPrecalculated0) if (conv->tailPrecalculated0)
spa_fga_dsp_sum(dsp, &output[processed], &output[processed], spa_fga_dsp_sum(dsp, &output[processed], &output[processed],
&conv->tailPrecalculated0[conv->precalculatedPos], &conv->tailPrecalculated0[conv->tailInputFill],
processing); processing);
if (conv->tailPrecalculated) if (conv->tailPrecalculated)
spa_fga_dsp_sum(dsp, &output[processed], &output[processed], spa_fga_dsp_sum(dsp, &output[processed], &output[processed],
&conv->tailPrecalculated[conv->precalculatedPos], &conv->tailPrecalculated[conv->tailInputFill],
processing); processing);
conv->precalculatedPos += processing;
spa_fga_dsp_copy(dsp, conv->tailInput + conv->tailInputFill, input + processed, processing); spa_fga_dsp_copy(dsp, conv->tailInput + conv->tailInputFill, input + processed, processing);
conv->tailInputFill += processing; conv->tailInputFill += processing;
@ -385,10 +383,9 @@ int convolver_run(struct convolver *conv, const float *input, float *output, int
convolver1_run(dsp, conv->tailConvolver, conv->tailInput, convolver1_run(dsp, conv->tailConvolver, conv->tailInput,
conv->tailOutput, conv->tailBlockSize); conv->tailOutput, conv->tailBlockSize);
} }
if (conv->tailInputFill == conv->tailBlockSize) { if (conv->tailInputFill == conv->tailBlockSize)
conv->tailInputFill = 0; conv->tailInputFill = 0;
conv->precalculatedPos = 0;
}
processed += processing; processed += processing;
} }
} }