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

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
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
23
void
Jacob Vosmaer's avatar
Jacob Vosmaer committed
24
gate_on_legato(uint8_t v)
Jacob Vosmaer's avatar
Jacob Vosmaer committed
25
{
26
	if (v >= NUM_VOICES) {
Jacob Vosmaer's avatar
Jacob Vosmaer committed
27 28 29 30 31 32 33 34 35
		return;
	}

	PORTC |= _BV(v);
}

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

40
	_gate_retrig[v] = 0;
Jacob Vosmaer's avatar
Jacob Vosmaer committed
41 42
	PORTC &= ~_BV(v);
}
43 44 45 46 47 48 49 50 51 52

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

	gate_off(v);
	_gate_retrig[v] = RETRIG_DELAY;
53
	pitch_env_trigger(v);
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
}

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);
	}
}