vibrato.c 1.14 KB
Newer Older
1 2
#include "vibrato.h"
#include "dac.h"
Jacob Vosmaer's avatar
Jacob Vosmaer committed
3
#include <math.h>
4 5

static uint32_t phase;
6
static uint8_t rate;
7 8 9
static int16_t vibrato;
static uint8_t depth;

10 11 12
enum { NUM_CC = 128,
       LFO_RANGE = 8,	  // LFO rate range in octaves
       PHASE_MIN_INCR = 20000, // minimum phase increment
Jacob Vosmaer's avatar
Jacob Vosmaer committed
13 14 15 16 17 18 19 20
};

static float exp_table[NUM_CC];

void
vibrato_precompute(void)
{
	for (uint8_t i = 0; i < NUM_CC; i++) {
21 22
		exp_table[i] = (float)PHASE_MIN_INCR *
			       pow(2, ((float)i * LFO_RANGE) / (NUM_CC - 1));
Jacob Vosmaer's avatar
Jacob Vosmaer committed
23 24 25
	}
}

26 27 28
void
vibrato_set_rate(uint8_t val)
{
29
	rate = val;
30 31 32 33 34 35 36 37
}

void
vibrato_set_depth(uint8_t val)
{
	depth = val;
}

38 39 40 41 42 43
void
vibrato_init(void)
{
	vibrato_set_depth(0);
}

44 45 46 47 48 49
int16_t
vibrato_detune(void)
{
	return vibrato;
}

50
enum { VIB_MID = INT16_MAX >> 1,
Jacob Vosmaer's avatar
Jacob Vosmaer committed
51
};
52 53 54 55

void
vibrato_update(uint8_t delta)
{
56
	phase += delta * exp_table[rate];
57 58 59 60 61 62 63 64 65 66

	uint16_t phase16 = phase >> 16;
	if (phase16 < INT16_MAX) {
		vibrato = phase16 - VIB_MID;
	} else {
		vibrato = phase16 - INT16_MAX;
		vibrato = INT16_MAX - vibrato;
		vibrato -= VIB_MID;
	}

67
	float pitch_factor = dac_pitch_delta(7) / ((float)INT16_MAX);
68 69 70 71 72
	vibrato *= pitch_factor;

	float depth_factor = depth / 127.0;
	vibrato *= depth_factor;
}