Nucleo Sequencer of my Base Machine

Dependencies:   Amp AverageAnalogIn Envelope FilterController Sequence BaseMachineComon mbed-rtos mbed

Fork of SpiSequenceSender_Test by Ryo Od

main.cpp

Committer:
ryood
Date:
2016-08-23
Revision:
17:557658db3e81
Parent:
16:b0419e3c9079
Child:
18:309f794eba74

File content as of revision 17:557658db3e81:

/*
 * main.cpp
 * SpiSequencerSender_test
 *
 * 2016.08.20 mbed Rev 121 / mbed-rtos Rev 117で動作確認
 *
 */

#include "mbed.h"
#include "rtos.h"
#include "st7565LCD.h"

#define UART_TRACE  (0)
#include "SpiSequenceSender.h"
#include "EnvelopeGenerator.h"
#include "SpiAmpController.h"
#include "SpiFilterController.h"
#include "ST7565_SequencerDisplay.h"

#define TITLE_STR1  ("BaseMachine Sequencer")
#define TITLE_STR2  ("20160823")

#define SEQUENCE_N  (16)
#define SPI_RATE    (8000000)

const int samplingPeriod = 1;   // ms
const int bpm = 120;
const int envelopeLength = (60 * 1000 / (bpm * 4)) / samplingPeriod;
const int waveShape = SpiSequenceSender::WAVESHAPE_SAW;
const int baseNoteNumber = 48;

// Initial Sequence
const int noteOn[SEQUENCE_N] = { 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0 };
const int octave[SEQUENCE_N] = {-1,-1,-1, 0, 0,-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 };
const int pitch[SEQUENCE_N]  = { 9, 7, 3, 0, 0, 3, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0 };
const int tie[SEQUENCE_N]    = { 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0 };

// Devices
//
//SPI (PinName mosi, PinName miso, PinName sclk, PinName ssel=NC)
//SPI spiMaster(PA_7, PA_6, PA_5);
SPI spiMaster(SPI_MOSI, SPI_MISO, SPI_SCK);

//ST7565(PinName mosi, PinName sclk, PinName cs, PinName rst, PinName a0);
ST7565 gLCD(PB_15, PB_13, PB_12, PB_2, PB_1);

//AnalogIn levelIn(A0);
AnalogIn durationIn(A2);
AnalogIn decayIn(A1);
AnalogIn sustainIn(A0);
AnalogIn cutoffIn(A3);
AnalogIn resonanceIn(A4);

// Grobal Variables
//
Sequence sequences[SEQUENCE_N];
SpiSequenceSender sequenceSender(&spiMaster, D9, sequences, SEQUENCE_N, samplingPeriod, bpm);

Envelope envelope(4095, envelopeLength, envelopeLength*3/4, envelopeLength/2, 2047);
EnvelopeGenerator envelopeGenerator;
SpiAmpController ampController(&spiMaster, D8, D7);

SpiFilterController filterController(&spiMaster, D10);

ST7565_SequencerDisplay sequencerDisplay(&gLCD, sequences, SEQUENCE_N);

volatile int currentStep = 0;
volatile bool isRunning = false;
volatile bool isDirty = false;
volatile uint8_t pinFlag = 0x00;

enum PinBit {
    bWaveShape  = 0x01,
    bModNumber  = 0x02,
    bOctaveUp   = 0x04,
    bOctaveDown = 0x08,
    bNoteOnOff  = 0x10,
    bTie        = 0x20,
    bAccent     = 0x40,
    bRunStop    = 0x80
};

// とりあえずの変数(後でClassのメンバ変数に格納)
#define MOD_NUMBER_MAX 1
volatile int modNumber = 0;
volatile uint8_t cutOff;
volatile uint8_t resonance;
volatile uint8_t envMod;
volatile uint8_t level;
volatile uint8_t duration;
volatile uint8_t decay;
volatile uint8_t sustain;

//------------------------------------------------------------------------
// Callback functions
//------------------------------------------------------------------------
void updateFunction(int ticks)
{
    if (ticks == 0) {
        envelopeGenerator.init(envelope);
    }

    if (sequenceSender.getSequences()[sequenceSender.getStep()].isNoteOn()) {
        uint16_t level = envelopeGenerator.getModLevel();
        ampController.outDca(level);
    } else {
        ampController.outDca(0);
    }
    envelopeGenerator.update();
    
    filterController.outDcf();
    
    // ToDo: 再生中のLCD表示を検討→SPI1とSPI2の信号のタイミングを調査
    //sequencerDisplay.update(SequencerDisplay::stop, sequenceSender.getStep());
}

