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
diff --git a/Open_Theremin_V3/SPImcpDAC.h b/Open_Theremin_V3/SPImcpDAC.h
new file mode 100644
index 0000000..57ab867
--- /dev/null
+++ b/Open_Theremin_V3/SPImcpDAC.h
@@ -0,0 +1,102 @@
+/* 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 <Arduino.h>
+
+// 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 |= SPI2X;          // double the SPI clock, ideally we get 8 MHz, so that a 16bit word goes out in 2us plus only a small overhead
+}
+
+static inline void SPImcpDACtransmit(uint16_t data)
+{
+  // Send highbyte and wait for complete
+  SPDR = highByte(data);
+  while (!(SPSR && _BV(SPIF)))
+    ;
+  // Send lowbyte and wait for complete
+  SPDR = lowByte(data);
+  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 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 80dc893..c0c3c3f 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"
@@ -42,13 +42,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();
@@ -327,7 +327,7 @@ static long pitchfn = 0;
   
   InitialisePitchMeasurement();
   interrupts();
-  mcpDacInit();
+  SPImcpDACinit();
 
   qMeasurement = GetQMeasurement();  // Measure Arudino clock frequency 
   Serial.print("Arudino Freq: ");
@@ -344,13 +344,13 @@ Serial.print("\nPitch Set Frequency: ");
 Serial.println(pitchfn);
 
 
-mcpDac2BSend(1600);
+SPImcpDAC2Bsend(1600);
 
-mcpDac2ASend(pitchXn0);
+SPImcpDAC2Asend(pitchXn0);
 delay(100);
 pitchfn0 = GetPitchMeasurement();
 
-mcpDac2ASend(pitchXn1);
+SPImcpDAC2Asend(pitchXn1);
 delay(100);
 pitchfn1 = GetPitchMeasurement();
 
@@ -362,11 +362,11 @@ Serial.println(pitchfn1);
  
 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;
 
@@ -411,7 +411,7 @@ static long volumefn = 0;
     
   InitialiseVolumeMeasurement();
   interrupts();
-  mcpDacInit();
+  SPImcpDACinit();
 
 
 volumeXn0 = 0;
@@ -424,12 +424,12 @@ Serial.print("\nVolume Set Frequency: ");
 Serial.println(volumefn);
 
 
-mcpDac2BSend(volumeXn0);
+SPImcpDAC2Bsend(volumeXn0);
 delay_NOP(44316);//44316=100ms
 
 volumefn0 = GetVolumeMeasurement();
 
-mcpDac2BSend(volumeXn1);
+SPImcpDAC2Bsend(volumeXn1);
 
 delay_NOP(44316);//44316=100ms
 volumefn1 = GetVolumeMeasurement();
@@ -443,11 +443,11 @@ Serial.println(volumefn1);
 
 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;
 
@@ -474,7 +474,7 @@ EEPROM.put(2,volumeXn0);
   HW_LED2_OFF;
   HW_LED1_ON;
 
-  Serial.println("\nCALIBRATION COMPTLETED\n");
+  Serial.println("\nCALIBRATION COMPLETED\n");
 }
 
 void Application::hzToAddVal(float hz) {
@@ -512,7 +512,3 @@ void Application::delay_NOP(unsigned long time) {
       __asm__ __volatile__ ("nop");
   }
 }
-
-
-
-
diff --git a/Open_Theremin_V3/ihandlers.cpp b/Open_Theremin_V3/ihandlers.cpp
index 8025fa8..4da4830 100644
--- a/Open_Theremin_V3/ihandlers.cpp
+++ b/Open_Theremin_V3/ihandlers.cpp
@@ -1,8 +1,9 @@
 #include "Arduino.h"
 
 #include "ihandlers.h"
-#include "mcpDac.h"
+#include "SPImcpDAC.h"
 #include "timer.h"
+#include "hw.h"
 #include "build.h"
 
 #include "theremin_sintable.c"
@@ -31,7 +32,7 @@ static const uint32_t MCP_DAC_BASE = 2047;
 #define PC_STATE      (PINB & (1<<PORTB0))
 
 // Added by ThF 20200419
-// #define TH_DEBUG 			// <-- comment this out for normal operation
+#define TH_DEBUG 			// <-- comment this out for normal operation
 // end
 
 #ifdef TH_DEBUG
@@ -126,12 +127,14 @@ static inline uint32_t mulsu_16_8(uint16_t a, uint8_t b)
 
 /* Externaly generated 31250 Hz Interrupt for WAVE generator (32us) */
 ISR (INT1_vect) {
-  // Interrupt takes up a total of max 25 us
-  
-  // Added by ThF 20200419
-  #ifdef TH_DEBUG
-    HW_LED2_ON;
-  #endif
+  // Interrupt takes up a total of 15us when not interrupted itself.
+// Added by ThF 20200419
+#ifdef TH_DEBUG
+  HW_LED2_ON;
+#endif
+
+	// Latch previously written DAC value:
+	SPImcpDAClatch();
 
 	disableInt1(); // Disable External Interrupt INT1 to avoid recursive interrupts
 	// Enable Interrupts to allow counter 1 interrupts
@@ -154,9 +157,11 @@ ISR (INT1_vect) {
   // multiply 16 bit wave number by 8 bit volume value (11.2us / 5.4us)
   scaledSample = MCP_DAC_BASE + (mulsu_16_8(waveSample, vScaledVolume) >> 8);
 
-  mcpDacSend(scaledSample);        //Send result to Digital to Analogue Converter (audio out) (9.6 us)
 
-  pointer = pointer + vPointerIncrement;    // increment table pointer (ca. 2us)
+	SPImcpDACsend(scaledSample); //Send result to Digital to Analogue Converter (audio out) (6 us)
+
+
+	pointer = pointer + vPointerIncrement; // increment table pointer (ca. 2us)
 
 #endif                          //CV play sound
   incrementTimer();               // update 32us timer
@@ -187,10 +192,8 @@ ISR (INT1_vect) {
 
   noInterrupts();
   enableInt1();
-
-  // Added by ThF 20200419
-  #ifdef TH_DEBUG
-	HW_LED2_OFF;
+#ifdef TH_DEBUG
+  HW_LED2_OFF;
 #endif
 }
 
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
- * <http://www.gnu.org/licenses/>.
- */
-/**
- *  Macros and inline functions for MCP4921 DAC
- */   
-#ifndef mcpDac_h
-#define mcpDac_h
-
-#include <avr/io.h>
-#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