Commit d698dec1 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Negative exponential pitch envelope

parent 1f8d5350
......@@ -8,3 +8,5 @@
midi-test
list-test
avrdude_port
pitch_env-plot.dat
pitch_env-plot
PRG = crowbx
OBJ = crowbx.o midi.o dac.o uart.o gate.o poly.o mono.o list.o vibrato.o poly2.o poly_voice.o safe_add.o pitch.o buffer.o
OBJ = crowbx.o midi.o dac.o uart.o gate.o poly.o mono.o list.o vibrato.o poly2.o poly_voice.o safe_add.o pitch.o buffer.o pitch_env.o
MCU_TARGET = atmega328p
OPTIMIZE = -O3
......@@ -32,6 +32,11 @@ test:
$(TESTCC) -o list-test list-test.c list.c
./list-test
plot:
$(TESTCC) -o pitch_env-plot pitch_env-plot.c pitch_env.c
./pitch_env-plot > pitch_env-plot.dat
gnuplot -e "plot 'pitch_env-plot.dat'"
clean:
rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak
rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)
......
......@@ -5,6 +5,7 @@
#include "midi.h"
#include "mono.h"
#include "pitch.h"
#include "pitch_env.h"
#include "poly.h"
#include "poly2.h"
#include "vibrato.h"
......
#include "pitch.h"
#include "dac.h"
#include "pitch_env.h"
#include "safe_add.h"
#include "voice.h"
#include <math.h>
......@@ -10,22 +11,9 @@ enum { BEND_CENTER = 8192,
static uint16_t _bend = BEND_CENTER;
static uint16_t _decay_counter[NUM_VOICES];
static uint16_t _env_delta[NUM_VOICES];
static uint8_t _env_decay;
static uint8_t _env_amount;
enum { DECAY_SCALE = 10000 };
void
pitch_init(void)
{
for_each_voice (v) {
_decay_counter[v] = 0;
}
_env_decay = 0;
_env_amount = 0;
}
void
......@@ -38,7 +26,8 @@ pitch_set_note(uint8_t voice, uint8_t note, int16_t detune)
uint16_t data = dac_note_pitch(voice, note);
data = safe_add(data, detune);
data = safe_add(data, _env_delta[voice]);
data =
safe_add(data, pitch_env_delta(voice) * (float)dac_pitch_delta(5));
float bend_factor =
((int16_t)(_bend & BEND_MAX) - BEND_CENTER) / ((float)BEND_MAX);
......@@ -57,46 +46,5 @@ pitch_set_bend(uint16_t bend)
void
pitch_update_clock(uint8_t delta)
{
for_each_voice (v) {
if (_decay_counter[v] <= delta) {
_decay_counter[v] = 0;
_env_delta[v] = 0;
continue;
}
_decay_counter[v] = _decay_counter[v] - delta;
_env_delta[v] = -log((DECAY_SCALE - _decay_counter[v] + 1) /
((float)DECAY_SCALE)) *
(_env_amount / 127.0) * dac_pitch_delta(5);
}
}
void
pitch_env_set_decay(uint8_t decay)
{
if (decay > 127) {
decay = 127;
}
_env_decay = decay;
}
void
pitch_env_set_amount(uint8_t amount)
{
if (amount > 127) {
amount = 127;
}
_env_amount = amount;
}
void
pitch_env_trigger(uint8_t voice)
{
if (voice >= NUM_VOICES) {
return;
}
_decay_counter[voice] = (_env_decay / 127.0) * DECAY_SCALE;
pitch_env_update_clock(delta);
}
#include "pitch_env.h"
#include <stdio.h>
int
main(int argc, char **argv)
{
pitch_env_set_amount(127);
pitch_env_set_decay(12);
pitch_env_trigger(0);
for (int i = 0; i < 100; i++) {
pitch_env_update_clock(10);
printf("%d %g\n", i, pitch_env_delta(0));
}
return 0;
}
#include "pitch_env.h"
#include "voice.h"
static float _env_delta[NUM_VOICES];
static uint8_t _env_decay;
static uint8_t _env_amount;
float
pitch_env_delta(uint8_t voice)
{
return _env_delta[voice];
}
void
pitch_env_update_clock(uint8_t delta)
{
for_each_voice (v) {
float descent = 20000 / ((127 - _env_decay) + 1);
_env_delta[v] =
_env_delta[v] - (float)delta * _env_delta[v] / descent;
if (_env_delta[v] < 0) {
_env_delta[v] = 0;
}
}
}
void
pitch_env_set_decay(uint8_t decay)
{
if (decay > 127) {
decay = 127;
}
_env_decay = decay;
}
void
pitch_env_set_amount(uint8_t amount)
{
if (amount > 127) {
amount = 127;
}
_env_amount = amount;
}
void
pitch_env_trigger(uint8_t voice)
{
if (voice >= NUM_VOICES) {
return;
}
_env_delta[voice] = (_env_amount / 127.0);
}
#ifndef _pitch_env_h
#define _pitch_env_h
#include <stdint.h>
void pitch_env_update_clock(uint8_t delta);
void pitch_env_set_decay(uint8_t decay);
void pitch_env_set_amount(uint8_t amount);
void pitch_env_trigger(uint8_t voice);
float pitch_env_delta(uint8_t voice);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment