#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->cur_block_count = 0;
    gate->cur_block_sum = 0.0;

    gate->is_active = false;
    gate->cur_gain = 1.0;
    gate->attack = 1.0 / 512.0;
    gate->release = 1.0 / 4096.0;
}

void gate_process(
    struct gate * gate,
    size_t frame_size,
    float const * in,
    float * out
) {

  bool act = false;

    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 %f, gain = %f\n", gate->cur_block_sum, gate->cur_gain);

	  gate->last_block_sum = gate->cur_block_sum;
	  gate->cur_block_sum = 0.0;

	  if( gate->last_block_sum > 0.03 ) {
              act = true;
	  } else {
              act = false;
	  }
	}

	if( act ) {
	    gate->cur_gain += gate->attack;
	    if( gate->cur_gain > 1.0 ) {
                gate->cur_gain = 1.0;
            }
	} else {
	    gate->cur_gain -= gate->release;
	    if( gate->cur_gain < 0.0 ) {
                gate->cur_gain = 0.0;
            }
	}

        out[i] = in[i] * gate->cur_gain;
    }
}