Ryo Od
/
NucleoF446_EnvelopeGenerator_AR
AR Envelope Generator
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 (;;) {} }