KIK 01 Prototype 05

Dependencies:   AverageMCP3008 mbed-rtos mbed mcp3008

Fork of KIK01_Proto03 by Ryo Od

Committer:
ryood
Date:
Sun Jun 04 06:25:48 2017 +0000
Revision:
3:f89b400cfe57
Parent:
2:8dff77a1ee4d
Child:
4:9f53a82fc1b6
Impl. BPM

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ryood 3:f89b400cfe57 1 /*
ryood 3:f89b400cfe57 2 * KIK01
ryood 3:f89b400cfe57 3 * Kick Machine
ryood 3:f89b400cfe57 4 *
ryood 3:f89b400cfe57 5 * 2017.06.04 created.
ryood 3:f89b400cfe57 6 *
ryood 3:f89b400cfe57 7 */
ryood 3:f89b400cfe57 8
ryood 0:2dcec10e9199 9 #include "mbed.h"
ryood 0:2dcec10e9199 10 #include "rtos.h"
ryood 0:2dcec10e9199 11
ryood 0:2dcec10e9199 12 #define TITLE_STR1 ("KIK01 Kick Machine")
ryood 0:2dcec10e9199 13 #define TITLE_STR2 ("20170604")
ryood 0:2dcec10e9199 14
ryood 0:2dcec10e9199 15 #define PI_F (3.1415926f)
ryood 2:8dff77a1ee4d 16 #define SAMPLING_RATE (96000)
ryood 0:2dcec10e9199 17 #define SAMPLING_PERIOD (1.0f/SAMPLING_RATE)
ryood 0:2dcec10e9199 18
ryood 0:2dcec10e9199 19 #define FREQUENCY_ATTACK (5)
ryood 0:2dcec10e9199 20 #define FREQUENCY_RELEASE (300)
ryood 0:2dcec10e9199 21 #define AMPLITUDE_ATTACK (50)
ryood 0:2dcec10e9199 22 #define AMPLITUDE_RELEASE (200)
ryood 0:2dcec10e9199 23
ryood 3:f89b400cfe57 24 AnalogOut Dac1(PA_5);
ryood 3:f89b400cfe57 25
ryood 3:f89b400cfe57 26 AnalogIn AinBpm(PA_0);
ryood 0:2dcec10e9199 27
ryood 0:2dcec10e9199 28 class EnvelopeAR {
ryood 0:2dcec10e9199 29 public:
ryood 0:2dcec10e9199 30 EnvelopeAR(int _attack, int _release, float _v0, float _v1, float _v2, float _attackTauRatio=0.36f, float _releaseTauRatio=0.36f) :
ryood 0:2dcec10e9199 31 amplitude(_v0),
ryood 0:2dcec10e9199 32 v0(_v0),
ryood 0:2dcec10e9199 33 v1(_v1),
ryood 0:2dcec10e9199 34 v2(_v2),
ryood 0:2dcec10e9199 35 vLast(_v0),
ryood 0:2dcec10e9199 36 attackTauRatio(_attackTauRatio),
ryood 0:2dcec10e9199 37 releaseTauRatio(_releaseTauRatio)
ryood 0:2dcec10e9199 38 {
ryood 0:2dcec10e9199 39 setAttack(_attack);
ryood 0:2dcec10e9199 40 setRelease(_release);
ryood 0:2dcec10e9199 41 }
ryood 0:2dcec10e9199 42
ryood 0:2dcec10e9199 43 ~EnvelopeAR() {}
ryood 0:2dcec10e9199 44
ryood 0:2dcec10e9199 45 void setAttack(int _attack) {
ryood 0:2dcec10e9199 46 attack = _attack;
ryood 0:2dcec10e9199 47 tau0 = attack * attackTauRatio;
ryood 0:2dcec10e9199 48 }
ryood 0:2dcec10e9199 49 int getAttack() { return attack; }
ryood 0:2dcec10e9199 50
ryood 0:2dcec10e9199 51 void setRelease(int _release) {
ryood 0:2dcec10e9199 52 release = _release;
ryood 0:2dcec10e9199 53 tau1 = release * releaseTauRatio;
ryood 0:2dcec10e9199 54 }
ryood 0:2dcec10e9199 55 int getRelease() { return release; }
ryood 0:2dcec10e9199 56
ryood 0:2dcec10e9199 57 void setAttackTauRatio(float _attackTauRatio) { attackTauRatio = _attackTauRatio; }
ryood 0:2dcec10e9199 58 float getAttackTauRatio() { return attackTauRatio; }
ryood 0:2dcec10e9199 59
ryood 0:2dcec10e9199 60 void setReleaseTauRatio(float _releaseTauRatio) { releaseTauRatio = _releaseTauRatio; }
ryood 0:2dcec10e9199 61 float getReleaseTauRatio() { return releaseTauRatio; }
ryood 0:2dcec10e9199 62
ryood 0:2dcec10e9199 63 void setV0(float _v0) { v0 = _v0; }
ryood 0:2dcec10e9199 64 float getV0() { return v0; }
ryood 0:2dcec10e9199 65 void setV1(float _v1) { v1 = _v1; }
ryood 0:2dcec10e9199 66 float getV1() { return v1; }
ryood 0:2dcec10e9199 67 void setV2(float _v2) { v2 = _v2; }
ryood 0:2dcec10e9199 68 float getV2() { return v2; }
ryood 0:2dcec10e9199 69
ryood 0:2dcec10e9199 70 float getAmplitude() { return amplitude; }
ryood 0:2dcec10e9199 71 float getAmplitude(int tick) {
ryood 0:2dcec10e9199 72 if (tick < attack) {
ryood 0:2dcec10e9199 73 // attackの処理
ryood 0:2dcec10e9199 74 amplitude = v0 + (v1 - v0) * (1 - expf(-(float)tick / tau0));
ryood 0:2dcec10e9199 75 vLast = amplitude;
ryood 0:2dcec10e9199 76 }
ryood 0:2dcec10e9199 77 else {
ryood 0:2dcec10e9199 78 // releaseの処理
ryood 0:2dcec10e9199 79 amplitude = (vLast - v2) * (expf(-(float)(tick - attack) / tau1)) + v2;
ryood 0:2dcec10e9199 80 }
ryood 0:2dcec10e9199 81 return amplitude;
ryood 0:2dcec10e9199 82 }
ryood 0:2dcec10e9199 83
ryood 0:2dcec10e9199 84 private:
ryood 0:2dcec10e9199 85 int attack;
ryood 0:2dcec10e9199 86 int release;
ryood 0:2dcec10e9199 87 float amplitude;
ryood 0:2dcec10e9199 88 float v0;
ryood 0:2dcec10e9199 89 float v1;
ryood 0:2dcec10e9199 90 float v2;
ryood 0:2dcec10e9199 91 float vLast;
ryood 0:2dcec10e9199 92 float tau0;
ryood 0:2dcec10e9199 93 float tau1;
ryood 0:2dcec10e9199 94 float attackTauRatio;
ryood 0:2dcec10e9199 95 float releaseTauRatio;
ryood 0:2dcec10e9199 96 };
ryood 0:2dcec10e9199 97
ryood 0:2dcec10e9199 98 EnvelopeAR envelopeFrequency(
ryood 0:2dcec10e9199 99 FREQUENCY_ATTACK, FREQUENCY_RELEASE, 880.0f, 120.0f, 40.0f, 0.36f, 0.1f);
ryood 0:2dcec10e9199 100 EnvelopeAR envelopeAmplitude(AMPLITUDE_ATTACK, AMPLITUDE_RELEASE, 0.9f, 1.0f, 0.0f);
ryood 0:2dcec10e9199 101
ryood 3:f89b400cfe57 102 volatile int ticks;
ryood 3:f89b400cfe57 103 volatile int envelopeTicks;
ryood 3:f89b400cfe57 104 volatile float frequency;
ryood 3:f89b400cfe57 105 volatile float phi;
ryood 3:f89b400cfe57 106 volatile float phiDelta;
ryood 3:f89b400cfe57 107 volatile float amplitude;
ryood 3:f89b400cfe57 108
ryood 3:f89b400cfe57 109 float bpm;
ryood 3:f89b400cfe57 110 int envelopeLength;
ryood 0:2dcec10e9199 111
ryood 0:2dcec10e9199 112 void generateWave()
ryood 0:2dcec10e9199 113 {
ryood 0:2dcec10e9199 114 phi += phiDelta;
ryood 0:2dcec10e9199 115 if (phi >= 1.0f) {
ryood 0:2dcec10e9199 116 phi -= 2.0f;
ryood 0:2dcec10e9199 117 }
ryood 0:2dcec10e9199 118 float level = sinf(PI_F * phi) * amplitude;
ryood 1:f9b967ae26e4 119
ryood 3:f89b400cfe57 120 Dac1.write((level * 0.7f + 1.0f) / 2.0f);
ryood 0:2dcec10e9199 121 }
ryood 0:2dcec10e9199 122
ryood 0:2dcec10e9199 123 void generateEnvelope()
ryood 0:2dcec10e9199 124 {
ryood 0:2dcec10e9199 125 // Frequency Envelope
ryood 0:2dcec10e9199 126 frequency = envelopeFrequency.getAmplitude(envelopeTicks);
ryood 0:2dcec10e9199 127 phiDelta = 2.0f * frequency / SAMPLING_RATE;
ryood 0:2dcec10e9199 128
ryood 0:2dcec10e9199 129 // Amplitude Envelope
ryood 0:2dcec10e9199 130 amplitude = envelopeAmplitude.getAmplitude(envelopeTicks);
ryood 0:2dcec10e9199 131
ryood 0:2dcec10e9199 132 envelopeTicks++;
ryood 3:f89b400cfe57 133 if (envelopeTicks == envelopeLength) {
ryood 0:2dcec10e9199 134 envelopeTicks = 0;
ryood 0:2dcec10e9199 135 }
ryood 0:2dcec10e9199 136 }
ryood 0:2dcec10e9199 137
ryood 2:8dff77a1ee4d 138 void update()
ryood 2:8dff77a1ee4d 139 {
ryood 3:f89b400cfe57 140 ticks++;
ryood 3:f89b400cfe57 141 if (ticks == SAMPLING_RATE / 1000) {
ryood 3:f89b400cfe57 142 ticks = 0;
ryood 2:8dff77a1ee4d 143 generateEnvelope();
ryood 2:8dff77a1ee4d 144 }
ryood 2:8dff77a1ee4d 145 generateWave();
ryood 2:8dff77a1ee4d 146 }
ryood 2:8dff77a1ee4d 147
ryood 0:2dcec10e9199 148 int main()
ryood 0:2dcec10e9199 149 {
ryood 0:2dcec10e9199 150 printf("%s %s\r\n", TITLE_STR1, TITLE_STR2);
ryood 0:2dcec10e9199 151
ryood 0:2dcec10e9199 152 frequency = 1000.0f;
ryood 0:2dcec10e9199 153 phiDelta = 2.0f * frequency / SAMPLING_RATE;
ryood 0:2dcec10e9199 154 amplitude = 1.0f;
ryood 0:2dcec10e9199 155
ryood 3:f89b400cfe57 156 ticks = 0;
ryood 2:8dff77a1ee4d 157 envelopeTicks = 0;
ryood 1:f9b967ae26e4 158
ryood 2:8dff77a1ee4d 159 Ticker samplingTicker;
ryood 2:8dff77a1ee4d 160 samplingTicker.attach(&update, SAMPLING_PERIOD);
ryood 2:8dff77a1ee4d 161
ryood 3:f89b400cfe57 162 bpm = 120.0f;
ryood 3:f89b400cfe57 163 for (;;) {
ryood 3:f89b400cfe57 164 bpm = AinBpm.read() * 120.0f + 60.0f;
ryood 3:f89b400cfe57 165 envelopeLength = 60 * 1000 / bpm;
ryood 3:f89b400cfe57 166 printf("%f\t%d\r\n", bpm, envelopeLength);
ryood 3:f89b400cfe57 167 Thread::wait(100);
ryood 3:f89b400cfe57 168 }
ryood 0:2dcec10e9199 169 }