OSCtoCV Library

Dependents:   OSCtoCVConverter

OSCtoCV_Sequencer.cpp

Committer:
casiotone401
Date:
2016-02-18
Revision:
5:abe335652add
Parent:
4:fe335dc8d53d
Child:
6:7fb15b1b5459

File content as of revision 5:abe335652add:

/*
 OSCtoCV_Sequencer.cpp 
*/

#include "mbed.h"
#include "OSCtoCV_Sequencer.h"
#include "OSCtoCV.h"

//-------------------------------------------------------------
// Sequence & Shift Out CV

void ShiftCVSeq(int trigger, bool reset, unsigned int channelRange)
{
    int i, j;
    static bool triggerState = false;
    static bool stepFoward = false;
    static bool _reset = false;
    static uint8_t currentStep;
    static int resetCount;
    static uint8_t gateMode;
    static uint8_t _gateMode[16];
    static uint8_t ch;
    static float glidecv[8], shiftcv[8];
    unsigned int cv;
    static float qcv;
    static int jitter, jitterCount;

    switch (CheckQuantizeMode()) 
    {
        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;
    }
    
    CheckAnalogMode();
    
    if (!gCtrlSW[4]) 
    { 
        jitter = 0;
    
    } else if (gCtrlSW[4] && jitterCount % 64 == 0) { // ASR Analog Mode
        
        jitter = ANALOG_JITTER; 
    }
    
    cv = (unsigned int)(glidecv[0] + jitter);
    
    UpdateCV(WRITE_UPDATE_N, 0, &cv);
    
    for (i = 1; i < channelRange; ++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, SHIFTSEQ);
    }
    
    if (reset && !_reset) // Stop & Reset
    {
        sendMes.setTopAddress(SetMatrixAddress(0, currentStep, SHIFTSEQ));
        sendMes.setArgs("i", 0);
        osc.sendOsc(&sendMes);
        
        currentStep = 0;

        sendMes.setTopAddress(SetMatrixAddress(0, currentStep, SHIFTSEQ));
        sendMes.setArgs("i", 1);
        osc.sendOsc(&sendMes);
        
        _reset = true;
        stepFoward = triggerState = false;

    } 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, SHIFTSEQ));
        sendMes.setArgs("i", 0);
        osc.sendOsc(&sendMes);
                    
        ++currentStep;

        if (gCtrlSW[2]) // 4step break
        {
            resetCount = 3;
            
        } else {
            
            resetCount = gCtrl[4] * 15;
        }
        
        CheckResetCount(resetCount, SHIFTSEQ);
        
        if (currentStep > resetCount)  // reset
        {
            currentStep = 0;
        }
        
        sendMes.setTopAddress(SetMatrixAddress(0, currentStep, SHIFTSEQ));
        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] = true;
        
        } else {
            
            gGATES[2] = false;
        }
        
        stepFoward = false;
    }
    
    ++ch;
    ch &= 0x0F;
    
    ++jitterCount;
    jitterCount &= 0x1FF;
}

//-------------------------------------------------------------
// M185 Sequencer

void M185Seq(int trigger, bool reset, unsigned int channelRange)
{
    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;
    static uint8_t gateMode;
    static uint8_t _gateMode[8];
    static uint8_t _pulseCount[8];
    static uint8_t ch;
    static float glidecv[8], shiftcv[8];
    unsigned int cv;
    static float qcv;
    static int jitterCount;
    static int jitter;

    switch (CheckQuantizeMode()) 
    {
        case Lin:

            glidecv[0] = glidecv[0] * gSlide185[currentStep] + g185_cv[currentStep] * (1.0f - gSlide185[currentStep]);
            
            break;

        case Chr:

            qcv = calibMap1[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES1 - 1))];

            glidecv[0] = glidecv[0] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);

            break;

        case Maj:

            qcv = calibMap2[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES2 - 1))];

            glidecv[0] = glidecv[0] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);
            
            break;

        case M7:

            qcv = calibMap3[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES3 - 1))];

            glidecv[0] = glidecv[0] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);
            
            break;

        case Min7:

            qcv = calibMap4[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES4 - 1))];
        
            glidecv[0] = glidecv[0] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);
            
            break;
        
        case Dor:

            qcv = calibMap5[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES5 - 1))];

            glidecv[0] = glidecv[0] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);

            break;

        case Min:

            qcv = calibMap6[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES6 - 1))];

            glidecv[0] = glidecv[0] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);
            
            break;

        case S5th:

            qcv = calibMap7[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES7 - 1))];

            glidecv[0] = glidecv[0] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);

            break;

        case Wht:

            qcv = calibMap8[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES8 - 1))];

            glidecv[0] = glidecv[0] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);

            break;
    }
    
    CheckAnalogMode();
        
    if (!gCtrlSW[4]) 
    { 
        jitter = 0;
    
    } else if (gCtrlSW[4] && jitterCount % 64 == 0) { // ASR Analog Mode
        
        jitter = ANALOG_JITTER; 
    }
    
    cv = (unsigned int)(glidecv[0] + jitter);

    UpdateCV(WRITE_UPDATE_N, 0, &cv);

    for (i = 1; i < channelRange; ++i)
    {
        glidecv[i] = glidecv[i] * gSlide185[currentStep] + shiftcv[i] * (1.0f - gSlide185[currentStep]);
        cv = (unsigned int)(glidecv[i] + jitter);

        UpdateCV(WRITE_UPDATE_N, i, &cv);
    }
    
    if (trigger && !triggerState) // trigger ON
    {
        if (gateMode == MULTI) 
        {
            gGATES[0] = true;
            
            sendMes.setTopAddress(SetMatrixAddress(0, currentStep, M185SEQ));
            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, M185SEQ));
            sendMes.setArgs("i", 0);
            osc.sendOsc(&sendMes);
        }
        
        triggerState = false;
    }

// check & update touchOSC ctrl parameter        
    if (_gateMode[ch] != gGateMode185[ch] * 3 || _pulseCount[ch] != gPulseCount[ch] * 7)
    {
        _gateMode[ch] = (gGateMode185[ch] * 3);
        _pulseCount[ch] = (gPulseCount[ch] * 7);
        
        SendCtrlState(ch, _gateMode[ch], _pulseCount[ch], M185SEQ);
    }
    
    if (reset && !_reset) // Stop & Reset
    {
        sendMes.setTopAddress(SetMatrixAddress(0, currentStep, M185SEQ));
        sendMes.setArgs("i", 0);
        osc.sendOsc(&sendMes);
        
        currentStep = 0;

        sendMes.setTopAddress(SetMatrixAddress(0, currentStep, M185SEQ));
        sendMes.setArgs("i", 1);
        osc.sendOsc(&sendMes);
        
        _reset = true;
        stepFoward = triggerState = false;

    } 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, M185SEQ));
            sendMes.setArgs("i", 0);
            osc.sendOsc(&sendMes); 
            
            ++currentStep;
            
            if (gCtrlSW[2]) // 4step break
            {
                resetCount = 3;
            
            } else {
            
                resetCount = gCtrl[5] * 7;
            }
        
            CheckResetCount(resetCount, M185SEQ);

            if (currentStep > resetCount) // reset
            {
                currentStep = 0;
            }
        
            sendMes.setTopAddress(SetMatrixAddress(0, currentStep, M185SEQ));
            sendMes.setArgs("i", 1);
            osc.sendOsc(&sendMes);
                    
            UpdateCVMeter(currentStep, &cv);
            
        // check Pulse Count & Gate Mode
            stepCount = (gPulseCount[currentStep] * 7);
        
            gateMode = (gGateMode185[currentStep] * 3);
            
            if (gateMode != MUTE)
            {
                gGATES[0] = true;
            }
            
            if (gAccent185[currentStep]) // accent
            {
                gGATES[2] = true;

            } else {

                gGATES[2] = false;
            }
        }
                
        stepFoward = false;
    }
        
    ++ch;
    ch &= 0x07;
    
    ++jitterCount;
    jitterCount &= 0x1FF;
}

//-------------------------------------------------------------
// M185 Sequencer

