guitfx/gate.c
2025-01-27 21:00:17 +01:00

85 lines
1.9 KiB
C

#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
#include "gate.h"
#include <math.h>
void gate_init(
struct gate * gate
) {
gate->threshold = 0.0;
gate->enable_calibration = false;
gate->block_size = 1024;
gate->hist_size = 256;
gate->hist_idx = 0;
gate->hist = malloc( sizeof(float) * gate->hist_size );
gate->cur_block_count = 0;
gate->cur_block_sum = 0.0;
}
void gate_process(
struct gate * gate,
size_t frame_size,
float const * in,
float * out
) {
float sum = 0.0;
int last_frame = 0;
for( size_t i = 0; i < frame_size; ++i ) {
gate->cur_block_sum += fabs( in[i] );
gate->cur_block_count += 1;
if( gate->cur_block_count >= gate->block_size ) {
printf("new block sum [%lu] (frame %lu) : %f\n", gate->hist_idx, i, gate->cur_block_sum);
if( gate->cur_block_sum > 20.0 ) {
gate->is_active = true;
} else {
gate->is_active = false;
}
gate->hist[ gate->hist_idx ] = gate->cur_block_sum;
gate->hist_idx = (gate->hist_idx + 1) % gate->hist_size;
gate->cur_block_sum = 0.0;
gate->cur_block_count = 0;
last_frame = i;
}
}
unsigned enable_pos = gate->is_active ? 0 : frame_size;
unsigned disable_pos = gate->is_active ? frame_size : 0;
unsigned blocks_per_buffer = frame_size / gate->block_size;
/* start from last block sum and iterate backwards to find
* the timepoint where a block sum crosses the threshold
*/
/*
unsigned i = gate->hist_idx;
while( last_frame > 0 ) {
if( gate->hist[ i ] < gate->threshold ) {
disable_pos = last_frame;
}
last_frame -= gate->block_size;
i -= 1;
}
*/
for( size_t i = 0; i < frame_size; ++i ) {
// if( i >= enable_pos && i < disable_pos )
if( gate->is_active )
out[i] = in[i];
else
out[i] = 0.0;
}
}