#include #include #include #include #include "gate.h" #include 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; gate->is_active = false; gate->cur_gain = 1.0; gate->attack = 1.0 / 4096.0; gate->release = 1.0 / 4096.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 = (i - 1) % gate->hist_size; } */ for( size_t i = 0; i < frame_size; ++i ) { if( gate->is_active ) { gate->cur_gain += gate->attack; if( gate->cur_gain > 1.0 ) { gate->cur_gain = 1.0; } } else { gate->cur_gain -= gate->attack; if( gate->cur_gain < 0.0 ) { gate->cur_gain = 0.0; } } out[i] = in[i] * gate->cur_gain; } }