//------------------------------------------------------------------------
// Functions
//------------------------------------------------------------------------
void dumpToLCD()
{
    char buff[64];
    int col = 0;
    
    gLCD.clear();

    sprintf(buff, "Run: %d", isRunning);
    gLCD.drawstring(0, col++, buff);
    sprintf(buff, "BPM: %d", sequenceSender.getBpm());
    gLCD.drawstring(0, col++, buff);

    sprintf(buff, "Step: %d", currentStep);
    gLCD.drawstring(0, col++, buff);
    sprintf(buff, "NoteOn: %d", sequences[currentStep].isNoteOn());
    gLCD.drawstring(0, col++, buff);
    sprintf(buff, "Pitch: %d", sequences[currentStep].getPitch());
    gLCD.drawstring(0, col++, buff);
    sprintf(buff, "Octave: %d", sequences[currentStep].getOctave());
    gLCD.drawstring(0, col++, buff);
    sprintf(buff, "Tie: %d", sequences[currentStep].isTie());
    gLCD.drawstring(0, col++, buff);
    sprintf(buff, "Accent: %d", sequences[currentStep].isAccent());
    gLCD.drawstring(0, col++, buff);
    
    col = 0;
    sprintf(buff, "WavS: %d", sequenceSender.getWaveShape());
    gLCD.drawstring(64, col++, buff);
    sprintf(buff, "ModN: %d", modNumber);
    gLCD.drawstring(64, col++, buff);
    
    col = 2;
    sprintf(buff, "PW%3d CO%3d", sequenceSender.getPulseWidth(), cutOff);
    gLCD.drawstring(60, col++, buff);
    sprintf(buff, "RS%3d EV%3d", resonance, envMod);
    gLCD.drawstring(60, col++, buff);
    sprintf(buff, "LV%3d DR%3d", level, duration);
    gLCD.drawstring(60, col++, buff);
    sprintf(buff, "DC%3d ST%3d", decay, sustain);
    gLCD.drawstring(60, col++, buff);

    gLCD.display();
}

//------------------------------------------------------------------------
// Main routine
//------------------------------------------------------------------------
int main()
{
    // Setup Devices
    //
    spiMaster.format(8, 0);
    spiMaster.frequency(SPI_RATE);
    
    gLCD.begin(0x12);
    gLCD.clear();
    gLCD.drawstring(0, 0, TITLE_STR1);
    gLCD.drawstring(0, 1, TITLE_STR2);
    gLCD.display();
    Thread::wait(1000);
    
    dumpToLCD();
    Thread::wait(1000);
    
    sequencerDisplay.update(SequencerDisplay::stop, 0);
    
    // Test SequencerSender Run
    //
    Sequence::setBaseNoteNumber(baseNoteNumber);
    sequenceSender.setBpm(bpm);
    
    for (int i = 0; i < SEQUENCE_N; i++) {
        Sequence& seq = sequenceSender.getSequences()[i];
        seq.setPitch(pitch[i]);
        seq.setOctave(octave[i]);
        seq.setNoteOn(noteOn[i]);
        seq.setTie(tie[i]);
    }
    
    envelopeGenerator.init(envelope);

    sequenceSender.attachUpdate(&updateFunction);
    sequenceSender.setWaveShape(waveShape);
    sequenceSender.run(0);
    
    for (;;) {
        /*
        sequenceSender.setPulseWidth(sequenceSender.getPulseWidth() + 4);
        Thread::wait(500);
        sequenceSender.setWaveShape(SpiSequenceSender::WAVESHAPE_SAW);
        Thread::wait(500);
        sequenceSender.setWaveShape(SpiSequenceSender::WAVESHAPE_SQUARE);
        */
        //envelope.setLevel(levelIn * 4095);
        envelope.setLevel(4095);
        envelope.setDuration(durationIn * envelopeLength);
        envelope.setDecay(decayIn * envelopeLength);
        envelope.setSustain(sustainIn * 4095);
        
        filterController.setCutoff(cutoffIn * 255);
        filterController.setResonance(resonanceIn * 255);
        
        #if(UART_TRACE)
        printf("%d\t%d\t%d\t%d\t%d\t%d\r\n",
            filterController.getCutoff(),
            filterController.getResonance(),
            envelope.getLevel(),
            envelope.getDuration(),
            envelope.getDecay(),
            envelope.getSustain()
        );
        #endif
    }
}