| 1690 | |
| 1691 | #ifdef HAVE_MIDI |
| 1692 | void MainWindow::registerMidiParams() |
| 1693 | { |
| 1694 | using P = MidiParamType; |
| 1695 | // Setters/getters stored on MainWindow for main-thread dispatch (#502). |
| 1696 | // MidiControlManager gets metadata only (no lambdas that capture main-thread objects). |
| 1697 | auto reg = [this](const char* id, const char* name, const char* cat, |
| 1698 | MidiParamType type, float lo, float hi, |
| 1699 | std::function<void(float)> setter, |
| 1700 | std::function<float()> getter = {}) { |
| 1701 | m_midiSetters[id] = setter; |
| 1702 | if (getter) m_midiGetters[id] = getter; |
| 1703 | m_midiControl->registerParam({id, name, cat, type, lo, hi, std::move(setter), std::move(getter)}); |
| 1704 | }; |
| 1705 | |
| 1706 | // ── RX ────────────────────────────────────────────────────────────── |
| 1707 | reg("rx.afGain", "AF Gain", "RX", P::Slider, 0, 200, |
| 1708 | [this](float v) { if (auto* s = activeSlice()) s->setAudioGain(v); }, |
| 1709 | [this]() -> float { auto* s = activeSlice(); return s ? s->audioGain() : 0; }); |
| 1710 | |
| 1711 | reg("rx.squelch", "Squelch Level", "RX", P::Slider, 0, 100, |
| 1712 | [this](float v) { |
| 1713 | if (auto* s = activeSlice()) { |
| 1714 | s->setSquelch(s->receiveSquelchOn(), static_cast<int>(v)); |
| 1715 | } |
| 1716 | }, |
| 1717 | [this]() -> float { |
| 1718 | auto* s = activeSlice(); |
| 1719 | return s ? s->receiveSquelchLevel() : 0; |
| 1720 | }); |
| 1721 | |
| 1722 | reg("rx.agcThreshold", "AGC Threshold", "RX", P::Slider, 0, 100, |
| 1723 | [this](float v) { |
| 1724 | if (auto* s = activeSlice()) { |
| 1725 | s->setAgcThreshold(controllerValueToAgcThreshold(s, v)); |
| 1726 | } |
| 1727 | }, |
| 1728 | [this]() -> float { |
| 1729 | return agcThresholdToControllerValue(activeSlice()); |
| 1730 | }); |
| 1731 | |
| 1732 | reg("rx.audioPan", "Audio Pan", "RX", P::Slider, 0, 100, |
| 1733 | [this](float v) { if (auto* s = activeSlice()) s->setAudioPan(static_cast<int>(v)); }, |
| 1734 | [this]() -> float { auto* s = activeSlice(); return s ? s->audioPan() : 50; }); |
| 1735 | |
| 1736 | reg("rx.nbEnable", "Noise Blanker", "RX", P::Toggle, 0, 1, |
| 1737 | [this](float v) { if (auto* s = activeSlice()) s->setNb(v > 0.5f); }, |
| 1738 | [this]() -> float { auto* s = activeSlice(); return s && s->nbOn() ? 1 : 0; }); |
| 1739 | |
| 1740 | reg("rx.nrEnable", "Noise Reduction", "RX", P::Toggle, 0, 1, |
| 1741 | [this](float v) { if (auto* s = activeSlice()) s->setNr(v > 0.5f); }, |
| 1742 | [this]() -> float { auto* s = activeSlice(); return s && s->nrOn() ? 1 : 0; }); |
| 1743 | |
| 1744 | reg("rx.anfEnable", "Auto Notch", "RX", P::Toggle, 0, 1, |
| 1745 | [this](float v) { if (auto* s = activeSlice()) s->setAnf(v > 0.5f); }, |
| 1746 | [this]() -> float { auto* s = activeSlice(); return s && s->anfOn() ? 1 : 0; }); |
| 1747 | |
| 1748 | reg("rx.squelchEnable", "Squelch Enable", "RX", P::Toggle, 0, 1, |
| 1749 | [this](float v) { |
nothing calls this directly
no test coverage detected