void PolyM185Seq(int trigger, bool reset, unsigned int channelRange)
{
    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;
    static uint8_t gateMode;
    static uint8_t _gateMode[8];
    static uint8_t _pulseCount[8];
    static uint8_t ch;
    static float glidecv[8], shiftcv[8];
    unsigned int cv;
    static float qcv;
    static int jitterCount;
    static int jitter;
    
    switch (CheckQuantizeMode()) 
    {
        case Lin:

            glidecv[4] = glidecv[4] * gSlide185[currentStep] + g185_cv[currentStep] * (1.0f - gSlide185[currentStep]);
            
            break;

        case Chr:

            qcv = calibMap1[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES1 - 1))];

            glidecv[4] = glidecv[4] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);

            break;

        case Maj:

            qcv = calibMap2[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES2 - 1))];

            glidecv[4] = glidecv[4] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);
            
            break;

        case M7:

            qcv = calibMap3[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES3 - 1))];

            glidecv[4] = glidecv[4] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);
            
            break;

        case Min7:

            qcv = calibMap4[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES4 - 1))];
        
            glidecv[4] = glidecv[4] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);
            
            break;
        
        case Dor:

            qcv = calibMap5[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES5 - 1))];

            glidecv[4] = glidecv[4] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);

            break;

        case Min:

            qcv = calibMap6[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES6 - 1))];

            glidecv[4] = glidecv[4] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);
            
            break;

        case S5th:

            qcv = calibMap7[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES7 - 1))];

            glidecv[4] = glidecv[4] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);

            break;

        case Wht:

            qcv = calibMap8[(unsigned int)MapFloat(g185_cv[currentStep], 0, SCALING_N, 0, (QUAN_RES8 - 1))];

            glidecv[4] = glidecv[4] * gSlide185[currentStep] + (qcv * SCALING_N) * (1.0f - gSlide185[currentStep]);

            break;
    }
    
    CheckAnalogMode();
    
    if (!gCtrlSW[4]) 
    { 
        jitter = 0;
    
    } else if (gCtrlSW[4] && jitterCount % 64 == 0) { // ASR Analog Mode
        
        jitter = ANALOG_JITTER; 
    }
    
    cv = (unsigned int)(glidecv[4] + jitter);

    UpdateCV(WRITE_UPDATE_N, 4, &cv);

    for (i = 5; i < channelRange; ++i)
    {
        glidecv[i] = glidecv[i] * gSlide185[currentStep] + shiftcv[i] * (1.0f - gSlide185[currentStep]);
        cv = (unsigned int)(glidecv[i] + jitter);

        UpdateCV(WRITE_UPDATE_N, i, &cv);
    }
    
    if (trigger && !triggerState) // trigger ON
    {
        if (gateMode == MULTI) 
        {
            gGATES[3] = true;
            
            sendMes.setTopAddress(SetMatrixAddress(0, currentStep, M185SEQ));
            sendMes.setArgs("i", 1);
            osc.sendOsc(&sendMes);
        }
        
        stepFoward = triggerState = true;
        
    } else if (!trigger) {        // trigger OFF
        
        if (gateMode != HOLD) 
        {
            gGATES[3] = false;
        }
        
        if (gateMode == MULTI)
        {
            sendMes.setTopAddress(SetMatrixAddress(0, currentStep, M185SEQ));
            sendMes.setArgs("i", 0);
            osc.sendOsc(&sendMes);
        }
        
        triggerState = false;
    }

// check & update touchOSC ctrl parameter        
    if (_gateMode[ch] != gGateMode185[ch] * 3 || _pulseCount[ch] != gPulseCount[ch] * 7)
    {
        _gateMode[ch] = (gGateMode185[ch] * 3);
        _pulseCount[ch] = (gPulseCount[ch] * 7);
        
        SendCtrlState(ch, _gateMode[ch], _pulseCount[ch], M185SEQ);
    }
    
    if (reset && !_reset) // Stop & Reset
    {   
        sendMes.setTopAddress(SetMatrixAddress(0, currentStep, M185SEQ));
        sendMes.setArgs("i", 0);
        osc.sendOsc(&sendMes);
        
        currentStep = 0;
        
        sendMes.setTopAddress(SetMatrixAddress(0, currentStep, M185SEQ));
        sendMes.setArgs("i", 1);
        osc.sendOsc(&sendMes);
        
        _reset = true;
        stepFoward = triggerState = false;

    } else if (!reset) {

        _reset = false;
    }
    
    if (stepFoward)
    {
        if (gateMode != HOLD) // shift CV
        {
            for (j = 5; j < 8; ++j) 
            {
                shiftcv[j] = glidecv[j-1];
            }
        }
        
        --stepCount;
                
        if (stepCount == -1)
        {   
            sendMes.setTopAddress(SetMatrixAddress(0, currentStep, M185SEQ));
            sendMes.setArgs("i", 0);
            osc.sendOsc(&sendMes); 
            
            ++currentStep;
            
            if (gCtrlSW[2]) // 4step break
            {
                resetCount = 3;
            
            } else {
            
                resetCount = gCtrl[5] * 7;
            }
        
            CheckResetCount(resetCount, M185SEQ);

            if (currentStep > resetCount) // reset
            {
                currentStep = 0;
            }
            
            sendMes.setTopAddress(SetMatrixAddress(0, currentStep, M185SEQ));
            sendMes.setArgs("i", 1);
            osc.sendOsc(&sendMes);
            
        // check Pulse Count & Gate Mode
            stepCount = (gPulseCount[currentStep] * 7);
        
            gateMode = (gGateMode185[currentStep] * 3);
            
            if (gateMode != MUTE)
            {
                gGATES[3] = true;
            }

        }
                
        stepFoward = false;
    }
        
    ++ch;
    ch &= 0x07;
    
    ++jitterCount;
    jitterCount &= 0x1FF;
}

