diff --git a/include/constants.h b/include/constants.h index 1744236..e8674c2 100644 --- a/include/constants.h +++ b/include/constants.h @@ -6,7 +6,7 @@ #define MEGAFM_CONSTANTS_H const byte kVersion0 = 3; -const byte kVersion1 = 5; +const byte kVersion1 = 6; const byte kDefaultSeq[16] = {0, 0, 0, 0, 12, 12, 12, 12, 0, 0, 12, 0, 0, 12, 12, 0}; diff --git a/include/megafm.h b/include/megafm.h index 544a415..848f828 100644 --- a/include/megafm.h +++ b/include/megafm.h @@ -16,6 +16,8 @@ #define YM_CS2 14 #define YM_WR 11 #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 diff --git a/src/FM.cpp b/src/FM.cpp index 71600c2..d50ac89 100644 --- a/src/FM.cpp +++ b/src/FM.cpp @@ -115,7 +115,7 @@ void fm(byte number, byte data) { ym.setTotalLevel(127 - (data >> fmShifts[number])); break; // op level case 12: - op(1); + op(2); ym.setRateScaling((data) >> fmShifts[number]); break; case 13: @@ -152,7 +152,7 @@ void fm(byte number, byte data) { ym.setTotalLevel(127 - (data >> fmShifts[number])); break; // op level case 21: - op(2); + op(1); ym.setRateScaling(data >> fmShifts[number]); break; case 22: diff --git a/src/MEGAfm.cpp b/src/MEGAfm.cpp index 6fe6597..6681d5a 100644 --- a/src/MEGAfm.cpp +++ b/src/MEGAfm.cpp @@ -106,6 +106,8 @@ int setupCounter; bool justQuitSetup; bool invertedSquare[3]; bool invertedSaw[3]; +bool loopChanged; +bool loopHeld; bool showLfoFlag; int showSSEGCounter; // used to temporarily show the SSEG settings of the last tweaked operator byte lastOperator; // keep track of the last operator we tweaked to enable SSGEG diff --git a/src/arp.cpp b/src/arp.cpp index be6d544..f6fbf6f 100644 --- a/src/arp.cpp +++ b/src/arp.cpp @@ -152,7 +152,7 @@ void arpFire() { } seqStep++; - if (seqStep > seqLength) { + if (seqStep >= seqLength) { seqStep = 0; arpIndex++; diff --git a/src/buttons.cpp b/src/buttons.cpp index 59129d9..3777e2e 100644 --- a/src/buttons.cpp +++ b/src/buttons.cpp @@ -571,30 +571,8 @@ void buttChanged(Button number, bool value) { } break; // retrig case kButtonLoop: - if (bankCounter) { - if (presetTargetMode) { - presetCounts = 40; - } - bank = 5; - ledSet(16 + bank, 1); - flashCounter2 = 0; - flasher = false; - EEPROM.write(3964, bank); - clearLfoLeds(); - if (!presetTargetMode) { - loadPreset(); - resetFunction = 0; - } - bankCounter = 20; - } else { - if (!showSSEGCounter) { - looping[selectedLfo] = !looping[selectedLfo]; - showLfo(); - sendCC(58, looping[selectedLfo]); - } else { - setSSEG(lastOperator, 1, !bitRead(SSEG[lastOperator], 1)); // flip the SSEG enable bit - } - } + loopChanged = false; + loopHeld = true; break; // loop default: break; @@ -689,7 +667,7 @@ void buttChanged(Button number, bool value) { case kButtonPresetUp: pressedUp = false; if (seqRec) { - if (seqLength < 15) { + if (seqLength < 16) { seq[seqLength] = 255; seqLength++; ledNumber(seqLength + 1); @@ -928,13 +906,44 @@ void buttChanged(Button number, bool value) { } } break; // chain3 + case kButtonLoop: + loopHeld = false; + if (!loopChanged) { + if (bankCounter) { + if (presetTargetMode) { + presetCounts = 40; + } + bank = 5; + ledSet(16 + bank, 1); + flashCounter2 = 0; + flasher = false; + EEPROM.write(3964, bank); + clearLfoLeds(); + if (!presetTargetMode) { + loadPreset(); + resetFunction = 0; + } + bankCounter = 20; + } else { + if (!showSSEGCounter) { + + looping[selectedLfo] = !looping[selectedLfo]; + showLfo(); + sendCC(58, looping[selectedLfo]); + } else { + setSSEG(lastOperator, 1, + !bitRead(SSEG[lastOperator], 1)); // flip the SSEG enable bit + } + } + } + break; // loop case kButtonSquare: // square case kButtonTriangle: // triangle case kButtonSaw: // saw case kButtonNoise: // noise case kButtonRetrig: // retrig - case kButtonLoop: // loop + default: break; } diff --git a/src/midi.cpp b/src/midi.cpp index 70f937b..ed987bb 100644 --- a/src/midi.cpp +++ b/src/midi.cpp @@ -448,7 +448,7 @@ static void handleNoteOn(byte channel, byte note, byte velocity) { seq[seqLength]--; } ledNumber(seqLength + 1); - if (seqLength < 15) { + if (seqLength < 16) { seqLength++; } diff --git a/src/pots.cpp b/src/pots.cpp index 5e7ed3c..6e2d5d5 100644 --- a/src/pots.cpp +++ b/src/pots.cpp @@ -212,12 +212,19 @@ void movedPot(byte number, byte data, bool isMidi) { // OP1 case 18: showPickupAnimation = false; - fmBase[0] = data; - updateFMifNecessary(0); - if (voiceMode == kVoicingDualCh3) { - ledNumber(data >> 2); + if (loopHeld) { + loopChanged = true; + updateFMifNecessary(3); + fmBase[3] = data; + ledNumber(data >> 6); } else { - ledNumber(-3 + (data >> 5)); + fmBase[0] = data; + updateFMifNecessary(0); + if (voiceMode == kVoicingDualCh3) { + ledNumber(data >> 2); + } else { + ledNumber(-3 + (data >> 5)); + } } if (!isMidi) { isFader = true; @@ -307,12 +314,19 @@ void movedPot(byte number, byte data, bool isMidi) { // OP2 case 31: showPickupAnimation = false; - fmBase[18] = data; - updateFMifNecessary(18); - if (voiceMode == kVoicingDualCh3) { - ledNumber(data >> 2); + if (loopHeld) { + loopChanged = true; + updateFMifNecessary(12); + fmBase[12] = data; + ledNumber(data >> 6); } else { - ledNumber(-3 + (data >> 5)); + fmBase[18] = data; + updateFMifNecessary(18); + if (voiceMode == kVoicingDualCh3) { + ledNumber(data >> 2); + } else { + ledNumber(-3 + (data >> 5)); + } } if (!isMidi) { isFader = true; @@ -401,12 +415,20 @@ void movedPot(byte number, byte data, bool isMidi) { // OP3 case 20: showPickupAnimation = false; - fmBase[9] = data; - updateFMifNecessary(9); - if (voiceMode == kVoicingDualCh3) { - ledNumber(data >> 2); + + if (loopHeld) { + loopChanged = true; + updateFMifNecessary(21); + fmBase[21] = data; + ledNumber(data >> 6); } else { - ledNumber(-3 + (data >> 5)); + fmBase[9] = data; + updateFMifNecessary(9); + if (voiceMode == kVoicingDualCh3) { + ledNumber(data >> 2); + } else { + ledNumber(-3 + (data >> 5)); + } } if (!isMidi) { isFader = true; @@ -495,12 +517,19 @@ void movedPot(byte number, byte data, bool isMidi) { // OP4 case 47: showPickupAnimation = false; - fmBase[27] = data; - updateFMifNecessary(27); - if (voiceMode == kVoicingDualCh3) { - ledNumber(data >> 2); + if (loopHeld) { + loopChanged = true; + updateFMifNecessary(30); + fmBase[30] = data; + ledNumber(data >> 6); } else { - ledNumber(-3 + (data >> 5)); + fmBase[27] = data; + updateFMifNecessary(27); + if (voiceMode == kVoicingDualCh3) { + ledNumber(data >> 2); + } else { + ledNumber(-3 + (data >> 5)); + } } if (!isMidi) { isFader = true; diff --git a/src/preset.cpp b/src/preset.cpp index 337c02e..92792c3 100644 --- a/src/preset.cpp +++ b/src/preset.cpp @@ -355,6 +355,7 @@ void loadPreset() { bitWrite(seqLength, 1, bitRead(temp, 1)); bitWrite(seqLength, 2, bitRead(temp, 2)); bitWrite(seqLength, 3, bitRead(temp, 3)); + seqLength++; bitWrite(glide, 0, bitRead(temp, 4)); bitWrite(glide, 1, bitRead(temp, 5)); @@ -696,10 +697,10 @@ void savePreset() { } temp = 0; - bitWrite(temp, 0, bitRead(seqLength, 0)); - bitWrite(temp, 1, bitRead(seqLength, 1)); - bitWrite(temp, 2, bitRead(seqLength, 2)); - bitWrite(temp, 3, bitRead(seqLength, 3)); + bitWrite(temp, 0, bitRead(seqLength - 1, 0)); + bitWrite(temp, 1, bitRead(seqLength - 1, 1)); + bitWrite(temp, 2, bitRead(seqLength - 1, 2)); + bitWrite(temp, 3, bitRead(seqLength - 1, 3)); bitWrite(temp, 4, bitRead(glide, 0)); bitWrite(temp, 5, bitRead(glide, 1));