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で。
FMOscillator/FMAlgorithm.cpp@24:f93b49b4cd66, 2015-01-31 (annotated)
- Committer:
- kb10uy
- Date:
- Sat Jan 31 10:54:13 2015 +0000
- Revision:
- 24:f93b49b4cd66
- Parent:
- 23:deb76bdf6f03
NRPN 20h xxh???
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kb10uy | 19:f0dcf591c5dd | 1 | #include "FMAlgorithm.h" |
kb10uy | 19:f0dcf591c5dd | 2 | |
kb10uy | 19:f0dcf591c5dd | 3 | FMAlgorithm::FMAlgorithm() |
kb10uy | 19:f0dcf591c5dd | 4 | { |
kb10uy | 19:f0dcf591c5dd | 5 | opcount = 0; |
kb10uy | 19:f0dcf591c5dd | 6 | cncount = 0; |
kb10uy | 23:deb76bdf6f03 | 7 | cni = 0; |
kb10uy | 19:f0dcf591c5dd | 8 | operators = NULL; |
kb10uy | 19:f0dcf591c5dd | 9 | connections = NULL; |
kb10uy | 19:f0dcf591c5dd | 10 | } |
kb10uy | 19:f0dcf591c5dd | 11 | |
kb10uy | 23:deb76bdf6f03 | 12 | FMAlgorithm::FMAlgorithm(int opc, int cnc, Timer *tm, AOTTrigon *tri) |
kb10uy | 19:f0dcf591c5dd | 13 | { |
kb10uy | 19:f0dcf591c5dd | 14 | opcount = opc; |
kb10uy | 19:f0dcf591c5dd | 15 | cncount = cnc; |
kb10uy | 19:f0dcf591c5dd | 16 | operators = new FMOperator*[opcount]; |
kb10uy | 23:deb76bdf6f03 | 17 | for(int i = 0; i < opcount; i++) operators[i] = new FMOperator(tm, tri); |
kb10uy | 19:f0dcf591c5dd | 18 | connections = new FMAlgorithmConnection[cncount]; |
kb10uy | 19:f0dcf591c5dd | 19 | } |
kb10uy | 19:f0dcf591c5dd | 20 | |
kb10uy | 19:f0dcf591c5dd | 21 | FMAlgorithm::~FMAlgorithm() |
kb10uy | 19:f0dcf591c5dd | 22 | { |
kb10uy | 23:deb76bdf6f03 | 23 | if (operators != NULL) { |
kb10uy | 23:deb76bdf6f03 | 24 | for(int i = 0; i < opcount; i++) delete operators[i]; |
kb10uy | 23:deb76bdf6f03 | 25 | delete[] operators; |
kb10uy | 23:deb76bdf6f03 | 26 | } |
kb10uy | 19:f0dcf591c5dd | 27 | if (connections != NULL) delete[] connections; |
kb10uy | 19:f0dcf591c5dd | 28 | } |
kb10uy | 19:f0dcf591c5dd | 29 | |
kb10uy | 23:deb76bdf6f03 | 30 | void FMAlgorithm::setConnection(int t, int s) |
kb10uy | 19:f0dcf591c5dd | 31 | { |
kb10uy | 23:deb76bdf6f03 | 32 | if (cni >= cncount) return; |
kb10uy | 23:deb76bdf6f03 | 33 | connections[cni].target = t; |
kb10uy | 23:deb76bdf6f03 | 34 | connections[cni].source = s; |
kb10uy | 23:deb76bdf6f03 | 35 | connections[cni].allocated = true; |
kb10uy | 23:deb76bdf6f03 | 36 | cni++; |
kb10uy | 19:f0dcf591c5dd | 37 | } |
kb10uy | 19:f0dcf591c5dd | 38 | |
kb10uy | 23:deb76bdf6f03 | 39 | void FMAlgorithm::setConnectionIndex(int id) { |
kb10uy | 23:deb76bdf6f03 | 40 | if (id >= cncount) return; |
kb10uy | 23:deb76bdf6f03 | 41 | cni = id; |
kb10uy | 23:deb76bdf6f03 | 42 | } |
kb10uy | 23:deb76bdf6f03 | 43 | |
kb10uy | 23:deb76bdf6f03 | 44 | void FMAlgorithm::enableCurrentConnection() { |
kb10uy | 23:deb76bdf6f03 | 45 | if (cni >= cncount) return; |
kb10uy | 23:deb76bdf6f03 | 46 | connections[cni].allocated = true; |
kb10uy | 23:deb76bdf6f03 | 47 | } |
kb10uy | 23:deb76bdf6f03 | 48 | |
kb10uy | 23:deb76bdf6f03 | 49 | void FMAlgorithm::disableCurrentConnection() { |
kb10uy | 23:deb76bdf6f03 | 50 | if (cni >= cncount) return; |
kb10uy | 23:deb76bdf6f03 | 51 | connections[cni].allocated = false; |
kb10uy | 20:8278e607a687 | 52 | } |
kb10uy | 21:e3014c1bdf9c | 53 | |
kb10uy | 21:e3014c1bdf9c | 54 | void FMAlgorithm::noteOn(float freq, double time) { |
kb10uy | 21:e3014c1bdf9c | 55 | for(int i = 0; i < opcount; i++) { |
kb10uy | 21:e3014c1bdf9c | 56 | if (operators[i] != NULL) operators[i]->attackNote(freq, time); |
kb10uy | 21:e3014c1bdf9c | 57 | } |
kb10uy | 21:e3014c1bdf9c | 58 | } |
kb10uy | 21:e3014c1bdf9c | 59 | |
kb10uy | 21:e3014c1bdf9c | 60 | void FMAlgorithm::noteOff(double time) { |
kb10uy | 21:e3014c1bdf9c | 61 | for(int i = 0; i < opcount; i++) { |
kb10uy | 21:e3014c1bdf9c | 62 | if (operators[i] != NULL) operators[i]->releaseNote(time); |
kb10uy | 21:e3014c1bdf9c | 63 | } |
kb10uy | 21:e3014c1bdf9c | 64 | } |
kb10uy | 21:e3014c1bdf9c | 65 | |
kb10uy | 21:e3014c1bdf9c | 66 | float FMAlgorithm::calculate() { |
kb10uy | 21:e3014c1bdf9c | 67 | return calculate(0); |
kb10uy | 21:e3014c1bdf9c | 68 | } |
kb10uy | 21:e3014c1bdf9c | 69 | |
kb10uy | 21:e3014c1bdf9c | 70 | float FMAlgorithm::calculate(int opn) { |
kb10uy | 21:e3014c1bdf9c | 71 | float sum = 0; |
kb10uy | 21:e3014c1bdf9c | 72 | for(int i = 0; i < cncount; i++) { |
kb10uy | 21:e3014c1bdf9c | 73 | if (connections[i].allocated && connections[i].target == opn) { |
kb10uy | 21:e3014c1bdf9c | 74 | sum += calculate(connections[i].source); |
kb10uy | 21:e3014c1bdf9c | 75 | } |
kb10uy | 21:e3014c1bdf9c | 76 | } |
kb10uy | 21:e3014c1bdf9c | 77 | return operators[opn]->calculate(sum); |
kb10uy | 21:e3014c1bdf9c | 78 | } |