pitch.c 1.57 KB
Newer Older
1 2 3 4
#include "pitch.h"
#include "voice.h"
#include "dac.h"
#include "safe_add.h"
5
#include <math.h>
6

7
static uint16_t _decay_counter[NUM_VOICES];
8 9 10 11
static uint16_t _env_delta[NUM_VOICES];

static uint8_t _env_decay;
static uint8_t _env_amount;
12 13 14

enum { DECAY_SCALE = 10000 };

15 16 17 18 19 20
void
pitch_init(void)
{
	for_each_voice(v) {
		_decay_counter[v] = 0;
	}
21 22
	_env_decay = 0;
	_env_amount = 0;
23 24
}

25 26 27 28 29 30 31 32
void
pitch_set_note(uint8_t voice, uint8_t note, int16_t detune, uint16_t bend)
{
	if ((voice >= NUM_VOICES) || (note > 127)) {
		return;
	}

	uint16_t data = dac_note_pitch(voice, note);
33

34
	data = safe_add(data, detune);
35
	data = safe_add(data, _env_delta[voice]);
36 37 38 39 40 41 42

	float bend_factor = ((int16_t) (bend & BEND_MAX) - BEND_CENTER) / ((float) BEND_MAX);
	int16_t bend_data = dac_pitch_delta(4) * bend_factor;
	data = safe_add(data, bend_data);

	dac_send(dac_command_set(voice), data);
}
43 44 45 46

void
pitch_update_clock(uint8_t delta)
{
47 48 49 50
	if (delta == 0) {
		return;
	}

51 52 53
	for_each_voice(v) {
		if (_decay_counter[v] <= delta) {
			_decay_counter[v] = 0;
54
			_env_delta[v] = 0;
55 56 57 58
			continue;
		}

		_decay_counter[v] = _decay_counter[v] - delta;
59
		_env_delta[v] = -log((DECAY_SCALE - _decay_counter[v] + 1) / ((float) DECAY_SCALE)) * (_env_amount / 127.0) * dac_pitch_delta(5);
60 61 62 63
	}
}

void
64
pitch_env_set_decay(uint8_t decay)
65 66 67 68 69
{
	if (decay > 127) {
		decay = 127;
	}

70 71 72 73 74 75 76 77 78 79 80
	_env_decay = decay;
}

void
pitch_env_set_amount(uint8_t amount)
{
	if (amount > 127) {
		amount = 127;
	}

	_env_amount = amount;
81 82 83
}

void
84
pitch_env_trigger(uint8_t voice)
85 86 87 88 89
{
	if (voice >= NUM_VOICES) {
		return;
	}

90
	_decay_counter[voice] = (_env_decay/127.0) * DECAY_SCALE;
91
}