OSCtoCV Library

Dependents:   OSCtoCVConverter

OSCtoCV_Random.cpp

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

File content as of revision 6:7fb15b1b5459:

/*
 OSCtoCV_Random.cpp 
*/

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

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

unsigned long seed = 1; // lcg seed
    
//-------------------------------------------------------------
// Linear congruential generator

double Lcg(void)  /* 0 <= rnd() < 1 */ 
{
    seed = seed * 69069 + 1;
           
    return (1.0 / (ULONG_MAX + 1.0)) * seed;
}

//-------------------------------------------------------------
// xorshift random generator

uint32_t Xorshift_32(void)
{
  static uint32_t y = 35342; // seed

  y = y ^ (y << 13);
  y = y ^ (y >> 17);

  return y = y ^ (y << 5);
}

//-------------------------------------------------------------
// generate random number from 0 to 1

double Rnd(void)  /* 0 <= rnd() < 1 */
{       
    return (1.0 / (UINT_MAX + 1.0)) * Xorshift_32();
}

//-------------------------------------------------------------
// beta distribution random generator

double RndBeta(double a, double b)
{
    double x, y;

    do {
        x = pow(Rnd(), (1 / a));
        y = pow(Rnd(), (1 / b));

    } while (x + y > 1);
    
    return x / (x + y);
}


//-------------------------------------------------------------
// sequential random cv generator

void RandomCVGenerator(int trigger)
{
    int i, modeState;
    static int _modeState = -1;
    static bool triggerState = false;
    static uint8_t ch;
    static float randomcv[8], glidecv[8];
    unsigned int cv;
    static float qcv;
    static int jitter, jitterCount;
    
    switch (CheckQuantizeMode()) 
    {
        case Lin:
            
            glidecv[ch] = glidecv[ch] * gGlide + randomcv[ch] * (1.0f - gGlide);
            break;
                
        case Chr:

            qcv = calibMap1[(unsigned int)MapFloat(randomcv[ch], 0, SCALING_N, 0, (QUAN_RES1 - 1))];
                
            glidecv[ch] = glidecv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);

            break;
            
        case Maj:

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

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

            break;
        
        case M7:
            
            qcv = calibMap3[(unsigned int)MapFloat(randomcv[ch], 0, SCALING_N, 0, (QUAN_RES3 - 1))];
                
            glidecv[ch] = glidecv[ch] * gGlide + (qcv * SCALING_N) * (1.0f - gGlide);

            break;
            
        case Min7:

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

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

            break;
                
        case Dor:
            
            qcv = calibMap5[(unsigned int)MapFloat(randomcv[ch], 0, SCALING_N, 0, (QUAN_RES5 - 1))];

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

            break;
    
        case Min:
            
            qcv = calibMap6[(unsigned int)MapFloat(randomcv[ch], 0, SCALING_N, 0, (QUAN_RES6 - 1))];

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

            break;
            
        case S5th:

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

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

            break;
            
        case Wht:
            
            qcv = calibMap8[(unsigned int)MapFloat(randomcv[ch], 0, SCALING_N, 0, (QUAN_RES8 - 1))];

            glidecv[ch] = glidecv[ch] * 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[ch] + jitter);
    
    UpdateCV(WRITE_UPDATE_N, ch, &cv);
    
    if (trigger && !triggerState) // trigger ON
    { 
        modeState = CheckSubMode1();
          
        for (i = 0; i < 8; ++i)
        {
            if (modeState % 2)
            {
                // xorshift random
                randomcv[i] = fmodf(Xorshift_32(), SCALING_N);
                
                if (_modeState != modeState)
                {
                    UpdateSubModeLCD("Xorshift");
                }
                
            } else {
                // beta dist random
                randomcv[i] = RndBeta(MapFloat(gArdPot[0], 0, 1023.0f, 0, 5), MapFloat(gArdPot[1], 0, 1023.0f, 0, 5)) * SCALING_N; 
            
                if (_modeState != modeState)
                {
                    UpdateSubModeLCD(" -dist");
                    gLCD.locate( 0, 1 );
                    gLCD.putc(0xE2); // beta
                    
                    sendMes.setTopAddress("/submode");
                    sendMes.setArgs("s", "beta-dist");
                    
                    osc.sendOsc(&sendMes);
                }
                
            }
            
        }
        
        _modeState = modeState;    
        
        UpdateCVMeter(ch, &cv);        

        gGATES[0] = gGATES[1] = true;
        
        triggerState = true;
        
    } else if (!trigger) {        // trigger OFF
        
        gGATES[0] = gGATES[1] = false;
        
        triggerState = false;
    }
    
    ++ch;
    ch &= 0x07;
    
    ++jitterCount;
    jitterCount &= 0x1FF;

}