wip noise gate
This commit is contained in:
parent
bcead0e0b5
commit
7e5a01f959
4 changed files with 143 additions and 4 deletions
85
gate.c
Normal file
85
gate.c
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
29
gate.h
Normal file
29
gate.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
struct gate {
|
||||||
|
float threshold;
|
||||||
|
bool enable_calibration;
|
||||||
|
|
||||||
|
unsigned block_size;
|
||||||
|
|
||||||
|
unsigned hist_idx;
|
||||||
|
unsigned hist_size;
|
||||||
|
float * hist;
|
||||||
|
|
||||||
|
unsigned cur_block_count;
|
||||||
|
float cur_block_sum;
|
||||||
|
|
||||||
|
bool is_active;
|
||||||
|
};
|
||||||
|
|
||||||
|
void gate_init();
|
||||||
|
void gate_process(
|
||||||
|
struct gate * gate,
|
||||||
|
size_t frame_size,
|
||||||
|
float const * in,
|
||||||
|
float * out
|
||||||
|
);
|
30
guitfx.c
30
guitfx.c
|
@ -15,8 +15,10 @@
|
||||||
|
|
||||||
#include "delay.h"
|
#include "delay.h"
|
||||||
#include "sust.h"
|
#include "sust.h"
|
||||||
|
#include "gate.h"
|
||||||
|
|
||||||
float envelope( float x );
|
float envelope( float x );
|
||||||
|
|
||||||
struct data;
|
struct data;
|
||||||
|
|
||||||
struct port {
|
struct port {
|
||||||
|
@ -34,6 +36,7 @@ struct data {
|
||||||
uint64_t last_tap;
|
uint64_t last_tap;
|
||||||
struct delay delay;
|
struct delay delay;
|
||||||
struct sust sust;
|
struct sust sust;
|
||||||
|
struct gate gate;
|
||||||
|
|
||||||
unsigned prog;
|
unsigned prog;
|
||||||
|
|
||||||
|
@ -100,6 +103,15 @@ static void on_process(void *userdata, struct spa_io_position *position)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x42:
|
case 0x42:
|
||||||
|
|
||||||
|
// noise gate calibration
|
||||||
|
if( data->prog == 2 ) {
|
||||||
|
if( midi_data[2] >= 64) {
|
||||||
|
data->gate.threshold = 0.0;//data->gate.cur_avg;
|
||||||
|
printf("calibrate noise gate: threshold = %f\n", data->gate.threshold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// sust pedal
|
// sust pedal
|
||||||
if( data->prog == 1 ) {
|
if( data->prog == 1 ) {
|
||||||
if( midi_data[2] >= 64) {
|
if( midi_data[2] >= 64) {
|
||||||
|
@ -133,6 +145,15 @@ static void on_process(void *userdata, struct spa_io_position *position)
|
||||||
|
|
||||||
case 0xc0:
|
case 0xc0:
|
||||||
// program change
|
// program change
|
||||||
|
if( midi_data[2] >= 64) {
|
||||||
|
sust_swap( &data->sust );
|
||||||
|
data->sust.playing = true;
|
||||||
|
|
||||||
|
data->sust.start_idx = data->sust.idx;
|
||||||
|
data->sust.idx = 0;
|
||||||
|
} else {
|
||||||
|
data->sust.playing = false;
|
||||||
|
}
|
||||||
printf("program change: %u\n", midi_data[1]);
|
printf("program change: %u\n", midi_data[1]);
|
||||||
data->prog = midi_data[1];
|
data->prog = midi_data[1];
|
||||||
break;
|
break;
|
||||||
|
@ -155,11 +176,13 @@ static void on_process(void *userdata, struct spa_io_position *position)
|
||||||
|
|
||||||
|
|
||||||
float * const in = pw_filter_get_dsp_buffer(data->guit_in_port, n_samples);
|
float * const in = pw_filter_get_dsp_buffer(data->guit_in_port, n_samples);
|
||||||
float tmp[n_samples];
|
float tmp1[n_samples];
|
||||||
|
float tmp2[n_samples];
|
||||||
float * out = pw_filter_get_dsp_buffer(data->out_port, n_samples);
|
float * out = pw_filter_get_dsp_buffer(data->out_port, n_samples);
|
||||||
if( in && out ) {
|
if( in && out ) {
|
||||||
sust_process( &data->sust, n_samples, in, tmp );
|
gate_process( &data->gate, n_samples, in, tmp1 );
|
||||||
delay_process( &data->delay, n_samples, tmp, out );
|
sust_process( &data->sust, n_samples, tmp1, tmp2 );
|
||||||
|
delay_process( &data->delay, n_samples, tmp2, out );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +201,7 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct data data = { 0, };
|
struct data data = { 0, };
|
||||||
|
|
||||||
|
gate_init( &data.gate );
|
||||||
delay_init( &data.delay );
|
delay_init( &data.delay );
|
||||||
sust_init( &data.sust );
|
sust_init( &data.sust );
|
||||||
data.prog = 0;
|
data.prog = 0;
|
||||||
|
|
|
@ -9,5 +9,6 @@ executable(
|
||||||
'guitfx.c',
|
'guitfx.c',
|
||||||
'delay.c',
|
'delay.c',
|
||||||
'sust.c',
|
'sust.c',
|
||||||
|
'gate.c',
|
||||||
dependencies : [pipewire_dep, m_dep],
|
dependencies : [pipewire_dep, m_dep],
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue