OSCtoCV Library
Diff: OSCtoCV_Sequencer.cpp
- Revision:
- 0:cd43a974c54c
- Child:
- 1:981b62bb5c87
diff -r 000000000000 -r cd43a974c54c OSCtoCV_Sequencer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/OSCtoCV_Sequencer.cpp Sun Jan 17 09:30:32 2016 +0000 @@ -0,0 +1,541 @@ +/* + OSCtoCV_Sequencer.cpp +*/ + +#include "mbed.h" +#include "OSCtoCV_Sequencer.h" +#include "OSCtoCV.h" + +//------------------------------------------------------------- +// Sequence & Shift Out CV + +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 + +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 + +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); + + if(stepCount != 8) + { + strcat(pulseAddress, currentStep); + sendMes.setTopAddress(pulseAddress); + sendMes.setArgs("i", (stepCount + 1)); + osc.sendOsc(&sendMes); + } + + strcat(gateModeAddress, currentStep); + 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); +} + +