//-------------------------------------------------------------
// 8ch drum track sequecer
unsigned int BeatsSeq(int trigger, bool reset, bool gatesOff)
{
    int rndVel;
    static bool triggerState = false;
    static bool stepFoward = false;
    static bool _reset = false;
    static uint8_t currentStep;
    static int stepCount;
    static int resetCount;
    static uint8_t _pulseCount[8];
    static uint8_t ch;
    static float decay[8] = {1};
    
        
    if (trigger && !triggerState) // trigger ON
    {
        if (stepCount != 0)
        {     
            for (ch = 0; ch < 8; ++ch) 
            {
                if (gBeatsMatrix[ch][currentStep])
                {   
                    midi.sendNoteOn(0, 127, (ch + 1)); // volca sample trriger on
                    
                    if (!gatesOff && ch < 4)
                    {
                        gGATES[ch] = true;
                    }
                }
            }
            
            sendMes.setTopAddress(SetMatrixAddress(0, currentStep, BEATSSEQ));
            sendMes.setArgs("i", 1);
            osc.sendOsc(&sendMes);
        }
        
        stepFoward = triggerState = true;

    } else if (!trigger) {        // trigger OFF
        
        if (!gatesOff)
        {
            gGATES[0] = gGATES[1] = gGATES[2] = gGATES[3] = false;
        }
        
        if (stepCount != 0) 
        {
            sendMes.setTopAddress(SetMatrixAddress(0, currentStep, BEATSSEQ));
            sendMes.setArgs("i", 0);
            osc.sendOsc(&sendMes);
        }

        triggerState = false;
    }

// check & update touchOSC ctrl parameter
    for (ch = 0; ch < 16; ++ch) 
    {
        if (_pulseCount[ch] != gPulseCountBeats[ch] * 7)
        {
            _pulseCount[ch] = (gPulseCountBeats[ch] * 7);
        
            SendCtrlState(ch, 0, _pulseCount[ch], BEATSSEQ);
        }
    }       
    
    if (reset && !_reset) // Stop & Reset
    {// current step indeicator Reset
        sendMes.setTopAddress(SetMatrixAddress(0, currentStep, BEATSSEQ));
        sendMes.setArgs("i", 0);
        osc.sendOsc(&sendMes);
        
        currentStep = 0;

        sendMes.setTopAddress(SetMatrixAddress(0, currentStep, BEATSSEQ));
        sendMes.setArgs("i", 1);
        osc.sendOsc(&sendMes);
        
        _reset = true;
        stepFoward = triggerState = false;

    } else if (!reset) {

        _reset = false;
    }
    
    if (stepFoward)
    {   
        --stepCount;
                
        if (stepCount == -1)
        {// last current step indeicator ON
            sendMes.setTopAddress(SetMatrixAddress(0, currentStep, BEATSSEQ));
            sendMes.setArgs("i", 0);
            osc.sendOsc(&sendMes);
            
            ++currentStep;
            
            if (gCtrlSW[2]) // 4step break
            {
                resetCount = 3;
            
            } else {
            
                resetCount = gCtrl[7] * 15;
            }
        
            CheckResetCount(resetCount, BEATSSEQ);

            if (currentStep > resetCount) // reset
            {
                currentStep = 0;
            }
        
        // current step indeicator ON
            sendMes.setTopAddress(SetMatrixAddress(0, currentStep, BEATSSEQ));
            sendMes.setArgs("i", 1);
            osc.sendOsc(&sendMes);
            
        // check Pulse Count & Gate Mode
            stepCount = (gPulseCountBeats[currentStep] * 7);
            
            for (ch = 0; ch < 8; ++ch) 
            {
                if (gBeatsMatrix[ch][currentStep])
                {
                    if (gCtrlSW[5]) //random Vel Mode /ctrlsw6
                    {
                        if (ch == 0 || ch == 2)
                        { 
                    
                            rndVel = 95 - (rand() % 14); // random velocity ch1, ch3
                    
                        } else if (ch == 1 || ch == 3) {
                            
                            rndVel = 80 - (rand() % 10);  // random velocity ch2, ch4
                        
                        } else {
                            
                            rndVel = 80;
                        }
                    
                    } else {
                        
                        rndVel = 95;
                    }
                    
                    if (gBeatsMatrix[8][currentStep])  // ch9 accent Velocity +20
                    {
                        rndVel += 32;
                    }
                    
                    midi.sendControlChange(0x07, (gBeatsLevel[ch] * rndVel), (ch + 1)); // volca sample Level
                    
                    if (decay[ch] != gBeatsDecay[ch])
                    {
                        decay[ch] = gBeatsDecay[ch];
                        midi.sendControlChange(0x30, (decay[ch] * 127), (ch + 1)); // volca sample Amp EG Decay
                    }
                    
                    midi.sendNoteOn(0, 127, (ch + 1)); // volca sample trriger on
                    
                    if (!gatesOff && ch < 4)
                    {
                        gGATES[ch] = true;
                    }
                }
            }
        }
                
        stepFoward = false;
    }
    
    return triggerState;

}

