Nucleo F401REでFM音源を実装するやつ 外部DACとオペアンプを利用 現在はMCP4922とNJM2737

Dependencies:   AOTTrigon I2CEEPROM MCP4922 AQM0802A mbed

Fork of NuMidi401 by Yuu Kobayashi

NuFM401

Nucleo F401用の自作ソフトウェアMIDI音源

概要

だいたいそんなもんです。

特徴

  • ブレッドボードの上で組める程度には簡単な回路構成
  • 外部のDACにMCP4922を採用
  • 念のためのボルテージフォロアとしてNJM2737Dを採用
  • バンク用EEPROMに24FC1025を採用
  • シリアル経由でMIDIデータを受信することで操作

補足

シリアル <=> MIDI のドライバにはHairless-MIDISerialをオススメします。 仮想MIDIケーブルはとりあえずMIDI Yokeで。

FMOscillator/MIDIChannel.NRPNFunction.cpp

Committer:
kb10uy
Date:
2015-01-31
Revision:
24:f93b49b4cd66
Parent:
23:deb76bdf6f03

File content as of revision 24:f93b49b4cd66:

#include "MIDIChannel.h"

void MIDIChannel::setNRPNFunctions()
{
    switch(nrpnMSB) {
        case 0x10:
            nrpnStateSetter.attach(this, &MIDIChannel::setStateNRPNAlgorithm);
            nrpnStateProcessor.attach(this, &MIDIChannel::nrpnAlgorithm);
            break;
        case 0x20:
            nrpnStateSetter.attach(this, &MIDIChannel::setStateNRPNOperator);
            nrpnStateProcessor.attach(this, &MIDIChannel::nrpnOperator);
            break;
        default:
            nrpnStateSetter.attach(this, &MIDIChannel::setStateNRPNUndefined);
            nrpnStateProcessor.attach(this, &MIDIChannel::nrpnUndefined);
            break;
    }
}

// -- xxh xxh Undefined

void MIDIChannel::nrpnUndefined()
{

}

void MIDIChannel::setStateNRPNUndefined()
{

}

// -- 10h xxh Algorithm

void MIDIChannel::nrpnAlgorithm()
{
    switch(nrpnLSB) {
        case 0x01:
            if (algo != NULL) delete algo;
            algo = new FMAlgorithm(dataEntryMSB, dataEntryLSB, timer, trigon);
            break;
        case 0x02:
            //FMOperatorをFMAlgorithm持ちにしたので廃止
            break;
        case 0x03:
            algo->setConnectionIndex(dataEntryMSB);
            break;
        case 0x04:
            algo->setConnection(dataEntryMSB, dataEntryLSB);
            break;
        case 0x05:
            algo->disableCurrentConnection();
            break;
        case 0x06:
            algo->enableCurrentConnection();
            break;
    }
}

void MIDIChannel::setStateNRPNAlgorithm()
{
    switch(nrpnLSB) {
        case 0x01:
        case 0x02:
        case 0x04:
            state = NRPNDoubleData;
            break;
        case 0x03:
            state = NRPNSingleData;
            break;
        case 0x05:
        case 0x06:
            state = NRPNNoData;
            break;
    }
}

// -- 20h xxh Operator

void MIDIChannel::nrpnOperator()
{
    switch(nrpnLSB) {
        case 0x01:
            algo->getOperator(dataEntryMSB)->setAttack(dataEntryLSB);
            break;
        case 0x02:
            algo->getOperator(dataEntryMSB)->setDecay(dataEntryLSB);
            break;
        case 0x03:
            algo->getOperator(dataEntryMSB)->setSustain(dataEntryLSB);
            break;
        case 0x04:
            algo->getOperator(dataEntryMSB)->setSustainRate(dataEntryLSB);
            break;
        case 0x05:
            algo->getOperator(dataEntryMSB)->setRelease(dataEntryLSB);
            break;
        case 0x06:
            algo->getOperator(dataEntryMSB)->setFrequencyMultiple(dataEntryLSB);
            break;
        case 0x07:
            algo->getOperator(dataEntryMSB)->setFrequencyMultipleFloating(dataEntryLSB);
            break;
        case 0x08:
            algo->getOperator(dataEntryMSB)->setTotalLevel(dataEntryLSB);
            break;
        case 0x09:
            algo->getOperator(dataEntryMSB)->setFeedback(dataEntryLSB);
            break;
    }
}

void MIDIChannel::setStateNRPNOperator()
{
    state = NRPNDoubleData;
}