diff --git a/src/Makefile b/src/Makefile
index 8612096..fff576f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -9,7 +9,7 @@ CMSIS_DIR = ../CMSIS_5/CMSIS
 OBJS = main.o kernel.o minidexed.o config.o userinterface.o uimenu.o \
        mididevice.o midikeyboard.o serialmididevice.o pckeyboard.o \
        sysexfileloader.o performanceconfig.o perftimer.o \
-       effect_platervbstereo.o effect_compressor.o
+       effect_mixer.o effect_compressor.o effect_platervbstereo.o
 
 include ./Synth_Dexed.mk
 include ./Rules.mk
diff --git a/src/effect_mixer.cpp b/src/effect_mixer.cpp
index 2a4861c..77d65fd 100644
--- a/src/effect_mixer.cpp
+++ b/src/effect_mixer.cpp
@@ -1,38 +1,22 @@
 // Taken from https://github.com/manicken/Audio/tree/templateMixer
 // Adapted for MiniDexed by Holger Wirtz <dcoredump@googlemail.com>
 
-/* Audio Library for Teensy 3.X
- * Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
- *
- * Development of this audio library was funded by PJRC.COM, LLC by sales of
- * Teensy and Audio Adaptor boards.  Please support PJRC's efforts to develop
- * open source software by purchasing Teensy or other PJRC products.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice, development funding notice, and this permission
- * notice shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
 #include <cstdlib>
 #include <stdint.h>
 #include <assert.h>
 #include "arm_math.h"
 #include "effect_mixer.h"
 
+template <int NN> AudioMixer<NN>::AudioMixer(uint16_t len)
+{
+    buffer_length=len;
+    for (uint8_t i=0; i<NN; i++)
+      multiplier[i] = UNITY_GAIN;
+
+    sumbufL=(float32_t*)malloc(sizeof(float32_t) * buffer_length);
+    arm_fill_f32(0.0, sumbufL, len);
+}
+
 template <int NN> void AudioMixer<NN>::gain(uint8_t channel, float32_t gain)
 {
     if (channel >= NN) return;
@@ -56,50 +40,108 @@ template <int NN> void AudioMixer<NN>::gain(float32_t gain)
     } 
 }
 
-template <int NN> void AudioMixer<NN>::doAddMix(uint8_t channel, float32_t* in, float32_t* out, uint16_t len)
+template <int NN> void AudioMixer<NN>::doAddMix(uint8_t channel, float32_t* in)
 {
-    float32_t* tmp=malloc(sizeof(float32_t)*len);
+    float32_t* tmp=malloc(sizeof(float32_t)*buffer_length);
 
     assert(tmp!=NULL);
+    assert(in);
+
+    if(multiplier[channel]!=UNITY_GAIN)
+      arm_scale_f32(in,multiplier[channel],tmp,buffer_length);
+    arm_add_f32(sumbufL, tmp, sumbufL, buffer_length);
 
-    arm_scale_f32(in,multiplier[channel],tmp,len);
-    arm_add_f32(out, tmp, out, len);
+    if(sumbufL)
+      arm_fill_f32(0.0, sumbufL, buffer_length);
 
     free(tmp);
 }
 
-template <int NN> void AudioMixer<NN>::get_mix(float32_t* buffer, uint16_t len)
+template <int NN> void AudioMixer<NN>::getMix(float32_t* buffer)
 {
     assert(buffer);
-    assert(sumbuf);
-    arm_copy_f32 (sumbuf, buffer, len);
+    assert(sumbufL);
+    arm_copy_f32(sumbufL, buffer, buffer_length);
+}
+
+template <int NN> AudioStereoMixer<NN>::AudioStereoMixer(uint16_t len) : AudioMixer<NN>(len)
+{
+    buffer_length=len;
+    for (uint8_t i=0; i<NN; i++)
+      panorama[i] = UNITY_PANORAMA;
+
+    sumbufR=(float32_t*)malloc(sizeof(float32_t) * buffer_length);
+    arm_fill_f32(0.0, sumbufR, buffer_length);
+}
+
+template <int NN> void AudioStereoMixer<NN>::pan(uint8_t channel, float32_t pan)
+{
+    if (channel >= NN) return;
+
+    if (pan > MAX_PANORAMA)
+         pan = MAX_PANORAMA;
+    else if (pan < MIN_PANORAMA)
+         pan = MIN_PANORAMA;
+    panorama[channel] = pan;
 }
 
-template <int NN> void AudioStereoMixer<NN>::doAddMix(uint8_t channel, float32_t* inL, float32_t* inR, float32_t* outL, float32_t* outR, uint16_t len)
+template <int NN> void AudioStereoMixer<NN>::doAddMix(uint8_t channel, float32_t* in)
 {
-    float32_t* tmp=malloc(sizeof(float32_t)*len);
+    float32_t* tmp=malloc(sizeof(float32_t)*buffer_length);
 
     assert(tmp!=NULL);
+    assert(in);
 
-    // panorama
-    for(uint16_t i=0;i<len;i++)
-    {
-	// left
-    	arm_scale_f32(inL,AudioMixer<NN>::multiplier[channel],tmp,len);
-    	arm_add_f32(outL, tmp, outL, len);
-	// right
-    	arm_scale_f32(inR,AudioMixer<NN>::multiplier[channel],tmp,len);
-    	arm_add_f32(outR, tmp, outR, len);
-    }
+    // left
+    arm_scale_f32(in, 1.0f-panorama[channel], tmp, buffer_length);
+    if(multiplier[channel]!=UNITY_GAIN)
+      arm_scale_f32(tmp,AudioMixer<NN>::multiplier[channel],tmp,buffer_length);
+    arm_add_f32(sumbufL, tmp, sumbufL, buffer_length);
+    // right
+    arm_scale_f32(in, panorama[channel], tmp, buffer_length);
+    if(multiplier[channel]!=UNITY_GAIN)
+       arm_scale_f32(tmp,AudioMixer<NN>::multiplier[channel],tmp,buffer_length);
+    arm_add_f32(sumbufR, tmp, sumbufR, buffer_length);
+
+    if(sumbufL)
+      arm_fill_f32(0.0, sumbufL, buffer_length);
+    if(sumbufR)
+      arm_fill_f32(0.0, sumbufR, buffer_length);
+
+    free(tmp);
+}
+
+template <int NN> void AudioStereoMixer<NN>::doAddMix(uint8_t channel, float32_t* inL, float32_t* inR)
+{
+    float32_t* tmp=malloc(sizeof(float32_t)*buffer_length);
+
+    assert(tmp!=NULL);
+    assert(inL);
+    assert(inR);
+
+    // left
+    if(multiplier[channel]!=UNITY_GAIN)
+      arm_scale_f32(inL,AudioMixer<NN>::multiplier[channel],tmp,buffer_length);
+    arm_add_f32(sumbufL, tmp, sumbufL, buffer_length);
+    // right
+    if(multiplier[channel]!=UNITY_GAIN)
+       arm_scale_f32(inR,AudioMixer<NN>::multiplier[channel],tmp,buffer_length);
+    arm_add_f32(sumbufR, tmp, sumbufR, buffer_length);
+
+    if(sumbufL)
+      arm_fill_f32(0.0, sumbufL, buffer_length);
+    if(sumbufR)
+      arm_fill_f32(0.0, sumbufR, buffer_length);
 
     free(tmp);
 }
 
-template <int NN> void AudioMixer<NN>::get_mix(float32_t* bufferL, float32_t bufferL, uint16_t len)
+template <int NN> void AudioStereoMixer<NN>::getMix(float32_t* bufferL, float32_t* bufferR)
 {
     assert(bufferR);
     assert(bufferL);
-    assert(sumbuf);
-    arm_copy_f32 (sumbuf[0], bufferL, len);
-    arm_copy_f32 (sumbuf[1], bufferR, len);
+    assert(sumbufL);
+    assert(sumbufR);
+    arm_copy_f32 (sumbufL, bufferL, buffer_length);
+    arm_copy_f32 (sumbufR, bufferR, buffer_length);
 }
diff --git a/src/effect_mixer.h b/src/effect_mixer.h
index 1df26ce..2a401a4 100644
--- a/src/effect_mixer.h
+++ b/src/effect_mixer.h
@@ -1,87 +1,45 @@
 // Taken from https://github.com/manicken/Audio/tree/templateMixer
 // Adapted for MiniDexed by Holger Wirtz <dcoredump@googlemail.com>
 
-/* Audio Library for Teensy 3.X
- * Copyright (c) 2014, Paul Stoffregen, paul@pjrc.com
- *
- * Development of this audio library was funded by PJRC.COM, LLC by sales of
- * Teensy and Audio Adaptor boards.  Please support PJRC's efforts to develop
- * open source software by purchasing Teensy or other PJRC products.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice, development funding notice, and this permission
- * notice shall be included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
- 
 #ifndef template_mixer_h_
 #define template_mixer_h_
 
 #include "arm_math.h"
 #include <stdint.h>
 
-#define UNITYGAIN 1.0f
+#define UNITY_GAIN 1.0f
 #define MAX_GAIN 1.0f
 #define MIN_GAIN 0.0f
+#define UNITY_PANORAMA 1.0f
+#define MAX_PANORAMA 1.0f
+#define MIN_PANORAMA 0.0f
 
 template <int NN> class AudioMixer
 {
 public:
-	AudioMixer(uint16_t len)
-        {
-	    for (uint8_t i=0; i<NN; i++)
-                multiplier[i] = UNITYGAIN;
-
-	    sumbufL=(float32_t*)malloc(sizeof(float32_t) * len);
-	    arm_fill_f32(0.0, sumbufL, len);
-	};
-        void doAddMix(uint8_t channel, float32_t* in, uint16_t len);
-	/**
-	 * this sets the individual gains
-	 * @param channel
-	 * @param gain
-	 */
+	AudioMixer(uint16_t len);
+        void doAddMix(uint8_t channel, float32_t* in);
 	void gain(uint8_t channel, float32_t gain);
-	/**
-	 * set all channels to specified gain
-	 * @param gain
-	 */
 	void gain(float32_t gain);
-	void get_mix(float32_t* buffer, uint16_t len);
-
+	void getMix(float32_t* buffer);
 protected:
 	float32_t multiplier[NN];
 	float32_t* sumbufL;
+	uint16_t buffer_length;
 };
 
 template <int NN> class AudioStereoMixer : public AudioMixer<NN>
 {
 public:
-	AudioStereoMixer(uint16_t len)
-	{
-	    AudioMixer<NN>(len);
-    	    for (uint8_t i=0; i<NN; i++)
-               	panorama[i] = 0.0;
-
-	    sumbufR=(float32_t*)malloc(sizeof(float32_t) * len);
-	    arm_fill_f32(0.0, sumbufR, len);
-	};
-	void doAddMix(uint8_t channel, float32_t* inL, float32_t* inR, uint16_t len);
-	void get_mix(float32_t* bufferL, float32_t* bufferR, uint16_t len);
+	AudioStereoMixer(uint16_t len);
+        void pan(uint8_t channel, float32_t pan);
+	void doAddMix(uint8_t channel, float32_t* in);
+	void doAddMix(uint8_t channel, float32_t* inL, float32_t* inR);
+	void getMix(float32_t* bufferL, float32_t* bufferR);
 protected:
+	using AudioMixer<NN>::sumbufL;
+	using AudioMixer<NN>::multiplier;
+	using AudioMixer<NN>::buffer_length;
 	float32_t panorama[NN];
 	float32_t* sumbufR;
 };
