OSC-CV Converter

Dependencies:   Bonjour OSCReceiver TextLCD mbed mbed-rpc BurstSPI DebouncedInterrupt FastIO MIDI OSC OSCtoCV ClockControl

OSC to CV Converter

http://gtbts.tumblr.com/post/125663817741/osc-to-cv-converter-ver2-mbed-osctocv

/media/uploads/casiotone401/tumblr_nsg7y4pkfg1qlle9fo1_540.png

Revision:
14:977f3c5a4b4e
Parent:
13:3f42e451a8d3
Child:
15:3e4bc47d6a39
--- a/main.cpp	Sun Mar 09 04:52:52 2014 +0000
+++ b/main.cpp	Thu Oct 16 14:14:25 2014 +0000
@@ -35,24 +35,32 @@
 //-------------------------------------------------------------
 // Define
 
-#define MODE_LIN            0        // Linear      LinearCV Mode
-#define MODE_QChr           1        // Chromatic   Quantize Mode
-#define MODE_QMaj           2        // Major
-#define MODE_QDor           3        // Dorian
-#define MODE_Q5th           4        // 5th
-#define MODE_QWht           5        // Wholetone
-#define MODE_SEQ            6        // Sequencer & Shift Register
-#define MODE_Calb           7        // Calibration (for VCO Tuning)
+#define MODE_Calb           0        // Calibration (for VCO Tuning)
+#define MODE_LIN            1        // Linear LinearCV
+#define MODE_SEQ            2        // Mode Shift
+
+#define MODE_NUM            3        // Modes
 
-#define MODE_NUM            8        // Modes
+#define Lin                 0        // Linear LinearCV
+#define Chr                 1        // Chromatic
+#define Maj                 2        // Major
+#define M7                  3        // Major7
+#define Min7                4        // Minor7
+#define Dor                 5        // Dorian
+#define Min                 6        // Minor
+#define S5th                7        // 5th
+#define Wht                 8        // Wholetone
 
 #define QUAN_RES1           115      // Quantize voltage Steps
 #define QUAN_RES2           67
-#define QUAN_RES3           67  
-#define QUAN_RES4           17
-#define QUAN_RES5           57
+#define QUAN_RES3           39
+#define QUAN_RES4           48
+#define QUAN_RES5           67
+#define QUAN_RES6           67  
+#define QUAN_RES7           17
+#define QUAN_RES8           57
 
-#define SPI_RATE            40000000 // 40Mbps SPI Clock
+#define SPI_RATE            20000000 // 20Mbps SPI Clock
 #define SCALING_N           38400.0
 #define INPUT_PORT          12345    // Input Port Number
 
@@ -110,14 +118,18 @@
 inline void NetPoll(void);
 void InitOSCCV(void);
 inline void UpdateCV(int, int, const unsigned int*);
-int UpdateGate(int, int, int, int, bool);
-inline void SetCV(void);
-void SeqCV(int);
+inline void CalibCV(void);
+inline void SetSCV(void);
+inline void SeqCV(int);
+inline void Seq(void);
+inline int UpdateGate(int, int, int, int, bool);
+inline void UpdateSync(int, int, bool);
 void CheckModeSW(void);
 inline void CVMeter(int, const unsigned int*);
 void LCD();
 void WriteCustomChar(unsigned char, unsigned char*);
 int  SetupEthNetIf(void);
+inline size_t strlength(const char *);
 inline void onUDPSocketEvent(UDPSocketEvent);
 
 //-------------------------------------------------------------
@@ -126,89 +138,133 @@
 
 // Chromatic Scale
 const float calibMap1[QUAN_RES1] = {
-0.00559238,   0.01324014,   0.02088790,   0.02853566,   0.03618342, 
-0.04383118,   0.05147894,   0.05912671,   0.06677447,   0.07442223, 
-0.08206999,   0.08971775,   0.09736551,   0.10501327,   0.11266103, 
-0.12030879,   0.12775089,   0.13486665,   0.14198242,   0.14909819, 
-0.15621395,   0.16332972,   0.17044549,   0.17756125,   0.18467702, 
-0.19179279,   0.19890857,   0.20602433,   0.21314010,   0.22025587, 
-0.22737163,   0.23448740,   0.24160317,   0.24871893,   0.25587305, 
-0.26303557,   0.27019811,   0.27736065,   0.28452319,   0.29168573, 
-0.29884824,   0.30601078,   0.31317332,   0.32033587,   0.32749838, 
-0.33466092,   0.34182346,   0.34898600,   0.35614854,   0.36331105, 
-0.37047359,   0.37764084,   0.38481620,   0.39199156,   0.39916691, 
-0.40634227,   0.41351759,   0.42069295,   0.42786831,   0.43504366, 
-0.44221902,   0.44939438,   0.45656973,   0.46374506,   0.47092041, 
-0.47809577,   0.48527113,   0.49244648,   0.49962184,   0.50685716, 
-0.51409578,   0.52133441,   0.52857304,   0.53581166,   0.54305035, 
-0.55028898,   0.55752760,   0.56476623,   0.57200485,   0.57924354, 
-0.58648217,   0.59372079,   0.60095942,   0.60819805,   0.61543667, 
-0.62267536,   0.62996829,   0.63728690,   0.64460552,   0.65192413, 
-0.65924275,   0.66656137,   0.67387998,   0.68119860,   0.68851727, 
-0.69583589,   0.70315450,   0.71047312,   0.71779174,   0.72511035, 
-0.73242897,   0.73974758,   0.74706620,   0.75810421,   0.77163076, 
-0.78515732,   0.79868382,   0.81221038,   0.82573694,   0.83926344, 
-0.85279000,   0.86631656,   0.88188213,   0.90110368,   0.92032516
+0.00331362,   0.01097947,   0.01864531,   0.02631116,   0.03397701, 
+0.04164285,   0.04930869,   0.05697454,   0.06464039,   0.07230624, 
+0.07997208,   0.08763793,   0.09530377,   0.10296962,   0.11063547, 
+0.11830132,   0.12590303,   0.13306051,   0.14021800,   0.14737549, 
+0.15453300,   0.16169049,   0.16884798,   0.17600547,   0.18316296, 
+0.19032045,   0.19747795,   0.20463544,   0.21179293,   0.21895042, 
+0.22610791,   0.23326540,   0.24042290,   0.24758039,   0.25476459, 
+0.26196238,   0.26916021,   0.27635801,   0.28355584,   0.29075363, 
+0.29795146,   0.30514926,   0.31234708,   0.31954488,   0.32674271, 
+0.33394051,   0.34113833,   0.34833613,   0.35553396,   0.36273175, 
+0.36992958,   0.37713069,   0.38433966,   0.39154866,   0.39875764, 
+0.40596664,   0.41317561,   0.42038459,   0.42759359,   0.43480256, 
+0.44201156,   0.44922054,   0.45642951,   0.46363851,   0.47084749, 
+0.47805649,   0.48526546,   0.49247447,   0.49968344,   0.50694764, 
+0.51421440,   0.52148110,   0.52874786,   0.53601462,   0.54328132, 
+0.55054808,   0.55781484,   0.56508154,   0.57234830,   0.57961506, 
+0.58688176,   0.59414852,   0.60141528,   0.60868198,   0.61594874, 
+0.62321550,   0.63052768,   0.63785475,   0.64518178,   0.65250880, 
+0.65983582,   0.66716284,   0.67448992,   0.68181694,   0.68914396, 
+0.69647098,   0.70379800,   0.71112502,   0.71845210,   0.72577912, 
+0.73310614,   0.74043316,   0.74776018,   0.75861782,   0.77102989, 
+0.78344196,   0.79585397,   0.80826604,   0.82067811,   0.83309019, 
+0.84550226,   0.85791427,   0.87032634,   0.90296346,   0.94781560
+};
+
+//  Major Scale
+const float calibMap2[QUAN_RES2] = {
+0.01097947,   0.02631116,   0.03397701,   0.04930869,   0.06464039,
+0.07997208,   0.08763793,   0.10296962,   0.11830132,   0.12590303,
+0.14021800,   0.15453300,   0.16884798,   0.17600547,   0.19032045,
+0.20463544,   0.21179293,   0.22610791,   0.24042290,   0.25476459,
+0.26196238,   0.27635801,   0.29075363,   0.29795146,   0.31234708,
+0.32674271,   0.34113833,   0.34833613,   0.36273175,   0.37713069,
+0.38433966,   0.39875764,   0.41317561,   0.42759359,   0.43480256,
+0.44922054,   0.46363851,   0.47084749,   0.48526546,   0.49968344,
+0.51421440,   0.52148110,   0.53601462,   0.55054808,   0.55781484,
+0.57234830,   0.58688176,   0.60141528,   0.60868198,   0.62321550,
+0.63785475,   0.64518178,   0.65983582,   0.67448992,   0.68914396,
+0.69647098,   0.71112502,   0.72577912,   0.73310614,   0.74776018,
+0.77102989,   0.79585397,   0.80826604,   0.83309019,   0.85791427,
+0.87032634,   0.94781560
+};
+
+//  M7(9)
+const float calibMap3[QUAN_RES3] = {
+0.02631116,   0.04930869,   0.07997208,   0.08763793,   0.11830132,
+0.14021800,   0.16884798,   0.17600547,   0.20463544,   0.22610791,
+0.25476459,   0.26196238,   0.29075363,   0.31234708,   0.34113833,
+0.34833613,   0.37713069,   0.39875764,   0.42759359,   0.43480256,
+0.44922054,   0.46363851,   0.48526546,   0.51421440,   0.52148110,
+0.55054808,   0.57234830,   0.60141528,   0.60868198,   0.62321550,
+0.63785475,   0.65983582,   0.68914396,   0.69647098,   0.72577912,
+0.74776018,   0.79585397,   0.85791427,   0.94781560
 };
 
