2021-02-22 17:35:24 +02:00
# include "TCITransceiver.hpp"
# include <QRegularExpression>
# include <QLocale>
# include <QThread>
# include <qmath.h>
# if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
# include <QRandomGenerator>
# endif
# include "commons.h"
# include "NetworkServerLookup.hpp"
# include "moc_TCITransceiver.cpp"
namespace
{
2021-06-14 15:40:14 +03:00
char const * const TCI_transceiver_1_name { " TCI Client RX1 " } ;
char const * const TCI_transceiver_2_name { " TCI Client RX2 " } ;
2021-02-22 17:35:24 +02:00
QString map_mode ( Transceiver : : MODE mode )
{
switch ( mode )
{
case Transceiver : : AM : return " am " ;
case Transceiver : : CW : return " cw " ;
// case Transceiver::CW_R: return "CW-R";
case Transceiver : : USB : return " usb " ;
case Transceiver : : LSB : return " lsb " ;
// case Transceiver::FSK: return "RTTY";
// case Transceiver::FSK_R: return "RTTY-R";
case Transceiver : : DIG_L : return " digl " ;
case Transceiver : : DIG_U : return " digu " ;
case Transceiver : : FM : return " wfm " ;
case Transceiver : : DIG_FM :
return " nfm " ;
default : break ;
}
return " " ;
}
static const QString SmTZ ( " ; " ) ;
static const QString SmDP ( " : " ) ;
static const QString SmCM ( " , " ) ;
static const QString SmTrue ( " true " ) ;
static const QString SmFalse ( " false " ) ;
// Command maps
static const QString CmdDevice ( " device " ) ;
static const QString CmdReceiveOnly ( " receive_only " ) ;
static const QString CmdTrxCount ( " trx_count " ) ;
static const QString CmdChannelCount ( " channels_count " ) ;
static const QString CmdVfoLimits ( " vfo_limits " ) ;
static const QString CmdIfLimits ( " if_limits " ) ;
static const QString CmdModeList ( " modulations_list " ) ;
static const QString CmdMode ( " modulation " ) ;
static const QString CmdReady ( " ready " ) ;
static const QString CmdStop ( " stop " ) ;
static const QString CmdStart ( " start " ) ;
static const QString CmdPreamp ( " preamp " ) ;
static const QString CmdDds ( " dds " ) ;
static const QString CmdIf ( " if " ) ;
static const QString CmdTrx ( " trx " ) ;
static const QString CmdRxEnable ( " rx_enable " ) ;
static const QString CmdTxEnable ( " tx_enable " ) ;
2021-06-14 15:40:14 +03:00
static const QString CmdRxChannelEnable ( " rx_channel_enable " ) ;
2021-02-22 17:35:24 +02:00
static const QString CmdRitEnable ( " rit_enable " ) ;
static const QString CmdRitOffset ( " rit_offset " ) ;
static const QString CmdXitEnable ( " xit_enable " ) ;
static const QString CmdXitOffset ( " xit_offset " ) ;
static const QString CmdSplitEnable ( " split_enable " ) ;
static const QString CmdIqSR ( " iq_samplerate " ) ;
static const QString CmdIqStart ( " iq_start " ) ;
static const QString CmdIqStop ( " iq_stop " ) ;
static const QString CmdCWSpeed ( " cw_macros_speed " ) ;
static const QString CmdCWDelay ( " cw_macros_delay " ) ;
static const QString CmdSpot ( " spot " ) ;
static const QString CmdSpotDelete ( " spot_delete " ) ;
static const QString CmdFilterBand ( " rx_filter_band " ) ;
static const QString CmdVFO ( " vfo " ) ;
static const QString CmdVersion ( " protocol " ) ; //protocol:esdr,1.2;
static const QString CmdTune ( " tune " ) ;
static const QString CmdRxMute ( " rx_mute " ) ;
static const QString CmdSmeter ( " rx_smeter " ) ;
static const QString CmdPower ( " tx_power " ) ;
static const QString CmdSWR ( " tx_swr " ) ;
static const QString CmdECoderRX ( " ecoder_switch_rx " ) ;
static const QString CmdECoderVFO ( " ecoder_switch_channel " ) ;
static const QString CmdAudioSR ( " audio_samplerate " ) ;
static const QString CmdAudioStart ( " audio_start " ) ;
static const QString CmdAudioStop ( " audio_stop " ) ;
static const QString CmdAppFocus ( " app_focus " ) ;
static const QString CmdVolume ( " volume " ) ;
static const QString CmdSqlEnable ( " sql_enable " ) ;
static const QString CmdSqlLevel ( " sql_level " ) ;
static const QString CmdDrive ( " drive " ) ;
static const QString CmdTuneDrive ( " tune_drive " ) ;
static const QString CmdMute ( " mute " ) ;
2021-06-14 15:40:14 +03:00
static const QString CmdRxSensorsEnable ( " rx_sensors_enable " ) ;
static const QString CmdTxSensorsEnable ( " tx_sensors_enable " ) ;
static const QString CmdRxSensors ( " rx_sensors " ) ;
static const QString CmdTxSensors ( " tx_sensors " ) ;
static const QString CmdAgcMode ( " agc_mode " ) ;
static const QString CmdAgcGain ( " agc_gain " ) ;
static const QString CmdLock ( " lock " ) ;
2021-02-22 17:35:24 +02:00
}
extern " C " {
void fil4_ ( qint16 * , qint32 * , qint16 * , qint32 * , float * ) ;
}
extern dec_data dec_data ;
extern float gran ( ) ; // Noise generator (for tests only)
# define RAMP_INCREMENT 64 // MUST be an integral factor of 2^16
# if defined (WSJT_SOFT_KEYING)
# define SOFT_KEYING WSJT_SOFT_KEYING
# else
# define SOFT_KEYING 1
# endif
double constexpr TCITransceiver : : m_twoPi ;
2021-06-14 15:40:14 +03:00
void TCITransceiver : : register_transceivers ( TransceiverFactory : : Transceivers * registry , unsigned id1 , unsigned id2 )
2021-02-22 17:35:24 +02:00
{
2021-06-14 15:40:14 +03:00
( * registry ) [ TCI_transceiver_1_name ] = TransceiverFactory : : Capabilities { id1 , TransceiverFactory : : Capabilities : : tci , true } ;
( * registry ) [ TCI_transceiver_2_name ] = TransceiverFactory : : Capabilities { id2 , TransceiverFactory : : Capabilities : : tci , true } ;
2021-02-22 17:35:24 +02:00
}
static constexpr quint32 AudioHeaderSize = 16u * sizeof ( quint32 ) ;
2021-06-14 15:40:14 +03:00
TCITransceiver : : TCITransceiver ( std : : unique_ptr < TransceiverBase > wrapped , QString const & rignr ,
2021-02-22 17:35:24 +02:00
QString const & address , bool use_for_ptt ,
int poll_interval , QObject * parent )
: PollingTransceiver { poll_interval , parent }
, wrapped_ { std : : move ( wrapped ) }
2021-06-14 15:40:14 +03:00
, rx_ { rignr }
, server_ { address }
2021-02-22 17:35:24 +02:00
, use_for_ptt_ { use_for_ptt }
2021-02-28 12:10:31 +02:00
, errortable { tr ( " ConnectionRefused " ) ,
tr ( " RemoteHostClosed " ) ,
tr ( " HostNotFound " ) ,
tr ( " SocketAccess " ) ,
tr ( " SocketResource " ) ,
tr ( " SocketTimeout " ) ,
tr ( " DatagramTooLarge " ) ,
tr ( " Network " ) ,
tr ( " AddressInUse " ) ,
tr ( " SocketAddressNotAvailable " ) ,
tr ( " UnsupportedSocketOperation " ) ,
tr ( " UnfinishedSocketOperation " ) ,
tr ( " ProxyAuthenticationRequired " ) ,
tr ( " SslHandshakeFailed " ) ,
tr ( " ProxyConnectionRefused " ) ,
tr ( " ProxyConnectionClosed " ) ,
tr ( " ProxyConnectionTimeout " ) ,
tr ( " ProxyNotFound " ) ,
tr ( " ProxyProtocol " ) ,
tr ( " Operation " ) ,
tr ( " SslInternal " ) ,
tr ( " SslInvalidUserData " ) ,
tr ( " Temporary " ) ,
tr ( " UnknownSocket " ) }
2021-03-01 10:47:46 +02:00
, error_ { " " }
2021-02-22 17:35:24 +02:00
, do_snr_ { ( poll_interval & do__snr ) = = do__snr }
, do_pwr_ { ( poll_interval & do__pwr ) = = do__pwr }
, rig_power_ { ( poll_interval & rig__power ) = = rig__power }
2021-02-23 12:55:37 +02:00
, rig_power_off_ { ( poll_interval & rig__power_off ) = = rig__power_off }
2021-03-16 10:27:24 +02:00
, tci_audio_ { ( poll_interval & tci__audio ) = = tci__audio }
2021-02-22 17:35:24 +02:00
, commander_ { nullptr }
, tci_timer1_ { nullptr }
, tci_loop1_ { nullptr }
, tci_timer2_ { nullptr }
, tci_loop2_ { nullptr }
, tci_timer3_ { nullptr }
, tci_loop3_ { nullptr }
2021-03-08 09:36:55 +02:00
, wavptr_ { nullptr }
2021-02-28 12:10:31 +02:00
, m_jtdxtime { nullptr }
2021-02-22 17:35:24 +02:00
, m_downSampleFactor { 4 }
, m_buffer ( ( m_downSampleFactor > 1 ) ?
new short [ max_buffer_size * m_downSampleFactor ] : nullptr )
, m_quickClose { false }
, m_phi { 0.0 }
, m_toneSpacing { 0.0 }
, m_fSpread { 0.0 }
, m_state { Idle }
, m_tuning { false }
, m_cwLevel { false }
, m_j0 { - 1 }
, m_toneFrequency0 { 1500.0 }
, debug_file_ { QDir ( QStandardPaths : : writableLocation ( QStandardPaths : : DataLocation ) ) . absoluteFilePath ( " jtdx_debug.txt " ) . toStdString ( ) }
2021-03-08 09:36:55 +02:00
, wav_file_ { QDir ( QStandardPaths : : writableLocation ( QStandardPaths : : DataLocation ) ) . absoluteFilePath ( " tx.wav " ) . toStdString ( ) }
2021-02-22 17:35:24 +02:00
{
m_samplesPerFFT = 6912 / 2 ;
tci_Ready = false ;
trxA = 0 ;
trxB = 0 ;
cntIQ = 0 ;
bIQ = false ;
inConnected = false ;
audioSampleRate = 48000u ;
mapCmd_ [ CmdDevice ] = Cmd_Device ;
mapCmd_ [ CmdReceiveOnly ] = Cmd_ReceiveOnly ;
mapCmd_ [ CmdTrxCount ] = Cmd_TrxCount ;
mapCmd_ [ CmdChannelCount ] = Cmd_ChannelCount ;
mapCmd_ [ CmdVfoLimits ] = Cmd_VfoLimits ;
mapCmd_ [ CmdIfLimits ] = Cmd_IfLimits ;
mapCmd_ [ CmdModeList ] = Cmd_ModeList ;
mapCmd_ [ CmdMode ] = Cmd_Mode ;
mapCmd_ [ CmdReady ] = Cmd_Ready ;
mapCmd_ [ CmdStop ] = Cmd_Stop ;
mapCmd_ [ CmdStart ] = Cmd_Start ;
mapCmd_ [ CmdPreamp ] = Cmd_Preamp ;
mapCmd_ [ CmdDds ] = Cmd_Dds ;
mapCmd_ [ CmdIf ] = Cmd_If ;
mapCmd_ [ CmdTrx ] = Cmd_Trx ;
mapCmd_ [ CmdRxEnable ] = Cmd_RxEnable ;
mapCmd_ [ CmdTxEnable ] = Cmd_TxEnable ;
2021-06-14 15:40:14 +03:00
mapCmd_ [ CmdRxChannelEnable ] = Cmd_RxChannelEnable ;
2021-02-22 17:35:24 +02:00
mapCmd_ [ CmdRitEnable ] = Cmd_RitEnable ;
mapCmd_ [ CmdRitOffset ] = Cmd_RitOffset ;
mapCmd_ [ CmdXitEnable ] = Cmd_XitEnable ;
mapCmd_ [ CmdXitOffset ] = Cmd_XitOffset ;
mapCmd_ [ CmdSplitEnable ] = Cmd_SplitEnable ;
mapCmd_ [ CmdIqSR ] = Cmd_IqSR ;
mapCmd_ [ CmdIqStart ] = Cmd_IqStart ;
mapCmd_ [ CmdIqStop ] = Cmd_IqStop ;
mapCmd_ [ CmdCWSpeed ] = Cmd_CWSpeed ;
mapCmd_ [ CmdCWDelay ] = Cmd_CWDelay ;
mapCmd_ [ CmdFilterBand ] = Cmd_FilterBand ;
mapCmd_ [ CmdVFO ] = Cmd_VFO ;
mapCmd_ [ CmdVersion ] = Cmd_Version ;
mapCmd_ [ CmdTune ] = Cmd_Tune ;
mapCmd_ [ CmdRxMute ] = Cmd_RxMute ;
mapCmd_ [ CmdSmeter ] = Cmd_Smeter ;
mapCmd_ [ CmdPower ] = Cmd_Power ;
mapCmd_ [ CmdSWR ] = Cmd_SWR ;
mapCmd_ [ CmdECoderRX ] = Cmd_ECoderRX ;
mapCmd_ [ CmdECoderVFO ] = Cmd_ECoderVFO ;
mapCmd_ [ CmdAudioSR ] = Cmd_AudioSR ;
mapCmd_ [ CmdAudioStart ] = Cmd_AudioStart ;
mapCmd_ [ CmdAudioStop ] = Cmd_AudioStop ;
mapCmd_ [ CmdAppFocus ] = Cmd_AppFocus ;
mapCmd_ [ CmdVolume ] = Cmd_Volume ;
mapCmd_ [ CmdSqlEnable ] = Cmd_SqlEnable ;
mapCmd_ [ CmdSqlLevel ] = Cmd_SqlLevel ;
mapCmd_ [ CmdDrive ] = Cmd_Drive ;
mapCmd_ [ CmdTuneDrive ] = Cmd_TuneDrive ;
mapCmd_ [ CmdMute ] = Cmd_Mute ;
2021-06-14 15:40:14 +03:00
mapCmd_ [ CmdRxSensorsEnable ] = Cmd_RxSensorsEnable ;
mapCmd_ [ CmdTxSensorsEnable ] = Cmd_TxSensorsEnable ;
mapCmd_ [ CmdRxSensors ] = Cmd_RxSensors ;
mapCmd_ [ CmdTxSensors ] = Cmd_TxSensors ;
mapCmd_ [ CmdAgcMode ] = Cmd_AgcMode ;
mapCmd_ [ CmdAgcGain ] = Cmd_AgcGain ;
mapCmd_ [ CmdLock ] = Cmd_Lock ;
2021-02-22 17:35:24 +02:00
}
void TCITransceiver : : onConnected ( )
{
inConnected = true ;
// printf("%s(%0.1f) TCI connected\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI connected \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
}
void TCITransceiver : : onDisconnected ( )
{
inConnected = false ;
// printf("%s(%0.1f) TCI disconnected\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI disconnected \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
}
void TCITransceiver : : onError ( QAbstractSocket : : SocketError err )
{
//qDebug() << "WebInThread::onError";
// printf("%s(%0.1f) TCI error:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),err);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI error:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , err ) ;
fclose ( pFile ) ;
# endif
2021-03-01 10:47:46 +02:00
error_ = tr ( " TCI websocket error: %1 " ) . arg ( errortable . at ( err ) ) ;
2021-02-22 17:35:24 +02:00
}
int TCITransceiver : : do_start ( JTDXDateTime * jtdxtime )
{
2022-02-08 20:25:43 +02:00
if ( tci_audio_ ) QThread : : currentThread ( ) - > setPriority ( QThread : : HighPriority ) ;
2021-02-22 17:35:24 +02:00
// printf("do_start tci_Ready:%d\n",tci_Ready);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " do_start tci_Ready:%d \n " , tci_Ready ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
TRACE_CAT ( " TCITransceiver " , " starting " ) ;
m_jtdxtime = jtdxtime ;
if ( wrapped_ ) wrapped_ - > start ( 0 , m_jtdxtime ) ;
url_ . setUrl ( " ws:// " + server_ ) ; //server_
if ( url_ . host ( ) = = " " ) url_ . setHost ( " localhost " ) ;
if ( url_ . port ( ) = = - 1 ) url_ . setPort ( 40001 ) ;
if ( ! commander_ )
{
commander_ = new QWebSocket { } ; // QObject takes ownership
2021-03-12 17:43:55 +02:00
// printf ("commander created");
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " commander created " ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
connect ( commander_ , SIGNAL ( connected ( ) ) , this , SLOT ( onConnected ( ) ) ) ;
connect ( commander_ , SIGNAL ( disconnected ( ) ) , this , SLOT ( onDisconnected ( ) ) ) ;
connect ( commander_ , SIGNAL ( binaryMessageReceived ( QByteArray ) ) , this , SLOT ( onBinaryReceived ( QByteArray ) ) ) ;
connect ( commander_ , SIGNAL ( textMessageReceived ( QString ) ) , this , SLOT ( onMessageReceived ( QString ) ) ) ;
connect ( commander_ , SIGNAL ( error ( QAbstractSocket : : SocketError ) ) , this , SLOT ( onError ( QAbstractSocket : : SocketError ) ) ) ;
}
if ( ! tci_loop1_ ) {
tci_loop1_ = new QEventLoop { this } ;
}
if ( ! tci_timer1_ ) {
tci_timer1_ = new QTimer { this } ;
tci_timer1_ - > setSingleShot ( true ) ;
connect ( tci_timer1_ , & QTimer : : timeout , tci_loop1_ , & QEventLoop : : quit ) ;
connect ( this , & TCITransceiver : : tci_done1 , tci_loop1_ , & QEventLoop : : quit ) ;
}
if ( ! tci_loop2_ ) {
tci_loop2_ = new QEventLoop { this } ;
}
if ( ! tci_timer2_ ) {
tci_timer2_ = new QTimer { this } ;
tci_timer2_ - > setSingleShot ( true ) ;
connect ( tci_timer2_ , & QTimer : : timeout , tci_loop2_ , & QEventLoop : : quit ) ;
connect ( this , & TCITransceiver : : tci_done2 , tci_loop2_ , & QEventLoop : : quit ) ;
}
if ( ! tci_loop3_ ) {
tci_loop3_ = new QEventLoop { this } ;
}
if ( ! tci_timer3_ ) {
tci_timer3_ = new QTimer { this } ;
tci_timer3_ - > setSingleShot ( true ) ;
connect ( tci_timer3_ , & QTimer : : timeout , tci_loop3_ , & QEventLoop : : quit ) ;
connect ( this , & TCITransceiver : : tci_done3 , tci_loop3_ , & QEventLoop : : quit ) ;
}
2021-11-12 21:02:34 +02:00
tx_fifo = 0 ; tx_top_ = true ;
2021-02-22 17:35:24 +02:00
tci_Ready = false ;
2021-06-14 15:40:14 +03:00
ESDR3 = false ;
band_change = false ;
2021-02-22 17:35:24 +02:00
trxA = 0 ;
trxB = 0 ;
busy_rx_frequency_ = false ;
2021-06-14 15:40:14 +03:00
busy_mode_ = false ;
2021-02-22 17:35:24 +02:00
busy_other_frequency_ = false ;
2021-06-14 15:40:14 +03:00
busy_split_ = false ;
2021-02-22 17:35:24 +02:00
busy_drive_ = false ;
busy_PTT_ = false ;
2021-06-14 15:40:14 +03:00
busy_rx2_ = false ;
2021-11-04 13:42:48 +02:00
rx2_ = false ;
2022-01-28 14:50:03 +02:00
requested_rx2_ = false ;
started_rx2_ = false ;
2021-02-22 17:35:24 +02:00
split_ = false ;
requested_split_ = false ;
2022-01-28 14:50:03 +02:00
started_split_ = false ;
2021-02-22 17:35:24 +02:00
PTT_ = false ;
requested_PTT_ = false ;
mode_ = " " ;
2022-01-28 14:50:03 +02:00
requested_mode_ = " " ;
started_mode_ = " " ;
2021-02-22 17:35:24 +02:00
requested_rx_frequency_ = " " ;
rx_frequency_ = " " ;
requested_other_frequency_ = " " ;
other_frequency_ = " " ;
2022-01-28 14:50:03 +02:00
requested_drive_ = " " ;
drive_ = " " ;
2021-03-04 10:21:10 +02:00
level_ = - 54 ;
2021-02-22 17:35:24 +02:00
power_ = 0 ;
2021-11-17 19:59:24 +02:00
swr_ = 0 ;
2021-02-22 17:35:24 +02:00
m_bufferPos = 0 ;
m_downSampleFactor = 4 ;
m_ns = 999 ;
audio_ = false ;
requested_stream_audio_ = false ;
stream_audio_ = false ;
_power_ = false ;
2021-03-16 10:27:24 +02:00
// printf ("%s(%0.1f) TCI open %s rig_power:%d rig_power_off:%d tci_audio:%d do_snr:%d do_pwr:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),url_.toString().toStdString().c_str(),rig_power_,rig_power_off_,tci_audio_,do_snr_,do_pwr_);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
2021-03-16 10:27:24 +02:00
fprintf ( pFile , " %s(%0.1f) TCI open %s rig_power:%d rig_power_off:%d tci_audio:%d do_snr:%d do_pwr:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , url_ . toString ( ) . toStdString ( ) . c_str ( ) , rig_power_ , rig_power_off_ , tci_audio_ , do_snr_ , do_pwr_ ) ;
2021-03-13 14:31:44 +02:00
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
commander_ - > open ( url_ ) ;
mysleep1 ( 1500 ) ;
2021-06-14 15:40:14 +03:00
if ( ESDR3 ) mysleep1 ( 500 ) ; else mysleep1 ( 100 ) ;
// mysleep1 (100);
2021-12-12 12:28:54 +02:00
if ( error_ . isEmpty ( ) ) {
tci_Ready = true ;
2021-02-22 17:35:24 +02:00
if ( ! _power_ ) {
if ( rig_power_ ) {
rig_power ( true ) ;
2021-06-14 15:40:14 +03:00
mysleep1 ( 1000 ) ;
2021-02-22 17:35:24 +02:00
if ( ! _power_ ) throw error { tr ( " TCI SDR could not be switched on " ) } ;
2021-03-30 10:06:12 +03:00
} else {
tci_Ready = false ;
throw error { tr ( " TCI SDR is not switched on " ) } ;
}
2021-02-22 17:35:24 +02:00
}
2021-06-14 15:40:14 +03:00
if ( rx_ = = " 1 " & & ! rx2_ ) {
rx2_enable ( true ) ;
if ( ! rx2_ ) {
tci_Ready = false ;
throw error { tr ( " TCI RX2 could not be enabled " ) } ;
}
}
2021-03-16 10:27:24 +02:00
if ( tci_audio_ ) {
2021-02-22 17:35:24 +02:00
stream_audio ( true ) ;
mysleep1 ( 500 ) ;
2021-03-30 10:06:12 +03:00
if ( ! stream_audio_ ) {
tci_Ready = false ;
throw error { tr ( " TCI Audio could not be switched on " ) } ;
}
2021-02-22 17:35:24 +02:00
}
2021-06-14 15:40:14 +03:00
if ( ESDR3 ) {
2021-06-25 09:46:34 +03:00
const QString cmd = CmdRxSensorsEnable + SmDP + ( do_snr_ ? " true " : " false " ) + SmCM + " 500 " + SmTZ ;
2021-06-14 15:40:14 +03:00
sendTextMessage ( cmd ) ;
} else if ( do_snr_ ) {
const QString cmd = CmdSmeter + SmDP + rx_ + SmCM + " 0 " + SmTZ ;
sendTextMessage ( cmd ) ;
2021-04-11 09:04:17 +03:00
}
2021-03-21 10:18:01 +02:00
if ( ! requested_rx_frequency_ . isEmpty ( ) ) do_frequency ( string_to_frequency ( requested_rx_frequency_ ) , get_mode ( true ) , false ) ;
if ( ! requested_other_frequency_ . isEmpty ( ) ) do_tx_frequency ( string_to_frequency ( requested_other_frequency_ ) , get_mode ( true ) , false ) ;
2022-02-03 12:24:25 +02:00
else if ( requested_split_ ! = split_ ) { /*printf("splt from start %d\n",requested_split_);*/ rig_split ( ) ; } // split_ = requested_split_; mysleep2(100);}
2022-01-28 14:50:03 +02:00
if ( ! requested_drive_ . isEmpty ( ) & & requested_drive_ ! = drive_ ) {
busy_drive_ = true ;
if ( ESDR3 ) {
const QString cmd = CmdDrive + SmDP + rx_ + SmCM + requested_drive_ + SmTZ ;
sendTextMessage ( cmd ) ;
} else {
const QString cmd = CmdDrive + SmDP + requested_drive_ + SmTZ ;
sendTextMessage ( cmd ) ;
}
}
2021-02-22 17:35:24 +02:00
do_poll ( ) ;
2021-06-14 15:40:14 +03:00
if ( ESDR3 ) {
2021-06-25 09:46:34 +03:00
const QString cmd = CmdTxSensorsEnable + SmDP + ( do_pwr_ ? " true " : " false " ) + SmCM + " 500 " + SmTZ ;
2021-06-14 15:40:14 +03:00
sendTextMessage ( cmd ) ;
}
2021-04-01 16:41:27 +03:00
if ( stream_audio_ ) do_audio ( true ) ;
2021-02-22 17:35:24 +02:00
TRACE_CAT ( " TCITransceiver " , " started " ) ;
// printf("%s(%0.1f) TCI Transceiver started\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI Transceiver started \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
return 0 ;
2021-03-01 10:47:46 +02:00
} else {
// printf("%s(%0.1f) TCI Transceiver not started %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),error_.toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI Transceiver not started %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , error_ . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-03-01 10:47:46 +02:00
if ( error_ . isEmpty ( ) )
throw error { tr ( " TCI could not be opened " ) } ;
else
throw error { error_ } ;
}
2021-02-22 17:35:24 +02:00
}
void TCITransceiver : : do_stop ( )
{
// printf ("TCI close\n");
2022-01-16 17:30:56 +02:00
if ( ! commander_ ) return ;
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " TCI close \n " ) ;
# endif
2021-03-29 22:44:25 +03:00
if ( stream_audio_ & & tci_Ready & & inConnected & & _power_ ) {
2021-03-13 14:31:44 +02:00
stream_audio ( false ) ;
mysleep1 ( 500 ) ;
// printf ("TCI audio closed\n");
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " TCI audio closed \n " ) ;
# endif
2021-03-10 11:52:12 +02:00
}
2021-03-29 22:44:25 +03:00
if ( tci_Ready & & inConnected & & _power_ ) {
2021-03-21 10:18:01 +02:00
requested_other_frequency_ = " " ;
2022-01-28 14:50:03 +02:00
if ( started_split_ ! = split_ ) { requested_split_ = started_split_ ; rig_split ( ) ; }
if ( started_mode_ ! = mode_ ) sendTextMessage ( mode_to_command ( started_mode_ ) ) ;
if ( ! started_rx2_ & & rx2_ ) {
rx2_enable ( false ) ;
}
2021-03-21 10:18:01 +02:00
}
2021-03-29 22:44:25 +03:00
if ( _power_ & & rig_power_off_ & & tci_Ready & & inConnected & & _power_ ) {
2021-03-13 14:31:44 +02:00
rig_power ( false ) ;
mysleep1 ( 500 ) ;
// printf ("TCI power down\n");
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " TCI power down \n " ) ;
# endif
2021-03-10 11:52:12 +02:00
}
2021-02-22 17:35:24 +02:00
tci_Ready = false ;
if ( commander_ )
{
2021-03-10 11:52:12 +02:00
if ( inConnected ) commander_ - > close ( QWebSocketProtocol : : CloseCodeNormal , " end " ) ;
2021-02-22 17:35:24 +02:00
delete commander_ , commander_ = nullptr ;
2021-03-13 14:31:44 +02:00
// printf ("commander ");
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " commander " ) ;
# endif
2021-02-22 17:35:24 +02:00
}
if ( tci_timer1_ )
{
if ( tci_timer1_ - > isActive ( ) ) tci_timer1_ - > stop ( ) ;
delete tci_timer1_ , tci_timer1_ = nullptr ;
2021-03-13 14:31:44 +02:00
// printf ("timer1 ");
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " timer1 " ) ;
# endif
2021-02-22 17:35:24 +02:00
}
if ( tci_loop1_ )
{
tci_loop1_ - > quit ( ) ;
delete tci_loop1_ , tci_loop1_ = nullptr ;
2021-03-13 14:31:44 +02:00
// printf ("loop1 ");
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " loop1 " ) ;
# endif
2021-02-22 17:35:24 +02:00
}
if ( tci_timer2_ )
{
if ( tci_timer2_ - > isActive ( ) ) tci_timer2_ - > stop ( ) ;
delete tci_timer2_ , tci_timer2_ = nullptr ;
2021-03-13 14:31:44 +02:00
// printf ("timer2 ");
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " timer2 " ) ;
# endif
2021-02-22 17:35:24 +02:00
}
if ( tci_loop2_ )
{
tci_loop2_ - > quit ( ) ;
delete tci_loop2_ , tci_loop2_ = nullptr ;
2021-03-13 14:31:44 +02:00
// printf ("loop2 ");
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " loop2 " ) ;
# endif
2021-02-22 17:35:24 +02:00
}
if ( tci_timer3_ )
{
if ( tci_timer3_ - > isActive ( ) ) tci_timer3_ - > stop ( ) ;
delete tci_timer3_ , tci_timer3_ = nullptr ;
2021-03-13 14:31:44 +02:00
// printf ("timer3 ");
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " timer3 " ) ;
# endif
2021-02-22 17:35:24 +02:00
}
if ( tci_loop3_ )
{
tci_loop3_ - > quit ( ) ;
delete tci_loop3_ , tci_loop3_ = nullptr ;
2021-03-13 14:31:44 +02:00
// printf ("loop3 ");
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " loop3 " ) ;
# endif
2021-02-22 17:35:24 +02:00
}
if ( wrapped_ ) wrapped_ - > stop ( ) ;
TRACE_CAT ( " TCITransceiver " , " stopped " ) ;
2021-03-13 14:31:44 +02:00
// printf ("deleted\nTCI closed\n");
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " deleted \n TCI closed \n " ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
}
void TCITransceiver : : onMessageReceived ( const QString & str )
{
//qDebug() << "From WEB" << str;
QStringList cmd_list = str . split ( " ; " , SkipEmptyParts ) ;
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile ;
# endif
2021-02-22 17:35:24 +02:00
for ( QString cmds : cmd_list ) {
QStringList cmd = cmds . split ( " : " , SkipEmptyParts ) ;
QStringList args = cmd . last ( ) . split ( " , " , SkipEmptyParts ) ;
Tci_Cmd idCmd = mapCmd_ [ cmd . first ( ) ] ;
2021-06-14 15:40:14 +03:00
// if (idCmd != Cmd_Power && idCmd != Cmd_SWR && idCmd != Cmd_Smeter && idCmd != Cmd_AppFocus && idCmd != Cmd_RxSensors && idCmd != Cmd_TxSensors) { printf ("%s(%0.1f) TCI message received:|%s| ",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),str.toStdString().c_str()); printf("idCmd : %d args : %s\n",idCmd,args.join("|").toStdString().c_str());}
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
2021-06-14 15:40:14 +03:00
if ( idCmd ! = Cmd_Power & & idCmd ! = Cmd_SWR & & idCmd ! = Cmd_Smeter & & idCmd ! = Cmd_AppFocus & & idCmd ! = Cmd_RxSensors & & idCmd ! = Cmd_TxSensors ) {
2021-03-13 14:31:44 +02:00
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI message received:|%s| " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , str . toStdString ( ) . c_str ( ) ) ;
fprintf ( pFile , " idCmd : %d args : %s \n " , idCmd , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
}
# endif
2021-02-22 17:35:24 +02:00
//qDebug() << cmds << idCmd;
2021-03-13 14:31:44 +02:00
if ( idCmd < = 0 ) continue ;
2021-02-22 17:35:24 +02:00
switch ( idCmd ) {
case Cmd_Smeter :
2021-06-14 15:40:14 +03:00
if ( args . at ( 0 ) = = rx_ & & args . at ( 1 ) = = " 0 " ) level_ = args . at ( 2 ) . toInt ( ) + 73 ;
break ;
case Cmd_RxSensors :
if ( args . at ( 0 ) = = rx_ ) level_ = args . at ( 1 ) . split ( " . " ) [ 0 ] . toInt ( ) + 73 ;
2021-06-25 09:46:34 +03:00
// printf("Smeter=%d\n",level_);
2021-06-14 15:40:14 +03:00
break ;
case Cmd_TxSensors :
if ( args . at ( 0 ) = = rx_ ) {
power_ = 10 * args . at ( 3 ) . split ( " . " ) [ 0 ] . toInt ( ) + args . at ( 3 ) . split ( " . " ) [ 1 ] . toInt ( ) ;
swr_ = 10 * args . at ( 4 ) . split ( " . " ) [ 0 ] . toInt ( ) + args . at ( 4 ) . split ( " . " ) [ 1 ] . toInt ( ) ;
2021-06-25 09:46:34 +03:00
// printf("Power=%d SWR=%d\n",power_,swr_);
2021-06-14 15:40:14 +03:00
}
2021-02-22 17:35:24 +02:00
break ;
case Cmd_SWR :
// printf("%s(%0.1f) Cmd_SWR : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
swr_ = 10 * args . at ( 0 ) . split ( " . " ) [ 0 ] . toInt ( ) + args . at ( 0 ) . split ( " . " ) [ 1 ] . toInt ( ) ;
break ;
case Cmd_Power :
power_ = 10 * args . at ( 0 ) . split ( " . " ) [ 0 ] . toInt ( ) + args . at ( 0 ) . split ( " . " ) [ 1 ] . toInt ( ) ;
// printf("%s(%0.1f) Cmd_Power : %s %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str(),power_);
break ;
case Cmd_VFO :
// printf("%s(%0.1f) Cmd_VFO : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) Cmd_VFO : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
if ( args . at ( 0 ) = = rx_ & & args . at ( 1 ) = = " 0 " ) {
2021-02-22 17:35:24 +02:00
rx_frequency_ = args . at ( 2 ) ;
2021-03-21 10:18:01 +02:00
if ( requested_rx_frequency_ . isEmpty ( ) ) { requested_rx_frequency_ = rx_frequency_ ; }
2021-06-14 15:40:14 +03:00
if ( busy_rx_frequency_ ) { /*printf ("cmdvfo0 done1\n");*/ tci_done1 ( ) ; }
2022-02-08 20:25:43 +02:00
else if ( ! tci_timer2_ - > isActive ( ) & & split_ ) tci_timer2_ - > start ( 300 ) ;
2021-02-22 17:35:24 +02:00
}
2021-06-14 15:40:14 +03:00
else if ( args . at ( 0 ) = = rx_ & & args . at ( 1 ) = = " 1 " ) {
2021-02-22 17:35:24 +02:00
other_frequency_ = args . at ( 2 ) ;
2021-03-21 10:18:01 +02:00
// if (requested_other_frequency_.isEmpty()) requested_other_frequency_ = other_frequency_;
2021-06-14 15:40:14 +03:00
if ( band_change ) tci_done1 ( ) ;
else if ( busy_other_frequency_ ) tci_done2 ( ) ;
2022-02-08 20:25:43 +02:00
else if ( other_frequency_ ! = requested_other_frequency_ & & tci_Ready & & split_ & & ! tci_timer2_ - > isActive ( ) ) tci_timer2_ - > start ( 300 ) ;
2021-02-22 17:35:24 +02:00
}
break ;
case Cmd_Mode :
// printf("%s(%0.1f) Cmd_Mode : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) Cmd_Mode : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
if ( args . at ( 0 ) = = rx_ ) {
if ( ESDR3 ) {
if ( args . at ( 1 ) = = " 0 " ) mode_ = args . at ( 2 ) . toLower ( ) ; else mode_ = args . at ( 1 ) . toLower ( ) ;
} else mode_ = args . at ( 1 ) ;
2022-01-28 14:50:03 +02:00
if ( started_mode_ . isEmpty ( ) ) { requested_mode_ = mode_ ; started_mode_ = mode_ ; }
2021-06-14 15:40:14 +03:00
if ( busy_mode_ ) tci_done1 ( ) ;
else if ( requested_mode_ ! = mode_ & & ! band_change ) {
2021-02-22 17:35:24 +02:00
sendTextMessage ( mode_to_command ( requested_mode_ ) ) ;
}
}
break ;
case Cmd_SplitEnable :
// printf("%s(%0.1f) Cmd_SplitEnable : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) Cmd_SplitEnable : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
if ( args . at ( 0 ) = = rx_ ) {
2021-02-22 17:35:24 +02:00
if ( args . at ( 1 ) = = " false " ) split_ = false ;
else if ( args . at ( 1 ) = = " true " ) split_ = true ;
2022-02-03 12:24:25 +02:00
if ( ! tci_Ready ) { started_split_ = split_ ; }
2022-01-28 14:50:03 +02:00
else if ( busy_split_ ) tci_done2 ( ) ;
2022-01-16 17:30:56 +02:00
else if ( requested_split_ ! = split_ & & ! tci_timer2_ - > isActive ( ) ) {
tci_timer2_ - > start ( 200 ) ;
rig_split ( ) ;
}
2021-02-22 17:35:24 +02:00
}
break ;
case Cmd_Drive :
// printf("%s(%0.1f) Cmd_Drive : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) Cmd_Drive : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
if ( ! ESDR3 | | args . at ( 0 ) = = rx_ ) {
2022-01-28 14:50:03 +02:00
if ( ESDR3 ) drive_ = args . at ( 1 ) ; else drive_ = args . at ( 0 ) ;
if ( requested_drive_ . isEmpty ( ) ) requested_drive_ = drive_ ;
2021-06-14 15:40:14 +03:00
busy_drive_ = false ;
}
2021-02-22 17:35:24 +02:00
break ;
case Cmd_Trx :
// printf("%s(%0.1f) Cmd_Trx : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) Cmd_Trx : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
if ( args . at ( 0 ) = = rx_ ) {
2021-02-22 17:35:24 +02:00
if ( args . at ( 1 ) = = " false " ) PTT_ = false ;
else if ( args . at ( 1 ) = = " true " ) PTT_ = true ;
if ( tci_Ready & & requested_PTT_ = = PTT_ ) tci_done3 ( ) ;
2021-11-04 13:42:48 +02:00
else if ( tci_Ready & & ! PTT_ ) {
requested_PTT_ = PTT_ ;
update_PTT ( PTT_ ) ;
power_ = 0 ; if ( do_pwr_ ) update_power ( 0 ) ;
2021-11-17 19:59:24 +02:00
swr_ = 0 ; if ( do_pwr_ ) update_swr ( 0 ) ;
2021-11-04 13:42:48 +02:00
}
2021-02-22 17:35:24 +02:00
}
break ;
case Cmd_AudioStart :
// printf("%s(%0.1f) Cmd_AudioStart : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) Cmd_AudioStart : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
if ( args . at ( 0 ) = = rx_ ) {
2021-02-22 17:35:24 +02:00
stream_audio_ = true ;
2021-03-21 10:18:01 +02:00
// printf ("cmdaudiostart done1\n");
2021-02-22 17:35:24 +02:00
tci_done1 ( ) ;
}
break ;
2021-06-14 15:40:14 +03:00
case Cmd_RxEnable :
// printf("%s(%0.1f) Cmd_RxEnable : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) Cmd_RxEnable : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
if ( args . at ( 0 ) = = " 1 " ) {
if ( args . at ( 1 ) = = " false " ) rx2_ = false ;
else if ( args . at ( 1 ) = = " true " ) rx2_ = true ;
if ( ! tci_Ready ) { requested_rx2_ = rx2_ ; started_rx2_ = rx2_ ; }
else if ( tci_Ready & & busy_rx2_ & & requested_rx2_ = = rx2_ ) tci_done1 ( ) ;
}
break ;
2021-02-22 17:35:24 +02:00
case Cmd_AudioStop :
// printf("%s(%0.1f) CmdAudioStop : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) CmdAudioStop : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
if ( args . at ( 0 ) = = rx_ ) {
2021-02-22 17:35:24 +02:00
stream_audio_ = false ;
2021-03-21 10:18:01 +02:00
// printf ("cmdaudiostop done1\n");
2021-02-22 17:35:24 +02:00
tci_done1 ( ) ;
}
break ;
case Cmd_Start :
// printf("%s(%0.1f) CmdStart : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) CmdStart : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
_power_ = true ;
2021-03-21 10:18:01 +02:00
// printf ("cmdstart done1\n");
2021-06-14 15:40:14 +03:00
if ( tci_Ready ) tci_done1 ( ) ;
2021-02-22 17:35:24 +02:00
break ;
case Cmd_Stop :
// printf("%s(%0.1f) CmdStop : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) CmdStop : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-11-04 13:42:48 +02:00
if ( tci_Ready & & PTT_ ) {
PTT_ = false ;
requested_PTT_ = PTT_ ;
update_PTT ( PTT_ ) ;
power_ = 0 ; if ( do_pwr_ ) update_power ( 0 ) ;
2021-11-17 19:59:24 +02:00
swr_ = 0 ; if ( do_pwr_ ) update_swr ( 0 ) ;
2021-11-04 13:42:48 +02:00
m_state = Idle ;
Q_EMIT tci_mod_active ( m_state ! = Idle ) ;
}
2021-02-22 17:35:24 +02:00
_power_ = false ;
2021-03-21 10:18:01 +02:00
if ( tci_timer1_ - > isActive ( ) ) { /*printf ("cmdstop done1\n");*/ tci_done1 ( ) ; }
2021-02-28 12:10:31 +02:00
else {
tci_Ready = false ;
}
2021-02-22 17:35:24 +02:00
break ;
2021-06-14 15:40:14 +03:00
case Cmd_Version :
// printf("%s(%0.1f) CmdVersion : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) CmdVersion : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
if ( args . at ( 0 ) = = " ExpertSDR3 " ) ESDR3 = true ;
break ;
case Cmd_Device :
// printf("%s(%0.1f) CmdDevice : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) CmdVersion : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
if ( ( args . at ( 0 ) = = " SunSDR2DX " | | args . at ( 0 ) = = " SunSDR2PRO " ) & & ! ESDR3 ) tx_top_ = false ;
// printf ("tx_top_:%d\n",tx_top_);
break ;
2021-03-29 22:44:25 +03:00
case Cmd_Ready :
// printf("%s(%0.1f) CmdReady : %s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),args.join("|").toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
2021-03-29 22:44:25 +03:00
fprintf ( pFile , " %s(%0.1f) CmdReady : %s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , args . join ( " | " ) . toStdString ( ) . c_str ( ) ) ;
2021-03-13 14:31:44 +02:00
fclose ( pFile ) ;
# endif
2021-03-29 22:44:25 +03:00
tci_done1 ( ) ;
2021-02-22 17:35:24 +02:00
break ;
default :
break ;
}
}
}
void TCITransceiver : : sendTextMessage ( const QString & message )
{
2021-03-09 10:55:21 +02:00
if ( inConnected ) commander_ - > sendTextMessage ( message ) ;
2021-02-22 17:35:24 +02:00
}
void TCITransceiver : : onBinaryReceived ( const QByteArray & data )
{
/* if (++cntIQ % 50 == 0){
bIQ = ! bIQ ;
nIqBytes + = data . size ( ) ;
printf ( " receiveIQ \n " ) ;
emit receiveIQ ( bIQ , nIqBytes ) ;
nIqBytes = 0 ;
} else {
nIqBytes + = data . size ( ) ;
} */
Data_Stream * pStream = ( Data_Stream * ) ( data . data ( ) ) ;
if ( pStream - > type ! = last_type ) {
// printf ("%s(%0.1f) binary resceived type=%d last_type=%d %d samplerate %d stream_size %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),pStream->type,last_type,data.size(),pStream->sampleRate,pStream->length);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) binary resceived type=%d last_type=%d %d samplerate %d stream_size %d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , pStream - > type , last_type , data . size ( ) , pStream - > sampleRate , pStream - > length ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
last_type = pStream - > type ;
2021-03-08 09:36:55 +02:00
# if JTDX_DEBUG_TO_FILE
if ( last_type = = TxChrono ) { // audio transmit starts
struct {
char ariff [ 4 ] ; //ChunkID: "RIFF"
int nchunk ; //ChunkSize: 36+SubChunk2Size
char awave [ 4 ] ; //Format: "WAVE"
char afmt [ 4 ] ; //Subchunk1ID: "fmt "
int lenfmt ; //Subchunk1Size: 16
short int nfmt2 ; //AudioFormat: 1
short int nchan2 ; //NumChannels: 1
int nsamrate ; //SampleRate: 12000
int nbytesec ; //ByteRate: SampleRate*NumChannels*BitsPerSample/8
short int nbytesam2 ; //BlockAlign: NumChannels*BitsPerSample/8
short int nbitsam2 ; //BitsPerSample: 16
char adata [ 4 ] ; //Subchunk2ID: "data"
int ndata ; //Subchunk2Size: numSamples*NumChannels*BitsPerSample/8
} hdr ;
int npts = static_cast < int > ( m_period ) * 48000 ;
wavptr_ = fopen ( wav_file_ . c_str ( ) , " wb " ) ;
if ( wavptr_ ! = NULL ) {
// Write a WAV header
hdr . ariff [ 0 ] = ' R ' ;
hdr . ariff [ 1 ] = ' I ' ;
hdr . ariff [ 2 ] = ' F ' ;
hdr . ariff [ 3 ] = ' F ' ;
hdr . nchunk = 36 + 2 * npts ;
hdr . awave [ 0 ] = ' W ' ;
hdr . awave [ 1 ] = ' A ' ;
hdr . awave [ 2 ] = ' V ' ;
hdr . awave [ 3 ] = ' E ' ;
hdr . afmt [ 0 ] = ' f ' ;
hdr . afmt [ 1 ] = ' m ' ;
hdr . afmt [ 2 ] = ' t ' ;
hdr . afmt [ 3 ] = ' ' ;
hdr . lenfmt = 16 ;
hdr . nfmt2 = 1 ;
hdr . nchan2 = 1 ;
hdr . nsamrate = 48000 ;
hdr . nbytesec = 2 * 48000 ;
hdr . nbytesam2 = 2 ;
hdr . nbitsam2 = 16 ;
hdr . adata [ 0 ] = ' d ' ;
hdr . adata [ 1 ] = ' a ' ;
hdr . adata [ 2 ] = ' t ' ;
hdr . adata [ 3 ] = ' a ' ;
hdr . ndata = 2 * npts ;
fwrite ( & hdr , sizeof ( hdr ) , 1 , wavptr_ ) ;
}
}
else if ( last_type = = RxAudioStream ) { // audio switched back to resceive
if ( wavptr_ ! = NULL ) {
fclose ( wavptr_ ) ;
wavptr_ = nullptr ;
}
}
# endif
2021-02-22 17:35:24 +02:00
}
if ( pStream - > type = = Iq_Stream ) {
bool tx = false ;
if ( pStream - > receiver = = 0 ) {
tx = trxA = = 0 ;
trxA = 1 ;
}
if ( pStream - > receiver = = 1 ) {
tx = trxB = = 0 ;
trxB = 1 ;
}
// printf("sendIqData\n");
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " sendIqData \n " ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
emit sendIqData ( pStream - > receiver , pStream - > length , pStream - > data , tx ) ;
qDebug ( ) < < " IQ " < < data . size ( ) < < pStream - > length ;
2021-06-14 15:40:14 +03:00
} else if ( pStream - > type = = RxAudioStream & & audio_ & & pStream - > receiver = = rx_ . toUInt ( ) ) {
2021-02-22 17:35:24 +02:00
// printf("%s(%0.1f) writeAudioData\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset());
writeAudioData ( pStream - > data , pStream - > length ) ;
qDebug ( ) < < " Audio " < < data . size ( ) < < pStream - > length ;
2021-06-14 15:40:14 +03:00
} else if ( pStream - > type = = TxChrono & & pStream - > receiver = = rx_ . toUInt ( ) ) {
2021-11-13 10:04:42 +02:00
mtx_ . lock ( ) ; tx_fifo + = 1 ; tx_fifo & = 7 ;
2021-02-22 17:35:24 +02:00
int ssize = AudioHeaderSize + pStream - > length * sizeof ( float ) * 2 ;
// printf("%s(%0.1f) TxChrono ",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset());
quint16 tehtud ;
2021-12-30 22:05:32 +02:00
if ( m_tx1 [ tx_fifo ] . size ( ) ! = ssize ) { m_tx1 [ tx_fifo ] . resize ( ssize ) ; /* m_tx1[tx_fifo].fill('\0x00');*/ }
2021-11-12 21:02:34 +02:00
Data_Stream * pOStream1 = ( Data_Stream * ) ( m_tx1 [ tx_fifo ] . data ( ) ) ;
2021-02-22 17:35:24 +02:00
pOStream1 - > receiver = pStream - > receiver ;
pOStream1 - > sampleRate = pStream - > sampleRate ;
pOStream1 - > format = pStream - > format ;
pOStream1 - > codec = 0 ;
pOStream1 - > crc = 0 ;
pOStream1 - > length = pStream - > length ;
pOStream1 - > type = TxAudioStream ;
2021-11-12 21:02:34 +02:00
// for (size_t i = 0; i < pStream->length; i++) pOStream1->data[i] = 0;
2021-02-22 17:35:24 +02:00
// printf("%s(%0.1f) txAudioChrono %d %d %d",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),ssize,pStream->length,pStream->sampleRate);
tehtud = readAudioData ( pOStream1 - > data , pOStream1 - > length ) ;
// printf(" %s(%0.1f) tehtud%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),tehtud);
if ( tehtud & & tehtud ! = pOStream1 - > length ) {
2021-12-25 20:15:08 +02:00
quint16 valmis = tehtud ;
2021-02-22 17:35:24 +02:00
// printf("%s(%0.1f) Audio build 1 mismatch requested %d done %d",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),pOStream1->length,tehtud);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) Audio build 1 mismatch requested %d done %d " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , pOStream1 - > length , tehtud ) ;
# endif
2021-02-22 17:35:24 +02:00
tehtud = readAudioData ( pOStream1 - > data + valmis , pOStream1 - > length - valmis ) ;
// printf("got %d\n",tehtud);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
fprintf ( pFile , " got %d \n " , tehtud ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
// if (tehtud && tehtud != pOStream1->length - valmis) {
// valmis += tehtud;
// for (size_t i = 0; i < pOStream1->length - valmis; i++) pOStream1->data[i+valmis] = 0;
// }
// else if (tehtud == 0) for (size_t i = 0; i < pOStream1->length - valmis; i++) pOStream1->data[i+valmis] = 0;
// }
// else if (tehtud == 0) {
// for (size_t i = 0; i < pStream->length; i++) pOStream1->data[i] = 0;
}
2021-03-08 09:36:55 +02:00
# if JTDX_DEBUG_TO_FILE
if ( wavptr_ ! = NULL ) {
static constexpr float K = 0x7FFF ;
for ( size_t i = 0 ; i < pOStream1 - > length ; i + = 2 ) {
qint16 value = static_cast < int16_t > ( K * pOStream1 - > data [ i ] ) ;
fwrite ( & value , 2 , 1 , wavptr_ ) ;
}
}
# endif
2021-12-25 20:15:08 +02:00
tx_fifo2 = tx_fifo ; mtx_ . unlock ( ) ;
if ( ! inConnected | | commander_ - > sendBinaryMessage ( m_tx1 [ tx_fifo2 ] ) ! = m_tx1 [ tx_fifo2 ] . size ( ) ) {
2021-03-13 14:31:44 +02:00
// printf("%s(%0.1f) Sent 1 loaded failed\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset());
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) Sent 1 loaded failed \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) ) ;
fclose ( pFile ) ;
# endif
}
2021-11-26 12:44:52 +02:00
} // else printf ("Unused binary message received type=%d receiver=%d\n",pStream->type,pStream->receiver);
2021-02-22 17:35:24 +02:00
}
void TCITransceiver : : txAudioData ( quint32 len , float * data )
{
QByteArray tx ;
// printf("%s(%0.1f) txAudioData %d %ld\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),len,(AudioHeaderSize+len*sizeof(float)*2));
tx . resize ( AudioHeaderSize + len * sizeof ( float ) * 2 ) ;
// printf("%s(%0.1f) txAudioData %d %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),len,tx.size());
2021-03-13 14:31:44 +02:00
// Data_Stream * pStream = reinterpret_cast<Data_Stream*>(tx.data());
2021-02-22 17:35:24 +02:00
Data_Stream * pStream = ( Data_Stream * ) ( tx . data ( ) ) ;
pStream - > receiver = 0 ;
pStream - > sampleRate = audioSampleRate ;
pStream - > format = 3 ;
pStream - > codec = 0 ;
pStream - > crc = 0 ;
pStream - > length = len ;
pStream - > type = TxAudioStream ;
memcpy ( pStream - > data , data , len * sizeof ( float ) * 2 ) ;
commander_ - > sendBinaryMessage ( tx ) ;
}
quint32 TCITransceiver : : writeAudioData ( float * data , qint32 maxSize )
{
static unsigned mstr0 = 999999 ;
qint64 ms0 = m_jtdxtime - > currentMSecsSinceEpoch2 ( ) % 86400000 ; //m_jtdxtime -> currentMSecsSinceEpoch2() % 86400000;
unsigned mstr = ms0 % int ( 1000.0 * m_period ) ; // ms into the nominal Tx start time
2022-01-04 09:22:35 +02:00
if ( mstr < mstr0 / 2 ) { //When mstr has wrapped around to 0, restart the buffer
2021-02-22 17:35:24 +02:00
dec_data . params . kin = 0 ;
m_bufferPos = 0 ;
// printf("%s(%0.1f) reset buffer mstr:%d mstr0:%d maxSize:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),mstr,mstr0,maxSize);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) reset buffer mstr:%d mstr0:%d maxSize:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , mstr , mstr0 , maxSize ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
}
mstr0 = mstr ;
// no torn frames
Q_ASSERT ( ! ( maxSize % static_cast < qint32 > ( bytesPerFrame ) ) ) ;
// these are in terms of input frames (not down sampled)
size_t framesAcceptable ( ( sizeof ( dec_data . d2 ) /
sizeof ( dec_data . d2 [ 0 ] ) - dec_data . params . kin ) * m_downSampleFactor ) ;
size_t framesAccepted ( qMin ( static_cast < size_t > ( maxSize /
bytesPerFrame ) , framesAcceptable ) ) ;
if ( framesAccepted < static_cast < size_t > ( maxSize / bytesPerFrame ) ) {
qDebug ( ) < < " dropped " < < maxSize / bytesPerFrame - framesAccepted
< < " frames of data on the floor! "
< < dec_data . params . kin < < mstr ;
2021-02-28 21:23:20 +02:00
// printf("%s(%0.1f) dropped %ld frames of data %d %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),maxSize / bytesPerFrame - framesAccepted,dec_data.params.kin,mstr);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) dropped %ld frames of data %d %d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , maxSize / bytesPerFrame - framesAccepted , dec_data . params . kin , mstr ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
}
for ( unsigned remaining = framesAccepted ; remaining ; ) {
size_t numFramesProcessed ( qMin ( m_samplesPerFFT *
m_downSampleFactor - m_bufferPos , remaining ) ) ;
if ( m_downSampleFactor > 1 ) {
// printf ("%s(%0.1f) writeAudioData maxs %d bytesPerFrame %ld Accepted %ld remaining %d Processed %ld Bufferpos %d kin %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),
// m_jtdxtime->GetOffset(),maxSize,bytesPerFrame,framesAccepted,remaining,numFramesProcessed,m_bufferPos,dec_data.params.kin);
store ( & data [ ( framesAccepted - remaining ) * bytesPerFrame ] ,
numFramesProcessed , & m_buffer [ m_bufferPos ] ) ;
m_bufferPos + = numFramesProcessed ;
if ( m_bufferPos = = m_samplesPerFFT * m_downSampleFactor ) {
qint32 framesToProcess ( m_samplesPerFFT * m_downSampleFactor ) ;
qint32 framesAfterDownSample ( m_samplesPerFFT ) ;
if ( m_downSampleFactor > 1 & & dec_data . params . kin > = 0 & &
dec_data . params . kin < ( NTMAX * 12000 - framesAfterDownSample ) ) {
fil4_ ( & m_buffer [ 0 ] , & framesToProcess , & dec_data . d2 [ dec_data . params . kin ] ,
& framesAfterDownSample , & dec_data . dd2 [ dec_data . params . kin ] ) ;
dec_data . params . kin + = framesAfterDownSample ;
} else {
// qDebug() << "framesToProcess = " << framesToProcess;
// qDebug() << "dec_data.params.kin = " << dec_data.params.kin;
// qDebug() << "secondInPeriod = " << secondInPeriod();
// qDebug() << "framesAfterDownSample" << framesAfterDownSample;
}
// printf("%s(%0.1f) frameswritten %d downSampleFactor %d samplesPerFFT %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),dec_data.params.kin,m_downSampleFactor,m_samplesPerFFT);
Q_EMIT tciframeswritten ( dec_data . params . kin ) ;
// printf("%s(%0.1f) frameswritten done\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset());
m_bufferPos = 0 ;
}
} else {
// printf ("%s(%0.1f) writeAudioData2 maxs %d bytesPerFrame %ld Accepted %ld remaining %d Processed %ld Bufferpos %d kin %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),maxSize,bytesPerFrame,framesAccepted,remaining,numFramesProcessed,m_bufferPos,dec_data.params.kin);
store ( & data [ ( framesAccepted - remaining ) * bytesPerFrame ] ,
numFramesProcessed , & dec_data . d2 [ dec_data . params . kin ] ) ;
m_bufferPos + = numFramesProcessed ;
dec_data . params . kin + = numFramesProcessed ;
if ( m_bufferPos = = static_cast < unsigned > ( m_samplesPerFFT ) ) {
// printf("%s(%0.1f) frameswritten2 %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),dec_data.params.kin);
Q_EMIT tciframeswritten ( dec_data . params . kin ) ;
// printf("%s(%0.1f) frameswritten2 done\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset());
m_bufferPos = 0 ;
}
}
remaining - = numFramesProcessed ;
}
return maxSize ; // we drop any data past the end of the buffer on
// the floor until the next period starts
}
2021-06-14 15:40:14 +03:00
void TCITransceiver : : rx2_enable ( bool on )
{
// printf ("%s(%0.1f) TCI rx2_enable:%d->%d busy:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),rx2_,on,busy_rx2_);
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI rx2_enable:%d->%d busy:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , rx2_ , on , busy_rx2_ ) ;
fclose ( pFile ) ;
# endif
if ( busy_rx2_ ) return ;
requested_rx2_ = on ;
busy_rx2_ = true ;
const QString cmd = CmdRxEnable + SmDP + " 1 " + SmCM + ( requested_rx2_ ? " true " : " false " ) + SmTZ ;
sendTextMessage ( cmd ) ;
mysleep1 ( 1000 ) ;
busy_rx2_ = false ;
}
2021-03-18 16:21:04 +02:00
void TCITransceiver : : rig_split ( )
{
2021-06-14 15:40:14 +03:00
// printf ("%s(%0.1f) TCI rig_split:%d->%d busy:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),split_,requested_split_,busy_split_);
2021-03-18 16:21:04 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
2021-06-14 15:40:14 +03:00
fprintf ( pFile , " %s(%0.1f) TCI rig_split:%d->%d busy:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , split_ , requested_split_ , busy_split_ ) ;
2021-03-18 16:21:04 +02:00
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
if ( busy_split_ ) return ;
2022-01-16 17:30:56 +02:00
if ( tci_timer2_ - > isActive ( ) ) mysleep2 ( 0 ) ;
2021-06-14 15:40:14 +03:00
busy_split_ = true ;
const QString cmd = CmdSplitEnable + SmDP + rx_ + SmCM + ( requested_split_ ? " true " : " false " ) + SmTZ ;
2021-03-18 16:21:04 +02:00
sendTextMessage ( cmd ) ;
2021-06-14 15:40:14 +03:00
mysleep2 ( 500 ) ;
busy_split_ = false ;
2022-01-16 17:30:56 +02:00
if ( requested_split_ = = split_ ) update_split ( split_ ) ;
else {
// printf ("%s(%0.1f) TCI failed set split:%d->%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),split_,requested_split_);
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI failed set split:%d->%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , split_ , requested_split_ ) ;
fclose ( pFile ) ;
# endif
error_ = tr ( " TCI failed set split " ) ;
}
2021-03-18 16:21:04 +02:00
}
2021-02-22 17:35:24 +02:00
void TCITransceiver : : rig_power ( bool on )
{
TRACE_CAT ( " TCITransceiver " , on < < state ( ) ) ;
// printf ("%s(%0.1f) TCI rig_power:%d _power_:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),on,_power_);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI rig_power:%d _power_:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , on , _power_ ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
if ( on ! = _power_ ) {
if ( on ) {
const QString cmd = CmdStart + SmTZ ;
sendTextMessage ( cmd ) ;
} else {
const QString cmd = CmdStop + SmTZ ;
sendTextMessage ( cmd ) ;
}
}
}
void TCITransceiver : : stream_audio ( bool on )
{
TRACE_CAT ( " TCITransceiver " , on < < state ( ) ) ;
2021-11-26 00:17:48 +02:00
// printf ("%s(%0.1f) TCI stream_audio:%d stream_audio_:%d requested_stream_audio_:%d rx_=%s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),on,stream_audio_,requested_stream_audio_,rx_.toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
2021-11-26 00:17:48 +02:00
fprintf ( pFile , " %s(%0.1f) TCI stream_audio:%d stream_audio_:%d requested_stream_audio_:%d rx_=%s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , on , stream_audio_ , requested_stream_audio_ , rx_ . toStdString ( ) . c_str ( ) ) ;
2021-03-13 14:31:44 +02:00
fclose ( pFile ) ;
# endif
2021-02-28 12:10:31 +02:00
if ( on ! = stream_audio_ & & tci_Ready ) {
2021-02-22 17:35:24 +02:00
requested_stream_audio_ = on ;
if ( on ) {
2021-06-14 15:40:14 +03:00
const QString cmd = CmdAudioStart + SmDP + rx_ + SmTZ ;
2021-02-22 17:35:24 +02:00
sendTextMessage ( cmd ) ;
} else {
2021-06-14 15:40:14 +03:00
const QString cmd = CmdAudioStop + SmDP + rx_ + SmTZ ;
2021-02-22 17:35:24 +02:00
sendTextMessage ( cmd ) ;
}
}
}
void TCITransceiver : : do_audio ( bool on )
{
TRACE_CAT ( " TCITransceiver " , on < < state ( ) ) ;
// printf ("%s(%0.1f) TCI do_audio:%d audio_:%d state:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),on,audio_,state().audio());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI do_audio:%d audio_:%d state:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , on , audio_ , state ( ) . audio ( ) ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
if ( on ) {
dec_data . params . kin = 0 ;
m_bufferPos = 0 ;
}
audio_ = on ;
}
void TCITransceiver : : do_period ( double period )
{
TRACE_CAT ( " TCITransceiver " , period < < state ( ) ) ;
// printf ("%s(%0.1f) TCI do_period:%0.1f m_period_:%0.1f state:%0.1f\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),period,m_period,state().period());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI do_period:%0.1f m_period_:%0.1f state:%0.1f \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , period , m_period , state ( ) . period ( ) ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
m_period = period ;
}
void TCITransceiver : : do_txvolume ( qreal volume )
{
2021-02-28 12:10:31 +02:00
TRACE_CAT ( " TCITransceiver " , volume < < state ( ) ) ;
2021-02-22 17:35:24 +02:00
QString drive = QString : : number ( round ( 100 - volume * 2.2222222 ) ) ;
2022-01-28 14:50:03 +02:00
// printf ("%s(%0.1f) TCI tci_Ready:%d do_txvolume:%0.1f state:%0.1f drive:%s drive_:%s drive_busy:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),tci_Ready,volume,state().volume(),drive.toStdString().c_str(),drive_.toStdString().c_str(),busy_drive_);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
2022-02-02 09:06:59 +02:00
fprintf ( pFile , " %s(%0.1f) TCI tci_Ready:%d do_txvolume:%0.1f state:%0.1f drive:%s drive_:%s drive_busy:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , tci_Ready , volume , state ( ) . volume ( ) , drive . toStdString ( ) . c_str ( ) , drive_ . toStdString ( ) . c_str ( ) , busy_drive_ ) ;
2021-03-13 14:31:44 +02:00
fclose ( pFile ) ;
# endif
2022-01-28 14:50:03 +02:00
requested_drive_ = drive ;
if ( busy_drive_ | | ! tci_Ready | | drive_ = = drive ) {
2021-11-04 13:42:48 +02:00
if ( busy_drive_ ) busy_drive_ = false ;
return ;
} else busy_drive_ = true ;
2021-06-14 15:40:14 +03:00
if ( ESDR3 ) {
const QString cmd = CmdDrive + SmDP + rx_ + SmCM + drive + SmTZ ;
sendTextMessage ( cmd ) ;
} else {
const QString cmd = CmdDrive + SmDP + drive + SmTZ ;
sendTextMessage ( cmd ) ;
}
2021-02-22 17:35:24 +02:00
}
void TCITransceiver : : do_blocksize ( qint32 blocksize )
{
TRACE_CAT ( " TCITransceiver " , blocksize < < state ( ) ) ;
// printf ("%s(%0.1f) TCI do_blocksize:%d m_samplesPerFFT:%d state:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),blocksize,m_samplesPerFFT,state().blocksize());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI do_blocksize:%d m_samplesPerFFT:%d state:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , blocksize , m_samplesPerFFT , state ( ) . blocksize ( ) ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
m_samplesPerFFT = blocksize ;
}
void TCITransceiver : : do_ptt ( bool on )
{
TRACE_CAT ( " TCITransceiver " , on < < state ( ) ) ;
2021-03-10 11:52:12 +02:00
// printf ("%s(%0.1f) TCI do_ptt:%d PTT_:%d requested_PTT_:%d busy_PTT_:%d state:%d use_for_ptt:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),on,PTT_,requested_PTT_,busy_PTT_,state().ptt(),use_for_ptt_);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI do_ptt:%d PTT_:%d requested_PTT_:%d busy_PTT_:%d state:%d use_for_ptt:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , on , PTT_ , requested_PTT_ , busy_PTT_ , state ( ) . ptt ( ) , use_for_ptt_ ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
if ( use_for_ptt_ )
{
if ( on ! = PTT_ ) {
2021-03-12 17:43:55 +02:00
if ( ! inConnected & & ! error_ . isEmpty ( ) ) throw error { error_ } ;
// if (!inConnected){ PTT_ = on; update_PTT(on); return; }
2021-03-29 22:44:25 +03:00
else if ( busy_PTT_ | | ! tci_Ready | | ! _power_ ) return ;
2021-02-22 17:35:24 +02:00
else busy_PTT_ = true ;
requested_PTT_ = on ;
2021-06-14 15:40:14 +03:00
if ( ESDR3 ) {
const QString cmd = CmdTrx + SmDP + rx_ + SmCM + ( on ? " true " : " false " ) + SmCM + " tci " + SmTZ ;
sendTextMessage ( cmd ) ;
} else {
const QString cmd = CmdTrx + SmDP + rx_ + SmCM + ( on ? " true " : " false " ) + SmTZ ;
sendTextMessage ( cmd ) ;
}
2021-02-22 17:35:24 +02:00
mysleep3 ( 1000 ) ;
busy_PTT_ = false ;
2021-03-04 10:21:10 +02:00
if ( requested_PTT_ = = PTT_ ) {
update_PTT ( PTT_ ) ;
if ( PTT_ & & do_snr_ ) update_level ( - 54 ) ;
2021-11-17 19:59:24 +02:00
else { power_ = 0 ; if ( do_pwr_ ) update_power ( 0 ) ; swr_ = 0 ; if ( do_pwr_ ) update_swr ( 0 ) ; }
2021-03-04 10:21:10 +02:00
} else {
2021-03-30 09:47:58 +03:00
// printf ("%s(%0.1f) TCI failed set ptt %d->%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),PTT_,requested_PTT_);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
2021-03-30 09:47:58 +03:00
fprintf ( pFile , " %s(%0.1f) TCI failed set ptt %d->%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , PTT_ , requested_PTT_ ) ;
2021-03-13 14:31:44 +02:00
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
error_ = tr ( " TCI failed to set ptt " ) ;
// tci_Ready = false;
// throw error {tr ("TCI failed to set ptt")};
2021-02-22 17:35:24 +02:00
}
} else update_PTT ( on ) ;
}
else
{
TRACE_CAT ( " TCITransceiver " , " TCI should use PTT via CAT " ) ;
throw error { tr ( " TCI should use PTT via CAT " ) } ;
}
}
void TCITransceiver : : do_frequency ( Frequency f , MODE m , bool no_ignore )
{
TRACE_CAT ( " TCITransceiver " , f < < state ( ) ) ;
2021-03-21 20:20:00 +02:00
auto f_string = frequency_to_string ( f ) ;
// printf ("%s(%0.1f) TCI do_frequency:%s current_frequency:%s mode:%s current_mode:%s no_ignore:%d busy:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),f_string.toStdString().c_str(),rx_frequency_.toStdString().c_str(),map_mode(m).toStdString().c_str(),requested_mode_.toStdString().c_str(),no_ignore,busy_rx_frequency_);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
2021-03-21 20:20:00 +02:00
fprintf ( pFile , " %s(%0.1f) TCI do_frequency:%s current_frequency:%s mode:%s current_mode:%s no_ignore:%d busy:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , f_string . toStdString ( ) . c_str ( ) , rx_frequency_ . toStdString ( ) . c_str ( ) , map_mode ( m ) . toStdString ( ) . c_str ( ) , requested_mode_ . toStdString ( ) . c_str ( ) , no_ignore , busy_rx_frequency_ ) ;
2021-03-13 14:31:44 +02:00
fclose ( pFile ) ;
# endif
if ( tci_Ready & & busy_rx_frequency_ & & no_ignore ) {
// printf ("%s(%0.1f) TCI do_frequency critical no_ignore set vfo will be missed\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset());
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI do_frequency critical no_ignore set vfo will be missed \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) ) ;
fclose ( pFile ) ;
# endif
}
2021-03-21 20:20:00 +02:00
if ( busy_rx_frequency_ ) return ;
else {
requested_rx_frequency_ = f_string ;
requested_mode_ = map_mode ( m ) ;
}
2021-03-29 22:44:25 +03:00
if ( tci_Ready & & _power_ ) {
2021-03-21 10:18:01 +02:00
if ( rx_frequency_ ! = requested_rx_frequency_ ) {
2021-06-14 15:40:14 +03:00
busy_rx_frequency_ = true ;
band_change = abs ( rx_frequency_ . toInt ( ) - requested_rx_frequency_ . toInt ( ) ) > 1000000 ;
const QString cmd = CmdVFO + SmDP + rx_ + SmCM + " 0 " + SmCM + requested_rx_frequency_ + SmTZ ;
sendTextMessage ( cmd ) ;
2021-03-21 10:18:01 +02:00
mysleep1 ( 1000 ) ;
2021-11-04 13:42:48 +02:00
// if (band_change) mysleep1(500);
2021-03-21 10:18:01 +02:00
if ( requested_rx_frequency_ = = rx_frequency_ ) update_rx_frequency ( f ) ;
else {
// printf ("%s(%0.1f) TCI failed set rxfreq:%s->%s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),rx_frequency_.toStdString().c_str(),requested_rx_frequency_.toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
2021-03-21 10:18:01 +02:00
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI failed set rxfreq:%s->%s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , rx_frequency_ . toStdString ( ) . c_str ( ) , requested_rx_frequency_ . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
2021-03-13 14:31:44 +02:00
# endif
2021-06-14 15:40:14 +03:00
error_ = tr ( " TCI failed set rxfreq " ) ;
// tci_Ready = false;
// throw error {tr ("TCI failed set rxfreq")};
2021-03-21 10:18:01 +02:00
}
2021-06-14 15:40:14 +03:00
busy_rx_frequency_ = false ;
}
if ( ! requested_mode_ . isEmpty ( ) & & requested_mode_ ! = mode_ ) {
busy_mode_ = true ;
2021-03-21 10:18:01 +02:00
sendTextMessage ( mode_to_command ( requested_mode_ ) ) ;
mysleep1 ( 1000 ) ;
if ( requested_mode_ . isEmpty ( ) | | requested_mode_ = = mode_ ) update_mode ( m ) ;
else {
// printf ("%s(%0.1f) TCI failed set mode %s->%s",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),mode_.toStdString().c_str(),requested_mode_.toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
2021-03-21 10:18:01 +02:00
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI failed set mode %s->%s " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , mode_ . toStdString ( ) . c_str ( ) , requested_mode_ . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
2021-03-13 14:31:44 +02:00
# endif
2021-06-14 15:40:14 +03:00
error_ = tr ( " TCI failed set mode " ) ;
// tci_Ready = false;
// throw error {tr ("TCI failed set mode")};
2021-03-21 10:18:01 +02:00
}
2021-06-14 15:40:14 +03:00
busy_mode_ = false ;
2021-03-21 10:18:01 +02:00
}
2021-06-14 15:40:14 +03:00
if ( band_change ) {
band_change = false ;
2022-02-11 10:35:57 +02:00
if ( tci_timer2_ - > isActive ( ) ) tci_done2 ( ) ; else if ( split_ ) tci_timer2_ - > start ( 300 ) ;
2021-06-14 15:40:14 +03:00
}
} else {
2021-03-21 10:18:01 +02:00
update_rx_frequency ( f ) ;
update_mode ( m ) ;
}
2021-02-22 17:35:24 +02:00
}
void TCITransceiver : : do_tx_frequency ( Frequency tx , MODE mode , bool no_ignore )
{
TRACE_CAT ( " TCITransceiver " , tx < < state ( ) ) ;
2021-03-21 20:20:00 +02:00
auto f_string = frequency_to_string ( tx ) ;
2022-02-08 20:25:43 +02:00
// printf ("%s(%0.1f) TCI do_tx_frequency:%s current_frequency:%s mode:%s no_ignore:%d busy:%d timer:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),f_string.toStdString().c_str(),other_frequency_.toStdString().c_str(),map_mode(mode).toStdString().c_str(),no_ignore,busy_other_frequency_,tci_timer2_->isActive());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
2022-02-10 13:18:01 +02:00
fprintf ( pFile , " %s(%0.1f) TCI do_tx_frequency:%s current_frequency:%s mode:%s no_ignore:%d busy:%d timer:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , f_string . toStdString ( ) . c_str ( ) , other_frequency_ . toStdString ( ) . c_str ( ) , map_mode ( mode ) . toStdString ( ) . c_str ( ) , no_ignore , busy_other_frequency_ , tci_timer2_ - > isActive ( ) ) ;
2021-03-13 14:31:44 +02:00
fclose ( pFile ) ;
# endif
if ( tci_Ready & & busy_other_frequency_ & & no_ignore ) {
// printf ("%s(%0.1f) TCI do_txfrequency critical no_ignore set tx vfo will be missed\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset());
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI do_txfrequency critical no_ignore set tx vfo will be missed \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) ) ;
fclose ( pFile ) ;
# endif
}
2021-03-21 20:20:00 +02:00
if ( busy_other_frequency_ ) return ;
requested_other_frequency_ = f_string ;
2021-02-22 17:35:24 +02:00
requested_mode_ = map_mode ( mode ) ;
if ( tx )
{
2021-03-18 16:21:04 +02:00
requested_split_ = true ;
2021-03-29 22:44:25 +03:00
if ( tci_Ready & & _power_ ) {
2022-02-11 10:35:57 +02:00
if ( ( band_change | | busy_rx_frequency_ ) & & ! tci_timer2_ - > isActive ( ) ) mysleep2 ( 300 ) ;
2021-03-21 10:18:01 +02:00
if ( requested_split_ ! = split_ ) rig_split ( ) ;
if ( other_frequency_ ! = requested_other_frequency_ ) {
2021-06-14 15:40:14 +03:00
busy_other_frequency_ = true ;
2022-01-16 17:30:56 +02:00
if ( tci_timer2_ - > isActive ( ) ) mysleep2 ( 0 ) ;
2021-06-14 15:40:14 +03:00
const QString cmd = CmdVFO + SmDP + rx_ + SmCM + " 1 " + SmCM + requested_other_frequency_ + SmTZ ;
2021-03-21 10:18:01 +02:00
sendTextMessage ( cmd ) ;
mysleep2 ( 1000 ) ;
if ( requested_other_frequency_ = = other_frequency_ ) update_other_frequency ( tx ) ;
else {
// printf ("%s(%0.1f) TCI failed set txfreq:%s->%s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),other_frequency_.toStdString().c_str(),requested_other_frequency_.toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
2021-03-21 10:18:01 +02:00
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI failed set txfreq:%s->%s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , other_frequency_ . toStdString ( ) . c_str ( ) , requested_other_frequency_ . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
2021-03-13 14:31:44 +02:00
# endif
2021-06-14 15:40:14 +03:00
error_ = tr ( " TCI failed set txfreq " ) ;
// tci_Ready = false;
// throw error {tr ("TCI failed set txfreq")};
2021-03-21 10:18:01 +02:00
}
2021-06-14 15:40:14 +03:00
busy_other_frequency_ = false ;
2021-02-22 17:35:24 +02:00
}
2021-06-14 15:40:14 +03:00
2021-03-21 10:18:01 +02:00
} else {
update_split ( requested_split_ ) ;
update_other_frequency ( tx ) ;
2021-02-22 17:35:24 +02:00
}
}
2021-03-18 16:21:04 +02:00
else {
requested_split_ = false ;
2021-06-14 15:40:14 +03:00
if ( tci_Ready & & _power_ ) {
2021-03-21 10:18:01 +02:00
requested_other_frequency_ = " " ;
update_other_frequency ( tx ) ;
2022-01-16 17:30:56 +02:00
if ( requested_split_ ! = split_ ) rig_split ( ) ;
2021-03-21 10:18:01 +02:00
} else {
update_other_frequency ( tx ) ;
update_split ( requested_split_ ) ;
}
2021-03-18 16:21:04 +02:00
}
2021-02-22 17:35:24 +02:00
}
void TCITransceiver : : do_mode ( MODE m )
{
TRACE_CAT ( " TCITransceiver " , m < < state ( ) ) ;
auto m_string = map_mode ( m ) ;
// printf ("%s(%0.1f) TCI do_mode:%s->%s\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),mode_.toStdString().c_str(),m_string.toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI do_mode:%s->%s \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , mode_ . toStdString ( ) . c_str ( ) , m_string . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
if ( requested_mode_ ! = m_string ) requested_mode_ = m_string ;
if ( mode_ ! = m_string ) {
sendTextMessage ( mode_to_command ( m_string ) ) ;
mysleep1 ( 1000 ) ;
if ( requested_mode_ = = mode_ ) update_mode ( m ) ;
else {
// printf ("%s(%0.1f) TCI failed set mode %s->%s",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),mode_.toStdString().c_str(),requested_mode_.toStdString().c_str());
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI failed set mode %s->%s " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , mode_ . toStdString ( ) . c_str ( ) , requested_mode_ . toStdString ( ) . c_str ( ) ) ;
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
error_ = tr ( " TCI failed set mode " ) ;
// tci_Ready = false;
// throw error {tr ("TCI failed set mode")};
2021-02-22 17:35:24 +02:00
}
}
}
void TCITransceiver : : do_poll ( )
{
2021-03-13 14:31:44 +02:00
if ( ! inConnected ) {
// printf("%s(%0.1f) TCI do_poll |%s| split:%d ptt:%d rx_busy:%d tx_busy:%d level:%d power:%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),error_.toStdString().c_str(),state ().split (),state (). ptt (),busy_rx_frequency_,busy_other_frequency_,level_,power_);
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI do_poll |%s| split:%d ptt:%d rx_busy:%d tx_busy:%d level:%d power:%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , error_ . toStdString ( ) . c_str ( ) , state ( ) . split ( ) , state ( ) . ptt ( ) , busy_rx_frequency_ , busy_other_frequency_ , level_ , power_ ) ;
fclose ( pFile ) ;
# endif
}
2022-01-16 17:30:56 +02:00
if ( /*!inConnected && */ ! error_ . isEmpty ( ) ) { tci_Ready = false ; throw error { error_ } ; }
2021-03-01 10:47:46 +02:00
else if ( ! tci_Ready ) throw error { tr ( " TCI could not be opened " ) } ;
2021-02-22 17:35:24 +02:00
update_rx_frequency ( string_to_frequency ( rx_frequency_ ) ) ;
2021-03-18 16:21:04 +02:00
update_split ( split_ ) ;
2022-02-08 20:25:43 +02:00
if ( state ( ) . split ( ) ) {
if ( other_frequency_ = = requested_other_frequency_ ) update_other_frequency ( string_to_frequency ( other_frequency_ ) ) ;
else if ( ! busy_rx_frequency_ ) do_tx_frequency ( string_to_frequency ( requested_other_frequency_ ) , get_mode ( true ) , false ) ;
}
2021-02-22 17:35:24 +02:00
update_mode ( get_mode ( ) ) ;
2021-11-26 12:44:52 +02:00
if ( do_pwr_ & & PTT_ ) { update_power ( power_ * 100 ) ; update_swr ( swr_ * 10 ) ; }
2021-03-04 10:21:10 +02:00
if ( do_snr_ & & ! PTT_ ) {
2021-02-22 17:35:24 +02:00
update_level ( level_ ) ;
2021-06-14 15:40:14 +03:00
if ( ! ESDR3 ) {
const QString cmd = CmdSmeter + SmDP + rx_ + SmCM + " 0 " + SmTZ ;
sendTextMessage ( cmd ) ;
}
2021-02-22 17:35:24 +02:00
}
}
auto TCITransceiver : : get_mode ( bool requested ) - > MODE
{
MODE m { UNK } ;
if ( requested ) {
if ( " am " = = requested_mode_ )
{
m = AM ;
}
else if ( " cw " = = requested_mode_ )
{
m = CW ;
}
else if ( " wfm " = = requested_mode_ )
{
m = FM ;
}
else if ( " nfm " = = requested_mode_ )
{
m = DIG_FM ;
}
else if ( " lsb " = = requested_mode_ )
{
m = LSB ;
}
else if ( " usb " = = requested_mode_ )
{
m = USB ;
}
else if ( " digl " = = requested_mode_ )
{
m = DIG_L ;
}
else if ( " digu " = = requested_mode_ )
{
m = DIG_U ;
}
else
{
m = USB ;
}
} else {
if ( " am " = = mode_ )
{
m = AM ;
}
else if ( " cw " = = mode_ )
{
m = CW ;
}
else if ( " wfm " = = mode_ )
{
m = FM ;
}
else if ( " nfm " = = mode_ )
{
m = DIG_FM ;
}
else if ( " lsb " = = mode_ )
{
m = LSB ;
}
else if ( " usb " = = mode_ )
{
m = USB ;
}
else if ( " digl " = = mode_ )
{
m = DIG_L ;
}
else if ( " digu " = = mode_ )
{
m = DIG_U ;
}
else
{
m = USB ;
}
}
return m ;
}
QString TCITransceiver : : mode_to_command ( QString m_string ) const
{
2021-06-14 15:40:14 +03:00
// if (ESDR3) {
// const QString cmd = CmdMode + SmDP + rx_ + SmCM + m_string.toUpper() + SmTZ;
// return cmd;
// } else {
const QString cmd = CmdMode + SmDP + rx_ + SmCM + m_string + SmTZ ;
return cmd ;
// }
2021-02-22 17:35:24 +02:00
}
QString TCITransceiver : : frequency_to_string ( Frequency f ) const
{
// number is localized and in kHz, avoid floating point translation
// errors by adding a small number (0.1Hz)
2021-11-24 12:24:41 +02:00
// auto f_string = QString {"%L2"}.arg (f);
auto f_string = QString { } . setNum ( f ) ;
// f_string = f_string.simplified().remove(' ');
// f_string = f_string.replace(",","");
// f_string = f_string.replace(".","");
// f_string = f_string.replace("'","");
// f_string = f_string.replace("’ ","");
// printf ("frequency_to_string3 |%s|\n",f_string.toStdString().c_str());
2021-02-22 17:35:24 +02:00
return f_string ;
}
auto TCITransceiver : : string_to_frequency ( QString s ) const - > Frequency
{
// temporary hack because Commander is returning invalid UTF-8 bytes
s . replace ( QChar { QChar : : ReplacementCharacter } , locale_ . groupSeparator ( ) ) ;
bool ok ;
auto f = QLocale : : c ( ) . toDouble ( s , & ok ) ; // temporary fix
if ( ! ok )
{
2021-03-21 10:18:01 +02:00
throw error { tr ( " TCI sent an unrecognized frequency " ) + " | " + s + " | " } ;
2021-02-22 17:35:24 +02:00
}
return f ;
}
void TCITransceiver : : mysleep1 ( int ms )
{
// tci_timer1->setSingleShot(true);
2021-03-29 22:44:25 +03:00
// printf("%s(%0.1f) TCI sleep1 start %d %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),ms,tci_timer1_->isActive());
2022-01-16 17:30:56 +02:00
if ( ms ) tci_timer1_ - > start ( ms ) ;
2021-02-22 17:35:24 +02:00
tci_loop1_ - > exec ( ) ;
2021-03-21 10:18:01 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI sleep1 %d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , tci_timer1_ - > isActive ( ) ) ;
fclose ( pFile ) ;
# endif
2021-03-29 22:44:25 +03:00
// printf("%s(%0.1f) TCI sleep1 end %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),tci_timer1_->isActive());
2021-02-22 17:35:24 +02:00
if ( tci_timer1_ - > isActive ( ) & & tci_Ready ) tci_timer1_ - > stop ( ) ;
}
void TCITransceiver : : mysleep2 ( int ms )
{
// tci_timer2->setSingleShot(true);
2021-03-29 22:44:25 +03:00
// printf("%s(%0.1f) TCI sleep2 start %d %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),ms,tci_timer2_->isActive());
2022-01-16 17:30:56 +02:00
if ( ms ) tci_timer2_ - > start ( ms ) ;
2021-02-22 17:35:24 +02:00
tci_loop2_ - > exec ( ) ;
2021-03-21 10:18:01 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI sleep2 %d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , tci_timer2_ - > isActive ( ) ) ;
fclose ( pFile ) ;
# endif
2021-06-14 15:40:14 +03:00
// printf("%s(%0.1f) TCI sleep2 end %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),tci_timer2_->isActive());
2021-02-22 17:35:24 +02:00
if ( tci_timer2_ - > isActive ( ) ) tci_timer2_ - > stop ( ) ;
}
void TCITransceiver : : mysleep3 ( int ms )
{
// tci_timer3->setSingleShot(true);
2021-03-29 22:44:25 +03:00
// printf("%s(%0.1f) TCI sleep3 start %d %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),ms,tci_timer3_->isActive());
2022-01-16 17:30:56 +02:00
if ( ms ) tci_timer3_ - > start ( ms ) ;
2021-02-22 17:35:24 +02:00
tci_loop3_ - > exec ( ) ;
2021-03-21 10:18:01 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI sleep3 %d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , tci_timer3_ - > isActive ( ) ) ;
fclose ( pFile ) ;
# endif
2021-03-29 22:44:25 +03:00
// printf("%s(%0.1f) TCI sleep3 end %d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),tci_timer3_->isActive());
2021-02-22 17:35:24 +02:00
if ( tci_timer3_ - > isActive ( ) ) tci_timer3_ - > stop ( ) ;
}
// Modulator part
void TCITransceiver : : do_modulator_start ( unsigned symbolsLength , double framesPerSymbol ,
double frequency , double toneSpacing , bool synchronize , double dBSNR , double TRperiod )
{
// QThread::currentThread()->setPriority(QThread::HighPriority);
// Q_ASSERT (stream);
// Time according to this computer which becomes our base time
qint64 ms0 = m_jtdxtime - > currentMSecsSinceEpoch2 ( ) % 86400000 ;
// qDebug() << "ModStart" << QDateTime::currentDateTimeUtc().toString("hh:mm:ss.sss");
unsigned mstr = ms0 % int ( 1000.0 * m_period ) ; // ms into the nominal Tx start time
if ( m_state ! = Idle ) {
// stop ();
throw error { tr ( " TCI modulator not Idle " ) } ;
}
m_quickClose = false ;
m_symbolsLength = symbolsLength ;
m_isym0 = std : : numeric_limits < unsigned > : : max ( ) ; // big number
m_frequency0 = 0. ;
m_phi = 0. ;
m_addNoise = dBSNR < 0. ;
m_nsps = framesPerSymbol ;
m_trfrequency = frequency ;
m_amp = std : : numeric_limits < qint16 > : : max ( ) ;
m_toneSpacing = toneSpacing ;
m_TRperiod = TRperiod ;
unsigned delay_ms = 1000 ;
if ( m_nsps = = 1920 ) delay_ms = 500 ; //FT8
else if ( m_nsps = = 576 ) {
delay_ms = 500 ; //FT4
}
// noise generator parameters
if ( m_addNoise ) {
m_snr = qPow ( 10.0 , 0.05 * ( dBSNR - 6.0 ) ) ;
m_fac = 3000.0 ;
if ( m_snr > 1.0 ) m_fac = 3000.0 / m_snr ;
}
// round up to an exact portion of a second that allows for startup delays
//m_ic = (mstr / delay_ms) * audioSampleRate * delay_ms / 1000;
auto mstr2 = mstr - delay_ms ;
if ( mstr < = delay_ms ) {
m_ic = 0 ;
} else {
m_ic = mstr2 * ( audioSampleRate / 1000 ) ;
}
m_silentFrames = 0 ;
// calculate number of silent frames to send
if ( m_ic = = 0 & & synchronize & & ! m_tuning ) {
m_silentFrames = audioSampleRate / ( 1000 / delay_ms ) - ( mstr * ( audioSampleRate / 1000 ) ) ;
}
2021-03-13 14:31:44 +02:00
m_state = ( synchronize & & m_silentFrames ) ?
Synchronizing : Active ;
2022-01-02 10:24:49 +02:00
// printf ("%s(%0.1f) TCI modulator startdelay_ms=%d ASR=%d mstr=%d mstr2=%d m_ic=%d s_Frames=%lld synchronize=%d m_tuning=%d State=%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),delay_ms,audioSampleRate,mstr,mstr2,m_ic,m_silentFrames,synchronize,m_tuning,m_state);
2021-02-22 17:35:24 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
2022-01-02 10:24:49 +02:00
fprintf ( pFile , " %s(%0.1f) TCI modulator startdelay_ms=%d ASR=%d mstr=%d mstr2=%d m_ic=%d s_Frames=%lld synchronize=%d m_tuning=%d State=%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , delay_ms , audioSampleRate , mstr , mstr2 , m_ic , m_silentFrames , synchronize , m_tuning , m_state ) ;
2021-02-22 17:35:24 +02:00
fclose ( pFile ) ;
# endif
Q_EMIT tci_mod_active ( m_state ! = Idle ) ;
}
void TCITransceiver : : do_tune ( bool newState )
{
2021-03-12 17:43:55 +02:00
// printf("%s(%0.1f) TCI modulator tune %d ->%d\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),m_tuning,newState);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI modulator tune %d ->%d \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , m_tuning , newState ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
m_tuning = newState ;
if ( ! m_tuning ) do_modulator_stop ( true ) ;
}
void TCITransceiver : : do_modulator_stop ( bool quick )
{
m_quickClose = quick ;
if ( m_state ! = Idle ) {
m_state = Idle ;
Q_EMIT tci_mod_active ( m_state ! = Idle ) ;
}
tx_audio_ = false ;
}
quint16 TCITransceiver : : readAudioData ( float * data , qint32 maxSize )
{
double toneFrequency = 1500.0 ;
if ( m_nsps = = 6 ) {
toneFrequency = 1000.0 ;
m_trfrequency = 1000.0 ;
m_frequency0 = 1000.0 ;
}
if ( maxSize = = 0 ) return 0 ;
qint64 numFrames ( maxSize / bytesPerFrame ) ;
float * samples ( reinterpret_cast < float * > ( data ) ) ;
float * end ( samples + numFrames * bytesPerFrame ) ;
2022-01-02 10:24:49 +02:00
// printf("%s(%0.1f) readAudioData %f %f %lld %lld %d %p %p\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),m_nsps,m_TRperiod,numFrames,m_silentFrames,maxSize,samples,end);
2021-02-22 17:35:24 +02:00
qint64 framesGenerated ( 0 ) ;
switch ( m_state )
{
case Synchronizing :
{
if ( m_silentFrames ) { // send silence up to first second
framesGenerated = qMin ( m_silentFrames , numFrames ) ;
for ( ; samples ! = end ; samples = load ( 0 , samples ) ) { // silence
}
m_silentFrames - = framesGenerated ;
return framesGenerated * bytesPerFrame ;
}
m_state = Active ;
Q_EMIT tci_mod_active ( m_state ! = Idle ) ;
m_cwLevel = false ;
m_ramp = 0 ; // prepare for CW wave shaping
}
// fall through
case Active :
{
unsigned int isym = 0 ;
qint16 sample = 0 ;
if ( ! m_tuning ) isym = m_ic / ( 4.0 * m_nsps ) ; // Actual fsample=48000
bool slowCwId = ( ( isym > = m_symbolsLength ) & & ( icw [ 0 ] > 0 ) ) ;
m_nspd = 2560 ; // 22.5 WPM
if ( m_TRperiod > 16.0 & & slowCwId ) { // Transmit CW ID?
m_dphi = m_twoPi * m_trfrequency / audioSampleRate ;
unsigned ic0 = m_symbolsLength * 4 * m_nsps ;
unsigned j ( 0 ) ;
while ( samples ! = end ) {
j = ( m_ic - ic0 ) / m_nspd + 1 ; // symbol of this sample
bool level { bool ( icw [ j ] ) } ;
m_phi + = m_dphi ;
if ( m_phi > m_twoPi ) m_phi - = m_twoPi ;
sample = 0 ;
float amp = 32767.0 ;
float x = 0.0 ;
if ( m_ramp ! = 0 ) {
x = qSin ( float ( m_phi ) ) ;
if ( SOFT_KEYING ) {
amp = qAbs ( qint32 ( m_ramp ) ) ;
if ( amp > 32767.0 ) amp = 32767.0 ;
}
sample = round ( amp * x ) ;
}
if ( int ( j ) < = icw [ 0 ] & & j < NUM_CW_SYMBOLS ) { // stopu condition
samples = load ( postProcessSample ( sample ) , samples ) ;
+ + framesGenerated ;
+ + m_ic ;
} else {
m_state = Idle ;
2021-03-09 10:55:21 +02:00
// printf("%s(%0.1f) TCI modulator Idle1 %lld frames generated\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),framesGenerated);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI modulator Idle1 %lld frames generated \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , framesGenerated ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
Q_EMIT tci_mod_active ( m_state ! = Idle ) ;
return framesGenerated * bytesPerFrame ;
}
// adjust ramp
if ( ( m_ramp ! = 0 & & m_ramp ! = std : : numeric_limits < qint16 > : : min ( ) ) | | level ! = m_cwLevel ) {
// either ramp has terminated at max/min or direction has changed
m_ramp + = RAMP_INCREMENT ; // ramp
}
m_cwLevel = level ;
}
return framesGenerated * bytesPerFrame ;
} //End of code for CW ID
double const baud ( 12000.0 / m_nsps ) ;
// fade out parameters (no fade out for tuning)
unsigned int i0 , i1 ;
if ( m_tuning ) {
i1 = i0 = 9999 * m_nsps ;
} else {
i0 = ( m_symbolsLength - 0.017 ) * 4.0 * m_nsps ;
i1 = m_symbolsLength * 4.0 * m_nsps ;
}
sample = 0 ;
for ( unsigned i = 0 ; i < numFrames & & m_ic < = i1 ; + + i ) {
// printf("algus %d %lld %d %d",i,numFrames,m_ic,i1);
if ( m_TRperiod > 16.0 | | m_tuning ) {
isym = 0 ;
if ( ! m_tuning ) isym = m_ic / ( 4.0 * m_nsps ) ; //Actual fsample=48000
if ( isym ! = m_isym0 | | m_trfrequency ! = m_frequency0 ) {
if ( itone [ 0 ] > = 100 ) {
m_toneFrequency0 = itone [ 0 ] ;
} else {
if ( m_toneSpacing = = 0.0 ) {
m_toneFrequency0 = m_trfrequency + itone [ isym ] * baud ;
} else {
m_toneFrequency0 = m_trfrequency + itone [ isym ] * m_toneSpacing ;
}
}
// qDebug() << "B" << m_ic << numFrames << isym << itone[isym] << toneFrequency0 << m_nsps;
m_dphi = m_twoPi * m_toneFrequency0 / audioSampleRate ;
m_isym0 = isym ;
m_frequency0 = m_trfrequency ; //???
}
int j = m_ic / 480 ;
if ( m_fSpread > 0.0 and j ! = m_j0 ) {
# if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
float x1 = QRandomGenerator : : global ( ) - > generateDouble ( ) ;
float x2 = QRandomGenerator : : global ( ) - > generateDouble ( ) ;
# else
float x1 = ( float ) qrand ( ) / RAND_MAX ;
float x2 = ( float ) qrand ( ) / RAND_MAX ;
# endif
toneFrequency = m_toneFrequency0 + 0.5 * m_fSpread * ( x1 + x2 - 1.0 ) ;
m_dphi = m_twoPi * toneFrequency / audioSampleRate ;
m_j0 = j ;
}
m_phi + = m_dphi ;
if ( m_phi > m_twoPi ) m_phi - = m_twoPi ;
//ramp for first tone
if ( m_ic = = 0 ) m_amp = m_amp * 0.008144735 ;
if ( m_ic > 0 and m_ic < 191 ) m_amp = m_amp / 0.975 ;
//ramp for last tone
if ( m_ic > i0 ) m_amp = 0.99 * m_amp ;
if ( m_ic > i1 ) m_amp = 0.0 ;
sample = qRound ( m_amp * qSin ( m_phi ) ) ;
}
//transmit from a precomputed FT8 wave[] array:
if ( ! m_tuning and ( m_toneSpacing < 0.0 ) ) { m_amp = 32767.0 ; sample = qRound ( m_amp * foxcom_ . wave [ m_ic ] ) ; }
samples = load ( postProcessSample ( sample ) , samples ) ;
+ + framesGenerated ; + + m_ic ;
}
// printf("sample saved %lld %d\n",framesGenerated,m_ic);
if ( m_amp = = 0.0 ) { // TODO G4WJS: compare double with zero might not be wise
if ( icw [ 0 ] = = 0 ) {
// no CW ID to send
m_state = Idle ;
2021-03-09 10:55:21 +02:00
// printf("%s(%0.1f) TCI modulator Idle2 %lld frames generated\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),framesGenerated);
2021-03-13 14:31:44 +02:00
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI modulator Idle2 %lld frames generated \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , framesGenerated ) ;
fclose ( pFile ) ;
# endif
2021-02-22 17:35:24 +02:00
Q_EMIT tci_mod_active ( m_state ! = Idle ) ;
return framesGenerated * bytesPerFrame ;
}
m_phi = 0.0 ;
}
m_frequency0 = m_trfrequency ;
// done for this chunk - continue on next call
2021-03-13 14:31:44 +02:00
if ( samples ! = end & & framesGenerated ) {
// printf("%s(%0.1f) TCI modulator Idle3 %lld frames generated\n",m_jtdxtime->currentDateTimeUtc2().toString("hh:mm:ss.zzz").toStdString().c_str(),m_jtdxtime->GetOffset(),framesGenerated);
# if JTDX_DEBUG_TO_FILE
FILE * pFile = fopen ( debug_file_ . c_str ( ) , " a " ) ;
fprintf ( pFile , " %s(%0.1f) TCI modulator Idle3 %lld frames generated \n " , m_jtdxtime - > currentDateTimeUtc2 ( ) . toString ( " hh:mm:ss.zzz " ) . toStdString ( ) . c_str ( ) , m_jtdxtime - > GetOffset ( ) , framesGenerated ) ;
fclose ( pFile ) ;
# endif
}
2021-02-22 17:35:24 +02:00
while ( samples ! = end ) { // pad block with silence
samples = load ( 0 , samples ) ;
+ + framesGenerated ;
}
return framesGenerated * bytesPerFrame ;
}
// fall through
case Idle :
2022-01-02 10:24:49 +02:00
while ( samples ! = end ) samples = load ( 0 , samples ) ;
2021-02-22 17:35:24 +02:00
}
Q_ASSERT ( Idle = = m_state ) ;
return 0 ;
}
qint16 TCITransceiver : : postProcessSample ( qint16 sample ) const
{
if ( m_addNoise ) { // Test frame, we'll add noise
qint32 s = m_fac * ( gran ( ) + sample * m_snr / 32768.0 ) ;
if ( s > std : : numeric_limits < qint16 > : : max ( ) ) {
s = std : : numeric_limits < qint16 > : : max ( ) ;
}
if ( s < std : : numeric_limits < qint16 > : : min ( ) ) {
s = std : : numeric_limits < qint16 > : : min ( ) ;
}
sample = s ;
}
return sample ;
}