Skip to content

Instantly share code, notes, and snippets.

@orukusaki
Created July 6, 2021 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orukusaki/0dcdec3f006f652568b1b8d625c4c2ae to your computer and use it in GitHub Desktop.
Save orukusaki/0dcdec3f006f652568b1b8d625c4c2ae to your computer and use it in GitHub Desktop.
/**
* Multi-saw oscilator. Output on pin D6
* A0 controls base frequency, A1 controls spread. Sync on 3
*/
#define NUM_SAWS 8
typedef union {
uint16_t value;
uint8_t bytes[2];
} Word;
volatile Word saws[NUM_SAWS];
volatile Word increments[NUM_SAWS];
void setup() {
pinMode(6, OUTPUT);
pinMode(5, OUTPUT);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
cli();
TCCR1A = 0;
TCCR1B = _BV(WGM12) | _BV(CS11); // prescaler 8 CTC mode
OCR1A = 64; // 31250Hz
TIMSK1 = _BV(OCIE1A); // enable ISR for Timer 1A
TCCR0A = 0xA3;
TCCR0B = 0x01; // fast pwm
attachInterrupt(digitalPinToInterrupt(3), sync, RISING);
sei();
}
void loop() {
uint16_t pitchCtl = analogRead(A0);
uint16_t spreadCtl = analogRead(A1);
unsigned long incrementsPerSecond = (0xffL * 440L * pitchCtl) + (440L * 0xffl);
uint16_t base = incrementsPerSecond * (0xffff/(F_CPU >> 9)) >> 16;
Word increment;
for (int i = 0; i < NUM_SAWS; i++) {
increment.value = (i * spreadCtl);
if (i % 2 == 0) {
increments[i].value = base + increment.bytes[1];
} else {
increments[i].value = base - increment.bytes[1];
}
}
}
void sync() {
saws[0].value = 0;
saws[1].value = 0;
saws[2].value = 0;
saws[3].value = 0;
saws[4].value = 0;
saws[5].value = 0;
saws[6].value = 0;
saws[7].value = 0;
}
ISR(TIMER1_COMPA_vect) {
uint16_t value = 0;
saws[0].value += increments[0].value;
saws[1].value += increments[1].value;
saws[2].value += increments[2].value;
saws[3].value += increments[3].value;
saws[4].value += increments[4].value;
saws[5].value += increments[5].value;
saws[6].value += increments[6].value;
saws[7].value += increments[7].value;
value += saws[0].bytes[1];
value += saws[1].bytes[1];
value += saws[2].bytes[1];
value += saws[3].bytes[1];
value += saws[4].bytes[1];
value += saws[5].bytes[1];
value += saws[6].bytes[1];
value += saws[7].bytes[1];
OCR0A = value >> 3;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment