Commit 4531b71a authored by Jacob Vosmaer's avatar Jacob Vosmaer

Inline header files

parent f27b0394
PRG = crowbx
OBJ = crowbx.o midi.o list.o clamp_add.o pitch_env.o vibrato_rate.o voice.o
OBJ = crowbx.o midi.o list.o pitch_env.o vibrato_rate.o voice.o
MCU_TARGET = atmega328p
OPTIMIZE = -O3
......
#include "clamp_add.h"
uint16_t clamp_add(uint16_t x, int16_t delta) {
if (delta < 0) {
uint16_t sub = -delta;
if (x < sub) {
return 0;
}
return x - sub;
}
uint16_t add = delta;
if (UINT16_MAX - x < add) {
return UINT16_MAX;
}
return x + add;
}
#ifndef CLAMP_ADD_H
#define CLAMP_ADD_H
#include <stdint.h>
uint16_t clamp_add(uint16_t x, int16_t delta);
#endif
......@@ -5,19 +5,43 @@
#include <util/delay.h>
#include "array_size.h"
#include "clamp_add.h"
#include "dac.h"
#include "gate.h"
#include "list.h"
#include "midi.h"
#include "notes.h"
#include "pitch.h"
#include "pitch_env.h"
#include "uart.h"
#include "vibrato.h"
#include "vibrato_rate.h"
#include "voice.h"
uint16_t clamp_add(uint16_t x, int16_t delta);
void dac_init(void);
uint16_t dac_pitch_delta(uint8_t semitones);
void dac_send(uint8_t command, uint16_t data);
uint16_t dac_note_pitch(uint8_t voice, uint8_t note);
uint8_t dac_command_set(uint8_t voice);
void gate_init(void);
void gate_on(uint8_t voice);
void gate_on_legato(uint8_t voice);
void gate_off(uint8_t voice);
void gate_update(uint8_t delta);
enum { NUM_NOTES = 128 };
int16_t vibrato_detune(void);
void vibrato_update(uint8_t delta);
void vibrato_set_rate(uint8_t val);
void vibrato_set_depth(uint8_t val);
void pitch_set_note(uint8_t voice, uint8_t note, int16_t detune);
void pitch_set_bend(uint16_t bend);
uint16_t pitch_delta(uint8_t semitones);
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);
static struct {
uint8_t data[16];
uint8_t head;
......@@ -645,3 +669,19 @@ uint16_t dac_note_pitch(uint8_t v, uint8_t note) {
d->offset + octave * d->scale,
dac_semitone_offset((note - MIDI_LOWEST) % NUM_SEMITONES));
}
uint16_t clamp_add(uint16_t x, int16_t delta) {
if (delta < 0) {
uint16_t sub = -delta;
if (x < sub) {
return 0;
}
return x - sub;
}
uint16_t add = delta;
if (UINT16_MAX - x < add) {
return UINT16_MAX;
}
return x + add;
}
#include "dac.h"
#include "clamp_add.h"
#include "voice.h"
#include <avr/io.h>
#include <util/delay.h>
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
}
#define MIDI_LOWEST 24
uint16_t dac_note_pitch(uint8_t v, uint8_t note) {
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));
}
#ifndef DAC_H
#define DAC_H
#include <stdint.h>
void dac_init(void);
uint16_t dac_pitch_delta(uint8_t semitones);
void dac_send(uint8_t command, uint16_t data);
uint16_t dac_note_pitch(uint8_t voice, uint8_t note);
uint8_t dac_command_set(uint8_t voice);
#endif
#ifndef GATE_H
#define GATE_H
#include <stdint.h>
void gate_init(void);
void gate_on(uint8_t voice);
void gate_on_legato(uint8_t voice);
void gate_off(uint8_t voice);
void gate_update(uint8_t delta);
#endif
#ifndef NOTES_H
#define NOTES_H
enum { NUM_NOTES = 128,
};
#endif
#ifndef PITCH_H
#define PITCH_H
#include <stdint.h>
void pitch_set_note(uint8_t voice, uint8_t note, int16_t detune);
void pitch_set_bend(uint16_t bend);
uint16_t pitch_delta(uint8_t semitones);
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);
#endif
#ifndef VIBRATO_H
#define VIBRATO_H
#include <stdint.h>
int16_t vibrato_detune(void);
void vibrato_update(uint8_t delta);
void vibrato_set_rate(uint8_t val);
void vibrato_set_depth(uint8_t val);
#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