//-------------------------------------------------------------
// shift cv seq ch1 ~ ch4 m185 seq ch5 ~ ch8

void PolyCVSeq(int trigger, bool reset)
{
    ShiftCVSeq(trigger, reset, CV_CHANNEL4);
    PolyM185Seq(trigger, reset, CV_CHANNEL8);
}

//-------------------------------------------------------------
// check reset count & send osc

void CheckResetCount(uint8_t resetCount, uint8_t mode)
{
    static uint8_t _resetCountShift, _resetCount185, _resetCountBeats;
    
    switch (mode)
    {
        case SHIFTSEQ:
        
            if (_resetCountShift != resetCount)
            {
                sendMes.setTopAddress(RESET_COUNTER_ADDRESS);
                sendMes.setArgs("i", (resetCount + 1));
                osc.sendOsc(&sendMes);
        
                sendMes.setTopAddress("/ctrl5");
                sendMes.setArgs("f", gCtrl[4]);
                osc.sendOsc(&sendMes);
                
                _resetCountShift = resetCount;
            }
            break;
        
        case M185SEQ:
        
            if (_resetCount185 != resetCount)
            {   
                sendMes.setTopAddress(RESET185_COUNTER_ADDRESS);
                sendMes.setArgs("i", (resetCount + 1));
                osc.sendOsc(&sendMes);

                sendMes.setTopAddress("/ctrl6");
                sendMes.setArgs("f", gCtrl[5]);
                osc.sendOsc(&sendMes);
    
                _resetCount185 = resetCount;
            }
            break;
        
        case BEATSSEQ:
        
            if (_resetCountBeats != resetCount)
            {
                sendMes.setTopAddress(BEATS_COUNTER_ADDRESS);
                sendMes.setArgs("i", (resetCount + 1));
                osc.sendOsc(&sendMes);
        
                sendMes.setTopAddress("/ctrl8");
                sendMes.setArgs("f", gCtrl[7]);
                osc.sendOsc(&sendMes);
                
                _resetCountBeats = resetCount;
            }
            break;
            
        default:
            break;
    }
    
}

//-------------------------------------------------------------
// check analog mode & send osc

inline void CheckAnalogMode()
{
    static bool _analogMode;
    
    if (_analogMode != gCtrlSW[4])
    {
        sendMes.setTopAddress("/ctrlsw5");
        sendMes.setArgs("i", gCtrlSW[4]);
        osc.sendOsc(&sendMes);
        
        _analogMode = gCtrlSW[4];
    }
    
}

//-------------------------------------------------------------
// Send Sequencer Status to touchOSC

void SendCtrlState(uint8_t step, uint8_t gateMode, uint8_t stepCount, uint8_t mode)
{
    char pulseAddress[10] = PULSE_COUNT_ADDRESS;
    char beatsPulseAddress[10] = BEATS_PULSE_COUNT_ADDRESS;
    char gateModeAddress[10] = GATE_MODE_ADDRESS;
    char gate185ModeAddress[10] = GATE185_MODE_ADDRESS;
    char currentStep[2];
    
    sprintf(currentStep, "%d", step + 1);
    
    if(stepCount != 8) 
    {
        if (mode == BEATSSEQ)
        {
            strcat(beatsPulseAddress, currentStep);
            sendMes.setTopAddress(beatsPulseAddress);
            
        } else {
            
            strcat(pulseAddress, currentStep);
            sendMes.setTopAddress(pulseAddress);
        }
        
        sendMes.setArgs("i", (stepCount + 1));
        osc.sendOsc(&sendMes);
    }
    
    if (mode != BEATSSEQ)
    {
        switch (mode)
        {
            case SHIFTSEQ:
            
                strcat(gateModeAddress, currentStep);
                sendMes.setTopAddress(gateModeAddress);
                break;
                
            case M185SEQ:
                
                strcat(gate185ModeAddress, currentStep);
                sendMes.setTopAddress(gate185ModeAddress);
                break;
                
            default:
                break;
        }

        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);
    }
    
}