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で。

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)