diff --git a/src/minidexed.cpp b/src/minidexed.cpp
index a242a6e..18d32c2 100644
--- a/src/minidexed.cpp
+++ b/src/minidexed.cpp
@@ -115,7 +115,7 @@ CMiniDexed::CMiniDexed (CConfig *pConfig, CInterruptSystem *pInterrupt,
 #endif
 
 	// BEGIN setup tg_mixer
-	//tg_mixer = new AudioStereoMixer<8>(pConfig->GetChunkSize());
+	tg_mixer = new AudioStereoMixer<8>(pConfig->GetChunkSize());
 	// END setup tgmixer
 
 	// BEGIN setup reverb
@@ -748,7 +748,6 @@ void CMiniDexed::ProcessSound (void)
 		//
 
 		// now mix the output of all TGs
-		float32_t SampleBuffer[2][nFrames];
 		uint8_t indexL=0, indexR=1;
 
 		if (m_bChannelsSwapped)
@@ -756,42 +755,29 @@ void CMiniDexed::ProcessSound (void)
 			indexL=1;
 			indexR=0;
 		}
-
-		// init left sum output
-		assert (SampleBuffer[0]!=NULL);
-		arm_fill_f32(0.0, SampleBuffer[0], nFrames);
-		// init right sum output
-		assert (SampleBuffer[1]!=NULL);
-		arm_fill_f32(0.0, SampleBuffer[1], nFrames);
 		
 		assert (CConfig::ToneGenerators == 8);
 
 		// BEGIN stereo panorama and TG mixing
 		for (uint8_t i = 0; i < CConfig::ToneGenerators; i++)
 		{
-			float32_t tmpBuffer[2][nFrames];
-
-			assert (tmpBuffer[0]!=NULL);
-			arm_fill_f32(0.0, tmpBuffer[0], nFrames);
-			assert (tmpBuffer[1]!=NULL);
-			arm_fill_f32(0.0, tmpBuffer[1], nFrames);
-
-			m_PanoramaSpinLock.Acquire ();
-			// calculate left panorama of this TG
-			arm_scale_f32(m_OutputLevel[i], 1.0f-m_fPan[i], tmpBuffer[0], nFrames);
-			// add left panorama output of this TG to sum output
-			arm_add_f32(SampleBuffer[indexL], tmpBuffer[0], SampleBuffer[indexL], nFrames);
-
-			// calculate right panorama of this TG
-			arm_scale_f32(m_OutputLevel[i], m_fPan[i], tmpBuffer[1], nFrames);
-			// add right panaorama output of this TG to sum output
-			arm_add_f32(SampleBuffer[indexR], tmpBuffer[1], SampleBuffer[indexR], nFrames);
-			//tg_mixer->doAddMix(i,tmpBuffer[0],tmpBuffer[1],nFrames);
-			m_PanoramaSpinLock.Release ();
+			tg_mixer->pan(i,m_fPan[i]);
+			tg_mixer->doAddMix(i,m_OutputLevel[i]);
 		}
 		// END stereo panorama and TG mixing
 
 		// BEGIN adding reverb
