convolver: rename some fields

This commit is contained in:
Wim Taymans 2026-04-20 13:41:59 +02:00
parent d8db536d36
commit 2b96f694f7

View file

@ -18,14 +18,15 @@ struct partition {
struct convolver *conv; struct convolver *conv;
int block_size; int block_size;
int segSize; int time_size;
int segCount; int freq_size;
int fftComplexSize;
int n_segments;
float **segments; float **segments;
float **segmentsIr; float **segments_ir;
int current;
float *fft_buffer[2]; float *time_buffer[2];
void *fft; void *fft;
void *ifft; void *ifft;
@ -34,9 +35,8 @@ struct partition {
float *freq; float *freq;
float *precalc[2]; float *precalc[2];
int inputBufferFill; int block_fill;
int current;
float scale; float scale;
}; };
@ -57,8 +57,8 @@ struct convolver
bool threaded; bool threaded;
bool running; bool running;
pthread_t thread; pthread_t thread;
sem_t semStart; sem_t sem_start;
sem_t semFinish; sem_t sem_finish;
}; };
static int next_power_of_two(int val) static int next_power_of_two(int val)
@ -72,37 +72,37 @@ static int next_power_of_two(int val)
static void partition_reset(struct spa_fga_dsp *dsp, struct partition *part) static void partition_reset(struct spa_fga_dsp *dsp, struct partition *part)
{ {
int i; int i;
for (i = 0; i < part->segCount; i++) for (i = 0; i < part->n_segments; i++)
spa_fga_dsp_fft_memclear(dsp, part->segments[i], part->fftComplexSize, false); spa_fga_dsp_fft_memclear(dsp, part->segments[i], part->freq_size, false);
spa_fga_dsp_fft_memclear(dsp, part->fft_buffer[0], part->segSize, true); spa_fga_dsp_fft_memclear(dsp, part->time_buffer[0], part->time_size, true);
spa_fga_dsp_fft_memclear(dsp, part->fft_buffer[1], part->segSize, true); spa_fga_dsp_fft_memclear(dsp, part->time_buffer[1], part->time_size, true);
spa_fga_dsp_fft_memclear(dsp, part->pre_mult, part->fftComplexSize, false); spa_fga_dsp_fft_memclear(dsp, part->pre_mult, part->freq_size, false);
spa_fga_dsp_fft_memclear(dsp, part->freq, part->fftComplexSize, false); spa_fga_dsp_fft_memclear(dsp, part->freq, part->freq_size, false);
spa_fga_dsp_fft_memclear(dsp, part->precalc[0], part->segSize, true); spa_fga_dsp_fft_memclear(dsp, part->precalc[0], part->block_size, true);
spa_fga_dsp_fft_memclear(dsp, part->precalc[1], part->segSize, true); spa_fga_dsp_fft_memclear(dsp, part->precalc[1], part->block_size, true);
part->inputBufferFill = 0; part->block_fill = 0;
part->current = 0; part->current = 0;
} }
static void partition_free(struct spa_fga_dsp *dsp, struct partition *part) static void partition_free(struct spa_fga_dsp *dsp, struct partition *part)
{ {
int i; int i;
for (i = 0; i < part->segCount; i++) { for (i = 0; i < part->n_segments; i++) {
if (part->segments) if (part->segments)
spa_fga_dsp_fft_memfree(dsp, part->segments[i]); spa_fga_dsp_fft_memfree(dsp, part->segments[i]);
if (part->segmentsIr) if (part->segments_ir)
spa_fga_dsp_fft_memfree(dsp, part->segmentsIr[i]); spa_fga_dsp_fft_memfree(dsp, part->segments_ir[i]);
} }
if (part->fft) if (part->fft)
spa_fga_dsp_fft_free(dsp, part->fft); spa_fga_dsp_fft_free(dsp, part->fft);
if (part->ifft) if (part->ifft)
spa_fga_dsp_fft_free(dsp, part->ifft); spa_fga_dsp_fft_free(dsp, part->ifft);
if (part->fft_buffer[0]) if (part->time_buffer[0])
spa_fga_dsp_fft_memfree(dsp, part->fft_buffer[0]); spa_fga_dsp_fft_memfree(dsp, part->time_buffer[0]);
if (part->fft_buffer[1]) if (part->time_buffer[1])
spa_fga_dsp_fft_memfree(dsp, part->fft_buffer[1]); spa_fga_dsp_fft_memfree(dsp, part->time_buffer[1]);
free(part->segments); free(part->segments);
free(part->segmentsIr); free(part->segments_ir);
spa_fga_dsp_fft_memfree(dsp, part->pre_mult); spa_fga_dsp_fft_memfree(dsp, part->pre_mult);
spa_fga_dsp_fft_memfree(dsp, part->freq); spa_fga_dsp_fft_memfree(dsp, part->freq);
spa_fga_dsp_fft_memfree(dsp, part->precalc[0]); spa_fga_dsp_fft_memfree(dsp, part->precalc[0]);
@ -133,49 +133,50 @@ static struct partition *partition_new(struct convolver *conv, int block, const
part->block_size = next_power_of_two(block); part->block_size = next_power_of_two(block);
part->segSize = 2 * part->block_size; part->time_size = 2 * part->block_size;
part->segCount = (irlen + part->block_size-1) / part->block_size; part->n_segments = (irlen + part->block_size-1) / part->block_size;
part->fftComplexSize = (part->segSize / 2) + 1; part->freq_size = (part->time_size / 2) + 1;
part->fft = spa_fga_dsp_fft_new(dsp, part->segSize, true); part->fft = spa_fga_dsp_fft_new(dsp, part->time_size, true);
if (part->fft == NULL) if (part->fft == NULL)
goto error; goto error;
part->ifft = spa_fga_dsp_fft_new(dsp, part->segSize, true); part->ifft = spa_fga_dsp_fft_new(dsp, part->time_size, true);
if (part->ifft == NULL) if (part->ifft == NULL)
goto error; goto error;
part->fft_buffer[0] = spa_fga_dsp_fft_memalloc(dsp, part->segSize, true); part->time_buffer[0] = spa_fga_dsp_fft_memalloc(dsp, part->time_size, true);
part->fft_buffer[1] = spa_fga_dsp_fft_memalloc(dsp, part->segSize, true); part->time_buffer[1] = spa_fga_dsp_fft_memalloc(dsp, part->time_size, true);
if (part->fft_buffer[0] == NULL || part->fft_buffer[1] == NULL) if (part->time_buffer[0] == NULL || part->time_buffer[1] == NULL)
goto error; goto error;
part->segments = calloc(part->segCount, sizeof(float*)); part->segments = calloc(part->n_segments, sizeof(float*));
part->segmentsIr = calloc(part->segCount, sizeof(float*)); part->segments_ir = calloc(part->n_segments, sizeof(float*));
if (part->segments == NULL || part->segmentsIr == NULL) if (part->segments == NULL || part->segments_ir == NULL)
goto error; goto error;
for (i = 0; i < part->segCount; i++) { for (i = 0; i < part->n_segments; i++) {
int left = irlen - (i * part->block_size); int left = irlen - (i * part->block_size);
int copy = SPA_MIN(part->block_size, left); int copy = SPA_MIN(part->block_size, left);
part->segments[i] = spa_fga_dsp_fft_memalloc(dsp, part->fftComplexSize, false); part->segments[i] = spa_fga_dsp_fft_memalloc(dsp, part->freq_size, false);
part->segmentsIr[i] = spa_fga_dsp_fft_memalloc(dsp, part->fftComplexSize, false); part->segments_ir[i] = spa_fga_dsp_fft_memalloc(dsp, part->freq_size, false);
if (part->segments[i] == NULL || part->segmentsIr[i] == NULL) if (part->segments[i] == NULL || part->segments_ir[i] == NULL)
goto error; goto error;
spa_fga_dsp_copy(dsp, part->fft_buffer[0], &ir[i * part->block_size], copy); spa_fga_dsp_copy(dsp, part->time_buffer[0], &ir[i * part->block_size], copy);
if (copy < part->segSize) if (copy < part->time_size)
spa_fga_dsp_fft_memclear(dsp, part->fft_buffer[0] + copy, part->segSize - copy, true); spa_fga_dsp_fft_memclear(dsp, part->time_buffer[0] + copy, part->time_size - copy, true);
spa_fga_dsp_fft_run(dsp, part->fft, 1, part->fft_buffer[0], part->segmentsIr[i]); spa_fga_dsp_fft_run(dsp, part->fft, 1, part->time_buffer[0], part->segments_ir[i]);
} }
part->pre_mult = spa_fga_dsp_fft_memalloc(dsp, part->fftComplexSize, false); part->pre_mult = spa_fga_dsp_fft_memalloc(dsp, part->freq_size, false);
part->freq = spa_fga_dsp_fft_memalloc(dsp, part->fftComplexSize, false); part->freq = spa_fga_dsp_fft_memalloc(dsp, part->freq_size, false);
part->precalc[0] = spa_fga_dsp_fft_memalloc(dsp, part->block_size, false); part->precalc[0] = spa_fga_dsp_fft_memalloc(dsp, part->block_size, true);
part->precalc[1] = spa_fga_dsp_fft_memalloc(dsp, part->block_size, false); part->precalc[1] = spa_fga_dsp_fft_memalloc(dsp, part->block_size, true);
if (part->pre_mult == NULL || part->freq == NULL) if (part->pre_mult == NULL || part->freq == NULL ||
goto error; part->precalc[0] == NULL || part->precalc[1] == NULL)
part->scale = 1.0f / part->segSize; goto error;
part->scale = 1.0f / part->time_size;
partition_reset(dsp, part); partition_reset(dsp, part);
return part; return part;
@ -187,44 +188,44 @@ error:
static int partition_run(struct spa_fga_dsp *dsp, struct partition *part, const float *input, float *output, int len) static int partition_run(struct spa_fga_dsp *dsp, struct partition *part, const float *input, float *output, int len)
{ {
int i; int i;
int inputBufferFill = part->inputBufferFill; int block_fill = part->block_fill;
int indexAudio = part->current; int current = part->current;
spa_fga_dsp_fft_run(dsp, part->fft, 1, input, part->segments[part->current]); spa_fga_dsp_fft_run(dsp, part->fft, 1, input, part->segments[current]);
spa_fga_dsp_fft_cmul(dsp, part->fft, spa_fga_dsp_fft_cmul(dsp, part->fft,
part->freq, part->freq,
part->segments[indexAudio], part->segments[current],
part->segmentsIr[0], part->segments_ir[0],
part->fftComplexSize, part->scale); part->freq_size, part->scale);
for (i = 1; i < part->segCount; i++) { for (i = 1; i < part->n_segments; i++) {
if (++indexAudio == part->segCount) if (++current == part->n_segments)
indexAudio = 0; current = 0;
spa_fga_dsp_fft_cmuladd(dsp, part->fft, spa_fga_dsp_fft_cmuladd(dsp, part->fft,
part->freq, part->freq,
part->freq, part->freq,
part->segments[indexAudio], part->segments[current],
part->segmentsIr[i], part->segments_ir[i],
part->fftComplexSize, part->scale); part->freq_size, part->scale);
} }
spa_fga_dsp_fft_run(dsp, part->ifft, -1, part->freq, part->fft_buffer[0]); spa_fga_dsp_fft_run(dsp, part->ifft, -1, part->freq, part->time_buffer[0]);
spa_fga_dsp_sum(dsp, output, part->fft_buffer[0] + inputBufferFill, spa_fga_dsp_sum(dsp, output, part->time_buffer[0] + block_fill,
part->fft_buffer[1] + part->block_size + inputBufferFill, len); part->time_buffer[1] + part->block_size + block_fill, len);
inputBufferFill += len; block_fill += len;
if (inputBufferFill == part->block_size) { if (block_fill == part->block_size) {
inputBufferFill = 0; block_fill = 0;
SPA_SWAP(part->fft_buffer[0], part->fft_buffer[1]); SPA_SWAP(part->time_buffer[0], part->time_buffer[1]);
if (part->current == 0) if (part->current == 0)
part->current = part->segCount; part->current = part->n_segments;
part->current--; part->current--;
} }
part->inputBufferFill = inputBufferFill; part->block_fill = block_fill;
return len; return len;
} }
@ -234,14 +235,14 @@ static void *do_background_process(void *data)
struct convolver *conv = part->conv; struct convolver *conv = part->conv;
while (conv->running) { while (conv->running) {
sem_wait(&conv->semStart); sem_wait(&conv->sem_start);
if (!conv->running) if (!conv->running)
break; break;
partition_run(conv->dsp, part, conv->delay[1], part->precalc[1], part->block_size); partition_run(conv->dsp, part, conv->delay[1], part->time_buffer[1], part->block_size);
sem_post(&conv->semFinish); sem_post(&conv->sem_finish);
} }
return NULL; return NULL;
} }
@ -315,16 +316,16 @@ struct convolver *convolver_new(struct spa_fga_dsp *dsp, int head_block, int tai
if (conv->threaded) { if (conv->threaded) {
int res; int res;
sem_init(&conv->semStart, 0, 1); sem_init(&conv->sem_start, 0, 1);
sem_init(&conv->semFinish, 0, 0); sem_init(&conv->sem_finish, 0, 0);
conv->running = true; conv->running = true;
res = pthread_create(&conv->thread, NULL, res = pthread_create(&conv->thread, NULL,
do_background_process, conv); do_background_process, conv);
if (res != 0) { if (res != 0) {
conv->threaded = false; conv->threaded = false;
sem_destroy(&conv->semStart); sem_destroy(&conv->sem_start);
sem_destroy(&conv->semFinish); sem_destroy(&conv->sem_finish);
} }
} }
return conv; return conv;
@ -340,10 +341,10 @@ void convolver_free(struct convolver *conv)
if (conv->threaded) { if (conv->threaded) {
conv->running = false; conv->running = false;
sem_post(&conv->semStart); sem_post(&conv->sem_start);
pthread_join(conv->thread, NULL); pthread_join(conv->thread, NULL);
sem_destroy(&conv->semStart); sem_destroy(&conv->sem_start);
sem_destroy(&conv->semFinish); sem_destroy(&conv->sem_finish);
} }
for (i = 0; i < conv->n_partition; i++) for (i = 0; i < conv->n_partition; i++)
partition_free(dsp, conv->partition[i]); partition_free(dsp, conv->partition[i]);
@ -360,28 +361,30 @@ int convolver_run(struct convolver *conv, const float *input, float *output, int
while (processed < length) { while (processed < length) {
int remaining = length - processed; int remaining = length - processed;
int blockRemain = conv->delay_fill % conv->min_size;
int processing = SPA_MIN(remaining, conv->min_size - blockRemain);
int delay_fill = conv->delay_fill;
float *delay = conv->delay[0]; float *delay = conv->delay[0];
int delay_fill = conv->delay_fill;
struct partition *part = conv->partition[0]; struct partition *part = conv->partition[0];
int block_size = part->block_size;
int block_fill = delay_fill % block_size;
int processing = SPA_MIN(remaining, block_size - block_fill);
spa_memcpy(delay + delay_fill, input + processed, processing * sizeof(float)); spa_memcpy(delay + delay_fill, input + processed, processing * sizeof(float));
conv->delay_fill += processing; conv->delay_fill += processing;
partition_run(dsp, part, delay + delay_fill - blockRemain, &output[processed], processing); partition_run(dsp, part, delay + delay_fill - block_fill, &output[processed], processing);
for (i = 1; i < conv->n_partition; i++) { for (i = 1; i < conv->n_partition; i++) {
part = conv->partition[i]; part = conv->partition[i];
int fill = delay_fill % part->block_size; block_size = part->block_size;
block_fill = delay_fill % block_size;
spa_fga_dsp_sum(dsp, &output[processed], &output[processed], spa_fga_dsp_sum(dsp, &output[processed], &output[processed],
&part->precalc[0][fill], processing); &part->precalc[0][block_fill], processing);
if (fill + processing == part->block_size) { if (block_fill + processing == block_size) {
SPA_SWAP(part->precalc[0], part->precalc[1]); SPA_SWAP(part->precalc[0], part->precalc[1]);
partition_run(dsp, part, delay + conv->delay_fill - part->block_size, partition_run(dsp, part, delay + conv->delay_fill - block_size,
part->precalc[0], part->block_size); part->precalc[0], block_size);
} }
} }
if (conv->delay_fill == conv->max_size) { if (conv->delay_fill == conv->max_size) {