2023-09-04 19:06:44 +01:00
/*
Copyright ( C ) 2019 - 2020 Andrei Kopanchuk UZ7HO
This file is part of QtSoundModem
QtSoundModem is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
QtSoundModem is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with QtSoundModem . If not , see http : //www.gnu.org/licenses
*/
// UZ7HO Soundmodem Port by John Wiseman G8BPQ
// UZ7HO Soundmodem Port
// Not Working 4psk100 FEC
// Thoughts on Waterfall Display.
// Original used a 2048 sample FFT giving 5.859375 Hz bins. We plotted 1024 points, giving a 0 to 6000 specrum
// If we want say 300 to 3300 we need about half the bin size so twice the fft size. But should we also fit required range to window size?
// Unless we resize the most displayed bit of the screen in around 900 pixels. So each bin should be 3300 / 900 = 3.66667 Hz or a FFT size of around 3273
# include "QtSoundModem.h"
# include <qheaderview.h>
//#include <QDebug>
# include <QHostAddress>
# include <QAbstractSocket>
# include <QSettings>
# include <QPainter>
# include <QtSerialPort/QSerialPort>
# include <QtSerialPort/QSerialPortInfo>
# include <QMessageBox>
# include <QTimer>
# include <qevent.h>
# include <QStandardItemModel>
# include <QScrollBar>
2023-10-07 12:21:48 +01:00
# include <QFontDialog>
2024-07-23 21:26:30 +01:00
# include <QFile>
2023-09-04 19:06:44 +01:00
# include "UZ7HOStuff.h"
2024-07-23 21:26:30 +01:00
# include <time.h>
2023-09-04 19:06:44 +01:00
2023-09-12 21:38:15 +01:00
QImage * Constellation [ 4 ] ;
2023-12-17 13:53:32 +00:00
QImage * Waterfall = 0 ;
2023-09-04 19:06:44 +01:00
QLabel * DCDLabel [ 4 ] ;
QLineEdit * chanOffsetLabel [ 4 ] ;
QImage * DCDLed [ 4 ] ;
QImage * RXLevel ;
2023-12-17 13:53:32 +00:00
QImage * RXLevel2 ;
QLabel * WaterfallCopy ;
2023-09-04 19:06:44 +01:00
2023-10-07 12:21:48 +01:00
QLabel * RXLevelCopy ;
2023-12-17 13:53:32 +00:00
QLabel * RXLevel2Copy ;
2023-09-04 19:06:44 +01:00
QTextEdit * monWindowCopy ;
extern workerThread * t ;
extern QtSoundModem * w ;
2023-10-07 12:21:48 +01:00
extern QCoreApplication * a ;
2024-10-29 22:45:21 +00:00
extern serialThread * serial ;
2023-09-04 19:06:44 +01:00
QList < QSerialPortInfo > Ports = QSerialPortInfo : : availablePorts ( ) ;
void saveSettings ( ) ;
void getSettings ( ) ;
2023-12-17 13:53:32 +00:00
void DrawModemFreqRange ( ) ;
2023-09-04 19:06:44 +01:00
extern " C " void CloseSound ( ) ;
extern " C " void GetSoundDevices ( ) ;
2023-09-12 21:38:15 +01:00
extern " C " char modes_name [ modes_count ] [ 21 ] ;
2023-09-04 19:06:44 +01:00
extern " C " int speed [ 5 ] ;
extern " C " int KISSPort ;
extern " C " short rx_freq [ 5 ] ;
extern " C " int CaptureCount ;
extern " C " int PlaybackCount ;
extern " C " int CaptureIndex ; // Card number
extern " C " int PlayBackIndex ;
extern " C " char CaptureNames [ 16 ] [ 256 ] ;
extern " C " char PlaybackNames [ 16 ] [ 256 ] ;
extern " C " int SoundMode ;
2024-10-29 22:45:21 +00:00
extern " C " bool onlyMixSnoop ;
2024-07-23 21:26:30 +01:00
2023-09-04 19:06:44 +01:00
extern " C " int multiCore ;
extern " C " int refreshModems ;
2023-09-12 21:38:15 +01:00
int NeedPSKRefresh ;
2023-09-04 19:06:44 +01:00
extern " C " int pnt_change [ 5 ] ;
extern " C " int needRSID [ 4 ] ;
extern " C " int needSetOffset [ 4 ] ;
extern " C " float MagOut [ 4096 ] ;
extern " C " float MaxMagOut ;
extern " C " int MaxMagIndex ;
2023-09-12 21:38:15 +01:00
extern " C " int using48000 ; // Set if using 48K sample rate (ie RUH Modem active)
extern " C " int ReceiveSize ;
extern " C " int SendSize ; // 100 mS for now
2024-07-23 21:26:30 +01:00
extern " C " int txLatency ;
2024-10-29 22:45:21 +00:00
extern " C " int BusyDet ;
2023-09-04 19:06:44 +01:00
extern " C "
{
int InitSound ( BOOL Report ) ;
void soundMain ( ) ;
void MainLoop ( ) ;
void modulator ( UCHAR snd_ch , int buf_size ) ;
void SampleSink ( int LR , short Sample ) ;
void doCalib ( int Port , int Act ) ;
int Freq_Change ( int Chan , int Freq ) ;
void set_speed ( int snd_ch , int Modem ) ;
void init_speed ( int snd_ch ) ;
void FourierTransform ( int NumSamples , short * RealIn , float * RealOut , float * ImagOut , int InverseTransform ) ;
void dofft ( short * in , float * outr , float * outi ) ;
void init_raduga ( ) ;
2023-12-17 13:53:32 +00:00
void DrawFreqTicks ( ) ;
2023-09-04 19:06:44 +01:00
void AGW_Report_Modem_Change ( int port ) ;
char * strlop ( char * buf , char delim ) ;
void sendRSID ( int Chan , int dropTX ) ;
void RSIDinitfft ( ) ;
void il2p_init ( int il2p_debug ) ;
2024-07-23 21:26:30 +01:00
void closeTraceLog ( ) ;
2023-09-04 19:06:44 +01:00
}
void make_graph_buf ( float * buf , short tap , QPainter * bitmap ) ;
int ModemA = 2 ;
int ModemB = 2 ;
int ModemC = 2 ;
int ModemD = 2 ;
int FreqA = 1500 ;
int FreqB = 1500 ;
int FreqC = 1500 ;
int FreqD = 1500 ;
int DCD = 50 ;
char CWIDCall [ 128 ] = " " ;
2024-07-23 21:26:30 +01:00
extern " C " char CWIDMark [ 32 ] ;
2023-09-04 19:06:44 +01:00
int CWIDInterval = 0 ;
int CWIDLeft = 0 ;
int CWIDRight = 0 ;
int CWIDType = 1 ; // on/off
2023-10-07 12:21:48 +01:00
bool afterTraffic = 0 ;
bool cwidtimerisActive = false ;
2023-09-04 19:06:44 +01:00
int WaterfallMin = 00 ;
int WaterfallMax = 6000 ;
int Configuring = 0 ;
2023-12-17 13:53:32 +00:00
bool lockWaterfall = false ;
bool inWaterfall = false ;
2023-09-04 19:06:44 +01:00
2024-10-29 22:45:21 +00:00
int MgmtPort = 0 ;
2023-12-17 13:53:32 +00:00
extern " C " int NeedWaterfallHeaders ;
2023-09-12 21:38:15 +01:00
extern " C " float BinSize ;
2023-09-04 19:06:44 +01:00
extern " C " { int RSID_SABM [ 4 ] ; }
extern " C " { int RSID_UI [ 4 ] ; }
extern " C " { int RSID_SetModem [ 4 ] ; }
2023-09-12 21:38:15 +01:00
extern " C " unsigned int pskStates [ 4 ] ;
2023-09-04 19:06:44 +01:00
int Closing = FALSE ; // Set to stop background thread
QRgb white = qRgb ( 255 , 255 , 255 ) ;
QRgb black = qRgb ( 0 , 0 , 0 ) ;
QRgb green = qRgb ( 0 , 255 , 0 ) ;
QRgb red = qRgb ( 255 , 0 , 0 ) ;
QRgb yellow = qRgb ( 255 , 255 , 0 ) ;
QRgb cyan = qRgb ( 0 , 255 , 255 ) ;
2023-12-17 13:53:32 +00:00
QRgb txText = qRgb ( 192 , 0 , 0 ) ;
QRgb rxText = qRgb ( 0 , 0 , 192 ) ;
bool darkTheme = true ;
bool minimizeonStart = true ;
2024-10-29 22:45:21 +00:00
extern " C " bool useKISSControls ;
2023-12-17 13:53:32 +00:00
2023-09-04 19:06:44 +01:00
// Indexed colour list from ARDOPC
# define WHITE 0
# define Tomato 1
# define Gold 2
# define Lime 3
# define Yellow 4
# define Orange 5
# define Khaki 6
# define Cyan 7
# define DeepSkyBlue 8
# define RoyalBlue 9
# define Navy 10
# define Black 11
# define Goldenrod 12
# define Fuchsia 13
QRgb vbColours [ 16 ] = { qRgb ( 255 , 255 , 255 ) , qRgb ( 255 , 99 , 71 ) , qRgb ( 255 , 215 , 0 ) , qRgb ( 0 , 255 , 0 ) ,
qRgb ( 255 , 255 , 0 ) , qRgb ( 255 , 165 , 0 ) , qRgb ( 240 , 240 , 140 ) , qRgb ( 0 , 255 , 255 ) ,
qRgb ( 0 , 191 , 255 ) , qRgb ( 65 , 105 , 225 ) , qRgb ( 0 , 0 , 128 ) , qRgb ( 0 , 0 , 0 ) ,
qRgb ( 218 , 165 , 32 ) , qRgb ( 255 , 0 , 255 ) } ;
unsigned char WaterfallLines [ 2 ] [ 80 ] [ 4096 ] = { 0 } ;
2023-12-17 13:53:32 +00:00
int NextWaterfallLine [ 2 ] = { 0 , 0 } ;
2023-09-04 19:06:44 +01:00
unsigned int LastLevel = 255 ;
unsigned int LastBusy = 255 ;
extern " C " int UDPClientPort ;
extern " C " int UDPServerPort ;
extern " C " int TXPort ;
extern char UDPHost [ 64 ] ;
QTimer * cwidtimer ;
2024-07-23 21:26:30 +01:00
QTimer * PTTWatchdog ;
2023-10-07 12:21:48 +01:00
QWidget * mythis ;
2024-07-23 21:26:30 +01:00
QElapsedTimer pttOnTimer ;
2023-09-04 19:06:44 +01:00
QSystemTrayIcon * trayIcon = nullptr ;
int MintoTray = 1 ;
int RSID_WF = 0 ; // Set to use RSID FFT for Waterfall.
2024-10-29 22:45:21 +00:00
char SixPackDevice [ 256 ] = " " ;
int SixPackPort = 0 ;
int SixPackEnable = 0 ;
// Stats
uint64_t PTTonTime [ 4 ] = { 0 } ;
uint64_t PTTActivemS [ 4 ] = { 0 } ; // For Stats
uint64_t BusyonTime [ 4 ] = { 0 } ;
uint64_t BusyActivemS [ 4 ] = { 0 } ;
int AvPTT [ 4 ] = { 0 } ;
int AvBusy [ 4 ] = { 0 } ;
2023-09-04 19:06:44 +01:00
extern " C " void WriteDebugLog ( char * Mess )
{
qDebug ( ) < < Mess ;
}
void QtSoundModem : : doupdateDCD ( int Chan , int State )
{
DCDLabel [ Chan ] - > setVisible ( State ) ;
2024-10-29 22:45:21 +00:00
// This also tries to get a percentage on time over a minute
uint64_t Time = QDateTime : : currentMSecsSinceEpoch ( ) ;
if ( State )
{
BusyonTime [ Chan ] = Time ;
return ;
}
if ( BusyonTime [ Chan ] )
{
BusyActivemS [ Chan ] + = Time - BusyonTime [ Chan ] ;
BusyonTime [ Chan ] = 0 ;
}
2023-09-04 19:06:44 +01:00
}
extern " C " char * frame_monitor ( string * frame , char * code , bool tx_stat ) ;
extern " C " char * ShortDateTime ( ) ;
extern " C " void mon_rsid ( int snd_ch , char * RSID )
{
int Len ;
char * Msg = ( char * ) malloc ( 1024 ) ; // Cant pass local variable via signal/slot
sprintf ( Msg , " %d:%s [%s%c] " , snd_ch + 1 , RSID , ShortDateTime ( ) , ' R ' ) ;
Len = strlen ( Msg ) ;
if ( Msg [ Len - 1 ] ! = ' \r ' )
{
Msg [ Len + + ] = ' \r ' ;
Msg [ Len ] = 0 ;
}
emit t - > sendtoTrace ( Msg , 0 ) ;
}
extern " C " void put_frame ( int snd_ch , string * frame , char * code , int tx , int excluded )
{
UNUSED ( excluded ) ;
int Len ;
char * Msg = ( char * ) malloc ( 1024 ) ; // Cant pass local variable via signal/slot
if ( strcmp ( code , " NON-AX25 " ) = = 0 )
sprintf ( Msg , " %d: <NON-AX25 frame Len = %d [%s%c] \r " , snd_ch , frame - > Length , ShortDateTime ( ) , ' R ' ) ;
else
sprintf ( Msg , " %d:%s " , snd_ch + 1 , frame_monitor ( frame , code , tx ) ) ;
Len = strlen ( Msg ) ;
if ( Msg [ Len - 1 ] ! = ' \r ' )
{
Msg [ Len + + ] = ' \r ' ;
Msg [ Len ] = 0 ;
}
emit t - > sendtoTrace ( Msg , tx ) ;
}
extern " C " void updateDCD ( int Chan , bool State )
{
emit t - > updateDCD ( Chan , State ) ;
}
bool QtSoundModem : : eventFilter ( QObject * obj , QEvent * evt )
{
UNUSED ( obj ) ;
if ( evt - > type ( ) = = QEvent : : Resize )
{
return QWidget : : event ( evt ) ;
}
if ( evt - > type ( ) = = QEvent : : WindowStateChange )
{
if ( windowState ( ) . testFlag ( Qt : : WindowMinimized ) = = true )
w_state = WIN_MINIMIZED ;
else
w_state = WIN_MAXIMIZED ;
}
// if (evt->type() == QGuiApplication::applicationStateChanged) - this is a sigma;
// {
// qDebug() << "App State changed =" << evt->type() << endl;
// }
return QWidget : : event ( evt ) ;
}
void QtSoundModem : : resizeEvent ( QResizeEvent * event )
{
QMainWindow : : resizeEvent ( event ) ;
QRect r = geometry ( ) ;
2023-12-17 13:53:32 +00:00
int modemBoxHeight = 34 ;
int Width = r . width ( ) ;
int Height = r . height ( ) - 25 ;
int monitorTop ;
int monitorHeight ;
int sessionTop ;
int sessionHeight = 0 ;
int waterfallsTop ;
int waterfallsHeight = WaterfallImageHeight ;
2023-09-04 19:06:44 +01:00
ui . modeB - > setVisible ( soundChannel [ 1 ] ) ;
ui . centerB - > setVisible ( soundChannel [ 1 ] ) ;
ui . labelB - > setVisible ( soundChannel [ 1 ] ) ;
DCDLabel [ 1 ] - > setVisible ( soundChannel [ 1 ] ) ;
ui . RXOffsetB - > setVisible ( soundChannel [ 1 ] ) ;
ui . modeC - > setVisible ( soundChannel [ 2 ] ) ;
ui . centerC - > setVisible ( soundChannel [ 2 ] ) ;
ui . labelC - > setVisible ( soundChannel [ 2 ] ) ;
DCDLabel [ 2 ] - > setVisible ( soundChannel [ 2 ] ) ;
ui . RXOffsetC - > setVisible ( soundChannel [ 2 ] ) ;
ui . modeD - > setVisible ( soundChannel [ 3 ] ) ;
ui . centerD - > setVisible ( soundChannel [ 3 ] ) ;
ui . labelD - > setVisible ( soundChannel [ 3 ] ) ;
DCDLabel [ 3 ] - > setVisible ( soundChannel [ 3 ] ) ;
ui . RXOffsetD - > setVisible ( soundChannel [ 3 ] ) ;
if ( soundChannel [ 2 ] | | soundChannel [ 3 ] )
modemBoxHeight = 60 ;
2023-12-17 13:53:32 +00:00
ui . Waterfall - > setVisible ( 0 ) ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
monitorTop = modemBoxHeight + 1 ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
// Now have one waterfall label containing headers and waterfalls
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
if ( Firstwaterfall | | Secondwaterfall )
ui . Waterfall - > setVisible ( 1 ) ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
if ( AGWServ )
{
sessionTable - > setVisible ( true ) ;
sessionHeight = 150 ;
2023-09-04 19:06:44 +01:00
}
else
{
2023-12-17 13:53:32 +00:00
sessionTable - > setVisible ( false ) ;
}
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
// if only displaying one Waterfall, change height of waterfall area
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
if ( UsingBothChannels = = 0 | | ( Firstwaterfall = = 0 ) | | ( Secondwaterfall = = 0 ) )
{
waterfallsHeight / = 2 ;
2023-09-04 19:06:44 +01:00
}
2023-12-17 13:53:32 +00:00
if ( ( Firstwaterfall = = 0 ) & & ( Secondwaterfall = = 0 ) )
waterfallsHeight = 0 ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
monitorHeight = Height - sessionHeight - waterfallsHeight - modemBoxHeight ;
waterfallsTop = Height - waterfallsHeight ;
sessionTop = Height - ( sessionHeight + waterfallsHeight ) ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
ui . monWindow - > setGeometry ( QRect ( 0 , monitorTop , Width , monitorHeight ) ) ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
if ( AGWServ )
sessionTable - > setGeometry ( QRect ( 0 , sessionTop , Width , sessionHeight ) ) ;
if ( waterfallsHeight )
ui . Waterfall - > setGeometry ( QRect ( 0 , waterfallsTop , Width , waterfallsHeight + 2 ) ) ;
2023-09-04 19:06:44 +01:00
}
QAction * setupMenuLine ( QMenu * Menu , char * Label , QObject * parent , int State )
{
QAction * Act = new QAction ( Label , parent ) ;
Menu - > addAction ( Act ) ;
Act - > setCheckable ( true ) ;
if ( State )
Act - > setChecked ( true ) ;
parent - > connect ( Act , SIGNAL ( triggered ( ) ) , parent , SLOT ( menuChecked ( ) ) ) ;
return Act ;
}
void QtSoundModem : : menuChecked ( )
{
QAction * Act = static_cast < QAction * > ( QObject : : sender ( ) ) ;
int state = Act - > isChecked ( ) ;
if ( Act = = actWaterfall1 )
Firstwaterfall = state ;
else if ( Act = = actWaterfall2 )
Secondwaterfall = state ;
2023-12-17 13:53:32 +00:00
initWaterfall ( Firstwaterfall | Secondwaterfall ) ;
2023-09-04 19:06:44 +01:00
saveSettings ( ) ;
}
2023-12-17 13:53:32 +00:00
void QtSoundModem : : initWaterfall ( int state )
2023-09-04 19:06:44 +01:00
{
if ( state = = 1 )
{
2023-12-17 13:53:32 +00:00
// if (ui.Waterfall)
// {
// delete ui.Waterfall;
// ui.Waterfall = new QLabel(ui.centralWidget);
// }
WaterfallCopy = ui . Waterfall ;
Waterfall = new QImage ( 1024 , WaterfallImageHeight + 2 , QImage : : Format_RGB32 ) ;
NeedWaterfallHeaders = 1 ;
2023-09-04 19:06:44 +01:00
}
else
{
2023-12-17 13:53:32 +00:00
delete ( Waterfall ) ;
Waterfall = 0 ;
2023-09-04 19:06:44 +01:00
}
QSize Size ( 800 , 602 ) ; // Not actually used, but Event constructor needs it
2023-12-17 13:53:32 +00:00
2023-09-04 19:06:44 +01:00
QResizeEvent * event = new QResizeEvent ( Size , Size ) ;
QApplication : : sendEvent ( this , event ) ;
}
2023-09-12 21:38:15 +01:00
QRect PSKRect = { 100 , 100 , 100 , 100 } ;
QDialog * constellationDialog ;
QLabel * constellationLabel [ 4 ] ;
QLabel * QualLabel [ 4 ] ;
2023-09-04 19:06:44 +01:00
// Local copies
QLabel * RXOffsetLabel ;
QSlider * RXOffset ;
2023-10-07 12:21:48 +01:00
QFont Font ;
2023-09-12 21:38:15 +01:00
extern " C " void CheckPSKWindows ( )
{
NeedPSKRefresh = 1 ;
}
void DoPSKWindows ( )
{
// Display Constellation for PSK Window;
int NextX = 0 ;
int i ;
for ( i = 0 ; i < 4 ; i + + )
{
2024-04-13 17:48:58 +01:00
if ( soundChannel [ i ] & & pskStates [ i ] )
2023-09-12 21:38:15 +01:00
{
constellationLabel [ i ] - > setGeometry ( QRect ( NextX , 19 , 121 , 121 ) ) ;
QualLabel [ i ] - > setGeometry ( QRect ( 1 + NextX , 1 , 120 , 15 ) ) ;
constellationLabel [ i ] - > setVisible ( 1 ) ;
QualLabel [ i ] - > setVisible ( 1 ) ;
NextX + = 122 ;
}
else
{
constellationLabel [ i ] - > setVisible ( 0 ) ;
QualLabel [ i ] - > setVisible ( 0 ) ;
}
}
constellationDialog - > resize ( NextX , 140 ) ;
}
2023-12-17 13:53:32 +00:00
QTimer * wftimer ;
2024-07-23 21:26:30 +01:00
extern " C " struct timespec pttclk ;
2023-09-12 21:38:15 +01:00
2023-09-04 19:06:44 +01:00
QtSoundModem : : QtSoundModem ( QWidget * parent ) : QMainWindow ( parent )
{
2023-10-07 12:21:48 +01:00
QString family ;
int csize ;
QFont : : Weight weight ;
2024-07-23 21:26:30 +01:00
# ifndef WIN32
clock_getres ( CLOCK_MONOTONIC , & pttclk ) ;
printf ( " CLOCK_MONOTONIC %d, %d \n " , pttclk . tv_sec , pttclk . tv_nsec ) ;
# endif
2023-09-04 19:06:44 +01:00
ui . setupUi ( this ) ;
2023-10-07 12:21:48 +01:00
mythis = this ;
2023-12-17 13:53:32 +00:00
getSettings ( ) ;
2024-10-29 22:45:21 +00:00
serial = new serialThread ;
2023-09-04 19:06:44 +01:00
QSettings mysettings ( " QtSoundModem.ini " , QSettings : : IniFormat ) ;
2023-10-07 12:21:48 +01:00
family = mysettings . value ( " FontFamily " , " Courier New " ) . toString ( ) ;
csize = mysettings . value ( " PointSize " , 0 ) . toInt ( ) ;
weight = ( QFont : : Weight ) mysettings . value ( " Weight " , 50 ) . toInt ( ) ;
Font = QFont ( family ) ;
Font . setPointSize ( csize ) ;
Font . setWeight ( weight ) ;
QApplication : : setFont ( Font ) ;
2023-09-12 21:38:15 +01:00
constellationDialog = new QDialog ( nullptr , Qt : : WindowTitleHint | Qt : : WindowSystemMenuHint ) ;
constellationDialog - > resize ( 488 , 140 ) ;
constellationDialog - > setGeometry ( PSKRect ) ;
QFont f ( " Arial " , 8 , QFont : : Normal ) ;
for ( int i = 0 ; i < 4 ; i + + )
{
char Text [ 16 ] ;
sprintf ( Text , " Chan %c " , i + ' A ' ) ;
constellationLabel [ i ] = new QLabel ( constellationDialog ) ;
constellationDialog - > setWindowTitle ( " PSK Constellations " ) ;
QualLabel [ i ] = new QLabel ( constellationDialog ) ;
QualLabel [ i ] - > setText ( Text ) ;
QualLabel [ i ] - > setFont ( f ) ;
Constellation [ i ] = new QImage ( 121 , 121 , QImage : : Format_RGB32 ) ;
Constellation [ i ] - > fill ( black ) ;
constellationLabel [ i ] - > setPixmap ( QPixmap : : fromImage ( * Constellation [ i ] ) ) ;
}
constellationDialog - > show ( ) ;
2023-09-04 19:06:44 +01:00
if ( MintoTray )
{
char popUp [ 256 ] ;
sprintf ( popUp , " QtSoundModem %d %d " , AGWPort , KISSPort ) ;
trayIcon = new QSystemTrayIcon ( QIcon ( " :/QtSoundModem/soundmodem.ico " ) , this ) ;
trayIcon - > setToolTip ( popUp ) ;
trayIcon - > show ( ) ;
2023-09-12 21:38:15 +01:00
2023-09-04 19:06:44 +01:00
connect ( trayIcon , SIGNAL ( activated ( QSystemTrayIcon : : ActivationReason ) ) , this , SLOT ( TrayActivated ( QSystemTrayIcon : : ActivationReason ) ) ) ;
}
2023-09-12 21:38:15 +01:00
using48000 = 0 ; // Set if using 48K sample rate (ie RUH Modem active)
ReceiveSize = 512 ;
SendSize = 1024 ; // 100 mS for now
for ( int i = 0 ; i < 4 ; i + + )
{
if ( soundChannel [ i ] & & ( speed [ i ] = = SPEED_RUH48 | | speed [ i ] = = SPEED_RUH96 ) )
{
using48000 = 1 ; // Set if using 48K sample rate (ie RUH Modem active)
ReceiveSize = 2048 ;
SendSize = 4096 ; // 100 mS for now
}
}
2023-09-04 19:06:44 +01:00
float FFTCalc = 12000.0f / ( ( WaterfallMax - WaterfallMin ) / 900.0f ) ;
FFTSize = FFTCalc + 0.4999 ;
if ( FFTSize > 8191 )
FFTSize = 8190 ;
if ( FFTSize & 1 ) // odd
FFTSize - - ;
BinSize = 12000.0 / FFTSize ;
restoreGeometry ( mysettings . value ( " geometry " ) . toByteArray ( ) ) ;
restoreState ( mysettings . value ( " windowState " ) . toByteArray ( ) ) ;
2023-12-17 13:53:32 +00:00
sessionTable = new QTableWidget ( ui . centralWidget ) ;
2023-09-04 19:06:44 +01:00
sessionTable - > verticalHeader ( ) - > setVisible ( FALSE ) ;
sessionTable - > verticalHeader ( ) - > setDefaultSectionSize ( 20 ) ;
sessionTable - > horizontalHeader ( ) - > setDefaultSectionSize ( 68 ) ;
sessionTable - > setRowCount ( 1 ) ;
sessionTable - > setColumnCount ( 12 ) ;
m_TableHeader < < " MyCall " < < " DestCall " < < " Status " < < " Sent pkts " < < " Sent Bytes " < < " Rcvd pkts " < < " Rcvd bytes " < < " Rcvd FC " < < " FEC corr " < < " CPS TX " < < " CPS RX " < < " Direction " ;
2023-12-17 13:53:32 +00:00
mysetstyle ( ) ;
2023-09-04 19:06:44 +01:00
sessionTable - > setHorizontalHeaderLabels ( m_TableHeader ) ;
sessionTable - > setColumnWidth ( 0 , 80 ) ;
sessionTable - > setColumnWidth ( 1 , 80 ) ;
sessionTable - > setColumnWidth ( 4 , 76 ) ;
sessionTable - > setColumnWidth ( 5 , 76 ) ;
sessionTable - > setColumnWidth ( 6 , 80 ) ;
sessionTable - > setColumnWidth ( 11 , 72 ) ;
for ( int i = 0 ; i < modes_count ; i + + )
{
ui . modeA - > addItem ( modes_name [ i ] ) ;
ui . modeB - > addItem ( modes_name [ i ] ) ;
ui . modeC - > addItem ( modes_name [ i ] ) ;
ui . modeD - > addItem ( modes_name [ i ] ) ;
}
// Set up Menus
setupMenu = ui . menuBar - > addMenu ( tr ( " Settings " ) ) ;
actDevices = new QAction ( " Setup Devices " , this ) ;
setupMenu - > addAction ( actDevices ) ;
connect ( actDevices , SIGNAL ( triggered ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
actDevices - > setObjectName ( " actDevices " ) ;
actModems = new QAction ( " Setup Modems " , this ) ;
actModems - > setObjectName ( " actModems " ) ;
setupMenu - > addAction ( actModems ) ;
connect ( actModems , SIGNAL ( triggered ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
2023-10-07 12:21:48 +01:00
actFont = new QAction ( " Setup Font " , this ) ;
actFont - > setObjectName ( " actFont " ) ;
setupMenu - > addAction ( actFont ) ;
connect ( actFont , SIGNAL ( triggered ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
2023-09-04 19:06:44 +01:00
actMintoTray = setupMenu - > addAction ( " Minimize to Tray " , this , SLOT ( MinimizetoTray ( ) ) ) ;
actMintoTray - > setCheckable ( 1 ) ;
actMintoTray - > setChecked ( MintoTray ) ;
viewMenu = ui . menuBar - > addMenu ( tr ( " &View " ) ) ;
actWaterfall1 = setupMenuLine ( viewMenu , ( char * ) " First waterfall " , this , Firstwaterfall ) ;
actWaterfall2 = setupMenuLine ( viewMenu , ( char * ) " Second Waterfall " , this , Secondwaterfall ) ;
actCalib = ui . menuBar - > addAction ( " &Calibration " ) ;
connect ( actCalib , SIGNAL ( triggered ( ) ) , this , SLOT ( doCalibrate ( ) ) ) ;
actRestartWF = ui . menuBar - > addAction ( " Restart Waterfall " ) ;
connect ( actRestartWF , SIGNAL ( triggered ( ) ) , this , SLOT ( doRestartWF ( ) ) ) ;
actAbout = ui . menuBar - > addAction ( " &About " ) ;
connect ( actAbout , SIGNAL ( triggered ( ) ) , this , SLOT ( doAbout ( ) ) ) ;
RXLevel = new QImage ( 150 , 10 , QImage : : Format_RGB32 ) ;
2023-10-07 12:21:48 +01:00
RXLevel - > fill ( white ) ;
ui . RXLevel - > setPixmap ( QPixmap : : fromImage ( * RXLevel ) ) ;
RXLevelCopy = ui . RXLevel ;
2024-04-13 17:48:58 +01:00
RXLevel2 = new QImage ( 150 , 10 , QImage : : Format_RGB32 ) ;
RXLevel2 - > fill ( white ) ;
ui . RXLevel2 - > setPixmap ( QPixmap : : fromImage ( * RXLevel2 ) ) ;
RXLevel2Copy = ui . RXLevel2 ;
2023-09-04 19:06:44 +01:00
DCDLabel [ 0 ] = new QLabel ( this ) ;
DCDLabel [ 0 ] - > setObjectName ( QString : : fromUtf8 ( " DCDLedA " ) ) ;
DCDLabel [ 0 ] - > setGeometry ( QRect ( 280 , 31 , 12 , 12 ) ) ;
DCDLabel [ 0 ] - > setVisible ( TRUE ) ;
DCDLabel [ 1 ] = new QLabel ( this ) ;
DCDLabel [ 1 ] - > setObjectName ( QString : : fromUtf8 ( " DCDLedB " ) ) ;
DCDLabel [ 1 ] - > setGeometry ( QRect ( 575 , 31 , 12 , 12 ) ) ;
DCDLabel [ 1 ] - > setVisible ( TRUE ) ;
DCDLabel [ 2 ] = new QLabel ( this ) ;
DCDLabel [ 2 ] - > setObjectName ( QString : : fromUtf8 ( " DCDLedC " ) ) ;
DCDLabel [ 2 ] - > setGeometry ( QRect ( 280 , 61 , 12 , 12 ) ) ;
DCDLabel [ 2 ] - > setVisible ( FALSE ) ;
DCDLabel [ 3 ] = new QLabel ( this ) ;
DCDLabel [ 3 ] - > setObjectName ( QString : : fromUtf8 ( " DCDLedD " ) ) ;
DCDLabel [ 3 ] - > setGeometry ( QRect ( 575 , 61 , 12 , 12 ) ) ;
DCDLabel [ 3 ] - > setVisible ( FALSE ) ;
DCDLed [ 0 ] = new QImage ( 12 , 12 , QImage : : Format_RGB32 ) ;
DCDLed [ 1 ] = new QImage ( 12 , 12 , QImage : : Format_RGB32 ) ;
DCDLed [ 2 ] = new QImage ( 12 , 12 , QImage : : Format_RGB32 ) ;
DCDLed [ 3 ] = new QImage ( 12 , 12 , QImage : : Format_RGB32 ) ;
DCDLed [ 0 ] - > fill ( red ) ;
DCDLed [ 1 ] - > fill ( red ) ;
DCDLed [ 2 ] - > fill ( red ) ;
DCDLed [ 3 ] - > fill ( red ) ;
DCDLabel [ 0 ] - > setPixmap ( QPixmap : : fromImage ( * DCDLed [ 0 ] ) ) ;
DCDLabel [ 1 ] - > setPixmap ( QPixmap : : fromImage ( * DCDLed [ 1 ] ) ) ;
DCDLabel [ 2 ] - > setPixmap ( QPixmap : : fromImage ( * DCDLed [ 2 ] ) ) ;
DCDLabel [ 3 ] - > setPixmap ( QPixmap : : fromImage ( * DCDLed [ 3 ] ) ) ;
chanOffsetLabel [ 0 ] = ui . RXOffsetA ;
chanOffsetLabel [ 1 ] = ui . RXOffsetB ;
chanOffsetLabel [ 2 ] = ui . RXOffsetC ;
chanOffsetLabel [ 3 ] = ui . RXOffsetD ;
2023-12-17 13:53:32 +00:00
WaterfallCopy = ui . Waterfall ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
initWaterfall ( Firstwaterfall | Secondwaterfall ) ;
2023-09-04 19:06:44 +01:00
monWindowCopy = ui . monWindow ;
ui . monWindow - > document ( ) - > setMaximumBlockCount ( 10000 ) ;
// connect(ui.monWindow, SIGNAL(selectionChanged()), this, SLOT(onTEselectionChanged()));
connect ( ui . modeA , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( clickedSlotI ( int ) ) ) ;
connect ( ui . modeB , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( clickedSlotI ( int ) ) ) ;
connect ( ui . modeC , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( clickedSlotI ( int ) ) ) ;
connect ( ui . modeD , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( clickedSlotI ( int ) ) ) ;
2023-09-12 21:38:15 +01:00
ModemA = speed [ 0 ] ;
ModemB = speed [ 1 ] ;
ModemC = speed [ 2 ] ;
ModemD = speed [ 3 ] ;
2023-09-04 19:06:44 +01:00
ui . modeA - > setCurrentIndex ( speed [ 0 ] ) ;
ui . modeB - > setCurrentIndex ( speed [ 1 ] ) ;
ui . modeC - > setCurrentIndex ( speed [ 2 ] ) ;
ui . modeD - > setCurrentIndex ( speed [ 3 ] ) ;
ModemA = ui . modeA - > currentIndex ( ) ;
ui . centerA - > setValue ( rx_freq [ 0 ] ) ;
ui . centerB - > setValue ( rx_freq [ 1 ] ) ;
ui . centerC - > setValue ( rx_freq [ 2 ] ) ;
ui . centerD - > setValue ( rx_freq [ 3 ] ) ;
connect ( ui . centerA , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( clickedSlotI ( int ) ) ) ;
connect ( ui . centerB , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( clickedSlotI ( int ) ) ) ;
connect ( ui . centerC , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( clickedSlotI ( int ) ) ) ;
connect ( ui . centerD , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( clickedSlotI ( int ) ) ) ;
ui . DCDSlider - > setValue ( dcd_threshold ) ;
char valChar [ 32 ] ;
sprintf ( valChar , " RX Offset %d " , rxOffset ) ;
ui . RXOffsetLabel - > setText ( valChar ) ;
ui . RXOffset - > setValue ( rxOffset ) ;
RXOffsetLabel = ui . RXOffsetLabel ;
RXOffset = ui . RXOffset ;
connect ( ui . DCDSlider , SIGNAL ( sliderMoved ( int ) ) , this , SLOT ( clickedSlotI ( int ) ) ) ;
connect ( ui . RXOffset , SIGNAL ( valueChanged ( int ) ) , this , SLOT ( clickedSlotI ( int ) ) ) ;
QObject : : connect ( t , SIGNAL ( sendtoTrace ( char * , int ) ) , this , SLOT ( sendtoTrace ( char * , int ) ) , Qt : : QueuedConnection ) ;
QObject : : connect ( t , SIGNAL ( updateDCD ( int , int ) ) , this , SLOT ( doupdateDCD ( int , int ) ) , Qt : : QueuedConnection ) ;
2023-10-07 12:21:48 +01:00
QObject : : connect ( t , SIGNAL ( startCWIDTimer ( ) ) , this , SLOT ( startCWIDTimerSlot ( ) ) , Qt : : QueuedConnection ) ;
2024-07-23 21:26:30 +01:00
QObject : : connect ( t , SIGNAL ( setWaterfallImage ( ) ) , this , SLOT ( setWaterfallImage ( ) ) , Qt : : QueuedConnection ) ;
QObject : : connect ( t , SIGNAL ( setLevelImage ( ) ) , this , SLOT ( setLevelImage ( ) ) , Qt : : QueuedConnection ) ;
QObject : : connect ( t , SIGNAL ( setConstellationImage ( int , int ) ) , this , SLOT ( setConstellationImage ( int , int ) ) , Qt : : QueuedConnection ) ;
QObject : : connect ( t , SIGNAL ( startWatchdog ( ) ) , this , SLOT ( StartWatchdog ( ) ) , Qt : : QueuedConnection ) ;
QObject : : connect ( t , SIGNAL ( stopWatchdog ( ) ) , this , SLOT ( StopWatchdog ( ) ) , Qt : : QueuedConnection ) ;
2023-10-07 12:21:48 +01:00
2023-09-04 19:06:44 +01:00
connect ( ui . RXOffsetA , SIGNAL ( returnPressed ( ) ) , this , SLOT ( returnPressed ( ) ) ) ;
connect ( ui . RXOffsetB , SIGNAL ( returnPressed ( ) ) , this , SLOT ( returnPressed ( ) ) ) ;
connect ( ui . RXOffsetC , SIGNAL ( returnPressed ( ) ) , this , SLOT ( returnPressed ( ) ) ) ;
connect ( ui . RXOffsetD , SIGNAL ( returnPressed ( ) ) , this , SLOT ( returnPressed ( ) ) ) ;
QTimer * timer = new QTimer ( this ) ;
connect ( timer , SIGNAL ( timeout ( ) ) , this , SLOT ( MyTimerSlot ( ) ) ) ;
timer - > start ( 100 ) ;
2024-10-29 22:45:21 +00:00
QTimer * statstimer = new QTimer ( this ) ;
connect ( statstimer , SIGNAL ( timeout ( ) ) , this , SLOT ( StatsTimer ( ) ) ) ;
statstimer - > start ( 60000 ) ; // One Minute
2023-12-17 13:53:32 +00:00
wftimer = new QTimer ( this ) ;
2023-09-12 21:38:15 +01:00
connect ( wftimer , SIGNAL ( timeout ( ) ) , this , SLOT ( doRestartWF ( ) ) ) ;
2024-07-23 21:26:30 +01:00
// wftimer->start(1000 * 300);
2023-09-04 19:06:44 +01:00
cwidtimer = new QTimer ( this ) ;
connect ( cwidtimer , SIGNAL ( timeout ( ) ) , this , SLOT ( CWIDTimer ( ) ) ) ;
2024-07-23 21:26:30 +01:00
PTTWatchdog = new QTimer ( this ) ;
connect ( PTTWatchdog , SIGNAL ( timeout ( ) ) , this , SLOT ( PTTWatchdogExpired ( ) ) ) ;
2023-10-07 12:21:48 +01:00
if ( CWIDInterval & & afterTraffic = = false )
2023-09-04 19:06:44 +01:00
cwidtimer - > start ( CWIDInterval * 60000 ) ;
if ( RSID_SetModem [ 0 ] )
{
RSID_WF = 1 ;
RSIDinitfft ( ) ;
}
2023-10-07 12:21:48 +01:00
// il2p_init(1);
QTimer : : singleShot ( 200 , this , & QtSoundModem : : updateFont ) ;
2024-10-29 22:45:21 +00:00
connect ( serial , & serialThread : : request , this , & QtSoundModem : : showRequest ) ;
2023-10-07 12:21:48 +01:00
}
void QtSoundModem : : updateFont ( )
{
QApplication : : setFont ( Font ) ;
2023-09-04 19:06:44 +01:00
}
void QtSoundModem : : MinimizetoTray ( )
{
MintoTray = actMintoTray - > isChecked ( ) ;
saveSettings ( ) ;
QMessageBox : : about ( this , tr ( " QtSoundModem " ) ,
tr ( " Program must be restarted to change Minimize mode " ) ) ;
}
void QtSoundModem : : TrayActivated ( QSystemTrayIcon : : ActivationReason reason )
{
if ( reason = = 3 )
{
showNormal ( ) ;
w - > setWindowState ( ( w - > windowState ( ) & ~ Qt : : WindowMinimized ) | Qt : : WindowActive ) ;
}
}
extern " C " void sendCWID ( char * strID , BOOL blnPlay , int Chan ) ;
2023-10-07 12:21:48 +01:00
extern " C " void checkforCWID ( )
{
emit ( t - > startCWIDTimer ( ) ) ;
} ;
extern " C " void QtSoundModem : : startCWIDTimerSlot ( )
{
if ( CWIDInterval & & afterTraffic = = 1 & & cwidtimerisActive = = false )
{
cwidtimerisActive = true ;
QTimer : : singleShot ( CWIDInterval * 60000 , this , & QtSoundModem : : CWIDTimer ) ;
}
}
2023-09-04 19:06:44 +01:00
void QtSoundModem : : CWIDTimer ( )
{
2023-10-07 12:21:48 +01:00
cwidtimerisActive = false ;
2023-09-04 19:06:44 +01:00
sendCWID ( CWIDCall , CWIDType , 0 ) ;
calib_mode [ 0 ] = 4 ;
}
void extSetOffset ( int chan )
{
char valChar [ 32 ] ;
sprintf ( valChar , " %d " , chanOffset [ chan ] ) ;
chanOffsetLabel [ chan ] - > setText ( valChar ) ;
2023-12-17 13:53:32 +00:00
NeedWaterfallHeaders = true ;
2023-09-04 19:06:44 +01:00
pnt_change [ 0 ] = 1 ;
pnt_change [ 1 ] = 1 ;
pnt_change [ 2 ] = 1 ;
pnt_change [ 3 ] = 1 ;
return ;
}
2024-10-29 22:45:21 +00:00
extern TMgmtMode * * MgmtConnections ;
extern int MgmtConCount ;
extern QList < QTcpSocket * > _MgmtSockets ;
extern " C " void doAGW2MinTimer ( ) ;
# define FEND 0xc0
# define QTSMKISSCMD 7
int AGW2MinTimer = 0 ;
void QtSoundModem : : StatsTimer ( )
{
// Calculate % Busy over last minute
for ( int n = 0 ; n < 4 ; n + + )
{
if ( soundChannel [ n ] = = 0 ) // Channel not used
continue ;
AvPTT [ n ] = PTTActivemS [ n ] / 600 ; // ms but want %
PTTActivemS [ n ] = 0 ;
AvBusy [ n ] = BusyActivemS [ n ] / 600 ;
BusyActivemS [ n ] = 0 ;
2023-09-04 19:06:44 +01:00
2024-10-29 22:45:21 +00:00
// send to any connected Mgmt streams
char Msg [ 64 ] ;
uint64_t ret ;
if ( ! useKISSControls )
{
for ( QTcpSocket * socket : _MgmtSockets )
{
// Find Session
TMgmtMode * MGMT = NULL ;
for ( int i = 0 ; i < MgmtConCount ; i + + )
{
if ( MgmtConnections [ i ] - > Socket = = socket )
{
MGMT = MgmtConnections [ i ] ;
break ;
}
}
if ( MGMT = = NULL )
continue ;
if ( MGMT - > BPQPort [ n ] )
{
sprintf ( Msg , " STATS %d %d %d \r " , MGMT - > BPQPort [ n ] , AvPTT [ n ] , AvBusy [ n ] ) ;
ret = socket - > write ( Msg ) ;
}
}
}
else // useKISSControls set
{
UCHAR * Control = ( UCHAR * ) malloc ( 32 ) ;
int len = sprintf ( ( char * ) Control , " %c%cSTATS %d %d%c " , FEND , ( n ) < < 4 | QTSMKISSCMD , AvPTT [ n ] , AvBusy [ n ] , FEND ) ;
KISSSendtoServer ( NULL , Control , len ) ;
}
}
AGW2MinTimer + + ;
if ( AGW2MinTimer > 1 )
{
AGW2MinTimer = 0 ;
doAGW2MinTimer ( ) ;
}
}
// PTT Stats
extern " C " void UpdatePTTStats ( int Chan , int State )
{
uint64_t Time = QDateTime : : currentMSecsSinceEpoch ( ) ;
if ( State )
{
PTTonTime [ Chan ] = Time ;
// Cancel Busy timer (stats include ptt on time in port active
if ( BusyonTime [ Chan ] )
{
BusyActivemS [ Chan ] + = ( Time - BusyonTime [ Chan ] ) ;
BusyonTime [ Chan ] = 0 ;
}
}
else
{
if ( PTTonTime [ Chan ] )
{
PTTActivemS [ Chan ] + = ( Time - PTTonTime [ Chan ] ) ;
PTTonTime [ Chan ] = 0 ;
}
}
}
2023-09-04 19:06:44 +01:00
void QtSoundModem : : MyTimerSlot ( )
{
// 100 mS Timer Event
for ( int i = 0 ; i < 4 ; i + + )
{
if ( needSetOffset [ i ] )
{
needSetOffset [ i ] = 0 ;
extSetOffset ( i ) ; // Update GUI
}
}
if ( refreshModems )
{
refreshModems = 0 ;
ui . modeA - > setCurrentIndex ( speed [ 0 ] ) ;
ui . modeB - > setCurrentIndex ( speed [ 1 ] ) ;
ui . modeC - > setCurrentIndex ( speed [ 2 ] ) ;
ui . modeD - > setCurrentIndex ( speed [ 3 ] ) ;
ui . centerA - > setValue ( rx_freq [ 0 ] ) ;
ui . centerB - > setValue ( rx_freq [ 1 ] ) ;
ui . centerC - > setValue ( rx_freq [ 2 ] ) ;
ui . centerD - > setValue ( rx_freq [ 3 ] ) ;
}
2023-09-12 21:38:15 +01:00
if ( NeedPSKRefresh )
{
NeedPSKRefresh = 0 ;
DoPSKWindows ( ) ;
}
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
if ( NeedWaterfallHeaders )
{
NeedWaterfallHeaders = 0 ;
if ( Waterfall )
{
Waterfall - > fill ( black ) ;
DrawModemFreqRange ( ) ;
DrawFreqTicks ( ) ;
}
}
2023-09-04 19:06:44 +01:00
show_grid ( ) ;
}
void QtSoundModem : : returnPressed ( )
{
char Name [ 32 ] ;
int Chan ;
QString val ;
strcpy ( Name , sender ( ) - > objectName ( ) . toUtf8 ( ) ) ;
Chan = Name [ 8 ] - ' A ' ;
val = chanOffsetLabel [ Chan ] - > text ( ) ;
chanOffset [ Chan ] = val . toInt ( ) ;
needSetOffset [ Chan ] = 1 ; // Update GUI
}
2023-09-12 21:38:15 +01:00
void CheckforChanges ( int Mode , int OldMode )
{
int old48000 = using48000 ;
if ( OldMode ! = Mode & & Mode = = 15 )
{
QMessageBox msgBox ;
msgBox . setText ( " Warning!! \n ARDOP Packet is NOT the same as ARDOP \n "
" It is an experimental mode for sending ax.25 frames using ARDOP packet formats \n " ) ;
msgBox . setStandardButtons ( QMessageBox : : Ok ) ;
msgBox . exec ( ) ;
}
// See if need to switch beween 12000 and 48000
using48000 = 0 ; // Set if using 48K sample rate (ie RUH Modem active)
ReceiveSize = 512 ;
SendSize = 1024 ; // 100 mS for now
for ( int i = 0 ; i < 4 ; i + + )
{
if ( soundChannel [ i ] & & ( speed [ i ] = = SPEED_RUH48 | | speed [ i ] = = SPEED_RUH96 ) )
{
using48000 = 1 ; // Set if using 48K sample rate (ie RUH Modem active)
ReceiveSize = 2048 ;
SendSize = 4096 ; // 100 mS for now
}
}
if ( using48000 ! = old48000 )
{
InitSound ( 1 ) ;
}
}
2023-09-04 19:06:44 +01:00
void QtSoundModem : : clickedSlotI ( int i )
{
char Name [ 32 ] ;
strcpy ( Name , sender ( ) - > objectName ( ) . toUtf8 ( ) ) ;
if ( strcmp ( Name , " modeA " ) = = 0 )
{
2023-09-12 21:38:15 +01:00
int OldModem = ModemA ;
2023-09-04 19:06:44 +01:00
ModemA = ui . modeA - > currentIndex ( ) ;
set_speed ( 0 , ModemA ) ;
2023-09-12 21:38:15 +01:00
CheckforChanges ( ModemA , OldModem ) ;
2023-09-04 19:06:44 +01:00
saveSettings ( ) ;
AGW_Report_Modem_Change ( 0 ) ;
return ;
}
if ( strcmp ( Name , " modeB " ) = = 0 )
{
2023-09-12 21:38:15 +01:00
int OldModem = ModemB ;
2023-09-04 19:06:44 +01:00
ModemB = ui . modeB - > currentIndex ( ) ;
set_speed ( 1 , ModemB ) ;
2023-09-12 21:38:15 +01:00
CheckforChanges ( ModemB , OldModem ) ;
2023-09-04 19:06:44 +01:00
saveSettings ( ) ;
AGW_Report_Modem_Change ( 1 ) ;
return ;
}
if ( strcmp ( Name , " modeC " ) = = 0 )
{
2023-09-12 21:38:15 +01:00
int OldModem = ModemC ;
2023-09-04 19:06:44 +01:00
ModemC = ui . modeC - > currentIndex ( ) ;
set_speed ( 2 , ModemC ) ;
2023-09-12 21:38:15 +01:00
CheckforChanges ( ModemC , OldModem ) ;
2023-09-04 19:06:44 +01:00
saveSettings ( ) ;
AGW_Report_Modem_Change ( 2 ) ;
return ;
}
if ( strcmp ( Name , " modeD " ) = = 0 )
{
2023-09-12 21:38:15 +01:00
int OldModem = ModemD ;
2023-09-04 19:06:44 +01:00
ModemD = ui . modeD - > currentIndex ( ) ;
set_speed ( 3 , ModemD ) ;
2023-09-12 21:38:15 +01:00
CheckforChanges ( ModemD , OldModem ) ;
2023-09-04 19:06:44 +01:00
saveSettings ( ) ;
AGW_Report_Modem_Change ( 3 ) ;
return ;
}
if ( strcmp ( Name , " centerA " ) = = 0 )
{
2023-09-12 21:38:15 +01:00
if ( i > 299 )
2023-09-04 19:06:44 +01:00
{
QSettings * settings = new QSettings ( " QtSoundModem.ini " , QSettings : : IniFormat ) ;
ui . centerA - > setValue ( Freq_Change ( 0 , i ) ) ;
settings - > setValue ( " Modem/RXFreq1 " , ui . centerA - > value ( ) ) ;
AGW_Report_Modem_Change ( 0 ) ;
}
return ;
}
if ( strcmp ( Name , " centerB " ) = = 0 )
{
2024-07-23 21:26:30 +01:00
if ( i > 300 )
2023-09-04 19:06:44 +01:00
{
QSettings * settings = new QSettings ( " QtSoundModem.ini " , QSettings : : IniFormat ) ;
ui . centerB - > setValue ( Freq_Change ( 1 , i ) ) ;
settings - > setValue ( " Modem/RXFreq2 " , ui . centerB - > value ( ) ) ;
AGW_Report_Modem_Change ( 1 ) ;
}
return ;
}
if ( strcmp ( Name , " centerC " ) = = 0 )
{
2023-09-12 21:38:15 +01:00
if ( i > 299 )
2023-09-04 19:06:44 +01:00
{
QSettings * settings = new QSettings ( " QtSoundModem.ini " , QSettings : : IniFormat ) ;
ui . centerC - > setValue ( Freq_Change ( 2 , i ) ) ;
settings - > setValue ( " Modem/RXFreq3 " , ui . centerC - > value ( ) ) ;
AGW_Report_Modem_Change ( 2 ) ;
}
return ;
}
if ( strcmp ( Name , " centerD " ) = = 0 )
{
2023-09-12 21:38:15 +01:00
if ( i > 299 )
2023-09-04 19:06:44 +01:00
{
QSettings * settings = new QSettings ( " QtSoundModem.ini " , QSettings : : IniFormat ) ;
ui . centerD - > setValue ( Freq_Change ( 3 , i ) ) ;
settings - > setValue ( " Modem/RXFreq4 " , ui . centerD - > value ( ) ) ;
AGW_Report_Modem_Change ( 3 ) ;
}
return ;
}
if ( strcmp ( Name , " DCDSlider " ) = = 0 )
{
dcd_threshold = i ;
2024-10-29 22:45:21 +00:00
BusyDet = i / 10 ; // for ardop busy detect code
2023-09-04 19:06:44 +01:00
saveSettings ( ) ;
return ;
}
if ( strcmp ( Name , " RXOffset " ) = = 0 )
{
char valChar [ 32 ] ;
rxOffset = i ;
sprintf ( valChar , " RX Offset %d " , rxOffset ) ;
ui . RXOffsetLabel - > setText ( valChar ) ;
2023-12-17 13:53:32 +00:00
NeedWaterfallHeaders = true ;
2023-09-04 19:06:44 +01:00
pnt_change [ 0 ] = 1 ;
pnt_change [ 1 ] = 1 ;
pnt_change [ 2 ] = 1 ;
pnt_change [ 3 ] = 1 ;
saveSettings ( ) ;
return ;
}
QMessageBox msgBox ;
msgBox . setWindowTitle ( " MessageBox Title " ) ;
msgBox . setText ( " You Clicked " + ( ( QPushButton * ) sender ( ) ) - > objectName ( ) ) ;
msgBox . exec ( ) ;
}
void QtSoundModem : : clickedSlot ( )
{
char Name [ 32 ] ;
strcpy ( Name , sender ( ) - > objectName ( ) . toUtf8 ( ) ) ;
if ( strcmp ( Name , " actDevices " ) = = 0 )
{
doDevices ( ) ;
return ;
}
if ( strcmp ( Name , " actModems " ) = = 0 )
{
doModems ( ) ;
return ;
}
if ( strcmp ( Name , " showBPF_A " ) = = 0 )
{
doFilter ( 0 , 0 ) ;
return ;
}
if ( strcmp ( Name , " showTXBPF_A " ) = = 0 )
{
doFilter ( 0 , 1 ) ;
return ;
}
if ( strcmp ( Name , " showLPF_A " ) = = 0 )
{
doFilter ( 0 , 2 ) ;
return ;
}
if ( strcmp ( Name , " showBPF_B " ) = = 0 )
{
doFilter ( 1 , 0 ) ;
return ;
}
if ( strcmp ( Name , " showTXBPF_B " ) = = 0 )
{
doFilter ( 1 , 1 ) ;
return ;
}
if ( strcmp ( Name , " showLPF_B " ) = = 0 )
{
doFilter ( 1 , 2 ) ;
return ;
}
if ( strcmp ( Name , " Low_A " ) = = 0 )
{
handleButton ( 0 , 1 ) ;
return ;
}
if ( strcmp ( Name , " High_A " ) = = 0 )
{
handleButton ( 0 , 2 ) ;
return ;
}
if ( strcmp ( Name , " Both_A " ) = = 0 )
{
handleButton ( 0 , 3 ) ;
return ;
}
if ( strcmp ( Name , " Stop_A " ) = = 0 )
{
handleButton ( 0 , 0 ) ;
return ;
}
if ( strcmp ( Name , " Low_B " ) = = 0 )
{
handleButton ( 1 , 1 ) ;
return ;
}
if ( strcmp ( Name , " High_B " ) = = 0 )
{
handleButton ( 1 , 2 ) ;
return ;
}
if ( strcmp ( Name , " Both_B " ) = = 0 )
{
handleButton ( 1 , 3 ) ;
return ;
}
if ( strcmp ( Name , " Stop_B " ) = = 0 )
{
handleButton ( 1 , 0 ) ;
return ;
}
if ( strcmp ( Name , " Low_C " ) = = 0 )
{
handleButton ( 2 , 1 ) ;
return ;
}
if ( strcmp ( Name , " High_C " ) = = 0 )
{
handleButton ( 2 , 2 ) ;
return ;
}
if ( strcmp ( Name , " Both_C " ) = = 0 )
{
handleButton ( 2 , 3 ) ;
return ;
}
if ( strcmp ( Name , " Stop_C " ) = = 0 )
{
handleButton ( 2 , 0 ) ;
return ;
}
if ( strcmp ( Name , " Low_D " ) = = 0 )
{
handleButton ( 3 , 1 ) ;
return ;
}
if ( strcmp ( Name , " High_D " ) = = 0 )
{
handleButton ( 3 , 2 ) ;
return ;
}
if ( strcmp ( Name , " Both_D " ) = = 0 )
{
handleButton ( 3 , 3 ) ;
return ;
}
if ( strcmp ( Name , " Stop_D " ) = = 0 )
{
handleButton ( 3 , 0 ) ;
return ;
}
2024-10-29 22:45:21 +00:00
if ( strcmp ( Name , " Cal1500 " ) = = 0 )
{
char call [ ] = " 1500TONE " ;
sendCWID ( call , 0 , 0 ) ;
calib_mode [ 0 ] = 4 ;
return ;
}
2023-10-07 12:21:48 +01:00
if ( strcmp ( Name , " actFont " ) = = 0 )
{
bool ok ;
Font = QFontDialog : : getFont ( & ok , QFont ( Font , this ) ) ;
2023-12-17 13:53:32 +00:00
2023-10-07 12:21:48 +01:00
if ( ok )
{
// the user clicked OK and font is set to the font the user selected
QApplication : : setFont ( Font ) ;
2023-12-17 13:53:32 +00:00
sessionTable - > horizontalHeader ( ) - > setFont ( Font ) ;
2023-10-07 12:21:48 +01:00
saveSettings ( ) ;
}
else
{
// the user canceled the dialog; font is set to the initial
// value, in this case Helvetica [Cronyx], 10
2023-12-17 13:53:32 +00:00
// QApplication::setFont(Font);
2023-10-07 12:21:48 +01:00
}
return ;
}
2023-09-04 19:06:44 +01:00
QMessageBox msgBox ;
msgBox . setWindowTitle ( " MessageBox Title " ) ;
msgBox . setText ( " You Clicked " + ( ( QPushButton * ) sender ( ) ) - > objectName ( ) ) ;
msgBox . exec ( ) ;
}
Ui_ModemDialog * Dlg ;
QDialog * modemUI ;
QDialog * deviceUI ;
void QtSoundModem : : doModems ( )
{
Dlg = new ( Ui_ModemDialog ) ;
QDialog UI ;
char valChar [ 10 ] ;
Dlg - > setupUi ( & UI ) ;
modemUI = & UI ;
deviceUI = 0 ;
myResize * resize = new myResize ( ) ;
UI . installEventFilter ( resize ) ;
sprintf ( valChar , " %d " , bpf [ 0 ] ) ;
Dlg - > BPFWidthA - > setText ( valChar ) ;
sprintf ( valChar , " %d " , bpf [ 1 ] ) ;
Dlg - > BPFWidthB - > setText ( valChar ) ;
sprintf ( valChar , " %d " , bpf [ 2 ] ) ;
Dlg - > BPFWidthC - > setText ( valChar ) ;
sprintf ( valChar , " %d " , bpf [ 3 ] ) ;
Dlg - > BPFWidthD - > setText ( valChar ) ;
sprintf ( valChar , " %d " , txbpf [ 0 ] ) ;
Dlg - > TXBPFWidthA - > setText ( valChar ) ;
sprintf ( valChar , " %d " , txbpf [ 1 ] ) ;
Dlg - > TXBPFWidthB - > setText ( valChar ) ;
sprintf ( valChar , " %d " , txbpf [ 2 ] ) ;
Dlg - > TXBPFWidthC - > setText ( valChar ) ;
sprintf ( valChar , " %d " , txbpf [ 3 ] ) ;
Dlg - > TXBPFWidthD - > setText ( valChar ) ;
sprintf ( valChar , " %d " , lpf [ 0 ] ) ;
Dlg - > LPFWidthA - > setText ( valChar ) ;
sprintf ( valChar , " %d " , lpf [ 1 ] ) ;
Dlg - > LPFWidthB - > setText ( valChar ) ;
sprintf ( valChar , " %d " , lpf [ 2 ] ) ;
Dlg - > LPFWidthC - > setText ( valChar ) ;
sprintf ( valChar , " %d " , lpf [ 4 ] ) ;
Dlg - > LPFWidthD - > setText ( valChar ) ;
sprintf ( valChar , " %d " , BPF_tap [ 0 ] ) ;
Dlg - > BPFTapsA - > setText ( valChar ) ;
sprintf ( valChar , " %d " , BPF_tap [ 1 ] ) ;
Dlg - > BPFTapsB - > setText ( valChar ) ;
sprintf ( valChar , " %d " , BPF_tap [ 2 ] ) ;
Dlg - > BPFTapsC - > setText ( valChar ) ;
sprintf ( valChar , " %d " , BPF_tap [ 3 ] ) ;
Dlg - > BPFTapsD - > setText ( valChar ) ;
sprintf ( valChar , " %d " , LPF_tap [ 0 ] ) ;
Dlg - > LPFTapsA - > setText ( valChar ) ;
sprintf ( valChar , " %d " , LPF_tap [ 1 ] ) ;
Dlg - > LPFTapsB - > setText ( valChar ) ;
sprintf ( valChar , " %d " , LPF_tap [ 2 ] ) ;
Dlg - > LPFTapsC - > setText ( valChar ) ;
sprintf ( valChar , " %d " , LPF_tap [ 3 ] ) ;
Dlg - > LPFTapsD - > setText ( valChar ) ;
Dlg - > preEmphAllA - > setChecked ( emph_all [ 0 ] ) ;
if ( emph_all [ 0 ] )
Dlg - > preEmphA - > setDisabled ( TRUE ) ;
else
Dlg - > preEmphA - > setCurrentIndex ( emph_db [ 0 ] ) ;
Dlg - > preEmphAllB - > setChecked ( emph_all [ 1 ] ) ;
if ( emph_all [ 1 ] )
Dlg - > preEmphB - > setDisabled ( TRUE ) ;
else
Dlg - > preEmphB - > setCurrentIndex ( emph_db [ 1 ] ) ;
Dlg - > preEmphAllC - > setChecked ( emph_all [ 2 ] ) ;
if ( emph_all [ 2 ] )
Dlg - > preEmphC - > setDisabled ( TRUE ) ;
else
Dlg - > preEmphC - > setCurrentIndex ( emph_db [ 2 ] ) ;
Dlg - > preEmphAllD - > setChecked ( emph_all [ 3 ] ) ;
if ( emph_all [ 3 ] )
Dlg - > preEmphD - > setDisabled ( TRUE ) ;
else
Dlg - > preEmphD - > setCurrentIndex ( emph_db [ 3 ] ) ;
Dlg - > nonAX25A - > setChecked ( NonAX25 [ 0 ] ) ;
Dlg - > nonAX25B - > setChecked ( NonAX25 [ 1 ] ) ;
Dlg - > nonAX25C - > setChecked ( NonAX25 [ 2 ] ) ;
Dlg - > nonAX25D - > setChecked ( NonAX25 [ 3 ] ) ;
Dlg - > KISSOptA - > setChecked ( KISS_opt [ 0 ] ) ;
Dlg - > KISSOptB - > setChecked ( KISS_opt [ 1 ] ) ;
Dlg - > KISSOptC - > setChecked ( KISS_opt [ 2 ] ) ;
Dlg - > KISSOptD - > setChecked ( KISS_opt [ 3 ] ) ;
2023-09-12 21:38:15 +01:00
sprintf ( valChar , " %d " , maxframe [ 0 ] ) ;
Dlg - > MaxFrameA - > setText ( valChar ) ;
sprintf ( valChar , " %d " , maxframe [ 1 ] ) ;
Dlg - > MaxFrameB - > setText ( valChar ) ;
sprintf ( valChar , " %d " , maxframe [ 2 ] ) ;
Dlg - > MaxFrameC - > setText ( valChar ) ;
sprintf ( valChar , " %d " , maxframe [ 3 ] ) ;
Dlg - > MaxFrameD - > setText ( valChar ) ;
2023-09-04 19:06:44 +01:00
sprintf ( valChar , " %d " , txdelay [ 0 ] ) ;
Dlg - > TXDelayA - > setText ( valChar ) ;
sprintf ( valChar , " %d " , txdelay [ 1 ] ) ;
Dlg - > TXDelayB - > setText ( valChar ) ;
sprintf ( valChar , " %d " , txdelay [ 2 ] ) ;
Dlg - > TXDelayC - > setText ( valChar ) ;
sprintf ( valChar , " %d " , txdelay [ 3 ] ) ;
Dlg - > TXDelayD - > setText ( valChar ) ;
2023-09-12 21:38:15 +01:00
2023-09-04 19:06:44 +01:00
sprintf ( valChar , " %d " , txtail [ 0 ] ) ;
Dlg - > TXTailA - > setText ( valChar ) ;
sprintf ( valChar , " %d " , txtail [ 1 ] ) ;
Dlg - > TXTailB - > setText ( valChar ) ;
sprintf ( valChar , " %d " , txtail [ 2 ] ) ;
Dlg - > TXTailC - > setText ( valChar ) ;
sprintf ( valChar , " %d " , txtail [ 3 ] ) ;
Dlg - > TXTailD - > setText ( valChar ) ;
Dlg - > FrackA - > setText ( QString : : number ( frack_time [ 0 ] ) ) ;
Dlg - > FrackB - > setText ( QString : : number ( frack_time [ 1 ] ) ) ;
Dlg - > FrackC - > setText ( QString : : number ( frack_time [ 2 ] ) ) ;
Dlg - > FrackD - > setText ( QString : : number ( frack_time [ 3 ] ) ) ;
Dlg - > RetriesA - > setText ( QString : : number ( fracks [ 0 ] ) ) ;
Dlg - > RetriesB - > setText ( QString : : number ( fracks [ 1 ] ) ) ;
Dlg - > RetriesC - > setText ( QString : : number ( fracks [ 2 ] ) ) ;
Dlg - > RetriesD - > setText ( QString : : number ( fracks [ 3 ] ) ) ;
sprintf ( valChar , " %d " , RCVR [ 0 ] ) ;
Dlg - > AddRXA - > setText ( valChar ) ;
sprintf ( valChar , " %d " , RCVR [ 1 ] ) ;
Dlg - > AddRXB - > setText ( valChar ) ;
sprintf ( valChar , " %d " , RCVR [ 2 ] ) ;
Dlg - > AddRXC - > setText ( valChar ) ;
sprintf ( valChar , " %d " , RCVR [ 3 ] ) ;
Dlg - > AddRXD - > setText ( valChar ) ;
sprintf ( valChar , " %d " , rcvr_offset [ 0 ] ) ;
Dlg - > RXShiftA - > setText ( valChar ) ;
sprintf ( valChar , " %d " , rcvr_offset [ 1 ] ) ;
Dlg - > RXShiftB - > setText ( valChar ) ;
sprintf ( valChar , " %d " , rcvr_offset [ 2 ] ) ;
Dlg - > RXShiftC - > setText ( valChar ) ;
sprintf ( valChar , " %d " , rcvr_offset [ 3 ] ) ;
Dlg - > RXShiftD - > setText ( valChar ) ;
// speed[1]
// speed[2];
Dlg - > recoverBitA - > setCurrentIndex ( recovery [ 0 ] ) ;
Dlg - > recoverBitB - > setCurrentIndex ( recovery [ 1 ] ) ;
Dlg - > recoverBitC - > setCurrentIndex ( recovery [ 2 ] ) ;
Dlg - > recoverBitD - > setCurrentIndex ( recovery [ 3 ] ) ;
Dlg - > fx25ModeA - > setCurrentIndex ( fx25_mode [ 0 ] ) ;
Dlg - > fx25ModeB - > setCurrentIndex ( fx25_mode [ 1 ] ) ;
Dlg - > fx25ModeC - > setCurrentIndex ( fx25_mode [ 2 ] ) ;
Dlg - > fx25ModeD - > setCurrentIndex ( fx25_mode [ 3 ] ) ;
Dlg - > IL2PModeA - > setCurrentIndex ( il2p_mode [ 0 ] ) ;
Dlg - > IL2PModeB - > setCurrentIndex ( il2p_mode [ 1 ] ) ;
Dlg - > IL2PModeC - > setCurrentIndex ( il2p_mode [ 2 ] ) ;
Dlg - > IL2PModeD - > setCurrentIndex ( il2p_mode [ 3 ] ) ;
2024-07-23 21:26:30 +01:00
Dlg - > CRCTX_A - > setChecked ( ( il2p_crc [ 0 ] & 1 ) ) ;
Dlg - > CRCRX_A - > setChecked ( ( il2p_crc [ 0 ] & 2 ) ) ;
Dlg - > CRCTX_B - > setChecked ( ( il2p_crc [ 1 ] & 1 ) ) ;
Dlg - > CRCRX_B - > setChecked ( ( il2p_crc [ 1 ] & 2 ) ) ;
Dlg - > CRCTX_C - > setChecked ( ( il2p_crc [ 2 ] & 1 ) ) ;
Dlg - > CRCRX_C - > setChecked ( ( il2p_crc [ 2 ] & 2 ) ) ;
Dlg - > CRCTX_D - > setChecked ( ( il2p_crc [ 3 ] & 1 ) ) ;
Dlg - > CRCRX_D - > setChecked ( ( il2p_crc [ 3 ] & 2 ) ) ;
2023-12-17 13:53:32 +00:00
2023-09-04 19:06:44 +01:00
Dlg - > CWIDCall - > setText ( CWIDCall ) ;
Dlg - > CWIDInterval - > setText ( QString : : number ( CWIDInterval ) ) ;
2023-09-12 21:38:15 +01:00
Dlg - > CWIDMark - > setText ( CWIDMark ) ;
2023-09-04 19:06:44 +01:00
if ( CWIDType )
Dlg - > radioButton_2 - > setChecked ( 1 ) ;
else
Dlg - > CWIDType - > setChecked ( 1 ) ;
2023-10-07 12:21:48 +01:00
Dlg - > afterTraffic - > setChecked ( afterTraffic ) ;
2023-09-04 19:06:44 +01:00
Dlg - > RSIDSABM_A - > setChecked ( RSID_SABM [ 0 ] ) ;
Dlg - > RSIDSABM_B - > setChecked ( RSID_SABM [ 1 ] ) ;
Dlg - > RSIDSABM_C - > setChecked ( RSID_SABM [ 2 ] ) ;
Dlg - > RSIDSABM_D - > setChecked ( RSID_SABM [ 3 ] ) ;
Dlg - > RSIDUI_A - > setChecked ( RSID_UI [ 0 ] ) ;
Dlg - > RSIDUI_B - > setChecked ( RSID_UI [ 1 ] ) ;
Dlg - > RSIDUI_C - > setChecked ( RSID_UI [ 2 ] ) ;
Dlg - > RSIDUI_D - > setChecked ( RSID_UI [ 3 ] ) ;
Dlg - > DigiCallsA - > setText ( MyDigiCall [ 0 ] ) ;
Dlg - > DigiCallsB - > setText ( MyDigiCall [ 1 ] ) ;
Dlg - > DigiCallsC - > setText ( MyDigiCall [ 2 ] ) ;
Dlg - > DigiCallsD - > setText ( MyDigiCall [ 3 ] ) ;
Dlg - > RSID_1_SETMODEM - > setChecked ( RSID_SetModem [ 0 ] ) ;
Dlg - > RSID_2_SETMODEM - > setChecked ( RSID_SetModem [ 1 ] ) ;
Dlg - > RSID_3_SETMODEM - > setChecked ( RSID_SetModem [ 2 ] ) ;
Dlg - > RSID_4_SETMODEM - > setChecked ( RSID_SetModem [ 3 ] ) ;
connect ( Dlg - > showBPF_A , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showTXBPF_A , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showLPF_A , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showBPF_B , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showTXBPF_B , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showLPF_B , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showBPF_C , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showTXBPF_C , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showLPF_C , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showBPF_D , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showTXBPF_D , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > showLPF_D , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Dlg - > okButton , SIGNAL ( clicked ( ) ) , this , SLOT ( modemaccept ( ) ) ) ;
connect ( Dlg - > modemSave , SIGNAL ( clicked ( ) ) , this , SLOT ( modemSave ( ) ) ) ;
connect ( Dlg - > cancelButton , SIGNAL ( clicked ( ) ) , this , SLOT ( modemreject ( ) ) ) ;
connect ( Dlg - > SendRSID_1 , SIGNAL ( clicked ( ) ) , this , SLOT ( doRSIDA ( ) ) ) ;
connect ( Dlg - > SendRSID_2 , SIGNAL ( clicked ( ) ) , this , SLOT ( doRSIDB ( ) ) ) ;
connect ( Dlg - > SendRSID_3 , SIGNAL ( clicked ( ) ) , this , SLOT ( doRSIDC ( ) ) ) ;
connect ( Dlg - > SendRSID_4 , SIGNAL ( clicked ( ) ) , this , SLOT ( doRSIDD ( ) ) ) ;
connect ( Dlg - > preEmphAllA , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( preEmphAllAChanged ( int ) ) ) ;
connect ( Dlg - > preEmphAllB , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( preEmphAllBChanged ( int ) ) ) ;
connect ( Dlg - > preEmphAllC , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( preEmphAllCChanged ( int ) ) ) ;
connect ( Dlg - > preEmphAllD , SIGNAL ( stateChanged ( int ) ) , this , SLOT ( preEmphAllDChanged ( int ) ) ) ;
UI . exec ( ) ;
}
void QtSoundModem : : preEmphAllAChanged ( int state )
{
Dlg - > preEmphA - > setDisabled ( state ) ;
}
void QtSoundModem : : preEmphAllBChanged ( int state )
{
Dlg - > preEmphB - > setDisabled ( state ) ;
}
void QtSoundModem : : preEmphAllCChanged ( int state )
{
Dlg - > preEmphC - > setDisabled ( state ) ;
}
void QtSoundModem : : preEmphAllDChanged ( int state )
{
Dlg - > preEmphD - > setDisabled ( state ) ;
}
extern " C " void get_exclude_list ( char * line , TStringList * list ) ;
void QtSoundModem : : modemaccept ( )
{
modemSave ( ) ;
2023-12-17 13:53:32 +00:00
AGW_Report_Modem_Change ( 0 ) ;
AGW_Report_Modem_Change ( 1 ) ;
AGW_Report_Modem_Change ( 2 ) ;
AGW_Report_Modem_Change ( 3 ) ;
2023-09-04 19:06:44 +01:00
delete ( Dlg ) ;
saveSettings ( ) ;
modemUI - > accept ( ) ;
}
void QtSoundModem : : modemSave ( )
{
QVariant Q ;
emph_all [ 0 ] = Dlg - > preEmphAllA - > isChecked ( ) ;
emph_db [ 0 ] = Dlg - > preEmphA - > currentIndex ( ) ;
emph_all [ 1 ] = Dlg - > preEmphAllB - > isChecked ( ) ;
emph_db [ 1 ] = Dlg - > preEmphB - > currentIndex ( ) ;
emph_all [ 2 ] = Dlg - > preEmphAllC - > isChecked ( ) ;
emph_db [ 2 ] = Dlg - > preEmphC - > currentIndex ( ) ;
emph_all [ 3 ] = Dlg - > preEmphAllD - > isChecked ( ) ;
emph_db [ 3 ] = Dlg - > preEmphD - > currentIndex ( ) ;
NonAX25 [ 0 ] = Dlg - > nonAX25A - > isChecked ( ) ;
NonAX25 [ 1 ] = Dlg - > nonAX25B - > isChecked ( ) ;
NonAX25 [ 2 ] = Dlg - > nonAX25C - > isChecked ( ) ;
NonAX25 [ 3 ] = Dlg - > nonAX25D - > isChecked ( ) ;
KISS_opt [ 0 ] = Dlg - > KISSOptA - > isChecked ( ) ;
KISS_opt [ 1 ] = Dlg - > KISSOptB - > isChecked ( ) ;
KISS_opt [ 2 ] = Dlg - > KISSOptC - > isChecked ( ) ;
KISS_opt [ 3 ] = Dlg - > KISSOptD - > isChecked ( ) ;
if ( emph_db [ 0 ] < 0 | | emph_db [ 0 ] > nr_emph )
emph_db [ 0 ] = 0 ;
if ( emph_db [ 1 ] < 0 | | emph_db [ 1 ] > nr_emph )
emph_db [ 1 ] = 0 ;
if ( emph_db [ 2 ] < 0 | | emph_db [ 2 ] > nr_emph )
emph_db [ 2 ] = 0 ;
if ( emph_db [ 3 ] < 0 | | emph_db [ 3 ] > nr_emph )
emph_db [ 3 ] = 0 ;
Q = Dlg - > TXDelayA - > text ( ) ;
txdelay [ 0 ] = Q . toInt ( ) ;
Q = Dlg - > TXDelayB - > text ( ) ;
txdelay [ 1 ] = Q . toInt ( ) ;
Q = Dlg - > TXDelayC - > text ( ) ;
txdelay [ 2 ] = Q . toInt ( ) ;
Q = Dlg - > TXDelayD - > text ( ) ;
txdelay [ 3 ] = Q . toInt ( ) ;
2023-09-12 21:38:15 +01:00
Q = Dlg - > MaxFrameA - > text ( ) ;
maxframe [ 0 ] = Q . toInt ( ) ;
Q = Dlg - > MaxFrameB - > text ( ) ;
maxframe [ 1 ] = Q . toInt ( ) ;
Q = Dlg - > MaxFrameC - > text ( ) ;
maxframe [ 2 ] = Q . toInt ( ) ;
Q = Dlg - > MaxFrameD - > text ( ) ;
maxframe [ 3 ] = Q . toInt ( ) ;
if ( maxframe [ 0 ] = = 0 | | maxframe [ 0 ] > 7 ) maxframe [ 0 ] = 3 ;
if ( maxframe [ 1 ] = = 0 | | maxframe [ 1 ] > 7 ) maxframe [ 1 ] = 3 ;
if ( maxframe [ 2 ] = = 0 | | maxframe [ 2 ] > 7 ) maxframe [ 2 ] = 3 ;
if ( maxframe [ 3 ] = = 0 | | maxframe [ 3 ] > 7 ) maxframe [ 3 ] = 3 ;
2023-09-04 19:06:44 +01:00
Q = Dlg - > TXTailA - > text ( ) ;
txtail [ 0 ] = Q . toInt ( ) ;
Q = Dlg - > TXTailB - > text ( ) ;
txtail [ 1 ] = Q . toInt ( ) ;
Q = Dlg - > TXTailC - > text ( ) ;
txtail [ 2 ] = Q . toInt ( ) ;
txtail [ 3 ] = Dlg - > TXTailD - > text ( ) . toInt ( ) ;
frack_time [ 0 ] = Dlg - > FrackA - > text ( ) . toInt ( ) ;
frack_time [ 1 ] = Dlg - > FrackB - > text ( ) . toInt ( ) ;
frack_time [ 2 ] = Dlg - > FrackC - > text ( ) . toInt ( ) ;
frack_time [ 3 ] = Dlg - > FrackD - > text ( ) . toInt ( ) ;
fracks [ 0 ] = Dlg - > RetriesA - > text ( ) . toInt ( ) ;
fracks [ 1 ] = Dlg - > RetriesB - > text ( ) . toInt ( ) ;
fracks [ 2 ] = Dlg - > RetriesC - > text ( ) . toInt ( ) ;
fracks [ 3 ] = Dlg - > RetriesD - > text ( ) . toInt ( ) ;
Q = Dlg - > AddRXA - > text ( ) ;
RCVR [ 0 ] = Q . toInt ( ) ;
Q = Dlg - > AddRXB - > text ( ) ;
RCVR [ 1 ] = Q . toInt ( ) ;
Q = Dlg - > AddRXC - > text ( ) ;
RCVR [ 2 ] = Q . toInt ( ) ;
Q = Dlg - > AddRXD - > text ( ) ;
RCVR [ 3 ] = Q . toInt ( ) ;
Q = Dlg - > RXShiftA - > text ( ) ;
rcvr_offset [ 0 ] = Q . toInt ( ) ;
Q = Dlg - > RXShiftB - > text ( ) ;
rcvr_offset [ 1 ] = Q . toInt ( ) ;
Q = Dlg - > RXShiftC - > text ( ) ;
rcvr_offset [ 2 ] = Q . toInt ( ) ;
Q = Dlg - > RXShiftD - > text ( ) ;
rcvr_offset [ 3 ] = Q . toInt ( ) ;
fx25_mode [ 0 ] = Dlg - > fx25ModeA - > currentIndex ( ) ;
fx25_mode [ 1 ] = Dlg - > fx25ModeB - > currentIndex ( ) ;
fx25_mode [ 2 ] = Dlg - > fx25ModeC - > currentIndex ( ) ;
fx25_mode [ 3 ] = Dlg - > fx25ModeD - > currentIndex ( ) ;
il2p_mode [ 0 ] = Dlg - > IL2PModeA - > currentIndex ( ) ;
il2p_mode [ 1 ] = Dlg - > IL2PModeB - > currentIndex ( ) ;
il2p_mode [ 2 ] = Dlg - > IL2PModeC - > currentIndex ( ) ;
il2p_mode [ 3 ] = Dlg - > IL2PModeD - > currentIndex ( ) ;
2024-07-23 21:26:30 +01:00
il2p_crc [ 0 ] = Dlg - > CRCTX_A - > isChecked ( ) ;
if ( Dlg - > CRCRX_A - > isChecked ( ) )
il2p_crc [ 0 ] | = 2 ;
il2p_crc [ 1 ] = Dlg - > CRCTX_B - > isChecked ( ) ;
if ( Dlg - > CRCRX_B - > isChecked ( ) )
il2p_crc [ 1 ] | = 2 ;
il2p_crc [ 2 ] = Dlg - > CRCTX_C - > isChecked ( ) ;
if ( Dlg - > CRCRX_C - > isChecked ( ) )
il2p_crc [ 2 ] | = 2 ;
il2p_crc [ 3 ] = Dlg - > CRCTX_D - > isChecked ( ) ;
if ( Dlg - > CRCRX_D - > isChecked ( ) )
il2p_crc [ 3 ] | = 2 ;
2023-12-17 13:53:32 +00:00
2023-09-04 19:06:44 +01:00
recovery [ 0 ] = Dlg - > recoverBitA - > currentIndex ( ) ;
recovery [ 1 ] = Dlg - > recoverBitB - > currentIndex ( ) ;
recovery [ 2 ] = Dlg - > recoverBitC - > currentIndex ( ) ;
recovery [ 3 ] = Dlg - > recoverBitD - > currentIndex ( ) ;
strcpy ( CWIDCall , Dlg - > CWIDCall - > text ( ) . toUtf8 ( ) . toUpper ( ) ) ;
2023-09-12 21:38:15 +01:00
strcpy ( CWIDMark , Dlg - > CWIDMark - > text ( ) . toUtf8 ( ) . toUpper ( ) ) ;
2023-09-04 19:06:44 +01:00
CWIDInterval = Dlg - > CWIDInterval - > text ( ) . toInt ( ) ;
CWIDType = Dlg - > radioButton_2 - > isChecked ( ) ;
2023-10-07 12:21:48 +01:00
afterTraffic = Dlg - > afterTraffic - > isChecked ( ) ;
if ( CWIDInterval & & afterTraffic = = false )
2023-09-04 19:06:44 +01:00
cwidtimer - > start ( CWIDInterval * 60000 ) ;
else
cwidtimer - > stop ( ) ;
RSID_SABM [ 0 ] = Dlg - > RSIDSABM_A - > isChecked ( ) ;
RSID_SABM [ 1 ] = Dlg - > RSIDSABM_B - > isChecked ( ) ;
RSID_SABM [ 2 ] = Dlg - > RSIDSABM_C - > isChecked ( ) ;
RSID_SABM [ 3 ] = Dlg - > RSIDSABM_D - > isChecked ( ) ;
RSID_UI [ 0 ] = Dlg - > RSIDUI_A - > isChecked ( ) ;
RSID_UI [ 1 ] = Dlg - > RSIDUI_B - > isChecked ( ) ;
RSID_UI [ 2 ] = Dlg - > RSIDUI_C - > isChecked ( ) ;
RSID_UI [ 3 ] = Dlg - > RSIDUI_D - > isChecked ( ) ;
RSID_SetModem [ 0 ] = Dlg - > RSID_1_SETMODEM - > isChecked ( ) ;
RSID_SetModem [ 1 ] = Dlg - > RSID_2_SETMODEM - > isChecked ( ) ;
RSID_SetModem [ 2 ] = Dlg - > RSID_3_SETMODEM - > isChecked ( ) ;
RSID_SetModem [ 3 ] = Dlg - > RSID_4_SETMODEM - > isChecked ( ) ;
Q = Dlg - > DigiCallsA - > text ( ) ;
strcpy ( MyDigiCall [ 0 ] , Q . toString ( ) . toUtf8 ( ) . toUpper ( ) ) ;
Q = Dlg - > DigiCallsB - > text ( ) ;
strcpy ( MyDigiCall [ 1 ] , Q . toString ( ) . toUtf8 ( ) . toUpper ( ) ) ;
Q = Dlg - > DigiCallsC - > text ( ) ;
strcpy ( MyDigiCall [ 2 ] , Q . toString ( ) . toUtf8 ( ) . toUpper ( ) ) ;
Q = Dlg - > DigiCallsD - > text ( ) ;
strcpy ( MyDigiCall [ 3 ] , Q . toString ( ) . toUtf8 ( ) . toUpper ( ) ) ;
int i ;
for ( i = 0 ; i < 4 ; i + + )
{
initTStringList ( & list_digi_callsigns [ i ] ) ;
get_exclude_list ( MyDigiCall [ i ] , & list_digi_callsigns [ i ] ) ;
}
2023-10-07 12:21:48 +01:00
/*
Q = Dlg - > LPFWidthA - > text ( ) ;
lpf [ 0 ] = Q . toInt ( ) ;
Q = Dlg - > LPFWidthB - > text ( ) ;
lpf [ 1 ] = Q . toInt ( ) ;
Q = Dlg - > LPFWidthC - > text ( ) ;
lpf [ 2 ] = Q . toInt ( ) ;
Q = Dlg - > LPFWidthD - > text ( ) ;
lpf [ 3 ] = Q . toInt ( ) ;
*/
2023-12-17 13:53:32 +00:00
2023-09-04 19:06:44 +01:00
}
void QtSoundModem : : modemreject ( )
{
delete ( Dlg ) ;
modemUI - > reject ( ) ;
}
void QtSoundModem : : doRSIDA ( )
{
needRSID [ 0 ] = 1 ;
}
void QtSoundModem : : doRSIDB ( )
{
needRSID [ 1 ] = 1 ;
}
void QtSoundModem : : doRSIDC ( )
{
needRSID [ 2 ] = 1 ;
}
void QtSoundModem : : doRSIDD ( )
{
needRSID [ 3 ] = 1 ;
}
void QtSoundModem : : doFilter ( int Chan , int Filter )
{
Ui_Dialog Dev ;
QImage * bitmap ;
QDialog UI ;
Dev . setupUi ( & UI ) ;
bitmap = new QImage ( 642 , 312 , QImage : : Format_RGB32 ) ;
bitmap - > fill ( qRgb ( 255 , 255 , 255 ) ) ;
QPainter qPainter ( bitmap ) ;
qPainter . setBrush ( Qt : : NoBrush ) ;
qPainter . setPen ( Qt : : black ) ;
if ( Filter = = 0 )
make_graph_buf ( DET [ 0 ] [ 0 ] . BPF_core [ Chan ] , BPF_tap [ Chan ] , & qPainter ) ;
else if ( Filter = = 1 )
make_graph_buf ( tx_BPF_core [ Chan ] , tx_BPF_tap [ Chan ] , & qPainter ) ;
else
make_graph_buf ( LPF_core [ Chan ] , LPF_tap [ Chan ] , & qPainter ) ;
qPainter . end ( ) ;
Dev . label - > setPixmap ( QPixmap : : fromImage ( * bitmap ) ) ;
UI . exec ( ) ;
}
Ui_devicesDialog * Dev ;
char NewPTTPort [ 80 ] ;
int newSoundMode = 0 ;
int oldSoundMode = 0 ;
2024-07-23 21:26:30 +01:00
int oldSnoopMix = 0 ;
int newSnoopMix = 0 ;
2023-09-04 19:06:44 +01:00
void QtSoundModem : : SoundModeChanged ( bool State )
{
UNUSED ( State ) ;
// Mustn't change SoundMode until dialog is accepted
2024-07-23 21:26:30 +01:00
newSnoopMix = Dev - > onlyMixSnoop - > isChecked ( ) ;
2023-09-04 19:06:44 +01:00
if ( Dev - > UDP - > isChecked ( ) )
newSoundMode = 3 ;
else if ( Dev - > PULSE - > isChecked ( ) )
newSoundMode = 2 ;
else
newSoundMode = Dev - > OSS - > isChecked ( ) ;
}
void QtSoundModem : : DualPTTChanged ( bool State )
{
UNUSED ( State ) ;
// Forse Evaluation of Cat Port setting
PTTPortChanged ( 0 ) ;
}
void QtSoundModem : : CATChanged ( bool State )
{
UNUSED ( State ) ;
PTTPortChanged ( 0 ) ;
}
void QtSoundModem : : PTTPortChanged ( int Selected )
{
UNUSED ( Selected ) ;
QVariant Q = Dev - > PTTPort - > currentText ( ) ;
strcpy ( NewPTTPort , Q . toString ( ) . toUtf8 ( ) ) ;
Dev - > RTSDTR - > setVisible ( false ) ;
Dev - > CAT - > setVisible ( false ) ;
Dev - > PTTOnLab - > setVisible ( false ) ;
Dev - > PTTOn - > setVisible ( false ) ;
Dev - > PTTOff - > setVisible ( false ) ;
Dev - > PTTOffLab - > setVisible ( false ) ;
Dev - > CATLabel - > setVisible ( false ) ;
Dev - > CATSpeed - > setVisible ( false ) ;
Dev - > GPIOLab - > setVisible ( false ) ;
Dev - > GPIOLeft - > setVisible ( false ) ;
Dev - > GPIORight - > setVisible ( false ) ;
Dev - > GPIOLab2 - > setVisible ( false ) ;
Dev - > CM108Label - > setVisible ( false ) ;
Dev - > VIDPID - > setVisible ( false ) ;
if ( strcmp ( NewPTTPort , " None " ) = = 0 )
{
}
else if ( strcmp ( NewPTTPort , " GPIO " ) = = 0 )
{
Dev - > GPIOLab - > setVisible ( true ) ;
Dev - > GPIOLeft - > setVisible ( true ) ;
if ( Dev - > DualPTT - > isChecked ( ) )
{
Dev - > GPIORight - > setVisible ( true ) ;
Dev - > GPIOLab2 - > setVisible ( true ) ;
}
}
else if ( strcmp ( NewPTTPort , " CM108 " ) = = 0 )
{
Dev - > CM108Label - > setVisible ( true ) ;
//#ifdef __ARM_ARCHX
Dev - > CM108Label - > setText ( " CM108 Device " ) ;
//#else
// Dev->CM108Label->setText("CM108 VID/PID");
//#endif
Dev - > VIDPID - > setText ( CM108Addr ) ;
Dev - > VIDPID - > setVisible ( true ) ;
}
else if ( strcmp ( NewPTTPort , " HAMLIB " ) = = 0 )
{
Dev - > CM108Label - > setVisible ( true ) ;
Dev - > CM108Label - > setText ( " rigctrld Port " ) ;
Dev - > VIDPID - > setText ( QString : : number ( HamLibPort ) ) ;
Dev - > VIDPID - > setVisible ( true ) ;
Dev - > PTTOnLab - > setText ( " rigctrld Host " ) ;
Dev - > PTTOnLab - > setVisible ( true ) ;
Dev - > PTTOn - > setText ( HamLibHost ) ;
Dev - > PTTOn - > setVisible ( true ) ;
}
2024-07-23 21:26:30 +01:00
else if ( strcmp ( NewPTTPort , " FLRIG " ) = = 0 )
{
Dev - > CM108Label - > setVisible ( true ) ;
Dev - > CM108Label - > setText ( " FLRig Port " ) ;
Dev - > VIDPID - > setText ( QString : : number ( FLRigPort ) ) ;
Dev - > VIDPID - > setVisible ( true ) ;
Dev - > PTTOnLab - > setText ( " FLRig Host " ) ;
Dev - > PTTOnLab - > setVisible ( true ) ;
Dev - > PTTOn - > setText ( FLRigHost ) ;
Dev - > PTTOn - > setVisible ( true ) ;
}
2023-09-04 19:06:44 +01:00
else
{
Dev - > RTSDTR - > setVisible ( true ) ;
Dev - > CAT - > setVisible ( true ) ;
if ( Dev - > CAT - > isChecked ( ) )
{
Dev - > PTTOnLab - > setVisible ( true ) ;
Dev - > PTTOnLab - > setText ( " PTT On String " ) ;
Dev - > PTTOn - > setText ( PTTOnString ) ;
Dev - > PTTOn - > setVisible ( true ) ;
Dev - > PTTOff - > setVisible ( true ) ;
Dev - > PTTOff - > setText ( PTTOffString ) ;
Dev - > PTTOffLab - > setVisible ( true ) ;
Dev - > CATLabel - > setVisible ( true ) ;
Dev - > CATSpeed - > setVisible ( true ) ;
}
}
}
bool myResize : : eventFilter ( QObject * obj , QEvent * event )
{
if ( event - > type ( ) = = QEvent : : Resize )
{
QResizeEvent * resizeEvent = static_cast < QResizeEvent * > ( event ) ;
QSize size = resizeEvent - > size ( ) ;
int h = size . height ( ) ;
int w = size . width ( ) ;
if ( obj = = deviceUI )
Dev - > scrollArea - > setGeometry ( QRect ( 5 , 5 , w - 10 , h - 10 ) ) ;
else
Dlg - > scrollArea - > setGeometry ( QRect ( 5 , 5 , w - 10 , h - 10 ) ) ;
return true ;
}
return QObject : : eventFilter ( obj , event ) ;
}
void QtSoundModem : : doDevices ( )
{
char valChar [ 10 ] ;
2024-10-29 22:45:21 +00:00
QStringList items ;
2023-09-04 19:06:44 +01:00
Dev = new ( Ui_devicesDialog ) ;
QDialog UI ;
int i ;
Dev - > setupUi ( & UI ) ;
deviceUI = & UI ;
modemUI = 0 ;
myResize * resize = new myResize ( ) ;
UI . installEventFilter ( resize ) ;
2024-10-29 22:45:21 +00:00
// Set serial names
for ( const QSerialPortInfo & info : Ports )
{
items . append ( info . portName ( ) ) ;
}
items . sort ( ) ;
Dev - > SixPackSerial - > addItem ( " None " ) ;
for ( const QString & info : items )
{
Dev - > SixPackSerial - > addItem ( info ) ;
}
2023-09-04 19:06:44 +01:00
newSoundMode = SoundMode ;
oldSoundMode = SoundMode ;
2024-07-23 21:26:30 +01:00
oldSnoopMix = newSnoopMix = onlyMixSnoop ;
2023-09-04 19:06:44 +01:00
# ifdef WIN32
Dev - > ALSA - > setText ( " WaveOut " ) ;
Dev - > OSS - > setVisible ( 0 ) ;
Dev - > PULSE - > setVisible ( 0 ) ;
2024-07-23 21:26:30 +01:00
Dev - > onlyMixSnoop - > setVisible ( 0 ) ;
Dev - > ALSA - > setChecked ( 1 ) ;
# else
2023-09-04 19:06:44 +01:00
if ( SoundMode = = 0 )
2024-07-23 21:26:30 +01:00
{
Dev - > onlyMixSnoop - > setVisible ( 1 ) ;
2023-09-04 19:06:44 +01:00
Dev - > ALSA - > setChecked ( 1 ) ;
2024-07-23 21:26:30 +01:00
}
2023-09-04 19:06:44 +01:00
else if ( SoundMode = = 1 )
Dev - > OSS - > setChecked ( 1 ) ;
else if ( SoundMode = = 2 )
Dev - > PULSE - > setChecked ( 1 ) ;
else if ( SoundMode = = 2 )
Dev - > UDP - > setChecked ( 1 ) ;
2024-07-23 21:26:30 +01:00
# endif
Dev - > onlyMixSnoop - > setChecked ( onlyMixSnoop ) ;
2023-09-04 19:06:44 +01:00
connect ( Dev - > ALSA , SIGNAL ( toggled ( bool ) ) , this , SLOT ( SoundModeChanged ( bool ) ) ) ;
connect ( Dev - > OSS , SIGNAL ( toggled ( bool ) ) , this , SLOT ( SoundModeChanged ( bool ) ) ) ;
connect ( Dev - > PULSE , SIGNAL ( toggled ( bool ) ) , this , SLOT ( SoundModeChanged ( bool ) ) ) ;
connect ( Dev - > UDP , SIGNAL ( toggled ( bool ) ) , this , SLOT ( SoundModeChanged ( bool ) ) ) ;
2024-07-23 21:26:30 +01:00
connect ( Dev - > onlyMixSnoop , SIGNAL ( toggled ( bool ) ) , this , SLOT ( SoundModeChanged ( bool ) ) ) ;
2023-09-04 19:06:44 +01:00
for ( i = 0 ; i < PlaybackCount ; i + + )
Dev - > outputDevice - > addItem ( & PlaybackNames [ i ] [ 0 ] ) ;
i = Dev - > outputDevice - > findText ( PlaybackDevice , Qt : : MatchContains ) ;
if ( i = = - 1 )
{
// Add device to list
Dev - > outputDevice - > addItem ( PlaybackDevice ) ;
i = Dev - > outputDevice - > findText ( PlaybackDevice , Qt : : MatchContains ) ;
}
Dev - > outputDevice - > setCurrentIndex ( i ) ;
for ( i = 0 ; i < CaptureCount ; i + + )
Dev - > inputDevice - > addItem ( & CaptureNames [ i ] [ 0 ] ) ;
i = Dev - > inputDevice - > findText ( CaptureDevice , Qt : : MatchContains ) ;
if ( i = = - 1 )
{
// Add device to list
Dev - > inputDevice - > addItem ( CaptureDevice ) ;
i = Dev - > inputDevice - > findText ( CaptureDevice , Qt : : MatchContains ) ;
}
Dev - > inputDevice - > setCurrentIndex ( i ) ;
2024-07-23 21:26:30 +01:00
Dev - > txLatency - > setText ( QString : : number ( txLatency ) ) ;
2023-09-04 19:06:44 +01:00
Dev - > Modem_1_Chan - > setCurrentIndex ( soundChannel [ 0 ] ) ;
Dev - > Modem_2_Chan - > setCurrentIndex ( soundChannel [ 1 ] ) ;
Dev - > Modem_3_Chan - > setCurrentIndex ( soundChannel [ 2 ] ) ;
Dev - > Modem_4_Chan - > setCurrentIndex ( soundChannel [ 3 ] ) ;
// Disable "None" option in first modem
QStandardItemModel * model = dynamic_cast < QStandardItemModel * > ( Dev - > Modem_1_Chan - > model ( ) ) ;
QStandardItem * item = model - > item ( 0 , 0 ) ;
item - > setEnabled ( false ) ;
2024-10-29 22:45:21 +00:00
Dev - > useKISSControls - > setChecked ( useKISSControls ) ;
2023-09-04 19:06:44 +01:00
Dev - > singleChannelOutput - > setChecked ( SCO ) ;
Dev - > colourWaterfall - > setChecked ( raduga ) ;
sprintf ( valChar , " %d " , KISSPort ) ;
Dev - > KISSPort - > setText ( valChar ) ;
Dev - > KISSEnabled - > setChecked ( KISSServ ) ;
sprintf ( valChar , " %d " , AGWPort ) ;
Dev - > AGWPort - > setText ( valChar ) ;
Dev - > AGWEnabled - > setChecked ( AGWServ ) ;
2024-10-29 22:45:21 +00:00
Dev - > MgmtPort - > setText ( QString : : number ( MgmtPort ) ) ;
// If we are using a user specifed device add it
i = Dev - > SixPackSerial - > findText ( SixPackDevice , Qt : : MatchFixedString ) ;
if ( i = = - 1 )
{
// Add our device to list
Dev - > SixPackSerial - > insertItem ( 0 , SixPackDevice ) ;
i = Dev - > SixPackSerial - > findText ( SixPackDevice , Qt : : MatchContains ) ;
}
Dev - > SixPackSerial - > setCurrentIndex ( i ) ;
sprintf ( valChar , " %d " , SixPackPort ) ;
Dev - > SixPackTCP - > setText ( valChar ) ;
Dev - > SixPackEnable - > setChecked ( SixPackEnable ) ;
2023-09-04 19:06:44 +01:00
Dev - > PTTOn - > setText ( PTTOnString ) ;
Dev - > PTTOff - > setText ( PTTOffString ) ;
sprintf ( valChar , " %d " , PTTBAUD ) ;
Dev - > CATSpeed - > setText ( valChar ) ;
sprintf ( valChar , " %d " , UDPClientPort ) ;
Dev - > UDPPort - > setText ( valChar ) ;
Dev - > UDPTXHost - > setText ( UDPHost ) ;
if ( UDPServerPort ! = TXPort )
sprintf ( valChar , " %d/%d " , UDPServerPort , TXPort ) ;
else
sprintf ( valChar , " %d " , UDPServerPort ) ;
Dev - > UDPTXPort - > setText ( valChar ) ;
Dev - > UDPEnabled - > setChecked ( UDPServ ) ;
sprintf ( valChar , " %d " , pttGPIOPin ) ;
Dev - > GPIOLeft - > setText ( valChar ) ;
sprintf ( valChar , " %d " , pttGPIOPinR ) ;
Dev - > GPIORight - > setText ( valChar ) ;
Dev - > VIDPID - > setText ( CM108Addr ) ;
connect ( Dev - > CAT , SIGNAL ( toggled ( bool ) ) , this , SLOT ( CATChanged ( bool ) ) ) ;
connect ( Dev - > DualPTT , SIGNAL ( toggled ( bool ) ) , this , SLOT ( DualPTTChanged ( bool ) ) ) ;
connect ( Dev - > PTTPort , SIGNAL ( currentIndexChanged ( int ) ) , this , SLOT ( PTTPortChanged ( int ) ) ) ;
if ( PTTMode = = PTTCAT )
Dev - > CAT - > setChecked ( true ) ;
else
Dev - > RTSDTR - > setChecked ( true ) ;
Dev - > PTTPort - > addItem ( " None " ) ;
Dev - > PTTPort - > addItem ( " CM108 " ) ;
//#ifdef __ARM_ARCH
Dev - > PTTPort - > addItem ( " GPIO " ) ;
//#endif
Dev - > PTTPort - > addItem ( " HAMLIB " ) ;
2024-07-23 21:26:30 +01:00
Dev - > PTTPort - > addItem ( " FLRIG " ) ;
2023-09-04 19:06:44 +01:00
for ( const QString & info : items )
{
Dev - > PTTPort - > addItem ( info ) ;
}
2023-10-07 12:21:48 +01:00
// If we are using a user specifed device add it
i = Dev - > PTTPort - > findText ( PTTPort , Qt : : MatchFixedString ) ;
if ( i = = - 1 )
{
// Add our device to list
Dev - > PTTPort - > insertItem ( 0 , PTTPort ) ;
i = Dev - > PTTPort - > findText ( PTTPort , Qt : : MatchContains ) ;
}
Dev - > PTTPort - > setCurrentIndex ( i ) ;
2023-09-04 19:06:44 +01:00
PTTPortChanged ( 0 ) ; // Force reevaluation
Dev - > txRotation - > setChecked ( TX_rotate ) ;
Dev - > DualPTT - > setChecked ( DualPTT ) ;
Dev - > multiCore - > setChecked ( multiCore ) ;
2023-12-17 13:53:32 +00:00
Dev - > darkTheme - > setChecked ( darkTheme ) ;
2023-09-04 19:06:44 +01:00
Dev - > WaterfallMin - > setCurrentIndex ( Dev - > WaterfallMin - > findText ( QString : : number ( WaterfallMin ) , Qt : : MatchFixedString ) ) ;
Dev - > WaterfallMax - > setCurrentIndex ( Dev - > WaterfallMax - > findText ( QString : : number ( WaterfallMax ) , Qt : : MatchFixedString ) ) ;
QObject : : connect ( Dev - > okButton , SIGNAL ( clicked ( ) ) , this , SLOT ( deviceaccept ( ) ) ) ;
QObject : : connect ( Dev - > cancelButton , SIGNAL ( clicked ( ) ) , this , SLOT ( devicereject ( ) ) ) ;
UI . exec ( ) ;
}
2023-12-17 13:53:32 +00:00
void QtSoundModem : : mysetstyle ( )
{
if ( darkTheme )
{
qApp - > setStyleSheet (
" QWidget {color: white; background-color: black} "
" QTabBar::tab {color: rgb(127, 127, 127); background-color: black} "
" QTabBar::tab::selected {color: white} "
" QPushButton {border-style: outset; border-width: 2px; border-color: rgb(127, 127, 127)} "
" QPushButton::default {border-style: outset; border-width: 2px; border-color: white} " ) ;
sessionTable - > setStyleSheet ( " QHeaderView::section { background-color:rgb(40, 40, 40) } " ) ;
txText = qRgb ( 255 , 127 , 127 ) ;
rxText = qRgb ( 173 , 216 , 230 ) ;
}
else
{
qApp - > setStyleSheet ( " " ) ;
sessionTable - > setStyleSheet ( " QHeaderView::section { background-color:rgb(224, 224, 224) } " ) ;
txText = qRgb ( 192 , 0 , 0 ) ;
rxText = qRgb ( 0 , 0 , 192 ) ;
}
}
2023-09-04 19:06:44 +01:00
void QtSoundModem : : deviceaccept ( )
{
QVariant Q = Dev - > inputDevice - > currentText ( ) ;
int cardChanged = 0 ;
char portString [ 32 ] ;
int newMax ;
int newMin ;
if ( Dev - > UDP - > isChecked ( ) )
{
// cant have server and slave
if ( Dev - > UDPEnabled - > isChecked ( ) )
{
QMessageBox : : about ( this , tr ( " QtSoundModem " ) ,
tr ( " Can't have UDP sound source and UDP server at same time " ) ) ;
return ;
}
}
2024-07-23 21:26:30 +01:00
if ( oldSoundMode ! = newSoundMode | | oldSnoopMix ! = newSnoopMix )
2023-09-04 19:06:44 +01:00
{
QMessageBox msgBox ;
msgBox . setText ( " QtSoundModem must restart to change Sound Mode. \n "
" Program will close if you hit Ok \n "
" You will need to reselect audio devices after restarting " ) ;
msgBox . setStandardButtons ( QMessageBox : : Ok | QMessageBox : : Cancel ) ;
int i = msgBox . exec ( ) ;
if ( i = = QMessageBox : : Ok )
{
SoundMode = newSoundMode ;
2024-07-23 21:26:30 +01:00
onlyMixSnoop = newSnoopMix ;
2023-09-04 19:06:44 +01:00
saveSettings ( ) ;
Closing = 1 ;
return ;
}
if ( oldSoundMode = = 0 )
Dev - > ALSA - > setChecked ( 1 ) ;
else if ( oldSoundMode = = 1 )
Dev - > OSS - > setChecked ( 1 ) ;
else if ( oldSoundMode = = 2 )
Dev - > PULSE - > setChecked ( 1 ) ;
else if ( oldSoundMode = = 3 )
Dev - > UDP - > setChecked ( 1 ) ;
QMessageBox : : about ( this , tr ( " Info " ) ,
tr ( " <p align = 'center'>Changes not saved</p> " ) ) ;
return ;
}
if ( strcmp ( CaptureDevice , Q . toString ( ) . toUtf8 ( ) ) ! = 0 )
{
strcpy ( CaptureDevice , Q . toString ( ) . toUtf8 ( ) ) ;
cardChanged = 1 ;
}
2024-07-23 21:26:30 +01:00
if ( onlyMixSnoop ! = Dev - > onlyMixSnoop - > isChecked ( ) )
{
onlyMixSnoop = Dev - > onlyMixSnoop - > isChecked ( ) ;
cardChanged = 1 ;
}
2023-09-04 19:06:44 +01:00
CaptureIndex = Dev - > inputDevice - > currentIndex ( ) ;
Q = Dev - > outputDevice - > currentText ( ) ;
if ( strcmp ( PlaybackDevice , Q . toString ( ) . toUtf8 ( ) ) ! = 0 )
{
strcpy ( PlaybackDevice , Q . toString ( ) . toUtf8 ( ) ) ;
cardChanged = 1 ;
}
PlayBackIndex = Dev - > outputDevice - > currentIndex ( ) ;
2024-07-23 21:26:30 +01:00
Q = Dev - > txLatency - > text ( ) ;
txLatency = Q . toInt ( ) ;
2023-09-04 19:06:44 +01:00
soundChannel [ 0 ] = Dev - > Modem_1_Chan - > currentIndex ( ) ;
soundChannel [ 1 ] = Dev - > Modem_2_Chan - > currentIndex ( ) ;
soundChannel [ 2 ] = Dev - > Modem_3_Chan - > currentIndex ( ) ;
soundChannel [ 3 ] = Dev - > Modem_4_Chan - > currentIndex ( ) ;
UsingLeft = 0 ;
UsingRight = 0 ;
UsingBothChannels = 0 ;
for ( int i = 0 ; i < 4 ; i + + )
{
if ( soundChannel [ i ] = = LEFT )
{
UsingLeft = 1 ;
modemtoSoundLR [ i ] = 0 ;
}
else if ( soundChannel [ i ] = = RIGHT )
{
UsingRight = 1 ;
modemtoSoundLR [ i ] = 1 ;
}
}
if ( UsingLeft & & UsingRight )
UsingBothChannels = 1 ;
2024-10-29 22:45:21 +00:00
useKISSControls = Dev - > useKISSControls - > isChecked ( ) ;
2023-09-04 19:06:44 +01:00
SCO = Dev - > singleChannelOutput - > isChecked ( ) ;
raduga = Dev - > colourWaterfall - > isChecked ( ) ;
AGWServ = Dev - > AGWEnabled - > isChecked ( ) ;
KISSServ = Dev - > KISSEnabled - > isChecked ( ) ;
Q = Dev - > KISSPort - > text ( ) ;
KISSPort = Q . toInt ( ) ;
Q = Dev - > AGWPort - > text ( ) ;
AGWPort = Q . toInt ( ) ;
2024-10-29 22:45:21 +00:00
Q = Dev - > MgmtPort - > text ( ) ;
MgmtPort = Q . toInt ( ) ;
Q = Dev - > SixPackSerial - > currentText ( ) ;
char temp [ 256 ] ;
strcpy ( temp , Q . toString ( ) . toUtf8 ( ) ) ;
if ( strlen ( temp ) )
strcpy ( SixPackDevice , temp ) ;
Q = Dev - > SixPackTCP - > text ( ) ;
SixPackPort = Q . toInt ( ) ;
SixPackEnable = Dev - > SixPackEnable - > isChecked ( ) ;
2023-09-04 19:06:44 +01:00
Q = Dev - > PTTPort - > currentText ( ) ;
2023-10-07 12:21:48 +01:00
strcpy ( temp , Q . toString ( ) . toUtf8 ( ) ) ;
if ( strlen ( temp ) )
strcpy ( PTTPort , temp ) ;
2023-09-04 19:06:44 +01:00
DualPTT = Dev - > DualPTT - > isChecked ( ) ;
TX_rotate = Dev - > txRotation - > isChecked ( ) ;
multiCore = Dev - > multiCore - > isChecked ( ) ;
2023-12-17 13:53:32 +00:00
darkTheme = Dev - > darkTheme - > isChecked ( ) ;
mysetstyle ( ) ;
2023-09-04 19:06:44 +01:00
if ( Dev - > CAT - > isChecked ( ) )
PTTMode = PTTCAT ;
else
PTTMode = PTTRTS ;
Q = Dev - > PTTOn - > text ( ) ;
strcpy ( PTTOnString , Q . toString ( ) . toUtf8 ( ) ) ;
Q = Dev - > PTTOff - > text ( ) ;
strcpy ( PTTOffString , Q . toString ( ) . toUtf8 ( ) ) ;
Q = Dev - > CATSpeed - > text ( ) ;
PTTBAUD = Q . toInt ( ) ;
Q = Dev - > UDPPort - > text ( ) ;
UDPClientPort = Q . toInt ( ) ;
Q = Dev - > UDPTXPort - > text ( ) ;
strcpy ( portString , Q . toString ( ) . toUtf8 ( ) ) ;
UDPServerPort = atoi ( portString ) ;
if ( strchr ( portString , ' / ' ) )
{
char * ptr = strlop ( portString , ' / ' ) ;
TXPort = atoi ( ptr ) ;
}
else
TXPort = UDPServerPort ;
Q = Dev - > UDPTXHost - > text ( ) ;
strcpy ( UDPHost , Q . toString ( ) . toUtf8 ( ) ) ;
UDPServ = Dev - > UDPEnabled - > isChecked ( ) ;
Q = Dev - > GPIOLeft - > text ( ) ;
pttGPIOPin = Q . toInt ( ) ;
Q = Dev - > GPIORight - > text ( ) ;
pttGPIOPinR = Q . toInt ( ) ;
Q = Dev - > VIDPID - > text ( ) ;
if ( strcmp ( PTTPort , " CM108 " ) = = 0 )
strcpy ( CM108Addr , Q . toString ( ) . toUtf8 ( ) ) ;
else if ( strcmp ( PTTPort , " HAMLIB " ) = = 0 )
{
HamLibPort = Q . toInt ( ) ;
Q = Dev - > PTTOn - > text ( ) ;
strcpy ( HamLibHost , Q . toString ( ) . toUtf8 ( ) ) ;
}
2024-07-23 21:26:30 +01:00
else if ( strcmp ( PTTPort , " FLRIG " ) = = 0 )
{
FLRigPort = Q . toInt ( ) ;
Q = Dev - > PTTOn - > text ( ) ;
strcpy ( FLRigHost , Q . toString ( ) . toUtf8 ( ) ) ;
}
2023-09-04 19:06:44 +01:00
Q = Dev - > WaterfallMax - > currentText ( ) ;
newMax = Q . toInt ( ) ;
Q = Dev - > WaterfallMin - > currentText ( ) ;
newMin = Q . toInt ( ) ;
if ( newMax ! = WaterfallMax | | newMin ! = WaterfallMin )
{
QMessageBox msgBox ;
msgBox . setText ( " QtSoundModem must restart to change Waterfall range. Program will close if you hit Ok \n "
" It may take up to 30 seconds for the program to start for the first time after changing settings " ) ;
msgBox . setStandardButtons ( QMessageBox : : Ok | QMessageBox : : Cancel ) ;
int i = msgBox . exec ( ) ;
if ( i = = QMessageBox : : Ok )
{
Configuring = 1 ; // Stop Waterfall
WaterfallMax = newMax ;
WaterfallMin = newMin ;
saveSettings ( ) ;
Closing = 1 ;
return ;
}
}
ClosePTTPort ( ) ;
OpenPTTPort ( ) ;
2023-12-17 13:53:32 +00:00
NeedWaterfallHeaders = true ;
2023-09-04 19:06:44 +01:00
delete ( Dev ) ;
saveSettings ( ) ;
deviceUI - > accept ( ) ;
if ( cardChanged )
{
InitSound ( 1 ) ;
}
2023-09-12 21:38:15 +01:00
// Reset title and tooltip in case ports changed
2023-09-04 19:06:44 +01:00
char Title [ 128 ] ;
2023-09-12 21:38:15 +01:00
sprintf ( Title , " QtSoundModem Version %s Ports %d%s/%d%s " , VersionString , AGWPort , AGWServ ? " * " : " " , KISSPort , KISSServ ? " * " : " " ) ;
2023-09-04 19:06:44 +01:00
w - > setWindowTitle ( Title ) ;
sprintf ( Title , " QtSoundModem %d %d " , AGWPort , KISSPort ) ;
if ( trayIcon )
trayIcon - > setToolTip ( Title ) ;
QSize newSize ( this - > size ( ) ) ;
QSize oldSize ( this - > size ( ) ) ;
QResizeEvent * myResizeEvent = new QResizeEvent ( newSize , oldSize ) ;
QCoreApplication : : postEvent ( this , myResizeEvent ) ;
}
void QtSoundModem : : devicereject ( )
{
delete ( Dev ) ;
deviceUI - > reject ( ) ;
}
void QtSoundModem : : handleButton ( int Port , int Type )
{
// interlock calib with CWID
if ( calib_mode [ 0 ] = = 4 ) // CWID
return ;
doCalib ( Port , Type ) ;
}
2023-12-17 13:53:32 +00:00
2024-07-23 21:26:30 +01:00
2023-09-04 19:06:44 +01:00
void QtSoundModem : : doRestartWF ( )
{
2024-07-23 21:26:30 +01:00
return ;
if ( ( ( tx_status [ 0 ] | tx_status [ 1 ] | tx_status [ 2 ] | tx_status [ 3 ] ) ! = TX_SILENCE ) | | inWaterfall )
2023-09-04 19:06:44 +01:00
{
2023-12-17 13:53:32 +00:00
// in waterfall update thread
wftimer - > start ( 5000 ) ;
return ;
2023-09-04 19:06:44 +01:00
}
2024-07-23 21:26:30 +01:00
wftimer - > start ( 1000 * 300 ) ;
2023-12-17 13:53:32 +00:00
lockWaterfall = true ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
if ( Firstwaterfall | Secondwaterfall )
2023-09-04 19:06:44 +01:00
{
2023-12-17 13:53:32 +00:00
initWaterfall ( 0 ) ;
initWaterfall ( 1 ) ;
2023-09-04 19:06:44 +01:00
}
2023-10-07 12:21:48 +01:00
delete ( RXLevel ) ;
delete ( ui . RXLevel ) ;
ui . RXLevel = new QLabel ( ui . centralWidget ) ;
RXLevelCopy = ui . RXLevel ;
2023-12-17 13:53:32 +00:00
ui . RXLevel - > setGeometry ( QRect ( 780 , 14 , 150 , 11 ) ) ;
ui . RXLevel - > setFrameShape ( QFrame : : Box ) ;
ui . RXLevel - > setFrameShadow ( QFrame : : Sunken ) ;
delete ( RXLevel2 ) ;
delete ( ui . RXLevel2 ) ;
ui . RXLevel2 = new QLabel ( ui . centralWidget ) ;
RXLevel2Copy = ui . RXLevel2 ;
ui . RXLevel2 - > setGeometry ( QRect ( 780 , 23 , 150 , 11 ) ) ;
ui . RXLevel2 - > setFrameShape ( QFrame : : Box ) ;
ui . RXLevel2 - > setFrameShadow ( QFrame : : Sunken ) ;
2023-10-07 12:21:48 +01:00
RXLevel = new QImage ( 150 , 10 , QImage : : Format_RGB32 ) ;
RXLevel - > fill ( cyan ) ;
2023-12-17 13:53:32 +00:00
RXLevel2 = new QImage ( 150 , 10 , QImage : : Format_RGB32 ) ;
RXLevel2 - > fill ( white ) ;
2023-10-07 12:21:48 +01:00
ui . RXLevel - > setVisible ( 1 ) ;
2024-04-13 17:48:58 +01:00
ui . RXLevel2 - > setVisible ( 1 ) ;
2023-12-17 13:53:32 +00:00
lockWaterfall = false ;
2023-09-04 19:06:44 +01:00
}
void QtSoundModem : : doAbout ( )
{
QMessageBox : : about ( this , tr ( " About " ) ,
tr ( " G8BPQ's port of UZ7HO's Soundmodem \n \n Copyright (C) 2019-2020 Andrei Kopanchuk UZ7HO " ) ) ;
}
void QtSoundModem : : doCalibrate ( )
{
Ui_calDialog Calibrate ;
{
QDialog UI ;
Calibrate . setupUi ( & UI ) ;
connect ( Calibrate . Low_A , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . High_A , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Both_A , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Stop_A , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Low_B , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . High_B , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Both_B , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Stop_B , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Low_C , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . High_C , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Both_C , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Stop_C , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Low_D , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . High_D , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Both_D , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
connect ( Calibrate . Stop_D , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
2024-10-29 22:45:21 +00:00
connect ( Calibrate . Cal1500 , SIGNAL ( released ( ) ) , this , SLOT ( clickedSlot ( ) ) ) ;
2023-09-04 19:06:44 +01:00
/*
connect ( Calibrate . Low_A , & QPushButton : : released , this , [ = ] { handleButton ( 0 , 1 ) ; } ) ;
connect ( Calibrate . High_A , & QPushButton : : released , this , [ = ] { handleButton ( 0 , 2 ) ; } ) ;
connect ( Calibrate . Both_A , & QPushButton : : released , this , [ = ] { handleButton ( 0 , 3 ) ; } ) ;
connect ( Calibrate . Stop_A , & QPushButton : : released , this , [ = ] { handleButton ( 0 , 0 ) ; } ) ;
connect ( Calibrate . Low_B , & QPushButton : : released , this , [ = ] { handleButton ( 1 , 1 ) ; } ) ;
connect ( Calibrate . High_B , & QPushButton : : released , this , [ = ] { handleButton ( 1 , 2 ) ; } ) ;
connect ( Calibrate . Both_B , & QPushButton : : released , this , [ = ] { handleButton ( 1 , 3 ) ; } ) ;
connect ( Calibrate . Stop_B , & QPushButton : : released , this , [ = ] { handleButton ( 1 , 0 ) ; } ) ;
// connect(Calibrate.High_A, SIGNAL(released()), this, SLOT(handleButton(1, 2)));
*/
UI . exec ( ) ;
}
}
void QtSoundModem : : RefreshSpectrum ( unsigned char * Data )
{
int i ;
// Last 4 bytes are level busy and Tuning lines
2023-12-17 13:53:32 +00:00
Waterfall - > fill ( Black ) ;
2023-09-04 19:06:44 +01:00
if ( Data [ 206 ] ! = LastLevel )
{
LastLevel = Data [ 206 ] ;
// RefreshLevel(LastLevel);
}
if ( Data [ 207 ] ! = LastBusy )
{
LastBusy = Data [ 207 ] ;
// Busy->setVisible(LastBusy);
}
for ( i = 0 ; i < 205 ; i + + )
{
int val = Data [ 0 ] ;
if ( val > 63 )
val = 63 ;
2023-12-17 13:53:32 +00:00
Waterfall - > setPixel ( i , val , Yellow ) ;
2023-09-04 19:06:44 +01:00
if ( val < 62 )
2023-12-17 13:53:32 +00:00
Waterfall - > setPixel ( i , val + 1 , Gold ) ;
2023-09-04 19:06:44 +01:00
Data + + ;
}
2023-12-17 13:53:32 +00:00
ui . Waterfall - > setPixmap ( QPixmap : : fromImage ( * Waterfall ) ) ;
2023-09-04 19:06:44 +01:00
}
2024-04-13 17:48:58 +01:00
void RefreshLevel ( unsigned int Level , unsigned int LevelR )
2023-10-07 12:21:48 +01:00
{
// Redraw the RX Level Bar Graph
unsigned int x , y ;
for ( x = 0 ; x < 150 ; x + + )
{
for ( y = 0 ; y < 10 ; y + + )
{
if ( x < Level )
{
if ( Level < 50 )
RXLevel - > setPixel ( x , y , yellow ) ;
else if ( Level > 135 )
RXLevel - > setPixel ( x , y , red ) ;
else
RXLevel - > setPixel ( x , y , green ) ;
}
else
RXLevel - > setPixel ( x , y , white ) ;
}
}
2024-07-23 21:26:30 +01:00
// RXLevelCopy->setPixmap(QPixmap::fromImage(*RXLevel));
2024-04-13 17:48:58 +01:00
for ( x = 0 ; x < 150 ; x + + )
{
for ( y = 0 ; y < 10 ; y + + )
{
if ( x < LevelR )
{
if ( LevelR < 50 )
RXLevel2 - > setPixel ( x , y , yellow ) ;
else if ( LevelR > 135 )
RXLevel2 - > setPixel ( x , y , red ) ;
else
RXLevel2 - > setPixel ( x , y , green ) ;
}
else
RXLevel2 - > setPixel ( x , y , white ) ;
}
}
2024-07-23 21:26:30 +01:00
emit t - > setLevelImage ( ) ;
/// RXLevel2Copy->setPixmap(QPixmap::fromImage(*RXLevel2));
2023-10-07 12:21:48 +01:00
}
extern " C " unsigned char CurrentLevel ;
2024-04-13 17:48:58 +01:00
extern " C " unsigned char CurrentLevelR ;
2023-10-07 12:21:48 +01:00
2023-09-04 19:06:44 +01:00
void QtSoundModem : : RefreshWaterfall ( int snd_ch , unsigned char * Data )
{
int j ;
unsigned char * Line ;
2023-12-17 13:53:32 +00:00
int len = Waterfall - > bytesPerLine ( ) ;
2023-09-04 19:06:44 +01:00
int TopLine = NextWaterfallLine [ snd_ch ] ;
// Write line to cyclic buffer then draw starting with the line just written
// Length is 208 bytes, including Level and Busy flags
memcpy ( & WaterfallLines [ snd_ch ] [ NextWaterfallLine [ snd_ch ] + + ] [ 0 ] , Data , 206 ) ;
if ( NextWaterfallLine [ snd_ch ] > 63 )
NextWaterfallLine [ snd_ch ] = 0 ;
for ( j = 63 ; j > 0 ; j - - )
{
2023-12-17 13:53:32 +00:00
Line = Waterfall - > scanLine ( j ) ;
2023-09-04 19:06:44 +01:00
memcpy ( Line , & WaterfallLines [ snd_ch ] [ TopLine + + ] [ 0 ] , len ) ;
if ( TopLine > 63 )
TopLine = 0 ;
}
2023-12-17 13:53:32 +00:00
ui . Waterfall - > setPixmap ( QPixmap : : fromImage ( * Waterfall ) ) ;
2023-09-04 19:06:44 +01:00
}
void QtSoundModem : : sendtoTrace ( char * Msg , int tx )
{
const QTextCursor old_cursor = monWindowCopy - > textCursor ( ) ;
const int old_scrollbar_value = monWindowCopy - > verticalScrollBar ( ) - > value ( ) ;
const bool is_scrolled_down = old_scrollbar_value = = monWindowCopy - > verticalScrollBar ( ) - > maximum ( ) ;
// Move the cursor to the end of the document.
monWindowCopy - > moveCursor ( QTextCursor : : End ) ;
// Insert the text at the position of the cursor (which is the end of the document).
if ( tx )
2023-12-17 13:53:32 +00:00
monWindowCopy - > setTextColor ( txText ) ;
2023-09-04 19:06:44 +01:00
else
2023-12-17 13:53:32 +00:00
monWindowCopy - > setTextColor ( rxText ) ;
2023-09-04 19:06:44 +01:00
monWindowCopy - > textCursor ( ) . insertText ( Msg ) ;
if ( old_cursor . hasSelection ( ) | | ! is_scrolled_down )
{
// The user has selected text or scrolled away from the bottom: maintain position.
monWindowCopy - > setTextCursor ( old_cursor ) ;
monWindowCopy - > verticalScrollBar ( ) - > setValue ( old_scrollbar_value ) ;
}
else
{
// The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom.
monWindowCopy - > moveCursor ( QTextCursor : : End ) ;
monWindowCopy - > verticalScrollBar ( ) - > setValue ( monWindowCopy - > verticalScrollBar ( ) - > maximum ( ) ) ;
}
free ( Msg ) ;
}
// I think this does the waterfall
typedef struct TRGBQ_t
{
Byte b , g , r , re ;
} TRGBWQ ;
typedef struct tagRECT
{
int left ;
int top ;
int right ;
int bottom ;
} RECT ;
unsigned int RGBWF [ 256 ] ;
extern " C " void init_raduga ( )
{
Byte offset [ 6 ] = { 0 , 51 , 102 , 153 , 204 } ;
Byte i , n ;
for ( n = 0 ; n < 52 ; n + + )
{
i = n * 5 ;
RGBWF [ n + offset [ 0 ] ] = qRgb ( 0 , 0 , i ) ;
RGBWF [ n + offset [ 1 ] ] = qRgb ( 0 , i , 255 ) ;
RGBWF [ n + offset [ 2 ] ] = qRgb ( 0 , 255 , 255 - i ) ;
RGBWF [ n + offset [ 3 ] ] = qRgb ( 1 , 255 , 0 ) ;
RGBWF [ n + offset [ 4 ] ] = qRgb ( 255 , 255 - 1 , 0 ) ;
}
}
extern " C " int nonGUIMode ;
// This draws the Frequency Scale on Waterfall
2023-12-17 13:53:32 +00:00
extern " C " void DrawFreqTicks ( )
2023-09-04 19:06:44 +01:00
{
if ( nonGUIMode )
return ;
2023-12-17 13:53:32 +00:00
// Draw Frequency Markers on waterfall header(s);
2023-09-04 19:06:44 +01:00
int x , i ;
char Textxx [ 20 ] ;
2023-12-17 13:53:32 +00:00
QImage * bm = Waterfall ;
2023-09-04 19:06:44 +01:00
QPainter qPainter ( bm ) ;
qPainter . setBrush ( Qt : : black ) ;
qPainter . setPen ( Qt : : white ) ;
2023-12-17 13:53:32 +00:00
int Chan ;
2023-09-04 19:06:44 +01:00
# ifdef WIN32
2023-12-17 13:53:32 +00:00
int Top = 3 ;
2023-09-04 19:06:44 +01:00
# else
2023-12-17 13:53:32 +00:00
int Top = 4 ;
2023-09-04 19:06:44 +01:00
# endif
2023-12-17 13:53:32 +00:00
int Base = 0 ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
for ( Chan = 0 ; Chan < 2 ; Chan + + )
{
if ( Chan = = 1 | | ( ( UsingBothChannels = = 0 ) & & ( UsingRight = = 1 ) ) )
sprintf ( Textxx , " Right " ) ;
else
sprintf ( Textxx , " Left " ) ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
qPainter . drawText ( 2 , Top , 100 , 20 , 0 , Textxx ) ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
// We drew markers every 100 Hz or 100 / binsize pixels
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
int Markers = ( ( WaterfallMax - WaterfallMin ) / 100 ) + 5 ; // Number of Markers to draw
int Freq = WaterfallMin ;
float PixelsPerMarker = 100.0 / BinSize ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
for ( i = 0 ; i < Markers ; i + + )
2023-09-04 19:06:44 +01:00
{
2023-12-17 13:53:32 +00:00
x = round ( PixelsPerMarker * i ) ;
if ( x < 1025 )
{
if ( ( Freq % 500 ) = = 0 )
qPainter . drawLine ( x , Base + 22 , x , Base + 15 ) ;
else
qPainter . drawLine ( x , Base + 22 , x , Base + 18 ) ;
if ( ( Freq % 500 ) = = 0 )
{
sprintf ( Textxx , " %d " , Freq ) ;
if ( x < 924 )
qPainter . drawText ( x - 12 , Top , 100 , 20 , 0 , Textxx ) ;
}
}
Freq + = 100 ;
2023-09-04 19:06:44 +01:00
}
2023-12-17 13:53:32 +00:00
if ( UsingBothChannels = = 0 )
break ;
Top + = WaterfallTotalPixels ;
Base = WaterfallTotalPixels ;
2023-09-04 19:06:44 +01:00
}
}
2023-12-17 13:53:32 +00:00
// These draws the frequency Markers on the Waterfall
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
void DrawModemFreqRange ( )
2023-09-04 19:06:44 +01:00
{
if ( nonGUIMode )
return ;
2023-12-17 13:53:32 +00:00
// Draws the modem freq bars on waterfall header(s)
2023-09-04 19:06:44 +01:00
int x1 , x2 , k , pos1 , pos2 , pos3 ;
2023-12-17 13:53:32 +00:00
QImage * bm = Waterfall ;
2023-09-04 19:06:44 +01:00
QPainter qPainter ( bm ) ;
qPainter . setBrush ( Qt : : NoBrush ) ;
qPainter . setPen ( Qt : : white ) ;
2023-12-17 13:53:32 +00:00
int Chan ;
int LRtoDisplay = LEFT ;
int top = 0 ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
for ( Chan = 0 ; Chan < 2 ; Chan + + )
2023-09-04 19:06:44 +01:00
{
2023-12-17 13:53:32 +00:00
if ( Chan = = 1 | | ( ( UsingBothChannels = = 0 ) & & ( UsingRight = = 1 ) ) )
LRtoDisplay = RIGHT ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
// bm->fill(black);
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
// qPainter.fillRect(top, 23, 1024, 10, Qt::black);
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
// We drew markers every 100 Hz or 100 / binsize pixels
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
float PixelsPerHz = 1.0 / BinSize ;
k = 26 + top ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
// draw all enabled ports on the ports on this soundcard
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
// First Modem is always on the first waterfall
// If second is enabled it is on the first unless different
// channel from first
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
for ( int i = 0 ; i < 4 ; i + + )
2023-09-04 19:06:44 +01:00
{
2023-12-17 13:53:32 +00:00
if ( soundChannel [ i ] ! = LRtoDisplay )
continue ;
pos1 = roundf ( ( ( ( rxOffset + chanOffset [ i ] + rx_freq [ i ] ) - 0.5 * rx_shift [ i ] ) - WaterfallMin ) * PixelsPerHz ) - 5 ;
pos2 = roundf ( ( ( ( rxOffset + chanOffset [ i ] + rx_freq [ i ] ) + 0.5 * rx_shift [ i ] ) - WaterfallMin ) * PixelsPerHz ) - 5 ;
pos3 = roundf ( ( ( rxOffset + chanOffset [ i ] + rx_freq [ i ] ) ) - WaterfallMin * PixelsPerHz ) ;
x1 = pos1 + 5 ;
x2 = pos2 + 5 ;
qPainter . setPen ( Qt : : white ) ;
qPainter . drawLine ( x1 , k , x2 , k ) ;
qPainter . drawLine ( x1 , k - 3 , x1 , k + 3 ) ;
qPainter . drawLine ( x2 , k - 3 , x2 , k + 3 ) ;
// qPainter.drawLine(pos3, k - 3, pos3, k + 3);
if ( rxOffset | | chanOffset [ i ] )
{
// Draw TX posn if rxOffset used
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
pos3 = roundf ( ( rx_freq [ i ] - WaterfallMin ) * PixelsPerHz ) ;
qPainter . setPen ( Qt : : magenta ) ;
qPainter . drawLine ( pos3 , k - 3 , pos3 , k + 3 ) ;
qPainter . drawLine ( pos3 , k - 3 , pos3 , k + 3 ) ;
qPainter . drawLine ( pos3 - 2 , k - 3 , pos3 + 2 , k - 3 ) ;
}
k + = 3 ;
2023-09-04 19:06:44 +01:00
}
2023-12-17 13:53:32 +00:00
if ( UsingBothChannels = = 0 )
break ;
2023-10-07 12:21:48 +01:00
2023-12-17 13:53:32 +00:00
LRtoDisplay = RIGHT ;
top = WaterfallTotalPixels ;
2023-09-04 19:06:44 +01:00
}
}
void doWaterfallThread ( void * param ) ;
extern " C " void doWaterfall ( int snd_ch )
{
if ( nonGUIMode )
return ;
if ( Closing )
return ;
2023-12-17 13:53:32 +00:00
if ( lockWaterfall )
return ;
2023-09-04 19:06:44 +01:00
// if (multiCore) // Run modems in separate threads
// _beginthread(doWaterfallThread, 0, xx);
// else
doWaterfallThread ( ( void * ) ( size_t ) snd_ch ) ;
}
2023-12-17 13:53:32 +00:00
extern " C " void displayWaterfall ( )
{
// if we are using both channels but only want right need to extract correct half of Image
if ( Waterfall = = nullptr )
return ;
if ( UsingBothChannels & & ( Firstwaterfall = = 0 ) )
WaterfallCopy - > setAlignment ( Qt : : AlignBottom | Qt : : AlignLeft ) ;
else
WaterfallCopy - > setAlignment ( Qt : : AlignTop | Qt : : AlignLeft ) ;
2024-07-23 21:26:30 +01:00
// WaterfallCopy->setPixmap(QPixmap::fromImage(*Waterfall));
emit t - > setWaterfallImage ( ) ;
2023-12-17 13:53:32 +00:00
}
2023-09-04 19:06:44 +01:00
extern " C " float aFFTAmpl [ 1024 ] ;
2023-09-12 21:38:15 +01:00
extern " C " void SMUpdateBusyDetector ( int LR , float * Real , float * Imag ) ;
2023-09-04 19:06:44 +01:00
void doWaterfallThread ( void * param )
{
int snd_ch = ( int ) ( size_t ) param ;
2023-12-17 13:53:32 +00:00
if ( lockWaterfall )
return ;
if ( Configuring )
return ;
2024-07-23 21:26:30 +01:00
if ( inWaterfall )
return ;
2023-12-17 13:53:32 +00:00
inWaterfall = true ; // don't allow restart waterfall
2023-10-07 12:21:48 +01:00
if ( snd_ch = = 1 & & UsingLeft = = 0 ) // Only using right
snd_ch = 0 ; // Samples are in first buffer
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
QImage * bm = Waterfall ;
2023-09-04 19:06:44 +01:00
int i ;
single mag ;
UCHAR * p ;
UCHAR Line [ 4096 ] = " " ; // 4 bytes per pixel
int lineLen , Start , End ;
word hFFTSize ;
Byte n ;
float RealOut [ 8192 ] = { 0 } ;
float ImagOut [ 8192 ] ;
2024-04-13 17:48:58 +01:00
RefreshLevel ( CurrentLevel , CurrentLevelR ) ; // Signal Level
2023-10-07 12:21:48 +01:00
2023-09-04 19:06:44 +01:00
hFFTSize = FFTSize / 2 ;
// I think an FFT should produce n/2 bins, each of Samp/n Hz
// Looks like my code only works with n a power of 2
// So can use 1024 or 4096. 1024 gives 512 bins of 11.71875 and a 512 pixel
// display (is this enough?)
Start = ( WaterfallMin / BinSize ) ; // First and last bins to process
End = ( WaterfallMax / BinSize ) ;
if ( 0 ) //RSID_WF
{
// Use the Magnitudes in float aFFTAmpl[RSID_FFT_SIZE];
for ( i = 0 ; i < hFFTSize ; i + + )
{
mag = aFFTAmpl [ i ] ;
mag * = 0.00000042f ;
if ( mag < 0.00001f )
mag = 0.00001f ;
if ( mag > 1.0f )
mag = 1.0f ;
mag = 22 * log2f ( mag ) + 255 ;
if ( mag < 0 )
mag = 0 ;
fft_disp [ snd_ch ] [ i ] = round ( mag ) ;
}
}
else
2023-12-17 13:53:32 +00:00
{
2023-09-04 19:06:44 +01:00
dofft ( & fft_buf [ snd_ch ] [ 0 ] , RealOut , ImagOut ) ;
// FourierTransform(1024, &fft_buf[snd_ch][0], RealOut, ImagOut, 0);
for ( i = Start ; i < End ; i + + )
{
//mag: = ComplexMag(fft_d[i])*0.00000042;
// mag = sqrtf(powf(RealOut[i], 2) + powf(ImagOut[i], 2)) * 0.00000042f;
mag = powf ( RealOut [ i ] , 2 ) ;
mag + = powf ( ImagOut [ i ] , 2 ) ;
mag = sqrtf ( mag ) ;
mag * = 0.00000042f ;
if ( mag > MaxMagOut )
{
MaxMagOut = mag ;
MaxMagIndex = i ;
}
if ( mag < 0.00001f )
mag = 0.00001f ;
if ( mag > 1.0f )
mag = 1.0f ;
mag = 22 * log2f ( mag ) + 255 ;
if ( mag < 0 )
mag = 0 ;
MagOut [ i ] = mag ; // for Freq Guess
fft_disp [ snd_ch ] [ i ] = round ( mag ) ;
}
}
2023-09-12 21:38:15 +01:00
SMUpdateBusyDetector ( snd_ch , RealOut , ImagOut ) ;
2024-07-23 21:26:30 +01:00
// we always do fft so we can get centre freq and do busy detect. But only update waterfall if on display
2023-10-07 12:21:48 +01:00
2023-09-04 19:06:44 +01:00
if ( bm = = 0 )
2023-12-17 13:53:32 +00:00
{
inWaterfall = false ;
2023-09-04 19:06:44 +01:00
return ;
2023-12-17 13:53:32 +00:00
}
if ( ( Firstwaterfall = = 0 & & snd_ch = = 0 ) | | ( Secondwaterfall = = 0 & & snd_ch = = 1 ) )
2023-09-04 19:06:44 +01:00
{
2023-12-17 13:53:32 +00:00
inWaterfall = false ;
return ;
}
2023-10-07 12:21:48 +01:00
2023-12-17 13:53:32 +00:00
p = Line ;
lineLen = 4096 ;
2023-10-07 12:21:48 +01:00
2023-12-17 13:53:32 +00:00
if ( raduga = = DISP_MONO )
{
for ( i = Start ; i < End ; i + + )
2023-09-04 19:06:44 +01:00
{
2023-12-17 13:53:32 +00:00
n = fft_disp [ snd_ch ] [ i ] ;
* ( p + + ) = n ; // all colours the same
* ( p + + ) = n ;
* ( p + + ) = n ;
p + + ;
2023-09-04 19:06:44 +01:00
}
2023-12-17 13:53:32 +00:00
}
else
{
for ( i = Start ; i < End ; i + + )
2023-09-04 19:06:44 +01:00
{
2023-12-17 13:53:32 +00:00
n = fft_disp [ snd_ch ] [ i ] ;
memcpy ( p , & RGBWF [ n ] , 4 ) ;
p + = 4 ;
2023-09-04 19:06:44 +01:00
}
2023-12-17 13:53:32 +00:00
}
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
// Scroll
2023-09-04 19:06:44 +01:00
2024-07-23 21:26:30 +01:00
2023-12-17 13:53:32 +00:00
int TopLine = NextWaterfallLine [ snd_ch ] ;
int TopScanLine = WaterfallHeaderPixels ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
if ( snd_ch )
TopScanLine + = WaterfallTotalPixels ;
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
// Write line to cyclic buffer then draw starting with the line just written
2023-09-04 19:06:44 +01:00
2023-12-17 13:53:32 +00:00
memcpy ( & WaterfallLines [ snd_ch ] [ NextWaterfallLine [ snd_ch ] + + ] [ 0 ] , Line , 4096 ) ;
if ( NextWaterfallLine [ snd_ch ] > 79 )
NextWaterfallLine [ snd_ch ] = 0 ;
2024-07-23 21:26:30 +01:00
// Sanity check
if ( ( 79 + TopScanLine ) > = bm - > height ( ) )
{
printf ( " Invalid WFMaxLine %d \n " , bm - > height ( ) ) ;
exit ( 1 ) ;
}
2023-10-07 12:21:48 +01:00
2023-12-17 13:53:32 +00:00
for ( int j = 79 ; j > 0 ; j - - )
2023-09-04 19:06:44 +01:00
{
2023-12-17 13:53:32 +00:00
p = bm - > scanLine ( j + TopScanLine ) ;
2024-07-23 21:26:30 +01:00
if ( p = = nullptr )
{
printf ( " Invalid WF Pointer \n " ) ;
exit ( 1 ) ;
}
2023-12-17 13:53:32 +00:00
memcpy ( p , & WaterfallLines [ snd_ch ] [ TopLine ] [ 0 ] , lineLen ) ;
TopLine + + ;
if ( TopLine > 79 )
TopLine = 0 ;
2023-09-04 19:06:44 +01:00
}
2023-12-17 13:53:32 +00:00
inWaterfall = false ;
2023-09-04 19:06:44 +01:00
}
2024-07-23 21:26:30 +01:00
void QtSoundModem : : setWaterfallImage ( )
{
ui . Waterfall - > setPixmap ( QPixmap : : fromImage ( * Waterfall ) ) ;
}
void QtSoundModem : : setLevelImage ( )
{
RXLevelCopy - > setPixmap ( QPixmap : : fromImage ( * RXLevel ) ) ;
RXLevel2Copy - > setPixmap ( QPixmap : : fromImage ( * RXLevel2 ) ) ;
}
void QtSoundModem : : setConstellationImage ( int chan , int Qual )
{
char QualText [ 64 ] ;
sprintf ( QualText , " Chan %c Qual = %d " , chan + ' A ' , Qual ) ;
QualLabel [ chan ] - > setText ( QualText ) ;
constellationLabel [ chan ] - > setPixmap ( QPixmap : : fromImage ( * Constellation [ chan ] ) ) ;
}
2023-09-04 19:06:44 +01:00
void QtSoundModem : : changeEvent ( QEvent * e )
{
if ( e - > type ( ) = = QEvent : : WindowStateChange )
{
QWindowStateChangeEvent * ev = static_cast < QWindowStateChangeEvent * > ( e ) ;
qDebug ( ) < < windowState ( ) ;
if ( ! ( ev - > oldState ( ) & Qt : : WindowMinimized ) & & windowState ( ) & Qt : : WindowMinimized )
{
if ( trayIcon )
setVisible ( false ) ;
}
// if (!(ev->oldState() != Qt::WindowNoState) && windowState() == Qt::WindowNoState)
// {
// QMessageBox::information(this, "", "Window has been restored");
// }
}
QWidget : : changeEvent ( e ) ;
}
# include <QCloseEvent>
void QtSoundModem : : closeEvent ( QCloseEvent * event )
{
UNUSED ( event ) ;
QSettings mysettings ( " QtSoundModem.ini " , QSettings : : IniFormat ) ;
mysettings . setValue ( " geometry " , QWidget : : saveGeometry ( ) ) ;
mysettings . setValue ( " windowState " , saveState ( ) ) ;
Closing = TRUE ;
qDebug ( ) < < " Closing " ;
QThread : : msleep ( 100 ) ;
}
QtSoundModem : : ~ QtSoundModem ( )
{
qDebug ( ) < < " Saving Settings " ;
2024-07-23 21:26:30 +01:00
closeTraceLog ( ) ;
2023-09-04 19:06:44 +01:00
QSettings mysettings ( " QtSoundModem.ini " , QSettings : : IniFormat ) ;
mysettings . setValue ( " geometry " , saveGeometry ( ) ) ;
mysettings . setValue ( " windowState " , saveState ( ) ) ;
saveSettings ( ) ;
Closing = TRUE ;
qDebug ( ) < < " Closing " ;
QThread : : msleep ( 100 ) ;
}
extern " C " void QSleep ( int ms )
{
QThread : : msleep ( ms ) ;
}
int upd_time = 30 ;
void QtSoundModem : : show_grid ( )
{
// This refeshes the session list
int snd_ch , i , num_rows , row_idx ;
QTableWidgetItem * item ;
2024-07-23 21:26:30 +01:00
const char * msg = " " ;
2023-09-04 19:06:44 +01:00
int speed_tx , speed_rx ;
if ( grid_time < 10 )
{
grid_time + + ;
return ;
}
grid_time = 0 ;
//label7.Caption = inttostr(stat_r_mem); mem_arq
num_rows = 0 ;
row_idx = 0 ;
for ( snd_ch = 0 ; snd_ch < 4 ; snd_ch + + )
{
for ( i = 0 ; i < port_num ; i + + )
{
if ( AX25Port [ snd_ch ] [ i ] . status ! = STAT_NO_LINK )
num_rows + + ;
}
}
if ( num_rows = = 0 )
{
sessionTable - > clearContents ( ) ;
sessionTable - > setRowCount ( 0 ) ;
sessionTable - > setRowCount ( 1 ) ;
}
else
sessionTable - > setRowCount ( num_rows ) ;
for ( snd_ch = 0 ; snd_ch < 4 ; snd_ch + + )
{
for ( i = 0 ; i < port_num ; i + + )
{
if ( AX25Port [ snd_ch ] [ i ] . status ! = STAT_NO_LINK )
{
switch ( AX25Port [ snd_ch ] [ i ] . status )
{
case STAT_NO_LINK :
msg = " No link " ;
break ;
case STAT_LINK :
msg = " Link " ;
break ;
case STAT_CHK_LINK :
msg = " Chk link " ;
break ;
case STAT_WAIT_ANS :
msg = " Wait ack " ;
break ;
case STAT_TRY_LINK :
msg = " Try link " ;
break ;
case STAT_TRY_UNLINK :
msg = " Try unlink " ;
}
item = new QTableWidgetItem ( ( char * ) AX25Port [ snd_ch ] [ i ] . mycall ) ;
sessionTable - > setItem ( row_idx , 0 , item ) ;
item = new QTableWidgetItem ( AX25Port [ snd_ch ] [ i ] . kind ) ;
sessionTable - > setItem ( row_idx , 11 , item ) ;
item = new QTableWidgetItem ( ( char * ) AX25Port [ snd_ch ] [ i ] . corrcall ) ;
sessionTable - > setItem ( row_idx , 1 , item ) ;
item = new QTableWidgetItem ( msg ) ;
sessionTable - > setItem ( row_idx , 2 , item ) ;
item = new QTableWidgetItem ( QString : : number ( AX25Port [ snd_ch ] [ i ] . info . stat_s_pkt ) ) ;
sessionTable - > setItem ( row_idx , 3 , item ) ;
item = new QTableWidgetItem ( QString : : number ( AX25Port [ snd_ch ] [ i ] . info . stat_s_byte ) ) ;
sessionTable - > setItem ( row_idx , 4 , item ) ;
item = new QTableWidgetItem ( QString : : number ( AX25Port [ snd_ch ] [ i ] . info . stat_r_pkt ) ) ;
sessionTable - > setItem ( row_idx , 5 , item ) ;
item = new QTableWidgetItem ( QString : : number ( AX25Port [ snd_ch ] [ i ] . info . stat_r_byte ) ) ;
sessionTable - > setItem ( row_idx , 6 , item ) ;
item = new QTableWidgetItem ( QString : : number ( AX25Port [ snd_ch ] [ i ] . info . stat_r_fc ) ) ;
sessionTable - > setItem ( row_idx , 7 , item ) ;
item = new QTableWidgetItem ( QString : : number ( AX25Port [ snd_ch ] [ i ] . info . stat_fec_count ) ) ;
sessionTable - > setItem ( row_idx , 8 , item ) ;
if ( grid_timer ! = upd_time )
grid_timer + + ;
else
{
grid_timer = 0 ;
speed_tx = round ( abs ( AX25Port [ snd_ch ] [ i ] . info . stat_s_byte - AX25Port [ snd_ch ] [ i ] . info . stat_l_s_byte ) / upd_time ) ;
speed_rx = round ( abs ( AX25Port [ snd_ch ] [ i ] . info . stat_r_byte - AX25Port [ snd_ch ] [ i ] . info . stat_l_r_byte ) / upd_time ) ;
item = new QTableWidgetItem ( QString : : number ( speed_tx ) ) ;
sessionTable - > setItem ( row_idx , 9 , item ) ;
item = new QTableWidgetItem ( QString : : number ( speed_rx ) ) ;
sessionTable - > setItem ( row_idx , 10 , item ) ;
AX25Port [ snd_ch ] [ i ] . info . stat_l_r_byte = AX25Port [ snd_ch ] [ i ] . info . stat_r_byte ;
AX25Port [ snd_ch ] [ i ] . info . stat_l_s_byte = AX25Port [ snd_ch ] [ i ] . info . stat_s_byte ;
}
row_idx + + ;
}
}
}
}
// "Copy on Select" Code
void QtSoundModem : : onTEselectionChanged ( )
{
QTextEdit * x = static_cast < QTextEdit * > ( QObject : : sender ( ) ) ;
x - > copy ( ) ;
}
2023-09-12 21:38:15 +01:00
# define ConstellationHeight 121
# define ConstellationWidth 121
# define PLOTRADIUS 60
# define MAX(x, y) ((x) > (y) ? (x) : (y))
extern " C " int SMUpdatePhaseConstellation ( int chan , float * Phases , float * Mags , int intPSKPhase , int Count )
{
2024-07-23 21:26:30 +01:00
// Subroutine to update Constellation plot for PSK modes...
2023-09-12 21:38:15 +01:00
// Skip plotting and calculations of intPSKPhase(0) as this is a reference phase (9/30/2014)
float dblPhaseError ;
float dblPhaseErrorSum = 0 ;
float intP = 0 ;
float dblRad = 0 ;
float dblAvgRad = 0 ;
float dbPhaseStep ;
float MagMax = 0 ;
float dblPlotRotation = 0 ;
int i , intQuality ;
int intX , intY ;
int yCenter = ( ConstellationHeight - 2 ) / 2 ;
int xCenter = ( ConstellationWidth - 2 ) / 2 ;
if ( Count = = 0 )
return 0 ;
2023-10-07 12:21:48 +01:00
if ( nonGUIMode = = 0 )
{
Constellation [ chan ] - > fill ( black ) ;
for ( i = 0 ; i < 120 ; i + + )
{
Constellation [ chan ] - > setPixel ( xCenter , i , cyan ) ;
Constellation [ chan ] - > setPixel ( i , xCenter , cyan ) ;
}
}
2023-09-12 21:38:15 +01:00
dbPhaseStep = 2 * M_PI / intPSKPhase ;
for ( i = 1 ; i < Count ; i + + ) // Don't plot the first phase (reference)
{
MagMax = MAX ( MagMax , Mags [ i ] ) ; // find the max magnitude to auto scale
dblAvgRad + = Mags [ i ] ;
}
dblAvgRad = dblAvgRad / Count ; // the average radius
2023-10-07 12:21:48 +01:00
for ( i = 0 ; i < Count ; i + + )
2023-09-12 21:38:15 +01:00
{
dblRad = PLOTRADIUS * Mags [ i ] / MagMax ; // scale the radius dblRad based on intMag
intP = round ( ( Phases [ i ] ) / dbPhaseStep ) ;
// compute the Phase error
dblPhaseError = fabsf ( Phases [ i ] - intP * dbPhaseStep ) ; // always positive and < .5 * dblPhaseStep
dblPhaseErrorSum + = dblPhaseError ;
2023-10-07 12:21:48 +01:00
if ( nonGUIMode = = 0 )
{
intX = xCenter + dblRad * cosf ( dblPlotRotation + Phases [ i ] ) ;
intY = yCenter + dblRad * sinf ( dblPlotRotation + Phases [ i ] ) ;
2023-09-12 21:38:15 +01:00
2023-10-07 12:21:48 +01:00
if ( intX > 0 & & intY > 0 )
if ( intX ! = xCenter & & intY ! = yCenter )
Constellation [ chan ] - > setPixel ( intX , intY , yellow ) ;
}
2023-09-12 21:38:15 +01:00
}
dblAvgRad = dblAvgRad / Count ; // the average radius
intQuality = MAX ( 0 , ( ( 100 - 200 * ( dblPhaseErrorSum / ( Count ) ) / dbPhaseStep ) ) ) ; // ignore radius error for (PSK) but include for QAM
2023-10-07 12:21:48 +01:00
if ( nonGUIMode = = 0 )
{
2024-07-23 21:26:30 +01:00
emit t - > setConstellationImage ( chan , intQuality ) ;
// char QualText[64];
// sprintf(QualText, "Chan %c Qual = %d", chan + 'A', intQuality);
// QualLabel[chan]->setText(QualText);
// constellationLabel[chan]->setPixmap(QPixmap::fromImage(*Constellation[chan]));
2023-10-07 12:21:48 +01:00
}
2023-09-12 21:38:15 +01:00
return intQuality ;
}
2024-07-23 21:26:30 +01:00
QFile tracefile ( " Tracelog.txt " ) ;
extern " C " int openTraceLog ( )
{
if ( ! tracefile . open ( QIODevice : : Append | QIODevice : : Text ) )
return 0 ;
return 1 ;
}
2024-10-29 22:45:21 +00:00
extern " C " qint64 writeTraceLog ( char * Data )
2024-07-23 21:26:30 +01:00
{
return tracefile . write ( Data ) ;
}
extern " C " void closeTraceLog ( )
{
tracefile . close ( ) ;
}
extern " C " void debugTimeStamp ( char * Text , char Dirn )
{
# ifndef LOGTX
if ( Dirn = = ' T ' )
return ;
# endif
# ifndef LOGRX
if ( Dirn = = ' R ' )
return ;
# endif
QTime Time ( QTime : : currentTime ( ) ) ;
QString String = Time . toString ( " hh:mm:ss.zzz " ) ;
char Msg [ 2048 ] ;
sprintf ( Msg , " %s %s \n " , String . toUtf8 ( ) . data ( ) , Text ) ;
2024-10-29 22:45:21 +00:00
writeTraceLog ( Msg ) ;
2024-07-23 21:26:30 +01:00
}
// Timer functions need to run in GUI Thread
extern " C " int SampleNo ;
extern " C " int pttOnTime ( )
{
return pttOnTimer . elapsed ( ) ;
}
extern " C " void startpttOnTimer ( )
{
pttOnTimer . start ( ) ;
}
extern " C " void StartWatchdog ( )
{
// Get Monotonic clock for PTT drop time calculation
# ifndef WIN32
clock_gettime ( CLOCK_MONOTONIC , & pttclk ) ;
# endif
debugTimeStamp ( ( char * ) " PTT On " , ' T ' ) ;
emit t - > startWatchdog ( ) ;
pttOnTimer . start ( ) ;
}
extern " C " void StopWatchdog ( )
{
int txlenMs = ( 1000 * SampleNo / TX_Samplerate ) ;
Debugprintf ( " Samples Sent %d, Calc Time %d, PTT Time %d " , SampleNo , txlenMs , pttOnTime ( ) ) ;
debugTimeStamp ( ( char * ) " PTT Off " , ' T ' ) ;
closeTraceLog ( ) ;
openTraceLog ( ) ;
debugTimeStamp ( ( char * ) " Log Reopened " , ' T ' ) ;
emit t - > stopWatchdog ( ) ;
}
void QtSoundModem : : StartWatchdog ( )
{
PTTWatchdog - > start ( 60 * 1000 ) ;
}
void QtSoundModem : : StopWatchdog ( )
{
PTTWatchdog - > stop ( ) ;
}
void QtSoundModem : : PTTWatchdogExpired ( )
{
PTTWatchdog - > stop ( ) ;
}
2023-09-12 21:38:15 +01:00
2024-10-29 22:45:21 +00:00
// KISS Serial Port code - mainly for 6Pack but should work with KISS as well
// Serial Read needs to block and signal the main thread whenever a character is received. TX can probably be uncontrolled
void serialThread : : startSlave ( const QString & portName , int waitTimeout , const QString & response )
{
QMutexLocker locker ( & mutex ) ;
this - > portName = portName ;
this - > waitTimeout = waitTimeout ;
this - > response = response ;
if ( ! isRunning ( ) )
start ( ) ;
}
void serialThread : : run ( )
{
QSerialPort serial ;
bool currentPortNameChanged = false ;
mutex . lock ( ) ;
QString currentPortName ;
if ( currentPortName ! = portName ) {
currentPortName = portName ;
currentPortNameChanged = true ;
}
int currentWaitTimeout = waitTimeout ;
QString currentRespone = response ;
mutex . unlock ( ) ;
if ( currentPortName . isEmpty ( ) )
{
Debugprintf ( " Port not set " ) ;
return ;
}
serial . setPortName ( currentPortName ) ;
if ( ! serial . open ( QIODevice : : ReadWrite ) )
{
Debugprintf ( " Can't open %s, error code %d " , portName , serial . error ( ) ) ;
return ;
}
while ( 1 )
{
if ( serial . waitForReadyRead ( currentWaitTimeout ) )
{
// read request
QByteArray requestData = serial . readAll ( ) ;
while ( serial . waitForReadyRead ( 10 ) )
requestData + = serial . readAll ( ) ;
// Pass data to 6pack handler
emit this - > request ( requestData ) ;
}
else {
Debugprintf ( " Serial read request timeout " ) ;
}
}
}
void Process6PackData ( unsigned char * Bytes , int Len ) ;
void QtSoundModem : : showRequest ( QByteArray Data )
{
Process6PackData ( ( unsigned char * ) Data . data ( ) , Data . length ( ) ) ;
}