Integrated version
BaseMachineUIController.h
- Committer:
- ryood
- Date:
- 2016-11-07
- Revision:
- 3:f790643458d9
- Parent:
- 2:238127b00dd3
- Child:
- 4:0a55042fa86c
File content as of revision 3:f790643458d9:
/* * BaseMachineUIController.h * * 2016.11.06 created * */ #ifndef _UICONTROLLER_H_ #define _UICONTROLLER_H_ #include "mbed.h" #include "rtos.h" #include "BaseMachineCommon.h" #include "st7565LCD.h" #include "PinDetect.h" #include "RotaryEncoder.h" #include "AverageAnalogIn.h" #include "Sequence.h" #include "ST7565_SequencerDisplay.h" #define GLCD_SPI_RATE (1000000) #define POT_RESOLUTION (7) // bit #define AIN_AVERAGE (16) // AnalogInを移動平均する要素数 const int bpmMax = 240; const int bpmMin = 60; const int octaveMax = 2; const int octaveMin = -2; const int waveShapeMax = 1; const int UImodeMax = 2; struct OscillatorParam { uint8_t waveShape; uint8_t pulseWidth; OscillatorParam() : waveShape(0), pulseWidth(0) {} }; struct FilterParam { uint8_t cutoff; uint8_t resonance; FilterParam() : cutoff(0), resonance(0) {} }; struct EnvelopeParam { uint8_t level; uint8_t length; uint8_t duration; uint8_t decay; uint8_t sustain; EnvelopeParam() : level(0), length(0), duration(0), decay(0), sustain(0) {} }; class BaseMachineUIController { public: BaseMachineUIController() : bpm(120), accentLevel(127), editingStep(0), playingStep(0), isRunning(false), isDirty(true), UImode(0), isStepChanged(false), errCutoff(0), errDuration(0), errDecay(0), errSustain(0), errResonance(0), errLevel(0), errPulseWidth(0), errAccentLevel(0) { } ~BaseMachineUIController() {} void init() { //-------------------------------------------------------------------- // Create Dvices // //ST7565(PinName mosi, PinName sclk, PinName cs, PinName rst, PinName a0); gLCD = new ST7565(PB_15, PB_13, PB_12, PB_2, PB_1); sequencerDisplay = new ST7565_SequencerDisplay(gLCD, sequences, SEQUENCE_N); AinPulseWidth = new AverageAnalogIn(PC_2, AIN_AVERAGE); AinCutOff = new AverageAnalogIn(PB_0, AIN_AVERAGE); AinResonance = new AverageAnalogIn(PC_1, AIN_AVERAGE); AinLevel = new AverageAnalogIn(PC_0, AIN_AVERAGE); AinDuration = new AverageAnalogIn(PA_4, AIN_AVERAGE); AinDecay = new AverageAnalogIn(PA_1, AIN_AVERAGE); AinSustain = new AverageAnalogIn(PA_0, AIN_AVERAGE); AinAccentLevel= new AverageAnalogIn(PC_3, AIN_AVERAGE); RotEncStep = new RotaryEncoder(PA_11, PA_12, 0, SEQUENCE_N - 1, 0); RotEncPitch = new RotaryEncoder(PB_5, PB_4, 0, Sequence::getMaxPitch() - 1, 0); RotEncBpm = new RotaryEncoder(PC_12, PC_10, bpmMin, bpmMax, 120); PinWaveShape = new PinDetect(PD_2, PullUp); PinUIMode = new PinDetect(PC_11, PullUp); PinOctaveUp = new PinDetect(PB_3, PullUp); PinOctaveDown = new PinDetect(PA_10, PullUp); PinNoteOnOff = new PinDetect(PC_5, PullUp); PinTie = new PinDetect(PC_6, PullUp); PinAccent = new PinDetect(PC_8, PullUp); PinRunStop = new PinDetect(PC_9, PullUp); //-------------------------------------------------------------------- // Setup Devices // gLCD->set_spi_frequency(GLCD_SPI_RATE); gLCD->begin(0x12); gLCD->clear(); gLCD->drawstring(0, 0, TITLE_STR1); gLCD->drawstring(0, 1, TITLE_STR2); gLCD->display(); Thread::wait(1000); RotEncStep->setInterval(100); RotEncPitch->setInterval(100); RotEncBpm->setInterval(100); PinWaveShape->attach_asserted(this, &BaseMachineUIController::swWaveShapePressed); PinWaveShape->setAssertValue(0); PinWaveShape->setSampleFrequency(); PinUIMode->attach_asserted(this, &BaseMachineUIController::swUIModePressed); PinUIMode->setAssertValue(0); PinUIMode->setSampleFrequency(); PinOctaveUp->attach_asserted(this, &BaseMachineUIController::swOctaveUpPressed); PinOctaveUp->setAssertValue(0); PinOctaveUp->setSampleFrequency(); PinOctaveDown->attach_asserted(this, &BaseMachineUIController::swOctaveDownPressed); PinOctaveDown->setAssertValue(0); PinOctaveDown->setSampleFrequency(); PinNoteOnOff->attach_asserted(this, &BaseMachineUIController::swNoteOnOffPressed); PinNoteOnOff->setAssertValue(0); PinNoteOnOff->setSampleFrequency(); PinTie->attach_asserted(this, &BaseMachineUIController::swTiePressed); PinTie->setAssertValue(0); PinTie->setSampleFrequency(); PinAccent->attach_asserted(this, &BaseMachineUIController::swAccentPressed); PinAccent->setAssertValue(0); PinAccent->setSampleFrequency(); PinRunStop->attach_asserted(this, &BaseMachineUIController::swRunStopPressed); PinRunStop->setAssertValue(0); PinRunStop->setSampleFrequency(); //-------------------------------------------------------------------- // Initialize objects // Sequence::setBaseNoteNumber(baseNoteNumber); for (int i = 0; i < SEQUENCE_N; i++) { Sequence& seq = sequences[i]; seq.setPitch(pitch[i]); seq.setNoteOn(noteOn[i]); seq.setTie(tie[i]); seq.setAccent(accent[i]); } RotEncPitch->setVal(sequences[0].getPitch()); } void destract() { //-------------------------------------------------------------------- // Destract Devices // delete gLCD; delete AinPulseWidth; delete AinCutOff; delete AinResonance; delete AinLevel; delete AinDuration; delete AinDecay; delete AinSustain; delete AinAccentLevel; delete RotEncStep; delete RotEncPitch; delete RotEncBpm; delete PinWaveShape; delete PinUIMode; delete PinOctaveUp; delete PinOctaveDown; delete PinNoteOnOff; delete PinTie; delete PinAccent; delete PinRunStop; } void getSequences(Sequence (*pSequences)[SEQUENCE_N]) { memcpy(pSequences, sequences, sizeof(sequences)); } void getOscillatorParam(OscillatorParam* pParam) { memcpy(pParam, &oscillatorParam, sizeof(oscillatorParam)); } void getFilterParam(FilterParam* pParam) { memcpy(pParam, &filterParam, sizeof(filterParam)); } void getEnvelopeParam(EnvelopeParam* pParam) { memcpy(pParam, &envelopeParam, sizeof(envelopeParam)); } uint8_t getBpm() { return bpm; } uint8_t getAccentLevel() { return accentLevel; } bool getIsRunning() { return isRunning; } void setPlayingStep(int step) { playingStep = step; isDirty = true; } void update() { pollingRotEncs(); pollingPots(); switch (UImode) { case 0: if (isDirty) { if (isRunning) { sequencerDisplay->update(SequencerDisplay::run, editingStep, playingStep); } else { sequencerDisplay->update(SequencerDisplay::stop, editingStep, playingStep); } isDirty = false; } break; case 1: dumpToLCD00(); break; case 2: dumpToLCD01(); break; } } private: ST7565* gLCD; AverageAnalogIn* AinPulseWidth; AverageAnalogIn* AinCutOff; AverageAnalogIn* AinResonance; AverageAnalogIn* AinLevel; AverageAnalogIn* AinDuration; AverageAnalogIn* AinDecay; AverageAnalogIn* AinSustain; AverageAnalogIn* AinAccentLevel; RotaryEncoder* RotEncStep; RotaryEncoder* RotEncPitch; RotaryEncoder* RotEncBpm; PinDetect* PinWaveShape; PinDetect* PinUIMode; PinDetect* PinOctaveUp; PinDetect* PinOctaveDown; PinDetect* PinNoteOnOff; PinDetect* PinTie; PinDetect* PinAccent; PinDetect* PinRunStop; ST7565_SequencerDisplay* sequencerDisplay; Sequence sequences[SEQUENCE_N]; OscillatorParam oscillatorParam; FilterParam filterParam; EnvelopeParam envelopeParam; uint8_t bpm; uint8_t accentLevel; int editingStep; int playingStep; bool isRunning; bool isDirty; int UImode; bool isStepChanged; int errCutoff; int errDuration; int errDecay; int errSustain; int errResonance; int errLevel; int errPulseWidth; int errAccentLevel; //------------------------------------------------------------------------ // PinDetect callback functions //------------------------------------------------------------------------ void swWaveShapePressed() { #if (UART_TRACE) printf("PinWaveShape Pushed\r\n"); #endif uint8_t _waveShape = oscillatorParam.waveShape; _waveShape++; if (_waveShape > waveShapeMax) { _waveShape = 0; } oscillatorParam.waveShape = _waveShape; sequencerDisplay->setWaveShape(_waveShape); isDirty = true; } void swUIModePressed() { #if (UART_TRACE) printf("PinUIMode Pushed\r\n"); #endif UImode++; if (UImode > UImodeMax) { UImode = 0; } isDirty = true; } void swOctaveUpPressed() { #if (UART_TRACE) printf("PinOctaveUp Pushed\r\n"); #endif if (sequencerDisplay->getOctave() < octaveMax) { sequencerDisplay->setOctave(sequencerDisplay->getOctave() + 1); isDirty = true; } } void swOctaveDownPressed() { #if (UART_TRACE) printf("PinOctaveDown Pushed\r\n"); #endif if (sequencerDisplay->getOctave () > octaveMin) { sequencerDisplay->setOctave(sequencerDisplay->getOctave() - 1); isDirty = true; } } void swNoteOnOffPressed() { #if (UART_TRACE) printf("PinNoteOnOff Pushed\r\n"); #endif sequences[editingStep].setNoteOn(!sequences[editingStep].isNoteOn()); isDirty = true; } void swTiePressed() { #if (UART_TRACE) printf("PinTie Pushed\r\n"); #endif sequences[editingStep].setTie(!sequences[editingStep].isTie()); isDirty = true; } void swAccentPressed() { #if (UART_TRACE) printf("PinAccent Pushed\r\n"); #endif sequences[editingStep].setAccent(!sequences[editingStep].isAccent()); isDirty = true; } void swRunStopPressed() { #if (UART_TRACE) printf("PinRunStop Pushed\r\n"); #endif if (isRunning) { isRunning = false; } else { isRunning = true; } isDirty = true; } //------------------------------------------------------------------------ // Functions //------------------------------------------------------------------------ void pollingRotEncs() { int _bpm = RotEncBpm->getVal(); if (_bpm != bpm) { bpm = _bpm; sequencerDisplay->setBpm(_bpm); isDirty = true; } int _step = RotEncStep->getVal(); if (_step != editingStep) { editingStep = _step; // syncronize sequence value & Rotary Encoder's value RotEncPitch->setVal(sequences[editingStep].getPitch()); isDirty = true; } int _pitch = RotEncPitch->getVal(); if (_pitch != sequences[editingStep].getPitch()) { sequences[editingStep].setPitch(_pitch); isDirty = true; } } void pollingPots() { uint8_t pulseWidth = AinPulseWidth->read_u16() >> (16 - POT_RESOLUTION); if (pulseWidth != oscillatorParam.pulseWidth) { oscillatorParam.pulseWidth = pulseWidth; errPulseWidth++; //isDirty = true; } uint8_t cutoff = AinCutOff->read_u16() >> (16 - POT_RESOLUTION); if (cutoff != filterParam.cutoff) { filterParam.cutoff = cutoff; errCutoff++; //isDirty = true; } uint8_t resonance = AinResonance->read_u16() >> (16 - POT_RESOLUTION); if (resonance != filterParam.resonance) { filterParam.resonance = resonance; errResonance++; //isDirty = true; } uint8_t level = AinLevel->read_u16() >> (16 - POT_RESOLUTION); if (level != envelopeParam.level) { errLevel++; envelopeParam.level = level; //isDirty = true; } uint8_t duration = AinDuration->read_u16() >> (16 - POT_RESOLUTION); if (duration != envelopeParam.duration) { errDuration++; envelopeParam.duration = duration; //isDirty = true; } uint8_t decay = AinDecay->read_u16() >> (16 - POT_RESOLUTION); if (decay != envelopeParam.decay) { errDecay++; envelopeParam.decay = decay; //isDirty = true; } uint8_t sustain = AinSustain->read_u16() >> (16 - POT_RESOLUTION); if (sustain != envelopeParam.sustain) { errSustain++; envelopeParam.sustain = sustain; //isDirty = true; } uint8_t _accentLevel = AinAccentLevel->read_u16() >> (16 - POT_RESOLUTION); if (_accentLevel != accentLevel) { errAccentLevel++; accentLevel = _accentLevel; //isDirty = true; } } void dumpToLCD00() { char buff[64]; int col = 0; gLCD->clear(); sprintf(buff, "Run:%d BPM:%03d", isRunning, bpm); gLCD->drawstring(0, col++, buff); sprintf(buff, "Stp:%02d Nto:%d Pch:%02d", editingStep, sequences[editingStep].isNoteOn(), sequences[editingStep].getPitch()); gLCD->drawstring(0, col++, buff); sprintf(buff, "Oct:%-2d Tie:%d Acc:%d", sequencerDisplay->getOctave(), sequences[editingStep].isTie(),sequences[editingStep].isAccent()); gLCD->drawstring(0, col++, buff); sprintf(buff, "Wsp:%d Mod:%d pStp:%d", oscillatorParam.waveShape, UImode, playingStep); gLCD->drawstring(0, col++, buff); sprintf(buff, "RSO:%4d CO :%4d", filterParam.resonance, filterParam.cutoff); gLCD->drawstring(0, col++, buff); sprintf(buff, "LVL:%4d DUR:%4d", envelopeParam.level, envelopeParam.duration); gLCD->drawstring(0, col++, buff); sprintf(buff, "PW :%4d DCY:%4d", oscillatorParam.pulseWidth, envelopeParam.decay); gLCD->drawstring(0, col++, buff); sprintf(buff, "ACL:%4d SUS:%4d", accentLevel, envelopeParam.sustain); gLCD->drawstring(0, col++, buff); gLCD->display(); } void dumpToLCD01() { char buff[64]; gLCD->clear(); sprintf(buff, "Cutoff %3d %5d", filterParam.cutoff, errCutoff); gLCD->drawstring(0, 0, buff); sprintf(buff, "Duration %3d %5d", envelopeParam.duration, errDuration); gLCD->drawstring(0, 1, buff); sprintf(buff, "Decay %3d %5d", envelopeParam.decay, errDecay); gLCD->drawstring(0, 2, buff); sprintf(buff, "Sustain %3d %5d", envelopeParam.sustain, errSustain); gLCD->drawstring(0, 3, buff); sprintf(buff, "Resonance %3d %5d", filterParam.resonance, errResonance); gLCD->drawstring(0, 4, buff); sprintf(buff, "Level %3d %5d", envelopeParam.level, errLevel); gLCD->drawstring(0, 5, buff); sprintf(buff, "PulseWidth %3d %5d", oscillatorParam.pulseWidth, errPulseWidth); gLCD->drawstring(0, 6, buff); sprintf(buff, "AccentLvl %3d %5d", accentLevel, errAccentLevel); gLCD->drawstring(0, 7, buff); gLCD->display(); } }; #endif //_UICONTROLLER_H_