diff --git a/README.md b/README.md
index 5817a16..ec0edd9 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
# QO-100-modem
The purpose of this project is to transfer data (pictures...) via a 2,7kHz SSB channel on the narrow band transponder as fast as possible.
+Now also including RTTY mode.
# this is work in progress
-Version 0.55
+Version 0.64
Windows 10 (should work on Win7, not tested)
linux Desktop PC,
Odroid SBC
diff --git a/WinRelease/hsmodem.exe b/WinRelease/hsmodem.exe
index 048d8a9..1fa2a45 100755
Binary files a/WinRelease/hsmodem.exe and b/WinRelease/hsmodem.exe differ
diff --git a/WinRelease/hsmodem.iobj b/WinRelease/hsmodem.iobj
deleted file mode 100755
index 2289cf4..0000000
Binary files a/WinRelease/hsmodem.iobj and /dev/null differ
diff --git a/WinRelease/hsmodem.ipdb b/WinRelease/hsmodem.ipdb
deleted file mode 100755
index da71cc2..0000000
Binary files a/WinRelease/hsmodem.ipdb and /dev/null differ
diff --git a/WinRelease/hsmodem.pdb b/WinRelease/hsmodem.pdb
deleted file mode 100755
index 29e3771..0000000
Binary files a/WinRelease/hsmodem.pdb and /dev/null differ
diff --git a/WinRelease/oscardata.exe b/WinRelease/oscardata.exe
index 28bc9e3..a83dfd7 100755
Binary files a/WinRelease/oscardata.exe and b/WinRelease/oscardata.exe differ
diff --git a/WinRelease/sio_list_devices.exe b/WinRelease/sio_list_devices.exe
deleted file mode 100755
index 0bc7bf8..0000000
Binary files a/WinRelease/sio_list_devices.exe and /dev/null differ
diff --git a/WinRelease/sio_sine.exe b/WinRelease/sio_sine.exe
deleted file mode 100755
index 785f254..0000000
Binary files a/WinRelease/sio_sine.exe and /dev/null differ
diff --git a/hsmodem/announcement.cpp b/hsmodem/announcement.cpp
index 15ffaf9..9669645 100755
--- a/hsmodem/announcement.cpp
+++ b/hsmodem/announcement.cpp
@@ -27,8 +27,6 @@
#include "hsmodem.h"
-void close_a();
-
const int h_len = 57;
float h[h_len];
firfilt_crcf qfilt = NULL;
diff --git a/hsmodem/baudot.h b/hsmodem/baudot.h
new file mode 100755
index 0000000..2d17902
--- /dev/null
+++ b/hsmodem/baudot.h
@@ -0,0 +1,7 @@
+#pragma once
+
+typedef struct _BAUDOTTAB_ {
+ unsigned char baudot;
+ char letter;
+ char number;
+} BAUDOTTAB;
diff --git a/hsmodem/fft.cpp b/hsmodem/fft.cpp
index ef1918b..c10fc8c 100755
--- a/hsmodem/fft.cpp
+++ b/hsmodem/fft.cpp
@@ -47,6 +47,24 @@ int rxlevel_deteced = 0;
int rx_in_sync = 0;
msresamp_crcf fftdecim = NULL;
+float doublePeak(float *f_fftout, int e)
+{
+ // measure level at rtty freq
+ // -100..-70 and +70..+100
+ float v = 0;
+ v += f_fftout[e - 7];
+ v += f_fftout[e - 8];
+ v += f_fftout[e - 9];
+ v += f_fftout[e - 10];
+
+ v += f_fftout[e + 7];
+ v += f_fftout[e + 8];
+ v += f_fftout[e + 9];
+ v += f_fftout[e + 10];
+
+ return v;
+}
+
uint16_t *make_waterfall(float fre, int *retlen)
{
int fftrdy = 0;
@@ -101,9 +119,27 @@ uint16_t *make_waterfall(float fre, int *retlen)
// measure level at mid band
float midlevel = 0;
- for (int e = 100; e < 200; e++)
- midlevel += f_fftout[e];
- midlevel /= 100;
+ if (speedmode == 10)
+ {
+ // RTTY
+ int mid = (rtty_frequency - 170 / 2) / 10;
+ int lowlow = mid - 5;
+ int lowhigh = mid + 5;
+ mid = (rtty_frequency + 170 / 2) / 10;
+ int highlow = mid - 5;
+ int highhigh = mid + 5;
+ for (int e = lowlow; e < lowhigh; e++)
+ midlevel += f_fftout[e];
+ for (int e = highlow; e < highhigh; e++)
+ midlevel += f_fftout[e];
+ midlevel /= ((lowhigh-lowlow) + (highhigh-highlow));
+ }
+ else
+ {
+ for (int e = 100; e < 200; e++)
+ midlevel += f_fftout[e];
+ midlevel /= 100;
+ }
//calc difference in %
int idiff = (int)((edgelevel * 100) / midlevel);
@@ -118,10 +154,62 @@ uint16_t *make_waterfall(float fre, int *retlen)
// check if signal detected or not
if (idiff > 100) sig = 0;
- if (idiff < 30) sig = 1;
+ if (idiff < 50) sig = 1;
rxlevel_deteced = sig;
+ if (speedmode == 10 && rtty_autosync == 1)
+ {
+ // find an RTTY signal
+ // from 200 to 2800 Hz look for the beste double peak
+ float dp = 0;
+ int dpidx = 0;
+
+ for (int e = 20; e < 280; e++)
+ {
+ float d = doublePeak(f_fftout, e);
+ if (d > dp)
+ {
+ dp = d;
+ dpidx = e;
+ }
+ }
+
+ //printf("Signal at: %d Hz\n", (int)(dpidx * 10));
+
+ // accept if we get 3 equal values after each other
+ const static int simi = 3;
+ static int simiarr[simi];
+ static int simiidx = 0;
+ simiarr[simiidx] = (int)(dpidx * 10);
+ if (++simiidx >= simi) simiidx = 0;
+
+ int cp0 = simiarr[0];
+ for (int i = 1; i < simi; i++)
+ if (simiarr[i] < (cp0-10) || simiarr[i] > (cp0 + 10)) cp0 = 0;
+
+ if (cp0 > 0)
+ {
+ // mid value of last "arl" frequencies
+ const static int arl = 10;
+ static int fra[arl];
+ static int fraidx = 0;
+ fra[fraidx] = cp0;
+ if (++fraidx >= arl) fraidx = 0;
+ int fm = 0;
+ for (int i = 0; i < arl; i++)
+ fm += fra[i];
+ fm /= arl;
+
+ static int lastfm = 0;
+ if (fm == lastfm)
+ {
+ rtty_modifyRXfreq(fm);
+ }
+ lastfm = fm;
+ }
+ }
+
// check if changed since last check
if (sig != lastsig)
{
diff --git a/hsmodem/fifo.cpp b/hsmodem/fifo.cpp
index 5d1584e..6083e63 100755
--- a/hsmodem/fifo.cpp
+++ b/hsmodem/fifo.cpp
@@ -27,6 +27,8 @@
#include "hsmodem.h"
+void rtty_init_pipes();
+
#ifdef _WIN32_
CRITICAL_SECTION io_cap_crit_sec;
CRITICAL_SECTION io_pb_crit_sec;
@@ -77,6 +79,7 @@ void io_init_pipes()
#endif
io_voice_init_pipes();
+ rtty_init_pipes();
}
// write one sample into the fifo
@@ -190,19 +193,25 @@ int io_pb_fifo_freespace(int nolock)
int io_pb_fifo_usedspace()
{
+ IO_PB_LOCK;
+ int elemInFifo = (io_pb_wridx + AUDIO_PLAYBACK_BUFLEN - io_pb_rdidx) % AUDIO_PLAYBACK_BUFLEN;
+ IO_PB_UNLOCK();
+
+ return elemInFifo;
+ /*
int anz = io_pb_fifo_freespace(0);
- return AUDIO_PLAYBACK_BUFLEN - anz;
+ return AUDIO_PLAYBACK_BUFLEN - anz;*/
}
// read num elements
-// if num elems not avail, return 0
+// if num elems not avail, return all what fifo has stored
int io_pb_read_fifo_num(float* data, int num)
{
IO_PB_LOCK;
int elemInFifo = (io_pb_wridx + AUDIO_PLAYBACK_BUFLEN - io_pb_rdidx) % AUDIO_PLAYBACK_BUFLEN;
- if (elemInFifo < num)
+ if (elemInFifo == 0)
{
// Fifo empty, no data available
//printf("only %d elements available\n", elemInFifo);
@@ -210,14 +219,17 @@ int io_pb_read_fifo_num(float* data, int num)
return 0;
}
+ if (num > elemInFifo)
+ num = elemInFifo;
+
for (int i = 0; i < num; i++)
{
*data++ = io_pb_buffer[io_pb_rdidx];
if (++io_pb_rdidx >= AUDIO_PLAYBACK_BUFLEN) io_pb_rdidx = 0;
}
IO_PB_UNLOCK();
-
- return 1;
+
+ return num;
}
void io_clear_audio_fifos()
@@ -225,3 +237,152 @@ void io_clear_audio_fifos()
io_pb_write_fifo_clear();
io_cap_write_fifo_clear();
}
+
+// ================== RTTY FIFO ===================
+
+void clear_rtty_fifos();
+
+#ifdef _WIN32_
+CRITICAL_SECTION rtty_tx_crit_sec;
+CRITICAL_SECTION rtty_rx_crit_sec;
+#define RTTY_TX_LOCK EnterCriticalSection(&rtty_tx_crit_sec)
+#define RTTY_RX_LOCK EnterCriticalSection(&rtty_rx_crit_sec)
+void RTTY_TX_UNLOCK()
+{
+ if (&rtty_tx_crit_sec != NULL)
+ LeaveCriticalSection(&rtty_tx_crit_sec);
+}
+void RTTY_RX_UNLOCK()
+{
+ if (&rtty_rx_crit_sec != NULL)
+ LeaveCriticalSection(&rtty_rx_crit_sec);
+}
+#endif
+
+#ifdef _LINUX_
+pthread_mutex_t rtty_tx_crit_sec;
+pthread_mutex_t rtty_rx_crit_sec;
+#define RTTY_TX_LOCK pthread_mutex_lock(&rtty_tx_crit_sec)
+void RTTY_TX_UNLOCK() { pthread_mutex_unlock(&rtty_tx_crit_sec); }
+#define RTTY_RX_LOCK pthread_mutex_lock(&rtty_rx_crit_sec)
+void RTTY_RX_UNLOCK() { pthread_mutex_unlock(&rtty_rx_crit_sec); }
+#endif
+
+void rtty_init_pipes()
+{
+#ifdef _WIN32_
+ if (&rtty_tx_crit_sec != NULL) DeleteCriticalSection(&rtty_tx_crit_sec);
+ InitializeCriticalSection(&rtty_tx_crit_sec);
+
+ if (&rtty_rx_crit_sec != NULL) DeleteCriticalSection(&rtty_rx_crit_sec);
+ InitializeCriticalSection(&rtty_rx_crit_sec);
+
+#endif
+
+ clear_rtty_fifos();
+}
+
+#define RTTY_FIFOLEN 200
+
+int rtty_tx_wridx = 0;
+int rtty_tx_rdidx = 0;
+char rtty_tx_buffer[RTTY_FIFOLEN];
+
+int rtty_rx_wridx = 0;
+int rtty_rx_rdidx = 0;
+char rtty_rx_buffer[RTTY_FIFOLEN];
+
+// TX char from GUI to RTTY TX thread
+
+void clear_rtty_fifos()
+{
+ rtty_tx_wridx = rtty_tx_rdidx = 0;
+ rtty_rx_wridx = rtty_rx_rdidx = 0;
+}
+
+int rtty_tx_fifo_freespace()
+{
+ int elemInFifo = (rtty_tx_wridx + RTTY_FIFOLEN - rtty_tx_rdidx) % RTTY_FIFOLEN;
+ return RTTY_FIFOLEN - elemInFifo;
+}
+
+void clear_rtty_txfifo()
+{
+ RTTY_TX_LOCK;
+ rtty_tx_wridx = rtty_tx_rdidx = 0;
+ RTTY_TX_UNLOCK();
+}
+
+void rtty_tx_write_fifo(char c)
+{
+ RTTY_TX_LOCK;
+
+ // check if there is free space in fifo
+ if (rtty_tx_fifo_freespace() == 0)
+ {
+ RTTY_TX_UNLOCK();
+ return;
+ }
+
+ rtty_tx_buffer[rtty_tx_wridx] = c;
+ if (++rtty_tx_wridx >= RTTY_FIFOLEN) rtty_tx_wridx = 0;
+ RTTY_TX_UNLOCK();
+}
+
+int rtty_tx_read_fifo(char *pc)
+{
+ RTTY_TX_LOCK;
+
+ if (rtty_tx_rdidx == rtty_tx_wridx)
+ {
+ // Fifo empty, no data available
+ RTTY_TX_UNLOCK();
+ return 0;
+ }
+
+ *pc = rtty_tx_buffer[rtty_tx_rdidx];
+ if (++rtty_tx_rdidx >= RTTY_FIFOLEN) rtty_tx_rdidx = 0;
+ RTTY_TX_UNLOCK();
+
+ return 1;
+}
+
+int rtty_rx_fifo_freespace()
+{
+ int elemInFifo = (rtty_rx_wridx + RTTY_FIFOLEN - rtty_rx_rdidx) % RTTY_FIFOLEN;
+ return RTTY_FIFOLEN - elemInFifo;
+}
+
+void rtty_rx_write_fifo(char c)
+{
+ RTTY_RX_LOCK;
+
+ // check if there is free space in fifo
+ if (rtty_rx_fifo_freespace() == 0)
+ {
+ RTTY_RX_UNLOCK();
+ return;
+ }
+
+ rtty_rx_buffer[rtty_rx_wridx] = c;
+ if (++rtty_rx_wridx >= RTTY_FIFOLEN) rtty_rx_wridx = 0;
+ RTTY_RX_UNLOCK();
+}
+
+int rtty_rx_read_fifo(char* pc)
+{
+ RTTY_RX_LOCK;
+
+ if (rtty_rx_rdidx == rtty_rx_wridx)
+ {
+ // Fifo empty, no data available
+ RTTY_RX_UNLOCK();
+ return 0;
+ }
+
+ *pc = rtty_rx_buffer[rtty_rx_rdidx];
+ if (++rtty_rx_rdidx >= RTTY_FIFOLEN) rtty_rx_rdidx = 0;
+ RTTY_RX_UNLOCK();
+
+ return 1;
+}
diff --git a/hsmodem/fm.cpp b/hsmodem/fm.cpp
new file mode 100755
index 0000000..2266498
--- /dev/null
+++ b/hsmodem/fm.cpp
@@ -0,0 +1,222 @@
+
+#include "hsmodem.h"
+
+void initfm();
+void runfm();
+
+freqmod fmmod;
+freqdem fdem = NULL;
+nco_crcf fm_dnnco = NULL;
+nco_crcf fm_upnco = NULL;
+
+firfilt_crcf fm_q = NULL;
+
+void fmtest()
+{
+ static int f = 1;
+ if (f)
+ {
+ f = 0;
+ initfm();
+ }
+
+ runfm();
+}
+
+#define CENTERF 1700.0f
+
+/*
+* fmin = 1200 Hz
+* fmax = 2300 Hz
+* fcarrier = 1700 Hz
+*
+* kf = max.deviation / samplerate
+* max deviation = 2300 - 1700 = 600 Hz
+* kf = 600/48000 = 0.0125
+*
+* this results in:
+* -0.99 ... 1100 Hz
+* +0.99 ... 2300 Hz
+*/
+const int sstv_fsync = 1200;
+const int sstv_fblack = 1500;
+const int sstv_fwhite = 2300;
+
+const int sstv_maxbw = (sstv_fwhite - sstv_fsync);
+const float sstv_kf = ((float)sstv_maxbw / 2.0f) / (float)caprate;
+const float sstv_carrier = (sstv_maxbw / 2) + sstv_fsync;
+
+// frequency values per millisecond
+#define COLLECT 5
+const float per_ms = (float)COLLECT * 1000.0f / 48000.0f;
+int realsync = 0;
+const int maxpixel = 5000;
+const int maxlines = 300;
+int pidx = 0;
+int lidx = 0;
+uint8_t fmap[maxlines][maxpixel*2];
+
+void initfm()
+{
+ fmmod = freqmod_create(sstv_kf); // modulator
+ fdem = freqdem_create(sstv_kf);
+
+ // create NCO for up-mixing to 1500 Hz
+ float fm_RX_RADIANS_PER_SAMPLE = 2.0f * (float)M_PI * sstv_carrier / (float)caprate;
+ fm_upnco = nco_crcf_create(LIQUID_NCO);
+ nco_crcf_set_phase(fm_upnco, 0.0f);
+ nco_crcf_set_frequency(fm_upnco, fm_RX_RADIANS_PER_SAMPLE);
+
+ // create NCO for down-mixing from 1500 Hz
+ fm_dnnco = nco_crcf_create(LIQUID_NCO);
+ nco_crcf_set_phase(fm_dnnco, 0.0f);
+ nco_crcf_set_frequency(fm_dnnco, fm_RX_RADIANS_PER_SAMPLE);
+
+ // RX Filter
+ unsigned int flt_h_len = 31; // filter length
+ // we filter at 48k samp rate
+ float flt_fc = (float)sstv_fwhite / 2.0f / 48000.0f; // cutoff frequency
+ float flt_As = 40.0f; // stop-band attenuation
+
+ fm_q = firfilt_crcf_create_kaiser(flt_h_len, flt_fc, flt_As, 0.0f);
+ firfilt_crcf_set_scale(fm_q, 2.0f * flt_fc);
+}
+
+void runfm()
+{
+ int synpulse = 0;
+ int syncanz = 0;
+ float f;
+ liquid_float_complex s; // modulated signal
+ liquid_float_complex sbase;
+ liquid_float_complex sbasef;
+ float syntim = 0;
+ float sigtim = 0;
+
+ while (keeprunning)
+ {
+ int ret = io_cap_read_fifo(&f);
+ if (ret == 0)
+ {
+ sleep_ms(1);
+ continue;
+ }
+
+ nco_crcf_step(fm_dnnco);
+ s.real = f;
+ s.imag = f;
+ nco_crcf_mix_down(fm_dnnco, s, &sbase);
+
+ // sharp filter
+ firfilt_crcf_push(fm_q, sbase); // push input sample
+ firfilt_crcf_execute(fm_q, &sbasef); // compute output
+
+ float y; // output/demodulated message
+ freqdem_demodulate(fdem, sbasef, &y);
+
+ // y: -1..+1 (fsync..fwhite)
+ y += 1; // y: 0..2 (fsync..fwhite)
+ y *= (sstv_maxbw/2); // y: 0..maxbw (1100)
+ y += sstv_fsync; // y: fsync..fwhite
+ int freq = (int)y;
+
+ printf("%d ", freq);
+ if (freq < 2000) printf("\n");
+
+ static int farr[COLLECT];
+ static int fidx = 0;
+
+ farr[fidx] = freq;
+ if (++fidx < COLLECT) continue;
+ fidx = 0;
+
+ for (int i = 0; i < COLLECT; i++)
+ freq += farr[i];
+ freq /= COLLECT;
+
+ if (freq < sstv_fsync) freq = sstv_fsync;
+ if (freq > sstv_fwhite) freq = sstv_fwhite;
+
+ //printf("%d ", freq);
+ //if (freq < 2000) printf("\n");
+
+ syntim += per_ms;
+ sigtim += per_ms;
+
+ // detect start of sync pulse
+ if (synpulse == 0 && freq < 1480 && sigtim > 430.0f)
+ {
+ // syn pulse starts
+ if (sigtim < 431.0f)
+ {
+ printf("syn pulse missed, forced after %10.6f\n", sigtim);
+ realsync = 0;
+ syncanz = 0;
+ }
+ else
+ {
+ printf("syn pulse starts after %10.6f\n", sigtim);
+ realsync = 1;
+ if(syncanz < 4) syncanz++;
+ if (syncanz == 3)
+ {
+ printf("picture start\n");
+ lidx = 0;
+ }
+ }
+ synpulse = 1;
+ syntim = 0;
+ if (lidx < maxlines) lidx++;
+ }
+
+ // detect end of syn pulse
+ if (synpulse == 1 && freq > 1480)
+ {
+ // syn pulse ends
+ // check if valid length
+ if (syntim > 4.0f)
+ {
+ printf("syn pulse ends after %10.6f. In Sync:%d, written:%d to line:%d\n",syntim,realsync,pidx,lidx);
+ synpulse = 0;
+ sigtim = 0;
+ pidx = 0;
+ }
+ }
+
+ if (synpulse == 0)
+ {
+ fmap[lidx][pidx * 2] = freq >> 8;
+ fmap[lidx][pidx * 2 + 1] = freq & 0xff;
+ if (pidx < maxpixel) pidx++;
+
+ if (lidx == 260)
+ {
+ FILE* fp = fopen("sstv.img", "wb");
+ if(fp)
+ {
+ for (int i = 0; i < 260; i++)
+ {
+ fwrite(fmap[i], 1, maxpixel*2, fp);
+ }
+ fclose(fp);
+ printf("file saved\n");
+ sleep_ms(10000);
+ }
+ }
+ }
+
+
+
+
+ //printf("%10.6f %10.6f %d\n", f, y, freq);
+
+ /*
+ // monitor
+ nco_crcf_step(fm_upnco);
+ nco_crcf_mix_up(fm_upnco, sbasef, &s);
+ float usbf = s.real + s.imag;
+
+ io_pb_write_fifo(usbf * 0.2f); // reduce volume and send to soundcard
+ */
+ }
+}
\ No newline at end of file
diff --git a/hsmodem/hsmodem.cpp b/hsmodem/hsmodem.cpp
index 806d484..2ffcf13 100755
--- a/hsmodem/hsmodem.cpp
+++ b/hsmodem/hsmodem.cpp
@@ -56,6 +56,7 @@ int UdpDataPort_ModemToApp = 40133;
// op mode depending values
// default mode if not set by the app
int speedmode = 4;
+int set_speedmode = 4;
int bitsPerSymbol = 2; // QPSK=2, 8PSK=3
int constellationSize = 4; // QPSK=4, 8PSK=8
@@ -208,10 +209,11 @@ int main(int argc, char* argv[])
{
if (restart_modems == 1)
{
+ printf("restart modem requested\n");
startModem();
restart_modems = 0;
}
-
+
//doArraySend();
if (VoiceAudioMode == VOICEMODE_INTERNALLOOP)
{
@@ -255,24 +257,34 @@ int main(int argc, char* argv[])
do_tuning(tuning);
}
- // demodulate incoming audio data stream
- static uint64_t old_tm = 0;
- uint64_t tm = getms();
- if (tm >= (old_tm + 1000))
+ if (speedmode == 10)
{
- // read Audio device list every 1s
- io_readAudioDevices();
- old_tm = tm;
+ //testall();
+ //fmtest();
+ sleep_ms(10); // nothing to do here
}
- int dret = demodulator();
- if (dret == 0)
+ else
{
- // no new data in fifo
+ // demodulate incoming audio data stream
+ static uint64_t old_tm = 0;
+ uint64_t tm = getms();
+ if (tm >= (old_tm + 1000))
+ {
+ // read Audio device list every 1s
+ io_readAudioDevices();
+ old_tm = tm;
+ }
+ int dret = demodulator();
+ if (dret == 0)
+ {
+ // no new data in fifo
#ifdef _LINUX_
// not important how long to sleep, 10ms is fine
- sleep_ms(10);
+ sleep_ms(10);
#endif
+ }
}
+
}
printf("stopped: %d\n", keeprunning);
@@ -283,7 +295,6 @@ int main(int argc, char* argv[])
closesocket(BC_sock_AppToModem);
#endif
-
return 0;
}
@@ -298,7 +309,7 @@ typedef struct {
} SPEEDRATE;
// AudioRate, TX-Resampler, RX-Resampler/4, bit/symbol, Codec-Rate
-SPEEDRATE sr[10] = {
+SPEEDRATE sr[11] = {
// BPSK modes
{48000, 40,10, 1, 1200, 800},
{48000, 20, 5, 1, 2400, 2000},
@@ -314,10 +325,19 @@ SPEEDRATE sr[10] = {
{48000, 24, 6, 3, 6000, 4800},
{44100, 20, 5, 3, 6600, 5200},
{48000, 20, 5, 3, 7200, 6000},
+
+ // RTTY
+ {48000, 0, 0, 0, 0, 0},
};
void startModem()
{
+ printf("startModem\n");
+ close_dsp();
+ close_rtty();
+ io_close_audio();
+ speedmode = set_speedmode;
+
bitsPerSymbol = sr[speedmode].bpsym;
constellationSize = (1 << bitsPerSymbol); // QPSK=4, 8PSK=8
@@ -328,10 +348,27 @@ void startModem()
opusbitrate = sr[speedmode].codecrate;
// int TX audio and modulator
- close_dsp();
init_audio_result = io_init_sound(playbackDeviceName, captureDeviceName);
_init_fft();
- init_dsp();
+ if (speedmode < 10)
+ {
+ init_dsp();
+ }
+ if (speedmode == 10)
+ {
+ rtty_txoff = 1;
+ init_rtty();
+ }
+}
+
+// called from UDP callback ! DO NOT call any system functions
+void setSpeedmode(int spm)
+{
+ printf("set speedmode:%d\n", spm);
+
+ set_speedmode = spm;
+ restart_modems = 1;
+ transmissions = 1000; // announcement at next TX
}
void io_setAudioDevices(uint8_t pbvol, uint8_t capvol, uint8_t announce, uint8_t pbls, uint8_t pbmic, char *pbname, char*capname)
@@ -374,7 +411,8 @@ void bc_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
* 5 ... DV mic volume
* 6 ... safe mode number
* 7 ... send Intro
- * 8..9 ... unused
+ * 8 ... rtty autosync
+ * 9 ... unused
* 10 .. 109 ... PB device name
* 110 .. 209 ... CAP device name
*/
@@ -429,6 +467,7 @@ void bc_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
io_setAudioDevices(pdata[1], pdata[2], pdata[3], pdata[4], pdata[5], (char*)(pdata + 10), (char*)(pdata + 110));
safemode = pdata[6];
sendIntro = pdata[7];
+ rtty_autosync = pdata[8];
lastms = actms;
}
@@ -440,19 +479,13 @@ void appdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
uint8_t type = pdata[0];
uint8_t minfo = pdata[1];
+ //printf("from GUI: %d %d\n", pdata[0], pdata[1]);
+
// type values: see oscardata config.cs: frame types
if (type == 16)
{
- // Byte 1 contains the resampler ratio for TX and RX modem
- if (pdata[1] >= 12)
- {
- printf("wrong speedmode %d, ignoring\n", pdata[1]);
- return;
- }
- speedmode = pdata[1];
- printf("set speedmode to %d\n", speedmode);
- restart_modems = 1;
- transmissions = 1000; // announcement at next TX
+ // Byte 1 contains the speed mode index
+ setSpeedmode(pdata[1]);
return;
}
@@ -544,7 +577,7 @@ void appdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
VoiceAudioMode = pdata[1];
codec = pdata[2];
- printf("LS:<%s> MIC:<%s> Mode:%d codec:%d\n", lsDeviceName, micDeviceName, VoiceAudioMode, codec);
+ //printf("LS:<%s> MIC:<%s> Mode:%d codec:%d\n", lsDeviceName, micDeviceName, VoiceAudioMode, codec);
// init voice audio
if (VoiceAudioMode == VOICEMODE_OFF)
@@ -585,14 +618,61 @@ void appdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
return;
}
- if (type == 29)
+ if (speedmode == 10)
{
- int v = minfo;
- if (v > 128)
- v = v - 255;
- modifyRXfreq(float(v));
- return;
+ // rtty commands
+ if (type == 29)
+ {
+ int16_t freq = pdata[1];
+ freq <<= 8;
+ freq += pdata[2];
+ printf("set freq:%d\n", freq);
+
+ rtty_modifyRXfreq(freq);
+ return;
+ }
+
+ if (type == 30)
+ {
+ // rtty key pressed
+ rtty_tx_write_fifo(minfo);
+ return;
+ }
+
+ if (type == 31)
+ {
+ // rtty string
+ int len = pdata[1];
+ len <<= 8;
+ len += pdata[2];
+ len++; // the first toTX command
+ //printf("hsmodem.cpp rtty_tx_write_fifo: ");
+ for (int i = 0; i < len; i++)
+ {
+ //printf("%c", pdata[3 + i]);
+ rtty_tx_write_fifo(pdata[3 + i]);
+ }
+ //printf("\n");
+ return;
+ }
+
+ if (type == 32)
+ {
+ // TX on/off, but send buffer
+ rtty_txoff = minfo?0:1;
+ return;
+ }
+
+ if (type == 33)
+ {
+ // stop TX immediately
+ rtty_txoff = 1;
+ clear_rtty_txfifo();
+ }
}
+ if (type >= 29 && type <= 32) return;
+
+ if (speedmode == 10) return;
// here we are with payload data to be sent via the modulator
@@ -741,8 +821,11 @@ void GRdata_rxdata(uint8_t* pdata, int len, struct sockaddr_in* rxsock)
// reset modem if more than 2 frames have not been received
trigger_resetmodem = 0;
rx_in_sync = 0;
- printf("no signal detected, reset RX modem\n");
- resetModem();
+ if (speedmode < 10)
+ {
+ printf("no signal detected, reset RX modem\n");
+ resetModem();
+ }
lasttime = acttm;
}
}
diff --git a/hsmodem/hsmodem.h b/hsmodem/hsmodem.h
index 43744d6..e1232ba 100755
--- a/hsmodem/hsmodem.h
+++ b/hsmodem/hsmodem.h
@@ -64,6 +64,7 @@
#include "symboltracker.h"
#include "codec2.h"
#include "soundio.h"
+#include "baudot.h"
#define jpg_tempfilename "rxdata.jpg"
@@ -191,14 +192,15 @@ void write_sample_s16ne(char* ptr, double sample);
int io_ls_fifo_usedspace();
void write_sample_float32ne(char* ptr, double sample);
-void km_symtrack_cccf_create(int _ftype,
- unsigned int _k,
- unsigned int _m,
- float _beta,
- int _ms);
-void km_symtrack_cccf_reset(int mode);
-void km_symtrack_cccf_set_bandwidth(float _bw);
-void km_symtrack_execute(liquid_float_complex _x, liquid_float_complex* _y, unsigned int* _ny, unsigned int* psym_out);
+SYMTRACK* km_symtrack_cccf_create( int _ftype,
+ unsigned int _k,
+ unsigned int _m,
+ float _beta,
+ int _ms);
+void km_symtrack_cccf_reset(SYMTRACK*, int mode);
+void km_symtrack_cccf_set_bandwidth(SYMTRACK* , float _bw);
+void km_symtrack_execute(SYMTRACK* ,liquid_float_complex _x, liquid_float_complex* _y, unsigned int* _ny, unsigned int* psym_out);
+void km_symtrack_cccf_destroy(SYMTRACK*);
void io_saveStream(float f);
void playIntro();
@@ -206,10 +208,24 @@ void io_clear_voice_fifos();
float do_tuning(int send);
void init_tune();
float singleFrequency();
-void rtty_tx();
int rtty_rx();
-void modifyRXfreq(float fr);
+void modifyRXfreq(float diff_Hz, int absolute);
void showbytestring16(char* title, uint16_t* data, int anz);
+void rtty_sendChar(int c);
+void init_rtty();
+int do_rtty();
+void make_FFTdata(float f);
+void getMax(float fv);
+void close_rtty();
+void close_a();
+void rtty_modifyRXfreq(int);
+void showbitstring(char* title, uint8_t* data, int totallen, int anz);
+void rtty_tx_write_fifo(char c);
+int rtty_tx_read_fifo(char* pc);
+void rtty_rx_write_fifo(char c);
+int rtty_rx_read_fifo(char* pc);
+void clear_rtty_txfifo();
+void fmtest();
extern int speedmode;
@@ -252,9 +268,13 @@ extern int sendIntro;
extern int tuning;
extern uint32_t tuning_runtime;
extern int marker;
+extern int rtty_txoff;
+extern int rtty_txidx;
+extern int rtty_frequency;
+extern int rtty_autosync;
+
#ifdef _LINUX_
int isRunning(char* prgname);
void install_signal_handler();
-int isRunning(char* prgname);
#endif
diff --git a/hsmodem/hsmodem.vcxproj b/hsmodem/hsmodem.vcxproj
index ffff591..3007ea5 100755
--- a/hsmodem/hsmodem.vcxproj
+++ b/hsmodem/hsmodem.vcxproj
@@ -223,6 +223,7 @@
+
diff --git a/hsmodem/hsmodem.vcxproj.filters b/hsmodem/hsmodem.vcxproj.filters
index f1cf294..ce43efa 100755
--- a/hsmodem/hsmodem.vcxproj.filters
+++ b/hsmodem/hsmodem.vcxproj.filters
@@ -122,5 +122,8 @@
Header Files
+
+ Header Files
+
\ No newline at end of file
diff --git a/hsmodem/liquid_if.cpp b/hsmodem/liquid_if.cpp
index a42c075..aa3f2d4 100755
--- a/hsmodem/liquid_if.cpp
+++ b/hsmodem/liquid_if.cpp
@@ -200,7 +200,7 @@ void modulator(uint8_t sym_in)
// adapt speed to soundcard samplerate
int fs;
- while(1)
+ while(keeprunning)
{
fs = io_pb_fifo_freespace(0);
// wait until there is space in fifo
@@ -218,7 +218,6 @@ void modulator(uint8_t sym_in)
// =========== DEMODULATOR =============================
nco_crcf dnnco = NULL;
-symtrack_cccf symtrack = NULL;
firdecim_crcf decim = NULL;
msresamp_crcf adecim = NULL;
msresamp_crcf lsresamp = NULL;
@@ -243,14 +242,8 @@ uint8_t maxTXLevel = 0; // maximum TXlevel over the last x samples in %
float radians_per_sample = ((2.0f * (float)M_PI * (float)FREQUENCY) / (float)caprate);
float last_radians_per_sample = 0;
-float actfrequency = (float)FREQUENCY;
-void modifyRXfreq(float diff_Hz)
-{
- actfrequency += diff_Hz;
- printf("set:%f Hz\n", actfrequency);
- radians_per_sample = ((2.0f * (float)M_PI * actfrequency) / (float)caprate);
-}
+SYMTRACK *km_symtrack = NULL;
void init_demodulator()
{
@@ -275,8 +268,8 @@ void init_demodulator()
lsresamp = msresamp_crcf_create((float)(48000.0/44100.0), As_adecim);
// create symbol tracking synchronizer
- km_symtrack_cccf_create(ftype_st, k_st, m_st, beta_st, getMod());
- km_symtrack_cccf_set_bandwidth(bandwidth_st);
+ km_symtrack = km_symtrack_cccf_create(ftype_st, k_st, m_st, beta_st, getMod());
+ km_symtrack_cccf_set_bandwidth(km_symtrack, bandwidth_st);
}
void close_demodulator()
@@ -287,16 +280,17 @@ void close_demodulator()
adecim = NULL;
if (lsresamp) msresamp_crcf_destroy(lsresamp);
lsresamp = NULL;
- if (symtrack != NULL) symtrack_cccf_destroy(symtrack);
- symtrack = NULL;
if (dnnco != NULL) nco_crcf_destroy(dnnco);
dnnco = NULL;
+ if (km_symtrack != NULL) km_symtrack_cccf_destroy(km_symtrack);
+ km_symtrack = NULL;
}
void resetModem()
{
//printf("Reset Symtrack\n");
- km_symtrack_cccf_reset(0xff);
+ if (km_symtrack == NULL) return;
+ km_symtrack_cccf_reset(km_symtrack,0xff);
}
// called for Audio-Samples (FFT)
@@ -307,33 +301,6 @@ void make_FFTdata(float f)
uint16_t* fft = make_waterfall(f, &fftlen);
if (fft != NULL)
{
- // fft data are in fft[] size: 0..fftlen
- // 10 Hz per value
- float fdiff = (float)FREQUENCY - actfrequency;
- // shift spectrum if we are off 1500 Hz
- int diff10Hz = (int)(fdiff / 10.0);
- if (diff10Hz != 0)
- {
- //printf("%d %f %f %d\n", FREQUENCY, actfrequency, fdiff, diff10Hz);
- if (diff10Hz < 0)
- {
- diff10Hz = -diff10Hz;
- for (int i = 0; i < (fftlen-diff10Hz); i++)
- fft[i] = fft[i + diff10Hz];
-
- for (int i = (fftlen - diff10Hz); i < fftlen; i++)
- fft[i] = 0;
- }
- else
- {
- for (int i = fftlen-1; i >= diff10Hz; i--)
- fft[i] = fft[i - diff10Hz];
-
- for (int i = 0; i < diff10Hz; i++)
- fft[i] = 0;
- }
- }
-
uint8_t txpl[10000];
if (fftlen > (10000 * 2 + 1))
{
@@ -344,10 +311,17 @@ void make_FFTdata(float f)
int bidx = 0;
txpl[bidx++] = 4; // type 4: FFT data follows
- int us = io_pb_fifo_usedBlocks();
+ int us = 0;
+ if(speedmode < 10)
+ us = io_pb_fifo_usedBlocks();
+ if (speedmode == 10)
+ {
+ // RTTY
+ us = io_pb_fifo_usedspace();
+ }
+
if (us > 255 || ann_running == 1) us = 255;
txpl[bidx++] = us; // usage of TX fifo
-
us = io_cap_fifo_usedPercent();
if (us > 255) us = 255;
txpl[bidx++] = us; // usage of TX fifo
@@ -355,8 +329,11 @@ void make_FFTdata(float f)
txpl[bidx++] = rxlevel_deteced; // RX level present
txpl[bidx++] = rx_in_sync;
- txpl[bidx++] = maxLevel; // actual max level on sound capture in %
- txpl[bidx++] = maxTXLevel; // actual max level on sound playback in %
+ txpl[bidx++] = maxLevel; // actual max level on sound capture in %
+ txpl[bidx++] = maxTXLevel; // actual max level on sound playback in %
+
+ txpl[bidx++] = rtty_frequency >> 8; // rtty qrg by autosync
+ txpl[bidx++] = rtty_frequency & 0xff;
for (int i = 0; i < fftlen; i++)
{
@@ -491,7 +468,7 @@ static int const_idx = 0;
unsigned int num_symbols_sync;
liquid_float_complex syms;
unsigned int nsym_out; // demodulated output symbol
- km_symtrack_execute(y, &syms, &num_symbols_sync, &nsym_out);
+ km_symtrack_execute(km_symtrack,y, &syms, &num_symbols_sync, &nsym_out);
if (num_symbols_sync > 1) printf("symtrack_cccf_execute %d output symbols ???\n", num_symbols_sync);
if (num_symbols_sync != 0)
diff --git a/hsmodem/main_helper.cpp b/hsmodem/main_helper.cpp
index 4ad0325..6929c4b 100755
--- a/hsmodem/main_helper.cpp
+++ b/hsmodem/main_helper.cpp
@@ -100,9 +100,17 @@ void closeAllandTerminate()
exit(0);
}
+void showbitstring(char* title, uint8_t* data, int totallen, int anz)
+{
+ printf("%s. len %d: ", title, totallen);
+ for (int i = 0; i < anz; i++)
+ printf("%01X ", data[i]);
+ printf("\n");
+}
+
void showbytestring(char *title, uint8_t *data, int totallen, int anz)
{
- printf("%s. Len %d: ",title, totallen);
+ printf("%s. len %d: ",title, totallen);
for(int i=0; i1...downcount for off
+int synced = 0;
+int run_rtty_threads = 0;
-void init_rtty()
+int rtty_frequency = rtty_CENTERFREQUENCY;
+
+unsigned int m = 1; // number of bits/symbol
+#define k 264 // filter samples/symbol
+float SNRdB = 0.0f; // signal-to-noise ratio [dB]
+float bandwidth = 0.001894f; // frequency spacing
+unsigned int nfft = 1200; // FFT size for compute spectrum
+
+liquid_float_complex buf_tx[k]; // transmit buffer
+liquid_float_complex buf_rx[k]; // transmit buffer
+unsigned int sym_out;
+float nstd;
+
+fskmod modi = NULL;
+fskdem dem = NULL;
+
+int rtty_autosync = 0;
+
+
+void rtty_modifyRXfreq(int f_Hz)
{
- close_rtty();
+ printf("set:%d Hz\n", f_Hz);
+ rtty_frequency = f_Hz;
+ rtty_RX_RADIANS_PER_SAMPLE = ((2.0f * (float)M_PI * (float)f_Hz) / (float)caprate);
+}
- rtty_mod = fskmod_create(rtty_m, rtty_k, rtty_bandwith);
- rtty_dem = fskdem_create(rtty_m, rtty_k, rtty_bandwith);
- // TX: Interpolator Filter
- rtty_k_SampPerSymb = caprate / rtty_CENTERFREQUENCY;
+void sendRttyToGUI(uint8_t b)
+{
+ uint8_t txpl[7];
+ txpl[0] = 6; // RTTY RX Byte follows
+ txpl[1] = b; // RXed byte
+ txpl[2] = rtty_txoff?0:1; // TX on/off
+ txpl[3] = synced;
+ txpl[4] = 0; // unused
+ txpl[5] = 0;
+ txpl[6] = 0;
+ sendUDP(appIP, UdpDataPort_ModemToApp, txpl, sizeof(txpl));
+}
- // compute delay
- while (rtty_tau_FracSymbOffset < 0) rtty_tau_FracSymbOffset += 1.0f; // ensure positive tau
- float g = rtty_k_SampPerSymb * rtty_tau_FracSymbOffset; // number of samples offset
- int ds = (int)floorf(g); // additional symbol delay
- float dt = (g - (float)ds); // fractional sample offset
- // force dt to be in [0.5,0.5]
- if (dt > 0.5f)
+/*
+* space=lower tone (Bitvalue=1)
+* mark=higher tone (Bitvalue=0)
+*
+* start (space)
+* bit 4
+* bit 3
+* bit 2
+* bit 1
+* bit 0
+* stop (mark)
+* stop (mark)
+*
+* send space if nothing to transmit
+*/
+BAUDOTTAB baudot[] = {
+ {0b00010111,'Q','1',},
+ {0b00010011,'W','2',},
+ {0b00000001,'E','3',},
+ {0b00001010,'R','4',},
+ {0b00010000,'T','5',},
+ {0b00010101,'Y','6',},
+ {0b00000111,'U','7',},
+ {0b00000110,'I','8',},
+ {0b00011000,'O','9',},
+ {0b00010110,'P','0',},
+ {0b00000011,'A','-',},
+ {0b00000101,'S','\'',},
+ {0b00001001,'D','|',},
+ {0b00001101,'F','|',},
+ {0b00011010,'G','|',},
+ {0b00010100,'H','|',},
+ {0b00001011,'J','|',},
+ {0b00001111,'K','(',},
+ {0b00010010,'L',')',},
+ {0b00010001,'Z','+',},
+ {0b00011101,'X','/',},
+ {0b00001110,'C',':',},
+ {0b00011110,'V','=',},
+ {0b00011001,'B','?',},
+ {0b00001100,'N',',',},
+ {0b00011100,'M','.',},
+ {0b00001000,'\r','\r',},
+ {0b00000010,'\n','\n',},
+ {0b00000100,' ',' ',},
+ {0b00011011,'@','@',}, // switch to numbers
+ {0b00011111,'§','§',}, // switch to letters (if already letter, then backspace)
+ {0xff,' ',' '} // end of table
+};
+
+int isletters = 1;
+
+void baudot_encoder(char c, uint8_t bd[2], int* pnum)
+{
+ int anz = 0;
+ int letters = 0;
+
+ //printf("ascii:%c letter:%d (%d)\n", c, letters,isletters);
+
+ if (c == '#')
{
- dt -= 1.0f;
- ds++;
- }
-
- // calculate filter coeffs
- unsigned int h_len_NumFilterCoeefs = 2 * rtty_k_SampPerSymb * rtty_m_filterDelay_Symbols + 1;
- float h[4000];
- if (h_len_NumFilterCoeefs >= 4000)
- {
- printf("rtty h in h_len_NumFilterCoeefs too small, need %d\n", h_len_NumFilterCoeefs);
+ rtty_txoff = 0;
+ *pnum = 0;
return;
}
- liquid_firdes_prototype(LIQUID_FIRFILT_RRC,
- rtty_k_SampPerSymb,
- rtty_m_filterDelay_Symbols,
- rtty_beta_excessBW,
- dt,
- h);
- // create the filter
- rtty_TX_interpolator = firinterp_crcf_create(rtty_k_SampPerSymb, h, h_len_NumFilterCoeefs);
- // create NCO for upmixing to 1500 Hz
- float rtty_RADIANS_PER_SAMPLE = ((2.0f * (float)M_PI * (float)rtty_CENTERFREQUENCY) / (float)caprate);
+ if (c == '~')
+ {
+ rtty_txoff = 10;
+ *pnum = 0;
+ return;
+ }
+
+ if (c == 0x08)
+ {
+ // backspace does not exist in RTTY
+ return;
+ }
+
+ if (c == ' ')
+ {
+ bd[anz++] = 4;
+ *pnum = anz;
+ return;
+ }
+
+ if (c == '\n')
+ {
+ bd[anz++] = getBaudot('\n', letters);
+ bd[anz++] = getBaudot('\r', letters);
+ *pnum = anz;
+ return;
+ }
+
+ if (c >= 'A' && c <= 'Z') letters = 1;
+
+ if (letters == 1 && isletters == 0)
+ {
+ bd[anz++] = getBaudot('§', letters);
+ isletters = 1;
+ }
+
+ if (letters == 0 && isletters == 1)
+ {
+ bd[anz++] = getBaudot('@', letters);
+ isletters = 0;
+ }
+
+bd[anz++] = getBaudot(c, letters);
+
+*pnum = anz;
+}
+
+uint8_t getBaudot(char c, int letters)
+{
+ uint8_t res = 0;
+ int idx = 0;
+
+ while (baudot[idx].baudot != 0xff)
+ {
+ if (letters == 1 && c == baudot[idx].letter)
+ {
+ res = baudot[idx].baudot;
+ break;
+ }
+
+ if (letters == 0 && c == baudot[idx].number)
+ {
+ res = baudot[idx].baudot;
+ break;
+ }
+
+ idx++;
+ }
+ return res;
+}
+
+char baudot_decoder(char c)
+{
+ static int letter = 1;
+
+ if (c == 0x1b)
+ {
+ letter = 0;
+ return 0;
+ }
+
+ if (c == 0x1f)
+ {
+ letter = 1;
+ return 0;
+ }
+
+ int idx = 0;
+ while (baudot[idx].baudot != 0xff)
+ {
+ if (baudot[idx].baudot == c)
+ {
+ if (letter == 1)
+ return baudot[idx].letter;
+ else
+ return baudot[idx].number;
+ }
+ idx++;
+ }
+ return 0;
+}
+
+
+/*
+// ======================================================================================
+// Testfunctions: sends 010101.. in rtty speed and shows RX
+// 1. disable rtty_init()
+// 2. call testall() from hsmodem if speedmode==10
+
+
+void ttest();
+int rtest();
+void itest();
+
+
+void testall()
+{
+ static int f = 1;
+ if (f)
+ {
+ itest();
+ f = 0;
+ }
+
+ while (keeprunning)
+ {
+ ttest();
+ while(keeprunning && rtest());
+ sleep_ms(1);
+ }
+}
+
+void itest()
+{
+ M = 1 << m;
+ nstd = powf(10.0f, -SNRdB / 20.0f);
+
+ // create modulator/demodulator pair
+ modi = fskmod_create(m, k, bandwidth);
+ dem = fskdem_create(m, k, bandwidth);
+ fskdem_print(dem);
+
+ // create NCO for up-mixing to 1500 Hz
+ rtty_RADIANS_PER_SAMPLE = ((2.0f * (float)M_PI * (float)rtty_CENTERFREQUENCY) / (float)caprate);
rtty_upnco = nco_crcf_create(LIQUID_NCO);
nco_crcf_set_phase(rtty_upnco, 0.0f);
nco_crcf_set_frequency(rtty_upnco, rtty_RADIANS_PER_SAMPLE);
+ // create NCO for down-mixing from 1500 Hz
+ float rtty_RX_RADIANS_PER_SAMPLE = 2.0f * (float)M_PI * (float)rtty_CENTERFREQUENCY / (float)caprate;
rtty_dnnco = nco_crcf_create(LIQUID_NCO);
nco_crcf_set_phase(rtty_dnnco, 0.0f);
- nco_crcf_set_frequency(rtty_dnnco, rtty_RADIANS_PER_SAMPLE);
+ nco_crcf_set_frequency(rtty_dnnco, rtty_RX_RADIANS_PER_SAMPLE);
- rtty_decim = firdecim_crcf_create_kaiser(rtty_k_SampPerSymb, rtty_m_predec, rtty_As_predec);
- firdecim_crcf_set_scale(rtty_decim, 1.0f / (float)rtty_k_SampPerSymb);
+ // modulate, demodulate, count errors
+ unsigned int num_symbol_errors = 0;
}
-void close_rtty()
+void ttest()
{
- if (rtty_mod != NULL) fskmod_destroy(rtty_mod);
- rtty_mod = NULL;
- if (rtty_TX_interpolator != NULL) firinterp_crcf_destroy(rtty_TX_interpolator);
- rtty_TX_interpolator = NULL;
- if (rtty_upnco != NULL) nco_crcf_destroy(rtty_upnco);
- rtty_upnco = NULL;
- if (rtty_dnnco != NULL) nco_crcf_destroy(rtty_dnnco);
- rtty_dnnco = NULL;
- if (rtty_decim != NULL) firdecim_crcf_destroy(rtty_decim);
- rtty_decim = NULL;
- if (rtty_dem != NULL) fskdem_destroy(rtty_dem);
- rtty_dem = NULL;
-}
+ int i, j;
+ static unsigned int sym_in=0;
-char text[6] = {"ABCD\n"};
-int tidx = 0;
-int bitidx = 1;
+ int fs = io_pb_fifo_freespace(0);
+ if (fs < 20000) return;
-void rtty_tx()
-{
- if (rtty_mod == NULL)
- init_rtty();
-
- unsigned int sym = (text[tidx] & bitidx) ? 1 : 0;
- bitidx <<= 1;
- if (bitidx == 0x0100)
+ static int scnt = 0;
+ if (++scnt == 8)
{
- bitidx = 1;
- tidx++;
- if (tidx == 6) tidx = 0;
+ scnt = 0;
+ sym_in = 1 - sym_in;
}
+ //unsigned int sym_in = rand() % M;
- liquid_float_complex rtty_txbuf[33+1];
+ //measure_speed_bps(1);
- // gets one symbol at a speed of 45.45
- fskmod_modulate(rtty_mod, sym, rtty_txbuf);
- // here we have the complex RTTY signal in baseband
- // one symbol was expanded to rtty_k periods:
- // 45.454545 * 33 = 1500 periods
-
- for (unsigned int i = 0; i < rtty_k; i++)
+ //printf("modulate\n");
+ fskmod_modulate(modi, sym_in, &(buf_tx[0]));
+
+ // move sample to 1,5kHz carrier
+ for (j = 0; j < k; j++)
{
- // resample it to the soundcard rate caprate
- // interpolate by k_SampPerSymb
- liquid_float_complex y[40];
- if (rtty_k_SampPerSymb >= 40)
- {
- printf("y in k_SampPerSymb too small, need %d\n", rtty_k_SampPerSymb);
- return;
- }
+ nco_crcf_step(rtty_upnco);
+ nco_crcf_mix_up(rtty_upnco, buf_tx[j], &(buf_tx1500[j]));
- firinterp_crcf_execute(rtty_TX_interpolator, rtty_txbuf[i], y);
- // here we have rtty_k_SampPerSymb samples in y[] in the baseband at caprate
- // speed
-
- for (unsigned int i = 0; i < rtty_k_SampPerSymb; i++)
- {
- // move sample to 1,5kHz carrier
- nco_crcf_step(rtty_upnco);
+ usbf = (buf_tx1500[j]).real + (buf_tx1500[j]).imag;
- liquid_float_complex c;
- nco_crcf_mix_up(rtty_upnco, y[i], &c);
- float usb = c.real + c.imag;
+ //measure_speed_bps(1);
- // speed: 48000
- // adapt speed to soundcard samplerate
- int fs;
- while (1)
- {
- fs = io_pb_fifo_freespace(0);
- // wait until there is space in fifo
- if (fs > 20000) break;
- sleep_ms(10);
- }
-
- io_pb_write_fifo(usb * 0.2f); // reduce volume and send to soundcard
- }
+ io_pb_write_fifo(usbf * 0.2f); // reduce volume and send to soundcard
}
}
-// RTTY: sample rate HAS TO BE 48000
-int rtty_rx()
+int rtest()
{
- static liquid_float_complex ccol[500];
- static unsigned int ccol_idx = 0;
+ static int bridx = 0;
- if (rtty_dnnco == NULL) return 0;
-
- // get one received sample
+ int j;
float f;
int ret = io_cap_read_fifo(&f);
if (ret == 0) return 0;
- if (VoiceAudioMode == VOICEMODE_LISTENAUDIOIN)
- io_ls_write_fifo(f);
+ // noise
+ //printf("%f\n", f);
+ //f = f + nstd * randnf() * M_SQRT1_2;
- // input volume
- f *= softwareCAPvolume;
-
- //getMax(f);
- //make_FFTdata(f * 100);
-
- // downconvert 1,5kHz into baseband, still at soundcard sample rate
+ (buf_rx1500[bridx]).real = f;
+ (buf_rx1500[bridx]).imag = f;
nco_crcf_step(rtty_dnnco);
+ nco_crcf_mix_down(rtty_dnnco, buf_rx1500[bridx], &(buf_rx[bridx]));
+ bridx++;
- liquid_float_complex in;
- in.real = f;
- in.imag = f;
- liquid_float_complex c;
- nco_crcf_mix_down(rtty_dnnco, in, &c);
-
- // c is the actual sample, converted to complex and shifted to baseband
-
- // this is the first decimator. We need to collect rtty_k_SampPerSymb number of samples
- // then call execute which will give us one decimated sample
- ccol[ccol_idx++] = c;
- if (ccol_idx < rtty_k_SampPerSymb) return 1;
- ccol_idx = 0;
-
- // we have rtty_k_SampPerSymb samples in ccol
- liquid_float_complex y;
- firdecim_crcf_execute(rtty_decim, ccol, &y);
- // the output of the pre decimator is exactly one sample in y
- // ready for demodulation
- // here we have 1500 samples/s
- // collect rtty_k (33) samples then demodulate, 1500/33 = 45.45
- static unsigned int cs = 0;
- static liquid_float_complex camps[rtty_k];
- camps[cs] = y;
- if (++cs < rtty_k) return 1;
- cs = 0;
-
- //measure_speed_bps(1);
-
- unsigned int sym_out = fskdem_demodulate(rtty_dem, camps);
-
- static int sym = 0;
- static int symidx = 0;
- sym |= sym_out << symidx;
- symidx++;
- if (symidx == 8)
+ if (bridx == k)
{
- symidx = 0;
- printf("%d: %c\n", sym, sym);
- sym = 0;
+ bridx = 0;
+
+ sym_out = fskdem_demodulate(dem, buf_rx);
+
+ static int nlixd = 0;
+
+ //measure_speed_bps(1);
+
+ printf("%01X ", sym_out);
+ if (++nlixd == 16)
+ {
+ nlixd = 0;
+ printf("\n");
+ }
}
+
return 1;
}
+*/
+// ==========================================================================
+
+#ifdef _LINUX_
+void* rtty_tx_function(void* param);
+void* rtty_rx_function(void* param);
+#endif
+
+#ifdef _WIN32_
+void rtty_tx_function(void* param);
+void rtty_rx_function(void* param);
+#endif
+
+void init_rtty()
+{
+ //printf("wegen FM test, kein Init RTTY\n");
+ //return;
+
+ close_rtty();
+
+ printf("Init RTTY\n");
+ nstd = powf(10.0f, -SNRdB / 20.0f); // SNR Simulation referenced to -1..+1
+
+ // create modulator/demodulator pair
+ modi = fskmod_create(m, k, bandwidth);
+ dem = fskdem_create(m, k, bandwidth);
+
+ // create NCO for up-mixing to 1500 Hz
+ rtty_RADIANS_PER_SAMPLE = ((2.0f * (float)M_PI * (float)rtty_CENTERFREQUENCY) / (float)caprate);
+ rtty_upnco = nco_crcf_create(LIQUID_NCO);
+ nco_crcf_set_phase(rtty_upnco, 0.0f);
+ nco_crcf_set_frequency(rtty_upnco, rtty_RADIANS_PER_SAMPLE);
+
+ // create NCO for down-mixing from 1500 Hz
+ rtty_RX_RADIANS_PER_SAMPLE = 2.0f * (float)M_PI * (float)rtty_CENTERFREQUENCY / (float)caprate;
+ rtty_dnnco = nco_crcf_create(LIQUID_NCO);
+ nco_crcf_set_phase(rtty_dnnco, 0.0f);
+ nco_crcf_set_frequency(rtty_dnnco, rtty_RX_RADIANS_PER_SAMPLE);
+
+ // RTTY RX Filter
+ rtty_q = firfilt_crcf_create_kaiser(flt_h_len, flt_fc, flt_As, 0.0f);
+ firfilt_crcf_set_scale(rtty_q, 2.0f * flt_fc);
+
+ // create the rtty TX threads
+ static int f = 1;
+ if (f)
+ {
+ f = 0;
+
+#ifdef _LINUX_
+ pthread_t rtty_txthread;
+ pthread_create(&rtty_txthread, NULL, rtty_tx_function, NULL);
+ pthread_t rtty_rxthread;
+ pthread_create(&rtty_rxthread, NULL, rtty_rx_function, NULL);
+#endif
+#ifdef _WIN32_
+ _beginthread(rtty_tx_function, 0, NULL);
+ _beginthread(rtty_rx_function, 0, NULL);
+#endif
+ }
+
+ run_rtty_threads = 1;
+}
+
+void close_rtty()
+{
+ printf("Close RTTY\n");
+
+ run_rtty_threads = 0;
+ sleep_ms(100);
+
+ if (modi != NULL) fskmod_destroy(modi);
+ modi = NULL;
+
+ if (dem != NULL) fskdem_destroy(dem);
+ dem = NULL;
+
+ if (rtty_upnco != NULL) nco_crcf_destroy(rtty_upnco);
+ rtty_upnco = NULL;
+
+ if (rtty_dnnco != NULL) nco_crcf_destroy(rtty_dnnco);
+ rtty_dnnco = NULL;
+
+ if (rtty_q != NULL) firfilt_crcf_destroy(rtty_q);
+ rtty_q = NULL;
+}
+
+// RTTY TX thread
+#ifdef _LINUX_
+void* rtty_tx_function(void* param)
+{
+ pthread_detach(pthread_self());
+#endif
+#ifdef _WIN32_
+void rtty_tx_function(void* param)
+{
+#endif
+
+ uint8_t bd[2];
+ int anz = 0;
+
+ while (keeprunning)
+ {
+ while (run_rtty_threads == 0)
+ {
+ sleep_ms(100);
+ if (keeprunning == 0)
+ {
+#ifdef _LINUX_
+ pthread_exit(NULL); // self terminate this thread
+ return NULL;
+#endif
+#ifdef _WIN32_
+ return;
+#endif
+ }
+ }
+
+ /*static int last_txoff = -2;
+ if (last_txoff != 0 && rtty_txoff == 0)
+ {
+ // just switched TX on
+ //printf("force Bu/Zi switch: %d %d\n", rtty_txoff, last_txoff);
+ isletters = isletters ? 0 : 1; // force Bu/Zi command
+ }
+ last_txoff = rtty_txoff;*/
+
+ char csend;
+ if (rtty_tx_read_fifo(&csend))
+ {
+ baudot_encoder(csend, bd, &anz);
+ //printf("read fifo: %d -> %02X\n", csend, bd[0]);
+ }
+ else
+ {
+ bd[0] = 0x1f; // idle
+ anz = 1;
+
+ if (rtty_txoff == 1)
+ {
+ sleep_ms(10);
+ continue;
+ }
+
+ if (rtty_txoff > 1) rtty_txoff--;
+ }
+
+ //if(bd[0] != 0x1f) printf("send chars: %02X\n",bd[0]);
+
+ for (int i = 0; i < anz; i++)
+ {
+ char c = bd[i];
+ // c is the baudot code, fill into final byte cs
+ uint8_t cs = 0;
+ cs |= ((c & 1) ? 0x40 : 0);
+ cs |= ((c & 2) ? 0x20 : 0);
+ cs |= ((c & 4) ? 0x10 : 0);
+ cs |= ((c & 8) ? 0x08 : 0);
+ cs |= ((c & 16) ? 0x04 : 0);
+ cs &= ~0x80; // Start bit to 1
+ cs |= 3; // 2 stop bits
+
+ // send cs bit per bit
+ for (int bitidx = 7; bitidx >= 0; bitidx--)
+ {
+ if (run_rtty_threads == 0) break;
+
+ //measure_speed_bps(1);
+
+ unsigned int sym_in = (cs & (1 << bitidx)) ? 1 : 0;
+
+ for (int twice = 0; twice < 4; twice++)
+ {
+ if (bitidx == 0 && twice == 2) break; //last bit only once
+
+ fskmod_modulate(modi, sym_in, &(buf_tx[0]));
+
+ // move sample to 1,5kHz carrier
+ for (int j = 0; j < k; j++)
+ {
+ nco_crcf_step(rtty_upnco);
+ liquid_float_complex outb;
+ nco_crcf_mix_up(rtty_upnco, buf_tx[j], &outb);
+
+ float usbf = outb.real + outb.imag;
+
+ // adapt to audio sample rate
+ int fs;
+ while (keeprunning && run_rtty_threads)
+ {
+ fs = io_pb_fifo_usedspace();
+ //printf("%d\n", fs);
+ // attention: if this number is too low, the audio write callback will not process it
+ if (fs < 24000) break;
+ sleep_ms(1);
+ }
+
+ io_pb_write_fifo(usbf * 0.05f); // reduce volume and send to soundcard
+ }
+ }
+ }
+ }
+ }
+#ifdef _LINUX_
+ pthread_exit(NULL); // self terminate this thread
+ return NULL;
+#endif
+}
+
+// RTTY RX thread
+#ifdef _LINUX_
+void* rtty_rx_function(void* param)
+{
+pthread_detach(pthread_self());
+#endif
+#ifdef _WIN32_
+void rtty_rx_function(void* param)
+{
+#endif
+
+ while (keeprunning)
+ {
+ while (run_rtty_threads == 0)
+ {
+ sleep_ms(100);
+ if (keeprunning == 0)
+ {
+#ifdef _LINUX_
+ pthread_exit(NULL); // self terminate this thread
+ return NULL;
+#endif
+#ifdef _WIN32_
+ return;
+#endif
+ }
+ }
+
+ static int bridx = 0;
+ float f;
+ int ret = io_cap_read_fifo(&f);
+ if (ret)
+ {
+ if (VoiceAudioMode == VOICEMODE_LISTENAUDIOIN)
+ io_ls_write_fifo(f);
+
+ // input volume
+ f *= softwareCAPvolume;
+
+ // TODO check Multithreading !!!!!!!!!
+ getMax(f);
+ make_FFTdata(f * 25);
+
+ static float last_rs = 0;
+ if (rtty_RX_RADIANS_PER_SAMPLE != last_rs)
+ {
+ // tuning freq was changed, set NCO
+ nco_crcf_set_frequency(rtty_dnnco, rtty_RX_RADIANS_PER_SAMPLE);
+ last_rs = rtty_RX_RADIANS_PER_SAMPLE;
+ }
+
+ liquid_float_complex rx1500;
+ rx1500.real = f;
+ rx1500.imag = f;
+ nco_crcf_step(rtty_dnnco);
+ liquid_float_complex dc_out;
+ nco_crcf_mix_down(rtty_dnnco, rx1500, &dc_out);
+
+ // sharp filter
+ firfilt_crcf_push(rtty_q, dc_out); // push input sample
+ firfilt_crcf_execute(rtty_q, &(buf_rx[bridx])); // compute output
+
+ bridx++;
+
+ if (bridx == k)
+ {
+ bridx = 0;
+
+ sym_out = fskdem_demodulate(dem, buf_rx);
+
+ int db = evalSymbols(sym_out);
+ if (db != -1)
+ {
+ char lt = baudot_decoder((uint8_t)db);
+ //printf("rxbyte:%02X deoced:%02X\n", db, lt);
+ if (lt > 0)
+ sendRttyToGUI(lt);
+ }
+ }
+ }
+ else
+ sleep_ms(1);
+ }
+
+#ifdef _LINUX_
+ pthread_exit(NULL); // self terminate this thread
+ return NULL;
+#endif
+}
+
+
+// get the bit level,
+// offs ... offset from beginning of the symbol buffer in bits,
+// so offset 0 ist the beginning
+// and offset 1 is the "overs" bit, i.e.: symbol[4]
+// this eliminates the need of thinking in oversampled bits
+
+const int maxsym = 8; // stop-start-1-2-3-4-5-stop
+const int overs = 4; // symbols per bit
+uint8_t symbuf[maxsym * overs];
+int bitcnt = 0;
+
+uint8_t getBit(int offs)
+{
+ // we have overs symbols per bit
+ // the first or maybe last symbol may be wrong, so we don't use it
+ // looks like that ignoring the first sample is the best solution
+ // lets evaluate the value of three symbols
+ int pos = offs * overs;
+ uint8_t h = 0, l = 0;
+ for (int i = 0+1; i < overs - 1+1; i++)
+ {
+ if (symbuf[pos + i]) h++;
+ else l++;
+ }
+
+ return (h > l) ? 1 : 0;
+}
+
+uint8_t getDatebyte()
+{
+ uint8_t db = 0;
+
+ db |= getBit(2) ? 0x01 : 0;
+ db |= getBit(3) ? 0x02 : 0;
+ db |= getBit(4) ? 0x04 : 0;
+ db |= getBit(5) ? 0x08 : 0;
+ db |= getBit(6) ? 0x10 : 0;
+
+ return db;
+}
+
+// check if there is a complete frame in the symbol buffer
+int findStart()
+{
+ if ((synced == 0 || bitcnt > overs * 6) && symbuf[3] == 1 && symbuf[4] == 0)
+ {
+ if (getBit(0) == 1 && getBit(1) == 0 && getBit(7) == 1)
+ {
+ //printf("possible Frame Detection at index:%d\n", bitcnt);
+ bitcnt = 0;
+ synced = 1;
+ return getDatebyte();
+ }
+ else
+ synced = 0;
+ }
+ bitcnt++;
+
+ return -1;
+}
+
+int evalSymbols(uint8_t sym)
+{
+ // feed smbol in buffer
+ memmove(symbuf, symbuf + 1, maxsym * overs - 1);
+ symbuf[maxsym * overs - 1] = sym;
+
+ //showbitstring("rx: ", symbuf, sizeof(symbuf), sizeof(symbuf));
+
+ int db = findStart();
+ if (db != -1)
+ {
+ //printf("Data_ %02X\n", db);
+ }
+ return db;
+}
diff --git a/hsmodem/soundio.cpp b/hsmodem/soundio.cpp
index c3839a0..c44d5aa 100755
--- a/hsmodem/soundio.cpp
+++ b/hsmodem/soundio.cpp
@@ -36,7 +36,7 @@ struct SoundIoDevice* io_cap_device = NULL;
struct SoundIoInStream* instream = NULL;
struct SoundIoOutStream* outstream = NULL;
-float latenz = 0.1f;
+float latenz = 0.1f; // long (some seconds) delay can be caused by SDR console (not this program and not the VAC)
typedef struct _AUDIODEV_ {
@@ -83,6 +83,7 @@ static void get_channel_layout(const struct SoundIoChannelLayout* layout)
int print_device(struct SoundIoDevice* device)
{
+ if (soundio == NULL) return 0;
if (!device->probe_error)
{
// ignore if exists
@@ -119,6 +120,7 @@ int print_device(struct SoundIoDevice* device)
static int scan_devices(struct SoundIo* soundio)
{
+ if (soundio == NULL) return 0;
audiodevidx = 0;
for (int i = 0; i < soundio_input_device_count(soundio); i++)
{
@@ -224,14 +226,14 @@ int min_int(int a, int b)
void read_callback(struct SoundIoInStream* instream, int frame_count_min, int frame_count_max)
{
int err;
- if (instream == NULL) return;
+ if (instream == NULL || soundio == NULL) return;
//printf("cap: %d %d\n", frame_count_min, frame_count_max);
//int chans = instream->layout.channel_count;
struct SoundIoChannelArea* areas;
// samples are in areas.ptr
int frames_left = frame_count_max; // take all
- while (1)
+ while (keeprunning)
{
int frame_count = frames_left;
if ((err = soundio_instream_begin_read(instream, &areas, &frame_count)))
@@ -340,6 +342,7 @@ static double seconds_offset = 0.0;
static void write_callback(struct SoundIoOutStream* outstream, int frame_count_min, int frame_count_max)
{
+ if(outstream == NULL || soundio == NULL) return;
//printf("pb: %d %d\n", frame_count_min, frame_count_max);
#ifdef SINEWAVETEST
double float_sample_rate = outstream->sample_rate;
@@ -431,7 +434,7 @@ int io_init_sound(char *pbname, char *capname)
init_audio_result = 0;
printf("\n ==== IO INIT AUDIO devices ====\n");
- printf("requested\nTX:<%s>\nRX:<%s>\ncapture rate:%d\n\n",pbname,capname,caprate);
+ //printf("requested\nTX:<%s>\nRX:<%s>\ncapture rate:%d\n\n",pbname,capname,caprate);
io_close_audio();
diff --git a/hsmodem/symboltracker.cpp b/hsmodem/symboltracker.cpp
index 41bd425..8e0b375 100755
--- a/hsmodem/symboltracker.cpp
+++ b/hsmodem/symboltracker.cpp
@@ -1,7 +1,6 @@
#include "hsmodem.h"
-SYMTRACK km_symtrack;
-SYMTRACK* q = &km_symtrack;
+
// create km_symtrack object with basic parameters
// _ftype : filter type (e.g. LIQUID_FIRFILT_RRC)
@@ -9,7 +8,7 @@ SYMTRACK* q = &km_symtrack;
// _m : filter delay (symbols)
// _beta : filter excess bandwidth
// _ms : modulation scheme (e.g. LIQUID_MODEM_QPSK)
-void km_symtrack_cccf_create(int _ftype,
+SYMTRACK* km_symtrack_cccf_create(int _ftype,
unsigned int _k,
unsigned int _m,
float _beta,
@@ -17,7 +16,7 @@ void km_symtrack_cccf_create(int _ftype,
{
// validate input
if (_k < 2)
- printf((char *)"symtrack_cccf_create(), filter samples/symbol must be at least 2\n");
+ printf((char*)"symtrack_cccf_create(), filter samples/symbol must be at least 2\n");
if (_m == 0)
printf((char*)"symtrack_cccf_create(), filter delay must be greater than zero\n");
if (_beta <= 0.0f || _beta > 1.0f)
@@ -25,6 +24,9 @@ void km_symtrack_cccf_create(int _ftype,
if (_ms == LIQUID_MODEM_UNKNOWN || _ms >= LIQUID_MODEM_NUM_SCHEMES)
printf((char*)"symtrack_cccf_create(), invalid modulation scheme\n");
+ // allocate memory for main object
+ SYMTRACK *q = (SYMTRACK *) malloc(sizeof(SYMTRACK));
+
// set input parameters
q->filter_type = _ftype;
q->k = _k;
@@ -54,14 +56,33 @@ void km_symtrack_cccf_create(int _ftype,
q->demod = modem_create((modulation_scheme)q->mod_scheme);
// set default bandwidth
- km_symtrack_cccf_set_bandwidth(0.9f);
+ km_symtrack_cccf_set_bandwidth(q, 0.9f);
// reset and return main object
- km_symtrack_cccf_reset(0xff);
+ km_symtrack_cccf_reset(q, 0xff);
+
+ return q;
}
-void km_symtrack_cccf_reset(int mode)
+void km_symtrack_cccf_destroy(SYMTRACK *_q)
{
+ if (_q == NULL) return;
+
+ // destroy objects
+ agc_crcf_destroy(_q->agc);
+ symsync_crcf_destroy(_q->symsync);
+ eqlms_cccf_destroy(_q->eq);
+ nco_crcf_destroy(_q->nco);
+ modem_destroy(_q->demod);
+
+ // free main object
+ free(_q);
+}
+
+void km_symtrack_cccf_reset(SYMTRACK* q, int mode)
+{
+ if (q == NULL) return;
+
// reset objects
if (mode & 1) agc_crcf_reset(q->agc);
if (mode & 2) symsync_crcf_reset(q->symsync);
@@ -74,7 +95,7 @@ void km_symtrack_cccf_reset(int mode)
q->num_syms_rx = 0;
}
-void km_symtrack_cccf_set_bandwidth(float _bw)
+void km_symtrack_cccf_set_bandwidth(SYMTRACK *q, float _bw)
{
// validate input
if (_bw < 0)
@@ -106,8 +127,10 @@ void km_symtrack_cccf_set_bandwidth(float _bw)
// _x : input data sample
// _y : output data array
// _ny : number of samples written to output buffer
-void km_symtrack_execute(liquid_float_complex _x, liquid_float_complex* _y, unsigned int* _ny, unsigned int *psym_out)
+void km_symtrack_execute(SYMTRACK* q, liquid_float_complex _x, liquid_float_complex* _y, unsigned int* _ny, unsigned int *psym_out)
{
+ if (q == NULL) return;
+
liquid_float_complex v; // output sample
unsigned int i;
unsigned int num_outputs = 0;
diff --git a/hsmodem/tuning.cpp b/hsmodem/tuning.cpp
index 5580d31..090b1a0 100755
--- a/hsmodem/tuning.cpp
+++ b/hsmodem/tuning.cpp
@@ -79,7 +79,7 @@ float do_tuning(int send)
// adapt speed to soundcard samplerate
int fs;
- while (1)
+ while (keeprunning)
{
fs = io_pb_fifo_freespace(0);
// wait until there is space in fifo
diff --git a/hsmodem/voiceio.cpp b/hsmodem/voiceio.cpp
index 268d388..f02f28a 100755
--- a/hsmodem/voiceio.cpp
+++ b/hsmodem/voiceio.cpp
@@ -46,7 +46,7 @@ void read_voicecallback(struct SoundIoInStream* instream, int frame_count_min, i
struct SoundIoChannelArea* areas;
// samples are in areas.ptr
int frames_left = frame_count_max; // take all
- while (1)
+ while (keeprunning)
{
int frame_count = frames_left;
if ((err = soundio_instream_begin_read(instream, &areas, &frame_count)))
diff --git a/hsmodem/voiceprocessor.cpp b/hsmodem/voiceprocessor.cpp
index a0406c0..763df73 100755
--- a/hsmodem/voiceprocessor.cpp
+++ b/hsmodem/voiceprocessor.cpp
@@ -168,7 +168,7 @@ void sendCodecToModulator(uint8_t *pdata, int len)
toGR_sendData(payload, 6, 1 ,0); // 6 ... voice data, 1 ... valid voice data
}
- while (1)
+ while (keeprunning)
{
// we have to check if the TX fifo has enough data. In case of an underrun the Q(8A)PSK signal will be distorted
int us = io_pb_fifo_usedspace();
diff --git a/hsmodemLinux/audio/announcement.pcm b/hsmodemLinux/audio/announcement.pcm
deleted file mode 100644
index 84d6293..0000000
Binary files a/hsmodemLinux/audio/announcement.pcm and /dev/null differ
diff --git a/hsmodemLinux/hsmodem b/hsmodemLinux/hsmodem
index c1ed2a1..30eddd7 100755
Binary files a/hsmodemLinux/hsmodem and b/hsmodemLinux/hsmodem differ
diff --git a/hsmodemLinux/oscardata.exe b/hsmodemLinux/oscardata.exe
index 2568aac..a83dfd7 100755
Binary files a/hsmodemLinux/oscardata.exe and b/hsmodemLinux/oscardata.exe differ
diff --git a/oscardata/oscardata/Form1.Designer.cs b/oscardata/oscardata/Form1.Designer.cs
index 3747193..d05166b 100755
--- a/oscardata/oscardata/Form1.Designer.cs
+++ b/oscardata/oscardata/Form1.Designer.cs
@@ -43,10 +43,10 @@
this.tabPage_ber = new System.Windows.Forms.TabPage();
this.bt_allf = new System.Windows.Forms.Button();
this.lb_tuningqrgs = new System.Windows.Forms.Label();
+ this.rtb = new System.Windows.Forms.RichTextBox();
this.button_stopBERtest = new System.Windows.Forms.Button();
this.imageList1 = new System.Windows.Forms.ImageList(this.components);
this.button_startBERtest = new System.Windows.Forms.Button();
- this.rtb = new System.Windows.Forms.RichTextBox();
this.tabPage_image = new System.Windows.Forms.TabPage();
this.groupBox1 = new System.Windows.Forms.Panel();
this.cb_loop = new System.Windows.Forms.CheckBox();
@@ -97,7 +97,46 @@
this.label10 = new System.Windows.Forms.Label();
this.cb_mic = new System.Windows.Forms.ComboBox();
this.label11 = new System.Windows.Forms.Label();
+ this.tabPage_rtty = new System.Windows.Forms.TabPage();
+ this.label4 = new System.Windows.Forms.Label();
+ this.label3 = new System.Windows.Forms.Label();
+ this.tb_rtty_TX = new System.Windows.Forms.TextBox();
+ this.tb_rtty_RX = new System.Windows.Forms.TextBox();
+ this.panel1 = new System.Windows.Forms.Panel();
+ this.rb_rtty_real = new System.Windows.Forms.RadioButton();
+ this.bt_rtty_text6 = new System.Windows.Forms.Button();
+ this.bt_rtty_text5 = new System.Windows.Forms.Button();
+ this.bt_rtty_text4 = new System.Windows.Forms.Button();
+ this.bt_rtty_text3 = new System.Windows.Forms.Button();
+ this.bt_rtty_text2 = new System.Windows.Forms.Button();
+ this.bt_rtty_text1 = new System.Windows.Forms.Button();
+ this.button5 = new System.Windows.Forms.Button();
+ this.bt_rtty_RY = new System.Windows.Forms.Button();
+ this.textBox2 = new System.Windows.Forms.TextBox();
+ this.button4 = new System.Windows.Forms.Button();
+ this.bt_rtty_cq = new System.Windows.Forms.Button();
+ this.bt_rxfont = new System.Windows.Forms.Button();
+ this.bt_rtty_answerCQ = new System.Windows.Forms.Button();
+ this.button3 = new System.Windows.Forms.Button();
+ this.bt_rtty_start = new System.Windows.Forms.Button();
+ this.button1 = new System.Windows.Forms.Button();
+ this.bt_rtty_end = new System.Windows.Forms.Button();
+ this.textBox5 = new System.Windows.Forms.TextBox();
+ this.bt_rtty_endqso = new System.Windows.Forms.Button();
+ this.rb_rtty_edit = new System.Windows.Forms.RadioButton();
+ this.bt_rtty_myinfo = new System.Windows.Forms.Button();
+ this.rb_rtty_normal = new System.Windows.Forms.RadioButton();
+ this.bt_rtty_station = new System.Windows.Forms.Button();
+ this.bt_rtty_default = new System.Windows.Forms.Button();
+ this.bt_rtty_tx = new System.Windows.Forms.Button();
+ this.label_urname = new System.Windows.Forms.Label();
+ this.tb_rtty_deftext = new System.Windows.Forms.TextBox();
+ this.tb_urname = new System.Windows.Forms.TextBox();
+ this.tb_urcall = new System.Windows.Forms.TextBox();
+ this.label_urcall = new System.Windows.Forms.Label();
this.tabPage_setup = new System.Windows.Forms.TabPage();
+ this.label_cfgpath = new System.Windows.Forms.Label();
+ this.label_cfgpath_tit = new System.Windows.Forms.Label();
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.label13 = new System.Windows.Forms.Label();
this.label12 = new System.Windows.Forms.Label();
@@ -123,6 +162,12 @@
this.cb_audioPB = new System.Windows.Forms.ComboBox();
this.cb_audioCAP = new System.Windows.Forms.ComboBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
+ this.tb_myqthloc = new System.Windows.Forms.TextBox();
+ this.label14 = new System.Windows.Forms.Label();
+ this.tb_myqth = new System.Windows.Forms.TextBox();
+ this.lb_qth = new System.Windows.Forms.Label();
+ this.tb_myname = new System.Windows.Forms.TextBox();
+ this.lb_myname = new System.Windows.Forms.Label();
this.lb_rec = new System.Windows.Forms.Label();
this.tb_recintro = new System.Windows.Forms.TextBox();
this.bt_astop = new System.Windows.Forms.Button();
@@ -144,14 +189,16 @@
this.label_speed = new System.Windows.Forms.Label();
this.timer_searchmodem = new System.Windows.Forms.Timer(this.components);
this.label_fifo = new System.Windows.Forms.Label();
- this.bt_blockinfo = new System.Windows.Forms.Button();
this.label_capfifo = new System.Windows.Forms.Label();
this.lb_rxsignal = new System.Windows.Forms.Label();
this.lb_rxsync = new System.Windows.Forms.Label();
- this.pb_rxsync = new System.Windows.Forms.PictureBox();
+ this.pn1 = new System.Windows.Forms.Panel();
this.pb_rxsignal = new System.Windows.Forms.PictureBox();
- this.progressBar_capfifo = new oscardata.KmProgressBar();
+ this.pb_rxsync = new System.Windows.Forms.PictureBox();
+ this.cb_rx_autosync = new System.Windows.Forms.CheckBox();
+ this.textBox6 = new System.Windows.Forms.TextBox();
this.progressBar_fifo = new oscardata.KmProgressBar();
+ this.progressBar_capfifo = new oscardata.KmProgressBar();
this.vu_cap = new oscardata.KmProgressBar();
this.vu_pb = new oscardata.KmProgressBar();
this.statusStrip1.SuspendLayout();
@@ -173,6 +220,8 @@
((System.ComponentModel.ISupportInitialize)(this.pb_voicePBstatus)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.tb_mic)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.tb_loadspeaker)).BeginInit();
+ this.tabPage_rtty.SuspendLayout();
+ this.panel1.SuspendLayout();
this.tabPage_setup.SuspendLayout();
this.groupBox4.SuspendLayout();
this.groupBox3.SuspendLayout();
@@ -184,8 +233,9 @@
((System.ComponentModel.ISupportInitialize)(this.tb_PBvol)).BeginInit();
this.groupBox2.SuspendLayout();
this.tabPage_about.SuspendLayout();
- ((System.ComponentModel.ISupportInitialize)(this.pb_rxsync)).BeginInit();
+ this.pn1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.pb_rxsignal)).BeginInit();
+ ((System.ComponentModel.ISupportInitialize)(this.pb_rxsync)).BeginInit();
this.SuspendLayout();
//
// timer_udpTX
@@ -204,9 +254,9 @@
this.toolStripStatusLabel,
this.ts_ip,
this.RXstatus});
- this.statusStrip1.Location = new System.Drawing.Point(0, 669);
+ this.statusStrip1.Location = new System.Drawing.Point(0, 671);
this.statusStrip1.Name = "statusStrip1";
- this.statusStrip1.Size = new System.Drawing.Size(1293, 22);
+ this.statusStrip1.Size = new System.Drawing.Size(1296, 22);
this.statusStrip1.TabIndex = 4;
this.statusStrip1.Text = "statusStrip1";
//
@@ -259,15 +309,16 @@
this.panel_txspectrum.Size = new System.Drawing.Size(442, 76);
this.panel_txspectrum.TabIndex = 6;
this.panel_txspectrum.Paint += new System.Windows.Forms.PaintEventHandler(this.panel_txspectrum_Paint);
+ this.panel_txspectrum.DoubleClick += new System.EventHandler(this.panel_txspectrum_DoubleClick);
//
// tabPage_ber
//
this.tabPage_ber.BackColor = System.Drawing.Color.Transparent;
this.tabPage_ber.Controls.Add(this.bt_allf);
this.tabPage_ber.Controls.Add(this.lb_tuningqrgs);
+ this.tabPage_ber.Controls.Add(this.rtb);
this.tabPage_ber.Controls.Add(this.button_stopBERtest);
this.tabPage_ber.Controls.Add(this.button_startBERtest);
- this.tabPage_ber.Controls.Add(this.rtb);
this.tabPage_ber.ImageIndex = 4;
this.tabPage_ber.Location = new System.Drawing.Point(4, 23);
this.tabPage_ber.Name = "tabPage_ber";
@@ -296,6 +347,15 @@
this.lb_tuningqrgs.TabIndex = 21;
this.lb_tuningqrgs.Text = "Frequency Test:";
//
+ // rtb
+ //
+ this.rtb.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.rtb.Location = new System.Drawing.Point(6, 51);
+ this.rtb.Name = "rtb";
+ this.rtb.Size = new System.Drawing.Size(1266, 494);
+ this.rtb.TabIndex = 0;
+ this.rtb.Text = "";
+ //
// button_stopBERtest
//
this.button_stopBERtest.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
@@ -327,6 +387,16 @@
this.imageList1.Images.SetKeyName(10, "transmit.png");
this.imageList1.Images.SetKeyName(11, "voice.png");
this.imageList1.Images.SetKeyName(12, "about.png");
+ this.imageList1.Images.SetKeyName(13, "rtty.png");
+ this.imageList1.Images.SetKeyName(14, "home-icon.png");
+ this.imageList1.Images.SetKeyName(15, "ryry-icon.png");
+ this.imageList1.Images.SetKeyName(16, "voice-icon.png");
+ this.imageList1.Images.SetKeyName(17, "user-icon.png");
+ this.imageList1.Images.SetKeyName(18, "answer.png");
+ this.imageList1.Images.SetKeyName(19, "stop-icon.png");
+ this.imageList1.Images.SetKeyName(20, "start-icon.png");
+ this.imageList1.Images.SetKeyName(21, "endqso-icon.png");
+ this.imageList1.Images.SetKeyName(22, "text-icon.png");
//
// button_startBERtest
//
@@ -342,15 +412,6 @@
this.button_startBERtest.UseVisualStyleBackColor = true;
this.button_startBERtest.Click += new System.EventHandler(this.button_startBERtest_Click);
//
- // rtb
- //
- this.rtb.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.rtb.Location = new System.Drawing.Point(6, 51);
- this.rtb.Name = "rtb";
- this.rtb.Size = new System.Drawing.Size(1266, 494);
- this.rtb.TabIndex = 0;
- this.rtb.Text = "";
- //
// tabPage_image
//
this.tabPage_image.BackColor = System.Drawing.Color.Transparent;
@@ -531,6 +592,7 @@
this.tabControl1.Controls.Add(this.tabPage_file);
this.tabControl1.Controls.Add(this.tabPage_audio);
this.tabControl1.Controls.Add(this.tabPage_ber);
+ this.tabControl1.Controls.Add(this.tabPage_rtty);
this.tabControl1.Controls.Add(this.tabPage_setup);
this.tabControl1.Controls.Add(this.tabPage_about);
this.tabControl1.ImageList = this.imageList1;
@@ -948,9 +1010,490 @@
this.label11.TabIndex = 10;
this.label11.Text = "Microphone:";
//
+ // tabPage_rtty
+ //
+ this.tabPage_rtty.Controls.Add(this.label4);
+ this.tabPage_rtty.Controls.Add(this.label3);
+ this.tabPage_rtty.Controls.Add(this.tb_rtty_TX);
+ this.tabPage_rtty.Controls.Add(this.tb_rtty_RX);
+ this.tabPage_rtty.Controls.Add(this.panel1);
+ this.tabPage_rtty.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.tabPage_rtty.ImageIndex = 13;
+ this.tabPage_rtty.Location = new System.Drawing.Point(4, 23);
+ this.tabPage_rtty.Name = "tabPage_rtty";
+ this.tabPage_rtty.Size = new System.Drawing.Size(1280, 552);
+ this.tabPage_rtty.TabIndex = 7;
+ this.tabPage_rtty.Text = "RTTY";
+ this.tabPage_rtty.UseVisualStyleBackColor = true;
+ //
+ // label4
+ //
+ this.label4.AutoSize = true;
+ this.label4.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label4.Location = new System.Drawing.Point(13, 393);
+ this.label4.Name = "label4";
+ this.label4.Size = new System.Drawing.Size(29, 20);
+ this.label4.TabIndex = 32;
+ this.label4.Text = "TX";
+ //
+ // label3
+ //
+ this.label3.AutoSize = true;
+ this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.label3.Location = new System.Drawing.Point(13, 13);
+ this.label3.Name = "label3";
+ this.label3.Size = new System.Drawing.Size(32, 20);
+ this.label3.TabIndex = 26;
+ this.label3.Text = "RX";
+ //
+ // tb_rtty_TX
+ //
+ this.tb_rtty_TX.BackColor = System.Drawing.Color.AliceBlue;
+ this.tb_rtty_TX.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.tb_rtty_TX.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
+ this.tb_rtty_TX.Font = new System.Drawing.Font("Courier New", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.tb_rtty_TX.Location = new System.Drawing.Point(9, 416);
+ this.tb_rtty_TX.Multiline = true;
+ this.tb_rtty_TX.Name = "tb_rtty_TX";
+ this.tb_rtty_TX.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.tb_rtty_TX.Size = new System.Drawing.Size(675, 103);
+ this.tb_rtty_TX.TabIndex = 1;
+ this.tb_rtty_TX.TextChanged += new System.EventHandler(this.tb_rtty_TX_TextChanged);
+ this.tb_rtty_TX.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tb_rtty_TX_KeyDown);
+ //
+ // tb_rtty_RX
+ //
+ this.tb_rtty_RX.BackColor = System.Drawing.Color.Cornsilk;
+ this.tb_rtty_RX.BorderStyle = System.Windows.Forms.BorderStyle.None;
+ this.tb_rtty_RX.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
+ this.tb_rtty_RX.Font = new System.Drawing.Font("Courier New", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.tb_rtty_RX.Location = new System.Drawing.Point(9, 35);
+ this.tb_rtty_RX.Multiline = true;
+ this.tb_rtty_RX.Name = "tb_rtty_RX";
+ this.tb_rtty_RX.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+ this.tb_rtty_RX.Size = new System.Drawing.Size(675, 348);
+ this.tb_rtty_RX.TabIndex = 2;
+ this.tb_rtty_RX.MouseDown += new System.Windows.Forms.MouseEventHandler(this.tb_rtty_RX_MouseDown);
+ //
+ // panel1
+ //
+ this.panel1.BackColor = System.Drawing.Color.Transparent;
+ this.panel1.Controls.Add(this.textBox6);
+ this.panel1.Controls.Add(this.cb_rx_autosync);
+ this.panel1.Controls.Add(this.rb_rtty_real);
+ this.panel1.Controls.Add(this.bt_rtty_text6);
+ this.panel1.Controls.Add(this.bt_rtty_text5);
+ this.panel1.Controls.Add(this.bt_rtty_text4);
+ this.panel1.Controls.Add(this.bt_rtty_text3);
+ this.panel1.Controls.Add(this.bt_rtty_text2);
+ this.panel1.Controls.Add(this.bt_rtty_text1);
+ this.panel1.Controls.Add(this.button5);
+ this.panel1.Controls.Add(this.bt_rtty_RY);
+ this.panel1.Controls.Add(this.textBox2);
+ this.panel1.Controls.Add(this.button4);
+ this.panel1.Controls.Add(this.bt_rtty_cq);
+ this.panel1.Controls.Add(this.bt_rxfont);
+ this.panel1.Controls.Add(this.bt_rtty_answerCQ);
+ this.panel1.Controls.Add(this.button3);
+ this.panel1.Controls.Add(this.bt_rtty_start);
+ this.panel1.Controls.Add(this.button1);
+ this.panel1.Controls.Add(this.bt_rtty_end);
+ this.panel1.Controls.Add(this.textBox5);
+ this.panel1.Controls.Add(this.bt_rtty_endqso);
+ this.panel1.Controls.Add(this.rb_rtty_edit);
+ this.panel1.Controls.Add(this.bt_rtty_myinfo);
+ this.panel1.Controls.Add(this.rb_rtty_normal);
+ this.panel1.Controls.Add(this.bt_rtty_station);
+ this.panel1.Controls.Add(this.bt_rtty_default);
+ this.panel1.Controls.Add(this.bt_rtty_tx);
+ this.panel1.Controls.Add(this.label_urname);
+ this.panel1.Controls.Add(this.tb_rtty_deftext);
+ this.panel1.Controls.Add(this.tb_urname);
+ this.panel1.Controls.Add(this.tb_urcall);
+ this.panel1.Controls.Add(this.label_urcall);
+ this.panel1.Location = new System.Drawing.Point(696, 8);
+ this.panel1.Name = "panel1";
+ this.panel1.Size = new System.Drawing.Size(564, 514);
+ this.panel1.TabIndex = 31;
+ //
+ // rb_rtty_real
+ //
+ this.rb_rtty_real.AutoSize = true;
+ this.rb_rtty_real.Location = new System.Drawing.Point(373, 203);
+ this.rb_rtty_real.Name = "rb_rtty_real";
+ this.rb_rtty_real.Size = new System.Drawing.Size(47, 17);
+ this.rb_rtty_real.TabIndex = 33;
+ this.rb_rtty_real.Text = "Real";
+ this.rb_rtty_real.UseVisualStyleBackColor = true;
+ this.rb_rtty_real.CheckedChanged += new System.EventHandler(this.rb_rtty_real_CheckedChanged);
+ //
+ // bt_rtty_text6
+ //
+ this.bt_rtty_text6.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_text6.ImageIndex = 22;
+ this.bt_rtty_text6.ImageList = this.imageList1;
+ this.bt_rtty_text6.Location = new System.Drawing.Point(432, 293);
+ this.bt_rtty_text6.Name = "bt_rtty_text6";
+ this.bt_rtty_text6.Size = new System.Drawing.Size(107, 25);
+ this.bt_rtty_text6.TabIndex = 32;
+ this.bt_rtty_text6.Text = "TEXT 6";
+ this.bt_rtty_text6.UseVisualStyleBackColor = true;
+ this.bt_rtty_text6.Click += new System.EventHandler(this.bt_rtty_text6_Click);
+ //
+ // bt_rtty_text5
+ //
+ this.bt_rtty_text5.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_text5.ImageIndex = 22;
+ this.bt_rtty_text5.ImageList = this.imageList1;
+ this.bt_rtty_text5.Location = new System.Drawing.Point(432, 264);
+ this.bt_rtty_text5.Name = "bt_rtty_text5";
+ this.bt_rtty_text5.Size = new System.Drawing.Size(107, 25);
+ this.bt_rtty_text5.TabIndex = 31;
+ this.bt_rtty_text5.Text = "TEXT 5";
+ this.bt_rtty_text5.UseVisualStyleBackColor = true;
+ this.bt_rtty_text5.Click += new System.EventHandler(this.bt_rtty_text5_Click);
+ //
+ // bt_rtty_text4
+ //
+ this.bt_rtty_text4.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_text4.ImageIndex = 22;
+ this.bt_rtty_text4.ImageList = this.imageList1;
+ this.bt_rtty_text4.Location = new System.Drawing.Point(432, 235);
+ this.bt_rtty_text4.Name = "bt_rtty_text4";
+ this.bt_rtty_text4.Size = new System.Drawing.Size(107, 25);
+ this.bt_rtty_text4.TabIndex = 30;
+ this.bt_rtty_text4.Text = "TEXT 4";
+ this.bt_rtty_text4.UseVisualStyleBackColor = true;
+ this.bt_rtty_text4.Click += new System.EventHandler(this.bt_rtty_text4_Click);
+ //
+ // bt_rtty_text3
+ //
+ this.bt_rtty_text3.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_text3.ImageIndex = 22;
+ this.bt_rtty_text3.ImageList = this.imageList1;
+ this.bt_rtty_text3.Location = new System.Drawing.Point(319, 293);
+ this.bt_rtty_text3.Name = "bt_rtty_text3";
+ this.bt_rtty_text3.Size = new System.Drawing.Size(107, 25);
+ this.bt_rtty_text3.TabIndex = 29;
+ this.bt_rtty_text3.Text = "TEXT 3";
+ this.bt_rtty_text3.UseVisualStyleBackColor = true;
+ this.bt_rtty_text3.Click += new System.EventHandler(this.bt_rtty_text3_Click);
+ //
+ // bt_rtty_text2
+ //
+ this.bt_rtty_text2.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_text2.ImageIndex = 22;
+ this.bt_rtty_text2.ImageList = this.imageList1;
+ this.bt_rtty_text2.Location = new System.Drawing.Point(319, 264);
+ this.bt_rtty_text2.Name = "bt_rtty_text2";
+ this.bt_rtty_text2.Size = new System.Drawing.Size(107, 25);
+ this.bt_rtty_text2.TabIndex = 28;
+ this.bt_rtty_text2.Text = "TEXT 2";
+ this.bt_rtty_text2.UseVisualStyleBackColor = true;
+ this.bt_rtty_text2.Click += new System.EventHandler(this.bt_rtty_text2_Click);
+ //
+ // bt_rtty_text1
+ //
+ this.bt_rtty_text1.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_text1.ImageIndex = 22;
+ this.bt_rtty_text1.ImageList = this.imageList1;
+ this.bt_rtty_text1.Location = new System.Drawing.Point(319, 235);
+ this.bt_rtty_text1.Name = "bt_rtty_text1";
+ this.bt_rtty_text1.Size = new System.Drawing.Size(107, 25);
+ this.bt_rtty_text1.TabIndex = 27;
+ this.bt_rtty_text1.Text = "TEXT 1";
+ this.bt_rtty_text1.UseVisualStyleBackColor = true;
+ this.bt_rtty_text1.Click += new System.EventHandler(this.bt_rtty_text1_Click);
+ //
+ // button5
+ //
+ this.button5.BackColor = System.Drawing.Color.Transparent;
+ this.button5.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+ this.button5.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.button5.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.button5.ImageIndex = 1;
+ this.button5.ImageList = this.imageList1;
+ this.button5.Location = new System.Drawing.Point(39, 123);
+ this.button5.Name = "button5";
+ this.button5.Size = new System.Drawing.Size(114, 38);
+ this.button5.TabIndex = 26;
+ this.button5.Text = "Stop TX";
+ this.button5.UseVisualStyleBackColor = false;
+ this.button5.Click += new System.EventHandler(this.button5_Click);
+ //
+ // bt_rtty_RY
+ //
+ this.bt_rtty_RY.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_RY.ImageIndex = 15;
+ this.bt_rtty_RY.ImageList = this.imageList1;
+ this.bt_rtty_RY.Location = new System.Drawing.Point(179, 293);
+ this.bt_rtty_RY.Name = "bt_rtty_RY";
+ this.bt_rtty_RY.Size = new System.Drawing.Size(134, 25);
+ this.bt_rtty_RY.TabIndex = 25;
+ this.bt_rtty_RY.Text = "RYRYRY...";
+ this.bt_rtty_RY.UseVisualStyleBackColor = true;
+ this.bt_rtty_RY.Click += new System.EventHandler(this.bt_rtty_RY_Click);
+ //
+ // textBox2
+ //
+ this.textBox2.BackColor = System.Drawing.SystemColors.Control;
+ this.textBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.textBox2.Enabled = false;
+ this.textBox2.Font = new System.Drawing.Font("Courier New", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.textBox2.Location = new System.Drawing.Point(305, 18);
+ this.textBox2.Multiline = true;
+ this.textBox2.Name = "textBox2";
+ this.textBox2.ReadOnly = true;
+ this.textBox2.Size = new System.Drawing.Size(186, 143);
+ this.textBox2.TabIndex = 12;
+ this.textBox2.Text = "Special Markers:\r\n%m ... my call\r\n%c ... ur call\r\n%n ... ur name\r\n%r ... stop TX\r" +
+ "\n";
+ //
+ // button4
+ //
+ this.button4.BackgroundImage = global::oscardata.Properties.Resources.foht;
+ this.button4.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+ this.button4.Location = new System.Drawing.Point(1, 429);
+ this.button4.Name = "button4";
+ this.button4.Size = new System.Drawing.Size(24, 24);
+ this.button4.TabIndex = 24;
+ this.button4.UseVisualStyleBackColor = true;
+ this.button4.Click += new System.EventHandler(this.button4_Click);
+ //
+ // bt_rtty_cq
+ //
+ this.bt_rtty_cq.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_cq.ImageIndex = 16;
+ this.bt_rtty_cq.ImageList = this.imageList1;
+ this.bt_rtty_cq.Location = new System.Drawing.Point(39, 177);
+ this.bt_rtty_cq.Name = "bt_rtty_cq";
+ this.bt_rtty_cq.Size = new System.Drawing.Size(134, 25);
+ this.bt_rtty_cq.TabIndex = 3;
+ this.bt_rtty_cq.Text = "Call CQ";
+ this.bt_rtty_cq.UseVisualStyleBackColor = true;
+ this.bt_rtty_cq.Click += new System.EventHandler(this.bt_rtty_cq_Click);
+ //
+ // bt_rxfont
+ //
+ this.bt_rxfont.BackgroundImage = global::oscardata.Properties.Resources.foht;
+ this.bt_rxfont.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+ this.bt_rxfont.Location = new System.Drawing.Point(1, 59);
+ this.bt_rxfont.Name = "bt_rxfont";
+ this.bt_rxfont.Size = new System.Drawing.Size(24, 24);
+ this.bt_rxfont.TabIndex = 23;
+ this.bt_rxfont.UseVisualStyleBackColor = true;
+ this.bt_rxfont.Click += new System.EventHandler(this.bt_rxfont_Click);
+ //
+ // bt_rtty_answerCQ
+ //
+ this.bt_rtty_answerCQ.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_answerCQ.ImageIndex = 18;
+ this.bt_rtty_answerCQ.ImageList = this.imageList1;
+ this.bt_rtty_answerCQ.Location = new System.Drawing.Point(39, 206);
+ this.bt_rtty_answerCQ.Name = "bt_rtty_answerCQ";
+ this.bt_rtty_answerCQ.Size = new System.Drawing.Size(134, 25);
+ this.bt_rtty_answerCQ.TabIndex = 4;
+ this.bt_rtty_answerCQ.Text = "Answer CQ Call";
+ this.bt_rtty_answerCQ.UseVisualStyleBackColor = true;
+ this.bt_rtty_answerCQ.Click += new System.EventHandler(this.bt_rtty_answerCQ_Click);
+ //
+ // button3
+ //
+ this.button3.BackgroundImage = global::oscardata.Properties.Resources.clearscreen;
+ this.button3.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+ this.button3.Location = new System.Drawing.Point(1, 399);
+ this.button3.Name = "button3";
+ this.button3.Size = new System.Drawing.Size(24, 24);
+ this.button3.TabIndex = 22;
+ this.button3.UseVisualStyleBackColor = true;
+ this.button3.Click += new System.EventHandler(this.button3_Click);
+ //
+ // bt_rtty_start
+ //
+ this.bt_rtty_start.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_start.ImageIndex = 20;
+ this.bt_rtty_start.ImageList = this.imageList1;
+ this.bt_rtty_start.Location = new System.Drawing.Point(39, 235);
+ this.bt_rtty_start.Name = "bt_rtty_start";
+ this.bt_rtty_start.Size = new System.Drawing.Size(134, 25);
+ this.bt_rtty_start.TabIndex = 5;
+ this.bt_rtty_start.Text = "Start Transmission";
+ this.bt_rtty_start.UseVisualStyleBackColor = true;
+ this.bt_rtty_start.Click += new System.EventHandler(this.bt_rtty_start_Click);
+ //
+ // button1
+ //
+ this.button1.BackgroundImage = global::oscardata.Properties.Resources.clearscreen;
+ this.button1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+ this.button1.Location = new System.Drawing.Point(1, 29);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(24, 24);
+ this.button1.TabIndex = 21;
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click_1);
+ //
+ // bt_rtty_end
+ //
+ this.bt_rtty_end.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_end.ImageIndex = 19;
+ this.bt_rtty_end.ImageList = this.imageList1;
+ this.bt_rtty_end.Location = new System.Drawing.Point(39, 264);
+ this.bt_rtty_end.Name = "bt_rtty_end";
+ this.bt_rtty_end.Size = new System.Drawing.Size(134, 25);
+ this.bt_rtty_end.TabIndex = 6;
+ this.bt_rtty_end.Text = "End Transmission";
+ this.bt_rtty_end.UseVisualStyleBackColor = true;
+ this.bt_rtty_end.Click += new System.EventHandler(this.bt_rtty_end_Click);
+ //
+ // textBox5
+ //
+ this.textBox5.BackColor = System.Drawing.SystemColors.Control;
+ this.textBox5.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.textBox5.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F);
+ this.textBox5.Location = new System.Drawing.Point(171, 67);
+ this.textBox5.Multiline = true;
+ this.textBox5.Name = "textBox5";
+ this.textBox5.ReadOnly = true;
+ this.textBox5.Size = new System.Drawing.Size(117, 50);
+ this.textBox5.TabIndex = 20;
+ this.textBox5.Text = "Click Callsign and Names in RX-Windows";
+ //
+ // bt_rtty_endqso
+ //
+ this.bt_rtty_endqso.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_endqso.ImageIndex = 21;
+ this.bt_rtty_endqso.ImageList = this.imageList1;
+ this.bt_rtty_endqso.Location = new System.Drawing.Point(39, 293);
+ this.bt_rtty_endqso.Name = "bt_rtty_endqso";
+ this.bt_rtty_endqso.Size = new System.Drawing.Size(134, 25);
+ this.bt_rtty_endqso.TabIndex = 7;
+ this.bt_rtty_endqso.Text = "End QSO";
+ this.bt_rtty_endqso.UseVisualStyleBackColor = true;
+ this.bt_rtty_endqso.Click += new System.EventHandler(this.bt_rtty_endqso_Click);
+ //
+ // rb_rtty_edit
+ //
+ this.rb_rtty_edit.AutoSize = true;
+ this.rb_rtty_edit.Location = new System.Drawing.Point(436, 203);
+ this.rb_rtty_edit.Name = "rb_rtty_edit";
+ this.rb_rtty_edit.Size = new System.Drawing.Size(43, 17);
+ this.rb_rtty_edit.TabIndex = 19;
+ this.rb_rtty_edit.Text = "Edit";
+ this.rb_rtty_edit.UseVisualStyleBackColor = true;
+ this.rb_rtty_edit.CheckedChanged += new System.EventHandler(this.rb_rtty_edit_CheckedChanged);
+ //
+ // bt_rtty_myinfo
+ //
+ this.bt_rtty_myinfo.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_myinfo.ImageIndex = 17;
+ this.bt_rtty_myinfo.ImageList = this.imageList1;
+ this.bt_rtty_myinfo.Location = new System.Drawing.Point(179, 235);
+ this.bt_rtty_myinfo.Name = "bt_rtty_myinfo";
+ this.bt_rtty_myinfo.Size = new System.Drawing.Size(134, 25);
+ this.bt_rtty_myinfo.TabIndex = 8;
+ this.bt_rtty_myinfo.Text = "My Info";
+ this.bt_rtty_myinfo.UseVisualStyleBackColor = true;
+ this.bt_rtty_myinfo.Click += new System.EventHandler(this.bt_rtty_myinfo_Click);
+ //
+ // rb_rtty_normal
+ //
+ this.rb_rtty_normal.AutoSize = true;
+ this.rb_rtty_normal.Checked = true;
+ this.rb_rtty_normal.Location = new System.Drawing.Point(320, 203);
+ this.rb_rtty_normal.Name = "rb_rtty_normal";
+ this.rb_rtty_normal.Size = new System.Drawing.Size(39, 17);
+ this.rb_rtty_normal.TabIndex = 18;
+ this.rb_rtty_normal.TabStop = true;
+ this.rb_rtty_normal.Text = "TX";
+ this.rb_rtty_normal.UseVisualStyleBackColor = true;
+ this.rb_rtty_normal.CheckedChanged += new System.EventHandler(this.rb_rtty_normal_CheckedChanged);
+ //
+ // bt_rtty_station
+ //
+ this.bt_rtty_station.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_station.ImageIndex = 14;
+ this.bt_rtty_station.ImageList = this.imageList1;
+ this.bt_rtty_station.Location = new System.Drawing.Point(179, 264);
+ this.bt_rtty_station.Name = "bt_rtty_station";
+ this.bt_rtty_station.Size = new System.Drawing.Size(134, 25);
+ this.bt_rtty_station.TabIndex = 9;
+ this.bt_rtty_station.Text = "My Station";
+ this.bt_rtty_station.UseVisualStyleBackColor = true;
+ this.bt_rtty_station.Click += new System.EventHandler(this.bt_rtty_station_Click);
+ //
+ // bt_rtty_default
+ //
+ this.bt_rtty_default.Enabled = false;
+ this.bt_rtty_default.Location = new System.Drawing.Point(305, 167);
+ this.bt_rtty_default.Name = "bt_rtty_default";
+ this.bt_rtty_default.Size = new System.Drawing.Size(186, 23);
+ this.bt_rtty_default.TabIndex = 17;
+ this.bt_rtty_default.Text = "set Default Text";
+ this.bt_rtty_default.UseVisualStyleBackColor = true;
+ this.bt_rtty_default.Click += new System.EventHandler(this.bt_rtty_default_Click);
+ //
+ // bt_rtty_tx
+ //
+ this.bt_rtty_tx.BackColor = System.Drawing.Color.LightGreen;
+ this.bt_rtty_tx.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.bt_rtty_tx.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+ this.bt_rtty_tx.ImageIndex = 9;
+ this.bt_rtty_tx.ImageList = this.imageList1;
+ this.bt_rtty_tx.Location = new System.Drawing.Point(39, 79);
+ this.bt_rtty_tx.Name = "bt_rtty_tx";
+ this.bt_rtty_tx.Size = new System.Drawing.Size(114, 38);
+ this.bt_rtty_tx.TabIndex = 10;
+ this.bt_rtty_tx.Text = "TX on/off";
+ this.bt_rtty_tx.UseVisualStyleBackColor = false;
+ this.bt_rtty_tx.Click += new System.EventHandler(this.bt_rtty_tx_Click);
+ //
+ // label_urname
+ //
+ this.label_urname.AutoSize = true;
+ this.label_urname.Location = new System.Drawing.Point(74, 46);
+ this.label_urname.Name = "label_urname";
+ this.label_urname.Size = new System.Drawing.Size(63, 13);
+ this.label_urname.TabIndex = 16;
+ this.label_urname.Text = "Your Name:";
+ //
+ // tb_rtty_deftext
+ //
+ this.tb_rtty_deftext.Font = new System.Drawing.Font("Courier New", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.tb_rtty_deftext.Location = new System.Drawing.Point(39, 341);
+ this.tb_rtty_deftext.Multiline = true;
+ this.tb_rtty_deftext.Name = "tb_rtty_deftext";
+ this.tb_rtty_deftext.Size = new System.Drawing.Size(522, 153);
+ this.tb_rtty_deftext.TabIndex = 11;
+ this.tb_rtty_deftext.TextChanged += new System.EventHandler(this.tb_rtty_deftext_TextChanged);
+ //
+ // tb_urname
+ //
+ this.tb_urname.Location = new System.Drawing.Point(171, 43);
+ this.tb_urname.Name = "tb_urname";
+ this.tb_urname.Size = new System.Drawing.Size(117, 20);
+ this.tb_urname.TabIndex = 15;
+ //
+ // tb_urcall
+ //
+ this.tb_urcall.Location = new System.Drawing.Point(171, 17);
+ this.tb_urcall.Name = "tb_urcall";
+ this.tb_urcall.Size = new System.Drawing.Size(117, 20);
+ this.tb_urcall.TabIndex = 13;
+ //
+ // label_urcall
+ //
+ this.label_urcall.AutoSize = true;
+ this.label_urcall.Location = new System.Drawing.Point(74, 20);
+ this.label_urcall.Name = "label_urcall";
+ this.label_urcall.Size = new System.Drawing.Size(71, 13);
+ this.label_urcall.TabIndex = 14;
+ this.label_urcall.Text = "Your Callsign:";
+ //
// tabPage_setup
//
this.tabPage_setup.BackColor = System.Drawing.Color.Transparent;
+ this.tabPage_setup.Controls.Add(this.label_cfgpath);
+ this.tabPage_setup.Controls.Add(this.label_cfgpath_tit);
this.tabPage_setup.Controls.Add(this.groupBox4);
this.tabPage_setup.Controls.Add(this.groupBox3);
this.tabPage_setup.Controls.Add(this.groupBox2);
@@ -961,6 +1504,24 @@
this.tabPage_setup.TabIndex = 4;
this.tabPage_setup.Text = "Setup";
//
+ // label_cfgpath
+ //
+ this.label_cfgpath.AutoSize = true;
+ this.label_cfgpath.Location = new System.Drawing.Point(162, 441);
+ this.label_cfgpath.Name = "label_cfgpath";
+ this.label_cfgpath.Size = new System.Drawing.Size(16, 13);
+ this.label_cfgpath.TabIndex = 17;
+ this.label_cfgpath.Text = "...";
+ //
+ // label_cfgpath_tit
+ //
+ this.label_cfgpath_tit.AutoSize = true;
+ this.label_cfgpath_tit.Location = new System.Drawing.Point(17, 441);
+ this.label_cfgpath_tit.Name = "label_cfgpath_tit";
+ this.label_cfgpath_tit.Size = new System.Drawing.Size(115, 13);
+ this.label_cfgpath_tit.TabIndex = 16;
+ this.label_cfgpath_tit.Text = "Configuration stored in:";
+ //
// groupBox4
//
this.groupBox4.Controls.Add(this.label13);
@@ -1254,6 +1815,12 @@
//
// groupBox2
//
+ this.groupBox2.Controls.Add(this.tb_myqthloc);
+ this.groupBox2.Controls.Add(this.label14);
+ this.groupBox2.Controls.Add(this.tb_myqth);
+ this.groupBox2.Controls.Add(this.lb_qth);
+ this.groupBox2.Controls.Add(this.tb_myname);
+ this.groupBox2.Controls.Add(this.lb_myname);
this.groupBox2.Controls.Add(this.lb_rec);
this.groupBox2.Controls.Add(this.tb_recintro);
this.groupBox2.Controls.Add(this.bt_astop);
@@ -1276,12 +1843,61 @@
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Personal Settings";
//
+ // tb_myqthloc
+ //
+ this.tb_myqthloc.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
+ this.tb_myqthloc.Location = new System.Drawing.Point(71, 99);
+ this.tb_myqthloc.Name = "tb_myqthloc";
+ this.tb_myqthloc.Size = new System.Drawing.Size(104, 20);
+ this.tb_myqthloc.TabIndex = 35;
+ //
+ // label14
+ //
+ this.label14.AutoSize = true;
+ this.label14.Location = new System.Drawing.Point(14, 102);
+ this.label14.Name = "label14";
+ this.label14.Size = new System.Drawing.Size(54, 13);
+ this.label14.TabIndex = 34;
+ this.label14.Text = "QTHLOC:";
+ //
+ // tb_myqth
+ //
+ this.tb_myqth.Location = new System.Drawing.Point(71, 72);
+ this.tb_myqth.Name = "tb_myqth";
+ this.tb_myqth.Size = new System.Drawing.Size(104, 20);
+ this.tb_myqth.TabIndex = 33;
+ //
+ // lb_qth
+ //
+ this.lb_qth.AutoSize = true;
+ this.lb_qth.Location = new System.Drawing.Point(14, 75);
+ this.lb_qth.Name = "lb_qth";
+ this.lb_qth.Size = new System.Drawing.Size(33, 13);
+ this.lb_qth.TabIndex = 32;
+ this.lb_qth.Text = "QTH:";
+ //
+ // tb_myname
+ //
+ this.tb_myname.Location = new System.Drawing.Point(71, 46);
+ this.tb_myname.Name = "tb_myname";
+ this.tb_myname.Size = new System.Drawing.Size(104, 20);
+ this.tb_myname.TabIndex = 31;
+ //
+ // lb_myname
+ //
+ this.lb_myname.AutoSize = true;
+ this.lb_myname.Location = new System.Drawing.Point(14, 49);
+ this.lb_myname.Name = "lb_myname";
+ this.lb_myname.Size = new System.Drawing.Size(38, 13);
+ this.lb_myname.TabIndex = 30;
+ this.lb_myname.Text = "Name:";
+ //
// lb_rec
//
this.lb_rec.AutoSize = true;
this.lb_rec.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lb_rec.ForeColor = System.Drawing.Color.Red;
- this.lb_rec.Location = new System.Drawing.Point(576, 101);
+ this.lb_rec.Location = new System.Drawing.Point(712, 101);
this.lb_rec.Name = "lb_rec";
this.lb_rec.Size = new System.Drawing.Size(23, 13);
this.lb_rec.TabIndex = 29;
@@ -1293,7 +1909,7 @@
this.tb_recintro.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.tb_recintro.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.tb_recintro.ForeColor = System.Drawing.Color.Black;
- this.tb_recintro.Location = new System.Drawing.Point(334, 100);
+ this.tb_recintro.Location = new System.Drawing.Point(470, 100);
this.tb_recintro.Multiline = true;
this.tb_recintro.Name = "tb_recintro";
this.tb_recintro.Size = new System.Drawing.Size(121, 19);
@@ -1306,7 +1922,7 @@
this.bt_astop.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.bt_astop.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.bt_astop.ForeColor = System.Drawing.SystemColors.Control;
- this.bt_astop.Location = new System.Drawing.Point(527, 89);
+ this.bt_astop.Location = new System.Drawing.Point(663, 89);
this.bt_astop.Name = "bt_astop";
this.bt_astop.Size = new System.Drawing.Size(32, 36);
this.bt_astop.TabIndex = 27;
@@ -1319,7 +1935,7 @@
this.bt_aplay.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.bt_aplay.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.bt_aplay.ForeColor = System.Drawing.SystemColors.Control;
- this.bt_aplay.Location = new System.Drawing.Point(489, 89);
+ this.bt_aplay.Location = new System.Drawing.Point(625, 89);
this.bt_aplay.Name = "bt_aplay";
this.bt_aplay.Size = new System.Drawing.Size(32, 36);
this.bt_aplay.TabIndex = 26;
@@ -1332,7 +1948,7 @@
this.bt_arecord.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.bt_arecord.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.bt_arecord.ForeColor = System.Drawing.SystemColors.Control;
- this.bt_arecord.Location = new System.Drawing.Point(451, 89);
+ this.bt_arecord.Location = new System.Drawing.Point(587, 89);
this.bt_arecord.Name = "bt_arecord";
this.bt_arecord.Size = new System.Drawing.Size(32, 36);
this.bt_arecord.TabIndex = 25;
@@ -1344,7 +1960,7 @@
this.cb_sendIntro.AutoSize = true;
this.cb_sendIntro.Checked = true;
this.cb_sendIntro.CheckState = System.Windows.Forms.CheckState.Checked;
- this.cb_sendIntro.Location = new System.Drawing.Point(71, 104);
+ this.cb_sendIntro.Location = new System.Drawing.Point(207, 104);
this.cb_sendIntro.Name = "cb_sendIntro";
this.cb_sendIntro.Size = new System.Drawing.Size(105, 17);
this.cb_sendIntro.TabIndex = 24;
@@ -1356,7 +1972,7 @@
this.cb_stampinfo.AutoSize = true;
this.cb_stampinfo.Checked = true;
this.cb_stampinfo.CheckState = System.Windows.Forms.CheckState.Checked;
- this.cb_stampinfo.Location = new System.Drawing.Point(71, 84);
+ this.cb_stampinfo.Location = new System.Drawing.Point(207, 84);
this.cb_stampinfo.Name = "cb_stampinfo";
this.cb_stampinfo.Size = new System.Drawing.Size(128, 17);
this.cb_stampinfo.TabIndex = 23;
@@ -1367,7 +1983,7 @@
//
this.tb_info.Location = new System.Drawing.Point(243, 28);
this.tb_info.Name = "tb_info";
- this.tb_info.Size = new System.Drawing.Size(413, 20);
+ this.tb_info.Size = new System.Drawing.Size(492, 20);
this.tb_info.TabIndex = 22;
this.tb_info.Text = "tnx fer QSO, vy 73";
//
@@ -1395,7 +2011,7 @@
"8",
"9",
"10"});
- this.cb_announcement.Location = new System.Drawing.Point(453, 60);
+ this.cb_announcement.Location = new System.Drawing.Point(589, 60);
this.cb_announcement.Name = "cb_announcement";
this.cb_announcement.Size = new System.Drawing.Size(56, 21);
this.cb_announcement.TabIndex = 19;
@@ -1407,7 +2023,7 @@
this.textBox4.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBox4.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBox4.ForeColor = System.Drawing.Color.Black;
- this.textBox4.Location = new System.Drawing.Point(518, 62);
+ this.textBox4.Location = new System.Drawing.Point(654, 62);
this.textBox4.Multiline = true;
this.textBox4.Name = "textBox4";
this.textBox4.Size = new System.Drawing.Size(75, 19);
@@ -1420,7 +2036,7 @@
this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.textBox1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBox1.ForeColor = System.Drawing.Color.Black;
- this.textBox1.Location = new System.Drawing.Point(259, 64);
+ this.textBox1.Location = new System.Drawing.Point(395, 64);
this.textBox1.Multiline = true;
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(196, 19);
@@ -1430,7 +2046,7 @@
// tb_callsign
//
this.tb_callsign.CharacterCasing = System.Windows.Forms.CharacterCasing.Upper;
- this.tb_callsign.Location = new System.Drawing.Point(71, 28);
+ this.tb_callsign.Location = new System.Drawing.Point(71, 20);
this.tb_callsign.Name = "tb_callsign";
this.tb_callsign.Size = new System.Drawing.Size(104, 20);
this.tb_callsign.TabIndex = 1;
@@ -1438,7 +2054,7 @@
// label1
//
this.label1.AutoSize = true;
- this.label1.Location = new System.Drawing.Point(14, 31);
+ this.label1.Location = new System.Drawing.Point(14, 23);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(46, 13);
this.label1.TabIndex = 0;
@@ -1449,7 +2065,7 @@
this.cb_stampcall.AutoSize = true;
this.cb_stampcall.Checked = true;
this.cb_stampcall.CheckState = System.Windows.Forms.CheckState.Checked;
- this.cb_stampcall.Location = new System.Drawing.Point(71, 64);
+ this.cb_stampcall.Location = new System.Drawing.Point(207, 64);
this.cb_stampcall.Name = "cb_stampcall";
this.cb_stampcall.Size = new System.Drawing.Size(146, 17);
this.cb_stampcall.TabIndex = 2;
@@ -1472,7 +2088,7 @@
this.richTextBox1.BorderStyle = System.Windows.Forms.BorderStyle.None;
this.richTextBox1.Location = new System.Drawing.Point(17, 22);
this.richTextBox1.Name = "richTextBox1";
- this.richTextBox1.Size = new System.Drawing.Size(855, 527);
+ this.richTextBox1.Size = new System.Drawing.Size(573, 527);
this.richTextBox1.TabIndex = 0;
this.richTextBox1.Text = resources.GetString("richTextBox1.Text");
//
@@ -1489,8 +2105,9 @@
"5500 8APSK BW: 2300 Hz",
"6000 8APSK BW: 2500 Hz (QO-100 Transceiver)",
"6600 8APSK BW: 2600 Hz",
- "7200 8APSK BW: 2700 Hz (QO-100 SDR)"});
- this.cb_speed.Location = new System.Drawing.Point(658, 591);
+ "7200 8APSK BW: 2700 Hz (QO-100 SDR)",
+ "45.45 Baud RTTY"});
+ this.cb_speed.Location = new System.Drawing.Point(122, 2);
this.cb_speed.Name = "cb_speed";
this.cb_speed.Size = new System.Drawing.Size(304, 21);
this.cb_speed.TabIndex = 11;
@@ -1500,7 +2117,7 @@
// label_speed
//
this.label_speed.AutoSize = true;
- this.label_speed.Location = new System.Drawing.Point(567, 594);
+ this.label_speed.Location = new System.Drawing.Point(31, 5);
this.label_speed.Name = "label_speed";
this.label_speed.Size = new System.Drawing.Size(71, 13);
this.label_speed.TabIndex = 12;
@@ -1514,26 +2131,16 @@
// label_fifo
//
this.label_fifo.AutoSize = true;
- this.label_fifo.Location = new System.Drawing.Point(567, 620);
+ this.label_fifo.Location = new System.Drawing.Point(31, 31);
this.label_fifo.Name = "label_fifo";
this.label_fifo.Size = new System.Drawing.Size(55, 13);
this.label_fifo.TabIndex = 14;
this.label_fifo.Text = "TX Buffer:";
//
- // bt_blockinfo
- //
- this.bt_blockinfo.Location = new System.Drawing.Point(1213, 591);
- this.bt_blockinfo.Name = "bt_blockinfo";
- this.bt_blockinfo.Size = new System.Drawing.Size(68, 23);
- this.bt_blockinfo.TabIndex = 13;
- this.bt_blockinfo.Text = "Block Info";
- this.bt_blockinfo.UseVisualStyleBackColor = true;
- this.bt_blockinfo.Click += new System.EventHandler(this.bt_blockinfo_Click);
- //
// label_capfifo
//
this.label_capfifo.AutoSize = true;
- this.label_capfifo.Location = new System.Drawing.Point(567, 643);
+ this.label_capfifo.Location = new System.Drawing.Point(31, 54);
this.label_capfifo.Name = "label_capfifo";
this.label_capfifo.Size = new System.Drawing.Size(56, 13);
this.label_capfifo.TabIndex = 16;
@@ -1542,7 +2149,7 @@
// lb_rxsignal
//
this.lb_rxsignal.AutoSize = true;
- this.lb_rxsignal.Location = new System.Drawing.Point(984, 643);
+ this.lb_rxsignal.Location = new System.Drawing.Point(448, 54);
this.lb_rxsignal.Name = "lb_rxsignal";
this.lb_rxsignal.Size = new System.Drawing.Size(57, 13);
this.lb_rxsignal.TabIndex = 18;
@@ -1551,46 +2158,76 @@
// lb_rxsync
//
this.lb_rxsync.AutoSize = true;
- this.lb_rxsync.Location = new System.Drawing.Point(984, 596);
+ this.lb_rxsync.Location = new System.Drawing.Point(448, 7);
this.lb_rxsync.Name = "lb_rxsync";
this.lb_rxsync.Size = new System.Drawing.Size(52, 13);
this.lb_rxsync.TabIndex = 20;
this.lb_rxsync.Text = "RX Sync:";
//
- // pb_rxsync
+ // pn1
//
- this.pb_rxsync.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pb_rxsync.BackgroundImage")));
- this.pb_rxsync.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
- this.pb_rxsync.Location = new System.Drawing.Point(1047, 591);
- this.pb_rxsync.Name = "pb_rxsync";
- this.pb_rxsync.Size = new System.Drawing.Size(24, 24);
- this.pb_rxsync.TabIndex = 19;
- this.pb_rxsync.TabStop = false;
+ this.pn1.Controls.Add(this.progressBar_fifo);
+ this.pn1.Controls.Add(this.label_capfifo);
+ this.pn1.Controls.Add(this.label_speed);
+ this.pn1.Controls.Add(this.pb_rxsignal);
+ this.pn1.Controls.Add(this.lb_rxsync);
+ this.pn1.Controls.Add(this.progressBar_capfifo);
+ this.pn1.Controls.Add(this.cb_speed);
+ this.pn1.Controls.Add(this.lb_rxsignal);
+ this.pn1.Controls.Add(this.pb_rxsync);
+ this.pn1.Controls.Add(this.label_fifo);
+ this.pn1.Location = new System.Drawing.Point(540, 588);
+ this.pn1.Name = "pn1";
+ this.pn1.Size = new System.Drawing.Size(538, 74);
+ this.pn1.TabIndex = 30;
//
// pb_rxsignal
//
this.pb_rxsignal.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pb_rxsignal.BackgroundImage")));
this.pb_rxsignal.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
- this.pb_rxsignal.Location = new System.Drawing.Point(1047, 636);
+ this.pb_rxsignal.Location = new System.Drawing.Point(511, 47);
this.pb_rxsignal.Name = "pb_rxsignal";
this.pb_rxsignal.Size = new System.Drawing.Size(24, 24);
this.pb_rxsignal.TabIndex = 17;
this.pb_rxsignal.TabStop = false;
//
- // progressBar_capfifo
+ // pb_rxsync
//
- this.progressBar_capfifo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128)))));
- this.progressBar_capfifo.Location = new System.Drawing.Point(658, 642);
- this.progressBar_capfifo.Name = "progressBar_capfifo";
- this.progressBar_capfifo.Size = new System.Drawing.Size(304, 18);
- this.progressBar_capfifo.Step = 1;
- this.progressBar_capfifo.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
- this.progressBar_capfifo.TabIndex = 15;
+ this.pb_rxsync.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("pb_rxsync.BackgroundImage")));
+ this.pb_rxsync.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom;
+ this.pb_rxsync.Location = new System.Drawing.Point(511, 2);
+ this.pb_rxsync.Name = "pb_rxsync";
+ this.pb_rxsync.Size = new System.Drawing.Size(24, 24);
+ this.pb_rxsync.TabIndex = 19;
+ this.pb_rxsync.TabStop = false;
+ //
+ // cb_rx_autosync
+ //
+ this.cb_rx_autosync.AutoSize = true;
+ this.cb_rx_autosync.Location = new System.Drawing.Point(195, 146);
+ this.cb_rx_autosync.Name = "cb_rx_autosync";
+ this.cb_rx_autosync.Size = new System.Drawing.Size(93, 17);
+ this.cb_rx_autosync.TabIndex = 34;
+ this.cb_rx_autosync.Text = "RX Auto Sync";
+ this.cb_rx_autosync.UseVisualStyleBackColor = true;
+ //
+ // textBox6
+ //
+ this.textBox6.BackColor = System.Drawing.SystemColors.Control;
+ this.textBox6.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+ this.textBox6.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F);
+ this.textBox6.Location = new System.Drawing.Point(195, 167);
+ this.textBox6.Multiline = true;
+ this.textBox6.Name = "textBox6";
+ this.textBox6.ReadOnly = true;
+ this.textBox6.Size = new System.Drawing.Size(93, 35);
+ this.textBox6.TabIndex = 35;
+ this.textBox6.Text = "or double click in spectrum";
//
// progressBar_fifo
//
this.progressBar_fifo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(255)))), ((int)(((byte)(255)))));
- this.progressBar_fifo.Location = new System.Drawing.Point(658, 618);
+ this.progressBar_fifo.Location = new System.Drawing.Point(122, 29);
this.progressBar_fifo.Maximum = 20;
this.progressBar_fifo.Name = "progressBar_fifo";
this.progressBar_fifo.Size = new System.Drawing.Size(304, 18);
@@ -1598,6 +2235,16 @@
this.progressBar_fifo.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
this.progressBar_fifo.TabIndex = 13;
//
+ // progressBar_capfifo
+ //
+ this.progressBar_capfifo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128)))));
+ this.progressBar_capfifo.Location = new System.Drawing.Point(122, 53);
+ this.progressBar_capfifo.Name = "progressBar_capfifo";
+ this.progressBar_capfifo.Size = new System.Drawing.Size(304, 18);
+ this.progressBar_capfifo.Step = 1;
+ this.progressBar_capfifo.Style = System.Windows.Forms.ProgressBarStyle.Continuous;
+ this.progressBar_capfifo.TabIndex = 15;
+ //
// vu_cap
//
this.vu_cap.Location = new System.Drawing.Point(479, 111);
@@ -1617,18 +2264,8 @@
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.SystemColors.Control;
- this.ClientSize = new System.Drawing.Size(1293, 691);
- this.Controls.Add(this.lb_rxsync);
- this.Controls.Add(this.pb_rxsync);
- this.Controls.Add(this.lb_rxsignal);
- this.Controls.Add(this.pb_rxsignal);
- this.Controls.Add(this.label_capfifo);
- this.Controls.Add(this.progressBar_capfifo);
- this.Controls.Add(this.bt_blockinfo);
- this.Controls.Add(this.label_fifo);
- this.Controls.Add(this.progressBar_fifo);
- this.Controls.Add(this.cb_speed);
- this.Controls.Add(this.label_speed);
+ this.ClientSize = new System.Drawing.Size(1296, 693);
+ this.Controls.Add(this.pn1);
this.Controls.Add(this.panel_txspectrum);
this.Controls.Add(this.panel_constel);
this.Controls.Add(this.statusStrip1);
@@ -1636,7 +2273,7 @@
this.ForeColor = System.Drawing.SystemColors.ControlText;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "Form1";
- this.Text = "AMSAT-DL Multimedia HS Modem V0.56 by DJ0ABR";
+ this.Text = "AMSAT-DL Multimedia HS Modem V0.64 by DJ0ABR";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
this.statusStrip1.ResumeLayout(false);
this.statusStrip1.PerformLayout();
@@ -1665,7 +2302,12 @@
((System.ComponentModel.ISupportInitialize)(this.pb_voicePBstatus)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.tb_mic)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.tb_loadspeaker)).EndInit();
+ this.tabPage_rtty.ResumeLayout(false);
+ this.tabPage_rtty.PerformLayout();
+ this.panel1.ResumeLayout(false);
+ this.panel1.PerformLayout();
this.tabPage_setup.ResumeLayout(false);
+ this.tabPage_setup.PerformLayout();
this.groupBox4.ResumeLayout(false);
this.groupBox4.PerformLayout();
this.groupBox3.ResumeLayout(false);
@@ -1679,8 +2321,10 @@
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.tabPage_about.ResumeLayout(false);
- ((System.ComponentModel.ISupportInitialize)(this.pb_rxsync)).EndInit();
+ this.pn1.ResumeLayout(false);
+ this.pn1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.pb_rxsignal)).EndInit();
+ ((System.ComponentModel.ISupportInitialize)(this.pb_rxsync)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@@ -1766,7 +2410,6 @@
private System.Windows.Forms.Label label10;
private System.Windows.Forms.ComboBox cb_mic;
private System.Windows.Forms.Label label11;
- private System.Windows.Forms.Button bt_blockinfo;
private System.Windows.Forms.CheckBox cb_switchtoLS;
private System.Windows.Forms.GroupBox groupBox6;
private System.Windows.Forms.CheckBox cb_voiceloop;
@@ -1812,6 +2455,54 @@
private System.Windows.Forms.PictureBox pictureBox4;
private System.Windows.Forms.Button bt_tune_minus;
private System.Windows.Forms.Button bt_tune_plus;
+ private System.Windows.Forms.TabPage tabPage_rtty;
+ private System.Windows.Forms.TextBox tb_rtty_TX;
+ private System.Windows.Forms.Button bt_rtty_station;
+ private System.Windows.Forms.Button bt_rtty_myinfo;
+ private System.Windows.Forms.Button bt_rtty_endqso;
+ private System.Windows.Forms.Button bt_rtty_end;
+ private System.Windows.Forms.Button bt_rtty_start;
+ private System.Windows.Forms.Button bt_rtty_answerCQ;
+ private System.Windows.Forms.Button bt_rtty_cq;
+ private System.Windows.Forms.TextBox tb_rtty_deftext;
+ private System.Windows.Forms.Button bt_rtty_tx;
+ private System.Windows.Forms.TextBox textBox2;
+ private System.Windows.Forms.Label label_urname;
+ private System.Windows.Forms.TextBox tb_urname;
+ private System.Windows.Forms.Label label_urcall;
+ private System.Windows.Forms.TextBox tb_urcall;
+ private System.Windows.Forms.Button bt_rtty_default;
+ private System.Windows.Forms.RadioButton rb_rtty_edit;
+ private System.Windows.Forms.RadioButton rb_rtty_normal;
+ private System.Windows.Forms.TextBox tb_rtty_RX;
+ private System.Windows.Forms.TextBox textBox5;
+ private System.Windows.Forms.TextBox tb_myqthloc;
+ private System.Windows.Forms.Label label14;
+ private System.Windows.Forms.TextBox tb_myqth;
+ private System.Windows.Forms.Label lb_qth;
+ private System.Windows.Forms.TextBox tb_myname;
+ private System.Windows.Forms.Label lb_myname;
+ private System.Windows.Forms.Label label_cfgpath_tit;
+ private System.Windows.Forms.Label label_cfgpath;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.Button button3;
+ private System.Windows.Forms.Button bt_rxfont;
+ private System.Windows.Forms.Button button4;
+ private System.Windows.Forms.Button bt_rtty_RY;
+ private System.Windows.Forms.Panel pn1;
+ private System.Windows.Forms.Panel panel1;
+ private System.Windows.Forms.Label label4;
+ private System.Windows.Forms.Label label3;
+ private System.Windows.Forms.Button button5;
+ private System.Windows.Forms.Button bt_rtty_text6;
+ private System.Windows.Forms.Button bt_rtty_text5;
+ private System.Windows.Forms.Button bt_rtty_text4;
+ private System.Windows.Forms.Button bt_rtty_text3;
+ private System.Windows.Forms.Button bt_rtty_text2;
+ private System.Windows.Forms.Button bt_rtty_text1;
+ private System.Windows.Forms.RadioButton rb_rtty_real;
+ private System.Windows.Forms.CheckBox cb_rx_autosync;
+ private System.Windows.Forms.TextBox textBox6;
}
}
diff --git a/oscardata/oscardata/Form1.cs b/oscardata/oscardata/Form1.cs
index ac2f82a..8ff712e 100755
--- a/oscardata/oscardata/Form1.cs
+++ b/oscardata/oscardata/Form1.cs
@@ -48,6 +48,8 @@ namespace oscardata
int last_initVoiceStatus;
int recordStatus = 0;
int recPhase = 0;
+ const int Rtty_deftext_anz = 20;
+ String[] Rtty_deftext = new string[Rtty_deftext_anz];
public Form1()
@@ -55,6 +57,8 @@ namespace oscardata
// init GUI
InitializeComponent();
+ //showSSTV();
+
// needed for ARM mono, which cannot load a picbox directly from file
var bmp = new Bitmap(Resources.hintergrundxcf);
pictureBox_rximage.BackgroundImage = bmp;
@@ -122,6 +126,10 @@ namespace oscardata
// TX timer
private void timer1_Tick(object sender, EventArgs e)
{
+ // cancel high speed TX in RTTY mode
+ if(statics.real_datarate == 45)
+ txcommand = statics.noTX;
+
// BER testdata
if (txcommand == statics.BERtest)
{
@@ -596,7 +604,10 @@ namespace oscardata
pb_rxsignal.BackgroundImage = Resources.redmarker;
showType(-1);
}
- if (statics.RXinSync == 1) pb_rxsync.BackgroundImage = Resources.greenmarker; else pb_rxsync.BackgroundImage = Resources.redmarker;
+ if (statics.real_datarate == 45)
+ if (rtty_sync == 1 && statics.RXlevelDetected == 1) pb_rxsync.BackgroundImage = Resources.greenmarker; else pb_rxsync.BackgroundImage = Resources.redmarker;
+ else
+ if (statics.RXinSync == 1) pb_rxsync.BackgroundImage = Resources.greenmarker; else pb_rxsync.BackgroundImage = Resources.redmarker;
// update rx,tx level progress bar
int factor = 1;
@@ -644,6 +655,72 @@ namespace oscardata
bt_resetmodem_Click(null, null);
statics.tuning_active = 0;
}
+
+ Byte[] ba = Udp.getRTTYrx();
+ if (ba != null)
+ {
+ int rtty_val = ba[0];
+ rtty_txon = ba[1];
+ rtty_sync = ba[2];
+ if (rtty_val != 0)
+ {
+ if (rtty_val == 0x08)
+ {
+ // backspace
+ tb_rtty_RX.Text = tb_rtty_RX.Text.Trim(new char[] { '\r', '\n' });
+ if (tb_rtty_RX.Text.Length > 0)
+ tb_rtty_RX.Text = tb_rtty_RX.Text.Substring(0, tb_rtty_RX.Text.Length - 1);
+ }
+ else if (rtty_val != '\r')
+ {
+ String s = "";
+ s += (char)rtty_val;
+ if (rtty_val == '\n')
+ s = "\r" + s;
+ if(statics.RXlevelDetected == 1) // do not print if no signal detected
+ tb_rtty_RX.AppendText(s);
+ }
+ }
+ }
+ if (rtty_txon == 1)
+ {
+ bt_rtty_tx.BackColor = Color.Red;
+ tb_rtty_TX.Enabled = true;
+ }
+ else
+ {
+ bt_rtty_tx.BackColor = Color.LightGreen;
+ tb_rtty_TX.Enabled = false;
+ }
+ }
+
+ // click into RTTY RX Textbox
+ Point RTTYmousepos = new Point(0, 0);
+ private void tb_rtty_RX_MouseDown(object sender, MouseEventArgs e)
+ {
+ RTTYmousepos.X = e.X;
+ RTTYmousepos.Y = e.Y;
+ int cidx = tb_rtty_RX.GetCharIndexFromPosition(RTTYmousepos);
+
+ // get the word under this position
+ // text after pos
+ String ls = tb_rtty_RX.Text.Substring(cidx);
+ ls = ls.Trim(new char[] { ' ', '\r', '\n' });
+ int lidx = ls.IndexOfAny(new char[] {' ', '\r', '\n' });
+ if (lidx != -1)
+ ls = tb_rtty_RX.Text.Substring(0, lidx + cidx);
+ else
+ ls = tb_rtty_RX.Text.Trim(new char[] { ' ', '\r', '\n' });
+ int fidx = ls.LastIndexOf(' ');
+ if (fidx != -1)
+ ls = ls.Substring(fidx).Trim();
+
+ // ls is the word under the caret
+ // check if it is a name or callsign
+ if (ls.IndexOfAny(new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' }) == -1)
+ tb_urname.Text = ls;
+ else
+ tb_urcall.Text = ls;
}
private void panel_constel_Paint(object sender, PaintEventArgs e)
@@ -719,6 +796,11 @@ namespace oscardata
AppendTextOnce(rtb, new Font("Courier New", (float)8), Color.Blue, Color.White, s);
}
+ void printTextnoFont(RichTextBox rtb, String s)
+ {
+ AppendTextOnce(rtb, null, Color.Blue, Color.FromArgb(255, 255, 230), s);
+ }
+
void AppendTextOnce(RichTextBox rtb, Font selfont, Color color, Color bcolor, string text)
{
try
@@ -746,7 +828,7 @@ namespace oscardata
// Textbox may transform chars, so (end-start) != text.Length
rtb.Select(start, end - start);
rtb.SelectionColor = color;
- rtb.SelectionFont = selfont;
+ if(selfont != null) rtb.SelectionFont = selfont;
rtb.SelectionBackColor = bcolor;
rtb.Select(end, 0);
@@ -1075,24 +1157,19 @@ namespace oscardata
label_txfile.Location = new Point(rtb_TXfile.Location.X, ly);
label_rxfile.Location = new Point(rtb_RXfile.Location.X, ly);
- label_speed.Location = new Point(panel_txspectrum.Location.X + panel_txspectrum.Size.Width + 15,panel_txspectrum.Location.Y+10);
- cb_speed.Location = new Point(label_speed.Location.X + label_speed.Size.Width + 10, label_speed.Location.Y-5);
+ pn1.Location = new Point(panel_txspectrum.Location.X + panel_txspectrum.Size.Width + 10, panel_txspectrum.Location.Y +0);
- int y = 26;
- label_fifo.Location = new Point(label_speed.Location.X, label_speed.Location.Y + y);
- progressBar_fifo.Location = new Point(cb_speed.Location.X, cb_speed.Location.Y + y+5);
- progressBar_fifo.Size = new Size(progressBar_fifo.Width, 18);
+ tb_rtty_RX.Location = new Point(9, 35);
+ tb_rtty_RX.Size = new Size(675, 348);
- y = 20;
- label_capfifo.Location = new Point(label_fifo.Location.X, label_fifo.Location.Y + y);
- progressBar_capfifo.Location = new Point(progressBar_fifo.Location.X, progressBar_fifo.Location.Y + y);
- progressBar_capfifo.Size = new Size(progressBar_capfifo.Width, 18);
+ tb_rtty_TX.Location = new Point(9, 416);
+ tb_rtty_TX.Size = new Size(675, 103);
- lb_rxsignal.Location = new Point(progressBar_capfifo.Location.X + progressBar_capfifo.Size.Width + 15, label_fifo.Location.Y-15);
- pb_rxsignal.Location = new Point(lb_rxsignal.Location.X + lb_rxsignal.Size.Width + 2, label_fifo.Location.Y-5-15);
+ label4.Location = new Point(13, 393);
- lb_rxsync.Location = new Point(progressBar_capfifo.Location.X + progressBar_capfifo.Size.Width + 15, label_capfifo.Location.Y);
- pb_rxsync.Location = new Point(lb_rxsignal.Location.X + lb_rxsignal.Size.Width + 2, label_capfifo.Location.Y-5);
+ panel1.Location = new Point(696,8);
+
+ tb_rtty_deftext.Size = new Size(522, 160);
}
public String GetMyBroadcastIP()
@@ -1157,7 +1234,7 @@ namespace oscardata
txb[5] = (Byte)tb_mic.Value;
txb[6] = safemode;
txb[7] = (Byte)(cb_sendIntro.Checked?1:0);
- txb[8] = (Byte)0; // unused
+ txb[8] = (Byte)(cb_rx_autosync.Checked ? 1 : 0);
txb[9] = (Byte)0; // unused
Byte[] bpb = statics.StringToByteArrayUtf8(cb_audioPB.Text);
@@ -1243,12 +1320,45 @@ namespace oscardata
}
}
+ /*void removeTab(TabPage tb)
+ {
+ if (tabControl1.TabPages.IndexOf(tb) != -1)
+ tabControl1.TabPages.Remove(tb);
+ }
+
+ void addTab(int idx, TabPage tb)
+ {
+ if (tabControl1.TabPages.IndexOf(tb) == -1)
+ tabControl1.TabPages.Insert(idx,tb);
+ }*/
+
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
bool b = cb_switchtoLS.Checked;
allVoiceModesOff();
cb_switchtoLS.Checked = b;
+ if (cb_speed.Text.Contains("45"))
+ {
+ txcommand = statics.noTX;
+ panel_constel.Visible = false;
+ statics.real_datarate = 45;
+ /*removeTab(tabPage_image);
+ removeTab(tabPage_file);
+ removeTab(tabPage_audio);
+ removeTab(tabPage_ber);
+ addTab(0,tabPage_rtty);*/
+ }
+ else
+ {
+ panel_constel.Visible = true;
+ /*addTab(0,tabPage_image);
+ addTab(1,tabPage_file);
+ addTab(2,tabPage_audio);
+ addTab(3,tabPage_ber);
+ removeTab(tabPage_rtty);*/
+ }
+
if (cb_speed.Text.Contains("3000")) statics.real_datarate = 3000;
if (cb_speed.Text.Contains("4000")) statics.real_datarate = 4000;
if (cb_speed.Text.Contains("4410")) statics.real_datarate = 4410;
@@ -1366,7 +1476,9 @@ namespace oscardata
{
try
{
- using (StreamReader sr = new StreamReader(statics.getHomePath("", "od.cfg")))
+ String fn = statics.getHomePath("", "od.cfg");
+ label_cfgpath.Text = fn;
+ using (StreamReader sr = new StreamReader(fn))
{
tb_callsign.Text = ReadString(sr);
cb_speed.Text = ReadString(sr);
@@ -1397,6 +1509,32 @@ namespace oscardata
catch { }
try { cb_language.Text = ReadString(sr); } catch { }
try { s = ReadString(sr); cb_sendIntro.Checked = (s == "1"); } catch { }
+ for (int i = 0; i < Rtty_deftext_anz; i++)
+ {
+ String sx = "";
+ try
+ {
+ sx = ReadString(sr).Trim();
+ if(sx.Length == 0)
+ initRttyDefString(i);
+ else
+ Rtty_deftext[i] = ParagrToCRLF(sx);
+ }
+ catch
+ {
+ initRttyDefString(i);
+ break;
+ }
+ }
+ tb_myname.Text = ReadString(sr);
+ tb_myqth.Text = ReadString(sr);
+ tb_myqthloc.Text = ReadString(sr);
+ Font fnt1 = FontDeserialize(ReadString(sr));
+ if (fnt1 != null) tb_rtty_RX.Font = fnt1;
+ fnt1 = FontDeserialize(ReadString(sr));
+ if (fnt1 != null) tb_rtty_TX.Font = fnt1;
+ s = ReadString(sr);
+ cb_rx_autosync.Checked = (s == "1");
}
}
catch
@@ -1441,11 +1579,110 @@ namespace oscardata
sw.WriteLine(rb_opus.Checked ? "1" : "0");
sw.WriteLine(cb_language.Text);
sw.WriteLine(cb_sendIntro.Checked ? "1" : "0");
+ for(int i=0; i < Rtty_deftext_anz; i++)
+ {
+ if (Rtty_deftext[i] == null)
+ Rtty_deftext[i] = " ";
+ sw.WriteLine(CRLFtoParagr(Rtty_deftext[i]));
+ }
+ sw.WriteLine(tb_myname.Text.Trim());
+ sw.WriteLine(tb_myqth.Text.Trim());
+ sw.WriteLine(tb_myqthloc.Text.Trim());
+ sw.WriteLine(FontSerialize(tb_rtty_RX.Font));
+ sw.WriteLine(FontSerialize(tb_rtty_TX.Font));
+ sw.WriteLine(cb_rx_autosync.Checked ? "1" : "0");
}
}
catch { }
}
+ String FontSerialize(Font value)
+ {
+ String str;
+
+ str = value.Name + "," + value.Size.ToString() + ",";
+ if (value.Style == FontStyle.Regular)
+ {
+ str += "R";
+ }
+ else
+ {
+ if (value.Bold) str += "B";
+ if (value.Italic) str += "I";
+ if (value.Underline) str += "U";
+ }
+
+ return str;
+ }
+
+ Font FontDeserialize(String s)
+ {
+ String[] sa = s.Split(',');
+
+ FontStyle fs = FontStyle.Regular;
+ if (sa[2] == "B") fs = FontStyle.Bold;
+ if (sa[2] == "I") fs = FontStyle.Italic;
+ if (sa[2] == "U") fs = FontStyle.Underline;
+
+ FontFamily ff = new FontFamily(sa[0]);
+ float size = (float)statics.MyToDouble(sa[1]);
+
+ Font fnt = new Font(ff, size, fs);
+
+ return fnt;
+ }
+
+ String CRLFtoParagr(String s)
+ {
+ s = s.Replace('\n', '§');
+ s = s.Replace("\r", String.Empty);
+ // make String 200 chars long, for exact storage position in cfg file
+ s = s.PadRight(210);
+ s = s.Substring(0, 200);
+ return s;
+ }
+
+ String ParagrToCRLF(String s)
+ {
+ s = s.Replace("§", "\r\n").TrimEnd(new char[] {' '});
+ return s;
+ }
+
+
+ void initRttyDefString(int i)
+ {
+ switch(i)
+ {
+ case 0:
+ Rtty_deftext[0] = "\r\n\r\nCQ CQ CQ de %m CQ CQ CQ de %m pse k k k\r\n%r"; // CQ call
+ break;
+ case 1:
+ Rtty_deftext[1] = "\r\n\r\n%c de %m pse k k k\r\n%r"; // answer CQ call
+ break;
+ case 2:
+ Rtty_deftext[2] = "\r\n\r\n%c de %m\r\n"; // start TX
+ break;
+ case 3:
+ Rtty_deftext[3] = "\r\nbtu dr %n %c de %m pse k k k\r\n%r"; // end TX
+ break;
+ case 4:
+ Rtty_deftext[4] = "\r\nmany thanks for the nice QSO dr %n.\r\nHpe to see you agn. gl es mny 73 %c de %m bye bye ar sk\r\n%r"; // end QSO
+ break;
+ case 5:
+ Rtty_deftext[5] = "\r\nName: %i\r\nQTH: %s\r\nQTHLOC: %q\r\n";
+ break;
+ case 6:
+ Rtty_deftext[6] = "\r\n%m station:\r\n"; // my station
+ break;
+ case 7:
+ Rtty_deftext[7] = "RYRYRYRYRYRYRYRYRYRY";
+ break;
+ default:
+ Rtty_deftext[i] = " ";
+ break;
+ }
+ }
+
private void bt_shutdown_Click(object sender, EventArgs e)
{
DialogResult dr = MessageBox.Show(statics.langstr[23], statics.langstr[22], MessageBoxButtons.YesNo);
@@ -1494,27 +1731,6 @@ namespace oscardata
setCAPvolume = tb_CAPvol.Value;
}
- private void bt_blockinfo_Click(object sender, EventArgs e)
- {
- String s;
- int[] d = new int[2];
- recfile.oldblockinfo(d);
- int failed = d[0] - d[1];
-
- s = statics.langstr[25] +
- "---------------\n" +
- "total : " + d[0] + "\n" +
- statics.langstr[26] + d[1] + "\n" +
- statics.langstr[27] + failed + "\n";
- if(failed > 1)
- {
- s += statics.langstr[28];
- }
-
- Form2_showtext sf = new Form2_showtext("Block Info",s);
- sf.ShowDialog();
- }
-
void setVoiceAudio(Byte opmode = 0)
{
/*
@@ -1762,7 +1978,6 @@ namespace oscardata
tabPage_about.Text = "About";
label_speed.Text = "Speed [bit/s]:";
label_fifo.Text = "TX Buffer:";
- bt_blockinfo.Text = "Block Info";
label_capfifo.Text = "RX Buffer:";
lb_rxsignal.Text = "RX Signal:";
lb_rxsync.Text = "RX Sync:";
@@ -1771,6 +1986,29 @@ namespace oscardata
lb_tuningqrgs.Text = "Send Mid-Frequency:";
cb_marker.Text = "2.9kHz Tuning Marker";
label13.Text = "Data Security:";
+ textBox5.Text = "Click on Callsign or Name in RX window";
+ textBox2.Text = @"Special Markers:
+%m... my call
+%i... my name
+%s... my city
+%q... my qthloc
+%c... ur call
+%n... ur name
+%r... switch to RX
+";
+ label_cfgpath_tit.Text = "Configuration stored in:";
+ label_urcall.Text = "Your Callsign:";
+ label_urname.Text = "Your Name:";
+ bt_rtty_tx.Text = "TX On/Off";
+ bt_rtty_default.Text = "set Default Text";
+ bt_rtty_cq.Text = "Call CQ";
+ bt_rtty_answerCQ.Text = "Answer CQ Call";
+ bt_rtty_endqso.Text = "End QSO";
+ bt_rtty_start.Text = "Start Transmission";
+ bt_rtty_end.Text = "End Transmission";
+ bt_rtty_myinfo.Text = "My Info";
+ bt_rtty_station.Text = "My Station";
+ textBox6.Text = "or double click in spectrum";
}
if (language == 1)
@@ -1828,6 +2066,29 @@ namespace oscardata
lb_tuningqrgs.Text = "Sende Mittenfrequenz:";
cb_marker.Text = "2,9kHz Tuning Markierung";
label13.Text = "Datensicherheit:";
+ textBox5.Text = "Klicke auf Rufzeichen und Namen im RX Fenster";
+ textBox2.Text = @"Spezialzeichen:
+%m... mein Rufzeichen
+%i... mein Name
+%s... mein Ort
+%q... mein QTHLOC
+%c... dein Rufzeichen
+%n... dein Name
+%r... schalte auf RX
+";
+ label_cfgpath_tit.Text = "Konfiguration gespeichert in:";
+ label_urcall.Text = "Dein Rufzeichen:";
+ label_urname.Text = "Dein Name:";
+ bt_rtty_tx.Text = "TX ein/aus";
+ bt_rtty_default.Text = "setze Standardtexte";
+ bt_rtty_cq.Text = "Rufe CQ";
+ bt_rtty_answerCQ.Text = "Beantworte CQ";
+ bt_rtty_endqso.Text = "Beende QSO";
+ bt_rtty_start.Text = "Start Durchgang";
+ bt_rtty_end.Text = "Beende Durchgang";
+ bt_rtty_myinfo.Text = "Meine Info";
+ bt_rtty_station.Text = "Meine Station";
+ textBox6.Text = "oder Doppelklick in Spektrum";
}
}
@@ -1873,6 +2134,8 @@ namespace oscardata
" of ", //30
"Bad blocks, retransmission required",
"Bad blocks", //32
+ "Set RTTY predefinded text messages to default values. Are you sure ?", //33
+ "Set Default Mesages", //34
};
String[] langstr_de = new String[]{
@@ -1909,6 +2172,8 @@ namespace oscardata
" von ", //30
"defekte Blöcke, Datei muss nochmal empfangen werden",
"defekte Blöcke", //32
+ "Setze RTTY Nachrichten auf die Standardtexte zurück. Sind sie sicher?", //33
+ "Setze Standardnachrichten", //34
};
private void cb_autostart_CheckedChanged(object sender, EventArgs e)
@@ -1986,6 +2251,316 @@ namespace oscardata
txdata[1] = 255 - 10;
Udp.UdpSendCtrl(txdata);
}
- }
+ bool backspace = false;
+ private void tb_rtty_TX_TextChanged(object sender, EventArgs e)
+ {
+ if (backspace)
+ {
+ backspace = false;
+ return;
+ }
+
+ if (tb_rtty_TX.Text.Length > 0)
+ {
+ char c = tb_rtty_TX.Text[tb_rtty_TX.Text.Length - 1];
+
+ c = char.ToUpper(c);
+
+ // filter allowed characters
+ bool ok = false;
+ if (c >= 'A' && c <= 'Z') ok = true;
+ if (c >= '0' && c <= '9') ok = true;
+ if (c == '\\') ok = true;
+ if (c == '(') ok = true;
+ if (c == ')') ok = true;
+ if (c == '+') ok = true;
+ if (c == '/') ok = true;
+ if (c == '-') ok = true;
+ if (c == ':') ok = true;
+ if (c == '=') ok = true;
+ if (c == '?') ok = true;
+ if (c == ',') ok = true;
+ if (c == '.') ok = true;
+ if (c == ' ') ok = true;
+ if (c == '\n') ok = true;
+
+ if (ok)
+ {
+ Byte[] txdata = new byte[2];
+ txdata[0] = statics.rttykey;
+ txdata[1] = (Byte)c;
+ Udp.UdpSendCtrl(txdata);
+ }
+ }
+ }
+
+ /*
+ %m ... my call
+ %i ... my name
+ %s ... my city
+ %q ... my qthloc
+ %c ... ur call
+ %n ... ur name
+ %r ... stop TX
+ */
+ // convert short forms into text
+ String realRTTYtext(String s)
+ {
+ String sdec = s;
+ sdec = sdec.Replace("%m", tb_callsign.Text.Trim().ToUpper());
+ sdec = sdec.Replace("%i", tb_myname.Text.Trim().ToUpper());
+ sdec = sdec.Replace("%s", tb_myqth.Text.Trim().ToUpper());
+ sdec = sdec.Replace("%q", tb_myqthloc.Text.Trim().ToUpper());
+ sdec = sdec.Replace("%c", tb_urcall.Text.Trim().ToUpper());
+ sdec = sdec.Replace("%n", tb_urname.Text.Trim().ToUpper());
+ if(tb_urname.Text.Length == 0)
+ {
+ sdec = sdec.Replace(" dr ", " ");
+ }
+ sdec = sdec.Replace("%r", "[RX]");
+
+ return sdec.ToUpper();
+ }
+
+ int selected_rtty_deftext = 0;
+
+ void ShowRTTYtext(int selnum, int nosend = 0)
+ {
+ if (selnum >= Rtty_deftext_anz) return;
+
+ selected_rtty_deftext = selnum;
+
+ if (rb_rtty_normal.Checked)
+ {
+ bt_rtty_default.Enabled = textBox2.Enabled = false;
+ tb_rtty_deftext.ReadOnly = true;
+ tb_rtty_deftext.Text = realRTTYtext(Rtty_deftext[selnum]);
+
+ if (nosend == 0)
+ {
+ String sx = tb_rtty_deftext.Text;
+ sx = sx.Replace("[RX]", "~");
+
+ // print also in TX window
+ String sxtx = sx;
+ sxtx = sxtx.Replace('~', ' ');
+ tb_rtty_TX.AppendText(sxtx);
+
+ Byte[] tarr = statics.StringToByteArray(sx);
+
+ Byte[] txdata = new byte[4 + tarr.Length];
+ txdata[0] = statics.rttystring;
+ int len = tarr.Length;
+ txdata[1] = (Byte)(len >> 8);
+ txdata[2] = (Byte)(len & 0xff);
+ txdata[3] = (Byte)'#'; // always switch TX on before transmitting
+ for (int i = 0; i < tarr.Length; i++)
+ txdata[i + 4] = tarr[i];
+ Udp.UdpSendCtrl(txdata);
+ }
+ }
+ else if (rb_rtty_real.Checked)
+ {
+ bt_rtty_default.Enabled = textBox2.Enabled = false;
+ tb_rtty_deftext.ReadOnly = true;
+ tb_rtty_deftext.Text = realRTTYtext(Rtty_deftext[selnum]);
+ }
+ else
+ {
+ bt_rtty_default.Enabled = textBox2.Enabled = true;
+ tb_rtty_deftext.ReadOnly = false;
+ tb_rtty_deftext.Text = Rtty_deftext[selnum];
+ }
+ }
+
+ private void bt_rtty_cq_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(0);
+ }
+
+ private void bt_rtty_answerCQ_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(1);
+ }
+
+ private void bt_rtty_endqso_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(4);
+ }
+
+ private void bt_rtty_start_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(2);
+ }
+
+ private void bt_rtty_end_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(3);
+ }
+
+ private void bt_rtty_myinfo_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(5);
+ }
+
+ private void bt_rtty_station_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(6);
+ }
+
+ private void bt_rtty_RY_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(7);
+ }
+
+ private void tb_rtty_deftext_TextChanged(object sender, EventArgs e)
+ {
+ if (rb_rtty_edit.Checked)
+ {
+ try
+ {
+ Rtty_deftext[selected_rtty_deftext] = tb_rtty_deftext.Text;
+ }
+ catch
+ {
+ Rtty_deftext[selected_rtty_deftext] = "";
+ }
+ }
+ }
+
+ private void bt_rtty_default_Click(object sender, EventArgs e)
+ {
+ if (MessageBox.Show(statics.langstr[33], statics.langstr[34], MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
+ {
+ for (int i = 0; i < Rtty_deftext_anz; i++)
+ initRttyDefString(i);
+
+ ShowRTTYtext(selected_rtty_deftext);
+ }
+ }
+
+ private void rb_rtty_normal_CheckedChanged(object sender, EventArgs e)
+ {
+ if (rb_rtty_normal.Checked)
+ ShowRTTYtext(selected_rtty_deftext,1);
+ }
+
+ private void rb_rtty_edit_CheckedChanged(object sender, EventArgs e)
+ {
+ if (rb_rtty_edit.Checked)
+ ShowRTTYtext(selected_rtty_deftext, 0);
+ }
+
+ private void rb_rtty_real_CheckedChanged(object sender, EventArgs e)
+ {
+ if (rb_rtty_real.Checked)
+ ShowRTTYtext(selected_rtty_deftext, 0);
+ }
+
+ int rtty_txon = 0;
+ int rtty_sync = 0;
+ private void bt_rtty_tx_Click(object sender, EventArgs e)
+ {
+ Byte[] txdata = new byte[2];
+ txdata[0] = statics.txonoff;
+ txdata[1] = (Byte)((rtty_txon==1)?0:1);
+ Udp.UdpSendCtrl(txdata);
+ }
+
+ private void tb_rtty_TX_KeyDown(object sender, KeyEventArgs e)
+ {
+ if(e.KeyValue == 8)
+ {
+ // back space
+ backspace = true; // do not process text change
+ Byte[] txdata = new byte[2];
+ txdata[0] = statics.rttykey;
+ txdata[1] = 0x08;
+ Udp.UdpSendCtrl(txdata);
+ }
+ }
+
+ private void button1_Click_1(object sender, EventArgs e)
+ {
+ tb_rtty_RX.Text = "";
+ }
+
+ private void button3_Click(object sender, EventArgs e)
+ {
+ tb_rtty_TX.Text = "";
+ }
+
+ private void bt_rxfont_Click(object sender, EventArgs e)
+ {
+ FontDialog fontDialog1 = new FontDialog();
+ fontDialog1.Font = tb_rtty_RX.Font;
+ if (fontDialog1.ShowDialog() == DialogResult.OK)
+ {
+ tb_rtty_RX.Font = fontDialog1.Font;
+ }
+ }
+
+ private void button4_Click(object sender, EventArgs e)
+ {
+ FontDialog fontDialog1 = new FontDialog();
+ fontDialog1.Font = tb_rtty_TX.Font;
+ if (fontDialog1.ShowDialog() == DialogResult.OK)
+ {
+ tb_rtty_TX.Font = fontDialog1.Font;
+ }
+ }
+
+ private void panel_txspectrum_DoubleClick(object sender, EventArgs e)
+ {
+ MouseEventArgs a = (MouseEventArgs)e;
+ Int16 freq = (Int16)(10 * (a.X - 16));
+
+ statics.tune_frequency = freq;
+
+ Byte[] txdata = new byte[3];
+ txdata[0] = statics.setfreq;
+ txdata[1] = (Byte)(freq >> 8);
+ txdata[2] = (Byte)(freq & 0xff);
+ Udp.UdpSendCtrl(txdata);
+
+ }
+
+ private void button5_Click(object sender, EventArgs e)
+ {
+ Byte[] txdata = new byte[1];
+ txdata[0] = statics.rtty_stopTX;
+ Udp.UdpSendCtrl(txdata);
+ }
+
+ private void bt_rtty_text1_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(8);
+ }
+
+ private void bt_rtty_text2_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(9);
+ }
+
+ private void bt_rtty_text3_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(10);
+ }
+
+ private void bt_rtty_text4_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(11);
+ }
+
+ private void bt_rtty_text5_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(12);
+ }
+
+ private void bt_rtty_text6_Click(object sender, EventArgs e)
+ {
+ ShowRTTYtext(13);
+ }
+ }
}
diff --git a/oscardata/oscardata/Form1.resx b/oscardata/oscardata/Form1.resx
index ddd53e9..242b4af 100755
--- a/oscardata/oscardata/Form1.resx
+++ b/oscardata/oscardata/Form1.resx
@@ -136,9 +136,9 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
- ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABw
- FwAAAk1TRnQBSQFMAgEBDQEAAUABBgFAAQYBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
- AwABQAMAAUADAAEBAQABCAYAARAYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAA+
+ JQAAAk1TRnQBSQFMAgEBFwEAAYgBDAGIAQwBEAEAARABAAT/AQkBAAj/AUIBTQE2AQQGAAE2AQQCAAEo
+ AwABQAMAAWADAAEBAQABCAYAARgYAAGAAgABgAMAAoABAAGAAwABgAEAAYABAAKAAgADwAEAAcAB3AHA
AQAB8AHKAaYBAAEzBQABMwEAATMBAAEzAQACMwIAAxYBAAMcAQADIgEAAykBAANVAQADTQEAA0IBAAM5
AQABgAF8Af8BAAJQAf8BAAGTAQAB1gEAAf8B7AHMAQABxgHWAe8BAAHWAucBAAGQAakBrQIAAf8BMwMA
AWYDAAGZAwABzAIAATMDAAIzAgABMwFmAgABMwGZAgABMwHMAgABMwH/AgABZgMAAWYBMwIAAmYCAAFm
@@ -165,79 +165,137 @@
AcwBAAH/AZkB/wEAAf8BzAIAAf8BzAEzAQAB/wHMAWYBAAH/AcwBmQEAAf8CzAEAAf8BzAH/AQAC/wEz
AQABzAH/AWYBAAL/AZkBAAL/AcwBAAJmAf8BAAFmAf8BZgEAAWYC/wEAAf8CZgEAAf8BZgH/AQAC/wFm
AQABIQEAAaUBAANfAQADdwEAA4YBAAOWAQADywEAA7IBAAPXAQAD3QEAA+MBAAPqAQAD8QEAA/gBAAHw
- AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wQAARoBmQEbAf8CAAH/
- AfQBGgGZAf81AAF0ATIBNwFLAfEB9AF0ATEBOAEyAfM1AAF5AzgCNwM4ATEB8zUAAZkEOAH7AzgBMQH0
- NQABmQg4ATEB9jUAAZkEegJZAjgBMQH0MwAB/wGZAVgIegFZAXkB/zIAARoBWQt6AVIB/zAAAfQBeQ16
- ARowAAHzAVIMegF5AZkxAAH2ARsBGgGZBnoBmQEaARsB9AH/NQABGwF6ApoBegF5Af85AAH/AXkCoAF6
- AfY7AAH2AXoBoAEaPQABGwGaAf93AAH/DPIB9AH/BwABBwHsAeoBbQHqAewBvBMABP8B9AHzAQcB7wHw
- AfQF/wEAAZMDRQZGBEUB9AkAAW0BEwHsBgAC/wn2Af8FAAH0AfAB9wEUARECEAYAAf8BbwIfAUYGJQFG
- ASQBHwFFAfIDAAH0BfMBbQFDAZIFAAH/AZkBUwkyAXUB/wEAAf8BBwHwAfEB9AH/AfMCBwHyAwAB/wIA
- Af8BbwEfAW8B9AF0ASUCJgIlARsBkwEfAUUB8gMAAe0BEQFEAQEBRAIRAQ8BkgUAAf8CUwGaAVMBwwFZ
- AcMBWQQyAfYBAAH/AfIB8AERAfQHAAHxAUMB8wEAAf8BbwEfAZMC8wF1AiwBTQHxAfMB8AFFASQB8gQA
- Af8BRQEfAW4B/wHrAQ4B7QUAAf8BMgFTARoBWQH/AVkB/wFZBDIB9gEAAfQB7AETAQ8B8gcAAe8BEQEV
- AfEB/wFvAR8BJAGTAfIB8QF1ASwBvAHxAbwBJAEfASQB8gUAAW8BIAGTAQABbQEAAe0FAAH/AzIBmgHD
- AVkB/wE4BDIB9gEAAfQBDgHqARAB8gcAAe8BQwEVAZIB/wFvAh8BJAGTAfEB8AK8AQcBRgMfAfIFAAFv
- ASABkwEAAW0BAAHtBQAB/wEyAVMBGgGaAVMBmgF6BTIB9gEAAfQB6gHrAUMB8gcAAe8BEwHqAQcB/wFv
- AQEBHwEkAUYBHAHxAfABBwElAh8BAQEfAfIFAAFvASABkwEAAesBEAHtBQAB/wEsAjIBWQH2ARoBUwUy
- AfYCAAEHAe0BFAHyBwAB7wFtAewB8AH/AW8BRQFGAUwBbwPxAfABkwFvAUYCRQHyBAAB/wFuASABkwEA
- AesBDwGSAwAB8wEAAf8BUwF6AcMBGgGaAXoBWQJ6A1MB/wIAAfIBvAESAfMHAAEHAesB8AHzAf8EbwHx
- AfIBvAEHAfEB8gGTA28B8gQAAfMBCwEfAZMBAAHrAREBkgMAARMBAAH/AVMDdQR6BHUB/wIAAfQBvAH/
- CQAB/wHvAf8BAAJvAZMC8wG8AZMBbwEHAfIB8wGTAm8B8wQAAfQBDwEBAZMBAAHrAUMBkgEAAf8BvAER
- AQAB/wFTCnoBdQH/AgAB/wGSAfQJAAHyAe8B/wEAAm8BvAHzAfAEbwHvAvMBkwFvAfMEAAH/AREBEAFD
- AW0BQwIVAW0BFAERARQBAAH/AVMKegF1Af8DAAH/AfIJAAHyAwADkwEHBpMB7wOTAfMB9AFvAgAB/wIS
- AW0D7QFEAu0B7AGSAQAB/wF1CpoBegH/BAABvAHvAf8FAAH0AewB8QMADpMB8wH/AUUB/wIAARwB7QHv
- AgAB8QFFBQAB/wEbAXoJdQEaAf8EAAH/AkMBvAL/AfQBBwEQAW0B/wMAAfMMkwEaAv8CbgLvAW4B9wHs
- Ae8BkwJuBgAM/wYAAf8B7wETAw4BFAEHAf8TAAH/C28bAAH/AfMB/wYABP8C9AHvAewBkgHyAfQF/wMA
- C/8CAAH/AfAB7wHyAf8HAAH/AfMBGgH/EwAB9AESAewE7wHsAfAFAAH/AfQK8gHzAf8BAAH/AQcB/wHv
- AfIB/wUAAf8B8gFSATgBGgQAAfQBCAwAAfAC7ALwAv8B9AGSAfAB7QQAAf8B8gHxAQgCvAHwAQgEGwLz
- Av8BBwG8AewB7QHyAf8DAAH/AfABUgI4AZkEAAHyAU8BlwH0CQAB/wHsAW0D/wL0Av8BBwHzAQcDAAH0
- AfMBcgEoAS4BLwF4AS8ENQEbAfIB/wEAAfQBBwEUAQ8B7QH0Af8BAAH/AfIBMQE4AVkBdAH/BAAB8gIt
- AU8B/wgAAeoBbQH0AbwD9AHzAfQBBwH0AZIBBwMAAfQB8wFyAigCmAIvAzUBGwHyAf8BAAH/AfQB7wET
- ARQB9wH0Af8B8wFSAlkBmQH/BQAB8gIzAS0BTwG8Af8FAAH/Ae0BvAT0AfMB8gT0AfEBBwIAAfQB8wFy
- AigB/wEIBS8BCAHyAf8DAAH/AQcBEgFDAe8BvAExATgBWQGZAf8GAAHyAjMCLQECAZgB/wQAAfAB7AH0
- AfMC9AEHAfQBGgP0AfAB7QHsAgAB9AHzAXICKAH/AfQBUAEuAXgBUAEvAbwB8gH/BAAB/wEHAhIB7QFZ
- ATIB8wH/BwAB8gIzAS0CAgEnAXIB9AMAAQcB7AL0AvMB9AEfAbwE9AHtAe8BDgEAAfQB8wFyAigB9AL/
- AbwB/wFQASgBvAHyAf8FAAH/Ae8B7AHwAfcBvAH/CAAB8gMtAgIBJwEhAUkB9AIAAbwBkgLzAfAC8wEH
- Ae0E8wHtAe8B/wEAAfQB8wFyAigBUAH0A/8BUAEoAbwB8gH/BQAB/wIHAewB6wEHAfMC/wYAAfEGTwFJ
- AZgB/wIAAf8BBwHxAfMB8gHzAZMC8wEHAvMB8QHwAQcCAAH0AfMBcgMoAZgD/wFQASgBvAHyAf8EAAH/
- AQcB8QHyAQcB7wHsAesB7AHvAfQB/wQAAfEGTwEIBQABBwHrAfMB7wHzARoD8wHwAfEB7AHzAf8CAAH0
- AfMBcgIoAVAECAFKASgBvAHyAf8DAAH0AQcBvAHyAv8B8AHsAe0B7wLtAfQEAAHxAU8EcgHxAf8FAAHz
- AfEB7AHyAfAD8wHyAbwB7AHxAe8DAAH0AfMBcgkoAbwB8gH/AgAB/wEHAfIB8wMAAfIBvAEHAbwC7wHx
- BAAB8QFyAZcBcgFJAfQIAAEHAfMB6wHvAfcBBwHvAe0BbQHwAe0B9wHtAf8BAAH0AfMBHAlyAfEB8gL/
- AfMB7wG8AfMB/wMAAfQBBwHyAQcB9AH/AfQEAAHxAnIB7wH/CgAC8wG8Ae0C7AEHAfMBBwHyAbwB9AEH
- AQAB/wHwCvMB8gH0AQAB/wIHAfMFAAH/Ae8B9AHvAfMB/wUAAfEBTwEIAf8NAAHzAbwBBwG8AfICAAHy
- AfQBAAG8AQAC/wr0Av8BAAH/AfEB8gH/BQAB/wHyAfAB8wEHAfQFAAH/AfMXAALxHAAB/wHzAf8cAAH/
- AfADmAH0IAAF/wH0Cv8B9A3yAZEB7xAAEP8QAAHxAvQC/wHvA/8B8gHxAfQBCAG7AfABkQQAAQEBHgQA
- Af8BRQEBAwAB8wHwBfIC8QbyAfABAAG8ArQLtQH/AfIC9AL/Ae8D/wHyAfEBcgFxAZEBSQFyAwABAQH5
- AUcBCwIAAf8BHgH5ARcBAQIAAfIB8wP/AfMBuwK0AQkB9AT/AfABAAH3AUMBFQJKAUQBQwERA0MBFQFD
- ARMB9AHyAvQC/wHvA/8B8gHxAUkC/wEHAXECAAGTAW8C+QFHAQsB/wELA/kBRQIAAfIB8wL/AfQBtAGz
- AgkCtAHxA/8B8AEAAfcBEQFDAkoBFQMQAhEBQwERAWYB9AHyBAcB7AG8AvACvAFJAfMB9AHxAXIDAAJv
- AiABRgEOAyABAQH/AgAB8gHzAv8CiwG0AgkBtAGLAa4D/wHwAQAB9wEQAUMCSgFEAREDEAMRARUB9AHy
- BLwBkgHwAvEB8AG8AUkB7wHwAewB7wQAAW8BTAUgAQEB/wMAAfIB8wH/AQcBhgGtAbQBCQG6AbMBrQGG
- AQcC/wHwAQAB9wIUAkoBFAERARABDwQOARUB9AHyAfQBBwEIAf8BBwH/AfIB/wHzAfEB8AFJAQ0B7QH/
- BQABbwFMAyABHwH/BAAB8gHzAf8BtQGGArQCswGtAosBrgL/AfEBAAHvAusBbQHqARIBFAEVAREBEAIP
- ARABFQH0AfIC8wEHAfQBBwH/AbwB/wHzAfED/wHyAf8EAAH/AR8DRgFvAUYBHwQAAfIB8wH/AbUBhgG7
- AQkBtAGtAosBzwGuAv8B8QEAAQcBkwF0AXkCegJTAkwDKwFLAfQB8gHzAQcBvAH0AQcB/wHwAf8B8wHy
- A/8B8wQAAf8BHwNGAXQCRgFvAR8DAAHyAfMB/wK1AgkBtAKLAYYBiwG1Av8B8QEAAQcBlAGaAqABegF1
- AlMETQFvAfQB8gG8AwcB9wG8BPAB8wH0Af8B8wMAAf8BHwNvAQEBbgF0Am8BFgEfAgAB8gHzAf8B8wG1
- AQcBCQG0Ac8CiwGuAfQC/wHxAQABBwKUA5oDdQLjAhcBbwH0BfMBBwP0AfMB8gP/AfMDAAEaAUwCFgEf
- Af8BAAFvAxYBHwIAAfIB8wL/AfABtQEJAa4BtAGuAc8BvAP/AfEBAAEHBrcDlAOxAY4B9ALzAggB8wG8
- A/QB8wHyA/8B8wQAARoBTAEfAf8DAAFvARYBHwMAAvID8wG8ArUBrgG1AbwE8wHxAQABBwHPDLUB9ALz
- AfIBBwHzAfAE8wHyA/QB8wUAARoB/wUAAZMEAAHyCfAC7wO1AfABAAG7A60DswK0BdUB9ALzAvAB8wHw
- BfMD9AHzEQAB9Am8AQcBvAMHAfIBAAHyBQkE3QQZAv8G8gfzAf8xAAFCAU0BPgcAAT4DAAEoAwABQAMA
- AUADAAEBAQABAQYAAQIWAAP/AQAB4QGDBgAB4AEDBgAB4AEDBgAB4AEDBgAB4AEDBgAB4AEDBgABgAEB
- BgABgBcAAYAHAAH4AQ8GAAH4AR8GAAH8AT8GAAH+AT8GAAL/BgABgAEAAf4BAwL/AYABAAGAAQAB/wGP
- AcABAwHgAT8CAAHgAQ8BgAEBAQABOwIAAeABDwGAAQEBBwHxAgAB8AEPAYABAQEHAfACAAH4AY8BgAEB
- AQcB8AIAAfgBjwGAAQEBBwHwAgAB+AGPAYABAQGHAfACAAHwAY4BgAEBAYcB8AIAAfABjgGAAQEBjwH4
- AYABAAHwAYgBgAEBAY8B+AGAAQAB8AEAAYABAQHPAfsBgAEAATABAAGAAQEC4wGAAQABGAHPAYABAQHg
- AQMBgAIAAQ8BwAEDAfABBwL/AQABDwL/Af4BPwIAAeABAwEHAfAC/wHgAQ8BgAEBAQMB4AHzAf8BwAEH
- AYABAAEBAcAB8AH/AYABAwGAAQACgAHwAX8BgAEDAYABAAGAAQEB8AEfAQABAQGAAQAB4AEDAfABDwEA
- AQEBgAEAAfABBwHwAQcCAAGAAQAB+AEPAfABAwIAAYABAAH4AQMB8AEDAQABAQGAAQAB8AEAAfABDwGA
- AQEBgAEAAeABAAHwAQ8BgAEDAYABAAHDAYAB8AE/AcABAAGAAQABAwGAAfABfwHgAQABgAEBAQ8BgQHw
- Af8B+AEyAYABAQEPAYEB8wL/AfkD/wHjA/8BwAT/BAAC/wIAAv8CAAHzAccCAAGAAwAB4QGDAgABgAMA
- AcABAwIAAYADAAHgAQMCAAGAAwAB8AEHAgABgAMAAfgBDwIAAYADAAHwAQ8CAAGAAgABAQHgAQcCAAGA
- AgABAQHAAQMCAAGAAgABAQHAAYMCAAGAAgABAQHhAccCAAGAAgABAQHzAe8CAAGAAgABAQL/AgABgAIA
- AQEG/ws=
+ AfsB/wEAAaQCoAEAA4ADAAH/AgAB/wMAAv8BAAH/AwAB/wEAAf8BAAL/AgAD/wQAAf8B8gHvAesB6gES
+ AW0BkgHwAf8GAAH/AfIB7wHsAeoBEgFtAZIB8AH/CAAB9AXyAf8XAAHvARIBEwHrAe0BkgHsARIBEwFt
+ AfQFAAHvAhIB6wKSAewCEgFtAfQHAAH0AQcCDgFtAfMB/xUAAf8BkgESAewBBwHyAvMB8gHxAZIB6gHs
+ AfQCAAH/AfcB6gHsAbwB8gLzAfIB8QH3AeoB7AH0CAABbQEPAfIXAAEHARIB7QHxAfMB9AL/AvQB8gG8
+ AeoBbQH/AQABBwHqAZIB8QHzAfQC/wL0AfIBvAJtAf8HAAHsAREB8xYAAf8BbQHrAfEB9AH/AesBBwP/
+ AfQB8gH3ARIB8AH/AusB8QH0Av8BGgG9Av8B9AHyAfcB6gHwBwAB7AEVAfMWAAHwARIBvAHzAv8BEwEV
+ AewB9AL/AfQB8QESAZIB8AHqAbwB8wL/AWkCIAFGAfQB/wH0AfEB6gH3BwAB7QETAfMWAAHsAW0B8QH0
+ Av8BQwIQAeoBBwL/AfIB7AHrAe0B6wHxAfQB/wEWBCABRgL/AfIC7AcAAZIB6gHzFgABbQHsAfIB9AL/
+ ARECDgERARMBkgH/AfMB9wHqAesB7AHyAfQB/wEXASAC+QIgAb0B/wHzAfcBbQcAAfcB6wHzFgAB6wHs
+ AfEB9AL/AW0BEwEUARMB6wG8Af8B8gGSAW0C7AHxAfQB/wEWARcCRwFGASABGgH/AfIBkgFtBwAB7wHs
+ AfMWAAH3AW0B8QH0Av8B6wFtARIB7QL/AfQB8gLsAe8B6wHxAfQB/wG9ARcDRgFvAf8B9AHyAuwHAAHv
+ AewB8xYAAfMBbQHvAfQC/wLsAbwD/wHzAbwB6gHvAfMBbQHvAfQC/wG9ARYBbwGUAv8B8wG8AW0BBwcA
+ AfcB6wHzFwAB7QFtAfAB9AH/Ae8E/wH0AfEB7QFtAfIBAAGSAW0B8AH0Bv8B9AHxAe0B6wHyAgAB7wH/
+ AwAB9wFtAfMDAAHxEwAB8gFtAewB8QHzBPQB8wHxAZIBbQEHAf8BAAHyAesB7AHxAfME9AHzAfEB9wHr
+ AQcB/wIAAe0B8wMAAZIB6gHzAwAB7xQAAfEB6wFtAe8B8QLyAfEBvAHsAesB7wQAAfEB7AFtAe8B8QLy
+ AfEBvAHsAesB7wQAAe0B7AH0Av8B7QETAfMC/wEHAW0VAAHyAZIB6wTsAesB7AG8Af8FAAHyAZIF7AHr
+ AewB8AH/BAABBwrsAfcXAAHzAe8C7AHvAfEB/wkAAfMB7wHtAewB7wHxAf80AAH/AfQC8wHyAvEB8ALx
+ AbwBuwG0AQkB9AH/EwAB/wHyAe8B6wHqARIBbQGSAfAB/wgAAf8B8wH/CAAB9ALxBvQBuwGsAbMB7wGt
+ AYoB9BMAAe8BEgETAesB7QGSAewBEgETAW0B9AQAAfEBswHzAfEB8wHyAfEB8gYAAf8B8QHyBvQBtAGK
+ AbQB8QGtAYoBuwUAAv8B9AHzAfQE/wMAAf8BkgESAewBBwHyAvMB8gHxAZIB6gHsAfQCAAH/ArMB7AHt
+ AQcB8wEAAfAHAAHyAfMG9AKLAbQB/wGtAYoBtAQAAf8B7wGLAWwCZgLqAWYBbAG8Af8BAAEHARIB7QHx
+ AfMB9AL/AvQB8gG8AeoBbQH/AQAB8gEZAbsCvAEHAfcB7QGSAbwB8gL/AQAB/wEAAfQB8gHzBPQB/wG0
+ Aa0BswG7Aq0BuwMAAfABZgFDARADDwIOAQABvAIAAf8BbQHrAfEB9AHxBfAB8wHyAfcBEgHwAQAB8wEJ
+ AfAC8gHxAbwBBwH3AewB6wHqAewBvAG0AwAB9AHzAfIBmQEcAfEBuwGzAbQB/wG0AbMB8wIAAfQBEQEO
+ AQ8BEAENAhABDwIOAe8CAAHwARIBvAHzAf8B7AETAhQBEwHqAfAB9AHxARIBkgEAAv8B8gL0AfMB8gHx
+ AbwBBwH3AewBbQGKAfAFAAHzAZMBHAG8Af8B8gEJAbUBCQHzAf8BAAH/ARMBDgEQAg0CZQINARABDgEV
+ Af8BAAHsAW0B8QH0Af8B7AEVAREBEAFDARQB8AH/AfIB7AHrAwAB/wHyAfQB/wH0AfMB8gHwAbwB7wGR
+ AbMB/wUAAfECmgGTAf8HAAHzAQ4EDQNmAkMBEAEOAfMBAAFtAewB8gH0Af8B6wERAg4BEAEVAfAB/wHz
+ AfcB6gQAAf8B8gH0Af8C9AHzAfEBBwGzAfQGAAEaA5oB9AcAAfMBEAFDARUDZgNsARIBEwEUAfMBAAHr
+ AewB8QH0Af8B7QFtARMCFQETAfAB/wHyAZIBbQUAAfQB8gP/AfQB8gG0AQkGAAH0AZoDGgEbBwAB9AJm
+ AmwB6gFsBW0B6gH/AQAB9wFtAfEB9AH/AfcB6wFtAxIB8AH0AfIC7AYAAfQB8wP/AQkB2wH/BQAB/wGZ
+ BRoHAAH/AewDrgHrAa4C7AGuAuwB7wIAAfMBbQHvAfQB/wEHAfcB7QPsAfEB8wG8AeoB7wcAAfQB8wH/
+ AfMB2wHzBgAB/wEcAhoBGwEaAZkIAAH/BOwE7QL3AfQDAAHtAW0B8AH0Bv8B9AHxAe0BbQHyBwAB/wH0
+ AfICCQgAAXMBmgG8ApkBkwkAAfQB7wT3Au8BBwH0BAAB8gFtAewB8QHzBPQB8wHxAZIBbQEHAf8JAAHz
+ AdsB9AgAAbwCbgIcAbwLAAHzAQcC7wG8AfMB/wYAAfEB6wFtAe8B8QLyAfEBvAHsAesB7wsAAfQBGQH/
+ CAAB/wEHAW4BHAEHAfQZAAHyAZIB6wTsAesB7AG8Af8YAAL/HQAB8wHvAuwB7wHxAf8HAAEaAZkBGwH/
+ AgAB/wH0ARoBmQH/AwAC/wHyBrwB8AK8AfQC/wEAAf8B8wHyAfMH8gLzAv8BAAH/AfEBCQEZAf8BAAH/
+ AfABCQHyAZgBAgEIBQABdAEyATcBSwHxAfQBdAExATgBMgHzBQAB7wHwBv8B8gGSAfMEAAETAW0G7AHt
+ AewB6wHqAwABCQGKAbMBsgHzAQABuwKzAbIBTwFVAZgFAAF5AzgCNwM4ATEB8wIAAf8C9AHvAewC8wP0
+ AfMB7wFtAfIB9AH/AgABBwP0AUoBKQIDA/QB8QIAAf8BuwGzAdQBswG7AfMBtAGzAXEBSQFPAVUBcgGY
+ AQgDAAGZBDgB+wM4ATEB9AIAAf8CBwHsARQCBwK8AgcB7AESAgcB8QIAAQcBHAFzAZkBSwIrAUwB8AJz
+ AQcCAAEJAYoBiwLUA4oBkAFyA5gBlwFPAS4DAAGZCDgBMQH2AgAB9ALxAewIFQESAfABvAHyAgABBwHv
+ AQcBmQFLAisBTAEaA+8CAAGLAbMC1APaAtsBnQFyAZcBmAFyAZgBCAMAAZkEegJZAjgBMQH0AgAO9AHw
+ AfMCAAHvAZkBvAGZAUsBJAEqAUsBvAIHAe8CAAKzAtQD2gTbAZ0BCAFyAwAB/wGZAVgIegFZAXkB/wEA
+ AfQC8AH3Am0B6wPsAm0B6wLwAfICAAHvAZkBvAEHAUsBKgJLAfECmQEHAgAB9AEJArMB2wGzAbkBugGz
+ AbkB2wGdAZgBCAMAARoBWQt6AVIC/wHzAfQB7wgSAW0C9AHzAQAB8wH3A/MEGgPzAbwB8AH/AgAB8gGz
+ AdsBugG0AQABCQG0AdsBswGdAf8CAAH0AXkNegEaAf8BBwG8Ae8E6wHsA+sB7AG8AQcB8gEAAfIBEgEH
+ CPQB8wHrAQcB/wIAAf8BswLbAawB8wHyAbMC2wGzAfMB9AH/AfMBUgx6AXkBmQEAAu8D7AXtAewBEwHv
+ AZIB8gIAAfQBEgEHBvIB8AESAQcDAAH/AYoBkALcAbMCiwGzAtwBswGLAbIBGQEAAfYBGwEaAZkGegGZ
+ ARoBGwH0Af8BAAHzAfIBBwG8AfAB8QHyAvEB8AG8AewB8wHyAf8DAAHyAeoB7wTyAfACbQHzAwAB8gGz
+ C9wBuQG7BQABGwF6ApoBegF5Af8HAALxAfME9AHzAfEB7QcAAfQBEgHvArwBBwETAesBvAH0AwAB8wG6
+ AhkC3AIJARkBCQLcAwkFAAH/AXkCoAF6AfYIAALzBv8B9AG8CAAB8gESAZIBBwFtAQcB7wEHAfQDAAH/
+ ARkBugGzAhkBswK6AbMCCQGzAQkB9AYAAfYBegGgARoJAAH0CP8B8wkAAfQBEgEUAQcBAAH0AfMB/wUA
+ Af8BsgEJARkBugEAAf8BsgEJARkBugkAARsBmgH/CQAB9AjwAfMKAAHzAbwB/woAAgkBuQEJAQAB/wG7
+ AQkBuQEJFQAK/xgAAfQB/wQAAfQB/wQAAf8M8gH0Af8HAAEHAewB6gFtAeoB7AG8EwAE/wH0AfMBBwHv
+ AfAB9AX/AQABkwNFBkYERQH0CQABbQETAewGAAL/CfYB/wUAAfQB8AH3ARQBEQIQBgAB/wFvAh8BRgYl
+ AUYBJAEfAUUB8gMAAfQF8wFtAUMBkgUAAf8BmQFTCTIBdQH/AQAB/wEHAfAB8QH0Af8B8wIHAfIDAAH/
+ AgAB/wFvAR8BbwH0AXQBJQImAiUBGwGTAR8BRQHyAwAB7QERAUQBAQFEAhEBDwGSBQAB/wJTAZoBUwHD
+ AVkBwwFZBDIB9gEAAf8B8gHwAREB9AcAAfEBQwHzAQAB/wFvAR8BkwLzAXUCLAFNAfEB8wHwAUUBJAHy
+ BAAB/wFFAR8BbgH/AesBDgHtBQAB/wEyAVMBGgFZAf8BWQH/AVkEMgH2AQAB9AHsARMBDwHyBwAB7wER
+ ARUB8QH/AW8BHwEkAZMB8gHxAXUBLAG8AfEBvAEkAR8BJAHyBQABbwEgAZMBAAFtAQAB7QUAAf8DMgGa
+ AcMBWQH/ATgEMgH2AQAB9AEOAeoBEAHyBwAB7wFDARUBkgH/AW8CHwEkAZMB8QHwArwBBwFGAx8B8gUA
+ AW8BIAGTAQABbQEAAe0FAAH/ATIBUwEaAZoBUwGaAXoFMgH2AQAB9AHqAesBQwHyBwAB7wETAeoBBwH/
+ AW8BAQEfASQBRgEcAfEB8AEHASUCHwEBAR8B8gUAAW8BIAGTAQAB6wEQAe0FAAH/ASwCMgFZAfYBGgFT
+ BTIB9gIAAQcB7QEUAfIHAAHvAW0B7AHwAf8BbwFFAUYBTAFvA/EB8AGTAW8BRgJFAfIEAAH/AW4BIAGT
+ AQAB6wEPAZIDAAHzAQAB/wFTAXoBwwEaAZoBegFZAnoDUwH/AgAB8gG8ARIB8wcAAQcB6wHwAfMB/wRv
+ AfEB8gG8AQcB8QHyAZMDbwHyBAAB8wELAR8BkwEAAesBEQGSAwABEwEAAf8BUwN1BHoEdQH/AgAB9AG8
+ Af8JAAH/Ae8B/wEAAm8BkwLzAbwBkwFvAQcB8gHzAZMCbwHzBAAB9AEPAQEBkwEAAesBQwGSAQAB/wG8
+ AREBAAH/AVMKegF1Af8CAAH/AZIB9AkAAfIB7wH/AQACbwG8AfMB8ARvAe8C8wGTAW8B8wQAAf8BEQEQ
+ AUMBbQFDAhUBbQEUAREBFAEAAf8BUwp6AXUB/wMAAf8B8gkAAfIDAAOTAQcGkwHvA5MB8wH0AW8CAAH/
+ AhIBbQPtAUQC7QHsAZIBAAH/AXUKmgF6Af8EAAG8Ae8B/wUAAfQB7AHxAwAOkwHzAf8BRQH/AgABHAHt
+ Ae8CAAHxAUUFAAH/ARsBegl1ARoB/wQAAf8CQwG8Av8B9AEHARABbQH/AwAB8wyTARoC/wJuAu8BbgH3
+ AewB7wGTAm4GAAz/BgAB/wHvARMDDgEUAQcB/xMAAf8LbxsAAf8B8wH/BgAE/wL0Ae8B7AGSAfIB9AX/
+ AwAL/wIAAf8B8AHvAfIB/wcAAf8B8wEaAf8TAAH0ARIB7ATvAewB8AUAAf8B9AryAfMB/wEAAf8BBwH/
+ Ae8B8gH/BQAB/wHyAVIBOAEaBAAB9AEIDAAB8ALsAvAC/wH0AZIB8AHtBAAB/wHyAfEBCAK8AfABCAQb
+ AvMC/wEHAbwB7AHtAfIB/wMAAf8B8AFSAjgBmQQAAfIBTwGXAfQJAAH/AewBbQP/AvQC/wEHAfMBBwMA
+ AfQB8wFyASgBLgEvAXgBLwQ1ARsB8gH/AQAB9AEHARQBDwHtAfQB/wEAAf8B8gExATgBWQF0Af8EAAHy
+ Ai0BTwH/CAAB6gFtAfQBvAP0AfMB9AEHAfQBkgEHAwAB9AHzAXICKAKYAi8DNQEbAfIB/wEAAf8B9AHv
+ ARMBFAH3AfQB/wHzAVICWQGZAf8FAAHyAjMBLQFPAbwB/wUAAf8B7QG8BPQB8wHyBPQB8QEHAgAB9AHz
+ AXICKAH/AQgFLwEIAfIB/wMAAf8BBwESAUMB7wG8ATEBOAFZAZkB/wYAAfICMwItAQIBmAH/BAAB8AHs
+ AfQB8wL0AQcB9AEaA/QB8AHtAewCAAH0AfMBcgIoAf8B9AFQAS4BeAFQAS8BvAHyAf8EAAH/AQcCEgHt
+ AVkBMgHzAf8HAAHyAjMBLQICAScBcgH0AwABBwHsAvQC8wH0AR8BvAT0Ae0B7wEOAQAB9AHzAXICKAH0
+ Av8BvAH/AVABKAG8AfIB/wUAAf8B7wHsAfAB9wG8Af8IAAHyAy0CAgEnASEBSQH0AgABvAGSAvMB8ALz
+ AQcB7QTzAe0B7wH/AQAB9AHzAXICKAFQAfQD/wFQASgBvAHyAf8FAAH/AgcB7AHrAQcB8wL/BgAB8QZP
+ AUkBmAH/AgAB/wEHAfEB8wHyAfMBkwLzAQcC8wHxAfABBwIAAfQB8wFyAygBmAP/AVABKAG8AfIB/wQA
+ Af8BBwHxAfIBBwHvAewB6wHsAe8B9AH/BAAB8QZPAQgFAAEHAesB8wHvAfMBGgPzAfAB8QHsAfMB/wIA
+ AfQB8wFyAigBUAQIAUoBKAG8AfIB/wMAAfQBBwG8AfIC/wHwAewB7QHvAu0B9AQAAfEBTwRyAfEB/wUA
+ AfMB8QHsAfIB8APzAfIBvAHsAfEB7wMAAfQB8wFyCSgBvAHyAf8CAAH/AQcB8gHzAwAB8gG8AQcBvALv
+ AfEEAAHxAXIBlwFyAUkB9AgAAQcB8wHrAe8B9wEHAe8B7QFtAfAB7QH3Ae0B/wEAAfQB8wEcCXIB8QHy
+ Av8B8wHvAbwB8wH/AwAB9AEHAfIBBwH0Af8B9AQAAfECcgHvAf8KAALzAbwB7QLsAQcB8wEHAfIBvAH0
+ AQcBAAH/AfAK8wHyAfQBAAH/AgcB8wUAAf8B7wH0Ae8B8wH/BQAB8QFPAQgB/w0AAfMBvAEHAbwB8gIA
+ AfIB9AEAAbwBAAL/CvQC/wEAAf8B8QHyAf8FAAH/AfIB8AHzAQcB9AUAAf8B8xcAAvEcAAH/AfMB/xwA
+ Af8B8AOYAfQgAAX/AfQK/wH0DfIBkQHvEAAQ/xAAAfEC9AL/Ae8D/wHyAfEB9AEIAbsB8AGRBAABAQEe
+ BAAB/wFFAQEDAAHzAfAF8gLxBvIB8AEAAbwCtAu1Af8B8gL0Av8B7wP/AfIB8QFyAXEBkQFJAXIDAAEB
+ AfkBRwELAgAB/wEeAfkBFwEBAgAB8gHzA/8B8wG7ArQBCQH0BP8B8AEAAfcBQwEVAkoBRAFDAREDQwEV
+ AUMBEwH0AfIC9AL/Ae8D/wHyAfEBSQL/AQcBcQIAAZMBbwL5AUcBCwH/AQsD+QFFAgAB8gHzAv8B9AG0
+ AbMCCQK0AfED/wHwAQAB9wERAUMCSgEVAxACEQFDAREBZgH0AfIEBwHsAbwC8AK8AUkB8wH0AfEBcgMA
+ Am8CIAFGAQ4DIAEBAf8CAAHyAfMC/wKLAbQCCQG0AYsBrgP/AfABAAH3ARABQwJKAUQBEQMQAxEBFQH0
+ AfIEvAGSAfAC8QHwAbwBSQHvAfAB7AHvBAABbwFMBSABAQH/AwAB8gHzAf8BBwGGAa0BtAEJAboBswGt
+ AYYBBwL/AfABAAH3AhQCSgEUAREBEAEPBA4BFQH0AfIB9AEHAQgB/wEHAf8B8gH/AfMB8QHwAUkBDQHt
+ Af8FAAFvAUwDIAEfAf8EAAHyAfMB/wG1AYYCtAKzAa0CiwGuAv8B8QEAAe8C6wFtAeoBEgEUARUBEQEQ
+ Ag8BEAEVAfQB8gLzAQcB9AEHAf8BvAH/AfMB8QP/AfIB/wQAAf8BHwNGAW8BRgEfBAAB8gHzAf8BtQGG
+ AbsBCQG0Aa0CiwHPAa4C/wHxAQABBwGTAXQBeQJ6AlMCTAMrAUsB9AHyAfMBBwG8AfQBBwH/AfAB/wHz
+ AfID/wHzBAAB/wEfA0YBdAJGAW8BHwMAAfIB8wH/ArUCCQG0AosBhgGLAbUC/wHxAQABBwGUAZoCoAF6
+ AXUCUwRNAW8B9AHyAbwDBwH3AbwE8AHzAfQB/wHzAwAB/wEfA28BAQFuAXQCbwEWAR8CAAHyAfMB/wHz
+ AbUBBwEJAbQBzwKLAa4B9AL/AfEBAAEHApQDmgN1AuMCFwFvAfQF8wEHA/QB8wHyA/8B8wMAARoBTAIW
+ AR8B/wEAAW8DFgEfAgAB8gHzAv8B8AG1AQkBrgG0Aa4BzwG8A/8B8QEAAQcGtwOUA7EBjgH0AvMCCAHz
+ AbwD9AHzAfID/wHzBAABGgFMAR8B/wMAAW8BFgEfAwAC8gPzAbwCtQGuAbUBvATzAfEBAAEHAc8MtQH0
+ AvMB8gEHAfMB8ATzAfID9AHzBQABGgH/BQABkwQAAfIJ8ALvA7UB8AEAAbsDrQOzArQF1QH0AvMC8AHz
+ AfAF8wP0AfMRAAH0CbwBBwG8AwcB8gEAAfIFCQTdBBkC/wbyB/MB/zEAAUIBTQE+BwABPgMAASgDAAFA
+ AwABYAMAAQEBAAEBBgABAxYAA/8BAAHgAQcB4AEHAfgBDwIAAeABAwHgAQMB+AEPAgABgAEBAYABAQH+
+ AT8CAAGAAQABgAEAAf4BPwYAAf4BPwYAAf4BPwYAAf4BPwYAAf4BPwYAAf4BPwYAAf4BPwYAAf4BPwIA
+ AYABAAGAAQABzgE7AgABgAEAAYABAAHOATsCAAHAAQMBwAEDAcABAwIAAeABAwHgAQMBwAEDAgAB+AEP
+ AfgBDwL/AgAC/wIAAv8B4AEHAfgB/wIAAv8B4AEDAcABPwIAAfgBAwGAAQEBgAG/AYABAAHwAQABgAEA
+ AYABAgGAAQAB4AEDAgABgAEAAeABAAHAAQMCAAGAAQAB+AEAAYABAQIAAeABAAH4AT8BgAEBAgAB8AEB
+ AfgBPwGAAQECAAH4AQMB8AE/AYABAQIAAfwBAwHgAT8BgAEDAgAB/gEHAeABPwHAAQMBgAEAAf4BDwHw
+ AT8B4AEHAYABAAH/AY8B8AE/AfgBDwHAAQMB/wGPAfABPwL/AeABAwL/AfwD/wH4AQ8B4QGDAYABAAGA
+ AQABggEDAeABAwHgAQMBwAEDAYIBAwHgAQMCAAHAAQMCAAHgAQMCAAHAAQMCAAHgAQMCAAHAAQMCAAHg
+ AQMCAAHAAQMBAAEDAYABAQIAAcABAwEAAQMBgAMAAYABAAHBAQMEAAGAAQABwAMAAYABAAHAAQMBgAEA
+ AYABAAGAAQAB4AEDAYABAAH4AQ8B4AEHAfABAwGAAQAB+AEfAeABBwH4AQMBgAEAAfwBPwHgAQcB/AEj
+ AeABgwH+AT8B4AEHAf4BPwHwAYMC/wHgAQcC/wH5AecBgAEAAf4BAwL/AYABAAGAAQAB/wGPAcABAwHg
+ AT8CAAHgAQ8BgAEBAQABOwIAAeABDwGAAQEBBwHxAgAB8AEPAYABAQEHAfACAAH4AY8BgAEBAQcB8AIA
+ AfgBjwGAAQEBBwHwAgAB+AGPAYABAQGHAfACAAHwAY4BgAEBAYcB8AIAAfABjgGAAQEBjwH4AYABAAHw
+ AYgBgAEBAY8B+AGAAQAB8AEAAYABAQHPAfsBgAEAATABAAGAAQEC4wGAAQABGAHPAYABAQHgAQMBgAIA
+ AQ8BwAEDAfABBwL/AQABDwL/Af4BPwIAAeABAwEHAfAC/wHgAQ8BgAEBAQMB4AHzAf8BwAEHAYABAAEB
+ AcAB8AH/AYABAwGAAQACgAHwAX8BgAEDAYABAAGAAQEB8AEfAQABAQGAAQAB4AEDAfABDwEAAQEBgAEA
+ AfABBwHwAQcCAAGAAQAB+AEPAfABAwIAAYABAAH4AQMB8AEDAQABAQGAAQAB8AEAAfABDwGAAQEBgAEA
+ AeABAAHwAQ8BgAEDAYABAAHDAYAB8AE/AcABAAGAAQABAwGAAfABfwHgAQABgAEBAQ8BgQHwAf8B+AEy
+ AYABAQEPAYEB8wL/AfkD/wHjA/8BwAT/BAAC/wIAAv8CAAHzAccCAAGAAwAB4QGDAgABgAMAAcABAwIA
+ AYADAAHgAQMCAAGAAwAB8AEHAgABgAMAAfgBDwIAAYADAAHwAQ8CAAGAAgABAQHgAQcCAAGAAgABAQHA
+ AQMCAAGAAgABAQHAAYMCAAGAAgABAQHhAccCAAGAAgABAQHzAe8CAAGAAgABAQL/AgABgAIAAQEG/ws=
@@ -4495,344 +4553,6 @@
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
-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
- wIg2Hr6dReMAAAAASUVORK5CYII=
-
-
-
-
- iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAtxJREFUSEvt
- 0m1Ik1EUB3C3yk193OPUJZovm69Zznwpw2BYkE6TNDdNbaXOt+l0Pr61FNNSFMs0bUUayoKIgpaYmNN0
- U1MxJCKiD2VFkBBRBNGnovKcDG6CGFHql8IfHC6c87/nfrkWa/4PTmVOXLVBrY3SRQlJa/Vw1VxLXh2v
- Vz+jR6FO+IKlYbmT0cpRamqDY4PjzYp7FWB4awDdEx3Qp+hndDm9iUSWj5fDW+9c63ydMTPYNdMFnTOd
- +KMaphtA0iG5TWJL+df4y5huZtz3uK8vaS1hl2u3zq3G7UqeUYWtD1qw5X4zNE+fwaapJhSfF3+xLbVN
- JNHFeIW8+IhLks+Nk3WwvTX0lQvj4kVGC+wz7dmiKlFX9q0MqJ+sgbq71XBypBpqTScgpC34K1vFPkKi
- iwk0guiws8GfKoYYrDQzcHSoAHc0hr50znde+BkOCgeWt9a7XXkjBapGi6HCxKB2kMGqwXKQ6MK/cVSc
- TBJdyqfSx6juVoCmTwnMgBJKhpVQPJAOodXbnjtlbXTlK/gsz0LRubSr8VBmzoLiO0oo6leC1qgG6YU9
- c1Y5Viqy6teoDMrL85jrbKYhDnP75JA/KMcCUyIW9MsgqGzrU/ds9/ZUfSRoRpJAPSTHPKMcSgYyUNYR
- PUdlURqy5vds0mz8/LTC15k9kaAciMRsUxTmjkVBbn8kpuolmD8egyUTiVA6mjz/cBwc7IgGOyVdRq7/
- GRuFzZaActGbtN6dmDwoxkPmQFCMilExGoDJw5tR2iOA3ddojDjtBfbp/Epy7e9QSVSguMjjXUKfC0Sb
- aYgdn68JGvaNzZ/DfJC2+oBdKl1D4stDJVAhQRqP94en3ED2iI/yx3xMeuiA8Rf9gJbR9SS2Mtb7rcNC
- Cz0+qGY8MG1WgCmX/ZGO5TVxpBwWiawcN4YbvosRfVQbgoEnpdo4ey1Xb/lPggO2YZ6pjgVULJdNWmv+
- GRYW3wHoVCJ7F4lIiQAAAABJRU5ErkJggg==
-
-
-
-
- iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAtxJREFUSEvt
- 0m1Ik1EUB3C3yk193OPUJZovm69Zznwpw2BYkE6TNDdNbaXOt+l0Pr61FNNSFMs0bUUayoKIgpaYmNN0
- U1MxJCKiD2VFkBBRBNGnovKcDG6CGFHql8IfHC6c87/nfrkWa/4PTmVOXLVBrY3SRQlJa/Vw1VxLXh2v
- Vz+jR6FO+IKlYbmT0cpRamqDY4PjzYp7FWB4awDdEx3Qp+hndDm9iUSWj5fDW+9c63ydMTPYNdMFnTOd
- +KMaphtA0iG5TWJL+df4y5huZtz3uK8vaS1hl2u3zq3G7UqeUYWtD1qw5X4zNE+fwaapJhSfF3+xLbVN
- JNHFeIW8+IhLks+Nk3WwvTX0lQvj4kVGC+wz7dmiKlFX9q0MqJ+sgbq71XBypBpqTScgpC34K1vFPkKi
- iwk0guiws8GfKoYYrDQzcHSoAHc0hr50znde+BkOCgeWt9a7XXkjBapGi6HCxKB2kMGqwXKQ6MK/cVSc
- TBJdyqfSx6juVoCmTwnMgBJKhpVQPJAOodXbnjtlbXTlK/gsz0LRubSr8VBmzoLiO0oo6leC1qgG6YU9
- c1Y5Viqy6teoDMrL85jrbKYhDnP75JA/KMcCUyIW9MsgqGzrU/ds9/ZUfSRoRpJAPSTHPKMcSgYyUNYR
- PUdlURqy5vds0mz8/LTC15k9kaAciMRsUxTmjkVBbn8kpuolmD8egyUTiVA6mjz/cBwc7IgGOyVdRq7/
- GRuFzZaActGbtN6dmDwoxkPmQFCMilExGoDJw5tR2iOA3ddojDjtBfbp/Epy7e9QSVSguMjjXUKfC0Sb
- aYgdn68JGvaNzZ/DfJC2+oBdKl1D4stDJVAhQRqP94en3ED2iI/yx3xMeuiA8Rf9gJbR9SS2Mtb7rcNC
- Cz0+qGY8MG1WgCmX/ZGO5TVxpBwWiawcN4YbvosRfVQbgoEnpdo4ey1Xb/lPggO2YZ6pjgVULJdNWmv+
- GRYW3wHoVCJ7F4lIiQAAAABJRU5ErkJggg==
@@ -5212,6 +4932,344 @@
aYgdn68JGvaNzZ/DfJC2+oBdKl1D4stDJVAhQRqP94en3ED2iI/yx3xMeuiA8Rf9gJbR9SS2Mtb7rcNC
Cz0+qGY8MG1WgCmX/ZGO5TVxpBwWiawcN4YbvosRfVQbgoEnpdo4ey1Xb/lPggO2YZ6pjgVULJdNWmv+
GRYW3wHoVCJ7F4lIiQAAAABJRU5ErkJggg==
+
+
+
+
+ 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
+ wIg2Hr6dReMAAAAASUVORK5CYII=
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAtxJREFUSEvt
+ 0m1Ik1EUB3C3yk193OPUJZovm69Zznwpw2BYkE6TNDdNbaXOt+l0Pr61FNNSFMs0bUUayoKIgpaYmNN0
+ U1MxJCKiD2VFkBBRBNGnovKcDG6CGFHql8IfHC6c87/nfrkWa/4PTmVOXLVBrY3SRQlJa/Vw1VxLXh2v
+ Vz+jR6FO+IKlYbmT0cpRamqDY4PjzYp7FWB4awDdEx3Qp+hndDm9iUSWj5fDW+9c63ydMTPYNdMFnTOd
+ +KMaphtA0iG5TWJL+df4y5huZtz3uK8vaS1hl2u3zq3G7UqeUYWtD1qw5X4zNE+fwaapJhSfF3+xLbVN
+ JNHFeIW8+IhLks+Nk3WwvTX0lQvj4kVGC+wz7dmiKlFX9q0MqJ+sgbq71XBypBpqTScgpC34K1vFPkKi
+ iwk0guiws8GfKoYYrDQzcHSoAHc0hr50znde+BkOCgeWt9a7XXkjBapGi6HCxKB2kMGqwXKQ6MK/cVSc
+ TBJdyqfSx6juVoCmTwnMgBJKhpVQPJAOodXbnjtlbXTlK/gsz0LRubSr8VBmzoLiO0oo6leC1qgG6YU9
+ c1Y5Viqy6teoDMrL85jrbKYhDnP75JA/KMcCUyIW9MsgqGzrU/ds9/ZUfSRoRpJAPSTHPKMcSgYyUNYR
+ PUdlURqy5vds0mz8/LTC15k9kaAciMRsUxTmjkVBbn8kpuolmD8egyUTiVA6mjz/cBwc7IgGOyVdRq7/
+ GRuFzZaActGbtN6dmDwoxkPmQFCMilExGoDJw5tR2iOA3ddojDjtBfbp/Epy7e9QSVSguMjjXUKfC0Sb
+ aYgdn68JGvaNzZ/DfJC2+oBdKl1D4stDJVAhQRqP94en3ED2iI/yx3xMeuiA8Rf9gJbR9SS2Mtb7rcNC
+ Cz0+qGY8MG1WgCmX/ZGO5TVxpBwWiawcN4YbvosRfVQbgoEnpdo4ey1Xb/lPggO2YZ6pjgVULJdNWmv+
+ GRYW3wHoVCJ7F4lIiQAAAABJRU5ErkJggg==
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAtxJREFUSEvt
+ 0m1Ik1EUB3C3yk193OPUJZovm69Zznwpw2BYkE6TNDdNbaXOt+l0Pr61FNNSFMs0bUUayoKIgpaYmNN0
+ U1MxJCKiD2VFkBBRBNGnovKcDG6CGFHql8IfHC6c87/nfrkWa/4PTmVOXLVBrY3SRQlJa/Vw1VxLXh2v
+ Vz+jR6FO+IKlYbmT0cpRamqDY4PjzYp7FWB4awDdEx3Qp+hndDm9iUSWj5fDW+9c63ydMTPYNdMFnTOd
+ +KMaphtA0iG5TWJL+df4y5huZtz3uK8vaS1hl2u3zq3G7UqeUYWtD1qw5X4zNE+fwaapJhSfF3+xLbVN
+ JNHFeIW8+IhLks+Nk3WwvTX0lQvj4kVGC+wz7dmiKlFX9q0MqJ+sgbq71XBypBpqTScgpC34K1vFPkKi
+ iwk0guiws8GfKoYYrDQzcHSoAHc0hr50znde+BkOCgeWt9a7XXkjBapGi6HCxKB2kMGqwXKQ6MK/cVSc
+ TBJdyqfSx6juVoCmTwnMgBJKhpVQPJAOodXbnjtlbXTlK/gsz0LRubSr8VBmzoLiO0oo6leC1qgG6YU9
+ c1Y5Viqy6teoDMrL85jrbKYhDnP75JA/KMcCUyIW9MsgqGzrU/ds9/ZUfSRoRpJAPSTHPKMcSgYyUNYR
+ PUdlURqy5vds0mz8/LTC15k9kaAciMRsUxTmjkVBbn8kpuolmD8egyUTiVA6mjz/cBwc7IgGOyVdRq7/
+ GRuFzZaActGbtN6dmDwoxkPmQFCMilExGoDJw5tR2iOA3ddojDjtBfbp/Epy7e9QSVSguMjjXUKfC0Sb
+ aYgdn68JGvaNzZ/DfJC2+oBdKl1D4stDJVAhQRqP94en3ED2iI/yx3xMeuiA8Rf9gJbR9SS2Mtb7rcNC
+ Cz0+qGY8MG1WgCmX/ZGO5TVxpBwWiawcN4YbvosRfVQbgoEnpdo4ey1Xb/lPggO2YZ6pjgVULJdNWmv+
+ GRYW3wHoVCJ7F4lIiQAAAABJRU5ErkJggg==
@@ -5265,7 +5323,7 @@ VIP user: DP0GVN: https://www.awi.de/expedition/stationen/neumayer-station-iii.h
482, 17
-
+
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL
EwAACxMBAJqcGAAAA3xJREFUSEulVstL1FEYvfmYMR+LisJoU5QEiVipSLQQn6RjNMk4ig+wCJSpDCzU
@@ -5286,7 +5344,7 @@ VIP user: DP0GVN: https://www.awi.de/expedition/stationen/neumayer-station-iii.h
f/5tMeY3ET3ttnz8RoQAAAAASUVORK5CYII=
-
+
iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAL
EwAACxMBAJqcGAAAA3xJREFUSEulVstL1FEYvfmYMR+LisJoU5QEiVipSLQQn6RjNMk4ig+wCJSpDCzU
diff --git a/oscardata/oscardata/Properties/Actions-go-next-view-icon.png b/oscardata/oscardata/Properties/Actions-go-next-view-icon.png
new file mode 100644
index 0000000..9857ab1
Binary files /dev/null and b/oscardata/oscardata/Properties/Actions-go-next-view-icon.png differ
diff --git a/oscardata/oscardata/Properties/Fernschreiben für Funkamateure.pdf b/oscardata/oscardata/Properties/Fernschreiben für Funkamateure.pdf
new file mode 100644
index 0000000..1930534
Binary files /dev/null and b/oscardata/oscardata/Properties/Fernschreiben für Funkamateure.pdf differ
diff --git a/oscardata/oscardata/Properties/Lehrstuhlseminar_BenjaminKoch.pdf b/oscardata/oscardata/Properties/Lehrstuhlseminar_BenjaminKoch.pdf
new file mode 100644
index 0000000..4a651be
Binary files /dev/null and b/oscardata/oscardata/Properties/Lehrstuhlseminar_BenjaminKoch.pdf differ
diff --git a/oscardata/oscardata/Properties/Resources.Designer.cs b/oscardata/oscardata/Properties/Resources.Designer.cs
index aa88aeb..84e419f 100755
--- a/oscardata/oscardata/Properties/Resources.Designer.cs
+++ b/oscardata/oscardata/Properties/Resources.Designer.cs
@@ -60,6 +60,26 @@ namespace oscardata.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap amsat_dl_logo {
+ get {
+ object obj = ResourceManager.GetObject("amsat_dl_logo", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap answer {
+ get {
+ object obj = ResourceManager.GetObject("answer", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
@@ -150,6 +170,16 @@ namespace oscardata.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap clearscreen {
+ get {
+ object obj = ResourceManager.GetObject("clearscreen", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
@@ -160,6 +190,16 @@ namespace oscardata.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap foht {
+ get {
+ object obj = ResourceManager.GetObject("foht", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
@@ -180,6 +220,16 @@ namespace oscardata.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap home_icon {
+ get {
+ object obj = ResourceManager.GetObject("home_icon", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
@@ -300,6 +350,26 @@ namespace oscardata.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap rtty {
+ get {
+ object obj = ResourceManager.GetObject("rtty", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap ryry_icon {
+ get {
+ object obj = ResourceManager.GetObject("ryry_icon", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
@@ -370,6 +440,16 @@ namespace oscardata.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap start_icon {
+ get {
+ object obj = ResourceManager.GetObject("start_icon", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
@@ -380,6 +460,16 @@ namespace oscardata.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap stop_icon {
+ get {
+ object obj = ResourceManager.GetObject("stop_icon", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
@@ -420,6 +510,16 @@ namespace oscardata.Properties {
}
}
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap user_icon {
+ get {
+ object obj = ResourceManager.GetObject("user_icon", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
///
@@ -439,5 +539,15 @@ namespace oscardata.Properties {
return ((System.Drawing.Bitmap)(obj));
}
}
+
+ ///
+ /// Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap voice_icon {
+ get {
+ object obj = ResourceManager.GetObject("voice_icon", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
}
}
diff --git a/oscardata/oscardata/Properties/Resources.resx b/oscardata/oscardata/Properties/Resources.resx
index a88624c..7a78a7c 100755
--- a/oscardata/oscardata/Properties/Resources.resx
+++ b/oscardata/oscardata/Properties/Resources.resx
@@ -232,4 +232,37 @@
playbackicon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+ rtty.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ amsat_dl_logo.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ clearscreen.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ foht.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ home-icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ryry-icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ voice-icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ answer.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ start-icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ stop-icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ user-icon.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
\ No newline at end of file
diff --git a/oscardata/oscardata/Properties/amsat_dl_logo.png b/oscardata/oscardata/Properties/amsat_dl_logo.png
new file mode 100644
index 0000000..6e7ad5e
Binary files /dev/null and b/oscardata/oscardata/Properties/amsat_dl_logo.png differ
diff --git a/oscardata/oscardata/Properties/answer.png b/oscardata/oscardata/Properties/answer.png
new file mode 100644
index 0000000..51ac561
Binary files /dev/null and b/oscardata/oscardata/Properties/answer.png differ
diff --git a/oscardata/oscardata/Properties/clearscreen.png b/oscardata/oscardata/Properties/clearscreen.png
new file mode 100644
index 0000000..820f4c1
Binary files /dev/null and b/oscardata/oscardata/Properties/clearscreen.png differ
diff --git a/oscardata/oscardata/Properties/endqso-icon.png b/oscardata/oscardata/Properties/endqso-icon.png
new file mode 100644
index 0000000..1075d70
Binary files /dev/null and b/oscardata/oscardata/Properties/endqso-icon.png differ
diff --git a/oscardata/oscardata/Properties/foht.png b/oscardata/oscardata/Properties/foht.png
new file mode 100644
index 0000000..f1d04b9
Binary files /dev/null and b/oscardata/oscardata/Properties/foht.png differ
diff --git a/oscardata/oscardata/Properties/home-icon.png b/oscardata/oscardata/Properties/home-icon.png
new file mode 100644
index 0000000..d49d6aa
Binary files /dev/null and b/oscardata/oscardata/Properties/home-icon.png differ
diff --git a/oscardata/oscardata/Properties/rtty.png b/oscardata/oscardata/Properties/rtty.png
new file mode 100644
index 0000000..0e07ac9
Binary files /dev/null and b/oscardata/oscardata/Properties/rtty.png differ
diff --git a/oscardata/oscardata/Properties/ryry-icon.png b/oscardata/oscardata/Properties/ryry-icon.png
new file mode 100644
index 0000000..50571d1
Binary files /dev/null and b/oscardata/oscardata/Properties/ryry-icon.png differ
diff --git a/oscardata/oscardata/Properties/start-icon.png b/oscardata/oscardata/Properties/start-icon.png
new file mode 100644
index 0000000..1f778d8
Binary files /dev/null and b/oscardata/oscardata/Properties/start-icon.png differ
diff --git a/oscardata/oscardata/Properties/stop-icon.png b/oscardata/oscardata/Properties/stop-icon.png
new file mode 100644
index 0000000..ef5edcc
Binary files /dev/null and b/oscardata/oscardata/Properties/stop-icon.png differ
diff --git a/oscardata/oscardata/Properties/text-icon.png b/oscardata/oscardata/Properties/text-icon.png
new file mode 100644
index 0000000..f1d04b9
Binary files /dev/null and b/oscardata/oscardata/Properties/text-icon.png differ
diff --git a/oscardata/oscardata/Properties/uart_design_doc.pdf b/oscardata/oscardata/Properties/uart_design_doc.pdf
new file mode 100644
index 0000000..4b03094
Binary files /dev/null and b/oscardata/oscardata/Properties/uart_design_doc.pdf differ
diff --git a/oscardata/oscardata/Properties/user-icon.png b/oscardata/oscardata/Properties/user-icon.png
new file mode 100644
index 0000000..317b8c5
Binary files /dev/null and b/oscardata/oscardata/Properties/user-icon.png differ
diff --git a/oscardata/oscardata/Properties/voice-icon.png b/oscardata/oscardata/Properties/voice-icon.png
new file mode 100644
index 0000000..f233f7a
Binary files /dev/null and b/oscardata/oscardata/Properties/voice-icon.png differ
diff --git a/oscardata/oscardata/bin/Release/oscardata.exe b/oscardata/oscardata/bin/Release/oscardata.exe
index 28bc9e3..a83dfd7 100755
Binary files a/oscardata/oscardata/bin/Release/oscardata.exe and b/oscardata/oscardata/bin/Release/oscardata.exe differ
diff --git a/oscardata/oscardata/config.cs b/oscardata/oscardata/config.cs
index 275d8e0..d353501 100755
--- a/oscardata/oscardata/config.cs
+++ b/oscardata/oscardata/config.cs
@@ -39,6 +39,10 @@ namespace oscardata
public static Byte tuning = 27;
public static Byte marker = 28;
public static Byte setfreq = 29;
+ public static Byte rttykey = 30;
+ public static Byte rttystring = 31;
+ public static Byte txonoff = 32;
+ public static Byte rtty_stopTX = 33;
// frame sequence, modem needs that for i.e. sending a preamble
public static Byte FirstFrame = 0;
@@ -51,6 +55,7 @@ namespace oscardata
public static Byte udp_bc = 3;
public static Byte udp_fft = 4;
public static Byte udp_iq = 5;
+ public static Byte udp_rtty_rx = 6;
// global static variables
public static bool running = true;
@@ -85,6 +90,7 @@ namespace oscardata
public static Color WindowBackColor;
public static String[] langstr;
public static int tuning_active = 0;
+ public static int tune_frequency = 1500;
public static String[] getOwnIPs()
{
@@ -435,5 +441,24 @@ namespace oscardata
}
catch { }
}
+
+ // Culture invariant conversion
+
+ public static double MyToDouble(String s)
+
+ {
+ double r = 0;
+
+ try
+ {
+ s = s.Replace(',', '.');
+ r = Convert.ToDouble(s, System.Globalization.CultureInfo.InvariantCulture);
+ }
+ catch
+ {
+ }
+ return r;
+
+ }
}
}
diff --git a/oscardata/oscardata/oscardata.csproj b/oscardata/oscardata/oscardata.csproj
index 2004078..ddd5021 100755
--- a/oscardata/oscardata/oscardata.csproj
+++ b/oscardata/oscardata/oscardata.csproj
@@ -64,12 +64,6 @@
Form1.cs
-
- Form
-
-
- Form2_showtext.cs
-
Component
@@ -82,9 +76,6 @@
Form1.cs
-
- Form2_showtext.cs
-
ResXFileCodeGenerator
Resources.Designer.cs
@@ -152,6 +143,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/oscardata/oscardata/udp.cs b/oscardata/oscardata/udp.cs
index e1488f2..4c05374 100755
--- a/oscardata/oscardata/udp.cs
+++ b/oscardata/oscardata/udp.cs
@@ -31,6 +31,7 @@ namespace oscardata
static UdpQueue uq_ctrl = new UdpQueue();
static UdpQueue uq_fft = new UdpQueue();
static UdpQueue uq_iq = new UdpQueue();
+ static UdpQueue uq_rtty_rx = new UdpQueue();
public static int searchtimeout = 0;
static String last_audiodevstring = "";
@@ -150,6 +151,10 @@ namespace oscardata
statics.RXinSync = b[3];
statics.maxRXlevel = b[4];
statics.maxTXlevel = b[5];
+ statics.tune_frequency = b[6];
+ statics.tune_frequency <<= 8;
+ statics.tune_frequency += b[7];
+ //Console.WriteLine("f:" + statics.tune_frequency);
Byte[] b1 = new byte[b.Length - 6];
Array.Copy(b, 6, b1, 0, b1.Length);
drawFftBitmap(b1);
@@ -175,6 +180,11 @@ namespace oscardata
}
drawBitmap(re, im);
}
+
+ if (rxtype == statics.udp_rtty_rx)
+ {
+ uq_rtty_rx.Add(b);
+ }
}
}
catch { }
@@ -267,19 +277,22 @@ namespace oscardata
static Font fnt = new Font("Verdana", 9.0f);
static Font smallfnt = new Font("Verdana", 7.0f);
static Pen penyl = new Pen(Brushes.Yellow, 1);
+ static Pen pengn = new Pen(Brushes.LightGreen, 3);
static void drawFftBitmap(Byte[] b1)
{
- if(!bmf)
+ int yl = ffth - 20;
+ int yh = 20;
+
+ if (!bmf)
{
// pre-draw background
bmf = true;
- int yl = ffth - 20;
- int yh = 20;
Pen pen = new Pen(Brushes.Navy, 1);
Pen pensolid = new Pen(Brushes.Navy, 1);
pen.DashPattern = new float[] { 1.0F, 2.0F, 1.0F, 2.0F };
Pen penred = new Pen(Brushes.Red, 1);
+ Pen penred2 = new Pen(Brushes.Red, 2);
using (Graphics gr = Graphics.FromImage(bmskala))
{
@@ -289,7 +302,7 @@ namespace oscardata
for (int x = 10; x <= 390; x += 10)
gr.DrawLine(pen, x, yl, x, yh);
- gr.DrawLine(penred, 10, yl, 10, yh);
+ gr.DrawLine(penred2, 11, yl, 10, yh);
gr.DrawLine(penred, 150, yl, 150, yh);
gr.DrawLine(pensolid, 20, yl, 20, yh);
gr.DrawLine(pensolid, 280, yl, 280, yh);
@@ -322,6 +335,15 @@ namespace oscardata
gr.FillRectangle(bgcol, 0, 0, bm.Width, bm.Height);
// scala
gr.DrawImage(bmskala,16,2);
+
+ if(statics.real_datarate == 45)
+ {
+ // RTTY Markers
+ int low = (statics.tune_frequency - 170 / 2)/10;
+ int high = (statics.tune_frequency + 170 / 2)/10;
+ gr.DrawLine(pengn, low + 16, yl, low + 16, yh + 3);
+ gr.DrawLine(pengn, high + 16, yl, high + 16, yh + 3);
+ }
/*
// screws at the 4 corners
Bitmap screw = new Bitmap(Properties.Resources.schraube);
@@ -463,6 +485,12 @@ namespace oscardata
if (uq_iq.Count() == 0) return false;
return true;
}
+
+ public static Byte[] getRTTYrx()
+ {
+ if (uq_rtty_rx.Count() == 0) return null;
+ return uq_rtty_rx.Getarr();
+ }
}
// this class is a thread safe queue wich is used