New upstream version 0.67
This commit is contained in:
parent
f7fc865d93
commit
3cdcbeea3e
36
ALSASound.c
36
ALSASound.c
|
@ -93,6 +93,22 @@ extern BOOL UseKISS; // Enable Packet (KISS) interface
|
|||
|
||||
extern short * DMABuffer;
|
||||
|
||||
#define MaxReceiveSize 2048 // Enough for 9600
|
||||
#define MaxSendSize 4096
|
||||
|
||||
short buffer[2][MaxSendSize * 2]; // Two Transfer/DMA buffers of 0.1 Sec (x2 for Stereo)
|
||||
short inbuffer[MaxReceiveSize * 2]; // Input Transfer/ buffers of 0.1 Sec (x2 for Stereo)
|
||||
|
||||
|
||||
extern short * DMABuffer;
|
||||
extern int Number;
|
||||
|
||||
int ReceiveSize = 512;
|
||||
int SendSize = 1024;
|
||||
int using48000 = 0;
|
||||
|
||||
int SampleRate = 12000;
|
||||
|
||||
|
||||
BOOL UseLeft = TRUE;
|
||||
BOOL UseRight = TRUE;
|
||||
|
@ -123,8 +139,6 @@ void Sleep(int mS)
|
|||
// Windows and ALSA work with signed samples +- 32767
|
||||
// STM32 and Teensy DAC uses unsigned 0 - 4095
|
||||
|
||||
short buffer[2][1200 * 2]; // Two Transfer/DMA buffers of 0.1 Sec
|
||||
short inbuffer[1200 * 2]; // Two Transfer/DMA buffers of 0.1 Sec
|
||||
|
||||
BOOL Loopback = FALSE;
|
||||
//BOOL Loopback = TRUE;
|
||||
|
@ -967,7 +981,7 @@ int SoundCardWrite(short * input, int nSamples)
|
|||
|
||||
// Debugprintf("Tosend %d Avail %d", nSamples, (int)avail);
|
||||
|
||||
while (avail < nSamples || (MaxAvail - avail) > 12000) // Limit to 1 sec of audio
|
||||
while (avail < nSamples || (MaxAvail - avail) > SampleRate) // Limit to 1 sec of audio
|
||||
{
|
||||
txSleep(10);
|
||||
avail = snd_pcm_avail_update(playhandle);
|
||||
|
@ -1203,15 +1217,29 @@ void GetSoundDevices()
|
|||
|
||||
int InitSound(BOOL Quiet)
|
||||
{
|
||||
if (using48000)
|
||||
{
|
||||
ReceiveSize = 2048;
|
||||
SendSize = 4096; // 100 mS for now
|
||||
SampleRate = 48000;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReceiveSize = 512;
|
||||
SendSize = 1024;
|
||||
SampleRate = 12000;
|
||||
}
|
||||
|
||||
GetSoundDevices();
|
||||
|
||||
switch (SoundMode)
|
||||
{
|
||||
case 0: // ALSA
|
||||
|
||||
if (!OpenSoundCard(CaptureDevice, PlaybackDevice, 12000, 12000, Quiet))
|
||||
if (!OpenSoundCard(CaptureDevice, PlaybackDevice, SampleRate, SampleRate, Quiet))
|
||||
return FALSE;
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case 1: // OSS
|
||||
|
|
|
@ -1,444 +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 <QSettings>
|
||||
|
||||
#include "UZ7HOStuff.h"
|
||||
|
||||
extern "C" void get_exclude_list(char * line, TStringList * list);
|
||||
extern "C" void get_exclude_frm(char * line, TStringList * list);
|
||||
|
||||
extern "C" int SoundMode;
|
||||
extern "C" int RX_SR;
|
||||
extern "C" int TX_SR;
|
||||
extern "C" int multiCore;
|
||||
extern "C" char * Wisdom;
|
||||
|
||||
extern "C" word MEMRecovery[5];
|
||||
|
||||
extern int MintoTray;
|
||||
extern "C" int UDPClientPort;
|
||||
extern "C" int UDPServerPort;
|
||||
extern "C" int TXPort;
|
||||
|
||||
extern char UDPHost[64];
|
||||
|
||||
extern char CWIDCall[128];
|
||||
extern int CWIDInterval;
|
||||
extern int CWIDLeft;
|
||||
extern int CWIDRight;
|
||||
extern int CWIDType;
|
||||
|
||||
extern "C" int RSID_SABM[4];
|
||||
extern "C" int RSID_UI[4];
|
||||
extern "C" int RSID_SetModem[4];
|
||||
|
||||
|
||||
QSettings* settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
|
||||
// This makes geting settings for more channels easier
|
||||
|
||||
char Prefix[16] = "AX25_A";
|
||||
|
||||
void GetPortSettings(int Chan);
|
||||
|
||||
QVariant getAX25Param(const char * key, QVariant Default)
|
||||
{
|
||||
char fullKey[64];
|
||||
|
||||
sprintf(fullKey, "%s/%s", Prefix, key);
|
||||
return settings->value(fullKey, Default);
|
||||
}
|
||||
|
||||
void getAX25Params(int chan)
|
||||
{
|
||||
Prefix[5] = chan + 'A';
|
||||
GetPortSettings(chan);
|
||||
}
|
||||
|
||||
|
||||
void GetPortSettings(int Chan)
|
||||
{
|
||||
tx_hitoneraisedb[Chan] = getAX25Param("HiToneRaise", 0).toInt();
|
||||
|
||||
maxframe[Chan] = getAX25Param("Maxframe", 3).toInt();
|
||||
fracks[Chan] = getAX25Param("Retries", 15).toInt();
|
||||
frack_time[Chan] = getAX25Param("FrackTime", 5).toInt();
|
||||
|
||||
idletime[Chan] = getAX25Param("IdleTime", 180).toInt();
|
||||
slottime[Chan] = getAX25Param("SlotTime", 100).toInt();
|
||||
persist[Chan] = getAX25Param("Persist", 128).toInt();
|
||||
resptime[Chan] = getAX25Param("RespTime", 1500).toInt();
|
||||
TXFrmMode[Chan] = getAX25Param("TXFrmMode", 1).toInt();
|
||||
max_frame_collector[Chan] = getAX25Param("FrameCollector", 6).toInt();
|
||||
//exclude_callsigns[Chan]= getAX25Param("ExcludeCallsigns/");
|
||||
//exclude_APRS_frm[Chan]= getAX25Param("ExcludeAPRSFrmType/");
|
||||
KISS_opt[Chan] = getAX25Param("KISSOptimization", false).toInt();;
|
||||
dyn_frack[Chan] = getAX25Param("DynamicFrack", false).toInt();;
|
||||
recovery[Chan] = getAX25Param("BitRecovery", 0).toInt();
|
||||
NonAX25[Chan] = getAX25Param("NonAX25Frm", false).toInt();;
|
||||
MEMRecovery[Chan]= getAX25Param("MEMRecovery", 200).toInt();
|
||||
IPOLL[Chan] = getAX25Param("IPOLL", 80).toInt();
|
||||
|
||||
strcpy(MyDigiCall[Chan], getAX25Param("MyDigiCall", "").toString().toUtf8());
|
||||
fx25_mode[Chan] = getAX25Param("FX25", FX25_MODE_RX).toInt();
|
||||
il2p_mode[Chan] = getAX25Param("IL2P", IL2P_MODE_NONE).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();
|
||||
}
|
||||
|
||||
void getSettings()
|
||||
{
|
||||
int snd_ch;
|
||||
|
||||
QSettings* settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
settings->sync();
|
||||
|
||||
SoundMode = settings->value("Init/SoundMode", 0).toInt();
|
||||
UDPClientPort = settings->value("Init/UDPClientPort", 8888).toInt();
|
||||
UDPServerPort = settings->value("Init/UDPServerPort", 8884).toInt();
|
||||
TXPort = settings->value("Init/TXPort", UDPServerPort).toInt();
|
||||
|
||||
strcpy(UDPHost, settings->value("Init/UDPHost", "192.168.1.255").toString().toUtf8());
|
||||
UDPServ = settings->value("Init/UDPServer", FALSE).toBool();
|
||||
|
||||
RX_SR = settings->value("Init/RXSampleRate", 12000).toInt();
|
||||
TX_SR = settings->value("Init/TXSampleRate", 12000).toInt();
|
||||
|
||||
strcpy(CaptureDevice, settings->value("Init/SndRXDeviceName", "hw:1,0").toString().toUtf8());
|
||||
strcpy(PlaybackDevice, settings->value("Init/SndTXDeviceName", "hw:1,0").toString().toUtf8());
|
||||
|
||||
raduga = settings->value("Init/DispMode", DISP_RGB).toInt();
|
||||
|
||||
strcpy(PTTPort, settings->value("Init/PTT", "").toString().toUtf8());
|
||||
PTTMode = settings->value("Init/PTTMode", 19200).toInt();
|
||||
PTTBAUD = settings->value("Init/PTTBAUD", 19200).toInt();
|
||||
|
||||
strcpy(PTTOnString, settings->value("Init/PTTOnString", "").toString().toUtf8());
|
||||
strcpy(PTTOffString, settings->value("Init/PTTOffString", "").toString().toUtf8());
|
||||
|
||||
pttGPIOPin = settings->value("Init/pttGPIOPin", 17).toInt();
|
||||
pttGPIOPinR = settings->value("Init/pttGPIOPinR", 17).toInt();
|
||||
|
||||
#ifdef WIN32
|
||||
strcpy(CM108Addr, settings->value("Init/CM108Addr", "0xD8C:0x08").toString().toUtf8());
|
||||
#else
|
||||
strcpy(CM108Addr, settings->value("Init/CM108Addr", "/dev/hidraw0").toString().toUtf8());
|
||||
#endif
|
||||
|
||||
HamLibPort = settings->value("Init/HamLibPort", 4532).toInt();
|
||||
strcpy(HamLibHost, settings->value("Init/HamLibHost", "127.0.0.1").toString().toUtf8());
|
||||
|
||||
DualPTT = settings->value("Init/DualPTT", 1).toInt();
|
||||
TX_rotate = settings->value("Init/TXRotate", 0).toInt();
|
||||
|
||||
multiCore = settings->value("Init/multiCore", 0).toInt();
|
||||
Wisdom = strdup(settings->value("Init/Wisdom", "").toString().toUtf8());
|
||||
|
||||
|
||||
|
||||
rx_freq[0] = settings->value("Modem/RXFreq1", 1700).toInt();
|
||||
rx_freq[1] = settings->value("Modem/RXFreq2", 1700).toInt();
|
||||
rx_freq[2] = settings->value("Modem/RXFreq3", 1700).toInt();
|
||||
rx_freq[3] = settings->value("Modem/RXFreq4", 1700).toInt();
|
||||
|
||||
rcvr_offset[0] = settings->value("Modem/RcvrShift1", 30).toInt();
|
||||
rcvr_offset[1] = settings->value("Modem/RcvrShift2", 30).toInt();
|
||||
rcvr_offset[2] = settings->value("Modem/RcvrShift3", 30).toInt();
|
||||
rcvr_offset[3] = settings->value("Modem/RcvrShift4", 30).toInt();
|
||||
speed[0] = settings->value("Modem/ModemType1", SPEED_1200).toInt();
|
||||
speed[1] = settings->value("Modem/ModemType2", SPEED_1200).toInt();
|
||||
speed[2] = settings->value("Modem/ModemType3", SPEED_1200).toInt();
|
||||
speed[3] = settings->value("Modem/ModemType4", SPEED_1200).toInt();
|
||||
|
||||
RCVR[0] = settings->value("Modem/NRRcvrPairs1", 0).toInt();;
|
||||
RCVR[1] = settings->value("Modem/NRRcvrPairs2", 0).toInt();;
|
||||
RCVR[2] = settings->value("Modem/NRRcvrPairs3", 0).toInt();;
|
||||
RCVR[3] = settings->value("Modem/NRRcvrPairs4", 0).toInt();;
|
||||
|
||||
soundChannel[0] = settings->value("Modem/soundChannel1", 1).toInt();
|
||||
soundChannel[1] = settings->value("Modem/soundChannel2", 0).toInt();
|
||||
soundChannel[2] = settings->value("Modem/soundChannel3", 0).toInt();
|
||||
soundChannel[3] = settings->value("Modem/soundChannel4", 0).toInt();
|
||||
|
||||
SCO = settings->value("Init/SCO", 0).toInt();
|
||||
|
||||
dcd_threshold = settings->value("Modem/DCDThreshold", 40).toInt();
|
||||
rxOffset = settings->value("Modem/rxOffset", 0).toInt();
|
||||
|
||||
AGWServ = settings->value("AGWHost/Server", TRUE).toBool();
|
||||
AGWPort = settings->value("AGWHost/Port", 8000).toInt();
|
||||
KISSServ = settings->value("KISS/Server", FALSE).toBool();
|
||||
KISSPort = settings->value("KISS/Port", 8105).toInt();
|
||||
|
||||
RX_Samplerate = RX_SR + RX_SR * 0.000001*RX_PPM;
|
||||
TX_Samplerate = TX_SR + TX_SR * 0.000001*TX_PPM;
|
||||
|
||||
emph_all[0] = settings->value("Modem/PreEmphasisAll1", FALSE).toBool();
|
||||
emph_all[1] = settings->value("Modem/PreEmphasisAll2", FALSE).toBool();
|
||||
emph_all[2] = settings->value("Modem/PreEmphasisAll3", FALSE).toBool();
|
||||
emph_all[3] = settings->value("Modem/PreEmphasisAll4", FALSE).toBool();
|
||||
|
||||
emph_db[0] = settings->value("Modem/PreEmphasisDB1", 0).toInt();
|
||||
emph_db[1] = settings->value("Modem/PreEmphasisDB2", 0).toInt();
|
||||
emph_db[2] = settings->value("Modem/PreEmphasisDB3", 0).toInt();
|
||||
emph_db[3] = settings->value("Modem/PreEmphasisDB4", 0).toInt();
|
||||
|
||||
Firstwaterfall = settings->value("Window/Waterfall1", TRUE).toInt();
|
||||
Secondwaterfall = settings->value("Window/Waterfall2", TRUE).toInt();
|
||||
|
||||
txdelay[0] = settings->value("Modem/TxDelay1", 250).toInt();
|
||||
txdelay[1] = settings->value("Modem/TxDelay2", 250).toInt();
|
||||
txdelay[2] = settings->value("Modem/TxDelay3", 250).toInt();
|
||||
txdelay[3] = settings->value("Modem/TxDelay4", 250).toInt();
|
||||
|
||||
strcpy(CWIDCall, settings->value("Modem/CWIDCall", "").toString().toUtf8().toUpper());
|
||||
CWIDInterval = settings->value("Modem/CWIDInterval", 0).toInt();
|
||||
CWIDLeft = settings->value("Modem/CWIDLeft", 0).toInt();
|
||||
CWIDRight = settings->value("Modem/CWIDRight", 0).toInt();
|
||||
CWIDType = settings->value("Modem/CWIDType", 1).toInt(); // on/off
|
||||
|
||||
|
||||
getAX25Params(0);
|
||||
getAX25Params(1);
|
||||
getAX25Params(2);
|
||||
getAX25Params(3);
|
||||
|
||||
// Validate and process settings
|
||||
|
||||
UsingLeft = 0;
|
||||
UsingRight = 0;
|
||||
UsingBothChannels = 0;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (soundChannel[i] == LEFT)
|
||||
{
|
||||
UsingLeft = 1;
|
||||
modemtoSoundLR[i] = 0;
|
||||
}
|
||||
else if (soundChannel[i] == RIGHT)
|
||||
{
|
||||
UsingRight = 1;
|
||||
modemtoSoundLR[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (UsingLeft && UsingRight)
|
||||
UsingBothChannels = 1;
|
||||
|
||||
for (snd_ch = 0; snd_ch < 4; snd_ch++)
|
||||
{
|
||||
tx_hitoneraise[snd_ch] = powf(10.0f, -abs(tx_hitoneraisedb[snd_ch]) / 20.0f);
|
||||
|
||||
if (IPOLL[snd_ch] < 0)
|
||||
IPOLL[snd_ch] = 0;
|
||||
else if (IPOLL[snd_ch] > 65535)
|
||||
IPOLL[snd_ch] = 65535;
|
||||
|
||||
if (MEMRecovery[snd_ch] < 1)
|
||||
MEMRecovery[snd_ch] = 1;
|
||||
|
||||
// if (MEMRecovery[snd_ch]> 65535)
|
||||
// MEMRecovery[snd_ch]= 65535;
|
||||
|
||||
/*
|
||||
if resptime[snd_ch] < 0 then resptime[snd_ch]= 0;
|
||||
if resptime[snd_ch] > 65535 then resptime[snd_ch]= 65535;
|
||||
if persist[snd_ch] > 255 then persist[snd_ch]= 255;
|
||||
if persist[snd_ch] < 32 then persist[snd_ch]= 32;
|
||||
if fracks[snd_ch] < 1 then fracks[snd_ch]= 1;
|
||||
if frack_time[snd_ch] < 1 then frack_time[snd_ch]= 1;
|
||||
if idletime[snd_ch] < frack_time[snd_ch] then idletime[snd_ch]= 180;
|
||||
*/
|
||||
|
||||
if (emph_db[snd_ch] < 0 || emph_db[snd_ch] > nr_emph)
|
||||
emph_db[snd_ch] = 0;
|
||||
|
||||
if (max_frame_collector[snd_ch] > 6) max_frame_collector[snd_ch] = 6;
|
||||
if (maxframe[snd_ch] == 0 || maxframe[snd_ch] > 7) maxframe[snd_ch] = 3;
|
||||
if (qpsk_set[snd_ch].mode > 1) qpsk_set[snd_ch].mode = 0;
|
||||
|
||||
}
|
||||
|
||||
delete(settings);
|
||||
}
|
||||
|
||||
void SavePortSettings(int Chan);
|
||||
|
||||
void saveAX25Param(const char * key, QVariant Value)
|
||||
{
|
||||
char fullKey[64];
|
||||
|
||||
sprintf(fullKey, "%s/%s", Prefix, key);
|
||||
|
||||
settings->setValue(fullKey, Value);
|
||||
}
|
||||
|
||||
void saveAX25Params(int chan)
|
||||
{
|
||||
Prefix[5] = chan + 'A';
|
||||
SavePortSettings(chan);
|
||||
}
|
||||
|
||||
void SavePortSettings(int Chan)
|
||||
{
|
||||
saveAX25Param("Retries", fracks[Chan]);
|
||||
saveAX25Param("HiToneRaise", tx_hitoneraisedb[Chan]);
|
||||
saveAX25Param("Maxframe",maxframe[Chan]);
|
||||
saveAX25Param("Retries", fracks[Chan]);
|
||||
saveAX25Param("FrackTime", frack_time[Chan]);
|
||||
saveAX25Param("IdleTime", idletime[Chan]);
|
||||
saveAX25Param("SlotTime", slottime[Chan]);
|
||||
saveAX25Param("Persist", persist[Chan]);
|
||||
saveAX25Param("RespTime", resptime[Chan]);
|
||||
saveAX25Param("TXFrmMode", TXFrmMode[Chan]);
|
||||
saveAX25Param("FrameCollector", max_frame_collector[Chan]);
|
||||
saveAX25Param("ExcludeCallsigns", exclude_callsigns[Chan]);
|
||||
saveAX25Param("ExcludeAPRSFrmType", exclude_APRS_frm[Chan]);
|
||||
saveAX25Param("KISSOptimization", KISS_opt[Chan]);
|
||||
saveAX25Param("DynamicFrack", dyn_frack[Chan]);
|
||||
saveAX25Param("BitRecovery", recovery[Chan]);
|
||||
saveAX25Param("NonAX25Frm", NonAX25[Chan]);
|
||||
saveAX25Param("MEMRecovery", MEMRecovery[Chan]);
|
||||
saveAX25Param("IPOLL", IPOLL[Chan]);
|
||||
saveAX25Param("MyDigiCall", MyDigiCall[Chan]);
|
||||
saveAX25Param("FX25", fx25_mode[Chan]);
|
||||
saveAX25Param("IL2P", il2p_mode[Chan]);
|
||||
saveAX25Param("RSID_UI", RSID_UI[Chan]);
|
||||
saveAX25Param("RSID_SABM", RSID_SABM[Chan]);
|
||||
saveAX25Param("RSID_SetModem", RSID_SetModem[Chan]);
|
||||
}
|
||||
|
||||
void saveSettings()
|
||||
{
|
||||
QSettings * settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
|
||||
settings->setValue("Init/SoundMode", SoundMode);
|
||||
settings->setValue("Init/UDPClientPort", UDPClientPort);
|
||||
settings->setValue("Init/UDPServerPort", UDPServerPort);
|
||||
settings->setValue("Init/TXPort", TXPort);
|
||||
|
||||
settings->setValue("Init/UDPServer", UDPServ);
|
||||
settings->setValue("Init/UDPHost", UDPHost);
|
||||
|
||||
|
||||
settings->setValue("Init/TXSampleRate", TX_SR);
|
||||
settings->setValue("Init/RXSampleRate", RX_SR);
|
||||
|
||||
settings->setValue("Init/SndRXDeviceName", CaptureDevice);
|
||||
settings->setValue("Init/SndTXDeviceName", PlaybackDevice);
|
||||
|
||||
settings->setValue("Init/SCO", SCO);
|
||||
settings->setValue("Init/DualPTT", DualPTT);
|
||||
settings->setValue("Init/TXRotate", TX_rotate);
|
||||
|
||||
settings->setValue("Init/DispMode", raduga);
|
||||
|
||||
settings->setValue("Init/PTT", PTTPort);
|
||||
settings->setValue("Init/PTTBAUD", PTTBAUD);
|
||||
settings->setValue("Init/PTTMode", PTTMode);
|
||||
|
||||
settings->setValue("Init/PTTOffString", PTTOffString);
|
||||
settings->setValue("Init/PTTOnString", PTTOnString);
|
||||
|
||||
settings->setValue("Init/pttGPIOPin", pttGPIOPin);
|
||||
settings->setValue("Init/pttGPIOPinR", pttGPIOPinR);
|
||||
|
||||
settings->setValue("Init/CM108Addr", CM108Addr);
|
||||
settings->setValue("Init/HamLibPort", HamLibPort);
|
||||
settings->setValue("Init/HamLibHost", HamLibHost);
|
||||
settings->setValue("Init/MinimizetoTray", MintoTray);
|
||||
|
||||
settings->setValue("Init/multiCore", multiCore);
|
||||
|
||||
settings->setValue("Init/Wisdom", Wisdom);
|
||||
|
||||
// Don't save freq on close as it could be offset by multiple decoders
|
||||
|
||||
settings->setValue("Modem/NRRcvrPairs1", RCVR[0]);
|
||||
settings->setValue("Modem/NRRcvrPairs2", RCVR[1]);
|
||||
settings->setValue("Modem/NRRcvrPairs3", RCVR[2]);
|
||||
settings->setValue("Modem/NRRcvrPairs4", RCVR[3]);
|
||||
|
||||
settings->setValue("Modem/RcvrShift1", rcvr_offset[0]);
|
||||
settings->setValue("Modem/RcvrShift2", rcvr_offset[1]);
|
||||
settings->setValue("Modem/RcvrShift3", rcvr_offset[2]);
|
||||
settings->setValue("Modem/RcvrShift4", rcvr_offset[3]);
|
||||
|
||||
settings->setValue("Modem/ModemType1", speed[0]);
|
||||
settings->setValue("Modem/ModemType2", speed[1]);
|
||||
settings->setValue("Modem/ModemType3", speed[2]);
|
||||
settings->setValue("Modem/ModemType4", speed[3]);
|
||||
|
||||
settings->setValue("Modem/soundChannel1", soundChannel[0]);
|
||||
settings->setValue("Modem/soundChannel2", soundChannel[1]);
|
||||
settings->setValue("Modem/soundChannel3", soundChannel[2]);
|
||||
settings->setValue("Modem/soundChannel4", soundChannel[3]);
|
||||
|
||||
settings->setValue("Modem/DCDThreshold", dcd_threshold);
|
||||
settings->setValue("Modem/rxOffset", rxOffset);
|
||||
|
||||
settings->setValue("AGWHost/Server", AGWServ);
|
||||
settings->setValue("AGWHost/Port", AGWPort);
|
||||
settings->setValue("KISS/Server", KISSServ);
|
||||
settings->setValue("KISS/Port", KISSPort);
|
||||
|
||||
settings->setValue("Modem/PreEmphasisAll1", emph_all[0]);
|
||||
settings->setValue("Modem/PreEmphasisAll2", emph_all[1]);
|
||||
settings->setValue("Modem/PreEmphasisAll3", emph_all[2]);
|
||||
settings->setValue("Modem/PreEmphasisAll4", emph_all[3]);
|
||||
|
||||
settings->setValue("Modem/PreEmphasisDB1", emph_db[0]);
|
||||
settings->setValue("Modem/PreEmphasisDB2", emph_db[1]);
|
||||
settings->setValue("Modem/PreEmphasisDB3", emph_db[2]);
|
||||
settings->setValue("Modem/PreEmphasisDB4", emph_db[3]);
|
||||
|
||||
settings->setValue("Window/Waterfall1", Firstwaterfall);
|
||||
settings->setValue("Window/Waterfall2", Secondwaterfall);
|
||||
|
||||
settings->setValue("Modem/TxDelay1", txdelay[0]);
|
||||
settings->setValue("Modem/TxDelay2", txdelay[1]);
|
||||
settings->setValue("Modem/TxDelay3", txdelay[2]);
|
||||
settings->setValue("Modem/TxDelay4", txdelay[3]);
|
||||
|
||||
settings->setValue("Modem/TxTail1", txtail[0]);
|
||||
settings->setValue("Modem/TxTail2", txtail[1]);
|
||||
settings->setValue("Modem/TxTail3", txtail[2]);
|
||||
settings->setValue("Modem/TxTail4", txtail[3]);
|
||||
|
||||
settings->setValue("Modem/CWIDCall", CWIDCall);
|
||||
settings->setValue("Modem/CWIDInterval", CWIDInterval);
|
||||
settings->setValue("Modem/CWIDLeft", CWIDLeft);
|
||||
settings->setValue("Modem/CWIDRight", CWIDRight);
|
||||
settings->setValue("Modem/CWIDType", CWIDType);
|
||||
|
||||
saveAX25Params(0);
|
||||
saveAX25Params(1);
|
||||
saveAX25Params(2);
|
||||
saveAX25Params(3);
|
||||
|
||||
settings->sync();
|
||||
|
||||
delete(settings);
|
||||
}
|
14
Config.cpp
14
Config.cpp
|
@ -21,6 +21,7 @@ along with QtSoundModem. If not, see http://www.gnu.org/licenses
|
|||
// UZ7HO Soundmodem Port by John Wiseman G8BPQ
|
||||
|
||||
#include <QSettings>
|
||||
#include <QDialog>
|
||||
|
||||
#include "UZ7HOStuff.h"
|
||||
|
||||
|
@ -43,8 +44,11 @@ extern "C" int UDPServerPort;
|
|||
extern "C" int TXPort;
|
||||
|
||||
extern char UDPHost[64];
|
||||
extern QDialog * constellationDialog;
|
||||
extern QRect PSKRect;
|
||||
|
||||
extern char CWIDCall[128];
|
||||
extern "C" char CWIDMark[32];
|
||||
extern int CWIDInterval;
|
||||
extern int CWIDLeft;
|
||||
extern int CWIDRight;
|
||||
|
@ -120,6 +124,8 @@ void getSettings()
|
|||
QSettings* settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
settings->sync();
|
||||
|
||||
PSKRect = settings->value("PSKWindow").toRect();
|
||||
|
||||
SoundMode = settings->value("Init/SoundMode", 0).toInt();
|
||||
UDPClientPort = settings->value("Init/UDPClientPort", 8888).toInt();
|
||||
UDPServerPort = settings->value("Init/UDPServerPort", 8884).toInt();
|
||||
|
@ -219,7 +225,13 @@ void getSettings()
|
|||
txdelay[2] = settings->value("Modem/TxDelay3", 250).toInt();
|
||||
txdelay[3] = settings->value("Modem/TxDelay4", 250).toInt();
|
||||
|
||||
txtail[0] = settings->value("Modem/TxTail1", 50).toInt();
|
||||
txtail[1] = settings->value("Modem/TxTail2", 50).toInt();
|
||||
txtail[2] = settings->value("Modem/TxTail3", 50).toInt();
|
||||
txtail[3] = settings->value("Modem/TxTail4", 50).toInt();
|
||||
|
||||
strcpy(CWIDCall, settings->value("Modem/CWIDCall", "").toString().toUtf8().toUpper());
|
||||
strcpy(CWIDMark, settings->value("Modem/CWIDMark", "").toString().toUtf8().toUpper());
|
||||
CWIDInterval = settings->value("Modem/CWIDInterval", 0).toInt();
|
||||
CWIDLeft = settings->value("Modem/CWIDLeft", 0).toInt();
|
||||
CWIDRight = settings->value("Modem/CWIDRight", 0).toInt();
|
||||
|
@ -341,6 +353,7 @@ void saveSettings()
|
|||
{
|
||||
QSettings * settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
|
||||
settings->setValue("PSKWindow", constellationDialog->geometry());
|
||||
settings->setValue("Init/SoundMode", SoundMode);
|
||||
settings->setValue("Init/UDPClientPort", UDPClientPort);
|
||||
settings->setValue("Init/UDPServerPort", UDPServerPort);
|
||||
|
@ -436,6 +449,7 @@ void saveSettings()
|
|||
settings->setValue("Modem/TxTail4", txtail[3]);
|
||||
|
||||
settings->setValue("Modem/CWIDCall", CWIDCall);
|
||||
settings->setValue("Modem/CWIDMark", CWIDMark);
|
||||
settings->setValue("Modem/CWIDInterval", CWIDInterval);
|
||||
settings->setValue("Modem/CWIDLeft", CWIDLeft);
|
||||
settings->setValue("Modem/CWIDRight", CWIDRight);
|
||||
|
|
439
Config.cpp.bak
439
Config.cpp.bak
|
@ -1,439 +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 <QSettings>
|
||||
|
||||
#include "UZ7HOStuff.h"
|
||||
|
||||
extern "C" void get_exclude_list(char * line, TStringList * list);
|
||||
extern "C" void get_exclude_frm(char * line, TStringList * list);
|
||||
|
||||
extern "C" int SoundMode;
|
||||
extern "C" int RX_SR;
|
||||
extern "C" int TX_SR;
|
||||
extern "C" int multiCore;
|
||||
|
||||
extern "C" word MEMRecovery[5];
|
||||
|
||||
extern int MintoTray;
|
||||
extern "C" int UDPClientPort;
|
||||
extern "C" int UDPServerPort;
|
||||
extern "C" int TXPort;
|
||||
|
||||
extern char UDPHost[64];
|
||||
|
||||
extern char CWIDCall[128];
|
||||
extern int CWIDInterval;
|
||||
extern int CWIDLeft;
|
||||
extern int CWIDRight;
|
||||
extern int CWIDType;
|
||||
|
||||
extern "C" int RSID_SABM[4];
|
||||
extern "C" int RSID_UI[4];
|
||||
extern "C" int RSID_SetModem[4];
|
||||
|
||||
|
||||
QSettings* settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
|
||||
// This makes geting settings for more channels easier
|
||||
|
||||
char Prefix[16] = "AX25_A";
|
||||
|
||||
void GetPortSettings(int Chan);
|
||||
|
||||
QVariant getAX25Param(const char * key, QVariant Default)
|
||||
{
|
||||
char fullKey[64];
|
||||
|
||||
sprintf(fullKey, "%s/%s", Prefix, key);
|
||||
return settings->value(fullKey, Default);
|
||||
}
|
||||
|
||||
void getAX25Params(int chan)
|
||||
{
|
||||
Prefix[5] = chan + 'A';
|
||||
GetPortSettings(chan);
|
||||
}
|
||||
|
||||
|
||||
void GetPortSettings(int Chan)
|
||||
{
|
||||
tx_hitoneraisedb[Chan] = getAX25Param("HiToneRaise", 0).toInt();
|
||||
|
||||
maxframe[Chan] = getAX25Param("Maxframe", 3).toInt();
|
||||
fracks[Chan] = getAX25Param("Retries", 15).toInt();
|
||||
frack_time[Chan] = getAX25Param("FrackTime", 5).toInt();
|
||||
|
||||
idletime[Chan] = getAX25Param("IdleTime", 180).toInt();
|
||||
slottime[Chan] = getAX25Param("SlotTime", 100).toInt();
|
||||
persist[Chan] = getAX25Param("Persist", 128).toInt();
|
||||
resptime[Chan] = getAX25Param("RespTime", 1500).toInt();
|
||||
TXFrmMode[Chan] = getAX25Param("TXFrmMode", 1).toInt();
|
||||
max_frame_collector[Chan] = getAX25Param("FrameCollector", 6).toInt();
|
||||
//exclude_callsigns[Chan]= getAX25Param("ExcludeCallsigns/");
|
||||
//exclude_APRS_frm[Chan]= getAX25Param("ExcludeAPRSFrmType/");
|
||||
KISS_opt[Chan] = getAX25Param("KISSOptimization", false).toInt();;
|
||||
dyn_frack[Chan] = getAX25Param("DynamicFrack", false).toInt();;
|
||||
recovery[Chan] = getAX25Param("BitRecovery", 0).toInt();
|
||||
NonAX25[Chan] = getAX25Param("NonAX25Frm", false).toInt();;
|
||||
MEMRecovery[Chan]= getAX25Param("MEMRecovery", 200).toInt();
|
||||
IPOLL[Chan] = getAX25Param("IPOLL", 80).toInt();
|
||||
|
||||
strcpy(MyDigiCall[Chan], getAX25Param("MyDigiCall", "").toString().toUtf8());
|
||||
fx25_mode[Chan] = getAX25Param("FX25", FX25_MODE_RX).toInt();
|
||||
il2p_mode[Chan] = getAX25Param("IL2P", IL2P_MODE_NONE).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();
|
||||
}
|
||||
|
||||
void getSettings()
|
||||
{
|
||||
int snd_ch;
|
||||
|
||||
QSettings* settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
settings->sync();
|
||||
|
||||
SoundMode = settings->value("Init/SoundMode", 0).toInt();
|
||||
UDPClientPort = settings->value("Init/UDPClientPort", 8888).toInt();
|
||||
UDPServerPort = settings->value("Init/UDPServerPort", 8884).toInt();
|
||||
TXPort = settings->value("Init/TXPort", UDPServerPort).toInt();
|
||||
|
||||
strcpy(UDPHost, settings->value("Init/UDPHost", "192.168.1.255").toString().toUtf8());
|
||||
UDPServ = settings->value("Init/UDPServer", FALSE).toBool();
|
||||
|
||||
RX_SR = settings->value("Init/RXSampleRate", 12000).toInt();
|
||||
TX_SR = settings->value("Init/TXSampleRate", 12000).toInt();
|
||||
|
||||
strcpy(CaptureDevice, settings->value("Init/SndRXDeviceName", "hw:1,0").toString().toUtf8());
|
||||
strcpy(PlaybackDevice, settings->value("Init/SndTXDeviceName", "hw:1,0").toString().toUtf8());
|
||||
|
||||
raduga = settings->value("Init/DispMode", DISP_RGB).toInt();
|
||||
|
||||
strcpy(PTTPort, settings->value("Init/PTT", "").toString().toUtf8());
|
||||
PTTMode = settings->value("Init/PTTMode", 19200).toInt();
|
||||
PTTBAUD = settings->value("Init/PTTBAUD", 19200).toInt();
|
||||
|
||||
strcpy(PTTOnString, settings->value("Init/PTTOnString", "").toString().toUtf8());
|
||||
strcpy(PTTOffString, settings->value("Init/PTTOffString", "").toString().toUtf8());
|
||||
|
||||
pttGPIOPin = settings->value("Init/pttGPIOPin", 17).toInt();
|
||||
pttGPIOPinR = settings->value("Init/pttGPIOPinR", 17).toInt();
|
||||
|
||||
#ifdef WIN32
|
||||
strcpy(CM108Addr, settings->value("Init/CM108Addr", "0xD8C:0x08").toString().toUtf8());
|
||||
#else
|
||||
strcpy(CM108Addr, settings->value("Init/CM108Addr", "/dev/hidraw0").toString().toUtf8());
|
||||
#endif
|
||||
|
||||
HamLibPort = settings->value("Init/HamLibPort", 4532).toInt();
|
||||
strcpy(HamLibHost, settings->value("Init/HamLibHost", "127.0.0.1").toString().toUtf8());
|
||||
|
||||
DualPTT = settings->value("Init/DualPTT", 1).toInt();
|
||||
TX_rotate = settings->value("Init/TXRotate", 0).toInt();
|
||||
|
||||
multiCore = settings->value("Init/multiCore", 0).toInt();
|
||||
MintoTray = settings->value("Init/MinimizetoTray", 1).toInt();
|
||||
|
||||
rx_freq[0] = settings->value("Modem/RXFreq1", 1700).toInt();
|
||||
rx_freq[1] = settings->value("Modem/RXFreq2", 1700).toInt();
|
||||
rx_freq[2] = settings->value("Modem/RXFreq3", 1700).toInt();
|
||||
rx_freq[3] = settings->value("Modem/RXFreq4", 1700).toInt();
|
||||
|
||||
rcvr_offset[0] = settings->value("Modem/RcvrShift1", 30).toInt();
|
||||
rcvr_offset[1] = settings->value("Modem/RcvrShift2", 30).toInt();
|
||||
rcvr_offset[2] = settings->value("Modem/RcvrShift3", 30).toInt();
|
||||
rcvr_offset[3] = settings->value("Modem/RcvrShift4", 30).toInt();
|
||||
speed[0] = settings->value("Modem/ModemType1", SPEED_1200).toInt();
|
||||
speed[1] = settings->value("Modem/ModemType2", SPEED_1200).toInt();
|
||||
speed[2] = settings->value("Modem/ModemType3", SPEED_1200).toInt();
|
||||
speed[3] = settings->value("Modem/ModemType4", SPEED_1200).toInt();
|
||||
|
||||
RCVR[0] = settings->value("Modem/NRRcvrPairs1", 0).toInt();;
|
||||
RCVR[1] = settings->value("Modem/NRRcvrPairs2", 0).toInt();;
|
||||
RCVR[2] = settings->value("Modem/NRRcvrPairs3", 0).toInt();;
|
||||
RCVR[3] = settings->value("Modem/NRRcvrPairs4", 0).toInt();;
|
||||
|
||||
soundChannel[0] = settings->value("Modem/soundChannel1", 1).toInt();
|
||||
soundChannel[1] = settings->value("Modem/soundChannel2", 0).toInt();
|
||||
soundChannel[2] = settings->value("Modem/soundChannel3", 0).toInt();
|
||||
soundChannel[3] = settings->value("Modem/soundChannel4", 0).toInt();
|
||||
|
||||
SCO = settings->value("Init/SCO", 0).toInt();
|
||||
|
||||
dcd_threshold = settings->value("Modem/DCDThreshold", 40).toInt();
|
||||
rxOffset = settings->value("Modem/rxOffset", 0).toInt();
|
||||
|
||||
AGWServ = settings->value("AGWHost/Server", TRUE).toBool();
|
||||
AGWPort = settings->value("AGWHost/Port", 8000).toInt();
|
||||
KISSServ = settings->value("KISS/Server", FALSE).toBool();
|
||||
KISSPort = settings->value("KISS/Port", 8105).toInt();
|
||||
|
||||
RX_Samplerate = RX_SR + RX_SR * 0.000001*RX_PPM;
|
||||
TX_Samplerate = TX_SR + TX_SR * 0.000001*TX_PPM;
|
||||
|
||||
emph_all[0] = settings->value("Modem/PreEmphasisAll1", FALSE).toBool();
|
||||
emph_all[1] = settings->value("Modem/PreEmphasisAll2", FALSE).toBool();
|
||||
emph_all[2] = settings->value("Modem/PreEmphasisAll3", FALSE).toBool();
|
||||
emph_all[3] = settings->value("Modem/PreEmphasisAll4", FALSE).toBool();
|
||||
|
||||
emph_db[0] = settings->value("Modem/PreEmphasisDB1", 0).toInt();
|
||||
emph_db[1] = settings->value("Modem/PreEmphasisDB2", 0).toInt();
|
||||
emph_db[2] = settings->value("Modem/PreEmphasisDB3", 0).toInt();
|
||||
emph_db[3] = settings->value("Modem/PreEmphasisDB4", 0).toInt();
|
||||
|
||||
Firstwaterfall = settings->value("Window/Waterfall1", TRUE).toInt();
|
||||
Secondwaterfall = settings->value("Window/Waterfall2", TRUE).toInt();
|
||||
|
||||
txdelay[0] = settings->value("Modem/TxDelay1", 250).toInt();
|
||||
txdelay[1] = settings->value("Modem/TxDelay2", 250).toInt();
|
||||
txdelay[2] = settings->value("Modem/TxDelay3", 250).toInt();
|
||||
txdelay[3] = settings->value("Modem/TxDelay4", 250).toInt();
|
||||
|
||||
strcpy(CWIDCall, settings->value("Modem/CWIDCall", "").toString().toUtf8().toUpper());
|
||||
CWIDInterval = settings->value("Modem/CWIDInterval", 0).toInt();
|
||||
CWIDLeft = settings->value("Modem/CWIDLeft", 0).toInt();
|
||||
CWIDRight = settings->value("Modem/CWIDRight", 0).toInt();
|
||||
CWIDType = settings->value("Modem/CWIDType", 1).toInt(); // on/off
|
||||
|
||||
|
||||
getAX25Params(0);
|
||||
getAX25Params(1);
|
||||
getAX25Params(2);
|
||||
getAX25Params(3);
|
||||
|
||||
// Validate and process settings
|
||||
|
||||
UsingLeft = 0;
|
||||
UsingRight = 0;
|
||||
UsingBothChannels = 0;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (soundChannel[i] == LEFT)
|
||||
{
|
||||
UsingLeft = 1;
|
||||
modemtoSoundLR[i] = 0;
|
||||
}
|
||||
else if (soundChannel[i] == RIGHT)
|
||||
{
|
||||
UsingRight = 1;
|
||||
modemtoSoundLR[i] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (UsingLeft && UsingRight)
|
||||
UsingBothChannels = 1;
|
||||
|
||||
for (snd_ch = 0; snd_ch < 4; snd_ch++)
|
||||
{
|
||||
tx_hitoneraise[snd_ch] = powf(10.0f, -abs(tx_hitoneraisedb[snd_ch]) / 20.0f);
|
||||
|
||||
if (IPOLL[snd_ch] < 0)
|
||||
IPOLL[snd_ch] = 0;
|
||||
else if (IPOLL[snd_ch] > 65535)
|
||||
IPOLL[snd_ch] = 65535;
|
||||
|
||||
if (MEMRecovery[snd_ch] < 1)
|
||||
MEMRecovery[snd_ch] = 1;
|
||||
|
||||
// if (MEMRecovery[snd_ch]> 65535)
|
||||
// MEMRecovery[snd_ch]= 65535;
|
||||
|
||||
/*
|
||||
if resptime[snd_ch] < 0 then resptime[snd_ch]= 0;
|
||||
if resptime[snd_ch] > 65535 then resptime[snd_ch]= 65535;
|
||||
if persist[snd_ch] > 255 then persist[snd_ch]= 255;
|
||||
if persist[snd_ch] < 32 then persist[snd_ch]= 32;
|
||||
if fracks[snd_ch] < 1 then fracks[snd_ch]= 1;
|
||||
if frack_time[snd_ch] < 1 then frack_time[snd_ch]= 1;
|
||||
if idletime[snd_ch] < frack_time[snd_ch] then idletime[snd_ch]= 180;
|
||||
*/
|
||||
|
||||
if (emph_db[snd_ch] < 0 || emph_db[snd_ch] > nr_emph)
|
||||
emph_db[snd_ch] = 0;
|
||||
|
||||
if (max_frame_collector[snd_ch] > 6) max_frame_collector[snd_ch] = 6;
|
||||
if (maxframe[snd_ch] == 0 || maxframe[snd_ch] > 7) maxframe[snd_ch] = 3;
|
||||
if (qpsk_set[snd_ch].mode > 1) qpsk_set[snd_ch].mode = 0;
|
||||
|
||||
}
|
||||
|
||||
delete(settings);
|
||||
}
|
||||
|
||||
void SavePortSettings(int Chan);
|
||||
|
||||
void saveAX25Param(const char * key, QVariant Value)
|
||||
{
|
||||
char fullKey[64];
|
||||
|
||||
sprintf(fullKey, "%s/%s", Prefix, key);
|
||||
|
||||
settings->setValue(fullKey, Value);
|
||||
}
|
||||
|
||||
void saveAX25Params(int chan)
|
||||
{
|
||||
Prefix[5] = chan + 'A';
|
||||
SavePortSettings(chan);
|
||||
}
|
||||
|
||||
void SavePortSettings(int Chan)
|
||||
{
|
||||
saveAX25Param("Retries", fracks[Chan]);
|
||||
saveAX25Param("HiToneRaise", tx_hitoneraisedb[Chan]);
|
||||
saveAX25Param("Maxframe",maxframe[Chan]);
|
||||
saveAX25Param("Retries", fracks[Chan]);
|
||||
saveAX25Param("FrackTime", frack_time[Chan]);
|
||||
saveAX25Param("IdleTime", idletime[Chan]);
|
||||
saveAX25Param("SlotTime", slottime[Chan]);
|
||||
saveAX25Param("Persist", persist[Chan]);
|
||||
saveAX25Param("RespTime", resptime[Chan]);
|
||||
saveAX25Param("TXFrmMode", TXFrmMode[Chan]);
|
||||
saveAX25Param("FrameCollector", max_frame_collector[Chan]);
|
||||
saveAX25Param("ExcludeCallsigns", exclude_callsigns[Chan]);
|
||||
saveAX25Param("ExcludeAPRSFrmType", exclude_APRS_frm[Chan]);
|
||||
saveAX25Param("KISSOptimization", KISS_opt[Chan]);
|
||||
saveAX25Param("DynamicFrack", dyn_frack[Chan]);
|
||||
saveAX25Param("BitRecovery", recovery[Chan]);
|
||||
saveAX25Param("NonAX25Frm", NonAX25[Chan]);
|
||||
saveAX25Param("MEMRecovery", MEMRecovery[Chan]);
|
||||
saveAX25Param("IPOLL", IPOLL[Chan]);
|
||||
saveAX25Param("MyDigiCall", MyDigiCall[Chan]);
|
||||
saveAX25Param("FX25", fx25_mode[Chan]);
|
||||
saveAX25Param("IL2P", il2p_mode[Chan]);
|
||||
saveAX25Param("RSID_UI", RSID_UI[Chan]);
|
||||
saveAX25Param("RSID_SABM", RSID_SABM[Chan]);
|
||||
saveAX25Param("RSID_SetModem", RSID_SetModem[Chan]);
|
||||
}
|
||||
|
||||
void saveSettings()
|
||||
{
|
||||
QSettings * settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
|
||||
settings->setValue("Init/SoundMode", SoundMode);
|
||||
settings->setValue("Init/UDPClientPort", UDPClientPort);
|
||||
settings->setValue("Init/UDPServerPort", UDPServerPort);
|
||||
settings->setValue("Init/TXPort", TXPort);
|
||||
|
||||
settings->setValue("Init/UDPServer", UDPServ);
|
||||
settings->setValue("Init/UDPHost", UDPHost);
|
||||
|
||||
|
||||
settings->setValue("Init/TXSampleRate", TX_SR);
|
||||
settings->setValue("Init/RXSampleRate", RX_SR);
|
||||
|
||||
settings->setValue("Init/SndRXDeviceName", CaptureDevice);
|
||||
settings->setValue("Init/SndTXDeviceName", PlaybackDevice);
|
||||
|
||||
settings->setValue("Init/SCO", SCO);
|
||||
settings->setValue("Init/DualPTT", DualPTT);
|
||||
settings->setValue("Init/TXRotate", TX_rotate);
|
||||
|
||||
settings->setValue("Init/DispMode", raduga);
|
||||
|
||||
settings->setValue("Init/PTT", PTTPort);
|
||||
settings->setValue("Init/PTTBAUD", PTTBAUD);
|
||||
settings->setValue("Init/PTTMode", PTTMode);
|
||||
|
||||
settings->setValue("Init/PTTOffString", PTTOffString);
|
||||
settings->setValue("Init/PTTOnString", PTTOnString);
|
||||
|
||||
settings->setValue("Init/pttGPIOPin", pttGPIOPin);
|
||||
settings->setValue("Init/pttGPIOPinR", pttGPIOPinR);
|
||||
|
||||
settings->setValue("Init/CM108Addr", CM108Addr);
|
||||
settings->setValue("Init/HamLibPort", HamLibPort);
|
||||
settings->setValue("Init/HamLibHost", HamLibHost);
|
||||
settings->setValue("Init/MinimizetoTray", MintoTray);
|
||||
|
||||
settings->setValue("Init/multiCore", multiCore);
|
||||
|
||||
// Don't save freq on close as it could be offset by multiple decoders
|
||||
|
||||
settings->setValue("Modem/NRRcvrPairs1", RCVR[0]);
|
||||
settings->setValue("Modem/NRRcvrPairs2", RCVR[1]);
|
||||
settings->setValue("Modem/NRRcvrPairs3", RCVR[2]);
|
||||
settings->setValue("Modem/NRRcvrPairs4", RCVR[3]);
|
||||
|
||||
settings->setValue("Modem/RcvrShift1", rcvr_offset[0]);
|
||||
settings->setValue("Modem/RcvrShift2", rcvr_offset[1]);
|
||||
settings->setValue("Modem/RcvrShift3", rcvr_offset[2]);
|
||||
settings->setValue("Modem/RcvrShift4", rcvr_offset[3]);
|
||||
|
||||
settings->setValue("Modem/ModemType1", speed[0]);
|
||||
settings->setValue("Modem/ModemType2", speed[1]);
|
||||
settings->setValue("Modem/ModemType3", speed[2]);
|
||||
settings->setValue("Modem/ModemType4", speed[3]);
|
||||
|
||||
settings->setValue("Modem/soundChannel1", soundChannel[0]);
|
||||
settings->setValue("Modem/soundChannel2", soundChannel[1]);
|
||||
settings->setValue("Modem/soundChannel3", soundChannel[2]);
|
||||
settings->setValue("Modem/soundChannel4", soundChannel[3]);
|
||||
|
||||
settings->setValue("Modem/DCDThreshold", dcd_threshold);
|
||||
settings->setValue("Modem/rxOffset", rxOffset);
|
||||
|
||||
settings->setValue("AGWHost/Server", AGWServ);
|
||||
settings->setValue("AGWHost/Port", AGWPort);
|
||||
settings->setValue("KISS/Server", KISSServ);
|
||||
settings->setValue("KISS/Port", KISSPort);
|
||||
|
||||
settings->setValue("Modem/PreEmphasisAll1", emph_all[0]);
|
||||
settings->setValue("Modem/PreEmphasisAll2", emph_all[1]);
|
||||
settings->setValue("Modem/PreEmphasisAll3", emph_all[2]);
|
||||
settings->setValue("Modem/PreEmphasisAll4", emph_all[3]);
|
||||
|
||||
settings->setValue("Modem/PreEmphasisDB1", emph_db[0]);
|
||||
settings->setValue("Modem/PreEmphasisDB2", emph_db[1]);
|
||||
settings->setValue("Modem/PreEmphasisDB3", emph_db[2]);
|
||||
settings->setValue("Modem/PreEmphasisDB4", emph_db[3]);
|
||||
|
||||
settings->setValue("Window/Waterfall1", Firstwaterfall);
|
||||
settings->setValue("Window/Waterfall2", Secondwaterfall);
|
||||
|
||||
settings->setValue("Modem/TxDelay1", txdelay[0]);
|
||||
settings->setValue("Modem/TxDelay2", txdelay[1]);
|
||||
settings->setValue("Modem/TxDelay3", txdelay[2]);
|
||||
settings->setValue("Modem/TxDelay4", txdelay[3]);
|
||||
|
||||
settings->setValue("Modem/TxTail1", txtail[0]);
|
||||
settings->setValue("Modem/TxTail2", txtail[1]);
|
||||
settings->setValue("Modem/TxTail3", txtail[2]);
|
||||
settings->setValue("Modem/TxTail4", txtail[3]);
|
||||
|
||||
settings->setValue("Modem/CWIDCall", CWIDCall);
|
||||
settings->setValue("Modem/CWIDInterval", CWIDInterval);
|
||||
settings->setValue("Modem/CWIDLeft", CWIDLeft);
|
||||
settings->setValue("Modem/CWIDRight", CWIDRight);
|
||||
settings->setValue("Modem/CWIDType", CWIDType);
|
||||
|
||||
saveAX25Params(0);
|
||||
saveAX25Params(1);
|
||||
saveAX25Params(2);
|
||||
saveAX25Params(3);
|
||||
|
||||
settings->sync();
|
||||
|
||||
delete(settings);
|
||||
}
|
|
@ -0,0 +1,311 @@
|
|||
/*
|
||||
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
|
||||
|
||||
*/
|
||||
|
||||
//#define TXSILENCE
|
||||
|
||||
// UZ7HO Soundmodem Port by John Wiseman G8BPQ
|
||||
//
|
||||
// Audio interface Routine
|
||||
|
||||
// Passes audio samples to/from the sound interface
|
||||
|
||||
// As this is platform specific it also has the main() routine, which does
|
||||
// platform specific initialisation before calling ardopmain()
|
||||
|
||||
// This is ALSASound.c for Linux
|
||||
// Windows Version is Waveout.c
|
||||
|
||||
|
||||
|
||||
|
||||
void gpioSetMode(unsigned gpio, unsigned mode);
|
||||
void gpioWrite(unsigned gpio, unsigned level);
|
||||
int _memicmp(unsigned char *a, unsigned char *b, int n);
|
||||
int stricmp(const unsigned char * pStr1, const unsigned char *pStr2);
|
||||
int gpioInitialise(void);
|
||||
|
||||
void Sleep(int mS)
|
||||
{
|
||||
usleep(mS * 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// GPIO access stuff for PTT on PI
|
||||
|
||||
#ifdef __ARM_ARCH
|
||||
|
||||
/*
|
||||
tiny_gpio.c
|
||||
2016-04-30
|
||||
Public Domain
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#define GPSET0 7
|
||||
#define GPSET1 8
|
||||
|
||||
#define GPCLR0 10
|
||||
#define GPCLR1 11
|
||||
|
||||
#define GPLEV0 13
|
||||
#define GPLEV1 14
|
||||
|
||||
#define GPPUD 37
|
||||
#define GPPUDCLK0 38
|
||||
#define GPPUDCLK1 39
|
||||
|
||||
unsigned piModel;
|
||||
unsigned piRev;
|
||||
|
||||
static volatile uint32_t *gpioReg = MAP_FAILED;
|
||||
|
||||
#define PI_BANK (gpio>>5)
|
||||
#define PI_BIT (1<<(gpio&0x1F))
|
||||
|
||||
/* gpio modes. */
|
||||
|
||||
// PTT via GPIO code
|
||||
|
||||
#ifdef __ARM_ARCH
|
||||
|
||||
#define PI_INPUT 0
|
||||
#define PI_OUTPUT 1
|
||||
#define PI_ALT0 4
|
||||
#define PI_ALT1 5
|
||||
#define PI_ALT2 6
|
||||
#define PI_ALT3 7
|
||||
#define PI_ALT4 3
|
||||
#define PI_ALT5 2
|
||||
|
||||
// Set GPIO pin as output and set low
|
||||
|
||||
void SetupGPIOPTT()
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
void gpioSetMode(unsigned gpio, unsigned mode)
|
||||
{
|
||||
int reg, shift;
|
||||
|
||||
reg = gpio/10;
|
||||
shift = (gpio%10) * 3;
|
||||
|
||||
gpioReg[reg] = (gpioReg[reg] & ~(7<<shift)) | (mode<<shift);
|
||||
}
|
||||
|
||||
int gpioGetMode(unsigned gpio)
|
||||
{
|
||||
int reg, shift;
|
||||
|
||||
reg = gpio/10;
|
||||
shift = (gpio%10) * 3;
|
||||
|
||||
return (*(gpioReg + reg) >> shift) & 7;
|
||||
}
|
||||
|
||||
/* Values for pull-ups/downs off, pull-down and pull-up. */
|
||||
|
||||
#define PI_PUD_OFF 0
|
||||
#define PI_PUD_DOWN 1
|
||||
#define PI_PUD_UP 2
|
||||
|
||||
void gpioSetPullUpDown(unsigned gpio, unsigned pud)
|
||||
{
|
||||
*(gpioReg + GPPUD) = pud;
|
||||
|
||||
usleep(20);
|
||||
|
||||
*(gpioReg + GPPUDCLK0 + PI_BANK) = PI_BIT;
|
||||
|
||||
usleep(20);
|
||||
|
||||
*(gpioReg + GPPUD) = 0;
|
||||
|
||||
*(gpioReg + GPPUDCLK0 + PI_BANK) = 0;
|
||||
}
|
||||
|
||||
int gpioRead(unsigned gpio)
|
||||
{
|
||||
if ((*(gpioReg + GPLEV0 + PI_BANK) & PI_BIT) != 0) return 1;
|
||||
else return 0;
|
||||
}
|
||||
void gpioWrite(unsigned gpio, unsigned level)
|
||||
{
|
||||
if (level == 0)
|
||||
*(gpioReg + GPCLR0 + PI_BANK) = PI_BIT;
|
||||
else
|
||||
*(gpioReg + GPSET0 + PI_BANK) = PI_BIT;
|
||||
}
|
||||
|
||||
void gpioTrigger(unsigned gpio, unsigned pulseLen, unsigned level)
|
||||
{
|
||||
if (level == 0) *(gpioReg + GPCLR0 + PI_BANK) = PI_BIT;
|
||||
else *(gpioReg + GPSET0 + PI_BANK) = PI_BIT;
|
||||
|
||||
usleep(pulseLen);
|
||||
|
||||
if (level != 0) *(gpioReg + GPCLR0 + PI_BANK) = PI_BIT;
|
||||
else *(gpioReg + GPSET0 + PI_BANK) = PI_BIT;
|
||||
}
|
||||
|
||||
/* Bit (1<<x) will be set if gpio x is high. */
|
||||
|
||||
uint32_t gpioReadBank1(void) { return (*(gpioReg + GPLEV0)); }
|
||||
uint32_t gpioReadBank2(void) { return (*(gpioReg + GPLEV1)); }
|
||||
|
||||
/* To clear gpio x bit or in (1<<x). */
|
||||
|
||||
void gpioClearBank1(uint32_t bits) { *(gpioReg + GPCLR0) = bits; }
|
||||
void gpioClearBank2(uint32_t bits) { *(gpioReg + GPCLR1) = bits; }
|
||||
|
||||
/* To set gpio x bit or in (1<<x). */
|
||||
|
||||
void gpioSetBank1(uint32_t bits) { *(gpioReg + GPSET0) = bits; }
|
||||
void gpioSetBank2(uint32_t bits) { *(gpioReg + GPSET1) = bits; }
|
||||
|
||||
unsigned gpioHardwareRevision(void)
|
||||
{
|
||||
static unsigned rev = 0;
|
||||
|
||||
FILE * filp;
|
||||
char buf[512];
|
||||
char term;
|
||||
int chars=4; /* number of chars in revision string */
|
||||
|
||||
if (rev) return rev;
|
||||
|
||||
piModel = 0;
|
||||
|
||||
filp = fopen ("/proc/cpuinfo", "r");
|
||||
|
||||
if (filp != NULL)
|
||||
{
|
||||
while (fgets(buf, sizeof(buf), filp) != NULL)
|
||||
{
|
||||
if (piModel == 0)
|
||||
{
|
||||
if (!strncasecmp("model name", buf, 10))
|
||||
{
|
||||
if (strstr (buf, "ARMv6") != NULL)
|
||||
{
|
||||
piModel = 1;
|
||||
chars = 4;
|
||||
}
|
||||
else if (strstr (buf, "ARMv7") != NULL)
|
||||
{
|
||||
piModel = 2;
|
||||
chars = 6;
|
||||
}
|
||||
else if (strstr (buf, "ARMv8") != NULL)
|
||||
{
|
||||
piModel = 2;
|
||||
chars = 6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!strncasecmp("revision", buf, 8))
|
||||
{
|
||||
if (sscanf(buf+strlen(buf)-(chars+1),
|
||||
"%x%c", &rev, &term) == 2)
|
||||
{
|
||||
if (term != '\n') rev = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(filp);
|
||||
}
|
||||
return rev;
|
||||
}
|
||||
|
||||
int gpioInitialise(void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
piRev = gpioHardwareRevision(); /* sets piModel and piRev */
|
||||
|
||||
fd = open("/dev/gpiomem", O_RDWR | O_SYNC) ;
|
||||
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf(stderr, "failed to open /dev/gpiomem\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
gpioReg = (uint32_t *)mmap(NULL, 0xB4, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
|
||||
close(fd);
|
||||
|
||||
if (gpioReg == MAP_FAILED)
|
||||
{
|
||||
fprintf(stderr, "Bad, mmap failed\n");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int stricmp(const unsigned char * pStr1, const unsigned char *pStr2)
|
||||
{
|
||||
unsigned char c1, c2;
|
||||
int v;
|
||||
|
||||
if (pStr1 == NULL)
|
||||
{
|
||||
if (pStr2)
|
||||
Debugprintf("stricmp called with NULL 1st param - 2nd %s ", pStr2);
|
||||
else
|
||||
Debugprintf("stricmp called with two NULL params");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
c1 = *pStr1++;
|
||||
c2 = *pStr2++;
|
||||
/* The casts are necessary when pStr1 is shorter & char is signed */
|
||||
v = tolower(c1) - tolower(c2);
|
||||
} while ((v == 0) && (c1 != '\0') && (c2 != '\0') );
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
|
355
ModemDialog.ui
355
ModemDialog.ui
|
@ -320,7 +320,7 @@
|
|||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Modem type</string>
|
||||
<string>Modem params</string>
|
||||
</property>
|
||||
<widget class="QLineEdit" name="RXShiftA">
|
||||
<property name="geometry">
|
||||
|
@ -337,7 +337,7 @@
|
|||
<rect>
|
||||
<x>100</x>
|
||||
<y>21</y>
|
||||
<width>61</width>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -346,8 +346,8 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>51</y>
|
||||
<width>61</width>
|
||||
<y>50</y>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -399,7 +399,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>50</y>
|
||||
<y>49</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
|
@ -464,7 +464,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>176</x>
|
||||
<y>51</y>
|
||||
<y>50</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
|
@ -541,7 +541,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>80</y>
|
||||
<y>79</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
|
@ -554,7 +554,7 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>176</x>
|
||||
<y>81</y>
|
||||
<y>80</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
|
@ -567,31 +567,8 @@
|
|||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>81</y>
|
||||
<width>61</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_71">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>109</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Retries</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RetriesA">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>110</y>
|
||||
<width>61</width>
|
||||
<y>80</y>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -714,6 +691,52 @@
|
|||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_87">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>111</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>maxFrame</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="MaxFrameA">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>112</y>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RetriesA">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>111</y>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_71">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>110</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Retries</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -1051,7 +1074,7 @@
|
|||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Modem type</string>
|
||||
<string>Modem params</string>
|
||||
</property>
|
||||
<widget class="QLineEdit" name="RXShiftB">
|
||||
<property name="geometry">
|
||||
|
@ -1304,29 +1327,6 @@
|
|||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_74">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>109</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Retries</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RetriesB">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>110</y>
|
||||
<width>61</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="SendRSID_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
|
@ -1446,6 +1446,52 @@
|
|||
</item>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_88">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>121</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>maxFrame</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RetriesB">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>121</y>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_74">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>121</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Retries</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="MaxFrameB">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>121</y>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
|
@ -1782,7 +1828,7 @@
|
|||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Modem type</string>
|
||||
<string>Modem params</string>
|
||||
</property>
|
||||
<widget class="QLineEdit" name="RXShiftC">
|
||||
<property name="geometry">
|
||||
|
@ -2035,29 +2081,6 @@
|
|||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_77">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>109</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Retries</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RetriesC">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>110</y>
|
||||
<width>61</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="RSIDSABM_C">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
|
@ -2133,6 +2156,52 @@
|
|||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_89">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>111</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>maxFrame</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RetriesC">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>111</y>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_77">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>111</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Retries</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="MaxFrameC">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>111</y>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="IL2PModeC">
|
||||
<property name="geometry">
|
||||
|
@ -2513,7 +2582,7 @@
|
|||
</rect>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Modem type</string>
|
||||
<string>Modem params</string>
|
||||
</property>
|
||||
<widget class="QLineEdit" name="RXShiftD">
|
||||
<property name="geometry">
|
||||
|
@ -2766,29 +2835,6 @@
|
|||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_80">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>109</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Retries</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RetriesD">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>110</y>
|
||||
<width>61</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="RSIDSABM_D">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
|
@ -2864,6 +2910,52 @@
|
|||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_90">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>130</x>
|
||||
<y>111</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>maxFrame</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RetriesD">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>111</y>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_80">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>111</y>
|
||||
<width>71</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Retries</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="MaxFrameD">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>111</y>
|
||||
<width>41</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="IL2PModeD">
|
||||
<property name="geometry">
|
||||
|
@ -2963,8 +3055,8 @@
|
|||
<widget class="QLabel" name="label_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>80</x>
|
||||
<y>520</y>
|
||||
<x>44</x>
|
||||
<y>516</y>
|
||||
<width>71</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
@ -2976,8 +3068,8 @@
|
|||
<widget class="QLineEdit" name="CWIDCall">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>150</x>
|
||||
<y>520</y>
|
||||
<x>114</x>
|
||||
<y>516</y>
|
||||
<width>51</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
@ -2989,8 +3081,8 @@
|
|||
<widget class="QRadioButton" name="CWIDType">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>340</x>
|
||||
<y>520</y>
|
||||
<x>410</x>
|
||||
<y>516</y>
|
||||
<width>61</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
@ -3002,8 +3094,8 @@
|
|||
<widget class="QRadioButton" name="radioButton_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>390</x>
|
||||
<y>520</y>
|
||||
<x>460</x>
|
||||
<y>516</y>
|
||||
<width>101</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
@ -3015,8 +3107,8 @@
|
|||
<widget class="QLabel" name="label_66">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>220</x>
|
||||
<y>520</y>
|
||||
<x>190</x>
|
||||
<y>516</y>
|
||||
<width>61</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
|
@ -3028,13 +3120,42 @@
|
|||
<widget class="QLineEdit" name="CWIDInterval">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>270</x>
|
||||
<y>520</y>
|
||||
<x>240</x>
|
||||
<y>516</y>
|
||||
<width>31</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_91">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>294</x>
|
||||
<y>516</y>
|
||||
<width>61</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Mark Freq</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="CWIDMark">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>348</x>
|
||||
<y>516</y>
|
||||
<width>41</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Leave blank for default</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
|
|
29
Modulate.c
29
Modulate.c
|
@ -5,7 +5,9 @@
|
|||
|
||||
#define ARDOPBufferSize 12000 * 100
|
||||
|
||||
extern short ARDOPTXBuffer[4][12000 * 100]; // Enough to hold whole frame of samples
|
||||
extern char CWIDMark[32];
|
||||
|
||||
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
|
||||
|
@ -966,7 +968,7 @@ void sendCWID(char * strID, BOOL CWOnOff, int Chan)
|
|||
0x557, 0x155, 0x755, 0x1DD5, 0x7775, 0x1DDDD, 0x1D57, 0x1D57};
|
||||
|
||||
|
||||
float dblHiPhaseInc = 2 * M_PI * 1609.375f / 12000; // 1609.375 Hz High tone
|
||||
float dblHiPhaseInc = 2 * M_PI * 1509.375f / 12000; // 1609.375 Hz High tone
|
||||
float dblLoPhaseInc = 2 * M_PI * 1390.625f / 12000; // 1390.625 low tone
|
||||
float dblHiPhase = 0;
|
||||
float dblLoPhase = 0;
|
||||
|
@ -978,6 +980,23 @@ void sendCWID(char * strID, BOOL CWOnOff, int Chan)
|
|||
char * index;
|
||||
int intMask;
|
||||
int idoffset;
|
||||
int Filter = 1500;
|
||||
|
||||
if (CWIDMark[0])
|
||||
{
|
||||
// Want nonstandard tones
|
||||
|
||||
float Mark = atof(CWIDMark);
|
||||
float Space = Mark - 200;
|
||||
|
||||
dblHiPhaseInc = 2 * M_PI * Mark / 12000; // 1609.375 Hz High tone
|
||||
dblLoPhaseInc = 2 * M_PI * Space / 12000; // 1390.625 low tone
|
||||
|
||||
if (CWOnOff)
|
||||
Filter = Mark;
|
||||
else
|
||||
Filter = (Mark + Space) / 2;
|
||||
}
|
||||
|
||||
strlop(strID, '-'); // Remove any SSID
|
||||
|
||||
|
@ -1000,7 +1019,11 @@ void sendCWID(char * strID, BOOL CWOnOff, int Chan)
|
|||
dblLoPhase -= 2 * M_PI;
|
||||
}
|
||||
|
||||
initFilter(500,1500, Chan);
|
||||
if (CWOnOff)
|
||||
initFilter(500, Filter, Chan);
|
||||
else
|
||||
initFilter(200, Filter, Chan);
|
||||
|
||||
|
||||
//Generate leader for VOX 6 dots long
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,292 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4EDE958E-D0AC-37B4-81F7-78313A262DCD}</ProjectGuid>
|
||||
<RootNamespace>QtSoundModem</RootNamespace>
|
||||
<Keyword>QtVS_v304</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
|
||||
<QtMsBuild Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<OutputDirectory>release\</OutputDirectory>
|
||||
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<IntermediateDirectory>release\</IntermediateDirectory>
|
||||
<PrimaryOutput>QtSoundModem</PrimaryOutput>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<OutputDirectory>debug\</OutputDirectory>
|
||||
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<IntermediateDirectory>debug\</IntermediateDirectory>
|
||||
<PrimaryOutput>QtSoundModem</PrimaryOutput>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
|
||||
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
|
||||
</Target>
|
||||
<ImportGroup Label="ExtensionSettings" />
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
|
||||
<Import Project="$(QtMsBuild)\qt_defaults.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>QtSoundModem</TargetName>
|
||||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\\</IntDir>
|
||||
<TargetName>QtSoundModem</TargetName>
|
||||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<QtInstall>5.14</QtInstall>
|
||||
<QtModules>core;network;gui;widgets;serialport</QtModules>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<QtInstall>5.14.2</QtInstall>
|
||||
<QtModules>core;network;gui;widgets;serialport</QtModules>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
|
||||
<Import Project="$(QtMsBuild)\qt.props" />
|
||||
</ImportGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>rsid;.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;release;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<BrowseInformation>false</BrowseInformation>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libfftw3f-3.lib;shell32.lib;setupapi.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
||||
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<OutputFile>$(OutDir)QtSoundModem.exe</OutputFile>
|
||||
<RandomizedBaseAddress>true</RandomizedBaseAddress>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
</Link>
|
||||
<Midl>
|
||||
<DefaultCharType>Unsigned</DefaultCharType>
|
||||
<EnableErrorChecks>None</EnableErrorChecks>
|
||||
<WarningLevel>0</WarningLevel>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_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)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<QtMoc>
|
||||
<CompilerFlavor>msvc</CompilerFlavor>
|
||||
<Include>./$(Configuration)/moc_predefs.h</Include>
|
||||
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
|
||||
<DynamicSource>output</DynamicSource>
|
||||
<QtMocDir>$(IntDir)</QtMocDir>
|
||||
<QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
|
||||
</QtMoc>
|
||||
<QtRcc>
|
||||
<InitFuncName>QtSoundModem</InitFuncName>
|
||||
<Compression>default</Compression>
|
||||
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
|
||||
<QtRccDir>$(IntDir)</QtRccDir>
|
||||
<QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
|
||||
</QtRcc>
|
||||
<QtUic>
|
||||
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
|
||||
<QtUicDir>$(IntDir)</QtUicDir>
|
||||
<QtUicFileName>ui_%(Filename).h</QtUicFileName>
|
||||
</QtUic>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;debug;/include;rsid;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<BrowseInformation>false</BrowseInformation>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libfftw3f-3.lib;shell32.lib;setupapi.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
||||
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<OutputFile>$(OutDir)\QtSoundModem.exe</OutputFile>
|
||||
<RandomizedBaseAddress>true</RandomizedBaseAddress>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
<Midl>
|
||||
<DefaultCharType>Unsigned</DefaultCharType>
|
||||
<EnableErrorChecks>None</EnableErrorChecks>
|
||||
<WarningLevel>0</WarningLevel>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_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)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<QtMoc>
|
||||
<CompilerFlavor>msvc</CompilerFlavor>
|
||||
<Include>./$(Configuration)/moc_predefs.h</Include>
|
||||
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
|
||||
<DynamicSource>output</DynamicSource>
|
||||
<QtMocDir>$(IntDir)</QtMocDir>
|
||||
<QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
|
||||
</QtMoc>
|
||||
<QtRcc>
|
||||
<InitFuncName>QtSoundModem</InitFuncName>
|
||||
<Compression>default</Compression>
|
||||
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
|
||||
<QtRccDir>$(IntDir)</QtRccDir>
|
||||
<QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
|
||||
</QtRcc>
|
||||
<QtUic>
|
||||
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
|
||||
<QtUicDir>$(IntDir)</QtUicDir>
|
||||
<QtUicFileName>ui_%(Filename).h</QtUicFileName>
|
||||
</QtUic>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ARDOPC.c" />
|
||||
<ClCompile Include="BusyDetect.c" />
|
||||
<ClCompile Include="Config.cpp" />
|
||||
<ClCompile Include="dw9600.c" />
|
||||
<ClCompile Include="hid.c" />
|
||||
<ClCompile Include="il2p.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsC</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Modulate.c" />
|
||||
<ClCompile Include="QtSoundModem.cpp" />
|
||||
<ClCompile Include="rsid.c" />
|
||||
<ClCompile Include="RSUnit.c" />
|
||||
<ClCompile Include="SMMain.c" />
|
||||
<ClCompile Include="ShowFilter.cpp" />
|
||||
<ClCompile Include="SoundInput.c" />
|
||||
<ClCompile Include="UZ7HOUtils.c" />
|
||||
<ClCompile Include="ardopSampleArrays.c" />
|
||||
<ClCompile Include="ax25.c" />
|
||||
<ClCompile Include="ax25_agw.c" />
|
||||
<ClCompile Include="ax25_demod.c" />
|
||||
<ClCompile Include="ax25_fec.c" />
|
||||
<ClCompile Include="ax25_l2.c" />
|
||||
<ClCompile Include="ax25_mod.c" />
|
||||
<ClCompile Include="berlekamp.c" />
|
||||
<ClCompile Include="galois.c" />
|
||||
<ClCompile Include="kiss_mode.c" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="ofdm.c" />
|
||||
<ClCompile Include="pktARDOP.c" />
|
||||
<ClCompile Include="rs.c" />
|
||||
<ClCompile Include="sm_main.c" />
|
||||
<ClCompile Include="tcpCode.cpp" />
|
||||
<ClCompile Include="Waveout.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="QtSoundModem.h">
|
||||
</QtMoc>
|
||||
<ClInclude Include="UZ7HOStuff.h" />
|
||||
<QtMoc Include="tcpCode.h">
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
||||
<FileType>Document</FileType>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">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</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Generate moc_predefs.h</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">debug\moc_predefs.h;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="release\moc_predefs.h.cbt">
|
||||
<FileType>Document</FileType>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">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</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Generate moc_predefs.h</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">release\moc_predefs.h;%(Outputs)</Outputs>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUic Include="ModemDialog.ui">
|
||||
</QtUic>
|
||||
<QtUic Include="QtSoundModem.ui">
|
||||
</QtUic>
|
||||
<QtUic Include="calibrateDialog.ui">
|
||||
</QtUic>
|
||||
<QtUic Include="devicesDialog.ui">
|
||||
</QtUic>
|
||||
<QtUic Include="filterWindow.ui">
|
||||
</QtUic>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtRcc Include="QtSoundModem.qrc">
|
||||
</QtRcc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include=".\QtSoundModem_resource.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="QtSoundModem.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
|
||||
<Import Project="$(QtMsBuild)\qt.targets" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
272
QtSoundModem.cpp
272
QtSoundModem.cpp
|
@ -50,7 +50,7 @@ along with QtSoundModem. If not, see http://www.gnu.org/licenses
|
|||
#include "UZ7HOStuff.h"
|
||||
|
||||
|
||||
QImage *Constellation;
|
||||
QImage *Constellation[4];
|
||||
QImage *Waterfall[4] = { 0,0,0,0 };
|
||||
QImage *Header[4];
|
||||
QLabel *DCDLabel[4];
|
||||
|
@ -73,7 +73,7 @@ void saveSettings();
|
|||
void getSettings();
|
||||
extern "C" void CloseSound();
|
||||
extern "C" void GetSoundDevices();
|
||||
extern "C" char modes_name[modes_count][20];
|
||||
extern "C" char modes_name[modes_count][21];
|
||||
extern "C" int speed[5];
|
||||
extern "C" int KISSPort;
|
||||
extern "C" short rx_freq[5];
|
||||
|
@ -91,6 +91,7 @@ extern "C" int SoundMode;
|
|||
extern "C" int multiCore;
|
||||
|
||||
extern "C" int refreshModems;
|
||||
int NeedPSKRefresh;
|
||||
|
||||
extern "C" int pnt_change[5];
|
||||
extern "C" int needRSID[4];
|
||||
|
@ -101,6 +102,11 @@ extern "C" float MagOut[4096];
|
|||
extern "C" float MaxMagOut;
|
||||
extern "C" int MaxMagIndex;
|
||||
|
||||
|
||||
extern "C" int using48000; // Set if using 48K sample rate (ie RUH Modem active)
|
||||
extern "C" int ReceiveSize;
|
||||
extern "C" int SendSize; // 100 mS for now
|
||||
|
||||
extern "C"
|
||||
{
|
||||
int InitSound(BOOL Report);
|
||||
|
@ -137,6 +143,7 @@ int FreqD = 1500;
|
|||
int DCD = 50;
|
||||
|
||||
char CWIDCall[128] = "";
|
||||
extern "C" char CWIDMark[32] = "";
|
||||
int CWIDInterval = 0;
|
||||
int CWIDLeft = 0;
|
||||
int CWIDRight = 0;
|
||||
|
@ -147,11 +154,12 @@ int WaterfallMax = 6000;
|
|||
|
||||
int Configuring = 0;
|
||||
|
||||
float BinSize;
|
||||
extern "C" float BinSize;
|
||||
|
||||
extern "C" { int RSID_SABM[4]; }
|
||||
extern "C" { int RSID_UI[4]; }
|
||||
extern "C" { int RSID_SetModem[4]; }
|
||||
extern "C" unsigned int pskStates[4];
|
||||
|
||||
int Closing = FALSE; // Set to stop background thread
|
||||
|
||||
|
@ -461,17 +469,80 @@ void QtSoundModem::initWaterfall(int chan, int state)
|
|||
QApplication::sendEvent(this, event);
|
||||
}
|
||||
|
||||
QRect PSKRect = { 100,100,100,100 };
|
||||
|
||||
QDialog * constellationDialog;
|
||||
QLabel * constellationLabel[4];
|
||||
QLabel * QualLabel[4];
|
||||
|
||||
// Local copies
|
||||
|
||||
QLabel *RXOffsetLabel;
|
||||
QSlider *RXOffset;
|
||||
|
||||
extern "C" void CheckPSKWindows()
|
||||
{
|
||||
NeedPSKRefresh = 1;
|
||||
}
|
||||
void DoPSKWindows()
|
||||
{
|
||||
// Display Constellation for PSK Window;
|
||||
|
||||
int NextX = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (pskStates[i])
|
||||
{
|
||||
constellationLabel[i]->setGeometry(QRect(NextX, 19, 121, 121));
|
||||
QualLabel[i]->setGeometry(QRect(1 + NextX, 1, 120, 15));
|
||||
constellationLabel[i]->setVisible(1);
|
||||
QualLabel[i]->setVisible(1);
|
||||
|
||||
NextX += 122;
|
||||
}
|
||||
else
|
||||
{
|
||||
constellationLabel[i]->setVisible(0);
|
||||
QualLabel[i]->setVisible(0);
|
||||
}
|
||||
}
|
||||
constellationDialog->resize(NextX, 140);
|
||||
}
|
||||
|
||||
|
||||
|
||||
QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
|
||||
QSettings mysettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
|
||||
constellationDialog = new QDialog(nullptr, Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
|
||||
constellationDialog->resize(488, 140);
|
||||
constellationDialog->setGeometry(PSKRect);
|
||||
|
||||
QFont f("Arial", 8, QFont::Normal);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
char Text[16];
|
||||
sprintf(Text, "Chan %c", i + 'A');
|
||||
|
||||
constellationLabel[i] = new QLabel(constellationDialog);
|
||||
constellationDialog->setWindowTitle("PSK Constellations");
|
||||
|
||||
QualLabel[i] = new QLabel(constellationDialog);
|
||||
QualLabel[i]->setText(Text);
|
||||
QualLabel[i]->setFont(f);
|
||||
|
||||
Constellation[i] = new QImage(121, 121, QImage::Format_RGB32);
|
||||
Constellation[i]->fill(black);
|
||||
constellationLabel[i]->setPixmap(QPixmap::fromImage(*Constellation[i]));
|
||||
}
|
||||
constellationDialog->show();
|
||||
|
||||
if (MintoTray)
|
||||
{
|
||||
char popUp[256];
|
||||
|
@ -483,6 +554,20 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
|
|||
connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(TrayActivated(QSystemTrayIcon::ActivationReason)));
|
||||
}
|
||||
|
||||
using48000 = 0; // Set if using 48K sample rate (ie RUH Modem active)
|
||||
ReceiveSize = 512;
|
||||
SendSize = 1024; // 100 mS for now
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (soundChannel[i] && (speed[i] == SPEED_RUH48 || speed[i] == SPEED_RUH96))
|
||||
{
|
||||
using48000 = 1; // Set if using 48K sample rate (ie RUH Modem active)
|
||||
ReceiveSize = 2048;
|
||||
SendSize = 4096; // 100 mS for now
|
||||
}
|
||||
}
|
||||
|
||||
float FFTCalc = 12000.0f / ((WaterfallMax - WaterfallMin) / 900.0f);
|
||||
|
||||
FFTSize = FFTCalc + 0.4999;
|
||||
|
@ -648,6 +733,11 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
|
|||
connect(ui.modeC, SIGNAL(currentIndexChanged(int)), this, SLOT(clickedSlotI(int)));
|
||||
connect(ui.modeD, SIGNAL(currentIndexChanged(int)), this, SLOT(clickedSlotI(int)));
|
||||
|
||||
ModemA = speed[0];
|
||||
ModemB = speed[1];
|
||||
ModemC = speed[2];
|
||||
ModemD = speed[3];
|
||||
|
||||
ui.modeA->setCurrentIndex(speed[0]);
|
||||
ui.modeB->setCurrentIndex(speed[1]);
|
||||
ui.modeC->setCurrentIndex(speed[2]);
|
||||
|
@ -692,6 +782,10 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent)
|
|||
connect(timer, SIGNAL(timeout()), this, SLOT(MyTimerSlot()));
|
||||
timer->start(100);
|
||||
|
||||
QTimer *wftimer = new QTimer(this);
|
||||
connect(wftimer, SIGNAL(timeout()), this, SLOT(doRestartWF()));
|
||||
wftimer->start(1000 * 300);
|
||||
|
||||
|
||||
cwidtimer = new QTimer(this);
|
||||
connect(cwidtimer, SIGNAL(timeout()), this, SLOT(CWIDTimer()));
|
||||
|
@ -776,6 +870,11 @@ void QtSoundModem::MyTimerSlot()
|
|||
ui.centerC->setValue(rx_freq[2]);
|
||||
ui.centerD->setValue(rx_freq[3]);
|
||||
}
|
||||
if (NeedPSKRefresh)
|
||||
{
|
||||
NeedPSKRefresh = 0;
|
||||
DoPSKWindows();
|
||||
}
|
||||
|
||||
show_grid();
|
||||
}
|
||||
|
@ -798,6 +897,44 @@ void QtSoundModem::returnPressed()
|
|||
|
||||
}
|
||||
|
||||
void CheckforChanges(int Mode, int OldMode)
|
||||
{
|
||||
int old48000 = using48000;
|
||||
|
||||
if (OldMode != Mode && Mode == 15)
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
|
||||
msgBox.setText("Warning!!\nARDOP Packet is NOT the same as ARDOP\n"
|
||||
"It is an experimental mode for sending ax.25 frames using ARDOP packet formats\n");
|
||||
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
|
||||
msgBox.exec();
|
||||
}
|
||||
|
||||
// See if need to switch beween 12000 and 48000
|
||||
|
||||
using48000 = 0; // Set if using 48K sample rate (ie RUH Modem active)
|
||||
ReceiveSize = 512;
|
||||
SendSize = 1024; // 100 mS for now
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (soundChannel[i] && (speed[i] == SPEED_RUH48 || speed[i] == SPEED_RUH96))
|
||||
{
|
||||
using48000 = 1; // Set if using 48K sample rate (ie RUH Modem active)
|
||||
ReceiveSize = 2048;
|
||||
SendSize = 4096; // 100 mS for now
|
||||
}
|
||||
}
|
||||
|
||||
if (using48000 != old48000)
|
||||
{
|
||||
InitSound(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QtSoundModem::clickedSlotI(int i)
|
||||
{
|
||||
|
@ -807,8 +944,10 @@ void QtSoundModem::clickedSlotI(int i)
|
|||
|
||||
if (strcmp(Name, "modeA") == 0)
|
||||
{
|
||||
int OldModem = ModemA;
|
||||
ModemA = ui.modeA->currentIndex();
|
||||
set_speed(0, ModemA);
|
||||
CheckforChanges(ModemA, OldModem);
|
||||
saveSettings();
|
||||
AGW_Report_Modem_Change(0);
|
||||
return;
|
||||
|
@ -816,8 +955,10 @@ void QtSoundModem::clickedSlotI(int i)
|
|||
|
||||
if (strcmp(Name, "modeB") == 0)
|
||||
{
|
||||
int OldModem = ModemB;
|
||||
ModemB = ui.modeB->currentIndex();
|
||||
set_speed(1, ModemB);
|
||||
CheckforChanges(ModemB, OldModem);
|
||||
saveSettings();
|
||||
AGW_Report_Modem_Change(1);
|
||||
return;
|
||||
|
@ -825,8 +966,10 @@ void QtSoundModem::clickedSlotI(int i)
|
|||
|
||||
if (strcmp(Name, "modeC") == 0)
|
||||
{
|
||||
int OldModem = ModemC;
|
||||
ModemC = ui.modeC->currentIndex();
|
||||
set_speed(2, ModemC);
|
||||
CheckforChanges(ModemC, OldModem);
|
||||
saveSettings();
|
||||
AGW_Report_Modem_Change(2);
|
||||
return;
|
||||
|
@ -834,8 +977,10 @@ void QtSoundModem::clickedSlotI(int i)
|
|||
|
||||
if (strcmp(Name, "modeD") == 0)
|
||||
{
|
||||
int OldModem = ModemD;
|
||||
ModemD = ui.modeD->currentIndex();
|
||||
set_speed(3, ModemD);
|
||||
CheckforChanges(ModemD, OldModem);
|
||||
saveSettings();
|
||||
AGW_Report_Modem_Change(3);
|
||||
return;
|
||||
|
@ -843,7 +988,7 @@ void QtSoundModem::clickedSlotI(int i)
|
|||
|
||||
if (strcmp(Name, "centerA") == 0)
|
||||
{
|
||||
if (i > 300)
|
||||
if (i > 299)
|
||||
{
|
||||
QSettings * settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
ui.centerA->setValue(Freq_Change(0, i));
|
||||
|
@ -856,7 +1001,7 @@ void QtSoundModem::clickedSlotI(int i)
|
|||
|
||||
if (strcmp(Name, "centerB") == 0)
|
||||
{
|
||||
if (i > 300)
|
||||
if (i > 299)
|
||||
{
|
||||
QSettings * settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
ui.centerB->setValue(Freq_Change(1, i));
|
||||
|
@ -868,7 +1013,7 @@ void QtSoundModem::clickedSlotI(int i)
|
|||
|
||||
if (strcmp(Name, "centerC") == 0)
|
||||
{
|
||||
if (i > 300)
|
||||
if (i > 299)
|
||||
{
|
||||
QSettings * settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
ui.centerC->setValue(Freq_Change(2, i));
|
||||
|
@ -880,7 +1025,7 @@ void QtSoundModem::clickedSlotI(int i)
|
|||
|
||||
if (strcmp(Name, "centerD") == 0)
|
||||
{
|
||||
if (i > 300)
|
||||
if (i > 299)
|
||||
{
|
||||
QSettings * settings = new QSettings("QtSoundModem.ini", QSettings::IniFormat);
|
||||
ui.centerD->setValue(Freq_Change(3, i));
|
||||
|
@ -1187,6 +1332,15 @@ void QtSoundModem::doModems()
|
|||
Dlg->KISSOptC->setChecked(KISS_opt[2]);
|
||||
Dlg->KISSOptD->setChecked(KISS_opt[3]);
|
||||
|
||||
sprintf(valChar, "%d", maxframe[0]);
|
||||
Dlg->MaxFrameA->setText(valChar);
|
||||
sprintf(valChar, "%d", maxframe[1]);
|
||||
Dlg->MaxFrameB->setText(valChar);
|
||||
sprintf(valChar, "%d", maxframe[2]);
|
||||
Dlg->MaxFrameC->setText(valChar);
|
||||
sprintf(valChar, "%d", maxframe[3]);
|
||||
Dlg->MaxFrameD->setText(valChar);
|
||||
|
||||
sprintf(valChar, "%d", txdelay[0]);
|
||||
Dlg->TXDelayA->setText(valChar);
|
||||
sprintf(valChar, "%d", txdelay[1]);
|
||||
|
@ -1196,6 +1350,7 @@ void QtSoundModem::doModems()
|
|||
sprintf(valChar, "%d", txdelay[3]);
|
||||
Dlg->TXDelayD->setText(valChar);
|
||||
|
||||
|
||||
sprintf(valChar, "%d", txtail[0]);
|
||||
Dlg->TXTailA->setText(valChar);
|
||||
sprintf(valChar, "%d", txtail[1]);
|
||||
|
@ -1255,6 +1410,7 @@ void QtSoundModem::doModems()
|
|||
|
||||
Dlg->CWIDCall->setText(CWIDCall);
|
||||
Dlg->CWIDInterval->setText(QString::number(CWIDInterval));
|
||||
Dlg->CWIDMark->setText(CWIDMark);
|
||||
|
||||
if (CWIDType)
|
||||
Dlg->radioButton_2->setChecked(1);
|
||||
|
@ -1396,6 +1552,23 @@ void QtSoundModem::modemSave()
|
|||
Q = Dlg->TXDelayD->text();
|
||||
txdelay[3] = Q.toInt();
|
||||
|
||||
Q = Dlg->MaxFrameA->text();
|
||||
maxframe[0] = Q.toInt();
|
||||
|
||||
Q = Dlg->MaxFrameB->text();
|
||||
maxframe[1] = Q.toInt();
|
||||
|
||||
Q = Dlg->MaxFrameC->text();
|
||||
maxframe[2] = Q.toInt();
|
||||
|
||||
Q = Dlg->MaxFrameD->text();
|
||||
maxframe[3] = Q.toInt();
|
||||
|
||||
if (maxframe[0] == 0 || maxframe[0] > 7) maxframe[0] = 3;
|
||||
if (maxframe[1] == 0 || maxframe[1] > 7) maxframe[1] = 3;
|
||||
if (maxframe[2] == 0 || maxframe[2] > 7) maxframe[2] = 3;
|
||||
if (maxframe[3] == 0 || maxframe[3] > 7) maxframe[3] = 3;
|
||||
|
||||
Q = Dlg->TXTailA->text();
|
||||
txtail[0] = Q.toInt();
|
||||
|
||||
|
@ -1458,6 +1631,7 @@ void QtSoundModem::modemSave()
|
|||
|
||||
|
||||
strcpy(CWIDCall, Dlg->CWIDCall->text().toUtf8().toUpper());
|
||||
strcpy(CWIDMark, Dlg->CWIDMark->text().toUtf8().toUpper());
|
||||
CWIDInterval = Dlg->CWIDInterval->text().toInt();
|
||||
CWIDType = Dlg->radioButton_2->isChecked();
|
||||
|
||||
|
@ -2094,7 +2268,7 @@ void QtSoundModem::deviceaccept()
|
|||
// Reset title and tooltip in case ports changed
|
||||
|
||||
char Title[128];
|
||||
sprintf(Title, "QtSoundModem Version %s Ports %d/%d", VersionString, AGWPort, KISSPort);
|
||||
sprintf(Title, "QtSoundModem Version %s Ports %d%s/%d%s", VersionString, AGWPort, AGWServ ? "*": "", KISSPort, KISSServ ? "*" : "");
|
||||
w->setWindowTitle(Title);
|
||||
|
||||
sprintf(Title, "QtSoundModem %d %d", AGWPort, KISSPort);
|
||||
|
@ -2517,6 +2691,7 @@ extern "C" void doWaterfall(int snd_ch)
|
|||
|
||||
|
||||
extern "C" float aFFTAmpl[1024];
|
||||
extern "C" void SMUpdateBusyDetector(int LR, float * Real, float *Imag);
|
||||
|
||||
void doWaterfallThread(void * param)
|
||||
{
|
||||
|
@ -2617,6 +2792,8 @@ void doWaterfallThread(void * param)
|
|||
}
|
||||
}
|
||||
|
||||
SMUpdateBusyDetector(snd_ch, RealOut, ImagOut);
|
||||
|
||||
if (bm == 0)
|
||||
return;
|
||||
|
||||
|
@ -2875,3 +3052,82 @@ void QtSoundModem::onTEselectionChanged()
|
|||
x->copy();
|
||||
}
|
||||
|
||||
#define ConstellationHeight 121
|
||||
#define ConstellationWidth 121
|
||||
#define PLOTRADIUS 60
|
||||
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
extern "C" int SMUpdatePhaseConstellation(int chan, float * Phases, float * Mags, int intPSKPhase, int Count)
|
||||
{
|
||||
// Subroutine to update bmpConstellation plot for PSK modes...
|
||||
// Skip plotting and calculations of intPSKPhase(0) as this is a reference phase (9/30/2014)
|
||||
|
||||
float dblPhaseError;
|
||||
float dblPhaseErrorSum = 0;
|
||||
float intP = 0;
|
||||
float dblRad = 0;
|
||||
float dblAvgRad = 0;
|
||||
float dbPhaseStep;
|
||||
float MagMax = 0;
|
||||
float dblPlotRotation = 0;
|
||||
|
||||
int i, intQuality;
|
||||
|
||||
int intX, intY;
|
||||
int yCenter = (ConstellationHeight - 2) / 2;
|
||||
int xCenter = (ConstellationWidth - 2) / 2;
|
||||
|
||||
Constellation[chan]->fill(black);
|
||||
|
||||
for (i = 0; i < 120; i++)
|
||||
{
|
||||
Constellation[chan]->setPixel(xCenter, i, cyan);
|
||||
Constellation[chan]->setPixel(i, xCenter, cyan);
|
||||
}
|
||||
|
||||
if (Count == 0)
|
||||
return 0;
|
||||
|
||||
dbPhaseStep = 2 * M_PI / intPSKPhase;
|
||||
|
||||
for (i = 1; i < Count; i++) // Don't plot the first phase (reference)
|
||||
{
|
||||
MagMax = MAX(MagMax, Mags[i]); // find the max magnitude to auto scale
|
||||
dblAvgRad += Mags[i];
|
||||
}
|
||||
|
||||
dblAvgRad = dblAvgRad / Count; // the average radius
|
||||
|
||||
for (i = 0; i < Count; i++)
|
||||
{
|
||||
dblRad = PLOTRADIUS * Mags[i] / MagMax; // scale the radius dblRad based on intMag
|
||||
intP = round((Phases[i]) / dbPhaseStep);
|
||||
|
||||
// compute the Phase error
|
||||
|
||||
dblPhaseError = fabsf(Phases[i] - intP * dbPhaseStep); // always positive and < .5 * dblPhaseStep
|
||||
dblPhaseErrorSum += dblPhaseError;
|
||||
|
||||
intX = xCenter + dblRad * cosf(dblPlotRotation + Phases[i]);
|
||||
intY = yCenter + dblRad * sinf(dblPlotRotation + Phases[i]);
|
||||
|
||||
if (intX > 0 && intY > 0)
|
||||
if (intX != xCenter && intY != yCenter)
|
||||
Constellation[chan]->setPixel(intX, intY, yellow);
|
||||
}
|
||||
|
||||
dblAvgRad = dblAvgRad / Count; // the average radius
|
||||
|
||||
intQuality = MAX(0, ((100 - 200 * (dblPhaseErrorSum / (Count)) / dbPhaseStep))); // ignore radius error for (PSK) but include for QAM
|
||||
|
||||
char QualText[64];
|
||||
sprintf(QualText, "Chan %c Qual = %d", chan + 'A', intQuality);
|
||||
QualLabel[chan]->setText(QualText);
|
||||
constellationLabel[chan]->setPixmap(QPixmap::fromImage(*Constellation[chan]));
|
||||
// constellationDialog[chan]->setWindowTitle(QualText);
|
||||
return intQuality;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -43,7 +43,8 @@ SOURCES += ./audio.c \
|
|||
./Modulate.c \
|
||||
./ofdm.c \
|
||||
./pktARDOP.c \
|
||||
./BusyDetect.c
|
||||
./BusyDetect.c \
|
||||
./DW9600.c
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -124,9 +124,9 @@
|
|||
<widget class="QLabel" name="WaterfallA">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<x>80</x>
|
||||
<y>488</y>
|
||||
<width>953</width>
|
||||
<width>881</width>
|
||||
<height>80</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
|
|
@ -1,516 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>QtSoundModemClass</class>
|
||||
<widget class="QMainWindow" name="QtSoundModemClass">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>962</width>
|
||||
<height>721</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>1024</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>QtSoundModem</string>
|
||||
</property>
|
||||
<property name="windowIcon">
|
||||
<iconset resource="QtSoundModem.qrc">
|
||||
<normaloff>:/QtSoundModem/soundmodem.ico</normaloff>:/QtSoundModem/soundmodem.ico</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<widget class="QSpinBox" name="centerA">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>174</x>
|
||||
<y>6</y>
|
||||
<width>56</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>3000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1500</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="modeB">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>316</x>
|
||||
<y>6</y>
|
||||
<width>145</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="WaterfallB">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>586</y>
|
||||
<width>959</width>
|
||||
<height>80</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>5000</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>6</x>
|
||||
<y>7</y>
|
||||
<width>16</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>A:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="centerB">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>468</x>
|
||||
<y>6</y>
|
||||
<width>56</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>3000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1500</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="WaterfallA">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>488</y>
|
||||
<width>953</width>
|
||||
<height>80</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>80</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>5000</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="modeA">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>22</x>
|
||||
<y>6</y>
|
||||
<width>145</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>690</x>
|
||||
<y>0</y>
|
||||
<width>73</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>DCD Level</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="labelB">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>300</x>
|
||||
<y>9</y>
|
||||
<width>16</width>
|
||||
<height>14</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>B:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSlider" name="DCDSlider">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>690</x>
|
||||
<y>18</y>
|
||||
<width>73</width>
|
||||
<height>14</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="holdPointers">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>782</x>
|
||||
<y>6</y>
|
||||
<width>93</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Hold Pointers</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="HeaderA">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>25</x>
|
||||
<y>460</y>
|
||||
<width>1076</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>5000</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>fall</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="HeaderB">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>560</y>
|
||||
<width>1076</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>600</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>5000</width>
|
||||
<height>100</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>8</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::Box</enum>
|
||||
</property>
|
||||
<property name="frameShadow">
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>fall</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTextEdit" name="monWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>-6</x>
|
||||
<y>60</y>
|
||||
<width>971</width>
|
||||
<height>201</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="readOnly">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="labelC">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>5</x>
|
||||
<y>32</y>
|
||||
<width>16</width>
|
||||
<height>18</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>C:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="modeC">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>22</x>
|
||||
<y>31</y>
|
||||
<width>145</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="centerD">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>468</x>
|
||||
<y>31</y>
|
||||
<width>56</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>3000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1500</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="modeD">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>316</x>
|
||||
<y>31</y>
|
||||
<width>145</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="labelD">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>298</x>
|
||||
<y>33</y>
|
||||
<width>16</width>
|
||||
<height>14</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>D:</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSpinBox" name="centerC">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>174</x>
|
||||
<y>31</y>
|
||||
<width>56</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>3000</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>1500</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QSlider" name="RXOffset">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>600</x>
|
||||
<y>18</y>
|
||||
<width>63</width>
|
||||
<height>14</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>-200</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>200</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>10</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="RXOffsetLabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>600</x>
|
||||
<y>2</y>
|
||||
<width>87</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>RX Offset 0</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RXOffsetA">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>238</x>
|
||||
<y>6</y>
|
||||
<width>37</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RXOffsetB">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>532</x>
|
||||
<y>6</y>
|
||||
<width>37</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RXOffsetC">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>238</x>
|
||||
<y>31</y>
|
||||
<width>37</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="RXOffsetD">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>532</x>
|
||||
<y>31</y>
|
||||
<width>37</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QMenuBar" name="menuBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>962</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
<include location="QtSoundModem.qrc"/>
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,6 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
|
@ -9,12 +13,16 @@
|
|||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{4EDE958E-D0AC-37B4-81F7-78313A262DCD}</ProjectGuid>
|
||||
<RootNamespace>QtSoundModem</RootNamespace>
|
||||
<Keyword>QtVS_v304</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.19041.0</WindowsTargetPlatformMinVersion>
|
||||
<QtMsBuild Condition="'$(QtMsBuild)'=='' or !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
|
||||
</PropertyGroup>
|
||||
|
@ -28,6 +36,15 @@
|
|||
<IntermediateDirectory>release\</IntermediateDirectory>
|
||||
<PrimaryOutput>QtSoundModem</PrimaryOutput>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<OutputDirectory>release\</OutputDirectory>
|
||||
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<IntermediateDirectory>release\</IntermediateDirectory>
|
||||
<PrimaryOutput>QtSoundModem</PrimaryOutput>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<OutputDirectory>debug\</OutputDirectory>
|
||||
|
@ -37,6 +54,15 @@
|
|||
<IntermediateDirectory>debug\</IntermediateDirectory>
|
||||
<PrimaryOutput>QtSoundModem</PrimaryOutput>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<OutputDirectory>debug\</OutputDirectory>
|
||||
<ATLMinimizesCRunTimeLibraryUsage>false</ATLMinimizesCRunTimeLibraryUsage>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<IntermediateDirectory>debug\</IntermediateDirectory>
|
||||
<PrimaryOutput>QtSoundModem</PrimaryOutput>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
|
||||
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
|
||||
|
@ -45,9 +71,15 @@
|
|||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
|
||||
<Import Project="$(QtMsBuild)\qt_defaults.props" />
|
||||
|
@ -59,6 +91,13 @@
|
|||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\</IntDir>
|
||||
<TargetName>QtSoundModem</TargetName>
|
||||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\\</IntDir>
|
||||
|
@ -66,14 +105,29 @@
|
|||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)Intermed\$(Platform)\$(Configuration)\\</IntDir>
|
||||
<TargetName>QtSoundModem</TargetName>
|
||||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<QtInstall>5.14.2</QtInstall>
|
||||
<QtModules>core;network;gui;widgets;serialport</QtModules>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="QtSettings">
|
||||
<QtInstall>msvc 2017 5.1464</QtInstall>
|
||||
<QtModules>core;network;gui;widgets;serialport</QtModules>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<QtInstall>5.14.2</QtInstall>
|
||||
<QtModules>core;network;gui;widgets;serialport</QtModules>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="QtSettings">
|
||||
<QtInstall>5.14.2</QtInstall>
|
||||
<QtModules>core;network;gui;widgets;serialport</QtModules>
|
||||
</PropertyGroup>
|
||||
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.props')">
|
||||
<Import Project="$(QtMsBuild)\qt.props" />
|
||||
</ImportGroup>
|
||||
|
@ -140,6 +194,69 @@
|
|||
<QtUicFileName>ui_%(Filename).h</QtUicFileName>
|
||||
</QtUic>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>rsid;.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;release;/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<BrowseInformation>false</BrowseInformation>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;NDEBUG;QT_NO_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libfftw3f-3.lib;shell32.lib;setupapi.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
||||
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<OutputFile>$(OutDir)QtSoundModem.exe</OutputFile>
|
||||
<RandomizedBaseAddress>true</RandomizedBaseAddress>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
</Link>
|
||||
<Midl>
|
||||
<DefaultCharType>Unsigned</DefaultCharType>
|
||||
<EnableErrorChecks>None</EnableErrorChecks>
|
||||
<WarningLevel>0</WarningLevel>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_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)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<QtMoc>
|
||||
<CompilerFlavor>msvc</CompilerFlavor>
|
||||
<Include>./$(Configuration)/moc_predefs.h</Include>
|
||||
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
|
||||
<DynamicSource>output</DynamicSource>
|
||||
<QtMocDir>$(IntDir)</QtMocDir>
|
||||
<QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
|
||||
</QtMoc>
|
||||
<QtRcc>
|
||||
<InitFuncName>QtSoundModem</InitFuncName>
|
||||
<Compression>default</Compression>
|
||||
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
|
||||
<QtRccDir>$(IntDir)</QtRccDir>
|
||||
<QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
|
||||
</QtRcc>
|
||||
<QtUic>
|
||||
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
|
||||
<QtUicDir>$(IntDir)</QtUicDir>
|
||||
<QtUicFileName>ui_%(Filename).h</QtUicFileName>
|
||||
</QtUic>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;debug;/include;rsid;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
|
@ -202,13 +319,77 @@
|
|||
<QtUicFileName>ui_%(Filename).h</QtUicFileName>
|
||||
</QtUic>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>.\GeneratedFiles\$(ConfigurationName);.\GeneratedFiles;.;debug;/include;rsid;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>-Zc:rvalueCast -Zc:inline -Zc:strictStrings -Zc:throwingNew -Zc:referenceBinding -Zc:__cplusplus -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<BrowseInformation>false</BrowseInformation>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4577;4467;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_WINDOWS;UNICODE;_UNICODE;WIN32;_ENABLE_EXTENDED_ALIGNED_STORAGE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PreprocessToFile>false</PreprocessToFile>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>libfftw3f-64-3.lib;shell32.lib;setupapi.lib;WS2_32.Lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>C:\opensslx86\lib;C:\Utils\my_sql\mysql-5.7.25-win32\lib;C:\Utils\postgresqlx86\pgsql\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalOptions>"/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions)</AdditionalOptions>
|
||||
<DataExecutionPrevention>true</DataExecutionPrevention>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<IgnoreImportLibrary>true</IgnoreImportLibrary>
|
||||
<OutputFile>$(OutDir)\QtSoundModem.exe</OutputFile>
|
||||
<RandomizedBaseAddress>true</RandomizedBaseAddress>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<SuppressStartupBanner>true</SuppressStartupBanner>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</Link>
|
||||
<Midl>
|
||||
<DefaultCharType>Unsigned</DefaultCharType>
|
||||
<EnableErrorChecks>None</EnableErrorChecks>
|
||||
<WarningLevel>0</WarningLevel>
|
||||
</Midl>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_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)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<QtMoc>
|
||||
<CompilerFlavor>msvc</CompilerFlavor>
|
||||
<Include>./$(Configuration)/moc_predefs.h</Include>
|
||||
<ExecutionDescription>Moc'ing %(Identity)...</ExecutionDescription>
|
||||
<DynamicSource>output</DynamicSource>
|
||||
<QtMocDir>$(IntDir)</QtMocDir>
|
||||
<QtMocFileName>moc_%(Filename).cpp</QtMocFileName>
|
||||
</QtMoc>
|
||||
<QtRcc>
|
||||
<InitFuncName>QtSoundModem</InitFuncName>
|
||||
<Compression>default</Compression>
|
||||
<ExecutionDescription>Rcc'ing %(Identity)...</ExecutionDescription>
|
||||
<QtRccDir>$(IntDir)</QtRccDir>
|
||||
<QtRccFileName>qrc_%(Filename).cpp</QtRccFileName>
|
||||
</QtRcc>
|
||||
<QtUic>
|
||||
<ExecutionDescription>Uic'ing %(Identity)...</ExecutionDescription>
|
||||
<QtUicDir>$(IntDir)</QtUicDir>
|
||||
<QtUicFileName>ui_%(Filename).h</QtUicFileName>
|
||||
</QtUic>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ARDOPC.c" />
|
||||
<ClCompile Include="BusyDetect.c" />
|
||||
<ClCompile Include="Config.cpp" />
|
||||
<ClCompile Include="dw9600.c" />
|
||||
<ClCompile Include="hid.c" />
|
||||
<ClCompile Include="il2p.c">
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CompileAsC</CompileAs>
|
||||
<CompileAs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">CompileAsC</CompileAs>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Modulate.c" />
|
||||
<ClCompile Include="QtSoundModem.cpp" />
|
||||
|
@ -247,18 +428,15 @@
|
|||
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
||||
<FileType>Document</FileType>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">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</Command>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">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</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Generate moc_predefs.h</Message>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Generate moc_predefs.h</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">debug\moc_predefs.h;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="release\moc_predefs.h.cbt">
|
||||
<FileType>Document</FileType>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(QTDIR)\mkspecs\features\data\dummy.cpp;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">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</Command>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Generate moc_predefs.h</Message>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">release\moc_predefs.h;%(Outputs)</Outputs>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">debug\moc_predefs.h;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>C:\DevProgs\BPQ32\SMTest</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommandArguments>
|
||||
</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerWorkingDirectory>c:\devprogs\bpq32\SMSAT2</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommandArguments>< d:\samples.wav</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>.\debug</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LocalDebuggerWorkingDirectory>C:\DevProgs\BPQ32\SMSat</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<QtLastBackgroundBuild>2023-08-21T20:12:53.1523329Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="QtSettings">
|
||||
<QtLastBackgroundBuild>2022-03-11T19:38:31.5906689Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<QtLastBackgroundBuild>2023-08-18T07:29:42.4175478Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="QtSettings">
|
||||
<QtLastBackgroundBuild>2022-03-11T19:38:33.3845083Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -137,6 +137,9 @@
|
|||
<ClCompile Include="il2p.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dw9600.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="QtSoundModem.h">
|
||||
|
@ -153,9 +156,6 @@
|
|||
<CustomBuild Include="debug\moc_predefs.h.cbt">
|
||||
<Filter>Generated Files</Filter>
|
||||
</CustomBuild>
|
||||
<CustomBuild Include="release\moc_predefs.h.cbt">
|
||||
<Filter>Generated Files</Filter>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtUic Include="ModemDialog.ui">
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>C:\DevProgs\BPQ32\SM2</LocalDebuggerWorkingDirectory>
|
||||
<LocalDebuggerWorkingDirectory>C:\DevProgs\BPQ32\SMTest</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommandArguments>
|
||||
</LocalDebuggerCommandArguments>
|
||||
|
@ -20,15 +20,15 @@
|
|||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<QtLastBackgroundBuild>2023-06-27T07:43:13.0567353Z</QtLastBackgroundBuild>
|
||||
<QtLastBackgroundBuild>2023-08-31T18:31:29.1703485Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="QtSettings">
|
||||
<QtLastBackgroundBuild>2022-03-11T19:38:31.5906689Z</QtLastBackgroundBuild>
|
||||
<QtLastBackgroundBuild>2023-08-31T18:31:29.3763536Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="QtSettings" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<QtLastBackgroundBuild>2023-06-27T07:43:13.1602990Z</QtLastBackgroundBuild>
|
||||
<QtLastBackgroundBuild>2023-08-31T18:31:30.2753833Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="QtSettings">
|
||||
<QtLastBackgroundBuild>2022-03-11T19:38:33.3845083Z</QtLastBackgroundBuild>
|
||||
<QtLastBackgroundBuild>2023-08-31T18:31:32.1264353Z</QtLastBackgroundBuild>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -27,6 +27,7 @@ along with QtSoundModem. If not, see http://www.gnu.org/licenses
|
|||
#include "hidapi.h"
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
BOOL KISSServ;
|
||||
int KISSPort;
|
||||
|
@ -62,13 +63,24 @@ extern int pnt_change[5]; // Freq Changed Flag
|
|||
fftwf_complex *in, *out;
|
||||
fftwf_plan p;
|
||||
|
||||
#define N 2048
|
||||
int FFTSize = 4096;
|
||||
|
||||
char * Wisdom;
|
||||
|
||||
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);
|
||||
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)
|
||||
|
@ -77,7 +89,7 @@ void dofft(short * inp, float * outr, float * outi)
|
|||
|
||||
fftwf_complex * fft = in;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
for (i = 0; i < FFTSize; i++)
|
||||
{
|
||||
fft[0][0] = inp[0] * 1.0f;
|
||||
fft[0][1] = 0;
|
||||
|
@ -89,7 +101,7 @@ void dofft(short * inp, float * outr, float * outi)
|
|||
|
||||
fft = out;
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
for (i = 0; i < FFTSize; i++)
|
||||
{
|
||||
outr[0] = fft[0][0];
|
||||
outi[0] = fft[0][1];
|
||||
|
@ -165,6 +177,18 @@ void SampleSink(int LR, short 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)
|
||||
|
@ -321,194 +345,171 @@ extern UCHAR * pixelPointer;
|
|||
#endif
|
||||
|
||||
extern int blnBusyStatus;
|
||||
BusyDet = 0;
|
||||
BusyDet = 5;
|
||||
|
||||
#define PLOTWATERFALL
|
||||
|
||||
int WaterfallActive = 1;
|
||||
int SpectrumActive;
|
||||
|
||||
/*
|
||||
float BinSize;
|
||||
|
||||
void UpdateBusyDetector(short * bytNewSamples)
|
||||
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.
|
||||
{
|
||||
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
|
||||
// First sort signals and look at highes signals:baseline ratio..
|
||||
|
||||
static BOOL blnLastBusyStatus;
|
||||
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;
|
||||
int i, chan;
|
||||
|
||||
// if (State != SearchingForLeader)
|
||||
// return; // only when looking for leader
|
||||
return;
|
||||
|
||||
if (Now - LastBusyCheck < 100)
|
||||
if (Now - LastBusyCheck < 100) // ??
|
||||
return;
|
||||
|
||||
LastBusyCheck = Now;
|
||||
|
||||
FourierTransform(1024, bytNewSamples, &dblReF[0], &dblImF[0], FALSE);
|
||||
// We need to run busy test on the frequncies used by each modem.
|
||||
|
||||
for (i = 0; i < 206; i++)
|
||||
for (chan = 0; chan < 4; chan++)
|
||||
{
|
||||
// starting at ~300 Hz to ~2700 Hz Which puts the center of the signal in the center of the window (~1500Hz)
|
||||
int Low, High, Start, End;
|
||||
|
||||
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
|
||||
}
|
||||
if (soundChannel[chan] != (LR + 1)) // on this side of soundcard
|
||||
continue;
|
||||
|
||||
// LookforPacket(dblMag, dblMagAvg, 206, &dblReF[25], &dblImF[25]);
|
||||
// packet_process_samples(bytNewSamples, 1200);
|
||||
Low = tx_freq[chan] - txbpf[chan] / 2;
|
||||
High = tx_freq[chan] + txbpf[chan] / 2;
|
||||
|
||||
intDelta = roundf(500 / 2) + 50 / 11.719f;
|
||||
// BinSize is width of each fft bin in Hz
|
||||
|
||||
intTuneLineLow = max((103 - intDelta), 3);
|
||||
intTuneLineHi = min((103 + intDelta), 203);
|
||||
Start = (Low / BinSize); // First and last bins to process
|
||||
End = (High / BinSize);
|
||||
|
||||
// if (ProtocolState == DISC) // ' Only process busy when in DISC state
|
||||
{
|
||||
// blnBusyStatus = BusyDetect3(dblMag, intTuneLineLow, intTuneLineHi);
|
||||
|
||||
if (blnBusyStatus && !blnLastBusyStatus)
|
||||
for (i = Start; i < End; i++)
|
||||
{
|
||||
// QueueCommandToHost("BUSY TRUE");
|
||||
// newStatus = TRUE; // report to PTC
|
||||
|
||||
if (!WaterfallActive && !SpectrumActive)
|
||||
{
|
||||
UCHAR Msg[2];
|
||||
|
||||
// Msg[0] = blnBusyStatus;
|
||||
// SendtoGUI('B', Msg, 1);
|
||||
}
|
||||
dblMag[i] = powf(Real[i], 2) + powf(Imag[i], 2); // first pass
|
||||
dblMagAvg += dblMag[i];
|
||||
}
|
||||
// stcStatus.Text = "TRUE"
|
||||
// queTNCStatus.Enqueue(stcStatus)
|
||||
// 'Debug.WriteLine("BUSY TRUE @ " & Format(DateTime.UtcNow, "HH:mm:ss"))
|
||||
|
||||
else if (blnLastBusyStatus && !blnBusyStatus)
|
||||
blnBusyStatus = SMBusyDetect3(dblMag, Start, End);
|
||||
|
||||
if (blnBusyStatus && !blnLastBusyStatus[chan])
|
||||
{
|
||||
// QueueCommandToHost("BUSY FALSE");
|
||||
// newStatus = TRUE; // report to PTC
|
||||
|
||||
if (!WaterfallActive && !SpectrumActive)
|
||||
{
|
||||
UCHAR Msg[2];
|
||||
|
||||
Msg[0] = blnBusyStatus;
|
||||
// SendtoGUI('B', Msg, 1);
|
||||
}
|
||||
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 = 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
|
||||
blnLastBusyStatus[chan] = blnBusyStatus;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
extern short rawSamples[2400]; // Get Frame Type need 2400 and we may add 1200
|
||||
int rawSamplesLength = 0;
|
||||
|
@ -600,6 +601,7 @@ 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;
|
||||
|
||||
|
@ -628,6 +630,7 @@ int ARDOPSendToCard(int Chan, int Len)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
DMABuffer = SendtoCard(DMABuffer, Len);
|
||||
|
||||
ARDOPTXPtr[Chan] += Len;
|
||||
|
@ -669,6 +672,8 @@ void DoTX(int Chan)
|
|||
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
|
||||
|
@ -680,7 +685,7 @@ void DoTX(int Chan)
|
|||
{
|
||||
// Continue the send
|
||||
|
||||
if (modem_mode[Chan] == MODE_ARDOP)
|
||||
if (modem_mode[Chan] == MODE_ARDOP || modem_mode[Chan] == MODE_RUH)
|
||||
{
|
||||
// if (SeeIfCardBusy())
|
||||
// return 0;
|
||||
|
@ -699,6 +704,8 @@ void DoTX(int Chan)
|
|||
SoundIsPlaying = TRUE;
|
||||
Number = 0;
|
||||
|
||||
Continuation[Chan] = 1;
|
||||
|
||||
Debugprintf("TX Continuing");
|
||||
|
||||
string * myTemp = Strings(&all_frame_buf[Chan], 0); // get message
|
||||
|
@ -728,12 +735,17 @@ void DoTX(int Chan)
|
|||
|
||||
put_frame(Chan, tx_data, "", TRUE, FALSE);
|
||||
|
||||
PktARDOPEncode(tx_data->Data, tx_data->Length - 2, Chan);
|
||||
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;
|
||||
|
@ -741,6 +753,8 @@ void DoTX(int Chan)
|
|||
|
||||
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
|
||||
|
@ -845,6 +859,50 @@ void DoTX(int Chan)
|
|||
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);
|
||||
|
@ -852,16 +910,6 @@ void DoTX(int Chan)
|
|||
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)
|
||||
|
@ -1146,6 +1194,8 @@ void CM108_set_ptt(int PTTState)
|
|||
|
||||
void RadioPTT(int snd_ch, BOOL PTTState)
|
||||
{
|
||||
snd_status[snd_ch] = PTTState; // SND_IDLE = 0 SND_TX = 1
|
||||
|
||||
#ifdef __ARM_ARCH
|
||||
if (useGPIO)
|
||||
{
|
389
SMMain.c
389
SMMain.c
|
@ -27,6 +27,7 @@ along with QtSoundModem. If not, see http://www.gnu.org/licenses
|
|||
#include "hidapi.h"
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
|
||||
BOOL KISSServ;
|
||||
int KISSPort;
|
||||
|
@ -40,6 +41,9 @@ int SoundIsPlaying = 0;
|
|||
int UDPSoundIsPlaying = 0;
|
||||
int Capturing = 0;
|
||||
|
||||
int txmin = 0;
|
||||
int txmax = 0;
|
||||
|
||||
extern unsigned short buffer[2][1200];
|
||||
extern int SoundMode;
|
||||
extern int needRSID[4];
|
||||
|
@ -176,6 +180,18 @@ void SampleSink(int LR, short 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)
|
||||
|
@ -332,194 +348,171 @@ extern UCHAR * pixelPointer;
|
|||
#endif
|
||||
|
||||
extern int blnBusyStatus;
|
||||
BusyDet = 0;
|
||||
BusyDet = 5;
|
||||
|
||||
#define PLOTWATERFALL
|
||||
|
||||
int WaterfallActive = 1;
|
||||
int SpectrumActive;
|
||||
|
||||
/*
|
||||
float BinSize;
|
||||
|
||||
void UpdateBusyDetector(short * bytNewSamples)
|
||||
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.
|
||||
{
|
||||
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
|
||||
// First sort signals and look at highes signals:baseline ratio..
|
||||
|
||||
static BOOL blnLastBusyStatus;
|
||||
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;
|
||||
int i, chan;
|
||||
|
||||
// if (State != SearchingForLeader)
|
||||
// return; // only when looking for leader
|
||||
return;
|
||||
|
||||
if (Now - LastBusyCheck < 100)
|
||||
if (Now - LastBusyCheck < 100) // ??
|
||||
return;
|
||||
|
||||
LastBusyCheck = Now;
|
||||
|
||||
FourierTransform(1024, bytNewSamples, &dblReF[0], &dblImF[0], FALSE);
|
||||
// We need to run busy test on the frequncies used by each modem.
|
||||
|
||||
for (i = 0; i < 206; i++)
|
||||
for (chan = 0; chan < 4; chan++)
|
||||
{
|
||||
// starting at ~300 Hz to ~2700 Hz Which puts the center of the signal in the center of the window (~1500Hz)
|
||||
int Low, High, Start, End;
|
||||
|
||||
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
|
||||
}
|
||||
if (soundChannel[chan] != (LR + 1)) // on this side of soundcard
|
||||
continue;
|
||||
|
||||
// LookforPacket(dblMag, dblMagAvg, 206, &dblReF[25], &dblImF[25]);
|
||||
// packet_process_samples(bytNewSamples, 1200);
|
||||
Low = tx_freq[chan] - txbpf[chan] / 2;
|
||||
High = tx_freq[chan] + txbpf[chan] / 2;
|
||||
|
||||
intDelta = roundf(500 / 2) + 50 / 11.719f;
|
||||
// BinSize is width of each fft bin in Hz
|
||||
|
||||
intTuneLineLow = max((103 - intDelta), 3);
|
||||
intTuneLineHi = min((103 + intDelta), 203);
|
||||
Start = (Low / BinSize); // First and last bins to process
|
||||
End = (High / BinSize);
|
||||
|
||||
// if (ProtocolState == DISC) // ' Only process busy when in DISC state
|
||||
{
|
||||
// blnBusyStatus = BusyDetect3(dblMag, intTuneLineLow, intTuneLineHi);
|
||||
|
||||
if (blnBusyStatus && !blnLastBusyStatus)
|
||||
for (i = Start; i < End; i++)
|
||||
{
|
||||
// QueueCommandToHost("BUSY TRUE");
|
||||
// newStatus = TRUE; // report to PTC
|
||||
|
||||
if (!WaterfallActive && !SpectrumActive)
|
||||
{
|
||||
UCHAR Msg[2];
|
||||
|
||||
// Msg[0] = blnBusyStatus;
|
||||
// SendtoGUI('B', Msg, 1);
|
||||
}
|
||||
dblMag[i] = powf(Real[i], 2) + powf(Imag[i], 2); // first pass
|
||||
dblMagAvg += dblMag[i];
|
||||
}
|
||||
// stcStatus.Text = "TRUE"
|
||||
// queTNCStatus.Enqueue(stcStatus)
|
||||
// 'Debug.WriteLine("BUSY TRUE @ " & Format(DateTime.UtcNow, "HH:mm:ss"))
|
||||
|
||||
else if (blnLastBusyStatus && !blnBusyStatus)
|
||||
blnBusyStatus = SMBusyDetect3(dblMag, Start, End);
|
||||
|
||||
if (blnBusyStatus && !blnLastBusyStatus[chan])
|
||||
{
|
||||
// QueueCommandToHost("BUSY FALSE");
|
||||
// newStatus = TRUE; // report to PTC
|
||||
|
||||
if (!WaterfallActive && !SpectrumActive)
|
||||
{
|
||||
UCHAR Msg[2];
|
||||
|
||||
Msg[0] = blnBusyStatus;
|
||||
// SendtoGUI('B', Msg, 1);
|
||||
}
|
||||
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 = 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
|
||||
blnLastBusyStatus[chan] = blnBusyStatus;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
extern short rawSamples[2400]; // Get Frame Type need 2400 and we may add 1200
|
||||
int rawSamplesLength = 0;
|
||||
|
@ -554,9 +547,12 @@ int Freq_Change(int Chan, int Freq)
|
|||
{
|
||||
int low, high;
|
||||
|
||||
low = round(rx_shift[1] / 2 + RCVR[Chan] * rcvr_offset[Chan] + 1);
|
||||
low = round(rx_shift[Chan] / 2 + (RCVR[Chan] * rcvr_offset[Chan]));
|
||||
high = round(RX_Samplerate / 2 - (rx_shift[Chan] / 2 + RCVR[Chan] * rcvr_offset[Chan]));
|
||||
|
||||
if (Freq < 300)
|
||||
return rx_freq[Chan]; // Dont allow change
|
||||
|
||||
if (Freq < low)
|
||||
return rx_freq[Chan]; // Dont allow change
|
||||
|
||||
|
@ -611,6 +607,7 @@ 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;
|
||||
|
||||
|
@ -639,6 +636,7 @@ int ARDOPSendToCard(int Chan, int Len)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
DMABuffer = SendtoCard(DMABuffer, Len);
|
||||
|
||||
ARDOPTXPtr[Chan] += Len;
|
||||
|
@ -679,7 +677,9 @@ void DoTX(int Chan)
|
|||
{
|
||||
Flush();
|
||||
Debugprintf("TX Complete");
|
||||
RadioPTT(0, 0);
|
||||
RadioPTT(Chan, 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
|
||||
|
@ -691,7 +691,7 @@ void DoTX(int Chan)
|
|||
{
|
||||
// Continue the send
|
||||
|
||||
if (modem_mode[Chan] == MODE_ARDOP)
|
||||
if (modem_mode[Chan] == MODE_ARDOP || modem_mode[Chan] == MODE_RUH)
|
||||
{
|
||||
// if (SeeIfCardBusy())
|
||||
// return 0;
|
||||
|
@ -710,6 +710,8 @@ void DoTX(int Chan)
|
|||
SoundIsPlaying = TRUE;
|
||||
Number = 0;
|
||||
|
||||
Continuation[Chan] = 1;
|
||||
|
||||
Debugprintf("TX Continuing");
|
||||
|
||||
string * myTemp = Strings(&all_frame_buf[Chan], 0); // get message
|
||||
|
@ -739,19 +741,26 @@ void DoTX(int Chan)
|
|||
|
||||
put_frame(Chan, tx_data, "", TRUE, FALSE);
|
||||
|
||||
PktARDOPEncode(tx_data->Data, tx_data->Length - 2, Chan);
|
||||
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);
|
||||
RadioPTT(Chan, 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
|
||||
|
@ -856,6 +865,50 @@ void DoTX(int Chan)
|
|||
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);
|
||||
|
@ -863,16 +916,6 @@ void DoTX(int Chan)
|
|||
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)
|
||||
|
@ -1153,10 +1196,24 @@ void CM108_set_ptt(int PTTState)
|
|||
|
||||
}
|
||||
|
||||
|
||||
float amplitudes[4] = { 32767, 32767, 32767, 32767 };
|
||||
extern float amplitude;
|
||||
|
||||
void RadioPTT(int snd_ch, BOOL PTTState)
|
||||
{
|
||||
snd_status[snd_ch] = PTTState; // SND_IDLE = 0 SND_TX = 1
|
||||
|
||||
if (PTTState)
|
||||
{
|
||||
txmax = txmin = 0;
|
||||
amplitude = amplitudes[snd_ch];
|
||||
}
|
||||
else
|
||||
{
|
||||
Debugprintf("Output peaks = %d, %d, amp %f", txmin, txmax, amplitude);
|
||||
amplitudes[snd_ch] = amplitude;
|
||||
}
|
||||
|
||||
#ifdef __ARM_ARCH
|
||||
if (useGPIO)
|
||||
{
|
||||
|
|
|
@ -1,234 +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 <QPainter>
|
||||
|
||||
// This displays a graph of the filter characteristics
|
||||
|
||||
#define c3 -1.5000000000000E+00f // cos(2*pi / 3) - 1;
|
||||
#define c32 8.6602540378444E-01f // sin(2*pi / 3);
|
||||
|
||||
#define u5 1.2566370614359E+00f // 2*pi / 5;
|
||||
#define c51 -1.2500000000000E+00f // (cos(u5) + cos(2*u5))/2 - 1;
|
||||
#define c52 5.5901699437495E-01f // (cos(u5) - cos(2*u5))/2;
|
||||
#define c53 -9.5105651629515E-0f //- sin(u5);
|
||||
#define c54 -1.5388417685876E+00f //-(sin(u5) + sin(2*u5));
|
||||
#define c55 3.6327126400268E-01f // (sin(u5) - sin(2*u5));
|
||||
#define c8 = 7.0710678118655E-01f // 1 / sqrt(2);
|
||||
|
||||
|
||||
float pnt_graph_buf[4096];
|
||||
float graph_buf[4096];
|
||||
float prev_graph_buf[4096];
|
||||
float src_graph_buf[4096];
|
||||
float graph_f;
|
||||
float RealOut[4096];
|
||||
short RealIn[4096];
|
||||
float ImagOut[4096];
|
||||
|
||||
#define Image1Width 642
|
||||
#define Image1Height 312
|
||||
|
||||
void filter_grid(QPainter * Painter)
|
||||
{
|
||||
int col = 20;
|
||||
int row = 8;
|
||||
int top_margin = 10;
|
||||
int bottom_margin = 20;
|
||||
int left_margin = 30;
|
||||
int right_margin = 10;
|
||||
|
||||
int x, y;
|
||||
float kx, ky;
|
||||
|
||||
QPen pen; // creates a default pen
|
||||
|
||||
pen.setStyle(Qt::DotLine);
|
||||
Painter->setPen(pen);
|
||||
|
||||
|
||||
ky = 35;
|
||||
|
||||
kx = (Image1Width - left_margin - right_margin - 2) / col;
|
||||
|
||||
for (y = 0; y < row; y++)
|
||||
{
|
||||
Painter->drawLine(
|
||||
left_margin + 1,
|
||||
top_margin + round(ky*y) + 1,
|
||||
Image1Width - right_margin - 1,
|
||||
top_margin + round(ky*y) + 1);
|
||||
}
|
||||
|
||||
for (x = 0; x < col; x++)
|
||||
{
|
||||
Painter->drawLine(
|
||||
left_margin + round(kx*x) + 1,
|
||||
top_margin + 1,
|
||||
left_margin + round(kx*x) + 1,
|
||||
Image1Height - bottom_margin - 1);
|
||||
}
|
||||
|
||||
pen.setStyle(Qt::SolidLine);
|
||||
Painter->setPen(pen);
|
||||
|
||||
for (y = 0; y < row / 2; y++)
|
||||
{
|
||||
char Textxx[20];
|
||||
|
||||
sprintf(Textxx, "%d", y * -20);
|
||||
|
||||
Painter->drawLine(
|
||||
left_margin + 1,
|
||||
top_margin + round(ky*y * 2) + 1,
|
||||
Image1Width - right_margin - 1,
|
||||
top_margin + round(ky*y * 2) + 1);
|
||||
|
||||
Painter->drawText(
|
||||
1,
|
||||
top_margin + round(ky*y * 2) + 1,
|
||||
100, 20, 0, Textxx);
|
||||
|
||||
}
|
||||
|
||||
|
||||
for (x = 0; x <= col / 5; x++)
|
||||
{
|
||||
char Textxx[20];
|
||||
|
||||
sprintf(Textxx, "%d", x * 1000);
|
||||
|
||||
Painter->drawLine(
|
||||
left_margin + round(kx*x * 5) + 1,
|
||||
top_margin + 1,
|
||||
left_margin + round(kx*x * 5) + 1,
|
||||
Image1Height - bottom_margin - 1);
|
||||
|
||||
Painter->drawText(
|
||||
top_margin + round(kx*x * 5) + 8,
|
||||
Image1Height - 15,
|
||||
100, 20, 0, Textxx);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void FourierTransform(int NumSamples, short * RealIn, float * RealOut, float * ImagOut, int InverseTransform);
|
||||
|
||||
|
||||
void make_graph(float * buf, int buflen, QPainter * Painter)
|
||||
{
|
||||
int top_margin = 10;
|
||||
int bottom_margin = 20;
|
||||
int left_margin = 30;
|
||||
|
||||
int i, y1, y2;
|
||||
float pixel;
|
||||
|
||||
if (buflen == 0)
|
||||
return;
|
||||
|
||||
for (i = 0; i <= buflen - 2; i++)
|
||||
{
|
||||
y1 = 1 - round(buf[i]);
|
||||
|
||||
if (y1 > Image1Height - top_margin - bottom_margin - 2)
|
||||
y1 = Image1Height - top_margin - bottom_margin - 2;
|
||||
|
||||
y2 = 1 - round(buf[i + 1]);
|
||||
|
||||
if (y2 > Image1Height - top_margin - bottom_margin - 2)
|
||||
y2 = Image1Height - top_margin - bottom_margin - 2;
|
||||
|
||||
// 150 pixels for 1000 Hz
|
||||
|
||||
// i is the bin number, but bin is not 10 Hz but 12000 /1024
|
||||
// so freq = i * 12000 / 1024;
|
||||
// and pixel is freq * 300 /1000
|
||||
|
||||
pixel = i * 12000.0f / 1024.0f;
|
||||
pixel = pixel * 150.0f /1000.0f;
|
||||
|
||||
Painter->drawLine(
|
||||
left_margin + pixel,
|
||||
top_margin + y1,
|
||||
left_margin + pixel + 1,
|
||||
top_margin + y2);
|
||||
}
|
||||
}
|
||||
|
||||
void make_graph_buf(float * buf, short tap, QPainter * Painter)
|
||||
{
|
||||
int FFTSize;
|
||||
float max;
|
||||
int i, k;
|
||||
|
||||
FFTSize = 1024; // 12000 / 10; // 10hz on sample;
|
||||
|
||||
for (i = 0; i < tap; i++)
|
||||
prev_graph_buf[i]= 0;
|
||||
|
||||
for (i = 0; i < FFTSize; i++)
|
||||
src_graph_buf[i] = 0;
|
||||
|
||||
src_graph_buf[0]= 1;
|
||||
|
||||
FIR_filter(src_graph_buf, FFTSize, tap, buf, graph_buf, prev_graph_buf);
|
||||
|
||||
|
||||
for (k = 0; k < FFTSize; k++)
|
||||
RealIn[k] = graph_buf[k] * 32768;
|
||||
|
||||
FourierTransform(FFTSize, RealIn, RealOut, ImagOut, 0);
|
||||
|
||||
for (k = 0; k < (FFTSize / 2) - 1; k++)
|
||||
pnt_graph_buf[k] = powf(RealOut[k], 2) + powf(ImagOut[k], 2);
|
||||
|
||||
max = 0;
|
||||
|
||||
for (i = 0; i < (FFTSize / 2) - 1; i++)
|
||||
{
|
||||
if (pnt_graph_buf[i] > max)
|
||||
max = pnt_graph_buf[i];
|
||||
}
|
||||
|
||||
if (max > 0)
|
||||
{
|
||||
for (i = 0; i < (FFTSize / 2) - 1; i++)
|
||||
pnt_graph_buf[i] = pnt_graph_buf[i] / max;
|
||||
}
|
||||
|
||||
for (i = 0; i < (FFTSize / 2) - 1; i++)
|
||||
{
|
||||
if (pnt_graph_buf[i] > 0)
|
||||
pnt_graph_buf[i] = 70 * log10(pnt_graph_buf[i]);
|
||||
|
||||
else
|
||||
|
||||
pnt_graph_buf[i] = 0;
|
||||
}
|
||||
|
||||
filter_grid(Painter);
|
||||
|
||||
Painter->setPen(Qt::blue);
|
||||
|
||||
make_graph(pnt_graph_buf, 400, Painter);
|
||||
}
|
10
SoundInput.c
10
SoundInput.c
|
@ -322,7 +322,7 @@ VOID Track1Car4FSK(short * intSamples, int * intPtr, int intSampPerSymbol, float
|
|||
VOID Decode1CarPSK(int Carrier, BOOL OFDM);
|
||||
int EnvelopeCorrelator();
|
||||
int EnvelopeCorrelatorNew();
|
||||
BOOL DecodeFrame(int intFrameType, UCHAR * bytData);
|
||||
BOOL DecodeFrame(int chan, int intFrameType, UCHAR * bytData);
|
||||
|
||||
void Update4FSKConstellation(int * intToneMags, int * intQuality);
|
||||
void Update16FSKConstellation(int * intToneMags, int * intQuality);
|
||||
|
@ -864,7 +864,7 @@ float dblFreqBin[MAXCAR];
|
|||
|
||||
BOOL CheckFrameTypeParity(int intTonePtr, int * intToneMags);
|
||||
|
||||
void ARDOPProcessNewSamples(short * Samples, int nSamples)
|
||||
void ARDOPProcessNewSamples(int chan, short * Samples, int nSamples)
|
||||
{
|
||||
BOOL blnFrameDecodedOK = FALSE;
|
||||
|
||||
|
@ -1264,7 +1264,7 @@ else if (intPhaseError > 2)
|
|||
// This mechanism is to skip actual decoding and reply/change state...no need to decode
|
||||
|
||||
|
||||
blnFrameDecodedOK = DecodeFrame(intFrameType, bytData);
|
||||
blnFrameDecodedOK = DecodeFrame(chan, intFrameType, bytData);
|
||||
|
||||
ProcessFrame:
|
||||
|
||||
|
@ -3047,7 +3047,7 @@ void DemodulateFrame(int intFrameType)
|
|||
int intSNdB = 0, intQuality = 0;
|
||||
|
||||
|
||||
BOOL DecodeFrame(int xxx, UCHAR * bytData)
|
||||
BOOL DecodeFrame(int chan, int xxx, UCHAR * bytData)
|
||||
{
|
||||
BOOL blnDecodeOK = FALSE;
|
||||
char strCallerCallsign[10] = "";
|
||||
|
@ -3176,7 +3176,7 @@ BOOL DecodeFrame(int xxx, UCHAR * bytData)
|
|||
|
||||
// Data in bytData len in frameLen
|
||||
|
||||
ProcessPktFrame(0, bytData, frameLen);
|
||||
ProcessPktFrame(chan, bytData, frameLen);
|
||||
// else
|
||||
// L2Routine(bytData, frameLen, intLastRcvdFrameQuality, totalRSErrors, intNumCar, pktRXMode);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
91
UZ7HOStuff.h
91
UZ7HOStuff.h
|
@ -1,9 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
//
|
||||
// My port of UZ7HO's Soundmodem
|
||||
//
|
||||
|
||||
#define VersionString "0.0.0.66"
|
||||
#define VersionBytes {0, 0, 0, 66}
|
||||
#define VersionString "0.0.0.67-2"
|
||||
#define VersionBytes {0, 0, 0, 67}
|
||||
|
||||
// Added FX25. 4x100 FEC and V27 not Working and disabled
|
||||
|
||||
|
@ -146,7 +148,17 @@
|
|||
// 0.66 Allow configuration of waterfall span June 23
|
||||
// Add Exclude
|
||||
|
||||
// .67 Add extra modes 8PSK 900 RUH 4800 RUH 9600 QPSK 600 QPSK 2400 August 23
|
||||
// Fix loading txtail
|
||||
// Fix digipeating
|
||||
// Add MaxFrame to Modem Dialog
|
||||
// Fix 64 bit compatibility in ackmode
|
||||
// Add option to change CWID tones
|
||||
// Fix minimum centre freq validation
|
||||
|
||||
// .68 Monitor XID and TEST
|
||||
// Flag active interface in title bar
|
||||
// Improve header validation in il2p
|
||||
|
||||
|
||||
|
||||
|
@ -402,7 +414,6 @@ typedef struct TDetector_t
|
|||
Byte rx_decoded;
|
||||
Byte errors;
|
||||
|
||||
|
||||
} TDetector;
|
||||
|
||||
|
||||
|
@ -516,6 +527,10 @@ typedef struct TAX25Port_t
|
|||
#define U_UA 99
|
||||
#define U_FRMR 135
|
||||
#define U_UI 3
|
||||
|
||||
#define U_XID 0xAF
|
||||
#define U_TEST 0xE3
|
||||
|
||||
// PID flags
|
||||
#define PID_X25 0x01 // 00000001-CCIT X25 PLP
|
||||
#define PID_SEGMENT 0x08 // 00001000-Segmentation fragment
|
||||
|
@ -528,10 +543,11 @@ typedef struct TAX25Port_t
|
|||
#define PID_NET_ROM 0xCF // 11001111-NET/ROM
|
||||
|
||||
|
||||
// Sound interface buffer size
|
||||
// Sound interface buffer sizes
|
||||
|
||||
extern int ReceiveSize;
|
||||
extern int SendSize;
|
||||
|
||||
#define SendSize 1024 // 100 mS for now
|
||||
#define ReceiveSize 512 // try 100 mS for now
|
||||
#define NumberofinBuffers 4
|
||||
|
||||
#define Now getTicks()
|
||||
|
@ -543,8 +559,7 @@ typedef struct TAX25Port_t
|
|||
#define MODEM_CAPTION 'SoundModem by UZ7HO'
|
||||
#define MODEM_VERSION '1.06'
|
||||
#define SND_IDLE 0
|
||||
#define SND_RX 1
|
||||
#define SND_TX 2
|
||||
#define SND_TX 1
|
||||
#define BUF_EMPTY 0
|
||||
#define BUF_FULL 1
|
||||
#define DISP_MONO FALSE
|
||||
|
@ -564,7 +579,7 @@ typedef struct TAX25Port_t
|
|||
#define DEBUG_SOUND 8
|
||||
#define IS_LAST TRUE
|
||||
#define IS_NOT_LAST FALSE
|
||||
#define modes_count 16
|
||||
#define modes_count 20
|
||||
#define SPEED_300 0
|
||||
#define SPEED_1200 1
|
||||
#define SPEED_600 2
|
||||
|
@ -579,8 +594,12 @@ typedef struct TAX25Port_t
|
|||
#define SPEED_MP400 11
|
||||
#define SPEED_DW2400 12
|
||||
#define SPEED_8P4800 13
|
||||
#define SPEED_AE2400 14
|
||||
#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
|
||||
|
@ -589,11 +608,11 @@ typedef struct TAX25Port_t
|
|||
#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
|
||||
|
@ -720,7 +739,7 @@ typedef struct TAX25Port_t
|
|||
|
||||
#define ARDOPBufferSize 12000 * 100
|
||||
|
||||
extern short ARDOPTXBuffer[4][12000 * 100]; // Enough to hold whole frame of samples
|
||||
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
|
||||
|
@ -776,6 +795,7 @@ 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];
|
||||
|
@ -927,6 +947,7 @@ 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];
|
||||
|
@ -976,6 +997,10 @@ extern int tx_fx25_mode[4];
|
|||
|
||||
extern int SatelliteMode;
|
||||
|
||||
extern int using48000; // Set if using 48K sample rate (ie RUH Modem active)
|
||||
|
||||
extern int txmin, txmax;
|
||||
|
||||
// Function prototypes
|
||||
|
||||
void KISS_send_ack(UCHAR port, string * data);
|
||||
|
@ -1014,7 +1039,7 @@ double pila(double x);
|
|||
|
||||
void AGW_Raw_monitor(int snd_ch, string * data);
|
||||
|
||||
// Dephi emulation functions
|
||||
// Delphi emulation functions
|
||||
|
||||
string * Strings(TStringList * Q, int Index);
|
||||
void Clear(TStringList * Q);
|
||||
|
@ -1053,6 +1078,46 @@ 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
|
31
Waveout.c
31
Waveout.c
|
@ -54,12 +54,19 @@ void GetSoundDevices();
|
|||
|
||||
// Currently use 1200 samples for TX but 480 for RX to reduce latency
|
||||
|
||||
short buffer[2][SendSize * 2]; // Two Transfer/DMA buffers of 0.1 Sec (x2 for Stereo)
|
||||
short inbuffer[5][ReceiveSize * 2]; // Input Transfer/ buffers of 0.1 Sec (x2 for Stereo)
|
||||
#define MaxReceiveSize 2048 // Enough for 9600
|
||||
#define MaxSendSize 4096
|
||||
|
||||
short buffer[2][MaxSendSize * 2]; // Two Transfer/DMA buffers of 0.1 Sec (x2 for Stereo)
|
||||
short inbuffer[5][MaxReceiveSize * 2]; // Input Transfer/ buffers of 0.1 Sec (x2 for Stereo)
|
||||
|
||||
extern short * DMABuffer;
|
||||
extern int Number;
|
||||
|
||||
int ReceiveSize = 512;
|
||||
int SendSize = 1024;
|
||||
int using48000 = 0;
|
||||
|
||||
int SoundMode = 0;
|
||||
int stdinMode = 0;
|
||||
|
||||
|
@ -248,7 +255,7 @@ short * SendtoCard(unsigned short * buf, int n)
|
|||
|
||||
while (!(header[!Index].dwFlags & WHDR_DONE))
|
||||
{
|
||||
txSleep(10); // Run buckground while waiting
|
||||
txSleep(5); // Run buckground while waiting
|
||||
}
|
||||
|
||||
waveOutUnprepareHeader(hWaveOut, &header[!Index], sizeof(WAVEHDR));
|
||||
|
@ -404,6 +411,21 @@ int InitSound(BOOL Report)
|
|||
}
|
||||
}
|
||||
|
||||
if (using48000)
|
||||
{
|
||||
wfx.nSamplesPerSec = 48000;
|
||||
wfx.nAvgBytesPerSec = 48000 * 4;
|
||||
ReceiveSize = 2048;
|
||||
SendSize = 4096; // 100 mS for now
|
||||
}
|
||||
else
|
||||
{
|
||||
wfx.nSamplesPerSec = 12000;
|
||||
wfx.nAvgBytesPerSec = 12000 * 4;
|
||||
ReceiveSize = 512;
|
||||
SendSize = 1024;
|
||||
}
|
||||
|
||||
ret = waveOutOpen(&hWaveOut, PlayBackIndex, &wfx, 0, 0, CALLBACK_NULL); //WAVE_MAPPER
|
||||
|
||||
if (ret)
|
||||
|
@ -507,7 +529,7 @@ void PollReceivedSamples()
|
|||
return;
|
||||
}
|
||||
|
||||
if (inheader[inIndex].dwFlags & WHDR_DONE)
|
||||
while (inheader[inIndex].dwFlags & WHDR_DONE)
|
||||
{
|
||||
short * ptr = &inbuffer[inIndex][0];
|
||||
int i;
|
||||
|
@ -656,6 +678,7 @@ VOID WriteSamples(short * buffer, int len)
|
|||
short * SoundInit()
|
||||
{
|
||||
Index = 0;
|
||||
inIndex = 0;
|
||||
return &buffer[0][0];
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
|
||||
#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
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
|
||||
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);
|
|
@ -0,0 +1,191 @@
|
|||
|
||||
/* 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 */
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
|
||||
/* audio_stats.h */
|
||||
|
||||
|
||||
extern void audio_stats (int adev, int nchan, int nsamp, int interval);
|
||||
|
36
ax25.c
36
ax25.c
|
@ -1526,6 +1526,40 @@ void get_exclude_list(char * line, TStringList * list)
|
|||
}
|
||||
}
|
||||
|
||||
void get_digi_list(char * line, TStringList * list)
|
||||
{
|
||||
// Convert comma separated list of calls to ax25 format in list
|
||||
|
||||
string axcall;
|
||||
|
||||
char copy[512];
|
||||
|
||||
char * ptr, *Context;
|
||||
|
||||
if (line[0] == 0)
|
||||
return;
|
||||
|
||||
strcpy(copy, line); // copy as strtok messes with it
|
||||
strcat(copy, ",");
|
||||
|
||||
axcall.Length = 7;
|
||||
axcall.AllocatedLength = 8;
|
||||
axcall.Data = malloc(8);
|
||||
|
||||
memset(axcall.Data, 0, 8);
|
||||
|
||||
ptr = strtok_s(copy, " ,", &Context);
|
||||
|
||||
while (ptr)
|
||||
{
|
||||
if (ConvToAX25(ptr, axcall.Data) == 0)
|
||||
return;
|
||||
|
||||
Add(list, duplicateString(&axcall));
|
||||
ptr = strtok_s(NULL, " ,", &Context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void get_exclude_frm(char * line, TStringList * list)
|
||||
|
@ -1959,7 +1993,7 @@ void ax25_init()
|
|||
initTStringList(&list_digi_callsigns[i]);
|
||||
initTStringList(&KISS_acked[i]);
|
||||
|
||||
get_exclude_list(MyDigiCall[i], &list_digi_callsigns[i]);
|
||||
get_digi_list(MyDigiCall[i], &list_digi_callsigns[i]);
|
||||
get_exclude_list(exclude_callsigns[i], &list_exclude_callsigns[i]);
|
||||
get_exclude_frm(exclude_APRS_frm[i], &list_exclude_APRS_frm[i]);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ along with QtSoundModem. If not, see http://www.gnu.org/licenses
|
|||
|
||||
#include "UZ7HOStuff.h"
|
||||
|
||||
extern char modes_name[modes_count][20];
|
||||
extern char modes_name[modes_count][21];
|
||||
extern int RSID_SABM[4];
|
||||
extern int RSID_UI[4];
|
||||
extern int RSID_SetModem[4];
|
||||
|
|
296
ax25_demod.c
296
ax25_demod.c
|
@ -29,6 +29,10 @@ void make_rx_frame_FX25(int snd_ch, int rcvr_nr, int emph, string * data);
|
|||
string * memory_ARQ(TStringList * buf, string * data);
|
||||
|
||||
float GuessCentreFreq(int i);
|
||||
void ProcessRXFrames(int snd_ch);
|
||||
|
||||
extern struct il2p_context_s *il2p_context[4][16][3];
|
||||
|
||||
|
||||
/*
|
||||
|
||||
|
@ -116,6 +120,8 @@ int dcd_on_hdr[5] = { 0 };
|
|||
|
||||
extern int centreFreq[4];
|
||||
|
||||
float lastangle[4]; // pevious value for differential modes
|
||||
|
||||
|
||||
unsigned short n_INTR[5] = { 1,1,1,1,1 };
|
||||
unsigned short INTR_tap[5] = { 16, 16,16,16,16 };
|
||||
|
@ -154,6 +160,12 @@ int modemtoSoundLR[4] = { 0 };
|
|||
|
||||
struct TDetector_t DET[nr_emph + 1][16];
|
||||
|
||||
// Chan, Decoder, Emph
|
||||
|
||||
float Phases[4][16][nr_emph + 1][4096];
|
||||
float Mags[4][16][nr_emph + 1][4096];
|
||||
int nPhases[4][16][nr_emph + 1];
|
||||
|
||||
TStringList detect_list_l[5];
|
||||
TStringList detect_list[5];
|
||||
TStringList detect_list_c[5];
|
||||
|
@ -341,6 +353,10 @@ void chk_dcd1(int snd_ch, int buf_size)
|
|||
{
|
||||
dcd_bit_sync[snd_ch] = blnBusyStatus;
|
||||
}
|
||||
else if (modem_mode[snd_ch] == MODE_RUH)
|
||||
{
|
||||
dcd_bit_sync[snd_ch] = blnBusyStatus;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dcd_bit_cnt[snd_ch] > 0)
|
||||
|
@ -1341,7 +1357,7 @@ int stats[2] = { 0 };
|
|||
void decode_stream_MPSK(int snd_ch, int rcvr_nr, float * src, int buf_size, int last)
|
||||
{
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef XXXX
|
||||
|
||||
// Until ASM is converted
|
||||
|
||||
|
@ -2787,6 +2803,9 @@ void decode_stream_BPSK(int last, int snd_ch, int rcvr_nr, int emph, float * src
|
|||
angle = atan2f(sumIQ2, sumIQ1);
|
||||
PSK_IZ1 = PkAmpI;
|
||||
PSK_QZ1 = PkAmpQ;
|
||||
|
||||
float Mag = sqrtf(powf(PSK_IZ1, 2) + powf(PSK_QZ1, 2));
|
||||
|
||||
// Phase corrector
|
||||
|
||||
if (fabsf(angle) < PI5)
|
||||
|
@ -2808,11 +2827,24 @@ void decode_stream_BPSK(int last, int snd_ch, int rcvr_nr, int emph, float * src
|
|||
bit = RX_BIT0;
|
||||
//
|
||||
|
||||
// is this the best place to store phase for constellation?
|
||||
// only for ilp2 for now
|
||||
|
||||
if (il2p_mode[snd_ch])
|
||||
{
|
||||
struct il2p_context_s * il2p = il2p_context[snd_ch][rcvr_nr][emph];
|
||||
|
||||
if (il2p && il2p->state > IL2P_SEARCHING)
|
||||
{
|
||||
Phases[snd_ch][rcvr_nr][emph][nPhases[snd_ch][rcvr_nr][emph]] = angle;
|
||||
Mags[snd_ch][rcvr_nr][emph][nPhases[snd_ch][rcvr_nr][emph]++] = Mag;
|
||||
if (nPhases[snd_ch][rcvr_nr][emph] > 4090)
|
||||
nPhases[snd_ch][rcvr_nr][emph]--;
|
||||
}
|
||||
il2p_rec_bit(snd_ch, rcvr_nr, emph, bit);
|
||||
if (il2p_mode[snd_ch] == IL2P_MODE_ONLY) // Dont try HDLC decode
|
||||
continue;
|
||||
|
||||
}
|
||||
if (bit)
|
||||
stats[1]++;
|
||||
else
|
||||
|
@ -2949,7 +2981,6 @@ void decode_stream_QPSK(int last, int snd_ch, int rcvr_nr, int emph, float * src
|
|||
|
||||
struct TDetector_t * pDET = &DET[emph][rcvr_nr];
|
||||
|
||||
|
||||
bit_stuff_cnt = pDET->bit_stuff_cnt[snd_ch];
|
||||
last_rx_bit = pDET->last_rx_bit[snd_ch];
|
||||
sample_cnt = pDET->sample_cnt[snd_ch];
|
||||
|
@ -3073,6 +3104,8 @@ void decode_stream_QPSK(int last, int snd_ch, int rcvr_nr, int emph, float * src
|
|||
PSK_IZ1 = PkAmpI;
|
||||
PSK_QZ1 = PkAmpQ;
|
||||
|
||||
float Mag = sqrtf(powf(PSK_IZ1, 2) + powf(PSK_QZ1, 2));
|
||||
|
||||
if (angle > pi || angle < -pi)
|
||||
angle = angle;
|
||||
|
||||
|
@ -3120,6 +3153,8 @@ void decode_stream_QPSK(int last, int snd_ch, int rcvr_nr, int emph, float * src
|
|||
}
|
||||
else
|
||||
{
|
||||
// "Normal" QPSK
|
||||
|
||||
// Phase corrector
|
||||
|
||||
// I think this sends 0 90 180 270
|
||||
|
@ -3158,6 +3193,26 @@ void decode_stream_QPSK(int last, int snd_ch, int rcvr_nr, int emph, float * src
|
|||
{
|
||||
dibit = dibit << 1;
|
||||
|
||||
// is this the best place to store phase for constellation?
|
||||
// only for ilp2 for now
|
||||
|
||||
if (il2p_mode[snd_ch])
|
||||
{
|
||||
struct il2p_context_s * il2p = il2p_context[snd_ch][rcvr_nr][emph];
|
||||
|
||||
if (il2p && il2p->state > IL2P_SEARCHING)
|
||||
{
|
||||
Phases[snd_ch][rcvr_nr][emph][nPhases[snd_ch][rcvr_nr][emph]] = angle;
|
||||
Mags[snd_ch][rcvr_nr][emph][nPhases[snd_ch][rcvr_nr][emph]++] = Mag;
|
||||
if (nPhases[snd_ch][rcvr_nr][emph] > 4090)
|
||||
nPhases[snd_ch][rcvr_nr][emph]--;
|
||||
}
|
||||
|
||||
il2p_rec_bit(snd_ch, rcvr_nr, emph, (dibit & RX_BIT1));
|
||||
if (il2p_mode[snd_ch] == IL2P_MODE_ONLY) // Dont try HDLC decode
|
||||
continue;
|
||||
}
|
||||
|
||||
// NRZI
|
||||
|
||||
if (last_rx_bit == (dibit & RX_BIT1))
|
||||
|
@ -3328,7 +3383,13 @@ void decode_stream_8PSK(int last, int snd_ch, int rcvr_nr, int emph, float * src
|
|||
dcd_bit_cnt[snd_ch] = 0;
|
||||
}
|
||||
|
||||
baudrate = 1600 / 6;
|
||||
// Not sure how this works
|
||||
|
||||
if (tx_baudrate[snd_ch] == 300)
|
||||
baudrate = 300;
|
||||
else
|
||||
baudrate = 1600 / 6;
|
||||
|
||||
div_bit_afc = 1.0 / round(BIT_AFC*(RX_Samplerate / 11025));
|
||||
x = baudrate / RX_Samplerate;
|
||||
max_cnt = round(RX_Samplerate / baudrate) + 1;
|
||||
|
@ -3403,6 +3464,8 @@ void decode_stream_8PSK(int last, int snd_ch, int rcvr_nr, int emph, float * src
|
|||
PSK_IZ1 = PkAmpI;
|
||||
PSK_QZ1 = PkAmpQ;
|
||||
|
||||
float Mag = sqrtf(powf(PSK_IZ1, 2) + powf(PSK_QZ1, 2));
|
||||
|
||||
// Phase corrector
|
||||
|
||||
if (fabsf(angle) < PI125)
|
||||
|
@ -3431,7 +3494,6 @@ void decode_stream_8PSK(int last, int snd_ch, int rcvr_nr, int emph, float * src
|
|||
|
||||
AngleCorr = AngleCorr * 0.95 - KCorr * 0.05;
|
||||
angle = angle + AngleCorr;
|
||||
//
|
||||
|
||||
if (fabsf(angle) < PI125)
|
||||
tribit = 1;
|
||||
|
@ -3455,6 +3517,29 @@ void decode_stream_8PSK(int last, int snd_ch, int rcvr_nr, int emph, float * src
|
|||
for (j = 0; j < 3; j++)
|
||||
{
|
||||
tribit = tribit << 1;
|
||||
|
||||
// look for il2p before nrzi
|
||||
|
||||
// is this the best place to store phase for constellation?
|
||||
// only for ilp2 for now
|
||||
|
||||
if (il2p_mode[snd_ch])
|
||||
{
|
||||
struct il2p_context_s * il2p = il2p_context[snd_ch][rcvr_nr][emph];
|
||||
|
||||
if (il2p && il2p->state > IL2P_SEARCHING)
|
||||
{
|
||||
Phases[snd_ch][rcvr_nr][emph][nPhases[snd_ch][rcvr_nr][emph]] = angle;
|
||||
Mags[snd_ch][rcvr_nr][emph][nPhases[snd_ch][rcvr_nr][emph]++] = Mag;
|
||||
if (nPhases[snd_ch][rcvr_nr][emph] > 4090)
|
||||
nPhases[snd_ch][rcvr_nr][emph]--;
|
||||
}
|
||||
|
||||
il2p_rec_bit(snd_ch, rcvr_nr, emph, tribit & RX_BIT1);
|
||||
if (il2p_mode[snd_ch] == IL2P_MODE_ONLY) // Dont try HDLC decode
|
||||
continue;
|
||||
}
|
||||
|
||||
//NRZI
|
||||
|
||||
if (last_rx_bit == (tribit & RX_BIT1))
|
||||
|
@ -3733,6 +3818,14 @@ void make_core_INTR(UCHAR snd_ch)
|
|||
n_INTR[snd_ch] = 1;
|
||||
break;
|
||||
|
||||
|
||||
case SPEED_Q300:
|
||||
case SPEED_8PSK300:
|
||||
|
||||
width = roundf(RX_Samplerate / 2);
|
||||
n_INTR[snd_ch] = 1;
|
||||
break;
|
||||
|
||||
case SPEED_600:
|
||||
|
||||
width = roundf(RX_Samplerate / 4);
|
||||
|
@ -3755,6 +3848,11 @@ void make_core_INTR(UCHAR snd_ch)
|
|||
n_INTR[snd_ch] = 4;
|
||||
break;
|
||||
|
||||
// case SPEED_Q1200:
|
||||
// width = roundf(RX_Samplerate / 8);
|
||||
// n_INTR[snd_ch] = 4;
|
||||
// break;
|
||||
|
||||
case SPEED_Q2400:
|
||||
width = 300;
|
||||
n_INTR[snd_ch] = 4;
|
||||
|
@ -3766,7 +3864,7 @@ void make_core_INTR(UCHAR snd_ch)
|
|||
n_INTR[snd_ch] = 4;
|
||||
break;
|
||||
|
||||
case SPEED_AE2400:
|
||||
case SPEED_2400V26B:
|
||||
|
||||
width = 300;
|
||||
n_INTR[snd_ch] = 4;
|
||||
|
@ -3784,6 +3882,7 @@ void make_core_INTR(UCHAR snd_ch)
|
|||
break;
|
||||
|
||||
case SPEED_8P4800:
|
||||
|
||||
width = 100;
|
||||
n_INTR[snd_ch] = 6;
|
||||
break;
|
||||
|
@ -4121,7 +4220,7 @@ void Demodulator(int snd_ch, int rcvr_nr, float * src_buf, int last, int xcenter
|
|||
QPSK_Demodulator(snd_ch, rcvr_nr, emph_db[snd_ch], last);
|
||||
}
|
||||
|
||||
// QPSK demodulator
|
||||
// 8PSK demodulator
|
||||
|
||||
if (modem_mode[snd_ch]==MODE_8PSK)
|
||||
{
|
||||
|
@ -4147,120 +4246,125 @@ void Demodulator(int snd_ch, int rcvr_nr, float * src_buf, int last, int xcenter
|
|||
// I think this handles multiple decoders and passes packet on to next level
|
||||
|
||||
// Packet manager
|
||||
|
||||
if (last)
|
||||
ProcessRXFrames(snd_ch);
|
||||
}
|
||||
|
||||
void ProcessRXFrames(int snd_ch)
|
||||
{
|
||||
boolean fecflag = 0;
|
||||
char indicators[5] = "-$#F+"; // None, Single, MEM, FEC, Normal
|
||||
|
||||
// Work out which decoder and which emph settings worked.
|
||||
|
||||
if (snd_ch < 0 || snd_ch >3)
|
||||
return;
|
||||
|
||||
if (detect_list[snd_ch].Count > 0) // no point if nothing decoded
|
||||
{
|
||||
boolean fecflag = 0;
|
||||
char decoded[32] = "";
|
||||
char indicators[5] = "-$#F+"; // None, Single, MEM, FEC, Normal
|
||||
char s_emph[4] = "";
|
||||
int emph[4] = { 0 };
|
||||
char report[32] = "";
|
||||
int il2perrors = 255;
|
||||
|
||||
// Work out which decoder and which emph settings worked.
|
||||
// The is one DET for each Decoder for each Emph setting
|
||||
|
||||
if (detect_list[snd_ch].Count > 0) // no point if nothing decoded
|
||||
struct TDetector_t * pDET;
|
||||
int i = 0, j, found;
|
||||
int maxemph = nr_emph;
|
||||
|
||||
for (i = 0; i <= nr_emph; i++)
|
||||
{
|
||||
char decoded[32] = "";
|
||||
char indicators[5] = "-$#F+"; // None, Single, MEM, FEC, Normal
|
||||
char s_emph[4] = "";
|
||||
int emph[4] = { 0 };
|
||||
char report[32] = "";
|
||||
int il2perrors = 255;
|
||||
for (j = 0; j <= RCVR[snd_ch] * 2; j++)
|
||||
{
|
||||
pDET = &DET[i][j];
|
||||
|
||||
// The is one DET for each Decoder for each Emph setting
|
||||
if (pDET->rx_decoded > decoded[j]) // Better than other one (| is higher than F)
|
||||
decoded[j] = pDET->rx_decoded;
|
||||
|
||||
struct TDetector_t * pDET;
|
||||
int i = 0, j;
|
||||
int maxemph = nr_emph;
|
||||
if (pDET->emph_decoded > emph[i])
|
||||
emph[i] = pDET->emph_decoded;
|
||||
|
||||
if (il2perrors > pDET->errors)
|
||||
il2perrors = pDET->errors;
|
||||
|
||||
pDET->rx_decoded = 0;
|
||||
pDET->emph_decoded = 0; // Ready for next time
|
||||
pDET->errors = 255;
|
||||
}
|
||||
if (emph_all[snd_ch] == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
decoded[j] = 0;
|
||||
|
||||
for (j--; j >= 0; j--)
|
||||
decoded[j] = indicators[decoded[j]];
|
||||
|
||||
if (emph_all[snd_ch])
|
||||
{
|
||||
for (i = 0; i <= nr_emph; i++)
|
||||
{
|
||||
for (j = 0; j <= RCVR[snd_ch] * 2; j++)
|
||||
{
|
||||
pDET = &DET[i][j];
|
||||
|
||||
if (pDET->rx_decoded > decoded[j]) // Better than other one (| is higher than F)
|
||||
decoded[j] = pDET->rx_decoded;
|
||||
|
||||
if (pDET->emph_decoded > emph[i])
|
||||
emph[i] = pDET->emph_decoded;
|
||||
|
||||
if (il2perrors > pDET->errors)
|
||||
il2perrors = pDET->errors;
|
||||
|
||||
pDET->rx_decoded = 0;
|
||||
pDET->emph_decoded = 0; // Ready for next time
|
||||
pDET->errors = 255;
|
||||
}
|
||||
if (emph_all[snd_ch] == 0)
|
||||
break;
|
||||
s_emph[i] = indicators[emph[i]];
|
||||
}
|
||||
sprintf(report, "%s][%s", s_emph, decoded);
|
||||
}
|
||||
|
||||
decoded[j] = 0;
|
||||
else
|
||||
strcpy(report, decoded);
|
||||
|
||||
for (j--; j >= 0; j--)
|
||||
decoded[j] = indicators[decoded[j]];
|
||||
if (detect_list_c[snd_ch].Items[0]->Length)
|
||||
{
|
||||
if (il2perrors < 255 && il2perrors > 0)
|
||||
sprintf(detect_list_c[snd_ch].Items[0]->Data, "%s-%d", detect_list_c[snd_ch].Items[0]->Data, il2perrors);
|
||||
|
||||
if (emph_all[snd_ch])
|
||||
strcat(report, "][");
|
||||
strcat(report, detect_list_c[snd_ch].Items[0]->Data);
|
||||
}
|
||||
|
||||
if (detect_list[snd_ch].Count > 0)
|
||||
{
|
||||
for (i = 0; i < detect_list[snd_ch].Count; i++)
|
||||
{
|
||||
for (i = 0; i <= nr_emph; i++)
|
||||
found = 0;
|
||||
|
||||
// if (detect_list_l[snd_ch].Count > 0)
|
||||
// if (my_indexof(&detect_list_l[snd_ch], detect_list[snd_ch].Items[i]) > -1)
|
||||
// found = 1;
|
||||
|
||||
if (found == 0)
|
||||
{
|
||||
s_emph[i] = indicators[emph[i]];
|
||||
}
|
||||
sprintf(report, "%s][%s", s_emph, decoded);
|
||||
}
|
||||
|
||||
else
|
||||
strcpy(report, decoded);
|
||||
|
||||
if (detect_list_c[snd_ch].Items[0]->Length)
|
||||
{
|
||||
if (il2perrors < 255 && il2perrors > 0)
|
||||
sprintf(detect_list_c[snd_ch].Items[0]->Data, "%s-%d", detect_list_c[snd_ch].Items[0]->Data, il2perrors);
|
||||
|
||||
strcat(report, "][");
|
||||
strcat(report, detect_list_c[snd_ch].Items[0]->Data);
|
||||
}
|
||||
|
||||
if (detect_list[snd_ch].Count > 0)
|
||||
{
|
||||
for (i = 0; i < detect_list[snd_ch].Count; i++)
|
||||
{
|
||||
found = 0;
|
||||
|
||||
// if (detect_list_l[snd_ch].Count > 0)
|
||||
// if (my_indexof(&detect_list_l[snd_ch], detect_list[snd_ch].Items[i]) > -1)
|
||||
// found = 1;
|
||||
|
||||
if (found == 0)
|
||||
if (modem_mode[snd_ch] == MODE_MPSK)
|
||||
{
|
||||
if (modem_mode[snd_ch] == MODE_MPSK)
|
||||
{
|
||||
// analiz_frame(snd_ch, detect_list[snd_ch].Items[i]->Data, [snd_ch].Items[i]->Data + ' dF: ' + FloatToStrF(DET[0, 0].AFC_dF[snd_ch], ffFixed, 0, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
analiz_frame(snd_ch, detect_list[snd_ch].Items[i], report, fecflag);
|
||||
}
|
||||
// analiz_frame(snd_ch, detect_list[snd_ch].Items[i]->Data, [snd_ch].Items[i]->Data + ' dF: ' + FloatToStrF(DET[0, 0].AFC_dF[snd_ch], ffFixed, 0, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
analiz_frame(snd_ch, detect_list[snd_ch].Items[i], report, fecflag);
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel FX25 decode
|
||||
|
||||
if (fx25_mode[snd_ch] != FX25_MODE_NONE)
|
||||
{
|
||||
int e;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
for (e = 0; e <= nr_emph; e++)
|
||||
DET[e][i].fx25[snd_ch].status = FX25_TAG;
|
||||
}
|
||||
}
|
||||
|
||||
// Assign(&detect_list_l[snd_ch], &detect_list[snd_ch]); // Duplicate detect_list to detect_list_l
|
||||
// Cancel FX25 decode
|
||||
|
||||
Clear(&detect_list[snd_ch]);
|
||||
Clear(&detect_list_c[snd_ch]);
|
||||
if (fx25_mode[snd_ch] != FX25_MODE_NONE)
|
||||
{
|
||||
int e;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
for (e = 0; e <= nr_emph; e++)
|
||||
DET[e][i].fx25[snd_ch].status = FX25_TAG;
|
||||
}
|
||||
}
|
||||
chk_dcd1(snd_ch, rx_bufsize);
|
||||
|
||||
// Assign(&detect_list_l[snd_ch], &detect_list[snd_ch]); // Duplicate detect_list to detect_list_l
|
||||
|
||||
Clear(&detect_list[snd_ch]);
|
||||
Clear(&detect_list_c[snd_ch]);
|
||||
}
|
||||
chk_dcd1(snd_ch, rx_bufsize);
|
||||
}
|
||||
|
||||
string * memory_ARQ(TStringList * buf, string * data)
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
|
||||
/* 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 */
|
File diff suppressed because it is too large
Load Diff
146
ax25_mod.c
146
ax25_mod.c
|
@ -45,6 +45,7 @@ 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
|
||||
|
||||
|
@ -89,7 +90,8 @@ 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_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};
|
||||
|
@ -1191,8 +1193,10 @@ float make_samples(unsigned char snd_ch, unsigned char * bitptr)
|
|||
|
||||
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; // il2p generates TXDELAY as part of the frame, so go straight to TX_FRAME
|
||||
tx_status[snd_ch] = TX_FRAME;
|
||||
|
||||
if (tx_status[snd_ch] == TX_TAIL)
|
||||
bit = get_new_bit_tail(snd_ch, bit);
|
||||
|
@ -1240,6 +1244,8 @@ float make_samples(unsigned char snd_ch, unsigned char * bitptr)
|
|||
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)
|
||||
|
@ -1273,7 +1279,7 @@ float make_samples(unsigned char snd_ch, unsigned char * bitptr)
|
|||
|
||||
// QPSK Mode
|
||||
|
||||
if (modem_mode[snd_ch] == MODE_QPSK)
|
||||
else if (modem_mode[snd_ch] == MODE_QPSK)
|
||||
{
|
||||
dibit = 0;
|
||||
for (i = 0; i < 2; i++)
|
||||
|
@ -1284,13 +1290,35 @@ float make_samples(unsigned char snd_ch, unsigned char * bitptr)
|
|||
tx_delay_cnt[snd_ch] = 0;
|
||||
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);
|
||||
dibit = (dibit << 1) | tx_nrzi(snd_ch, bit);
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1348,19 +1376,38 @@ float make_samples(unsigned char snd_ch, unsigned char * bitptr)
|
|||
tx_status[snd_ch] = TX_DELAY;
|
||||
}
|
||||
|
||||
if (tx_status[snd_ch] == TX_DELAY)
|
||||
bit = get_new_bit_delay(snd_ch, bit);
|
||||
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_TAIL)
|
||||
bit = get_new_bit_tail(snd_ch, bit);
|
||||
|
||||
if (tx_status[snd_ch] == TX_FRAME)
|
||||
bit = get_new_bit(snd_ch, bit);
|
||||
if (tx_status[snd_ch] == TX_FRAME)
|
||||
bit = il2p_get_new_bit(snd_ch, bit);
|
||||
|
||||
*bitptr = tx_nrzi(snd_ch, bit);
|
||||
// No nrzi for il2p
|
||||
|
||||
dibit = (dibit << 1) | *bitptr;
|
||||
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
|
||||
|
@ -1436,16 +1483,36 @@ float make_samples(unsigned char snd_ch, unsigned char * bitptr)
|
|||
tx_delay_cnt[snd_ch] = 0;
|
||||
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);
|
||||
|
||||
tribit = (tribit << 1) | tx_nrzi(snd_ch, bit);
|
||||
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;
|
||||
|
@ -1632,7 +1699,7 @@ float make_samples_calib(UCHAR snd_ch, UCHAR tones)
|
|||
return amp * sinf(tx_osc[snd_ch]);
|
||||
}
|
||||
|
||||
int amplitude = 22000;
|
||||
float amplitude = 32000;
|
||||
|
||||
void modulator(UCHAR snd_ch, int buf_size)
|
||||
{
|
||||
|
@ -1641,7 +1708,7 @@ void modulator(UCHAR snd_ch, int buf_size)
|
|||
// I think this is the top of the TX hierarchy
|
||||
|
||||
int i;
|
||||
short Sample;
|
||||
int Sample;
|
||||
|
||||
if (calib_mode[snd_ch] > 0)
|
||||
{
|
||||
|
@ -1694,6 +1761,12 @@ void modulator(UCHAR snd_ch, int buf_size)
|
|||
for (i = 0; i < buf_size; i++)
|
||||
{
|
||||
Sample = tx_BPF_buf[snd_ch][i] * amplitude;
|
||||
|
||||
if (Sample < txmin)
|
||||
txmin = Sample;
|
||||
else if (Sample > txmax)
|
||||
txmax = Sample;
|
||||
|
||||
SampleSink(modemtoSoundLR[snd_ch], Sample);
|
||||
}
|
||||
}
|
||||
|
@ -1734,7 +1807,22 @@ void modulator(UCHAR snd_ch, int buf_size)
|
|||
|
||||
for (i = 0; i < buf_size; i++)
|
||||
{
|
||||
Sample = tx_BPF_buf[snd_ch][i] * 20000.0f;
|
||||
Sample = tx_BPF_buf[snd_ch][i] * amplitude;
|
||||
|
||||
if (Sample < txmin)
|
||||
txmin = Sample;
|
||||
else if (Sample > txmax)
|
||||
{
|
||||
txmax = Sample;
|
||||
|
||||
if (txmax > 32767)
|
||||
{
|
||||
amplitude = amplitude * 32767 / txmax;
|
||||
txmax = 32767;
|
||||
Sample = 32767;
|
||||
}
|
||||
}
|
||||
|
||||
SampleSink(modemtoSoundLR[snd_ch], Sample);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*-------------------------------------------------------------------
|
||||
*
|
||||
* 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 */
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
/* 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);
|
|
@ -0,0 +1,62 @@
|
|||
|
||||
|
||||
#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 */
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
/* 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);
|
|
@ -0,0 +1,262 @@
|
|||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* 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 <hostname>" */
|
||||
|
||||
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 */
|
||||
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
[General]
|
||||
geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\a\0\0\0\0\0\0\x3\xca\0\0\x2\xf0\0\0\0\b\0\0\0\x1f\0\0\x3\xc9\0\0\x2\xef\0\0\0\0\0\0\0\0\x5\0\0\0\0\b\0\0\0\x1f\0\0\x3\xc9\0\0\x2\xef)
|
||||
windowState=@ByteArray(\0\0\0\xff\0\0\0\0\xfd\0\0\0\0\0\0\x3\xc2\0\0\x2\xbc\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)
|
||||
|
||||
[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 #x08ac4c16 #x457005cc #xea102cf7 #xd7ff9038\n (fftwf_dft_vrank_geq1_register 0 #x10048 #x10048 #x0 #x2fce15e1 #x178d4f4d #x1e956a41 #xf3fd6b80)\n (fftwf_dft_buffered_register 0 #x11048 #x11048 #x0 #x4f8e87b4 #xec4f2fa0 #x79fe76a1 #xa16e32a5)\n (fftwf_codelet_t1fv_6_sse2 0 #x10048 #x10048 #x0 #xd9db29d8 #x3302fcf3 #x19ce6e5d #x869fc341)\n (fftwf_codelet_t1fv_12_sse2 0 #x10048 #x10048 #x0 #x0b0d3933 #x08267d12 #x45613873 #xde496efe)\n (fftwf_codelet_n2fv_12_sse2 0 #x10048 #x10048 #x0 #xb0767e46 #x8d41dd22 #x439264a0 #x18435a99)\n (fftwf_dft_bluestein_register 0 #x11048 #x11048 #x0 #x5e17c068 #x1682c5d6 #x89dd79be #x9b951c0f)\n (fftwf_codelet_t1fuv_8_sse2 0 #x11048 #x11048 #x0 #x34057a74 #x664db78f #xa9524ebc #x606afd88)\n (fftwf_dft_r2hc_register 0 #x11048 #x11048 #x0 #x576d5db6 #xa6a15f8a #x875d87d5 #x7561a866)\n (fftwf_dft_vrank_geq1_register 0 #x11048 #x11048 #x0 #x1e354940 #xac45f390 #x8260fb76 #x1a44862e)\n (fftwf_rdft_rank0_register 0 #x11048 #x11048 #x0 #xff75c762 #x3a0ee093 #x5b78d592 #x6b6be60e)\n (fftwf_dft_nop_register 0 #x11048 #x11048 #x0 #x4a593e24 #xb5f06ddf #xf11fe7f2 #xc010b545)\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=
|
||||
|
||||
[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
|
|
@ -0,0 +1,12 @@
|
|||
#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
|
|
@ -0,0 +1,12 @@
|
|||
#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 _DEBUG
|
||||
#define _MT
|
||||
#define _DLL
|
|
@ -0,0 +1,150 @@
|
|||
|
||||
/* 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
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
|
||||
void dedupe_init (int ttl);
|
||||
|
||||
void dedupe_remember (packet_t pp, int chan);
|
||||
|
||||
int dedupe_check (packet_t pp, int chan);
|
||||
|
||||
|
||||
/* end dedupe.h */
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
|
||||
/* 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);
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
/* 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);
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
/* 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);
|
|
@ -0,0 +1,78 @@
|
|||
|
||||
#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 */
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* 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 */
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#if (USE_AVAHI_CLIENT|USE_MACOS_DNSSD)
|
||||
|
||||
char *dns_sd_default_service_name(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
#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
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
|
||||
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
|
|
@ -0,0 +1,14 @@
|
|||
/* 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 */
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
|
||||
/* dwgps.h */
|
||||
|
||||
#ifndef DWGPS_H
|
||||
#define DWGPS_H 1
|
||||
|
||||
|
||||
#include <time.h>
|
||||
#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 */
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
/* 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 */
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
/* 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 */
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
/* 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
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
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);
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
/* 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 */
|
||||
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/* 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 };
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
|
||||
#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
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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);
|
|
@ -0,0 +1,501 @@
|
|||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
/* 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 */
|
||||
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
|
||||
/*----------------------------------------------------------------------------
|
||||
*
|
||||
* 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
|
95
il2p.c
95
il2p.c
|
@ -48,6 +48,7 @@ along with QtSoundModem. If not, see http://www.gnu.org/licenses
|
|||
#include "UZ7HOStuff.h"
|
||||
|
||||
void Debugprintf(const char * format, ...);
|
||||
int SMUpdatePhaseConstellation(int chan, float * Phases, float * Mags, int intPSKPhase, int Count);
|
||||
|
||||
#define MAX_ADEVS 3
|
||||
|
||||
|
@ -69,6 +70,10 @@ void Debugprintf(const char * format, ...);
|
|||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
|
||||
extern int nPhases[4][16][nr_emph + 1];
|
||||
extern float Phases[4][16][nr_emph + 1][4096];
|
||||
extern float Mags[4][16][nr_emph + 1][4096];
|
||||
|
||||
/* For option to try fixing frames with bad CRC. */
|
||||
|
||||
typedef enum retry_e {
|
||||
|
@ -106,6 +111,7 @@ int MaxMagIndex = 0;
|
|||
|
||||
#include <stdint.h> // for uint64_t
|
||||
|
||||
extern unsigned int pskStates[4];
|
||||
|
||||
/* Reed-Solomon codec control block */
|
||||
struct rs {
|
||||
|
@ -702,7 +708,7 @@ packet_t ax25_new(void)
|
|||
//if (new_count > delete_count + 100) {
|
||||
if (new_count > delete_count + 256) {
|
||||
|
||||
Debugprintf("Report to WB2OSZ - Memory leak for packet objects. new=%d, delete=%d\n", new_count, delete_count);
|
||||
Debugprintf("Memory leak for packet objects. new=%d, delete=%d\n", new_count, delete_count);
|
||||
#if AX25MEMDEBUG
|
||||
#endif
|
||||
}
|
||||
|
@ -1004,7 +1010,8 @@ void multi_modem_process_rec_packet(int snd_ch, int subchan, int slice, packet_t
|
|||
|
||||
struct TDetector_t * pDET = &DET[emph][subchan];
|
||||
string * data = newString();
|
||||
char Mode[16] = "IL2P";
|
||||
char Mode[32] = "IL2P";
|
||||
int Quality = 0;
|
||||
|
||||
sprintf(Mode, "IL2P %d", centreFreq);
|
||||
|
||||
|
@ -1038,6 +1045,12 @@ void multi_modem_process_rec_packet(int snd_ch, int subchan, int slice, packet_t
|
|||
string * xx = newString();
|
||||
memset(xx->Data, 0, 16);
|
||||
|
||||
if (pskStates[snd_ch])
|
||||
{
|
||||
Quality = SMUpdatePhaseConstellation(snd_ch, &Phases[snd_ch][subchan][slice][0], &Mags[snd_ch][subchan][slice][0], pskStates[snd_ch], nPhases[snd_ch][subchan][slice]);
|
||||
sprintf(Mode, "%s][Q%d", Mode, Quality);
|
||||
}
|
||||
|
||||
Add(&detect_list_c[snd_ch], xx);
|
||||
Add(&detect_list[snd_ch], data);
|
||||
|
||||
|
@ -1045,6 +1058,8 @@ void multi_modem_process_rec_packet(int snd_ch, int subchan, int slice, packet_t
|
|||
// sprintf(Mode, "IP2P-%d", retries);
|
||||
|
||||
stringAdd(xx, Mode, strlen(Mode));
|
||||
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
@ -2256,6 +2271,7 @@ int il2p_decode_rs(unsigned char *rec_block, int data_size, int num_parity, unsi
|
|||
int derrlocs[FX25_MAX_CHECK]; // Half would probably be OK.
|
||||
|
||||
int derrors = DECODE_RS(il2p_find_rs(num_parity), rs_block, derrlocs, 0);
|
||||
|
||||
memcpy(out, rs_block + sizeof(rs_block) - n, data_size);
|
||||
|
||||
if (il2p_get_debug() >= 3) {
|
||||
|
@ -2753,7 +2769,6 @@ void fx_hex_dump(unsigned char *p, int len)
|
|||
|
||||
int il2p_encode_frame(packet_t pp, int max_fec, unsigned char *iout)
|
||||
{
|
||||
|
||||
// Can a type 1 header be used?
|
||||
|
||||
unsigned char hdr[IL2P_HEADER_SIZE + IL2P_HEADER_PARITY];
|
||||
|
@ -2772,6 +2787,7 @@ int il2p_encode_frame(packet_t pp, int max_fec, unsigned char *iout)
|
|||
}
|
||||
|
||||
// Payload is AX.25 info part.
|
||||
|
||||
unsigned char *pinfo;
|
||||
int info_len;
|
||||
info_len = ax25_get_info(pp, &pinfo);
|
||||
|
@ -3583,6 +3599,12 @@ int il2p_clarify_header(unsigned char *rec_hdr, unsigned char *corrected_descram
|
|||
|
||||
int e = il2p_decode_rs(rec_hdr, IL2P_HEADER_SIZE, IL2P_HEADER_PARITY, corrected);
|
||||
|
||||
if (e > 1) // only have 2 rs bytes so can only detect 1 error
|
||||
{
|
||||
Debugprintf("Header correction seems ok but errors > 1");
|
||||
return -1;
|
||||
}
|
||||
|
||||
il2p_descramble_block(corrected, corrected_descrambled_hdr, IL2P_HEADER_SIZE);
|
||||
|
||||
return (e);
|
||||
|
@ -3857,38 +3879,7 @@ int il2p_decode_payload(unsigned char *received, int payload_size, int max_fec,
|
|||
|
||||
// end il2p_payload.c
|
||||
|
||||
|
||||
|
||||
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.
|
||||
};
|
||||
|
||||
static struct il2p_context_s *il2p_context[MAX_CHANS][MAX_SUBCHANS][MAX_SLICERS];
|
||||
|
||||
struct il2p_context_s *il2p_context[4][16][3];
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
|
@ -3948,6 +3939,7 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
|
|||
F->state = IL2P_HEADER;
|
||||
F->bc = 0;
|
||||
F->hc = 0;
|
||||
nPhases[chan][subchan][slice] = 0;
|
||||
|
||||
// Determine Centre Freq
|
||||
|
||||
|
@ -3962,6 +3954,7 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
|
|||
F->bc = 0;
|
||||
F->hc = 0;
|
||||
centreFreq[chan] = GuessCentreFreq(chan);
|
||||
nPhases[chan][subchan][slice] = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -4005,6 +3998,12 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit)
|
|||
plprop.large_block_count, plprop.large_block_size, plprop.parity_symbols_per_block);
|
||||
}
|
||||
|
||||
if (len > 340)
|
||||
{
|
||||
Debugprintf("Packet too big for QtSM");
|
||||
// F->state = IL2P_SEARCHING;
|
||||
// return;
|
||||
}
|
||||
if (F->eplen >= 1) { // Need to gather payload.
|
||||
F->pc = 0;
|
||||
F->state = IL2P_PAYLOAD;
|
||||
|
@ -4277,12 +4276,12 @@ string * il2p_send_frame(int chan, packet_t pp, int max_fec, int polarity)
|
|||
int preamblecount;
|
||||
unsigned char preamble[1024];
|
||||
|
||||
|
||||
encoded[0] = (IL2P_SYNC_WORD >> 16) & 0xff;
|
||||
encoded[1] = (IL2P_SYNC_WORD >> 8) & 0xff;
|
||||
encoded[2] = (IL2P_SYNC_WORD) & 0xff;
|
||||
|
||||
int elen = il2p_encode_frame(pp, max_fec, encoded + IL2P_SYNC_WORD_SIZE);
|
||||
|
||||
if (elen <= 0) {
|
||||
Debugprintf("IL2P: Unable to encode frame into IL2P.\n");
|
||||
return (packet);
|
||||
|
@ -4301,14 +4300,27 @@ string * il2p_send_frame(int chan, packet_t pp, int max_fec, int polarity)
|
|||
|
||||
// Try using preaamble for txdelay
|
||||
|
||||
preamblecount = (txdelay[chan] * tx_baudrate[chan]) / 8000; // 8 for bits, 1000 for mS
|
||||
// Nino now uses 00 as preamble for QPSK
|
||||
|
||||
if (preamblecount > 1024)
|
||||
preamblecount = 1024;
|
||||
// We don't need txdelay between frames in one transmission
|
||||
|
||||
memset(preamble, IL2P_PREAMBLE, preamblecount);
|
||||
|
||||
stringAdd(packet, preamble, preamblecount);
|
||||
if (Continuation[chan] == 0)
|
||||
{
|
||||
preamblecount = (txdelay[chan] * tx_bitrate[chan]) / 8000; // 8 for bits, 1000 for mS
|
||||
|
||||
if (preamblecount > 1024)
|
||||
preamblecount = 1024;
|
||||
|
||||
if (pskStates[chan]) // PSK Modes
|
||||
memset(preamble, 01, preamblecount);
|
||||
else
|
||||
memset(preamble, IL2P_PREAMBLE, preamblecount);
|
||||
|
||||
stringAdd(packet, preamble, preamblecount);
|
||||
Continuation[chan] = 1;
|
||||
}
|
||||
|
||||
stringAdd(packet, encoded, elen);
|
||||
|
||||
tx_fx25_size[chan] = packet->Length * 8;
|
||||
|
@ -4351,7 +4363,6 @@ string * fill_il2p_data(int snd_ch, string * data)
|
|||
string * result;
|
||||
packet_t pp = ax25_new();
|
||||
|
||||
|
||||
// Call il2p_send_frame to build the bit stream
|
||||
|
||||
pp->frame_len = data->Length - 2; // Included CRC
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
/*
|
||||
* 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 */
|
|
@ -0,0 +1,126 @@
|
|||
|
||||
/* 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 */
|
|
@ -473,7 +473,7 @@ void sendAckModeAcks(int snd_ch)
|
|||
|
||||
// Socket to reply to is on end
|
||||
|
||||
Msg += (temp->Length - 4);
|
||||
Msg += (temp->Length - sizeof(void *));
|
||||
|
||||
memcpy(&socket, Msg, sizeof(void *));
|
||||
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
/*
|
||||
* 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 */
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
/*
|
||||
* 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 */
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
/* 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);
|
Binary file not shown.
|
@ -0,0 +1,19 @@
|
|||
|
||||
/* 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);
|
2
main.cpp
2
main.cpp
|
@ -67,7 +67,7 @@ int main(int argc, char *argv[])
|
|||
w = new QtSoundModem();
|
||||
|
||||
char Title[128];
|
||||
sprintf(Title, "QtSoundModem Version %s Ports %d/%d", VersionString, AGWPort, KISSPort);
|
||||
sprintf(Title, "QtSoundModem Version %s Ports %d%s/%d%s", VersionString, AGWPort, AGWServ ? "*" : "", KISSPort, KISSServ ? "*" : "");
|
||||
w->setWindowTitle(Title);
|
||||
|
||||
w->show();
|
||||
|
|
|
@ -0,0 +1,276 @@
|
|||
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
|
||||
/* 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);
|
|
@ -0,0 +1,8 @@
|
|||
/* 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
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/* 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
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
/* 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);
|
|
@ -48,7 +48,7 @@ extern int PacketMonLength;
|
|||
|
||||
#define ARDOPBufferSize 12000 * 100
|
||||
|
||||
short ARDOPTXBuffer[4][12000 * 100]; // Enough to hold whole frame of samples
|
||||
short ARDOPTXBuffer[4][ARDOPBufferSize]; // Enough to hold whole frame of samples
|
||||
|
||||
int ARDOPTXLen[4] = { 0,0,0,0 }; // Length of frame
|
||||
int ARDOPTXPtr[4] = { 0,0,0,0 }; // Tx Pointer
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
/* recv.h */
|
||||
|
||||
void recv_init (struct audio_s *pa);
|
||||
|
||||
void recv_process (void);
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
|
||||
#ifndef REDECODE_H
|
||||
#define REDECODE_H 1
|
||||
|
||||
#include "rrbb.h"
|
||||
|
||||
|
||||
extern void redecode_init (struct audio_s *p_audio_config);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* end redecode.h */
|
||||
|
|
@ -0,0 +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
|
|
@ -0,0 +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
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* 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 */
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
|
||||
#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
|
|
@ -0,0 +1,32 @@
|
|||
/* serial_port.h */
|
||||
|
||||
|
||||
#ifndef SERIAL_PORT_H
|
||||
#define SERIAL_PORT_H 1
|
||||
|
||||
|
||||
#if __WIN32__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
/*
|
||||
* 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 */
|
2850
sm_main - Copy.c
2850
sm_main - Copy.c
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,19 @@
|
|||
|
||||
/* 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 */
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
|
||||
/* 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);
|
|
@ -0,0 +1,41 @@
|
|||
|
||||
/*------------------------------------------------------------------
|
||||
*
|
||||
* 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 */
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
/* 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 */
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
/* 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);
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue