gate.c 935 Bytes
Newer Older
Jacob Vosmaer's avatar
Jacob Vosmaer committed
1 2 3 4
#include <avr/io.h>
#include "voice.h"
#include "gate.h"

5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
static uint8_t _gate_retrig[NUM_VOICES];

enum {
	// RETRIG_DELAY should be as low as possible to reduce MIDI latency, but
	// high enough to allow the hardware envelope generators in the CrowBX to
	// reset. I know 0x3f to be too low.
	RETRIG_DELAY = 0x5f,
};

void
gate_init(void)
{
	for_each_voice(v) {
		gate_off(v);
	}
}

Jacob Vosmaer's avatar
Jacob Vosmaer committed
22
void
Jacob Vosmaer's avatar
Jacob Vosmaer committed
23
gate_on_legato(uint8_t v)
Jacob Vosmaer's avatar
Jacob Vosmaer committed
24
{
25
	if (v >= NUM_VOICES) {
Jacob Vosmaer's avatar
Jacob Vosmaer committed
26 27 28 29 30 31 32 33 34
		return;
	}

	PORTC |= _BV(v);
}

void
gate_off(uint8_t v)
{
35
	if (v >= NUM_VOICES) {
Jacob Vosmaer's avatar
Jacob Vosmaer committed
36 37 38
		return;
	}

39
	_gate_retrig[v] = 0;
Jacob Vosmaer's avatar
Jacob Vosmaer committed
40 41
	PORTC &= ~_BV(v);
}
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

void
gate_on(uint8_t v)
{
	if (v >= NUM_VOICES) {
		return;
	}

	gate_off(v);
	_gate_retrig[v] = RETRIG_DELAY;
}

void
gate_update(uint8_t delta)
{
	for_each_voice(v) {
		if (_gate_retrig[v] == 0) {
			continue;
		}
	
		if (delta < _gate_retrig[v]) {
			_gate_retrig[v] -= delta;
			continue;
		}
	
		_gate_retrig[v] = 0;
 		gate_on_legato(v);
	}
}