Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: Bonjour OSCReceiver TextLCD mbed mbed-rpc BurstSPI DebouncedInterrupt FastIO MIDI OSC OSCtoCV ClockControl
Diff: main.cpp
- Revision:
- 20:a44f4a024902
- Parent:
- 19:467f98c51e2d
- Child:
- 21:2273c3676f1b
--- a/main.cpp Mon Jan 04 12:45:30 2016 +0000
+++ b/main.cpp Sat Jan 09 10:58:45 2016 +0000
@@ -1,6 +1,5 @@
//-------------------------------------------------------------
-// TI DAC8568 OSCtoCV Converter ver.2
-// http://gtbts.tumblr.com/post/125663817741/osc-to-cv-converter-ver2-mbed-osctocv
+// TI DAC8568 OSCtoCV Converter
//
// DAC8568 16bit Octal DAC http://www.ti.com/product/dac8568
//
@@ -24,8 +23,8 @@
#include "mbed.h"
#include "FastIO.h"
+//#include "FastAnalogIn.h"
#include "DebouncedInterrupt.h"
-#include "BurstSPI.h"
#include "TextLCD.h" //edit "writeCommand" "writeData" protected -> public
#include "EthernetNetIf.h"
#include "HTTPServer.h"
@@ -34,12 +33,17 @@
#include "OSCReceiver.h"
#include "mbedOSC.h"
#include "MIDI.h"
+#include "OSCtoCV.h"
+#include "OSCtoCV_Sequencer.h"
+#include "OSCtoCV_GateSequencer.h"
+#include "OSCtoCV_Euclidean.h"
+
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
//-------------------------------------------------------------
-// Define
+// Macros
#define MODE_Calb 0 // Calibration (for VCO Tuning)
#define MODE_OSC 1 // Mode OSCtoCV
@@ -49,292 +53,25 @@
#define MODE_TOTAL 5 // 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 SCALE_NUM 9 // Count Scale
-#define SCALE_AOUT (65535 / SCALE_NUM - 1)
-
-#define QUAN_RES1 116 // Quantize voltage Steps
-#define QUAN_RES2 68
-#define QUAN_RES3 46
-#define QUAN_RES4 40
-#define QUAN_RES5 68
-#define QUAN_RES6 68
-#define QUAN_RES7 16
-#define QUAN_RES8 58
-
-#define SPI_RATE 20000000 // 10Mbps SPI Clock
-#define SCALING_N 32256.0f
-#define INPUT_PORT 12345 // Input Port Number
-
-#define POLLING_INTERVAL 21 // Polling Interval (us)
-
-//-------------------------------------------------------------
-// DAC8568 Control Bits (See datasheet)
-
-#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
-
-//-------------------------------------------------------------
-// Gate Sequencer Macros
-
-#define _DISABLE 0
-#define _ENABLE 1
-
-#define GATE1 0
-#define GATE2 1
-#define GATE3 2
-#define GATE4 3
-#define SUBGATE 4
-#define GATE_TOTAL 5
-
-#define INVERT 1
-#define NON_INVERT 0
-
-#define GATESOUT_ON 0
-#define GATESOUT_OFF 1
-
-#define SYNC_ON 0
-#define SYNC_OFF 1
-
-//-------------------------------------------------------------
-// Beats (Note values)
-
-#define N1ST 1 // whole
-#define N2ND 2 // harf
-#define N4TH 4 // quarter
-#define N8TH 8
-#define N16TH 16
-#define N32TH 32
-#define N64TH 64
-#define NDOT2 3 // dotted
-#define NDOT4 7
-#define NDOT8 9
-#define NDOT16 11
-#define NDOT32 13
-#define TRIP2 3 // triplets
-#define TRIP4 6
-#define TRIP8 12
-#define TRIP16 24
-#define TRIP32 48
-#define SYNC24 96
-#define NRESET 0 // Gate Reset
-
-//-------------------------------------------------------------
-// Sequencer Macros
-
-#define STEP_INDICATOR_ADDRESS "/seqstep/" // touchOSC multi toggle(1x16(8)) for Current Step Indicator
-#define RESET_COUNTER_ADDRESS "/reset" // touchOSC label for Sequencer reset count
-
-//-------------------------------------------------------------
-// M185 Macros
-
-#define PULSE_COUNT_ADDRESS "/pulse" // /pulse1 ~ pulse8 M185 Pulse Count
-#define GATE_MODE_ADDRESS "/gatemode" // /gatemode1 ~ gatemode8 M185 Gate Mode
-
-#define SINGLE 0
-#define MUTE 1
-#define MULTI 2
-#define HOLD 3
-
-//-------------------------------------------------------------
-// Euclidean Sequencer Macros
-
-#define READ_DELAY 10 // for debouncing
-#define MAXCHANNELS 4
-#define MAXSTEPS 16 // max step length
-#define TRIGGER_DURATION 2200
-
-#define DISPLAY_UPDATE 2000 // how long active channel display is shown
-#define MATRIX_ADDRESS "/matrix/" // touchOSC multi toggle(9x16) OSC address
-
-
//-------------------------------------------------------------
// Functions
void InitOSCCV(void);
inline void NetPoll(void);
-inline float MapFloat(float, float, float, float, float);
-inline void UpdateCV(int, int, const unsigned int*);
-inline void CalibrationCV(void);
+void CalibrationCV(void);
inline void SetCV(void);
-inline void ShiftCVSeq(int, bool);
-inline void M185Seq(int, bool);
-inline void SendCtrlState(uint8_t, uint8_t, uint8_t);
-inline int GateSeq(int, int, int, int, bool, bool, bool);
inline int CheckBPM(void);
-inline void CheckModeSW(void);
+void CheckModeSW(void);
inline void LCD();
-inline void UpdateCVMeter(int, const unsigned int*);
void WriteCustomChar(unsigned char, unsigned char*);
int SetupEthNetIf(void);
-inline size_t strlength(const char *);
inline void onUDPSocketEvent(UDPSocketEvent);
-void EuclideanSeq(int, bool, bool);
-unsigned int Euclid(int, int, int);
-inline int BitRead(uint16_t, int);
-uint16_t BitReadOffset(int, uint16_t, uint16_t);
-unsigned int ConcatBin(unsigned int, unsigned int);
-void Sync(int, bool);
-int EncodeReadN(int);
-int EncodeReadK(int);
-int EncodeReadO(int);
-inline char * SetMatrixAddress(int, int, bool);
+
//-------------------------------------------------------------
-// Silentway Calibration Data Mapping
-// http://www.expert-sleepers.co.uk/silentway.html
-
-// Chromatic Scale
-const float calibMap1[QUAN_RES1] = {
-0.00076928, 0.00900736, 0.01724544, 0.02548352, 0.03372160,
-0.04195968, 0.05019776, 0.05843584, 0.06667392, 0.07491200,
-0.08315008, 0.09138816, 0.09962624, 0.10786432, 0.11610240,
-0.12434047, 0.13258974, 0.14083999, 0.14909023, 0.15734047,
-0.16559070, 0.17384095, 0.18209119, 0.19034143, 0.19859168,
-0.20684192, 0.21509215, 0.22334240, 0.23159264, 0.23984288,
-0.24809311, 0.25634655, 0.26460093, 0.27285531, 0.28110969,
-0.28936407, 0.29761845, 0.30587283, 0.31412721, 0.32238159,
-0.33063596, 0.33889034, 0.34714472, 0.35539910, 0.36365348,
-0.37190786, 0.38017464, 0.38844886, 0.39672306, 0.40499726,
-0.41327149, 0.42154568, 0.42981988, 0.43809411, 0.44636831,
-0.45464250, 0.46291673, 0.47119093, 0.47946513, 0.48773935,
-0.49601355, 0.50430328, 0.51260746, 0.52091163, 0.52921581,
-0.53751999, 0.54582411, 0.55412829, 0.56243247, 0.57073665,
-0.57904083, 0.58734500, 0.59564912, 0.60395330, 0.61225748,
-0.62056166, 0.62890279, 0.63728637, 0.64566994, 0.65405351,
-0.66243708, 0.67082065, 0.67920423, 0.68758780, 0.69597137,
-0.70435494, 0.71273851, 0.72112209, 0.72950566, 0.73788923,
-0.74627280, 0.75476575, 0.76334614, 0.77192658, 0.78050703,
-0.78908741, 0.79766786, 0.80624831, 0.81482869, 0.82340914,
-0.83198959, 0.84056997, 0.84915042, 0.85773087, 0.86631125,
-0.87489170, 0.88425636, 0.89363104, 0.90300572, 0.91238040,
-0.92175508, 0.93112975, 0.94050443, 0.94987911, 0.95925385,
-0.96862853
-};
-
-// Major Scale
-const float calibMap2[QUAN_RES2] = {
-calibMap1[0], calibMap1[2], calibMap1[4], calibMap1[5], calibMap1[7],
-calibMap1[9], calibMap1[11], calibMap1[12], calibMap1[14], calibMap1[16],
-calibMap1[17], calibMap1[19], calibMap1[21], calibMap1[23], calibMap1[24],
-calibMap1[26], calibMap1[28], calibMap1[29], calibMap1[31], calibMap1[33],
-calibMap1[35], calibMap1[36], calibMap1[38], calibMap1[40], calibMap1[41],
-calibMap1[43], calibMap1[45], calibMap1[47], calibMap1[48], calibMap1[50],
-calibMap1[52], calibMap1[53], calibMap1[55], calibMap1[57], calibMap1[59],
-calibMap1[60], calibMap1[62], calibMap1[64], calibMap1[65], calibMap1[67],
-calibMap1[69], calibMap1[71], calibMap1[72], calibMap1[74], calibMap1[76],
-calibMap1[77], calibMap1[79], calibMap1[81], calibMap1[83], calibMap1[84],
-calibMap1[86], calibMap1[88], calibMap1[89], calibMap1[91], calibMap1[93],
-calibMap1[95], calibMap1[96], calibMap1[98], calibMap1[100], calibMap1[101],
-calibMap1[103], calibMap1[105], calibMap1[107], calibMap1[108], calibMap1[110],
-calibMap1[112], calibMap1[113], calibMap1[115]
-};
-
-// M7(9)
-const float calibMap3[QUAN_RES3] = {
-calibMap1[0], calibMap1[4], calibMap1[7], calibMap1[11], calibMap1[12],
-calibMap1[14], calibMap1[16], calibMap1[19], calibMap1[23], calibMap1[24],
-calibMap1[26], calibMap1[28], calibMap1[31], calibMap1[35], calibMap1[36],
-calibMap1[38], calibMap1[40], calibMap1[43], calibMap1[47], calibMap1[48],
-calibMap1[50], calibMap1[52], calibMap1[55], calibMap1[59], calibMap1[60],
-calibMap1[62], calibMap1[64], calibMap1[67], calibMap1[71], calibMap1[72],
-calibMap1[76], calibMap1[79], calibMap1[83], calibMap1[84], calibMap1[86],
-calibMap1[88], calibMap1[91], calibMap1[95], calibMap1[96], calibMap1[100],
-calibMap1[103], calibMap1[107], calibMap1[108], calibMap1[110], calibMap1[112],
-calibMap1[115]
-};
+// Global Variables
-// m7(9)
-const float calibMap4[QUAN_RES4] = {
-calibMap1[0], calibMap1[3], calibMap1[7], calibMap1[10], calibMap1[12],
-calibMap1[15], calibMap1[19], calibMap1[22], calibMap1[26], calibMap1[27],
-calibMap1[31], calibMap1[34], calibMap1[36], calibMap1[38], calibMap1[39],
-calibMap1[43], calibMap1[46], calibMap1[50], calibMap1[53], calibMap1[55],
-calibMap1[58], calibMap1[60], calibMap1[63], calibMap1[67], calibMap1[70],
-calibMap1[72], calibMap1[74], calibMap1[75], calibMap1[79], calibMap1[82],
-calibMap1[86], calibMap1[89], calibMap1[91], calibMap1[94], calibMap1[96],
-calibMap1[99], calibMap1[103], calibMap1[106], calibMap1[110], calibMap1[113]
-};
-
-// Dorian Scale
-const float calibMap5[QUAN_RES5] = {
-calibMap1[0], calibMap1[2], calibMap1[3], calibMap1[5], calibMap1[7],
-calibMap1[9], calibMap1[10], calibMap1[12], calibMap1[14], calibMap1[15],
-calibMap1[17], calibMap1[19], calibMap1[20], calibMap1[21], calibMap1[24],
-calibMap1[26], calibMap1[27], calibMap1[29], calibMap1[31], calibMap1[33],
-calibMap1[34], calibMap1[36], calibMap1[38], calibMap1[39], calibMap1[41],
-calibMap1[43], calibMap1[45], calibMap1[46], calibMap1[48], calibMap1[50],
-calibMap1[51], calibMap1[53], calibMap1[55], calibMap1[57], calibMap1[58],
-calibMap1[60], calibMap1[62], calibMap1[63], calibMap1[65], calibMap1[67],
-calibMap1[69], calibMap1[70], calibMap1[72], calibMap1[74], calibMap1[75],
-calibMap1[77], calibMap1[79], calibMap1[81], calibMap1[82], calibMap1[84],
-calibMap1[86], calibMap1[87], calibMap1[89], calibMap1[91], calibMap1[93],
-calibMap1[94], calibMap1[96], calibMap1[98], calibMap1[99], calibMap1[101],
-calibMap1[103], calibMap1[105], calibMap1[106], calibMap1[108], calibMap1[110],
-calibMap1[111], calibMap1[113], calibMap1[115]
-};
-
-// Minor Scale
-const float calibMap6[QUAN_RES6] = {
-calibMap1[0], calibMap1[2], calibMap1[3], calibMap1[5], calibMap1[7],
-calibMap1[8], calibMap1[10], calibMap1[12], calibMap1[14], calibMap1[15],
-calibMap1[17], calibMap1[19], calibMap1[20], calibMap1[22], calibMap1[24],
-calibMap1[26], calibMap1[27], calibMap1[29], calibMap1[31], calibMap1[32],
-calibMap1[34], calibMap1[36], calibMap1[38], calibMap1[39], calibMap1[41],
-calibMap1[43], calibMap1[44], calibMap1[46], calibMap1[48], calibMap1[50],
-calibMap1[51], calibMap1[53], calibMap1[55], calibMap1[56], calibMap1[58],
-calibMap1[60], calibMap1[62], calibMap1[63], calibMap1[65], calibMap1[67],
-calibMap1[68], calibMap1[70], calibMap1[72], calibMap1[74], calibMap1[75],
-calibMap1[77], calibMap1[79], calibMap1[80], calibMap1[82], calibMap1[84],
-calibMap1[86], calibMap1[87], calibMap1[89], calibMap1[91], calibMap1[92],
-calibMap1[94], calibMap1[96], calibMap1[98], calibMap1[99], calibMap1[101],
-calibMap1[103], calibMap1[104], calibMap1[106], calibMap1[108], calibMap1[110],
-calibMap1[111], calibMap1[113], calibMap1[115]
-};
-
-// 5th
-const float calibMap7[QUAN_RES7] = {
-calibMap1[0], calibMap1[7], calibMap1[14], calibMap1[21], calibMap1[28],
-calibMap1[35], calibMap1[42], calibMap1[49], calibMap1[56], calibMap1[63],
-calibMap1[70], calibMap1[77], calibMap1[84], calibMap1[91], calibMap1[98],
-calibMap1[105]
-};
-
-// Whole tone
-const float calibMap8[QUAN_RES8] = {
-calibMap1[0], calibMap1[1], calibMap1[2], calibMap1[6], calibMap1[8],
-calibMap1[10], calibMap1[12], calibMap1[14], calibMap1[16], calibMap1[18],
-calibMap1[20], calibMap1[22], calibMap1[24], calibMap1[26], calibMap1[28],
-calibMap1[30], calibMap1[32], calibMap1[34], calibMap1[36], calibMap1[38],
-calibMap1[40], calibMap1[42], calibMap1[44], calibMap1[46], calibMap1[48],
-calibMap1[50], calibMap1[52], calibMap1[54], calibMap1[56], calibMap1[58],
-calibMap1[60], calibMap1[62], calibMap1[64], calibMap1[66], calibMap1[68],
-calibMap1[70], calibMap1[72], calibMap1[74], calibMap1[76], calibMap1[78],
-calibMap1[80], calibMap1[82], calibMap1[84], calibMap1[86], calibMap1[88],
-calibMap1[90], calibMap1[92], calibMap1[94], calibMap1[96], calibMap1[98],
-calibMap1[100], calibMap1[102], calibMap1[104], calibMap1[106], calibMap1[108],
-calibMap1[110], calibMap1[112], calibMap1[114]
-};
-
-//-------------------------------------------------------------
// 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};
@@ -344,113 +81,11 @@
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 gSeq_cv[16];
-float gGlide;
-int gMode;
-
-// Variables for Control
-/*
-gCtrl[0] /ctrl1 BPM
-gCtrl[1] /ctrl2 Quantize mode
-gCtrl[3] /ctrl4 Glide
-gCtrl[4] /ctrl5 M185 Reset Count
-
-gCtrlSW[0] /ctrlsw1 Sequencer STOP
-gCtrlSW[1] /ctrlsw2 Euclidean Sequencer reset
-gCtrlSW[2] /ctrlsw3 Sequencer Loop
-gCtrlSW[3] /ctrlsw4 Euclid Seq ON
-gCtrlSW[4] /ctrlsw5 ASR Analog Mode
-
-float gPulseCount[8] = {0}; M185 Pulse Count
-float gGateMode[8] = {0}; M185 Gate Mode
-float gSlide[8]; M185 Slide
-
-gEucA[0] /euca1 Euclidean Pattern length (n) ch1
-gEucA[1] /euca2 Euclidean Pattern density (k) ch1
-gEucA[2] /euca3 Euclidean Pattern offset (o) ch1
-gEucA[3] ~ [5] /euca4 ~ /euca6 Euclidean Pattern nko ch2
-gEucB[0] ~ [5] /eucb1 ~ /eucb6 Euclidean Pattern nko ch3 ~ ch4
-*/
-
-float gCtrl[8];
-bool gCtrlSW[8] = {false};
-
-// Variables for Sequencer
-float gPulseCount[8] = {0};
-float gGateMode[16] = {0};
-float gSlide[16];
-float gAccent[16] = {0};
-
-// Euclidean SEQ Variables
-float gEucA[6], gEucB[6];
-int channels = MAXCHANNELS;
-unsigned int beat_holder[MAXCHANNELS];
-unsigned int channelbeats[MAXCHANNELS][5];
-
-bool pulses_active = false; // is active while a beat pulse is playing
-bool lights_active = false;
-int pulse_length = TRIGGER_DURATION; //pulse length
+// OSCtoCV Converter Mode
+int gMode;
-unsigned int last_read[MAXCHANNELS];
-unsigned int last_changed[MAXCHANNELS];
-unsigned int last_sync;
-
-unsigned int euc_time;
-
-// Variables for Arduino
-uint16_t gArdCV[4];
-uint16_t gArdCtrl[4];
-bool gArdSW[4] = {false};
-
-//-------------------------------------------------------------
-// mbed Functions
-
-TextLCD gLCD(p9, p10, p11, p12, p13, p14); // rs, e, d4-d7
-
-BurstSPI gSPI(p5,p6,p7); // SPI (p6 unconnected)
-
-FastOut<p15> gSYNCMODE; // SYNC DAC8568
-FastOut<p16> gLDAC; // LDAC DAC8568
-
-DigitalOut gGATES[4] = {p21, p22, p23, p24}; // GateOut
-FastOut<p19> gSUBGATE; // SubGateOut
-FastOut<p25> gCLOCKOUT; // ClockOut
-
-AnalogOut gAOUT(p18);
-
-AnalogIn gAIN(p17);
-DebouncedInterrupt gSW(p30); // Mode SW
-
-// Serial for Arduino
-//BufferedSoftSerial ardSerial(p25, p26);
-MIDI midi(p28, p27);
-
-Timer gTimer; // Timer
-Ticker gPoller; // Ticker for Polling
-
-// Ethernet
-EthernetNetIf gEth;
-/* static ip
-EthernetNetIf gEth(
- IpAddr(192,168,1,2),
- IpAddr(255,255,255,0),
- IpAddr(192,168,1,1),
- IpAddr(192,168,1,1)
- );
-*/
-
-UDPSocket gUdp;
-
-// touchOSC Address
-uint8_t touchOSCAddress[] = { 192, 168, 1, 7 };
-int touchOSCPort = 9000;
-
-OSCClass osc;
-OSCMessage sendMes;
+// UDP Socket
+UDPSocket gUdp;
//-------------------------------------------------------------
// main
@@ -459,42 +94,10 @@
{
float pot, _pot;
int bpm;
+
+ InitOSCCV();
-//Clock Up --------------------------------------------------------------------
- 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 = 0x00020038; /* 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)
- {
- for (int i = 0; i < 4; ++i)
- {
- gGATES[i] = true;
- wait(0.25);
- }
-
- return -1;
- }
-
- InitOSCCV();
+ InitEuclideanSeq(); // Init Euclidean Sequencer
gCtrl[3] = _pot = pot = gMode = 0;
gGlide = gAIN.read();
@@ -575,11 +178,57 @@
}
//-------------------------------------------------------------
+// Ethernet Polling
+
+inline void NetPoll()
+{
+ Net::poll();
+}
+
+//-------------------------------------------------------------
// Initialize OSCtoCV
void InitOSCCV()
{
int i;
+
+//Clock Up --------------------------------------------------------------------
+ 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 = 0x00020038; /* 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();
+//-----------------------------------------------------------------------------
+
+ wait(0.5);
+
+// Setup Ethernet
+ SetupEthNetIf();
+
+// Announce mdnsResponder (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});
+
// Write custom char LCD CGRAM
WriteCustomChar(0x00, str1);
WriteCustomChar(0x01, str2);
@@ -596,33 +245,7 @@
gSPI.frequency(SPI_RATE);
UpdateCV(CLR, 0, 0); // Ignore CLR Pin
-
-// Initialize Euclid Sequencer
- channelbeats[0][0] = 16;
- channelbeats[0][1] = 8;
- channelbeats[0][2] = 0;
- channelbeats[0][3] = 0;
-
- channelbeats[1][0] = 16;
- channelbeats[1][1] = 9;
- channelbeats[1][2] = 0;
- channelbeats[1][3] = 0;
-
- channelbeats[2][0] = 16;
- channelbeats[2][1] = 7;
- channelbeats[2][2] = 0;
- channelbeats[2][3] = 0;
-
- channelbeats[3][0] = 16;
- channelbeats[3][1] = 9;
- channelbeats[3][2] = 0;
- channelbeats[3][3] = 0;
-
- for (i = 0; i < channels; ++i)
- {
- beat_holder[i] = Euclid(channelbeats[i][0], channelbeats[i][1], channelbeats[i][3]);
- }
-
+
// Init BPM
gCtrl[0] = 0.398f;
@@ -634,16 +257,7 @@
// Init M185 Reset Count
gCtrl[4] = 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});
-
// Set OSC message for sending
sendMes.setIp(touchOSCAddress);
sendMes.setPort(touchOSCPort);
@@ -652,78 +266,13 @@
wait(0.5);
gPoller.attach_us(&NetPoll, POLLING_INTERVAL); // Ticker Polling
- wait(1.5);
-
- // Begin Serial for Arduino
- //ardSerial.baud(115200);
-}
-
-//-------------------------------------------------------------
-// Ethernet Polling
-
-inline void NetPoll()
-{
- Net::poll();
-}
-
-//-------------------------------------------------------------
-// Map Function
-
-inline float MapFloat(float x, float in_min, float in_max, float out_min, float out_max)
-{
- return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
-}
-
-//-------------------------------------------------------------
-// SPI Transfer
-// DAC8568 data word length 32bit (8bit shift out)
-
-inline void UpdateCV(int control, int address, const unsigned int *data)
-{
-
- 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;
- }
+ wait(1.8);
}
//-------------------------------------------------------------
// Calibration Mode
-inline void CalibrationCV()
+void CalibrationCV()
{
static int ch;
unsigned int cv;
@@ -852,694 +401,6 @@
}
}
-//-------------------------------------------------------------
-// Sequence & Shift Out CV
-
-inline void ShiftCVSeq(int trigger, bool reset)
-{
- int i, j;
- static bool triggerState = false;
- static bool stepFoward = false;
- static bool _reset = false;
- static uint8_t currentStep;
- static int _resetCount, resetCount;
- static uint8_t gateMode;
- static uint8_t _gateMode[16];
- static uint8_t ch, qmode, amode;
- static float glidecv[8], shiftcv[8];
- unsigned int cv;
- static float qcv;
- static int jitterCount;
- static int jitter;
-
- qmode = (gCtrl[1] * (SCALE_NUM - 1.0f)); // Sequencer Quantize Mode (gCtrl[1])
- amode = SCALE_AOUT * qmode;
-
- gAOUT.write_u16(amode);
-
- switch (qmode)
- {
- case Lin:
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + gSeq_cv[currentStep] * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Chr:
-
- qcv = calibMap1[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES1 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Maj:
-
- qcv = calibMap2[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES2 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case M7:
-
- qcv = calibMap3[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES3 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Min7:
-
- qcv = calibMap4[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES4 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Dor:
-
- qcv = calibMap5[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES5 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Min:
-
- qcv = calibMap6[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES6 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case S5th:
-
- qcv = calibMap7[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES7 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Wht:
-
- qcv = calibMap8[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES8 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
- }
-
- if (!gCtrlSW[4])
- {
- jitter = 0;
-
- } else if (gCtrlSW[4] && jitterCount % 64 == 0) { // ASR Analog Mode
-
- jitter = (rand() % 100 - 50);
- }
-
- cv = (unsigned int)(glidecv[0] + jitter);
-
- UpdateCV(WRITE_UPDATE_N, 0, &cv);
-
- for (i = 1; i < 8; ++i)
- {
- glidecv[i] = glidecv[i] * gSlide[currentStep] + shiftcv[i] * (1.0f - gSlide[currentStep]);
- cv = (unsigned int)(glidecv[i] + jitter);
-
- UpdateCV(WRITE_UPDATE_N, i, &cv);
- }
-
- if (trigger && !triggerState) // trigger ON
- {
- stepFoward = triggerState = true;
-
- } else if (!trigger) { // trigger OFF
-
- if (gateMode != HOLD)
- {
- gGATES[0] = false;
- }
-
- triggerState = false;
- }
-
-// check & update touchOSC ctrl parameter
- if (_gateMode[ch] != (gGateMode[ch] * 3))
- {
- _gateMode[ch] = (gGateMode[ch] * 3);
-
- if (_gateMode[ch] == MULTI)
- {
- _gateMode[ch] = HOLD;
- }
-
- SendCtrlState(ch, _gateMode[ch], 8);
- }
-
- if (reset && !_reset) // Stop & Reset
- {
- sendMes.setTopAddress(SetMatrixAddress(0, currentStep, false));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
-
- currentStep = 0;
-
- sendMes.setTopAddress(SetMatrixAddress(0, currentStep, false));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- _reset = true;
-
- } else if (!reset) {
-
- _reset = false;
- }
-
- if (stepFoward)
- {
- if (gateMode != HOLD) // shift CV
- {
- for (j = 1; j < 8; ++j)
- {
- shiftcv[j] = glidecv[j-1];
- }
- }
-
- sendMes.setTopAddress(SetMatrixAddress(0, currentStep, false));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
-
- ++currentStep;
-
- if (gCtrlSW[2])
- {
- resetCount = 3;
-
- } else {
-
- resetCount = gCtrl[4] * 15;
- }
-
- if (_resetCount != resetCount)
- {
- sendMes.setTopAddress(RESET_COUNTER_ADDRESS);
- sendMes.setArgs("i", (resetCount + 1));
- osc.sendOsc(&sendMes);
- }
-
- if (currentStep > resetCount) // reset
- {
- currentStep = 0;
- }
-
- sendMes.setTopAddress(SetMatrixAddress(0, currentStep, false));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- if (currentStep < 8)
- {
- UpdateCVMeter(currentStep, &cv);
-
- } else {
-
- UpdateCVMeter((currentStep - 8), &cv);
- }
-
- gateMode = (gGateMode[currentStep] * 3);
-
- if (gateMode == MULTI) // omit MULTI mode
- {
- gateMode = HOLD;
- }
-
- if (gateMode != MUTE)
- {
- gGATES[0] = true;
- }
-
- if (gAccent[currentStep]) // accent
- {
- gGATES[2] = gGATES[3] = true;
-
- } else {
-
- gGATES[2] = gGATES[3] = false;
- }
-
- stepFoward = false;
- }
-
- ++ch;
- ch &= 0x0F;
-
- ++jitterCount;
- jitterCount &= 0x1FF;
-}
-
-//-------------------------------------------------------------
-// M185 Sequencer
-
-inline void M185Seq(int trigger, bool reset)
-{
- int i, j;
- static bool triggerState = false;
- static bool stepFoward = false;
- static bool _reset = false;
- static uint8_t currentStep;
- static int stepCount;
- static int _resetCount, resetCount;
- static uint8_t gateMode;
- static uint8_t _gateMode[8];
- static uint8_t _pulseCount[8];
- static uint8_t ch, qmode, amode;
- static float glidecv[8], shiftcv[8];
- unsigned int cv;
- static float qcv;
-
- qmode = (gCtrl[1] * (SCALE_NUM - 1)); // Sequencer Quantize Mode (gCtrl[1])
- amode = SCALE_AOUT * qmode;
-
- gAOUT.write_u16(amode);
-
- switch (qmode)
- {
- case Lin:
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + gSeq_cv[currentStep] * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Chr:
-
- qcv = calibMap1[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES1 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Maj:
-
- qcv = calibMap2[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES2 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case M7:
-
- qcv = calibMap3[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES3 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Min7:
-
- qcv = calibMap4[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES4 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Dor:
-
- qcv = calibMap5[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES5 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Min:
-
- qcv = calibMap6[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES6 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case S5th:
-
- qcv = calibMap7[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES7 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
-
- case Wht:
-
- qcv = calibMap8[(unsigned int)MapFloat(gSeq_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES8 - 1))];
-
- glidecv[0] = glidecv[0] * gSlide[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide[currentStep]);
-
- break;
- }
-
- cv = (unsigned int)glidecv[0];
-
- UpdateCV(WRITE_UPDATE_N, 0, &cv);
-
- for (i = 1; i < 8; ++i)
- {
- glidecv[i] = glidecv[i] * gSlide[currentStep] + shiftcv[i] * (1.0f - gSlide[currentStep]);
- cv = (unsigned int)glidecv[i];
-
- UpdateCV(WRITE_UPDATE_N, i, &cv);
- }
-
- if (trigger && !triggerState) // trigger ON
- {
- if (gateMode == MULTI)
- {
- gGATES[0] = true;
-
- sendMes.setTopAddress(SetMatrixAddress(0, currentStep, false));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
- }
-
- stepFoward = triggerState = true;
-
- } else if (!trigger) { // trigger OFF
-
- if (gateMode != HOLD)
- {
- gGATES[0] = false;
- }
-
- if (gateMode == MULTI)
- {
- sendMes.setTopAddress(SetMatrixAddress(0, currentStep, false));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
- }
-
- triggerState = false;
- }
-
-// check & update touchOSC ctrl parameter
- if (_gateMode[ch] != gGateMode[ch] * 3 || _pulseCount[ch] != gPulseCount[ch] * 7)
- {
- _gateMode[ch] = (gGateMode[ch] * 3);
- _pulseCount[ch] = (gPulseCount[ch] * 7);
-
- SendCtrlState(ch, _gateMode[ch], _pulseCount[ch]);
- }
-
- if (reset && !_reset) // Stop & Reset
- {
- sendMes.setTopAddress(SetMatrixAddress(0, currentStep, false));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
-
- currentStep = 0;
-
- sendMes.setTopAddress(SetMatrixAddress(0, currentStep, false));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- _reset = true;
-
- } else if (!reset) {
-
- _reset = false;
- }
-
- if (stepFoward)
- {
- if (gateMode != HOLD) // shift CV
- {
- for (j = 1; j < 8; ++j)
- {
- shiftcv[j] = glidecv[j-1];
- }
- }
-
- --stepCount;
-
- if (stepCount == -1)
- {
- sendMes.setTopAddress(SetMatrixAddress(0, currentStep, false));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
-
- ++currentStep;
-
- if (gCtrlSW[2])
- {
- resetCount = 3;
-
- } else {
-
- resetCount = gCtrl[4] * 7;
- }
-
- if (_resetCount != resetCount)
- {
- sendMes.setTopAddress(RESET_COUNTER_ADDRESS);
- sendMes.setArgs("i", (resetCount + 1));
- osc.sendOsc(&sendMes);
- }
-
- if (currentStep > resetCount) // reset
- {
- currentStep = 0;
- }
-
- sendMes.setTopAddress(SetMatrixAddress(0, currentStep, false));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- UpdateCVMeter(currentStep, &cv);
-
- // check Pulse Count & Gate Mode
- stepCount = (gPulseCount[currentStep] * 7);
-
- gateMode = (gGateMode[currentStep] * 3);
-
- if (gateMode != MUTE)
- {
- gGATES[0] = true;
- }
-
- }
-
- stepFoward = false;
- }
-
- ++ch;
- ch &= 0x07;
-}
-
-//-------------------------------------------------------------
-// Send M185 Sequencer Status to touchOSC
-
-inline void SendCtrlState(uint8_t step, uint8_t gateMode, uint8_t stepCount)
-{
- char pulseAddress[10] = PULSE_COUNT_ADDRESS;
- char gateModeAddress[10] = GATE_MODE_ADDRESS;
- char currentStep[2];
-
- sprintf(currentStep, "%d", step + 1);
-
- strcat(gateModeAddress, currentStep);
-
- if(stepCount != 8)
- {
- strcat(pulseAddress, currentStep);
- sendMes.setTopAddress(pulseAddress);
- sendMes.setArgs("i", (stepCount + 1));
- osc.sendOsc(&sendMes);
- }
-
- sendMes.setTopAddress(gateModeAddress);
-
- switch (gateMode)
- {
- case SINGLE:
-
- sendMes.setArgs("s", "|");
-
- break;
-
- case MUTE:
-
- sendMes.setArgs("s", "O");
-
- break;
-
- case MULTI:
-
- sendMes.setArgs("s", "||");
-
- break;
-
- case HOLD:
-
- sendMes.setArgs("s", "|-");
-
- break;
- }
-
- osc.sendOsc(&sendMes);
-}
-
-//-------------------------------------------------------------
-// Gate Sequencer beat(Note values) length(Gate time) invert(invert Gate)
-
-inline int GateSeq(int bpm, int beat, int ch, int length, bool invert, bool gatesoff, bool syncoff)
-{
- int i;
- static int gatetime[GATE_TOTAL], oldgatetime[GATE_TOTAL];
- static int _bpm, bar, sync24, oldsynctime;
-
- int time = gTimer.read_us();
-
- if (_bpm != bpm)
- {
- if (!bpm)
- {
- beat = NRESET;
-
- } else {
-
- bar = (60.0f / bpm) * 4000000;
- //sync24 = (bar / 4) / 24; // sync24 not tested
-
- _bpm = bpm;
- }
- }
-
- switch (beat) // Calculate Note values
- {
- case NDOT2:
-
- gatetime[ch] = (bar / 4) * 3;
- break;
-
- case NDOT4:
-
- gatetime[ch] = (bar / 8) * 3;
- break;
-
- case NDOT8:
-
- gatetime[ch] = (bar / 16) * 3;
- break;
-
- case NDOT16:
-
- gatetime[ch] = (bar / 32) * 3;
- break;
-
- case NDOT32:
-
- gatetime[ch] = (bar / 64) * 3;
- break;
-
- case NRESET:
-
- gTimer.reset();
-
- for (i = 0; i < GATE_TOTAL; ++i) // Reset
- {
- oldsynctime = oldgatetime[i] = gatetime[i] = NRESET;
- }
-
- return 0;
-
- default:
-
- gatetime[ch] = bar / beat;
- sync24 = bar / 16;
- break;
- }
-
- if (time > oldsynctime + sync24) // sync24 not tested
- {
- if (!syncoff)
- {
- oldsynctime = time;
- gCLOCKOUT = true;
-
- midi.sendRealTime(Clock); // MIDI Clock
- }
-
- } else if (time > oldsynctime - (sync24 - 2)) {
-
- if (!syncoff)
- {
- gCLOCKOUT = false;
- }
- }
-
- if (ch == GATE_TOTAL)
- {
- return -1;
-
- } else if (time > oldgatetime[ch] + gatetime[ch] && !invert) {
-
- oldgatetime[ch] = time;
-
- if (!gatesoff)
- {
- gGATES[ch] = true;
-
- } else if (ch == SUBGATE) {
-
- gSUBGATE = true;
- }
-
- return 1;
-
- } else if (time > oldgatetime[ch] + gatetime[ch] && invert) {
-
- oldgatetime[ch] = time;
-
- if (!gatesoff)
- {
- gGATES[ch] = false;
-
- } else if (ch == SUBGATE) {
-
- gSUBGATE = false;
- }
-
- return 0;
-
- } else if (time > oldgatetime[ch] + (gatetime[ch] - gatetime[ch] / length) && !invert) {
-
- if (!gatesoff)
- {
- gGATES[ch] = false;
-
- } else if (ch == SUBGATE) {
-
- gSUBGATE = false;
- }
-
- return 0;
-
- } else if (time > oldgatetime[ch] + (gatetime[ch] - gatetime[ch] / length) && invert) {
-
- if (!gatesoff)
- {
- gGATES[ch] = true;
-
- } else if (ch == SUBGATE) {
-
- gSUBGATE = true;
- }
-
- return 1;
-
- } else {
-
- return -1;
- }
-}
-
//-------------------------------------------------------------
// Check BPM
@@ -1556,20 +417,7 @@
return bpm;
}
- if (!gCtrl[0])
- {
- bpm = gArdCtrl[0] * 0.25f + 5;
-
- if (abs(bpm - _bpm) > 1)
- {
- _bpm = bpm;
-
- sendMes.setTopAddress("/bpm");
- sendMes.setArgs("i", bpm);
- osc.sendOsc(&sendMes);
- }
-
- } else if (gCtrl[0]) {
+ if (gCtrl[0]) {
bpm = (gCtrl[0] * 240 + 5);
@@ -1589,7 +437,7 @@
//-------------------------------------------------------------
// Check Mode SW
-inline void CheckModeSW()
+void CheckModeSW()
{
if (gMode < MODE_TOTAL - 1)
{
@@ -1773,15 +621,6 @@
}
-//-------------------------------------------------------------
-// CV Meter
-
-inline void UpdateCVMeter(int ch, const unsigned int *level)
-{
- gLCD.locate ( ch, 0 );
- gLCD.putc(*level * 0.0002192f); // put custom char
-}
-
//-------------------------------------------------------------
// Write command Custom Char LCD CGRAM for CV Meter)
@@ -1833,23 +672,6 @@
return 0;
}
-//-------------------------------------------------------------
-// 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 OSC UDP Packet
@@ -2010,6 +832,22 @@
gEucB[num] = msg[2].f;
continue;
+ } else if (!strncmp(msg[0].address + (len - offset) - 3, "acv", 3) && (num != -1)) {
+ if (num > 3) continue;
+ gArd_cv[num] = msg[2].f * (SCALING_N);
+ continue;
+
+ } else if (!strncmp(msg[0].address + (len - offset) - 3, "pot", 3) && (num != -1)) {
+ if (num > 2) continue;
+ gArdPot[num] = msg[2].f;
+ continue;
+
+ } else if (!strncmp(msg[0].address + (len - offset) - 2, "sw", 2) && (num != -1)) {
+ if (num > 2) continue;
+ if (msg[2].i != 0) gArdSW[num] = true;
+ else gArdSW[num] = false;
+ continue;
+
} else {
continue;
}
@@ -2018,832 +856,3 @@
}
}
-//-------------------------------------------------------------
-// Euclidean Sequencer
-
-void EuclideanSeq(int trigger, bool reset, bool gatesoff) {
- /*
- What's in the loop:
- Update euc_time variable
- Check to see if it is euc_time go go to sleep
- Changes routine - update beat_holder when channelbeats changes - triggered by changes == true
- Trigger routines - on trigget update displays and pulse
- Read encoders
- Read switches
- */
-
- static uint8_t nn, kk, oo;
- static uint8_t changes[MAXCHANNELS] = {0};
- static int nknob, kknob, oknob;
- static int _nknob, _kknob, _oknob;
- static bool triggerState = false;
-
- uint8_t i, ch;
- uint8_t maxn = MAXSTEPS; // maximums and minimums for n and k
- uint8_t minn = 1;
- uint8_t mink = 1;
- uint8_t mino = 0;
-
- static uint8_t active_channel;
-
- euc_time = gTimer.read_ms();
-
- nn = channelbeats[active_channel][0];
- kk = channelbeats[active_channel][1];
- oo = channelbeats[active_channel][3];
-
- // UPDATE BEAT HOLDER WHEN KNOBS ARE MOVED
- if (changes[active_channel]) {
-
- beat_holder[active_channel] = Euclid(nn, kk, oo);
-
- switch (changes[active_channel])
- {
- case 1:
- case 3:
- for (int i = 0; i < MAXSTEPS; ++i) {
-
- if (BitRead(beat_holder[active_channel], nn - 1 - i) && (i < nn)) {
- sendMes.setTopAddress(SetMatrixAddress(active_channel * 2, i, true));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- } else {
-
- sendMes.setTopAddress(SetMatrixAddress(active_channel * 2, i, true));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
- }
- }
-
- break;
-
- case 2:
- for (int i = 0; i < MAXSTEPS; ++i) {
-
- if (i < nn) {
- sendMes.setTopAddress(SetMatrixAddress(active_channel * 2, i, true));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- } else {
-
- sendMes.setTopAddress(SetMatrixAddress(active_channel * 2, i, true));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
- }
- }
-
- break;
-
- default:
- break;
- }
-
- changes[active_channel] = 0;
- last_changed[active_channel] = gTimer.read_ms();
- }
-
- // ANALOG PULSE TRIGGER
- if (trigger && !triggerState) {
-
- Sync(active_channel, gatesoff);
- triggerState = true;
-
- } else if (!trigger) {
-
- triggerState = false;
- }
-
- // READ K KNOB
- kknob = EncodeReadK(active_channel);
-
- if (_kknob != kknob) {
-
- _kknob = kknob;
-
- if (kknob != 0 && (euc_time - last_read[active_channel] > READ_DELAY)) {
-
- if ((kk + kknob) > nn) {
-
- kknob = 0;
- kk = nn;
-
- } else if ((kk + kknob) < mink) {
-
- kknob = 0;
- kk = mink;
- };
-
- kk = channelbeats[active_channel][1] = (kk + kknob); // update with encoder reading
-
- last_read[active_channel] = gTimer.read_ms();
- changes[active_channel] = 1; // k change = 1
- }
- }
-
- // READ N KNOB
- nknob = EncodeReadN(active_channel);
-
- if (_nknob != nknob) {
-
- _nknob = nknob;
-
- if (nknob != 0 && (euc_time - last_read[active_channel] > READ_DELAY)) {
-
- if ((nn + nknob) > maxn) {
-
- nknob = 0;
- nn = maxn;
-
- } else if ((nn + nknob) < minn) {
-
- nknob = 0;
- nn = minn;
- };
-
- if (kk > (nn + nknob)) {// check if new n is lower than k + reduce K if it is
- channelbeats[active_channel][1] = (nn + nknob);
- };
-
- if (oo > (nn + nknob - 1)) {// check if new n is lower than o + reduce o if it is
- channelbeats[active_channel][3] = (nn + nknob - 1);
- };
-
- nn = channelbeats[active_channel][0] = (nn + nknob); // update with encoder reading
- oo = channelbeats[active_channel][3];
-
- last_read[active_channel] = gTimer.read_ms();
- changes[active_channel] = 2; // n change = 2
- }
-
- }
-
- // READ O KNOB
- oknob = EncodeReadO(active_channel);
-
- if (_oknob != oknob) {
-
- _oknob = oknob;
-
- if (oknob != 0 && (euc_time - last_read[active_channel] > READ_DELAY)) {
- // Sense check o encoder reading to prevent crashes
-
- if ((oo + oknob) > (nn - 1)) {
-
- oknob = 0;
- oo = (nn - 1);
-
- } else if ((oo + oknob) < mino) {
-
- oknob = 0;
- oo = mino;
- }
-
- channelbeats[active_channel][3] = (oo + oknob);
-
- last_read[active_channel] = gTimer.read_ms();
- changes[active_channel] = 3; // o change = 3
- }
-
- }
-
- // ENABLE RESET BUTTON ** ADD FLASH RESET HERE ***
- if (gCtrlSW[1] && channelbeats[active_channel][2]) {
-
- for (ch = 0; ch < channels; ++ch) {
- channelbeats[ch][2] = 0;
- }
- }
-
- // Stop & Reset (gCtrlSW[0])
- if (reset) {
-
- for (ch = 0; ch < channels; ++ch) {
-
- channelbeats[ch][2] = 0;
-
- for (i = 0; i < MAXSTEPS; ++i) {
-
- sendMes.setTopAddress(SetMatrixAddress(ch * 2 + 1, i, true));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
- }
-
- }
-
- }
-
- // TURN OFF ANY LIGHTS THAT ARE ON
- if ((euc_time - last_sync) > pulse_length && lights_active) {
-
- for (ch = 0; ch < channels; ++ch) {
- sendMes.setTopAddress(SetMatrixAddress((MAXCHANNELS * 2), 3 - ch, true));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
-
- sendMes.setTopAddress(SetMatrixAddress((MAXCHANNELS * 2), 5, true));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
-
- }
-
- lights_active = false;
- }
-
- // FINISH ANY PULSES THAT ARE ACTIVE - PULSES LAST 1/4 AS LONG AS LIGHTS
- if (euc_time - last_sync > (pulse_length / 4) && pulses_active) {
-
- for (ch = 0; ch < channels; ++ch) {
-
- if (!gatesoff)
- {
- gGATES[ch] = false;
- gCLOCKOUT = false;
- //digitalWrite(sparepin, LOW);
- }
- }
-
- pulses_active = false;
- }
-
- ++active_channel;
- active_channel &= (channels - 1);
-}
-
-//-------------------------------------------------------------
-// Euclid calculation function
-
-unsigned int Euclid(int n, int k, int o) { // inputs: n=total, k=beats, o = offset
- int pauses = (n - k);
- int pulses = k;
- int offset = o;
- int steps = n;
- int per_pulse = (pauses / k);
- int remainder = (pauses % pulses);
- unsigned int workbeat[n];
- unsigned int outbeat;
- uint16_t outbeat2;
- int workbeat_count = n;
- int a_remainder, b_remainder;
- int groupa, groupb;
- int i, j;
- int trim_count;
-
- for (i = 0; i < n; ++i) { // Populate workbeat with unsorted pulses and pauses
-
- if (i < pulses) {
-
- workbeat[i] = 1;
-
- } else {
-
- workbeat[i] = 0;
- }
- }
-
- if (per_pulse > 0 && remainder < 2) { // Handle easy cases where there is no or only one remainer
-
- for (i = 0; i < pulses; ++i) {
-
- for (j = (workbeat_count - 1); j > (workbeat_count - per_pulse - 1); --j) {
- workbeat[i] = ConcatBin(workbeat[i], workbeat[j]);
- }
-
- workbeat_count = (workbeat_count - per_pulse);
-
- }
-
- outbeat = 0; // Concatenate workbeat into outbeat - according to workbeat_count
-
- for (i = 0; i < workbeat_count; ++i) {
- outbeat = ConcatBin(outbeat, workbeat[i]);
- }
-
-
- if (offset != 0) {
-
- outbeat2 = BitReadOffset(offset, outbeat, steps); // Add offset to the step pattern
-
- } else {
-
- outbeat2 = outbeat;
- }
-
- return outbeat2;
-
- } else {
-
- groupa = pulses;
- groupb = pauses;
-
- while (groupb > 1) { //main recursive loop
-
- if (groupa > groupb) { // more Group A than Group B
-
- a_remainder = (groupa - groupb); // what will be left of groupa once groupB is interleaved
- trim_count = 0;
-
- for (i = 0; i < (groupa - a_remainder); ++i) { //count through the matching sets of A, ignoring remaindered
- workbeat[i] = ConcatBin(workbeat[i], workbeat[workbeat_count - 1 - i]);
- ++trim_count;
- }
-
- workbeat_count = (workbeat_count - trim_count);
-
- groupa = groupb;
- groupb = a_remainder;
-
- } else if (groupb > groupa) { // More Group B than Group A
-
- b_remainder = (groupb - groupa); // what will be left of group once group A is interleaved
- trim_count = 0;
-
- for (i = workbeat_count-1; i >= (groupa + b_remainder); --i) { //count from right back through the Bs
- workbeat[workbeat_count - i - 1] = ConcatBin(workbeat[workbeat_count - 1 - i], workbeat[i]);
-
- ++trim_count;
- }
-
- workbeat_count = (workbeat_count - trim_count);
- groupb = b_remainder;
-
- } else if (groupa == groupb) { // groupa = groupb
-
- trim_count = 0;
-
- for (i = 0; i < groupa; ++i) {
- workbeat[i] = ConcatBin(workbeat[i], workbeat[workbeat_count - 1 - i]);
- ++trim_count;
- }
-
- workbeat_count = (workbeat_count - trim_count);
- groupb = 0;
-
- }
- }
-
- outbeat = 0; // Concatenate workbeat into outbeat - according to workbeat_count
-
- for (i = 0; i < workbeat_count; ++i) {
-
- outbeat = ConcatBin(outbeat, workbeat[i]);
- }
-
- if (offset != 0) {
-
- outbeat2 = BitReadOffset(offset, outbeat, steps); // Add offset to the step pattern
-
- } else {
-
- outbeat2 = outbeat;
- }
-
- return outbeat2;
- }
-}
-
-//-------------------------------------------------------------
-// Reads a bit of a number
-
-inline int BitRead(uint16_t b, int bitPos) {
- int x;
-
- x = b & (1 << bitPos);
-
- return x == 0 ? 0 : 1;
-}
-
-//-------------------------------------------------------------
-// Function to right rotate n by d bits
-
-uint16_t BitReadOffset(int shift, uint16_t value, uint16_t pattern_length) {
- uint16_t mask = ((1 << pattern_length) - 1);
- value &= mask;
-
- return ((value >> shift) | (value << (pattern_length - shift))) & mask;
-}
-
-//-------------------------------------------------------------
-// Function to find the binary length of a number by counting bitwise
-
-int findlength(unsigned int bnry) {
- bool lengthfound = false;
- int i;
- int length = 1; // no number can have a length of zero - single 0 has a length of one, but no 1s for the sytem to count
-
- for (i = 32; i >= 0; i--) {
-
- if ((BitRead(bnry, i)) && !lengthfound) {
- length = (i + 1);
- lengthfound = true;
- }
-
- }
-
- return length;
-}
-
-//-------------------------------------------------------------
-// Function to concatenate two binary numbers bitwise
-
-unsigned int ConcatBin(unsigned int bina, unsigned int binb) {
- int binb_len = findlength(binb);
- unsigned int sum = (bina << binb_len);
-
- sum = sum | binb;
-
- return sum;
-}
-
-//-------------------------------------------------------------
-// routine triggered by each beat
-
-void Sync(int active_channel, bool gatesoff) {
- int read_head, erase;
- int rand_vel, rand_len;
- int ch, i;
- static int masterclock;
-
- if (masterclock % 2 == 0) {
- sendMes.setTopAddress(SetMatrixAddress((MAXCHANNELS * 2), 7, true));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- } else {
-
- sendMes.setTopAddress(SetMatrixAddress((MAXCHANNELS * 2), 7, true));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
- }
-
- // Cycle through channels
- for (ch = 0; ch < channels; ++ch) {
-
- read_head = (channelbeats[ch][0] - channelbeats[ch][2] - 1);
-
- if (ch != active_channel || (euc_time - last_changed[active_channel]) > DISPLAY_UPDATE) {
-
- if (channelbeats[ch][2] < MAXSTEPS) {
-
- for (i = 0; i < MAXSTEPS; ++i) {
-
- if (BitRead(beat_holder[ch],channelbeats[ch][0] - 1 - i) && i < channelbeats[ch][0]) {
-
- sendMes.setTopAddress(SetMatrixAddress(ch * 2, i, true));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- } else {
-
- sendMes.setTopAddress(SetMatrixAddress(ch * 2, i, true));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
- }
-
- }
- }
- }
-
- if (channelbeats[ch][2]) {
-
- if (!masterclock) {
-
- erase = MAXSTEPS - 1;
-
- } else {
-
- erase = masterclock - 1;
- }
-
- sendMes.setTopAddress(SetMatrixAddress((ch * 2) + 1, erase, true));
- sendMes.setArgs("i", 0);
- osc.sendOsc(&sendMes);
-
- sendMes.setTopAddress(SetMatrixAddress((ch * 2) + 1, masterclock, true));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- }
-
- // turn on pulses on channels where a beat is present
- if (BitRead(beat_holder[ch], read_head)) {
-
- if (!gatesoff)
- {
- gGATES[ch] = true; // pulse out
- }
-
- sendMes.setTopAddress(SetMatrixAddress((MAXCHANNELS * 2), 3 - ch, true));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- lights_active = pulses_active = true;
-
- if (!ch || (ch == 2)) {
-
- rand_vel = 127 - (rand() / (RAND_MAX / 40)); // random velocity ch1, ch3
-
- } else {
-
- rand_vel = 95 - (rand() / (RAND_MAX / 70)); // random velocity ch2, ch4
- }
-
- rand_len = 127 - (rand() / (RAND_MAX / 110)); // random Amp EG Decay
-
- midi.sendControlChange(0x07, rand_vel, (ch + 1)); // volca sample Vol
- midi.sendControlChange(0x30, rand_len, (ch + 1)); // volca sample Amp EG Decay
- midi.sendNoteOn(0, 127, (ch + 1)); // volca sample trriger on
- }
-
- // send off pulses to spare output for the first channel
- if (!(BitRead(beat_holder[ch], read_head)) && !ch) { // only relates to first channel
-
- if (!gatesoff)
- {
- gCLOCKOUT = true;
- }
-
- sendMes.setTopAddress(SetMatrixAddress((MAXCHANNELS * 2), 5, true));
- sendMes.setArgs("i", 1);
- osc.sendOsc(&sendMes);
-
- lights_active = pulses_active = true;
- }
-
- // move counter to next position, ready for next pulse
- ++channelbeats[ch][2];
-
- if ((channelbeats[ch][2]) >= (channelbeats[ch][0])) {
- channelbeats[ch][2] = 0;
- }
- }
-
- ++masterclock;
- masterclock &= (MAXSTEPS - 1);
-
- pulse_length = ((euc_time - last_sync) / 5);
- last_sync = euc_time;
-}
-
-/* 3 functions to read each encoder
- returns +1, 0 or -1 dependent on direction
- Contains no internal debounce, so calls should be delayed
- */
-
-//-------------------------------------------------------------
-// Check Euclidean Seq N(length) Value
-
-int EncodeReadN(int ch) {
- static float _enc[4];
- int result = 0;
-
- switch (ch)
- {
- case 0:
-
- if (gEucA[0] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucA[0] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucA[0];
-
- } else if (gEucA[0] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucA[0];
- }
-
- break;
-
- case 1:
-
- if (gEucA[3] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucA[3] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucA[3];
-
- } else if (gEucA[3] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucA[3];
- }
-
- break;
-
- case 2:
-
- if (gEucB[0] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucB[0] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucB[0];
-
- } else if (gEucB[0] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucB[0];
- }
-
- break;
-
- case 3:
-
- if (gEucB[3] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucB[3] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucB[3];
-
- } else if (gEucB[3] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucB[3];
- }
-
- break;
-
- default:
- break;
- }
-
- return result;
-}
-
-//-------------------------------------------------------------
-// Check Euclidean Seq K(Density) Value
-
-int EncodeReadK(int ch) {
- static float _enc[4];
- int result = 0;
-
- switch (ch)
- {
- case 0:
-
- if (gEucA[1] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucA[1] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucA[1];
-
- } else if (gEucA[1] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucA[1];
- }
-
- break;
-
- case 1:
-
- if (gEucA[4] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucA[4] < _enc[ch]) {
- result = -4;
- _enc[ch] = gEucA[4];
-
- } else if (gEucA[4] > _enc[ch]) {
- result = 4;
- _enc[ch] = gEucA[4];
- }
-
- break;
-
- case 2:
-
- if (gEucB[1] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucB[1] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucB[1];
-
- } else if (gEucB[1] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucB[1];
- }
-
- break;
-
- case 3:
-
- if (gEucB[4] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucB[4] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucB[4];
-
- } else if (gEucB[4] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucB[4];
- }
-
- break;
-
- default:
- break;
- }
-
- return result;
-}
-
-//-------------------------------------------------------------
-// Check Euclidean Seq O(Offset) Value
-
-int EncodeReadO(int ch) {
- static float _enc[4];
- int result = 0;
-
- switch (ch)
- {
- case 0:
-
- if (gEucA[2] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucA[2] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucA[2];
-
- } else if (gEucA[2] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucA[2];
- }
-
- break;
-
- case 1:
-
- if (gEucA[5] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucA[5] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucA[5];
-
- } else if (gEucA[5] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucA[5];
- }
-
- break;
-
- case 2:
-
- if (gEucB[2] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucB[2] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucB[2];
-
- } else if (gEucB[2] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucB[2];
- }
-
- break;
-
- case 3:
-
- if (gEucB[5] == 0) {
- _enc[ch] = result = 0;
-
- } else if (gEucB[5] < _enc[ch]) {
- result = -1;
- _enc[ch] = gEucB[5];
-
- } else if (gEucB[5] > _enc[ch]) {
- result = 1;
- _enc[ch] = gEucB[5];
- }
-
- break;
-
- default:
- break;
- }
-
- return result;
-}
-
-inline char * SetMatrixAddress(int row, int column, bool euclid) {
-
- static char address[32];
-
- if (euclid)
- {
- sprintf(address, "%s%d/%d", MATRIX_ADDRESS, column + 1, row + 1);
-
- } else {
-
- sprintf(address, "%s%d/1", STEP_INDICATOR_ADDRESS, column + 1);
- }
-
- return address;
-}
-