From 0804f4a994d4d16438baa207f7cd0ba8400e9494 Mon Sep 17 00:00:00 2001 From: Dave Hibberd Date: Sat, 13 Apr 2024 17:48:58 +0100 Subject: [PATCH] New upstream version 0.72 --- ALSASound.c | 10 +- QtSoundModem.cpp | 37 ++++- QtSoundModem.vcxproj.user | 8 +- UZ7HOStuff.h | 12 +- Waveout.c | 51 +++--- ax25.c | 3 + dw9600.c | 338 +++++++++++++++++++++++++++----------- dw9600.h | 4 +- il2p.c | 20 +-- release/moc_predefs.h | 22 +-- 10 files changed, 342 insertions(+), 163 deletions(-) diff --git a/ALSASound.c b/ALSASound.c index 3507e9f..5764e94 100644 --- a/ALSASound.c +++ b/ALSASound.c @@ -799,7 +799,8 @@ int OpenSoundCapture(char * CaptureDevice, int m_sampleRate, int Report) if ((err = snd_pcm_hw_params_set_channels(rechandle, hw_params, m_recchannels)) < 0) { - Debugprintf("cannot set rec channel count to 2 (%s)", snd_strerror(err)); + if (Report) + Debugprintf("cannot set rec channel count to 2 (%s)", snd_strerror(err)); m_recchannels = 1; @@ -854,10 +855,10 @@ int OpenSoundCapture(char * CaptureDevice, int m_sampleRate, int Report) snd_pcm_hw_params_set_rate(rechandle, hw_params, m_sampleRate, 0); snd_pcm_hw_params_set_channels(rechandle, hw_params, m_recchannels); - err = snd_pcm_hw_params_set_buffer_size(rechandle, hw_params, 65536); + // err = snd_pcm_hw_params_set_buffer_size(rechandle, hw_params, 65536); - if (err) - Debugprintf("cannot set buffer size (%s)", snd_strerror(err)); + // if (err) + // Debugprintf("cannot set buffer size (%s)", snd_strerror(err)); err = snd_pcm_hw_params_set_period_size(rechandle, hw_params, (snd_pcm_uframes_t) { 1024 }, (int) { 0 }); @@ -1266,6 +1267,7 @@ int InitSound(BOOL Quiet) int min = 0, max = 0, lastlevelreport = 0, lastlevelGUI = 0; UCHAR CurrentLevel = 0; // Peak from current samples +UCHAR CurrentLevelR = 0; // Peak from current samples void PollReceivedSamples() { diff --git a/QtSoundModem.cpp b/QtSoundModem.cpp index 976ca95..fe1a717 100644 --- a/QtSoundModem.cpp +++ b/QtSoundModem.cpp @@ -481,7 +481,7 @@ void DoPSKWindows() for (i = 0; i < 4; i++) { - if (pskStates[i]) + if (soundChannel[i] && pskStates[i]) { constellationLabel[i]->setGeometry(QRect(NextX, 19, 121, 121)); QualLabel[i]->setGeometry(QRect(1 + NextX, 1, 120, 15)); @@ -660,6 +660,11 @@ QtSoundModem::QtSoundModem(QWidget *parent) : QMainWindow(parent) ui.RXLevel->setPixmap(QPixmap::fromImage(*RXLevel)); RXLevelCopy = ui.RXLevel; + RXLevel2 = new QImage(150, 10, QImage::Format_RGB32); + RXLevel2->fill(white); + ui.RXLevel2->setPixmap(QPixmap::fromImage(*RXLevel2)); + RXLevel2Copy = ui.RXLevel2; + DCDLabel[0] = new QLabel(this); DCDLabel[0]->setObjectName(QString::fromUtf8("DCDLedA")); DCDLabel[0]->setGeometry(QRect(280, 31, 12, 12)); @@ -2462,8 +2467,7 @@ void QtSoundModem::doRestartWF() RXLevel2->fill(white); ui.RXLevel->setVisible(1); - if (UsingBothChannels) - ui.RXLevel2->setVisible(1); + ui.RXLevel2->setVisible(1); lockWaterfall = false; } @@ -2553,7 +2557,7 @@ void QtSoundModem::RefreshSpectrum(unsigned char * Data) } -void RefreshLevel(unsigned int Level) +void RefreshLevel(unsigned int Level, unsigned int LevelR) { // Redraw the RX Level Bar Graph @@ -2577,9 +2581,29 @@ void RefreshLevel(unsigned int Level) } } RXLevelCopy->setPixmap(QPixmap::fromImage(*RXLevel)); + + for (x = 0; x < 150; x++) + { + for (y = 0; y < 10; y++) + { + if (x < LevelR) + { + if (LevelR < 50) + RXLevel2->setPixel(x, y, yellow); + else if (LevelR > 135) + RXLevel2->setPixel(x, y, red); + else + RXLevel2->setPixel(x, y, green); + } + else + RXLevel2->setPixel(x, y, white); + } + } + RXLevel2Copy->setPixmap(QPixmap::fromImage(*RXLevel2)); } extern "C" unsigned char CurrentLevel; +extern "C" unsigned char CurrentLevelR; void QtSoundModem::RefreshWaterfall(int snd_ch, unsigned char * Data) { @@ -2899,7 +2923,7 @@ void doWaterfallThread(void * param) float ImagOut[8192]; - RefreshLevel(CurrentLevel); // Signal Level + RefreshLevel(CurrentLevel, CurrentLevelR); // Signal Level hFFTSize = FFTSize / 2; @@ -2910,12 +2934,9 @@ void doWaterfallThread(void * param) // So can use 1024 or 4096. 1024 gives 512 bins of 11.71875 and a 512 pixel // display (is this enough?) - - Start = (WaterfallMin / BinSize); // First and last bins to process End = (WaterfallMax / BinSize); - if (0) //RSID_WF { // Use the Magnitudes in float aFFTAmpl[RSID_FFT_SIZE]; diff --git a/QtSoundModem.vcxproj.user b/QtSoundModem.vcxproj.user index 8b8926c..059beae 100644 --- a/QtSoundModem.vcxproj.user +++ b/QtSoundModem.vcxproj.user @@ -20,15 +20,15 @@ WindowsLocalDebugger - 2023-10-15T11:35:54.9027336Z + 2023-11-24T17:50:14.6138870Z - 2023-10-15T11:35:55.0741785Z + 2023-11-24T17:50:14.7454647Z - 2023-10-15T11:35:55.2661628Z + 2023-11-24T17:50:14.8872599Z - 2023-10-15T11:35:55.4659021Z + 2023-11-24T17:50:15.0594798Z \ No newline at end of file diff --git a/UZ7HOStuff.h b/UZ7HOStuff.h index 4a68356..b27e76f 100644 --- a/UZ7HOStuff.h +++ b/UZ7HOStuff.h @@ -4,8 +4,8 @@ // My port of UZ7HO's Soundmodem // -#define VersionString "0.0.0.71" -#define VersionBytes {0, 0, 0, 71} +#define VersionString "0.0.0.72 Beta 1" +#define VersionBytes {0, 0, 0, 72} // Added FX25. 4x100 FEC and V27 not Working and disabled @@ -106,13 +106,13 @@ // 0.48 Send FRMR for unrecognised frame types -// 0.49 Add Andy's FEC Tag correlation coode +// 0.49 Add Andy's FEC Tag correlation code // 0.50 Fix Waterfall display when only using right channel // Allow 1200 baud fsk at other center freqs // Add Port numbers to Window title and Try Icon tooltip // Fix calculation of filters for multiple decoders -// Add RX Offset setting (for satellite operation +// Add RX Offset setting (for satellite operation) // 0.51 Fix Multithreading with more that 2 modems @@ -178,7 +178,7 @@ // Improve reliability of waterfall update // Report and set fx.25 and il2p flags to/from BPQ - +// .72 Fix IL2P for RUH modems #include @@ -330,8 +330,6 @@ typedef struct TFX25_t Byte size_cnt; } TFX25; - - typedef struct TDetector_t { struct TFX25_t fx25[4]; diff --git a/Waveout.c b/Waveout.c index 0b37658..6b5c987 100644 --- a/Waveout.c +++ b/Waveout.c @@ -509,9 +509,10 @@ for (i = 0; i < 100; i++) return TRUE; } -static int min = 0, max = 0, lastlevelGUI = 0, lastlevelreport = 0; +static int minL = 0, maxL = 0, minR = 0; maxR = 0, lastlevelGUI = 0, lastlevelreport = 0; UCHAR CurrentLevel = 0; // Peak from current samples +UCHAR CurrentLevelR = 0; // Peak from current samples void PollReceivedSamples() { @@ -521,7 +522,7 @@ void PollReceivedSamples() // For level display we want a fairly rapid level average but only want to report // to log every 10 secs or so - // with Windows we get mono data + // We get stereo data if (stdinMode) { @@ -534,16 +535,26 @@ void PollReceivedSamples() short * ptr = &inbuffer[inIndex][0]; int i; + // Find min and max left abd right samples + for (i = 0; i < ReceiveSize; i++) { - if (*(ptr) < min) - min = *ptr; - else if (*(ptr) > max) - max = *ptr; + if (*(ptr) < minL) + minL = *ptr; + else if (*(ptr) > maxL) + maxL = *ptr; + + ptr++; + + if (*(ptr) < minR) + minR = *ptr; + else if (*(ptr) > maxR) + maxR = *ptr; ptr++; } - CurrentLevel = ((max - min) * 75) /32768; // Scale to 150 max + CurrentLevel = ((maxL - minL) * 75) / 32768; // Scale to 150 max + CurrentLevelR = ((maxR - minR) * 75) / 32768; // Scale to 150 max if ((Now - lastlevelGUI) > 2000) // 2 Secs { @@ -557,11 +568,13 @@ void PollReceivedSamples() char HostCmd[64]; lastlevelreport = Now; - sprintf(HostCmd, "INPUTPEAKS %d %d", min, max); - Debugprintf("Input peaks = %d, %d", min, max); - + sprintf(HostCmd, "INPUTPEAKS %d %d", minL, maxL); + if (UsingBothChannels) + Debugprintf("Input peaks L= %d, %d, R= %d, %d", minL, maxL, minR, maxR); + else + Debugprintf("Input peaks = %d, %d", minL, maxL); } - min = max = 0; + minL = maxL = minR = maxR = 0; } // debugprintf(LOGDEBUG, "Process %d %d", inIndex, inheader[inIndex].dwBytesRecorded/2); @@ -977,14 +990,14 @@ void StdinPollReceivedSamples() for (i = 0; i < ReceiveSize; i++) { - if (*(ptr) < min) - min = *ptr; - else if (*(ptr) > max) - max = *ptr; + if (*(ptr) < minL) + minL = *ptr; + else if (*(ptr) > maxL) + maxL = *ptr; ptr++; } - CurrentLevel = ((max - min) * 75) / 32768; // Scale to 150 max + CurrentLevel = ((maxL - minL) * 75) / 32768; // Scale to 150 max if ((Now - lastlevelGUI) > 2000) // 2 Secs { @@ -996,11 +1009,11 @@ void StdinPollReceivedSamples() char HostCmd[64]; lastlevelreport = Now; - sprintf(HostCmd, "INPUTPEAKS %d %d", min, max); - Debugprintf("Input peaks = %d, %d", min, max); + sprintf(HostCmd, "INPUTPEAKS %d %d", minL, maxL); + Debugprintf("Input peaks = %d, %d", minL, maxL); } - min = max = 0; + minL = maxL = 0; } // debugprintf(LOGDEBUG, "Process %d %d", inIndex, inheader[inIndex].dwBytesRecorded/2); diff --git a/ax25.c b/ax25.c index e55e286..4ae9083 100644 --- a/ax25.c +++ b/ax25.c @@ -869,6 +869,9 @@ int get_addr(char * Calls, UCHAR * AXCalls) ptr = strtok_s(NULL, " ,", &Context); + if (ptr == NULL) + return FALSE; + if (ConvToAX25(ptr, axptr) == 0) return FALSE; diff --git a/dw9600.c b/dw9600.c index 407feb1..8e6db00 100644 --- a/dw9600.c +++ b/dw9600.c @@ -27,6 +27,7 @@ extern int fx25_mode[4]; extern int il2p_mode[4]; extern int il2p_crc[4]; extern short rx_baudrate[5]; +extern short tx_bitrate[5]; #define FX25_MODE_NONE 0 #define FX25_MODE_RX 1 @@ -453,9 +454,11 @@ a good modem here and providing a result when it is received. void hdlc_rec_bit(int chan, int subchan, int slice, int raw, int is_scrambled, int not_used_remove) { - int dbit; /* Data bit after undoing NRZI. */ + int dbit; /* Data bit after undoing NRZI. */ /* Should be only 0 or 1. */ + struct hdlc_state_s *H; + int descram; /* * Different state information for each channel / subchannel / slice. @@ -469,27 +472,31 @@ void hdlc_rec_bit(int chan, int subchan, int slice, int raw, int is_scrambled, i * A '1' bit is represented by no change. */ - if (is_scrambled) { - int descram; - + if (is_scrambled) + { descram = descramble(raw, &(H->lfsr)); - - dbit = (descram == H->prev_descram); + dbit = (descram == H->prev_descram); // This does nrzi H->prev_descram = descram; H->prev_raw = raw; } else { dbit = (raw == H->prev_raw); - - H->prev_raw = raw; + H->prev_raw = raw; // This does nrzi } + // dbit should be after nrzi, descram after descramble but before nrzi + // After BER insertion, NRZI, and any descrambling, feed into FX.25 decoder as well. // fx25_rec_bit (chan, subchan, slice, dbit); - il2p_rec_bit (chan, subchan, slice, raw); // Note: skip NRZI. + if (il2p_mode[chan]) + { + il2p_rec_bit(chan, subchan, slice, raw); // not scrambled, not nrzi + if (il2p_mode[chan] == IL2P_MODE_ONLY) // Dont try HDLC decode + return; + } /* * Octets are sent LSB first. @@ -618,7 +625,7 @@ void hdlc_rec_bit(int chan, int subchan, int slice, int raw, int is_scrambled, i * * This indicates loss of signal. * But we will let it slip thru because it might diminish - * our single bit fixup effort. Instead give up on frame + * our float bit fixup effort. Instead give up on frame * only when we see eight 1 bits in a row. * * 11111111 @@ -961,7 +968,7 @@ typedef struct retry_conf_s { static const char * retry_text[] = { "NONE", - "SINGLE", + "float", "DOUBLE", "TRIPLE", "TWO_SEP", @@ -990,7 +997,7 @@ static int sanity_check(unsigned char *buf, int blen, retry_t bits_flipped, enum * Level of effort to recover from * a bad FCS on the frame. * 0 = no effort - * 1 = try inverting a single bit + * 1 = try inverting a float bit * 2... = more techniques... * * enum sanity_e sanity_test; @@ -1114,7 +1121,7 @@ void hdlc_rec2_block(rrbb_t block) * Global In: configuration fix_bits - Maximum level of fix up to attempt. * * RETRY_NONE (0) - Don't try any. - * RETRY_INVERT_SINGLE (1) - Try inverting single bits. + * RETRY_INVERT_float (1) - Try inverting float bits. * etc. * * configuration passall - Let it thru with bad CRC after exhausting @@ -1158,7 +1165,7 @@ static int try_to_fix_quick_now(rrbb_t block, int chan, int subchan, int slice, */ if (fix_bits < RETRY_INVERT_SINGLE) { - /* Stop before single bit fix up. */ + /* Stop before float bit fix up. */ return 0; /* failure. */ } @@ -1174,7 +1181,7 @@ static int try_to_fix_quick_now(rrbb_t block, int chan, int subchan, int slice, if (ok) { #if DEBUG text_color_set(DW_COLOR_ERROR); - dw_printf("*** Success by flipping SINGLE bit %d of %d ***\n", i, len); + dw_printf("*** Success by flipping float bit %d of %d ***\n", i, len); #endif return 1; } @@ -1227,7 +1234,7 @@ static int try_to_fix_quick_now(rrbb_t block, int chan, int subchan, int slice, /* - * Two non-adjacent ("separated") single bits. + * Two non-adjacent ("separated") float bits. * It chews up a lot of CPU time. Usual test takes 4 times longer to run. * * Processing time is order N squared so time goes up rapidly with larger frames. @@ -1363,7 +1370,7 @@ inline static char is_sep_bit_modified(int bit_idx, retry_conf_t retry_conf) { * retry: * Level of effort to recover from a bad FCS on the frame. * RETRY_NONE = 0 - * RETRY_INVERT_SINGLE = 1 + * RETRY_INVERT_float = 1 * RETRY_INVERT_DOUBLE = 2 * RETRY_INVERT_TRIPLE = 3 * RETRY_INVERT_TWO_SEP = 4 @@ -3282,73 +3289,40 @@ static const int gray2phase_v27[8] = { 1, 0, 2, 3, 6, 7, 5, 4 }; // We are only using this for RUH modes -void tone_gen_put_bit(int chan, int dat) +void tone_gen_put_bit(int chan, int dat, int scramble) { - int modem_type = MODEM_SCRAMBLE; int a = 0; // scramble - int x; + if (scramble) + { + int x; - x = (dat ^ (lfsr[chan] >> 16) ^ (lfsr[chan] >> 11)) & 1; - lfsr[chan] = (lfsr[chan] << 1) | (x & 1); - dat = x; + x = (dat ^ (lfsr[chan] >> 16) ^ (lfsr[chan] >> 11)) & 1; + lfsr[chan] = (lfsr[chan] << 1) | (x & 1); + dat = x; + } do { /* until enough audio samples for this symbol. */ int sam; - switch (modem_type) + if (dat != prev_dat[chan]) { - - case MODEM_AFSK: - - // v1.7 reversed. - // Previously a data '1' selected the second (usually higher) tone. - // It never really mattered before because we were using NRZI. - // With the addition of IL2P, we need to be more careful. - // A data '1' should be the mark tone. - - tone_phase[chan] += dat ? f1_change_per_sample[chan] : f2_change_per_sample[chan]; - sam = sine_table[(tone_phase[chan] >> 24) & 0xff]; - gen_tone_put_sample(chan, a, sam); - break; - - case MODEM_QPSK: - case MODEM_8PSK: - tone_phase[chan] += f1_change_per_sample[chan]; - sam = sine_table[(tone_phase[chan] >> 24) & 0xff]; - gen_tone_put_sample(chan, a, sam); - break; - - case MODEM_BASEBAND: - case MODEM_SCRAMBLE: - case MODEM_AIS: - - if (dat != prev_dat[chan]) - { - tone_phase[chan] += f1_change_per_sample[chan]; - } - else - { - if (tone_phase[chan] & 0x80000000) - tone_phase[chan] = 0xc0000000; // 270 degrees. - else - tone_phase[chan] = 0x40000000; // 90 degrees. - } - - sam = sine_table[(tone_phase[chan] >> 24) & 0xff]; - gen_tone_put_sample(chan, a, sam); - break; - - default: - text_color_set(DW_COLOR_ERROR); - dw_printf("INTERNAL ERROR: %s %d achan[%d].modem_type = %d\n", - __FILE__, __LINE__, chan, save_audio_config_p->achan[chan].modem_type); - exit(0); } + else + { + if (tone_phase[chan] & 0x80000000) + tone_phase[chan] = 0xc0000000; // 270 degrees. + else + tone_phase[chan] = 0x40000000; // 90 degrees. + } + + sam = sine_table[(tone_phase[chan] >> 24) & 0xff]; + gen_tone_put_sample(chan, a, sam); + /* Enough for the bit time? */ @@ -3399,18 +3373,13 @@ void gen_tone_put_sample(int chan, int a, int sam) // along with this program. If not, see . // -static void send_byte_msb_first(int chan, int x, int polarity); static void send_control_nrzi(int, int); static void send_data_nrzi(int, int); static void send_bit_nrzi(int, int); - - static int number_of_bits_sent[MAX_CHANS]; // Count number of bits sent by "hdlc_send_frame" or "hdlc_send_flags" - - /*------------------------------------------------------------- * * Name: layer2_send_frame @@ -3521,23 +3490,6 @@ static int ax25_only_hdlc_send_frame(int chan, unsigned char *fbuf, int flen, in } - -// The next one is only for IL2P. No NRZI. -// MSB first, opposite of AX.25. - -static void send_byte_msb_first(int chan, int x, int polarity) -{ - int i; - - for (i = 0; i < 8; i++) { - int dbit = (x & 0x80) != 0; - tone_gen_put_bit(chan, (dbit ^ polarity) & 1); - x <<= 1; - number_of_bits_sent[chan]++; - } -} - - // The following are only for HDLC. // All bits are sent NRZI. // Data (non flags) use bit stuffing. @@ -3594,7 +3546,7 @@ static void send_bit_nrzi(int chan, int b) output[chan] = !output[chan]; } - tone_gen_put_bit(chan, output[chan]); + tone_gen_put_bit(chan, output[chan], MODEM_SCRAMBLE); number_of_bits_sent[chan]++; } @@ -4034,7 +3986,7 @@ void dw9600ProcessSample(int snd_ch, short Sample) void init_RUH48(int snd_ch) { modem_mode[snd_ch] = MODE_RUH; - rx_baudrate[snd_ch] = 4800; + tx_bitrate[snd_ch] = rx_baudrate[snd_ch] = 4800; if (was_init[snd_ch] == 0) { @@ -4054,7 +4006,7 @@ void init_RUH48(int snd_ch) void init_RUH96(int snd_ch) { modem_mode[snd_ch] = MODE_RUH; - rx_baudrate[snd_ch] = 9600; + tx_bitrate[snd_ch] = rx_baudrate[snd_ch] = 9600; if (was_init[snd_ch] == 0) { @@ -4077,16 +4029,163 @@ void text_color_set(dw_color_t c) return; } +typedef struct TMChannel_t +{ + + float prev_LPF1I_buf[4096]; + float LPF1Q_buf[4096]; + float prev_dLPFI_buf[4096]; + float prev_dLPFQ_buf[4096]; + float prev_AFCI_buf[4096]; + float prev_AFCQ_buf[4096]; + float AngleCorr; + float MUX_osc; + float AFC_IZ1; + float AFC_IZ2; + float AFC_QZ1; + float AFC_QZ2; + float AFC_bit_buf1I[1024]; + float AFC_bit_buf1Q[1024]; + float AFC_bit_buf2[1024]; + float AFC_IIZ1; + float AFC_QQZ1; + +} TMChannel; + + +typedef struct TFX25_t +{ + string data; + uint8_t status; + uint8_t bit_cnt; + uint8_t uint8_t_rx; + unsigned long long tag; + uint8_t size; + uint8_t rs_size; + uint8_t size_cnt; +} TFX25; + +typedef struct TDetector_t +{ + struct TFX25_t fx25[4]; + TStringList mem_ARQ_F_buf[5]; + TStringList mem_ARQ_buf[5]; + float pll_loop[5]; + float last_sample[5]; + uint8_t ones[5]; + uint8_t zeros[5]; + float bit_buf[5][1024]; + float bit_buf1[5][1024]; + uint8_t sample_cnt[5]; + uint8_t last_bit[5]; + float PSK_IZ1[5]; + float PSK_QZ1[5]; + float PkAmpI[5]; + float PkAmpQ[5]; + float PkAmp[5]; + float PkAmpMax[5]; + int newpkpos[5]; + float AverageAmp[5]; + float AngleCorr[5]; + float MinAmp[5]; + float MaxAmp[5]; + float MUX3_osc[5]; + float MUX3_1_osc[5]; + float MUX3_2_osc[5]; + float Preemphasis6[5]; + float Preemphasis12[5]; + float PSK_AGC[5]; + float AGC[5]; + float AGC1[5]; + float AGC2[5]; + float AGC3[5]; + float AGC_max[5]; + float AGC_min[5]; + float AFC_IZ1[5]; + float AFC_IZ2[5]; + float AFC_QZ1[5]; + float AFC_QZ2[5]; + + uint8_t last_rx_bit[5]; + uint8_t bit_stream[5]; + uint8_t uint8_t_rx[5]; + uint8_t bit_stuff_cnt[5]; + uint8_t bit_cnt[5]; + float bit_osc[5]; + uint8_t frame_status[5]; + string rx_data[5]; + string FEC_rx_data[5]; + // + uint8_t FEC_pol[5]; + unsigned short FEC_err[5]; + unsigned long long FEC_header1[5][2]; + unsigned short FEC_blk_int[5]; + unsigned short FEC_len_int[5]; + unsigned short FEC_len[5]; + + unsigned short FEC_len_cnt[5]; + + uint8_t rx_intv_tbl[5][4]; + uint8_t rx_intv_sym[5]; + uint8_t rx_viterbi[5]; + uint8_t viterbi_cnt[5]; + // SurvivorStates [1..4,0..511] of TSurvivor; + // + TMChannel MChannel[5][4]; + + float AFC_dF_avg[5]; + float AFC_dF[5]; + float AFC_bit_osc[5]; + float AFC_bit_buf[5][1024]; + unsigned short AFC_cnt[5]; + + string raw_bits1[5]; + string raw_bits[5]; + uint8_t last_nrzi_bit[5]; + + float BPF_core[5][2048]; + float LPF_core[5][2048]; + + float src_INTR_buf[5][8192]; + float src_INTRI_buf[5][8192]; + float src_INTRQ_buf[5][8192]; + float src_LPF1I_buf[5][8192]; + float src_LPF1Q_buf[5][8192]; + + float src_BPF_buf[5][2048]; + float src_Loop_buf[5][8192]; + float prev_BPF_buf[5][4096]; + + float prev_LPF1I_buf[5][4096]; + float prev_LPF1Q_buf[5][4096]; + float prev_INTR_buf[5][16384]; + float prev_INTRI_buf[5][16384]; + float prev_INTRQ_buf[5][16384]; + + uint8_t emph_decoded; + uint8_t rx_decoded; + uint8_t errors; + +} TDetector; + extern TStringList detect_list[5]; extern TStringList detect_list_c[5]; +#define nr_emph 2 +extern struct TDetector_t DET[nr_emph + 1][16]; + +#define decodedNormal 4 //'-' +#define decodedFEC 3 //'F' +#define decodedMEM 2 //'#' +#define decodedSingle 1 //'$' + int multi_modem_process_rec_frame(int chan, int subchan, int slice, unsigned char *fbuf, int flen, int alevel, int retries, int is_fx25) { // Convert to QtSM internal format -// struct TDetector_t * pDET = &DET[emph][subchan]; + struct TDetector_t * pDET = &DET[0][subchan]; string * data = newString(); char Mode[16] = "RUH"; int i, found; @@ -4100,7 +4199,7 @@ int multi_modem_process_rec_frame(int chan, int subchan, int slice, unsigned cha freeString(data); Debugprintf("Discarding copy rcvr %d emph %d", subchan, 0); - return; + return 0; } string * xx = newString(); @@ -4109,6 +4208,10 @@ int multi_modem_process_rec_frame(int chan, int subchan, int slice, unsigned cha Add(&detect_list_c[chan], xx); Add(&detect_list[chan], data); + pDET->rx_decoded = decodedNormal; + pDET->emph_decoded = decodedNormal; + pDET->errors = 0; + // if (retries) // sprintf(Mode, "IP2P-%d", retries); @@ -4137,13 +4240,52 @@ void RUHEncode(unsigned char * Data, int Len, int chan) int bitcount; int txdcount; - int j; + int i, j; unsigned short CRC; number_of_bits_sent[chan] = 0; SampleNo = 0; + if (il2p_mode[chan] >= IL2P_MODE_TXRX) + { + // il2p generates TXDELAY as part of the frame, so just build frame + + string * result; + packet_t pp = ax25_new(); + int polarity = 0; + + // Call il2p_send_frame to build the bit stream + + pp->frame_len = Len; + memcpy(pp->frame_data, Data, Len + 2); // Copy the crc in case we are going to send it + + result = il2p_send_frame(chan, pp, 1, 0); + + for (j = 0; j < result->Length; j++) + { + int x = result->Data[j]; + + for (i = 0; i < 8; i++) + { + int dbit = (x & 0x80) != 0; + tone_gen_put_bit(chan, (dbit ^ polarity) & 1, 0); // No Scramble + x <<= 1; + number_of_bits_sent[chan]++; + } + } + + freeString(result); + ax25_delete(pp); + + // sample No should now contain number of (stereo) samples + + ARDOPTXLen[chan] = SampleNo; + ARDOPTXPtr[chan] = 0; + + return; + } + // First do TX delay // Set up txd worth of flags diff --git a/dw9600.h b/dw9600.h index e80d2ac..ea34bae 100644 --- a/dw9600.h +++ b/dw9600.h @@ -376,7 +376,7 @@ typedef struct alevel_s { #ifndef AXTEST // TODO: remove this? -#define AX25MEMDEBUG 1 +#define AX25MEMDEBUG 0 #endif @@ -1982,7 +1982,7 @@ int gen_tone_init(struct audio_s *pp, int amp, int gen_packets); //int gen_tone_close (void); -void tone_gen_put_bit(int chan, int dat); +void tone_gen_put_bit(int chan, int dat, int scramble); void gen_tone_put_sample(int chan, int a, int sam); diff --git a/il2p.c b/il2p.c index 6a284f2..895feaa 100644 --- a/il2p.c +++ b/il2p.c @@ -127,7 +127,7 @@ typedef struct alevel_s { alevel_t demod_get_audio_level(int chan, int subchan); -void tone_gen_put_bit(int chan, int dat); +void tone_gen_put_bit(int chan, int dat, int scramble); int ax25memdebug = 1; @@ -1031,9 +1031,6 @@ packet_t ax25_i_frame(char addrs[AX25_MAX_ADDRS][AX25_MAX_ADDR_LEN], int num_add } /* end ax25_i_frame */ - - - extern TStringList detect_list[5]; extern TStringList detect_list_c[5]; @@ -1075,9 +1072,9 @@ void multi_modem_process_rec_packet(int snd_ch, int subchan, int slice, packet_t if (CRCCALC != CRCMSG) { Debugprintf("CRC Error Decoder %d Received %x Sent %x", subchan, CRCCALC, CRCMSG); - // freeString(data); - // ax25_delete(pp); - // return; + freeString(data); + ax25_delete(pp); + return; } } @@ -3959,7 +3956,7 @@ struct il2p_context_s *il2p_context[4][16][3]; * * Name: il2p_rec_bit * - * Purpose: Extract FX.25 packets from a stream of bits. + * Purpose: Extract il2p packets from a stream of bits. * * Inputs: chan - Channel number. * @@ -3984,15 +3981,18 @@ void il2p_rec_bit(int chan, int subchan, int slice, int dbit) if (dbit) dbit = 1; + else + dbit = 0; struct il2p_context_s *F = il2p_context[chan][subchan][slice]; + if (F == NULL) { //assert(chan >= 0 && chan < MAX_CHANS); //assert(subchan >= 0 && subchan < MAX_SUBCHANS); //assert(slice >= 0 && slice < MAX_SLICERS); F = il2p_context[chan][subchan][slice] = (struct il2p_context_s *)malloc(sizeof(struct il2p_context_s)); //assert(F != NULL); -memset(F, 0, sizeof(struct il2p_context_s)); + memset(F, 0, sizeof(struct il2p_context_s)); } // Accumulate most recent 24 bits received. Most recent is LSB. @@ -4018,7 +4018,7 @@ memset(F, 0, sizeof(struct il2p_context_s)); centreFreq[chan] = GuessCentreFreq(chan); } - else if (__builtin_popcount((~F->acc & 0x00ffffff) ^ IL2P_SYNC_WORD) <= 1) { + else if (__builtin_popcount((~(F->acc) & 0x00ffffff) ^ IL2P_SYNC_WORD) <= 1) { // FIXME - this pops up occasionally with random noise. Find better way to convey information. // This also happens for each slicer - to noisy. //Debugprintf ("IL2P header has reverse polarity\n"); diff --git a/release/moc_predefs.h b/release/moc_predefs.h index 54e9037..4c9c0c7 100644 --- a/release/moc_predefs.h +++ b/release/moc_predefs.h @@ -1,11 +1,11 @@ -#define _MSC_EXTENSIONS -#define _INTEGRAL_MAX_BITS 64 -#define _MSC_VER 1916 -#define _MSC_FULL_VER 191627043 -#define _MSC_BUILD 0 -#define _WIN32 -#define _M_IX86 600 -#define _M_IX86_FP 2 -#define _CPPRTTI -#define _MT -#define _DLL +#define _MSC_EXTENSIONS +#define _INTEGRAL_MAX_BITS 64 +#define _MSC_VER 1916 +#define _MSC_FULL_VER 191627043 +#define _MSC_BUILD 0 +#define _WIN32 +#define _M_IX86 600 +#define _M_IX86_FP 2 +#define _CPPRTTI +#define _MT +#define _DLL