diff --git a/HPSDRProtocol.pas b/HPSDRProtocol.pas index 42a92d1..94e65e8 100644 --- a/HPSDRProtocol.pas +++ b/HPSDRProtocol.pas @@ -250,7 +250,7 @@ type CWRampPeriod: Byte; // 17: ms, 0=default Reserved18: array[18..49] of Byte; MicLineSelect: Byte; // 50 - LineInGain: Byte; // 51: 0=+12dB, 31=-34.5dB + LineInGain: Byte; // 51: 0=-34.5dB .. 31=+12dB (шаг 1.5 dB) Reserved52: array[52..56] of Byte; StepAtten2: Byte; // 57: ADC2 atten during TX (0-31dB) StepAtten1: Byte; // 58: ADC1 atten during TX diff --git a/MainForm.pas b/MainForm.pas index 7beccfa..7029c2f 100644 --- a/MainForm.pas +++ b/MainForm.pas @@ -303,7 +303,6 @@ type FWebBindAddr: string; FWebUser: string; FWebPass: string; - FSavedMicSource: TTXMicSource; // сохраняется при переключении на txmsWeb FWebMicActive: Boolean; // True если текущий TX идёт через txmsWeb // --- CAT --- FCATEngine: TCATEngine; @@ -659,6 +658,7 @@ type procedure TrkVolumeChange(Sender: TObject); function CalcDriveByte: Byte; function ActiveTXFreqHz: Double; + function DefaultMicSource: TTXMicSource; procedure ApplyMOX(Active: Boolean); procedure OnTXIQReady(const Buf: array of Double; Count: Integer); procedure OnPASettingsChange(MaxPower: Double; const BandCal: array of Double); @@ -2884,7 +2884,7 @@ begin begin if FTransmitting then begin - if FTXSettings.MicSource = 1 then + if FDSPEngine.TXMicSource = txmsSoundCard then StatusBar1.Panels[5].Text := Format('TX sc: avail=%d ring=%d', [FAudioIn.Available, FDSPEngine.TXMicRingAvail]) @@ -3283,7 +3283,7 @@ begin // HW mic-стрим уходит в WDSP только если выбран источник Radio. // Иначе сэмплы игнорируются (mic берётся со звуковой карты). if FTransmitting and FWDSPReady and - (FTXSettings.MicSource = Ord(txmsRadio)) then + (FDSPEngine.TXMicSource = txmsRadio) then FDSPEngine.PushTXMicSamples16(Data.Samples, 64); end; @@ -3293,18 +3293,21 @@ end; function TMainForm.BuildMicLineSelectByte: Byte; // openHPSDR Ethernet Protocol v4.3, DUC Specific byte 50: -// bit 0 — Line in (1 = line-in вместо mic-in) -// bit 1 — Mic Boost (+20 dB) +// bit 0 — Line In (1 = line-in вместо mic-in) +// bit 1 — Mic Boost (+20 dB); не ставим когда Line In // bit 2 — 0 = Orion mic PTT enabled, 1 = disabled (инверсия!) -// bit 3 — PTT/bias polarity (не используем) +// bit 3 — Tip/Ring (0=Tip, 1=Ring; Orion/OrionMkII) // bit 4 — Orion mic bias (1 = enable +5V bias) -// bit 5 — Saturn 3.5mm/XLR (не используем) +// bit 5 — Saturn XLR/balanced (не используем) begin Result := 0; - if FTXSettings.MicLineIn then Result := Result or $01; - if FTXSettings.MicBoost then Result := Result or $02; - if not FTXSettings.MicPTTEnabled then Result := Result or $04; - if FTXSettings.MicBias then Result := Result or $10; + if FTXSettings.MicLineIn then + Result := Result or $01 // bit 0: Line In + else if FTXSettings.MicBoost then + Result := Result or $02; // bit 1: Boost только при Mic In + if not FTXSettings.MicPTTEnabled then Result := Result or $04; // bit 2: инверсия + if FTXSettings.MicTipRing then Result := Result or $08; // bit 3: Ring + if FTXSettings.MicBias then Result := Result or $10; // bit 4: bias end; procedure TMainForm.SendDUCSpecificFromSettings; @@ -3326,6 +3329,9 @@ begin DUCPkt.DUC0RateLo := Lo(RateKsps); DUCPkt.DUC0Bits := 24; DUCPkt.MicLineSelect := BuildMicLineSelectByte; + // Line In Gain (byte 51): 0=-34.5dB .. 31=+12dB (шаг 1.5 dB, формула Thetis). + // При Mic In значение игнорируется железом, но шлём корректное для Line In. + DUCPkt.LineInGain := Byte(EnsureRange(Round((FTXSettings.LineInGainDB + 34.5) / 1.5), 0, 31)); // ATT on TX — RX-ADC step attenuator во время передачи (Thetis-style protection). // Дублируем значение во все три ADC-байта: на однопотоковых платах активен только // ADC0, на Saturn/Hermes Lite 2 — могут использоваться ADC1/ADC2. @@ -3335,11 +3341,21 @@ begin FNetwork.SendDUCSpecific(DUCPkt); end; +function TMainForm.DefaultMicSource: TTXMicSource; +// Mic source для MOX-кнопки и Web-TX: если настроена звуковая карта — берём с неё, +// иначе используем HW mic-стрим от трансивера. +// HW PTT всегда переключает на txmsRadio непосредственно в ApplyMOX. +begin + if FAudioInDevName <> '' then Result := txmsSoundCard + else Result := txmsRadio; +end; + procedure TMainForm.ApplyTXSettingsToDSP; begin if not FWDSPReady then Exit; - // Mic source — сначала, чтобы PullSoundCardMic уже видел правильное значение - FDSPEngine.SetTXMicSource(TTXMicSource(FTXSettings.MicSource)); + // Mic source — выставляем значение по умолчанию для MOX-кнопки; + // при реальном PTT ApplyMOX скорректирует источник. + FDSPEngine.SetTXMicSource(DefaultMicSource); FDSPEngine.SetMicGain(FTXSettings.MicGainDB); FDSPEngine.SetTXFilterFull(FTXSettings.FilterLow, FTXSettings.FilterHigh, FTXSettings.FilterNC, FTXSettings.FilterMP, @@ -3368,7 +3384,7 @@ begin end; function TMainForm.PullSoundCardMic(MaxN: Integer): Integer; -// Колбэк, который TTXDSPThread зовёт при MicSource=SoundCard. +// Колбэк, который TTXDSPThread зовёт при TXMicSource=txmsSoundCard. // Тянем только реально доступные сэмплы из FAudioIn — иначе мы пушили бы // нули и mic-цепь в WDSP получала бы тишину вместо реального сигнала. // Читаем пачкой в локальный буфер и пушим одним вызовом — экономим @@ -3849,15 +3865,13 @@ begin FAudioOutDevName := ''; end; FAudioOut.Open; - // Аудио устройство ввода (TX mic). Если в настройках выбрана конкретная - // soundcard — открываем её и принудительно переключаем MicSource на SoundCard, - // иначе пользователь нажмёт MOX и не поймёт почему его микрофон молчит. + // Аудио устройство ввода (TX mic). MicSource (Radio/SoundCard) определяется + // автоматически в ApplyMOX по источнику PTT — здесь только открываем устройство. if G_Settings.AudioInDevice <> '' then begin FAudioIn.DeviceIndex := FAudioIn.FindDeviceByName(G_Settings.AudioInDevice); FAudioInDevName := G_Settings.AudioInDevice; FAudioIn.Open; - FTXSettings.MicSource := 1; // SoundCard end else begin @@ -5085,18 +5099,26 @@ begin end; if FWDSPReady then begin - // Переключаем источник микрофона: при TX из браузера — txmsWeb, - // при TX с кнопки без веб-клиента — штатный источник из настроек. - if FTransmitting and Assigned(FWebServer) and FWebServer.WebClientActive then + // Mic source — определяем автоматически по источнику TX: + // Web TX → txmsWeb + // HW PTT (FHWPTTActive при входе в ApplyMOX уже True) → txmsRadio + // MOX-кнопка/CAT → sound card если настроена, иначе txmsRadio + if FTransmitting then begin - FSavedMicSource := TTXMicSource(FTXSettings.MicSource); - FWebMicActive := True; - FDSPEngine.SetTXMicSource(txmsWeb); + if Assigned(FWebServer) and FWebServer.WebClientActive then + begin + FWebMicActive := True; + FDSPEngine.SetTXMicSource(txmsWeb); + end + else if FHWPTTActive then + FDSPEngine.SetTXMicSource(txmsRadio) + else + FDSPEngine.SetTXMicSource(DefaultMicSource); end - else if not FTransmitting and FWebMicActive then + else if FWebMicActive then begin FWebMicActive := False; - FDSPEngine.SetTXMicSource(FSavedMicSource); + FDSPEngine.SetTXMicSource(DefaultMicSource); end; // В non-DUP RX-IQ пакеты дропаются на входе DSP-потока во время TX, // чтобы TX leakage не накапливался в RXA pipeline и FFT-истории @@ -6683,26 +6705,9 @@ begin on E: Exception do StatusBar1.Panels[3].Text := 'Mic err: ' + E.Message; end; - // Автопереключение mic-источника: явный выбор PortAudio-устройства - // → берём mic со звуковой карты, иначе HW mic-стрим бы перебивал его. - FTXSettings.MicSource := 1; // SoundCard end else - begin StatusBar1.Panels[3].Text := 'Mic: none'; - // Нет выбранного soundcard mic → возвращаемся на HW mic-стрим. - FTXSettings.MicSource := 0; // Radio - end; - if FWDSPReady then - FDSPEngine.SetTXMicSource(TTXMicSource(FTXSettings.MicSource)); - if FDevConnected then - begin - FSettings.SaveTX(FDevMAC, FTXSettings); - FSettings.Save; - end; - // Если открыт диалог настроек — синхронизировать UI - if Assigned(FSettingsForm) then - TSettingsForm(FSettingsForm).LoadTXSettings(FTXSettings); end; procedure TMainForm.ApplyVisibility(ShowSpectrum, ShowWaterfall: Boolean); @@ -6770,7 +6775,8 @@ begin SF.OnWebSettingsChange := ApplyWebSettings; end; SF := TSettingsForm(FSettingsForm); - SF.LoadTXSettings(FTXSettings); + SF.LoadTXSettings(FTXSettings, + IfThen(FNetwork.Connected, FNetwork.Device.BoardType, FPendingBoardType)); SF.LoadAlexSettings(FAlexSettings, IfThen(FNetwork.Connected, FNetwork.Device.BoardType, FPendingBoardType)); SF.LoadXvtrSettings(FXvtrSettings); diff --git a/Settings.pas b/Settings.pas index d2c2d8d..914bcd4 100644 --- a/Settings.pas +++ b/Settings.pas @@ -44,16 +44,14 @@ type // TX-настройки per-device. Хранятся в JSON-секции "tx" под MAC, // отдельно от global/bands. Применяются к WDSP через SetTX* методы. - // (Тип TTXMicSource живёт в WDSPEngine — здесь храним как Integer, - // чтобы не тащить циклическую зависимость с WDSPEngine.) TTXSettings = record - // Mic source select - MicSource: Integer; // 0=Radio, 1=SoundCard - // Radio mic options (DUC Specific byte 50 bits) - MicBoost: Boolean; // bit0: +20 dB - MicBias: Boolean; // bit4: электретный bias - MicLineIn: Boolean; // bit1: 1=Line in, 0=Mic in - MicPTTEnabled: Boolean; // bit2: Mic PTT enable + // Radio mic options (DUC Specific byte 50/51) + MicLineIn: Boolean; // bit0: 1=Line In, 0=Mic In + MicBoost: Boolean; // bit1: +20 dB preamp (только когда Mic In) + MicPTTEnabled: Boolean; // bit2: Mic PTT enable (Orion) + MicTipRing: Boolean; // bit3: False=Tip, True=Ring (Orion/OrionMkII) + MicBias: Boolean; // bit4: электретный +5V bias (Orion) + LineInGainDB: Double; // byte51: -34.5..+12 dB (шаг 1.5; только когда Line In) // Mic gain (dB, применяется в WDSP PanelGain1) MicGainDB: Double; // -10..+30 // ATT on TX — ослабление RX-ADC во время передачи (защита от утечки TX). @@ -854,12 +852,12 @@ const 100, 200, 400, 700, 1100, 1500, 2000, 2500, 3000, 3500); begin FillChar(T, SizeOf(T), 0); - // Mic source — Radio (HW). 0=Radio, 1=SoundCard (синхронно с TTXMicSource в WDSPEngine). - T.MicSource := 0; - T.MicBoost := False; - T.MicBias := True; T.MicLineIn := False; + T.MicBoost := False; T.MicPTTEnabled := False; + T.MicTipRing := False; // Tip (mic at Tip, PTT at Ring) + T.MicBias := True; + T.LineInGainDB := 0.0; // 0 dB T.MicGainDB := 10.0; // ATT on TX — Thetis default 31 dB (полная защита RX-ADC во время передачи) T.AttOnTX := 31; @@ -933,11 +931,12 @@ begin if DevObj.Find('tx') = nil then Exit; O := EnsureObj(DevObj, 'tx'); - T.MicSource := JI(O,'mic_source', T.MicSource); - T.MicBoost := JB(O,'mic_boost', T.MicBoost); - T.MicBias := JB(O,'mic_bias', T.MicBias); T.MicLineIn := JB(O,'mic_line_in', T.MicLineIn); + T.MicBoost := JB(O,'mic_boost', T.MicBoost); T.MicPTTEnabled := JB(O,'mic_ptt_enabled', T.MicPTTEnabled); + T.MicTipRing := JB(O,'mic_tip_ring', T.MicTipRing); + T.MicBias := JB(O,'mic_bias', T.MicBias); + T.LineInGainDB := EnsureRange(JD(O,'line_in_gain_db', T.LineInGainDB), -34.5, 12.0); T.MicGainDB := JD(O,'mic_gain_db', T.MicGainDB); T.AttOnTX := EnsureRange(JI(O,'att_on_tx', T.AttOnTX), 0, 31); T.TUNLevel := EnsureRange(JI(O,'tun_level', T.TUNLevel), 0, 100); @@ -990,12 +989,13 @@ procedure TSettingsManager.SaveTX(const MAC: array of Byte; var O: TJSONObject; i: Integer; begin O := EnsureObj(GetDevObj(MacToStr(MAC)), 'tx'); - JW(O,'mic_source', T.MicSource); - JW(O,'mic_boost', T.MicBoost); - JW(O,'mic_bias', T.MicBias); - JW(O,'mic_line_in', T.MicLineIn); - JW(O,'mic_ptt_enabled', T.MicPTTEnabled); - JW(O,'mic_gain_db', T.MicGainDB); + JW(O,'mic_line_in', T.MicLineIn); + JW(O,'mic_boost', T.MicBoost); + JW(O,'mic_ptt_enabled', T.MicPTTEnabled); + JW(O,'mic_tip_ring', T.MicTipRing); + JW(O,'mic_bias', T.MicBias); + JW(O,'line_in_gain_db', T.LineInGainDB); + JW(O,'mic_gain_db', T.MicGainDB); JW(O,'att_on_tx', T.AttOnTX); JW(O,'tun_level', T.TUNLevel); JW(O,'tun_freq', T.TUNFreq); diff --git a/SettingsForm.pas b/SettingsForm.pas index f350eab..909e2eb 100644 --- a/SettingsForm.pas +++ b/SettingsForm.pas @@ -129,12 +129,14 @@ type // ---- Transmit tab controls ---- // Текущее состояние, отдаётся в OnTXChange целиком при любой правке. FTX: TTXSettings; - // Mic source / options - FCmbTXMicSource: TComboBox; - FChkTXMicBoost: TCheckBox; + FCmbTXMicJack: TComboBox; // "Mic In" / "Line In" + FChkTXMicBoost: TCheckBox; // +20 dB (только Mic In) + FLblLineInGain: TLabel; // метка "Line In gain" (только Line In) + FEdLineInGain: TFloatSpinEdit; // -34.5..+12 dB, шаг 1.5 (только Line In) FChkTXMicBias: TCheckBox; - FChkTXMicLineIn: TCheckBox; FChkTXMicPTT: TCheckBox; + FCmbTXMicTR: TComboBox; // "Tip" / "Ring" (только Orion) + FLblTipRing: TLabel; // метка (только Orion) FEdTXMicGain: TFloatSpinEdit; FEdTXAttOnTX: TSpinEdit; // Tune (TUN button) @@ -296,6 +298,8 @@ type procedure CollectTXFromUI; procedure FireTXChange; procedure OnTXAnyChange(Sender: TObject); + procedure OnMicJackChange(Sender: TObject); + procedure UpdateMicJackVisibility; procedure ApplyTheme(const T: TAppTheme); procedure NavClick(Sender: TObject); procedure SelectPage(APage: TWinControl; ANav: TFlatButton); @@ -374,7 +378,7 @@ type const SerPort: array of string; const SerBaud, SerDataBits, SerStopBits, SerParity: array of Integer; TcpEnabled: Boolean; TcpPort: Integer); - procedure LoadTXSettings(const T: TTXSettings); + procedure LoadTXSettings(const T: TTXSettings; BoardType: Integer = 0); procedure LoadAlexSettings(const A: TAlexSettings; BoardType: Integer); procedure LoadXvtrSettings(const X: TXvtrSettings); procedure LoadWfAGCNF(AGC, NF: Boolean); @@ -1083,31 +1087,43 @@ begin Font.Color := CLR_TEXTDIM; end; - // ---- Mic source / options ---- + // ---- Mic options ---- + // Mic source (Radio vs SoundCard) определяется автоматически по источнику PTT. Y := 86; - Grp := MakeGroupPanel(FPageTransmit, 'Microphone', MARGIN, Y, 700, 220); + Grp := MakeGroupPanel(FPageTransmit, 'Microphone', MARGIN, Y, 700, 188); - MakeLbl(Grp, 'Mic source', PAD, R1 + 5, LW); - FCmbTXMicSource := MkCmb(Grp, CX, R1, CMB_W); - FCmbTXMicSource.Items.Add('Radio (HW mic)'); - FCmbTXMicSource.Items.Add('Sound card'); - FCmbTXMicSource.ItemIndex := 0; + // Row 0: Mic jack selector | Boost (Mic In) или LineInGain (Line In) | Bias | PTT + MakeLbl(Grp, 'Mic jack', PAD, R1 + 5, 65); + FCmbTXMicJack := MkCmb(Grp, PAD + 68, R1, 110); + FCmbTXMicJack.Items.Add('Mic In'); + FCmbTXMicJack.Items.Add('Line In'); + FCmbTXMicJack.ItemIndex := 0; + FCmbTXMicJack.OnChange := OnMicJackChange; - FChkTXMicBoost := MkChk(Grp, PAD, R1 + STEP, 200, 'Mic boost +20 dB'); - FChkTXMicBias := MkChk(Grp, PAD + 200, R1 + STEP, 200, 'Mic bias'); - FChkTXMicLineIn := MkChk(Grp, PAD + 400, R1 + STEP, 160, 'Line in'); - FChkTXMicPTT := MkChk(Grp, PAD, R1 + 2 * STEP, 220, 'Mic-jack PTT'); + FChkTXMicBoost := MkChk(Grp, PAD + 190, R1, 165, 'Mic boost +20 dB'); + FLblLineInGain := MakeLbl(Grp, 'Line In gain', PAD + 190, R1 + 5, 80); + FEdLineInGain := MkFloat(Grp, PAD + 190 + 82, R1, 0.0, -34.5, 12.0, 1.5); + FEdLineInGain.DecimalPlaces := 1; + FChkTXMicBias := MkChk(Grp, PAD + 375, R1, 105, 'Mic bias'); + FChkTXMicPTT := MkChk(Grp, PAD + 490, R1, 160, 'Mic-jack PTT'); - MakeLbl(Grp, 'Mic gain (dB)', PAD, R1 + 3 * STEP + 5, LW); - FEdTXMicGain := MkFloat(Grp, CX, R1 + 3 * STEP, 10.0, -20.0, 60.0, 0.5); + // Row 1: Connector Tip/Ring (только Orion boards 4 и 5) + FLblTipRing := MakeLbl(Grp, 'Connector', PAD, R1 + STEP + 5, 70); + FCmbTXMicTR := MkCmb(Grp, PAD + 73, R1 + STEP, 90); + FCmbTXMicTR.Items.Add('Tip'); // MicTipRing=False, bit3=0 + FCmbTXMicTR.Items.Add('Ring'); // MicTipRing=True, bit3=1 + FCmbTXMicTR.ItemIndex := 0; + FLblTipRing.Visible := False; + FCmbTXMicTR.Visible := False; - // ATT on TX — RX-ADC ослабление во время передачи (DUC Specific bytes 57/58/59). - // Thetis-style default 31 dB. Помещаем на той же строке, что и Mic gain. - MakeLbl(Grp, 'ATT on TX (dB)', PAD + 320, R1 + 3 * STEP + 5, 110); - FEdTXAttOnTX := MkSpin(Grp, PAD + 320 + 120, R1 + 3 * STEP, 0, 31, 31); + // Row 2: Mic gain | ATT on TX + MakeLbl(Grp, 'Mic gain (dB)', PAD, R1 + 2 * STEP + 5, LW); + FEdTXMicGain := MkFloat(Grp, CX, R1 + 2 * STEP, 10.0, -20.0, 60.0, 0.5); + MakeLbl(Grp, 'ATT on TX (dB)', PAD + 320, R1 + 2 * STEP + 5, 110); + FEdTXAttOnTX := MkSpin(Grp, PAD + 320 + 120, R1 + 2 * STEP, 0, 31, 31); // ---- Tune (TUN button) ---- - Inc(Y, 220 + 12); + Inc(Y, 188 + 12); Grp := MakeGroupPanel(FPageTransmit, 'Tune (TUN)', MARGIN, Y, 700, 100); MakeLbl(Grp, 'Tune level (%)', PAD, R1 + 5, LW); @@ -1287,12 +1303,12 @@ end; procedure TSettingsForm.CollectTXFromUI; var i: Integer; begin - if FCmbTXMicSource <> nil then - FTX.MicSource := Max(0, FCmbTXMicSource.ItemIndex); - if FChkTXMicBoost <> nil then FTX.MicBoost := FChkTXMicBoost.Checked; - if FChkTXMicBias <> nil then FTX.MicBias := FChkTXMicBias.Checked; - if FChkTXMicLineIn <> nil then FTX.MicLineIn := FChkTXMicLineIn.Checked; + if FCmbTXMicJack <> nil then FTX.MicLineIn := FCmbTXMicJack.ItemIndex = 1; + if FChkTXMicBoost <> nil then FTX.MicBoost := FChkTXMicBoost.Checked; + if FEdLineInGain <> nil then FTX.LineInGainDB := FEdLineInGain.Value; + if FChkTXMicBias <> nil then FTX.MicBias := FChkTXMicBias.Checked; if FChkTXMicPTT <> nil then FTX.MicPTTEnabled := FChkTXMicPTT.Checked; + if FCmbTXMicTR <> nil then FTX.MicTipRing := FCmbTXMicTR.ItemIndex = 1; if FEdTXMicGain <> nil then FTX.MicGainDB := FEdTXMicGain.Value; if FEdTXAttOnTX <> nil then FTX.AttOnTX := FEdTXAttOnTX.Value; if FEdTUNLevel <> nil then FTX.TUNLevel := FEdTUNLevel.Value; @@ -1368,20 +1384,45 @@ begin FireTXChange; end; -procedure TSettingsForm.LoadTXSettings(const T: TTXSettings); -var i: Integer; +procedure TSettingsForm.UpdateMicJackVisibility; +var LineIn: Boolean; +begin + if FCmbTXMicJack = nil then Exit; + LineIn := FCmbTXMicJack.ItemIndex = 1; + if FChkTXMicBoost <> nil then FChkTXMicBoost.Visible := not LineIn; + if FLblLineInGain <> nil then FLblLineInGain.Visible := LineIn; + if FEdLineInGain <> nil then FEdLineInGain.Visible := LineIn; +end; + +procedure TSettingsForm.OnMicJackChange(Sender: TObject); +begin + UpdateMicJackVisibility; + FireTXChange; +end; + +procedure TSettingsForm.LoadTXSettings(const T: TTXSettings; BoardType: Integer = 0); +var i: Integer; IsOrion: Boolean; begin FLoading := True; try FTX := T; - if FCmbTXMicSource <> nil then - FCmbTXMicSource.ItemIndex := EnsureRange(T.MicSource, 0, FCmbTXMicSource.Items.Count - 1); - if FChkTXMicBoost <> nil then FChkTXMicBoost.Checked := T.MicBoost; - if FChkTXMicBias <> nil then FChkTXMicBias.Checked := T.MicBias; - if FChkTXMicLineIn <> nil then FChkTXMicLineIn.Checked := T.MicLineIn; - if FChkTXMicPTT <> nil then FChkTXMicPTT.Checked := T.MicPTTEnabled; - if FEdTXMicGain <> nil then FEdTXMicGain.Value := T.MicGainDB; - if FEdTXAttOnTX <> nil then FEdTXAttOnTX.Value := EnsureRange(T.AttOnTX, 0, 31); + if FCmbTXMicJack <> nil then + FCmbTXMicJack.ItemIndex := IfThen(T.MicLineIn, 1, 0); + UpdateMicJackVisibility; + if FChkTXMicBoost <> nil then FChkTXMicBoost.Checked := T.MicBoost; + if FEdLineInGain <> nil then FEdLineInGain.Value := EnsureRange(T.LineInGainDB, -34.5, 12.0); + if FChkTXMicBias <> nil then FChkTXMicBias.Checked := T.MicBias; + if FChkTXMicPTT <> nil then FChkTXMicPTT.Checked := T.MicPTTEnabled; + // Tip/Ring (Orion boards 4 и 5) + IsOrion := BoardType in [4, 5]; + if FLblTipRing <> nil then FLblTipRing.Visible := IsOrion; + if FCmbTXMicTR <> nil then + begin + FCmbTXMicTR.Visible := IsOrion; + FCmbTXMicTR.ItemIndex := IfThen(T.MicTipRing, 1, 0); + end; + if FEdTXMicGain <> nil then FEdTXMicGain.Value := T.MicGainDB; + if FEdTXAttOnTX <> nil then FEdTXAttOnTX.Value := EnsureRange(T.AttOnTX, 0, 31); if FEdTUNLevel <> nil then FEdTUNLevel.Value := EnsureRange(T.TUNLevel, 0, 100); if FEdTUNFreq <> nil then FEdTUNFreq.Value := EnsureRange(T.TUNFreq, 100, 5000); if FEdTXFiltLow <> nil then FEdTXFiltLow.Value := T.FilterLow;