#include "Arduino.h" #include "ihandlers.h" #include "SPImcpDAC.h" #include "timer.h" #include "build.h" #include "theremin_sintable.c" #include "theremin_sintable2.c" #include "theremin_sintable3.c" #include "theremin_sintable4.c" #include "theremin_sintable5.c" #include "theremin_sintable6.c" #include "theremin_sintable7.c" #include "theremin_sintable8.c" const int16_t* const wavetables[] = { //Fixed following a suggestion by Michael Freitas, does not need to be in PROGMEM sine_table, sine_table2, sine_table3, sine_table4, sine_table5, sine_table6, sine_table7, sine_table8 }; static const uint32_t MCP_DAC_BASE = 2048; #define INT0_STATE (PIND & (1<>6) & 0x3ff; #if CV_ENABLED // Generator for CV output vPointerIncrement = min(vPointerIncrement, 4095); SPImcpDACsend(vPointerIncrement); //Send result to Digital to Analogue Converter (audio out) (5.5 us) #else //Play sound // Read next wave table value waveSample = (int16_t)pgm_read_word_near(wavetables[vWavetableSelector] + offset); scaledSample = ((int32_t)waveSample * (uint32_t)vScaledVolume) >> 16; // The compiler optimizes this better than any assembly written by hand !!! SPImcpDACsend(scaledSample + MCP_DAC_BASE); //Send result to Digital to Analogue Converter (audio out) (5.5 us) pointer += vPointerIncrement; // increment table pointer #endif //CV play sound incrementTimer(); // update 32us timer incrementMidiTimer(); // update 32us miditimer if (PC_STATE) debounce_p++; if (debounce_p == 3) { noInterrupts(); pitch_counter = ICR1; // Get Timer-Counter 1 value pitch = (pitch_counter - pitch_counter_l); // Counter change since last interrupt -> pitch value pitch_counter_l = pitch_counter; // Set actual value as new last value }; if (debounce_p == 5) { pitchValueAvailable = true; }; if (INT0_STATE) debounce_v++; if (debounce_v == 3) { noInterrupts(); vol_counter = vol_counter_i; // Get Timer-Counter 1 value vol = (vol_counter - vol_counter_l); // Counter change since last interrupt vol_counter_l = vol_counter; // Set actual value as new last value }; if (debounce_v == 5) { volumeValueAvailable = true; }; noInterrupts(); enableInt1(); } /* VOLUME read - interrupt service routine for capturing volume counter value */ ISR (INT0_vect) { vol_counter_i = TCNT1; debounce_v = 0; }; /* PITCH read - interrupt service routine for capturing pitch counter value */ ISR (TIMER1_CAPT_vect) { debounce_p = 0; }; /* PITCH read absolute frequency - interrupt service routine for calibration measurement */ ISR(TIMER0_COMPA_vect) { timer_overflow_counter++; } /* VOLUME read absolute frequency - interrupt service routine for calibration measurement */ ISR(TIMER1_OVF_vect) { timer_overflow_counter++; }