AR Envelope Generator

Dependencies:   mbed

main.cpp

Committer:
ryood
Date:
2017-08-15
Revision:
0:a08920b1cb6d

File content as of revision 0:a08920b1cb6d:

/*
 * Nucleo F446 内蔵DACでエンベロープ波形発生
 *
 * 2017.08.14
 *
 */

#include "mbed.h"

#define UART_TRACE      (0)
#define TITLE_STR1      ("Envelope Generator")
#define TITLE_STR2      ("20170814")

#define PI_F            (3.1415926f)
#define SAMPLING_RATE   (48000)
#define SAMPLING_PERIOD (1.0f/SAMPLING_RATE)
#define ENVELOPE_UPDATE_RATE    SAMPLING_RATE

AnalogOut Dac1(PA_4);

class EnvelopeAR
{
public:
    EnvelopeAR(int _attack, int _release, float _v0, float _v1, float _v2, float _attackTauRatio=0.36f, float _releaseTauRatio=0.36f) :
        amplitude(_v0),
        v0(_v0),
        v1(_v1),
        v2(_v2),
        vLast(_v0),
        attackTauRatio(_attackTauRatio),
        releaseTauRatio(_releaseTauRatio) {
        setAttack(_attack);
        setRelease(_release);
    }

    ~EnvelopeAR() {}

    void setAttack(int _attack) {
        attack = _attack;
        tau0 = attack * attackTauRatio;
    }
    int getAttack() {
        return attack;
    }

    void setRelease(int _release) {
        release = _release;
        tau1 = release * releaseTauRatio;
    }
    int getRelease() {
        return release;
    }

    void setAttackTauRatio(float _attackTauRatio) {
        attackTauRatio = _attackTauRatio;
        tau0 = attack * attackTauRatio;
    }
    float getAttackTauRatio() {
        return attackTauRatio;
    }

    void setReleaseTauRatio(float _releaseTauRatio) {
        releaseTauRatio = _releaseTauRatio;
        tau1 = release * releaseTauRatio;
    }
    float getReleaseTauRatio() {
        return releaseTauRatio;
    }

    float getTau0() {
        return tau0;
    }
    float getTau1() {
        return tau1;
    }

    void setV0(float _v0) {
        v0 = _v0;
    }
    float getV0() {
        return v0;
    }
    void setV1(float _v1) {
        v1 = _v1;
    }
    float getV1() {
        return v1;
    }
    void setV2(float _v2) {
        v2 = _v2;
    }
    float getV2() {
        return v2;
    }

    float getAmplitude() {
        return amplitude;
    }
    float getAmplitude(int tick) {
        if (tick < attack) {
            // attackの処理
            amplitude = v0 + (v1 - v0) * (1 - expf(-(float)tick / tau0));
            vLast = amplitude;
        } else {
            // releaseの処理
            amplitude = (vLast - v2) * (expf(-(float)(tick - attack) / tau1)) + v2;
        }
        return amplitude;
    }

private:
    int attack;
    int release;
    float amplitude;
    float v0;
    float v1;
    float v2;
    float vLast;
    float tau0;
    float tau1;
    float attackTauRatio;
    float releaseTauRatio;
};

//EnvelopeAR(int _attack, int _release, float _v0, float _v1, float _v2, float _attackTauRatio=0.36f, float _releaseTauRatio=0.36f) :
EnvelopeAR envelopeAmplitude(50, 200, 0.99f, 1.0f, 0.0f, 0.36f, 0.36f);

volatile int envelopeTicks;
volatile int envelopeLength;
volatile float amplitude;

int bpm;

void generateEnvelope()
{
    // Amplitude Envelope
    amplitude = envelopeAmplitude.getAmplitude(envelopeTicks);

#if UART_TRACE
    printf("%8d\t%8d\t%f\r\n", envelopeLength, envelopeTicks, amplitude);
#endif

    Dac1.write(amplitude);

    envelopeTicks++;
    if (envelopeTicks >= envelopeLength) {
        envelopeTicks = 0;
    }
}

void update()
{
    generateEnvelope();
}

//------------------------------------------------------------------------------
// ここでパラメータを設定
//------------------------------------------------------------------------------
void setParams()
{
    bpm = 120.0f;

    envelopeLength = 60 * ENVELOPE_UPDATE_RATE / bpm;
    
    envelopeAmplitude.setAttack(envelopeLength * 0.1f);
    envelopeAmplitude.setRelease(envelopeLength * 0.6f);
    envelopeAmplitude.setV0(0.99f);
    envelopeAmplitude.setV1(1.0f);
    envelopeAmplitude.setV2(0.0f);
    envelopeAmplitude.setAttackTauRatio(0.36f);
    envelopeAmplitude.setReleaseTauRatio(0.6f);
}

int main()
{
#if UART_TRACE
    printf("%s %s\r\n", TITLE_STR1, TITLE_STR2);
#endif

    setParams();
    envelopeTicks = 0;

    Ticker samplingTicker;
    samplingTicker.attach(&update, SAMPLING_PERIOD);

    for (;;) {}
}