From ad0c37b16e5de0d83757cae9563c972f17c15795 Mon Sep 17 00:00:00 2001 From: MrDham Date: Sun, 26 Apr 2020 22:49:02 +0200 Subject: [PATCH 01/14] Add files via upload --- Open_Theremin_V3/application.cpp | 43 ++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/Open_Theremin_V3/application.cpp b/Open_Theremin_V3/application.cpp index adca14b..69ade8f 100644 --- a/Open_Theremin_V3/application.cpp +++ b/Open_Theremin_V3/application.cpp @@ -3,7 +3,7 @@ #include "application.h" #include "hw.h" -#include "mcpDac.h" +#include "SPImcpDAC.h" #include "ihandlers.h" #include "timer.h" #include "EEPROM.h" @@ -32,6 +32,7 @@ static uint8_t old_midi_loop_cc_val =0; static uint8_t midi_velocity = 0; +static uint8_t loop_hand_pos = 0; static uint8_t new_midi_rod_cc_val =0; static uint8_t old_midi_rod_cc_val =0; @@ -77,13 +78,13 @@ void Application::setup() { digitalWrite(Application::LED_PIN_1, HIGH); // turn the LED off by making the voltage LOW - mcpDacInit(); + SPImcpDACinit(); EEPROM.get(0,pitchDAC); EEPROM.get(2,volumeDAC); -mcpDac2ASend(pitchDAC); -mcpDac2BSend(volumeDAC); +SPImcpDAC2Asend(pitchDAC); +SPImcpDAC2Bsend(volumeDAC); initialiseTimer(); @@ -195,6 +196,7 @@ AppMode Application::nextMode() { void Application::loop() { int32_t pitch_v = 0, pitch_l = 0; // Last value of pitch (for filtering) int32_t vol_v = 0, vol_l = 0; // Last value of volume (for filtering) + uint16_t tmpVolume; uint16_t volumePotValue = 0; uint16_t pitchPotValue = 0; @@ -281,7 +283,7 @@ void Application::loop() { // set wave frequency for each mode switch (_mode) { case MUTE : /* NOTHING! */; break; - case NORMAL : setWavetableSampleAdvance((pitchCalibrationBase-pitch_v)/registerValue+2048-(pitchPotValue<<2)); break; + case NORMAL : setWavetableSampleAdvance(((pitchCalibrationBase-pitch_v)+2048-(pitchPotValue<<2))/registerValue); break; }; // HW_LED2_OFF; @@ -306,8 +308,11 @@ void Application::loop() { // vol_v = vol_v - (1 + MAX_VOLUME - (volumePotValue << 2)); vol_v = vol_v ; vol_v = max(vol_v, 0); - vScaledVolume = vol_v >> 4; + loop_hand_pos = vol_v >> 4; + // Give vScaledVolume a pseudo-exponential characteristic: + vScaledVolume = loop_hand_pos * (loop_hand_pos + 2); + volumeValueAvailable = false; } @@ -359,7 +364,7 @@ static long pitchfn = 0; InitialisePitchMeasurement(); interrupts(); - mcpDacInit(); + SPImcpDACinit(); qMeasurement = GetQMeasurement(); // Measure Arudino clock frequency @@ -372,24 +377,24 @@ pitchfn = q0-PitchFreqOffset; // Add offset calue to set frequency -mcpDac2BSend(1600); +SPImcpDAC2Bsend(1600); -mcpDac2ASend(pitchXn0); +SPImcpDAC2Asend(pitchXn0); delay(100); pitchfn0 = GetPitchMeasurement(); -mcpDac2ASend(pitchXn1); +SPImcpDAC2Asend(pitchXn1); delay(100); pitchfn1 = GetPitchMeasurement(); while(abs(pitchfn0-pitchfn1)>CalibrationTolerance){ // max allowed pitch frequency offset -mcpDac2ASend(pitchXn0); +SPImcpDAC2Asend(pitchXn0); delay(100); pitchfn0 = GetPitchMeasurement()-pitchfn; -mcpDac2ASend(pitchXn1); +SPImcpDAC2Asend(pitchXn1); delay(100); pitchfn1 = GetPitchMeasurement()-pitchfn; @@ -425,7 +430,7 @@ static long volumefn = 0; InitialiseVolumeMeasurement(); interrupts(); - mcpDacInit(); + SPImcpDACinit(); volumeXn0 = 0; @@ -436,12 +441,12 @@ volumefn = q0-VolumeFreqOffset; -mcpDac2BSend(volumeXn0); +SPImcpDAC2Bsend(volumeXn0); delay_NOP(44316);//44316=100ms volumefn0 = GetVolumeMeasurement(); -mcpDac2BSend(volumeXn1); +SPImcpDAC2Bsend(volumeXn1); delay_NOP(44316);//44316=100ms volumefn1 = GetVolumeMeasurement(); @@ -450,11 +455,11 @@ volumefn1 = GetVolumeMeasurement(); while(abs(volumefn0-volumefn1)>CalibrationTolerance){ -mcpDac2BSend(volumeXn0); +SPImcpDAC2Bsend(volumeXn0); delay_NOP(44316);//44316=100ms volumefn0 = GetVolumeMeasurement()-volumefn; -mcpDac2BSend(volumeXn1); +SPImcpDAC2Bsend(volumeXn1); delay_NOP(44316);//44316=100ms volumefn1 = GetVolumeMeasurement()-volumefn; @@ -478,7 +483,7 @@ void Application::hzToAddVal(float hz) { } void Application::playNote(float hz, uint16_t milliseconds = 500, uint8_t volume = 255) { - vScaledVolume = volume; + vScaledVolume = volume * (volume + 2); hzToAddVal(hz); millitimer(milliseconds); vScaledVolume = 0; @@ -544,7 +549,7 @@ void Application::midi_application () // Calculate loop antena cc value for midi - new_midi_loop_cc_val = vScaledVolume >> 1; + new_midi_loop_cc_val = loop_hand_pos >> 1; new_midi_loop_cc_val = min (new_midi_loop_cc_val, 127); delta_loop_cc_val = (double)new_midi_loop_cc_val - (double)old_midi_loop_cc_val; From 250bd4dc2177316147814a37d779efaac3580979 Mon Sep 17 00:00:00 2001 From: MrDham Date: Sun, 26 Apr 2020 22:57:42 +0200 Subject: [PATCH 02/14] Add files via upload --- Open_Theremin_V3/Open_Theremin_V3.ino | 5 +- Open_Theremin_V3/SPImcpDAC.h | 104 ++++++++++++++++++++++++++ Open_Theremin_V3/application.cpp | 1 - Open_Theremin_V3/ihandlers.cpp | 63 ++++------------ Open_Theremin_V3/ihandlers.h | 4 +- 5 files changed, 126 insertions(+), 51 deletions(-) create mode 100644 Open_Theremin_V3/SPImcpDAC.h diff --git a/Open_Theremin_V3/Open_Theremin_V3.ino b/Open_Theremin_V3/Open_Theremin_V3.ino index 4022591..b70f0b9 100644 --- a/Open_Theremin_V3/Open_Theremin_V3.ino +++ b/Open_Theremin_V3/Open_Theremin_V3.ino @@ -1,6 +1,8 @@ /* * Open Theremin V3 with MIDI interface control software for Arduino UNO * Based on Open Theremin V3 version 3.0 Copyright (C) 2010-2016 by Urs Gaudenz + * + * Also integrate changes from Open Theremin V3 Version 3.1 Copyright (C) 2010-2020 by Urs Gaudenz * * * Open Theremin V3 with MIDI interface control software is free software: @@ -19,9 +21,10 @@ * the Open Theremin V3 with MIDI interface control software. * If not, see . * - * Urs Gaudenz also credits for their important contributions to Open Theremin V3: + * Also credited for their important contributions to Open Theremin V3: * David Harvey * Michael Margolis + * "Theremingenieur" Thierry Frenkel */ /* Midi added by Vincent Dhamelincourt - September 2017. diff --git a/Open_Theremin_V3/SPImcpDAC.h b/Open_Theremin_V3/SPImcpDAC.h new file mode 100644 index 0000000..e87f9e8 --- /dev/null +++ b/Open_Theremin_V3/SPImcpDAC.h @@ -0,0 +1,104 @@ +/* Control the mcp 4921/4922 DACs with hardware SPI of the Arduino UNO + * ...without all the overhead of the Arduino SPI lib... + * Just the needed functions in a runtime optimized way by "Theremingenieur" Thierry Frenkel + * This file is free software: you can redistribute it and/or + * modify it under the terms of the GNU General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + */ + +#ifndef SPImcpDac_h +#define SPImcpDac_h + +#include + +// Data direction & Port register & Bit number for DAC Latch: +#define MCP_DAC_LDAC_DDR DDRD +#define MCP_DAC_LDAC_PORT PORTD +#define MCP_DAC_LDAC_BIT 7 +// Data direction & Port register & Bit number for DAC CS +#define MCP_DAC_CS_DDR DDRB +#define MCP_DAC_CS_PORT PORTB +#define MCP_DAC_CS_BIT 2 +// Data direction & Port register & Bit number for DAC2 CS +#define MCP_DAC2_CS_DDR DDRB +#define MCP_DAC2_CS_PORT PORTB +#define MCP_DAC2_CS_BIT 1 +// Data direction & Port registers & Bit numbers for Hardware SPI +#define HW_SPI_DDR DDRB +#define HW_SPI_SCK_BIT 5 +#define HW_SPI_MISO_BIT 4 // unused in this configuration +#define HW_SPI_MOSI_BIT 3 + +static inline void SPImcpDACinit() +{ + // initialize the latch pin: + MCP_DAC_LDAC_DDR |= _BV(MCP_DAC_LDAC_BIT); + MCP_DAC_LDAC_PORT |= _BV(MCP_DAC_LDAC_BIT); + // initialize the CS pins: + MCP_DAC_CS_DDR |= _BV(MCP_DAC_CS_BIT); + MCP_DAC_CS_PORT |= _BV(MCP_DAC_CS_BIT); + MCP_DAC2_CS_DDR |= _BV(MCP_DAC2_CS_BIT); + MCP_DAC2_CS_PORT |= _BV(MCP_DAC2_CS_BIT); + // initialize the hardware SPI pins: + HW_SPI_DDR |= _BV(HW_SPI_SCK_BIT); + HW_SPI_DDR |= _BV(HW_SPI_MOSI_BIT); + // initialize the hardware SPI registers + SPCR = _BV(SPE) | _BV(MSTR); // no interrupt, SPI enable, MSB first, SPI master, SPI mode 0, clock = f_osc/4 (maximum) + SPSR = _BV(SPI2X); // double the SPI clock, ideally we get 8 MHz, so that a 16bit word goes out in 3.5us (5.6us when called from an interrupt) including CS asserting/deasserting +} + +static inline void SPImcpDACtransmit(uint16_t data) +{ + // Send highbyte and wait for complete + SPDR = highByte(data); + asm("nop"); + while (!(SPSR & _BV(SPIF))) + ; + // Send lowbyte and wait for complete + SPDR = lowByte(data); + asm("nop"); + while (!(SPSR & _BV(SPIF))) + ; +} + +static inline void SPImcpDAClatch() +{ + MCP_DAC_LDAC_PORT &= ~_BV(MCP_DAC_LDAC_BIT); + MCP_DAC_LDAC_PORT |= _BV(MCP_DAC_LDAC_BIT); +} + +static inline void SPImcpDACsend(uint16_t data) +{ + MCP_DAC_CS_PORT &= ~_BV(MCP_DAC_CS_BIT); + // Sanitize input data and add DAC config MSBs + data &= 0x0FFF; + data |= 0x7000; + SPImcpDACtransmit(data); + MCP_DAC_CS_PORT |= _BV(MCP_DAC_CS_BIT); + // Do not latch immpediately, let's do it at the very beginning of the next interrupt to get consistent timing +} + +static inline void SPImcpDAC2Asend(uint16_t data) +{ + MCP_DAC2_CS_PORT &= ~_BV(MCP_DAC2_CS_BIT); + // Sanitize input data and add DAC config MSBs + data &= 0x0FFF; + data |= 0x7000; + SPImcpDACtransmit(data); + MCP_DAC2_CS_PORT |= _BV(MCP_DAC2_CS_BIT); + SPImcpDAClatch(); +} + +static inline void SPImcpDAC2Bsend(uint16_t data) +{ + MCP_DAC2_CS_PORT &= ~_BV(MCP_DAC2_CS_BIT); + // Sanitize input data and add DAC config MSBs + data &= 0x0FFF; + data |= 0xF000; + SPImcpDACtransmit(data); + MCP_DAC2_CS_PORT |= _BV(MCP_DAC2_CS_BIT); + SPImcpDAClatch(); +} + +#endif diff --git a/Open_Theremin_V3/application.cpp b/Open_Theremin_V3/application.cpp index 69ade8f..b51bce0 100644 --- a/Open_Theremin_V3/application.cpp +++ b/Open_Theremin_V3/application.cpp @@ -196,7 +196,6 @@ AppMode Application::nextMode() { void Application::loop() { int32_t pitch_v = 0, pitch_l = 0; // Last value of pitch (for filtering) int32_t vol_v = 0, vol_l = 0; // Last value of volume (for filtering) - uint16_t tmpVolume; uint16_t volumePotValue = 0; uint16_t pitchPotValue = 0; diff --git a/Open_Theremin_V3/ihandlers.cpp b/Open_Theremin_V3/ihandlers.cpp index a4da417..32a1e4b 100644 --- a/Open_Theremin_V3/ihandlers.cpp +++ b/Open_Theremin_V3/ihandlers.cpp @@ -1,7 +1,7 @@ #include "Arduino.h" #include "ihandlers.h" -#include "mcpDac.h" +#include "SPImcpDAC.h" #include "timer.h" #include "build.h" @@ -15,7 +15,7 @@ #include "theremin_sintable7.c" #include "theremin_sintable8.c" -const int16_t* const wavetables[] PROGMEM = { +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, @@ -26,12 +26,12 @@ const int16_t* const wavetables[] PROGMEM = { sine_table8 }; -static const uint32_t MCP_DAC_BASE = 2047; +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); - mcpDacSend(vPointerIncrement); //Send result to Digital to Analogue Converter (audio out) (9.6 us) + SPImcpDACsend(vPointerIncrement); //Send result to Digital to Analogue Converter (audio out) (5.5 us) #else //Play sound - // Read next wave table value (3.0us) - // The slightly odd tactic here is to provide compile-time expressions for the wavetable - // positions. Making addr1 the index into the wavtables array breaks the time limit for - // the interrupt handler - switch (vWavetableSelector) { - case 1: waveSample = (int16_t) pgm_read_word_near(wavetables[1] + offset); break; - case 2: waveSample = (int16_t) pgm_read_word_near(wavetables[2] + offset); break; - case 3: waveSample = (int16_t) pgm_read_word_near(wavetables[3] + offset); break; - case 4: waveSample = (int16_t) pgm_read_word_near(wavetables[4] + offset); break; - case 5: waveSample = (int16_t) pgm_read_word_near(wavetables[5] + offset); break; - case 6: waveSample = (int16_t) pgm_read_word_near(wavetables[6] + offset); break; - case 7: waveSample = (int16_t) pgm_read_word_near(wavetables[7] + offset); break; - default: waveSample = (int16_t) pgm_read_word_near(wavetables[0] + offset); break; - }; + // 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 !!! - if (waveSample > 0) { // multiply 16 bit wave number by 8 bit volume value (11.2us / 5.4us) - scaledSample = MCP_DAC_BASE + (mul_16_8(waveSample, vScaledVolume) >> 8); - } else { - scaledSample = MCP_DAC_BASE - (mul_16_8(-waveSample, vScaledVolume) >> 8); - } - mcpDacSend(scaledSample); //Send result to Digital to Analogue Converter (audio out) (9.6 us) + SPImcpDACsend(scaledSample + MCP_DAC_BASE); //Send result to Digital to Analogue Converter (audio out) (5.5 us) - pointer = pointer + vPointerIncrement; // increment table pointer (ca. 2us) + pointer += vPointerIncrement; // increment table pointer #endif //CV play sound incrementTimer(); // update 32us timer diff --git a/Open_Theremin_V3/ihandlers.h b/Open_Theremin_V3/ihandlers.h index d6de5d0..07c3c71 100644 --- a/Open_Theremin_V3/ihandlers.h +++ b/Open_Theremin_V3/ihandlers.h @@ -3,7 +3,7 @@ extern volatile uint16_t pitch; // Pitch value extern volatile uint16_t vol; // Volume value -extern volatile uint8_t vScaledVolume; // Volume byte +extern volatile uint16_t vScaledVolume; // Volume byte extern volatile uint16_t pitch_counter; // Pitch counter extern volatile uint16_t pitch_counter_l; // Last value of pitch counter @@ -41,4 +41,4 @@ void resetVolFlag(); void savePitchCounter(); void saveVolCounter(); -#endif // _IHANDLERS_H +#endif // _IHANDLERS_H From 66fa295d1c2b453a97633a599584515f19bccb47 Mon Sep 17 00:00:00 2001 From: MrDham Date: Sun, 26 Apr 2020 23:00:02 +0200 Subject: [PATCH 03/14] Delete mcpDac.h --- Open_Theremin_V3/mcpDac.h | 151 -------------------------------------- 1 file changed, 151 deletions(-) delete mode 100644 Open_Theremin_V3/mcpDac.h diff --git a/Open_Theremin_V3/mcpDac.h b/Open_Theremin_V3/mcpDac.h deleted file mode 100644 index ddbb1ce..0000000 --- a/Open_Theremin_V3/mcpDac.h +++ /dev/null @@ -1,151 +0,0 @@ -/* Arduino WaveHC Library - * Copyright (C) 2009 by William Greiman - * - * This file is part of the Arduino WaveHC Library - * - * This Library is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This Library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Arduino WaveHC Library. If not, see - * . - */ -/** - * Macros and inline functions for MCP4921 DAC - */ -#ifndef mcpDac_h -#define mcpDac_h - -#include -#include "OTPinDefs.h" - - -//------------------------------------------------------------------------------ -#define mcpDacCsLow() MCP_DAC_CS_PORT &= ~_BV(MCP_DAC_CS_BIT) -#define mcpDacCsHigh() MCP_DAC_CS_PORT |= _BV(MCP_DAC_CS_BIT) - -#define mcpDac2CsLow() MCP_DAC_CS_PORT &= ~_BV(MCP_DAC2_CS_BIT) -#define mcpDac2CsHigh() MCP_DAC_CS_PORT |= _BV(MCP_DAC2_CS_BIT) - -#define mcpDacSckLow() MCP_DAC_SCK_PORT &= ~_BV(MCP_DAC_SCK_BIT) -#define mcpDacSckHigh() MCP_DAC_SCK_PORT |= _BV(MCP_DAC_SCK_BIT) -#define mcpDacSckPulse() {mcpDacSckHigh();mcpDacSckLow();} - -#define mcpDacSdiLow() MCP_DAC_SDI_PORT &= ~_BV(MCP_DAC_SDI_BIT) -#define mcpDacSdiHigh() MCP_DAC_SDI_PORT |= _BV(MCP_DAC_SDI_BIT) -#define mcpDacSdiSet(v) if(v){mcpDacSdiHigh();}else{mcpDacSdiLow();} - -// send bit b of d -#define mcpDacSendBit(d, b) {mcpDacSdiSet(d&_BV(b));mcpDacSckPulse();} - -//------------------------------------------------------------------------------ -// init dac I/O ports -inline void mcpDacInit(void) { - // set all to output mode - MCP_DAC_CS_DDR |= _BV(MCP_DAC_CS_BIT); - MCP_DAC2_CS_DDR |= _BV(MCP_DAC2_CS_BIT); - - MCP_DAC_SCK_DDR |= _BV(MCP_DAC_SCK_BIT); - MCP_DAC_SDI_DDR |= _BV(MCP_DAC_SDI_BIT); - // chip select high - mcpDacCsHigh(); - mcpDac2CsHigh(); - -#if USE_MCP_DAC_LDAC - // LDAC low always - use unbuffered mode - MCP_DAC_LDAC_DDR |= _BV(MCP_DAC_LDAC_BIT); - MCP_DAC_LDAC_PORT &= ~_BV(MCP_DAC_LDAC_BIT); -#endif // USE_MCP_DAC_LDAC -} -//------------------------------------------------------------------------------ -// send 12 bits to dac -// trusted compiler to optimize and it does -// csLow to csHigh takes 8 - 9 usec on a 16 MHz Arduino -inline void mcpDacSend(uint16_t data) { - mcpDacCsLow(); - // send DAC config bits - mcpDacSdiLow(); - mcpDacSckPulse(); // DAC A - mcpDacSdiHigh(); - mcpDacSckPulse(); // buffered REF - - mcpDacSckPulse(); // 1X gain - mcpDacSckPulse(); // no SHDN - // send 12 data bits - mcpDacSendBit(data, 11); - mcpDacSendBit(data, 10); - mcpDacSendBit(data, 9); - mcpDacSendBit(data, 8); - mcpDacSendBit(data, 7); - mcpDacSendBit(data, 6); - mcpDacSendBit(data, 5); - mcpDacSendBit(data, 4); - mcpDacSendBit(data, 3); - mcpDacSendBit(data, 2); - mcpDacSendBit(data, 1); - mcpDacSendBit(data, 0); - mcpDacCsHigh(); -} - -inline void mcpDac2ASend(uint16_t data) { - mcpDac2CsLow(); - // send DAC config bits - mcpDacSdiLow(); - mcpDacSckPulse(); // DAC A - mcpDacSdiHigh(); - mcpDacSckPulse(); // buffered REF - - mcpDacSckPulse(); // 1X gain - mcpDacSckPulse(); // no SHDN - // send 12 data bits - mcpDacSendBit(data, 11); - mcpDacSendBit(data, 10); - mcpDacSendBit(data, 9); - mcpDacSendBit(data, 8); - mcpDacSendBit(data, 7); - mcpDacSendBit(data, 6); - mcpDacSendBit(data, 5); - mcpDacSendBit(data, 4); - mcpDacSendBit(data, 3); - mcpDacSendBit(data, 2); - mcpDacSendBit(data, 1); - mcpDacSendBit(data, 0); - mcpDac2CsHigh(); -} - -inline void mcpDac2BSend(uint16_t data) { - mcpDac2CsLow(); - // send DAC config bits - mcpDacSdiHigh(); - mcpDacSckPulse(); // DAC A - mcpDacSdiHigh(); - mcpDacSckPulse(); // buffered REF - - mcpDacSckPulse(); // 1X gain - mcpDacSckPulse(); // no SHDN - // send 12 data bits - mcpDacSendBit(data, 11); - mcpDacSendBit(data, 10); - mcpDacSendBit(data, 9); - mcpDacSendBit(data, 8); - mcpDacSendBit(data, 7); - mcpDacSendBit(data, 6); - mcpDacSendBit(data, 5); - mcpDacSendBit(data, 4); - mcpDacSendBit(data, 3); - mcpDacSendBit(data, 2); - mcpDacSendBit(data, 1); - mcpDacSendBit(data, 0); - mcpDac2CsHigh(); -} - - - -#endif //mcpDac_h From bbb55d39dd60da01477aa5ad558597ffab8fa60a Mon Sep 17 00:00:00 2001 From: MrDham Date: Sun, 26 Apr 2020 23:01:19 +0200 Subject: [PATCH 04/14] Delete OTPinDefs.h --- Open_Theremin_V3/OTPinDefs.h | 56 ------------------------------------ 1 file changed, 56 deletions(-) delete mode 100644 Open_Theremin_V3/OTPinDefs.h diff --git a/Open_Theremin_V3/OTPinDefs.h b/Open_Theremin_V3/OTPinDefs.h deleted file mode 100644 index cdd9996..0000000 --- a/Open_Theremin_V3/OTPinDefs.h +++ /dev/null @@ -1,56 +0,0 @@ -/** - * \file - * Pin definitions - */ - -#ifndef WavePinDefs_h -#define WavePinDefs_h - -//------------------------------------------------------------------------------ -// DAC pin definitions - -// LDAC may be connected to ground to save a pin -/** Set USE_MCP_DAC_LDAC to 0 if LDAC is grounded. */ -#define USE_MCP_DAC_LDAC 1 - -// use arduino pins 2, 3, 4, 5 for DAC - -// pin 2 is DAC chip select - -/** Data direction register for DAC chip select. */ -#define MCP_DAC_CS_DDR DDRB -#define MCP_DAC2_CS_DDR DDRB -/** Port register for DAC chip select. */ -#define MCP_DAC_CS_PORT PORTB -/** Port bit number for DAC chip select. */ -#define MCP_DAC_CS_BIT 2 -#define MCP_DAC2_CS_BIT 1 - -// pin 3 is DAC serial clock -/** Data direction register for DAC clock. */ -#define MCP_DAC_SCK_DDR DDRB -/** Port register for DAC clock. */ -#define MCP_DAC_SCK_PORT PORTB -/** Port bit number for DAC clock. */ -#define MCP_DAC_SCK_BIT 5 - -// pin 4 is DAC serial data in - -/** Data direction register for DAC serial in. */ -#define MCP_DAC_SDI_DDR DDRB -/** Port register for DAC clock. */ -#define MCP_DAC_SDI_PORT PORTB -/** Port bit number for DAC clock. */ -#define MCP_DAC_SDI_BIT 3 - -// pin 5 is LDAC if used -#if USE_MCP_DAC_LDAC -/** Data direction register for Latch DAC Input. */ -#define MCP_DAC_LDAC_DDR DDRD -/** Port register for Latch DAC Input. */ -#define MCP_DAC_LDAC_PORT PORTD -/** Port bit number for Latch DAC Input. */ -#define MCP_DAC_LDAC_BIT 7 -#endif // USE_MCP_DAC_LDAC - -#endif // WavePinDefs_h From f995079ee836105e3ce21f78faa3d60805beda0f Mon Sep 17 00:00:00 2001 From: MrDham Date: Sun, 26 Apr 2020 23:11:43 +0200 Subject: [PATCH 05/14] Update README.md --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c0234b2..f9eb0c7 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,20 @@ -## Open Theremin V3 with MIDI interface control software V2.0 for Arduino UNO +## Open Theremin V3 with MIDI interface control software V2.3 for Arduino UNO Based on Arduino UNO Software for the Open.Theremin version 3.0 Copyright (C) 2010-2016 by Urs Gaudenz https://github.com/GaudiLabs/OpenTheremin_V3 -Urs also made a very clear presentation of this MIDI feature on his website: http://www.gaudi.ch/OpenTheremin/index.php?option=com_content&view=article&id=200&Itemid=121, many thanks ! +This Open Theremin V3 with MIDI version V2.3 also takes into account +Changes added in Open.Theremin version 3.1 (all by @Theremingenieur): + + Fix a wavetable addressing issue (found by @miguelfreitas) + Use the Arduino's hardware SPI to control the DACS and use the Latch signal to reduce audio jitter + Improve the register switch to keep the tone spacing and pitch tuning consistent + Improve the audio volume response to give a smoother start and wider dynamics (*) + +(*) This relies on a recent gcc compiler version. Make sure to compile it with the Arduino IDE >= 1.8.10 + +Urs also made a very clear presentation of the MIDI feature on his website: http://www.gaudi.ch/OpenTheremin/index.php?option=com_content&view=article&id=200&Itemid=121, many thanks ! ### Don't click on the files! Click on the "clone or download" Button to the right. Then unpack the archive. From f2a1bea3e74fd23a2c852f6686db24e67261b2e6 Mon Sep 17 00:00:00 2001 From: MrDham Date: Mon, 27 Apr 2020 09:57:50 +0200 Subject: [PATCH 06/14] Extended Pitch bend range. Register: +/- 1 octave. --- Open_Theremin_V3/application.cpp | 1896 +++++++++++++++--------------- 1 file changed, 957 insertions(+), 939 deletions(-) diff --git a/Open_Theremin_V3/application.cpp b/Open_Theremin_V3/application.cpp index b51bce0..638c436 100644 --- a/Open_Theremin_V3/application.cpp +++ b/Open_Theremin_V3/application.cpp @@ -1,940 +1,958 @@ -#include "Arduino.h" - -#include "application.h" - -#include "hw.h" -#include "SPImcpDAC.h" -#include "ihandlers.h" -#include "timer.h" -#include "EEPROM.h" - -const AppMode AppModeValues[] = {MUTE,NORMAL}; -const int16_t CalibrationTolerance = 15; -const int16_t PitchFreqOffset = 700; -const int16_t VolumeFreqOffset = 700; -const int8_t HYST_VAL = 40; - -static int32_t pitchCalibrationBase = 0; -static int32_t pitchCalibrationBaseFreq = 0; -static int32_t pitchCalibrationConstant = 0; -static int32_t pitchSensitivityConstant = 70000; -static int16_t pitchDAC = 0; -static int16_t volumeDAC = 0; -static float qMeasurement = 0; - -static int32_t volCalibrationBase = 0; - -static uint8_t new_midi_note =0; -static uint8_t old_midi_note =0; - -static uint8_t new_midi_loop_cc_val =0; -static uint8_t old_midi_loop_cc_val =0; - -static uint8_t midi_velocity = 0; - -static uint8_t loop_hand_pos = 0; -static uint8_t new_midi_rod_cc_val =0; -static uint8_t old_midi_rod_cc_val =0; - -static uint16_t new_midi_bend =0; -static uint16_t old_midi_bend = 0; -static uint8_t midi_bend_low; -static uint8_t midi_bend_high; - -static double double_log_freq = 0; -static double midi_key_follow = 0.5; - -// Configuration parameters -static uint8_t registerValue = 4; - // wavetable selector is defined and initialized in ihandlers.cpp -static uint8_t midi_channel = 0; -static uint8_t old_midi_channel = 0; -static uint8_t midi_bend_range = 2; -static uint8_t midi_volume_trigger = 0; -static uint8_t flag_legato_on = 1; -static uint8_t flag_pitch_bend_on = 1; -static uint8_t loop_midi_cc = 7; -static uint8_t rod_midi_cc = 255; - -// tweakable paramameters -#define VELOCITY_SENS 9 // How easy it is to reach highest velocity (127). Something betwen 5 and 12. -#define PLAYER_ACCURACY 0.2 // between 0 (very accurate players) and 0.5 (not accurate at all) - -static uint16_t data_pot_value = 0; -static uint16_t old_data_pot_value = 0; - -Application::Application() - : _state(PLAYING), - _mode(NORMAL) { -}; - -void Application::setup() { - - HW_LED1_ON;HW_LED2_OFF; - - pinMode(Application::BUTTON_PIN, INPUT_PULLUP); - pinMode(Application::LED_PIN_1, OUTPUT); - pinMode(Application::LED_PIN_2, OUTPUT); - - digitalWrite(Application::LED_PIN_1, HIGH); // turn the LED off by making the voltage LOW - - SPImcpDACinit(); - -EEPROM.get(0,pitchDAC); -EEPROM.get(2,volumeDAC); - -SPImcpDAC2Asend(pitchDAC); -SPImcpDAC2Bsend(volumeDAC); - - -initialiseTimer(); -initialiseInterrupts(); - - - EEPROM.get(4,pitchCalibrationBase); - EEPROM.get(8,volCalibrationBase); - - init_parameters(); - midi_setup(); - -} - -void Application::initialiseTimer() { - ihInitialiseTimer(); -} - -void Application::initialiseInterrupts() { - ihInitialiseInterrupts(); -} - -void Application::InitialisePitchMeasurement() { - ihInitialisePitchMeasurement(); -} - -void Application::InitialiseVolumeMeasurement() { - ihInitialiseVolumeMeasurement(); -} - -unsigned long Application::GetQMeasurement() -{ - int qn=0; - - TCCR1B = (1<>2); - pitch_l=pitch_v; - - -//HW_LED2_ON; - - - // set wave frequency for each mode - switch (_mode) { - case MUTE : /* NOTHING! */; break; - case NORMAL : setWavetableSampleAdvance(((pitchCalibrationBase-pitch_v)+2048-(pitchPotValue<<2))/registerValue); break; - }; - - // HW_LED2_OFF; - - pitchValueAvailable = false; - } - - if (volumeValueAvailable) { - vol = max(vol, 5000); - - vol_v=vol; // Averaging volume values - vol_v=vol_l+((vol_v-vol_l)>>2); - vol_l=vol_v; - - switch (_mode) { - case MUTE: vol_v = 0; break; - case NORMAL: vol_v = MAX_VOLUME-(volCalibrationBase-vol_v)/2+(volumePotValue<<2)-1024; break; - }; - - // Limit and set volume value - vol_v = min(vol_v, 4095); - // vol_v = vol_v - (1 + MAX_VOLUME - (volumePotValue << 2)); - vol_v = vol_v ; - vol_v = max(vol_v, 0); - loop_hand_pos = vol_v >> 4; - - // Give vScaledVolume a pseudo-exponential characteristic: - vScaledVolume = loop_hand_pos * (loop_hand_pos + 2); - - volumeValueAvailable = false; - } - - if (midi_timer > 100) // run midi app every 100 ticks equivalent to approximatevely 3 ms to avoid synth's overload - { - midi_application (); - midi_timer = 0; - } - - goto mloop; // End of main loop -} - -void Application::calibrate() -{ - resetPitchFlag(); - resetTimer(); - savePitchCounter(); - while (!pitchValueAvailable && timerUnexpiredMillis(10)) - ; // NOP - pitchCalibrationBase = pitch; - pitchCalibrationBaseFreq = FREQ_FACTOR/pitchCalibrationBase; - pitchCalibrationConstant = FREQ_FACTOR/pitchSensitivityConstant/2+200; - - resetVolFlag(); - resetTimer(); - saveVolCounter(); - while (!volumeValueAvailable && timerUnexpiredMillis(10)) - ; // NOP - volCalibrationBase = vol; - - - EEPROM.put(4,pitchCalibrationBase); - EEPROM.put(8,volCalibrationBase); - -} - -void Application::calibrate_pitch() -{ - -static int16_t pitchXn0 = 0; -static int16_t pitchXn1 = 0; -static int16_t pitchXn2 = 0; -static float q0 = 0; -static long pitchfn0 = 0; -static long pitchfn1 = 0; -static long pitchfn = 0; - - - - InitialisePitchMeasurement(); - interrupts(); - SPImcpDACinit(); - - qMeasurement = GetQMeasurement(); // Measure Arudino clock frequency - -q0 = (16000000/qMeasurement*500000); //Calculated set frequency based on Arudino clock frequency - -pitchXn0 = 0; -pitchXn1 = 4095; - -pitchfn = q0-PitchFreqOffset; // Add offset calue to set frequency - - - -SPImcpDAC2Bsend(1600); - -SPImcpDAC2Asend(pitchXn0); -delay(100); -pitchfn0 = GetPitchMeasurement(); - -SPImcpDAC2Asend(pitchXn1); -delay(100); -pitchfn1 = GetPitchMeasurement(); - - -while(abs(pitchfn0-pitchfn1)>CalibrationTolerance){ // max allowed pitch frequency offset - -SPImcpDAC2Asend(pitchXn0); -delay(100); -pitchfn0 = GetPitchMeasurement()-pitchfn; - -SPImcpDAC2Asend(pitchXn1); -delay(100); -pitchfn1 = GetPitchMeasurement()-pitchfn; - -pitchXn2=pitchXn1-((pitchXn1-pitchXn0)*pitchfn1)/(pitchfn1-pitchfn0); // new DAC value - -delay(100); - - -pitchXn0 = pitchXn1; -pitchXn1 = pitchXn2; - -HW_LED2_TOGGLE; - -} -delay(100); - -EEPROM.put(0,pitchXn0); - -} - -void Application::calibrate_volume() -{ - - -static int16_t volumeXn0 = 0; -static int16_t volumeXn1 = 0; -static int16_t volumeXn2 = 0; -static float q0 = 0; -static long volumefn0 = 0; -static long volumefn1 = 0; -static long volumefn = 0; - - - InitialiseVolumeMeasurement(); - interrupts(); - SPImcpDACinit(); - - -volumeXn0 = 0; -volumeXn1 = 4095; - -q0 = (16000000/qMeasurement*460765); -volumefn = q0-VolumeFreqOffset; - - - -SPImcpDAC2Bsend(volumeXn0); -delay_NOP(44316);//44316=100ms - -volumefn0 = GetVolumeMeasurement(); - -SPImcpDAC2Bsend(volumeXn1); - -delay_NOP(44316);//44316=100ms -volumefn1 = GetVolumeMeasurement(); - - - -while(abs(volumefn0-volumefn1)>CalibrationTolerance){ - -SPImcpDAC2Bsend(volumeXn0); -delay_NOP(44316);//44316=100ms -volumefn0 = GetVolumeMeasurement()-volumefn; - -SPImcpDAC2Bsend(volumeXn1); -delay_NOP(44316);//44316=100ms -volumefn1 = GetVolumeMeasurement()-volumefn; - -volumeXn2=volumeXn1-((volumeXn1-volumeXn0)*volumefn1)/(volumefn1-volumefn0); // calculate new DAC value - -delay_NOP(44316);//44316=100ms - -volumeXn0 = volumeXn1; -volumeXn1 = volumeXn2; -HW_LED2_TOGGLE; - -} - -EEPROM.put(2,volumeXn0); - - -} - -void Application::hzToAddVal(float hz) { - setWavetableSampleAdvance((uint16_t)(hz * HZ_ADDVAL_FACTOR)); -} - -void Application::playNote(float hz, uint16_t milliseconds = 500, uint8_t volume = 255) { - vScaledVolume = volume * (volume + 2); - hzToAddVal(hz); - millitimer(milliseconds); - vScaledVolume = 0; -} - -void Application::playStartupSound() { - playNote(MIDDLE_C, 150, 25); - playNote(MIDDLE_C * 2, 150, 25); - playNote(MIDDLE_C * 4, 150, 25); -} - -void Application::playCalibratingCountdownSound() { - playNote(MIDDLE_C * 2, 150, 25); - playNote(MIDDLE_C * 2, 150, 25); -} - -void Application::playModeSettingSound() { - for (int i = 0; i <= _mode; i++) { - playNote(MIDDLE_C * 2, 200, 25); - millitimer(100); - } -} - -void Application::delay_NOP(unsigned long time) { - volatile unsigned long i = 0; - for (i = 0; i < time; i++) { - __asm__ __volatile__ ("nop"); - } -} - - - -void Application::midi_setup() -{ - // Set MIDI baud rate: - Serial.begin(115200); // Baudrate for midi to serial. Use a serial to midi router http://projectgus.github.com/hairless-midiserial/ - //Serial.begin(31250); // Baudrate for real midi. Use din connection https://www.arduino.cc/en/Tutorial/Midi or HIDUINO https://github.com/ddiakopoulos/hiduino - - _midistate = MIDI_SILENT; -} - - -void Application::midi_msg_send(uint8_t channel, uint8_t midi_cmd1, uint8_t midi_cmd2, uint8_t midi_value) -{ - uint8_t mixed_cmd1_channel; - - mixed_cmd1_channel = (midi_cmd1 & 0xF0)| (channel & 0x0F); - - Serial.write(mixed_cmd1_channel); - Serial.write(midi_cmd2); - Serial.write(midi_value); -} - -// midi_application sends note and volume and uses pitch bend to simulate continuous picth. -// Calibrate pitch bend and other parameters accordingly to the receiver synth (see midi_calibrate). -// New notes won't be generated as long as pitch bend will do the job. -// The bigger is synth's pitch bend range the beter is the effect. -// If pitch bend range = 1 no picth bend is generated (portamento will do a better job) -void Application::midi_application () -{ - double delta_loop_cc_val = 0; - double calculated_velocity = 0; - - - // Calculate loop antena cc value for midi - new_midi_loop_cc_val = loop_hand_pos >> 1; - new_midi_loop_cc_val = min (new_midi_loop_cc_val, 127); - delta_loop_cc_val = (double)new_midi_loop_cc_val - (double)old_midi_loop_cc_val; - - // Calculate log freq - if ((vPointerIncrement < 18) || (vPointerIncrement > 65518)) - { - // Lowest note - double_log_freq = 0; - } - else if ((vPointerIncrement > 26315) && (vPointerIncrement < 39221)) - { - // Highest note - double_log_freq = 127; - } - else if (vPointerIncrement < 32768) - { - // Positive frequencies - // Find note in the playing range - double_log_freq = (log (vPointerIncrement/17.152) / 0.057762265); // Precise note played in the logaritmic scale - } - else - { - // Negative frequencies - // Find note in the playing range - double_log_freq = (log ((65535-vPointerIncrement+1)/17.152) / 0.057762265); // Precise note played in the logaritmic scale - } - - // Calculate rod antena cc value for midi - new_midi_rod_cc_val = round (double_log_freq); - - // State machine for MIDI - switch (_midistate) - { - case MIDI_SILENT: - // Always refresh midi loop antena cc. - if (new_midi_loop_cc_val != old_midi_loop_cc_val) - { - midi_msg_send(midi_channel, 0xB0, loop_midi_cc, new_midi_loop_cc_val); - old_midi_loop_cc_val = new_midi_loop_cc_val; - } - else - { - // do nothing - } - - // Always refresh midi rod antena cc if applicable. - if ((rod_midi_cc != 255) && (new_midi_rod_cc_val != old_midi_rod_cc_val)) - { - midi_msg_send(midi_channel, 0xB0, rod_midi_cc, new_midi_rod_cc_val); - old_midi_rod_cc_val = new_midi_rod_cc_val; - } - else - { - // do nothing - } - - // If player's hand moves away from volume antenna - if (new_midi_loop_cc_val > midi_volume_trigger) - { - // Set key follow to the minimum in order to use closest note played as the center note - midi_key_follow = 0.5; - - // Calculate note and associated pitch bend - calculate_note_bend (); - - // Send pitch bend to reach precise played note (send 8192 (no pitch bend) in case of midi_bend_range == 1) - midi_msg_send(midi_channel, 0xE0, midi_bend_low, midi_bend_high); - old_midi_bend = new_midi_bend; - - // Calculate velocity - if (midi_timer != 0) - { - calculated_velocity = (64 * (127 - (double)midi_volume_trigger) / 127) + (VELOCITY_SENS * (double)midi_volume_trigger * delta_loop_cc_val / (double)midi_timer); - midi_velocity = min (round (abs (calculated_velocity)), 127); - } - else - { - // should not happen - midi_velocity = 64; - } - - - // Play the note - midi_msg_send(midi_channel, 0x90, new_midi_note, midi_velocity); - old_midi_note = new_midi_note; - - _midistate = MIDI_PLAYING; - } - else - { - // Do nothing - } - break; - - case MIDI_PLAYING: - // Always refresh midi loop antena cc. - if (new_midi_loop_cc_val != old_midi_loop_cc_val) - { - midi_msg_send(midi_channel, 0xB0, loop_midi_cc, new_midi_loop_cc_val); - old_midi_loop_cc_val = new_midi_loop_cc_val; - } - else - { - // do nothing - } - - // Always refresh midi rod antena cc if applicable. - if ((rod_midi_cc != 255) && (new_midi_rod_cc_val != old_midi_rod_cc_val)) - { - midi_msg_send(midi_channel, 0xB0, rod_midi_cc, new_midi_rod_cc_val); - old_midi_rod_cc_val = new_midi_rod_cc_val; - } - else - { - // do nothing - } - - // If player's hand is far from volume antenna - if (new_midi_loop_cc_val > midi_volume_trigger) - { - if ( flag_legato_on == 1) - { - // Set key follow so as next played note will be at limit of pitch bend range - midi_key_follow = (double)(midi_bend_range) - PLAYER_ACCURACY; - } - else - { - // Set key follow to max so as no key follows - midi_key_follow = 127; - } - - // Calculate note and associated pitch bend - calculate_note_bend (); - - // Refresh midi pitch bend value - if (new_midi_bend != old_midi_bend) - { - midi_msg_send(midi_channel, 0xE0, midi_bend_low, midi_bend_high); - old_midi_bend = new_midi_bend; - } - else - { - // do nothing - } - - // Refresh midi note - if (new_midi_note != old_midi_note) - { - // Play new note before muting old one to play legato on monophonic synth - // (pitch pend management tends to break expected effect here) - midi_msg_send(midi_channel, 0x90, new_midi_note, midi_velocity); - midi_msg_send(midi_channel, 0x90, old_midi_note, 0); - old_midi_note = new_midi_note; - } - else - { - // do nothing - } - } - else // Means that player's hand moves to the volume antenna - { - // Send note off - midi_msg_send(midi_channel, 0x90, old_midi_note, 0); - - _midistate = MIDI_SILENT; - } - break; - - case MIDI_STOP: - // Send all note off - midi_msg_send(midi_channel, 0xB0, 0x7B, 0x00); - - _midistate = MIDI_MUTE; - break; - - case MIDI_MUTE: - //do nothing - break; - - } -} - -void Application::calculate_note_bend () -{ - double double_log_bend; - double double_norm_log_bend; - - double_log_bend = double_log_freq - old_midi_note; // How far from last played midi chromatic note we are - - // If too much far from last midi chromatic note played (midi_key_follow depends on pitch bend range) - if ((abs (double_log_bend) >= midi_key_follow) && (midi_key_follow != 127)) - { - new_midi_note = round (double_log_freq); // Select the new midi chromatic note - double_log_bend = double_log_freq - new_midi_note; // calculate bend to reach precise note played - } - else - { - new_midi_note = old_midi_note; // No change - } - - // If pitch bend activated - if (flag_pitch_bend_on == 1) - { - // use it to reach precise note played - double_norm_log_bend = (double_log_bend / midi_bend_range); - if (double_norm_log_bend > 1) - { - double_norm_log_bend = 1; - } - else if (double_norm_log_bend < -1) - { - double_norm_log_bend = -1; - } - new_midi_bend = 8192 + (8191 * double_norm_log_bend); // Calculate midi pitch bend - } - else - { - // Don't use pitch bend - new_midi_bend = 8192; - } - - - // Prepare the 2 bites of picth bend midi message - midi_bend_low = (int8_t) (new_midi_bend & 0x007F); - midi_bend_high = (int8_t) ((new_midi_bend & 0x3F80)>> 7); -} - - - -void Application::init_parameters () -{ - // init data pot value to avoid 1st position to be taken into account - data_pot_value = analogRead(WAVE_SELECT_POT); - old_data_pot_value = data_pot_value; - -} - -void Application::set_parameters () -{ - uint16_t param_pot_value = 0; - - param_pot_value = analogRead(REGISTER_SELECT_POT); - data_pot_value = analogRead(WAVE_SELECT_POT); - - // If data pot moved - if (abs((int32_t)data_pot_value - (int32_t)old_data_pot_value) >= 8) - { - // Modify selected parameter - switch (param_pot_value >> 7) - { - case 0: - // Transpose - registerValue=4-(data_pot_value>>8); - break; - - case 1: - // Waveform - vWavetableSelector=data_pot_value>>7; - break; - - case 2: - // Channel - midi_channel = (uint8_t)((data_pot_value >> 6) & 0x000F); - if (old_midi_channel != midi_channel) - { - // Send all note off to avoid stuck notes - midi_msg_send(old_midi_channel, 0xB0, 0x7B, 0x00); - old_midi_channel = midi_channel; - } - break; - - case 3: - // Rod antenna mode - switch (data_pot_value >> 7) - { - case 0: - case 1: - flag_legato_on = 0; - flag_pitch_bend_on = 0; - break; - case 2: - case 3: - flag_legato_on = 0; - flag_pitch_bend_on = 1; - break; - case 4: - case 5: - flag_legato_on = 1; - flag_pitch_bend_on = 0; - break; - default: - flag_legato_on = 1; - flag_pitch_bend_on = 1; - break; - } - break; - - case 4: - // Pitch bend range - switch (data_pot_value >> 7) - { - case 0: - midi_bend_range = 1; - break; - case 1: - case 2: - midi_bend_range = 2; - break; - case 3: - case 4: - midi_bend_range = 7; - break; - case 5: - case 6: - midi_bend_range = 12; - break; - default: - midi_bend_range = 24; - break; - } - break; - - case 5: - // Volume trigger - midi_volume_trigger = (uint8_t)((data_pot_value >> 3) & 0x007F); - break; - - case 6: - //Rod antenna cc - switch (data_pot_value >> 7) - { - case 0: - rod_midi_cc = 255; // Nothing - break; - case 1: - case 2: - rod_midi_cc = 8; // Balance - break; - case 3: - case 4: - rod_midi_cc = 10; // Pan - break; - case 5: - case 6: - rod_midi_cc = 16; // Ribbon Controler - break; - default: - rod_midi_cc = 74; // Cutoff (exists of both loop and rod) - break; - } - break; - - - default: - // Loop antenna cc - switch (data_pot_value >> 7) - { - case 0: - loop_midi_cc = 1; // Modulation - break; - case 1: - loop_midi_cc = 7; // Volume - break; - case 2: - loop_midi_cc = 11; // Expression - break; - case 3: - loop_midi_cc = 71; // Resonnance - break; - case 4: - loop_midi_cc = 74; // Cutoff (exists of both loop and rod) - break; - case 5: - loop_midi_cc = 91; // Reverb - break; - case 6: - loop_midi_cc = 93; // Chorus - break; - default: - loop_midi_cc = 95; // Phaser - break; - } - break; - } - - // Memorize data pot value to monitor changes - old_data_pot_value = data_pot_value; - } +#include "Arduino.h" + +#include "application.h" + +#include "hw.h" +#include "SPImcpDAC.h" +#include "ihandlers.h" +#include "timer.h" +#include "EEPROM.h" + +const AppMode AppModeValues[] = {MUTE,NORMAL}; +const int16_t CalibrationTolerance = 15; +const int16_t PitchFreqOffset = 700; +const int16_t VolumeFreqOffset = 700; +const int8_t HYST_VAL = 40; + +static int32_t pitchCalibrationBase = 0; +static int32_t pitchCalibrationBaseFreq = 0; +static int32_t pitchCalibrationConstant = 0; +static int32_t pitchSensitivityConstant = 70000; +static int16_t pitchDAC = 0; +static int16_t volumeDAC = 0; +static float qMeasurement = 0; + +static int32_t volCalibrationBase = 0; + +static uint8_t new_midi_note =0; +static uint8_t old_midi_note =0; + +static uint8_t new_midi_loop_cc_val =0; +static uint8_t old_midi_loop_cc_val =0; + +static uint8_t midi_velocity = 0; + +static uint8_t loop_hand_pos = 0; +static uint8_t new_midi_rod_cc_val =0; +static uint8_t old_midi_rod_cc_val =0; + +static uint16_t new_midi_bend =0; +static uint16_t old_midi_bend = 0; +static uint8_t midi_bend_low; +static uint8_t midi_bend_high; + +static double double_log_freq = 0; +static double midi_key_follow = 0.5; + +// Configuration parameters +static uint8_t registerValue = 4; + // wavetable selector is defined and initialized in ihandlers.cpp +static uint8_t midi_channel = 0; +static uint8_t old_midi_channel = 0; +static uint8_t midi_bend_range = 2; +static uint8_t midi_volume_trigger = 0; +static uint8_t flag_legato_on = 1; +static uint8_t flag_pitch_bend_on = 1; +static uint8_t loop_midi_cc = 7; +static uint8_t rod_midi_cc = 255; + +// tweakable paramameters +#define VELOCITY_SENS 9 // How easy it is to reach highest velocity (127). Something betwen 5 and 12. +#define PLAYER_ACCURACY 0.2 // between 0 (very accurate players) and 0.5 (not accurate at all) + +static uint16_t data_pot_value = 0; +static uint16_t old_data_pot_value = 0; + +Application::Application() + : _state(PLAYING), + _mode(NORMAL) { +}; + +void Application::setup() { + + HW_LED1_ON;HW_LED2_OFF; + + pinMode(Application::BUTTON_PIN, INPUT_PULLUP); + pinMode(Application::LED_PIN_1, OUTPUT); + pinMode(Application::LED_PIN_2, OUTPUT); + + digitalWrite(Application::LED_PIN_1, HIGH); // turn the LED off by making the voltage LOW + + SPImcpDACinit(); + +EEPROM.get(0,pitchDAC); +EEPROM.get(2,volumeDAC); + +SPImcpDAC2Asend(pitchDAC); +SPImcpDAC2Bsend(volumeDAC); + + +initialiseTimer(); +initialiseInterrupts(); + + + EEPROM.get(4,pitchCalibrationBase); + EEPROM.get(8,volCalibrationBase); + + init_parameters(); + midi_setup(); + +} + +void Application::initialiseTimer() { + ihInitialiseTimer(); +} + +void Application::initialiseInterrupts() { + ihInitialiseInterrupts(); +} + +void Application::InitialisePitchMeasurement() { + ihInitialisePitchMeasurement(); +} + +void Application::InitialiseVolumeMeasurement() { + ihInitialiseVolumeMeasurement(); +} + +unsigned long Application::GetQMeasurement() +{ + int qn=0; + + TCCR1B = (1<>2); + pitch_l=pitch_v; + + +//HW_LED2_ON; + + + // set wave frequency for each mode + switch (_mode) { + case MUTE : /* NOTHING! */; break; + case NORMAL : setWavetableSampleAdvance(((pitchCalibrationBase-pitch_v)+2048-(pitchPotValue<<2))>>registerValue); break; + }; + + // HW_LED2_OFF; + + pitchValueAvailable = false; + } + + if (volumeValueAvailable) { + vol = max(vol, 5000); + + vol_v=vol; // Averaging volume values + vol_v=vol_l+((vol_v-vol_l)>>2); + vol_l=vol_v; + + switch (_mode) { + case MUTE: vol_v = 0; break; + case NORMAL: vol_v = MAX_VOLUME-(volCalibrationBase-vol_v)/2+(volumePotValue<<2)-1024; break; + }; + + // Limit and set volume value + vol_v = min(vol_v, 4095); + // vol_v = vol_v - (1 + MAX_VOLUME - (volumePotValue << 2)); + vol_v = vol_v ; + vol_v = max(vol_v, 0); + loop_hand_pos = vol_v >> 4; + + // Give vScaledVolume a pseudo-exponential characteristic: + vScaledVolume = loop_hand_pos * (loop_hand_pos + 2); + + volumeValueAvailable = false; + } + + if (midi_timer > 100) // run midi app every 100 ticks equivalent to approximatevely 3 ms to avoid synth's overload + { + midi_application (); + midi_timer = 0; + } + + goto mloop; // End of main loop +} + +void Application::calibrate() +{ + resetPitchFlag(); + resetTimer(); + savePitchCounter(); + while (!pitchValueAvailable && timerUnexpiredMillis(10)) + ; // NOP + pitchCalibrationBase = pitch; + pitchCalibrationBaseFreq = FREQ_FACTOR/pitchCalibrationBase; + pitchCalibrationConstant = FREQ_FACTOR/pitchSensitivityConstant/2+200; + + resetVolFlag(); + resetTimer(); + saveVolCounter(); + while (!volumeValueAvailable && timerUnexpiredMillis(10)) + ; // NOP + volCalibrationBase = vol; + + + EEPROM.put(4,pitchCalibrationBase); + EEPROM.put(8,volCalibrationBase); + +} + +void Application::calibrate_pitch() +{ + +static int16_t pitchXn0 = 0; +static int16_t pitchXn1 = 0; +static int16_t pitchXn2 = 0; +static float q0 = 0; +static long pitchfn0 = 0; +static long pitchfn1 = 0; +static long pitchfn = 0; + + + + InitialisePitchMeasurement(); + interrupts(); + SPImcpDACinit(); + + qMeasurement = GetQMeasurement(); // Measure Arudino clock frequency + +q0 = (16000000/qMeasurement*500000); //Calculated set frequency based on Arudino clock frequency + +pitchXn0 = 0; +pitchXn1 = 4095; + +pitchfn = q0-PitchFreqOffset; // Add offset calue to set frequency + + + +SPImcpDAC2Bsend(1600); + +SPImcpDAC2Asend(pitchXn0); +delay(100); +pitchfn0 = GetPitchMeasurement(); + +SPImcpDAC2Asend(pitchXn1); +delay(100); +pitchfn1 = GetPitchMeasurement(); + + +while(abs(pitchfn0-pitchfn1)>CalibrationTolerance){ // max allowed pitch frequency offset + +SPImcpDAC2Asend(pitchXn0); +delay(100); +pitchfn0 = GetPitchMeasurement()-pitchfn; + +SPImcpDAC2Asend(pitchXn1); +delay(100); +pitchfn1 = GetPitchMeasurement()-pitchfn; + +pitchXn2=pitchXn1-((pitchXn1-pitchXn0)*pitchfn1)/(pitchfn1-pitchfn0); // new DAC value + +delay(100); + + +pitchXn0 = pitchXn1; +pitchXn1 = pitchXn2; + +HW_LED2_TOGGLE; + +} +delay(100); + +EEPROM.put(0,pitchXn0); + +} + +void Application::calibrate_volume() +{ + + +static int16_t volumeXn0 = 0; +static int16_t volumeXn1 = 0; +static int16_t volumeXn2 = 0; +static float q0 = 0; +static long volumefn0 = 0; +static long volumefn1 = 0; +static long volumefn = 0; + + + InitialiseVolumeMeasurement(); + interrupts(); + SPImcpDACinit(); + + +volumeXn0 = 0; +volumeXn1 = 4095; + +q0 = (16000000/qMeasurement*460765); +volumefn = q0-VolumeFreqOffset; + + + +SPImcpDAC2Bsend(volumeXn0); +delay_NOP(44316);//44316=100ms + +volumefn0 = GetVolumeMeasurement(); + +SPImcpDAC2Bsend(volumeXn1); + +delay_NOP(44316);//44316=100ms +volumefn1 = GetVolumeMeasurement(); + + + +while(abs(volumefn0-volumefn1)>CalibrationTolerance){ + +SPImcpDAC2Bsend(volumeXn0); +delay_NOP(44316);//44316=100ms +volumefn0 = GetVolumeMeasurement()-volumefn; + +SPImcpDAC2Bsend(volumeXn1); +delay_NOP(44316);//44316=100ms +volumefn1 = GetVolumeMeasurement()-volumefn; + +volumeXn2=volumeXn1-((volumeXn1-volumeXn0)*volumefn1)/(volumefn1-volumefn0); // calculate new DAC value + +delay_NOP(44316);//44316=100ms + +volumeXn0 = volumeXn1; +volumeXn1 = volumeXn2; +HW_LED2_TOGGLE; + +} + +EEPROM.put(2,volumeXn0); + + +} + +void Application::hzToAddVal(float hz) { + setWavetableSampleAdvance((uint16_t)(hz * HZ_ADDVAL_FACTOR)); +} + +void Application::playNote(float hz, uint16_t milliseconds = 500, uint8_t volume = 255) { + vScaledVolume = volume * (volume + 2); + hzToAddVal(hz); + millitimer(milliseconds); + vScaledVolume = 0; +} + +void Application::playStartupSound() { + playNote(MIDDLE_C, 150, 25); + playNote(MIDDLE_C * 2, 150, 25); + playNote(MIDDLE_C * 4, 150, 25); +} + +void Application::playCalibratingCountdownSound() { + playNote(MIDDLE_C * 2, 150, 25); + playNote(MIDDLE_C * 2, 150, 25); +} + +void Application::playModeSettingSound() { + for (int i = 0; i <= _mode; i++) { + playNote(MIDDLE_C * 2, 200, 25); + millitimer(100); + } +} + +void Application::delay_NOP(unsigned long time) { + volatile unsigned long i = 0; + for (i = 0; i < time; i++) { + __asm__ __volatile__ ("nop"); + } +} + + + +void Application::midi_setup() +{ + // Set MIDI baud rate: + Serial.begin(115200); // Baudrate for midi to serial. Use a serial to midi router http://projectgus.github.com/hairless-midiserial/ + //Serial.begin(31250); // Baudrate for real midi. Use din connection https://www.arduino.cc/en/Tutorial/Midi or HIDUINO https://github.com/ddiakopoulos/hiduino + + _midistate = MIDI_SILENT; +} + + +void Application::midi_msg_send(uint8_t channel, uint8_t midi_cmd1, uint8_t midi_cmd2, uint8_t midi_value) +{ + uint8_t mixed_cmd1_channel; + + mixed_cmd1_channel = (midi_cmd1 & 0xF0)| (channel & 0x0F); + + Serial.write(mixed_cmd1_channel); + Serial.write(midi_cmd2); + Serial.write(midi_value); +} + +// midi_application sends note and volume and uses pitch bend to simulate continuous picth. +// Calibrate pitch bend and other parameters accordingly to the receiver synth (see midi_calibrate). +// New notes won't be generated as long as pitch bend will do the job. +// The bigger is synth's pitch bend range the beter is the effect. +// If pitch bend range = 1 no picth bend is generated (portamento will do a better job) +void Application::midi_application () +{ + double delta_loop_cc_val = 0; + double calculated_velocity = 0; + + + // Calculate loop antena cc value for midi + new_midi_loop_cc_val = loop_hand_pos >> 1; + new_midi_loop_cc_val = min (new_midi_loop_cc_val, 127); + delta_loop_cc_val = (double)new_midi_loop_cc_val - (double)old_midi_loop_cc_val; + + // Calculate log freq + if ((vPointerIncrement < 18) || (vPointerIncrement > 65518)) + { + // Lowest note + double_log_freq = 0; + } + else if ((vPointerIncrement > 26315) && (vPointerIncrement < 39221)) + { + // Highest note + double_log_freq = 127; + } + else if (vPointerIncrement < 32768) + { + // Positive frequencies + // Find note in the playing range + double_log_freq = (log (vPointerIncrement/17.152) / 0.057762265); // Precise note played in the logaritmic scale + } + else + { + // Negative frequencies + // Find note in the playing range + double_log_freq = (log ((65535-vPointerIncrement+1)/17.152) / 0.057762265); // Precise note played in the logaritmic scale + } + + // Calculate rod antena cc value for midi + new_midi_rod_cc_val = round (double_log_freq); + + // State machine for MIDI + switch (_midistate) + { + case MIDI_SILENT: + // Always refresh midi loop antena cc. + if (new_midi_loop_cc_val != old_midi_loop_cc_val) + { + midi_msg_send(midi_channel, 0xB0, loop_midi_cc, new_midi_loop_cc_val); + old_midi_loop_cc_val = new_midi_loop_cc_val; + } + else + { + // do nothing + } + + // Always refresh midi rod antena cc if applicable. + if ((rod_midi_cc != 255) && (new_midi_rod_cc_val != old_midi_rod_cc_val)) + { + midi_msg_send(midi_channel, 0xB0, rod_midi_cc, new_midi_rod_cc_val); + old_midi_rod_cc_val = new_midi_rod_cc_val; + } + else + { + // do nothing + } + + // If player's hand moves away from volume antenna + if (new_midi_loop_cc_val > midi_volume_trigger) + { + // Set key follow to the minimum in order to use closest note played as the center note + midi_key_follow = 0.5; + + // Calculate note and associated pitch bend + calculate_note_bend (); + + // Send pitch bend to reach precise played note (send 8192 (no pitch bend) in case of midi_bend_range == 1) + midi_msg_send(midi_channel, 0xE0, midi_bend_low, midi_bend_high); + old_midi_bend = new_midi_bend; + + // Calculate velocity + if (midi_timer != 0) + { + calculated_velocity = (64 * (127 - (double)midi_volume_trigger) / 127) + (VELOCITY_SENS * (double)midi_volume_trigger * delta_loop_cc_val / (double)midi_timer); + midi_velocity = min (round (abs (calculated_velocity)), 127); + } + else + { + // should not happen + midi_velocity = 64; + } + + + // Play the note + midi_msg_send(midi_channel, 0x90, new_midi_note, midi_velocity); + old_midi_note = new_midi_note; + + _midistate = MIDI_PLAYING; + } + else + { + // Do nothing + } + break; + + case MIDI_PLAYING: + // Always refresh midi loop antena cc. + if (new_midi_loop_cc_val != old_midi_loop_cc_val) + { + midi_msg_send(midi_channel, 0xB0, loop_midi_cc, new_midi_loop_cc_val); + old_midi_loop_cc_val = new_midi_loop_cc_val; + } + else + { + // do nothing + } + + // Always refresh midi rod antena cc if applicable. + if ((rod_midi_cc != 255) && (new_midi_rod_cc_val != old_midi_rod_cc_val)) + { + midi_msg_send(midi_channel, 0xB0, rod_midi_cc, new_midi_rod_cc_val); + old_midi_rod_cc_val = new_midi_rod_cc_val; + } + else + { + // do nothing + } + + // If player's hand is far from volume antenna + if (new_midi_loop_cc_val > midi_volume_trigger) + { + if ( flag_legato_on == 1) + { + // Set key follow so as next played note will be at limit of pitch bend range + midi_key_follow = (double)(midi_bend_range) - PLAYER_ACCURACY; + } + else + { + // Set key follow to max so as no key follows + midi_key_follow = 127; + } + + // Calculate note and associated pitch bend + calculate_note_bend (); + + // Refresh midi pitch bend value + if (new_midi_bend != old_midi_bend) + { + midi_msg_send(midi_channel, 0xE0, midi_bend_low, midi_bend_high); + old_midi_bend = new_midi_bend; + } + else + { + // do nothing + } + + // Refresh midi note + if (new_midi_note != old_midi_note) + { + // Play new note before muting old one to play legato on monophonic synth + // (pitch pend management tends to break expected effect here) + midi_msg_send(midi_channel, 0x90, new_midi_note, midi_velocity); + midi_msg_send(midi_channel, 0x90, old_midi_note, 0); + old_midi_note = new_midi_note; + } + else + { + // do nothing + } + } + else // Means that player's hand moves to the volume antenna + { + // Send note off + midi_msg_send(midi_channel, 0x90, old_midi_note, 0); + + _midistate = MIDI_SILENT; + } + break; + + case MIDI_STOP: + // Send all note off + midi_msg_send(midi_channel, 0xB0, 0x7B, 0x00); + + _midistate = MIDI_MUTE; + break; + + case MIDI_MUTE: + //do nothing + break; + + } +} + +void Application::calculate_note_bend () +{ + double double_log_bend; + double double_norm_log_bend; + + double_log_bend = double_log_freq - old_midi_note; // How far from last played midi chromatic note we are + + // If too much far from last midi chromatic note played (midi_key_follow depends on pitch bend range) + if ((abs (double_log_bend) >= midi_key_follow) && (midi_key_follow != 127)) + { + new_midi_note = round (double_log_freq); // Select the new midi chromatic note + double_log_bend = double_log_freq - new_midi_note; // calculate bend to reach precise note played + } + else + { + new_midi_note = old_midi_note; // No change + } + + // If pitch bend activated + if (flag_pitch_bend_on == 1) + { + // use it to reach precise note played + double_norm_log_bend = (double_log_bend / midi_bend_range); + if (double_norm_log_bend > 1) + { + double_norm_log_bend = 1; + } + else if (double_norm_log_bend < -1) + { + double_norm_log_bend = -1; + } + new_midi_bend = 8192 + (8191 * double_norm_log_bend); // Calculate midi pitch bend + } + else + { + // Don't use pitch bend + new_midi_bend = 8192; + } + + + // Prepare the 2 bites of picth bend midi message + midi_bend_low = (int8_t) (new_midi_bend & 0x007F); + midi_bend_high = (int8_t) ((new_midi_bend & 0x3F80)>> 7); +} + + + +void Application::init_parameters () +{ + // init data pot value to avoid 1st position to be taken into account + data_pot_value = analogRead(WAVE_SELECT_POT); + old_data_pot_value = data_pot_value; + +} + +void Application::set_parameters () +{ + uint16_t param_pot_value = 0; + + param_pot_value = analogRead(REGISTER_SELECT_POT); + data_pot_value = analogRead(WAVE_SELECT_POT); + + // If data pot moved + if (abs((int32_t)data_pot_value - (int32_t)old_data_pot_value) >= 8) + { + // Modify selected parameter + switch (param_pot_value >> 7) + { + case 0: + // Transpose + switch (data_pot_value >> 8) + { + case 0: + registerValue=3; // -1 Octave + break; + case 1: + case 2: + registerValue=2; // Center + break; + default: + registerValue=1; // +1 Octave + break; + } + break; + + case 1: + // Waveform + vWavetableSelector=data_pot_value>>7; + break; + + case 2: + // Channel + midi_channel = (uint8_t)((data_pot_value >> 6) & 0x000F); + if (old_midi_channel != midi_channel) + { + // Send all note off to avoid stuck notes + midi_msg_send(old_midi_channel, 0xB0, 0x7B, 0x00); + old_midi_channel = midi_channel; + } + break; + + case 3: + // Rod antenna mode + switch (data_pot_value >> 7) + { + case 0: + case 1: + flag_legato_on = 0; + flag_pitch_bend_on = 0; + break; + case 2: + case 3: + flag_legato_on = 0; + flag_pitch_bend_on = 1; + break; + case 4: + case 5: + flag_legato_on = 1; + flag_pitch_bend_on = 0; + break; + default: + flag_legato_on = 1; + flag_pitch_bend_on = 1; + break; + } + break; + + case 4: + // Pitch bend range + switch (data_pot_value >> 7) + { + case 0: + midi_bend_range = 1; + break; + case 1: + midi_bend_range = 2; + break; + case 2: + midi_bend_range = 4; + break; + case 3: + midi_bend_range = 5; + break; + case 4: + midi_bend_range = 7; + break; + case 5: + midi_bend_range = 12; + break; + case 6: + midi_bend_range = 24; + break; + default: + midi_bend_range = 48; + break; + } + break; + + case 5: + // Volume trigger + midi_volume_trigger = (uint8_t)((data_pot_value >> 3) & 0x007F); + break; + + case 6: + //Rod antenna cc + switch (data_pot_value >> 7) + { + case 0: + rod_midi_cc = 255; // Nothing + break; + case 1: + case 2: + rod_midi_cc = 8; // Balance + break; + case 3: + case 4: + rod_midi_cc = 10; // Pan + break; + case 5: + case 6: + rod_midi_cc = 16; // Ribbon Controler + break; + default: + rod_midi_cc = 74; // Cutoff (exists of both loop and rod) + break; + } + break; + + + default: + // Loop antenna cc + switch (data_pot_value >> 7) + { + case 0: + loop_midi_cc = 1; // Modulation + break; + case 1: + loop_midi_cc = 7; // Volume + break; + case 2: + loop_midi_cc = 11; // Expression + break; + case 3: + loop_midi_cc = 71; // Resonnance + break; + case 4: + loop_midi_cc = 74; // Cutoff (exists of both loop and rod) + break; + case 5: + loop_midi_cc = 91; // Reverb + break; + case 6: + loop_midi_cc = 93; // Chorus + break; + default: + loop_midi_cc = 95; // Phaser + break; + } + break; + } + + // Memorize data pot value to monitor changes + old_data_pot_value = data_pot_value; + } } From 0f6af9592e5f631c418b0ec38af1583c2f9647d0 Mon Sep 17 00:00:00 2001 From: MrDham Date: Mon, 27 Apr 2020 11:53:37 +0200 Subject: [PATCH 07/14] Register +/-1 Octave - Extend PB Range --- Quick guide open theremin midi.bmp | Bin 2677422 -> 2677422 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/Quick guide open theremin midi.bmp b/Quick guide open theremin midi.bmp index 942cd3031841b224b917e2487c16cbb5ca9d37e1..072e7bb2a7873a48108d4ff90046a2d1bb10c37b 100644 GIT binary patch delta 77649 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 delta 62535 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 Date: Mon, 27 Apr 2020 12:00:37 +0200 Subject: [PATCH 08/14] Add files via upload --- MIDI Open Theremin V3 HMI.bmp | Bin 601446 -> 615654 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/MIDI Open Theremin V3 HMI.bmp b/MIDI Open Theremin V3 HMI.bmp index a00eb12178603a432498b33f0f4ffa3df7f530b8..6fe07fdee63c49b7e514b13d8fafda9b94958fb4 100644 GIT binary patch delta 13769 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 Xi{E&0t9?+x`+tpLX4BEx@5}pl!&tJB delta 12694 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 DXXc?m From 4bdc6283b29cd61f1019cbd02682f6d3401be480 Mon Sep 17 00:00:00 2001 From: MrDham Date: Mon, 27 Apr 2020 12:13:31 +0200 Subject: [PATCH 10/14] Add files via upload --- Open_Theremin_V3/application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Open_Theremin_V3/application.cpp b/Open_Theremin_V3/application.cpp index 638c436..e692342 100644 --- a/Open_Theremin_V3/application.cpp +++ b/Open_Theremin_V3/application.cpp @@ -45,7 +45,7 @@ static double double_log_freq = 0; static double midi_key_follow = 0.5; // Configuration parameters -static uint8_t registerValue = 4; +static uint8_t registerValue = 2; // wavetable selector is defined and initialized in ihandlers.cpp static uint8_t midi_channel = 0; static uint8_t old_midi_channel = 0; @@ -857,7 +857,7 @@ void Application::set_parameters () break; } break; - + case 4: // Pitch bend range switch (data_pot_value >> 7) From 6fd6788ab377fa6e0d1a5ab3cb81c019bd8bd561 Mon Sep 17 00:00:00 2001 From: MrDham Date: Mon, 27 Apr 2020 12:20:59 +0200 Subject: [PATCH 11/14] Update README.md --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f9eb0c7..552007a 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,8 @@ Changes added in Open.Theremin version 3.1 (all by @Theremingenieur): (*) This relies on a recent gcc compiler version. Make sure to compile it with the Arduino IDE >= 1.8.10 +Pitch Bend Range choice is also extended (Allows 4 octaves Bend) + Urs also made a very clear presentation of the MIDI feature on his website: http://www.gaudi.ch/OpenTheremin/index.php?option=com_content&view=article&id=200&Itemid=121, many thanks ! ### Don't click on the files! @@ -85,12 +87,12 @@ Let's consider a Fade-in / Picth Variation / Fade-out sequence (I use right hand "Register" pot becomes "Selected Parameter" pot and have 8 positions. "Timbre" pot becomes "Parameter's Value" and have a variable number of positions depending on selected parameter: - 1. Register: 4 positions as in original Open Theremin V3 + 1. Register: 3 positions (-1 Octave, center, +1 Octave) as in original Open Theremin V3 (version V3.1) 2. Timbre: 8 positions as in original Open Theremin V3 3. Channel: 16 positions (channel 1 to 16) 4. Rod antenna mode: 4 positions (Legato off/Pitch Bend off, Legato off/Pitch Bend on, Legato on/Pitch Bend off, Legato on/Pitch Bend on) - 5. Pitch bend range: 5 positions (1, 2, 7, 12, 24 Semitones). + 5. Pitch bend range: 8 positions (1, 2, 4, 5, 7, 12, 24, 48 Semitones). For classical glissando and in order to have same note on audio and MIDI, use exactly same pitch bend range on your synth. Maximum setting possible is recomended. 6. Volume trigger / Velocity sensitivity (how fast moves the volume loop's hand): 128 positions (0 to 127) @@ -111,7 +113,7 @@ Volume trigger = 127 (Maximum) won't generate any NOTE ON. It can be used to gen Manipulation of "Rod antenna MIDI CC" and "Loop antenna MIDI CC" is not error proof. MIDI newbies should be advised to change their value in MUTE mode. -Default configuration is: Register = Lowest Register, Timbre = 1st Waveform, Channel = MIDI Channel 1, Rod antenna mode = Legato on/Pitch Bend on, Pitch bend range = 2 Semitones, Volume trigger = 0, Rod antenna MIDI CC = None, Loop antenna MIDI CC = 7-Volume. +Default configuration is: Register = Center, Timbre = 1st Waveform, Channel = MIDI Channel 1, Rod antenna mode = Legato on/Pitch Bend on, Pitch bend range = 2 Semitones, Volume trigger = 0, Rod antenna MIDI CC = None, Loop antenna MIDI CC = 7-Volume. MUTE BUTTON: From e9a89d0ea2ab004da9fa6de2b4aee346f703f081 Mon Sep 17 00:00:00 2001 From: MrDham Date: Mon, 27 Apr 2020 12:38:47 +0200 Subject: [PATCH 12/14] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 552007a..186c199 100644 --- a/README.md +++ b/README.md @@ -9,8 +9,8 @@ Changes added in Open.Theremin version 3.1 (all by @Theremingenieur): Fix a wavetable addressing issue (found by @miguelfreitas) Use the Arduino's hardware SPI to control the DACS and use the Latch signal to reduce audio jitter - Improve the register switch to keep the tone spacing and pitch tuning consistent - Improve the audio volume response to give a smoother start and wider dynamics (*) + Improve the register switch to transpose by clean octaves and keep the tone spacing and pitch tuning consistent + Improve the volume response to give a smoother start and wider dynamics (*) (*) This relies on a recent gcc compiler version. Make sure to compile it with the Arduino IDE >= 1.8.10 From d52d543ca7949b454b7e11b96ceb6d8d7658fbb0 Mon Sep 17 00:00:00 2001 From: MrDham Date: Mon, 27 Apr 2020 14:56:39 +0200 Subject: [PATCH 13/14] Delete README.md~ --- README.md~ | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 README.md~ diff --git a/README.md~ b/README.md~ deleted file mode 100644 index 128f3a7..0000000 --- a/README.md~ +++ /dev/null @@ -1,22 +0,0 @@ -## Open.Theremin V3 control software - -Arduino UNO Software for the Open.Theremin - -### Don't click on the files! -Click on the "Download ZIP" Button to the right or [Click here](https://github.com/GaudiLabs/OpenTheremin_V3/archive/master.zip) -Then unpack the archive. - -### Open Source Theremin based on the Arduino Platform - -Open.Theremin is an arduino shield to build the legendary music instrument invented by Leon Theremin back in 1920. The theremin is played with two antennas, one to control the pitch and one for volume. The electronic shield with two ports to connect those antennas comprises two heterodyne oscillators to measure the distance of the hand to the antenna when playing the instrument. The resulting signal is fed into the arduino. After linearization and filtering the arduino generates the instruments sound that is then played through a high quality digital analog audio converter on the board. The characteristics of the sound can be determined by a wave table on the arduino. - -For more info on the open source project and on availability of ready made shield see: - -http://www.gaudi.ch/OpenTheremin/ - -### Installation -1. Open up the Arduino IDE -2. Open the File "Open_Theremin_V3.ino" -3. Selecting the correct usb port on Tools -> Serial Port -4. Select the correct arduino board from Tools -> Board -5. Upload the code by clicking on the upload button. From d217bb2678fc00d8446d95858eb28cbe9fa7634e Mon Sep 17 00:00:00 2001 From: MrDham Date: Tue, 28 Apr 2020 23:11:32 +0200 Subject: [PATCH 14/14] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 186c199..3a0905f 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ Let's consider a Fade-in / Picth Variation / Fade-out sequence (I use right hand 2. Pitch variation - When right hand moves next to PITCH ANTENNA (ROD), PITCH BEND messages are generated (if activated) to reach exact pitch as long as pitch bend range will do. Beyond, a new NOTE ON followed by a NOTE OFF for the previous note are generated if legato mode is activated. Pitch bend range can be configured (1, 2, 7, 12 or 24 semitones) to align with synth's maximum capabilities. + When right hand moves next to PITCH ANTENNA (ROD), PITCH BEND messages are generated (if activated) to reach exact pitch as long as pitch bend range will do. Beyond, a new NOTE ON followed by a NOTE OFF for the previous note are generated if legato mode is activated. Pitch bend range can be configured (1, 2, 4, 5, 7, 12, 24 or 48 semitones) to align with synth's maximum capabilities. 3. Fade-Out @@ -158,7 +158,7 @@ I'll try to answer you if I can. ### LICENSE -Original project ,Open Theremin, was written by Urs Gaudenz, GaudiLabs, in 2016 +Original project, Open Theremin, was written by Urs Gaudenz, GaudiLabs, in 2016 GNU license. This Project inherits this 2016 GNU License. Check LICENSE file for more information