| 135 | // ── Phone sub-panel (existing P/CW controls) ──────────────────────────────── |
| 136 | |
| 137 | void PhoneCwApplet::buildPhonePanel() |
| 138 | { |
| 139 | m_phonePanel = new QWidget; |
| 140 | auto* vbox = new QVBoxLayout(m_phonePanel); |
| 141 | vbox->setContentsMargins(4, 2, 4, 2); |
| 142 | vbox->setSpacing(2); |
| 143 | |
| 144 | // ── Level gauge (mic peak, dBFS: -40 to +10) ──────────────────────── |
| 145 | m_levelGauge = new HGauge(-40.0f, 10.0f, 0.0f, "Level", "dB", |
| 146 | {{-40, "-40dB"}, {-30, "-30"}, {-20, "-20"}, {-10, "-10"}, {0, "0"}, {5, "+5"}, {10, "+10"}}, |
| 147 | nullptr, -10.0f); |
| 148 | m_levelGauge->setAccessibleName("Microphone level gauge"); |
| 149 | m_levelGauge->setAccessibleDescription("Microphone input level in dBFS"); |
| 150 | // Mouse-over readout: exact mic peak in dB. (#3936) |
| 151 | m_levelGauge->setHoverValueFormatter([](float v) { |
| 152 | return QStringLiteral("%1 dB").arg(QString::number(v, 'f', 1)); |
| 153 | }); |
| 154 | m_levelGauge->setHoverValuePopupEnabled(true); |
| 155 | vbox->addWidget(m_levelGauge); |
| 156 | |
| 157 | // ── Compression gauge (dB: -25 to 0, fills right-to-left) ─────────── |
| 158 | m_compGauge = new HGauge(-25.0f, 0.0f, 1.0f, "Compression", "", |
| 159 | {{-25, "-25dB"}, {-20, "-20"}, {-15, "-15"}, {-10, "-10"}, {-5, "-5"}, {0, "0"}}); |
| 160 | m_compGauge->setReversed(true); |
| 161 | m_compGauge->setAccessibleName("Compression gauge"); |
| 162 | m_compGauge->setAccessibleDescription("Speech compression amount in dB"); |
| 163 | // Mouse-over readout: the gauge stores compression as a negative offset |
| 164 | // (-25…0); report it as a positive "amount of compression" in dB. (#3936) |
| 165 | m_compGauge->setHoverValueFormatter([](float v) { |
| 166 | return QStringLiteral("%1 dB").arg(QString::number(-v, 'f', 1)); |
| 167 | }); |
| 168 | m_compGauge->setHoverValuePopupEnabled(true); |
| 169 | vbox->addWidget(m_compGauge); |
| 170 | |
| 171 | // ── ALC gauge (post-SW-ALC SSB-peak, dBFS) ────────────────────────── |
| 172 | // Mirrored in m_cwPanel; both gauges read from MeterModel::swAlcChanged |
| 173 | // so SSB operators watching mic gain see the same indicator CW |
| 174 | // operators use to verify clean keying envelope shape. |
| 175 | m_alcGaugePhone = new HGauge(kAlcGaugeFloorDbfs, 0.0f, -3.0f, "ALC", "dBFS", |
| 176 | {{-20, "-20"}, {-15, "-15"}, {-10, "-10"}, {-5, "-5"}, {0, "0"}}); |
| 177 | m_alcGaugePhone->setFillFromRight(true); // empty at -20, fills leftward toward 0 |
| 178 | m_alcGaugePhone->setValueImmediate(kAlcGaugeFloorDbfs); |
| 179 | m_alcGaugePhone->setAccessibleName("ALC gauge (Phone)"); |
| 180 | m_alcGaugePhone->setAccessibleDescription("Automatic level control — post-software-ALC SSB peak (dBFS)"); |
| 181 | m_alcGaugePhone->setHoverValueFormatter(alcHoverFormatter()); |
| 182 | m_alcGaugePhone->setHoverValuePopupEnabled(true); |
| 183 | vbox->addWidget(m_alcGaugePhone); |
| 184 | vbox->addSpacing(4); |
| 185 | |
| 186 | // ── Mic profile dropdown ───────────────────────────────────────────── |
| 187 | m_micProfileCombo = new GuardedComboBox; |
| 188 | m_micProfileCombo->setFixedHeight(22); |
| 189 | m_micProfileCombo->setAccessibleName("Microphone profile"); |
| 190 | m_micProfileCombo->setAccessibleDescription("Select microphone processing profile"); |
| 191 | AetherSDR::applyComboStyle(m_micProfileCombo); |
| 192 | connect(m_micProfileCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), |
| 193 | this, [this](int) { |
| 194 | if (!m_updatingFromModel && m_model) { |
nothing calls this directly
no test coverage detected