diff --git a/Config.cpp b/Config.cpp index ad03176..f660aaa 100644 --- a/Config.cpp +++ b/Config.cpp @@ -54,6 +54,7 @@ extern int CWIDLeft; extern int CWIDRight; extern int CWIDType; extern bool afterTraffic; +extern bool darkTheme; extern "C" int RSID_SABM[4]; extern "C" int RSID_UI[4]; @@ -115,6 +116,7 @@ void GetPortSettings(int Chan) fx25_mode[Chan] = getAX25Param("FX25", FX25_MODE_RX).toInt(); il2p_mode[Chan] = getAX25Param("IL2P", IL2P_MODE_NONE).toInt(); + il2p_crc[Chan] = getAX25Param("IL2PCRC", 0).toInt(); RSID_UI[Chan] = getAX25Param("RSID_UI", 0).toInt(); RSID_SABM[Chan] = getAX25Param("RSID_SABM", 0).toInt(); RSID_SetModem[Chan] = getAX25Param("RSID_SetModem", 0).toInt(); @@ -303,6 +305,8 @@ void getSettings() } + darkTheme = settings->value("Init/darkTheme", false).toBool(); + delete(settings); } @@ -347,6 +351,7 @@ void SavePortSettings(int Chan) saveAX25Param("MyDigiCall", MyDigiCall[Chan]); saveAX25Param("FX25", fx25_mode[Chan]); saveAX25Param("IL2P", il2p_mode[Chan]); + saveAX25Param("IL2PCRC", il2p_crc[Chan]); saveAX25Param("RSID_UI", RSID_UI[Chan]); saveAX25Param("RSID_SABM", RSID_SABM[Chan]); saveAX25Param("RSID_SetModem", RSID_SetModem[Chan]); @@ -463,6 +468,8 @@ void saveSettings() settings->setValue("Modem/CWIDType", CWIDType); settings->setValue("Modem/afterTraffic", afterTraffic); + settings->setValue("Init/darkTheme", darkTheme); + saveAX25Params(0); saveAX25Params(1); saveAX25Params(2); diff --git a/ModemDialog.ui b/ModemDialog.ui index e8f7903..9b5b856 100644 --- a/ModemDialog.ui +++ b/ModemDialog.ui @@ -737,6 +737,19 @@ Retries + + + + 200 + 280 + 53 + 21 + + + + CRC + + @@ -1445,6 +1458,19 @@ + + + + 200 + 280 + 53 + 21 + + + + CRC + + @@ -2202,6 +2228,19 @@ + + + + 200 + 280 + 53 + 21 + + + + CRC + + @@ -2956,6 +2995,19 @@ + + + + 200 + 280 + 53 + 21 + + + + CRC + + @@ -3041,6 +3093,9 @@ Save + + true + diff --git a/QtSoundModem-DESKTOP-MHE5LO8.vcxproj b/QtSoundModem-DESKTOP-MHE5LO8.vcxproj deleted file mode 100644 index adcd4b6..0000000 --- a/QtSoundModem-DESKTOP-MHE5LO8.vcxproj +++ /dev/null @@ -1,292 +0,0 @@ - - - - - Release - Win32 - - - Debug - Win32 - - - - {4EDE958E-D0AC-37B4-81F7-78313A262DCD} - QtSoundModem - QtVS_v304 - 10.0.17763.0 - 10.0.19041.0 - $(MSBuildProjectDirectory)\QtMsBuild - - - - v141 - release\ - false - NotSet - Application - release\ - QtSoundModem - - - v141 - debug\ - false - NotSet - Application - debug\ - QtSoundModem - - - - - - - - - - - - - - - - - - $(SolutionDir)$(Platform)\$(Configuration)\ - $(SolutionDir)Intermed\$(Platform)\$(Configuration)\ - QtSoundModem - true - true - - - $(SolutionDir)$(Platform)\$(Configuration)\ - $(SolutionDir)Intermed\$(Platform)\$(Configuration)\\ - QtSoundModem - true - false - - - 5.14 - core;network;gui;widgets;serialport - - - 5.14.2 - core;network;gui;widgets;serialport - - - - - - - rsid;.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;release;/include;%(AdditionalIncludeDirectories) - -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions) - $(IntDir) - false - None - 4577;4467;%(DisableSpecificWarnings) - Sync - $(IntDir) - MaxSpeed - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions) - false - $(OutDir) - MultiThreadedDLL - true - true - Level3 - true - - - libfftw3f-3.lib;shell32.lib;setupapi.lib;WS2_32.Lib;%(AdditionalDependencies) - C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories) - "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) - true - false - true - false - true - $(OutDir)QtSoundModem.exe - true - Windows - true - - - Unsigned - None - 0 - - - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;%(PreprocessorDefinitions) - - - msvc - ./$(Configuration)/moc_predefs.h - Moc'ing %(Identity)... - output - $(IntDir) - moc_%(Filename).cpp - - - QtSoundModem - default - Rcc'ing %(Identity)... - $(IntDir) - qrc_%(Filename).cpp - - - Uic'ing %(Identity)... - $(IntDir) - ui_%(Filename).h - - - - - .\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;debug;/include;rsid;%(AdditionalIncludeDirectories) - -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions) - $(IntDir) - false - EditAndContinue - 4577;4467;%(DisableSpecificWarnings) - Sync - $(IntDir) - Disabled - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;%(PreprocessorDefinitions) - false - MultiThreadedDebugDLL - true - true - Level3 - true - $(OutDir) - - - libfftw3f-3.lib;shell32.lib;setupapi.lib;WS2_32.Lib;%(AdditionalDependencies) - C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories) - "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) - true - true - true - $(OutDir)\QtSoundModem.exe - true - Windows - true - false - - - Unsigned - None - 0 - - - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions) - - - msvc - ./$(Configuration)/moc_predefs.h - Moc'ing %(Identity)... - output - $(IntDir) - moc_%(Filename).cpp - - - QtSoundModem - default - Rcc'ing %(Identity)... - $(IntDir) - qrc_%(Filename).cpp - - - Uic'ing %(Identity)... - $(IntDir) - ui_%(Filename).h - - - - - - - - - - CompileAsC - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Document - true - $(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs) - cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2>NUL >debug\moc_predefs.h - Generate moc_predefs.h - debug\moc_predefs.h;%(Outputs) - - - Document - $(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs) - cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2>NUL >release\moc_predefs.h - Generate moc_predefs.h - release\moc_predefs.h;%(Outputs) - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/QtSoundModem-HPLaptop.vcxproj b/QtSoundModem-HPLaptop.vcxproj deleted file mode 100644 index 3b99dd0..0000000 --- a/QtSoundModem-HPLaptop.vcxproj +++ /dev/null @@ -1,288 +0,0 @@ - - - - - Release - Win32 - - - Debug - Win32 - - - - {4EDE958E-D0AC-37B4-81F7-78313A262DCD} - QtSoundModem - QtVS_v304 - 10.0.19041.0 - 10.0.19041.0 - $(MSBuildProjectDirectory)\QtMsBuild - - - - v141 - release\ - false - NotSet - Application - release\ - QtSoundModem - - - v141 - debug\ - false - NotSet - Application - debug\ - QtSoundModem - - - - - - - - - - - - - - - - - - C:\Dev\Msdev2005\projects\QT\QtSoundModem\Win32\Debug\ - C:\Dev\Msdev2005\projects\QT\QtSoundModem\Intermed\Win32\Debug\ - QtSoundModem - true - true - - - C:\Dev\Msdev2005\projects\QT\QtSoundModem\Win32\Release\ - C:\Dev\Msdev2005\projects\QT\QtSoundModem\Intermed\Win32\Release\ - QtSoundModem - true - false - - - 5.14.2_msvc2017 - core;network;gui;widgets;serialport - - - 5.14.2_msvc2017 - core;network;gui;widgets;serialport - - - - - - - rsid;.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;release;/include;%(AdditionalIncludeDirectories) - -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions) - $(IntDir) - false - None - 4577;4467;%(DisableSpecificWarnings) - Sync - $(IntDir) - MaxSpeed - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions) - false - $(OutDir) - MultiThreadedDLL - true - true - Level3 - true - - - libfftw3f-3.lib;shell32.lib;setupapi.lib;WS2_32.Lib;%(AdditionalDependencies) - C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories) - "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) - true - false - true - false - true - $(OutDir)\QtSoundModem.exe - true - Windows - true - - - Unsigned - None - 0 - - - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;NDEBUG;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;%(PreprocessorDefinitions) - - - msvc - ./$(Configuration)/moc_predefs.h - Moc'ing %(Identity)... - output - $(IntDir) - moc_%(Filename).cpp - - - QtSoundModem - default - Rcc'ing %(Identity)... - $(IntDir) - qrc_%(Filename).cpp - - - Uic'ing %(Identity)... - $(IntDir) - ui_%(Filename).h - - - - - .\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;debug;/include;rsid;%(AdditionalIncludeDirectories) - -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions) - $(IntDir) - false - EditAndContinue - 4577;4467;%(DisableSpecificWarnings) - Sync - $(IntDir) - Disabled - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;%(PreprocessorDefinitions) - false - MultiThreadedDebugDLL - true - true - Level3 - true - $(OutDir) - - - libfftw3f-3.lib;shell32.lib;setupapi.lib;WS2_32.Lib;%(AdditionalDependencies) - C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories) - "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) - true - true - true - $(OutDir)\QtSoundModem.exe - true - Windows - true - false - - - Unsigned - None - 0 - - - _WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;QT_WIDGETS_LIB;QT_GUI_LIB;QT_NETWORK_LIB;QT_SERIALPORT_LIB;QT_CORE_LIB;_DEBUG;%(PreprocessorDefinitions) - - - msvc - ./$(Configuration)/moc_predefs.h - Moc'ing %(Identity)... - output - $(IntDir) - moc_%(Filename).cpp - - - QtSoundModem - default - Rcc'ing %(Identity)... - $(IntDir) - qrc_%(Filename).cpp - - - Uic'ing %(Identity)... - $(IntDir) - ui_%(Filename).h - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Document - true - $(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs) - cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -Zi -MDd -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2>NUL >debug\moc_predefs.h - Generate moc_predefs.h - debug\moc_predefs.h;%(Outputs) - - - Document - $(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs) - cl -Bx"$(QTDIR)\bin\qmake.exe" -nologo -Zc:wchar_t -FS -Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -O2 -MD -W3 -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 -wd4577 -wd4467 -E $(QTDIR)\mkspecs\features\data\dummy.cpp 2>NUL >release\moc_predefs.h - Generate moc_predefs.h - release\moc_predefs.h;%(Outputs) - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/QtSoundModem.cpp b/QtSoundModem.cpp index cadb3fb..976ca95 100644 --- a/QtSoundModem.cpp +++ b/QtSoundModem.cpp @@ -51,17 +51,18 @@ along with QtSoundModem. If not, see http://www.gnu.org/licenses QImage *Constellation[4]; -QImage *Waterfall[4] = { 0,0,0,0 }; -QImage *Header[4]; +QImage *Waterfall = 0; QLabel *DCDLabel[4]; QLineEdit *chanOffsetLabel[4]; QImage *DCDLed[4]; QImage *RXLevel; +QImage *RXLevel2; + +QLabel *WaterfallCopy; -QLabel *WaterfallCopy[2]; -QLabel *HeaderCopy[2]; QLabel * RXLevelCopy; +QLabel * RXLevel2Copy; QTextEdit * monWindowCopy; @@ -73,6 +74,8 @@ QList Ports = QSerialPortInfo::availablePorts(); void saveSettings(); void getSettings(); +void DrawModemFreqRange(); + extern "C" void CloseSound(); extern "C" void GetSoundDevices(); extern "C" char modes_name[modes_count][21]; @@ -120,11 +123,10 @@ extern "C" int Freq_Change(int Chan, int Freq); void set_speed(int snd_ch, int Modem); void init_speed(int snd_ch); - void wf_pointer(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(); - void wf_Scale(int Chan); + void DrawFreqTicks(); void AGW_Report_Modem_Change(int port); char * strlop(char * buf, char delim); void sendRSID(int Chan, int dropTX); @@ -157,7 +159,10 @@ int WaterfallMin = 00; int WaterfallMax = 6000; int Configuring = 0; +bool lockWaterfall = false; +bool inWaterfall = false; +extern "C" int NeedWaterfallHeaders; extern "C" float BinSize; extern "C" { int RSID_SABM[4]; } @@ -175,6 +180,12 @@ QRgb red = qRgb(255, 0, 0); QRgb yellow = qRgb(255, 255, 0); QRgb cyan = qRgb(0, 255, 255); +QRgb txText = qRgb(192, 0, 0); +QRgb rxText = qRgb(0, 0, 192); + +bool darkTheme = true; +bool minimizeonStart = true; + // Indexed colour list from ARDOPC #define WHITE 0 @@ -198,7 +209,7 @@ QRgb vbColours[16] = { qRgb(255, 255, 255), qRgb(255, 99, 71), qRgb(255, 215, 0) qRgb(218, 165, 32), qRgb(255, 0, 255) }; unsigned char WaterfallLines[2][80][4096] = { 0 }; -int NextWaterfallLine[2] = { 0 }; +int NextWaterfallLine[2] = {0, 0}; unsigned int LastLevel = 255; unsigned int LastBusy = 255; @@ -307,8 +318,20 @@ void QtSoundModem::resizeEvent(QResizeEvent* event) QRect r = geometry(); - int A, B, C, W; - int modemBoxHeight = 30; + QRect r1 = ui.monWindow->geometry(); + QRect r2 = ui.centralWidget->geometry(); + + 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; ui.modeB->setVisible(soundChannel[1]); ui.centerB->setVisible(soundChannel[1]); @@ -331,78 +354,46 @@ void QtSoundModem::resizeEvent(QResizeEvent* event) if (soundChannel[2] || soundChannel[3]) modemBoxHeight = 60; + ui.Waterfall->setVisible(0); - A = r.height() - 25; // No waterfalls + monitorTop = modemBoxHeight + 1; - if (UsingBothChannels && Secondwaterfall) + // Now have one waterfall label containing headers and waterfalls + + if (Firstwaterfall || Secondwaterfall) + ui.Waterfall->setVisible(1); + + if (AGWServ) { - // Two waterfalls - - ui.WaterfallA->setVisible(1); - ui.HeaderA->setVisible(1); - ui.WaterfallB->setVisible(1); - ui.HeaderB->setVisible(1); - - A = r.height() - 258; // Top of Waterfall A - B = A + 115; // Top of Waterfall B + sessionTable->setVisible(true); + sessionHeight = 150; } else { - // One waterfall - - // Could be Left or Right - - if (Firstwaterfall) - { - if (soundChannel[0] == RIGHT) - { - ui.WaterfallA->setVisible(0); - ui.HeaderA->setVisible(0); - ui.WaterfallB->setVisible(1); - ui.HeaderB->setVisible(1); - } - else - { - ui.WaterfallA->setVisible(1); - ui.HeaderA->setVisible(1); - ui.WaterfallB->setVisible(0); - ui.HeaderB->setVisible(0); - } - - A = r.height() - 145; // Top of Waterfall A - } - else - A = r.height() - 25; // Top of Waterfall A + sessionTable->setVisible(false); } - C = A - 150; // Bottom of Monitor, Top of connection list - W = r.width(); + // if only displaying one Waterfall, change height of waterfall area - // Calc Positions of Waterfalls - - ui.monWindow->setGeometry(QRect(0, modemBoxHeight, W, C - (modemBoxHeight + 26))); - sessionTable->setGeometry(QRect(0, C, W, 175)); - - if (UsingBothChannels) + if (UsingBothChannels == 0 || (Firstwaterfall == 0) || (Secondwaterfall == 0)) { - ui.HeaderA->setGeometry(QRect(0, A, W, 38)); - ui.WaterfallA->setGeometry(QRect(0, A + 38, W, 80)); - ui.HeaderB->setGeometry(QRect(0, B, W, 38)); - ui.WaterfallB->setGeometry(QRect(0, B + 38, W, 80)); - } - else - { - if (soundChannel[0] == RIGHT) - { - ui.HeaderB->setGeometry(QRect(0, A, W, 38)); - ui.WaterfallB->setGeometry(QRect(0, A + 38, W, 80)); - } - else - { - ui.HeaderA->setGeometry(QRect(0, A, W, 38)); - ui.WaterfallA->setGeometry(QRect(0, A + 38, W, 80)); - } + waterfallsHeight /= 2; } + + if ((Firstwaterfall == 0) && (Secondwaterfall == 0)) + waterfallsHeight = 0; + + monitorHeight = Height - sessionHeight - waterfallsHeight - modemBoxHeight; + waterfallsTop = Height - waterfallsHeight; + sessionTop = Height - (sessionHeight + waterfallsHeight); + + ui.monWindow->setGeometry(QRect(0, monitorTop, Width, monitorHeight)); + + if (AGWServ) + sessionTable->setGeometry(QRect(0, sessionTop, Width, sessionHeight)); + + if (waterfallsHeight) + ui.Waterfall->setGeometry(QRect(0, waterfallsTop, Width, waterfallsHeight + 2)); } QAction * setupMenuLine(QMenu * Menu, char * Label, QObject * parent, int State) @@ -426,50 +417,40 @@ void QtSoundModem::menuChecked() int state = Act->isChecked(); if (Act == actWaterfall1) - { - int oldstate = Firstwaterfall; Firstwaterfall = state; - if (state != oldstate) - initWaterfall(0, state); - - } else if (Act == actWaterfall2) - { - int oldstate = Secondwaterfall; Secondwaterfall = state; - if (state != oldstate) - initWaterfall(1, state); + initWaterfall(Firstwaterfall | Secondwaterfall); - } saveSettings(); } -void QtSoundModem::initWaterfall(int chan, int state) +void QtSoundModem::initWaterfall(int state) { if (state == 1) { - if (chan == 0) - { - ui.WaterfallA = new QLabel(ui.centralWidget); - WaterfallCopy[0] = ui.WaterfallA; - } - else - { - ui.WaterfallB = new QLabel(ui.centralWidget); - WaterfallCopy[1] = ui.WaterfallB; - } - Waterfall[chan] = new QImage(1024, 80, QImage::Format_RGB32); - Waterfall[chan]->fill(black); + // 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; + } else { - delete(Waterfall[chan]); - Waterfall[chan] = 0; + delete(Waterfall); + Waterfall = 0; } QSize Size(800, 602); // Not actually used, but Event constructor needs it + QResizeEvent *event = new QResizeEvent(Size, Size); QApplication::sendEvent(this, event); } @@ -518,7 +499,7 @@ void DoPSKWindows() constellationDialog->resize(NextX, 140); } - +QTimer *wftimer; QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent) { @@ -530,6 +511,8 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent) mythis = this; + getSettings(); + QSettings mysettings("QtSoundModem.ini", QSettings::IniFormat); family = mysettings.value("FontFamily", "Courier New").toString(); @@ -606,7 +589,7 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent) restoreGeometry(mysettings.value("geometry").toByteArray()); restoreState(mysettings.value("windowState").toByteArray()); - sessionTable = new QTableWidget(this); + sessionTable = new QTableWidget(ui.centralWidget); sessionTable->verticalHeader()->setVisible(FALSE); sessionTable->verticalHeader()->setDefaultSectionSize(20); @@ -615,7 +598,7 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent) 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"; - sessionTable->setStyleSheet("QHeaderView::section { background-color:rgb(224, 224, 224) }"); + mysetstyle(); sessionTable->setHorizontalHeaderLabels(m_TableHeader); sessionTable->setColumnWidth(0, 80); @@ -672,14 +655,11 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent) actAbout = ui.menuBar->addAction("&About"); connect(actAbout, SIGNAL(triggered()), this, SLOT(doAbout())); - Header[0] = new QImage(1024, 38, QImage::Format_RGB32); - Header[1] = new QImage(1024, 38, QImage::Format_RGB32); RXLevel = new QImage(150, 10, QImage::Format_RGB32); RXLevel->fill(white); ui.RXLevel->setPixmap(QPixmap::fromImage(*RXLevel)); RXLevelCopy = ui.RXLevel; - DCDLabel[0] = new QLabel(this); DCDLabel[0]->setObjectName(QString::fromUtf8("DCDLedA")); DCDLabel[0]->setGeometry(QRect(280, 31, 12, 12)); @@ -720,42 +700,16 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent) chanOffsetLabel[2] = ui.RXOffsetC; chanOffsetLabel[3] = ui.RXOffsetD; + WaterfallCopy = ui.Waterfall; - // Waterfall[0]->setColorCount(16); - // Waterfall[1]->setColorCount(16); + initWaterfall(Firstwaterfall | Secondwaterfall); - - // for (i = 0; i < 16; i++) - // { - // Waterfall[0]->setColor(i, vbColours[i]); - // Waterfall[1]->setColor(i, vbColours[i]); - // } - - WaterfallCopy[0] = ui.WaterfallA; - WaterfallCopy[1] = ui.WaterfallB; - - initWaterfall(0, 1); - initWaterfall(1, 1); - - Header[0]->fill(black); - Header[1]->fill(black); - - HeaderCopy[0] = ui.HeaderA; - HeaderCopy[1] = ui.HeaderB; monWindowCopy = ui.monWindow; ui.monWindow->document()->setMaximumBlockCount(10000); // connect(ui.monWindow, SIGNAL(selectionChanged()), this, SLOT(onTEselectionChanged())); - ui.HeaderA->setPixmap(QPixmap::fromImage(*Header[0])); - ui.HeaderB->setPixmap(QPixmap::fromImage(*Header[1])); - - wf_pointer(soundChannel[0]); - wf_pointer(soundChannel[1]); - wf_Scale(0); - wf_Scale(1); - 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))); @@ -785,7 +739,6 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent) ui.DCDSlider->setValue(dcd_threshold); - char valChar[32]; sprintf(valChar, "RX Offset %d", rxOffset); ui.RXOffsetLabel->setText(valChar); @@ -811,7 +764,7 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent) connect(timer, SIGNAL(timeout()), this, SLOT(MyTimerSlot())); timer->start(100); - QTimer *wftimer = new QTimer(this); + wftimer = new QTimer(this); connect(wftimer, SIGNAL(timeout()), this, SLOT(doRestartWF())); wftimer->start(1000 * 300); @@ -885,7 +838,7 @@ void extSetOffset(int chan) sprintf(valChar, "%d", chanOffset[chan]); chanOffsetLabel[chan]->setText(valChar); - wf_pointer(soundChannel[chan]); + NeedWaterfallHeaders = true; pnt_change[0] = 1; pnt_change[1] = 1; @@ -928,6 +881,18 @@ void QtSoundModem::MyTimerSlot() DoPSKWindows(); } + if (NeedWaterfallHeaders) + { + NeedWaterfallHeaders = 0; + + if (Waterfall) + { + Waterfall->fill(black); + DrawModemFreqRange(); + DrawFreqTicks(); + } + } + show_grid(); } @@ -1101,8 +1066,7 @@ void QtSoundModem::clickedSlotI(int i) sprintf(valChar, "RX Offset %d",rxOffset); ui.RXOffsetLabel->setText(valChar); - wf_pointer(soundChannel[0]); - wf_pointer(soundChannel[1]); + NeedWaterfallHeaders = true; pnt_change[0] = 1; pnt_change[1] = 1; @@ -1276,10 +1240,13 @@ void QtSoundModem::clickedSlot() { bool ok; Font = QFontDialog::getFont(&ok, QFont(Font, this)); + if (ok) { // the user clicked OK and font is set to the font the user selected QApplication::setFont(Font); + sessionTable->horizontalHeader()->setFont(Font); + saveSettings(); } else @@ -1287,7 +1254,7 @@ void QtSoundModem::clickedSlot() // the user canceled the dialog; font is set to the initial // value, in this case Helvetica [Cronyx], 10 - QApplication::setFont(Font); +// QApplication::setFont(Font); } return; @@ -1480,6 +1447,11 @@ void QtSoundModem::doModems() Dlg->IL2PModeC->setCurrentIndex(il2p_mode[2]); Dlg->IL2PModeD->setCurrentIndex(il2p_mode[3]); + Dlg->CRC_A->setChecked(il2p_crc[0]); + Dlg->CRC_B->setChecked(il2p_crc[1]); + Dlg->CRC_C->setChecked(il2p_crc[2]); + Dlg->CRC_D->setChecked(il2p_crc[3]); + Dlg->CWIDCall->setText(CWIDCall); Dlg->CWIDInterval->setText(QString::number(CWIDInterval)); Dlg->CWIDMark->setText(CWIDMark); @@ -1569,6 +1541,12 @@ extern "C" void get_exclude_list(char * line, TStringList * list); void QtSoundModem::modemaccept() { modemSave(); + + AGW_Report_Modem_Change(0); + AGW_Report_Modem_Change(1); + AGW_Report_Modem_Change(2); + AGW_Report_Modem_Change(3); + delete(Dlg); saveSettings(); @@ -1698,6 +1676,11 @@ void QtSoundModem::modemSave() il2p_mode[2] = Dlg->IL2PModeC->currentIndex(); il2p_mode[3] = Dlg->IL2PModeD->currentIndex(); + il2p_crc[0] = Dlg->CRC_A->isChecked(); + il2p_crc[1] = Dlg->CRC_B->isChecked(); + il2p_crc[2] = Dlg->CRC_C->isChecked(); + il2p_crc[3] = Dlg->CRC_D->isChecked(); + recovery[0] = Dlg->recoverBitA->currentIndex(); recovery[1] = Dlg->recoverBitB->currentIndex(); recovery[2] = Dlg->recoverBitC->currentIndex(); @@ -1749,7 +1732,6 @@ void QtSoundModem::modemSave() for (i = 0; i < 4; i++) { initTStringList(&list_digi_callsigns[i]); - get_exclude_list(MyDigiCall[i], &list_digi_callsigns[i]); } @@ -1766,6 +1748,7 @@ void QtSoundModem::modemSave() Q = Dlg->LPFWidthD->text(); lpf[3] = Q.toInt(); */ + } void QtSoundModem::modemreject() @@ -2139,6 +2122,7 @@ void QtSoundModem::doDevices() Dev->DualPTT->setChecked(DualPTT); Dev->multiCore->setChecked(multiCore); + Dev->darkTheme->setChecked(darkTheme); Dev->WaterfallMin->setCurrentIndex(Dev->WaterfallMin->findText(QString::number(WaterfallMin), Qt::MatchFixedString)); Dev->WaterfallMax->setCurrentIndex(Dev->WaterfallMax->findText(QString::number(WaterfallMax), Qt::MatchFixedString)); @@ -2150,6 +2134,33 @@ void QtSoundModem::doDevices() } +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); + } +} + void QtSoundModem::deviceaccept() { QVariant Q = Dev->inputDevice->currentText(); @@ -2251,7 +2262,6 @@ void QtSoundModem::deviceaccept() if (UsingLeft && UsingRight) UsingBothChannels = 1; - SCO = Dev->singleChannelOutput->isChecked(); raduga = Dev->colourWaterfall->isChecked(); AGWServ = Dev->AGWEnabled->isChecked(); @@ -2275,6 +2285,8 @@ void QtSoundModem::deviceaccept() DualPTT = Dev->DualPTT->isChecked(); TX_rotate = Dev->txRotation->isChecked(); multiCore = Dev->multiCore->isChecked(); + darkTheme = Dev->darkTheme->isChecked(); + mysetstyle(); if (Dev->CAT->isChecked()) PTTMode = PTTCAT; @@ -2360,8 +2372,7 @@ void QtSoundModem::deviceaccept() ClosePTTPort(); OpenPTTPort(); - wf_pointer(soundChannel[0]); - wf_pointer(soundChannel[1]); + NeedWaterfallHeaders = true; delete(Dev); saveSettings(); @@ -2406,33 +2417,55 @@ void QtSoundModem::handleButton(int Port, int Type) doCalib(Port, Type); } + + void QtSoundModem::doRestartWF() { - if (Firstwaterfall) + if (inWaterfall) { - initWaterfall(0, 0); - initWaterfall(0, 1); - } + // in waterfall update thread - if (Secondwaterfall) + wftimer->start(5000); + return; + } + + lockWaterfall = true; + + if (Firstwaterfall | Secondwaterfall) { - initWaterfall(1, 0); - initWaterfall(1, 1); + initWaterfall(0); + initWaterfall(1); } delete(RXLevel); delete(ui.RXLevel); ui.RXLevel = new QLabel(ui.centralWidget); RXLevelCopy = ui.RXLevel; - ui.RXLevel->setGeometry(QRect(780, 17, 150, 12)); -// ui.RXLevel->setFrameShape(QFrame::Box); -// ui.RXLevel->setFrameShadow(QFrame::Sunken); + 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); RXLevel = new QImage(150, 10, QImage::Format_RGB32); RXLevel->fill(cyan); -// ui.RXLevel->setPixmap(QPixmap::fromImage(*RXLevel)); + + RXLevel2 = new QImage(150, 10, QImage::Format_RGB32); + RXLevel2->fill(white); ui.RXLevel->setVisible(1); + if (UsingBothChannels) + ui.RXLevel2->setVisible(1); + + lockWaterfall = false; } @@ -2489,7 +2522,7 @@ void QtSoundModem::RefreshSpectrum(unsigned char * Data) // Last 4 bytes are level busy and Tuning lines - Waterfall[0]->fill(Black); + Waterfall->fill(Black); if (Data[206] != LastLevel) { @@ -2510,13 +2543,13 @@ void QtSoundModem::RefreshSpectrum(unsigned char * Data) if (val > 63) val = 63; - Waterfall[0]->setPixel(i, val, Yellow); + Waterfall->setPixel(i, val, Yellow); if (val < 62) - Waterfall[0]->setPixel(i, val + 1, Gold); + Waterfall->setPixel(i, val + 1, Gold); Data++; } - ui.WaterfallA->setPixmap(QPixmap::fromImage(*Waterfall[0])); + ui.Waterfall->setPixmap(QPixmap::fromImage(*Waterfall)); } @@ -2552,7 +2585,7 @@ void QtSoundModem::RefreshWaterfall(int snd_ch, unsigned char * Data) { int j; unsigned char * Line; - int len = Waterfall[0]->bytesPerLine(); + int len = Waterfall->bytesPerLine(); int TopLine = NextWaterfallLine[snd_ch]; // Write line to cyclic buffer then draw starting with the line just written @@ -2565,16 +2598,15 @@ void QtSoundModem::RefreshWaterfall(int snd_ch, unsigned char * Data) for (j = 63; j > 0; j--) { - Line = Waterfall[0]->scanLine(j); + Line = Waterfall->scanLine(j); memcpy(Line, &WaterfallLines[snd_ch][TopLine++][0], len); if (TopLine > 63) TopLine = 0; } - ui.WaterfallA->setPixmap(QPixmap::fromImage(*Waterfall[0])); + ui.Waterfall->setPixmap(QPixmap::fromImage(*Waterfall)); } - void QtSoundModem::sendtoTrace(char * Msg, int tx) { const QTextCursor old_cursor = monWindowCopy->textCursor(); @@ -2587,9 +2619,9 @@ void QtSoundModem::sendtoTrace(char * Msg, int tx) // Insert the text at the position of the cursor (which is the end of the document). if (tx) - monWindowCopy->setTextColor(qRgb(192, 0, 0)); + monWindowCopy->setTextColor(txText); else - monWindowCopy->setTextColor(qRgb(0, 0, 192)); + monWindowCopy->setTextColor(rxText); monWindowCopy->textCursor().insertText(Msg); @@ -2651,180 +2683,157 @@ extern "C" int nonGUIMode; // This draws the Frequency Scale on Waterfall -extern "C" void wf_Scale(int Chan) +extern "C" void DrawFreqTicks() { if (nonGUIMode) return; + // Draw Frequency Markers on waterfall header(s); + int x, i; char Textxx[20]; - QImage * bm = Header[Chan]; + QImage * bm = Waterfall; QPainter qPainter(bm); qPainter.setBrush(Qt::black); qPainter.setPen(Qt::white); - if (Chan == 0) - sprintf(Textxx, "Left"); - else - sprintf(Textxx, "Right"); + int Chan; #ifdef WIN32 - int Top = 3; + int Top = 3; #else - int Top = 4; + int Top = 4; #endif + int Base = 0; - qPainter.drawText(2, Top, 100, 20, 0, Textxx); - - // We drew markers every 100 Hz or 100 / binsize pixels - - - int Markers = ((WaterfallMax - WaterfallMin) / 100) + 5; // Number of Markers to draw - int Freq = WaterfallMin; - float PixelsPerMarker = 100.0 / BinSize; - - - - for (i = 0; i < Markers; i++) - { - x = round(PixelsPerMarker * i); - if (x < 1025) + for (Chan = 0; Chan < 2; Chan++) { - if ((Freq % 500) == 0) - qPainter.drawLine(x, 22, x, 15); + if (Chan == 1 || ((UsingBothChannels == 0) && (UsingRight == 1))) + sprintf(Textxx, "Right"); else - qPainter.drawLine(x, 22, x, 18); + sprintf(Textxx, "Left"); - if ((Freq % 500) == 0) + qPainter.drawText(2, Top, 100, 20, 0, Textxx); + + // We drew markers every 100 Hz or 100 / binsize pixels + + int Markers = ((WaterfallMax - WaterfallMin) / 100) + 5; // Number of Markers to draw + int Freq = WaterfallMin; + float PixelsPerMarker = 100.0 / BinSize; + + for (i = 0; i < Markers; i++) { - sprintf(Textxx, "%d", Freq); + 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 (x < 924) - qPainter.drawText(x - 12, Top, 100, 20, 0, Textxx); + if ((Freq % 500) == 0) + { + sprintf(Textxx, "%d", Freq); + + if (x < 924) + qPainter.drawText(x - 12, Top, 100, 20, 0, Textxx); + } + } + Freq += 100; } + + if (UsingBothChannels == 0) + break; + + Top += WaterfallTotalPixels; + Base = WaterfallTotalPixels; } - Freq += 100; - } - HeaderCopy[Chan]->setPixmap(QPixmap::fromImage(*bm)); } -// This draws the frequency Markers on the Waterfall +// These draws the frequency Markers on the Waterfall - -void do_pointer(int waterfall) +void DrawModemFreqRange() { if (nonGUIMode) return; + // Draws the modem freq bars on waterfall header(s) + int x1, x2, k, pos1, pos2, pos3; - QImage * bm = Header[waterfall]; + QImage * bm = Waterfall; QPainter qPainter(bm); qPainter.setBrush(Qt::NoBrush); qPainter.setPen(Qt::white); - // bm->fill(black); + int Chan; + int LRtoDisplay = LEFT; + int top = 0; - qPainter.fillRect(0, 23, 1024, 10, Qt::black); - - // We drew markers every 100 Hz or 100 / binsize pixels - - float PixelsPerHz = 1.0 / BinSize; - k = 26; - - // draw all enabled ports on the ports on this soundcard - - // First Modem is always on the first waterfall - // If second is enabled it is on the first unless different - // channel from first - - for (int i = 0; i < 4; i++) + for (Chan = 0; Chan < 2; Chan++) { + if (Chan == 1 || ((UsingBothChannels == 0) && (UsingRight == 1))) + LRtoDisplay = RIGHT; + + // bm->fill(black); + + // qPainter.fillRect(top, 23, 1024, 10, Qt::black); + + // We drew markers every 100 Hz or 100 / binsize pixels + + float PixelsPerHz = 1.0 / BinSize; + k = 26 + top; + + // draw all enabled ports on the ports on this soundcard + + // First Modem is always on the first waterfall + // If second is enabled it is on the first unless different + // channel from first + + for (int i = 0; i < 4; i++) + { + 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 + + 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; + } if (UsingBothChannels == 0) - { - // Only One Waterfall. If first chan is + break; - if ((waterfall == 0 && soundChannel[i] == RIGHT) || (waterfall == 1 && soundChannel[i] == LEFT)) - return; - } - - if (soundChannel[i] == 0) - continue; - - - if (UsingBothChannels == 1) - if ((waterfall == 0 && soundChannel[i] == RIGHT) || (waterfall == 1 && soundChannel[i] == LEFT)) - 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 - - 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; + LRtoDisplay = RIGHT; + top = WaterfallTotalPixels; } - HeaderCopy[waterfall]->setPixmap(QPixmap::fromImage(*bm)); -} - -void wf_pointer(int snd_ch) -{ - UNUSED(snd_ch); - - do_pointer(0); - do_pointer(1); -// do_pointer(2); -// do_pointer(3); } void doWaterfallThread(void * param); -/* -#ifdef WIN32 - -#define pthread_t uintptr_t - -extern "C" uintptr_t _beginthread(void(__cdecl *start_address)(void *), unsigned stack_size, void *arglist); - -#else - -#include - -extern "C" pthread_t _beginthread(void(*start_address)(void *), unsigned stack_size, void * arglist) -{ - pthread_t thread; - - if (pthread_create(&thread, NULL, (void * (*)(void *))start_address, (void*)arglist) != 0) - perror("New Thread"); - else - pthread_detach(thread); - - return thread; -} - -#endif -*/ extern "C" void doWaterfall(int snd_ch) { if (nonGUIMode) @@ -2833,6 +2842,9 @@ extern "C" void doWaterfall(int snd_ch) if (Closing) return; + if (lockWaterfall) + return; + // if (multiCore) // Run modems in separate threads // _beginthread(doWaterfallThread, 0, xx); // else @@ -2840,6 +2852,20 @@ extern "C" void doWaterfall(int snd_ch) } +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); + + WaterfallCopy->setPixmap(QPixmap::fromImage(*Waterfall)); +} extern "C" float aFFTAmpl[1024]; extern "C" void SMUpdateBusyDetector(int LR, float * Real, float *Imag); @@ -2847,13 +2873,20 @@ extern "C" void SMUpdateBusyDetector(int LR, float * Real, float *Imag); void doWaterfallThread(void * param) { int snd_ch = (int)(size_t)param; - int WaterfallNumber = snd_ch; + + if (lockWaterfall) + return; + + if (Configuring) + return; + + inWaterfall = true; // don't allow restart waterfall if (snd_ch == 1 && UsingLeft == 0) // Only using right snd_ch = 0; // Samples are in first buffer - QImage * bm = Waterfall[snd_ch]; - + QImage * bm = Waterfall; + int i; single mag; UCHAR * p; @@ -2865,9 +2898,8 @@ void doWaterfallThread(void * param) float RealOut[8192] = { 0 }; float ImagOut[8192]; - if (Configuring) - return; + RefreshLevel(CurrentLevel); // Signal Level hFFTSize = FFTSize / 2; @@ -2909,7 +2941,7 @@ void doWaterfallThread(void * param) } } else - { + { dofft(&fft_buf[snd_ch][0], RealOut, ImagOut); // FourierTransform(1024, &fft_buf[snd_ch][0], RealOut, ImagOut, 0); @@ -2950,71 +2982,70 @@ void doWaterfallThread(void * param) SMUpdateBusyDetector(snd_ch, RealOut, ImagOut); - RefreshLevel(CurrentLevel); // Signal Level + // we always do fft so we can get centre freq and do busy detect. But only upodate waterfall if on display if (bm == 0) + { + inWaterfall = false; return; - - try - { - - p = Line; - lineLen = bm->bytesPerLine(); - - if (raduga == DISP_MONO) - { - for (i = Start; i < End; i++) - { - n = fft_disp[snd_ch][i]; - *(p++) = n; // all colours the same - *(p++) = n; - *(p++) = n; - p++; - } - } - else - { - for (i = Start; i < End; i++) - { - n = fft_disp[snd_ch][i]; - memcpy(p, &RGBWF[n], 4); - p += 4; - } - } - - // Scroll - - int TopLine = NextWaterfallLine[snd_ch]; - - // Write line to cyclic buffer then draw starting with the line just written - - memcpy(&WaterfallLines[snd_ch][NextWaterfallLine[snd_ch]++][0], Line, 4096); - if (NextWaterfallLine[snd_ch] > 79) - NextWaterfallLine[snd_ch] = 0; - - for (int j = 79; j > 0; j--) - { - p = bm->scanLine(j); - memcpy(p, &WaterfallLines[snd_ch][TopLine][0], lineLen); - TopLine++; - if (TopLine > 79) - TopLine = 0; - } - - WaterfallCopy[WaterfallNumber]->setPixmap(QPixmap::fromImage(*bm)); - // WaterfallCopy[snd_ch - 1]->setPixmap(*pm); - // WaterfallCopy[1]->setPixmap(QPixmap::fromImage(*bm)); } - catch (const std::exception& e) // caught by reference to base + if ((Firstwaterfall == 0 && snd_ch == 0) || (Secondwaterfall == 0 && snd_ch == 1)) { - qDebug() << " a standard exception was caught, with message '" - << e.what() << "'\n"; + inWaterfall = false; + return; } + p = Line; + lineLen = 4096; + + if (raduga == DISP_MONO) + { + for (i = Start; i < End; i++) + { + n = fft_disp[snd_ch][i]; + *(p++) = n; // all colours the same + *(p++) = n; + *(p++) = n; + p++; + } + } + else + { + for (i = Start; i < End; i++) + { + n = fft_disp[snd_ch][i]; + memcpy(p, &RGBWF[n], 4); + p += 4; + } + } + + // Scroll + + int TopLine = NextWaterfallLine[snd_ch]; + int TopScanLine = WaterfallHeaderPixels; + + if (snd_ch) + TopScanLine += WaterfallTotalPixels; + + // Write line to cyclic buffer then draw starting with the line just written + + memcpy(&WaterfallLines[snd_ch][NextWaterfallLine[snd_ch]++][0], Line, 4096); + if (NextWaterfallLine[snd_ch] > 79) + NextWaterfallLine[snd_ch] = 0; + + for (int j = 79; j > 0; j--) + { + p = bm->scanLine(j + TopScanLine); + memcpy(p, &WaterfallLines[snd_ch][TopLine][0], lineLen); + TopLine++; + if (TopLine > 79) + TopLine = 0; + } + + inWaterfall = false; } - void QtSoundModem::changeEvent(QEvent* e) { if (e->type() == QEvent::WindowStateChange) diff --git a/QtSoundModem.h b/QtSoundModem.h index fc21d79..626ddd9 100644 --- a/QtSoundModem.h +++ b/QtSoundModem.h @@ -29,7 +29,7 @@ public: ~QtSoundModem(); void RefreshWaterfall(int snd_ch, unsigned char * Data); - void initWaterfall(int chan, int state); + void initWaterfall(int state); void show_grid(); void checkforCWID(); @@ -39,6 +39,7 @@ private slots: void CWIDTimer(); void doDevices(); + void mysetstyle(); void updateFont(); void MinimizetoTray(); void TrayActivated(QSystemTrayIcon::ActivationReason reason); @@ -111,3 +112,9 @@ protected: bool eventFilter(QObject *obj, QEvent *event) override; }; + +#define WaterfallDisplayPixels 80 +#define WaterfallHeaderPixels 38 +#define WaterfallTotalPixels WaterfallDisplayPixels + WaterfallHeaderPixels +#define WaterfallImageHeight (WaterfallTotalPixels + WaterfallTotalPixels) + diff --git a/QtSoundModem.ui b/QtSoundModem.ui index e264b7d..1d7b110 100644 --- a/QtSoundModem.ui +++ b/QtSoundModem.ui @@ -6,8 +6,8 @@ 0 0 - 962 - 721 + 993 + 900 @@ -50,48 +50,6 @@ - - - - 0 - 586 - 959 - 80 - - - - - 0 - 0 - - - - - 600 - 80 - - - - - 5000 - 100 - - - - - 8 - - - - QFrame::Box - - - QFrame::Plain - - - Waterfall - - @@ -121,25 +79,25 @@ 1500 - + 80 488 881 - 80 + 100 600 - 80 + 100 5000 - 100 + 250 @@ -171,9 +129,9 @@ 690 - 0 + 2 73 - 16 + 13 @@ -215,78 +173,6 @@ 10 - - - - 25 - 460 - 1076 - 38 - - - - - 600 - 10 - - - - - 5000 - 100 - - - - - 8 - - - - QFrame::Box - - - QFrame::Plain - - - Waterfall - - - - - - 10 - 560 - 1076 - 38 - - - - - 600 - 10 - - - - - 5000 - 100 - - - - - 8 - - - - QFrame::Box - - - QFrame::Plain - - - Waterfall - - @@ -412,7 +298,7 @@ 600 2 87 - 16 + 13 @@ -487,9 +373,9 @@ 780 - 17 + 14 150 - 12 + 11 @@ -508,7 +394,7 @@ 780 0 91 - 16 + 13 @@ -526,13 +412,32 @@ true + + + + 780 + 23 + 150 + 11 + + + + QFrame::Box + + + QFrame::Sunken + + + + + 0 0 - 962 + 993 21 diff --git a/QtSoundModem.vcxproj-DESKTOP-MHE5LO8.user b/QtSoundModem.vcxproj-DESKTOP-MHE5LO8.user deleted file mode 100644 index a71d175..0000000 --- a/QtSoundModem.vcxproj-DESKTOP-MHE5LO8.user +++ /dev/null @@ -1,34 +0,0 @@ - - - - C:\DevProgs\BPQ32\SMTest - WindowsLocalDebugger - - - - - c:\devprogs\bpq32\SMSAT2 - WindowsLocalDebugger - < d:\samples.wav - - - .\debug - WindowsLocalDebugger - - - C:\DevProgs\BPQ32\SMSat - WindowsLocalDebugger - - - 2023-08-21T20:12:53.1523329Z - - - 2022-03-11T19:38:31.5906689Z - - - 2023-08-18T07:29:42.4175478Z - - - 2022-03-11T19:38:33.3845083Z - - \ No newline at end of file diff --git a/QtSoundModem.vcxproj-HPLaptop.user b/QtSoundModem.vcxproj-HPLaptop.user deleted file mode 100644 index 8995d93..0000000 --- a/QtSoundModem.vcxproj-HPLaptop.user +++ /dev/null @@ -1,34 +0,0 @@ - - - - C:\Devprogs\bpq32\SMSat2 - WindowsLocalDebugger - - - - - c:\devprogs\bpq32\SMSAT2 - WindowsLocalDebugger - < d:\samples.wav - - - C:\DevProgs\BPQ32\SMSat - WindowsLocalDebugger - - - C:\DevProgs\BPQ32\SMSat - WindowsLocalDebugger - - - 2022-12-30T15:55:55.0433562Z - - - 2022-03-11T19:38:31.5906689Z - - - 2022-12-30T15:55:55.2283725Z - - - 2022-03-11T19:38:33.3845083Z - - \ No newline at end of file diff --git a/QtSoundModem.vcxproj.user b/QtSoundModem.vcxproj.user index 65f157d..8b8926c 100644 --- a/QtSoundModem.vcxproj.user +++ b/QtSoundModem.vcxproj.user @@ -3,8 +3,7 @@ C:\DevProgs\BPQ32\SMTest WindowsLocalDebugger - - + -stylesheet StyleSheet.css c:\devprogs\bpq32\SMSAT2 @@ -12,23 +11,24 @@ < d:\samples.wav - .\debug + C:\DevProgs\BPQ32\SMTest WindowsLocalDebugger + -stylesheet StyleSheet.css C:\DevProgs\BPQ32\SMSat WindowsLocalDebugger - 2023-09-26T11:58:59.9128543Z + 2023-10-15T11:35:54.9027336Z - 2023-09-26T11:59:00.0378577Z + 2023-10-15T11:35:55.0741785Z - 2023-09-26T11:59:00.1388610Z + 2023-10-15T11:35:55.2661628Z - 2023-09-26T11:59:00.2228656Z + 2023-10-15T11:35:55.4659021Z \ No newline at end of file diff --git a/SMMain-DESKTOP-MHE5LO8.c b/SMMain-DESKTOP-MHE5LO8.c deleted file mode 100644 index 8fc249e..0000000 --- a/SMMain-DESKTOP-MHE5LO8.c +++ /dev/null @@ -1,1433 +0,0 @@ -/* -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 - -#include "UZ7HOStuff.h" -#include "fftw3.h" -#include -#include "ecc.h" // RS Constants -#include "hidapi.h" -#include -#include -#include - -BOOL KISSServ; -int KISSPort; - -BOOL AGWServ; -int AGWPort; - -int Number = 0; // Number waiting to be sent - -int SoundIsPlaying = 0; -int UDPSoundIsPlaying = 0; -int Capturing = 0; - -extern unsigned short buffer[2][1200]; -extern int SoundMode; -extern int needRSID[4]; - -extern short * DMABuffer; - -unsigned short * SendtoCard(unsigned short * buf, int n); -short * SoundInit(); -void DoTX(int Chan); -void UDPPollReceivedSamples(); - - -extern int SampleNo; - -extern int pnt_change[5]; // Freq Changed Flag - -// fftw library interface - - -fftwf_complex *in, *out; -fftwf_plan p; - -int FFTSize = 4096; - -char * Wisdom; - -void initfft() -{ - fftwf_import_wisdom_from_string(Wisdom); - fftwf_set_timelimit(30); - -#ifndef WIN32 - printf("It may take up to 30 seconds for the program to start for the first time\n"); -#endif - - in = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * 10000); - out = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * 10000); - p = fftwf_plan_dft_1d(FFTSize, in, out, FFTW_FORWARD, FFTW_PATIENT); - - Wisdom = fftwf_export_wisdom_to_string(); -} - -void dofft(short * inp, float * outr, float * outi) -{ - int i; - - fftwf_complex * fft = in; - - for (i = 0; i < FFTSize; i++) - { - fft[0][0] = inp[0] * 1.0f; - fft[0][1] = 0; - fft++; - inp++; - } - - fftwf_execute(p); - - fft = out; - - for (i = 0; i < FFTSize; i++) - { - outr[0] = fft[0][0]; - outi[0] = fft[0][1]; - fft++; - outi++; - outr++; - } -} - -void freefft() -{ - fftwf_destroy_plan(p); - fftwf_free(in); - fftwf_free(out); -} - -int nonGUIMode = 0; - -void soundMain() -{ - // non platform specific initialisation - - platformInit(); - - // initialise fft library - - RsCreate(); // RS code for MPSK - - detector_init(); - KISS_init(); - ax25_init(); - init_raduga(); // Set up waterfall colour table - - initfft(); - - if (nonGUIMode) - { - Firstwaterfall = 0; - Secondwaterfall = 0; - } - - OpenPTTPort(); -} - - -void SampleSink(int LR, short Sample) -{ - // This version is passed samples one at a time, as we don't have - // enough RAM in embedded systems to hold a full audio frame - - // LR - 1 == Right Chan - -#ifdef TEENSY - int work = Sample; - DMABuffer[Number++] = (work + 32768) >> 4; // 12 bit left justify -#else - if (SCO) // Single Channel Output - same to both L and R - { - DMABuffer[2 * Number] = Sample; - DMABuffer[1 + 2 * Number] = Sample; - - } - else - { - if (LR) // Right - { - DMABuffer[1 + 2 * Number] = Sample; - DMABuffer[2 * Number] = 0; - } - else - { - DMABuffer[2 * Number] = Sample; - DMABuffer[1 + 2 * Number] = 0; - } - } - if (using48000) - { - // Need to upsample to 48K. Try just duplicating sample - - uint32_t * ptr = &DMABuffer[2 * Number]; - - *(&ptr[1]) = *(ptr); - *(&ptr[2]) = *(ptr); - *(&ptr[3]) = *(ptr); - - Number += 3; - } - Number++; -#endif - if (Number >= SendSize) - { - // send this buffer to sound interface - - DMABuffer = SendtoCard(DMABuffer, SendSize); - Number = 0; - } - - -// Last120[Last120Put++] = Sample; - -// if (Last120Put == (intN + 1)) -// Last120Put = 0; - - SampleNo++; -} - - -void Flush() -{ - SoundFlush(Number); -} - -int ipow(int base, int exp) -{ - int result = 1; - while (exp) - { - if (exp & 1) - result *= base; - exp >>= 1; - base *= base; - } - - return result; -} - -int NumberOfBitsNeeded(int PowerOfTwo) -{ - int i; - - for (i = 0; i <= 16; i++) - { - if ((PowerOfTwo & ipow(2, i)) != 0) - return i; - - } - return 0; -} - - -int ReverseBits(int Index, int NumBits) -{ - int i, Rev = 0; - - for (i = 0; i < NumBits; i++) - { - Rev = (Rev * 2) | (Index & 1); - Index = Index / 2; - } - - return Rev; -} - - -void FourierTransform(int NumSamples, short * RealIn, float * RealOut, float * ImagOut, int InverseTransform) -{ - float AngleNumerator; - unsigned char NumBits; - - int i, j, K, n, BlockSize, BlockEnd; - float DeltaAngle, DeltaAr; - float Alpha, Beta; - float TR, TI, AR, AI; - - if (InverseTransform) - AngleNumerator = -2.0f * M_PI; - else - AngleNumerator = 2.0f * M_PI; - - NumBits = NumberOfBitsNeeded(NumSamples); - - for (i = 0; i < NumSamples; i++) - { - j = ReverseBits(i, NumBits); - RealOut[j] = RealIn[i]; - ImagOut[j] = 0.0f; // Not using i in ImageIn[i]; - } - - BlockEnd = 1; - BlockSize = 2; - - while (BlockSize <= NumSamples) - { - DeltaAngle = AngleNumerator / BlockSize; - Alpha = sinf(0.5f * DeltaAngle); - Alpha = 2.0f * Alpha * Alpha; - Beta = sinf(DeltaAngle); - - i = 0; - - while (i < NumSamples) - { - AR = 1.0f; - AI = 0.0f; - - j = i; - - for (n = 0; n < BlockEnd; n++) - { - K = j + BlockEnd; - TR = AR * RealOut[K] - AI * ImagOut[K]; - TI = AI * RealOut[K] + AR * ImagOut[K]; - RealOut[K] = RealOut[j] - TR; - ImagOut[K] = ImagOut[j] - TI; - RealOut[j] = RealOut[j] + TR; - ImagOut[j] = ImagOut[j] + TI; - DeltaAr = Alpha * AR + Beta * AI; - AI = AI - (Alpha * AI - Beta * AR); - AR = AR - DeltaAr; - j = j + 1; - } - i = i + BlockSize; - } - BlockEnd = BlockSize; - BlockSize = BlockSize * 2; - } - - if (InverseTransform) - { - // Normalize the resulting time samples... - - for (i = 0; i < NumSamples; i++) - { - RealOut[i] = RealOut[i] / NumSamples; - ImagOut[i] = ImagOut[i] / NumSamples; - } - } -} - - - -int LastBusyCheck = 0; - -extern UCHAR CurrentLevel; - -#ifdef PLOTSPECTRUM -float dblMagSpectrum[206]; -float dblMaxScale = 0.0f; -extern UCHAR Pixels[4096]; -extern UCHAR * pixelPointer; -#endif - -extern int blnBusyStatus; -BusyDet = 5; - -#define PLOTWATERFALL - -int WaterfallActive = 1; -int SpectrumActive; - -float BinSize; - -extern int intLastStart; -extern int intLastStop; - -void SMSortSignals2(float * dblMag, int intStartBin, int intStopBin, int intNumBins, float * dblAVGSignalPerBin, float * dblAVGBaselinePerBin); - - -BOOL SMBusyDetect3(float * dblMag, int intStart, int intStop) // this only called while searching for leader ...once leader detected, no longer called. -{ - // First sort signals and look at highes signals:baseline ratio.. - - float dblAVGSignalPerBinNarrow, dblAVGSignalPerBinWide, dblAVGBaselineNarrow, dblAVGBaselineWide; - float dblSlowAlpha = 0.2f; - float dblAvgStoNNarrow = 0, dblAvgStoNWide = 0; - int intNarrow = 8; // 8 x 11.72 Hz about 94 z - int intWide = ((intStop - intStart) * 2) / 3; //* 0.66); - int blnBusy = FALSE; - int BusyDet4th = BusyDet * BusyDet * BusyDet * BusyDet; - - // First sort signals and look at highest signals:baseline ratio.. - // First narrow band (~94Hz) - - SMSortSignals2(dblMag, intStart, intStop, intNarrow, &dblAVGSignalPerBinNarrow, &dblAVGBaselineNarrow); - - if (intLastStart == intStart && intLastStop == intStop) - dblAvgStoNNarrow = (1 - dblSlowAlpha) * dblAvgStoNNarrow + dblSlowAlpha * dblAVGSignalPerBinNarrow / dblAVGBaselineNarrow; - else - { - // This initializes the Narrow average after a bandwidth change - - dblAvgStoNNarrow = dblAVGSignalPerBinNarrow / dblAVGBaselineNarrow; - intLastStart = intStart; - intLastStop = intStop; - } - - // Wide band (66% of current bandwidth) - - SMSortSignals2(dblMag, intStart, intStop, intWide, &dblAVGSignalPerBinWide, &dblAVGBaselineWide); - - if (intLastStart == intStart && intLastStop == intStop) - dblAvgStoNWide = (1 - dblSlowAlpha) * dblAvgStoNWide + dblSlowAlpha * dblAVGSignalPerBinWide / dblAVGBaselineWide; - else - { - // This initializes the Wide average after a bandwidth change - - dblAvgStoNWide = dblAVGSignalPerBinWide / dblAVGBaselineWide; - intLastStart = intStart; - intLastStop = intStop; - } - - // Preliminary calibration...future a function of bandwidth and BusyDet. - - - blnBusy = (dblAvgStoNNarrow > (3 + 0.008 * BusyDet4th)) || (dblAvgStoNWide > (5 + 0.02 * BusyDet4th)); - -// if (BusyDet == 0) -// blnBusy = FALSE; // 0 Disables check ?? Is this the best place to do this? - -// WriteDebugLog(LOGDEBUG, "Busy %d Wide %f Narrow %f", blnBusy, dblAvgStoNWide, dblAvgStoNNarrow); - - return blnBusy; -} - -extern int compare(const void *p1, const void *p2); - -void SMSortSignals2(float * dblMag, int intStartBin, int intStopBin, int intNumBins, float * dblAVGSignalPerBin, float * dblAVGBaselinePerBin) -{ - // puts the top intNumber of bins between intStartBin and intStopBin into dblAVGSignalPerBin, the rest into dblAvgBaselinePerBin - // for decent accuracy intNumBins should be < 75% of intStopBin-intStartBin) - - // This version uses a native sort function which is much faster and reduces CPU loading significantly on wide bandwidths. - - float dblSort[8192]; - float dblSum1 = 0, dblSum2 = 0; - int numtoSort = (intStopBin - intStartBin) + 1, i; - - memcpy(dblSort, &dblMag[intStartBin], numtoSort * sizeof(float)); - - qsort((void *)dblSort, numtoSort, sizeof(float), compare); - - for (i = numtoSort - 1; i >= 0; i--) - { - if (i >= (numtoSort - intNumBins)) - dblSum1 += dblSort[i]; - else - dblSum2 += dblSort[i]; - } - - *dblAVGSignalPerBin = dblSum1 / intNumBins; - *dblAVGBaselinePerBin = dblSum2 / (intStopBin - intStartBin - intNumBins - 1); -} - - - -void SMUpdateBusyDetector(int LR, float * Real, float *Imag) -{ - // Energy based detector for each channel. - // Fed from FFT generated for waterfall display - // FFT size is 4096 - - float dblMag[4096]; - - static BOOL blnLastBusyStatus[4]; - - float dblMagAvg = 0; - int intTuneLineLow, intTuneLineHi, intDelta; - int i, chan; - - return; - - if (Now - LastBusyCheck < 100) // ?? - return; - - LastBusyCheck = Now; - - // We need to run busy test on the frequncies used by each modem. - - for (chan = 0; chan < 4; chan++) - { - int Low, High, Start, End; - - if (soundChannel[chan] != (LR + 1)) // on this side of soundcard - continue; - - Low = tx_freq[chan] - txbpf[chan] / 2; - High = tx_freq[chan] + txbpf[chan] / 2; - - // BinSize is width of each fft bin in Hz - - Start = (Low / BinSize); // First and last bins to process - End = (High / BinSize); - - - for (i = Start; i < End; i++) - { - dblMag[i] = powf(Real[i], 2) + powf(Imag[i], 2); // first pass - dblMagAvg += dblMag[i]; - } - - blnBusyStatus = SMBusyDetect3(dblMag, Start, End); - - if (blnBusyStatus && !blnLastBusyStatus[chan]) - { - Debugprintf("Ch %d Busy True", chan); - } - else if (blnLastBusyStatus[chan] && !blnBusyStatus) - { - Debugprintf("Ch %d Busy False", chan); - } - // stcStatus.Text = "FALSE" - // queTNCStatus.Enqueue(stcStatus) - // 'Debug.WriteLine("BUSY FALSE @ " & Format(DateTime.UtcNow, "HH:mm:ss")) - - blnLastBusyStatus[chan] = blnBusyStatus; - } -} - - -extern short rawSamples[2400]; // Get Frame Type need 2400 and we may add 1200 -int rawSamplesLength = 0; -extern int maxrawSamplesLength; - -void ProcessNewSamples(short * Samples, int nSamples) -{ - if (SoundIsPlaying == FALSE && UDPSoundIsPlaying == FALSE) - BufferFull(Samples, nSamples); -}; - -void doCalib(int Chan, int Act) -{ - if (Chan == 0 && calib_mode[1]) - return; - - if (Chan == 1 && calib_mode[0]) - return; - - calib_mode[Chan] = Act; - - if (Act == 0) - { - tx_status[Chan] = TX_SILENCE; // Stop TX - Flush(); - RadioPTT(Chan, 0); - Debugprintf("Stop Calib"); - } -} - -int Freq_Change(int Chan, int Freq) -{ - int low, high; - - low = round(rx_shift[1] / 2 + RCVR[Chan] * rcvr_offset[Chan] + 1); - high = round(RX_Samplerate / 2 - (rx_shift[Chan] / 2 + RCVR[Chan] * rcvr_offset[Chan])); - - if (Freq < low) - return rx_freq[Chan]; // Dont allow change - - if (Freq > high) - return rx_freq[Chan]; // Dont allow change - - rx_freq[Chan] = Freq; - tx_freq[Chan] = Freq; - - pnt_change[Chan] = TRUE; - wf_pointer(soundChannel[Chan]); - - return Freq; -} - -void MainLoop() -{ - // Called by background thread every 10 ms (maybe) - - // Actually we may have two cards - - // Original only allowed one channel per card. - // I think we should be able to run more, ie two or more - // modems on same soundcard channel - - // So All the soundcard stuff will need to be generalised - - if (UDPServ) - UDPPollReceivedSamples(); - - if (SoundMode == 3) - UDPPollReceivedSamples(); - else - PollReceivedSamples(); - - - for (int i = 0; i < 4; i++) - { - if (modem_mode[i] == MODE_ARDOP) - { - chk_dcd1(i, 512); - } - } - DoTX(0); - DoTX(1); - DoTX(2); - DoTX(3); - -} - -int ARDOPSendToCard(int Chan, int Len) -{ - // Send Next Block of samples to the soundcard - - - short * in = &ARDOPTXBuffer[Chan][ARDOPTXPtr[Chan]]; // Enough to hold whole frame of samples - short * out = DMABuffer; - - int LR = modemtoSoundLR[Chan]; - - int i; - - for (i = 0; i < Len; i++) - { - if (SCO) // Single Channel Output - same to both L and R - { - *out++ = *in; - *out++ = *in++; - } - else - { - if (LR) // Right - { - *out++ = 0; - *out++ = *in++; - } - else - { - *out++ = *in++; - *out++ = 0; - } - } - } - - DMABuffer = SendtoCard(DMABuffer, Len); - - ARDOPTXPtr[Chan] += Len; - - // See if end of buffer - - if (ARDOPTXPtr[Chan] > ARDOPTXLen[Chan]) - return 1; - - return 0; -} -void DoTX(int Chan) -{ - // This kicks off a send sequence or calibrate - -// printtick("dotx"); - - if (calib_mode[Chan]) - { - // Maybe new calib or continuation - - if (pnt_change[Chan]) - { - make_core_BPF(Chan, rx_freq[Chan], bpf[Chan]); - make_core_TXBPF(Chan, tx_freq[Chan], txbpf[Chan]); - pnt_change[Chan] = FALSE; - } - - // Note this may block in SendtoCard - - modulator(Chan, tx_bufsize); - return; - } - - // I think we have to detect NO_DATA here and drop PTT and return to SILENCE - - if (tx_status[Chan] == TX_NO_DATA) - { - Flush(); - Debugprintf("TX Complete"); - RadioPTT(0, 0); - Continuation[Chan] = 0; - - tx_status[Chan] = TX_SILENCE; - - // We should now send any ackmode acks as the channel is now free for dest to reply - - sendAckModeAcks(Chan); - } - - if (tx_status[Chan] != TX_SILENCE) - { - // Continue the send - - if (modem_mode[Chan] == MODE_ARDOP || modem_mode[Chan] == MODE_RUH) - { -// if (SeeIfCardBusy()) -// return 0; - - if (ARDOPSendToCard(Chan, SendSize) == 1) - { - // End of TX - - Number = 0; - Flush(); - - // See if more to send. If so, don't drop PTT - - if (all_frame_buf[Chan].Count) - { - SoundIsPlaying = TRUE; - Number = 0; - - Continuation[Chan] = 1; - - Debugprintf("TX Continuing"); - - string * myTemp = Strings(&all_frame_buf[Chan], 0); // get message - string * tx_data; - - if ((myTemp->Data[0] & 0x0f) == 12) // ACKMODE - { - // Save copy then copy data up 3 bytes - - Add(&KISS_acked[Chan], duplicateString(myTemp)); - - mydelete(myTemp, 0, 3); - myTemp->Length -= sizeof(void *); - } - else - { - // Just remove control - - mydelete(myTemp, 0, 1); - } - - tx_data = duplicateString(myTemp); // so can free original below - - Delete(&all_frame_buf[Chan], 0); // This will invalidate temp - - AGW_AX25_frame_analiz(Chan, FALSE, tx_data); - - put_frame(Chan, tx_data, "", TRUE, FALSE); - - if (modem_mode[Chan] == MODE_ARDOP) - PktARDOPEncode(tx_data->Data, tx_data->Length - 2, Chan); - else - RUHEncode(tx_data->Data, tx_data->Length - 2, Chan); - - freeString(tx_data); - - // Samples are now in DMABuffer = Send first block - - DMABuffer = SoundInit(); - - ARDOPSendToCard(Chan, SendSize); - tx_status[Chan] = TX_FRAME; - return; - } - - Debugprintf("TX Complete"); - RadioPTT(0, 0); - Continuation[Chan] = 0; - - tx_status[Chan] = TX_SILENCE; - - // We should now send any ackmode acks as the channel is now free for dest to reply - } - - return; - } - - modulator(Chan, tx_bufsize); - return; - } - - if (SoundIsPlaying || UDPSoundIsPlaying) - return; - - // Not doing anything so see if we have anything new to send - - // See if frequency has changed - - if (pnt_change[Chan]) - { - make_core_BPF(Chan, rx_freq[Chan], bpf[Chan]); - make_core_TXBPF(Chan, tx_freq[Chan], txbpf[Chan]); - pnt_change[Chan] = FALSE; - } - - // See if we need an RSID - - if (needRSID[Chan]) - { - needRSID[Chan] = 0; - - // Note this may block in SampleSink - - Debugprintf("Sending RSID"); - sendRSID(Chan, all_frame_buf[Chan].Count == 0); - return; - } - - if (all_frame_buf[Chan].Count == 0) - return; - - // Start a new send. modulator should handle TXD etc - - Debugprintf("TX Start"); - SampleNo = 0; - - SoundIsPlaying = TRUE; - RadioPTT(Chan, 1); - Number = 0; - - if (modem_mode[Chan] == MODE_ARDOP) - { - // I think ARDOP will have to generate a whole frame of samples - // then send them out a bit at a time to avoid stopping here for - // possibly 10's of seconds - - // Can do this here as unlike normal ardop we don't need to run on Teensy - // to 12000 sample rate we need either 24K or 48K per second, depending on - // where we do the stereo mux. - - // Slowest rate is 50 baud, so a 255 byte packet would take about a minute - // allowing for RS overhead. Not really realistic put perhaps should be possible. - // RAM isn't an issue so maybe allocate 2 MB. - - // ?? Should we allow two ARDOP modems - could make sense if we can run sound - // card channels independently - - string * myTemp = Strings(&all_frame_buf[Chan], 0); // get message - string * tx_data; - - if ((myTemp->Data[0] & 0x0f) == 12) // ACKMODE - { - // Save copy then copy data up 3 bytes - - Add(&KISS_acked[Chan], duplicateString(myTemp)); - - mydelete(myTemp, 0, 3); - myTemp->Length -= sizeof(void *); - } - else - { - // Just remove control - - mydelete(myTemp, 0, 1); - } - - tx_data = duplicateString(myTemp); // so can free original below - - Delete(&all_frame_buf[Chan], 0); // This will invalidate temp - - AGW_AX25_frame_analiz(Chan, FALSE, tx_data); - - put_frame(Chan, tx_data, "", TRUE, FALSE); - - PktARDOPEncode(tx_data->Data, tx_data->Length - 2, Chan); - - freeString(tx_data); - - // Samples are now in DMABuffer = Send first block - - ARDOPSendToCard(Chan, SendSize); - tx_status[Chan] = TX_FRAME; - - } - else if (modem_mode[Chan] == MODE_RUH) - { - // Same as for ARDOP. Generate a whole frame of samples - // then send them out a bit at a time to avoid stopping here - - // We allow two RUH modems - - string * myTemp = Strings(&all_frame_buf[Chan], 0); // get message - string * tx_data; - - if ((myTemp->Data[0] & 0x0f) == 12) // ACKMODE - { - // Save copy then copy data up 3 bytes - - Add(&KISS_acked[Chan], duplicateString(myTemp)); - - mydelete(myTemp, 0, 3); - myTemp->Length -= sizeof(void *); - } - else - { - // Just remove control - - mydelete(myTemp, 0, 1); - } - - tx_data = duplicateString(myTemp); // so can free original below - - Delete(&all_frame_buf[Chan], 0); // This will invalidate temp - - AGW_AX25_frame_analiz(Chan, FALSE, tx_data); - - put_frame(Chan, tx_data, "", TRUE, FALSE); - - RUHEncode(tx_data->Data, tx_data->Length - 2, Chan); - - freeString(tx_data); - - // Samples are now in DMABuffer = Send first block - - ARDOPSendToCard(Chan, SendSize); - tx_status[Chan] = TX_FRAME; - - } - else - modulator(Chan, tx_bufsize); - - return; -} - -void RX2TX(int snd_ch) -{ - if (snd_status[snd_ch] == SND_IDLE) - { - DoTX(snd_ch); - } -} - -// PTT Stuff - -int hPTTDevice = 0; -char PTTPort[80] = ""; // Port for Hardware PTT - may be same as control port. -int PTTBAUD = 19200; -int PTTMode = PTTRTS; // PTT Control Flags. - -char PTTOnString[128] = ""; -char PTTOffString[128] = ""; - -UCHAR PTTOnCmd[64]; -UCHAR PTTOnCmdLen = 0; - -UCHAR PTTOffCmd[64]; -UCHAR PTTOffCmdLen = 0; - -int pttGPIOPin = 17; // Default -int pttGPIOPinR = 17; -BOOL pttGPIOInvert = FALSE; -BOOL useGPIO = FALSE; -BOOL gotGPIO = FALSE; - -int HamLibPort = 4532; -char HamLibHost[32] = "192.168.1.14"; - -char CM108Addr[80] = ""; - -int VID = 0; -int PID = 0; - -// CM108 Code - -char * CM108Device = NULL; - -void DecodeCM108(char * ptr) -{ - // Called if Device Name or PTT = Param is CM108 - -#ifdef WIN32 - - // Next Param is VID and PID - 0xd8c:0x8 or Full device name - // On Windows device name is very long and difficult to find, so - // easier to use VID/PID, but allow device in case more than one needed - - char * next; - long VID = 0, PID = 0; - char product[256] = "Unknown"; - - struct hid_device_info *devs, *cur_dev; - const char *path_to_open = NULL; - hid_device *handle = NULL; - - if (strlen(ptr) > 16) - CM108Device = _strdup(ptr); - else - { - VID = strtol(ptr, &next, 0); - if (next) - PID = strtol(++next, &next, 0); - - // Look for Device - - devs = hid_enumerate((unsigned short)VID, (unsigned short)PID); - cur_dev = devs; - - while (cur_dev) - { - if (cur_dev->product_string) - wcstombs(product, cur_dev->product_string, 255); - - Debugprintf("HID Device %s VID %X PID %X", product, cur_dev->vendor_id, cur_dev->product_id); - if (cur_dev->vendor_id == VID && cur_dev->product_id == PID) - { - path_to_open = cur_dev->path; - break; - } - cur_dev = cur_dev->next; - } - - if (path_to_open) - { - handle = hid_open_path(path_to_open); - - if (handle) - { - hid_close(handle); - CM108Device = _strdup(path_to_open); - } - else - { - Debugprintf("Unable to open CM108 device %x %x", VID, PID); - } - } - else - Debugprintf("Couldn't find CM108 device %x %x", VID, PID); - - hid_free_enumeration(devs); - } -#else - - // Linux - Next Param HID Device, eg /dev/hidraw0 - - CM108Device = _strdup(ptr); -#endif -} - -char * strlop(char * buf, char delim) -{ - // Terminate buf at delim, and return rest of string - - char * ptr = strchr(buf, delim); - - if (ptr == NULL) return NULL; - - *(ptr)++ = 0; - return ptr; -} - -void OpenPTTPort() -{ - PTTMode &= ~PTTCM108; - PTTMode &= ~PTTHAMLIB; - - if (PTTPort[0] && strcmp(PTTPort, "None") != 0) - { - if (PTTMode == PTTCAT) - { - // convert config strings from Hex - - char * ptr1 = PTTOffString; - UCHAR * ptr2 = PTTOffCmd; - char c; - int val; - - while (c = *(ptr1++)) - { - val = c - 0x30; - if (val > 15) val -= 7; - val <<= 4; - c = *(ptr1++) - 0x30; - if (c > 15) c -= 7; - val |= c; - *(ptr2++) = val; - } - - PTTOffCmdLen = ptr2 - PTTOffCmd; - - ptr1 = PTTOnString; - ptr2 = PTTOnCmd; - - while (c = *(ptr1++)) - { - val = c - 0x30; - if (val > 15) val -= 7; - val <<= 4; - c = *(ptr1++) - 0x30; - if (c > 15) c -= 7; - val |= c; - *(ptr2++) = val; - } - - PTTOnCmdLen = ptr2 - PTTOnCmd; - } - - if (stricmp(PTTPort, "GPIO") == 0) - { - // Initialise GPIO for PTT if available - -#ifdef __ARM_ARCH - - if (gpioInitialise() == 0) - { - printf("GPIO interface for PTT available\n"); - gotGPIO = TRUE; - - SetupGPIOPTT(); - } - else - printf("Couldn't initialise GPIO interface for PTT\n"); - -#else - printf("GPIO interface for PTT not available on this platform\n"); -#endif - - } - else if (stricmp(PTTPort, "CM108") == 0) - { - DecodeCM108(CM108Addr); - PTTMode |= PTTCM108; - } - - else if (stricmp(PTTPort, "HAMLIB") == 0) - { - PTTMode |= PTTHAMLIB; - HAMLIBSetPTT(0); // to open port - return; - } - - else // Not GPIO - { - hPTTDevice = OpenCOMPort(PTTPort, PTTBAUD, FALSE, FALSE, FALSE, 0); - } - } -} - -void ClosePTTPort() -{ - CloseCOMPort(hPTTDevice); - hPTTDevice = 0; -} -void CM108_set_ptt(int PTTState) -{ - char io[5]; - hid_device *handle; - int n; - - io[0] = 0; - io[1] = 0; - io[2] = 1 << (3 - 1); - io[3] = PTTState << (3 - 1); - io[4] = 0; - - if (CM108Device == NULL) - return; - -#ifdef WIN32 - handle = hid_open_path(CM108Device); - - if (!handle) { - printf("unable to open device\n"); - return; - } - - n = hid_write(handle, io, 5); - if (n < 0) - { - printf("Unable to write()\n"); - printf("Error: %ls\n", hid_error(handle)); - } - - hid_close(handle); - -#else - - int fd; - - fd = open(CM108Device, O_WRONLY); - - if (fd == -1) - { - printf("Could not open %s for write, errno=%d\n", CM108Device, errno); - return; - } - - io[0] = 0; - io[1] = 0; - io[2] = 1 << (3 - 1); - io[3] = PTTState << (3 - 1); - io[4] = 0; - - n = write(fd, io, 5); - if (n != 5) - { - printf("Write to %s failed, n=%d, errno=%d\n", CM108Device, n, errno); - } - - close(fd); -#endif - return; - -} - - - -void RadioPTT(int snd_ch, BOOL PTTState) -{ - snd_status[snd_ch] = PTTState; // SND_IDLE = 0 SND_TX = 1 - -#ifdef __ARM_ARCH - if (useGPIO) - { - if (DualPTT && modemtoSoundLR[snd_ch] == 1) - gpioWrite(pttGPIOPinR, (pttGPIOInvert ? (1 - PTTState) : (PTTState))); - else - gpioWrite(pttGPIOPin, (pttGPIOInvert ? (1 - PTTState) : (PTTState))); - - return; - } - -#endif - - if ((PTTMode & PTTCM108)) - { - CM108_set_ptt(PTTState); - return; - } - - if ((PTTMode & PTTHAMLIB)) - { - HAMLIBSetPTT(PTTState); - return; - } - if (hPTTDevice == 0) - return; - - if ((PTTMode & PTTCAT)) - { - if (PTTState) - WriteCOMBlock(hPTTDevice, PTTOnCmd, PTTOnCmdLen); - else - WriteCOMBlock(hPTTDevice, PTTOffCmd, PTTOffCmdLen); - - return; - } - - if (DualPTT && modemtoSoundLR[snd_ch] == 1) // use DTR - { - if (PTTState) - COMSetDTR(hPTTDevice); - else - COMClearDTR(hPTTDevice); - } - else - { - if ((PTTMode & PTTRTS)) - { - if (PTTState) - COMSetRTS(hPTTDevice); - else - COMClearRTS(hPTTDevice); - } - } - -} - -char ShortDT[] = "HH:MM:SS"; - -char * ShortDateTime() -{ - struct tm * tm; - time_t NOW = time(NULL); - - tm = gmtime(&NOW); - - sprintf(ShortDT, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); - return ShortDT; -} - - -// Reed Solomon Stuff - - -int NPAR = -1; // Number of Parity Bytes - used in RS Code - -int xMaxErrors = 0; - -int RSEncode(UCHAR * bytToRS, UCHAR * RSBytes, int DataLen, int RSLen) -{ - // This just returns the Parity Bytes. I don't see the point - // in copying the message about - - unsigned char Padded[256]; // The padded Data - - int Length = DataLen + RSLen; // Final Length of packet - int PadLength = 255 - Length; // Padding bytes needed for shortened RS codes - - // subroutine to do the RS encode. For full length and shortend RS codes up to 8 bit symbols (mm = 8) - - if (NPAR != RSLen) // Changed RS Len, so recalc constants; - { - NPAR = RSLen; - xMaxErrors = NPAR / 2; - initialize_ecc(); - } - - // Copy the supplied data to end of data array. - - memset(Padded, 0, PadLength); - memcpy(&Padded[PadLength], bytToRS, DataLen); - - encode_data(Padded, 255 - RSLen, RSBytes); - - return RSLen; -} - -// Main RS decode function - -extern int index_of[]; -extern int recd[]; -extern int Corrected[256]; -extern int tt; // number of errors that can be corrected -extern int kk; // Info Symbols - -extern BOOL blnErrorsCorrected; - - -BOOL RSDecode(UCHAR * bytRcv, int Length, int CheckLen, BOOL * blnRSOK) -{ - - - // Using a modified version of Henry Minsky's code - - //Copyright Henry Minsky (hqm@alum.mit.edu) 1991-2009 - - // Rick's Implementation processes the byte array in reverse. and also - // has the check bytes in the opposite order. I've modified the encoder - // to allow for this, but so far haven't found a way to mske the decoder - // work, so I have to reverse the data and checksum to decode G8BPQ Nov 2015 - - // returns TRUE if was ok or correction succeeded, FALSE if correction impossible - - UCHAR intTemp[256]; // WOrk Area to pass to Decoder - int i; - UCHAR * ptr2 = intTemp; - UCHAR * ptr1 = &bytRcv[Length - CheckLen - 1]; // Last Byte of Data - - int DataLen = Length - CheckLen; - int PadLength = 255 - Length; // Padding bytes needed for shortened RS codes - - *blnRSOK = FALSE; - - if (Length > 255 || Length < (1 + CheckLen)) //Too long or too short - return FALSE; - - if (NPAR != CheckLen) // Changed RS Len, so recalc constants; - { - NPAR = CheckLen; - xMaxErrors = NPAR / 2; - - initialize_ecc(); - } - - - // We reverse the data while zero padding it to speed things up - - // We Need (Data Reversed) (Zero Padding) (Checkbytes Reversed) - - // Reverse Data - - for (i = 0; i < DataLen; i++) - { - *(ptr2++) = *(ptr1--); - } - - // Clear padding - - memset(ptr2, 0, PadLength); - - ptr2 += PadLength; - - // Error Bits - - ptr1 = &bytRcv[Length - 1]; // End of check bytes - - for (i = 0; i < CheckLen; i++) - { - *(ptr2++) = *(ptr1--); - } - - decode_data(intTemp, 255); - - // check if syndrome is all zeros - - if (check_syndrome() == 0) - { - // RS ok, so no need to correct - - *blnRSOK = TRUE; - return TRUE; // No Need to Correct - } - - if (correct_errors_erasures(intTemp, 255, 0, 0) == 0) // Dont support erasures at the momnet - - // Uncorrectable - - return FALSE; - - // Data has been corrected, so need to reverse again - - ptr1 = &intTemp[DataLen - 1]; - ptr2 = bytRcv; // Last Byte of Data - - for (i = 0; i < DataLen; i++) - { - *(ptr2++) = *(ptr1--); - } - - // ?? Do we need to return the check bytes ?? - - // Yes, so we can redo RS Check on supposedly connected frame - - ptr1 = &intTemp[254]; // End of Check Bytes - - for (i = 0; i < CheckLen; i++) - { - *(ptr2++) = *(ptr1--); - } - - return TRUE; -} - -extern TStringList detect_list[5]; -extern TStringList detect_list_c[5]; - -void ProcessPktFrame(int snd_ch, UCHAR * Data, int frameLen) -{ - string * pkt = newString(); - - stringAdd(pkt, Data, frameLen + 2); // 2 for crc (not actually there) - - analiz_frame(snd_ch, pkt, "ARDOP", 1); - -} diff --git a/SMMain-HPLaptop.c b/SMMain-HPLaptop.c deleted file mode 100644 index 8daaf17..0000000 --- a/SMMain-HPLaptop.c +++ /dev/null @@ -1,1381 +0,0 @@ -/* -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 - -#include "UZ7HOStuff.h" -#include "fftw3.h" -#include -#include "ecc.h" // RS Constants -#include "hidapi.h" -#include -#include - -BOOL KISSServ; -int KISSPort; - -BOOL AGWServ; -int AGWPort; - -int Number = 0; // Number waiting to be sent - -int SoundIsPlaying = 0; -int UDPSoundIsPlaying = 0; -int Capturing = 0; - -extern unsigned short buffer[2][1200]; -extern int SoundMode; -extern int needRSID[4]; - -extern short * DMABuffer; - -unsigned short * SendtoCard(unsigned short * buf, int n); -short * SoundInit(); -void DoTX(int Chan); -void UDPPollReceivedSamples(); - - -extern int SampleNo; - -extern int pnt_change[5]; // Freq Changed Flag - -// fftw library interface - - -fftwf_complex *in, *out; -fftwf_plan p; - -#define N 2048 - -void initfft() -{ - in = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * N); - out = (fftwf_complex*)fftwf_malloc(sizeof(fftwf_complex) * N); - p = fftwf_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_ESTIMATE); -} - -void dofft(short * inp, float * outr, float * outi) -{ - int i; - - fftwf_complex * fft = in; - - for (i = 0; i < N; i++) - { - fft[0][0] = inp[0] * 1.0f; - fft[0][1] = 0; - fft++; - inp++; - } - - fftwf_execute(p); - - fft = out; - - for (i = 0; i < N; i++) - { - outr[0] = fft[0][0]; - outi[0] = fft[0][1]; - fft++; - outi++; - outr++; - } -} - -void freefft() -{ - fftwf_destroy_plan(p); - fftwf_free(in); - fftwf_free(out); -} - -int nonGUIMode = 0; - -void soundMain() -{ - // non platform specific initialisation - - platformInit(); - - // initialise fft library - - RsCreate(); // RS code for MPSK - - detector_init(); - KISS_init(); - ax25_init(); - init_raduga(); // Set up waterfall colour table - - initfft(); - - if (nonGUIMode) - { - Firstwaterfall = 0; - Secondwaterfall = 0; - } - - OpenPTTPort(); -} - - -void SampleSink(int LR, short Sample) -{ - // This version is passed samples one at a time, as we don't have - // enough RAM in embedded systems to hold a full audio frame - - // LR - 1 == Right Chan - -#ifdef TEENSY - int work = Sample; - DMABuffer[Number++] = (work + 32768) >> 4; // 12 bit left justify -#else - if (SCO) // Single Channel Output - same to both L and R - { - DMABuffer[2 * Number] = Sample; - DMABuffer[1 + 2 * Number] = Sample; - - } - else - { - if (LR) // Right - { - DMABuffer[1 + 2 * Number] = Sample; - DMABuffer[2 * Number] = 0; - } - else - { - DMABuffer[2 * Number] = Sample; - DMABuffer[1 + 2 * Number] = 0; - } - } - Number++; -#endif - if (Number >= SendSize) - { - // send this buffer to sound interface - - DMABuffer = SendtoCard(DMABuffer, SendSize); - Number = 0; - } - - -// Last120[Last120Put++] = Sample; - -// if (Last120Put == (intN + 1)) -// Last120Put = 0; - - SampleNo++; -} - - -void Flush() -{ - SoundFlush(Number); -} - -int ipow(int base, int exp) -{ - int result = 1; - while (exp) - { - if (exp & 1) - result *= base; - exp >>= 1; - base *= base; - } - - return result; -} - -int NumberOfBitsNeeded(int PowerOfTwo) -{ - int i; - - for (i = 0; i <= 16; i++) - { - if ((PowerOfTwo & ipow(2, i)) != 0) - return i; - - } - return 0; -} - - -int ReverseBits(int Index, int NumBits) -{ - int i, Rev = 0; - - for (i = 0; i < NumBits; i++) - { - Rev = (Rev * 2) | (Index & 1); - Index = Index / 2; - } - - return Rev; -} - - -void FourierTransform(int NumSamples, short * RealIn, float * RealOut, float * ImagOut, int InverseTransform) -{ - float AngleNumerator; - unsigned char NumBits; - - int i, j, K, n, BlockSize, BlockEnd; - float DeltaAngle, DeltaAr; - float Alpha, Beta; - float TR, TI, AR, AI; - - if (InverseTransform) - AngleNumerator = -2.0f * M_PI; - else - AngleNumerator = 2.0f * M_PI; - - NumBits = NumberOfBitsNeeded(NumSamples); - - for (i = 0; i < NumSamples; i++) - { - j = ReverseBits(i, NumBits); - RealOut[j] = RealIn[i]; - ImagOut[j] = 0.0f; // Not using i in ImageIn[i]; - } - - BlockEnd = 1; - BlockSize = 2; - - while (BlockSize <= NumSamples) - { - DeltaAngle = AngleNumerator / BlockSize; - Alpha = sinf(0.5f * DeltaAngle); - Alpha = 2.0f * Alpha * Alpha; - Beta = sinf(DeltaAngle); - - i = 0; - - while (i < NumSamples) - { - AR = 1.0f; - AI = 0.0f; - - j = i; - - for (n = 0; n < BlockEnd; n++) - { - K = j + BlockEnd; - TR = AR * RealOut[K] - AI * ImagOut[K]; - TI = AI * RealOut[K] + AR * ImagOut[K]; - RealOut[K] = RealOut[j] - TR; - ImagOut[K] = ImagOut[j] - TI; - RealOut[j] = RealOut[j] + TR; - ImagOut[j] = ImagOut[j] + TI; - DeltaAr = Alpha * AR + Beta * AI; - AI = AI - (Alpha * AI - Beta * AR); - AR = AR - DeltaAr; - j = j + 1; - } - i = i + BlockSize; - } - BlockEnd = BlockSize; - BlockSize = BlockSize * 2; - } - - if (InverseTransform) - { - // Normalize the resulting time samples... - - for (i = 0; i < NumSamples; i++) - { - RealOut[i] = RealOut[i] / NumSamples; - ImagOut[i] = ImagOut[i] / NumSamples; - } - } -} - - - -int LastBusyCheck = 0; - -extern UCHAR CurrentLevel; - -#ifdef PLOTSPECTRUM -float dblMagSpectrum[206]; -float dblMaxScale = 0.0f; -extern UCHAR Pixels[4096]; -extern UCHAR * pixelPointer; -#endif - -extern int blnBusyStatus; -BusyDet = 0; - -#define PLOTWATERFALL - -int WaterfallActive = 1; -int SpectrumActive; - -/* - -void UpdateBusyDetector(short * bytNewSamples) -{ - float dblReF[1024]; - float dblImF[1024]; - float dblMag[206]; -#ifdef PLOTSPECTRUM - float dblMagMax = 0.0000000001f; - float dblMagMin = 10000000000.0f; -#endif - UCHAR Waterfall[256]; // Colour index values to send to GUI - int clrTLC = Lime; // Default Bandwidth lines on waterfall - - static BOOL blnLastBusyStatus; - - float dblMagAvg = 0; - int intTuneLineLow, intTuneLineHi, intDelta; - int i; - - // if (State != SearchingForLeader) - // return; // only when looking for leader - - if (Now - LastBusyCheck < 100) - return; - - LastBusyCheck = Now; - - FourierTransform(1024, bytNewSamples, &dblReF[0], &dblImF[0], FALSE); - - for (i = 0; i < 206; i++) - { - // starting at ~300 Hz to ~2700 Hz Which puts the center of the signal in the center of the window (~1500Hz) - - dblMag[i] = powf(dblReF[i + 25], 2) + powf(dblImF[i + 25], 2); // first pass - dblMagAvg += dblMag[i]; -#ifdef PLOTSPECTRUM - dblMagSpectrum[i] = 0.2f * dblMag[i] + 0.8f * dblMagSpectrum[i]; - dblMagMax = max(dblMagMax, dblMagSpectrum[i]); - dblMagMin = min(dblMagMin, dblMagSpectrum[i]); -#endif - } - - // LookforPacket(dblMag, dblMagAvg, 206, &dblReF[25], &dblImF[25]); - // packet_process_samples(bytNewSamples, 1200); - - intDelta = roundf(500 / 2) + 50 / 11.719f; - - intTuneLineLow = max((103 - intDelta), 3); - intTuneLineHi = min((103 + intDelta), 203); - -// if (ProtocolState == DISC) // ' Only process busy when in DISC state - { - // blnBusyStatus = BusyDetect3(dblMag, intTuneLineLow, intTuneLineHi); - - if (blnBusyStatus && !blnLastBusyStatus) - { -// QueueCommandToHost("BUSY TRUE"); -// newStatus = TRUE; // report to PTC - - if (!WaterfallActive && !SpectrumActive) - { - UCHAR Msg[2]; - -// Msg[0] = blnBusyStatus; -// SendtoGUI('B', Msg, 1); - } - } - // stcStatus.Text = "TRUE" - // queTNCStatus.Enqueue(stcStatus) - // 'Debug.WriteLine("BUSY TRUE @ " & Format(DateTime.UtcNow, "HH:mm:ss")) - - else if (blnLastBusyStatus && !blnBusyStatus) - { -// QueueCommandToHost("BUSY FALSE"); -// newStatus = TRUE; // report to PTC - - if (!WaterfallActive && !SpectrumActive) - { - UCHAR Msg[2]; - - Msg[0] = blnBusyStatus; -// SendtoGUI('B', Msg, 1); - } - } - // stcStatus.Text = "FALSE" - // queTNCStatus.Enqueue(stcStatus) - // 'Debug.WriteLine("BUSY FALSE @ " & Format(DateTime.UtcNow, "HH:mm:ss")) - - blnLastBusyStatus = blnBusyStatus; - } - - if (BusyDet == 0) - clrTLC = Goldenrod; - else if (blnBusyStatus) - clrTLC = Fuchsia; - - // At the moment we only get here what seaching for leader, - // but if we want to plot spectrum we should call - // it always - - - - if (WaterfallActive) - { -#ifdef PLOTWATERFALL - dblMagAvg = log10f(dblMagAvg / 5000.0f); - - for (i = 0; i < 206; i++) - { - // The following provides some AGC over the waterfall to compensate for avg input level. - - float y1 = (0.25f + 2.5f / dblMagAvg) * log10f(0.01 + dblMag[i]); - int objColor; - - // Set the pixel color based on the intensity (log) of the spectral line - if (y1 > 6.5) - objColor = Orange; // Strongest spectral line - else if (y1 > 6) - objColor = Khaki; - else if (y1 > 5.5) - objColor = Cyan; - else if (y1 > 5) - objColor = DeepSkyBlue; - else if (y1 > 4.5) - objColor = RoyalBlue; - else if (y1 > 4) - objColor = Navy; - else - objColor = Black; - - if (i == 102) - Waterfall[i] = Tomato; // 1500 Hz line (center) - else if (i == intTuneLineLow || i == intTuneLineLow - 1 || i == intTuneLineHi || i == intTuneLineHi + 1) - Waterfall[i] = clrTLC; - else - Waterfall[i] = objColor; // ' Else plot the pixel as received - } - - // Send Signal level and Busy indicator to save extra packets - - Waterfall[206] = CurrentLevel; - Waterfall[207] = blnBusyStatus; - - doWaterfall(Waterfall); -#endif - } - else if (SpectrumActive) - { -#ifdef PLOTSPECTRUM - // This performs an auto scaling mechansim with fast attack and slow release - if (dblMagMin / dblMagMax < 0.0001) // more than 10000:1 difference Max:Min - dblMaxScale = max(dblMagMax, dblMaxScale * 0.9f); - else - dblMaxScale = max(10000 * dblMagMin, dblMagMax); - -// clearDisplay(); - - for (i = 0; i < 206; i++) - { - // The following provides some AGC over the spectrum to compensate for avg input level. - - float y1 = -0.25f * (SpectrumHeight - 1) * log10f((max(dblMagSpectrum[i], dblMaxScale / 10000)) / dblMaxScale); // ' range should be 0 to bmpSpectrumHeight -1 - int objColor = Yellow; - - Waterfall[i] = round(y1); - } - - // Send Signal level and Busy indicator to save extra packets - - Waterfall[206] = CurrentLevel; - Waterfall[207] = blnBusyStatus; - Waterfall[208] = intTuneLineLow; - Waterfall[209] = intTuneLineHi; - -// SendtoGUI('X', Waterfall, 210); -#endif - } -} - -*/ - -extern short rawSamples[2400]; // Get Frame Type need 2400 and we may add 1200 -int rawSamplesLength = 0; -extern int maxrawSamplesLength; - -void ProcessNewSamples(short * Samples, int nSamples) -{ - if (SoundIsPlaying == FALSE && UDPSoundIsPlaying == FALSE) - BufferFull(Samples, nSamples); -}; - -void doCalib(int Chan, int Act) -{ - if (Chan == 0 && calib_mode[1]) - return; - - if (Chan == 1 && calib_mode[0]) - return; - - calib_mode[Chan] = Act; - - if (Act == 0) - { - tx_status[Chan] = TX_SILENCE; // Stop TX - Flush(); - RadioPTT(Chan, 0); - Debugprintf("Stop Calib"); - } -} - -int Freq_Change(int Chan, int Freq) -{ - int low, high; - - low = round(rx_shift[1] / 2 + RCVR[Chan] * rcvr_offset[Chan] + 1); - high = round(RX_Samplerate / 2 - (rx_shift[Chan] / 2 + RCVR[Chan] * rcvr_offset[Chan])); - - if (Freq < low) - return rx_freq[Chan]; // Dont allow change - - if (Freq > high) - return rx_freq[Chan]; // Dont allow change - - rx_freq[Chan] = Freq; - tx_freq[Chan] = Freq; - - pnt_change[Chan] = TRUE; - wf_pointer(soundChannel[Chan]); - - return Freq; -} - -void MainLoop() -{ - // Called by background thread every 10 ms (maybe) - - // Actually we may have two cards - - // Original only allowed one channel per card. - // I think we should be able to run more, ie two or more - // modems on same soundcard channel - - // So All the soundcard stuff will need to be generalised - - if (UDPServ) - UDPPollReceivedSamples(); - - if (SoundMode == 3) - UDPPollReceivedSamples(); - else - PollReceivedSamples(); - - - if (modem_mode[0] == MODE_ARDOP) - { - chk_dcd1(0, 512); - } - - DoTX(0); - DoTX(1); - DoTX(2); - DoTX(3); - -} - -int ARDOPSendToCard(int Chan, int Len) -{ - // Send Next Block of samples to the soundcard - - short * in = &ARDOPTXBuffer[Chan][ARDOPTXPtr[Chan]]; // Enough to hold whole frame of samples - short * out = DMABuffer; - - int LR = modemtoSoundLR[Chan]; - - int i; - - for (i = 0; i < Len; i++) - { - if (SCO) // Single Channel Output - same to both L and R - { - *out++ = *in; - *out++ = *in++; - } - else - { - if (LR) // Right - { - *out++ = 0; - *out++ = *in++; - } - else - { - *out++ = *in++; - *out++ = 0; - } - } - } - DMABuffer = SendtoCard(DMABuffer, Len); - - ARDOPTXPtr[Chan] += Len; - - // See if end of buffer - - if (ARDOPTXPtr[Chan] > ARDOPTXLen[Chan]) - return 1; - - return 0; -} -void DoTX(int Chan) -{ - // This kicks off a send sequence or calibrate - -// printtick("dotx"); - - if (calib_mode[Chan]) - { - // Maybe new calib or continuation - - if (pnt_change[Chan]) - { - make_core_BPF(Chan, rx_freq[Chan], bpf[Chan]); - make_core_TXBPF(Chan, tx_freq[Chan], txbpf[Chan]); - pnt_change[Chan] = FALSE; - } - - // Note this may block in SendtoCard - - modulator(Chan, tx_bufsize); - return; - } - - // I think we have to detect NO_DATA here and drop PTT and return to SILENCE - - if (tx_status[Chan] == TX_NO_DATA) - { - Flush(); - Debugprintf("TX Complete"); - RadioPTT(0, 0); - tx_status[Chan] = TX_SILENCE; - - // We should now send any ackmode acks as the channel is now free for dest to reply - - sendAckModeAcks(Chan); - } - - if (tx_status[Chan] != TX_SILENCE) - { - // Continue the send - - if (modem_mode[Chan] == MODE_ARDOP) - { -// if (SeeIfCardBusy()) -// return 0; - - if (ARDOPSendToCard(Chan, SendSize) == 1) - { - // End of TX - - Number = 0; - Flush(); - - // See if more to send. If so, don't drop PTT - - if (all_frame_buf[Chan].Count) - { - SoundIsPlaying = TRUE; - Number = 0; - - Debugprintf("TX Continuing"); - - string * myTemp = Strings(&all_frame_buf[Chan], 0); // get message - string * tx_data; - - if ((myTemp->Data[0] & 0x0f) == 12) // ACKMODE - { - // Save copy then copy data up 3 bytes - - Add(&KISS_acked[Chan], duplicateString(myTemp)); - - mydelete(myTemp, 0, 3); - myTemp->Length -= sizeof(void *); - } - else - { - // Just remove control - - mydelete(myTemp, 0, 1); - } - - tx_data = duplicateString(myTemp); // so can free original below - - Delete(&all_frame_buf[Chan], 0); // This will invalidate temp - - AGW_AX25_frame_analiz(Chan, FALSE, tx_data); - - put_frame(Chan, tx_data, "", TRUE, FALSE); - - PktARDOPEncode(tx_data->Data, tx_data->Length - 2, Chan); - - freeString(tx_data); - - // Samples are now in DMABuffer = Send first block - - ARDOPSendToCard(Chan, SendSize); - tx_status[Chan] = TX_FRAME; - return; - } - - Debugprintf("TX Complete"); - RadioPTT(0, 0); - tx_status[Chan] = TX_SILENCE; - - // We should now send any ackmode acks as the channel is now free for dest to reply - } - - return; - } - - modulator(Chan, tx_bufsize); - return; - } - - if (SoundIsPlaying || UDPSoundIsPlaying) - return; - - // Not doing anything so see if we have anything new to send - - // See if frequency has changed - - if (pnt_change[Chan]) - { - make_core_BPF(Chan, rx_freq[Chan], bpf[Chan]); - make_core_TXBPF(Chan, tx_freq[Chan], txbpf[Chan]); - pnt_change[Chan] = FALSE; - } - - // See if we need an RSID - - if (needRSID[Chan]) - { - needRSID[Chan] = 0; - - // Note this may block in SampleSink - - Debugprintf("Sending RSID"); - sendRSID(Chan, all_frame_buf[Chan].Count == 0); - return; - } - - if (all_frame_buf[Chan].Count == 0) - return; - - // Start a new send. modulator should handle TXD etc - - Debugprintf("TX Start"); - SampleNo = 0; - - SoundIsPlaying = TRUE; - RadioPTT(Chan, 1); - Number = 0; - - if (modem_mode[Chan] == MODE_ARDOP) - { - // I think ARDOP will have to generate a whole frame of samples - // then send them out a bit at a time to avoid stopping here for - // possibly 10's of seconds - - // Can do this here as unlike normal ardop we don't need to run on Teensy - // to 12000 sample rate we need either 24K or 48K per second, depending on - // where we do the stereo mux. - - // Slowest rate is 50 baud, so a 255 byte packet would take about a minute - // allowing for RS overhead. Not really realistic put perhaps should be possible. - // RAM isn't an issue so maybe allocate 2 MB. - - // ?? Should we allow two ARDOP modems - could make sense if we can run sound - // card channels independently - - string * myTemp = Strings(&all_frame_buf[Chan], 0); // get message - string * tx_data; - - if ((myTemp->Data[0] & 0x0f) == 12) // ACKMODE - { - // Save copy then copy data up 3 bytes - - Add(&KISS_acked[Chan], duplicateString(myTemp)); - - mydelete(myTemp, 0, 3); - myTemp->Length -= sizeof(void *); - } - else - { - // Just remove control - - mydelete(myTemp, 0, 1); - } - - tx_data = duplicateString(myTemp); // so can free original below - - Delete(&all_frame_buf[Chan], 0); // This will invalidate temp - - AGW_AX25_frame_analiz(Chan, FALSE, tx_data); - - put_frame(Chan, tx_data, "", TRUE, FALSE); - - PktARDOPEncode(tx_data->Data, tx_data->Length - 2, Chan); - - freeString(tx_data); - - // Samples are now in DMABuffer = Send first block - - ARDOPSendToCard(Chan, SendSize); - tx_status[Chan] = TX_FRAME; - - } - else - modulator(Chan, tx_bufsize); - - return; -} - -void stoptx(int snd_ch) -{ - Flush(); - Debugprintf("TX Complete"); - RadioPTT(snd_ch, 0); - tx_status[snd_ch] = TX_SILENCE; - - snd_status[snd_ch] = SND_IDLE; -} - -void RX2TX(int snd_ch) -{ - if (snd_status[snd_ch] == SND_IDLE) - { - DoTX(snd_ch); - } -} - -// PTT Stuff - -int hPTTDevice = 0; -char PTTPort[80] = ""; // Port for Hardware PTT - may be same as control port. -int PTTBAUD = 19200; -int PTTMode = PTTRTS; // PTT Control Flags. - -char PTTOnString[128] = ""; -char PTTOffString[128] = ""; - -UCHAR PTTOnCmd[64]; -UCHAR PTTOnCmdLen = 0; - -UCHAR PTTOffCmd[64]; -UCHAR PTTOffCmdLen = 0; - -int pttGPIOPin = 17; // Default -int pttGPIOPinR = 17; -BOOL pttGPIOInvert = FALSE; -BOOL useGPIO = FALSE; -BOOL gotGPIO = FALSE; - -int HamLibPort = 4532; -char HamLibHost[32] = "192.168.1.14"; - -char CM108Addr[80] = ""; - -int VID = 0; -int PID = 0; - -// CM108 Code - -char * CM108Device = NULL; - -void DecodeCM108(char * ptr) -{ - // Called if Device Name or PTT = Param is CM108 - -#ifdef WIN32 - - // Next Param is VID and PID - 0xd8c:0x8 or Full device name - // On Windows device name is very long and difficult to find, so - // easier to use VID/PID, but allow device in case more than one needed - - char * next; - long VID = 0, PID = 0; - char product[256] = "Unknown"; - - struct hid_device_info *devs, *cur_dev; - const char *path_to_open = NULL; - hid_device *handle = NULL; - - if (strlen(ptr) > 16) - CM108Device = _strdup(ptr); - else - { - VID = strtol(ptr, &next, 0); - if (next) - PID = strtol(++next, &next, 0); - - // Look for Device - - devs = hid_enumerate((unsigned short)VID, (unsigned short)PID); - cur_dev = devs; - - while (cur_dev) - { - if (cur_dev->product_string) - wcstombs(product, cur_dev->product_string, 255); - - Debugprintf("HID Device %s VID %X PID %X", product, cur_dev->vendor_id, cur_dev->product_id); - if (cur_dev->vendor_id == VID && cur_dev->product_id == PID) - { - path_to_open = cur_dev->path; - break; - } - cur_dev = cur_dev->next; - } - - if (path_to_open) - { - handle = hid_open_path(path_to_open); - - if (handle) - { - hid_close(handle); - CM108Device = _strdup(path_to_open); - } - else - { - Debugprintf("Unable to open CM108 device %x %x", VID, PID); - } - } - else - Debugprintf("Couldn't find CM108 device %x %x", VID, PID); - - hid_free_enumeration(devs); - } -#else - - // Linux - Next Param HID Device, eg /dev/hidraw0 - - CM108Device = _strdup(ptr); -#endif -} - -char * strlop(char * buf, char delim) -{ - // Terminate buf at delim, and return rest of string - - char * ptr = strchr(buf, delim); - - if (ptr == NULL) return NULL; - - *(ptr)++ = 0; - return ptr; -} - -void OpenPTTPort() -{ - PTTMode &= ~PTTCM108; - PTTMode &= ~PTTHAMLIB; - - if (PTTPort[0] && strcmp(PTTPort, "None") != 0) - { - if (PTTMode == PTTCAT) - { - // convert config strings from Hex - - char * ptr1 = PTTOffString; - UCHAR * ptr2 = PTTOffCmd; - char c; - int val; - - while (c = *(ptr1++)) - { - val = c - 0x30; - if (val > 15) val -= 7; - val <<= 4; - c = *(ptr1++) - 0x30; - if (c > 15) c -= 7; - val |= c; - *(ptr2++) = val; - } - - PTTOffCmdLen = ptr2 - PTTOffCmd; - - ptr1 = PTTOnString; - ptr2 = PTTOnCmd; - - while (c = *(ptr1++)) - { - val = c - 0x30; - if (val > 15) val -= 7; - val <<= 4; - c = *(ptr1++) - 0x30; - if (c > 15) c -= 7; - val |= c; - *(ptr2++) = val; - } - - PTTOnCmdLen = ptr2 - PTTOnCmd; - } - - if (stricmp(PTTPort, "GPIO") == 0) - { - // Initialise GPIO for PTT if available - -#ifdef __ARM_ARCH - - if (gpioInitialise() == 0) - { - printf("GPIO interface for PTT available\n"); - gotGPIO = TRUE; - - SetupGPIOPTT(); - } - else - printf("Couldn't initialise GPIO interface for PTT\n"); - -#else - printf("GPIO interface for PTT not available on this platform\n"); -#endif - - } - else if (stricmp(PTTPort, "CM108") == 0) - { - DecodeCM108(CM108Addr); - PTTMode |= PTTCM108; - } - - else if (stricmp(PTTPort, "HAMLIB") == 0) - { - PTTMode |= PTTHAMLIB; - HAMLIBSetPTT(0); // to open port - return; - } - - else // Not GPIO - { - hPTTDevice = OpenCOMPort(PTTPort, PTTBAUD, FALSE, FALSE, FALSE, 0); - } - } -} - -void ClosePTTPort() -{ - CloseCOMPort(hPTTDevice); - hPTTDevice = 0; -} -void CM108_set_ptt(int PTTState) -{ - char io[5]; - hid_device *handle; - int n; - - io[0] = 0; - io[1] = 0; - io[2] = 1 << (3 - 1); - io[3] = PTTState << (3 - 1); - io[4] = 0; - - if (CM108Device == NULL) - return; - -#ifdef WIN32 - handle = hid_open_path(CM108Device); - - if (!handle) { - printf("unable to open device\n"); - return; - } - - n = hid_write(handle, io, 5); - if (n < 0) - { - printf("Unable to write()\n"); - printf("Error: %ls\n", hid_error(handle)); - } - - hid_close(handle); - -#else - - int fd; - - fd = open(CM108Device, O_WRONLY); - - if (fd == -1) - { - printf("Could not open %s for write, errno=%d\n", CM108Device, errno); - return; - } - - io[0] = 0; - io[1] = 0; - io[2] = 1 << (3 - 1); - io[3] = PTTState << (3 - 1); - io[4] = 0; - - n = write(fd, io, 5); - if (n != 5) - { - printf("Write to %s failed, n=%d, errno=%d\n", CM108Device, n, errno); - } - - close(fd); -#endif - return; - -} - - - -void RadioPTT(int snd_ch, BOOL PTTState) -{ -#ifdef __ARM_ARCH - if (useGPIO) - { - if (DualPTT && modemtoSoundLR[snd_ch] == 1) - gpioWrite(pttGPIOPinR, (pttGPIOInvert ? (1 - PTTState) : (PTTState))); - else - gpioWrite(pttGPIOPin, (pttGPIOInvert ? (1 - PTTState) : (PTTState))); - - return; - } - -#endif - - if ((PTTMode & PTTCM108)) - { - CM108_set_ptt(PTTState); - return; - } - - if ((PTTMode & PTTHAMLIB)) - { - HAMLIBSetPTT(PTTState); - return; - } - if (hPTTDevice == 0) - return; - - if ((PTTMode & PTTCAT)) - { - if (PTTState) - WriteCOMBlock(hPTTDevice, PTTOnCmd, PTTOnCmdLen); - else - WriteCOMBlock(hPTTDevice, PTTOffCmd, PTTOffCmdLen); - - return; - } - - if (DualPTT && modemtoSoundLR[snd_ch] == 1) // use DTR - { - if (PTTState) - COMSetDTR(hPTTDevice); - else - COMClearDTR(hPTTDevice); - } - else - { - if ((PTTMode & PTTRTS)) - { - if (PTTState) - COMSetRTS(hPTTDevice); - else - COMClearRTS(hPTTDevice); - } - } - -} - -char ShortDT[] = "HH:MM:SS"; - -char * ShortDateTime() -{ - struct tm * tm; - time_t NOW = time(NULL); - - tm = gmtime(&NOW); - - sprintf(ShortDT, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); - return ShortDT; -} - - -// Reed Solomon Stuff - - -int NPAR = -1; // Number of Parity Bytes - used in RS Code - -int xMaxErrors = 0; - -int RSEncode(UCHAR * bytToRS, UCHAR * RSBytes, int DataLen, int RSLen) -{ - // This just returns the Parity Bytes. I don't see the point - // in copying the message about - - unsigned char Padded[256]; // The padded Data - - int Length = DataLen + RSLen; // Final Length of packet - int PadLength = 255 - Length; // Padding bytes needed for shortened RS codes - - // subroutine to do the RS encode. For full length and shortend RS codes up to 8 bit symbols (mm = 8) - - if (NPAR != RSLen) // Changed RS Len, so recalc constants; - { - NPAR = RSLen; - xMaxErrors = NPAR / 2; - initialize_ecc(); - } - - // Copy the supplied data to end of data array. - - memset(Padded, 0, PadLength); - memcpy(&Padded[PadLength], bytToRS, DataLen); - - encode_data(Padded, 255 - RSLen, RSBytes); - - return RSLen; -} - -// Main RS decode function - -extern int index_of[]; -extern int recd[]; -extern int Corrected[256]; -extern int tt; // number of errors that can be corrected -extern int kk; // Info Symbols - -extern BOOL blnErrorsCorrected; - - -BOOL RSDecode(UCHAR * bytRcv, int Length, int CheckLen, BOOL * blnRSOK) -{ - - - // Using a modified version of Henry Minsky's code - - //Copyright Henry Minsky (hqm@alum.mit.edu) 1991-2009 - - // Rick's Implementation processes the byte array in reverse. and also - // has the check bytes in the opposite order. I've modified the encoder - // to allow for this, but so far haven't found a way to mske the decoder - // work, so I have to reverse the data and checksum to decode G8BPQ Nov 2015 - - // returns TRUE if was ok or correction succeeded, FALSE if correction impossible - - UCHAR intTemp[256]; // WOrk Area to pass to Decoder - int i; - UCHAR * ptr2 = intTemp; - UCHAR * ptr1 = &bytRcv[Length - CheckLen - 1]; // Last Byte of Data - - int DataLen = Length - CheckLen; - int PadLength = 255 - Length; // Padding bytes needed for shortened RS codes - - *blnRSOK = FALSE; - - if (Length > 255 || Length < (1 + CheckLen)) //Too long or too short - return FALSE; - - if (NPAR != CheckLen) // Changed RS Len, so recalc constants; - { - NPAR = CheckLen; - xMaxErrors = NPAR / 2; - - initialize_ecc(); - } - - - // We reverse the data while zero padding it to speed things up - - // We Need (Data Reversed) (Zero Padding) (Checkbytes Reversed) - - // Reverse Data - - for (i = 0; i < DataLen; i++) - { - *(ptr2++) = *(ptr1--); - } - - // Clear padding - - memset(ptr2, 0, PadLength); - - ptr2 += PadLength; - - // Error Bits - - ptr1 = &bytRcv[Length - 1]; // End of check bytes - - for (i = 0; i < CheckLen; i++) - { - *(ptr2++) = *(ptr1--); - } - - decode_data(intTemp, 255); - - // check if syndrome is all zeros - - if (check_syndrome() == 0) - { - // RS ok, so no need to correct - - *blnRSOK = TRUE; - return TRUE; // No Need to Correct - } - - if (correct_errors_erasures(intTemp, 255, 0, 0) == 0) // Dont support erasures at the momnet - - // Uncorrectable - - return FALSE; - - // Data has been corrected, so need to reverse again - - ptr1 = &intTemp[DataLen - 1]; - ptr2 = bytRcv; // Last Byte of Data - - for (i = 0; i < DataLen; i++) - { - *(ptr2++) = *(ptr1--); - } - - // ?? Do we need to return the check bytes ?? - - // Yes, so we can redo RS Check on supposedly connected frame - - ptr1 = &intTemp[254]; // End of Check Bytes - - for (i = 0; i < CheckLen; i++) - { - *(ptr2++) = *(ptr1--); - } - - return TRUE; -} - -extern TStringList detect_list[5]; -extern TStringList detect_list_c[5]; - -void ProcessPktFrame(int snd_ch, UCHAR * Data, int frameLen) -{ - string * pkt = newString(); - - stringAdd(pkt, Data, frameLen + 2); // 2 for crc (not actually there) - - analiz_frame(snd_ch, pkt, "ARDOP", 1); - -} diff --git a/SMMain.c b/SMMain.c index 141947b..24f6159 100644 --- a/SMMain.c +++ b/SMMain.c @@ -32,6 +32,8 @@ along with QtSoundModem. If not, see http://www.gnu.org/licenses BOOL KISSServ; int KISSPort; +int NeedWaterfallHeaders = 0; + BOOL AGWServ; int AGWPort; @@ -566,7 +568,7 @@ int Freq_Change(int Chan, int Freq) tx_freq[Chan] = Freq; pnt_change[Chan] = TRUE; - wf_pointer(Chan); + NeedWaterfallHeaders = TRUE; return Freq; } @@ -1203,7 +1205,7 @@ void CM108_set_ptt(int PTTState) } -float amplitudes[4] = { 32767, 32767, 32767, 32767 }; +float amplitudes[4] = { 32000, 32000, 32000, 32000 }; extern float amplitude; void RadioPTT(int snd_ch, BOOL PTTState) diff --git a/UZ7HOStuff-DESKTOP-MHE5LO8.h b/UZ7HOStuff-DESKTOP-MHE5LO8.h deleted file mode 100644 index 20721cc..0000000 --- a/UZ7HOStuff-DESKTOP-MHE5LO8.h +++ /dev/null @@ -1,1110 +0,0 @@ -#pragma once - -// -// My port of UZ7HO's Soundmodem -// - -#define VersionString "0.0.0.67alpha-6" -#define VersionBytes {0, 0, 0, 67} - -// Added FX25. 4x100 FEC and V27 not Working and disabled - -// 0.8 V27 now OK. - -// 0.9 Digipeating added - -// 0.10 Fix second channel tones and calibrate - -// 0.11 Fix allocation of sessions to correct modem -// Fix DCD -// Fix Monitoring of Multiline packets -// Fix possible saving of wrong center freq -// Limit TX sample Q in Linux -// - -// 0.12 Add AGWPE monitoring of received frames -// Fix DCD Threshold -// Fix KISS transparency issue - -// 0.13 Fix sending last few bits in FX.25 Mode - -// 0.14 Add "Copy on Select" to Trace Window - -// 0.15 Limit Trace window to 10000 lines - -// 0.16 Fix overwriting monitor window after scrollback - -// 0.17 Add GPIO and CAT PTT - -// 0.18 Add CM108/119 PTT - -// 0.19 Fix scheduling KISS frames - -// 0.20 Debug code added to RR processing - -// 0.21 Fix AGW monitor of multiple line packets -// Close ax.25 sessions if AGW Host session closes - -// 0.22 Add FEC Count to Session Stats - -// 0.23 Retry DISC until UA received or retry count exceeded - -// 0.24 More fixes to DISC handling - -// 0.26 Add OSS PulseAudio and HAMLIB support - -// 0.27 Dynamically load PulseAudio modules - -// 0.28 Add ARDOPPacket Mode - -// 0.29 Fix saving settings and geometry on close -// 0.30 Retructure code to build with Qt 5.3 -// Fix crash in nogui mode if pulse requested but not available -// Try to fix memory leaks - -// 0.31 Add option to run modems in seprate threads - -// 0.32 Fix timing problem with AGW connect at startup -// Add Memory ARQ -// Add Single bit "Correction" -// Fix error in 31 when using multiple decoders - -// 0.33 Fix Single bit correction -// More memory leak fixes - -// 0.34 Add API to set Modem and Center Frequency -// Fix crash in delete_incoming_mycalls - -// 0.35 Return Version in AGW Extended g response - -// 0.36 Fix timing problem on startup - -// 0.37 Add scrollbars to Device and Modem dialogs - -// 0.38 Change default CM108 name to /dev/hidraw0 on Linux - -// 0.39 Dont try to display Message Boxes in nogui mode. -// Close Device and Modem dialogs on Accept or Reject -// Fix using HAMLIB in nogui mode - -// 0.40 Fix bug in frame optimize when using 6 char calls - -// 0.41 Fix "glitch" on waterfall markers when changing modem freqs - -// 0.42 Add "Minimize to Tray" option - -// 0.43 Add Andy's on_SABM fix. -// Fix Crash if KISS Data sent to AGW port - -// 0.44 Add UDP bridge. - -// 0.45 Add two more modems. -// 0.46 Fix two more modems. - -// 0.47 Fix suprious DM when host connection lost -// Add CWID - -// 0.48 Send FRMR for unrecognised frame types - -// 0.49 Add Andy's FEC Tag correlation coode - -// 0.50 Fix Waterfall display when only using right channel -// Allow 1200 baud fsk at other center freqs -// Add Port numbers to Window title and Try Icon tooltip -// Fix calculation of filters for multiple decoders -// Add RX Offset setting (for satellite operation - -// 0.51 Fix Multithreading with more that 2 modems - -// 0.52 Add Stdin as source on Linux - -// 0.53 Use Byte instead of byte as byte is defined in newer versions of gcc - -// 0.54 Fix for ALSA problem on new pi OS - -// 0.55 Fix for compiler error with newer compiler - -// 0.56 Fix errors in Config.cpp June 22 - -// 0.57 Add Restart Waterfall action August 22 - -// 0.58 Add RSID Sept 2022 - -// 0.59 Add config of Digi Calls Dec 2022 - -// 0.60 Allow ARDOP Packet on modems 2 to 4 March 2023 - -// 0.61 Add il2p support April 2023 - -// 0.62 April 2023 -// Add option to specify sound devices that aren't in list -// Add Save button to Modem dialog to save current tab without closing dialog -// Don't add plug: to Linux device addresses unless addr contains : (allows use of eg ARDOP) - -// 0.64 Fix sending ax.25 (broken in .61) - -// 0.65 Allow Set Modem command to use modem index as well as modem name - -// 0.66 Allow configuration of waterfall span June 23 -// Add Exclude - -// .67 Add extra modes RUH 4800 RUH 9600 QPSK 600 QPSK 2400 July 23 -// 8PSK 900 added but not working -// Fix loading txtail -// Fix digipeating -// Add MaxFrame to Modem Dialog - -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define UNUSED(x) (void)(x) - -#ifdef M_PI -#undef M_PI -#endif - -#define M_PI 3.1415926f - -#define pi M_PI - -#ifndef WIN32 -#define _strdup strdup -#endif - - //#define NULL ((void *)0) - - //Delphi Types remember case insensitive - -#define single float -#define boolean int -#define Byte unsigned char // 0 to 255 -#define Word unsigned short // 0 to 65,535 -#define SmallInt short // -32,768 to 32,767 -#define LongWord unsigned int // 0 to 4,294,967,295 - // Int6 : Cardinal; // 0 to 4,294,967,295 -#define LongInt int // -2,147,483,648 to 2,147,483,647 -#define Integer int // -2,147,483,648 to 2,147,483,647 -//#define Int64 long long // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 - -//#define Byte unsigned char // 0 to 255 -#define word unsigned short // 0 to 65,535 -#define smallint short // -32,768 to 32,767 -#define longword unsigned int // 0 to 4,294,967,295 - // Int6 : Cardinal; // 0 to 4,294,967,295 -#define longint int // -2,147,483,648 to 2,147,483,647 -#define integer int // -2,147,483,648 to 2,147,483,647 - -typedef unsigned long ULONG; - -#define UCHAR unsigned char -#define UINT unsigned int -#define BOOL int -#define TRUE 1 -#define FALSE 0 - -// Soundcard Channels - -#define NONE 0 -#define LEFT 1 -#define RIGHT 2 - -#define nr_emph 2 - -#define decodedNormal 4 //'-' -#define decodedFEC 3 //'F' -#define decodedMEM 2 //'#' -#define decodedSingle 1 //'$' - - -// Think about implications of changing this !! -extern int FFTSize; - -// Seems to use Delphi TStringList for a lot of queues. This seems to be a list of pointers and a count -// Each pointer is to a Data/Length pair -//Maybe something like - -typedef struct string_T -{ - unsigned char * Data; - int Length; - int AllocatedLength; // A reasonable sized block is allocated at the start to speed up adding chars - -}string; - -typedef struct TStringList_T -{ - int Count; - string ** Items; - -} TStringList; - -// QPSK struct - -typedef struct TQPSK_t -{ - UCHAR tx[4]; - int count[4]; - UCHAR rx[4]; - UCHAR mode; -} TPQSK; - - -typedef struct TKISSMode_t -{ - string * data_in; - void * Socket; // Used as a key - - // Not sure what rest are used for. Seems to be one per channel - - TStringList buffer[4]; // Outgoing Frames - -} TKISSMode; - -typedef struct TMChannel_t -{ - - single prev_LPF1I_buf[4096]; - single prev_LPF1Q_buf[4096]; - single prev_dLPFI_buf[4096]; - single prev_dLPFQ_buf[4096]; - single prev_AFCI_buf[4096]; - single prev_AFCQ_buf[4096]; - single AngleCorr; - single MUX_osc; - single AFC_IZ1; - single AFC_IZ2; - single AFC_QZ1; - single AFC_QZ2; - single AFC_bit_buf1I[1024]; - single AFC_bit_buf1Q[1024]; - single AFC_bit_buf2[1024]; - single AFC_IIZ1; - single AFC_QQZ1; - -} TMChannel; - -typedef struct TFX25_t -{ - string data; - Byte status; - Byte bit_cnt; - Byte byte_rx; - unsigned long long tag; - Byte size; - Byte rs_size; - Byte size_cnt; -} TFX25; - - - -typedef struct TDetector_t -{ - struct TFX25_t fx25[4]; - TStringList mem_ARQ_F_buf[5]; - TStringList mem_ARQ_buf[5]; - float pll_loop[5]; - float last_sample[5]; - UCHAR ones[5]; - UCHAR zeros[5]; - float bit_buf[5][1024]; - float bit_buf1[5][1024]; - UCHAR sample_cnt[5]; - UCHAR last_bit[5]; - float PSK_IZ1[5]; - float PSK_QZ1[5]; - float PkAmpI[5]; - float PkAmpQ[5]; - float PkAmp[5]; - float PkAmpMax[5]; - int newpkpos[5]; - float AverageAmp[5]; - float AngleCorr[5]; - float MinAmp[5]; - float MaxAmp[5]; - float MUX3_osc[5]; - float MUX3_1_osc[5]; - float MUX3_2_osc[5]; - float Preemphasis6[5]; - float Preemphasis12[5]; - float PSK_AGC[5]; - float AGC[5]; - float AGC1[5]; - float AGC2[5]; - float AGC3[5]; - float AGC_max[5]; - float AGC_min[5]; - float AFC_IZ1[5]; - float AFC_IZ2[5]; - float AFC_QZ1[5]; - float AFC_QZ2[5]; - - UCHAR last_rx_bit[5]; - UCHAR bit_stream[5]; - UCHAR byte_rx[5]; - UCHAR bit_stuff_cnt[5]; - UCHAR bit_cnt[5]; - float bit_osc[5]; - UCHAR frame_status[5]; - string rx_data[5]; - string FEC_rx_data[5]; - // - UCHAR FEC_pol[5]; - unsigned short FEC_err[5]; - unsigned long long FEC_header1[5][2]; - unsigned short FEC_blk_int[5]; - unsigned short FEC_len_int[5]; - unsigned short FEC_len[5]; - - unsigned short FEC_len_cnt[5]; - - UCHAR rx_intv_tbl[5][4]; - UCHAR rx_intv_sym[5]; - UCHAR rx_viterbi[5]; - UCHAR viterbi_cnt[5]; - // SurvivorStates [1..4,0..511] of TSurvivor; - // - TMChannel MChannel[5][4]; - - float AFC_dF_avg[5]; - float AFC_dF[5]; - float AFC_bit_osc[5]; - float AFC_bit_buf[5][1024]; - unsigned short AFC_cnt[5]; - - string raw_bits1[5]; - string raw_bits[5]; - UCHAR last_nrzi_bit[5]; - - float BPF_core[5][2048]; - float LPF_core[5][2048]; - - float src_INTR_buf[5][8192]; - float src_INTRI_buf[5][8192]; - float src_INTRQ_buf[5][8192]; - float src_LPF1I_buf[5][8192]; - float src_LPF1Q_buf[5][8192]; - - float src_BPF_buf[5][2048]; - float src_Loop_buf[5][8192]; - float prev_BPF_buf[5][4096]; - - float prev_LPF1I_buf[5][4096]; - float prev_LPF1Q_buf[5][4096]; - float prev_INTR_buf[5][16384]; - float prev_INTRI_buf[5][16384]; - float prev_INTRQ_buf[5][16384]; - - Byte emph_decoded; - Byte rx_decoded; - Byte errors; - -} TDetector; - - - -typedef struct AGWUser_t -{ - void *socket; - string * data_in; - TStringList AGW_frame_buf; - boolean Monitor; - boolean Monitor_raw; - boolean reportFreqAndModem; // Can report modem and frequency to host - -} AGWUser; - -typedef struct TAX25Info_t -{ - longint stat_s_pkt; - longint stat_s_byte; - longint stat_r_pkt; - longint stat_r_byte; - longint stat_r_fc; - longint stat_fec_count; - time_t stat_begin_ses; - time_t stat_end_ses; - longint stat_l_r_byte; - longint stat_l_s_byte; - -} TAX25Info; - -typedef struct TAX25Port_t -{ - Byte hi_vs; - Byte vs; - Byte vr; - Byte PID; - TStringList in_data_buf; - TStringList frm_collector; - string frm_win[8]; - string out_data_buf; - word t1; - word t2; - word t3; - Byte i_lo; - Byte i_hi; - word n1; - word n2; - word IPOLL_cnt; - TStringList frame_buf; //áóôåð êàäðîâ íà ïåðåäà÷ó - TStringList I_frame_buf; - Byte status; - word clk_frack; - char corrcall[10]; - char mycall[10]; - UCHAR digi[56]; - UCHAR Path[80]; // Path in ax25 format - added to save building it each time - UCHAR ReversePath[80]; - int snd_ch; // Simplifies parameter passing - int port; - int pathLen; - void * socket; - char kind[16]; - TAX25Info info; -} TAX25Port; - - -#define LOGEMERGENCY 0 -#define LOGALERT 1 -#define LOGCRIT 2 -#define LOGERROR 3 -#define LOGWARNING 4 -#define LOGNOTICE 5 -#define LOGINFO 6 -#define LOGDEBUG 7 - -#define PTTRTS 1 -#define PTTDTR 2 -#define PTTCAT 4 -#define PTTCM108 8 -#define PTTHAMLIB 16 - -// Status flags - -#define STAT_NO_LINK 0 -#define STAT_LINK 1 -#define STAT_CHK_LINK 2 -#define STAT_WAIT_ANS 3 -#define STAT_TRY_LINK 4 -#define STAT_TRY_UNLINK 5 - - - // Ñmd,Resp,Poll,Final,Digipeater flags -#define SET_P 1 -#define SET_F 0 -#define SET_C 1 -#define SET_R 0 -#define SET_NO_RPT 0 -#define SET_RPT 1 - // Frame ID flags -#define I_FRM 0 -#define S_FRM 1 -#define U_FRM 2 -#define I_I 0 -#define S_RR 1 -#define S_RNR 5 -#define S_REJ 9 -#define S_SREJ 0x0D -#define U_SABM 47 -#define U_DISC 67 -#define U_DM 15 -#define U_UA 99 -#define U_FRMR 135 -#define U_UI 3 - // PID flags -#define PID_X25 0x01 // 00000001-CCIT X25 PLP -#define PID_SEGMENT 0x08 // 00001000-Segmentation fragment -#define PID_TEXNET 0xC3 // 11000011-TEXNET Datagram Protocol -#define PID_LQ 0xC4 // 11001000-Link Quality Protocol -#define PID_APPLETALK 0xCA // 11001010-Appletalk -#define PID_APPLEARP 0xCB // 11001011-Appletalk ARP -#define PID_IP 0xCC // 11001100-ARPA Internet Protocol -#define PID_ARP 0xCD // 11001101-ARPA Address Resolution Protocol -#define PID_NET_ROM 0xCF // 11001111-NET/ROM - - -// Sound interface buffer sizes - -extern int ReceiveSize; -extern int SendSize; - -#define NumberofinBuffers 4 - -#define Now getTicks() - -// #defines from all modules (?? is this a good idaa ?? - -#define WIN_MAXIMIZED 0 -#define WIN_MINIMIZED 1 -#define MODEM_CAPTION 'SoundModem by UZ7HO' -#define MODEM_VERSION '1.06' -#define SND_IDLE 0 -#define SND_TX 1 -#define BUF_EMPTY 0 -#define BUF_FULL 1 -#define DISP_MONO FALSE -#define DISP_RGB TRUE -#define MOD_IDLE 0 -#define MOD_RX 1 -#define MOD_TX 2 -#define MOD_WAIT 3 -#define TIMER_FREE 0 -#define TIMER_BUSY 1 -#define TIMER_OFF 2 -#define TIMER_EVENT_ON 3 -#define TIMER_EVENT_OFF 4 -#define DEBUG_TIMER 1 -#define DEBUG_WATERFALL 2 -#define DEBUG_DECODE 4 -#define DEBUG_SOUND 8 -#define IS_LAST TRUE -#define IS_NOT_LAST FALSE -#define modes_count 20 -#define SPEED_300 0 -#define SPEED_1200 1 -#define SPEED_600 2 -#define SPEED_2400 3 -#define SPEED_P1200 4 -#define SPEED_P600 5 -#define SPEED_P300 6 -#define SPEED_P2400 7 -#define SPEED_Q4800 8 -#define SPEED_Q3600 9 -#define SPEED_Q2400 10 -#define SPEED_MP400 11 -#define SPEED_DW2400 12 -#define SPEED_8P4800 13 -#define SPEED_2400V26B 14 -#define SPEED_ARDOP 15 -#define SPEED_Q300 16 -#define SPEED_8PSK300 17 -#define SPEED_RUH48 18 -#define SPEED_RUH96 19 - -#define MODE_FSK 0 -#define MODE_BPSK 1 -#define MODE_QPSK 2 -#define MODE_MPSK 3 -#define MODE_8PSK 4 -#define MODE_PI4QPSK 5 -#define MODE_ARDOP 6 -#define MODE_RUH 7 - -#define QPSK_SM 0 -#define QPSK_V26 1 - -#define MODEM_8P4800_BPF 3200 -#define MODEM_8P4800_TXBPF 3400 -#define MODEM_8P4800_LPF 1000 -#define MODEM_8P4800_BPF_TAP 64 -#define MODEM_8P4800_LPF_TAP 8 - // -#define MODEM_MP400_BPF 775 -#define MODEM_MP400_TXBPF 850 -#define MODEM_MP400_LPF 70 -#define MODEM_MP400_BPF_TAP 256 -#define MODEM_MP400_LPF_TAP 128 - // -#define MODEM_DW2400_BPF 2400 -#define MODEM_DW2400_TXBPF 2500 -#define MODEM_DW2400_LPF 900 -#define MODEM_DW2400_BPF_TAP 256 //256 -#define MODEM_DW2400_LPF_TAP 32 //128 - // -#define MODEM_Q2400_BPF 2400 -#define MODEM_Q2400_TXBPF 2500 -#define MODEM_Q2400_LPF 900 -#define MODEM_Q2400_BPF_TAP 256 //256 -#define MODEM_Q2400_LPF_TAP 128 //128 - // -#define MODEM_Q3600_BPF 3600 -#define MODEM_Q3600_TXBPF 3750 -#define MODEM_Q3600_LPF 1350 -#define MODEM_Q3600_BPF_TAP 256 -#define MODEM_Q3600_LPF_TAP 128 - // -#define MODEM_Q4800_BPF 4800 -#define MODEM_Q4800_TXBPF 5000 -#define MODEM_Q4800_LPF 1800 -#define MODEM_Q4800_BPF_TAP 256 -#define MODEM_Q4800_LPF_TAP 128 - // -#define MODEM_P2400_BPF 4800 -#define MODEM_P2400_TXBPF 5000 -#define MODEM_P2400_LPF 1800 -#define MODEM_P2400_BPF_TAP 256 -#define MODEM_P2400_LPF_TAP 128 - // -#define MODEM_P1200_BPF 2400 -#define MODEM_P1200_TXBPF 2500 -#define MODEM_P1200_LPF 900 -#define MODEM_P1200_BPF_TAP 256 -#define MODEM_P1200_LPF_TAP 128 - // -#define MODEM_P600_BPF 1200 -#define MODEM_P600_TXBPF 1250 -#define MODEM_P600_LPF 400 -#define MODEM_P600_BPF_TAP 256 -#define MODEM_P600_LPF_TAP 128 - // -#define MODEM_P300_BPF 600 -#define MODEM_P300_TXBPF 625 -#define MODEM_P300_LPF 200 -#define MODEM_P300_BPF_TAP 256 -#define MODEM_P300_LPF_TAP 128 - // -#define MODEM_300_BPF 500 -#define MODEM_300_TXBPF 500 -#define MODEM_300_LPF 155 -#define MODEM_300_BPF_TAP 256 -#define MODEM_300_LPF_TAP 128 - // -#define MODEM_600_BPF 800 -#define MODEM_600_TXBPF 900 -#define MODEM_600_LPF 325 -#define MODEM_600_BPF_TAP 256 -#define MODEM_600_LPF_TAP 128 - // -#define MODEM_1200_BPF 1400 -#define MODEM_1200_TXBPF 1600 -#define MODEM_1200_LPF 650 -#define MODEM_1200_BPF_TAP 256 -#define MODEM_1200_LPF_TAP 128 - // -#define MODEM_2400_BPF 3200 -#define MODEM_2400_TXBPF 3200 -#define MODEM_2400_LPF 1400 -#define MODEM_2400_BPF_TAP 256 -#define MODEM_2400_LPF_TAP 128 - -#define TX_SILENCE 0 -#define TX_DELAY 1 -#define TX_TAIL 2 -#define TX_NO_DATA 3 -#define TX_FRAME 4 -#define TX_WAIT_BPF 5 - - -#define FRAME_WAIT 0 -#define FRAME_LOAD 1 -#define RX_BIT0 0 -#define RX_BIT1 128 -#define DCD_WAIT_SLOT 0 -#define DCD_WAIT_PERSIST 1 - -#define FX25_MODE_NONE 0 -#define FX25_MODE_RX 1 -#define FX25_MODE_TXRX 2 -#define FX25_TAG 0 -#define FX25_LOAD 1 - -#define IL2P_MODE_NONE 0 -#define IL2P_MODE_RX 1 // RX il2p + HDLC -#define IL2P_MODE_TXRX 2 -#define IL2P_MODE_ONLY 3 // RX only il2p, TX il2p - - -#define MODE_OUR 0 -#define MODE_OTHER 1 -#define MODE_RETRY 2 - -#define FRAME_FLAG 126 // 7e - -#define port_num 32 // ?? Max AGW sessions -#define PKT_ERR 17 // Minimum packet size, bytes -#define I_MAX 7 // Maximum number of packets - - - // externs for all modules - -#define ARDOPBufferSize 12000 * 100 - -extern short ARDOPTXBuffer[4][ARDOPBufferSize]; // Enough to hold whole frame of samples - -extern int ARDOPTXLen[4]; // Length of frame -extern int ARDOPTXPtr[4]; // Tx Pointer - -extern BOOL KISSServ; -extern int KISSPort; - -extern BOOL AGWServ; -extern int AGWPort; - -extern TStringList KISS_acked[]; -extern TStringList KISS_iacked[]; - -extern TStringList all_frame_buf[5]; - -extern unsigned short pkt_raw_min_len; -extern int stat_r_mem; - -extern UCHAR diddles; - -extern int stdtones; -extern int fullduplex; - -extern struct TQPSK_t qpsk_set[4]; - -extern int NonAX25[5]; - -extern short txtail[5]; -extern short txdelay[5]; - -extern short modem_def[5]; - -extern int emph_db[5]; -extern UCHAR emph_all[5]; - -extern UCHAR modem_mode[5]; - -extern UCHAR RCVR[5]; -extern int soundChannel[5]; -extern int modemtoSoundLR[4]; - -extern short rx_freq[5]; -extern short active_rx_freq[5]; -extern short rx_shift[5]; -extern short rx_baudrate[5]; -extern short rcvr_offset[5]; - -extern int tx_hitoneraisedb[5]; -extern float tx_hitoneraise[5]; - - -extern UCHAR tx_status[5]; -extern float tx_freq[5]; -extern float tx_shift[5]; -extern unsigned short tx_baudrate[5]; -extern unsigned short tx_bitrate[5]; - -extern unsigned short bpf[5]; -extern unsigned short lpf[5]; - -extern unsigned short txbpf[5]; - -extern unsigned short tx_BPF_tap[5]; -extern unsigned short tx_BPF_timer[5]; - -extern unsigned short BPF_tap[5]; -extern unsigned short LPF_tap[5]; - -extern float tx_BPF_core[5][32768]; -extern float LPF_core[5][2048]; - -extern UCHAR xData[256]; -extern UCHAR xEncoded[256]; -extern UCHAR xDecoded[256]; - -extern float PI125; -extern float PI375; -extern float PI625; -extern float PI875; -extern float PI5; -extern float PI25; -extern float PI75; - -extern int max_frame_collector[4]; -extern boolean KISS_opt[4]; - -#define MaxErrors 4 - -extern BOOL MinOnStart; - -//RS TReedSolomon; -// Form1 TForm1; -// WaveFormat TWaveFormatEx; - -extern int UDPServ; -extern long long udpServerSeqno; - -extern int Channels; -extern int BitsPerSample; -extern float TX_Samplerate; -extern float RX_Samplerate; -extern int RX_SR; -extern int TX_SR; -extern int RX_PPM; -extern int TX_PPM; -extern int tx_bufsize; -extern int rx_bufsize; -extern int tx_bufcount; -extern int rx_bufcount; -extern int fft_size; -extern int mouse_down[2]; -//UCHAR * RX_pBuf array[257]; -// RX_header array[1..256] of TWaveHdr; -// TX_pBuf array[1..4,1..256] of pointer; -//TX_header array[1..4,1..256] of TWaveHdr; -extern UCHAR calib_mode[5]; -extern UCHAR snd_status[5]; -extern UCHAR buf_status[5]; -extern UCHAR tx_buf_num1[5]; -extern UCHAR tx_buf_num[5]; -extern int speed[5]; -extern int panels[6]; - -extern int FFTSize; -#define fft_size FFTSize - -extern float fft_window_arr[2048]; -// fft_s,fft_d array[0..2047] of TComplex; -extern short fft_buf[2][8192]; -extern UCHAR fft_disp[2][1024]; -// bm array[1..4] of TBitMap; -// bm1,bm2,bm3 TBitMap; - -// WaveInHandle hWaveIn; -// WaveOutHandle array[1..4] of hWaveOut; -extern int RXBufferLength; - -// data1 PData16; - -extern int grid_time; -extern int fft_mult; -extern int fft_spd; -extern int grid_timer; -extern int stop_wf; -extern int raduga; -extern char snd_rx_device_name[32]; -extern char snd_tx_device_name[32]; -extern int snd_rx_device; -extern int snd_tx_device; -extern UCHAR mod_icon_status; -extern UCHAR last_mod_icon_status; -extern UCHAR icon_timer; -// TelIni TIniFile; -extern char cur_dir[]; -// TimerId1 cardinal; -// TimerId2 cardinal; -extern UCHAR TimerStat1; -extern UCHAR TimerStat2; -extern int stat_log; - -extern char PTTPort[80]; // Port for Hardware PTT - may be same as control port. -extern int PTTMode; -extern int PTTBAUD ; - -extern char PTTOnString[128]; -extern char PTTOffString[128]; - -extern UCHAR PTTOnCmd[64]; -extern UCHAR PTTOnCmdLen; - -extern UCHAR PTTOffCmd[64]; -extern UCHAR PTTOffCmdLen; - -extern int PTT_device; -extern int RX_device; -extern int TX_device; -extern int TX_rotate; -extern int UsingLeft; -extern int UsingRight; -extern int UsingBothChannels; -extern int pttGPIOPin; -extern int pttGPIOPinR; -extern BOOL pttGPIOInvert; -extern BOOL useGPIO; -extern BOOL gotGPIO; -extern int VID; -extern int PID; -extern char CM108Addr[80]; -extern int HamLibPort; -extern char HamLibHost[]; - -extern int SCO; -extern int DualPTT; -extern UCHAR DebugMode; -extern UCHAR TimerEvent; -extern int nr_monitor_lines; -extern int UTC_Tim; -extern int MainPriority; -// MainThreadHandle THandle; -extern UCHAR w_state; - -extern BOOL Firstwaterfall; -extern BOOL Secondwaterfall; - -extern int dcd_threshold; -extern int rxOffset; -extern int chanOffset[4]; -extern int Continuation[4]; // Sending 2nd or more packet of burst - -extern boolean busy; -extern boolean dcd[5]; - -extern struct TKISSMode_t KISS; - -extern boolean dyn_frack[4] ; -extern Byte recovery[4]; -extern Byte users[4]; - -extern int resptime[4]; -extern int slottime[4]; -extern int persist[4]; -extern int fracks[4]; -extern int frack_time[4]; -extern int idletime[4]; -extern int redtime[4]; -extern int IPOLL[4]; -extern int maxframe[4]; -extern int TXFrmMode[4]; - -extern char MyDigiCall[4][512]; -extern char exclude_callsigns[4][512]; -extern char exclude_APRS_frm[4][512]; - -extern TStringList list_exclude_callsigns[4]; -extern TStringList list_exclude_APRS_frm[4]; -extern TStringList list_digi_callsigns[4]; - - -extern int SoundIsPlaying; -extern int Capturing; - -extern struct TDetector_t DET[nr_emph + 1][16]; - -extern char CaptureDevice[80]; -extern char PlaybackDevice[80]; - -extern TAX25Port AX25Port[4][port_num]; - -extern int fx25_mode[4]; -extern int il2p_mode[4]; - -extern int tx_fx25_size[4]; -extern int tx_fx25_size_cnt[4]; -extern int tx_fx25_mode[4]; - -extern int SatelliteMode; - -extern int using48000; // Set if using 48K sample rate (ie RUH Modem active) - - -// Function prototypes - -void KISS_send_ack(UCHAR port, string * data); -void AGW_AX25_frame_analiz(int snd_ch, int RX, string * frame); -void FIR_filter(float * src, unsigned short buf_size, unsigned short tap, float * core, float * dest, float * prev); -void make_core_TXBPF(UCHAR snd_ch, float freq, float width); -void OpenPTTPort(); -void ClosePTTPort(); - -void RadioPTT(int snd_ch, BOOL PTTState); -void put_frame(int snd_ch, string * frame, char * code, int tx_stat, int excluded); -void CloseCOMPort(int fd); -void COMClearRTS(int fd); -void COMClearDTR(int fd); -unsigned int getTicks(); -char * ShortDateTime(); -void write_ax25_info(TAX25Port * AX25Sess); -void reverse_addr(Byte * path, Byte * revpath, int Len); -string * get_mycall(string * path); -TAX25Port * get_user_port_by_calls(int snd_ch, char * CallFrom, char * CallTo); -TAX25Port * get_free_port(int snd_ch); -void * in_list_incoming_mycall(Byte * path); -boolean add_incoming_mycalls(void * socket, char * src_call); -int get_addr(char * Calls, UCHAR * AXCalls); -void reverse_addr(Byte * path, Byte * revpath, int Len); -void set_link(TAX25Port * AX25Sess, UCHAR * axpath); -void rst_timer(TAX25Port * AX25Sess); -void set_unlink(TAX25Port * AX25Sess, Byte * path); -unsigned short get_fcs(UCHAR * Data, unsigned short len); -void KISSSendtoServer(void * sock, Byte * Msg, int Len); -int ConvFromAX25(unsigned char * incall, char * outcall); -BOOL ConvToAX25(char * callsign, unsigned char * ax25call); -void Debugprintf(const char * format, ...); - -double pila(double x); - -void AGW_Raw_monitor(int snd_ch, string * data); - -// Delphi emulation functions - -string * Strings(TStringList * Q, int Index); -void Clear(TStringList * Q); -int Count(TStringList * List); - -string * newString(); -string * copy(string * Source, int StartChar, int Count); -TStringList * newTStringList(); - -void freeString(string * Msg); - -void initString(string * S); -void initTStringList(TStringList* T); - -// Two delete() This is confusing!! -// Not really - one acts on String, other TStringList - -void Delete(TStringList * Q, int Index); -void mydelete(string * Source, int StartChar, int Count); - -void move(UCHAR * SourcePointer, UCHAR * DestinationPointer, int CopyCount); -void fmove(float * SourcePointer, float * DestinationPointer, int CopyCount); - -void setlength(string * Msg, int Count); // Set string length - -string * stringAdd(string * Msg, UCHAR * Chars, int Count); // Extend string - -void Assign(TStringList * to, TStringList * from); // Duplicate from to to - -string * duplicateString(string * in); - -// This looks for a string in a stringlist. Returns inhex if found, otherwise -1 - -int my_indexof(TStringList * l, string * s); - -boolean compareStrings(string * a, string * b); - -int Add(TStringList * Q, string * Entry); - - -#define IL2P_SYNC_WORD_SIZE 3 -#define IL2P_HEADER_SIZE 13 // Does not include 2 parity. -#define IL2P_HEADER_PARITY 2 - -#define IL2P_MAX_PAYLOAD_SIZE 1023 -#define IL2P_MAX_PAYLOAD_BLOCKS 5 -#define IL2P_MAX_PARITY_SYMBOLS 16 // For payload only. -#define IL2P_MAX_ENCODED_PAYLOAD_SIZE (IL2P_MAX_PAYLOAD_SIZE + IL2P_MAX_PAYLOAD_BLOCKS * IL2P_MAX_PARITY_SYMBOLS) - -struct il2p_context_s { - - enum { IL2P_SEARCHING = 0, IL2P_HEADER, IL2P_PAYLOAD, IL2P_DECODE } state; - - unsigned int acc; // Accumulate most recent 24 bits for sync word matching. - // Lower 8 bits are also used for accumulating bytes for - // the header and payload. - - int bc; // Bit counter so we know when a complete byte has been accumulated. - - int polarity; // 1 if opposite of expected polarity. - - unsigned char shdr[IL2P_HEADER_SIZE + IL2P_HEADER_PARITY]; - // Scrambled header as received over the radio. Includes parity. - int hc; // Number if bytes placed in above. - - unsigned char uhdr[IL2P_HEADER_SIZE]; // Header after FEC and unscrambling. - - int eplen; // Encoded payload length. This is not the nuumber from - // from the header but rather the number of encoded bytes to gather. - - unsigned char spayload[IL2P_MAX_ENCODED_PAYLOAD_SIZE]; - // Scrambled and encoded payload as received over the radio. - int pc; // Number of bytes placed in above. - - int corrected; // Number of symbols corrected by RS FEC. -}; - - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/UZ7HOStuff-HPLaptop.h b/UZ7HOStuff-HPLaptop.h deleted file mode 100644 index dfc2886..0000000 --- a/UZ7HOStuff-HPLaptop.h +++ /dev/null @@ -1,1023 +0,0 @@ -// -// My port of UZ7HO's Soundmodem -// - -#define VersionString "0.0.0.59" -#define VersionBytes {0, 0, 0, 59} - -// Added FX25. 4x100 FEC and V27 not Working and disabled - -// 0.8 V27 now OK. - -// 0.9 Digipeating added - -// 0.10 Fix second channel tones and calibrate - -// 0.11 Fix allocation of sessions to correct modem -// Fix DCD -// Fix Monitoring of Multiline packets -// Fix possible saving of wrong center freq -// Limit TX sample Q in Linux -// - -// 0.12 Add AGWPE monitoring of received frames -// Fix DCD Threshold -// Fix KISS transparency issue - -// 0.13 Fix sending last few bits in FX.25 Mode - -// 0.14 Add "Copy on Select" to Trace Window - -// 0.15 Limit Trace window to 10000 lines - -// 0.16 Fix overwriting monitor window after scrollback - -// 0.17 Add GPIO and CAT PTT - -// 0.18 Add CM108/119 PTT - -// 0.19 Fix scheduling KISS frames - -// 0.20 Debug code added to RR processing - -// 0.21 Fix AGW monitor of multiple line packets -// Close ax.25 sessions if AGW Host session closes - -// 0.22 Add FEC Count to Session Stats - -// 0.23 Retry DISC until UA received or retry count exceeded - -// 0.24 More fixes to DISC handling - -// 0.26 Add OSS PulseAudio and HAMLIB support - -// 0.27 Dynamically load PulseAudio modules - -// 0.28 Add ARDOPPacket Mode - -// 0.29 Fix saving settings and geometry on close -// 0.30 Retructure code to build with Qt 5.3 -// Fix crash in nogui mode if pulse requested but not available -// Try to fix memory leaks - -// 0.31 Add option to run modems in seprate threads - -// 0.32 Fix timing problem with AGW connect at startup -// Add Memory ARQ -// Add Single bit "Correction" -// Fix error in 31 when using multiple decoders - -// 0.33 Fix Single bit correction -// More memory leak fixes - -// 0.34 Add API to set Modem and Center Frequency -// Fix crash in delete_incoming_mycalls - -// 0.35 Return Version in AGW Extended g response - -// 0.36 Fix timing problem on startup - -// 0.37 Add scrollbars to Device and Modem dialogs - -// 0.38 Change default CM108 name to /dev/hidraw0 on Linux - -// 0.39 Dont try to display Message Boxes in nogui mode. -// Close Device and Modem dialogs on Accept or Reject -// Fix using HAMLIB in nogui mode - -// 0.40 Fix bug in frame optimize when using 6 char calls - -// 0.41 Fix "glitch" on waterfall markers when changing modem freqs - -// 0.42 Add "Minimize to Tray" option - -// 0.43 Add Andy's on_SABM fix. -// Fix Crash if KISS Data sent to AGW port - -// 0.44 Add UDP bridge. - -// 0.45 Add two more modems. -// 0.46 Fix two more modems. - -// 0.47 Fix suprious DM when host connection lost -// Add CWID - -// 0.48 Send FRMR for unrecognised frame types - -// 0.49 Add Andy's FEC Tag correlation coode - -// 0.50 Fix Waterfall display when only using right channel -// Allow 1200 baud fsk at other center freqs -// Add Port numbers to Window title and Try Icon tooltip -// Fix calculation of filters for multiple decoders -// Add RX Offset setting (for satellite operation - -// 0.51 Fix Multithreading with more that 2 modems - -// 0.52 Add Stdin as source on Linux - -// 0.53 Use Byte instead of byte as byte is defined in newer versions of gcc - -// 0.54 Fix for ALSA problem on new pi OS - -// 0.55 Fix for compiler error with newer compiler - -// 0.56 Fix errors in Config.cpp June 22 - -// 0.57 Add Restart Waterfall action August 22 - -// 0.58 Add RSID Sept 2022 - -// 0.59 Add config of Digi Calls Dec 2022 - -#include -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define UNUSED(x) (void)(x) - -#ifdef M_PI -#undef M_PI -#endif - -#define M_PI 3.1415926f - -#define pi M_PI - -#ifndef WIN32 -#define _strdup strdup -#endif - - //#define NULL ((void *)0) - - //Delphi Types remember case insensitive - -#define single float -#define boolean int -#define Byte unsigned char // 0 to 255 -#define Word unsigned short // 0 to 65,535 -#define SmallInt short // -32,768 to 32,767 -#define LongWord unsigned int // 0 to 4,294,967,295 - // Int6 : Cardinal; // 0 to 4,294,967,295 -#define LongInt int // -2,147,483,648 to 2,147,483,647 -#define Integer int // -2,147,483,648 to 2,147,483,647 -//#define Int64 long long // -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 - -//#define Byte unsigned char // 0 to 255 -#define word unsigned short // 0 to 65,535 -#define smallint short // -32,768 to 32,767 -#define longword unsigned int // 0 to 4,294,967,295 - // Int6 : Cardinal; // 0 to 4,294,967,295 -#define longint int // -2,147,483,648 to 2,147,483,647 -#define integer int // -2,147,483,648 to 2,147,483,647 - -typedef unsigned long ULONG; - -#define UCHAR unsigned char -#define UINT unsigned int -#define BOOL int -#define TRUE 1 -#define FALSE 0 - -// Soundcard Channels - -#define NONE 0 -#define LEFT 1 -#define RIGHT 2 - -#define nr_emph 2 - -#define decodedNormal 4 //'|' -#define decodedFEC 3 //'F' -#define decodedMEM 2 //'#' -#define decodedSingle 1 //'$' - - -// Seems to use Delphi TStringList for a lot of queues. This seems to be a list of pointers and a count -// Each pointer is to a Data/Length pair -//Maybe something like - -typedef struct string_T -{ - unsigned char * Data; - int Length; - int AllocatedLength; // A reasonable sized block is allocated at the start to speed up adding chars - -}string; - -typedef struct TStringList_T -{ - int Count; - string ** Items; - -} TStringList; - -// QPSK struct - -typedef struct TQPSK_t -{ - UCHAR tx[4]; - int count[4]; - UCHAR rx[4]; - UCHAR mode; -} TPQSK; - - -typedef struct TKISSMode_t -{ - string * data_in; - void * Socket; // Used as a key - - // Not sure what rest are used for. Seems to be one per channel - - TStringList buffer[4]; // Outgoing Frames - -} TKISSMode; - -typedef struct TMChannel_t -{ - - single prev_LPF1I_buf[4096]; - single prev_LPF1Q_buf[4096]; - single prev_dLPFI_buf[4096]; - single prev_dLPFQ_buf[4096]; - single prev_AFCI_buf[4096]; - single prev_AFCQ_buf[4096]; - single AngleCorr; - single MUX_osc; - single AFC_IZ1; - single AFC_IZ2; - single AFC_QZ1; - single AFC_QZ2; - single AFC_bit_buf1I[1024]; - single AFC_bit_buf1Q[1024]; - single AFC_bit_buf2[1024]; - single AFC_IIZ1; - single AFC_QQZ1; - -} TMChannel; - -typedef struct TFX25_t -{ - string data; - Byte status; - Byte bit_cnt; - Byte byte_rx; - unsigned long long tag; - Byte size; - Byte rs_size; - Byte size_cnt; -} TFX25; - - - -typedef struct TDetector_t -{ - struct TFX25_t fx25[4]; - TStringList mem_ARQ_F_buf[5]; - TStringList mem_ARQ_buf[5]; - float pll_loop[5]; - float last_sample[5]; - UCHAR ones[5]; - UCHAR zeros[5]; - float bit_buf[5][1024]; - float bit_buf1[5][1024]; - UCHAR sample_cnt[5]; - UCHAR last_bit[5]; - float PSK_IZ1[5]; - float PSK_QZ1[5]; - float PkAmpI[5]; - float PkAmpQ[5]; - float PkAmp[5]; - float PkAmpMax[5]; - int newpkpos[5]; - float AverageAmp[5]; - float AngleCorr[5]; - float MinAmp[5]; - float MaxAmp[5]; - float MUX3_osc[5]; - float MUX3_1_osc[5]; - float MUX3_2_osc[5]; - float Preemphasis6[5]; - float Preemphasis12[5]; - float PSK_AGC[5]; - float AGC[5]; - float AGC1[5]; - float AGC2[5]; - float AGC3[5]; - float AGC_max[5]; - float AGC_min[5]; - float AFC_IZ1[5]; - float AFC_IZ2[5]; - float AFC_QZ1[5]; - float AFC_QZ2[5]; - - UCHAR last_rx_bit[5]; - UCHAR bit_stream[5]; - UCHAR byte_rx[5]; - UCHAR bit_stuff_cnt[5]; - UCHAR bit_cnt[5]; - float bit_osc[5]; - UCHAR frame_status[5]; - string rx_data[5]; - string FEC_rx_data[5]; - // - UCHAR FEC_pol[5]; - unsigned short FEC_err[5]; - unsigned long long FEC_header1[5][2]; - unsigned short FEC_blk_int[5]; - unsigned short FEC_len_int[5]; - unsigned short FEC_len[5]; - - unsigned short FEC_len_cnt[5]; - - UCHAR rx_intv_tbl[5][4]; - UCHAR rx_intv_sym[5]; - UCHAR rx_viterbi[5]; - UCHAR viterbi_cnt[5]; - // SurvivorStates [1..4,0..511] of TSurvivor; - // - TMChannel MChannel[5][4]; - - float AFC_dF_avg[5]; - float AFC_dF[5]; - float AFC_bit_osc[5]; - float AFC_bit_buf[5][1024]; - unsigned short AFC_cnt[5]; - - string raw_bits1[5]; - string raw_bits[5]; - UCHAR last_nrzi_bit[5]; - - float BPF_core[5][2048]; - float LPF_core[5][2048]; - - float src_INTR_buf[5][8192]; - float src_INTRI_buf[5][8192]; - float src_INTRQ_buf[5][8192]; - float src_LPF1I_buf[5][8192]; - float src_LPF1Q_buf[5][8192]; - - float src_BPF_buf[5][2048]; - float src_Loop_buf[5][8192]; - float prev_BPF_buf[5][4096]; - - float prev_LPF1I_buf[5][4096]; - float prev_LPF1Q_buf[5][4096]; - float prev_INTR_buf[5][16384]; - float prev_INTRI_buf[5][16384]; - float prev_INTRQ_buf[5][16384]; - - Byte emph_decoded; - Byte rx_decoded; - - -} TDetector; - - - -typedef struct AGWUser_t -{ - void *socket; - string * data_in; - TStringList AGW_frame_buf; - boolean Monitor; - boolean Monitor_raw; - boolean reportFreqAndModem; // Can report modem and frequency to host - -} AGWUser; - -typedef struct TAX25Info_t -{ - longint stat_s_pkt; - longint stat_s_byte; - longint stat_r_pkt; - longint stat_r_byte; - longint stat_r_fc; - longint stat_fec_count; - time_t stat_begin_ses; - time_t stat_end_ses; - longint stat_l_r_byte; - longint stat_l_s_byte; - -} TAX25Info; - -typedef struct TAX25Port_t -{ - Byte hi_vs; - Byte vs; - Byte vr; - Byte PID; - TStringList in_data_buf; - TStringList frm_collector; - string frm_win[8]; - string out_data_buf; - word t1; - word t2; - word t3; - Byte i_lo; - Byte i_hi; - word n1; - word n2; - word IPOLL_cnt; - TStringList frame_buf; //áóôåð êàäðîâ íà ïåðåäà÷ó - TStringList I_frame_buf; - Byte status; - word clk_frack; - char corrcall[10]; - char mycall[10]; - UCHAR digi[56]; - UCHAR Path[80]; // Path in ax25 format - added to save building it each time - UCHAR ReversePath[80]; - int snd_ch; // Simplifies parameter passing - int port; - int pathLen; - void * socket; - char kind[16]; - TAX25Info info; -} TAX25Port; - - -#define LOGEMERGENCY 0 -#define LOGALERT 1 -#define LOGCRIT 2 -#define LOGERROR 3 -#define LOGWARNING 4 -#define LOGNOTICE 5 -#define LOGINFO 6 -#define LOGDEBUG 7 - -#define PTTRTS 1 -#define PTTDTR 2 -#define PTTCAT 4 -#define PTTCM108 8 -#define PTTHAMLIB 16 - -// Status flags - -#define STAT_NO_LINK 0 -#define STAT_LINK 1 -#define STAT_CHK_LINK 2 -#define STAT_WAIT_ANS 3 -#define STAT_TRY_LINK 4 -#define STAT_TRY_UNLINK 5 - - - // Ñmd,Resp,Poll,Final,Digipeater flags -#define SET_P 1 -#define SET_F 0 -#define SET_C 1 -#define SET_R 0 -#define SET_NO_RPT 0 -#define SET_RPT 1 - // Frame ID flags -#define I_FRM 0 -#define S_FRM 1 -#define U_FRM 2 -#define I_I 0 -#define S_RR 1 -#define S_RNR 5 -#define S_REJ 9 -#define S_SREJ 0x0D -#define U_SABM 47 -#define U_DISC 67 -#define U_DM 15 -#define U_UA 99 -#define U_FRMR 135 -#define U_UI 3 - // PID flags -#define PID_X25 0x01 // 00000001-CCIT X25 PLP -#define PID_SEGMENT 0x08 // 00001000-Segmentation fragment -#define PID_TEXNET 0xC3 // 11000011-TEXNET Datagram Protocol -#define PID_LQ 0xC4 // 11001000-Link Quality Protocol -#define PID_APPLETALK 0xCA // 11001010-Appletalk -#define PID_APPLEARP 0xCB // 11001011-Appletalk ARP -#define PID_IP 0xCC // 11001100-ARPA Internet Protocol -#define PID_ARP 0xCD // 11001101-ARPA Address Resolution Protocol -#define PID_NET_ROM 0xCF // 11001111-NET/ROM - - -// Sound interface buffer size - -#define SendSize 1024 // 100 mS for now -#define ReceiveSize 512 // try 100 mS for now -#define NumberofinBuffers 4 - -#define Now getTicks() - -// #defines from all modules (?? is this a good idaa ?? - -#define WIN_MAXIMIZED 0 -#define WIN_MINIMIZED 1 -#define MODEM_CAPTION 'SoundModem by UZ7HO' -#define MODEM_VERSION '1.06' -#define SND_IDLE 0 -#define SND_RX 1 -#define SND_TX 2 -#define BUF_EMPTY 0 -#define BUF_FULL 1 -#define DISP_MONO FALSE -#define DISP_RGB TRUE -#define MOD_IDLE 0 -#define MOD_RX 1 -#define MOD_TX 2 -#define MOD_WAIT 3 -#define TIMER_FREE 0 -#define TIMER_BUSY 1 -#define TIMER_OFF 2 -#define TIMER_EVENT_ON 3 -#define TIMER_EVENT_OFF 4 -#define DEBUG_TIMER 1 -#define DEBUG_WATERFALL 2 -#define DEBUG_DECODE 4 -#define DEBUG_SOUND 8 -#define IS_LAST TRUE -#define IS_NOT_LAST FALSE -#define modes_count 16 -#define SPEED_300 0 -#define SPEED_1200 1 -#define SPEED_600 2 -#define SPEED_2400 3 -#define SPEED_P1200 4 -#define SPEED_P600 5 -#define SPEED_P300 6 -#define SPEED_P2400 7 -#define SPEED_Q4800 8 -#define SPEED_Q3600 9 -#define SPEED_Q2400 10 -#define SPEED_MP400 11 -#define SPEED_DW2400 12 -#define SPEED_8P4800 13 -#define SPEED_AE2400 14 -#define SPEED_ARDOP 15 - -#define MODE_FSK 0 -#define MODE_BPSK 1 -#define MODE_QPSK 2 -#define MODE_MPSK 3 -#define MODE_8PSK 4 -#define MODE_PI4QPSK 5 -#define MODE_ARDOP 6 - -#define QPSK_SM 0 -#define QPSK_V26 1 - - -#define MODEM_8P4800_BPF 3200 -#define MODEM_8P4800_TXBPF 3400 -#define MODEM_8P4800_LPF 1000 -#define MODEM_8P4800_BPF_TAP 64 -#define MODEM_8P4800_LPF_TAP 8 - // -#define MODEM_MP400_BPF 775 -#define MODEM_MP400_TXBPF 850 -#define MODEM_MP400_LPF 70 -#define MODEM_MP400_BPF_TAP 256 -#define MODEM_MP400_LPF_TAP 128 - // -#define MODEM_DW2400_BPF 2400 -#define MODEM_DW2400_TXBPF 2500 -#define MODEM_DW2400_LPF 900 -#define MODEM_DW2400_BPF_TAP 256 //256 -#define MODEM_DW2400_LPF_TAP 32 //128 - // -#define MODEM_Q2400_BPF 2400 -#define MODEM_Q2400_TXBPF 2500 -#define MODEM_Q2400_LPF 900 -#define MODEM_Q2400_BPF_TAP 256 //256 -#define MODEM_Q2400_LPF_TAP 128 //128 - // -#define MODEM_Q3600_BPF 3600 -#define MODEM_Q3600_TXBPF 3750 -#define MODEM_Q3600_LPF 1350 -#define MODEM_Q3600_BPF_TAP 256 -#define MODEM_Q3600_LPF_TAP 128 - // -#define MODEM_Q4800_BPF 4800 -#define MODEM_Q4800_TXBPF 5000 -#define MODEM_Q4800_LPF 1800 -#define MODEM_Q4800_BPF_TAP 256 -#define MODEM_Q4800_LPF_TAP 128 - // -#define MODEM_P2400_BPF 4800 -#define MODEM_P2400_TXBPF 5000 -#define MODEM_P2400_LPF 1800 -#define MODEM_P2400_BPF_TAP 256 -#define MODEM_P2400_LPF_TAP 128 - // -#define MODEM_P1200_BPF 2400 -#define MODEM_P1200_TXBPF 2500 -#define MODEM_P1200_LPF 900 -#define MODEM_P1200_BPF_TAP 256 -#define MODEM_P1200_LPF_TAP 128 - // -#define MODEM_P600_BPF 1200 -#define MODEM_P600_TXBPF 1250 -#define MODEM_P600_LPF 400 -#define MODEM_P600_BPF_TAP 256 -#define MODEM_P600_LPF_TAP 128 - // -#define MODEM_P300_BPF 600 -#define MODEM_P300_TXBPF 625 -#define MODEM_P300_LPF 200 -#define MODEM_P300_BPF_TAP 256 -#define MODEM_P300_LPF_TAP 128 - // -#define MODEM_300_BPF 500 -#define MODEM_300_TXBPF 500 -#define MODEM_300_LPF 155 -#define MODEM_300_BPF_TAP 256 -#define MODEM_300_LPF_TAP 128 - // -#define MODEM_600_BPF 800 -#define MODEM_600_TXBPF 900 -#define MODEM_600_LPF 325 -#define MODEM_600_BPF_TAP 256 -#define MODEM_600_LPF_TAP 128 - // -#define MODEM_1200_BPF 1400 -#define MODEM_1200_TXBPF 1600 -#define MODEM_1200_LPF 650 -#define MODEM_1200_BPF_TAP 256 -#define MODEM_1200_LPF_TAP 128 - // -#define MODEM_2400_BPF 3200 -#define MODEM_2400_TXBPF 3200 -#define MODEM_2400_LPF 1400 -#define MODEM_2400_BPF_TAP 256 -#define MODEM_2400_LPF_TAP 128 - -#define TX_SILENCE 0 -#define TX_DELAY 1 -#define TX_TAIL 2 -#define TX_NO_DATA 3 -#define TX_FRAME 4 -#define TX_WAIT_BPF 5 - - -#define FRAME_WAIT 0 -#define FRAME_LOAD 1 -#define RX_BIT0 0 -#define RX_BIT1 128 -#define DCD_WAIT_SLOT 0 -#define DCD_WAIT_PERSIST 1 - -#define FX25_MODE_NONE 0 -#define FX25_MODE_RX 1 -#define FX25_MODE_TXRX 2 -#define FX25_TAG 0 -#define FX25_LOAD 1 - -#define MODE_OUR 0 -#define MODE_OTHER 1 -#define MODE_RETRY 2 - -#define FRAME_FLAG 126 // 7e - -#define port_num 32 // ?? Max AGW sessions -#define PKT_ERR 17 // Minimum packet size, bytes -#define I_MAX 7 // Maximum number of packets - - - // externs for all modules - -#define ARDOPBufferSize 12000 * 100 - -extern short ARDOPTXBuffer[4][12000 * 100]; // Enough to hold whole frame of samples - -extern int ARDOPTXLen[4]; // Length of frame -extern int ARDOPTXPtr[4]; // Tx Pointer - -extern BOOL KISSServ; -extern int KISSPort; - -extern BOOL AGWServ; -extern int AGWPort; - -extern TStringList KISS_acked[]; -extern TStringList KISS_iacked[]; - -extern TStringList all_frame_buf[5]; - -extern unsigned short pkt_raw_min_len; -extern int stat_r_mem; - -extern UCHAR diddles; - -extern int stdtones; -extern int fullduplex; - -extern struct TQPSK_t qpsk_set[4]; - -extern int NonAX25[5]; - -extern short txtail[5]; -extern short txdelay[5]; - -extern short modem_def[5]; - -extern int emph_db[5]; -extern UCHAR emph_all[5]; - -extern UCHAR modem_mode[5]; - -extern UCHAR RCVR[5]; -extern int soundChannel[5]; -extern int modemtoSoundLR[4]; - -extern short rx_freq[5]; -extern short rx_shift[5]; -extern short rx_baudrate[5]; -extern short rcvr_offset[5]; - -extern int tx_hitoneraisedb[5]; -extern float tx_hitoneraise[5]; - - -extern UCHAR tx_status[5]; -extern float tx_freq[5]; -extern float tx_shift[5]; -extern unsigned short tx_baudrate[5]; - -extern unsigned short bpf[5]; -extern unsigned short lpf[5]; - -extern unsigned short txbpf[5]; - -extern unsigned short tx_BPF_tap[5]; -extern unsigned short tx_BPF_timer[5]; - -extern unsigned short BPF_tap[5]; -extern unsigned short LPF_tap[5]; - -extern float tx_BPF_core[5][32768]; -extern float LPF_core[5][2048]; - -extern UCHAR xData[256]; -extern UCHAR xEncoded[256]; -extern UCHAR xDecoded[256]; - -extern float PI125; -extern float PI375; -extern float PI625; -extern float PI875; -extern float PI5; -extern float PI25; -extern float PI75; - -extern int max_frame_collector[4]; -extern boolean KISS_opt[4]; - -#define MaxErrors 4 - -extern BOOL MinOnStart; - -//RS TReedSolomon; -// Form1 TForm1; -// WaveFormat TWaveFormatEx; - -extern int UDPServ; -extern long long udpServerSeqno; - -extern int Channels; -extern int BitsPerSample; -extern float TX_Samplerate; -extern float RX_Samplerate; -extern int RX_SR; -extern int TX_SR; -extern int RX_PPM; -extern int TX_PPM; -extern int tx_bufsize; -extern int rx_bufsize; -extern int tx_bufcount; -extern int rx_bufcount; -extern int fft_size; -extern int mouse_down[2]; -//UCHAR * RX_pBuf array[257]; -// RX_header array[1..256] of TWaveHdr; -// TX_pBuf array[1..4,1..256] of pointer; -//TX_header array[1..4,1..256] of TWaveHdr; -extern UCHAR calib_mode[5]; -extern UCHAR snd_status[5]; -extern UCHAR buf_status[5]; -extern UCHAR tx_buf_num1[5]; -extern UCHAR tx_buf_num[5]; -extern int speed[5]; -extern int panels[6]; - -extern float fft_window_arr[2048]; -// fft_s,fft_d array[0..2047] of TComplex; -extern short fft_buf[5][2048]; -extern UCHAR fft_disp[5][2048]; -// bm array[1..4] of TBitMap; -// bm1,bm2,bm3 TBitMap; - -// WaveInHandle hWaveIn; -// WaveOutHandle array[1..4] of hWaveOut; -extern int RXBufferLength; - -// data1 PData16; - -extern int grid_time; -extern int fft_mult; -extern int fft_spd; -extern int grid_timer; -extern int stop_wf; -extern int raduga; -extern char snd_rx_device_name[32]; -extern char snd_tx_device_name[32]; -extern int snd_rx_device; -extern int snd_tx_device; -extern UCHAR mod_icon_status; -extern UCHAR last_mod_icon_status; -extern UCHAR icon_timer; -// TelIni TIniFile; -extern char cur_dir[]; -// TimerId1 cardinal; -// TimerId2 cardinal; -extern UCHAR TimerStat1; -extern UCHAR TimerStat2; -extern int stat_log; - -extern char PTTPort[80]; // Port for Hardware PTT - may be same as control port. -extern int PTTMode; -extern int PTTBAUD ; - -extern char PTTOnString[128]; -extern char PTTOffString[128]; - -extern UCHAR PTTOnCmd[64]; -extern UCHAR PTTOnCmdLen; - -extern UCHAR PTTOffCmd[64]; -extern UCHAR PTTOffCmdLen; - -extern int PTT_device; -extern int RX_device; -extern int TX_device; -extern int TX_rotate; -extern int UsingLeft; -extern int UsingRight; -extern int UsingBothChannels; -extern int pttGPIOPin; -extern int pttGPIOPinR; -extern BOOL pttGPIOInvert; -extern BOOL useGPIO; -extern BOOL gotGPIO; -extern int VID; -extern int PID; -extern char CM108Addr[80]; -extern int HamLibPort; -extern char HamLibHost[]; - -extern int SCO; -extern int DualPTT; -extern UCHAR DebugMode; -extern UCHAR TimerEvent; -extern int nr_monitor_lines; -extern int UTC_Tim; -extern int MainPriority; -// MainThreadHandle THandle; -extern UCHAR w_state; - -extern BOOL Firstwaterfall; -extern BOOL Secondwaterfall; - -extern int dcd_threshold; -extern int rxOffset; -extern int chanOffset[4]; - -extern boolean busy; -extern boolean dcd[5]; - -extern struct TKISSMode_t KISS; - -extern boolean dyn_frack[4] ; -extern Byte recovery[4]; -extern Byte users[4]; - -extern int resptime[4]; -extern int slottime[4]; -extern int persist[4]; -extern int fracks[4]; -extern int frack_time[4]; -extern int idletime[4]; -extern int redtime[4]; -extern int IPOLL[4]; -extern int maxframe[4]; -extern int TXFrmMode[4]; - -extern char MyDigiCall[4][512]; -extern char exclude_callsigns[4][512]; -extern char exclude_APRS_frm[4][512]; - -extern TStringList list_exclude_callsigns[4]; -extern TStringList list_exclude_APRS_frm[4]; -extern TStringList list_digi_callsigns[4]; - - -extern int SoundIsPlaying; -extern int Capturing; - -extern struct TDetector_t DET[nr_emph + 1][16]; - -extern char CaptureDevice[80]; -extern char PlaybackDevice[80]; - -extern TAX25Port AX25Port[4][port_num]; - -extern int fx25_mode[4]; - -extern int tx_fx25_size[4]; -extern int tx_fx25_size_cnt[4]; -extern int tx_fx25_mode[4]; - -extern int SatelliteMode; - -// Function prototypes - -void KISS_send_ack(UCHAR port, string * data); -void AGW_AX25_frame_analiz(int snd_ch, int RX, string * frame); -void FIR_filter(float * src, unsigned short buf_size, unsigned short tap, float * core, float * dest, float * prev); -void make_core_TXBPF(UCHAR snd_ch, float freq, float width); -void OpenPTTPort(); -void ClosePTTPort(); - -void RadioPTT(int snd_ch, BOOL PTTState); -void put_frame(int snd_ch, string * frame, char * code, int tx_stat, int excluded); -void CloseCOMPort(int fd); -void COMClearRTS(int fd); -void COMClearDTR(int fd); -unsigned int getTicks(); -char * ShortDateTime(); -void write_ax25_info(TAX25Port * AX25Sess); -void reverse_addr(Byte * path, Byte * revpath, int Len); -string * get_mycall(string * path); -TAX25Port * get_user_port_by_calls(int snd_ch, char * CallFrom, char * CallTo); -TAX25Port * get_free_port(int snd_ch); -void * in_list_incoming_mycall(Byte * path); -boolean add_incoming_mycalls(void * socket, char * src_call); -int get_addr(char * Calls, UCHAR * AXCalls); -void reverse_addr(Byte * path, Byte * revpath, int Len); -void set_link(TAX25Port * AX25Sess, UCHAR * axpath); -void rst_timer(TAX25Port * AX25Sess); -void set_unlink(TAX25Port * AX25Sess, Byte * path); -unsigned short get_fcs(UCHAR * Data, unsigned short len); -void KISSSendtoServer(void * sock, Byte * Msg, int Len); -int ConvFromAX25(unsigned char * incall, char * outcall); -BOOL ConvToAX25(char * callsign, unsigned char * ax25call); -void Debugprintf(const char * format, ...); - -double pila(double x); - -void AGW_Raw_monitor(int snd_ch, string * data); - -// Dephi emulation functions - -string * Strings(TStringList * Q, int Index); -void Clear(TStringList * Q); -int Count(TStringList * List); - -string * newString(); -string * copy(string * Source, int StartChar, int Count); -TStringList * newTStringList(); - -void freeString(string * Msg); - -void initString(string * S); -void initTStringList(TStringList* T); - -// Two delete() This is confusing!! -// Not really - one acts on String, other TStringList - -void Delete(TStringList * Q, int Index); -void mydelete(string * Source, int StartChar, int Count); - -void move(UCHAR * SourcePointer, UCHAR * DestinationPointer, int CopyCount); -void fmove(float * SourcePointer, float * DestinationPointer, int CopyCount); - -void setlength(string * Msg, int Count); // Set string length - -string * stringAdd(string * Msg, UCHAR * Chars, int Count); // Extend string - -void Assign(TStringList * to, TStringList * from); // Duplicate from to to - -string * duplicateString(string * in); - -// This looks for a string in a stringlist. Returns inhex if found, otherwise -1 - -int my_indexof(TStringList * l, string * s); - -boolean compareStrings(string * a, string * b); - -int Add(TStringList * Q, string * Entry); -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/UZ7HOStuff.h b/UZ7HOStuff.h index f62c123..4a68356 100644 --- a/UZ7HOStuff.h +++ b/UZ7HOStuff.h @@ -4,8 +4,8 @@ // My port of UZ7HO's Soundmodem // -#define VersionString "0.0.0.68" -#define VersionBytes {0, 0, 0, 68} +#define VersionString "0.0.0.71" +#define VersionBytes {0, 0, 0, 71} // Added FX25. 4x100 FEC and V27 not Working and disabled @@ -167,6 +167,18 @@ // Fix Waterfall display when using right channel only // Allow PTT device to be added +// .69 Add basic Dark Theme +// Fix some timing bugs in Waterfall and RX Level refresh +// Only display session table if AGW interface is enabled +// Fix operation with both left and right channels in use + +// .70 Restructure Waterfall area to be a single image + +// .71 Add IL2P CRC Mode +// Improve reliability of waterfall update +// Report and set fx.25 and il2p flags to/from BPQ + + #include @@ -997,6 +1009,7 @@ extern TAX25Port AX25Port[4][port_num]; extern int fx25_mode[4]; extern int il2p_mode[4]; +extern int il2p_crc[4]; extern int tx_fx25_size[4]; extern int tx_fx25_size_cnt[4]; @@ -1098,7 +1111,7 @@ int Add(TStringList * Q, string * Entry); struct il2p_context_s { - enum { IL2P_SEARCHING = 0, IL2P_HEADER, IL2P_PAYLOAD, IL2P_DECODE } state; + enum { IL2P_SEARCHING = 0, IL2P_HEADER, IL2P_PAYLOAD, IL2P_CRC, IL2P_DECODE } state; unsigned int acc; // Accumulate most recent 24 bits for sync word matching. // Lower 8 bits are also used for accumulating bytes for @@ -1122,8 +1135,12 @@ struct il2p_context_s { int pc; // Number of bytes placed in above. int corrected; // Number of symbols corrected by RS FEC. + + int crccount; // fec chars collected + unsigned char crc[4]; // the 4 fec chars }; +extern int NeedWaterfallHeaders; #ifdef __cplusplus } diff --git a/agwlib.h b/agwlib.h deleted file mode 100644 index 688f918..0000000 --- a/agwlib.h +++ /dev/null @@ -1,45 +0,0 @@ - -#ifndef AGWLIB_H -#define AGWLIB_H 1 - - -// Call at beginning to start it up. - -int agwlib_init (char *host, char *port, int (*init_func)(void)); - - - -// Send commands to TNC. - - -int agwlib_X_register_callsign (int chan, char *call_from); - -int agwlib_x_unregister_callsign (int chan, char *call_from); - -int agwlib_G_ask_port_information (void); - -int agwlib_C_connect (int chan, char *call_from, char *call_to); - -int agwlib_d_disconnect (int chan, char *call_from, char *call_to); - -int agwlib_D_send_connected_data (int chan, int pid, char *call_from, char *call_to, int data_len, char *data); - -int agwlib_Y_outstanding_frames_for_station (int chan, char *call_from, char *call_to); - - - -// The application must define these. - -void agw_cb_C_connection_received (int chan, char *call_from, char *call_to, int data_len, char *data); -void on_C_connection_received (int chan, char *call_from, char *call_to, int incoming, char *data); - -void agw_cb_d_disconnected (int chan, char *call_from, char *call_to, int data_len, char *data); - -void agw_cb_D_connected_data (int chan, char *call_from, char *call_to, int data_len, char *data); - -void agw_cb_G_port_information (int num_chan, char *chan_descriptions[]); - -void agw_cb_Y_outstanding_frames_for_station (int chan, char *call_from, char *call_to, int frame_count); - - -#endif \ No newline at end of file diff --git a/ais.h b/ais.h deleted file mode 100644 index 6b96288..0000000 --- a/ais.h +++ /dev/null @@ -1,8 +0,0 @@ - - -void ais_to_nmea (unsigned char *ais, int ais_len, char *nema, int nema_size); - -int ais_parse (char *sentence, int quiet, char *descr, int descr_size, char *mssi, int mssi_size, double *odlat, double *odlon, - float *ofknots, float *ofcourse, float *ofalt_m, char *symtab, char *symbol, char *comment, int comment_size); - -int ais_check_length (int type, int length); diff --git a/aprs_tt.h b/aprs_tt.h deleted file mode 100644 index 4d33f48..0000000 --- a/aprs_tt.h +++ /dev/null @@ -1,191 +0,0 @@ - -/* aprs_tt.h */ - -#ifndef APRS_TT_H -#define APRS_TT_H 1 - - - -/* - * For holding location format specifications from config file. - * Same thing is also useful for macro definitions. - * We have exactly the same situation of looking for a pattern - * match and extracting fixed size groups of digits. - */ - -struct ttloc_s { - enum { TTLOC_POINT, TTLOC_VECTOR, TTLOC_GRID, TTLOC_UTM, TTLOC_MGRS, TTLOC_USNG, TTLOC_MACRO, TTLOC_MHEAD, TTLOC_SATSQ, TTLOC_AMBIG } type; - - char pattern[20]; /* e.g. B998, B5bbbdddd, B2xxyy, Byyyxxx, BAxxxx */ - /* For macros, it should be all fixed digits, */ - /* and the letters x, y, z. e.g. 911, xxyyyz */ - - union { - - struct { - double lat; /* Specific locations. */ - double lon; - } point; - - struct { - double lat; /* For bearing/direction. */ - double lon; - double scale; /* conversion to meters */ - } vector; - - struct { - double lat0; /* yyy all zeros. */ - double lon0; /* xxx */ - double lat9; /* yyy all nines. */ - double lon9; /* xxx */ - } grid; - - struct { - double scale; - double x_offset; - double y_offset; - long lzone; /* UTM zone, should be 1-60 */ - char latband; /* Latitude band if specified, otherwise space or - */ - char hemi; /* UTM Hemisphere, should be 'N' or 'S'. */ - } utm; - - struct { - char zone[8]; /* Zone and square for USNG/MGRS */ - } mgrs; - - struct { - char prefix[24]; /* should be 10, 6, or 4 digits to be */ - /* prepended to the received sequence. */ - } mhead; - - struct { - char *definition; - } macro; - - }; -}; - - -/* Error codes for sending responses to user. */ - -#define TT_ERROR_OK 0 /* Success. */ -#define TT_ERROR_D_MSG 1 /* D was first char of field. Not implemented yet. */ -#define TT_ERROR_INTERNAL 2 /* Internal error. Shouldn't be here. */ -#define TT_ERROR_MACRO_NOMATCH 3 /* No definition for digit sequence. */ -#define TT_ERROR_BAD_CHECKSUM 4 /* Bad checksum on call. */ -#define TT_ERROR_INVALID_CALL 5 /* Invalid callsign. */ -#define TT_ERROR_INVALID_OBJNAME 6 /* Invalid object name. */ -#define TT_ERROR_INVALID_SYMBOL 7 /* Invalid symbol specification. */ -#define TT_ERROR_INVALID_LOC 8 /* Invalid location. */ -#define TT_ERROR_NO_CALL 9 /* No call or object name included. */ -#define TT_ERROR_INVALID_MHEAD 10 /* Invalid Maidenhead Locator. */ -#define TT_ERROR_INVALID_SATSQ 11 /* Satellite square must be 4 digits. */ -#define TT_ERROR_SUFFIX_NO_CALL 12 /* No known callsign for suffix. */ - -#define TT_ERROR_MAXP1 13 /* Number of items above. i.e. Last number plus 1. */ - - -#if CONFIG_C /* Is this being included from config.c? */ - -/* Must keep in sync with above !!! */ - -static const char *tt_msg_id[TT_ERROR_MAXP1] = { - "OK", - "D_MSG", - "INTERNAL", - "MACRO_NOMATCH", - "BAD_CHECKSUM", - "INVALID_CALL", - "INVALID_OBJNAME", - "INVALID_SYMBOL", - "INVALID_LOC", - "NO_CALL", - "INVALID_MHEAD", - "INVALID_SATSQ", - "SUFFIX_NO_CALL" -}; - -#endif - -/* - * Configuration options for APRStt. - */ - -#define TT_MAX_XMITS 10 - -#define TT_MTEXT_LEN 64 - - -struct tt_config_s { - - int gateway_enabled; /* Send DTMF sequences to APRStt gateway. */ - - int obj_recv_chan; /* Channel to listen for tones. */ - - int obj_xmit_chan; /* Channel to transmit object report. */ - /* -1 for none. This could happen if we */ - /* are only sending to application */ - /* and/or IGate. */ - - int obj_send_to_app; /* send to attached application(s). */ - - int obj_send_to_ig; /* send to IGate. */ - - char obj_xmit_via[AX25_MAX_REPEATERS * (AX25_MAX_ADDR_LEN+1)]; - /* e.g. empty or "WIDE2-1,WIDE1-1" */ - - int retain_time; /* Seconds to keep information about a user. */ - - int num_xmits; /* Number of times to transmit object report. */ - - int xmit_delay[TT_MAX_XMITS]; /* Delay between them. */ - /* e.g. 3 seconds before first transmission then */ - /* delays of 16, 32, seconds etc. in between repeats. */ - - struct ttloc_s *ttloc_ptr; /* Pointer to variable length array of above. */ - int ttloc_size; /* Number of elements allocated. */ - int ttloc_len; /* Number of elements actually used. */ - - double corral_lat; /* The "corral" for unknown locations. */ - double corral_lon; - double corral_offset; - int corral_ambiguity; - - char status[10][TT_MTEXT_LEN]; /* Up to 9 status messages. e.g. "/enroute" */ - /* Position 0 means none and can't be changed. */ - - struct { - char method[AX25_MAX_ADDR_LEN]; /* SPEECH or MORSE[-n] */ - char mtext[TT_MTEXT_LEN]; /* Message text. */ - } response[TT_ERROR_MAXP1]; - - char ttcmd[80]; /* Command to generate custom audible response. */ -}; - - - - -void aprs_tt_init (struct tt_config_s *p_config, int debug); - -void aprs_tt_button (int chan, char button); - - - - - -#define APRSTT_LOC_DESC_LEN 32 /* Need at least 26 */ - -#define APRSTT_DEFAULT_SYMTAB '\\' -#define APRSTT_DEFAULT_SYMBOL 'A' - - -void aprs_tt_dao_to_desc (char *dao, char *str); - -void aprs_tt_sequence (int chan, char *msg); - -int dw_run_cmd (char *cmd, int oneline, char *result, size_t resultsiz); - - -#endif - -/* end aprs_tt.h */ \ No newline at end of file diff --git a/audio_stats.h b/audio_stats.h deleted file mode 100644 index 4cf8ad0..0000000 --- a/audio_stats.h +++ /dev/null @@ -1,7 +0,0 @@ - - -/* audio_stats.h */ - - -extern void audio_stats (int adev, int nchan, int nsamp, int interval); - diff --git a/ax25_agw.c b/ax25_agw.c index 5432195..ec73b2b 100644 --- a/ax25_agw.c +++ b/ax25_agw.c @@ -515,13 +515,15 @@ void on_AGW_Gs_frame(AGWUser * AGW, struct AGWHeader * Frame, Byte * Data) { // QTSM with a data field is used by QtSM to set/read Modem Params - Byte info[44] = { 0, 255, 24, 3, 100, 15, 6, 0, 1, 0, 0, 0 }; //QTSM Signature + Byte info[48] = { 0, 255, 24, 3, 100, 15, 6, 0, 1, 0, 0, 0 }; //QTSM Signature int Len = 12; if (Frame->DataLength == 32) { // BPQ to QTSM private Format. + // First 4 Freq, 4 to 24 Modem, rest was spare. Use 27-31 for modem control flags (fx.25 il2p etc) + int Freq; Byte versionBytes[4] = VersionBytes; @@ -542,7 +544,7 @@ void on_AGW_Gs_frame(AGWUser * AGW, struct AGWHeader * Frame, Byte * Data) // New Modem Name. Need to convert to index unless numeric int n; - + if (strlen(&Data[4]) < 3) { n = atoi(&Data[4]); @@ -569,6 +571,13 @@ void on_AGW_Gs_frame(AGWUser * AGW, struct AGWHeader * Frame, Byte * Data) } } + if (Data[27] == 2) + { + fx25_mode[Frame->Port] = Data[28]; + il2p_mode[Frame->Port] = Data[29]; + il2p_crc[Frame->Port] = Data[30]; + } + // Return Freq and Modem memcpy(&info[12], &rx_freq[Frame->Port], 2); @@ -577,6 +586,22 @@ void on_AGW_Gs_frame(AGWUser * AGW, struct AGWHeader * Frame, Byte * Data) memcpy(&info[38], versionBytes, 4); Len = 44; + + if (Data[27]) + { + // BPQ understands fx25 and il2p fields + + AGW->reportFreqAndModem = 2; // Can report frequency Modem and flags + + + Len = 48; + + info[44] = 1; // Show includes Modem Flags + info[45] = fx25_mode[Frame->Port]; + info[46] = il2p_mode[Frame->Port]; + info[47] = il2p_crc[Frame->Port]; + } + AGW_send_to_app(AGW->socket, AGW_Gs_Frame(Frame->Port, info, Len)); return; } @@ -1337,6 +1362,9 @@ void AGW_Report_Modem_Change(int port) AGWUser * AGW; string * pkt; + if (soundChannel[port] == 0) // Not in use + return; + // I think we send to all AGW sockets for (i = 0; i < AGWConCount; i++) @@ -1345,16 +1373,27 @@ void AGW_Report_Modem_Change(int port) if (AGW->reportFreqAndModem) { - // QTSM 's' Message with a data field is used by QtSM to set/read Modem Params + // QTSM 'g' Message with a data field is used by QtSM to set/read Modem Params - Byte info[44] = { 0, 255, 24, 3, 100, 15, 6, 0, 1, 0, 0, 0 }; //QTSM Signature + Byte info[48] = { 0, 255, 24, 3, 100, 15, 6, 0, 1, 0, 0, 0 }; //QTSM Signature + int Len = 44; // Return Freq and Modem memcpy(&info[12], &rx_freq[port], 2); memcpy(&info[16], modes_name[speed[port]], 20); info[37] = speed[port]; // Index - AGW_send_to_app(AGW->socket, AGW_Gs_Frame(port, info, 44)); + + if (AGW->reportFreqAndModem == 2) + { + Len = 48; + + info[44] = 1; // Show includes Modem Flags + info[45] = fx25_mode[port]; + info[46] = il2p_mode[port]; + info[47] = il2p_crc[port]; + } + AGW_send_to_app(AGW->socket, AGW_Gs_Frame(port, info, Len)); } } } diff --git a/ax25_demod.c b/ax25_demod.c index 3e1b5bb..f1b0b36 100644 --- a/ax25_demod.c +++ b/ax25_demod.c @@ -142,6 +142,7 @@ short active_rx_freq[5] = { 1700, 1700,1700,1700,1700 }; int fx25_mode[4] = { 0, 0, 0, 0 }; int il2p_mode[4] = { 0, 0, 0, 0 }; +int il2p_crc[4] = { 0, 0, 0, 0 }; int pnt_change[5] = { 0 }; float src_buf[5][2048]; diff --git a/ax25_link.h b/ax25_link.h deleted file mode 100644 index 40fa401..0000000 --- a/ax25_link.h +++ /dev/null @@ -1,88 +0,0 @@ - -/* ax25_link.h */ - - -#ifndef AX25_LINK_H -#define AX25_LINK_H 1 - -#include "ax25_pad.h" // for AX25_MAX_INFO_LEN - -#include "dlq.h" // for dlq_item_t - -#include "config.h" // for struct misc_config_s - - - -// Limits and defaults for parameters. - - -#define AX25_N1_PACLEN_MIN 1 // Max bytes in Information part of frame. -#define AX25_N1_PACLEN_DEFAULT 256 // some v2.0 implementations have 128 -#define AX25_N1_PACLEN_MAX AX25_MAX_INFO_LEN // from ax25_pad.h - - -#define AX25_N2_RETRY_MIN 1 // Number of times to retry before giving up. -#define AX25_N2_RETRY_DEFAULT 10 -#define AX25_N2_RETRY_MAX 15 - - -#define AX25_T1V_FRACK_MIN 1 // Number of seconds to wait before retrying. -#define AX25_T1V_FRACK_DEFAULT 3 // KPC-3+ has 4. TM-D710A has 3. -#define AX25_T1V_FRACK_MAX 15 - - -#define AX25_K_MAXFRAME_BASIC_MIN 1 // Window size - number of I frames to send before waiting for ack. -#define AX25_K_MAXFRAME_BASIC_DEFAULT 4 -#define AX25_K_MAXFRAME_BASIC_MAX 7 - -#define AX25_K_MAXFRAME_EXTENDED_MIN 1 -#define AX25_K_MAXFRAME_EXTENDED_DEFAULT 32 -#define AX25_K_MAXFRAME_EXTENDED_MAX 63 // In theory 127 but I'm restricting as explained in SREJ handling. - - - -// Call once at startup time. - -void ax25_link_init (struct misc_config_s *pconfig); - - - -// IMPORTANT: - -// These functions must be called on a single thread, one at a time. -// The Data Link Queue (DLQ) is used to serialize events from multiple sources. - -// Maybe the dispatch switch should be moved to ax25_link.c so they can all -// be made static and they can't be called from the wrong place accidentally. - -void dl_connect_request (dlq_item_t *E); - -void dl_disconnect_request (dlq_item_t *E); - -void dl_data_request (dlq_item_t *E); - -void dl_register_callsign (dlq_item_t *E); - -void dl_unregister_callsign (dlq_item_t *E); - -void dl_outstanding_frames_request (dlq_item_t *E); - -void dl_client_cleanup (dlq_item_t *E); - - -void lm_data_indication (dlq_item_t *E); - -void lm_seize_confirm (dlq_item_t *E); - -void lm_channel_busy (dlq_item_t *E); - - -void dl_timer_expiry (void); - - -double ax25_link_get_next_timer_expiry (void); - - -#endif - -/* end ax25_link.h */ \ No newline at end of file diff --git a/ax25_mod-DESKTOP-MHE5LO8.c b/ax25_mod-DESKTOP-MHE5LO8.c deleted file mode 100644 index 4c803c2..0000000 --- a/ax25_mod-DESKTOP-MHE5LO8.c +++ /dev/null @@ -1,1810 +0,0 @@ -/* -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 - - -#include "UZ7HOStuff.h" - -// I assume this modulates (and sends?} frames - -int RSEncode(UCHAR * bytToRS, UCHAR * RSBytes, int DataLen, int RSLen); - -//unit ax25_mod; - -//interface - -//uses sysutils,classes,math - -extern int SampleNo; - -extern BOOL KISSServ; - -extern TStringList KISS_acked[]; -extern TStringList KISS_iacked[]; - -extern UCHAR modem_mode[]; - -#define sbc 175 - -extern single ch_offset[4]; -int Continuation[4] = { 0, 0, 0, 0 }; // Sending 2nd or more packet of burst - -#define COS45 0.70710676908493f - -#define TX_SILENCE 0 -#define TX_DELAY 1 -#define TX_TAIL 2 -#define TX_NO_DATA 3 -#define TX_FRAME 4 -#define TX_WAIT_BPF 5 - - -#define TX_BIT0 0 -#define TX_BIT1 1 -#define FRAME_EMPTY 0 -#define FRAME_FULL 1 -#define FRAME_NO_FRAME 2 -#define FRAME_NEW_FRAME 3 -#define BYTE_EMPTY 0 -#define BYTE_FULL 1 - - -UCHAR gray_8PSK[8] = {7,0,6,5,2,1,3,4}; // ?? was 1::8 - -UCHAR gray_PI4QPSK[4] = {3,1,5,7}; - - -float audio_buf[5][32768]; // [1..4,0..32767] -float tx_src_BPF_buf[5][32768]; -float tx_BPF_buf[5][32768]; -float tx_prev_BPF_buf[5][32768]; -float tx_BPF_core[5][32768]; - -long tx_delay_cnt[5] = {0}; // : array[1..4] of longword=(0,0,0,0}; -long tx_tail_cnt[5] = {0}; - -int tx_hitoneraisedb[5] = {0}; // : array[1..4] of integer=(0,0,0,0}; -float tx_hitoneraise[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_freq[5] = { 1000, 1000, 1000, 1000, 1000}; // : array[1..4] of single=(1000,1000,1000,1000}; -float tx_shift[5] = { 200, 200, 200, 200, 200}; // : array[1..4] of single=(200,200,200,200}; -float tx_bit_mod[5] = {1, 1, 1, 1, 1}; // : array[1..4] of single=(1,1,1,1}; -float tx_osc[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_bit_osc[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -unsigned short txbpf[5] = { 400, 400, 400, 400, 400}; // : array[1..4] of word=(400,400,400,400}; -unsigned short tx_BPF_tap[5] = { 256, 256, 256, 256, 256}; // : array[1..4] of word=(256,256,256,256}; -unsigned short tx_baudrate[5] = { 300, 300, 300, 300, 300 }; // : array[1..4] of word=(300,300,300,300}; -unsigned short tx_bitrate[5] = { 300, 300, 300, 300, 300 }; // : array[1..4] of word=(300,300,300,300}; -unsigned short tx_BPF_timer[5] = {0}; // : array[1..4] of word=(0,0,0,0}; -UCHAR tx_pol[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_last_pol[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_last_diddle[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_flag_cnt[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_frame_status[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_byte_status[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_status[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_bit_stuff_cnt[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_bit_cnt[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_last_bit[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_bit_stream[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; - -UCHAR tx_8PSK[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; -UCHAR tx_QPSK[5] = {0}; // : array[1..4] of byte=(0,0,0,0}; - -float tx_I_mod[5] = {1, 1, 1, 1, 1}; // : array[1..4] of single=(1,1,1,1}; -float tx_Q_mod[5] = {1, 1, 1, 1, 1}; // : array[1..4] of single=(1,1,1,1}; -float tx_QPSK_avg_I[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_QPSK_avg_Q[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_QPSK_df_I[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_QPSK_df_Q [5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_QPSK_I[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_QPSK_Q[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_QPSK_old_I[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_QPSK_old_Q[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_8PSK_avg_I[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_8PSK_avg_Q[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_8PSK_df_I[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_8PSK_df_Q[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_8PSK_I[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_8PSK_Q[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_8PSK_old_I[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_8PSK_old_Q[5] = {0}; // : array[1..4] of single=(0,0,0,0}; - -float tx_osc1[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_osc2[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_osc3[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -float tx_osc4[5] = {0}; // : array[1..4] of single=(0,0,0,0}; -short tx_inv1[5] = {1, 1, 1, 1, 1}; // : array[1..4] of shortint=(1,1,1,1}; -short tx_inv2[5] = {1, 1, 1, 1, 1}; // : array[1..4] of shortint=(1,1,1,1}; -short tx_inv3[5] = {1, 1, 1, 1, 1}; // : array[1..4] of shortint=(1,1,1,1}; -short tx_inv4[5] = {1, 1, 1, 1, 1}; // : array[1..4] of shortint=(1,1,1,1}; -short tx_old_inv1[5] = {1, 1, 1, 1, 1}; // : array[1..4] of shortint=(1,1,1,1}; -short tx_old_inv2[5] = {1, 1, 1, 1, 1}; // : array[1..4] of shortint=(1,1,1,1}; -short tx_old_inv3[5] = {1, 1, 1, 1, 1}; // : array[1..4] of shortint=(1,1,1,1}; -short tx_old_inv4[5] = {1, 1, 1, 1, 1}; // : array[1..4] of shortint=(1,1,1,1}; -float tx_bit1_mod[5] = {1, 1, 1, 1, 1}; // : array[1..4] of single=(1,1,1,1}; -float tx_bit2_mod[5] = {1, 1, 1, 1, 1}; // : array[1..4] of single=(1,1,1,1}; -float tx_bit3_mod[5] = {1, 1, 1, 1, 1}; // : array[1..4] of single=(1,1,1,1}; -float tx_bit4_mod[5] = {1, 1, 1, 1, 1}; // : array[1..4] of single=(1,1,1,1}; -UINT tx_viterbi[5] = {0}; // : array[1..4] of word=(0,0,0,0}; -UCHAR tx_intv_tbl[5][4]; // : array[1..4,0..3] of byte; - -short tx_inv[5] = {1, 1, 1, 1, 1}; // : array[1..4] of shortint=(1,1,1,1}; -BOOL tx_change_phase[5] = {0}; // : array[1..4] of boolean=(FALSE,FALSE,FALSE,FALSE}; -BOOL tx_bs_bit[5] = {0}; // : array[1..4] of boolean=(FALSE,FALSE,FALSE,FALSE}; - -string * tx_data[5] = {0}; // : array[1..4] of string=('','','',''}; -int tx_data_len[5] = {0}; - -int tx_fx25_size[4] = { 0, 0, 0, 0 }; -int tx_fx25_size_cnt[4] = { 0, 0, 0, 0 }; -int tx_fx25_mode[4] = { 0, 0, 0, 0 }; - - -// uses sm_main,ax25,ax25_agw,ax25_demod,rsunit; - -UCHAR tx_nrzi(UCHAR snd_ch, UCHAR bit) -{ -// Debugprintf("Before NRZI %d", bit); - - if (bit == TX_BIT0) - { - // Zero so switch bit - - tx_last_bit[snd_ch] ^= 1; - } - return tx_last_bit[snd_ch]; -} - -BOOL tx_bit_stuffing(UCHAR snd_ch, UCHAR bit) -{ - // result = FALSE; - // if bit=TX_BIT1 then inc(tx_bit_stuff_cnt[snd_ch]}; - // if bit=TX_BIT0 then tx_bit_stuff_cnt[snd_ch] = 0; - // if tx_bit_stuff_cnt[snd_ch]=5 then begin tx_bit_stuff_cnt[snd_ch] = 0; result = TRUE; end; -//end; - - if (bit == TX_BIT1) - tx_bit_stuff_cnt[snd_ch]++; - - if (bit == TX_BIT0) - tx_bit_stuff_cnt[snd_ch] = 0; - - if (tx_bit_stuff_cnt[snd_ch] == 5) - { - tx_bit_stuff_cnt[snd_ch] = 0; - return TRUE; - } - - return FALSE; -} - - - - -void interleave(char *s, int len) -{ -// var - // data: string; - // i,k,len: word; - // nr_blocks: word; -//begin{ -// data = ''; - // len = length(s}; - // if len>0 then nr_blocks = ((len-1} div 16}+1 else nr_blocks = 1; - // for i = 1 to 16 do - // for k = 0 to nr_blocks-1 do - // if (i+k*16}<=len then data = data+s[i+k*16]; - // result = data; -//end; - - char data[1024]; - - UINT i,k; - UINT nr_blocks; - int n = 0; - - if (len > 0) - nr_blocks = ((len - 1) / 16) + 1; - else - nr_blocks = 1; - - for (i = 0; i < 16; i++) - { - for (k = 0; k < nr_blocks; k++) - { - if ((i + k * 16) <= len) - data[n++] = s[i + k * 16]; - } - } - - memcpy(s, data, len); -} - -//procedure get_new_frame(snd_ch: byte; var frame_stream: TStringList}; -//var -// header,line,temp: string; -// len,i,size: word; - // crc: word; -//begin - -void get_new_frame(UCHAR snd_ch, TStringList * frame_stream) -{ - UCHAR header[256]; - UCHAR line[1024]; - - int LineLen; - - string ** Items; - - string * myTemp; - - UCHAR temp[1024]; - - UINT len, i, size; - UINT crc; - - tx_bs_bit[snd_ch] = FALSE; - tx_bit_cnt[snd_ch] = 0; - tx_flag_cnt[snd_ch] = 0; - tx_bit_stuff_cnt[snd_ch] = 0; - tx_bit_stream[snd_ch] = FRAME_FLAG; - tx_frame_status[snd_ch] = FRAME_NEW_FRAME; - tx_byte_status[snd_ch] = BYTE_EMPTY; - - if (frame_stream->Count == 0) - { - tx_frame_status[snd_ch] = FRAME_NO_FRAME; - return; - } - - // We now pass control byte and ack bytes on front and pointer to socket on end if ackmode - - myTemp = Strings(frame_stream, 0); // get message - - if ((myTemp->Data[0] & 0x0f) == 12) // ACKMODE - { - // Save copy then copy data up 3 bytes - - Add(&KISS_acked[snd_ch], duplicateString(myTemp)); - - mydelete(myTemp, 0, 3); - myTemp->Length -= sizeof(void *); - } - else - { - // Just remove control - - mydelete(myTemp, 0, 1); - } - - tx_data[snd_ch] = duplicateString(myTemp); // so can free original below - - Delete(frame_stream, 0); // This will invalidate temp - - AGW_AX25_frame_analiz(snd_ch, FALSE, tx_data[snd_ch]); - - put_frame(snd_ch, tx_data[snd_ch], "", TRUE, FALSE); - - if (tx_data[snd_ch]->Length == 0 || modem_mode[snd_ch] != MODE_MPSK) - return; - - // Reformat MPSK Data - - //Take data 8 bytes at a time and add 8 bytes of RS data - - LineLen = 0; - - while (tx_data[snd_ch]->Length > 0) - { - size = tx_data[snd_ch]->Length; - - if (size > 8) - size = 8; - - memcpy(temp, tx_data[snd_ch]->Data, size); - - // Delete the chars from tx_data - - mydelete(tx_data[snd_ch], 0, 8); - - memset(xData, 0, sizeof(xData)); - memset(xEncoded, 0, sizeof(xEncoded)); - - memcpy(xData, temp, size); - - InitBuffers(); - EncodeRS(xData, xEncoded); // This puts the 8 RS bytes in xEncoded - - memcpy(&line[LineLen], xData, size); - memcpy(&line[LineLen + size], xEncoded, MaxErrors * 2); - - LineLen += size + (MaxErrors * 2); - } - - - - - len = LineLen; - - interleave(line, LineLen); - scrambler(line, LineLen); - - header[0] = 0x7e; - header[1] = 0x7e; - header[2] = len >> 8; - header[3] = len; - - crc = get_fcs(header, 4); - - header[4] = crc >> 8; - header[5] = crc; - - memset(xData, 0, sizeof(xData)); - memset(xEncoded, 0, sizeof(xEncoded)); - memmove(xData, header, 6); - - - // RSEncode(xData, xEncoded, 6 + (MaxErrors * 2), MaxErrors * 2); - - InitBuffers(); - EncodeRS(xData, xEncoded); - - fx25_encode_rs(xData, xEncoded, 0, 8); - - - // We should now have RS Encoded Header in xEncoded; - - // I think we send encoded header then line - - tx_data[snd_ch]->Length = 0; - - stringAdd(tx_data[snd_ch], xData, 6); - stringAdd(tx_data[snd_ch], xEncoded, MaxErrors * 2); - stringAdd(tx_data[snd_ch], line, LineLen); - - // For testing, descramble and de-interleve - - scrambler(line, LineLen); // should look like interleaved - { - Byte unscrambled[1024]; - int count, len; - int origlen; - - len = LineLen; - count = (len + 15) / 16; - - int j1, j2, j3, i, j; - - j3 = 0; - - for (j1 = 0; j1 < 16; j1++) - { - // Each char in block - - for (j2 = 0; j2 < count; j2++) - { - // Blocks - - unscrambled[j2 * 16 + j1] = line[j3]; - j3++; - } - } - - // Now remove RS (will check later) - - i = 0; - j = 0; - - while (j < len) - { - Byte line1[256]; - int nErr, eras_pos = 0; - Byte rs_block[256]; - - memcpy(line1, &unscrambled[j], 16); - - memset(xEncoded, 0, sizeof(xEncoded)); - memset(xDecoded, 0, sizeof(xDecoded)); - - memcpy(xEncoded, &unscrambled[j], 16); - -// nErr = DecodeRS(xEncoded, xDecoded); - - memset(rs_block, 0, 255); - memcpy(rs_block, &unscrambled[j], 8); - memcpy(&rs_block[255 - 8], &unscrambled[j+8], 8); - - nErr = fx25_decode_rs(rs_block, &eras_pos, 0, 0, 8); - - -// line1 = ''; -// for j1 = MaxErrors * 2 to size - 1 do line1 = line1 + chr(xDecoded[j1]); - - - memcpy(&unscrambled[i], &unscrambled[j], 8); - i += 8; - j += 16; - } - - j3 = j3; - - } - -} - - - -int get_new_bit(Byte snd_ch, Byte bit) -{ - unsigned short len; - string * s; - - if (tx_frame_status[snd_ch] == FRAME_FULL) - { - if (tx_byte_status[snd_ch] == BYTE_EMPTY) - { - len = tx_data[snd_ch]->Length; - - if (len > 0) - { - s = tx_data[snd_ch]; - tx_bit_stream[snd_ch] = (s->Data[0]); - tx_frame_status[snd_ch] = FRAME_FULL; - tx_byte_status[snd_ch] = BYTE_FULL; - tx_bit_cnt[snd_ch] = 0; - mydelete(tx_data[snd_ch], 0, 1); - } - - else tx_frame_status[snd_ch] = FRAME_EMPTY; - } - - if (tx_byte_status[snd_ch] == BYTE_FULL) - bit = tx_bit_stream[snd_ch] & TX_BIT1; - - if (modem_mode[snd_ch] == MODE_MPSK) - { - tx_bit_cnt[snd_ch]++; - tx_bit_stream[snd_ch] = tx_bit_stream[snd_ch] >> 1; - if (tx_bit_cnt[snd_ch] >= 8) - tx_byte_status[snd_ch] = BYTE_EMPTY; - - } - else - { - if (tx_bs_bit[snd_ch]) - bit = TX_BIT0; - - tx_bs_bit[snd_ch] = tx_bit_stuffing(snd_ch, bit); - - if (!tx_bs_bit[snd_ch]) - { - tx_bit_cnt[snd_ch]++; - tx_bit_stream[snd_ch] >>= 1; - if (tx_bit_cnt[snd_ch] >= 8 && !tx_bs_bit[snd_ch]) - tx_byte_status[snd_ch] = BYTE_EMPTY; - } - } - } - - if (tx_frame_status[snd_ch] == FRAME_EMPTY) - get_new_frame(snd_ch, &all_frame_buf[snd_ch]); - - if ((tx_frame_status[snd_ch] == FRAME_NEW_FRAME) || (tx_frame_status[snd_ch] == FRAME_NO_FRAME)) - { - bit = tx_bit_stream[snd_ch] & TX_BIT1; - tx_flag_cnt[snd_ch]++; - tx_bit_stream[snd_ch] >>= 1; - - if (tx_flag_cnt[snd_ch] == 8) - { - switch (tx_frame_status[snd_ch]) - { - case FRAME_NEW_FRAME: - - tx_frame_status[snd_ch] = FRAME_FULL; - break; - - case FRAME_NO_FRAME: - - tx_tail_cnt[snd_ch] = 0; - tx_frame_status[snd_ch] = FRAME_EMPTY; - tx_status[snd_ch] = TX_TAIL; - - break; - } - } - } - return bit; -} - -////// FX.25 ////// - - -void bit_to_fx25(Byte * tx_byte, Byte * bit_cnt, Byte bit, string * data, int * data_cnt) -{ - *tx_byte = (*tx_byte >> 1) | (bit << 7); - (*bit_cnt)++; - - if (*bit_cnt == 8) - { - stringAdd(data, tx_byte, 1); - *bit_cnt = 0; - } - (*data_cnt)++; -} - -string * fill_fx25_data(int snd_ch, string * data) -{ -#define nr_tags 5 - - string * result; - - Byte rs_roots[nr_tags + 1] = { 16, 32, 64, 32, 16, 16 }; - word rs_payload[nr_tags + 1] = { 1912, 1784, 1528, 1024, 512, 256 }; // 239, 233, 191, 128, 64, 32 - - unsigned long long rs_tag[nr_tags + 1] = - { - 0xB74DB7DF8A532F3E, // 255 / 16 (239) - 0x6E260B1AC5835FAE, // 255 / 32 (223) - 0x3ADB0C13DEAE2836, // 255 / 64 (191) - 0xFF94DC634F1CFF4E, // 160 / 32 (128) - 0xC7DC0508F3D9B09E, // 80 / 16 (64) - 0x8F056EB4369660EE // 48 / 16 (32) - }; - -// 0x26FF60A600CC8FDE) 144; = 16; -// 0x1EB7B9CDBC09C00E) 96; 32; -// 0xDBF869BD2DBB1776) 64;= 32; -// 0xAB69DB6A543188D6) 192; = 64; -// 0x4A4ABEC4A724B796) 128; = 64; - - string * ax25_data = newString(); - - int i, ax25_size; - Byte a, bit, bit_cnt, bit_cnt1, bs, tx_byte; - Byte rs_id; - Byte rs_block[256], parity[256]; - - ax25_size = 0; - bs = 0; - tx_byte = 0; - bit_cnt = 0; - - // Load start flag - a = FRAME_FLAG; - - for (i = 0; i < 8; i++) - { - bit = a & 1; - a = a >> 1; - bit_to_fx25(&tx_byte, &bit_cnt, bit, ax25_data, &ax25_size); - } - - // Load body - for (i = 0; i < data->Length; i++) - { - bit_cnt1 = 0; - a = data->Data[i]; - do - { - if (bs == 5) - { - bit = TX_BIT0; - bs = 0; - } - else - { - bit = a & 1; - a = a >> 1; - bit_cnt1++; - - if (bit == TX_BIT1) - bs++; - else - bs = 0; - } - - bit_to_fx25(&tx_byte, &bit_cnt, bit, ax25_data, &ax25_size); - - } while (bit_cnt1 != 8 || bs == 5); - } - - // Load close flag - - a = FRAME_FLAG; - - for (i = 0; i < 8; i++) - { - bit = a & 1; - a = a >> 1; - bit_to_fx25(&tx_byte, &bit_cnt, bit, ax25_data, &ax25_size); - } - - a = FRAME_FLAG; - - // if too short or too long - - if (ax25_size < 168 || ax25_size > 1912) // < 21 or > 239 - { - // Send as normal ax25 packet - - if (bit_cnt > 0) - { - do - { - tx_byte = tx_byte >> 1; - bit_cnt++; - if (bit_cnt == 8) - stringAdd(ax25_data, &tx_byte, 1); - } while (bit_cnt < 8); - } - tx_fx25_size[snd_ch] = ax25_size; - return ax25_data; - } - - // Send as FX25 Message - - // find RS block size - - rs_id = 0; - - for (i = 0; i <= nr_tags; i++) - if (ax25_size <= rs_payload[i]) - rs_id = i; - - // Padding to block size - - while (ax25_size != rs_payload[rs_id]) - { - bit = a & 1; - a = (a >> 1) | (bit << 7); - bit_to_fx25(&tx_byte, &bit_cnt, bit, ax25_data, &ax25_size); - } - - memset(rs_block, 0, 255); - move(&ax25_data->Data[0], &rs_block[0], ax25_data->Length); - - fx25_encode_rs(rs_block, parity, 0, rs_roots[rs_id]); - - result = newString(); - - stringAdd(result, (Byte *)&rs_tag[rs_id], 8); - stringAdd(result, ax25_data->Data, ax25_data->Length); - stringAdd(result, parity, rs_roots[rs_id]); - - tx_fx25_size[snd_ch] = result->Length << 3; - - freeString(ax25_data); - return result; -} - -void fx25_get_new_frame(int snd_ch, TStringList * frame_stream) -{ - string * myTemp; - - tx_bs_bit[snd_ch] = 0; - tx_bit_cnt[snd_ch] = 0; - tx_flag_cnt[snd_ch] = 0; - tx_bit_stuff_cnt[snd_ch] = 0; - tx_fx25_size_cnt[snd_ch] = 0; - tx_fx25_size[snd_ch] = 1; - tx_frame_status[snd_ch] = FRAME_NEW_FRAME; - tx_byte_status[snd_ch] = BYTE_EMPTY; - if (frame_stream->Count == 0) - tx_frame_status[snd_ch] = FRAME_NO_FRAME; - else - { - // We now pass control byte and ack bytes on front and pointer to socket on end if ackmode - - myTemp = Strings(frame_stream, 0); // get message - - if ((myTemp->Data[0] & 0x0f) == 12) // ACKMODE - { - // Save copy then copy data up 3 bytes - - Add(&KISS_acked[snd_ch], duplicateString(myTemp)); - - mydelete(myTemp, 0, 3); - myTemp->Length -= sizeof(void *); - } - else - { - // Just remove control - - mydelete(myTemp, 0, 1); - } - - AGW_AX25_frame_analiz(snd_ch, FALSE, myTemp); - put_frame(snd_ch, myTemp, "", TRUE, FALSE); - - tx_data[snd_ch] = fill_fx25_data(snd_ch, myTemp); - - Delete(frame_stream, 0); // This will invalidate temp - } -} - -int fx25_get_new_bit(int snd_ch, Byte bit) -{ - string *s; - - if (tx_frame_status[snd_ch] == FRAME_EMPTY) - { - fx25_get_new_frame(snd_ch, &all_frame_buf[snd_ch]); - if (tx_frame_status[snd_ch] == FRAME_NEW_FRAME) - tx_frame_status[snd_ch] = FRAME_FULL; - } - - if (tx_frame_status[snd_ch] == FRAME_FULL) - { - if (tx_byte_status[snd_ch] == BYTE_EMPTY) - { - if (tx_data[snd_ch]->Length) - { - s = tx_data[snd_ch]; - - tx_bit_stream[snd_ch] = s->Data[0]; - tx_frame_status[snd_ch] = FRAME_FULL; - tx_byte_status[snd_ch] = BYTE_FULL; - tx_bit_cnt[snd_ch] = 0; - mydelete(tx_data[snd_ch], 0, 1); - } - else - tx_frame_status[snd_ch] = FRAME_EMPTY; - } - if (tx_byte_status[snd_ch] == BYTE_FULL) - { - bit = tx_bit_stream[snd_ch] & TX_BIT1; - tx_bit_stream[snd_ch] = tx_bit_stream[snd_ch] >> 1; - tx_bit_cnt[snd_ch]++; - tx_fx25_size_cnt[snd_ch]++; - if (tx_bit_cnt[snd_ch] >= 8) - tx_byte_status[snd_ch] = BYTE_EMPTY; - if (tx_fx25_size_cnt[snd_ch] == tx_fx25_size[snd_ch]) - tx_frame_status[snd_ch] = FRAME_EMPTY; - } - } - - if (tx_frame_status[snd_ch] == FRAME_EMPTY) - { - fx25_get_new_frame(snd_ch, &all_frame_buf[snd_ch]); - - switch (tx_frame_status[snd_ch]) - { - case FRAME_NEW_FRAME: - tx_frame_status[snd_ch] = FRAME_FULL; - break; - - case FRAME_NO_FRAME: - tx_tail_cnt[snd_ch] = 0; - tx_frame_status[snd_ch] = FRAME_EMPTY; - tx_status[snd_ch] = TX_TAIL; - break; - } - } - return bit; -} - - -////////////////// - - -int get_new_bit_tail(UCHAR snd_ch, UCHAR bit) -{ - long _txtail = 0; - UCHAR _diddles; - - if (modem_mode[snd_ch] == MODE_FSK) - _diddles = diddles; - else - _diddles = 0; - - if (modem_mode[snd_ch] == MODE_FSK) - _txtail = txtail[snd_ch]; - - else if (modem_mode[snd_ch] == MODE_BPSK) - _txtail = txtail[snd_ch]; - - else if (modem_mode[snd_ch] == MODE_8PSK) - _txtail = txtail[snd_ch] * 3; - - else if (modem_mode[snd_ch] == MODE_QPSK || modem_mode[snd_ch] == MODE_PI4QPSK) - _txtail = txtail[snd_ch] << 1; - - else if (modem_mode[snd_ch] == MODE_MPSK) - _txtail = txtail[snd_ch] << 2; - - _txtail = (_txtail * tx_baudrate[snd_ch]) / 1000; - - if (qpsk_set[snd_ch].mode == QPSK_V26 || modem_mode[snd_ch] == MODE_8PSK) - _diddles = 2; - - switch (_diddles) - { - case 0: - - if (tx_tail_cnt[snd_ch] < _txtail) - { - bit = TX_BIT0; - tx_tail_cnt[snd_ch]++; - } - else - { - tx_status[snd_ch] = TX_WAIT_BPF; - } - - break; - - case 1: - - if (tx_tail_cnt[snd_ch] < _txtail) - { - if (tx_last_diddle[snd_ch] == TX_BIT0) - bit = TX_BIT1; - else - bit = TX_BIT0; - - tx_tail_cnt[snd_ch]++; - tx_last_diddle[snd_ch] = bit; - } - else - { - Debugprintf("End TXTAIL %d", SampleNo); - tx_status[snd_ch] = TX_WAIT_BPF; - } - - break; - - case 2: - - if (tx_tail_cnt[snd_ch] < _txtail) - { - bit = FRAME_FLAG >> (tx_tail_cnt[snd_ch] % 8) & 1; - tx_tail_cnt[snd_ch]++; - } - else - { - Debugprintf("End TXTAIL %d", SampleNo); - tx_status[snd_ch] = TX_WAIT_BPF; - } - break; - } - return bit; -} - -int get_new_bit_delay(UCHAR snd_ch, UCHAR bit) -{ - ULONG _txdelay = 0; - UCHAR _diddles; - - _diddles = 0; - - switch (modem_mode[snd_ch]) - { - case MODE_FSK: - - _diddles = diddles; - break; - - case MODE_PI4QPSK: - case MODE_8PSK: - - _diddles = 2; - break; - - case MODE_QPSK: - - if (qpsk_set[snd_ch].mode == QPSK_V26) - _diddles = 2; - break; - } - - if (modem_mode[snd_ch] == MODE_FSK) - _txdelay = txdelay[snd_ch]; - - else if (modem_mode[snd_ch] == MODE_BPSK) - _txdelay = txdelay[snd_ch]; - - else if (modem_mode[snd_ch] == MODE_8PSK) - _txdelay = txdelay[snd_ch] * 3; - - else if (modem_mode[snd_ch] == MODE_QPSK || modem_mode[snd_ch] == MODE_PI4QPSK) - _txdelay = txdelay[snd_ch] << 1; - - else if (modem_mode[snd_ch] == MODE_MPSK) - { - if (txdelay[snd_ch] < 400) - _txdelay = 400 << 2; //AFC delay - else - _txdelay = txdelay[snd_ch] << 2; - } - - _txdelay = (_txdelay * tx_baudrate[snd_ch]) / 1000; - - switch (_diddles) - { - case 0: - - if (tx_delay_cnt[snd_ch] < _txdelay) - { - bit = TX_BIT0; - tx_delay_cnt[snd_ch]++; - } - else - { - tx_status[snd_ch] = TX_FRAME; - } - - break; - - case 1: - - if (tx_delay_cnt[snd_ch] < _txdelay) - { - if (tx_last_diddle[snd_ch] == TX_BIT0) - bit = TX_BIT1; - else - bit = TX_BIT0; - - tx_delay_cnt[snd_ch]++; - tx_last_diddle[snd_ch] = bit; - } - else - { - tx_status[snd_ch] = TX_FRAME; - Debugprintf("End TXD %d", SampleNo); - } - break; - - case 2: - - // Send Flags - - if (tx_delay_cnt[snd_ch] < _txdelay) - { - bit = FRAME_FLAG >> ((8 - (_txdelay % 8) + tx_delay_cnt[snd_ch]) % 8) & 1; - tx_delay_cnt[snd_ch]++; - } - else - { - tx_status[snd_ch] = TX_FRAME; - Debugprintf("End TXD %d", SampleNo); - } - break; - } - return bit; -} - -// is this waiting for the filter to fill? -// No, flushing BPF - -void get_wait_bpf(UCHAR snd_ch) -{ - tx_BPF_timer[snd_ch]++; - - if (tx_BPF_timer[snd_ch] == tx_BPF_tap[snd_ch] ) - { - tx_status[snd_ch] = TX_NO_DATA; - tx_BPF_timer[snd_ch] = 0; - } -} - - -//procedure modulator(snd_ch: byte; var buf: array of single; buf_size: word}; -//{ -/* -function filter(x,k: single}: single; -begin - result = k*cos(x}; - if result>1 then result = 1; - if result<-1 then result = -1; -end; -} -*/ - -single filter(single x) -{ - if (x <= PI25) - return 1.0f; - - if (x >= PI75) - return -1.0f; - - return cosf(2.0f * x -PI5); -} - - -// make_samples return one sample of the waveform - -// But seems to be called only once per bit ?? - -// No, but needs to preserve bit between calls - -float make_samples(unsigned char snd_ch, unsigned char * bitptr) -{ - float pi2, x1, x; - Byte i,qbit,tribit,dibit; - float z1,z2,z3,z4; - unsigned short b, msb, lsb; - unsigned char bit = *bitptr; - - float amp = 0; - - pi2 = 2 * pi / TX_Samplerate; - x1 = pi * tx_baudrate[snd_ch] / TX_Samplerate; - - if (modem_mode[snd_ch] == MODE_FSK) - { - if (bit == TX_BIT0) - x = pi2*(tx_freq[snd_ch] + 0.5f * tx_shift[snd_ch]); - else - x = pi2*(tx_freq[snd_ch] - 0.5f * tx_shift[snd_ch]); - - amp = 1.0f; - - if (tx_baudrate[snd_ch] > 600) - { - if (tx_hitoneraisedb[snd_ch] < 0 && bit == TX_BIT0) - amp = tx_hitoneraise[snd_ch]; - - if (tx_hitoneraisedb[snd_ch] > 0 && bit == TX_BIT1) - amp = tx_hitoneraise[snd_ch]; - } - - tx_osc[snd_ch] = tx_osc[snd_ch] + x; - - if (tx_osc[snd_ch] > 2*pi) - tx_osc[snd_ch] = tx_osc[snd_ch] - 2*pi; - } - - else if (modem_mode[snd_ch] == MODE_BPSK) - { - if (tx_change_phase[snd_ch]) - tx_bit_mod[snd_ch] = tx_inv[snd_ch] * cos(tx_bit_osc[snd_ch]); - - x = pi2 * (tx_freq[snd_ch]); - - tx_osc[snd_ch] = tx_osc[snd_ch] + x; - - if (tx_osc[snd_ch] > 2 * pi) - tx_osc[snd_ch] = tx_osc[snd_ch] - 2 * pi; - } - - else if (modem_mode[snd_ch] == MODE_QPSK) - { - if (tx_QPSK_old_I[snd_ch] != tx_QPSK_I[snd_ch]) - - tx_I_mod[snd_ch] = tx_QPSK_avg_I[snd_ch] + tx_QPSK_df_I[snd_ch] * filter(tx_bit_osc[snd_ch]); - else - tx_I_mod[snd_ch] = tx_QPSK_I[snd_ch]; - - if (tx_QPSK_old_Q[snd_ch] != tx_QPSK_Q[snd_ch]) - tx_Q_mod[snd_ch] = tx_QPSK_avg_Q[snd_ch] + tx_QPSK_df_Q[snd_ch] * filter(tx_bit_osc[snd_ch]); - else - tx_Q_mod[snd_ch] = tx_QPSK_Q[snd_ch]; - - x = pi2 * (tx_freq[snd_ch]); - tx_osc[snd_ch] = tx_osc[snd_ch] + x; - if (tx_osc[snd_ch] > 2 * pi) - tx_osc[snd_ch] = tx_osc[snd_ch] - 2 * pi; - } - - else if (modem_mode[snd_ch] == MODE_8PSK || modem_mode[snd_ch] == MODE_PI4QPSK) - { - if (tx_8PSK_old_I[snd_ch] != tx_8PSK_I[snd_ch]) - tx_I_mod[snd_ch] = tx_8PSK_avg_I[snd_ch] + tx_8PSK_df_I[snd_ch] * filter(tx_bit_osc[snd_ch]); - else - tx_I_mod[snd_ch] = tx_8PSK_I[snd_ch]; - - if (tx_8PSK_old_Q[snd_ch] != tx_8PSK_Q[snd_ch]) - tx_Q_mod[snd_ch] = tx_8PSK_avg_Q[snd_ch] + tx_8PSK_df_Q[snd_ch] * filter(tx_bit_osc[snd_ch]); - else - tx_Q_mod[snd_ch] = tx_8PSK_Q[snd_ch]; - - x = pi2 * (tx_freq[snd_ch]); - tx_osc[snd_ch] = tx_osc[snd_ch] + x; - - if (tx_osc[snd_ch] > 2 * pi) - tx_osc[snd_ch] = tx_osc[snd_ch] - 2 * pi; - - } - - else if (modem_mode[snd_ch] == MODE_MPSK) - { - z1 = pi2 * (tx_freq[snd_ch] + ch_offset[0]); - z2 = pi2 * (tx_freq[snd_ch] + ch_offset[1]); - z3 = pi2 * (tx_freq[snd_ch] + ch_offset[2]); - z4 = pi2 * (tx_freq[snd_ch] + ch_offset[3]); - - tx_osc1[snd_ch] = tx_osc1[snd_ch] + z1; - tx_osc2[snd_ch] = tx_osc2[snd_ch] + z2; - tx_osc3[snd_ch] = tx_osc3[snd_ch] + z3; - tx_osc4[snd_ch] = tx_osc4[snd_ch] + z4; - - if (tx_osc1[snd_ch] > 2 * pi) - tx_osc1[snd_ch] = tx_osc1[snd_ch] - 2 * pi; - - if (tx_osc2[snd_ch] > 2 * pi) - tx_osc2[snd_ch] = tx_osc2[snd_ch] - 2 * pi; - - if (tx_osc3[snd_ch] > 2 * pi) - tx_osc3[snd_ch] = tx_osc3[snd_ch] - 2 * pi; - - if (tx_osc4[snd_ch] > 2 * pi) - tx_osc4[snd_ch] = tx_osc4[snd_ch] - 2 * pi; - - if (tx_old_inv1[snd_ch] != tx_inv1[snd_ch]) - tx_bit1_mod[snd_ch] = tx_inv1[snd_ch] * cos(tx_bit_osc[snd_ch]); - else - tx_bit1_mod[snd_ch] = -tx_inv1[snd_ch]; - - if (tx_old_inv2[snd_ch] != tx_inv2[snd_ch]) - tx_bit2_mod[snd_ch] = tx_inv2[snd_ch] * cos(tx_bit_osc[snd_ch]); - else - tx_bit2_mod[snd_ch] = -tx_inv2[snd_ch]; - - if (tx_old_inv3[snd_ch] != tx_inv3[snd_ch]) - tx_bit3_mod[snd_ch] = tx_inv3[snd_ch] * cos(tx_bit_osc[snd_ch]); - else - tx_bit3_mod[snd_ch] = -tx_inv3[snd_ch]; - - if (tx_old_inv4[snd_ch] != tx_inv4[snd_ch]) - tx_bit4_mod[snd_ch] = tx_inv4[snd_ch] * cos(tx_bit_osc[snd_ch]); - else - tx_bit4_mod[snd_ch] = -tx_inv4[snd_ch]; - } - - tx_bit_osc[snd_ch] = tx_bit_osc[snd_ch] + x1; - - if (tx_bit_osc[snd_ch] > pi) - { - // This seems to get the next bit, - // but why?? - end of samples for last bit - - tx_bit_osc[snd_ch] = tx_bit_osc[snd_ch] - pi; - - // FSK Mode - if (modem_mode[snd_ch] == MODE_FSK) - { - bit = 0; - - if (tx_status[snd_ch] == TX_SILENCE) - { - tx_delay_cnt[snd_ch] = 0; - tx_status[snd_ch] = TX_DELAY; - } - - if (il2p_mode[snd_ch] >= IL2P_MODE_TXRX) - { - // il2p generates TXDELAY as part of the frame, so go straight to TX_FRAME - - if (tx_status[snd_ch] == TX_DELAY) - tx_status[snd_ch] = TX_FRAME; - - if (tx_status[snd_ch] == TX_TAIL) - bit = get_new_bit_tail(snd_ch, bit); - - if (tx_status[snd_ch] == TX_FRAME) - bit = il2p_get_new_bit(snd_ch, bit); - - - // No nrzi for il2p - - *bitptr = bit; - } - else - { - // ax25/fx25 - - if (tx_status[snd_ch] == TX_DELAY) - bit = get_new_bit_delay(snd_ch, bit); - - if (tx_status[snd_ch] == TX_TAIL) - bit = get_new_bit_tail(snd_ch, bit); - - if (tx_status[snd_ch] == TX_FRAME) - { - if (tx_fx25_mode[snd_ch]) - bit = fx25_get_new_bit(snd_ch, bit); - else - bit = get_new_bit(snd_ch, bit); - } - - *bitptr = tx_nrzi(snd_ch, bit); - - } - } - - // BPSK Mode - if (modem_mode[snd_ch] == MODE_BPSK) - { - bit = 0; - - if (tx_status[snd_ch] == TX_SILENCE) - { - tx_delay_cnt[snd_ch] = 0; - Debugprintf("Start TXD"); - tx_status[snd_ch] = TX_DELAY; - } - - - - // il2p generates TXDELAY as part of the frame, so go straight too TX_FRAME - - if (tx_status[snd_ch] == TX_DELAY) - if (il2p_mode[snd_ch] >= IL2P_MODE_TXRX) - tx_status[snd_ch] = TX_FRAME; - else - bit = get_new_bit_delay(snd_ch, bit); - - if (tx_status[snd_ch] == TX_TAIL) - bit = get_new_bit_tail(snd_ch, bit); - - if (tx_status[snd_ch] == TX_FRAME) - { - if (il2p_mode[snd_ch] >= IL2P_MODE_TXRX) - bit = il2p_get_new_bit(snd_ch, bit); - else if (tx_fx25_mode[snd_ch]) - bit = fx25_get_new_bit(snd_ch, bit); - else - bit = get_new_bit(snd_ch, bit); - } - // ?? *bitptr = tx_nrzi(snd_ch, bit); - - if (bit == 0) - { - tx_inv[snd_ch] = -tx_inv[snd_ch]; - tx_change_phase[snd_ch] = TRUE; - } - else - tx_change_phase[snd_ch] = FALSE; - } - - // QPSK Mode - - else if (modem_mode[snd_ch] == MODE_QPSK) - { - dibit = 0; - for (i = 0; i < 2; i++) - { - bit = 0; - if (tx_status[snd_ch] == TX_SILENCE) - { - tx_delay_cnt[snd_ch] = 0; - tx_status[snd_ch] = TX_DELAY; - } - - if (il2p_mode[snd_ch] >= IL2P_MODE_TXRX) - { - if (tx_status[snd_ch] == TX_DELAY) - tx_status[snd_ch] = TX_FRAME; // il2p generates TXDELAY as part of the frame, so go straight to TX_FRAME - - if (tx_status[snd_ch] == TX_TAIL) - bit = get_new_bit_tail(snd_ch, bit); - - if (tx_status[snd_ch] == TX_FRAME) - bit = il2p_get_new_bit(snd_ch, bit); - - // No nrzi for il2p - - dibit = (dibit << 1) | bit; - } - else - { - // ax25/fx25 - - if (tx_status[snd_ch] == TX_DELAY) - bit = get_new_bit_delay(snd_ch, bit); - if (tx_status[snd_ch] == TX_TAIL) - bit = get_new_bit_tail(snd_ch, bit); - if (tx_status[snd_ch] == TX_FRAME) - bit = get_new_bit(snd_ch, bit); - dibit = (dibit << 1) | tx_nrzi(snd_ch, bit); - - } - } - - - dibit = qpsk_set[snd_ch].tx[dibit & 3]; - tx_QPSK[snd_ch] = (tx_QPSK[snd_ch] + dibit) & 3; - tx_QPSK_old_I[snd_ch] = tx_QPSK_I[snd_ch]; - tx_QPSK_old_Q[snd_ch] = tx_QPSK_Q[snd_ch]; - - switch (tx_QPSK[snd_ch]) - { - case 0: - - tx_QPSK_I[snd_ch] = COS45; - tx_QPSK_Q[snd_ch] = COS45; - break; - - case 1: - - tx_QPSK_I[snd_ch] = -COS45; - tx_QPSK_Q[snd_ch] = COS45; - break; - - case 2: - - tx_QPSK_I[snd_ch] = -COS45; - tx_QPSK_Q[snd_ch] = -COS45; - break; - - case 3: - - tx_QPSK_I[snd_ch] = COS45; - tx_QPSK_Q[snd_ch] = -COS45; - break; - } - - tx_QPSK_avg_I[snd_ch] = 0.5f*(tx_QPSK_old_I[snd_ch] + tx_QPSK_I[snd_ch]); - tx_QPSK_df_I[snd_ch] = 0.5f*(tx_QPSK_old_I[snd_ch] - tx_QPSK_I[snd_ch]); - tx_QPSK_avg_Q[snd_ch] = 0.5f*(tx_QPSK_old_Q[snd_ch] + tx_QPSK_Q[snd_ch]); - tx_QPSK_df_Q[snd_ch] = 0.5f*(tx_QPSK_old_Q[snd_ch] - tx_QPSK_Q[snd_ch]); - } - - // PI/4 QPSK Mode - - if (modem_mode[snd_ch] == MODE_PI4QPSK) - { - dibit = 0; - - for (i = 0; i < 2; i++) - { - bit = 0; - if (tx_status[snd_ch] == TX_SILENCE) - { - tx_delay_cnt[snd_ch] = 0; - Debugprintf("Start TXD"); - tx_status[snd_ch] = TX_DELAY; - } - - if (il2p_mode[snd_ch] >= IL2P_MODE_TXRX) - { - if (tx_status[snd_ch] == TX_DELAY) - tx_status[snd_ch] = TX_FRAME; // il2p generates TXDELAY as part of the frame, so go straight to TX_FRAME - - if (tx_status[snd_ch] == TX_TAIL) - bit = get_new_bit_tail(snd_ch, bit); - - if (tx_status[snd_ch] == TX_FRAME) - bit = il2p_get_new_bit(snd_ch, bit); - - // No nrzi for il2p - - dibit = (dibit << 1) | bit; - } - else - { - // ax25/fx25 - - if (tx_status[snd_ch] == TX_DELAY) - bit = get_new_bit_delay(snd_ch, bit); - - if (tx_status[snd_ch] == TX_TAIL) - bit = get_new_bit_tail(snd_ch, bit); - - if (tx_status[snd_ch] == TX_FRAME) - bit = get_new_bit(snd_ch, bit); - - *bitptr = tx_nrzi(snd_ch, bit); - - dibit = (dibit << 1) | *bitptr; - } - } - - // This returns 3,1,5 or 7 so we use the odd enties in the 8PSK table - - dibit = gray_PI4QPSK[dibit & 3]; - - tx_8PSK[snd_ch] = (tx_8PSK[snd_ch] + dibit) & 7; - tx_8PSK_old_I[snd_ch] = tx_8PSK_I[snd_ch]; - tx_8PSK_old_Q[snd_ch] = tx_8PSK_Q[snd_ch]; - - switch (tx_8PSK[snd_ch]) - { - case 0: - tx_8PSK_I[snd_ch] = 0; - tx_8PSK_Q[snd_ch] = 1; - break; - - case 1: - tx_8PSK_I[snd_ch] = COS45; - tx_8PSK_Q[snd_ch] = COS45; - break; - - case 2: - tx_8PSK_I[snd_ch] = 1; - tx_8PSK_Q[snd_ch] = 0; - break; - - case 3: - tx_8PSK_I[snd_ch] = COS45; - tx_8PSK_Q[snd_ch] = -COS45; - break; - - case 4: - tx_8PSK_I[snd_ch] = 0; - tx_8PSK_Q[snd_ch] = -1; - break; - - case 5: - tx_8PSK_I[snd_ch] = -COS45; - tx_8PSK_Q[snd_ch] = -COS45; - break; - - case 6: - tx_8PSK_I[snd_ch] = -1; - tx_8PSK_Q[snd_ch] = 0; - break; - - case 7: - tx_8PSK_I[snd_ch] = -COS45; - tx_8PSK_Q[snd_ch] = COS45; - break; - - } - - tx_8PSK_avg_I[snd_ch] = 0.5*(tx_8PSK_old_I[snd_ch] + tx_8PSK_I[snd_ch]); - tx_8PSK_df_I[snd_ch] = 0.5*(tx_8PSK_old_I[snd_ch] - tx_8PSK_I[snd_ch]); - tx_8PSK_avg_Q[snd_ch] = 0.5*(tx_8PSK_old_Q[snd_ch] + tx_8PSK_Q[snd_ch]); - tx_8PSK_df_Q[snd_ch] = 0.5*(tx_8PSK_old_Q[snd_ch] - tx_8PSK_Q[snd_ch]); - - } - - // 8PSK Mode - - if (modem_mode[snd_ch] == MODE_8PSK) - { - tribit = 0; - for (i = 0; i < 3; i++) - { - bit = 0; - - if (tx_status[snd_ch] == TX_SILENCE) - { - tx_delay_cnt[snd_ch] = 0; - tx_status[snd_ch] = TX_DELAY; - } - - if (il2p_mode[snd_ch] >= IL2P_MODE_TXRX) - { - if (tx_status[snd_ch] == TX_DELAY) - tx_status[snd_ch] = TX_FRAME; // il2p generates TXDELAY as part of the frame, so go straight to TX_FRAME - - if (tx_status[snd_ch] == TX_TAIL) - bit = get_new_bit_tail(snd_ch, bit); - - if (tx_status[snd_ch] == TX_FRAME) - bit = il2p_get_new_bit(snd_ch, bit); - - // No nrzi for il2p - - tribit = (tribit << 1) | bit; - } - else - { - // ax25/fx25 - - if (tx_status[snd_ch] == TX_DELAY) - bit = get_new_bit_delay(snd_ch, bit); - if (tx_status[snd_ch] == TX_TAIL) - bit = get_new_bit_tail(snd_ch, bit); - if (tx_status[snd_ch] == TX_FRAME) - bit = get_new_bit(snd_ch, bit); - - tribit = (tribit << 1) | tx_nrzi(snd_ch, bit); - } - } - tribit = gray_8PSK[tribit & 7]; - - tx_8PSK[snd_ch] = (tx_8PSK[snd_ch] + tribit) & 7; - tx_8PSK_old_I[snd_ch] = tx_8PSK_I[snd_ch]; - tx_8PSK_old_Q[snd_ch] = tx_8PSK_Q[snd_ch]; - - switch (tx_8PSK[snd_ch]) - { - case 0: - - tx_8PSK_I[snd_ch] = 0; - tx_8PSK_Q[snd_ch] = 1; - break; - - case 1: - - tx_8PSK_I[snd_ch] = COS45; - tx_8PSK_Q[snd_ch] = COS45; - break; - - case 2: - - tx_8PSK_I[snd_ch] = 1; - tx_8PSK_Q[snd_ch] = 0; - break; - - case 3: - - tx_8PSK_I[snd_ch] = COS45; - tx_8PSK_Q[snd_ch] = -COS45; - break; - - case 4: - - tx_8PSK_I[snd_ch] = 0; - tx_8PSK_Q[snd_ch] = -1; - break; - - case 5: - - tx_8PSK_I[snd_ch] = -COS45; - tx_8PSK_Q[snd_ch] = -COS45; - break; - - case 6: - - tx_8PSK_I[snd_ch] = -1; - tx_8PSK_Q[snd_ch] = 0; - break; - - case 7: - - tx_8PSK_I[snd_ch] = -COS45; - tx_8PSK_Q[snd_ch] = COS45; - break; - - } - - tx_8PSK_avg_I[snd_ch] = 0.5f*(tx_8PSK_old_I[snd_ch] + tx_8PSK_I[snd_ch]); - tx_8PSK_df_I[snd_ch] = 0.5f*(tx_8PSK_old_I[snd_ch] - tx_8PSK_I[snd_ch]); - tx_8PSK_avg_Q[snd_ch] = 0.5f*(tx_8PSK_old_Q[snd_ch] + tx_8PSK_Q[snd_ch]); - tx_8PSK_df_Q[snd_ch] = 0.5f*(tx_8PSK_old_Q[snd_ch] - tx_8PSK_Q[snd_ch]); - } - - if (modem_mode[snd_ch] == MODE_MPSK) - { - qbit = 0; - - // get the bits for each of 4 carriers - - for (i = 1; i <= 4; i++) - { - bit = 0; - - if (tx_status[snd_ch] == TX_SILENCE) - { - tx_delay_cnt[snd_ch] = 0; - Debugprintf("Start TXD"); - tx_status[snd_ch] = TX_DELAY; - } - - if (tx_status[snd_ch] == TX_DELAY) - bit = get_new_bit_delay(snd_ch, bit); - - if (tx_status[snd_ch] == TX_TAIL) - bit = get_new_bit_tail(snd_ch, bit); - - if (tx_status[snd_ch] == TX_FRAME) - bit = get_new_bit(snd_ch, bit); - - qbit = (qbit << 1) | bit; - } - - tx_old_inv1[snd_ch] = tx_inv1[snd_ch]; - tx_old_inv2[snd_ch] = tx_inv2[snd_ch]; - tx_old_inv3[snd_ch] = tx_inv3[snd_ch]; - tx_old_inv4[snd_ch] = tx_inv4[snd_ch]; - - if ((qbit & 8) == 0) - tx_inv1[snd_ch] = -tx_inv1[snd_ch]; - if ((qbit & 4) == 0) - tx_inv2[snd_ch] = -tx_inv2[snd_ch]; - if ((qbit & 2) == 0) - tx_inv3[snd_ch] = -tx_inv3[snd_ch]; - if ((qbit & 1) == 0) - tx_inv4[snd_ch] = -tx_inv4[snd_ch]; - - } - } - - if (tx_status[snd_ch] == TX_WAIT_BPF) - get_wait_bpf(snd_ch); - - if (modem_mode[snd_ch] == MODE_FSK) - return amp * sinf(tx_osc[snd_ch]); - - if (modem_mode[snd_ch] == MODE_BPSK) - return sinf(tx_osc[snd_ch]) * tx_bit_mod[snd_ch]; - - if (modem_mode[snd_ch] == MODE_QPSK || modem_mode[snd_ch] == MODE_8PSK || modem_mode[snd_ch] == MODE_PI4QPSK) - return sin(tx_osc[snd_ch]) * tx_I_mod[snd_ch] + cos(tx_osc[snd_ch]) * tx_Q_mod[snd_ch]; - - if (modem_mode[snd_ch] == MODE_MPSK) - return 0.35*(sinf(tx_osc1[snd_ch])*tx_bit1_mod[snd_ch] + - sinf(tx_osc2[snd_ch])*tx_bit2_mod[snd_ch] + - sinf(tx_osc3[snd_ch])*tx_bit3_mod[snd_ch] + - sinf(tx_osc4[snd_ch])*tx_bit4_mod[snd_ch]); - - return 0.0f; -} - -float make_samples_calib(UCHAR snd_ch, UCHAR tones) -{ - float amp, pi2, x, x1; - - x1 = pi * tx_baudrate[snd_ch] / TX_Samplerate; - pi2 = 2 * pi / TX_Samplerate; - - switch (tones) - { - case 1: - - tx_last_bit[snd_ch] = 1; - break; - - case 2: - - tx_last_bit[snd_ch] = 0; - break; - - case 3: - - tx_bit_osc[snd_ch] = tx_bit_osc[snd_ch] + x1; - - if (tx_bit_osc[snd_ch] > pi) - { - tx_bit_osc[snd_ch] = tx_bit_osc[snd_ch] - pi; - tx_last_bit[snd_ch] = tx_last_bit[snd_ch] ^ 1; - } - break; - } - - amp = 1; - - if (tx_baudrate[snd_ch] > 600) - { - if (tx_hitoneraisedb[snd_ch] < 0 && tx_last_bit[snd_ch] == 0) - amp = tx_hitoneraise[snd_ch]; - - if (tx_hitoneraisedb[snd_ch] > 0 && tx_last_bit[snd_ch] == 1) - amp = tx_hitoneraise[snd_ch]; - } - - if (tx_last_bit[snd_ch] == 0) - x = pi2*(tx_freq[snd_ch] + 0.5f * tx_shift[snd_ch]); - else - x = pi2*(tx_freq[snd_ch] - 0.5f * tx_shift[snd_ch]); - - tx_osc[snd_ch] = tx_osc[snd_ch] + x; - - if (tx_osc[snd_ch] > 2*pi) - tx_osc[snd_ch] = tx_osc[snd_ch] - 2 * pi; - - return amp * sinf(tx_osc[snd_ch]); -} - -int amplitude = 22000; - -void modulator(UCHAR snd_ch, int buf_size) -{ - // We feed samples to samplesink instead of buffering them - - // I think this is the top of the TX hierarchy - - int i; - short Sample; - - if (calib_mode[snd_ch] > 0) - { - if (calib_mode[snd_ch] == 4) // CWID - { - if (tx_status[snd_ch] == TX_SILENCE) - { - SoundIsPlaying = TRUE; - Debugprintf("Start CWID Chan %d", snd_ch); - RadioPTT(snd_ch, 1); - - tx_status[snd_ch] = 6; - } - - if (ARDOPSendToCard(snd_ch, SendSize) == 1) - { - // End of TX - - tx_status[snd_ch] = TX_SILENCE; // Stop TX - Flush(); - RadioPTT(snd_ch, 0); - Debugprintf("End CWID"); - calib_mode[snd_ch] = 0; - } - return; - } - - - if (tx_status[snd_ch] == TX_SILENCE) - { - SoundIsPlaying = TRUE; - Debugprintf("Start Calib Chan %d", snd_ch); - RadioPTT(snd_ch, 1); - - tx_bit_osc[snd_ch] = 0; - tx_last_bit[snd_ch] = 0; - - // fill filter - - for (i = 0; i < tx_BPF_tap[snd_ch]; i++) - tx_prev_BPF_buf[snd_ch][buf_size + i] = make_samples_calib(snd_ch,calib_mode[snd_ch]); - } - tx_status[snd_ch] = TX_WAIT_BPF; - - for (i = 0; i < buf_size; i++) - tx_src_BPF_buf[snd_ch][i] = make_samples_calib(snd_ch, calib_mode[snd_ch]); - - FIR_filter(tx_src_BPF_buf[snd_ch],buf_size,tx_BPF_tap[snd_ch],tx_BPF_core[snd_ch],tx_BPF_buf[snd_ch],tx_prev_BPF_buf[snd_ch]); - - for (i = 0; i < buf_size; i++) - { - Sample = tx_BPF_buf[snd_ch][i] * amplitude; - SampleSink(modemtoSoundLR[snd_ch], Sample); - } - } - else - { - if (tx_status[snd_ch] == TX_SILENCE) - { - if (fx25_mode[snd_ch] == FX25_MODE_TXRX) - tx_fx25_mode[snd_ch] = 1; - else - tx_fx25_mode[snd_ch] = 0; - - tx_bit_osc[snd_ch] = 0; - tx_8PSK[snd_ch] = 0; - tx_QPSK[snd_ch] = 0; - tx_last_bit[snd_ch] = 0; - tx_inv1[snd_ch] = 1; - tx_inv2[snd_ch] = 1; - tx_inv3[snd_ch] = 1; - tx_inv4[snd_ch] = 1; - tx_8PSK_I[snd_ch] = 0; - tx_8PSK_Q[snd_ch] = 1; - tx_8PSK_old_I[snd_ch] = 0; - tx_8PSK_old_Q[snd_ch] = 1; - tx_QPSK_I[snd_ch] = COS45; - tx_QPSK_Q[snd_ch] = COS45; - tx_QPSK_old_I[snd_ch] = COS45; - tx_QPSK_old_Q[snd_ch] = COS45; - - for (i = 0; i < tx_BPF_tap[snd_ch]; i++) - tx_prev_BPF_buf[snd_ch][buf_size+i] = make_samples(snd_ch, &tx_pol[snd_ch]); - } - - for (i = 0; i < buf_size; i++) - tx_src_BPF_buf[snd_ch][i] = make_samples(snd_ch, &tx_pol[snd_ch]); - - FIR_filter(tx_src_BPF_buf[snd_ch], buf_size, tx_BPF_tap[snd_ch], tx_BPF_core[snd_ch], tx_BPF_buf[snd_ch], tx_prev_BPF_buf[snd_ch]); - - for (i = 0; i < buf_size; i++) - { - Sample = tx_BPF_buf[snd_ch][i] * 20000.0f; - SampleSink(modemtoSoundLR[snd_ch], Sample); - } - } -} - - diff --git a/ax25_pad2.h b/ax25_pad2.h deleted file mode 100644 index c6dc17a..0000000 --- a/ax25_pad2.h +++ /dev/null @@ -1,55 +0,0 @@ -/*------------------------------------------------------------------- - * - * Name: ax25_pad2.h - * - * Purpose: Header file for using ax25_pad2.c - * ax25_pad dealt only with UI frames. - * This adds a facility for the other types: U, s, I. - * - *------------------------------------------------------------------*/ - -#ifndef AX25_PAD2_H -#define AX25_PAD2_H 1 - -#include "ax25_pad.h" - - - - -#if AX25MEMDEBUG // to investigate a memory leak problem - - - -packet_t ax25_u_frame_debug (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, cmdres_t cr, ax25_frame_type_t ftype, int pf, int pid, unsigned char *pinfo, int info_len, char *src_file, int src_line); - -packet_t ax25_s_frame_debug (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, cmdres_t cr, ax25_frame_type_t ftype, int modulo, int nr, int pf, unsigned char *pinfo, int info_len, char *src_file, int src_line); - -packet_t ax25_i_frame_debug (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, cmdres_t cr, int modulo, int nr, int ns, int pf, int pid, unsigned char *pinfo, int info_len, char *src_file, int src_line); - - -#define ax25_u_frame(a,n,c,f,p,q,i,l) ax25_u_frame_debug(a,n,c,f,p,q,i,l,__FILE__,__LINE__) - -#define ax25_s_frame(a,n,c,f,m,r,p,i,l) ax25_s_frame_debug(a,n,c,f,m,r,p,i,l,__FILE__,__LINE__) - -#define ax25_i_frame(a,n,c,m,r,s,p,q,i,l) ax25_i_frame_debug(a,n,c,m,r,s,p,q,i,l,__FILE__,__LINE__) - - -#else - -packet_t ax25_u_frame (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, cmdres_t cr, ax25_frame_type_t ftype, int pf, int pid, unsigned char *pinfo, int info_len); - -packet_t ax25_s_frame (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, cmdres_t cr, ax25_frame_type_t ftype, int modulo, int nr, int pf, unsigned char *pinfo, int info_len); - -packet_t ax25_i_frame (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, cmdres_t cr, int modulo, int nr, int ns, int pf, int pid, unsigned char *pinfo, int info_len); - - -#endif - - - - -#endif /* AX25_PAD2_H */ - -/* end ax25_pad2.h */ - - diff --git a/beacon.h b/beacon.h deleted file mode 100644 index f7d2a56..0000000 --- a/beacon.h +++ /dev/null @@ -1,6 +0,0 @@ - -/* beacon.h */ - -void beacon_init (struct audio_s *pmodem, struct misc_config_s *pconfig, struct igate_config_s *pigate); - -void beacon_tracker_set_debug (int level); diff --git a/cdigipeater.h b/cdigipeater.h deleted file mode 100644 index 69a4b8c..0000000 --- a/cdigipeater.h +++ /dev/null @@ -1,62 +0,0 @@ - - -#ifndef CDIGIPEATER_H -#define CDIGIPEATER_H 1 - -#include "regex.h" - -#include "direwolf.h" /* for MAX_CHANS */ -#include "ax25_pad.h" /* for packet_t */ -#include "audio.h" /* for radio channel properties */ - - -/* - * Information required for Connected mode digipeating. - * - * The configuration file reader fills in this information - * and it is passed to cdigipeater_init at application start up time. - */ - - -struct cdigi_config_s { - -/* - * Rules for each of the [from_chan][to_chan] combinations. - */ - int enabled[MAX_CHANS][MAX_CHANS]; // Is it enabled for from/to pair? - - int has_alias[MAX_CHANS][MAX_CHANS]; // If there was no alias in the config file, - // the structure below will not be set up - // properly and an attempt to use it could - // result in a crash. (fixed v1.5) - // Not needed for [APRS] DIGIPEAT because - // the alias is mandatory there. - regex_t alias[MAX_CHANS][MAX_CHANS]; - - char *cfilter_str[MAX_CHANS][MAX_CHANS]; - // NULL or optional Packet Filter strings such as "t/m". -}; - -/* - * Call once at application start up time. - */ - -extern void cdigipeater_init (struct audio_s *p_audio_config, struct cdigi_config_s *p_cdigi_config); - -/* - * Call this for each packet received. - * Suitable packets will be queued for transmission. - */ - -extern void cdigipeater (int from_chan, packet_t pp); - - -/* Make statistics available. */ - -int cdigipeater_get_count (int from_chan, int to_chan); - - -#endif - -/* end cdigipeater.h */ - diff --git a/cm108.h b/cm108.h deleted file mode 100644 index 2def77a..0000000 --- a/cm108.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Dire Wolf cm108.h */ - -extern void cm108_find_ptt (char *output_audio_device, char *ptt_device, int ptt_device_size); - -extern int cm108_set_gpio_pin (char *name, int num, int state); \ No newline at end of file diff --git a/config.h b/config.h deleted file mode 100644 index 360ac49..0000000 --- a/config.h +++ /dev/null @@ -1,262 +0,0 @@ - -/*---------------------------------------------------------------------------- - * - * Name: config.h - * - * Purpose: - * - * Description: - * - *-----------------------------------------------------------------------------*/ - - -#ifndef CONFIG_H -#define CONFIG_H 1 - -#include "audio.h" /* for struct audio_s */ -#include "digipeater.h" /* for struct digi_config_s */ -#include "cdigipeater.h" /* for struct cdigi_config_s */ -#include "aprs_tt.h" /* for struct tt_config_s */ -#include "igate.h" /* for struct igate_config_s */ - -/* - * All the leftovers. - * This wasn't thought out. It just happened. - */ - -enum beacon_type_e { BEACON_IGNORE, BEACON_POSITION, BEACON_OBJECT, BEACON_TRACKER, BEACON_CUSTOM, BEACON_IGATE }; - -enum sendto_type_e { SENDTO_XMIT, SENDTO_IGATE, SENDTO_RECV }; - - -#define MAX_BEACONS 30 -#define MAX_KISS_TCP_PORTS (MAX_CHANS+1) - -struct misc_config_s { - - int agwpe_port; /* TCP Port number for the "AGW TCPIP Socket Interface" */ - - // Previously we allowed only a single TCP port for KISS. - // An increasing number of people want to run multiple radios. - // Unfortunately, most applications don't know how to deal with multi-radio TNCs. - // They ignore the channel on receive and always transmit to channel 0. - // Running multiple instances of direwolf is a work-around but this leads to - // more complex configuration and we lose the cross-channel digipeating capability. - // In release 1.7 we add a new feature to assign a single radio channel to a TCP port. - // e.g. - // KISSPORT 8001 # default, all channels. Radio channel = KISS channel. - // - // KISSPORT 7000 0 # Only radio channel 0 for receive. - // # Transmit to radio channel 0, ignoring KISS channel. - // - // KISSPORT 7001 1 # Only radio channel 1 for receive. KISS channel set to 0. - // # Transmit to radio channel 1, ignoring KISS channel. - - int kiss_port[MAX_KISS_TCP_PORTS]; /* TCP Port number for the "TCP KISS" protocol. */ - int kiss_chan[MAX_KISS_TCP_PORTS]; /* Radio Channel number for this port or -1 for all. */ - - int kiss_copy; /* Data from network KISS client is copied to all others. */ - int enable_kiss_pt; /* Enable pseudo terminal for KISS. */ - /* Want this to be off by default because it hangs */ - /* after a while if nothing is reading from other end. */ - - char kiss_serial_port[20]; - /* Serial port name for our end of the */ - /* virtual null modem for native Windows apps. */ - /* Version 1.5 add same capability for Linux. */ - - int kiss_serial_speed; /* Speed, in bps, for the KISS serial port. */ - /* If 0, just leave what was already there. */ - - int kiss_serial_poll; /* When using Bluetooth KISS, the /dev/rfcomm0 device */ - /* will appear and disappear as the remote application */ - /* opens and closes the virtual COM port. */ - /* When this is non-zero, we will check periodically to */ - /* see if the device has appeared and we will open it. */ - - char gpsnmea_port[20]; /* Serial port name for reading NMEA sentences from GPS. */ - /* e.g. COM22, /dev/ttyACM0 */ - - int gpsnmea_speed; /* Speed for above, baud, default 4800. */ - - char gpsd_host[20]; /* Host for gpsd server. */ - /* e.g. localhost, 192.168.1.2 */ - - int gpsd_port; /* Port number for gpsd server. */ - /* Default is 2947. */ - - - char waypoint_serial_port[20]; /* Serial port name for sending NMEA waypoint sentences */ - /* to a GPS map display or other mapping application. */ - /* e.g. COM22, /dev/ttyACM0 */ - /* Currently no option for setting non-standard speed. */ - /* This was done in 2014 and no one has complained yet. */ - - char waypoint_udp_hostname[80]; /* Destination host when using UDP. */ - - int waypoint_udp_portnum; /* UDP port. */ - - int waypoint_formats; /* Which sentence formats should be generated? */ - -#define WPL_FORMAT_NMEA_GENERIC 0x01 /* N $GPWPL */ -#define WPL_FORMAT_GARMIN 0x02 /* G $PGRMW */ -#define WPL_FORMAT_MAGELLAN 0x04 /* M $PMGNWPL */ -#define WPL_FORMAT_KENWOOD 0x08 /* K $PKWDWPL */ -#define WPL_FORMAT_AIS 0x10 /* A !AIVDM */ - - - int log_daily_names; /* True to generate new log file each day. */ - - char log_path[80]; /* Either directory or full file name depending on above. */ - - int dns_sd_enabled; /* DNS Service Discovery announcement enabled. */ - char dns_sd_name[64]; /* Name announced on dns-sd; defaults to "Dire Wolf on " */ - - int sb_configured; /* TRUE if SmartBeaconing is configured. */ - int sb_fast_speed; /* MPH */ - int sb_fast_rate; /* seconds */ - int sb_slow_speed; /* MPH */ - int sb_slow_rate; /* seconds */ - int sb_turn_time; /* seconds */ - int sb_turn_angle; /* degrees */ - int sb_turn_slope; /* degrees * MPH */ - -// AX.25 connected mode. - - int frack; /* Number of seconds to wait for ack to transmission. */ - - int retry; /* Number of times to retry before giving up. */ - - int paclen; /* Max number of bytes in information part of frame. */ - - int maxframe_basic; /* Max frames to send before ACK. mod 8 "Window" size. */ - - int maxframe_extended; /* Max frames to send before ACK. mod 128 "Window" size. */ - - int maxv22; /* Maximum number of unanswered SABME frames sent before */ - /* switching to SABM. This is to handle the case of an old */ - /* TNC which simply ignores SABME rather than replying with FRMR. */ - - char **v20_addrs; /* Stations known to understand only AX.25 v2.0 so we don't */ - /* waste time trying v2.2 first. */ - - int v20_count; /* Number of station addresses in array above. */ - - char **noxid_addrs; /* Stations known not to understand XID command so don't */ - /* waste time sending it and eventually giving up. */ - /* AX.25 for Linux is the one known case, so far, where */ - /* SABME is implemented but XID is not. */ - - int noxid_count; /* Number of station addresses in array above. */ - - -// Beacons. - - int num_beacons; /* Number of beacons defined. */ - - struct beacon_s { - - enum beacon_type_e btype; /* Position or object. */ - - int lineno; /* Line number from config file for later error messages. */ - - enum sendto_type_e sendto_type; - - /* SENDTO_XMIT - Usually beacons go to a radio transmitter. */ - /* chan, below is the channel number. */ - /* SENDTO_IGATE - Send to IGate, probably to announce my position */ - /* rather than relying on someone else to hear */ - /* me on the radio and report me. */ - /* SENDTO_RECV - Pretend this was heard on the specified */ - /* radio channel. Mostly for testing. It is a */ - /* convenient way to send packets to attached apps. */ - - int sendto_chan; /* Transmit or simulated receive channel for above. Should be 0 for IGate. */ - - int delay; /* Seconds to delay before first transmission. */ - - int slot; /* Seconds after hour for slotted time beacons. */ - /* If specified, it overrides any 'delay' value. */ - - int every; /* Time between transmissions, seconds. */ - /* Remains fixed for PBEACON and OBEACON. */ - /* Dynamically adjusted for TBEACON. */ - - time_t next; /* Unix time to transmit next one. */ - - char *source; /* NULL or explicit AX.25 source address to use */ - /* instead of the mycall value for the channel. */ - - char *dest; /* NULL or explicit AX.25 destination to use */ - /* instead of the software version such as APDW11. */ - - int compress; /* Use more compact form? */ - - char objname[10]; /* Object name. Any printable characters. */ - - char *via; /* Path, e.g. "WIDE1-1,WIDE2-1" or NULL. */ - - char *custom_info; /* Info part for handcrafted custom beacon. */ - /* Ignore the rest below if this is set. */ - - char *custom_infocmd; /* Command to generate info part. */ - /* Again, other options below are then ignored. */ - - int messaging; /* Set messaging attribute for position report. */ - /* i.e. Data Type Indicator of '=' rather than '!' */ - - double lat; /* Latitude and longitude. */ - double lon; - int ambiguity; /* Number of lower digits to trim from location. 0 (default), 1, 2, 3, 4. */ - float alt_m; /* Altitude in meters. */ - - char symtab; /* Symbol table: / or \ or overlay character. */ - char symbol; /* Symbol code. */ - - float power; /* For PHG. */ - float height; /* HAAT in feet */ - float gain; /* Original protocol spec was unclear. */ - /* Addendum 1.1 clarifies it is dBi not dBd. */ - - char dir[3]; /* 1 or 2 of N,E,W,S, or empty for omni. */ - - float freq; /* MHz. */ - float tone; /* Hz. */ - float offset; /* MHz. */ - - char *comment; /* Comment or NULL. */ - char *commentcmd; /* Command to append more to Comment or NULL. */ - - - } beacon[MAX_BEACONS]; - -}; - - -#define MIN_IP_PORT_NUMBER 1024 -#define MAX_IP_PORT_NUMBER 49151 - - -#define DEFAULT_AGWPE_PORT 8000 /* Like everyone else. */ -#define DEFAULT_KISS_PORT 8001 /* Above plus 1. */ - - -#define DEFAULT_NULLMODEM "COM3" /* should be equiv. to /dev/ttyS2 on Cygwin */ - - - - -extern void config_init (char *fname, struct audio_s *p_modem, - struct digi_config_s *digi_config, - struct cdigi_config_s *cdigi_config, - struct tt_config_s *p_tt_config, - struct igate_config_s *p_igate_config, - struct misc_config_s *misc_config); - - - -#endif /* CONFIG_H */ - -/* end config.h */ - - diff --git a/debian/changelog b/debian/changelog index 19caecc..9dfc8ef 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +qtsoundmodem (0.0.0.71-1) unstable; urgency=medium + + * New Upstream Release + + -- Dave Hibberd Sun, 17 Dec 2023 14:07:52 +0000 + qtsoundmodem (0.0.0.68-1~bpo11+1) bullseye; urgency=medium * Rebuild for bullseye. diff --git a/debian/dirs b/debian/dirs deleted file mode 100644 index e6ca2b7..0000000 --- a/debian/dirs +++ /dev/null @@ -1 +0,0 @@ -opt/oarc/QtSoundModem diff --git a/debug/QtSoundModem.ini b/debug/QtSoundModem.ini deleted file mode 100644 index 0aefa4a..0000000 --- a/debug/QtSoundModem.ini +++ /dev/null @@ -1,201 +0,0 @@ -[General] -geometry="@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0z\0\0\0\t\0\0\x4=\0\0\x2\xf9\0\0\0{\0\0\0(\0\0\x4<\0\0\x2\xf8\0\0\0\0\0\0\0\0\x5\0\0\0\0{\0\0\0(\0\0\x4<\0\0\x2\xf8)" -windowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\x3\xc2\0\0\x2\xb9\0\0\0\x4\0\0\0\x4\0\0\0\b\0\0\0\b\xfc\0\0\0\0) -PSKWindow=@Rect(46 499 366 140) -FontFamily=Courier New -PointSize=12 -Weight=50 - -[AX25_A] -Retries=15 -HiToneRaise=0 -Maxframe=3 -FrackTime=5 -IdleTime=180 -SlotTime=100 -Persist=128 -RespTime=1500 -TXFrmMode=1 -FrameCollector=6 -ExcludeCallsigns= -ExcludeAPRSFrmType= -KISSOptimization=0 -DynamicFrack=0 -BitRecovery=0 -NonAX25Frm=0 -MEMRecovery=200 -IPOLL=80 -MyDigiCall= -FX25=1 -IL2P=2 -RSID_UI=0 -RSID_SABM=0 -RSID_SetModem=0 - -[Init] -SoundMode=0 -UDPClientPort=8888 -UDPServerPort=8884 -TXPort=8884 -UDPServer=0 -UDPHost=192.168.1.255 -TXSampleRate=12000 -RXSampleRate=12000 -SndRXDeviceName="CABLE-B OUTPUT (VB-AUDIO CABLE " -SndTXDeviceName=CABLE-B INPUT (VB-AUDIO CABLE B -SCO=0 -DualPTT=1 -TXRotate=0 -DispMode=1 -PTT= -PTTBAUD=19200 -PTTMode=1 -PTTOffString= -PTTOnString= -pttGPIOPin=17 -pttGPIOPinR=17 -CM108Addr=0xD8C:0x08 -HamLibPort=4532 -HamLibHost=127.0.0.1 -MinimizetoTray=1 -multiCore=1 -Wisdom=(fftw-3.3.5 fftwf_wisdom #x9e7d4dee #xdb14fed1 #x34bf76a4 #xeb6e8fdf\n (fftwf_codelet_n2fv_12_avx 0 #x10048 #x10048 #x0 #xb0767e46 #x8d41dd22 #x439264a0 #x18435a99)\n (fftwf_rdft_rank0_register 0 #x11048 #x11048 #x0 #xff75c762 #x3a0ee093 #x5b78d592 #x6b6be60e)\n (fftwf_codelet_t2fv_2_avx 0 #x11048 #x11048 #x0 #x34057a74 #x664db78f #xa9524ebc #x606afd88)\n (fftwf_dft_nop_register 0 #x11048 #x11048 #x0 #x4a593e24 #xb5f06ddf #xf11fe7f2 #xc010b545)\n (fftwf_dft_bluestein_register 0 #x11048 #x11048 #x0 #x5e17c068 #x1682c5d6 #x89dd79be #x9b951c0f)\n (fftwf_dft_vrank_geq1_register 0 #x10048 #x10048 #x0 #x2fce15e1 #x178d4f4d #x1e956a41 #xf3fd6b80)\n (fftwf_codelet_t1fuv_4_sse2 0 #x11048 #x11048 #x0 #x2fb84bc5 #x2792028e #x8ec66ed5 #x47b5f7dc)\n (fftwf_dft_buffered_register 0 #x11048 #x11048 #x0 #x4f8e87b4 #xec4f2fa0 #x79fe76a1 #xa16e32a5)\n (fftwf_dft_vrank_geq1_register 0 #x11048 #x11048 #x0 #x8a9c355b #xb6dbadad #xbac1daac #xa866ceb3)\n (fftwf_dft_r2hc_register 0 #x11048 #x11048 #x0 #x576d5db6 #xa6a15f8a #x875d87d5 #x7561a866)\n (fftwf_codelet_t1fv_6_avx 0 #x10048 #x10048 #x0 #xd9db29d8 #x3302fcf3 #x19ce6e5d #x869fc341)\n (fftwf_dft_vrank_geq1_register 0 #x11048 #x11048 #x0 #xf7abab03 #x5f0e79b1 #x1b8367ad #xe5028f2c)\n (fftwf_codelet_t1fv_12_avx 0 #x10048 #x10048 #x0 #x0b0d3933 #x08267d12 #x45613873 #xde496efe)\n)\n -WaterfallMin=0 -WaterfallMax=3300 - -[AX25_B] -Retries=15 -HiToneRaise=0 -Maxframe=3 -FrackTime=5 -IdleTime=180 -SlotTime=100 -Persist=128 -RespTime=1500 -TXFrmMode=1 -FrameCollector=6 -ExcludeCallsigns= -ExcludeAPRSFrmType= -KISSOptimization=0 -DynamicFrack=0 -BitRecovery=0 -NonAX25Frm=0 -MEMRecovery=200 -IPOLL=80 -MyDigiCall= -FX25=1 -IL2P=2 -RSID_UI=0 -RSID_SABM=0 -RSID_SetModem=0 - -[Modem] -NRRcvrPairs1=2 -NRRcvrPairs2=2 -NRRcvrPairs3=0 -NRRcvrPairs4=2 -RcvrShift1=50 -RcvrShift2=30 -RcvrShift3=30 -RcvrShift4=30 -ModemType1=4 -ModemType2=14 -ModemType3=0 -ModemType4=14 -soundChannel1=1 -soundChannel2=1 -soundChannel3=0 -soundChannel4=0 -DCDThreshold=40 -rxOffset=-100 -PreEmphasisAll1=0 -PreEmphasisAll2=0 -PreEmphasisAll3=0 -PreEmphasisAll4=0 -PreEmphasisDB1=0 -PreEmphasisDB2=0 -PreEmphasisDB3=0 -PreEmphasisDB4=0 -TxDelay1=250 -TxDelay2=250 -TxDelay3=250 -TxDelay4=250 -TxTail1=50 -TxTail2=50 -TxTail3=50 -TxTail4=50 -CWIDCall= -CWIDInterval=0 -CWIDLeft=0 -CWIDRight=0 -CWIDType=1 -RXFreq1=1700 -RXFreq2=1700 -RXFreq3=500 -RXFreq4=1700 -CWIDMark= -afterTraffic=false - -[AGWHost] -Server=1 -Port=8000 - -[KISS] -Server=0 -Port=8105 - -[AX25_C] -Retries=15 -HiToneRaise=0 -Maxframe=3 -FrackTime=5 -IdleTime=180 -SlotTime=100 -Persist=128 -RespTime=1500 -TXFrmMode=1 -FrameCollector=6 -ExcludeCallsigns= -ExcludeAPRSFrmType= -KISSOptimization=0 -DynamicFrack=0 -BitRecovery=0 -NonAX25Frm=0 -MEMRecovery=200 -IPOLL=80 -MyDigiCall= -FX25=1 -IL2P=0 -RSID_UI=0 -RSID_SABM=0 -RSID_SetModem=0 - -[Window] -Waterfall1=1 -Waterfall2=1 - -[AX25_D] -Retries=15 -HiToneRaise=0 -Maxframe=3 -FrackTime=5 -IdleTime=180 -SlotTime=100 -Persist=128 -RespTime=1500 -TXFrmMode=1 -FrameCollector=6 -ExcludeCallsigns= -ExcludeAPRSFrmType= -KISSOptimization=0 -DynamicFrack=0 -BitRecovery=0 -NonAX25Frm=0 -MEMRecovery=200 -IPOLL=80 -MyDigiCall= -FX25=1 -IL2P=0 -RSID_UI=0 -RSID_SABM=0 -RSID_SetModem=0 diff --git a/debug/moc_predefs-DESKTOP-MHE5LO8.h b/debug/moc_predefs-DESKTOP-MHE5LO8.h deleted file mode 100644 index 2c1557b..0000000 --- a/debug/moc_predefs-DESKTOP-MHE5LO8.h +++ /dev/null @@ -1,12 +0,0 @@ -#define _MSC_EXTENSIONS -#define _INTEGRAL_MAX_BITS 64 -#define _MSC_VER 1916 -#define _MSC_FULL_VER 191627050 -#define _MSC_BUILD 0 -#define _WIN32 -#define _M_IX86 600 -#define _M_IX86_FP 2 -#define _CPPRTTI -#define _DEBUG -#define _MT -#define _DLL diff --git a/debug/moc_predefs.h b/debug/moc_predefs.h index 8247e15..b857b2e 100644 --- a/debug/moc_predefs.h +++ b/debug/moc_predefs.h @@ -1,7 +1,7 @@ #define _MSC_EXTENSIONS #define _INTEGRAL_MAX_BITS 64 #define _MSC_VER 1916 -#define _MSC_FULL_VER 191627043 +#define _MSC_FULL_VER 191627045 #define _MSC_BUILD 0 #define _WIN32 #define _M_IX86 600 diff --git a/decode_aprs.h b/decode_aprs.h deleted file mode 100644 index f25d1e9..0000000 --- a/decode_aprs.h +++ /dev/null @@ -1,150 +0,0 @@ - -/* decode_aprs.h */ - - -#ifndef DECODE_APRS_H - -#define DECODE_APRS_H 1 - - - -#ifndef G_UNKNOWN -#include "latlong.h" -#endif - -#ifndef AX25_MAX_ADDR_LEN -#include "ax25_pad.h" -#endif - -#ifndef APRSTT_LOC_DESC_LEN -#include "aprs_tt.h" -#endif - -typedef struct decode_aprs_s { - - int g_quiet; /* Suppress error messages when decoding. */ - - char g_src[AX25_MAX_ADDR_LEN]; - - char g_dest[AX25_MAX_ADDR_LEN]; - - char g_data_type_desc[100]; /* APRS data type description. Telemetry descriptions get pretty long. */ - - char g_symbol_table; /* The Symbol Table Identifier character selects one */ - /* of the two Symbol Tables, or it may be used as */ - /* single-character (alpha or numeric) overlay, as follows: */ - - /* / Primary Symbol Table (mostly stations) */ - - /* \ Alternate Symbol Table (mostly Objects) */ - - /* 0-9 Numeric overlay. Symbol from Alternate Symbol */ - /* Table (uncompressed lat/long data format) */ - - /* a-j Numeric overlay. Symbol from Alternate */ - /* Symbol Table (compressed lat/long data */ - /* format only). i.e. a-j maps to 0-9 */ - - /* A-Z Alpha overlay. Symbol from Alternate Symbol Table */ - - - char g_symbol_code; /* Where the Symbol Table Identifier is 0-9 or A-Z (or a-j */ - /* with compressed position data only), the symbol comes from */ - /* the Alternate Symbol Table, and is overlaid with the */ - /* identifier (as a single digit or a capital letter). */ - - char g_aprstt_loc[APRSTT_LOC_DESC_LEN]; /* APRStt location from !DAO! */ - - double g_lat, g_lon; /* Location, degrees. Negative for South or West. */ - /* Set to G_UNKNOWN if missing or error. */ - - char g_maidenhead[12]; /* 4 or 6 (or 8?) character maidenhead locator. */ - - char g_name[12]; /* Object or item name. Max. 9 characters. */ - - char g_addressee[12]; /* Addressee for a "message." Max. 9 characters. */ - /* Also for Directed Station Query which is a */ - /* special case of message. */ - - enum message_subtype_e { message_subtype_invalid = 0, - message_subtype_message, - message_subtype_ack, - message_subtype_rej, - message_subtype_telem_parm, - message_subtype_telem_unit, - message_subtype_telem_eqns, - message_subtype_telem_bits, - message_subtype_directed_query - } g_message_subtype; /* Various cases of the overloaded "message." */ - - char g_message_number[12]; /* Message number. Should be 1 - 5 alphanumeric characters if used. */ - /* Addendum 1.1 has new format {mm} or {mm}aa with only two */ - /* characters for message number and an ack riding piggyback. */ - - float g_speed_mph; /* Speed in MPH. */ - /* The APRS transmission uses knots so watch out for */ - /* conversions when sending and receiving APRS packets. */ - - float g_course; /* 0 = North, 90 = East, etc. */ - - int g_power; /* Transmitter power in watts. */ - - int g_height; /* Antenna height above average terrain, feet. */ - - int g_gain; /* Antenna gain in dB. */ - - char g_directivity[12]; /* Direction of max signal strength */ - - float g_range; /* Precomputed radio range in miles. */ - - float g_altitude_ft; /* Feet above median sea level. */ - /* I used feet here because the APRS specification */ - /* has units of feet for alititude. Meters would be */ - /* more natural to the other 96% of the world. */ - - char g_mfr[80]; /* Manufacturer or application. */ - - char g_mic_e_status[32]; /* MIC-E message. */ - - double g_freq; /* Frequency, MHz */ - - float g_tone; /* CTCSS tone, Hz, one fractional digit */ - - int g_dcs; /* Digital coded squelch, print as 3 octal digits. */ - - int g_offset; /* Transmit offset, kHz */ - - - char g_query_type[12]; /* General Query: APRS, IGATE, WX, ... */ - /* Addressee is NOT set. */ - - /* Directed Station Query: exactly 5 characters. */ - /* APRSD, APRST, PING?, ... */ - /* Addressee is set. */ - - double g_footprint_lat; /* A general query may contain a foot print. */ - double g_footprint_lon; /* Set all to G_UNKNOWN if not used. */ - float g_footprint_radius; /* Radius in miles. */ - - char g_query_callsign[12]; /* Directed query may contain callsign. */ - /* e.g. tell me all objects from that callsign. */ - - - char g_weather[500]; /* Weather. Can get quite long. Rethink max size. */ - - char g_telemetry[256]; /* Telemetry data. Rethink max size. */ - - char g_comment[256]; /* Comment. */ - -} decode_aprs_t; - - - - - -extern void decode_aprs (decode_aprs_t *A, packet_t pp, int quiet, char *third_party_src); - -extern void decode_aprs_print (decode_aprs_t *A); - - -#endif diff --git a/dedupe.h b/dedupe.h deleted file mode 100644 index 9c0613c..0000000 --- a/dedupe.h +++ /dev/null @@ -1,10 +0,0 @@ - - -void dedupe_init (int ttl); - -void dedupe_remember (packet_t pp, int chan); - -int dedupe_check (packet_t pp, int chan); - - -/* end dedupe.h */ diff --git a/demod.h b/demod.h deleted file mode 100644 index 3233b9b..0000000 --- a/demod.h +++ /dev/null @@ -1,17 +0,0 @@ - - -/* demod.h */ - -#include "audio.h" /* for struct audio_s */ -#include "ax25_pad.h" /* for alevel_t */ - - -int demod_init (struct audio_s *pa); - -int demod_get_sample (int a); - -void demod_process_sample (int chan, int subchan, int sam); - -void demod_print_agc (int chan, int subchan); - -alevel_t demod_get_audio_level (int chan, int subchan); \ No newline at end of file diff --git a/demod_afsk.h b/demod_afsk.h deleted file mode 100644 index e44a44e..0000000 --- a/demod_afsk.h +++ /dev/null @@ -1,8 +0,0 @@ - -/* demod_afsk.h */ - - -void demod_afsk_init (int samples_per_sec, int baud, int mark_freq, - int space_freq, char profile, struct demodulator_state_s *D); - -void demod_afsk_process_sample (int chan, int subchan, int sam, struct demodulator_state_s *D); diff --git a/demod_psk.h b/demod_psk.h deleted file mode 100644 index 134b199..0000000 --- a/demod_psk.h +++ /dev/null @@ -1,7 +0,0 @@ - -/* demod_psk.h */ - - -void demod_psk_init (enum modem_t modem_type, enum v26_e v26_alt, int samples_per_sec, int bps, char profile, struct demodulator_state_s *D); - -void demod_psk_process_sample (int chan, int subchan, int sam, struct demodulator_state_s *D); diff --git a/devicesDialog.ui b/devicesDialog.ui index bf2bd9b..b090d6b 100644 --- a/devicesDialog.ui +++ b/devicesDialog.ui @@ -151,7 +151,7 @@ 20 304 - 251 + 231 17 @@ -582,6 +582,19 @@ to + + + + 260 + 304 + 161 + 17 + + + + Dark Theme + + diff --git a/digipeater.h b/digipeater.h deleted file mode 100644 index 5c84976..0000000 --- a/digipeater.h +++ /dev/null @@ -1,78 +0,0 @@ - -#ifndef DIGIPEATER_H -#define DIGIPEATER_H 1 - -#include "regex.h" - -#include "direwolf.h" /* for MAX_CHANS */ -#include "ax25_pad.h" /* for packet_t */ -#include "audio.h" /* for radio channel properties */ - - -/* - * Information required for digipeating. - * - * The configuration file reader fills in this information - * and it is passed to digipeater_init at application start up time. - */ - - -struct digi_config_s { - - - int dedupe_time; /* Don't digipeat duplicate packets */ - /* within this number of seconds. */ - -#define DEFAULT_DEDUPE 30 - -/* - * Rules for each of the [from_chan][to_chan] combinations. - */ - - regex_t alias[MAX_CHANS][MAX_CHANS]; - - regex_t wide[MAX_CHANS][MAX_CHANS]; - - int enabled[MAX_CHANS][MAX_CHANS]; - - enum preempt_e { PREEMPT_OFF, PREEMPT_DROP, PREEMPT_MARK, PREEMPT_TRACE } preempt[MAX_CHANS][MAX_CHANS]; - - // ATGP is an ugly hack for the specific need of ATGP which needs more that 8 digipeaters. - // DO NOT put this in the User Guide. On a need to know basis. - - char atgp[MAX_CHANS][MAX_CHANS][AX25_MAX_ADDR_LEN]; - - char *filter_str[MAX_CHANS+1][MAX_CHANS+1]; - // NULL or optional Packet Filter strings such as "t/m". - // Notice the size of arrays is one larger than normal. - // That extra position is for the IGate. - - int regen[MAX_CHANS][MAX_CHANS]; // Regenerate packet. - // Sort of like digipeating but passed along unchanged. -}; - -/* - * Call once at application start up time. - */ - -extern void digipeater_init (struct audio_s *p_audio_config, struct digi_config_s *p_digi_config); - -/* - * Call this for each packet received. - * Suitable packets will be queued for transmission. - */ - -extern void digipeater (int from_chan, packet_t pp); - -void digi_regen (int from_chan, packet_t pp); - - -/* Make statistics available. */ - -int digipeater_get_count (int from_chan, int to_chan); - - -#endif - -/* end digipeater.h */ - diff --git a/dlq.h b/dlq.h deleted file mode 100644 index 8771636..0000000 --- a/dlq.h +++ /dev/null @@ -1,148 +0,0 @@ - -/*------------------------------------------------------------------ - * - * Module: dlq.h - * - *---------------------------------------------------------------*/ - -#ifndef DLQ_H -#define DLQ_H 1 - -#include "ax25_pad.h" -#include "audio.h" - - -/* A transmit or receive data block for connected mode. */ - -typedef struct cdata_s { - int magic; /* For integrity checking. */ - -#define TXDATA_MAGIC 0x09110911 - - struct cdata_s *next; /* Pointer to next when part of a list. */ - - int pid; /* Protocol id. */ - - int size; /* Number of bytes allocated. */ - - int len; /* Number of bytes actually used. */ - - char data[]; /* Variable length data. */ - -} cdata_t; - - - -/* Types of things that can be in queue. */ - -typedef enum dlq_type_e {DLQ_REC_FRAME, DLQ_CONNECT_REQUEST, DLQ_DISCONNECT_REQUEST, DLQ_XMIT_DATA_REQUEST, DLQ_REGISTER_CALLSIGN, DLQ_UNREGISTER_CALLSIGN, DLQ_OUTSTANDING_FRAMES_REQUEST, DLQ_CHANNEL_BUSY, DLQ_SEIZE_CONFIRM, DLQ_CLIENT_CLEANUP} dlq_type_t; - - -/* A queue item. */ - -// TODO: call this event rather than item. -// TODO: should add fences. - -typedef struct dlq_item_s { - - struct dlq_item_s *nextp; /* Next item in queue. */ - - dlq_type_t type; /* Type of item. */ - /* See enum definition above. */ - - int chan; /* Radio channel of origin. */ - -// I'm not worried about amount of memory used but this might be a -// little clearer if a union was used for the different event types. - -// Used for received frame. - - int subchan; /* Winning "subchannel" when using multiple */ - /* decoders on one channel. */ - /* Special case, -1 means DTMF decoder. */ - /* Maybe we should have a different type in this case? */ - - int slice; /* Winning slicer. */ - - packet_t pp; /* Pointer to frame structure. */ - - alevel_t alevel; /* Audio level. */ - - int is_fx25; /* Was it from FX.25? */ - - retry_t retries; /* Effort expended to get a valid CRC. */ - /* Bits changed for regular AX.25. */ - /* Number of bytes fixed for FX.25. */ - - char spectrum[MAX_SUBCHANS*MAX_SLICERS+1]; /* "Spectrum" display for multi-decoders. */ - -// Used by requests from a client application, connect, etc. - - char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN]; - - int num_addr; /* Range 2 .. 10. */ - - int client; - - -// Used only by client request to transmit connected data. - - cdata_t *txdata; - -// Used for channel activity change. -// It is useful to know when the channel is busy either for carrier detect -// or when we are transmitting. - - int activity; /* OCTYPE_PTT for my transmission start/end. */ - /* OCTYPE_DCD if we hear someone else. */ - - int status; /* 1 for active or 0 for quiet. */ - -} dlq_item_t; - - - -void dlq_init (void); - - - -void dlq_rec_frame (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, int is_fx25, retry_t retries, char *spectrum); - -void dlq_connect_request (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, int chan, int client, int pid); - -void dlq_disconnect_request (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, int chan, int client); - -void dlq_outstanding_frames_request (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, int chan, int client); - -void dlq_xmit_data_request (char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, int chan, int client, int pid, char *xdata_ptr, int xdata_len); - -void dlq_register_callsign (char addr[AX25_MAX_ADDR_LEN], int chan, int client); - -void dlq_unregister_callsign (char addr[AX25_MAX_ADDR_LEN], int chan, int client); - -void dlq_channel_busy (int chan, int activity, int status); - -void dlq_seize_confirm (int chan); - -void dlq_client_cleanup (int client); - - - -int dlq_wait_while_empty (double timeout_val); - -struct dlq_item_s *dlq_remove (void); - -void dlq_delete (struct dlq_item_s *pitem); - - - -cdata_t *cdata_new (int pid, char *data, int len); - -void cdata_delete (cdata_t *txdata); - -void cdata_check_leak (void); - - -#endif - -/* end dlq.h */ diff --git a/dns_sd_common.h b/dns_sd_common.h deleted file mode 100644 index f104bf8..0000000 --- a/dns_sd_common.h +++ /dev/null @@ -1,7 +0,0 @@ - -#if (USE_AVAHI_CLIENT|USE_MACOS_DNSSD) - -char *dns_sd_default_service_name(void); - -#endif - diff --git a/dns_sd_dw.h b/dns_sd_dw.h deleted file mode 100644 index 79f4b86..0000000 --- a/dns_sd_dw.h +++ /dev/null @@ -1,10 +0,0 @@ - -#if (USE_AVAHI_CLIENT|USE_MACOS_DNSSD) - -#include "config.h" - -#define DNS_SD_SERVICE "_kiss-tnc._tcp" - -void dns_sd_announce (struct misc_config_s *mc); - -#endif // USE_AVAHI_CLIENT diff --git a/dtime_now.h b/dtime_now.h deleted file mode 100644 index 411534b..0000000 --- a/dtime_now.h +++ /dev/null @@ -1,18 +0,0 @@ - - -extern double dtime_realtime (void); - -extern double dtime_monotonic (void); - - -void timestamp_now (char *result, int result_size, int show_ms); - -void timestamp_user_format (char *result, int result_size, char *user_format); - -void timestamp_filename (char *result, int result_size); - - -// FIXME: remove temp workaround. -// Needs many scattered updates. - -#define dtime_now dtime_realtime diff --git a/dtmf.h b/dtmf.h deleted file mode 100644 index c1b52b9..0000000 --- a/dtmf.h +++ /dev/null @@ -1,14 +0,0 @@ -/* dtmf.h */ - - -#include "audio.h" - -void dtmf_init (struct audio_s *p_audio_config, int amp); - -char dtmf_sample (int c, float input); - -int dtmf_send (int chan, char *str, int speed, int txdelay, int txtail); - - -/* end dtmf.h */ - diff --git a/dw9600.c b/dw9600.c index 8307342..407feb1 100644 --- a/dw9600.c +++ b/dw9600.c @@ -25,6 +25,7 @@ typedef struct TStringList_T extern int fx25_mode[4]; extern int il2p_mode[4]; +extern int il2p_crc[4]; extern short rx_baudrate[5]; #define FX25_MODE_NONE 0 diff --git a/dwgps.h b/dwgps.h deleted file mode 100644 index 78f821f..0000000 --- a/dwgps.h +++ /dev/null @@ -1,61 +0,0 @@ - -/* dwgps.h */ - -#ifndef DWGPS_H -#define DWGPS_H 1 - - -#include -#include "config.h" /* for struct misc_config_s */ - - -/* - * Values for fix, equivalent to values from libgps. - * -2 = not initialized. - * -1 = error communicating with GPS receiver. - * 0 = nothing heard yet. - * 1 = had signal but lost it. - * 2 = 2D. - * 3 = 3D. - * - * Undefined float & double values are set to G_UNKNOWN. - * - */ - -enum dwfix_e { DWFIX_NOT_INIT= -2, DWFIX_ERROR= -1, DWFIX_NOT_SEEN=0, DWFIX_NO_FIX=1, DWFIX_2D=2, DWFIX_3D=3 }; - -typedef enum dwfix_e dwfix_t; - -typedef struct dwgps_info_s { - time_t timestamp; /* When last updated. System time. */ - dwfix_t fix; /* Quality of position fix. */ - double dlat; /* Latitude. Valid if fix >= 2. */ - double dlon; /* Longitude. Valid if fix >= 2. */ - float speed_knots; /* libgps uses meters/sec but we use GPS usual knots. */ - float track; /* What is difference between track and course? */ - float altitude; /* meters above mean sea level. Valid if fix == 3. */ -} dwgps_info_t; - - - - - -void dwgps_init (struct misc_config_s *pconfig, int debug); - -void dwgps_clear (dwgps_info_t *gpsinfo); - -dwfix_t dwgps_read (dwgps_info_t *gpsinfo); - -void dwgps_print (char *msg, dwgps_info_t *gpsinfo); - -void dwgps_term (void); - -void dwgps_set_data (dwgps_info_t *gpsinfo); - - -#endif /* DWGPS_H 1 */ - -/* end dwgps.h */ - - - diff --git a/dwgpsd.h b/dwgpsd.h deleted file mode 100644 index 4c0e0fd..0000000 --- a/dwgpsd.h +++ /dev/null @@ -1,22 +0,0 @@ - -/* dwgpsd.h - For communicating with daemon */ - - - -#ifndef DWGPSD_H -#define DWGPSD_H 1 - -#include "config.h" - - -int dwgpsd_init (struct misc_config_s *pconfig, int debug); - -void dwgpsd_term (void); - -#endif - - -/* end dwgpsd.h */ - - - diff --git a/dwgpsnmea.h b/dwgpsnmea.h deleted file mode 100644 index ffe5a12..0000000 --- a/dwgpsnmea.h +++ /dev/null @@ -1,32 +0,0 @@ - -/* dwgpsnmea.h - For reading NMEA sentences over serial port */ - - - -#ifndef DWGPSNMEA_H -#define DWGPSNMEA_H 1 - -#include "dwgps.h" /* for dwfix_t */ -#include "config.h" -#include "serial_port.h" /* for MYFDTYPE */ - - -int dwgpsnmea_init (struct misc_config_s *pconfig, int debug); - -MYFDTYPE dwgpsnmea_get_fd(char *wp_port_name, int speed); - -void dwgpsnmea_term (void); - - -dwfix_t dwgpsnmea_gprmc (char *sentence, int quiet, double *odlat, double *odlon, float *oknots, float *ocourse); - -dwfix_t dwgpsnmea_gpgga (char *sentence, int quiet, double *odlat, double *odlon, float *oalt, int *onsat); - - -#endif - - -/* end dwgpsnmea.h */ - - - diff --git a/dwsock.h b/dwsock.h deleted file mode 100644 index 986f6a2..0000000 --- a/dwsock.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* dwsock.h - Socket helper functions. */ - -#ifndef DWSOCK_H -#define DWSOCK_H 1 - -#define DWSOCK_IPADDR_LEN 48 // Size of string to hold IPv4 or IPv6 address. - // I think 40 would be adequate but we'll make - // it a little larger just to be safe. - // Use INET6_ADDRSTRLEN (from netinet/in.h) instead? - -int dwsock_init (void); - -int dwsock_connect (char *hostname, char *port, char *description, int allow_ipv6, int debug, char ipaddr_str[DWSOCK_IPADDR_LEN]); - /* ipaddr_str needs to be at least SOCK_IPADDR_LEN bytes */ - -char *dwsock_ia_to_text (int Family, void * pAddr, char * pStringBuf, size_t StringBufSize); - -void dwsock_close (int fd); - -#endif \ No newline at end of file diff --git a/encode_aprs.h b/encode_aprs.h deleted file mode 100644 index dc7b8bd..0000000 --- a/encode_aprs.h +++ /dev/null @@ -1,17 +0,0 @@ - -int encode_position (int messaging, int compressed, double lat, double lon, int ambiguity, int alt_ft, - char symtab, char symbol, - int power, int height, int gain, char *dir, - int course, int speed_knots, - float freq, float tone, float offset, - char *comment, - char *presult, size_t result_size); - -int encode_object (char *name, int compressed, time_t thyme, double lat, double lon, int ambiguity, - char symtab, char symbol, - int power, int height, int gain, char *dir, - int course, int speed_knots, - float freq, float tone, float offset, char *comment, - char *presult, size_t result_size); - -int encode_message (char *addressee, char *text, char *id, char *presult, size_t result_size); diff --git a/fcs_calc.h b/fcs_calc.h deleted file mode 100644 index 2e2b0ef..0000000 --- a/fcs_calc.h +++ /dev/null @@ -1,11 +0,0 @@ - -/* fcs_calc.h */ - - -unsigned short fcs_calc (unsigned char *data, int len); - -unsigned short crc16 (unsigned char *data, int len, unsigned short seed); - -/* end fcs_calc.h */ - - diff --git a/fsk_filters.h b/fsk_filters.h deleted file mode 100644 index 81c4e9a..0000000 --- a/fsk_filters.h +++ /dev/null @@ -1,7 +0,0 @@ -/* 1200 bits/sec with Audio sample rate = 11025 */ -/* Mark freq = 1200, Space freq = 2200 */ - -static const signed short m_sin_table[9] = { 0 , 7347 , 11257 , 9899 , 3909 , -3909 , -9899 , -11257 , -7347 }; -static const signed short m_cos_table[9] = { 11431 , 8756 , 1984 , -5715 , -10741 , -10741 , -5715 , 1984 , 8756 }; -static const signed short s_sin_table[9] = { 0 , 10950 , 6281 , -7347 , -10496 , 1327 , 11257 , 5130 , -8314 }; -static const signed short s_cos_table[9] = { 11431 , 3278 , -9550 , -8756 , 4527 , 11353 , 1984 , -10215 , -7844 }; diff --git a/fsk_gen_filter.h b/fsk_gen_filter.h deleted file mode 100644 index e7e8fa6..0000000 --- a/fsk_gen_filter.h +++ /dev/null @@ -1,15 +0,0 @@ - - -#ifndef FSK_GEN_FILTER_H -#define FSK_GEN_FILTER_H 1 - -#include "audio.h" -#include "fsk_demod_state.h" - -void fsk_gen_filter (int samples_per_sec, - int baud, - int mark_freq, int space_freq, - char profile, - struct demodulator_state_s *D); - -#endif \ No newline at end of file diff --git a/gen_tone.h b/gen_tone.h deleted file mode 100644 index bbe23b5..0000000 --- a/gen_tone.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * gen_tone.h - */ - - -int gen_tone_init (struct audio_s *pp, int amp, int gen_packets); - - -//int gen_tone_open (int nchan, int sample_rate, int bit_rate, int f1, int f2, int amp, char *fname); - -//int gen_tone_open_fd (int nchan, int sample_rate, int bit_rate, int f1, int f2, int amp, int fd) ; - -//int gen_tone_close (void); - -void tone_gen_put_bit (int chan, int dat); - -void gen_tone_put_sample (int chan, int a, int sam); \ No newline at end of file diff --git a/grm_sym.h b/grm_sym.h deleted file mode 100644 index 7a15041..0000000 --- a/grm_sym.h +++ /dev/null @@ -1,501 +0,0 @@ - -/* - * grm_sym.h - * - * Symbol codes for use in $PGRMWPL sentence. - * - * Copied from - * Garmin Device Interface Specification - * May 19, 2006 - * Drawing Number: 001-00063-00 Rev. C - */ - - -typedef unsigned short symbol_type_t; - -enum symbol_type_e -{ -/*--------------------------------------------------------------- -Marine symbols ----------------------------------------------------------------*/ -sym_anchor = 0, /* white anchor symbol */ -sym_bell = 1, /* white bell symbol */ -sym_diamond_grn = 2, /* green diamond symbol */ -sym_diamond_red = 3, /* red diamond symbol */ -sym_dive1 = 4, /* diver down flag 1 */ -sym_dive2 = 5, /* diver down flag 2 */ -sym_dollar = 6, /* white dollar symbol */ -sym_fish = 7, /* white fish symbol */ -sym_fuel = 8, /* white fuel symbol */ -sym_horn = 9, /* white horn symbol */ -sym_house = 10, /* white house symbol */ -sym_knife = 11, /* white knife & fork symbol */ -sym_light = 12, /* white light symbol */ -sym_mug = 13, /* white mug symbol */ -sym_skull = 14, /* white skull and crossbones symbol*/ -sym_square_grn = 15, /* green square symbol */ -sym_square_red = 16, /* red square symbol */ -sym_wbuoy = 17, /* white buoy waypoint symbol */ -sym_wpt_dot = 18, /* waypoint dot */ -sym_wreck = 19, /* white wreck symbol */ -sym_null = 20, /* null symbol (transparent) */ -sym_mob = 21, /* man overboard symbol */ -sym_buoy_ambr = 22, /* amber map buoy symbol */ -sym_buoy_blck = 23, /* black map buoy symbol */ -sym_buoy_blue = 24, /* blue map buoy symbol */ -sym_buoy_grn = 25, /* green map buoy symbol */ -sym_buoy_grn_red = 26, /* green/red map buoy symbol */ -sym_buoy_grn_wht = 27, /* green/white map buoy symbol */ -sym_buoy_orng = 28, /* orange map buoy symbol */ -sym_buoy_red = 29, /* red map buoy symbol */ -sym_buoy_red_grn = 30, /* red/green map buoy symbol */ -sym_buoy_red_wht = 31, /* red/white map buoy symbol */ -sym_buoy_violet = 32, /* violet map buoy symbol */ -sym_buoy_wht = 33, /* white map buoy symbol */ -sym_buoy_wht_grn = 34, /* white/green map buoy symbol */ -sym_buoy_wht_red = 35, /* white/red map buoy symbol */ -sym_dot = 36, /* white dot symbol */ -sym_rbcn = 37, /* radio beacon symbol */ -sym_boat_ramp = 150, /* boat ramp symbol */ -sym_camp = 151, /* campground symbol */ -sym_restrooms = 152, /* restrooms symbol */ -sym_showers = 153, /* shower symbol */ -sym_drinking_wtr = 154, /* drinking water symbol */ -sym_phone = 155, /* telephone symbol */ -sym_1st_aid = 156, /* first aid symbol */ -sym_info = 157, /* information symbol */ -sym_parking = 158, /* parking symbol */ -sym_park = 159, /* park symbol */ -sym_picnic = 160, /* picnic symbol */ -sym_scenic = 161, /* scenic area symbol */ -sym_skiing = 162, /* skiing symbol */ -sym_swimming = 163, /* swimming symbol */ -sym_dam = 164, /* dam symbol */ -sym_controlled = 165, /* controlled area symbol */ -sym_danger = 166, /* danger symbol */ -sym_restricted = 167, /* restricted area symbol */ -sym_null_2 = 168, /* null symbol */ -sym_ball = 169, /* ball symbol */ -sym_car = 170, /* car symbol */ -sym_deer = 171, /* deer symbol */ -sym_shpng_cart = 172, /* shopping cart symbol */ -sym_lodging = 173, /* lodging symbol */ -sym_mine = 174, /* mine symbol */ -sym_trail_head = 175, /* trail head symbol */ -sym_truck_stop = 176, /* truck stop symbol */ -sym_user_exit = 177, /* user exit symbol */ -sym_flag = 178, /* flag symbol */ -sym_circle_x = 179, /* circle with x in the center */ -sym_open_24hr = 180, /* open 24 hours symbol */ -sym_fhs_facility = 181, /* U Fishing Hot Spots(tm) Facility */ -sym_bot_cond = 182, /* Bottom Conditions */ -sym_tide_pred_stn = 183, /* Tide/Current Prediction Station */ -sym_anchor_prohib = 184, /* U anchor prohibited symbol */ -sym_beacon = 185, /* U beacon symbol */ -sym_coast_guard = 186, /* U coast guard symbol */ -sym_reef = 187, /* U reef symbol */ -sym_weedbed = 188, /* U weedbed symbol */ -sym_dropoff = 189, /* U dropoff symbol */ -sym_dock = 190, /* U dock symbol */ -sym_marina = 191, /* U marina symbol */ -sym_bait_tackle = 192, /* U bait and tackle symbol */ -sym_stump = 193, /* U stump symbol */ -/*--------------------------------------------------------------- -User customizable symbols -The values from sym_begin_custom to sym_end_custom inclusive are -reserved for the identification of user customizable symbols. ----------------------------------------------------------------*/ -sym_begin_custom = 7680, /* first user customizable symbol */ -sym_end_custom = 8191, /* last user customizable symbol */ -/*--------------------------------------------------------------- -Land symbols ----------------------------------------------------------------*/ -sym_is_hwy = 8192, /* interstate hwy symbol */ -sym_us_hwy = 8193, /* us hwy symbol */ -sym_st_hwy = 8194, /* state hwy symbol */ -sym_mi_mrkr = 8195, /* mile marker symbol */ -sym_trcbck = 8196, /* TracBack (feet) symbol */ -sym_golf = 8197, /* golf symbol */ -sym_sml_cty = 8198, /* small city symbol */ -sym_med_cty = 8199, /* medium city symbol */ -sym_lrg_cty = 8200, /* large city symbol */ -sym_freeway = 8201, /* intl freeway hwy symbol */ -sym_ntl_hwy = 8202, /* intl national hwy symbol */ -sym_cap_cty = 8203, /* capitol city symbol (star) */ -sym_amuse_pk = 8204, /* amusement park symbol */ -sym_bowling = 8205, /* bowling symbol */ -sym_car_rental = 8206, /* car rental symbol */ -sym_car_repair = 8207, /* car repair symbol */ -sym_fastfood = 8208, /* fast food symbol */ -sym_fitness = 8209, /* fitness symbol */ -sym_movie = 8210, /* movie symbol */ -sym_museum = 8211, /* museum symbol */ -sym_pharmacy = 8212, /* pharmacy symbol */ -sym_pizza = 8213, /* pizza symbol */ -sym_post_ofc = 8214, /* post office symbol */ -sym_rv_park = 8215, /* RV park symbol */ -sym_school = 8216, /* school symbol */ -sym_stadium = 8217, /* stadium symbol */ -sym_store = 8218, /* dept. store symbol */ -sym_zoo = 8219, /* zoo symbol */ -sym_gas_plus = 8220, /* convenience store symbol */ -sym_faces = 8221, /* live theater symbol */ -sym_ramp_int = 8222, /* ramp intersection symbol */ -sym_st_int = 8223, /* street intersection symbol */ -sym_weigh_sttn = 8226, /* inspection/weigh station symbol */ -sym_toll_booth = 8227, /* toll booth symbol */ -sym_elev_pt = 8228, /* elevation point symbol */ -sym_ex_no_srvc = 8229, /* exit without services symbol */ -sym_geo_place_mm = 8230, /* Geographic place name, man-made */ -sym_geo_place_wtr = 8231, /* Geographic place name, water */ -sym_geo_place_lnd = 8232, /* Geographic place name, land */ -sym_bridge = 8233, /* bridge symbol */ -sym_building = 8234, /* building symbol */ -sym_cemetery = 8235, /* cemetery symbol */ -sym_church = 8236, /* church symbol */ -sym_civil = 8237, /* civil location symbol */ -sym_crossing = 8238, /* crossing symbol */ -sym_hist_town = 8239, /* historical town symbol */ -sym_levee = 8240, /* levee symbol */ -sym_military = 8241, /* military location symbol */ -sym_oil_field = 8242, /* oil field symbol */ -sym_tunnel = 8243, /* tunnel symbol */ -sym_beach = 8244, /* beach symbol */ -sym_forest = 8245, /* forest symbol */ -sym_summit = 8246, /* summit symbol */ -sym_lrg_ramp_int = 8247, /* large ramp intersection symbol */ -sym_lrg_ex_no_srvc = 8248, /* large exit without services smbl */ -sym_badge = 8249, /* police/official badge symbol */ -sym_cards = 8250, /* gambling/casino symbol */ -sym_snowski = 8251, /* snow skiing symbol */ -sym_iceskate = 8252, /* ice skating symbol */ -sym_wrecker = 8253, /* tow truck (wrecker) symbol */ -sym_border = 8254, /* border crossing (port of entry) */ -sym_geocache = 8255, /* geocache location */ -sym_geocache_fnd = 8256, /* found geocache */ -sym_cntct_smiley = 8257, /* Rino contact symbol, "smiley" */ -sym_cntct_ball_cap = 8258, /* Rino contact symbol, "ball cap" */ -sym_cntct_big_ears = 8259, /* Rino contact symbol, "big ear" */ -sym_cntct_spike = 8260, /* Rino contact symbol, "spike" */ -sym_cntct_goatee = 8261, /* Rino contact symbol, "goatee" */ -sym_cntct_afro = 8262, /* Rino contact symbol, "afro" */ -sym_cntct_dreads = 8263, /* Rino contact symbol, "dreads" */ -sym_cntct_female1 = 8264, /* Rino contact symbol, "female 1" */ -sym_cntct_female2 = 8265, /* Rino contact symbol, "female 2" */ -sym_cntct_female3 = 8266, /* Rino contact symbol, "female 3" */ -sym_cntct_ranger = 8267, /* Rino contact symbol, "ranger" */ -sym_cntct_kung_fu = 8268, /* Rino contact symbol, "kung fu" */ -sym_cntct_sumo = 8269, /* Rino contact symbol, "sumo" */ -sym_cntct_pirate = 8270, /* Rino contact symbol, "pirate" */ -sym_cntct_biker = 8271, /* Rino contact symbol, "biker" */ -sym_cntct_alien = 8272, /* Rino contact symbol, "alien" */ -sym_cntct_bug = 8273, /* Rino contact symbol, "bug" */ -sym_cntct_cat = 8274, /* Rino contact symbol, "cat" */ -sym_cntct_dog = 8275, /* Rino contact symbol, "dog" */ -sym_cntct_pig = 8276, /* Rino contact symbol, "pig" */ -sym_hydrant = 8282, /* water hydrant symbol */ -sym_flag_blue = 8284, /* blue flag symbol */ -sym_flag_green = 8285, /* green flag symbol */ -sym_flag_red = 8286, /* red flag symbol */ -sym_pin_blue = 8287, /* blue pin symbol */ -sym_pin_green = 8288, /* green pin symbol */ -sym_pin_red = 8289, /* red pin symbol */ -sym_block_blue = 8290, /* blue block symbol */ -sym_block_green = 8291, /* green block symbol */ -sym_block_red = 8292, /* red block symbol */ -sym_bike_trail = 8293, /* bike trail symbol */ -sym_circle_red = 8294, /* red circle symbol */ -sym_circle_green = 8295, /* green circle symbol */ -sym_circle_blue = 8296, /* blue circle symbol */ -sym_diamond_blue = 8299, /* blue diamond symbol */ -sym_oval_red = 8300, /* red oval symbol */ -sym_oval_green = 8301, /* green oval symbol */ -sym_oval_blue = 8302, /* blue oval symbol */ -sym_rect_red = 8303, /* red rectangle symbol */ -sym_rect_green = 8304, /* green rectangle symbol */ -sym_rect_blue = 8305, /* blue rectangle symbol */ -sym_square_blue = 8308, /* blue square symbol */ -sym_letter_a_red = 8309, /* red letter 'A' symbol */ -sym_letter_b_red = 8310, /* red letter 'B' symbol */ -sym_letter_c_red = 8311, /* red letter 'C' symbol */ -sym_letter_d_red = 8312, /* red letter 'D' symbol */ -sym_letter_a_green = 8313, /* green letter 'A' symbol */ -sym_letter_c_green = 8314, /* green letter 'C' symbol */ -sym_letter_b_green = 8315, /* green letter 'B' symbol */ -sym_letter_d_green = 8316, /* green letter 'D' symbol */ -sym_letter_a_blue = 8317, /* blue letter 'A' symbol */ -sym_letter_b_blue = 8318, /* blue letter 'B' symbol */ -sym_letter_c_blue = 8319, /* blue letter 'C' symbol */ -sym_letter_d_blue = 8320, /* blue letter 'D' symbol */ -sym_number_0_red = 8321, /* red number '0' symbol */ -sym_number_1_red = 8322, /* red number '1' symbol */ -sym_number_2_red = 8323, /* red number '2' symbol */ -sym_number_3_red = 8324, /* red number '3' symbol */ -sym_number_4_red = 8325, /* red number '4' symbol */ -sym_number_5_red = 8326, /* red number '5' symbol */ -sym_number_6_red = 8327, /* red number '6' symbol */ -sym_number_7_red = 8328, /* red number '7' symbol */ -sym_number_8_red = 8329, /* red number '8' symbol */ -sym_number_9_red = 8330, /* red number '9' symbol */ -sym_number_0_green = 8331, /* green number '0' symbol */ -sym_number_1_green = 8332, /* green number '1' symbol */ -sym_number_2_green = 8333, /* green number '2' symbol */ -sym_number_3_green = 8334, /* green number '3' symbol */ -sym_number_4_green = 8335, /* green number '4' symbol */ -sym_number_5_green = 8336, /* green number '5' symbol */ -sym_number_6_green = 8337, /* green number '6' symbol */ -sym_number_7_green = 8338, /* green number '7' symbol */ -sym_number_8_green = 8339, /* green number '8' symbol */ -sym_number_9_green = 8340, /* green number '9' symbol */ -sym_number_0_blue = 8341, /* blue number '0' symbol */ -sym_number_1_blue = 8342, /* blue number '1' symbol */ -sym_number_2_blue = 8343, /* blue number '2' symbol */ -sym_number_3_blue = 8344, /* blue number '3' symbol */ -sym_number_4_blue = 8345, /* blue number '4' symbol */ -sym_number_5_blue = 8346, /* blue number '5' symbol */ -sym_number_6_blue = 8347, /* blue number '6' symbol */ -sym_number_7_blue = 8348, /* blue number '7' symbol */ -sym_number_8_blue = 8349, /* blue number '8' symbol */ -sym_number_9_blue = 8350, /* blue number '9' symbol */ -sym_triangle_blue = 8351, /* blue triangle symbol */ -sym_triangle_green = 8352, /* green triangle symbol */ -sym_triangle_red = 8353, /* red triangle symbol */ -sym_food_asian = 8359, /* asian food symbol */ -sym_food_deli = 8360, /* deli symbol */ -sym_food_italian = 8361, /* italian food symbol */ -sym_food_seafood = 8362, /* seafood symbol */ -sym_food_steak = 8363, /* steak symbol */ -/*--------------------------------------------------------------- -Aviation symbols ----------------------------------------------------------------*/ -sym_airport = 16384, /* airport symbol */ -sym_int = 16385, /* intersection symbol */ -sym_ndb = 16386, /* non-directional beacon symbol */ -sym_vor = 16387, /* VHF omni-range symbol */ -sym_heliport = 16388, /* heliport symbol */ -sym_private = 16389, /* private field symbol */ -sym_soft_fld = 16390, /* soft field symbol */ -sym_tall_tower = 16391, /* tall tower symbol */ -sym_short_tower = 16392, /* short tower symbol */ -sym_glider = 16393, /* glider symbol */ -sym_ultralight = 16394, /* ultralight symbol */ -sym_parachute = 16395, /* parachute symbol */ -sym_vortac = 16396, /* VOR/TACAN symbol */ -sym_vordme = 16397, /* VOR-DME symbol */ -sym_faf = 16398, /* first approach fix */ -sym_lom = 16399, /* localizer outer marker */ -sym_map = 16400, /* missed approach point */ -sym_tacan = 16401, /* TACAN symbol */ -sym_seaplane = 16402, /* Seaplane Base */ -}; - - - -/* - * Mapping from APRS symbols to Garmin. - */ - -// TODO: NEEDS MORE WORK!!! - - -#define SYMTAB_SIZE 95 - -#define sym_default sym_diamond_grn - - -static const symbol_type_t grm_primary_symtab[SYMTAB_SIZE] = { - - sym_default, // 00 --no-symbol-- - sym_cntct_ranger, // ! 01 Police, Sheriff - sym_default, // " 02 reserved (was rain) - sym_rbcn, // # 03 DIGI (white center) - sym_phone, // $ 04 PHONE - sym_rbcn, // % 05 DX CLUSTER - sym_rbcn, // & 06 HF GATEway - sym_glider, // ' 07 Small AIRCRAFT - sym_rbcn, // ( 08 Mobile Satellite Station - sym_default, // ) 09 Wheelchair (handicapped) - sym_car, // * 10 SnowMobile - sym_1st_aid, // + 11 Red Cross - sym_cntct_ball_cap, // , 12 Boy Scouts - sym_house, // - 13 House QTH (VHF) - sym_default, // . 14 X - sym_default, // / 15 Red Dot - sym_default, // 0 16 # circle (obsolete) - sym_default, // 1 17 TBD - sym_default, // 2 18 TBD - sym_default, // 3 19 TBD - sym_default, // 4 20 TBD - sym_default, // 5 21 TBD - sym_default, // 6 22 TBD - sym_default, // 7 23 TBD - sym_default, // 8 24 TBD - sym_default, // 9 25 TBD - sym_default, // : 26 FIRE - sym_camp, // ; 27 Campground (Portable ops) - sym_cntct_biker, // < 28 Motorcycle - sym_default, // = 29 RAILROAD ENGINE - sym_car, // > 30 CAR - sym_default, // ? 31 SERVER for Files - sym_default, // @ 32 HC FUTURE predict (dot) - sym_1st_aid, // A 33 Aid Station - sym_rbcn, // B 34 BBS or PBBS - sym_boat_ramp, // C 35 Canoe - sym_default, // D 36 - sym_default, // E 37 EYEBALL (Eye catcher!) - sym_default, // F 38 Farm Vehicle (tractor) - sym_default, // G 39 Grid Square (6 digit) - sym_lodging, // H 40 HOTEL (blue bed symbol) - sym_rbcn, // I 41 TcpIp on air network stn - sym_default, // J 42 - sym_school, // K 43 School - sym_default, // L 44 PC user - sym_default, // M 45 MacAPRS - sym_default, // N 46 NTS Station - sym_parachute, // O 47 BALLOON - sym_cntct_ranger, // P 48 Police - sym_default, // Q 49 TBD - sym_rv_park, // R 50 REC. VEHICLE - sym_glider, // S 51 SHUTTLE - sym_default, // T 52 SSTV - sym_car, // U 53 BUS - sym_cntct_biker, // V 54 ATV - sym_default, // W 55 National WX Service Site - sym_default, // X 56 HELO - sym_default, // Y 57 YACHT (sail) - sym_default, // Z 58 WinAPRS - sym_cntct_smiley, // [ 59 Human/Person (HT) - sym_triangle_green, // \ 60 TRIANGLE(DF station) - sym_default, // ] 61 MAIL/PostOffice(was PBBS) - sym_glider, // ^ 62 LARGE AIRCRAFT - sym_default, // _ 63 WEATHER Station (blue) - sym_rbcn, // ` 64 Dish Antenna - sym_1st_aid, // a 65 AMBULANCE - sym_cntct_biker, // b 66 BIKE - sym_default, // c 67 Incident Command Post - sym_hydrant, // d 68 Fire dept - sym_deer, // e 69 HORSE (equestrian) - sym_hydrant, // f 70 FIRE TRUCK - sym_glider, // g 71 Glider - sym_1st_aid, // h 72 HOSPITAL - sym_default, // i 73 IOTA (islands on the air) - sym_car, // j 74 JEEP - sym_car, // k 75 TRUCK - sym_default, // l 76 Laptop - sym_rbcn, // m 77 Mic-E Repeater - sym_default, // n 78 Node (black bulls-eye) - sym_default, // o 79 EOC - sym_cntct_dog, // p 80 ROVER (puppy, or dog) - sym_default, // q 81 GRID SQ shown above 128 m - sym_rbcn, // r 82 Repeater - sym_default, // s 83 SHIP (pwr boat) - sym_truck_stop, // t 84 TRUCK STOP - sym_truck_stop, // u 85 TRUCK (18 wheeler) - sym_car, // v 86 VAN - sym_drinking_wtr, // w 87 WATER station - sym_default, // x 88 xAPRS (Unix) - sym_tall_tower, // y 89 YAGI @ QTH - sym_default, // z 90 TBD - sym_default, // { 91 - sym_default, // | 92 TNC Stream Switch - sym_default, // } 93 - sym_default }; // ~ 94 TNC Stream Switch - -static const symbol_type_t grm_alternate_symtab[SYMTAB_SIZE] = { - - sym_default, // 00 --no-symbol-- - sym_default, // ! 01 EMERGENCY (!) - sym_default, // " 02 reserved - sym_default, // # 03 OVERLAY DIGI (green star) - sym_default, // $ 04 Bank or ATM (green box) - sym_default, // % 05 Power Plant with overlay - sym_rbcn, // & 06 I=Igte IGate R=RX T=1hopTX 2=2hopTX - sym_default, // ' 07 Crash (& now Incident sites) - sym_default, // ( 08 CLOUDY (other clouds w ovrly) - sym_hydrant, // ) 09 Firenet MEO, MODIS Earth Obs. - sym_default, // * 10 SNOW (& future ovrly codes) - sym_default, // + 11 Church - sym_cntct_female1, // , 12 Girl Scouts - sym_house, // - 13 House (H=HF) (O = Op Present) - sym_default, // . 14 Ambiguous (Big Question mark) - sym_default, // / 15 Waypoint Destination - sym_default, // 0 16 CIRCLE (E/I/W=IRLP/Echolink/WIRES) - sym_default, // 1 17 - sym_default, // 2 18 - sym_default, // 3 19 - sym_default, // 4 20 - sym_default, // 5 21 - sym_default, // 6 22 - sym_default, // 7 23 - sym_default, // 8 24 802.11 or other network node - sym_default, // 9 25 Gas Station (blue pump) - sym_default, // : 26 Hail (& future ovrly codes) - sym_park, // ; 27 Park/Picnic area - sym_default, // < 28 ADVISORY (one WX flag) - sym_rbcn, // = 29 APRStt Touchtone (DTMF users) - sym_car, // > 30 OVERLAID CAR - sym_default, // ? 31 INFO Kiosk (Blue box with ?) - sym_default, // @ 32 HURRICANE/Trop-Storm - sym_default, // A 33 overlayBOX DTMF & RFID & XO - sym_default, // B 34 Blwng Snow (& future codes) - sym_coast_guard, // C 35 Coast Guard - sym_default, // D 36 Drizzle (proposed APRStt) - sym_default, // E 37 Smoke (& other vis codes) - sym_default, // F 38 Freezng rain (&future codes) - sym_default, // G 39 Snow Shwr (& future ovrlys) - sym_default, // H 40 Haze (& Overlay Hazards) - sym_default, // I 41 Rain Shower - sym_default, // J 42 Lightning (& future ovrlys) - sym_rbcn, // K 43 Kenwood HT (W) - sym_light, // L 44 Lighthouse - sym_default, // M 45 MARS (A=Army,N=Navy,F=AF) - sym_default, // N 46 Navigation Buoy - sym_default, // O 47 Rocket - sym_default, // P 48 Parking - sym_default, // Q 49 QUAKE - sym_default, // R 50 Restaurant - sym_rbcn, // S 51 Satellite/Pacsat - sym_default, // T 52 Thunderstorm - sym_default, // U 53 SUNNY - sym_default, // V 54 VORTAC Nav Aid - sym_default, // W 55 # NWS site (NWS options) - sym_pharmacy, // X 56 Pharmacy Rx (Apothicary) - sym_rbcn, // Y 57 Radios and devices - sym_default, // Z 58 - sym_default, // [ 59 W.Cloud (& humans w Ovrly) - sym_default, // \ 60 New overlayable GPS symbol - sym_default, // ] 61 - sym_glider, // ^ 62 # Aircraft (shows heading) - sym_default, // _ 63 # WX site (green digi) - sym_default, // ` 64 Rain (all types w ovrly) - sym_default, // a 65 ARRL, ARES, WinLINK - sym_default, // b 66 Blwng Dst/Snd (& others) - sym_default, // c 67 CD triangle RACES/SATERN/etc - sym_default, // d 68 DX spot by callsign - sym_default, // e 69 Sleet (& future ovrly codes) - sym_default, // f 70 Funnel Cloud - sym_default, // g 71 Gale Flags - sym_default, // h 72 Store. or HAMFST Hh=HAM store - sym_default, // i 73 BOX or points of Interest - sym_default, // j 74 WorkZone (Steam Shovel) - sym_car, // k 75 Special Vehicle SUV,ATV,4x4 - sym_default, // l 76 Areas (box,circles,etc) - sym_default, // m 77 Value Sign (3 digit display) - sym_default, // n 78 OVERLAY TRIANGLE - sym_default, // o 79 small circle - sym_default, // p 80 Prtly Cldy (& future ovrlys) - sym_default, // q 81 - sym_restrooms, // r 82 Restrooms - sym_default, // s 83 OVERLAY SHIP/boat (top view) - sym_default, // t 84 Tornado - sym_car, // u 85 OVERLAID TRUCK - sym_car, // v 86 OVERLAID Van - sym_default, // w 87 Flooding - sym_wreck, // x 88 Wreck or Obstruction ->X<- - sym_default, // y 89 Skywarn - sym_default, // z 90 OVERLAID Shelter - sym_default, // { 91 Fog (& future ovrly codes) - sym_default, // | 92 TNC Stream Switch - sym_default, // } 93 - sym_default }; // ~ 94 TNC Stream Switch - diff --git a/hdlc_send.h b/hdlc_send.h deleted file mode 100644 index 4f8a105..0000000 --- a/hdlc_send.h +++ /dev/null @@ -1,17 +0,0 @@ - -/* hdlc_send.h */ - -// In version 1.7 an extra layer of abstraction was added here. -// Rather than calling hdlc_send_frame, we now use another function -// which sends AX.25, FX.25, or IL2P depending on - -#include "ax25_pad.h" -#include "audio.h" - -int layer2_send_frame (int chan, packet_t pp, int bad_fcs, struct audio_s *audio_config_p); - -int layer2_preamble_postamble (int chan, int flags, int finish, struct audio_s *audio_config_p); - -/* end hdlc_send.h */ - - diff --git a/igate.h b/igate.h deleted file mode 100644 index 8203ac7..0000000 --- a/igate.h +++ /dev/null @@ -1,128 +0,0 @@ - -/*---------------------------------------------------------------------------- - * - * Name: igate.h - * - * Purpose: Interface to the Internet Gateway functions. - * - *-----------------------------------------------------------------------------*/ - - -#ifndef IGATE_H -#define IGATE_H 1 - - -#include "ax25_pad.h" -#include "digipeater.h" -#include "audio.h" - - -#define DEFAULT_IGATE_PORT 14580 - - - -struct igate_config_s { - -/* - * For logging into the IGate server. - */ - char t2_server_name[40]; /* Tier 2 IGate server name. */ - - int t2_server_port; /* Typically 14580. */ - - char t2_login[AX25_MAX_ADDR_LEN];/* e.g. WA9XYZ-15 */ - /* Note that the ssid could be any two alphanumeric */ - /* characters not just 1 thru 15. */ - /* Could be same or different than the radio call(s). */ - /* Not sure what the consequences would be. */ - - char t2_passcode[8]; /* Max. 5 digits. Could be "-1". */ - - char *t2_filter; /* Optional filter for IS -> RF direction. */ - /* This is the "server side" filter. */ - /* A better name would be subscription or something */ - /* like that because we can only ask for more. */ - -/* - * For transmitting. - */ - int tx_chan; /* Radio channel for transmitting. */ - /* 0=first, etc. -1 for none. */ - /* Presently IGate can transmit on only a single channel. */ - /* A future version might generalize this. */ - /* Each transmit channel would have its own client side filtering. */ - - char tx_via[80]; /* VIA path for transmitting third party packets. */ - /* Usual text representation. */ - /* Must start with "," if not empty so it can */ - /* simply be inserted after the destination address. */ - - int max_digi_hops; /* Maximum number of digipeater hops possible for via path. */ - /* Derived from the SSID when last character of address is a digit. */ - /* e.g. "WIDE1-1,WIDE5-2" would be 3. */ - /* This is useful to know so we can determine how many */ - /* stations we might be able to reach. */ - - int tx_limit_1; /* Max. packets to transmit in 1 minute. */ - - int tx_limit_5; /* Max. packets to transmit in 5 minutes. */ - - int igmsp; /* Number of message sender position reports to allow. */ - /* Common practice is to default to 1. */ - /* We allow additional flexibility of 0 to disable feature */ - /* or a small number to allow more. */ - -/* - * Receiver to IS data options. - */ - int rx2ig_dedupe_time; /* seconds. 0 to disable. */ - -/* - * Special SATgate mode to delay packets heard directly. - */ - int satgate_delay; /* seconds. 0 to disable. */ -}; - - -#define IGATE_TX_LIMIT_1_DEFAULT 6 -#define IGATE_TX_LIMIT_1_MAX 20 - -#define IGATE_TX_LIMIT_5_DEFAULT 20 -#define IGATE_TX_LIMIT_5_MAX 80 - -#define IGATE_RX2IG_DEDUPE_TIME 0 /* Issue 85. 0 means disable dupe checking in RF>IS direction. */ - /* See comments in rx_to_ig_remember & rx_to_ig_allow. */ - /* Currently there is no configuration setting to change this. */ - -#define DEFAULT_SATGATE_DELAY 10 -#define MIN_SATGATE_DELAY 5 -#define MAX_SATGATE_DELAY 30 - - -/* Call this once at startup */ - -void igate_init (struct audio_s *p_audio_config, struct igate_config_s *p_igate_config, struct digi_config_s *p_digi_config, int debug_level); - -/* Call this with each packet received from the radio. */ - -void igate_send_rec_packet (int chan, packet_t recv_pp); - -/* This when digipeater transmits. Set bydigi to 1 . */ - -void ig_to_tx_remember (packet_t pp, int chan, int bydigi); - - - -/* Get statistics for IGATE status beacon. */ - -int igate_get_msg_cnt (void); - -int igate_get_pkt_cnt (void); - -int igate_get_upl_cnt (void); - -int igate_get_dnl_cnt (void); - - - -#endif diff --git a/il2p.c b/il2p.c index e51264c..6a284f2 100644 --- a/il2p.c +++ b/il2p.c @@ -42,11 +42,44 @@ along with QtSoundModem. If not, see http://www.gnu.org/licenses // IP2P receive code (il2p_rec_bit) is called from the bit receiving code in ax25_demod.c, so includes parallel decoders - - - #include "UZ7HOStuff.h" +#include // for uint64_t + + // Oct 2023 Nino has added an optional crc + +// Hamming(7,4) Encoding Table +// Enter this table with the 4-bit value to be encoded. +// Returns 7-bit encoded value, with high bit zero'd. + +uint8_t Hamming74EncodeTable[16] = { 0x0, 0x71, 0x62, 0x13, 0x54, 0x25, 0x36, 0x47, 0x38, 0x49, 0x5a, 0x2b, 0x6c, 0x1d, 0xe, 0x7f }; + +// Hamming(7,4) Decoding Table +// Enter this table with 7-bit encoded value, high bit masked. +// Returns 4-bit decoded value. + +uint16_t Hamming74DecodeTable[128] = { \ + 0x0, 0x0, 0x0, 0x3, 0x0, 0x5, 0xe, 0x7, \ + 0x0, 0x9, 0xe, 0xb, 0xe, 0xd, 0xe, 0xe, \ + 0x0, 0x3, 0x3, 0x3, 0x4, 0xd, 0x6, 0x3, \ + 0x8, 0xd, 0xa, 0x3, 0xd, 0xd, 0xe, 0xd, \ + 0x0, 0x5, 0x2, 0xb, 0x5, 0x5, 0x6, 0x5, \ + 0x8, 0xb, 0xb, 0xb, 0xc, 0x5, 0xe, 0xb, \ + 0x8, 0x1, 0x6, 0x3, 0x6, 0x5, 0x6, 0x6, \ + 0x8, 0x8, 0x8, 0xb, 0x8, 0xd, 0x6, 0xf, \ + 0x0, 0x9, 0x2, 0x7, 0x4, 0x7, 0x7, 0x7, \ + 0x9, 0x9, 0xa, 0x9, 0xc, 0x9, 0xe, 0x7, \ + 0x4, 0x1, 0xa, 0x3, 0x4, 0x4, 0x4, 0x7, \ + 0xa, 0x9, 0xa, 0xa, 0x4, 0xd, 0xa, 0xf, \ + 0x2, 0x1, 0x2, 0x2, 0xc, 0x5, 0x2, 0x7, \ + 0xc, 0x9, 0x2, 0xb, 0xc, 0xc, 0xc, 0xf, \ + 0x1, 0x1, 0x2, 0x1, 0x4, 0x1, 0x6, 0xf, \ + 0x8, 0x1, 0xa, 0xf, 0xc, 0xf, 0xf, 0xf }; + + + + + void Debugprintf(const char * format, ...); int SMUpdatePhaseConstellation(int chan, float * Phases, float * Mags, int intPSKPhase, int Count); @@ -109,7 +142,6 @@ int MaxMagIndex = 0; #ifndef FX25_H #define FX25_H -#include // for uint64_t extern unsigned int pskStates[4]; @@ -343,6 +375,7 @@ struct packet_s { unsigned char frame_data[AX25_MAX_PACKET_LEN + 1]; /* Raw frame contents, without the CRC. */ + unsigned char crc[4]; // received crc int magic2; /* Will get stomped on if above overflows. */ }; @@ -1015,6 +1048,39 @@ void multi_modem_process_rec_packet(int snd_ch, int subchan, int slice, packet_t sprintf(Mode, "IL2P %d", centreFreq); + // check crc if enabled + + if (il2p_crc[snd_ch]) + { + unsigned short CRCMSG; + unsigned short CRCCALC; + uint8_t crc[4]; + + // check crc if enabled + + // The four encoded CRC bytes are arranged : + // | CRC3 | CRC2 | CRC1 | CRC0 | but we store as received, so F->crc[0] is CRC3 + // CRC3 encoded from high nibble of 16 - bit CRC value (from crc2) + // CRC0 encoded from low nibble of 16 - bit CRC value (from crc1) + + crc[0] = Hamming74DecodeTable[(pp->crc[0] & 0x7f)]; + crc[1] = Hamming74DecodeTable[(pp->crc[1] & 0x7f)]; + crc[2] = Hamming74DecodeTable[(pp->crc[2] & 0x7f)]; + crc[3] = Hamming74DecodeTable[(pp->crc[3] & 0x7f)]; + + CRCMSG = crc[0] << 12 | crc[1] << 8 | crc[2] << 4 | crc[3]; + + CRCCALC = get_fcs(pp->frame_data, pp->frame_len); + + if (CRCCALC != CRCMSG) + { + Debugprintf("CRC Error Decoder %d Received %x Sent %x", subchan, CRCCALC, CRCMSG); + // freeString(data); + // ax25_delete(pp); + // return; + } + } + stringAdd(data, pp->frame_data, pp->frame_len + 2); // QTSM assumes a CRC ax25_delete(pp); @@ -3151,6 +3217,13 @@ int il2p_type_1_header(packet_t pp, int max_fec, unsigned char *hdr) ax25_get_addr_no_ssid(pp, AX25_SOURCE, src_addr); int src_ssid = ax25_get_ssid(pp, AX25_SOURCE); + if ((pp->frame_data[6] & 0x80) == (pp->frame_data[13] & 0x80)) + { + // Both C bits are the same (ax.25 v1) so can't be sent as type 1 as will be changed + + return -1; + } + unsigned char *a = (unsigned char *)dst_addr; for (int i = 0; *a != '\0'; i++, a++) { if (*a < ' ' || *a > '_') { @@ -3919,7 +3992,7 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit) //assert(slice >= 0 && slice < MAX_SLICERS); F = il2p_context[chan][subchan][slice] = (struct il2p_context_s *)malloc(sizeof(struct il2p_context_s)); //assert(F != NULL); - memset(F, 0, sizeof(struct il2p_context_s)); +memset(F, 0, sizeof(struct il2p_context_s)); } // Accumulate most recent 24 bits received. Most recent is LSB. @@ -3942,7 +4015,7 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit) nPhases[chan][subchan][slice] = 0; // Determine Centre Freq - + centreFreq[chan] = GuessCentreFreq(chan); } else if (__builtin_popcount((~F->acc & 0x00ffffff) ^ IL2P_SYNC_WORD) <= 1) { @@ -3956,7 +4029,7 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit) centreFreq[chan] = GuessCentreFreq(chan); nPhases[chan][subchan][slice] = 0; } - + break; case IL2P_HEADER: // Gathering the header. @@ -3990,7 +4063,7 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit) F->eplen = il2p_payload_compute(&plprop, len, max_fec); if (il2p_get_debug() >= 1) - { + { Debugprintf("Header type %d, max fec = %d", hdr_type, max_fec); Debugprintf("Need to collect %d encoded bytes for %d byte payload.", F->eplen, len); Debugprintf("%d small blocks of %d and %d large blocks of %d. %d parity symbols per block", @@ -4008,9 +4081,21 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit) F->pc = 0; F->state = IL2P_PAYLOAD; } - else if (F->eplen == 0) { // No payload. + else if (F->eplen == 0) + { + // No payload. + F->pc = 0; - F->state = IL2P_DECODE; + + if (il2p_crc[chan]) + { + // enter collect crc state + + F->crccount = 0; + F->state = IL2P_CRC; + } + else + F->state = IL2P_DECODE; } else { // Error. @@ -4039,16 +4124,47 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit) else { F->spayload[F->pc++] = (~F->acc) & 0xff; } - if (F->pc == F->eplen) { + if (F->pc == F->eplen) + { + // got frame. See if need crc - // TODO?: for symmetry it seems like we should clarify the payload before combining. + if (il2p_crc[chan]) + { + // enter collect crc state - F->state = IL2P_DECODE; + F->crccount = 0; + F->state = IL2P_CRC; + } + else + F->state = IL2P_DECODE; } } break; + case IL2P_CRC: + + F->bc++; + if (F->bc == 8) + { + // full byte has been collected. + F->bc = 0; + if (!F->polarity) + F->crc[F->crccount++] = F->acc & 0xff; + else + F->crc[F->crccount++] = (~F->acc) & 0xff; + + if (F->crccount == 4) + { + // have all crc bytes. enter DECODE + + F->state = IL2P_DECODE; + } + } + + break; + case IL2P_DECODE: + // We get here after a good header and any payload has been collected. // Processing is delayed by one bit but I think it makes the logic cleaner. // During unit testing be sure to send an extra bit to flush it out at the end. @@ -4077,6 +4193,18 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit) // TODO: Could we put last 3 arguments in packet object rather than passing around separately? + // if using crc pass received crc to packet object + + if (il2p_crc[chan]) + { + //copy crc bytes to packet object + + pp->crc[0] = F->crc[0]; + pp->crc[1] = F->crc[1]; + pp->crc[2] = F->crc[2]; + pp->crc[3] = F->crc[3]; + } + multi_modem_process_rec_packet(chan, subchan, slice, pp, alevel, retries, is_fx25, slice, centreFreq[chan]); } } // end block for local variables. @@ -4269,13 +4397,19 @@ static void send_bit(int chan, int b, int polarity); * *--------------------------------------------------------------*/ + string * il2p_send_frame(int chan, packet_t pp, int max_fec, int polarity) { - unsigned char encoded[IL2P_MAX_PACKET_SIZE]; + unsigned char encoded[IL2P_MAX_PACKET_SIZE] = ""; string * packet = newString(); int preamblecount; unsigned char preamble[1024]; + // The data includes the 2 byte crc but length doesn't + + uint8_t crc1 = pp->frame_data[pp->frame_len]; // Low 8 bits + uint8_t crc2 = pp->frame_data[pp->frame_len + 1]; // High 8 bits + encoded[0] = (IL2P_SYNC_WORD >> 16) & 0xff; encoded[1] = (IL2P_SYNC_WORD >> 8) & 0xff; encoded[2] = (IL2P_SYNC_WORD) & 0xff; @@ -4289,6 +4423,24 @@ string * il2p_send_frame(int chan, packet_t pp, int max_fec, int polarity) elen += IL2P_SYNC_WORD_SIZE; + // if we are using crc add it now. elen should point to end of data + // crc should be at pp->frame_data[pp->frame_len] + + if (il2p_crc[chan]) + { + // The four encoded CRC bytes are arranged : + // | CRC3 | CRC2 | CRC1 | CRC0 | + + // CRC3 encoded from high nibble of 16 - bit CRC value (from crc2) + // CRC0 encoded from low nibble of 16 - bit CRC value (from crc1) + + encoded[elen++] = Hamming74EncodeTable[crc2 >> 4]; + encoded[elen++] = Hamming74EncodeTable[crc2 & 0xf]; + encoded[elen++] = Hamming74EncodeTable[crc1 >> 4]; + encoded[elen++] = Hamming74EncodeTable[crc1 &0xf]; + } + + number_of_bits_sent[chan] = 0; if (il2p_get_debug() >= 1) { @@ -4366,7 +4518,7 @@ string * fill_il2p_data(int snd_ch, string * data) // Call il2p_send_frame to build the bit stream pp->frame_len = data->Length - 2; // Included CRC - memcpy(pp->frame_data, data->Data, data->Length); + memcpy(pp->frame_data, data->Data, data->Length); // Copy the crc in case we are going to send it result = il2p_send_frame(snd_ch, pp, 1, 0); diff --git a/kiss.h b/kiss.h deleted file mode 100644 index 1dc40da..0000000 --- a/kiss.h +++ /dev/null @@ -1,24 +0,0 @@ - -/* - * Name: kiss.h - * - * This is for the pseudo terminal KISS interface. - */ - - -#include "ax25_pad.h" /* for packet_t */ - -#include "config.h" - -#include "kiss_frame.h" // for struct kissport_status_s - - -void kisspt_init (struct misc_config_s *misc_config); - -void kisspt_send_rec_packet (int chan, int kiss_cmd, unsigned char *fbuf, int flen, - struct kissport_status_s *notused1, int notused2); - -void kisspt_set_debug (int n); - - -/* end kiss.h */ diff --git a/kiss_frame.h b/kiss_frame.h deleted file mode 100644 index 941f5c0..0000000 --- a/kiss_frame.h +++ /dev/null @@ -1,126 +0,0 @@ - -/* kiss_frame.h */ - -#ifndef KISS_FRAME_H -#define KISS_FRAME_H - - -#include "audio.h" /* for struct audio_s */ - - -/* - * The first byte of a KISS frame has: - * channel in upper nybble. - * command in lower nybble. - */ - -#define KISS_CMD_DATA_FRAME 0 -#define KISS_CMD_TXDELAY 1 -#define KISS_CMD_PERSISTENCE 2 -#define KISS_CMD_SLOTTIME 3 -#define KISS_CMD_TXTAIL 4 -#define KISS_CMD_FULLDUPLEX 5 -#define KISS_CMD_SET_HARDWARE 6 -#define XKISS_CMD_DATA 12 // Not supported. http://he.fi/pub/oh7lzb/bpq/multi-kiss.pdf -#define XKISS_CMD_POLL 14 // Not supported. -#define KISS_CMD_END_KISS 15 - - - -/* - * Special characters used by SLIP protocol. - */ - -#define FEND 0xC0 -#define FESC 0xDB -#define TFEND 0xDC -#define TFESC 0xDD - - - -enum kiss_state_e { - KS_SEARCHING = 0, /* Looking for FEND to start KISS frame. */ - /* Must be 0 so we can simply zero whole structure to initialize. */ - KS_COLLECTING}; /* In process of collecting KISS frame. */ - - -#define MAX_KISS_LEN 2048 /* Spec calls for at least 1024. */ - /* Might want to make it longer to accommodate */ - /* maximum packet length. */ - -#define MAX_NOISE_LEN 100 - -typedef struct kiss_frame_s { - - enum kiss_state_e state; - - unsigned char kiss_msg[MAX_KISS_LEN]; - /* Leading FEND is optional. */ - /* Contains escapes and ending FEND. */ - int kiss_len; - - unsigned char noise[MAX_NOISE_LEN]; - int noise_len; - -} kiss_frame_t; - - -// This is used only for TCPKISS but it put in kissnet.h, -// there would be a circular dependency between the two header files. -// Each KISS TCP port has its own status block. - -struct kissport_status_s { - - struct kissport_status_s *pnext; // To next in list. - - volatile int arg2; // temp for passing second arg into - // kissnet_listen_thread - - int tcp_port; // default 8001 - - int chan; // Radio channel for this tcp port. - // -1 for all. - - // The default is a limit of 3 client applications at the same time. - // You can increase the limit by changing the line below. - // A larger number consumes more resources so don't go crazy by making it larger than needed. - // TODO: Should this be moved to direwolf.h so max number of audio devices - // client apps are in the same place? - -#define MAX_NET_CLIENTS 3 - - int client_sock[MAX_NET_CLIENTS]; - /* File descriptor for socket for */ - /* communication with client application. */ - /* Set to -1 if not connected. */ - /* (Don't use SOCKET type because it is unsigned.) */ - - kiss_frame_t kf[MAX_NET_CLIENTS]; - /* Accumulated KISS frame and state of decoder. */ -}; - - - -#ifndef KISSUTIL -void kiss_frame_init (struct audio_s *pa); -#endif - -int kiss_encapsulate (unsigned char *in, int ilen, unsigned char *out); - -int kiss_unwrap (unsigned char *in, int ilen, unsigned char *out); - -void kiss_rec_byte (kiss_frame_t *kf, unsigned char ch, int debug, struct kissport_status_s *kps, int client, - void (*sendfun)(int chan, int kiss_cmd, unsigned char *fbuf, int flen, struct kissport_status_s *onlykps, int onlyclient)); - -typedef enum fromto_e { FROM_CLIENT=0, TO_CLIENT=1 } fromto_t; - -void kiss_process_msg (unsigned char *kiss_msg, int kiss_len, int debug, struct kissport_status_s *kps, int client, - void (*sendfun)(int chan, int kiss_cmd, unsigned char *fbuf, int flen, struct kissport_status_s *onlykps, int onlyclient)); - -void kiss_debug_print (fromto_t fromto, char *special, unsigned char *pmsg, int msg_len); - - -#endif // KISS_FRAME_H - - -/* end kiss_frame.h */ diff --git a/kiss_mode.c b/kiss_mode.c index 5adba5d..72688a7 100644 --- a/kiss_mode.c +++ b/kiss_mode.c @@ -245,7 +245,6 @@ void ProcessKISSFrame(void * socket, UCHAR * Msg, int Len) Add(&KISS.buffer[Chan], TXMSG); } - return; case KISS_DATA: diff --git a/kissnet.h b/kissnet.h deleted file mode 100644 index 469e4e6..0000000 --- a/kissnet.h +++ /dev/null @@ -1,29 +0,0 @@ - -/* - * Name: kissnet.h - */ - -#ifndef KISSNET_H -#define KISSNET_H - -#include "ax25_pad.h" /* for packet_t */ - -#include "config.h" - -#include "kiss_frame.h" - - - -void kissnet_init (struct misc_config_s *misc_config); - -void kissnet_send_rec_packet (int chan, int kiss_cmd, unsigned char *fbuf, int flen, - struct kissport_status_s *onlykps, int onlyclient); - -void kiss_net_set_debug (int n); - -void kissnet_copy (unsigned char *kiss_msg, int kiss_len, int chan, int cmd, struct kissport_status_s *from_kps, int from_client); - - -#endif // KISSNET_H - -/* end kissnet.h */ diff --git a/kissserial.h b/kissserial.h deleted file mode 100644 index 44fb3c3..0000000 --- a/kissserial.h +++ /dev/null @@ -1,23 +0,0 @@ - -/* - * Name: kissserial.h - */ - - -#include "ax25_pad.h" /* for packet_t */ - -#include "config.h" - -#include "kiss_frame.h" - - -void kissserial_init (struct misc_config_s *misc_config); - -void kissserial_send_rec_packet (int chan, int kiss_cmd, unsigned char *fbuf, int flen, - struct kissport_status_s *notused1, int notused2); - - -void kissserial_set_debug (int n); - - -/* end kissserial.h */ diff --git a/latlong.h b/latlong.h deleted file mode 100644 index ae98fe6..0000000 --- a/latlong.h +++ /dev/null @@ -1,24 +0,0 @@ - -/* latlong.h */ - - -/* Use this value for unknown latitude/longitude or other values. */ - -#define G_UNKNOWN (-999999) - - -void latitude_to_str (double dlat, int ambiguity, char *slat); -void longitude_to_str (double dlong, int ambiguity, char *slong); - -void latitude_to_comp_str (double dlat, char *clat); -void longitude_to_comp_str (double dlon, char *clon); - -void latitude_to_nmea (double dlat, char *slat, char *hemi); -void longitude_to_nmea (double dlong, char *slong, char *hemi); - -double latitude_from_nmea (char *pstr, char *phemi); -double longitude_from_nmea (char *pstr, char *phemi); - -double ll_distance_km (double lat1, double lon1, double lat2, double lon2); - -int ll_from_grid_square (char *maidenhead, double *dlat, double *dlon); \ No newline at end of file diff --git a/log.h b/log.h deleted file mode 100644 index 3afb6b1..0000000 --- a/log.h +++ /dev/null @@ -1,19 +0,0 @@ - -/* log.h */ - - -#include "hdlc_rec2.h" // for retry_t - -#include "decode_aprs.h" // for decode_aprs_t - -#include "ax25_pad.h" - - - -void log_init (int daily_names, char *path); - -void log_write (int chan, decode_aprs_t *A, packet_t pp, alevel_t alevel, retry_t retries); - -void log_rr_bits (decode_aprs_t *A, packet_t pp); - -void log_term (void); \ No newline at end of file diff --git a/main.cpp b/main.cpp index 402e849..43ea7cd 100644 --- a/main.cpp +++ b/main.cpp @@ -53,6 +53,8 @@ int main(int argc, char *argv[]) qDebug() << Title; + + if (nonGUIMode) a = new QCoreApplication(argc, argv); else @@ -60,6 +62,7 @@ int main(int argc, char *argv[]) getSettings(); + t = new workerThread; if (nonGUIMode == 0) @@ -85,4 +88,3 @@ int main(int argc, char *argv[]) } - diff --git a/mgn_icon.h b/mgn_icon.h deleted file mode 100644 index c870bc0..0000000 --- a/mgn_icon.h +++ /dev/null @@ -1,276 +0,0 @@ - - -/* - * MGN_icon.h - * - * Waypoint icon codes for use in the $PMGNWPL sentence. - * - * Derived from Data Transmission Protocol For Magellan Products - version 2.11, March 2003 - * - * http://www.gpsinformation.org/mag-proto-2-11.pdf - * - * - * That's 13 years ago. There should be something newer available but I can't find it. - * - * The is based on the newer models at the time. Earlier models had shorter incompatible icon lists. - */ - - - -#define MGN_crossed_square "a" -#define MGN_box "b" -#define MGN_house "c" -#define MGN_aerial "d" -#define MGN_airport "e" -#define MGN_amusement_park "f" -#define MGN_ATM "g" -#define MGN_auto_repair "h" -#define MGN_boating "I" -#define MGN_camping "j" -#define MGN_exit_ramp "k" -#define MGN_first_aid "l" -#define MGN_nav_aid "m" -#define MGN_buoy "n" -#define MGN_fuel "o" -#define MGN_garden "p" -#define MGN_golf "q" -#define MGN_hotel "r" -#define MGN_hunting_fishing "s" -#define MGN_large_city "t" -#define MGN_lighthouse "u" -#define MGN_major_city "v" -#define MGN_marina "w" -#define MGN_medium_city "x" -#define MGN_museum "y" -#define MGN_obstruction "z" -#define MGN_park "aa" -#define MGN_resort "ab" -#define MGN_restaurant "ac" -#define MGN_rock "ad" -#define MGN_scuba "ae" -#define MGN_RV_service "af" -#define MGN_shooting "ag" -#define MGN_sight_seeing "ah" -#define MGN_small_city "ai" -#define MGN_sounding "aj" -#define MGN_sports_arena "ak" -#define MGN_tourist_info "al" -#define MGN_truck_service "am" -#define MGN_winery "an" -#define MGN_wreck "ao" -#define MGN_zoo "ap" - - -/* - * Mapping from APRS symbols to Magellan. - * - * This is a bit of a challenge because there - * are no icons for moving objects. - * We can use airport for flying things but - * what about wheeled transportation devices? - */ - -// TODO: NEEDS MORE WORK!!! - - -#define MGN_default MGN_crossed_square - -#define SYMTAB_SIZE 95 - -static const char mgn_primary_symtab[SYMTAB_SIZE][3] = { - - MGN_default, // 00 --no-symbol-- - MGN_default, // ! 01 Police, Sheriff - MGN_default, // " 02 reserved (was rain) - MGN_aerial, // # 03 DIGI (white center) - MGN_default, // $ 04 PHONE - MGN_aerial, // % 05 DX CLUSTER - MGN_aerial, // & 06 HF GATEway - MGN_airport, // ' 07 Small AIRCRAFT - MGN_aerial, // ( 08 Mobile Satellite Station - MGN_default, // ) 09 Wheelchair (handicapped) - MGN_default, // * 10 SnowMobile - MGN_default, // + 11 Red Cross - MGN_default, // , 12 Boy Scouts - MGN_house, // - 13 House QTH (VHF) - MGN_default, // . 14 X - MGN_default, // / 15 Red Dot - MGN_default, // 0 16 # circle (obsolete) - MGN_default, // 1 17 TBD - MGN_default, // 2 18 TBD - MGN_default, // 3 19 TBD - MGN_default, // 4 20 TBD - MGN_default, // 5 21 TBD - MGN_default, // 6 22 TBD - MGN_default, // 7 23 TBD - MGN_default, // 8 24 TBD - MGN_default, // 9 25 TBD - MGN_default, // : 26 FIRE - MGN_camping, // ; 27 Campground (Portable ops) - MGN_default, // < 28 Motorcycle - MGN_default, // = 29 RAILROAD ENGINE - MGN_default, // > 30 CAR - MGN_default, // ? 31 SERVER for Files - MGN_default, // @ 32 HC FUTURE predict (dot) - MGN_first_aid, // A 33 Aid Station - MGN_aerial, // B 34 BBS or PBBS - MGN_boating, // C 35 Canoe - MGN_default, // D 36 - MGN_default, // E 37 EYEBALL (Eye catcher!) - MGN_default, // F 38 Farm Vehicle (tractor) - MGN_default, // G 39 Grid Square (6 digit) - MGN_hotel, // H 40 HOTEL (blue bed symbol) - MGN_aerial, // I 41 TcpIp on air network stn - MGN_default, // J 42 - MGN_default, // K 43 School - MGN_default, // L 44 PC user - MGN_default, // M 45 MacAPRS - MGN_aerial, // N 46 NTS Station - MGN_airport, // O 47 BALLOON - MGN_default, // P 48 Police - MGN_default, // Q 49 TBD - MGN_RV_service, // R 50 REC. VEHICLE - MGN_airport, // S 51 SHUTTLE - MGN_default, // T 52 SSTV - MGN_default, // U 53 BUS - MGN_default, // V 54 ATV - MGN_default, // W 55 National WX Service Site - MGN_default, // X 56 HELO - MGN_boating, // Y 57 YACHT (sail) - MGN_default, // Z 58 WinAPRS - MGN_default, // [ 59 Human/Person (HT) - MGN_default, // \ 60 TRIANGLE(DF station) - MGN_default, // ] 61 MAIL/PostOffice(was PBBS) - MGN_airport, // ^ 62 LARGE AIRCRAFT - MGN_default, // _ 63 WEATHER Station (blue) - MGN_aerial, // ` 64 Dish Antenna - MGN_default, // a 65 AMBULANCE - MGN_default, // b 66 BIKE - MGN_default, // c 67 Incident Command Post - MGN_default, // d 68 Fire dept - MGN_zoo, // e 69 HORSE (equestrian) - MGN_default, // f 70 FIRE TRUCK - MGN_airport, // g 71 Glider - MGN_default, // h 72 HOSPITAL - MGN_default, // i 73 IOTA (islands on the air) - MGN_default, // j 74 JEEP - MGN_default, // k 75 TRUCK - MGN_default, // l 76 Laptop - MGN_aerial, // m 77 Mic-E Repeater - MGN_default, // n 78 Node (black bulls-eye) - MGN_default, // o 79 EOC - MGN_zoo, // p 80 ROVER (puppy, or dog) - MGN_default, // q 81 GRID SQ shown above 128 m - MGN_aerial, // r 82 Repeater - MGN_default, // s 83 SHIP (pwr boat) - MGN_default, // t 84 TRUCK STOP - MGN_default, // u 85 TRUCK (18 wheeler) - MGN_default, // v 86 VAN - MGN_default, // w 87 WATER station - MGN_aerial, // x 88 xAPRS (Unix) - MGN_aerial, // y 89 YAGI @ QTH - MGN_default, // z 90 TBD - MGN_default, // { 91 - MGN_default, // | 92 TNC Stream Switch - MGN_default, // } 93 - MGN_default }; // ~ 94 TNC Stream Switch - - -static const char mgn_alternate_symtab[SYMTAB_SIZE][3] = { - - MGN_default, // 00 --no-symbol-- - MGN_default, // ! 01 EMERGENCY (!) - MGN_default, // " 02 reserved - MGN_aerial, // # 03 OVERLAY DIGI (green star) - MGN_ATM, // $ 04 Bank or ATM (green box) - MGN_default, // % 05 Power Plant with overlay - MGN_aerial, // & 06 I=Igte IGate R=RX T=1hopTX 2=2hopTX - MGN_default, // ' 07 Crash (& now Incident sites) - MGN_default, // ( 08 CLOUDY (other clouds w ovrly) - MGN_aerial, // ) 09 Firenet MEO, MODIS Earth Obs. - MGN_default, // * 10 SNOW (& future ovrly codes) - MGN_default, // + 11 Church - MGN_default, // , 12 Girl Scouts - MGN_house, // - 13 House (H=HF) (O = Op Present) - MGN_default, // . 14 Ambiguous (Big Question mark) - MGN_default, // / 15 Waypoint Destination - MGN_default, // 0 16 CIRCLE (E/I/W=IRLP/Echolink/WIRES) - MGN_default, // 1 17 - MGN_default, // 2 18 - MGN_default, // 3 19 - MGN_default, // 4 20 - MGN_default, // 5 21 - MGN_default, // 6 22 - MGN_default, // 7 23 - MGN_aerial, // 8 24 802.11 or other network node - MGN_fuel, // 9 25 Gas Station (blue pump) - MGN_default, // : 26 Hail (& future ovrly codes) - MGN_park, // ; 27 Park/Picnic area - MGN_default, // < 28 ADVISORY (one WX flag) - MGN_default, // = 29 APRStt Touchtone (DTMF users) - MGN_default, // > 30 OVERLAID CAR - MGN_tourist_info, // ? 31 INFO Kiosk (Blue box with ?) - MGN_default, // @ 32 HURRICANE/Trop-Storm - MGN_box, // A 33 overlayBOX DTMF & RFID & XO - MGN_default, // B 34 Blwng Snow (& future codes) - MGN_boating, // C 35 Coast Guard - MGN_default, // D 36 Drizzle (proposed APRStt) - MGN_default, // E 37 Smoke (& other vis codes) - MGN_default, // F 38 Freezng rain (&future codes) - MGN_default, // G 39 Snow Shwr (& future ovrlys) - MGN_default, // H 40 Haze (& Overlay Hazards) - MGN_default, // I 41 Rain Shower - MGN_default, // J 42 Lightning (& future ovrlys) - MGN_default, // K 43 Kenwood HT (W) - MGN_lighthouse, // L 44 Lighthouse - MGN_default, // M 45 MARS (A=Army,N=Navy,F=AF) - MGN_buoy, // N 46 Navigation Buoy - MGN_airport, // O 47 Rocket - MGN_default, // P 48 Parking - MGN_default, // Q 49 QUAKE - MGN_restaurant, // R 50 Restaurant - MGN_aerial, // S 51 Satellite/Pacsat - MGN_default, // T 52 Thunderstorm - MGN_default, // U 53 SUNNY - MGN_nav_aid, // V 54 VORTAC Nav Aid - MGN_default, // W 55 # NWS site (NWS options) - MGN_default, // X 56 Pharmacy Rx (Apothicary) - MGN_aerial, // Y 57 Radios and devices - MGN_default, // Z 58 - MGN_default, // [ 59 W.Cloud (& humans w Ovrly) - MGN_default, // \ 60 New overlayable GPS symbol - MGN_default, // ] 61 - MGN_airport, // ^ 62 # Aircraft (shows heading) - MGN_default, // _ 63 # WX site (green digi) - MGN_default, // ` 64 Rain (all types w ovrly) - MGN_aerial, // a 65 ARRL, ARES, WinLINK - MGN_default, // b 66 Blwng Dst/Snd (& others) - MGN_default, // c 67 CD triangle RACES/SATERN/etc - MGN_default, // d 68 DX spot by callsign - MGN_default, // e 69 Sleet (& future ovrly codes) - MGN_default, // f 70 Funnel Cloud - MGN_default, // g 71 Gale Flags - MGN_default, // h 72 Store. or HAMFST Hh=HAM store - MGN_box, // i 73 BOX or points of Interest - MGN_default, // j 74 WorkZone (Steam Shovel) - MGN_default, // k 75 Special Vehicle SUV,ATV,4x4 - MGN_default, // l 76 Areas (box,circles,etc) - MGN_default, // m 77 Value Sign (3 digit display) - MGN_default, // n 78 OVERLAY TRIANGLE - MGN_default, // o 79 small circle - MGN_default, // p 80 Prtly Cldy (& future ovrlys) - MGN_default, // q 81 - MGN_default, // r 82 Restrooms - MGN_default, // s 83 OVERLAY SHIP/boat (top view) - MGN_default, // t 84 Tornado - MGN_default, // u 85 OVERLAID TRUCK - MGN_default, // v 86 OVERLAID Van - MGN_default, // w 87 Flooding - MGN_wreck, // x 88 Wreck or Obstruction ->X<- - MGN_default, // y 89 Skywarn - MGN_default, // z 90 OVERLAID Shelter - MGN_default, // { 91 Fog (& future ovrly codes) - MGN_default, // | 92 TNC Stream Switch - MGN_default, // } 93 - MGN_default }; // ~ 94 TNC Stream Switch - diff --git a/mheard.h b/mheard.h deleted file mode 100644 index f8466ba..0000000 --- a/mheard.h +++ /dev/null @@ -1,20 +0,0 @@ - - -/* mheard.h */ - -#include "decode_aprs.h" // for decode_aprs_t - - -void mheard_init (int debug); - -void mheard_save_rf (int chan, decode_aprs_t *A, packet_t pp, alevel_t alevel, retry_t retries); - -void mheard_save_is (char *ptext); - -int mheard_count (int max_hops, int time_limit); - -int mheard_was_recently_nearby (char *role, char *callsign, int time_limit, int max_hops, double dlat, double dlon, double km); - -void mheard_set_msp (char *callsign, int num); - -int mheard_get_msp (char *callsign); \ No newline at end of file diff --git a/morse.h b/morse.h deleted file mode 100644 index e34dd7b..0000000 --- a/morse.h +++ /dev/null @@ -1,8 +0,0 @@ -/* morse.h */ - -int morse_init (struct audio_s *audio_config_p, int amp) ; - -int morse_send (int chan, char *str, int wpm, int txdelay, int txtail); - -#define MORSE_DEFAULT_WPM 10 - diff --git a/multi_modem.h b/multi_modem.h deleted file mode 100644 index de3061e..0000000 --- a/multi_modem.h +++ /dev/null @@ -1,24 +0,0 @@ -/* multi_modem.h */ - -#ifndef MULTI_MODEM_H -#define MULTI_MODEM 1 - -/* Needed for typedef retry_t. */ -#include "hdlc_rec2.h" - -/* Needed for struct audio_s */ -#include "audio.h" - - -void multi_modem_init (struct audio_s *pmodem); - -void multi_modem_process_sample (int c, int audio_sample); - -int multi_modem_get_dc_average (int chan); - -// Deprecated. Replace with ...packet -void multi_modem_process_rec_frame (int chan, int subchan, int slice, unsigned char *fbuf, int flen, alevel_t alevel, retry_t retries, int is_fx25); - -void multi_modem_process_rec_packet (int chan, int subchan, int slice, packet_t pp, alevel_t alevel, retry_t retries, int is_fx25); - -#endif diff --git a/pfilter.h b/pfilter.h deleted file mode 100644 index d54e056..0000000 --- a/pfilter.h +++ /dev/null @@ -1,13 +0,0 @@ - -/* pfilter.h */ - - -#include "igate.h" // for igate_config_s - - - -void pfilter_init (struct igate_config_s *p_igate_config, int debug_level); - -int pfilter (int from_chan, int to_chan, char *filter, packet_t pp, int is_aprs); - -int is_telem_metadata (char *infop); \ No newline at end of file diff --git a/ptt.h b/ptt.h deleted file mode 100644 index 6e75253..0000000 --- a/ptt.h +++ /dev/null @@ -1,26 +0,0 @@ - - -#ifndef PTT_H -#define PTT_H 1 - - -#include "audio.h" /* for struct audio_s and definitions for octype values */ - - -void ptt_set_debug(int debug); - -void ptt_init (struct audio_s *p_modem); - -void ptt_set (int octype, int chan, int ptt); - -void ptt_term (void); - -int get_input (int it, int chan); - -#endif - - -/* end ptt.h */ - - - diff --git a/recv.h b/recv.h deleted file mode 100644 index 3201991..0000000 --- a/recv.h +++ /dev/null @@ -1,6 +0,0 @@ - -/* recv.h */ - -void recv_init (struct audio_s *pa); - -void recv_process (void); \ No newline at end of file diff --git a/redecode.h b/redecode.h deleted file mode 100644 index ffd9a95..0000000 --- a/redecode.h +++ /dev/null @@ -1,15 +0,0 @@ - - -#ifndef REDECODE_H -#define REDECODE_H 1 - -#include "rrbb.h" - - -extern void redecode_init (struct audio_s *p_audio_config); - - -#endif - -/* end redecode.h */ - diff --git a/release/moc_predefs-DESKTOP-MHE5LO8.h b/release/moc_predefs.h similarity index 95% rename from release/moc_predefs-DESKTOP-MHE5LO8.h rename to release/moc_predefs.h index 4c9c0c7..54e9037 100644 --- a/release/moc_predefs-DESKTOP-MHE5LO8.h +++ b/release/moc_predefs.h @@ -1,11 +1,11 @@ -#define _MSC_EXTENSIONS -#define _INTEGRAL_MAX_BITS 64 -#define _MSC_VER 1916 -#define _MSC_FULL_VER 191627043 -#define _MSC_BUILD 0 -#define _WIN32 -#define _M_IX86 600 -#define _M_IX86_FP 2 -#define _CPPRTTI -#define _MT -#define _DLL +#define _MSC_EXTENSIONS +#define _INTEGRAL_MAX_BITS 64 +#define _MSC_VER 1916 +#define _MSC_FULL_VER 191627043 +#define _MSC_BUILD 0 +#define _WIN32 +#define _M_IX86 600 +#define _M_IX86_FP 2 +#define _CPPRTTI +#define _MT +#define _DLL diff --git a/rpack.h b/rpack.h deleted file mode 100644 index d972a54..0000000 --- a/rpack.h +++ /dev/null @@ -1,94 +0,0 @@ - -/*------------------------------------------------------------------ - * - * File: rpack.h - * - * Purpose: Definition of Garmin Rino message format. - * - * References: http://www.radio-active.net.au/web3/APRS/Resources/RINO - * - * http://www.radio-active.net.au/web3/APRS/Resources/RINO/OnAir - * - *---------------------------------------------------------------*/ - - -#ifndef RPACK_H -#define RPACK_H 1 - - -#define RPACK_FRAME_LEN 168 - - -#ifdef RPACK_C /* Expose private details */ - - - -// Transmission order is LSB first. - -struct __attribute__((__packed__)) rpack_s { - - int lat; // Latitude. - // Signed integer. Scaled by 2**30/90. - - int lon; // Longitude. Same encoding. - - char unknown1; // Unproven theory: altitude. - char unknown2; - - unsigned name0:6; // 10 character name. - unsigned name1:6; // Bit packing is implementation dependent. - unsigned name2:6; // Should rewrite to be more portable. - unsigned name3:6; - unsigned name4:6; - unsigned name5:6; - unsigned name6:6; - unsigned name7:6; - unsigned name8:6; - unsigned name9:6; - - unsigned symbol:5; - - unsigned unknown3:7; - - -// unsigned crc:16; // Safe bet this is CRC for error checking. - - unsigned char crc1; - unsigned char crc2; - - char dummy[3]; // Total size should be 24 bytes if no gaps. - -}; - -#else /* Show only public interface. */ - - -struct rpack_s { - char stuff[24]; -}; - - -#endif - - - -void rpack_set_bit (struct rpack_s *rp, int position, int value); - -int rpack_is_valid (struct rpack_s *rp); - -int rpack_get_bit (struct rpack_s *rp, int position); - -double rpack_get_lat (struct rpack_s *rp); - -double rpack_get_lon (struct rpack_s *rp); - -int rpack_get_symbol (struct rpack_s *rp); - -void rpack_get_name (struct rpack_s *rp, char *str); - - - -#endif - -/* end rpack.h */ - diff --git a/rrbb.h b/rrbb.h deleted file mode 100644 index 4b28372..0000000 --- a/rrbb.h +++ /dev/null @@ -1,92 +0,0 @@ - -#ifndef RRBB_H - -#define RRBB_H - - -#define FASTER13 1 // Don't pack 8 samples per byte. - - -//typedef short slice_t; - - -/* - * Maximum size (in bytes) of an AX.25 frame including the 2 octet FCS. - */ - -#define MAX_FRAME_LEN ((AX25_MAX_PACKET_LEN) + 2) - -/* - * Maximum number of bits in AX.25 frame excluding the flags. - * Adequate for extreme case of bit stuffing after every 5 bits - * which could never happen. - */ - -#define MAX_NUM_BITS (MAX_FRAME_LEN * 8 * 6 / 5) - -typedef struct rrbb_s { - int magic1; - struct rrbb_s* nextp; /* Next pointer to maintain a queue. */ - - int chan; /* Radio channel from which it was received. */ - int subchan; /* Which modem when more than one per channel. */ - int slice; /* Which slicer. */ - - alevel_t alevel; /* Received audio level at time of frame capture. */ - unsigned int len; /* Current number of samples in array. */ - - int is_scrambled; /* Is data scrambled G3RUH / K9NG style? */ - int descram_state; /* Descrambler state before first data bit of frame. */ - int prev_descram; /* Previous descrambled bit. */ - - unsigned char fdata[MAX_NUM_BITS]; - - int magic2; -} *rrbb_t; - - - -rrbb_t rrbb_new (int chan, int subchan, int slice, int is_scrambled, int descram_state, int prev_descram); - -void rrbb_clear (rrbb_t b, int is_scrambled, int descram_state, int prev_descram); - - -static inline /*__attribute__((always_inline))*/ void rrbb_append_bit (rrbb_t b, const unsigned char val) -{ - if (b->len >= MAX_NUM_BITS) { - return; /* Silently discard if full. */ - } - b->fdata[b->len] = val; - b->len++; -} - -static inline /*__attribute__((always_inline))*/ unsigned char rrbb_get_bit (const rrbb_t b, const int ind) -{ - return (b->fdata[ind]); -} - - -void rrbb_chop8 (rrbb_t b); - -int rrbb_get_len (rrbb_t b); - -//void rrbb_flip_bit (rrbb_t b, unsigned int ind); - -void rrbb_delete (rrbb_t b); - -void rrbb_set_nextp (rrbb_t b, rrbb_t np); -rrbb_t rrbb_get_nextp (rrbb_t b); - -int rrbb_get_chan (rrbb_t b); -int rrbb_get_subchan (rrbb_t b); -int rrbb_get_slice (rrbb_t b); - -void rrbb_set_audio_level (rrbb_t b, alevel_t alevel); -alevel_t rrbb_get_audio_level (rrbb_t b); - -int rrbb_get_is_scrambled (rrbb_t b); -int rrbb_get_descram_state (rrbb_t b); -int rrbb_get_prev_descram (rrbb_t b); - - -#endif diff --git a/serial_port.h b/serial_port.h deleted file mode 100644 index 8a65a0b..0000000 --- a/serial_port.h +++ /dev/null @@ -1,32 +0,0 @@ -/* serial_port.h */ - - -#ifndef SERIAL_PORT_H -#define SERIAL_PORT_H 1 - - -#if __WIN32__ - -#include - -typedef HANDLE MYFDTYPE; -#define MYFDERROR INVALID_HANDLE_VALUE - -#else - -typedef int MYFDTYPE; -#define MYFDERROR (-1) - -#endif - - -extern MYFDTYPE serial_port_open (char *devicename, int baud); - -extern int serial_port_write (MYFDTYPE fd, char *str, int len); - -extern int serial_port_get1 (MYFDTYPE fd); - -extern void serial_port_close (MYFDTYPE fd); - - -#endif \ No newline at end of file diff --git a/server.h b/server.h deleted file mode 100644 index 4cc2ea0..0000000 --- a/server.h +++ /dev/null @@ -1,32 +0,0 @@ - -/* - * Name: server.h - */ - - -#include "ax25_pad.h" /* for packet_t */ - -#include "config.h" - - -void server_set_debug (int n); - -void server_init (struct audio_s *audio_config_p, struct misc_config_s *misc_config); - -void server_send_rec_packet (int chan, packet_t pp, unsigned char *fbuf, int flen); - -void server_send_monitored (int chan, packet_t pp, int own_xmit); - -int server_callsign_registered_by_client (char *callsign); - - -void server_link_established (int chan, int client, char *remote_call, char *own_call, int incoming); - -void server_link_terminated (int chan, int client, char *remote_call, char *own_call, int timeout); - -void server_rec_conn_data (int chan, int client, char *remote_call, char *own_call, int pid, char *data_ptr, int data_len); - -void server_outstanding_frames_reply (int chan, int client, char *own_call, char *remote_call, int count); - - -/* end server.h */ diff --git a/sm_main.c b/sm_main.c index 57bf549..d2c6cfd 100644 --- a/sm_main.c +++ b/sm_main.c @@ -27,7 +27,6 @@ void make_core_BPF(UCHAR snd_ch, short freq, short width); void make_core_TXBPF(UCHAR snd_ch, float freq, float width); void make_core_INTR(UCHAR snd_ch); void make_core_LPF(UCHAR snd_ch, short width); -void wf_pointer(int snd_ch); void dw9600ProcessSample(int snd_ch, short Sample); void init_RUH48(int snd_ch); void init_RUH96(int snd_ch); @@ -65,11 +64,8 @@ int TXPort = 8884; BOOL Firstwaterfall = 1; BOOL Secondwaterfall = 1; - int multiCore = FALSE; - - BOOL MinOnStart = 0; //RS TReedSolomon; // Form1 TForm1; @@ -728,7 +724,7 @@ void init_speed(int snd_ch) form1.show_freq_a; form1.show_freq_b; */ - wf_pointer(snd_ch); + NeedWaterfallHeaders = TRUE; CheckPSKWindows(); } @@ -863,6 +859,8 @@ void runModemthread(void * param) // I think this processes a buffer of samples +int Toggle = 0; + void BufferFull(short * Samples, int nSamples) // These are Stereo Samples { word i, i1, j; @@ -1064,6 +1062,8 @@ void BufferFull(short * Samples, int nSamples) // These are Stereo Samples // Collect samples for both channels if needed + Toggle++; + Needed = FFTSize - fftCount; if (Needed <= rx_bufsize) @@ -1076,7 +1076,8 @@ void BufferFull(short * Samples, int nSamples) // These are Stereo Samples data1 += 2; } - doWaterfall(FirstWaterfallChan); + if ((Toggle & 1) || (UsingBothChannels == 0)) + doWaterfall(FirstWaterfallChan); if (data2) { @@ -1085,9 +1086,13 @@ void BufferFull(short * Samples, int nSamples) // These are Stereo Samples *ptr2++ = *data2; data2 += 2; } - doWaterfall(1); + if (((Toggle & 1) == 0)) + doWaterfall(1); } + if (Firstwaterfall || Secondwaterfall) + displayWaterfall(); + remainingSamples = rx_bufsize - Needed; fftCount = 0; diff --git a/symbols.h b/symbols.h deleted file mode 100644 index 5ed91ad..0000000 --- a/symbols.h +++ /dev/null @@ -1,19 +0,0 @@ - -/* symbols.h */ - -void symbols_init (void); - -void symbols_list (void); - -void symbols_from_dest_or_src (char dti, char *src, char *dest, char *symtab, char *symbol); - -int symbols_into_dest (char symtab, char symbol, char *dest); - -void symbols_get_description (char symtab, char symbol, char *description, size_t desc_size); - -int symbols_code_from_description (char overlay, char *description, char *symtab, char *symbol); - -void symbols_to_tones (char symtab, char symbol, char *tones, size_t tonessize); - - -/* end symbols.h */ diff --git a/telemetry.h b/telemetry.h deleted file mode 100644 index 4ef9b62..0000000 --- a/telemetry.h +++ /dev/null @@ -1,15 +0,0 @@ - - -/* telemetry.h */ - -void telemetry_data_original (char *station, char *info, int quiet, char *output, size_t outputsize, char *comment, size_t commentsize); - -void telemetry_data_base91 (char *station, char *cdata, char *output, size_t outputsize); - -void telemetry_name_message (char *station, char *msg); - -void telemetry_unit_label_message (char *station, char *msg); - -void telemetry_coefficents_message (char *station, char *msg, int quiet); - -void telemetry_bit_sense_message (char *station, char *msg, int quiet); diff --git a/tq.h b/tq.h deleted file mode 100644 index 37599d5..0000000 --- a/tq.h +++ /dev/null @@ -1,41 +0,0 @@ - -/*------------------------------------------------------------------ - * - * Module: tq.h - * - * Purpose: Transmit queue - hold packets for transmission until the channel is clear. - * - *---------------------------------------------------------------*/ - -#ifndef TQ_H -#define TQ_H 1 - -#include "ax25_pad.h" -#include "audio.h" - -#define TQ_NUM_PRIO 2 /* Number of priorities. */ - -#define TQ_PRIO_0_HI 0 -#define TQ_PRIO_1_LO 1 - - - -void tq_init (struct audio_s *audio_config_p); - -void tq_append (int chan, int prio, packet_t pp); - -void lm_data_request (int chan, int prio, packet_t pp); - -void lm_seize_request (int chan); - -void tq_wait_while_empty (int chan); - -packet_t tq_remove (int chan, int prio); - -packet_t tq_peek (int chan, int prio); - -int tq_count (int chan, int prio, char *source, char *dest, int bytes); - -#endif - -/* end tq.h */ diff --git a/tt_text.h b/tt_text.h deleted file mode 100644 index 7cab3b8..0000000 --- a/tt_text.h +++ /dev/null @@ -1,38 +0,0 @@ - -/* tt_text.h */ - - -/* Encode normal human readable to DTMF representation. */ - -int tt_text_to_multipress (const char *text, int quiet, char *buttons); - -int tt_text_to_two_key (const char *text, int quiet, char *buttons); - -int tt_text_to_call10 (const char *text, int quiet, char *buttons); - -int tt_text_to_mhead (const char *text, int quiet, char *buttons, size_t buttonsiz); - -int tt_text_to_satsq (const char *text, int quiet, char *buttons, size_t buttonsiz); - -int tt_text_to_ascii2d (const char *text, int quiet, char *buttons); - - -/* Decode DTMF to normal human readable form. */ - -int tt_multipress_to_text (const char *buttons, int quiet, char *text); - -int tt_two_key_to_text (const char *buttons, int quiet, char *text); - -int tt_call10_to_text (const char *buttons, int quiet, char *text); - -int tt_call5_suffix_to_text (const char *buttons, int quiet, char *text); - -int tt_mhead_to_text (const char *buttons, int quiet, char *text, size_t textsiz); - -int tt_satsq_to_text (const char *buttons, int quiet, char *text); - -int tt_ascii2d_to_text (const char *buttons, int quiet, char *text); - - - -/* end tt_text.h */ \ No newline at end of file diff --git a/tt_user.h b/tt_user.h deleted file mode 100644 index 4ff2ec8..0000000 --- a/tt_user.h +++ /dev/null @@ -1,15 +0,0 @@ - -/* tt_user.h */ - - -#include "audio.h" - -void tt_user_init (struct audio_s *p_audio_config, struct tt_config_s *p); - -int tt_user_heard (char *callsign, int ssid, char overlay, char symbol, char *loc_text, double latitude, - double longitude, int ambiguity, char *freq, char *ctcss, char *comment, char mic_e, char *dao); - -int tt_3char_suffix_search (char *suffix, char *callsign); - -void tt_user_background (void); -void tt_user_dump (void); \ No newline at end of file diff --git a/tune.h b/tune.h deleted file mode 100644 index 8d1c8b6..0000000 --- a/tune.h +++ /dev/null @@ -1 +0,0 @@ - diff --git a/version.h b/version.h deleted file mode 100644 index a09490c..0000000 --- a/version.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* Dire Wolf version 1.6 */ - -// Put in destination field to identify the equipment used. - -#define APP_TOCALL "APDW" // Assigned by WB4APR in tocalls.txt - -// This now comes from compile command line options. - -//#define MAJOR_VERSION 1 -//#define MINOR_VERSION 6 -//#define EXTRA_VERSION "Beta Test" - - -// For user-defined data format. -// APRS protocol spec Chapter 18 and http://www.aprs.org/aprs11/expfmts.txt - -#define USER_DEF_USER_ID 'D' // user id D for direwolf - -#define USER_DEF_TYPE_AIS 'A' // data type A for AIS NMEA sentence -#define USER_DEF_TYPE_EAS 'E' // data type E for EAS broadcasts diff --git a/waypoint.h b/waypoint.h deleted file mode 100644 index 3ba6f1c..0000000 --- a/waypoint.h +++ /dev/null @@ -1,24 +0,0 @@ - -/* - * Name: waypoint.h - */ - - -#include "ax25_pad.h" /* for packet_t */ - -#include "config.h" /* for struct misc_config_s */ - - -void waypoint_init (struct misc_config_s *misc_config); - -void waypoint_set_debug (int n); - -void waypoint_send_sentence (char *wname_in, double dlat, double dlong, char symtab, char symbol, - float alt, float course, float speed, char *comment_in); - -void waypoint_send_ais (char *sentence); - -void waypoint_term (); - - -/* end waypoint.h */ diff --git a/xid.h b/xid.h deleted file mode 100644 index a221b73..0000000 --- a/xid.h +++ /dev/null @@ -1,32 +0,0 @@ - - -/* xid.h */ - - -#include "ax25_pad.h" // for enum ax25_modulo_e - - -struct xid_param_s { - - int full_duplex; - - // Order is important because negotiation keeps the lower value of - // REJ (srej_none), SREJ (default without negotiation), Multi-SREJ (if both agree). - - enum srej_e { srej_none=0, srej_single=1, srej_multi=2, srej_not_specified=3 } srej; - - enum ax25_modulo_e modulo; - - int i_field_length_rx; /* In bytes. XID has it in bits. */ - - int window_size_rx; - - int ack_timer; /* "T1" in mSec. */ - - int retries; /* "N1" */ -}; - - -int xid_parse (unsigned char *info, int info_len, struct xid_param_s *result, char *desc, int desc_size); - -int xid_encode (struct xid_param_s *param, unsigned char *info, cmdres_t cr); \ No newline at end of file diff --git a/xmit.h b/xmit.h deleted file mode 100644 index 248037d..0000000 --- a/xmit.h +++ /dev/null @@ -1,27 +0,0 @@ - - -#ifndef XMIT_H -#define XMIT_H 1 - -#include "audio.h" /* for struct audio_s */ - - -extern void xmit_init (struct audio_s *p_modem, int debug_xmit_packet); - -extern void xmit_set_txdelay (int channel, int value); - -extern void xmit_set_persist (int channel, int value); - -extern void xmit_set_slottime (int channel, int value); - -extern void xmit_set_txtail (int channel, int value); - -extern void xmit_set_fulldup (int channel, int value); - - -extern int xmit_speak_it (char *script, int c, char *msg); - -#endif - -/* end xmit.h */ -