From 14323a182ab35fbc4385dc237f2ded685a94182e Mon Sep 17 00:00:00 2001
From: John Wiseman <john.wiseman@cantab.net>
Date: Fri, 27 Dec 2024 15:13:16 +0000
Subject: [PATCH] 0.0.0.74 Beta 2

---
 ALSASound.c   |    1 +
 SMMain.c      |   10 +-
 SoundInput.c  |    2 +-
 UZ7HOStuff.h  |   33 +-
 ax25.c        |    2 +-
 ax25_demod.c  |    2 +-
 ax25_l2.c     |    4 +-
 dw9600.c      |   53 +-
 il2p.c        |   81 +--
 sm_main.c     |   21 +-
 sm_main.c.bak | 1431 -------------------------------------------------
 11 files changed, 62 insertions(+), 1578 deletions(-)
 delete mode 100644 sm_main.c.bak

diff --git a/ALSASound.c b/ALSASound.c
index 6cb6121..f9786c3 100644
--- a/ALSASound.c
+++ b/ALSASound.c
@@ -73,6 +73,7 @@ void displayLevel(int max);
 BOOL WriteCOMBlock(HANDLE fd, char * Block, int BytesToWrite);
 VOID processargs(int argc, char * argv[]);
 void PollReceivedSamples();
+void closeTraceLog();
 
 
 HANDLE OpenCOMPort(char * Port, int speed, BOOL SetDTR, BOOL SetRTS, BOOL Quiet, int Stopbits);
diff --git a/SMMain.c b/SMMain.c
index dc8a0cf..6500e2b 100644
--- a/SMMain.c
+++ b/SMMain.c
@@ -224,7 +224,7 @@ void SampleSink(int LR, short Sample)
 	{
 		// Need to upsample to 48K. Try just duplicating sample
 
-		uint32_t * ptr = &DMABuffer[2 * Number];
+		uint16_t * ptr = &DMABuffer[2 * Number];
 
 		*(&ptr[1]) = *(ptr);
 		*(&ptr[2]) = *(ptr);
@@ -388,7 +388,7 @@ extern UCHAR * pixelPointer;
 #endif
 
 extern int blnBusyStatus;
-BusyDet = 5;
+int BusyDet = 5;
 
 #define PLOTWATERFALL
 
@@ -522,6 +522,12 @@ void SMUpdateBusyDetector(int LR, float * Real, float *Imag)
 		Low = tx_freq[chan] - txbpf[chan] / 2;
 		High = tx_freq[chan] + txbpf[chan] / 2;
 
+		if (Low < 100)
+			continue;
+
+		if (High > 3300)
+			continue;
+
 //		Low = tx_freq[chan] - 0.5*rx_shift[chan];
 //		High = tx_freq[chan] + 0.5*rx_shift[chan];
 
diff --git a/SoundInput.c b/SoundInput.c
index 32366f5..22b0a2e 100644
--- a/SoundInput.c
+++ b/SoundInput.c
@@ -32,7 +32,7 @@ extern unsigned int PKTLEDTimer;
 //#define min(x, y) ((x) < (y) ? (x) : (y))
 
 void SendFrametoHost(unsigned char *data, unsigned dlen);
-
+void ProcessPktFrame(int snd_ch, UCHAR * Data, int frameLen);
 void CheckandAdjustRXLevel(int maxlevel, int minlevel, BOOL Force);
 void mySetPixel(unsigned char x, unsigned char y, unsigned int Colour);
 void clearDisplay();
diff --git a/UZ7HOStuff.h b/UZ7HOStuff.h
index 563daf9..de40a92 100644
--- a/UZ7HOStuff.h
+++ b/UZ7HOStuff.h
@@ -4,8 +4,8 @@
 //	 My port of UZ7HO's Soundmodem
 //
 
-#define VersionString "0.0.0.73"
-#define VersionBytes {0, 0, 0, 73}
+#define VersionString "0.0.0.74 Beta 2"
+#define VersionBytes {0, 0, 0, 74}
 
 //#define LOGTX
 //#define LOGRX
@@ -197,7 +197,8 @@
 //		Use ARDOP Busy detector (Beta 3)
 //		Various fixes to AGW interface (Beta 4)
 
-
+//.74	Fix filter bandwidths		Nov 24
+//		Fixes for gcc 14			Beta 2
 
 // As far as I can see txtail is only there to make sure all bits get through the tx filter,
 // so it shouldn't really matter what is sent. Code worked in characters, so resolution of txtail
@@ -668,11 +669,11 @@ extern int SendSize;
 #define QPSK_SM 0
 #define QPSK_V26 1
 
-#define MODEM_8P4800_BPF 3200
-#define MODEM_8P4800_TXBPF 3400
+#define MODEM_8P4800_BPF 2800			// Baud 1600
+#define MODEM_8P4800_TXBPF 2800
 #define MODEM_8P4800_LPF 1000
-#define MODEM_8P4800_BPF_TAP 64
-#define MODEM_8P4800_LPF_TAP 8
+#define MODEM_8P4800_BPF_TAP 256
+#define MODEM_8P4800_LPF_TAP 128
  //
 #define MODEM_MP400_BPF 775
 #define MODEM_MP400_TXBPF 850
@@ -684,7 +685,7 @@ extern int SendSize;
 #define MODEM_DW2400_TXBPF 2500
 #define MODEM_DW2400_LPF 900
 #define MODEM_DW2400_BPF_TAP 256 //256
-#define MODEM_DW2400_LPF_TAP 32  //128
+#define MODEM_DW2400_LPF_TAP 128  //128
  //
 #define MODEM_Q2400_BPF 2400
 #define MODEM_Q2400_TXBPF 2500
@@ -692,20 +693,20 @@ extern int SendSize;
 #define MODEM_Q2400_BPF_TAP 256 //256
 #define MODEM_Q2400_LPF_TAP 128  //128
  //
-#define MODEM_Q3600_BPF 3600
-#define MODEM_Q3600_TXBPF 3000
+#define MODEM_Q3600_BPF 2800			// 1800 baud
+#define MODEM_Q3600_TXBPF 2800
 #define MODEM_Q3600_LPF 1350
 #define MODEM_Q3600_BPF_TAP 256
 #define MODEM_Q3600_LPF_TAP 128
  //
-#define MODEM_Q4800_BPF 4800
-#define MODEM_Q4800_TXBPF 5000
+#define MODEM_Q4800_BPF 2800			// 2400 baud
+#define MODEM_Q4800_TXBPF 2800
 #define MODEM_Q4800_LPF 1800
 #define MODEM_Q4800_BPF_TAP 256
 #define MODEM_Q4800_LPF_TAP 128
  //
-#define MODEM_P2400_BPF 4800
-#define MODEM_P2400_TXBPF 5000
+#define MODEM_P2400_BPF 2800			// 2400 baud
+#define MODEM_P2400_TXBPF 2800
 #define MODEM_P2400_LPF 1800
 #define MODEM_P2400_BPF_TAP 256
 #define MODEM_P2400_LPF_TAP 128
@@ -746,8 +747,8 @@ extern int SendSize;
 #define MODEM_1200_BPF_TAP 256
 #define MODEM_1200_LPF_TAP 128
  //
-#define MODEM_2400_BPF 3200
-#define MODEM_2400_TXBPF 3200
+#define MODEM_2400_BPF 2800				// 2400 baud
+#define MODEM_2400_TXBPF 2800
 #define MODEM_2400_LPF 1400
 #define MODEM_2400_BPF_TAP 256
 #define MODEM_2400_LPF_TAP 128
diff --git a/ax25.c b/ax25.c
index 32933cd..10992b9 100644
--- a/ax25.c
+++ b/ax25.c
@@ -1758,7 +1758,7 @@ int number_digi(char * path)
 
 
 
-get_monitor_path(Byte * path, char * mycall, char * corrcall, char * digi)
+void get_monitor_path(Byte * path, char * mycall, char * corrcall, char * digi)
 {
 	Byte * digiptr = digi;
 
diff --git a/ax25_demod.c b/ax25_demod.c
index a05f39f..919cc49 100644
--- a/ax25_demod.c
+++ b/ax25_demod.c
@@ -497,7 +497,7 @@ void chk_dcd1(int snd_ch, int buf_size)
 					for (int k = 0; k < KISS.buffer[snd_ch].Count; k++)
 					{
 						if (AGWServ)
-							AGW_Raw_monitor(snd_ch, Strings(&KISS.buffer[snd_ch], n));
+							AGW_Raw_monitor(snd_ch, Strings(&KISS.buffer[snd_ch], k));
 
 						// Need to add copy as clear will free original
 
diff --git a/ax25_l2.c b/ax25_l2.c
index 8efcceb..43e8039 100644
--- a/ax25_l2.c
+++ b/ax25_l2.c
@@ -374,7 +374,7 @@ void  delete_I_FRM(TAX25Port * AX25Sess, int  nr)
 void delete_I_FRM_port(TAX25Port * AX25Sess)
 {
 	string * frame;
-	string path = { 0 }; 
+	char path[] = ""; 
 	string data= { 0 };
 
 	Byte pid, nr, ns, f_type, f_id, rpt, cr, pf;
@@ -386,7 +386,7 @@ void delete_I_FRM_port(TAX25Port * AX25Sess)
 		optimize = TRUE;
 		frame = Strings(&AX25Sess->frame_buf, i);
 
-		decode_frame(frame->Data, frame->Length, &path, &data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
+		decode_frame(frame->Data, frame->Length, &path[0], &data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
 
 		if (f_id == I_I)
 		{
diff --git a/dw9600.c b/dw9600.c
index da9b3c7..2621b4a 100644
--- a/dw9600.c
+++ b/dw9600.c
@@ -21,6 +21,8 @@ typedef struct TStringList_T
 } TStringList;
 
 #include <stddef.h>
+#include <ctype.h>
+#include <stdlib.h>
 #include "dw9600.h"
 
 #define stringAdd(s1, s2, c) mystringAdd(s1, s2, c, __FILE__, __LINE__)
@@ -48,8 +50,13 @@ extern short tx_bitrate[5];
 extern unsigned short * DMABuffer;
 extern int SampleNo;
 
-
+string * il2p_send_frame(int chan, packet_t pp, int max_fec, int polarity);
+int fx25_send_frame(int chan, unsigned char *fbuf, int flen, int fx_mode);
+int multi_modem_process_rec_frame(int chan, int subchan, int slice, unsigned char *fbuf, int flen, int alevel, int retries, int is_fx25);
 void ProcessRXFrames(int snd_ch);
+unsigned short get_fcs(unsigned char * Data, unsigned short len);
+void il2p_rec_bit(int chan, int subchan, int slice, int dbit);
+void Debugprintf(const char * format, ...);
 
 //
 //    This file is part of Dire Wolf, an amateur radio packet TNC.
@@ -171,10 +178,8 @@ static int composite_dcd[MAX_CHANS][MAX_SUBCHANS + 1];
 
 int was_init[4] = { 0, 0, 0, 0 };
 
-struct audio_s *g_audio_p;
 extern struct audio_s pa[4];
 
-
 void hdlc_rec_init(struct audio_s *pa)
 {
 	int ch;
@@ -184,7 +189,7 @@ void hdlc_rec_init(struct audio_s *pa)
 	//dw_printf ("hdlc_rec_init (%p) \n", pa);
 
 	assert(pa != NULL);
-	g_audio_p = &pa;
+
 
 	memset(composite_dcd, 0, sizeof(composite_dcd));
 
@@ -336,7 +341,7 @@ static void eas_rec_bit(int chan, int subchan, int slice, int raw, int future_us
 		dw_printf("frame_buf %d = %s\n", slice, H->frame_buf);
 #endif
 		alevel_t alevel = demod_get_audio_level(chan, subchan);
-		multi_modem_process_rec_frame(chan, subchan, slice, H->frame_buf, H->frame_len, alevel, 0, 0);
+		multi_modem_process_rec_frame(chan, subchan, slice, H->frame_buf, H->frame_len, 0, 0, 0);
 		H->eas_gathering = 0;
 	}
 
@@ -1597,7 +1602,7 @@ static int try_decode(rrbb_t block, int chan, int subchan, int slice, alevel_t a
 
 			assert(rrbb_get_chan(block) == chan);
 			assert(rrbb_get_subchan(block) == subchan);
-			multi_modem_process_rec_frame(chan, subchan, slice, H2.frame_buf, H2.frame_len - 2, alevel, retry_conf.retry, 0);   /* len-2 to remove FCS. */
+			multi_modem_process_rec_frame(chan, subchan, slice, H2.frame_buf, H2.frame_len - 2, 0, retry_conf.retry, 0);   /* len-2 to remove FCS. */
 			return 1;		/* success */
 
 		}
@@ -1607,7 +1612,7 @@ static int try_decode(rrbb_t block, int chan, int subchan, int slice, alevel_t a
 				//text_color_set(DW_COLOR_ERROR);
 				//dw_printf ("ATTEMPTING PASSALL PROCESSING\n");
 
-				multi_modem_process_rec_frame(chan, subchan, slice, H2.frame_buf, H2.frame_len - 2, alevel, RETRY_MAX, 0);   /* len-2 to remove FCS. */
+				multi_modem_process_rec_frame(chan, subchan, slice, H2.frame_buf, H2.frame_len - 2, 0, RETRY_MAX, 0);   /* len-2 to remove FCS. */
 				return 1;		/* success */
 			}
 			else {
@@ -3423,40 +3428,6 @@ static int number_of_bits_sent[MAX_CHANS];	// Count number of bits sent by "hdlc
 static int ax25_only_hdlc_send_frame(int chan, unsigned char *fbuf, int flen, int bad_fcs);
 
 
-int layer2_send_frame(int chan, packet_t pp, int bad_fcs, struct audio_s *audio_config_p)
-{
-	if (audio_config_p->achan[chan].layer2_xmit == LAYER2_IL2P) {
-
-		int n = il2p_send_frame(chan, pp, audio_config_p->achan[chan].il2p_max_fec,
-			audio_config_p->achan[chan].il2p_invert_polarity);
-		if (n > 0) {
-			return (n);
-		}
-		text_color_set(DW_COLOR_ERROR);
-		dw_printf("Unable to send IL2p frame.  Falling back to regular AX.25.\n");
-		// Not sure if we should fall back to AX.25 or not here.
-	}
-	else if (audio_config_p->achan[chan].layer2_xmit == LAYER2_FX25) 
-	{
-		unsigned char fbuf[AX25_MAX_PACKET_LEN + 2];
-		int flen = ax25_pack(pp, fbuf);
-		int n = fx25_send_frame(chan, fbuf, flen, audio_config_p->achan[chan].fx25_strength);
-		if (n > 0) {
-			return (n);
-		}
-		text_color_set(DW_COLOR_ERROR);
-		dw_printf("Unable to send FX.25.  Falling back to regular AX.25.\n");
-		// Definitely need to fall back to AX.25 here because
-		// the FX.25 frame length is so limited.
-	}
-
-	unsigned char fbuf[AX25_MAX_PACKET_LEN + 2];
-	int flen = ax25_pack(pp, fbuf);
-	return (ax25_only_hdlc_send_frame(chan, fbuf, flen, bad_fcs));
-}
-
-
-
 static int ax25_only_hdlc_send_frame(int chan, unsigned char *fbuf, int flen, int bad_fcs)
 {
 	int j, fcs;
diff --git a/il2p.c b/il2p.c
index 1b8e2b8..9588df4 100644
--- a/il2p.c
+++ b/il2p.c
@@ -226,7 +226,6 @@ void FREE_RS(struct rs *rs);
 // Maybe these should be in a different file, separated from the internal stuff.
 
 void fx25_init(int debug_level);
-int fx25_send_frame(int chan, unsigned char *fbuf, int flen, int fx_mode);
 void fx25_rec_bit(int chan, int subchan, int slice, int dbit);
 int fx25_rec_busy(int chan);
 
@@ -398,7 +397,8 @@ typedef enum cmdres_e { cr_00 = 2, cr_cmd = 1, cr_res = 0, cr_11 = 3 } cmdres_t;
 extern packet_t ax25_new(void);
 
 
-#ifdef AX25_PAD_C	/* Keep this hidden - implementation could change. */
+int set_addrs(packet_t pp, char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_addr, cmdres_t cr);
+
 
 
 /*
@@ -441,8 +441,6 @@ static inline int ax25_get_num_control(packet_t this_p)
 	return (1);					/* U   xxxx xx11 */
 }
 
-
-
 /*
  * APRS always has one protocol octet of 0xF0 meaning no level 3
  * protocol but the more general case is 0, 1 or 2 protocol ID octets.
@@ -514,7 +512,7 @@ static inline int ax25_get_num_info(packet_t this_p)
 	return (len);
 }
 
-#endif
+
 
 
 typedef enum ax25_modulo_e { modulo_unknown = 0, modulo_8 = 8, modulo_128 = 128 } ax25_modulo_t;
@@ -1448,79 +1446,6 @@ int ax25_get_ssid(packet_t this_p, int n)
 
 
 
-static inline int ax25_get_pid_offset(packet_t this_p)
-{
-	return (ax25_get_control_offset(this_p) + ax25_get_num_control(this_p));
-}
-
-static int ax25_get_num_pid(packet_t this_p)
-{
-	int c;
-	int pid;
-
-	c = this_p->frame_data[ax25_get_control_offset(this_p)];
-
-	if ((c & 0x01) == 0 ||				/* I   xxxx xxx0 */
-		c == 0x03 || c == 0x13) {			/* UI  000x 0011 */
-
-		pid = this_p->frame_data[ax25_get_pid_offset(this_p)];
-		if (pid == AX25_PID_ESCAPE_CHARACTER) {
-			return (2);			/* pid 1111 1111 means another follows. */
-		}
-		return (1);
-	}
-	return (0);
-}
-
-
-inline int ax25_get_control_offset(packet_t this_p)
-{
-	return (this_p->num_addr * 7);
-}
-
-inline int ax25_get_num_control(packet_t this_p)
-{
-	int c;
-
-	c = this_p->frame_data[ax25_get_control_offset(this_p)];
-
-	if ((c & 0x01) == 0) {			/* I   xxxx xxx0 */
-		return ((this_p->modulo == 128) ? 2 : 1);
-	}
-
-	if ((c & 0x03) == 1) {			/* S   xxxx xx01 */
-		return ((this_p->modulo == 128) ? 2 : 1);
-	}
-
-	return (1);					/* U   xxxx xx11 */
-}
-
-
-
-
-int ax25_get_info_offset(packet_t this_p)
-{
-	int offset = ax25_get_control_offset(this_p) + ax25_get_num_control(this_p) + ax25_get_num_pid(this_p);
-	return (offset);
-}
-
-int ax25_get_num_info(packet_t this_p)
-{
-	int len;
-
-	/* assuming AX.25 frame. */
-
-	len = this_p->frame_len - this_p->num_addr * 7 - ax25_get_num_control(this_p) - ax25_get_num_pid(this_p);
-	if (len < 0) {
-		len = 0;		/* print error? */
-	}
-
-	return (len);
-}
-
-
-
-
 
 	/*------------------------------------------------------------------------------
 	 *
diff --git a/sm_main.c b/sm_main.c
index fba2f2f..7cc526b 100644
--- a/sm_main.c
+++ b/sm_main.c
@@ -30,8 +30,19 @@ void make_core_LPF(UCHAR snd_ch, short width);
 void dw9600ProcessSample(int snd_ch, short Sample);
 void init_RUH48(int snd_ch);
 void init_RUH96(int snd_ch);
+void CheckPSKWindows();
+void Demodulator(int snd_ch, int rcvr_nr, float * src_buf, int last, int xcenter);
+void sendSamplestoUDP(short * Samples, int nSamples, int Port);
+void RSIDProcessSamples(short * Samples, int nSamples);
+void ARDOPProcessNewSamples(int chan, short * Samples, int nSamples);
+void doWaterfall(int snd_ch);
+void  displayWaterfall();
+void timer_event();
+void decode_frame(Byte * frame, int len, Byte * path, string * data, Byte * pid, Byte * nr, Byte * ns, Byte * f_type, Byte * f_id, Byte *  rpt, Byte * pf, Byte * cr);
+void get_monitor_path(Byte * path, char * mycall, char * corrcall, char * digi);
+void ProcessRXFrames(int snd_ch);
 
-char modes_name[modes_count][21] = 
+char modes_name[modes_count][21] =
 {
 	"AFSK AX.25 300bd","AFSK AX.25 1200bd","AFSK AX.25 600bd","AFSK AX.25 2400bd",
 	"BPSK AX.25 1200bd","BPSK AX.25 600bd","BPSK AX.25 300bd","BPSK AX.25 2400bd",
@@ -827,10 +838,10 @@ void runModems()
 		if (thread[2]) WaitForSingleObject(&thread[2], 2000);
 		if (thread[3]) WaitForSingleObject(&thread[3], 2000);
 #else
-		if (thread[0]) pthread_join(thread[0], &res);
-		if (thread[1]) pthread_join(thread[1], &res);
-		if (thread[2]) pthread_join(thread[2], &res);
-		if (thread[3]) pthread_join(thread[3], &res);
+		if (thread[0]) pthread_join(thread[0], NULL);
+		if (thread[1]) pthread_join(thread[1], NULL);
+		if (thread[2]) pthread_join(thread[2], NULL);
+		if (thread[3]) pthread_join(thread[3], NULL);
 #endif
 	}
 }
diff --git a/sm_main.c.bak b/sm_main.c.bak
deleted file mode 100644
index e017275..0000000
--- a/sm_main.c.bak
+++ /dev/null
@@ -1,1431 +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.
-newsamp
-
-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"
-
-void make_core_BPF(UCHAR snd_ch, short freq, short width);
-void make_core_TXBPF(UCHAR snd_ch, float freq, float width);
-void make_core_INTR(UCHAR snd_ch);
-void make_core_LPF(UCHAR snd_ch, short width);
-void dw9600ProcessSample(int snd_ch, short Sample);
-void init_RUH48(int snd_ch);
-void init_RUH96(int snd_ch);
-
-char modes_name[modes_count][21] = 
-{
-	"AFSK AX.25 300bd","AFSK AX.25 1200bd","AFSK AX.25 600bd","AFSK AX.25 2400bd",
-	"BPSK AX.25 1200bd","BPSK AX.25 600bd","BPSK AX.25 300bd","BPSK AX.25 2400bd",
-	"QPSK AX.25 4800bd","QPSK AX.25 3600bd","QPSK AX.25 2400bd","BPSK FEC 4x100bd",
-	"QPSK V26A 2400bps","8PSK V27 4800bps","QPSK V26B 2400bps", "Not Available",
-	"QPSK V26A 600bps", "8PSK 900bps", "RUH 4800(DW)", "RUH 9600(DW)"
-};
-
-typedef struct wavehdr_tag {
-	unsigned short *  lpData;   /* pointer to locked data buffer */
-	int dwBufferLength;         /* length of data buffer */
-	int dwBytesRecorded;        /* used for input only */
-	int * dwUser;               /* for client's use */
-	int dwFlags;                /* assorted flags (see defines) */
-	int dwLoops;                /* loop control counter */
-	struct wavehdr_tag *lpNext; /* reserved for driver */
-	int *   reserved;           /* reserved for driver */
-} WAVEHDR, *PWAVEHDR,  * NPWAVEHDR,  * LPWAVEHDR;
-
-extern int pnt_change[5];
-int debugmode = 0;
-extern float src_buf[5][2048];
-extern Byte RCVR[5];
-
-int SatelliteMode = 0;
-
-int UDPServerPort = 8884;
-int UDPClientPort = 8888;
-int TXPort = 8884;
-
-BOOL Firstwaterfall = 1;
-BOOL Secondwaterfall = 1;
-int multiCore = FALSE;
-
-BOOL MinOnStart  =  0;
-//RS TReedSolomon;
-//  Form1 TForm1;
-//  WaveFormat TWaveFormatEx;
-int Channels = 2;
-int BitsPerSample = 16;
-float TX_Samplerate = 12000;
-float RX_Samplerate = 12000;
-int RX_SR = 11025;
-int TX_SR = 11025;
-int RX_PPM = 0;
-int TX_PPM = 0;
-int tx_bufsize = 512;
-int rx_bufsize = 512;
-int tx_bufcount = 16;
-int rx_bufcount = 16;
-int  mouse_down[2] = {0, 0};
-//UCHAR * RX_pBuf array[257];
-//  RX_header array[1..256] of TWaveHdr;
-//  TX_pBuf array[1..4,1..256] of pointer;
-//TX_header array[1..4,1..256] of TWaveHdr;
-UCHAR calib_mode[5] = {0,0,0,0};
-UCHAR snd_status [5] = {0,0,0,0};
-UCHAR buf_status [5]  = {0,0,0,0};
-UCHAR tx_buf_num1 [5] = {0,0,0,0};
-UCHAR tx_buf_num [5] = {0,0,0,0};
-
-extern short active_rx_freq[5];
-
-unsigned int pskStates[4] = {0, 0, 0, 0};	
-
-int speed[5] = {0,0,0,0};
-int panels[6] = {1,1,1,1,1};
-
-short fft_buf[2][8192];
-UCHAR fft_disp[2][1024];
-int fftCount = 0;			// FTF samples collected
-
-//  bm array[1..4] of TBitMap;
-//  bm1,bm2,bm3 TBitMap;
-
-//  WaveInHandle hWaveIn;
-//  WaveOutHandle array[1..4] of hWaveOut;
-int RXBufferLength;
-
-int grid_time = 0;
-int fft_mult = 0;
-int fft_spd = 3;
-int grid_timer = 0;
-int stop_wf  = 0;
-int raduga = DISP_RGB;
-char snd_rx_device_name[32] = "";
-char snd_tx_device_name[32] = "";
-int snd_rx_device = 0;
-int snd_tx_device = 0;
-UCHAR mod_icon_status = MOD_IDLE;
-UCHAR last_mod_icon_status = MOD_IDLE;
-UCHAR icon_timer = 0;
-//  TelIni TIniFile;
-char cur_dir[] = "";
-//  TimerId1 cardinal;
-//  TimerId2 cardinal;
-UCHAR TimerStat1 = TIMER_FREE;
-UCHAR TimerStat2 = TIMER_FREE;
-int stat_log = FALSE;
-
-int PTT_device = FALSE;
-int RX_device = FALSE;
-int TX_device = FALSE;
-int TX_rotate = FALSE;
-int UsingBothChannels = FALSE;
-int UsingLeft = FALSE;
-int UsingRight = FALSE;
-
-int SCO = FALSE;
-int DualPTT = TRUE;
-UCHAR  DebugMode = 0;
-UCHAR TimerEvent = TIMER_EVENT_OFF;
-int nr_monitor_lines = 50;
-int UTC_Time = FALSE;
-int MainPriority = 0;
-//  MainThreadHandle THandle;
-UCHAR w_state = WIN_MAXIMIZED;
- 
- 
-void get_filter_values(UCHAR snd_ch)
-{
-	//, unsigned short dbpf,
-//unsigned short dtxbpf,
-//unsigned short dbpftap,
-//unsigned short dlpf, 
-//unsigned short dlpftap)
-//	speed[snd_ch], bpf[snd_ch], txbpf[snd_ch], bpf_tap[snd_ch], lpf[snd_ch], lpf_tap[snd_ch]);
-
-	switch (speed[snd_ch])
-	{
-	case SPEED_8P4800:
-
-		lpf[snd_ch] = MODEM_8P4800_LPF;
-		bpf[snd_ch] = MODEM_8P4800_BPF;
-		txbpf[snd_ch] = MODEM_8P4800_TXBPF;
-		BPF_tap[snd_ch] = MODEM_8P4800_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_8P4800_LPF_TAP;
-		break;
-
-	case SPEED_MP400:
-
-		lpf[snd_ch] = MODEM_MP400_LPF;
-		bpf[snd_ch] = MODEM_MP400_BPF;
-		txbpf[snd_ch] = MODEM_MP400_TXBPF;
-		BPF_tap[snd_ch] = MODEM_MP400_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_MP400_LPF_TAP;
-
-		break;
-
-
-	case SPEED_Q4800:
-
-		lpf[snd_ch] = MODEM_Q4800_LPF;
-		bpf[snd_ch] = MODEM_Q4800_BPF;
-		txbpf[snd_ch] = MODEM_Q4800_TXBPF;
-		BPF_tap[snd_ch] = MODEM_Q4800_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_Q4800_LPF_TAP;
-
-		break;
-
-	case SPEED_Q3600:
-
-		lpf[snd_ch] = MODEM_Q3600_LPF;
-		bpf[snd_ch] = MODEM_Q3600_BPF;
-		txbpf[snd_ch] = MODEM_Q3600_TXBPF;
-		BPF_tap[snd_ch] = MODEM_Q3600_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_Q3600_LPF_TAP;
-		break;
-
-	case SPEED_Q2400:
-
-		lpf[snd_ch] = MODEM_Q2400_LPF;
-		bpf[snd_ch] = MODEM_Q2400_BPF;
-		txbpf[snd_ch] = MODEM_Q2400_TXBPF;
-		BPF_tap[snd_ch] = MODEM_Q2400_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_Q2400_LPF_TAP;
-
-		break;
-
-	case SPEED_DW2400:
-	case SPEED_2400V26B:
-
-
-		lpf[snd_ch] = MODEM_DW2400_LPF;
-		bpf[snd_ch] = MODEM_DW2400_BPF;
-		txbpf[snd_ch] = MODEM_DW2400_TXBPF;
-		BPF_tap[snd_ch] = MODEM_DW2400_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_DW2400_LPF_TAP;
-		break;
-
-	case SPEED_P2400:
-
-		lpf[snd_ch] = MODEM_P2400_LPF;
-		bpf[snd_ch] = MODEM_P2400_BPF;
-		txbpf[snd_ch] = MODEM_P2400_TXBPF;
-		BPF_tap[snd_ch] = MODEM_P2400_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_P2400_LPF_TAP;
-		break;
-
-	case SPEED_P1200:
-
-		lpf[snd_ch] = MODEM_P1200_LPF;
-		bpf[snd_ch] = MODEM_P1200_BPF;
-		txbpf[snd_ch] = MODEM_P1200_TXBPF;
-		BPF_tap[snd_ch] = MODEM_P1200_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_P1200_LPF_TAP;
-		break;
-
-	case SPEED_P600:
-
-		lpf[snd_ch] = MODEM_P600_LPF;
-		bpf[snd_ch] = MODEM_P600_BPF;
-		txbpf[snd_ch] = MODEM_P600_TXBPF;
-		BPF_tap[snd_ch] = MODEM_P600_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_P600_LPF_TAP;
-		break;
-
-	case SPEED_P300:
-
-		lpf[snd_ch] = MODEM_P300_LPF;
-		bpf[snd_ch] = MODEM_P300_BPF;
-		txbpf[snd_ch] = MODEM_P300_TXBPF;
-		BPF_tap[snd_ch] = MODEM_P300_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_P300_LPF_TAP;
-		break;
-
-	case SPEED_300:
-
-		lpf[snd_ch] = MODEM_300_LPF;
-		bpf[snd_ch] = MODEM_300_BPF;
-		txbpf[snd_ch] = MODEM_300_TXBPF;
-		BPF_tap[snd_ch] = MODEM_300_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_300_LPF_TAP;
-
-		break;
-
-	case SPEED_600:
-
-		lpf[snd_ch] = MODEM_600_LPF;
-		bpf[snd_ch] = MODEM_600_BPF;
-		txbpf[snd_ch] = MODEM_600_TXBPF;
-		BPF_tap[snd_ch] = MODEM_600_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_600_LPF_TAP;
-
-		break;
-
-	case SPEED_1200:
-
-		lpf[snd_ch] = MODEM_1200_LPF;
-		bpf[snd_ch] = MODEM_1200_BPF;
-		txbpf[snd_ch] = MODEM_1200_TXBPF;
-		BPF_tap[snd_ch] = MODEM_1200_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_1200_LPF_TAP;
-		break;
-
-	case SPEED_2400:
-
-		lpf[snd_ch] = MODEM_2400_LPF;
-		bpf[snd_ch] = MODEM_2400_BPF;
-		txbpf[snd_ch] = MODEM_2400_TXBPF;
-		BPF_tap[snd_ch] = MODEM_2400_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_2400_LPF_TAP;
-		break;
-
-
-	case SPEED_Q300:
-	case SPEED_8PSK300:
-
-		lpf[snd_ch] = MODEM_P300_LPF;
-		bpf[snd_ch] = MODEM_P300_BPF;
-		txbpf[snd_ch] = MODEM_P300_TXBPF;
-		BPF_tap[snd_ch] = MODEM_P300_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_P300_LPF_TAP;
-
-		break;
-
-/*
-
-	case SPEED_Q1200:
-
-		lpf[snd_ch] = MODEM_P1200_LPF;
-		bpf[snd_ch] = MODEM_P1200_BPF;
-		txbpf[snd_ch] = MODEM_P1200_TXBPF;
-		BPF_tap[snd_ch] = MODEM_P1200_BPF_TAP;
-		LPF_tap[snd_ch] = MODEM_P1200_LPF_TAP;
-		break;
-*/
-	}
-}
-
-
-void init_2400(int snd_ch)
-{
-	modem_mode[snd_ch] = MODE_FSK;
-	rx_shift[snd_ch] = 1805;
-	rx_baudrate[snd_ch] = 2400;
-	tx_bitrate[snd_ch] = 2400;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_1200(int snd_ch)
-{
-	modem_mode[snd_ch] = MODE_FSK;
-	rx_shift[snd_ch] = 1000;
-
-	if (stdtones)
-		rx_freq[snd_ch] = 1700;
-
-	rx_baudrate[snd_ch] = 1200;
-	tx_bitrate[snd_ch] = 1200;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_600(int snd_ch)
-{
-	modem_mode[snd_ch] = MODE_FSK;
-	rx_shift[snd_ch] = 450;
-
-	rx_baudrate[snd_ch] = 600;
-	tx_bitrate[snd_ch] = 600;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_300(int snd_ch)
-{
-	modem_mode[snd_ch] = MODE_FSK;
-	rx_shift[snd_ch] = 200;
-	rx_baudrate[snd_ch] = 300;
-	tx_bitrate[snd_ch] = 300;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_MP400(int snd_ch)
-{
-	modem_mode[snd_ch] = MODE_MPSK;
-	rx_shift[snd_ch] = 175 /*sbc*/ * 3;
-	rx_baudrate[snd_ch] = 100;
-	tx_bitrate[snd_ch] = 400;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-
-void init_8P4800(int snd_ch)
-{
-	modem_mode[snd_ch] = MODE_8PSK;
-	if (stdtones)
-		rx_freq[snd_ch] = 1800;
-
-	rx_shift[snd_ch] = 1600;
-	rx_baudrate[snd_ch] = 1600;
-	tx_bitrate[snd_ch] = 4800;
-	pskStates[snd_ch] = 8;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_V26B2400(int snd_ch)
-{
-	qpsk_set[snd_ch].mode = QPSK_V26;
-	modem_mode[snd_ch] = MODE_PI4QPSK;
-
-	if (stdtones)
-		rx_freq[snd_ch] = 1800;
-
-	rx_shift[snd_ch] = 1200;
-	rx_baudrate[snd_ch] = 1200;
-	tx_bitrate[snd_ch] = 2400;
-	pskStates[snd_ch] = 8;			// Pretend 8 so quality calc works
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_DW2400(int snd_ch)
-{
-	qpsk_set[snd_ch].mode = QPSK_V26;
-	modem_mode[snd_ch] = MODE_QPSK;
-
-	if (stdtones)
-		rx_freq[snd_ch] = 1800;
-
-	rx_shift[snd_ch] = 1200;
-	rx_baudrate[snd_ch] = 1200;
-	tx_bitrate[snd_ch] = 2400;
-	pskStates[snd_ch] = 4;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_Q4800(int snd_ch)
-{
-	qpsk_set[snd_ch].mode = QPSK_SM;
-	modem_mode[snd_ch] = MODE_QPSK;
-	rx_shift[snd_ch] = 2400;
-	rx_baudrate[snd_ch] = 2400;
-	tx_bitrate[snd_ch] = 4800;
-	pskStates[snd_ch] = 4;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_Q3600(int snd_ch)
-{
-	qpsk_set[snd_ch].mode = QPSK_SM;
-	modem_mode[snd_ch] = MODE_QPSK;
-	rx_shift[snd_ch] = 1800;
-	rx_baudrate[snd_ch] = 1800;
-	tx_bitrate[snd_ch] = 3600;
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_Q2400(int snd_ch)
-{
-  qpsk_set[snd_ch].mode = QPSK_SM;
-  modem_mode[snd_ch] = MODE_QPSK;
-  rx_shift[snd_ch] = 1200;
-  rx_baudrate[snd_ch] = 1200;
-  tx_bitrate[snd_ch] = 2400;
-  pskStates[snd_ch] = 4;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_P2400(int snd_ch)
-{
-  modem_mode[snd_ch] = MODE_BPSK;
-  rx_shift[snd_ch] = 2400;
-  rx_baudrate[snd_ch] = 2400;
-  tx_bitrate[snd_ch] = 2400;
-  pskStates[snd_ch] = 2;
-  
-  if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_P1200(int snd_ch)
-{
-  modem_mode[snd_ch] = MODE_BPSK;
-  rx_shift[snd_ch] = 1200;
-  rx_baudrate[snd_ch] = 1200;
-  tx_bitrate[snd_ch] = 1200;
-  pskStates[snd_ch] = 2;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_P600(int snd_ch)
-{
-  modem_mode[snd_ch] = MODE_BPSK;
-  rx_shift[snd_ch] = 600;
-  rx_baudrate[snd_ch] = 600;
-  tx_bitrate[snd_ch] = 600;
-  pskStates[snd_ch] = 2;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_P300(int snd_ch)
-{
-  modem_mode[snd_ch] = MODE_BPSK;
-  rx_shift[snd_ch] = 300;
-  rx_baudrate[snd_ch] = 300;
-  pskStates[snd_ch] = 2;
-  tx_bitrate[snd_ch] = 300;
-
-  if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_Q300(int snd_ch)
-{
-	qpsk_set[snd_ch].mode = QPSK_V26;
-	modem_mode[snd_ch] = MODE_QPSK;
-
-	rx_shift[snd_ch] = 300;
-	rx_baudrate[snd_ch] = 300;
-	tx_bitrate[snd_ch] = 600;
-	pskStates[snd_ch] = 4;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_8PSK300(int snd_ch)
-{
-	modem_mode[snd_ch] = MODE_8PSK;
-
-	rx_shift[snd_ch] = 300;
-	rx_baudrate[snd_ch] = 300;
-	tx_bitrate[snd_ch] = 900;
-	pskStates[snd_ch] = 8;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-void init_ARDOP(int snd_ch)
-{
-	modem_mode[snd_ch] = MODE_ARDOP;
-	rx_shift[snd_ch] = 500;
-	rx_freq[snd_ch] = 1500;
-	rx_baudrate[snd_ch] = 500;
-	tx_bitrate[snd_ch] = 500;
-
-	if (modem_def[snd_ch])
-		get_filter_values(snd_ch);
-}
-
-
-void init_speed(int snd_ch);
-
-void set_speed(int snd_ch, int Modem)
-{
-	speed[snd_ch] = Modem;
-
-	init_speed(snd_ch);
-
-}
-
-int needPSKRefresh = 0;
-
-void init_speed(int snd_ch)
-{
-	int low, high;
-
-	pskStates[snd_ch] = 0;		// Not PSK
-
-	switch (speed[snd_ch])
-	{
-	case SPEED_8P4800:
-		init_8P4800(snd_ch);
-		break;
-
-	case SPEED_2400V26B:
-		init_V26B2400(snd_ch);
-
-		break;
-
-	case SPEED_DW2400:
-		init_DW2400(snd_ch);
-		break;
-
-	case SPEED_MP400:
-		init_MP400(snd_ch);
-		break;
-	case SPEED_Q4800:
-		init_Q4800(snd_ch);
-		break;
-
-	case SPEED_Q3600:
-		init_Q3600(snd_ch);
-		break;
-
-	case SPEED_Q2400:
-		init_Q2400(snd_ch);
-		break;
-
-	case SPEED_P2400:
-		init_P2400(snd_ch);
-		break;
-
-	case SPEED_P1200:
-		init_P1200(snd_ch);
-		break;
-
-//	case SPEED_Q1200:
-//		init_Q1200(snd_ch);
-//		break;
-
-	case SPEED_P600:
-		init_P600(snd_ch);
-		break;
-
-	case SPEED_P300:
-		init_P300(snd_ch);
-		break;
-
-	case SPEED_Q300:
-		init_Q300(snd_ch);
-		break;
-
-	case SPEED_8PSK300:
-		init_8PSK300(snd_ch);
-		break;
-
-	case SPEED_300:
-
-		init_300(snd_ch);
-		break;
-
-	case SPEED_600:
-
-		init_600(snd_ch);
-		break;
-
-	case SPEED_1200:
-
-		init_1200(snd_ch);
-		break;
-
-	case SPEED_2400:
-
-		init_2400(snd_ch);
-		break;
-
-	case SPEED_ARDOP:
-
-		init_ARDOP(snd_ch);
-		break;
-
-	case SPEED_RUH48:
-
-		init_RUH48(snd_ch);
-		break;
-
-	case SPEED_RUH96:
-
-		init_RUH96(snd_ch);
-		break;
-
-	}
-
-	//QPSK_SM: begin move(#0#1#2#3, tx[0], 4); move(#0#32#64#96, rx[0], 4); end;
-	//QPSK_V26: begin move(#2#3#1#0, tx[0], 4); move(#96#64#0#32, rx[0], 4); end;
-
-	if (modem_mode[snd_ch] == MODE_QPSK || modem_mode[snd_ch] == MODE_PI4QPSK)
-	{
-		switch (qpsk_set[snd_ch].mode)
-		{
-		case QPSK_SM:
-
-			memcpy(&qpsk_set[snd_ch].tx[0], "\0\1\2\3", 4);
-			memcpy(&qpsk_set[snd_ch].rx[0], "\x0\x20\x40\x60", 4);
-			break;
-
-		case QPSK_V26:
-
-			memcpy(&qpsk_set[snd_ch].tx[0], "\2\3\1\0", 4);
-			memcpy(&qpsk_set[snd_ch].rx[0], "\x60\x40\0\x20", 4);
-			break;
-		}
-	}
-
-	tx_shift[snd_ch] = rx_shift[snd_ch];
-	tx_baudrate[snd_ch] = rx_baudrate[snd_ch];
-	low = roundf(rx_shift[snd_ch] / 2 + RCVR[snd_ch] * rcvr_offset[snd_ch] + 1);
-	high = roundf(RX_Samplerate / 2 - (rx_shift[snd_ch] / 2 + RCVR[snd_ch] * rcvr_offset[snd_ch]));
-
-	if (rx_freq[snd_ch] - low < 0)  rx_freq[snd_ch] = low;
-	if (high - rx_freq[snd_ch] < 0) rx_freq[snd_ch] = high;
-
-	tx_freq[snd_ch] = rx_freq[snd_ch];
-
-	make_core_BPF(snd_ch, rx_freq[snd_ch], bpf[snd_ch]);
-	make_core_TXBPF(snd_ch, tx_freq[snd_ch], txbpf[snd_ch]);
-	make_core_INTR(snd_ch);
-	make_core_LPF(snd_ch, lpf[snd_ch]);
-
-	/*
-	  for i = 0 to 16 do
-		for j = 0 to nr_emph do with DET[j,i] do
-		begin
-		  minamp[snd_ch] = 0;
-		  maxamp[snd_ch] = 0;
-		  ones[snd_ch] = 0;
-		  zeros[snd_ch] = 0;
-		  sample_cnt[snd_ch] = 0;
-		  bit_cnt[snd_ch] = 0;
-		  bit_osc[snd_ch] = 0;
-		  frame_status[snd_ch] = FRAME_WAIT;
-		end;
-	  form1.show_modes;
-	  form1.show_freq_a;
-	  form1.show_freq_b;
-	  */
-	NeedWaterfallHeaders = TRUE;
-
-	CheckPSKWindows();
-}
-
-
-void  chk_snd_buf(float * buf, int len)
-{
-	word i;
-	boolean  good;
-	single prev_amp;
-
-	if (len < 2)
-		return;
-
-	good = FALSE;
-	i = 1;
-	prev_amp = buf[0];
-	do
-	{
-		if (buf[i++] != prev_amp)
-			good = TRUE;
-
-	} while (good == FALSE && i < len);
-
-	// Make noise
-	if (!good)
-		for (i = 0; i < len; i++)
-			buf[i] = rand();
-}
-
-#ifdef WIN32
-
-typedef void *HANDLE;
-typedef unsigned long DWORD;
-
-#define WINAPI __stdcall
-__declspec(dllimport)
-DWORD
-WINAPI
-WaitForSingleObject(
-	__in HANDLE hHandle,
-	__in DWORD dwMilliseconds
-);
-
-
-
-
-#define pthread_t uintptr_t
-
-uintptr_t _beginthread(void(__cdecl *start_address)(void *), unsigned stack_size, void *arglist);
-#else
-
-#include <pthread.h>
-
-pthread_t _beginthread(void(*start_address)(void *), unsigned stack_size, void * arglist)
-{
-	pthread_t thread;
-
-	if (pthread_create(&thread, NULL, (void * (*)(void *))start_address, (void*)arglist) != 0)
-		perror("New Thread");
-
-	return thread;
-}
-
-#endif
-
-void runModemthread(void * param);
-
-void runModems()
-{
-	int snd_ch, res;
-	pthread_t thread[4] = { 0,0,0,0 };
-
-	for (snd_ch = 0; snd_ch < 4; snd_ch++)
-	{
-		if (soundChannel[snd_ch] == 0)				// Unused channed
-			continue;	
-	
-		if (modem_mode[snd_ch] == MODE_ARDOP)
-			continue;			// Processed above
-
-		if (modem_mode[snd_ch] == MODE_RUH)
-			continue;			// Processed above
-
-		// do we need to do this again ??
-		// make_core_BPF(snd_ch, rx_freq[snd_ch], bpf[snd_ch]);
-
-		if (multiCore)			// Run modems in separate threads
-			thread[snd_ch] = _beginthread(runModemthread, 0, (void *)(size_t)snd_ch);
-		else
-			runModemthread((void *)(size_t)snd_ch);
-	}
-
-	if (multiCore)
-	{
-#ifdef WIN32
-		if (thread[0]) WaitForSingleObject(&thread[0], 2000);
-		if (thread[1]) WaitForSingleObject(&thread[1], 2000);
-		if (thread[2]) WaitForSingleObject(&thread[2], 2000);
-		if (thread[3]) WaitForSingleObject(&thread[3], 2000);
-#else
-		if (thread[0]) pthread_join(thread[0], &res);
-		if (thread[1]) pthread_join(thread[1], &res);
-		if (thread[2]) pthread_join(thread[2], &res);
-		if (thread[3]) pthread_join(thread[3], &res);
-#endif
-	}
-}
-
-Byte rcvr_idx;
-
-void runModemthread(void * param)
-{
-	int snd_ch = (int)(size_t)param;
-
-	// I want to run lowest to highest to simplify my display 
-
-	int offset = -(RCVR[snd_ch] * rcvr_offset[snd_ch]); // lowest
-	int lastrx = RCVR[snd_ch] * 2;
-
-	if (soundChannel[snd_ch] == 0)				// Unused channed
-		return;
-
-	for (rcvr_idx = 0; rcvr_idx <= lastrx; rcvr_idx++)
-	{
-		active_rx_freq[snd_ch] = rxOffset + chanOffset[snd_ch] + rx_freq[snd_ch] + offset;
-		offset += rcvr_offset[snd_ch];
-
-		Demodulator(snd_ch, rcvr_idx, src_buf[modemtoSoundLR[snd_ch]], rcvr_idx == lastrx, offset == 0);
-	}
-}
-
-// I think this processes a buffer of samples
-
-int Toggle = 0;
-
-void BufferFull(short * Samples, int nSamples)			// These are Stereo Samples
-{
-	word i, i1, j;
-	Byte snd_ch, rcvr_idx;
-	int buf_offset;
-	int Needed;
-	short * data1;
-	short * data2 = 0;
-
-	// if UDP server active send as UDP Datagram
-
-	if (UDPServ)	// Extract just left
-	{
-		short Buff[1024];
-
-		i1 = 0;
-
-		for (i = 0; i < rx_bufsize; i++)
-		{
-			Buff[i] = Samples[i1];
-			i1 += 2;
-		}
-
-		sendSamplestoUDP(Buff, 512, TXPort);
-	}
-
-	// Do RSID processing (can we also use this for waterfall??
-
-	RSIDProcessSamples(Samples, nSamples);
-
-	// Do FFT on every 4th buffer (2048 samples)
-
-	// if in Satellite Mode look for a Tuning signal
-
-//	if (SatelliteMode)
-//	{
-//		doTuning(Samples, nSamples);
-//	}
-
-	for (snd_ch = 0; snd_ch < 4; snd_ch++)
-	{
-		if (soundChannel[snd_ch] == 0)				// Unused channed
-			continue;
-
-		if (pnt_change[snd_ch])
-		{
-			make_core_BPF(snd_ch, rx_freq[snd_ch], bpf[snd_ch]);
-			make_core_TXBPF(snd_ch, tx_freq[snd_ch], txbpf[snd_ch]);
-			pnt_change[snd_ch] = FALSE;
-		}
-
-	}
-
-	// I don't think we should process RX if either is sending
-
-	if (snd_status[0] != SND_TX && snd_status[1] != SND_TX && snd_status[2] != SND_TX && snd_status[3] != SND_TX)
-	{
-		for (snd_ch = 0; snd_ch < 4; snd_ch++)
-		{
-			if (soundChannel[snd_ch] == 0)				// Unused channed
-				continue;
-
-			if (modem_mode[snd_ch] == MODE_ARDOP)
-			{
-				short ardopbuff[1200];
-				i1 = 0;
-
-				if (using48000)
-				{
-					i1 = 0;
-					j = 0;
-
-					//	Need to downsample 48K to 12K
-					//	Try just skipping 3 samples	
-
-					nSamples /= 4;
-
-					for (i = 0; i < nSamples; i++)
-					{
-						ardopbuff[i] = Samples[i1];		
-						i1 += 8;
-					}
-				}
-				else
-				{
-					for (i = 0; i < nSamples; i++)
-					{
-						ardopbuff[i] = Samples[i1];
-						i1++;
-						i1++;
-					}
-				}
-				ARDOPProcessNewSamples(snd_ch, ardopbuff, nSamples);
-			}
-
-			else if (modem_mode[snd_ch] == MODE_RUH)
-			{
-				i1 = 0;
-				if (modemtoSoundLR[snd_ch] == 1)		// Using Right Chan
-					i1++;			
-
-				for (i = 0; i < nSamples; i++)
-				{
-					dw9600ProcessSample(snd_ch, Samples[i1]);
-					i1++;
-					i1++;
-				}
-			}
-			ProcessRXFrames(snd_ch);
-		}
-
-		// extract mono samples from data. 
-
-		data1 = Samples;
-
-		if (using48000)
-		{
-			i1 = 0;
-			j = 0;
-
-			//	Need to downsample 48K to 12K
-			//	Try just skipping 3 samples	
-
-			nSamples /= 4;
-
-			for (i = 0; i < nSamples; i++)
-			{
-				Samples[j++] = Samples[i1];
-				Samples[j++] = Samples[i1 + 1];
-				i1 += 8;
-			}
-		}
-
-		i1 = 0;
-
-		// src_buf[0] is left data,. src_buf[1] right
-
-		// We could skip extracting other channel if only one in use - is it worth it??
-
-		if (UsingBothChannels)
-		{
-			for (i = 0; i < nSamples; i++)
-			{
-				src_buf[0][i] = data1[i1];
-				i1++;
-				src_buf[1][i] = data1[i1];
-				i1++;
-			}
-		}
-		else if (UsingRight)
-		{
-			// Extract just right
-
-			i1 = 1;
-
-			for (i = 0; i < nSamples; i++)
-			{
-				src_buf[1][i] = data1[i1];
-				i1 += 2;
-			}
-		}
-		else
-		{
-			// Extract just left
-
-			for (i = 0; i < nSamples; i++)
-			{
-				src_buf[0][i] = data1[i1];
-				i1 += 2;
-			}
-		}
-
-		// Run modems before waterfall so fft buffer has values from before sync was detected
-
-		runModems();
-
-		// Do whichever waterfall is needed
-
-		// We need to run the waterfall FFT for the frequency guessing to work
-
-		// testing
-
-
-
-		int FirstWaterfallChan = 0;
-
-		doWaterfall(FirstWaterfallChan);
-		if (Firstwaterfall || Secondwaterfall)
-			displayWaterfall();
-
-
-
-
-/*
-
-		short * ptr1 = &fft_buf[0][fftCount];
-		short * ptr2 = &fft_buf[1][fftCount];
-
-		int remainingSamples = rx_bufsize;
-
-		if (UsingLeft == 0)
-		{
-			FirstWaterfallChan = 1;
-			data1++;					// to Right Samples
-		}
-
-		if (UsingBothChannels)			// Second is always Right
-			data2 = &Samples[1];		// to Right Samples
-
-
-		// FFT size isn't necessarily a multiple of rx_bufsize, so this is a bit more complicated
-		// Save FFTSize samples then process. Put the unused bits back in the fft buffer
-
-		// Collect samples for both channels if needed
-
-		Toggle++;
-
-		Needed = FFTSize - fftCount;
-
-		if (Needed <= rx_bufsize)
-		{
-			// add Needed samples to fft_buf and process. Copy rest to start of fft_buf
-
-			for (i = 0; i < Needed; i++)
-			{
-				*ptr1++ = *data1;
-				data1 += 2;
-			}
-
-			if ((Toggle & 1) || (UsingBothChannels == 0))
-				doWaterfall(FirstWaterfallChan);
-
-			if (data2)
-			{
-				for (i = 0; i < Needed; i++)
-				{
-					*ptr2++ = *data2;
-					data2 += 2;
-				}
-				if (((Toggle & 1) == 0))
-					doWaterfall(1);
-			}
-
-			if (Firstwaterfall || Secondwaterfall)
-				displayWaterfall();
-
-			remainingSamples = rx_bufsize - Needed;
-			fftCount = 0;
-
-			ptr1 = &fft_buf[0][0];
-			ptr2 = &fft_buf[1][0];
-		}
-
-		for (i = 0; i < remainingSamples; i++)
-		{
-			*ptr1++ = *data1;
-			data1 += 2;
-		}
-
-		if (data2)
-		{
-			for (i = 0; i < remainingSamples; i++)
-			{
-				*ptr2++ = *data2;
-				data2 += 2;
-			}
-		}
-		fftCount += remainingSamples;
-*/
-	}
-
-
-	if (TimerEvent == TIMER_EVENT_ON)
-	{
-		timer_event();
-//		timer_event2();
-	}
-}
-
-		/*
-
-procedure TForm1.BufferFull1(var Msg TMessage);
-var
-  i,snd_ch byte;
-begin
-  for snd_ch = 1 to 2 do
-    if pnt_change[snd_ch] then
-    begin
-      make_core_BPF(snd_ch,rx_freq[snd_ch],bpf[snd_ch]);
-      make_core_TXBPF(snd_ch,tx_freq[snd_ch],txbpf[snd_ch]);
-      pnt_change[snd_ch] = FALSE;
-    end;
-  snd_ch = 0;
-  for i = 1 to 2 do if msg.WParam = WaveOutHandle[i] then snd_ch = i;
-  if (snd_ch = 0) then exit;
-  if (snd_status[snd_ch]<>SND_TX) then exit;
-  inc(tx_buf_num[snd_ch]); if tx_buf_num[snd_ch]>tx_bufcount then tx_buf_num[snd_ch] = 1;
-  if (buf_status[snd_ch] = BUF_EMPTY) and (tx_buf_num[snd_ch] = tx_buf_num1[snd_ch]) then TX2RX(snd_ch);
-  if buf_status[snd_ch] = BUF_FULL then
-  beginf
-    make_wave_buf(snd_ch,TX_pbuf[snd_ch][tx_buf_num[snd_ch]]);
-    WaveOutWrite(WaveOutHandle[snd_ch],@TX_header[snd_ch][tx_buf_num[snd_ch]],sizeof(TWaveHdr));
-    inc(tx_buf_num1[snd_ch]); if tx_buf_num1[snd_ch]>tx_bufcount then tx_buf_num1[snd_ch] = 1;
-  end;
-end;
-
-procedure TForm1.TX2RX(snd_ch byte);
-begin
-  if snd_status[snd_ch] = SND_TX then stoptx(snd_ch);
-  if snd_status[snd_ch] = SND_IDLE then begin pttoff(snd_ch); end;
-end;
-*/
-
-
-// Monitor Code - from moncode.asm
-
-
-#define	CMDBIT	4		// CURRENT MESSAGE IS A COMMAND
-#define	RESP 2		// CURRENT MSG IS RESPONSE
-#define	VER1 1 		// CURRENT MSG IS VERSION 1
-
-
-#define	UI	3
-#define	SABM 0x2F
-#define	DISC 0x43
-#define	DM	0x0F
-#define	UA	0x63
-#define	FRMR 0x87
-#define	RR	1
-#define	RNR	5
-#define	REJ	9
-
-#define	SREJ 0x0D
-#define SABME 0x6F
-#define XID 0xAF
-#define TEST 0xE3
-
-
-#define	PFBIT 0x10		// POLL/FINAL BIT IN CONTROL BYTE
-
-#define	NETROM_PID 0xCF
-#define	IP_PID 0xCC
-#define	ARP_PID 0xCD
-
-#define	NODES_SIG	0xFF
-
-char FrameData[1024] = "";
-
-char * frame_monitor(string * frame, char * code, int tx_stat)
-{
-	char mon_frm[512];
-	char AGW_path[256];
-	string * AGW_data;
-
-	const Byte * frm = "???";
-	Byte * datap;
-	Byte _data[512] = "";
-	Byte * p_data = _data;
-	int _datalen;
-
-	char  agw_port;
-	char  CallFrom[10], CallTo[10], Digi[80];
-
-	char TR = 'R';
-	char codestr[64] = "";
-
-	integer i;
-	char  time_now[32];
-	int len;
-
-	AGWUser * AGW;
-
-	Byte pid, nr, ns, f_type, f_id;
-	Byte  rpt, cr, pf;
-	Byte path[80];
-	char c;
-	const char * p;
-
-	string * data = newString();
-
-	if (code[0] && strlen(code) < 60)
-		sprintf(codestr, "[%s]", code);
-
-	if (tx_stat)
-		TR = 'T';
-
-	decode_frame(frame->Data, frame->Length, path, data, &pid, &nr, &ns, &f_type, &f_id, &rpt, &pf, &cr);
-
-	datap = data->Data;
-
-	len = data->Length;
-
-	//	if (pid == 0xCF)
-	//		data = parse_NETROM(data, f_id);
-		// IP parsing
-	//	else if (pid == 0xCC)
-	//		data = parse_IP(data);
-		// ARP parsing
-	//	else if (pid == 0xCD)
-	//		data = parse_ARP(data);
-		//
-
-	if (len > 0)
-	{
-		for (i = 0; i < len; i++)
-		{
-			if (datap[i] > 31 || datap[i] == 13 || datap[i] == 9)
-				*(p_data++) = datap[i];
-		}
-	}
-
-	_datalen = p_data - _data;
-
-	if (_datalen)
-	{
-		Byte * ptr = _data;
-		i = 0;
-
-		// remove successive cr or cr on end		while (i < _datalen)
-
-		while (i < _datalen)
-		{
-			if ((_data[i] == 13) && (_data[i + 1] == 13))
-				i++;
-			else
-				*(ptr++) = _data[i++];
-		}
-
-		if (*(ptr - 1) == 13)
-			ptr--;
-
-		*ptr = 0;
-
-		_datalen = ptr - _data;
-	}
-
-	get_monitor_path(path, CallTo, CallFrom, Digi);
-
-	if (cr)
-	{
-		c = 'C';
-		if (pf)
-			p = " P";
-		else p = "";
-	}
-	else
-	{
-		c = 'R';
-		if (pf)
-			p = " F";
-		else
-			p = "";
-	}
-
-	switch (f_id)
-	{
-	case I_I:
-
-		frm = "I";
-		break;
-
-	case S_RR:
-
-		frm = "RR";
-		break;
-
-	case S_RNR:
-
-		frm = "RNR";
-		break;
-
-	case S_REJ:
-
-		frm = "REJ";
-		break;
-
-	case S_SREJ:
-
-		frm = "SREJ";
-		break;
-
-	case U_SABM:
-
-		frm = "SABM";
-		break;
-
-	case SABME:
-
-		frm = "SABME";
-		break;
-
-	case U_DISC:
-
-		frm = "DISC";
-		break;
-
-	case U_DM:
-
-		frm = "DM";
-		break;
-
-	case U_UA:
-
-		frm = "UA";
-		break;
-
-	case U_FRMR:
-
-		frm = "FRMR";
-		break;
-
-	case U_UI:
-
-		frm = "UI";
-		break;
-
-	case U_XID:
-
-		frm = "XID";
-		break;
-
-	case U_TEST:
-
-		frm = "TEST";
-	}
-
-	if (Digi[0])
-		sprintf(AGW_path, "Fm %s To %s Via %s <%s %c%s",CallFrom, CallTo, Digi, frm, c, p);
-	else
-		sprintf(AGW_path, "Fm %s To %s <%s %c %s", CallFrom, CallTo, frm, c, p);
-
-
-	switch (f_type)
-	{
-	case I_FRM:
-
-		//mon_frm = AGW_path + ctrl + ' R' + inttostr(nr) + ' S' + inttostr(ns) + ' pid=' + dec2hex(pid) + ' Len=' + inttostr(len) + ' >' + time_now + #13 + _data + #13#13;
-		sprintf(mon_frm, "%s R%d S%d pid=%X Len=%d>[%s%c]%s\r%s\r", AGW_path, nr, ns, pid, len, ShortDateTime(), TR, codestr, _data);
-
-		break;
-
-	case U_FRM:
-
-		if (f_id == U_UI)
-		{
-			sprintf(mon_frm, "%s pid=%X Len=%d>[%s%c]%s\r%s\r", AGW_path, pid, len, ShortDateTime(), TR, codestr, _data); // "= AGW_path + ctrl + '>' + time_now + #13;
-		}
-		else if (f_id == U_FRMR)
-		{
-			sprintf(mon_frm, "%s>%02x %02x %02x[%s]\r", AGW_path, datap[0], datap[1], datap[2], ShortDateTime()); // "= AGW_path + ctrl + '>' + time_now + #13;
-		}
-		else
-			sprintf(mon_frm, "%s>[%s%c]%s\r", AGW_path, ShortDateTime(), TR, codestr); // "= AGW_path + ctrl + '>' + time_now + #13;
-
-		break;
-
-	case S_FRM:
-
-		//		mon_frm = AGW_path + ctrl + ' R' + inttostr(nr) + ' >' + time_now + #13;
-		sprintf(mon_frm, "%s R%d>[%s%c]%s\r", AGW_path, nr, ShortDateTime(), TR, codestr); // "= AGW_path + ctrl + '>' + time_now + #13;
-
-		break;
-
-	}
-	sprintf(FrameData, "%s", mon_frm);
-	return FrameData;
-}
-