| 199 | |
| 200 | #ifdef HAVE_RADE |
| 201 | void MainWindow::activateRADE(int sliceId) |
| 202 | { |
| 203 | // Guard against duplicate activation (VfoWidget + RxApplet both selecting RADE) |
| 204 | if (m_radeSliceId == sliceId && m_radeEngine && m_radeEngine->isActive()) |
| 205 | return; |
| 206 | |
| 207 | // If RADE is already active on a different slice, deactivate it first |
| 208 | if (m_radeSliceId >= 0 && m_radeSliceId != sliceId) |
| 209 | deactivateRADE(); |
| 210 | |
| 211 | auto* s = m_radioModel.slice(sliceId); |
| 212 | if (!s) return; |
| 213 | |
| 214 | // Capture TX slice owner before potentially moving the badge, so the |
| 215 | // failure path can restore it. -1 means no TX slice existed. |
| 216 | int prevTxSliceId = sliceId; |
| 217 | if (!s->isTxSlice()) { |
| 218 | prevTxSliceId = -1; |
| 219 | for (auto* sl : m_radioModel.slices()) { |
| 220 | if (sl && sl->isTxSlice()) { prevTxSliceId = sl->sliceId(); break; } |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | // RADE needs to be the TX slice so it can transmit modem audio. |
| 225 | // Move TX badge to the RADE slice automatically. |
| 226 | if (!s->isTxSlice()) |
| 227 | s->setTxSlice(true); |
| 228 | |
| 229 | // Set radio mode to DIGU/DIGL (passthrough for OFDM modem). |
| 230 | // Use band convention from BandDefs to pick sideband — 60m is USB |
| 231 | // despite being below 10 MHz (#875). |
| 232 | double freqMhz = s->frequency(); |
| 233 | QString mode = "DIGU"; |
| 234 | for (const auto& band : AetherSDR::kBands) { |
| 235 | if (freqMhz >= band.lowMhz && freqMhz <= band.highMhz) { |
| 236 | mode = (QString(band.defaultMode) == "LSB") ? "DIGL" : "DIGU"; |
| 237 | break; |
| 238 | } |
| 239 | } |
| 240 | const QString prevMode = s->mode(); |
| 241 | const int prevFilterLow = s->filterLow(); |
| 242 | const int prevFilterHigh = s->filterHigh(); |
| 243 | s->setMode(mode); |
| 244 | if (mode == "DIGL") |
| 245 | s->setFilterWidth(-2250, -750); |
| 246 | else |
| 247 | s->setFilterWidth(750, 2250); |
| 248 | |
| 249 | // Remember which slice and its previous mute state |
| 250 | m_radeSliceId = sliceId; |
| 251 | m_radePrevMute = s->audioMute(); |
| 252 | s->setAudioMute(true); |
| 253 | |
| 254 | // Auto-deactivate if the slice mode is changed externally (TCI, profile |
| 255 | // load, remote SmartSDR client) — those paths bypass the VfoWidget and |
| 256 | // RxApplet combos and would otherwise leave audio_mute=1 stranded. |
| 257 | connect(s, &SliceModel::modeChanged, |
| 258 | this, &MainWindow::onRadeSliceModeChanged, |
nothing calls this directly
no test coverage detected