diff --git a/doc/HC-1.md b/doc/HC-1.md index 28bdf33..5fcd8dc 100644 --- a/doc/HC-1.md +++ b/doc/HC-1.md @@ -150,8 +150,14 @@ and the track around the knob becomes gold, with an indicator dot showing the ef CV inputs are processed only after the device has reached "Ready". - The boxed controls are the Eagan Matrix Recirculator. - The labels change to reflect the current preset's Recirculator type and the appropriate R1-R4 and Recirculator Mix (R5). - The indicator light button reflects the use of Extended (half-sample rate) computation. You can toggle extended computation on and off by clicking the light button. + The labels on the knobs change to reflect the current preset's Recirculator type and the appropriate R1-R4 and Recirculator Mix (R5) assignments. + When you see a number next a knob, it means that the corresponding pedal is assigned to that parameter. (You can change pedal assignments using the **Pedal 1** and **Pedal 2** modules.) + + The left light button enables and disables the recirculator. When lit the recirculator is active. + Recirculator on/off is global and doesn't change between presets. + The right light button reflects the use of Extended (half-sample rate) computation. + You can toggle extended computation on and off by clicking the light button. + You can temporarily change the Recirculator type in the **Recirculator** menu. Changes in recirculator type and extended mode are not saved. diff --git a/doc/HC-1.png b/doc/HC-1.png index efeffda..9158ec3 100644 Binary files a/doc/HC-1.png and b/doc/HC-1.png differ diff --git a/doc/HC-One-modules.png b/doc/HC-One-modules.png index ad7e201..6c51d1d 100644 Binary files a/doc/HC-One-modules.png and b/doc/HC-One-modules.png differ diff --git a/src/HC-1/HC-1-draw.cpp b/src/HC-1/HC-1-draw.cpp index 2d95ae6..49f5cae 100644 --- a/src/HC-1/HC-1-draw.cpp +++ b/src/HC-1/HC-1-draw.cpp @@ -268,9 +268,11 @@ void Hc1ModuleWidget::draw(const DrawArgs& args) #endif // recirculator - { // todo: move lines to SVG - Line(vg, RECIRC_BOX_LEFT, RECIRC_BOX_TOP, RECIRC_BOX_CENTER - (RECIRC_TITLE_WIDTH * .5f), RECIRC_BOX_TOP, RampGray(G_35), .5f); - Line(vg, RECIRC_LIGHT_CENTER + 15.f, RECIRC_BOX_TOP, RECIRC_BOX_RIGHT, RECIRC_BOX_TOP, RampGray(G_35), .5f); + { + Line(vg, RECIRC_BOX_LEFT, RECIRC_BOX_TOP, RECIRC_ENABLE_CENTER - 10.f, RECIRC_BOX_TOP, RampGray(G_35), .5f); + Line(vg, RECIRC_ENABLE_CENTER + 10.f, RECIRC_BOX_TOP, RECIRC_BOX_CENTER - RECIRC_TITLE_WIDTH *.5, RECIRC_BOX_TOP, RampGray(G_35), .5f); + Line(vg, RECIRC_BOX_CENTER + RECIRC_TITLE_WIDTH *.5, RECIRC_BOX_TOP, RECIRC_EXTEND_CENTER - 10.f, RECIRC_BOX_TOP, RampGray(G_35), .5f); + Line(vg, RECIRC_EXTEND_CENTER + 10.f, RECIRC_BOX_TOP, RECIRC_BOX_RIGHT, RECIRC_BOX_TOP, RampGray(G_35), .5f); Line(vg, RECIRC_BOX_LEFT, RECIRC_BOX_TOP, RECIRC_BOX_LEFT, RECIRC_BOX_BOTTOM, RampGray(G_35), .5f); Line(vg, RECIRC_BOX_RIGHT, RECIRC_BOX_TOP, RECIRC_BOX_RIGHT, RECIRC_BOX_BOTTOM, RampGray(G_35), .5f); Line(vg, RECIRC_BOX_LEFT, RECIRC_BOX_BOTTOM, RECIRC_BOX_RIGHT, RECIRC_BOX_BOTTOM, RampGray(G_35), .5f); diff --git a/src/HC-1/HC-1-layout.hpp b/src/HC-1/HC-1-layout.hpp index 253fbd3..b253952 100644 --- a/src/HC-1/HC-1-layout.hpp +++ b/src/HC-1/HC-1-layout.hpp @@ -35,7 +35,8 @@ constexpr const float RECIRC_BOX_HEIGHT = 52.5f; constexpr const float RECIRC_BOX_BOTTOM = RECIRC_BOX_TOP + RECIRC_BOX_HEIGHT; constexpr const float RECIRC_TITLE_WIDTH = 70.f; constexpr const float RECIRC_BOX_CENTER = RECIRC_BOX_LEFT + RECIRC_BOX_WIDTH *.5f; -constexpr const float RECIRC_LIGHT_CENTER = RECIRC_BOX_CENTER + (RECIRC_TITLE_WIDTH * .5f) + 5.f; +constexpr const float RECIRC_EXTEND_CENTER = RKNOB_LEFT + KNOB_SPREAD * 3.5f; +constexpr const float RECIRC_ENABLE_CENTER = RKNOB_LEFT + KNOB_SPREAD * .5f; constexpr const float STATUS_LEFT = 48.f; constexpr const float STATUS_SPREAD = 4.95f; diff --git a/src/HC-1/HC-1-menu.cpp b/src/HC-1/HC-1-menu.cpp index 5eedd65..cce1a31 100644 --- a/src/HC-1/HC-1-menu.cpp +++ b/src/HC-1/HC-1-menu.cpp @@ -39,9 +39,9 @@ void Hc1ModuleWidget::addRecirculator(Menu *menu, EM_Recirculator kind) [=](){ return my_module->recirculatorType() == kind; }, [=](){ bool extend = my_module->em.recirculator.extended(); - my_module->em.recirculator = Recirculator(kind); + my_module->em.recirculator.setKind(kind); my_module->em.recirculator.setExtended(extend); - my_module->sendControlChange(EM_SettingsChannel, EMCC_RecirculatorType, my_module->em.recirculator); + my_module->sendControlChange(EM_SettingsChannel, EMCC_RecirculatorType, my_module->em.recirculator.getValue()); } )); } diff --git a/src/HC-1/HC-1-midi.cpp b/src/HC-1/HC-1-midi.cpp index 356904e..81ce9e2 100644 --- a/src/HC-1/HC-1-midi.cpp +++ b/src/HC-1/HC-1-midi.cpp @@ -99,6 +99,15 @@ void Hc1Module::onChannel16CC(uint8_t cc, uint8_t value) preset0.bank_lo = value; break; + case EMCC_ActionAesMenuRecirc: + // TODO: Action, AES rate, Menu font also packed into this byte + if (value != em.global_ActionAesMenuRecirc) { + em.global_ActionAesMenuRecirc = value; + em.recirculator.setDisabled(value & 0x40); + getParamQuantity(RECIRC_ENABLE_PARAM)->setValue(static_cast(em.recirculator.enabled())); + } + break; + case EMCC_PedalType: { auto new_p1 = static_cast(value & 0x07); bool p1_change = new_p1 != em.pedal1.type; @@ -209,7 +218,7 @@ void Hc1Module::onChannel16CC(uint8_t cc, uint8_t value) } break; case EMCC_RecirculatorType: - em.recirculator = value; + em.recirculator.setValue(value); getParamQuantity(RECIRC_EXTEND_PARAM)->setValue(isExtendRecirculator() * 1.f); break; diff --git a/src/HC-1/HC-1-process.cpp b/src/HC-1/HC-1-process.cpp index ae815be..b997c01 100644 --- a/src/HC-1/HC-1-process.cpp +++ b/src/HC-1/HC-1-process.cpp @@ -79,6 +79,18 @@ void Hc1Module::processAllCV() } getLight(Lights::RECIRC_EXTEND_LIGHT).setBrightness(isExtendRecirculator() * 1.0f); } + // recirculator enabled + { + auto pq = getParamQuantity(RECIRC_ENABLE_PARAM); + bool disabled = pq->getValue() <= 0.5f; + if (disabled != em.recirculator.disabled()) { + em.recirculator.setDisabled(disabled); + em.global_ActionAesMenuRecirc = (em.global_ActionAesMenuRecirc & ~0x40) | (disabled * 0x40); + sendControlChange(EM_SettingsChannel, EMCC_ActionAesMenuRecirc, em.global_ActionAesMenuRecirc); + } + getLight(Lights::RECIRC_ENABLE_LIGHT).setBrightness((!disabled) * 1.0f); + } + } void Hc1Module::processReadyTrigger(bool ready, const ProcessArgs& args) diff --git a/src/HC-1/HC-1-ui.cpp b/src/HC-1/HC-1-ui.cpp index e7ebe4e..098a6f9 100644 --- a/src/HC-1/HC-1-ui.cpp +++ b/src/HC-1/HC-1-ui.cpp @@ -401,7 +401,8 @@ void Hc1ModuleWidget::createUi() addChild(createInputCentered( Vec(RKNOB_LEFT + 5.f * KNOB_SPREAD + RB_OFFSET + 14.f, CV_ROW_2 - RB_VOFFSET), my_module, Hc1in::MUTE_INPUT)); addChild(createStaticTextLabel(Vec(RKNOB_LEFT + KNOB_SPREAD * 5.f + 17.f, KNOB_ROW_2), 25.f, "Mute", TextAlignment::Left)); - addParam(createLightParamCentered>>(Vec(RECIRC_LIGHT_CENTER, RECIRC_BOX_TOP), my_module, Hc1p::RECIRC_EXTEND_PARAM, Hc1lt::RECIRC_EXTEND_LIGHT)); + addParam(createLightParamCentered>>(Vec(RECIRC_EXTEND_CENTER, RECIRC_BOX_TOP), my_module, Hc1p::RECIRC_EXTEND_PARAM, Hc1lt::RECIRC_EXTEND_LIGHT)); + addParam(createLightParamCentered>>(Vec(RECIRC_ENABLE_CENTER, RECIRC_BOX_TOP), my_module, Hc1p::RECIRC_ENABLE_PARAM, Hc1lt::RECIRC_ENABLE_LIGHT)); #ifdef TRANSPOSE_BUTTONS createTranspose(); diff --git a/src/HC-1/HC-1.cpp b/src/HC-1/HC-1.cpp index ed7f77c..420e7b6 100644 --- a/src/HC-1/HC-1.cpp +++ b/src/HC-1/HC-1.cpp @@ -44,6 +44,7 @@ Hc1Module::Hc1Module() configSwitch(VOLUME_REL_PARAM, 0.f, 1.f, 0.f, "Post level relative-CV", {"off", "on"}); configSwitch(MUTE_PARAM, 0.f, 1.f, 0.f, "Mute", {"off", "on"}); configSwitch(RECIRC_EXTEND_PARAM, 0.f, 1.f, 0.f, "Extended recirculator", {"off", "on"}); + configSwitch(RECIRC_ENABLE_PARAM, 0.f, 1.f, 1.f, "Recirculator enabled", {"off", "on"}); configInput(M1_INPUT, "Macro i"); configInput(M2_INPUT, "Macro ii"); @@ -68,6 +69,8 @@ Hc1Module::Hc1Module() configOutput(READY_TRIGGER, "Ready trigger"); getLight(HEART_LIGHT).setBrightness(.8f); + getLight(RECIRC_ENABLE_LIGHT).setBrightness(em.recirculator.enabled() * 1.0f); + clearCCValues(); loadStartupConfig(); } diff --git a/src/HC-1/HC-1.hpp b/src/HC-1/HC-1.hpp index a2dfdf7..b43d55c 100644 --- a/src/HC-1/HC-1.hpp +++ b/src/HC-1/HC-1.hpp @@ -37,6 +37,8 @@ struct Hc1Module : IPresetHolder, ISendMidi, IMidiDeviceHolder, IMidiDeviceChang R1_REL_PARAM, R2_REL_PARAM, R3_REL_PARAM, R4_REL_PARAM, RMIX_REL_PARAM, VOLUME_REL_PARAM, RECIRC_EXTEND_PARAM, + RECIRC_ENABLE_PARAM, + NUM_PARAMS, FIRST_REL_PARAM = M1_REL_PARAM, }; @@ -60,6 +62,7 @@ struct Hc1Module : IPresetHolder, ISendMidi, IMidiDeviceHolder, IMidiDeviceChang HEART_LIGHT, MUTE_LIGHT, RECIRC_EXTEND_LIGHT, + RECIRC_ENABLE_LIGHT, ROUND_Y_LIGHT, ROUND_INITIAL_LIGHT, ROUND_LIGHT, ROUND_RELEASE_LIGHT, //TRANSPOSE_UP_LIGHT, TRANSPOSE_NONE_LIGHT, TRANSPOSE_DOWN_LIGHT, // FILTER_LIGHT, @@ -328,6 +331,7 @@ struct Hc1Module : IPresetHolder, ISendMidi, IMidiDeviceHolder, IMidiDeviceChang EM_Recirculator recirculatorType() { return em.recirculator.kind(); } bool isExtendRecirculator() { return em.recirculator.extended(); } + bool isRecirculatorDisabled() { return em.recirculator.disabled(); } const std::string recirculatorName() { return em.recirculator.name(); } const std::string recirculatorParameterName(int r) { return em.recirculator.parameter_name(r); } void setRecirculatorCCValue(int id, uint8_t value); diff --git a/src/em.hpp b/src/em.hpp index cf0e695..78fd326 100644 --- a/src/em.hpp +++ b/src/em.hpp @@ -24,6 +24,7 @@ struct EaganMatrix PedalInfo pedal1; PedalInfo pedal2; bool reverse_surface; + uint8_t global_ActionAesMenuRecirc; // levels (PreLevel/PostLevel/AudioIn/LineOut/HeadphoneOut) // convolution diff --git a/src/em_midi.hpp b/src/em_midi.hpp index 198cc45..8aa230c 100644 --- a/src/em_midi.hpp +++ b/src/em_midi.hpp @@ -129,10 +129,11 @@ constexpr const uint8_t EMCC_RoundRate = 25; constexpr const uint8_t EMCC_PreLevel = 26; constexpr const uint8_t EMCC_Attenuation = 27; constexpr const uint8_t EMCC_RoundInitial = 28; -constexpr const uint8_t EMCC_Jack1 = 29; -constexpr const uint8_t EMCC_Jack2 = 30; +constexpr const uint8_t EMCC_Jack1 = 29; +constexpr const uint8_t EMCC_Jack2 = 30; constexpr const uint8_t EMCC_Advance = 31; //127 next, 64=next layer constexpr const uint8_t EMCC_Category = 32; +constexpr const uint8_t EMCC_ActionAesMenuRecirc = 33; constexpr const uint8_t EMCC_Routing = 36; constexpr const uint8_t EMCC_PedalType = 37; diff --git a/src/em_types/em_recirculator.hpp b/src/em_types/em_recirculator.hpp index 8c0c867..fecee19 100644 --- a/src/em_types/em_recirculator.hpp +++ b/src/em_types/em_recirculator.hpp @@ -11,19 +11,24 @@ using namespace em_midi; struct Recirculator { uint8_t r; + bool disable; - Recirculator() : r(0) {} - Recirculator(uint8_t value): r(value) {} + Recirculator() : r(0), disable(false) {} - operator uint8_t() const { return r; } + operator uint8_t() const { return r; } + void setValue(uint8_t R) { r = R; } + uint8_t getValue() { return r; } void clear() { r = 0; } bool extended() { return r & EM_Recirculator::Extend; } + bool disabled() { return disable; } + bool enabled() { return !disable; } void setExtended(bool extended) { r = extended ? (r | EM_Recirculator::Extend) : (r & ~EM_Recirculator::Extend); } + void setDisabled(bool value) { disable = value; } void setKind(EM_Recirculator kind) { r = (r & EM_Recirculator::Extend) | (kind & EM_Recirculator::Mask);