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

Committer:
kb10uy
Date:
Thu Jan 29 12:27:21 2015 +0000
Revision:
21:e3014c1bdf9c
Parent:
20:8278e607a687
Child:
22:500b4f2953fa
noteOn/Off????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kb10uy 17:2e577c6000cf 1 #include "MIDIChannel.h"
kb10uy 17:2e577c6000cf 2
kb10uy 17:2e577c6000cf 3 MIDIChannel::MIDIChannel()
kb10uy 17:2e577c6000cf 4 {
kb10uy 21:e3014c1bdf9c 5
kb10uy 21:e3014c1bdf9c 6 }
kb10uy 21:e3014c1bdf9c 7
kb10uy 21:e3014c1bdf9c 8 MIDIChannel::MIDIChannel(AQM0802A *l)
kb10uy 21:e3014c1bdf9c 9 {
kb10uy 17:2e577c6000cf 10 modulation = 0;
kb10uy 17:2e577c6000cf 11 portamentoTime = 0;
kb10uy 17:2e577c6000cf 12 portamento = false;
kb10uy 17:2e577c6000cf 13 volume = 127;
kb10uy 17:2e577c6000cf 14 panpot = 64;
kb10uy 17:2e577c6000cf 15 expression = 127;
kb10uy 17:2e577c6000cf 16 hold1 = false;
kb10uy 19:f0dcf591c5dd 17 dataEntryMSB = 0;
kb10uy 19:f0dcf591c5dd 18 dataEntryLSB = 0;
kb10uy 19:f0dcf591c5dd 19 nrpnMSB = 0;
kb10uy 19:f0dcf591c5dd 20 nrpnLSB = 0;
kb10uy 19:f0dcf591c5dd 21 rpnMSB = 0;
kb10uy 19:f0dcf591c5dd 22 rpnLSB = 0;
kb10uy 19:f0dcf591c5dd 23 algo = NULL;
kb10uy 19:f0dcf591c5dd 24 state = Undefined;
kb10uy 21:e3014c1bdf9c 25 lcd = l;
kb10uy 19:f0dcf591c5dd 26 }
kb10uy 19:f0dcf591c5dd 27
kb10uy 19:f0dcf591c5dd 28 MIDIChannel::~MIDIChannel()
kb10uy 19:f0dcf591c5dd 29 {
kb10uy 19:f0dcf591c5dd 30 if (algo != NULL) delete algo;
kb10uy 19:f0dcf591c5dd 31 }
kb10uy 19:f0dcf591c5dd 32
kb10uy 21:e3014c1bdf9c 33 void MIDIChannel::noteOn(char key, char vel, double time) {
kb10uy 21:e3014c1bdf9c 34 prkey = key;
kb10uy 21:e3014c1bdf9c 35 algo->noteOn(getNoteNumberFrequency(prkey), time);
kb10uy 21:e3014c1bdf9c 36 }
kb10uy 21:e3014c1bdf9c 37
kb10uy 21:e3014c1bdf9c 38 void MIDIChannel::noteOff(char key, double time) {
kb10uy 21:e3014c1bdf9c 39 if (prkey != key) return;
kb10uy 21:e3014c1bdf9c 40 algo->noteOff(time);
kb10uy 21:e3014c1bdf9c 41 }
kb10uy 21:e3014c1bdf9c 42
kb10uy 19:f0dcf591c5dd 43 void MIDIChannel::setDataEntryMSB(char msb)
kb10uy 19:f0dcf591c5dd 44 {
kb10uy 19:f0dcf591c5dd 45 dataEntryMSB = msb;
kb10uy 19:f0dcf591c5dd 46 }
kb10uy 19:f0dcf591c5dd 47
kb10uy 19:f0dcf591c5dd 48 void MIDIChannel::setDataEntryLSB(char lsb)
kb10uy 19:f0dcf591c5dd 49 {
kb10uy 19:f0dcf591c5dd 50 dataEntryLSB = lsb;
kb10uy 19:f0dcf591c5dd 51 }
kb10uy 19:f0dcf591c5dd 52
kb10uy 19:f0dcf591c5dd 53 void MIDIChannel::setNRPNMSB(char msb)
kb10uy 19:f0dcf591c5dd 54 {
kb10uy 19:f0dcf591c5dd 55 nrpnMSB = msb;
kb10uy 19:f0dcf591c5dd 56 if (msb >= 0x60) {
kb10uy 19:f0dcf591c5dd 57 state = NRPNSingleData;
kb10uy 19:f0dcf591c5dd 58 } else {
kb10uy 19:f0dcf591c5dd 59 state = NRPNDoubleData;
kb10uy 19:f0dcf591c5dd 60 }
kb10uy 19:f0dcf591c5dd 61 }
kb10uy 19:f0dcf591c5dd 62
kb10uy 19:f0dcf591c5dd 63 void MIDIChannel::setNRPNLSB(char lsb)
kb10uy 19:f0dcf591c5dd 64 {
kb10uy 19:f0dcf591c5dd 65 nrpnLSB = lsb;
kb10uy 19:f0dcf591c5dd 66 if (state == NRPNNoData) processNRPNFunction();
kb10uy 19:f0dcf591c5dd 67 }
kb10uy 19:f0dcf591c5dd 68
kb10uy 19:f0dcf591c5dd 69 void MIDIChannel::setRPNMSB(char msb)
kb10uy 19:f0dcf591c5dd 70 {
kb10uy 19:f0dcf591c5dd 71 rpnMSB = msb;
kb10uy 21:e3014c1bdf9c 72 if (msb == 0x7f) {
kb10uy 19:f0dcf591c5dd 73 state = RPNNoData;
kb10uy 19:f0dcf591c5dd 74 } else {
kb10uy 21:e3014c1bdf9c 75 state = RPNSingleData;
kb10uy 19:f0dcf591c5dd 76 }
kb10uy 19:f0dcf591c5dd 77 }
kb10uy 19:f0dcf591c5dd 78
kb10uy 19:f0dcf591c5dd 79 void MIDIChannel::setRPNLSB(char lsb)
kb10uy 19:f0dcf591c5dd 80 {
kb10uy 19:f0dcf591c5dd 81 rpnLSB = lsb;
kb10uy 19:f0dcf591c5dd 82 if (state == RPNNoData) processRPNFunction();
kb10uy 17:2e577c6000cf 83 }
kb10uy 17:2e577c6000cf 84
kb10uy 17:2e577c6000cf 85 void MIDIChannel::allSoundOff()
kb10uy 17:2e577c6000cf 86 {
kb10uy 17:2e577c6000cf 87 }
kb10uy 17:2e577c6000cf 88
kb10uy 17:2e577c6000cf 89 void MIDIChannel::allNoteOff()
kb10uy 17:2e577c6000cf 90 {
kb10uy 19:f0dcf591c5dd 91 }
kb10uy 19:f0dcf591c5dd 92
kb10uy 21:e3014c1bdf9c 93 void MIDIChannel::processNRPNFunction()
kb10uy 21:e3014c1bdf9c 94 {
kb10uy 19:f0dcf591c5dd 95 switch(nrpnMSB) {
kb10uy 21:e3014c1bdf9c 96
kb10uy 19:f0dcf591c5dd 97 }
kb10uy 20:8278e607a687 98 state = Undefined;
kb10uy 19:f0dcf591c5dd 99 }
kb10uy 19:f0dcf591c5dd 100
kb10uy 21:e3014c1bdf9c 101 void MIDIChannel::processRPNFunction()
kb10uy 21:e3014c1bdf9c 102 {
kb10uy 19:f0dcf591c5dd 103 switch(rpnMSB) {
kb10uy 19:f0dcf591c5dd 104 case 0x00:
kb10uy 19:f0dcf591c5dd 105 //LSB 0~2全部実装できないですから
kb10uy 19:f0dcf591c5dd 106 break;
kb10uy 19:f0dcf591c5dd 107 case 0x7f:
kb10uy 19:f0dcf591c5dd 108 if (rpnLSB == 0x7f) {
kb10uy 19:f0dcf591c5dd 109 rpnMSB = 0;
kb10uy 19:f0dcf591c5dd 110 rpnLSB = 0;
kb10uy 19:f0dcf591c5dd 111 nrpnMSB = 0;
kb10uy 19:f0dcf591c5dd 112 nrpnLSB = 0;
kb10uy 19:f0dcf591c5dd 113 }
kb10uy 21:e3014c1bdf9c 114 lcd->cls();
kb10uy 21:e3014c1bdf9c 115 lcd->printf("RPN/NRPN\nNULL");
kb10uy 19:f0dcf591c5dd 116 break;
kb10uy 19:f0dcf591c5dd 117 }
kb10uy 19:f0dcf591c5dd 118 state = Undefined;
kb10uy 20:8278e607a687 119 }