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/FMOperator.h

Committer:
kb10uy
Date:
2015-01-17
Revision:
13:e11380ceb460
Parent:
Operator.h@ 12:7408b85fba39
Child:
21:e3014c1bdf9c

File content as of revision 13:e11380ceb460:

#pragma once
#include "mbed.h"
#include "AOTTrigon.h"


class FMOperator {

public:
    FMOperator();
    FMOperator(Timer *tm, AOTTrigon *t);
    float calculate(double time, float fmIn);
    void attackNote(float freq, double time);
    void releaseNote(double time);
    
    inline void setAttack(char x) {
        attack = 0.0078125f * x;
    }
    inline void setDecay(char x) {
        decay = 0.0078125f * x;
    }
    inline void setSustain(char x) {
        sustain = 0.0078125f * (x + 1);
    }
    inline void setSustainRate(char x) {
        sustainRate = 0.0078125f * x;
    }
    inline void setRelease(char x) {
        release = 0.0078125f * x;
    }
    
    inline void setFrequencyMultiple(char x) {
        frequencyMultiple = x;
    }
    
    inline void setFrequencyMultipleFloating(char x) {
        frequencyMultiple *= 0.0078125f * (x + 1);
    }
    
    inline void setTotalLevel(char x) {
        totalLevel = 0.0078125f * (x + 1);
    }
    
    inline void setFeedback(char x) {
        feedback = 0.0078125f * x;
    } 

private:
    Timer *master;
    AOTTrigon *tri;
    //時間だけdouble確保
    double startTime;
    double releaseTime;
    bool released;
    double baseFrequency;
    
    float attack;
    float decay;
    float sustain;
    float sustainRate;
    float release;
    float frequencyMultiple;
    float totalLevel;
    float modulation;
    float feedback;
    float prev;
    
    float getEnvelopeRate(double t);
    float getEnvelopeReleaseRate(double rlst, float orate);
    
    inline float getCeilingFloatRate(char cr) {
        return 0.0078125f * (cr + 1);
    }
};