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:
0:a4d93cd4c30d
Child:
1:fd4f70088311
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Dec 21 13:32:18 2012 +0000
@@ -0,0 +1,620 @@
+//-------------------------------------------------------------
+//                  TI DAC8568  OSC-CV Converter
+//
+//   DAC8568 16bit Octal DAC http://www.ti.com/product/dac8568
+//
+//   referred to
+//   xshige's OSCReceiver
+//   http://mbed.org/users/xshige/programs/OSCReceiver/
+//   radiojunkbox's OSC-CV_Example
+//   http://mbed.org/users/radiojunkbox/code/KAMUI_OSC-CV_Example/
+//   Robin Price's Homebrew midi-cv box
+//   http://crx091081gb.net/?p=69
+//   Masahiro Hattori's TextLCD Module Functions
+//   http://www.eleclabo.com/denshi/device/lcd1602/gcram.html
+//   Dirk-Willem van Gulik's BonjourLib
+//   http://mbed.org/users/dirkx/code/BonjourLib/file/bb6472f455e8/services/mDNS
+//
+// Released under the MIT License: http://mbed.org/license/mit
+//-------------------------------------------------------------
+
+#pragma O3
+#pragma Otime
+
+#include "mbed.h"
+#include "TextLCD.h"       //edit "writeCommand" "writeData" protected -> public
+#include "EthernetNetIf.h"
+#include "HTTPServer.h"
+#include "mDNSResponder.h" // mDNS response to announce oneselve
+#include "UDPSocket.h"
+#include "OSCReceiver.h"
+#include <stdlib.h>
+#include <ctype.h>
+#include "math.h"
+
+//-------------------------------------------------------------
+// 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_QPen           4       // Pentatonic
+
+#define QUAN_RES1           116     // Quantize voltage Steps
+#define QUAN_RES2           69
+#define QUAN_RES3           68  
+#define QUAN_RES4           48
+
+#define MODE_NUM            5       // Modes
+
+#define SPI_RATE            40000000 // 40Mbps SPI Clock
+#define SCALING_N           38400.0
+#define INPUT_PORT          12345   // Input Port Number
+
+#define UPDATE_INTERVAL     60     // CV Update Interval (us)
+#define POLLING_INTERVAL    25     // Polling Interval (us)
+
+//-------------------------------------------------------------
+// DAC8568 Control Bits
+
+#define WRITE               0x00
+#define UPDATE              0x01
+#define WRITE_UPDATE_ALL    0x02       // LDAC Write to Selected Update All
+#define WRITE_UPDATE_N      0x03       // LDAC Write to Selected Update Respective
+#define POWER               0x04
+#define CLR                 0x05       // Clear Code Register
+#define WRITE_LDAC_REG      0x06
+#define RESET               0x07       // Software Reset DAC8568
+#define SETUP_INTERNAL_REF  0x08
+
+//------------------------------------------------------------- 
+
+#define _DISABLE            0
+#define _ENABLE             1
+
+//-------------------------------------------------------------
+// Functions
+
+void NetPoll(void);
+void InitOSCCV(void);
+void UpdateCV(unsigned char, unsigned char, unsigned int);
+void SetCV(void);
+void CheckSW(void);
+void CVMeter(unsigned int, unsigned int);
+void WriteCustomChar(unsigned char, unsigned char*);
+int  SetupEthNetIf(void);
+void onUDPSocketEvent(UDPSocketEvent);
+
+//-------------------------------------------------------------
+// Silentway Calibration Data Mapping
+// http://www.expert-sleepers.co.uk/silentway.html
+
+//  Chromatic Scale
+const float calibMap1[QUAN_RES1] = {
+0.00663080,   0.01433030,   0.02202980,   0.02972930,   0.03742880,
+0.04512830,   0.05282781,   0.06052731,   0.06822681,   0.07592630,
+0.08362581,   0.09132531,   0.09902481,   0.10672431,   0.11442380,
+0.12212331,   0.12951356,   0.13671936,   0.14392516,   0.15113096,
+0.15833676,   0.16554256,   0.17274836,   0.17995416,   0.18715996,
+0.19436575,   0.20157155,   0.20877735,   0.21598317,   0.22318897,
+0.23039477,   0.23760056,   0.24480636,   0.25202271,   0.25926629,
+0.26650983,   0.27375340,   0.28099698,   0.28824055,   0.29548413,
+0.30272770,   0.30997124,   0.31721482,   0.32445839,   0.33170196,
+0.33894554,   0.34618911,   0.35343266,   0.36067623,   0.36791980,
+0.37516347,   0.38241133,   0.38965923,   0.39690709,   0.40415496,
+0.41140282,   0.41865072,   0.42589858,   0.43314645,   0.44039431,
+0.44764221,   0.45489007,   0.46213794,   0.46938580,   0.47663370,
+0.48388156,   0.49112943,   0.49837729,   0.50566339,   0.51296055,
+0.52025765,   0.52755481,   0.53485191,   0.54214907,   0.54944617,
+0.55674326,   0.56404042,   0.57133752,   0.57863468,   0.58593178,
+0.59322894,   0.60052603,   0.60782319,   0.61512029,   0.62241745,
+0.62976688,   0.63714498,   0.64452308,   0.65190119,   0.65927929,
+0.66665739,   0.67403549,   0.68141359,   0.68879169,   0.69616979,
+0.70354789,   0.71092600,   0.71830410,   0.72568226,   0.73306036,
+0.74043846,   0.74781656,   0.75820577,   0.76986063,   0.78151548,
+0.79317033,   0.80482519,   0.81648004,   0.82813489,   0.83978975,
+0.85144460,   0.86309946,   0.87475431,   0.90686423,   0.93941462,
+0.97196496
+};
+
+//  Major Scale
+const float calibMap2[QUAN_RES2] = {
+0.00663080,   0.01433030,   0.02972930,   0.04512830,   0.05282781,
+0.06822681,   0.08362581,   0.09902481,   0.10672431,   0.12212331,
+0.13671936,   0.14392516,   0.15833676,   0.17274836,   0.18715996,
+0.19436575,   0.20877735,   0.22318897,   0.23039477,   0.24480636,
+0.25926629,   0.27375340,   0.28099698,   0.29548413,   0.30997124,
+0.31721482,   0.33170196,   0.34618911,   0.36067623,   0.36791980,
+0.38241133,   0.39690709,   0.40415496,   0.41865072,   0.43314645,
+0.44764221,   0.45489007,   0.46938580,   0.48388156,   0.49112943,
+0.50566339,   0.52025765,   0.53485191,   0.54214907,   0.55674326,
+0.57133752,   0.57863468,   0.59322894,   0.60782319,   0.62241745,
+0.62976688,   0.64452308,   0.65927929,   0.66665739,   0.68141359,
+0.69616979,   0.71092600,   0.71830410,   0.73306036,   0.74781656,
+0.75820577,   0.78151548,   0.80482519,   0.82813489,   0.83978975,
+0.86309946,   0.90686423,   0.93941462
+};
+
+//  Dorian Scale
+const float calibMap3[QUAN_RES3] = {
+0.00663080,   0.01433030,   0.02972930,   0.04512830,   0.06052731,
+0.06822681,   0.08362581,   0.09902481,   0.10672431,   0.12212331,
+0.13671936,   0.15113096,   0.15833676,   0.17274836,   0.18715996,
+0.19436575,   0.20877735,   0.22318897,   0.23760056,   0.24480636,
+0.25926629,   0.27375340,   0.28099698,   0.29548413,   0.30997124,
+0.32445839,   0.33170196,   0.34618911,   0.36067623,   0.36791980,
+0.38241133,   0.39690709,   0.41140282,   0.41865072,   0.43314645,
+0.44764221,   0.45489007,   0.46938580,   0.48388156,   0.49837729,
+0.50566339,   0.52025765,   0.53485191,   0.54214907,   0.55674326,
+0.57133752,   0.58593178,   0.59322894,   0.60782319,   0.62241745,
+0.62976688,   0.64452308,   0.65927929,   0.67403549,   0.68141359,
+0.69616979,   0.71092600,   0.71830410,   0.73306036,   0.74781656,
+0.76986063,   0.78151548,   0.80482519,   0.82813489,   0.83978975,
+0.86309946,   0.90686423,   0.97196496
+};
+
+//  Pentatonic Scale
+const float calibMap4[QUAN_RES4] = {
+0.01433030,   0.02972930,   0.04512830,   0.06822681,   0.08362581,
+0.10672431,   0.12212331,   0.13671936,   0.15833676,   0.17274836,
+0.19436575,   0.20877735,   0.22318897,   0.24480636,   0.25926629,
+0.28099698,   0.29548413,   0.30997124,   0.33170196,   0.34618911,
+0.36791980,   0.38241133,   0.39690709,   0.41865072,   0.43314645,
+0.45489007,   0.46938580,   0.48388156,   0.50566339,   0.52025765,
+0.54214907,   0.55674326,   0.57133752,   0.59322894,   0.60782319,
+0.62976688,   0.64452308,   0.65927929,   0.68141359,   0.69616979,
+0.71830410,   0.73306036,   0.74781656,   0.78151548,   0.80482519,
+0.83978975,   0.86309946,   0.90686423
+};
+
+//-------------------------------------------------------------
+// CV Meter Custom Character
+
+unsigned char str1[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F};
+unsigned char str2[8] = {0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F};
+unsigned char str3[8] = {0x00,0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F};
+unsigned char str4[8] = {0x00,0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F};
+unsigned char str5[8] = {0x00,0x00,0x00,0x1F,0x1F,0x1F,0x1F,0x1F};
+unsigned char str6[8] = {0x00,0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F};
+unsigned char str7[8] = {0x00,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F};
+unsigned char str8[8] = {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F};
+
+//-------------------------------------------------------------
+// Global Variables
+
+float           gOSC_cv[8];
+float           gGlide;
+unsigned int    gMode;
+
+//-------------------------------------------------------------
+// mbed Functions
+
+TextLCD gLCD(p9, p10, p11, p12, p13, p14); // rs, e, d4-d7
+
+SPI         gSPI(p5,p6,p7);     // SPI (p6 unconnected)
+DigitalOut  gSYNCMODE(p15);     // SYNC DAC8568
+DigitalOut  gLDAC(p16);         // LDAC DAC8568
+
+DigitalOut  gGATES[4] = {p21, p22, p23, p24};   // GateOut
+DigitalOut  gLEDS[4] = {p18, p19, p20, p28};    // LED
+DigitalOut  gCLOCKOUT(p25);             // ClockOut
+
+AnalogIn    gAIN(p17);  // Glide Potentiometer
+InterruptIn gSW(p30);   // Mode SW
+
+Ticker      gSetter;    // Ticker SetCV
+Ticker      gPoller;    // Ticker Polling
+
+// Ethernet
+EthernetNetIf   gEth;
+UDPSocket       gUdp;
+
+//-------------------------------------------------------------
+// main
+ 
+int main() 
+{ 
+    int i;
+        
+    if(SetupEthNetIf() == -1)
+    {
+        for(i = 0; i < 4; i++) 
+        {
+            gLEDS[i] = 1;
+            wait(0.25);
+        }
+        return -1;
+    }
+    
+    // mdns (Bonjour)
+    HTTPServer svr;
+    mDNSResponder mdns;
+    svr.addHandler<SimpleHandler>("/");
+    svr.bind(INPUT_PORT);
+    IpAddr ip = gEth.getIp();
+    mdns.announce(ip, "OSCtoCV", "_osc._udp", INPUT_PORT, "mbed(OSCtoCV)", (char *[]) {"path=/",NULL});
+    
+    InitOSCCV();
+    
+    // loop
+    while(1) 
+    {
+        gGlide = gAIN.read();
+        
+        gLCD.locate( 0, 1 );
+        gLCD.printf("12345678 G>>%3.2f", gGlide);
+        
+        switch(gMode) 
+            {
+                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_QPen: 
+                    gLCD.locate( 9, 0 );
+                    gLCD.printf("QUAN_P");  
+                    break;
+            }
+        //CV Meter
+        for(i = 0; i < 8; i++) 
+        {
+            CVMeter(i, (unsigned int)gOSC_cv[i]);
+        }
+    }
+}
+
+//-------------------------------------------------------------
+// Ethernet Polling
+
+void NetPoll()
+{
+    Net::poll();
+}
+
+//-------------------------------------------------------------
+// Initialize OSC-CV
+
+void InitOSCCV()
+{
+    // write custom char LCD CGRAM
+    WriteCustomChar(0x00, str1);
+    WriteCustomChar(0x01, str2);
+    WriteCustomChar(0x02, str3);
+    WriteCustomChar(0x03, str4);
+    WriteCustomChar(0x04, str5);
+    WriteCustomChar(0x05, str6);
+    WriteCustomChar(0x06, str7);
+    WriteCustomChar(0x07, str8);
+    
+    // Init. SPI
+    gLDAC = _ENABLE;
+    gSPI.format(8,1);       // Data word length 8bit, Mode=1
+    gSPI.frequency(SPI_RATE);
+    
+    UpdateCV(CLR, 0, 0);    // Ignore CLR Pin
+    
+    gSW.mode(PullUp);       //Use internal pullup for ModeSW
+    wait(.001);
+    
+    gMode = 0;
+    
+    gSW.fall(&CheckSW);     // InterruptIn falling edge(ModeSW)
+    gSetter.attach_us(&SetCV, UPDATE_INTERVAL);     // Ticker SetCV
+    gPoller.attach_us(&NetPoll, POLLING_INTERVAL);  // Ticker Polling
+    wait(0.5);
+}
+
+//-------------------------------------------------------------
+// SPI Transfer
+// DAC8568 data word length 32bit (8bit shift out)
+
+void UpdateCV(unsigned char control, unsigned char address, unsigned int data)
+{
+    typedef unsigned char byte;
+    
+    __disable_irq();
+    
+    switch(control)
+    {
+        case WRITE_UPDATE_N:
+        {   
+            gSYNCMODE = _DISABLE;
+            gSPI.write(00000000|control);           //padding at beginning of byte and control bits
+            gSPI.write(address << 4 | data >> 12);  //address(ch) bits
+            gSPI.write((data << 4) >> 8);           // middle 8 bits of data
+            gSPI.write((data << 12) >> 8 | 00001111);
+            gSYNCMODE = _ENABLE;
+            gLDAC = _DISABLE;
+            gLDAC = _ENABLE;
+            break;
+        }
+        case RESET:
+        {   
+            gSYNCMODE = _DISABLE;
+            gSPI.write(00000111);   //Software RESET
+            gSPI.write(00000000);
+            gSPI.write(00000000);
+            gSPI.write(00000000);
+            gSYNCMODE = _ENABLE;
+            break;
+        }
+        case CLR:
+        {            
+            gSYNCMODE = _DISABLE;
+            gSPI.write(00000101);   //CLR Register
+            gSPI.write(00000000);
+            gSPI.write(00000000);
+            gSPI.write(00000011);   //Ignore CLR Pin
+            gSYNCMODE = _ENABLE;
+            break;
+        }
+    }
+    
+    __enable_irq();
+}
+
+//-------------------------------------------------------------
+// Calculate CV
+
+void SetCV()
+{
+    static unsigned int ch;
+    float glidecv[8];
+    unsigned int cv[8];
+    static float oldcv[8];
+    static unsigned int quan;
+    float qcv;
+
+    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 = 65535 / 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 = 65535 / 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 = 65535 / 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_QPen:
+                
+                quan = 65535 / 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;
+        }
+        
+        ch++;
+        ch &= 0x07;
+}
+
+//-------------------------------------------------------------
+// Check SW
+
+void CheckSW() 
+{   
+    if (gMode < MODE_NUM - 1) 
+    {   
+        gMode++;
+                
+    } else {
+        
+        gMode = 0;
+    }
+}
+
+//-------------------------------------------------------------
+// CV meter
+
+void CVMeter(unsigned int ch, unsigned int level)
+{
+    unsigned int cvmeter;
+    
+    cvmeter = level / (SCALING_N / 7.9);
+    gLCD.locate ( ch, 0 );
+    gLCD.putc(cvmeter);     // put custom char
+}
+
+//-------------------------------------------------------------
+// Write command Custom Char LCD CGRAM(CV Meter) 
+
+void WriteCustomChar(unsigned char addr, unsigned char *c)
+{   
+    char cnt = 0;
+    addr = ((addr << 3) | 0x40);
+    
+    while(cnt < 0x08)
+    {
+        gLCD.writeCommand(addr | cnt);
+        gLCD.writeData(*c);
+        cnt++;
+        c++;
+    }
+}
+
+//-------------------------------------------------------------
+// Setup Ethernet port
+
+int SetupEthNetIf()
+{
+    gLCD.locate( 0, 1 );
+    gLCD.printf("Setting up...   ");
+//  printf("Setting up...\r\n");
+    EthernetErr ethErr = gEth.setup();
+    
+    if(ethErr)
+    {
+        gLCD.locate( 0, 1 );
+        gLCD.printf("Error in setup.");
+//  printf("Error %d in setup.\r\n", ethErr);
+        
+        return -1;
+    }
+//  printf("Setup OK\r\n");
+ 
+//  printf("IP address %d.%d.%d.%d\r\n", gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], gEth.getIp()[3]);
+    Host broadcast(IpAddr(gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], 255), INPUT_PORT, NULL);
+    gUdp.setOnEvent(&onUDPSocketEvent);
+    gUdp.bind(broadcast);
+ 
+    gLCD.locate( 0, 1 );
+    gLCD.printf("%03d.%03d.%03d.%03d", gEth.getIp()[0], gEth.getIp()[1], gEth.getIp()[2], gEth.getIp()[3]);
+    wait(2.0);
+    
+    return 0;
+}
+
+//-------------------------------------------------------------
+// Handller receive UDP Packet
+
+void onUDPSocketEvent(UDPSocketEvent e)
+{
+    union OSCarg msg[10];
+    static int num;
+    
+    switch(e)
+    {
+        case UDPSOCKET_READABLE: //The only event for now
+        char buf[256] = {0};
+        Host host;
+            
+        while( int len = gUdp.recvfrom( buf, 256, &host ))
+        {
+            if(len <= 0)  break;
+            //  printf("\r\nFrom %d.%d.%d.%d:\r\n", 
+            //  host.getIp()[0], host.getIp()[1], host.getIp()[2], host.getIp()[3]);
+            
+            getOSCmsg(buf,msg);
+            //  printf("OSCmsg: %s %s %f %i\r\n", 
+            //  msg[0].address, msg[1].typeTag, msg[2].f, msg[2].i);
+                
+            len = strlen(msg[0].address);
+            if(isdigit(msg[0].address[len-1])) num = msg[0].address[len-1] - '0' - 1;
+            else num = -1;
+            
+            unsigned int absv = msg[2].f * 1; //convert -0 to 0
+            
+            // address pattern SYNC & GATE (Type Tag int, float)
+            if((strncmp(msg[0].address,"/1/sync",7)==0) && (num == -1)) { 
+                if(num > 1) break;
+                if(absv >= 1 || msg[2].i >= 1) gCLOCKOUT = 1;
+                else                           gCLOCKOUT = 0;
+                break;
+    
+                } else if ((strncmp(msg[0].address,"/1/gate",7)==0) && (num != -1)) {
+                    if(num > 3) break;
+                    if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
+                    else                           gLEDS[num] = gGATES[num] = 0;
+                    break;
+                    // (touchOSC Control push, toggle)
+                    } else if ((strncmp(msg[0].address,"/1/push",7)==0) && (num != -1)) {     
+                        if(num > 3) break;
+                        if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
+                        else                           gLEDS[num] = gGATES[num] = 0;
+                        break;
+                    
+                        } else if ((strncmp(msg[0].address,"/1/toggle",9)==0) && (num != -1)) {
+                            if(num > 3) break;
+                            if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
+                            else                           gLEDS[num] = gGATES[num] = 0;
+                            break;
+                            } else if ((strncmp(msg[0].address,"/1/multipush",12)==0) && (num != -1)) {
+                                if(num > 3) break;
+                                if(absv >= 1 || msg[2].i >= 1) gLEDS[num] = gGATES[num] = 1;
+                                else                           gLEDS[num] = gGATES[num] = 0;
+                                break;
+                            }
+
+                        // address pattern CV (Type Tag float)
+                            if((strncmp(msg[0].address,"/1/cv",5)==0) && (num != -1)) {
+                                if(num > 7) break;
+                                if(msg[1].typeTag[1] == 'f') gOSC_cv[num] = msg[2].f * (SCALING_N);
+                                break;
+                            // (touchOSC Control fader, rotary, xy, multixy, multifader)
+                                } else if ((strncmp(msg[0].address,"/1/fader",8)==0) && (num != -1)) {
+                                    if(num > 7) break;                                                     
+                                    if(msg[1].typeTag[1] == 'f') gOSC_cv[num] = msg[2].f * (SCALING_N);
+                                    break;
+
+                                    } else if ((strncmp(msg[0].address,"/1/rotary",9)==0) && (num != -1)) { 
+                                        if(num > 7) break;
+                                        if(msg[1].typeTag[1] == 'f') gOSC_cv[num] = msg[2].f * (SCALING_N);
+                                        break;
+                    
+                                        } else if ((strncmp(msg[0].address,"/1/xy",5)==0) && (num != -1)) {
+                                            if(num > 7) break;
+                                            if(msg[1].typeTag[1] == 'f') gOSC_cv[num] = msg[2].f * (SCALING_N);
+                                            if(msg[1].typeTag[1] == 'f') gOSC_cv[++num] = msg[3].f * (SCALING_N);
+                                            break;
+                            
+                                            } else if ((strncmp(msg[0].address,"/1/multixy",10)==0) && (num != -1)) {
+                                                if(num > 7) break;
+                                                if(msg[1].typeTag[1] == 'f') gOSC_cv[num] = msg[2].f * (SCALING_N);
+                                                if(msg[1].typeTag[1] == 'f') gOSC_cv[++num] = msg[3].f * (SCALING_N);
+                                                break;
+                                
+                                                } else if ((strncmp(msg[0].address,"/1/multifader",13)==0) && (num != -1)) {
+                                                    if(num > 7) break;
+                                                    if(msg[1].typeTag[1] == 'f') gOSC_cv[num] = msg[2].f * (SCALING_N);
+                                                }
+                                            }
+                                        }                           
+                                    }