-// Major Scale
-const float calibMap2[QUAN_RES2] = {
-0.01324014,   0.02853566,   0.03618342,   0.05147894,   0.06677447,
-0.08206999,   0.08971775,   0.10501327,   0.12030879,   0.12775089,
-0.14198242,   0.15621395,   0.17044549,   0.17756125,   0.19179279,
-0.20602433,   0.21314010,   0.22737163,   0.24160317,   0.25587305,
-0.26303557,   0.27736065,   0.29168573,   0.29884824,   0.31317332,
-0.32749838,   0.34182346,   0.34898600,   0.36331105,   0.37764084,
-0.38481620,   0.39916691,   0.41351759,   0.42786831,   0.43504366,
-0.44939438,   0.46374506,   0.47092041,   0.48527113,   0.49962184,
-0.51409578,   0.52133441,   0.53581166,   0.55028898,   0.55752760,
-0.57200485,   0.58648217,   0.60095942,   0.60819805,   0.62267536,
-0.63728690,   0.64460552,   0.65924275,   0.67387998,   0.68851727,
-0.69583589,   0.71047312,   0.72511035,   0.73242897,   0.74706620,
-0.77163076,   0.79868382,   0.81221038,   0.83926344,   0.86631656,
-0.88188213,   0.92032516
+//  m7(9)
+const float calibMap4[QUAN_RES4] = {
+0.01097947,   0.01864531,   0.03397701,   0.04930869,   0.07230624,
+0.08763793,   0.11063547,   0.14021800,   0.16169049,   0.17600547,
+0.19747795,   0.22610791,   0.24042290,   0.24758039,   0.26196238,
+0.29075363,   0.31234708,   0.33394051,   0.34833613,   0.36273175,
+0.36992958,   0.38433966,   0.39875764,   0.41317561,   0.42038459,
+0.43480256,   0.45642951,   0.48526546,   0.50694764,   0.52148110,
+0.53601462,   0.55781484,   0.57234830,   0.59414852,   0.62321550,
+0.63052768,   0.64518178,   0.65983582,   0.68181694,   0.69647098,
+0.71845210,   0.74776018,   0.77102989,   0.78344196,   0.80826604,
+0.83309019,   0.84550226,   0.94781560
+};
+
+//  Dorian Scale
+const float calibMap5[QUAN_RES5] = {
+0.01097947,   0.02631116,   0.04164285,    0.04930869,   0.06464039,
+0.07997208,   0.08763793,   0.10296962,    0.11830132,   0.13306051,
+0.14021800,   0.15453300,   0.16884798,    0.17600547,   0.19032045,
+0.20463544,   0.21895042,   0.22610791,    0.24042290,   0.25476459,
+0.26196238,   0.27635801,   0.29075363,    0.30514926,   0.31234708,
+0.32674271,   0.34113833,   0.34833613,    0.36273175,   0.37713069,
+0.39154866,   0.39875764,   0.41317561,    0.42759359,   0.43480256,
+0.44922054,   0.46363851,   0.47805649,    0.48526546,   0.49968344,
+0.51421440,   0.52148110,   0.53601462,    0.55054808,   0.56508154,
+0.57234830,   0.58688176,   0.60141528,    0.60868198,   0.62321550,
+0.63785475,   0.65250880,   0.65983582,    0.67448992,   0.68914396,
+0.69647098,   0.71112502,   0.72577912,    0.74043316,   0.74776018,
+0.77102989,   0.79585397,   0.80826604,    0.83309019,   0.85791427,
+0.90296346,   0.94781560
 };
 
-// Dorian Scale
-const float calibMap3[QUAN_RES3] = {
-0.01324014,   0.02853566,   0.04383118,    0.05147894,   0.06677447,
-0.08206999,   0.08971775,   0.10501327,    0.12030879,   0.13486665,
-0.14198242,   0.15621395,   0.17044549,    0.17756125,   0.19179279,
-0.20602433,   0.22025587,   0.22737163,    0.24160317,   0.25587305,
-0.26303557,   0.27736065,   0.29168573,    0.30601078,   0.31317332,
-0.32749838,   0.34182346,   0.34898600,    0.36331105,   0.37764084,
-0.39199156,   0.39916691,   0.41351759,    0.42786831,   0.43504366,
-0.44939438,   0.46374506,   0.47809577,    0.48527113,   0.49962184,
-0.51409578,   0.52133441,   0.53581166,    0.55028898,   0.56476623,
-0.57200485,   0.58648217,   0.60095942,    0.60819805,   0.62267536,
-0.63728690,   0.65192413,   0.65924275,    0.67387998,   0.68851727,
-0.69583589,   0.71047312,   0.72511035,    0.73974758,   0.74706620,
-0.77163076,   0.79868382,   0.81221038,    0.83926344,   0.86631656,
-0.90110368,   0.92032516
+//  Minor Scale
+const float calibMap6[QUAN_RES6] = {
+0.01097947,   0.01864531,   0.03397701,   0.04930869,   0.05697454,
+0.07230624,   0.08763793,   0.10296962,   0.11063547,   0.12590303,
+0.14021800,   0.14737549,   0.16169049,   0.17600547,   0.19032045,
+0.19747795,   0.21179293,   0.22610791,   0.23326540,   0.24758039,
+0.26196238,   0.27635801,   0.28355584,   0.29795146,   0.31234708,
+0.31954488,   0.33394051,   0.34833613,   0.36273175,   0.36992958,
+0.38433966,   0.39875764,   0.40596664,   0.42038459,   0.43480256,
+0.44922054,   0.45642951,   0.47084749,   0.48526546,   0.49247447,
+0.50694764,   0.52148110,   0.53601462,   0.54328132,   0.55781484,
+0.57234830,   0.57961506,   0.59414852,   0.60868198,   0.62321550,
+0.63052768,   0.64518178,   0.65983582,   0.66716284,   0.68181694,
+0.69647098,   0.71112502,   0.71845210,   0.73310614,   0.74776018,
+0.75861782,   0.78344196,   0.80826604,   0.83309019,   0.84550226,
+0.87032634,   0.94781560
 };
 
-// 5th
-const float calibMap4[QUAN_RES4] = {
-0.01324014,  0.06677447,   0.12030879,    0.17044549,    0.22025587,
-0.27019811,  0.32033587,   0.37047359,    0.42069295,    0.47092041,
-0.52133441,  0.57200485,   0.62267536,    0.67387998,    0.72511035,
-0.79868382,  0.90110368
+//  5th
+const float calibMap7[QUAN_RES7] = {
+0.01097947,  0.06464039,   0.11830132,    0.16884798,    0.21895042,
+0.26916021,  0.31954488,   0.36992958,    0.42038459,    0.47084749,
+0.52148110,  0.57234830,   0.62321550,    0.67448992,    0.72577912,
+0.79585397,  0.90296346
 };
 
-// Whole tone
-const float calibMap5[QUAN_RES5] = {
-0.01324014,   0.02853566,   0.04383118,   0.05912671,    0.07442223,
-0.08971775,   0.10501327,   0.12030879,   0.13486665,    0.14909819,
-0.16332972,   0.17756125,   0.19179279,   0.20602433,    0.22025587,
-0.23448740,   0.24871893,   0.26303557,   0.27736065,    0.29168573,
-0.30601078,   0.32033587,   0.33466092,   0.34898600,    0.36331105,
-0.37764084,   0.39199156,   0.40634227,   0.42069295,    0.43504366,
-0.44939438,   0.46374506,   0.47809577,   0.49244648,    0.50685716,
-0.52133441,   0.53581166,   0.55028898,   0.56476623,    0.57924354,
-0.59372079,   0.60819805,   0.62267536,   0.63728690,    0.65192413,
-0.66656137,   0.68119860,   0.69583589,   0.71047312,    0.72511035,
-0.73974758,   0.75810421,   0.78515732,   0.81221038,    0.83926344,
-0.86631656,   0.90110368
+//  Whole tone
+const float calibMap8[QUAN_RES8] = {
+0.01097947,   0.02631116,   0.04164285,   0.05697454,    0.07230624,
+0.08763793,   0.10296962,   0.11830132,   0.13306051,    0.14737549,
+0.16169049,   0.17600547,   0.19032045,   0.20463544,    0.21895042,
+0.23326540,   0.24758039,   0.26196238,   0.27635801,    0.29075363,
+0.30514926,   0.31954488,   0.33394051,   0.34833613,    0.36273175,
+0.37713069,   0.39154866,   0.40596664,   0.42038459,    0.43480256,
+0.44922054,   0.46363851,   0.47805649,   0.49247447,    0.50694764,
+0.52148110,   0.53601462,   0.55054808,   0.56508154,    0.57961506,
+0.59414852,   0.60868198,   0.62321550,   0.63785475,    0.65250880,
+0.66716284,   0.68181694,   0.69647098,   0.71112502,    0.72577912,
+0.74043316,   0.75861782,   0.78344196,   0.80826604,    0.83309019,
+0.85791427,   0.90296346
 };
 
 //-------------------------------------------------------------
@@ -227,15 +283,14 @@
 // Global Variables
 
 float   gOSC_cv[8];
-float   gSeq_cv1[8];
-float   gSeq_cv2[8];
+float   gSeq_cv1[8], gSeq_cv2[8];
 float   gGlide;
-volatile int gMode;
+int     gMode;
 
 // Variables for Control
 
-volatile float gCtrl[2];
-volatile bool gCtrlSW[4] = {false};
+float gCtrl[6];
+bool gCtrlSW[6] = {false};
 
 //-------------------------------------------------------------
 // mbed Functions
@@ -266,7 +321,29 @@
 int main() 
 { 
     float pot, _pot;
-    int bpm, _bpm;
+    
+//Clock Up 110Mhz -------------------------------------------------------------
+    LPC_SC->PLL0CON   = 0x00;             /* PLL0 Disable                    */
+    LPC_SC->PLL0FEED  = 0xAA;
+    LPC_SC->PLL0FEED  = 0x55;
+ 
+    LPC_SC->CCLKCFG   = 0x00000003;       /* Select Clock Divisor = 4        */
+    LPC_SC->PLL0CFG   = 0x00020037;       /* configure PLL0                  */
+    LPC_SC->PLL0FEED  = 0xAA;             /* divide by 3 then multiply by 50 */
+    LPC_SC->PLL0FEED  = 0x55;             /* PLL0 frequency = 400,000,000    */
+ 
+    LPC_SC->PLL0CON   = 0x01;             /* PLL0 Enable                     */
+    LPC_SC->PLL0FEED  = 0xAA;
+    LPC_SC->PLL0FEED  = 0x55;
+    while (!(LPC_SC->PLL0STAT & (1<<26)));/* Wait for PLOCK0                 */
+ 
+    LPC_SC->PLL0CON   = 0x03;             /* PLL0 Enable & Connect           */
+    LPC_SC->PLL0FEED  = 0xAA;
+    LPC_SC->PLL0FEED  = 0x55;
+    while (!(LPC_SC->PLL0STAT & ((1<<25) | (1<<24))));/* Wait for PLLC0_STAT & PLLE0_STAT */
+    
+    SystemCoreClockUpdate();
+//-----------------------------------------------------------------------------
     
     if(SetupEthNetIf() == -1)
     {
@@ -290,9 +367,8 @@
     
     InitOSCCV();
     
-    pot = _pot = 0;
-    gGlide = gMode = 0;
-    bpm = _bpm = 120;
+    _pot = pot = gMode = 0;
+    gGlide = gCtrl[3] = gAIN.read();
         
     LCD();
     gLCD.locate( 0, 1 );
@@ -301,63 +377,41 @@
 // loop
     while(1) 
     {
-        gGlide = pot = gAIN.read();  // Glide Value
+        pot = gAIN.read();  // Glide Value
         
-        if(abs(pot - _pot) > 0.01f) 
+        if(pot == 0) 
         {
+            if(abs(gCtrl[3] - _pot) > 0.01f)
+            {
+                _pot = gGlide = gCtrl[3];
+            
+                gLCD.locate( 0, 1 );
+                gLCD.printf("12345678 G>>%3.2f", gGlide);
+            }
+        
+        } else if (abs(pot - _pot) > 0.01f) {
+            
+            gGlide = _pot = gAIN.read();
+            
             gLCD.locate( 0, 1 );
             gLCD.printf("12345678 G>>%3.2f", gGlide);
-            
-            _pot = gAIN.read();
         }
         
         switch(gMode)
-        {
-            case MODE_SEQ:
-                
-                bpm = (gCtrl[0] * 300 + 10);                        // Set BPM (gCtrl[0])
-            
-                if(abs(bpm - _bpm) > 1)
-                {
-                    UpdateGate(bpm, NRESET, GATEALL, 3, 0);         // Reset (if bpm change)
-                    _bpm = bpm;
-                    
-                } else if (gCtrlSW[0]) {                            // Stop (gCtrlSW[0])
-                        
-                    bpm = 0;
-                }
+        {               
+            case MODE_LIN:
             
-                if(!gCtrlSW[2] && !gCtrlSW[3])                      // Sequencer Mode1
-                {
-                    SeqCV((UpdateGate(bpm, N16TH, GATE1, 3, 0)));   // Shift Timming 16th note
-                    UpdateGate(bpm, N8TH, GATE2, 3, 0);
-                    UpdateGate(bpm, NDOT8, GATE3, 3, 0);
-                    UpdateGate(bpm, TRIP4, GATE4, 3, 0);
-
-                    break;
-                
-                } else if (gCtrlSW[2] && !gCtrlSW[3]) {            // Sequencer Mode2 (if gCtrlSW[2] ON)
+                SetSCV();
+                break;
                 
-                    SeqCV((UpdateGate(bpm, N16TH, GATE1, 3, 0)));  // Do shift ch 1~5
-                    SeqCV((UpdateGate(bpm, N4TH, GATE2, 3, 0)));   // Do shift  ch 6
-                    SeqCV((UpdateGate(bpm, NDOT4, GATE3, 3, 0)));  // Do shift  ch 7
-                    SeqCV((UpdateGate(bpm, TRIP8, GATE4, 3, 0)));  // Do shift ch 8
-                    
-                    break;
-                
-                } else if (gCtrlSW[3]) {                           // Sequencer Mode3 (if gCtrlSW[3] ON)
-                                                                   // (ch6,7,8, short loop)
-                    SeqCV((UpdateGate(bpm, N16TH, GATE1, 3, 0)));  // Do shift ch 1~5
-                    SeqCV((UpdateGate(bpm, N8TH, GATE2, 3, 0)));   // Do shift  ch 6
-                    SeqCV((UpdateGate(bpm, NDOT8, GATE3, 3, 0)));  // Do shift  ch 7
-                    SeqCV((UpdateGate(bpm, TRIP4, GATE4, 3, 0)));  // Do shift ch 8
-                    
-                    break;
-                }
+            case MODE_SEQ:
+        
+                Seq();
+                break;
                 
             default:
-            
-                SetCV();
+                
+                CalibCV();
                 break;
         }
     }
@@ -449,9 +503,437 @@
 }
 
 //-------------------------------------------------------------
+// Calibrate Mode
+
+inline void CalibCV()
+{
+    static int ch;
+    unsigned int cv;
+
+    switch(gMode) 
+        {
+            case MODE_Calb:
+                
+                cv = (unsigned int)((calibMap1[68] + 0.0007) * SCALING_N);    // A880.0Hz
+                
+                gGATES[0] = gGATES[1] = gGATES[2] = gGATES[3] = 1;
+                gLEDS[0] = gLEDS[1] = gLEDS[2] = gLEDS[3] = 1;
+                
+                UpdateCV(WRITE_UPDATE_N, ch, &cv);
+                break;
+        }
+
+        CVMeter(ch, &cv);
+        
+        ch++;
+        ch &= 0x07;
+}
+
+//-------------------------------------------------------------
+// Calculate CV
+
+inline void SetSCV()
+{
+    static int ch, quan, mode, mcount;
+    static float glidecv[8];
+    unsigned int cv;
+    static float qcv;
+
+    mode = (gCtrl[1] * 8);
+
+    switch(mode) 
+        {
+            case Lin:
+                
+                glidecv[ch] = glidecv[ch] * gGlide + gOSC_cv[ch] * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[ch];
+                    
+                UpdateCV(WRITE_UPDATE_N, ch, &cv);
+                break;
+                    
+            case Chr:
+            
+                quan = (40616 / QUAN_RES1);
+                qcv = calibMap1[(unsigned int)(gOSC_cv[ch] / quan)];
+                    
+                glidecv[ch] = glidecv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[ch];
+                        
+                UpdateCV(WRITE_UPDATE_N, ch, &cv);
+                break;
+                
+            case Maj:
+                
+                quan = (40616 / QUAN_RES2);
+                qcv = calibMap2[(unsigned int)(gOSC_cv[ch] / quan)];
+                    
+                glidecv[ch] = glidecv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[ch];
+                        
+                UpdateCV(WRITE_UPDATE_N, ch, &cv);
+                break;
+            
+            case M7:
+            
+                quan = (40616 / QUAN_RES3);
+                qcv = calibMap3[(unsigned int)(gOSC_cv[ch] / quan)];
+                    
+                glidecv[ch] = glidecv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[ch];
+                        
+                UpdateCV(WRITE_UPDATE_N, ch, &cv);
+                break;
+                
+            case Min7:
+                
+                quan = (40616 / QUAN_RES4);
+                qcv = calibMap4[(unsigned int)(gOSC_cv[ch] / quan)];
+                    
+                glidecv[ch] = glidecv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[ch];
+                        
+                UpdateCV(WRITE_UPDATE_N, ch, &cv);
+                break;
+                    
+            case Dor:
+                
+                quan = (40616 / QUAN_RES5);
+                qcv = calibMap5[(unsigned int)(gOSC_cv[ch] / quan)];
+                    
+                glidecv[ch] = glidecv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[ch];
+                        
+                UpdateCV(WRITE_UPDATE_N, ch, &cv);
+                break;
+        
+            case Min:
+                
+                quan = (40616 / QUAN_RES6);
+                qcv = calibMap6[(unsigned int)(gOSC_cv[ch] / quan)];
+                    
+                glidecv[ch] = glidecv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[ch];
+                        
+                UpdateCV(WRITE_UPDATE_N, ch, &cv);
+                break;
+                
+            case S5th:
+                
+                quan = (40616 / QUAN_RES7);
+                qcv = calibMap7[(unsigned int)(gOSC_cv[ch] / quan)];
+                    
+                glidecv[ch] = glidecv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[ch];
+                        
+                UpdateCV(WRITE_UPDATE_N, ch, &cv);
+                break;
+                
+            case Wht:
+                
+                quan = (40616 / QUAN_RES8);
+                qcv = calibMap8[(unsigned int)(gOSC_cv[ch] / quan)];
+                    
+                glidecv[ch] = glidecv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[ch];
+                        
+                UpdateCV(WRITE_UPDATE_N, ch, &cv);
+                break;
+        }
+
+        if(mcount % 16 == 0) 
+        {
+            CVMeter(ch, &cv);
+        }
+
+        ch++;
+        
+        if(ch &= 0x07)
+        {
+            mcount ++;
+            mcount &= 0x3F;
+        }
+        
+}
+
+//-------------------------------------------------------------
+// Sequence & Shift Out CV
+
+inline void SeqCV(int shift)
+{
+    int i, j;
+    static int ch, quan, mode;
+    static float glidecv[8], shiftcv[8];
+    unsigned int cv;
+    static float qcv;
+        
+    mode = (gCtrl[1] * 8);  // Sequencer Quantize Mode (gCtrl[1])
+    
+    switch(mode) 
+        {
+            case Lin:
+            
+                if(ch < 8)
+                {
+                    glidecv[0] = glidecv[0] * gGlide + gSeq_cv1[ch] * (1.0f - gGlide);
+                            
+                } else {
+                        
+                    glidecv[0] = glidecv[0] * gGlide + gSeq_cv2[ch-8] * (1.0f - gGlide);
+                }
+                
+                cv = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv);
+                break;
+                    
+            case Chr:
+            
+                quan = 40616 / QUAN_RES1;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap1[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap1[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                    
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv);
+                break;
+                
+            case Maj:
+                
+                quan = 40616 / QUAN_RES2;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap2[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap2[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                    
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv);
+                break;
+            
+            case M7:
+                
+                quan = 40616 / QUAN_RES3;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap3[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap3[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                    
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv);
+                break;
+                    
+            case Min7:
+                
+                quan = 40616 / QUAN_RES4;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap4[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap4[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv);
+                break;
+                            
+            case Dor:
+                
+                quan = 40616 / QUAN_RES5;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap5[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap5[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv);
+                break;
+                
+            case Min:
+                
+                quan = 40616 / QUAN_RES6;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap6[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap6[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv);
+                break;
+            
+            case S5th:
+                
+                quan = 40616 / QUAN_RES7;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap7[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap7[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv);
+                break;
+                
+            case Wht:
+                
+                quan = 40616 / QUAN_RES8;
+                
+                if(ch < 8)
+                {
+                    qcv = calibMap8[(unsigned int)(gSeq_cv1[ch] / quan)];
+                            
+                } else {
+                        
+                    qcv = calibMap8[(unsigned int)(gSeq_cv2[ch-8] / quan)];
+                }
+                    
+                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
+                cv = (unsigned int)glidecv[0];
+                
+                UpdateCV(WRITE_UPDATE_N, 0, &cv);
+                break;
+        }
+            
+        for(i = 1; i < 8; ++i)
+        {
+            glidecv[i] = glidecv[i] * gGlide + shiftcv[i] * (1.0f - gGlide);
+            cv = (unsigned int)glidecv[i];
+                
+            UpdateCV(WRITE_UPDATE_N, i, &cv);
+        }
+        
+        if(shift == 1)                  // GATE1
+        {
+            for(j = 1; j < 8; ++j)      // Shift ch2~8
+            {
+                shiftcv[j] = glidecv[j-1];
+            }
+        
+            ch++;
+            ch &= 0x0F;
+        }
+        
+     
+        if(ch < 8)
+        {
+            CVMeter(ch, &cv);
+                            
+        } else {
+                        
+            CVMeter((ch-8), &cv);
+        }
+
+}
+
+//-------------------------------------------------------------
+// Sequencer Mode
+
+inline void Seq()
+{
+    static int bpm, _bpm;
+    
+    bpm = (gCtrl[0] * 300 + 10);                    // Set BPM (gCtrl[0])
+            
+    if(abs(bpm - _bpm) > 1)
+    {
+        UpdateGate(bpm, NRESET, GATEALL, 3, false); // Reset (if bpm change)
+        _bpm = bpm;
+                    
+    } else if (gCtrlSW[0]) {                        // Stop (gCtrlSW[0])
+                        
+        bpm = 0;
+    }
+            
+    if(!gCtrlSW[2] && !gCtrlSW[3])                  // Sequencer Mode1
+    {
+        SeqCV((UpdateGate(bpm, N16TH, GATE1, 3, false)));   // Shift Timming 16th note
+        UpdateGate(bpm, N8TH, GATE2, 3, 0);
+        UpdateGate(bpm, NDOT8, GATE3, 3, 0);
+        UpdateGate(bpm, TRIP4, GATE4, 3, 0);            
+    }
+    
+}
+
+//-------------------------------------------------------------
+// Check SW
+
+void CheckModeSW()
+{   
+    wait(0.05);
+    
+    if(gMode < MODE_NUM - 1) 
+    {   
+        gMode++;
+            
+    } else {
+                
+        gMode = 0;
+    }
+    
+    gCLOCKOUT = gGATES[0] = gGATES[1] = gGATES[2] = gGATES[3] = 0;
+    gLEDS[0] = gLEDS[1] = gLEDS[2] = gLEDS[3] = 0;
+    
+    if(gMode == MODE_SEQ)
+    {
+        gTimer.start();     // Sequencer Timer Start
+        
+    } else {
+            
+        gTimer.stop();      // Sequencer Timer Stop
+    }
+    
+    LCD();
+}
+
+//-------------------------------------------------------------
 // GateOutSequence  beat(Note values) length(Gate time) invert(invert Gate)
 
-int UpdateGate(int bpm, int beat, int ch, int length, bool invert)
+inline int UpdateGate(int bpm, int beat, int ch, int length, bool invert)
 {
     int i;
     static int gatetime[4], oldgatetime[4];
@@ -460,9 +942,9 @@
     int time = gTimer.read_us();
     
     bar = (60.0f / bpm) * 4000000;
-    sync24 = (bar / 4) / 24;            // sync24 not tested
+    sync24 = (bar / 4) / 24; // sync24 not tested
     
-    switch(beat)                        // Calculate Note values 
+    switch(beat)                                // Calculate Note values 
         {
             case NDOT2:
                 
@@ -489,31 +971,6 @@
                 gatetime[ch] = (bar / 64) * 3;
                 break;
                 
-            case TRIP2:
-                
-                gatetime[ch] = bar / 3;
-                break;
-                
-            case TRIP4:
-                
-                gatetime[ch] = (bar / 2) / 3;
-                break;
-                
-            case TRIP8:
-                        
-                gatetime[ch] = (bar / 4) / 3;
-                break;
-            
-            case TRIP16:
-                
-                gatetime[ch] = (bar / 8) / 3;
-                break;
-            
-            case TRIP32:
-                
-                gatetime[ch] = (bar / 16) / 3;
-                break;
-                
             case NRESET:
                 
                 for(i = 0; i < GATEALL; ++i)    // Reset
@@ -575,426 +1032,51 @@
 }
 
 //-------------------------------------------------------------
-// Calculate CV
-
-inline void SetCV()
-{
-    static int ch, quan;
-    static float glidecv[8],  oldcv[8];
-    unsigned int cv[8];
-    float qcv;
+// SyncOut Sequence  beat(Note values) invert(invert Gate)
 
-    switch(gMode) 
-        {
-            case MODE_LIN:
-                
-                glidecv[ch] = oldcv[ch] * gGlide + gOSC_cv[ch] * (1.0f - gGlide);
-                oldcv[ch] = glidecv[ch];
-                cv[ch] = (unsigned int)glidecv[ch];
-                    
-                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
-                break;
-                    
-            case MODE_QChr:
-            
-                quan = 40616 / QUAN_RES1;
-                qcv = calibMap1[(unsigned int)(gOSC_cv[ch] / quan)];
-                    
-                glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                oldcv[ch] = glidecv[ch];
-                cv[ch] = (unsigned int)glidecv[ch];
-                        
-                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
-                break;
-                
-            case MODE_QMaj:
-                
-                quan = 40616 / QUAN_RES2;
-                qcv = calibMap2[(unsigned int)(gOSC_cv[ch] / quan)];
-                    
-                glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                oldcv[ch] = glidecv[ch];
-                cv[ch] = (unsigned int)glidecv[ch];
-                        
-                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
-                break;
-                    
-            case MODE_QDor:
-                
-                quan = 40616 / QUAN_RES3;
-                qcv = calibMap3[(unsigned int)(gOSC_cv[ch] / quan)];
-                    
-                glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                oldcv[ch] = glidecv[ch];
-                cv[ch] = (unsigned int)glidecv[ch];
-                        
-                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
-                break;
-                
-            case MODE_Q5th:
-                
-                quan = 40616 / QUAN_RES4;
-                qcv = calibMap4[(unsigned int)(gOSC_cv[ch] / quan)];
-                    
-                glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                oldcv[ch] = glidecv[ch];
-                cv[ch] = (unsigned int)glidecv[ch];
-                        
-                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
-                break;
-                
-            case MODE_QWht:
-                
-                quan = 40616 / QUAN_RES5;
-                qcv = calibMap5[(unsigned int)(gOSC_cv[ch] / quan)];
-                    
-                glidecv[ch] = oldcv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                oldcv[ch] = glidecv[ch];
-                cv[ch] = (unsigned int)glidecv[ch];
-                        
-                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
-                break;
-                
-            case MODE_Calb:
-                
-                cv[ch] = 19212;     // A880.0Hz
-                
-                gGATES[0] = gGATES[1] = gGATES[2] = gGATES[3] = 1;
-                gLEDS[0] = gLEDS[1] = gLEDS[2] = gLEDS[3] = 1;
-                
-                UpdateCV(WRITE_UPDATE_N, ch, &cv[ch]);
-                break;
-        }
-
-        CVMeter(ch, &cv[ch]);
-        
-        ch++;
-        ch &= 0x07;
-}
-
-//-------------------------------------------------------------
-// Sequence & Shift Out CV
-
-void SeqCV(int shift)
+inline void UpdateSync(int bpm, int beat, bool invert)
 {
-    int i, j, k;
-    static int ch, quan, SeqMode;
-    static int cnt1, cnt2, cnt3;
-    static int cntloop1, cntloop2, cntloop3;
-    static float glidecv[8], shiftcv[8];
-    static float buffercv[9], loopcv[3];
-    unsigned int cv[8];
-    float qcv;
-        
-    SeqMode = gCtrl[1] * (MODE_NUM - 3);    // Sequencer Quantize Mode (gCtrl[1])
+    static int bar, synctime, oldsynctime;
+    
+    int time = gTimer.read_us();
     
-    switch(SeqMode) 
-        {
-            case MODE_LIN:
-            
-                if(ch < 8)
-                {
-                    glidecv[0] = glidecv[0] * gGlide + gSeq_cv1[ch] * (1.0f - gGlide);
-                            
-                } else {
-                        
-                    glidecv[0] = glidecv[0] * gGlide + gSeq_cv2[ch-8] * (1.0f - gGlide);
-                }
-                
-                cv[0] = (unsigned int)glidecv[0];
-                
-                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
-                break;
-                    
-            case MODE_QChr:
-            
-                quan = 40616 / QUAN_RES1;
-                
-                if(ch < 8)
-                {
-                    qcv = calibMap1[(unsigned int)(gSeq_cv1[ch] / quan)];
-                            
-                } else {
-                        
-                    qcv = calibMap1[(unsigned int)(gSeq_cv2[ch-8] / quan)];
-                }
-                    
-                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                cv[0] = (unsigned int)glidecv[0];
-                
-                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
-                break;
-                
-            case MODE_QMaj:
-                
-                quan = 40616 / QUAN_RES2;
-                
-                if(ch < 8)
-                {
-                    qcv = calibMap2[(unsigned int)(gSeq_cv1[ch] / quan)];
-                            
-                } else {
-                        
-                    qcv = calibMap2[(unsigned int)(gSeq_cv2[ch-8] / quan)];
-                }
-                    
-                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                cv[0] = (unsigned int)glidecv[0];
-                
-                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
-                break;
-                    
-            case MODE_QDor:
-                
-                quan = 40616 / QUAN_RES3;
-                
-                if(ch < 8)
-                {
-                    qcv = calibMap3[(unsigned int)(gSeq_cv1[ch] / quan)];
-                            
-                } else {
-                        
-                    qcv = calibMap3[(unsigned int)(gSeq_cv2[ch-8] / quan)];
-                }
-                
-                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                cv[0] = (unsigned int)glidecv[0];
-                
-                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
-                break;
-                
-            case MODE_Q5th:
-                
-                quan = 40616 / QUAN_RES4;
-                
-                if(ch < 8)
-                {
-                    qcv = calibMap4[(unsigned int)(gSeq_cv1[ch] / quan)];
-                            
-                } else {
-                        
-                    qcv = calibMap4[(unsigned int)(gSeq_cv2[ch-8] / quan)];
-                }
-                
-                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                cv[0] = (unsigned int)glidecv[0];
-                
-                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
-                break;
-                
-            case MODE_QWht:
-                
-                quan = 40616 / QUAN_RES5;
-                
-                if(ch < 8)
-                {
-                    qcv = calibMap5[(unsigned int)(gSeq_cv1[ch] / quan)];
-                            
-                } else {
-                        
-                    qcv = calibMap5[(unsigned int)(gSeq_cv2[ch-8] / quan)];
-                }
-                    
-                glidecv[0] = glidecv[0] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);
-                cv[0] = (unsigned int)glidecv[0];
-                
-                UpdateCV(WRITE_UPDATE_N, 0, &cv[0]);
-                break;
-        }
-        
-        if(!gCtrlSW[2] && !gCtrlSW[3])      // Sequencer Mode1
-        {
-            for(i = 1; i < 8; ++i)
-            {
-                glidecv[i] = glidecv[i] * gGlide + shiftcv[i] * (1.0f - gGlide);
-                cv[i] = (unsigned int)glidecv[i];
-                    
-                UpdateCV(WRITE_UPDATE_N, i, &cv[i]);
-            }
-            
-            if(shift == 1)                  // GATE1
-            {
-                for(j = 1; j < 8; ++j)      // Shift ch2~8
-                {
-                    shiftcv[j] = glidecv[j-1];
-                }
-            
-                ch++;
-                ch &= 0x0F;
-            }
-            
-            cnt1 = cnt2 = cnt3 = 0;
-                    
-        } else if (gCtrlSW[2] && !gCtrlSW[3]) { // Sequencer Mode2
-                
-            for(i = 1; i < 8; ++i)
-            {
-                glidecv[i] = glidecv[i] * gGlide + shiftcv[i] * (1.0f - gGlide);
-                cv[i] = (unsigned int)glidecv[i];
-                    
-                UpdateCV(WRITE_UPDATE_N, i, &cv[i]);
-            }
-            
-            if(shift == 1)                      // GATE1
-            {
-                for(j = 1; j < 5; ++j)
-                {
-                    shiftcv[j] = glidecv[j-1];  // Shift ch2~5
-                }
-            
-                ch++;
-                ch &= 0x0F;
-                
-            } else if (shift == 2) {            // GATE2
-                
-                shiftcv[5] = glidecv[1];        // Shift ch6
-                
-            } else if (shift == 3) {            // GATE3
-                
-                shiftcv[6] = glidecv[2];        // Shift ch7
-                
-            } else if (shift == 4) {            // GATE4
-                
-                shiftcv[7] = glidecv[3];        // Shift ch8
-            }
-            
-            cnt1 = cnt2 = cnt3 = 0;
-                
-        } else if (gCtrlSW[3]) {                // Sequencer Mode3
-                
-            for(i = 1; i < 5; ++i)
-            {
-                glidecv[i] = glidecv[i] * gGlide + shiftcv[i] * (1.0f - gGlide);
-                cv[i] = (unsigned int)glidecv[i];
-                    
-                UpdateCV(WRITE_UPDATE_N, i, &cv[i]);            
-            }
-            
-            for(j = 5; j < 8; ++j)
-            {
-                glidecv[j] = glidecv[j] * gGlide + loopcv[j - 5] * (1.0f - gGlide);
-                cv[j] = (unsigned int)glidecv[j];
-                    
-                UpdateCV(WRITE_UPDATE_N, j, &cv[j]);            
-            }
-            
-            if(shift == 1)                      // GATE1
-            {
-                for(k = 1; k < 8; ++k)
-                {
-                    shiftcv[k] = glidecv[k-1];  // Shift ch2~5
-                }
-            
-                ch++;
-                ch &= 0x0F;
-                
-            } else if (shift == 2) {            // GATE2
-                
-                if(cnt1 < 4) 
-                {
-                    loopcv[0] = buffercv[cnt1] = shiftcv[4];
-                    
-                    cnt1++;
-                    
-                } else if (cnt1 >= 4) {
-                    
-                    loopcv[0] = buffercv[cntloop1];
-                    
-                    cntloop1++;
-                    cntloop1 &= 0x03;
-                }
-                        
-            } else if (shift == 3) {            // GATE3
-                
-                if(cnt2 < 3) 
-                {
-                    loopcv[1] = buffercv[(cnt2 + 4)] = shiftcv[5];
-                    
-                    cnt2++;
-                    
-                } else if (cnt2 >= 3) {
-                    
-                    loopcv[1] = buffercv[(cntloop2 + 4)];
-                    
-                    cntloop2++;
-                    cntloop2 &= 0x03;   
-                }
-                
-            } else if (shift == 4) {            // GATE4
-                
-                if(cnt3 < 2) 
-                {
-                    loopcv[2] = buffercv[(cnt3 + 7)] = shiftcv[6];
-                    
-                    cnt3++;
-                    
-                } else if (cnt3 >= 2) {
-                    
-                    loopcv[2] = buffercv[(cntloop3 + 7)];
-                    
-                    cntloop3++;
-                    cntloop3 &= 0x01;   
-                }
-            }
-            
-            if(gCtrlSW[1])                      // Update loop buffer (if gCtrlSW[1] ON)
-            {
-                cnt1 = cnt2 = cnt3 = 0;
-            } 
-        }
-        
-        if(ch < 8)
-        {
-            CVMeter(ch, &cv[0]);
-                            
-        } else {
-                        
-            CVMeter((ch-8), &cv[0]);
-        }
-}
+    bar = (60.0f / bpm) * 4000000;
 
-//-------------------------------------------------------------
-// Check SW
-
-void CheckModeSW()
-{   
-    wait(0.05);
+    synctime = bar / beat;
     
-    if(gMode < MODE_NUM - 1) 
-    {   
-        gMode++;
-            
-    } else {
-                
-        gMode = 0;
+    if(beat == NRESET) 
+    {
+        bar = synctime = oldsynctime = gCLOCKOUT = 0;
     }
     
-    gCLOCKOUT = gGATES[0] = gGATES[1] = gGATES[2] = gGATES[3] = 0;
-    gLEDS[0] = gLEDS[1] = gLEDS[2] = gLEDS[3] = 0;
-    
-    if(gMode == MODE_SEQ)
+    if((time > oldsynctime + synctime) && !invert)
     {
-        gTimer.start();     // Sequencer Timer Start
+        oldsynctime = time;
+        gCLOCKOUT = 1;
+        
+    } else if ((time > synctime - (synctime / 2)) && !invert) {
+    
+        gCLOCKOUT = 0;
         
-    } else {
-            
-        gTimer.stop();      // Sequencer Timer Stop
+    } else if((time > oldsynctime + synctime) && invert) {
+        
+        oldsynctime = time;
+        gCLOCKOUT = 0;
+        
+    } else if ((time > synctime - (synctime / 2)) && invert) {
+    
+        gCLOCKOUT = 1;
     }
     
-    LCD();
 }
 
 //-------------------------------------------------------------
 // CV meter
 
 inline void CVMeter(int ch, const unsigned int *level)
-{
-    int cvmeter;
-    
-    cvmeter = *level / (SCALING_N / 7.9f);
-        
+{       
     gLCD.locate ( ch, 0 );
-    gLCD.putc(cvmeter);     // put custom char
+    gLCD.putc(*level * 0.000205729);     // put custom char
 }
 
 //-------------------------------------------------------------
@@ -1004,44 +1086,19 @@
 {
     switch(gMode) 
         {
+            case MODE_Calb: 
+                gLCD.locate( 9, 0 );
+                gLCD.printf("Calibr "); 
+                break;
+                
             case MODE_LIN:
                 gLCD.locate( 9, 0 );
                 gLCD.printf("OSC-CV ");
                 break;
-                    
-            case MODE_QChr:
-                gLCD.locate( 9, 0 );
-                gLCD.printf("QUAN_C ");
-                break;
-                
-            case MODE_QMaj: 
-                gLCD.locate( 9, 0 );
-                gLCD.printf("QUAN_M ");
-                break;
-                    
-            case MODE_QDor: 
-                gLCD.locate( 9, 0 );
-                gLCD.printf("QUAN_D ");
-                break;
-                
-            case MODE_Q5th: 
-                gLCD.locate( 9, 0 );
-                gLCD.printf("QUAN_5 "); 
-                break;
-                    
-            case MODE_QWht: 
-                gLCD.locate( 9, 0 );
-                gLCD.printf("QUAN_W "); 
-                break;
-                
+
             case MODE_SEQ:  
                 gLCD.locate( 9, 0 );
-                gLCD.printf("ASRSEQ ");
-                break;
-                
-            case MODE_Calb: 
-                gLCD.locate( 9, 0 );
-                gLCD.printf("Calibr "); 
+                gLCD.printf("SHIFTCV");
                 break;
         }
 }
@@ -1096,6 +1153,24 @@
 }
 
 //-------------------------------------------------------------
+// Fast strlen function http://www.strchr.com/optimized_strlen_function
+
+size_t strlength(const char *s) 
+{
+    size_t len = 0;
+    
+    for(;;) 
+    {
+        unsigned x = *(unsigned*)s;
+        if((x & 0xFF) == 0) return len;
+        if((x & 0xFF00) == 0) return len + 1;
+        if((x & 0xFF0000) == 0) return len + 2;
+        if((x & 0xFF000000) == 0) return len + 3;
+        s += 4, len += 4;
+    }
+}
+
+//-------------------------------------------------------------
 // Handller receive UDP Packet
 
 inline void onUDPSocketEvent(UDPSocketEvent e)
@@ -1103,10 +1178,9 @@
     union OSCarg msg[10];
     char buf[768] = {0};
     int num, len;
-    volatile int recvlen;
-    volatile unsigned int absv;
-    volatile int messagepos = 0;
-    volatile bool bundleflag = false;
+    int recvlen;
+    int messagepos = 0;
+    bool bundleflag = false;
     
     Host host;
     
@@ -1152,37 +1226,35 @@
                     num = -1;
                 }
         
-                absv = msg[2].f + 0; //convert -0 to 0
-        
             // address pattern SYNC & GATE (Type Tag int, float)
                 if(!strncmp(msg[0].address+(len-1)-4, "sync", 4)) 
                 { 
-                    if(absv >= 1 || msg[2].i >= 1) gCLOCKOUT = 1;
-                    else                           gCLOCKOUT = 0;
+                    if(msg[2].i != 0) gCLOCKOUT = 1;
+                    else              gCLOCKOUT = 0;
                     continue;
 
                 } else if (!strncmp(msg[0].address+(len-1)-4, "gate", 4) && (num != -1)) {
-                    if(num > 4) continue;
-                    if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
-                    else                           gLEDS[num] = gGATES[num] = 0;
+                    if(num > 3) continue;
+                    if(msg[2].i != 0) gLEDS[num] = gGATES[num] = 1;
+                    else              gLEDS[num] = gGATES[num] = 0;
                     continue;
             // (touchOSC Control push, toggle)
                 } else if (!strncmp(msg[0].address+(len-1)-4, "push", 4) && (num != -1)) {     
                     if(num > 4) continue;
-                    if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
-                    else                           gLEDS[num] = gGATES[num] = 0;
+                    if(msg[2].i != 0) gLEDS[num] = gGATES[num] = 1;
+                    else              gLEDS[num] = gGATES[num] = 0;
                     continue;
                 
                 } else if (!strncmp(msg[0].address+(len-1)-6, "toggle", 6) && (num != -1)) {
                     if(num > 4) continue;
-                    if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
-                    else                           gLEDS[num] = gGATES[num] = 0;
+                    if(msg[2].i != 0) gLEDS[num] = gGATES[num] = 1;
+                    else              gLEDS[num] = gGATES[num] = 0;
                     continue;
                         
                 } else if (!strncmp(msg[0].address,"/1/multipush",12) && (num != -1)) {
                     if(num > 4) continue;
-                    if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
-                    else                           gLEDS[num] = gGATES[num] = 0;
+                    if(msg[2].i != 0) gLEDS[num] = gGATES[num] = 1;
+                    else              gLEDS[num] = gGATES[num] = 0;
                     continue;
             // address pattern CV (Type Tag float)  
                 } else if(!strncmp(msg[0].address+(len-1)-2, "cv", 2) && (num != -1)) {
@@ -1228,13 +1300,13 @@
                     continue;
             // address pattern for control
                 } else if (!strncmp(msg[0].address+(len-1)-6, "ctrlsw", 6) && (num != -1)) {
-                    if(num > 4) continue;
-                    if(absv >= 1 || msg[2].i >= 1) gCtrlSW[num] = true;
-                    else                           gCtrlSW[num] = false;
+                    if(num > 5) continue;
+                    if(msg[2].i != 0) gCtrlSW[num] = true;
+                    else              gCtrlSW[num] = false;
                     continue;
                                                 
                 } else if (!strncmp(msg[0].address+(len-1)-4, "ctrl", 4) && (num != -1)) {
-                    if(num > 3) continue;                                             
+                    if(num > 5) continue;                                             
                     if(msg[1].typeTag[1] == 'f') gCtrl[num] = msg[2].f;
                     continue;
                 }