Skip to content

Commit

Permalink
Lfo modulation of FM parameters is polyphonic when controlled by Afte…
Browse files Browse the repository at this point in the history
…rTouch or Velocity

Arp works in all voice modes (round robin)
Sustain pedal fix (avoid double trigger on noisy pedals)
enhanced mpe mode (correct bend range +/-48 semitone)
  • Loading branch information
Alex committed Apr 26, 2024
1 parent b5731eb commit 15ca7bb
Show file tree
Hide file tree
Showing 17 changed files with 1,007 additions and 470 deletions.
1 change: 1 addition & 0 deletions include/FM.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ void updateFMifNecessary(byte number);
void fmResetValues();
void fmUpdate();
void fm(byte number, byte data);
void fmMpe(byte channel, byte number, byte data);
void op(byte number);
void setupFM();
void WriteYMData(byte data);
Expand Down
125 changes: 125 additions & 0 deletions include/YM2612.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#define YM_MASTER_ADDR (0x22)
#define YM_CHN_ADDR (0x30)

static byte stagger[]{0, 6, 1, 7, 2, 8, 3, 9, 4, 10, 5, 11, 6, 12};

#define YM_MA_LFO_E offsetof(Master_t, LFO), 1, 3
#define YM_MA_LFO_F offsetof(Master_t, LFO), 3, 0
#define YM_MA_CH3_M offsetof(Master_t, CHAN3_MODE_TIMERS), 2, 6
Expand Down Expand Up @@ -113,6 +115,129 @@ class YM2612 {
void setRateScaling(int value) { setOperatorParameter(YM_OP_RS, value); }
void setSSG_EG(int value) { setOperatorParameter(YM_OP_SSG_EG, value); }

void setAmplitudeModulation(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}

setOperatorParameter(channel, YM_OP_AM, (value > 0));
chip = 0;
}
void setAttackRate(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}
setOperatorParameter(channel, YM_OP_AR, value);
chip = 0;
}
void setDecayRate(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}
setOperatorParameter(channel, YM_OP_D1R, value);
chip = 0;
}
void setSustainRate(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}
setOperatorParameter(channel, YM_OP_D2R, value);
chip = 0;
}
void setReleaseRate(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}
setOperatorParameter(channel, YM_OP_RR, value);
chip = 0;
}
void setTotalLevel(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}
setOperatorParameter(channel, YM_OP_TL, value);
chip = 0;
}
void setSustainLevel(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}
setOperatorParameter(channel, YM_OP_D1L, value);
chip = 0;
}
void setMultiply(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}
setOperatorParameter(channel, YM_OP_MUL, value);
chip = 0;
}
void setDetune(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}
setOperatorParameter(channel, YM_OP_DT1, value);
chip = 0;
}
void setRateScaling(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}
setOperatorParameter(channel, YM_OP_RS, value);
chip = 0;
}
void setSSG_EG(int channel, int value) {
channel = stagger[channel];
if (channel > 5) {
channel -= 6;
chip = 6;
} else {
chip = 2;
}
setOperatorParameter(channel, YM_OP_SSG_EG, value);
chip = 0;
}

void noteOn(byte chan);
void noteOff(byte chan);
void pitchBend(byte channel, int bend);
Expand Down
4 changes: 2 additions & 2 deletions include/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#ifndef MEGAFM_CONSTANTS_H
#define MEGAFM_CONSTANTS_H

const byte kVersion0 = 3;
const byte kVersion1 = 6;
const byte kVersion0 = 4;
const byte kVersion1 = 0;

const byte kDefaultSeq[16] = {0, 0, 0, 0, 12, 12, 12, 12, 0, 0, 12, 0, 0, 12, 12, 0};

Expand Down
12 changes: 8 additions & 4 deletions include/megafm.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
#define YM_IC 30
extern bool loopChanged;
extern bool loopHeld;
extern byte velocityLast; // keep track of velocity for LFO
extern byte presetChordNumber;
extern bool newWide; // enable new wide modes
extern bool chord;
Expand Down Expand Up @@ -165,15 +164,20 @@ extern VoiceMode voiceMode;
extern bool sync;
extern bool ab;
extern int potLast[64];

extern int lastMpeVoice;
extern int pressureCounter;
extern int lfoDepth[3];
extern bool buttLast[19];
extern byte keyPressure[128];
extern int algoLast;

extern int polyPressure[12];
extern int polyVel[12];
extern byte fmBase[51], fmBaseLast[51], fmBaseLastNumber[51];
extern int fmData[51], fmDataLast[51];
extern bool linked[3][51];
extern byte lfoRandom[3][32];
extern byte valPlusPressureLast[12][36];
extern byte valPlusVelLast[12][36];
extern byte randomIndex[3];
extern byte octOffset; // offset the preset by 0-3 octaves
extern bool pressedUp, pressedDown;
Expand All @@ -195,10 +199,10 @@ extern byte lfoShape[3];
extern byte lfo[3], lfoLast[3];
extern int lfoStep[3];
extern int lfoStepLast[3];
extern int at, atDest, atLast, atGlideCounter;
extern bool lfoNewRand[3];
extern int lfoCounter[3], lfoSpeed[3];
extern bool retrig[3];
extern byte robin;//used for polyphonic ar voice ordering (round robin)
extern int fatLast;
extern float fat;
extern float bendy;
Expand Down
42 changes: 22 additions & 20 deletions include/midi_pedal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,29 @@ class MidiPedalAdapter {
: pedal_down{0}, note_on_callback(note_on_callback), note_off_callback(note_off_callback) {}

void set_pedal(uint8_t channel, bool pedal) {

this->pedal_down[channel] = pedal;

// when pedal goes down, we want to transfer the notes that are held to sustained
if (pedal) {
for (int i = 0; i < 128; i++) {
sustainedNotes[channel].set(i, heldNotes[channel].get(i));
}
} else {

// when pedal goes up, we want to kill the notes that are sustained
for (int i = 0; i < 128; i++) {
if (!heldNotes[channel].get(i) && sustainedNotes[channel].get(i)) {
//*(only if not held by fingers)
note_off_callback(channel, i);
if (pedal_downLast[channel] != pedal) {
pedal_downLast[channel] = pedal;
this->pedal_down[channel] = pedal;

// when pedal goes down, we want to transfer the notes that are held to sustained
if (pedal) {
for (int i = 0; i < 128; i++) {
sustainedNotes[channel].set(i, heldNotes[channel].get(i));
}
} else {

// when pedal goes up, we want to kill the notes that are sustained
for (int i = 0; i < 128; i++) {
if (!heldNotes[channel].get(i) && sustainedNotes[channel].get(i)) {
//*(only if not held by fingers)
note_off_callback(channel, i);
}
}
}

// clear sustained notes
for (int i = 0; i < 128; i++) {
sustainedNotes[channel].set(i, 0);
// clear sustained notes
for (int i = 0; i < 128; i++) {
sustainedNotes[channel].set(i, 0);
}
}
}
}
Expand Down Expand Up @@ -109,7 +111,7 @@ class MidiPedalAdapter {
BooleanArray128 heldNotes[16];
BooleanArray128 sustainedNotes[16];
bool pedal_down[16];

bool pedal_downLast[16];
note_on_callback_t note_on_callback;
note_off_callback_t note_off_callback;
};
Loading

0 comments on commit 15ca7bb

Please sign in to comment.