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/FMOscillator.cpp

Committer:
kb10uy
Date:
2015-01-26
Revision:
16:5cfa8b491882
Parent:
15:b03677948732
Child:
17:2e577c6000cf

File content as of revision 16:5cfa8b491882:

#include "FMOscillator.h"

char sysexData[128];

FMOscillator::FMOscillator() {
    
}

FMOscillator::FMOscillator(int opc, Timer *tim, Serial *ser, AOTTrigon *tri, I2C *i2clcd) {
    master = tim;
    serial = ser;
    trigon = tri;
    opcount = opc;
    
    operators = new FMOperator*[opcount];
    for(int i = 0; i < opcount; i++) {
        operators[i] = new FMOperator(master, trigon);
    }
    lcd = new AQM0802A(*i2clcd);
    
    serial->baud(256000);
    serial->format();
    serial->attach(this, &FMOscillator::midiReceived);
    master->start();
    
    lcd->cls();
    lcd->printf("NuFM401\nFMDriver");
}

FMOscillator::~FMOscillator() {
    for(int i = 0; i < opcount; i++) {
        delete operators[i];
    }
    delete operators;
    delete lcd;
}

void FMOscillator::midiReceived()
{
    getMIDIMessage();
    while(serial->readable()) serial->getc();
}

void FMOscillator::getMIDIMessage()
{
    unsigned char st = serial->getc();
    switch(st >> 4) {
        case 0x8:
            midiNoteOff(st & 0xf, serial->getc(), serial->getc());
            break;
        case 0x9:
            midiNoteOn(st & 0xf, serial->getc(), serial->getc());
            break;
        case 0xa:
            midiPolyphonicKeyPressure(st & 0xf, serial->getc(), serial->getc());
            break;
        case 0xb:
            char b2 = serial->getc();
            if (b2 >= 120) {
                midiChannelMode(st & 0xf, b2, serial->getc());
            } else {
                midiControlChange(st & 0xf, b2, serial->getc());
            }
            break;
        case 0xc:
            midiProgramChange(st & 0xf, serial->getc());
            break;
        case 0xd:
            midiChannelPressure(st & 0xf, serial->getc());
            break;
        case 0xe:
            char LSB = serial->getc();
            char MSB = serial->getc();
            midiPitchBend(st & 0xf, ((LSB << 7) | (MSB << 7)) + 8192);
            break;
        case 0xf:
            int t2 = st & 0xf;
            if (t2 <= 7) {
                getMIDISystemCommonMessage(t2);
            } else {
                midiSystemRealtimeMessage(st);
            }
            break;
    }
}

void FMOscillator::getMIDISystemCommonMessage(char t2)
{
    switch(t2) {
        case 0:
            //もう面倒臭いから128byteのバッファに適当に放り込んでおこう
            sysexData[0] = 0xf0;
            int i = 1;
            char d = 0;
            do {
                d = serial->getc();
                sysexData[i]=d;
                i++;
            } while(d != 0xf7);

            break;
        case 1:
            serial->getc();
            break;
        case 2:
            serial->getc();
            serial->getc();
            break;
        case 3:
            serial->getc();
            break;
        case 4:
            break;
        case 5:
            break;
        case 6:
            break;
        case 7:
            //どうしろと
            break;
    }
}

void FMOscillator::midiSystemRealtimeMessage(char mes)
{

}


void FMOscillator::midiNoteOn(char ch, char note, char vel)
{
    lcd->cls();
    lcd->printf("Note On\n");
    lcd->printf("%1x: %2x,%2x", ch, note, vel);
    if (vel==0) {
        //globalrelease((ch<<8)|note);
    } else {
        //globalattack((ch<<8)|note,vel);
    }
}

void FMOscillator::midiNoteOff(char ch, char note, char vel)
{
    lcd->cls();
    lcd->printf("Note Off\n");
    lcd->printf("%1x: %2x,%2x", ch, note, vel);
    //globalrelease((ch<<8)|note);
}

void FMOscillator::midiPolyphonicKeyPressure(char ch, char note, char vel)
{

}

void FMOscillator::midiControlChange(char ch, char ctrl, char data)
{

}

void FMOscillator::midiChannelMode(char ch, char ctrl, char data)
{

}

void FMOscillator::midiProgramChange(char ch, char prg)
{

}

void FMOscillator::midiChannelPressure(char ch, char pres)
{

}

void FMOscillator::midiPitchBend(char ch, short pb)
{

}

void FMOscillator::midiSystemExclusiveMessage()
{

}