KIK01 Release
Dependencies: mcp3008 mbed mbed-rtos AverageMCP3008 VoltageMonitor
main.cpp
- Committer:
- ryood
- Date:
- 2017-07-06
- Revision:
- 15:8f674acdac03
- Parent:
- 14:8e96f97e261b
- Child:
- 16:30cb822e072f
File content as of revision 15:8f674acdac03:
/* * KIK01 * Kick Machine * * 2017.07.04 Proto03: MCP4922 DCA * 2017.06.19 Proto02 * 2017.06.04 created. * */ #include "mbed.h" #include "rtos.h" #include "mcp3008.h" #include "SpiAmpController.h" #define UART_TRACE (0) #define PIN_CHECK (1) #define TITLE_STR1 ("KIK01 Kick Machine") #define TITLE_STR2 ("20170704") #define PI_F (3.1415926f) #define SAMPLING_RATE (16000) #define SAMPLING_PERIOD (1.0f/SAMPLING_RATE) #define ENVELOPE_UPDATE_RATE SAMPLING_RATE #define AMP_VREF 0x0fff AnalogOut Dac1(PA_4); SPI SpiM(SPI_MOSI, SPI_MISO, SPI_SCK); MCP3008 Adc0(&SpiM, D10); MCP3008 Adc1(&SpiM, D9); SpiAmpController ampController(&SpiM, D8, D7); // Check pins DigitalOut Dout0(D2); DigitalOut Dout1(D3); DigitalOut Dout2(D4); // Sync DigitalOut SyncPin(D7); 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; }; class EnvelopeParam { public: int attack; int release; float v0; float v1; float v2; float attackTauRatio; float releaseTauRatio; }; EnvelopeAR envelopeFrequency(5, 300, 880.0f, 120.0f, 40.0f, 0.36f, 0.1f); EnvelopeAR envelopeAmplitude(50, 200, 0.99f, 1.0f, 0.0f); volatile EnvelopeParam frequencyParam; volatile EnvelopeParam amplitudeParam; volatile int ticks; volatile int envelopeTicks; volatile float frequency; volatile float phi; volatile float phiDelta; volatile float amplitude; volatile float bpm; volatile int envelopeLength; volatile int stepLength; //-----------------------------------------------------------------------------// // Internal DCA // void generateWave_DcaInternal() { phi += phiDelta; if (phi >= 1.0f) { phi -= 2.0f; } float level = cosf(PI_F * phi) * amplitude; Dac1.write((level * 0.7f + 1.0f) / 2.0f); } void generateEnvelope_DcaInternal() { // Frequency Envelope frequency = envelopeFrequency.getAmplitude(envelopeTicks); phiDelta = 2.0f * frequency / SAMPLING_RATE; // Amplitude Envelope amplitude = envelopeAmplitude.getAmplitude(envelopeTicks); envelopeTicks++; if (envelopeTicks >= envelopeLength) { envelopeTicks = 0; phi = PI_F / 2.0f; } } //-----------------------------------------------------------------------------// // External DCA // void generateWave_DcaExternal() { phi += phiDelta; if (phi >= 1.0f) { phi -= 2.0f; } //float level = cosf(PI_F * phi) * amplitude; float level = cosf(PI_F * phi); Dac1.write((level * 0.7f + 1.0f) / 2.0f); } void generateEnvelope_DcaExternal() { // Frequency Envelope frequency = envelopeFrequency.getAmplitude(envelopeTicks); phiDelta = 2.0f * frequency / SAMPLING_RATE; // Amplitude Envelope amplitude = envelopeAmplitude.getAmplitude(envelopeTicks); SpiM.lock(); SpiM.frequency(16000000); ampController.outDca(amplitude * 4096); SpiM.frequency(2000000); SpiM.unlock(); envelopeTicks++; if (envelopeTicks >= envelopeLength) { envelopeTicks = 0; phi = PI_F / 2.0f; } } void update() { #if (PIN_CHECK) Dout0 = 1; #endif // Output Sync Signal per steps if (envelopeTicks % stepLength == 0) { SyncPin = 1; } ticks++; if (ticks >= SAMPLING_RATE / ENVELOPE_UPDATE_RATE) { #if (PIN_CHECK) Dout1 = 1; #endif ticks = 0; // set envelope parameters envelopeAmplitude.setAttack(amplitudeParam.attack); envelopeAmplitude.setRelease(amplitudeParam.release); envelopeAmplitude.setV0(amplitudeParam.v0); envelopeAmplitude.setV1(amplitudeParam.v1); envelopeAmplitude.setV2(amplitudeParam.v2); envelopeAmplitude.setAttackTauRatio(amplitudeParam.attackTauRatio); envelopeAmplitude.setReleaseTauRatio(amplitudeParam.releaseTauRatio); envelopeFrequency.setAttack(frequencyParam.attack); envelopeFrequency.setRelease(frequencyParam.release); envelopeFrequency.setV0(frequencyParam.v0); envelopeFrequency.setV1(frequencyParam.v1); envelopeFrequency.setV2(frequencyParam.v2); envelopeFrequency.setAttackTauRatio(frequencyParam.attackTauRatio); envelopeFrequency.setReleaseTauRatio(frequencyParam.releaseTauRatio); generateEnvelope_DcaExternal(); #if (PIN_CHECK) Dout1 = 0; #endif } generateWave_DcaExternal(); // Output SyncSignal SyncPin = 0; #if (PIN_CHECK) Dout0 = 0; #endif } void setParams() { bpm = Adc0.read_input(7) * 180.0f + 60.0f; envelopeLength = 60 * ENVELOPE_UPDATE_RATE / bpm; stepLength = envelopeLength / 4; amplitudeParam.attack = Adc0.read_input(0) * envelopeLength; amplitudeParam.release = Adc0.read_input(1) * envelopeLength; amplitudeParam.v0 = Adc0.read_input(4); amplitudeParam.v1 = Adc0.read_input(5); amplitudeParam.v2 = Adc0.read_input(6); amplitudeParam.attackTauRatio = 0.36f; amplitudeParam.releaseTauRatio = Adc0.read_input(3) + 0.01f; frequencyParam.attack = Adc1.read_input(0) * envelopeLength * 0.1f; frequencyParam.release = Adc1.read_input(1) * envelopeLength + 1; frequencyParam.v0 = Adc1.read_input(4) * 4000.0f; frequencyParam.v1 = Adc1.read_input(5) * 400.0f; frequencyParam.v2 = Adc1.read_input(6) * 400.0f; frequencyParam.attackTauRatio = Adc1.read_input(2) + 0.01f; frequencyParam.releaseTauRatio = Adc1.read_input(3) + 0.01f; } int main() { printf("%s %s\r\n", TITLE_STR1, TITLE_STR2); SpiM.format(0, 0); SpiM.frequency(2000000); frequency = 1000.0f; phiDelta = 2.0f * frequency / SAMPLING_RATE; amplitude = 1.0f; ticks = 0; envelopeTicks = 0; bpm = 120.0f; setParams(); Ticker samplingTicker; samplingTicker.attach(&update, SAMPLING_PERIOD); for (;;) { #if (PIN_CHECK) Dout2 = 1; #endif setParams(); #if (PIN_CHECK) Dout2 = 0; #endif #if UART_TRACE printf("%.1f\t%d\t", bpm, envelopeLength); printf("%d\t%d\t", amplitudeParam.attack, amplitudeParam.release); printf("%.2f\t%.2f\t%.2f\t", amplitudeParam.v0, amplitudeParam.v1, amplitudeParam.v2); printf("%.2f\t%.2f\t", amplitudeParam.attackTauRatio, amplitudeParam.releaseTauRatio); printf("%d\t%d\t", frequencyParam.attack, frequencyParam.release); printf("%.2f\t%.2f\t%.2f\t", frequencyParam.v0, frequencyParam.v1, frequencyParam.v2); printf("%.2f\t%.2f\r\n", frequencyParam.attackTauRatio, frequencyParam.releaseTauRatio); #endif Thread::wait(1); } }