Nucleo F401REでFM音源を実装するやつ 外部DACとオペアンプを利用 現在はMCP4922とNJM2737
Dependencies: AOTTrigon I2CEEPROM MCP4922 AQM0802A mbed
Fork of NuMidi401 by
NuFM401
Nucleo F401用の自作ソフトウェアMIDI音源
概要
だいたいそんなもんです。
特徴
- ブレッドボードの上で組める程度には簡単な回路構成
- 外部のDACにMCP4922を採用
- 念のためのボルテージフォロアとしてNJM2737Dを採用
- バンク用EEPROMに24FC1025を採用
- シリアル経由でMIDIデータを受信することで操作
補足
シリアル <=> MIDI のドライバにはHairless-MIDISerialをオススメします。 仮想MIDIケーブルはとりあえずMIDI Yokeで。
Diff: FMOscillator/FMOscillator.cpp
- Revision:
- 17:2e577c6000cf
- Parent:
- 16:5cfa8b491882
- Child:
- 18:b20fdf1da8f8
--- a/FMOscillator/FMOscillator.cpp Mon Jan 26 13:26:34 2015 +0000 +++ b/FMOscillator/FMOscillator.cpp Tue Jan 27 12:56:33 2015 +0000 @@ -2,32 +2,41 @@ char sysexData[128]; -FMOscillator::FMOscillator() { - +FMOscillator::FMOscillator() +{ + } -FMOscillator::FMOscillator(int opc, Timer *tim, Serial *ser, AOTTrigon *tri, I2C *i2clcd) { +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); } + + channels = new MIDIChannel*[16]; + for(int i = 0; i < 16; i++) { + channels[i] = new MIDIChannel(); + } + lcd = new AQM0802A(*i2clcd); - + serial->baud(256000); serial->format(); serial->attach(this, &FMOscillator::midiReceived); master->start(); - + lcd->cls(); lcd->printf("NuFM401\nFMDriver"); } -FMOscillator::~FMOscillator() { +FMOscillator::~FMOscillator() +{ for(int i = 0; i < opcount; i++) { delete operators[i]; } @@ -154,12 +163,108 @@ void FMOscillator::midiControlChange(char ch, char ctrl, char data) { + switch(ctrl) { + //bank select + case 0x00: + break; + case 0x20: + break; + //modulation + case 0x01: + channels[ch]->setModulationMSB(data); + break; + case 0x21: + //channels[ch]->setModulationLSB(data); + break; + + //portamento time + case 0x05: + channels[ch]->setPortamentoTime(data); + break; + case 0x25: + break; + + //Volume + case 0x07: + channels[ch]->setVolume(data); + break; + case 0x37: + break; + + //balance + case 0x08: + break; + case 0x28: + break; + + //panpot + case 0x0a: + channels[ch]->setPanpot(data); + break; + case 0x2a: + break; + + //expression + case 0x0b: + channels[ch]->setExpression(data); + break; + case 0x2b: + break; + + //hold1 + case 0x40: + if (data > 0x40) { + channels[ch]->startHold1(); + } else { + channels[ch]->endHold1(); + } + break; + + //portamento + case 0x41: + channels[ch]->setPortamentoSwitch(data > 0x40); + break; + + //data entry + case 0x06: + channels[ch]->setDataEntryMSB(data); + break; + case 0x26: + channels[ch]->setDataEntryLSB(data); + break; + + //nrpn + case 0x63: + channels[ch]->setNRPNMSB(data); + break; + case 0x62: + channels[ch]->setNRPNLSB(data); + break; + + //rpn + case 0x65: + channels[ch]->setRPNMSB(data); + break; + case 0x64: + channels[ch]->setRPNLSB(data); + break; + } } void FMOscillator::midiChannelMode(char ch, char ctrl, char data) { - + switch(ctrl) { + case 0x78: + channels[ch]->allSoundOff(); + break; + + case 0x7b: + case 0x7c: + case 0x7d: + channels[ch]->allNoteOff(); + break; + } } void FMOscillator::midiProgramChange(char ch, char prg)