OSCtoCV Library

Dependents:   OSCtoCVConverter

OSCtoCV_LFO.cpp

Committer:
casiotone401
Date:
2016-02-25
Revision:
6:7fb15b1b5459
Parent:
4:fe335dc8d53d

File content as of revision 6:7fb15b1b5459:

/*
 OSCtoCV_Sequencer.cpp 
*/

#include <math.h>
#include <limits.h>

#include "OSCtoCV_LFO.h"
#include "OSCtoCV_Random.h"
#include "OSCtoCV.h"

#define M_PI 3.1415926535897932384626433832795

//-------------------------------------------------------------
// update LFO

float UpdateLFO(float freq)
{
    static float pos;
    
    pos += 0.000015259 * freq;

    if (pos > 1.0f)
    {
        pos = 0;
    }
    
    return pos;
}

//-------------------------------------------------------------
// triangle wave calc

float TriWave(float pos)
{
    return 1.0f - fabs(pos - 0.5f) * 2.0f;
}

//-------------------------------------------------------------
// saw(ramp) wave calc

float SawWave(float pos)
{
    return 1.0f - pos;
}

//-------------------------------------------------------------
// square wave calc

float SqrWave(float pos)
{
    return pos < 0.8f ? 1.0f : 0.0f;
}

//-------------------------------------------------------------
// sine wave calc

float SinWave(float pos)
{   
    return (sin(pos*2 * M_PI) + 1.0f) * 0.5f;
}

//-------------------------------------------------------------
// exponential wave calc

float ExpWave(float pos)
{
    return powf((1.0f - fabs(pos - 0.5f) * 2.0f), 2.0);
}

//-------------------------------------------------------------
// exp wave calc

float LogWave(float pos)
{
    return powf((1.0f - fabs(pos - 0.5f) * 2.0f), 0.5);
}

//-------------------------------------------------------------
// synthesis wave calc sin

float SynthWave1(float pos)
{
    return (SinWave(pos) + SinWave(3 * pos) - SinWave(2 * pos)) * 0.5;
}

//-------------------------------------------------------------
// synthesis wave calc sin

float SynthWave2(float pos)
{
    return (SinWave(pos) + SinWave(1 / 3 * pos) - SinWave(2 * pos)) * 0.3;
}

//-------------------------------------------------------------
// invert float value

float Invert(float x)
{   
    return SCALING_N - x;
}

//-------------------------------------------------------------
// LFO cv generator

void SteppedLFO(uint8_t channelOffset, bool quantizeOff)
{
    static uint8_t ch = channelOffset;
    static uint8_t mcount;
    int waveform;
    static int _waveform = -1;
    static int steps;
    uint8_t qmode;
    static float lfocv[8], glidecv[8];
    unsigned int cv;
    static float qcv;
    float freq;
    static int jitter, jitterCount;

    // select waveform ArdSW1(gArdSW[0])
    waveform = CheckSubMode1();
    
    if (_waveform != waveform) // update LCD
    {
        switch (waveform)
        {
            case TRIANGLE_WAVE:

                UpdateSubModeLCD("Tri:Wave");
                break;

            case SAW_WAVE:

                UpdateSubModeLCD("Saw:Wave");
                break;
                
            case SQUARE_WAVE:

                UpdateSubModeLCD("Sqr:Wave");
                break;

            case SINE_WAVE:

                UpdateSubModeLCD("Sin:Wave");
                break;

            case EXP_WAVE:

                UpdateSubModeLCD("Exp:Wave");
                break;

            case LOG_WAVE:

                UpdateSubModeLCD("Log:Wave");
                break;

            case SYNTH_WAVE:
            
                UpdateSubModeLCD("Syn:Wave");
                break;
                
            case NOISE:
        
                UpdateSubModeLCD("XorNoise");
                break;

            default:
                break;
        }
        
        _waveform = waveform;
    }
    
    // frequency control ArdPot1(gArdPot[0])
    freq = gArdPot[0] * 0.10f + 0.001f;

    switch (waveform)
    {
        case TRIANGLE_WAVE:

            lfocv[channelOffset] = TriWave(UpdateLFO(freq)) * SCALING_N;
            break;

        case SAW_WAVE:

            lfocv[channelOffset] = SawWave(UpdateLFO(freq)) * SCALING_N;
            break;

        case SQUARE_WAVE:

            lfocv[channelOffset] = SqrWave(UpdateLFO(freq)) * SCALING_N;
            break;

        case SINE_WAVE:

            lfocv[channelOffset] = SinWave(UpdateLFO(freq)) * SCALING_N;
            break;

        case EXP_WAVE:

            lfocv[channelOffset] = ExpWave(UpdateLFO(freq)) * SCALING_N;
            break;

        case LOG_WAVE:

            lfocv[channelOffset] = LogWave(UpdateLFO(freq)) * SCALING_N;
            break;

        case SYNTH_WAVE:

            lfocv[channelOffset] = SynthWave1(UpdateLFO(freq)) * SCALING_N;
            break;
            
        case NOISE:

            lfocv[channelOffset] = fmodf(Xorshift_32(), SCALING_N);
            break;

        default:
            break;
    }

    //lfocv[i + 4] = Invert(lfocv[i]); // ch4 ~ ch8 invert waveform
    
    if (quantizeOff) // quantize Off
    {
        qmode = Lin;
    
    } else {
        
        qmode = CheckQuantizeMode();
    }
    
    switch (qmode) 
    {
        case Lin:
        
            if (gArdPot[1] > 10) 
            {
                steps = (unsigned int)gArdPot[1] * 0.1; // check LFO Steps(Quantize Resolustion)ArdPot2gArdPot[1]
                
                lfocv[channelOffset] = quantizedMap[(unsigned int)(MapFloat(lfocv[channelOffset], 0, SCALING_N, 0, steps)) * (1024 / steps)];
            }
            
            glidecv[channelOffset] = glidecv[channelOffset] * gGlide + lfocv[channelOffset] * (1.0f - gGlide);
            break;

        case Chr:

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

            glidecv[channelOffset] = glidecv[channelOffset] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);

            break;

        case Maj:

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

            glidecv[channelOffset] = glidecv[channelOffset] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);

            break;

        case M7:

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

            glidecv[channelOffset] = glidecv[channelOffset] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);

            break;

        case Min7:

            qcv = calibMap4[(unsigned int)MapFloat(lfocv[channelOffset], 0, SCALING_N, 0, (QUAN_RES4 - 1))];

            glidecv[channelOffset] = glidecv[channelOffset] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);

            break;

        case Dor:

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

            glidecv[channelOffset] = glidecv[channelOffset] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);

            break;

        case Min:

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

            glidecv[channelOffset] = glidecv[channelOffset] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);

            break;

        case S5th:

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

            glidecv[channelOffset] = glidecv[channelOffset] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);

            break;

        case Wht:

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

            glidecv[channelOffset] = glidecv[channelOffset] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);

            break;
    }     

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

    UpdateCV(WRITE_UPDATE_N, ch, &cv);
    
    if (mcount == 0x1F) 
    {
        UpdateCVMeter(ch, &cv);
    }

    ++ch;
    
    if (ch == 8)
    {
        ch = channelOffset - 1; //output channelOffset ~ ch8
        
        ++mcount;
        mcount &= 0x3F;
    }
    
    ++jitterCount;
    jitterCount &= 0x1FF;

}