Commit f27b0394 authored by Jacob Vosmaer's avatar Jacob Vosmaer

Inline more stuff

parent 8c29b80d
PRG = crowbx
OBJ = crowbx.o midi.o dac.o list.o clamp_add.o pitch.o pitch_env.o vibrato_rate.o voice.o
OBJ = crowbx.o midi.o list.o clamp_add.o pitch_env.o vibrato_rate.o voice.o
MCU_TARGET = atmega328p
OPTIMIZE = -O3
......
......@@ -2,8 +2,10 @@
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/atomic.h>
#include <util/delay.h>
#include "array_size.h"
#include "clamp_add.h"
#include "dac.h"
#include "gate.h"
#include "list.h"
......@@ -180,7 +182,6 @@ int main(void) {
io_init();
dac_init();
midi_init();
pitch_init();
program_change(0);
for (;;) {
......@@ -523,3 +524,124 @@ void vibrato_update(uint8_t delta) {
vibrato.amount = 0;
}
}
enum { BEND_CENTER = 8192,
BEND_MAX = 16383,
};
struct {
int16_t bend_data;
uint16_t base_pitch[NUM_VOICES];
} pitch;
void pitch_set_note(uint8_t voice, uint8_t note, int16_t detune) {
if ((voice >= NUM_VOICES) || (note > 127)) {
return;
}
pitch.base_pitch[voice] =
clamp_add(dac_note_pitch(voice, note), detune);
}
void pitch_set_bend(uint16_t bend) {
float bend_factor =
((int16_t)(bend & BEND_MAX) - BEND_CENTER) / ((float)BEND_MAX);
pitch.bend_data = dac_pitch_delta(4) * bend_factor;
}
void pitch_update_clock(uint8_t delta) {
pitch_env_update_clock(delta);
for_each_voice (v) {
uint16_t data =
clamp_add(pitch.base_pitch[v], vibrato_detune());
data = clamp_add(data, pitch_env_delta(v) *
(float)dac_pitch_delta(5));
data = clamp_add(data, pitch.bend_data);
dac_send(dac_command_set(v), data);
}
}
uint16_t dac_pitch_delta(uint8_t semitones) {
if (semitones >= NUM_SEMITONES) {
semitones = NUM_SEMITONES - 1;
}
return dac_semitone_offset(semitones);
}
uint8_t spi_io(uint8_t data) {
SPDR = data;
loop_until_bit_is_set(SPSR, SPIF);
return SPDR;
}
#define DAC_SYNC PORTB1
#define MOSI PORTB3
#define MISO PORTB4
#define SCK PORTB5
#define SS PORTB2
uint8_t dac_command_set(uint8_t v) {
struct dac *d = dac(v);
if (!d) {
return 0;
};
return 0b00110000 | d->channel;
}
void dac_send(uint8_t command, uint16_t data) {
PORTB &= ~_BV(DAC_SYNC);
spi_io(command);
spi_io(data >> 8);
spi_io(data & 0xff);
PORTB |= _BV(DAC_SYNC);
}
void spi_init(void) {
// slave select, sck, mosi all as output
DDRB |= _BV(SS) | _BV(MOSI) | _BV(SCK);
PORTB |= _BV(MISO); // MISO pull-up to save power
// spi enable
SPCR |= _BV(SPE) | _BV(MSTR) | _BV(CPOL);
SPSR |= _BV(SPI2X);
}
void dac_init(void) {
DDRB |= _BV(DAC_SYNC);
spi_init();
// dac sync high for power saving
PORTB |= _BV(DAC_SYNC);
_delay_ms(1); // let dac boot up
}
uint16_t dac_note_pitch(uint8_t v, uint8_t note) {
enum { MIDI_LOWEST = 24 };
struct dac *d = dac(v);
if (!d) {
return 0;
};
// Don't go lower than "C0"
if (note < MIDI_LOWEST) {
note = MIDI_LOWEST;
}
if (note > 127) {
note = 127;
}
uint8_t octave = (note - MIDI_LOWEST) / NUM_SEMITONES;
if (octave > 7) {
return 0;
}
return clamp_add(
d->offset + octave * d->scale,
dac_semitone_offset((note - MIDI_LOWEST) % NUM_SEMITONES));
}
#include "pitch.h"
#include "clamp_add.h"
#include "dac.h"
#include "pitch_env.h"
#include "vibrato.h"
#include "voice.h"
enum { BEND_CENTER = 8192,
BEND_MAX = 16383,
};
static int16_t bend_data = 0;
static uint16_t base_pitch[NUM_VOICES];
void pitch_init(void) {}
void pitch_set_note(uint8_t voice, uint8_t note, int16_t detune) {
if ((voice >= NUM_VOICES) || (note > 127)) {
return;
}
base_pitch[voice] = clamp_add(dac_note_pitch(voice, note), detune);
}
void pitch_set_bend(uint16_t bend) {
float bend_factor =
((int16_t)(bend & BEND_MAX) - BEND_CENTER) / ((float)BEND_MAX);
bend_data = dac_pitch_delta(4) * bend_factor;
}
void pitch_update_clock(uint8_t delta) {
pitch_env_update_clock(delta);
for_each_voice (v) {
uint16_t data = clamp_add(base_pitch[v], vibrato_detune());
data = clamp_add(data, pitch_env_delta(v) *
(float)dac_pitch_delta(5));
data = clamp_add(data, bend_data);
dac_send(dac_command_set(v), data);
}
}
......@@ -10,6 +10,5 @@ void pitch_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);
void pitch_init(void);
#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