+		float32_t SampleBuffer[2][nFrames];
+
+		// init left sum output
+		assert (SampleBuffer[0]!=NULL);
+		arm_fill_f32(0.0, SampleBuffer[0], nFrames);
+		// init right sum output
+		assert (SampleBuffer[1]!=NULL);
+		arm_fill_f32(0.0, SampleBuffer[1], nFrames);
+
+                tg_mixer->getMix(SampleBuffer[indexL], SampleBuffer[indexR]);
+
 		if (m_nParameter[ParameterReverbEnable])
 		{
 			float32_t ReverbBuffer[2][nFrames];
diff --git a/src/minidexed.h b/src/minidexed.h
index f343879..2c22ece 100644
--- a/src/minidexed.h
+++ b/src/minidexed.h
@@ -42,7 +42,7 @@
 #include "common.h"
 #include "effect_platervbstereo.h"
 #include "effect_compressor.h"
-//#include "effect_mixer.h"
+#include "effect_mixer.h"
 
 class CMiniDexed
 #ifdef ARM_ALLOW_MULTI_CORE
@@ -176,7 +176,7 @@ private:
 	bool m_bProfileEnabled;
 
 	AudioEffectPlateReverb* reverb;
-	//AudioStereoMixer<8>* tg_mixer;
+	AudioStereoMixer<8>* tg_mixer;
 
 	CSpinLock m_PanoramaSpinLock;
 	CSpinLock m_ReverbSpinLock;