From 46003430f8435fa092cb28d479a91e831c0807b7 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Wed, 12 Oct 2022 17:44:51 -0400 Subject: [PATCH 01/97] adding dsssframe64gen object with example; needs appropriate sync --- examples/dsssframe64sync_example.c | 65 ++++++++++ include/liquid.h | 46 +++++++ makefile.in | 3 + src/framing/src/dsssframe64gen.c | 199 +++++++++++++++++++++++++++++ 4 files changed, 313 insertions(+) create mode 100644 examples/dsssframe64sync_example.c create mode 100644 src/framing/src/dsssframe64gen.c diff --git a/examples/dsssframe64sync_example.c b/examples/dsssframe64sync_example.c new file mode 100644 index 000000000..77592a0a6 --- /dev/null +++ b/examples/dsssframe64sync_example.c @@ -0,0 +1,65 @@ +// This example demonstrates the basic interface to the dsssframe64gen and +// dsssframe64sync objects. +#include +#include +#include +#include +#include +#include +#include + +#include "liquid.h" + +int main(int argc, char *argv[]) +{ + // options + unsigned int nfft=2400; + + // create dsssframe64gen object + dsssframe64gen fg = dsssframe64gen_create(); + + // generate the frame in blocks + unsigned int buf_len = dsssframe64gen_get_frame_len(fg); + float complex buf_tx[buf_len]; // transmit buffer + float complex buf_rx[buf_len]; // receive buffer (channel output) + + // create spectral periodogram for displaying spectrum + spgramcf periodogram = spgramcf_create_default(nfft); + + // generate in one step (for now) + dsssframe64gen_assemble(fg, NULL, NULL); + dsssframe64gen_write(fg, buf_tx, buf_len); + + // channel + memmove(buf_rx, buf_tx, buf_len*sizeof(float complex)); + + // push resulting sample through periodogram + spgramcf_write(periodogram, buf_tx, buf_len); + float psd[nfft]; + spgramcf_get_psd(periodogram, psd); + + // export results + const char * filename = "dsssframe64sync_example.m"; + FILE * fid = fopen(filename,"w"); + fprintf(fid,"%% %s : auto-generated file\n", filename); + fprintf(fid,"clear all; close all;\n"); + unsigned int i; +#if 0 + fprintf(fid,"n=%u; y=zeros(1,n);\n", buf_len); + for (i=0; i +#include +#include +#include +#include +#include + +#include "liquid.internal.h" + +struct dsssframe64gen_s { + qpacketmodem enc; // packet encoder/modulator + qpilotgen pilotgen; // pilot symbol generator + msequence ms; // spreading sequence generator + float complex pn_sequence[1024]; // 1024-symbol p/n sequence + unsigned char payload_dec[ 150]; // 600 = 150 bytes * 8 bits/bytes / 2 bits/symbol + float complex payload_sym[ 600]; // modulated payload symbols + float complex payload_tx [ 630]; // modulated payload symbols with pilots + unsigned int m; // filter delay (symbols) + float beta; // filter excess bandwidth factor + firinterp_crcf interp; // pulse-shaping filter/interpolator + float complex buf_output[2]; // output sample buffer + // TODO: counters, etc. +}; + +// create dsssframe64gen object +dsssframe64gen dsssframe64gen_create() +{ + dsssframe64gen q = (dsssframe64gen) malloc(sizeof(struct dsssframe64gen_s)); + q->m = 7; + q->beta = 0.3f; + + unsigned int i; + + // generate p/n sequence + q->ms = msequence_create(11, 0x0805, 1); + for (i=0; i<1024; i++) { + q->pn_sequence[i] = (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2); + q->pn_sequence[i] += (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2)*_Complex_I; + } + + // create payload encoder/modulator object + int check = LIQUID_CRC_24; + int fec0 = LIQUID_FEC_NONE; + int fec1 = LIQUID_FEC_GOLAY2412; + int mod_scheme = LIQUID_MODEM_QPSK; + q->enc = qpacketmodem_create(); + qpacketmodem_configure(q->enc, 72, check, fec0, fec1, mod_scheme); + //qpacketmodem_print(q->enc); + assert( qpacketmodem_get_frame_len(q->enc)==600 ); + + // create pilot generator + q->pilotgen = qpilotgen_create(600, 21); + assert( qpilotgen_get_frame_len(q->pilotgen)==630 ); + + // create pulse-shaping filter (k=2) + q->interp = firinterp_crcf_create_prototype(LIQUID_FIRFILT_ARKAISER,2,q->m,q->beta,0); + + // return main object + return q; +} + +// copy object +dsssframe64gen dsssframe64gen_copy(dsssframe64gen q_orig) +{ + // validate input + if (q_orig == NULL) + return liquid_error_config("dsssframe64gen_copy(), object cannot be NULL"); + + // not yet implemented + return NULL; +} + +// destroy dsssframe64gen object +int dsssframe64gen_destroy(dsssframe64gen _q) +{ + // destroy internal objects + msequence_destroy (_q->ms); + qpacketmodem_destroy (_q->enc); + qpilotgen_destroy (_q->pilotgen); + firinterp_crcf_destroy(_q->interp); + + // free main object memory + free(_q); + return LIQUID_OK; +} + +// print dsssframe64gen object internals +int dsssframe64gen_print(dsssframe64gen _q) +{ + printf("\n", _q->m, _q->beta); + return LIQUID_OK; +} + +// assmeble frame +// _q : frame generator object +// _header : 8-byte header data, NULL for random +// _payload : 64-byte payload data, NULL for random +// _frame : output frame samples [size: LIQUID_FRAME64_LEN x 1] +int dsssframe64gen_assemble(dsssframe64gen _q, + const unsigned char * _header, + const unsigned char * _payload) +{ + unsigned int i; + + // concatenate header and payload + for (i=0; i<8; i++) + _q->payload_dec[i] = _header==NULL ? rand() & 0xff : _header[i]; + for (i=0; i<64; i++) + _q->payload_dec[i+8] = _payload==NULL ? rand() & 0xff : _payload[i]; + + // run packet encoder and modulator + qpacketmodem_encode(_q->enc, _q->payload_dec, _q->payload_sym); + + // add pilot symbols + qpilotgen_execute(_q->pilotgen, _q->payload_sym, _q->payload_tx); + + // reset objects + firinterp_crcf_reset(_q->interp); + msequence_reset(_q->ms); + + // frame_assembled = 1 + return LIQUID_OK; +} + +// write samples to buffer +// _q : frame generator object +// _buf : output frame samples, shape: (_buf_len,) +// _buf_len : output frame buffer size +int dsssframe64gen_write(dsssframe64gen _q, + float complex * _buf, + unsigned int _buf_len) +{ + unsigned int i, j, n=0; + + // p/n sequence + for (i=0; i<1024; i++) { + firinterp_crcf_execute(_q->interp, _q->pn_sequence[i], &_buf[n]); + n+=2; + } + + // frame payload + for (i=0; i<630; i++) { + float complex sym = _q->payload_tx[i]; // strip out raw payload symbol + for (j=0; j<256; j++) { + // generate pseudo-random symbol + unsigned int p = msequence_generate_symbol(_q->ms, 2); + float complex s = cexpf(_Complex_I*2*M_PI*(float)p/(float)4); + firinterp_crcf_execute(_q->interp, sym*s, &_buf[n]); + n+=2; + } + } + + // interpolator settling + for (i=0; i<2*_q->m; i++) { + firinterp_crcf_execute(_q->interp, 0.0f, &_buf[n]); + n+=2; + } + + assert(n==dsssframe64gen_get_frame_len(_q)); + return LIQUID_OK; +} + +// is frame generation complete? +int dsssframe64gen_complete(dsssframe64gen _q) +{ + return 1; +} + +// get full frame length [samples] +unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q) +{ + return 2*(1024 + 630*256 + 2*_q->m); +} + From a63cd643b2e40596513dc8b822b8b4a700441919 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Wed, 12 Oct 2022 22:43:51 -0400 Subject: [PATCH 02/97] dsssframe64gen: dropping excess bandwidth, increasing filter length --- src/framing/src/dsssframe64gen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index 9fd78c3e8..3532fec04 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -51,8 +51,8 @@ struct dsssframe64gen_s { dsssframe64gen dsssframe64gen_create() { dsssframe64gen q = (dsssframe64gen) malloc(sizeof(struct dsssframe64gen_s)); - q->m = 7; - q->beta = 0.3f; + q->m = 15; + q->beta = 0.20f; unsigned int i; From f7061f41654d07bea28bf01a4f70534f5af9d4dd Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Fri, 14 Oct 2022 09:11:56 -0400 Subject: [PATCH 03/97] dsssframe64: adding sync method; really needs to be re-spun --- include/liquid.h | 14 +- makefile.in | 2 + src/framing/src/dsssframe64sync.c | 510 ++++++++++++++++++++++++++++++ 3 files changed, 525 insertions(+), 1 deletion(-) create mode 100644 src/framing/src/dsssframe64sync.c diff --git a/include/liquid.h b/include/liquid.h index c4f91faa7..71c462f77 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -5891,7 +5891,8 @@ framedatastats_s dsssframesync_get_framedatastats (dsssframesync _q); // // Direct sequence/spread spectrum framing with fixed 64-byte payload // -// DS/SS frame generator object type + +// frame generator object type typedef struct dsssframe64gen_s * dsssframe64gen; // create dsssframe64gen object @@ -5934,6 +5935,17 @@ int dsssframe64gen_complete(dsssframe64gen _q); unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q); +// frame synchronizer object type +typedef struct dsssframe64sync_s * dsssframe64sync; + +dsssframe64sync dsssframe64sync_create(framesync_callback _callback, void * _userdata); +int dsssframe64sync_destroy (dsssframe64sync _q); +int dsssframe64sync_print (dsssframe64sync _q); +int dsssframe64sync_reset (dsssframe64sync _q); +int dsssframe64sync_is_frame_open (dsssframe64sync _q); +int dsssframe64sync_reset_framedatastats(dsssframe64sync _q); +int dsssframe64sync_execute (dsssframe64sync _q, liquid_float_complex * _x, unsigned int _n); + // // OFDM flexframe generator // diff --git a/makefile.in b/makefile.in index abf7c2257..0017af192 100644 --- a/makefile.in +++ b/makefile.in @@ -630,6 +630,7 @@ framing_objects := \ src/framing/src/bsync_cccf.o \ src/framing/src/detector_cccf.o \ src/framing/src/dsssframe64gen.o \ + src/framing/src/dsssframe64sync.o \ src/framing/src/dsssframegen.o \ src/framing/src/dsssframesync.o \ src/framing/src/framedatastats.o \ @@ -665,6 +666,7 @@ src/framing/src/bsync_crcf.o : %.o : %.c $(include_headers) src/framing/s src/framing/src/bsync_cccf.o : %.o : %.c $(include_headers) src/framing/src/bsync.proto.c src/framing/src/detector_cccf.o : %.o : %.c $(include_headers) src/framing/src/dsssframe64gen.o : %.o : %.c $(include_headers) +src/framing/src/dsssframe64sync.o : %.o : %.c $(include_headers) src/framing/src/dsssframegen.o : %.o : %.c $(include_headers) src/framing/src/dsssframesync.o : %.o : %.c $(include_headers) src/framing/src/framedatastats.o : %.o : %.c $(include_headers) diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c new file mode 100644 index 000000000..892251816 --- /dev/null +++ b/src/framing/src/dsssframe64sync.c @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2007 - 2022 Joseph Gaeddert + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// basic frame synchronizer with 8 bytes header and 64 bytes payload + +#include +#include +#include +#include +#include +#include + +#include "liquid.internal.h" + +#define dsssframe64sync_ENABLE_EQ 0 + +// push samples through detection stage +int dsssframe64sync_execute_seekpn(dsssframe64sync _q, + float complex _x); + +// step receiver mixer, matched filter, decimator +// _q : frame synchronizer +// _x : input sample +// _y : output symbol +int dsssframe64sync_step(dsssframe64sync _q, + float complex _x, + float complex * _y); + +// push samples through synchronizer, saving received p/n symbols +int dsssframe64sync_execute_rxpreamble(dsssframe64sync _q, + float complex _x); + +// receive payload symbols +int dsssframe64sync_execute_rxpayload(dsssframe64sync _q, + float complex _x); + +// export debugging based on return value +// 0 : do not write file +// >0 : write specific number (hex) +// -1 : number of packets detected +// -2 : id using first 4 bytes of header +// -3 : write with random extension +int dsssframe64sync_debug_export(dsssframe64sync _q, int _code); + +// dsssframe64sync object structure +struct dsssframe64sync_s { + // callback + framesync_callback callback; // user-defined callback function + void * userdata; // user-defined data structure + framesyncstats_s framesyncstats; // frame statistic object (synchronizer) + framedatastats_s framedatastats; // frame statistic object (packet statistics) + + // synchronizer objects + unsigned int m; // filter delay (symbols) + float beta; // filter excess bandwidth factor + qdetector_cccf detector; // pre-demod detector + float tau_hat; // fractional timing offset estimate + float dphi_hat; // carrier frequency offset estimate + float phi_hat; // carrier phase offset estimate + float gamma_hat; // channel gain estimate + nco_crcf mixer; // coarse carrier frequency recovery + + // timing recovery objects, states + firpfb_crcf mf; // matched filter decimator + unsigned int npfb; // number of filters in symsync + int mf_counter; // matched filter output timer + unsigned int pfb_index; // filterbank index + + // preamble + float complex preamble_pn[64]; // known 64-symbol p/n sequence + float complex preamble_rx[64]; // received p/n symbols + + // payload decoder + float complex payload_rx [630]; // received payload symbols with pilots + float complex payload_sym[600]; // received payload symbols + unsigned char payload_dec[ 72]; // decoded payload bytes + qpacketmodem dec; // packet demodulator/decoder + qpilotsync pilotsync; // pilot extraction, carrier recovery + int payload_valid; // did payload pass crc? + + // status variables + enum { + dsssframe64sync_STATE_DETECTFRAME=0, // detect frame (seek p/n sequence) + dsssframe64sync_STATE_RXPREAMBLE, // receive p/n sequence + dsssframe64sync_STATE_RXPAYLOAD, // receive payload data + } state; + unsigned int preamble_counter; // counter: num of p/n syms received + unsigned int payload_counter; // counter: num of payload syms received +}; + +// create dsssframe64sync object +// _callback : callback function invoked when frame is received +// _userdata : user-defined data object passed to callback +dsssframe64sync dsssframe64sync_create(framesync_callback _callback, + void * _userdata) +{ + dsssframe64sync q = (dsssframe64sync) malloc(sizeof(struct dsssframe64sync_s)); + q->callback = _callback; + q->userdata = _userdata; + q->m = 7; // filter delay (symbols) + q->beta = 0.3f; // excess bandwidth factor + + unsigned int i; + + // generate p/n sequence + msequence ms = msequence_create(7, 0x0089, 1); + for (i=0; i<64; i++) { + q->preamble_pn[i] = (msequence_advance(ms) ? M_SQRT1_2 : -M_SQRT1_2); + q->preamble_pn[i] += (msequence_advance(ms) ? M_SQRT1_2 : -M_SQRT1_2)*_Complex_I; + } + msequence_destroy(ms); + + // create frame detector + unsigned int k = 2; // samples/symbol + q->detector = qdetector_cccf_create_linear(q->preamble_pn, 64, LIQUID_FIRFILT_ARKAISER, k, q->m, q->beta); + qdetector_cccf_set_threshold(q->detector, 0.5f); + + // create symbol timing recovery filters + q->npfb = 32; // number of filters in the bank + q->mf = firpfb_crcf_create_rnyquist(LIQUID_FIRFILT_ARKAISER, q->npfb,k,q->m,q->beta); + + // create down-coverters for carrier phase tracking + q->mixer = nco_crcf_create(LIQUID_NCO); + + // create payload demodulator/decoder object + int check = LIQUID_CRC_24; + int fec0 = LIQUID_FEC_NONE; + int fec1 = LIQUID_FEC_GOLAY2412; + int mod_scheme = LIQUID_MODEM_QPSK; + q->dec = qpacketmodem_create(); + qpacketmodem_configure(q->dec, 72, check, fec0, fec1, mod_scheme); + //qpacketmodem_print(q->dec); + assert( qpacketmodem_get_frame_len(q->dec)==600 ); + + // create pilot synchronizer + q->pilotsync = qpilotsync_create(600, 21); + assert( qpilotsync_get_frame_len(q->pilotsync)==630); + + // reset global data counters + dsssframe64sync_reset_framedatastats(q); + + // reset state and return + dsssframe64sync_reset(q); + return q; +} + +// copy object +dsssframe64sync dsssframe64sync_copy(dsssframe64sync q_orig) +{ + // validate input + if (q_orig == NULL) + return liquid_error_config("dsssframe64sync_copy(), object cannot be NULL"); + + // allocate memory for new object + dsssframe64sync q_copy = (dsssframe64sync) malloc(sizeof(struct dsssframe64sync_s)); + + // copy entire memory space over and overwrite values as needed + memmove(q_copy, q_orig, sizeof(struct dsssframe64sync_s)); + + // set callback and userdata fields + q_copy->callback = q_orig->callback; + q_copy->userdata = q_orig->userdata; + + // copy objects + q_copy->detector = qdetector_cccf_copy(q_orig->detector); + q_copy->mixer = nco_crcf_copy (q_orig->mixer); + q_copy->mf = firpfb_crcf_copy (q_orig->mf); + q_copy->dec = qpacketmodem_copy (q_orig->dec); + q_copy->pilotsync= qpilotsync_copy (q_orig->pilotsync); + + return q_copy; +} + +// destroy frame synchronizer object, freeing all internal memory +int dsssframe64sync_destroy(dsssframe64sync _q) +{ + // destroy synchronization objects + qdetector_cccf_destroy(_q->detector); // frame detector + firpfb_crcf_destroy (_q->mf); // matched filter + nco_crcf_destroy (_q->mixer); // coarse NCO + qpacketmodem_destroy (_q->dec); // payload demodulator + qpilotsync_destroy (_q->pilotsync); // pilot synchronizer + + // free main object memory + free(_q); + return LIQUID_OK; +} + +// print frame synchronizer object internals +int dsssframe64sync_print(dsssframe64sync _q) +{ + printf("dsssframe64sync:\n"); + return framedatastats_print(&_q->framedatastats); +} + +// reset frame synchronizer object +int dsssframe64sync_reset(dsssframe64sync _q) +{ + // reset binary pre-demod synchronizer + qdetector_cccf_reset(_q->detector); + + // reset carrier recovery objects + nco_crcf_reset(_q->mixer); + + // reset symbol timing recovery state + firpfb_crcf_reset(_q->mf); + + // reset state + _q->state = dsssframe64sync_STATE_DETECTFRAME; + _q->preamble_counter= 0; + _q->payload_counter = 0; + + // reset frame statistics + _q->framesyncstats.evm = 0.0f; + + return LIQUID_OK; +} + +// set the callback function +int dsssframe64sync_set_callback(dsssframe64sync _q, + framesync_callback _callback) +{ + _q->callback = _callback; + return LIQUID_OK; +} + +// set the user-defined data field (context) +int dsssframe64sync_set_userdata(dsssframe64sync _q, + void * _userdata) +{ + _q->userdata = _userdata; + return LIQUID_OK; +} + +// execute frame synchronizer +// _q : frame synchronizer object +// _x : input sample array [size: _n x 1] +// _n : number of input samples +int dsssframe64sync_execute(dsssframe64sync _q, + float complex * _x, + unsigned int _n) +{ + unsigned int i; + for (i=0; i<_n; i++) { + switch (_q->state) { + case dsssframe64sync_STATE_DETECTFRAME: + // detect frame (look for p/n sequence) + dsssframe64sync_execute_seekpn(_q, _x[i]); + break; + case dsssframe64sync_STATE_RXPREAMBLE: + // receive p/n sequence symbols + dsssframe64sync_execute_rxpreamble(_q, _x[i]); + break; + case dsssframe64sync_STATE_RXPAYLOAD: + // receive payload symbols + dsssframe64sync_execute_rxpayload(_q, _x[i]); + break; + default: + return liquid_error(LIQUID_EINT,"dsssframe64sync_exeucte(), unknown/unsupported state"); + } + } + return LIQUID_OK; +} + +// +// internal methods +// + +// execute synchronizer, seeking p/n sequence +// _q : frame synchronizer object +// _x : input sample +// _sym : demodulated symbol +int dsssframe64sync_execute_seekpn(dsssframe64sync _q, + float complex _x) +{ + // push through pre-demod synchronizer + float complex * v = qdetector_cccf_execute(_q->detector, _x); + + // check if frame has been detected + if (v != NULL) { + // get estimates + _q->tau_hat = qdetector_cccf_get_tau (_q->detector); + _q->gamma_hat = qdetector_cccf_get_gamma(_q->detector); + _q->dphi_hat = qdetector_cccf_get_dphi (_q->detector); + _q->phi_hat = qdetector_cccf_get_phi (_q->detector); + //printf("***** frame detected! tau-hat:%8.4f, dphi-hat:%8.4f, gamma:%8.2f dB\n", + // _q->tau_hat, _q->dphi_hat, 20*log10f(_q->gamma_hat)); + + // set appropriate filterbank index + if (_q->tau_hat > 0) { + _q->pfb_index = (unsigned int)( _q->tau_hat * _q->npfb) % _q->npfb; + _q->mf_counter = 0; + } else { + _q->pfb_index = (unsigned int)((1.0f+_q->tau_hat) * _q->npfb) % _q->npfb; + _q->mf_counter = 1; + } + + // output filter scale + firpfb_crcf_set_scale(_q->mf, 0.5f / _q->gamma_hat); + + // set frequency/phase of mixer + nco_crcf_set_frequency(_q->mixer, _q->dphi_hat); + nco_crcf_set_phase (_q->mixer, _q->phi_hat ); + + // update state + _q->state = dsssframe64sync_STATE_RXPREAMBLE; + + // run buffered samples through synchronizer + unsigned int buf_len = qdetector_cccf_get_buf_len(_q->detector); + dsssframe64sync_execute(_q, v, buf_len); + } + return LIQUID_OK; +} + +// step receiver mixer, matched filter, decimator +// _q : frame synchronizer +// _x : input sample +// _y : output symbol +int dsssframe64sync_step(dsssframe64sync _q, + float complex _x, + float complex * _y) +{ + // mix sample down + float complex v; + nco_crcf_mix_down(_q->mixer, _x, &v); + nco_crcf_step (_q->mixer); + + // push sample into filterbank + firpfb_crcf_push (_q->mf, v); + firpfb_crcf_execute(_q->mf, _q->pfb_index, &v); + + // increment counter to determine if sample is available + _q->mf_counter++; + int sample_available = (_q->mf_counter >= 1) ? 1 : 0; + + // set output sample if available + if (sample_available) { + + // set output + *_y = v; + + // decrement counter by k=2 samples/symbol + _q->mf_counter -= 2; + } + + // return flag + return sample_available; +} + +// execute synchronizer, receiving p/n sequence +// _q : frame synchronizer object +// _x : input sample +// _sym : demodulated symbol +int dsssframe64sync_execute_rxpreamble(dsssframe64sync _q, + float complex _x) +{ + // step synchronizer + float complex mf_out = 0.0f; + int sample_available = dsssframe64sync_step(_q, _x, &mf_out); + + // compute output if timeout + if (sample_available) { + + // save output in p/n symbols buffer + unsigned int delay = 2*_q->m; // delay from matched filter + if (_q->preamble_counter >= delay) { + unsigned int index = _q->preamble_counter-delay; + + _q->preamble_rx[index] = mf_out; + } + + // update p/n counter + _q->preamble_counter++; + + // update state + if (_q->preamble_counter == 64 + delay) + _q->state = dsssframe64sync_STATE_RXPAYLOAD; + } + return LIQUID_OK; +} + +// execute synchronizer, receiving payload +// _q : frame synchronizer object +// _x : input sample +// _sym : demodulated symbol +int dsssframe64sync_execute_rxpayload(dsssframe64sync _q, + float complex _x) +{ + // step synchronizer + float complex mf_out = 0.0f; + int sample_available = dsssframe64sync_step(_q, _x, &mf_out); + + // compute output if timeout + if (sample_available) { + // save payload symbols (modem input/output) + _q->payload_rx[_q->payload_counter] = mf_out; + + // increment counter + _q->payload_counter++; + + if (_q->payload_counter == 630) { + // recover data symbols from pilots + qpilotsync_execute(_q->pilotsync, _q->payload_rx, _q->payload_sym); + + // decode payload + _q->payload_valid = qpacketmodem_decode(_q->dec, + _q->payload_sym, + _q->payload_dec); + + // update statistics + _q->framedatastats.num_frames_detected++; + _q->framedatastats.num_headers_valid += _q->payload_valid; + _q->framedatastats.num_payloads_valid += _q->payload_valid; + _q->framedatastats.num_bytes_received += _q->payload_valid ? 64 : 0; + + // invoke callback + if (_q->callback != NULL) { + // set framesyncstats internals + _q->framesyncstats.evm = qpilotsync_get_evm(_q->pilotsync); + _q->framesyncstats.rssi = 20*log10f(_q->gamma_hat); + _q->framesyncstats.cfo = nco_crcf_get_frequency(_q->mixer); + _q->framesyncstats.framesyms = _q->payload_sym; + _q->framesyncstats.num_framesyms = 600; + _q->framesyncstats.mod_scheme = LIQUID_MODEM_QPSK; + _q->framesyncstats.mod_bps = 2; + _q->framesyncstats.check = LIQUID_CRC_24; + _q->framesyncstats.fec0 = LIQUID_FEC_NONE; + _q->framesyncstats.fec1 = LIQUID_FEC_GOLAY2412; + + // invoke callback method + int rc = + _q->callback(&_q->payload_dec[0], // header is first 8 bytes + _q->payload_valid, + &_q->payload_dec[8], // payload is last 64 bytes + 64, + _q->payload_valid, + _q->framesyncstats, + _q->userdata); + } + + // reset frame synchronizer + return dsssframe64sync_reset(_q); + } + } + return LIQUID_OK; +} + +// DEPRECATED: enable debugging +int dsssframe64sync_debug_enable(dsssframe64sync _q) +{ + return LIQUID_OK; +} + +// DEPRECATED: disable debugging +int dsssframe64sync_debug_disable(dsssframe64sync _q) +{ + return LIQUID_OK; +} + +// DEPRECATED: print debugging information +int dsssframe64sync_debug_print(dsssframe64sync _q, + const char * _filename) +{ + return LIQUID_OK; +} + +// get detection threshold +float dsssframe64sync_get_threshold(dsssframe64sync _q) +{ + return qdetector_cccf_get_threshold(_q->detector); +} + +// set detection threshold +int dsssframe64sync_set_threshold(dsssframe64sync _q, + float _threshold) +{ + return qdetector_cccf_set_threshold(_q->detector, _threshold); +} + +// reset frame data statistics +int dsssframe64sync_reset_framedatastats(dsssframe64sync _q) +{ + return framedatastats_reset(&_q->framedatastats); +} + +// retrieve frame data statistics +framedatastats_s dsssframe64sync_get_framedatastats(dsssframe64sync _q) +{ + return _q->framedatastats; +} + From 56d237bf0329fe9cad1f71f5768cb7401f8acfb4 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 16 Oct 2022 12:18:11 -0400 Subject: [PATCH 04/97] dsssframe64sync: completing methods to decode frame; not yet valid --- examples/dsssframe64sync_example.c | 21 +- src/framing/src/dsssframe64gen.c | 8 +- src/framing/src/dsssframe64sync.c | 449 ++++++++++------------------- 3 files changed, 173 insertions(+), 305 deletions(-) diff --git a/examples/dsssframe64sync_example.c b/examples/dsssframe64sync_example.c index 77592a0a6..7538a90c4 100644 --- a/examples/dsssframe64sync_example.c +++ b/examples/dsssframe64sync_example.c @@ -10,6 +10,20 @@ #include "liquid.h" +// static callback function +static int callback(unsigned char * _header, + int _header_valid, + unsigned char * _payload, + unsigned int _payload_len, + int _payload_valid, + framesyncstats_s _stats, + void * _userdata) +{ + printf("*** callback invoked (%s)***\n", _payload_valid ? "pass" : "FAIL"); + framesyncstats_print(&_stats); + return 0; +} + int main(int argc, char *argv[]) { // options @@ -30,9 +44,14 @@ int main(int argc, char *argv[]) dsssframe64gen_assemble(fg, NULL, NULL); dsssframe64gen_write(fg, buf_tx, buf_len); - // channel + // TODO: apply channel memmove(buf_rx, buf_tx, buf_len*sizeof(float complex)); + // run through sync + dsssframe64sync fs = dsssframe64sync_create(callback, NULL); + dsssframe64sync_execute(fs, buf_rx, buf_len); + dsssframe64sync_destroy(fs); + // push resulting sample through periodogram spgramcf_write(periodogram, buf_tx, buf_len); float psd[nfft]; diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index 3532fec04..4f1fec8bb 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -36,7 +36,7 @@ struct dsssframe64gen_s { qpacketmodem enc; // packet encoder/modulator qpilotgen pilotgen; // pilot symbol generator msequence ms; // spreading sequence generator - float complex pn_sequence[1024]; // 1024-symbol p/n sequence + float complex preamble_pn[1024]; // 1024-symbol p/n sequence unsigned char payload_dec[ 150]; // 600 = 150 bytes * 8 bits/bytes / 2 bits/symbol float complex payload_sym[ 600]; // modulated payload symbols float complex payload_tx [ 630]; // modulated payload symbols with pilots @@ -59,8 +59,8 @@ dsssframe64gen dsssframe64gen_create() // generate p/n sequence q->ms = msequence_create(11, 0x0805, 1); for (i=0; i<1024; i++) { - q->pn_sequence[i] = (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2); - q->pn_sequence[i] += (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2)*_Complex_I; + q->preamble_pn[i] = (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2); + q->preamble_pn[i] += (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2)*_Complex_I; } // create payload encoder/modulator object @@ -159,7 +159,7 @@ int dsssframe64gen_write(dsssframe64gen _q, // p/n sequence for (i=0; i<1024; i++) { - firinterp_crcf_execute(_q->interp, _q->pn_sequence[i], &_buf[n]); + firinterp_crcf_execute(_q->interp, _q->preamble_pn[i], &_buf[n]); n+=2; } diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 892251816..b1f55d23d 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -31,72 +31,47 @@ #include "liquid.internal.h" -#define dsssframe64sync_ENABLE_EQ 0 - -// push samples through detection stage -int dsssframe64sync_execute_seekpn(dsssframe64sync _q, - float complex _x); - -// step receiver mixer, matched filter, decimator -// _q : frame synchronizer -// _x : input sample -// _y : output symbol +// internal update int dsssframe64sync_step(dsssframe64sync _q, - float complex _x, - float complex * _y); - -// push samples through synchronizer, saving received p/n symbols -int dsssframe64sync_execute_rxpreamble(dsssframe64sync _q, - float complex _x); + float complex * _buf, + unsigned int _buf_len); -// receive payload symbols -int dsssframe64sync_execute_rxpayload(dsssframe64sync _q, - float complex _x); +// internal decode received frame, update statistics, invoke callback +int dsssframe64sync_decode(dsssframe64sync _q); -// export debugging based on return value -// 0 : do not write file -// >0 : write specific number (hex) -// -1 : number of packets detected -// -2 : id using first 4 bytes of header -// -3 : write with random extension -int dsssframe64sync_debug_export(dsssframe64sync _q, int _code); +// internal synchronization callback, return 0:continue, 1:reset +int dsssframe64sync_callback_internal(float complex * _buf, + unsigned int _buf_len, + void * _context) +{ return dsssframe64sync_step((dsssframe64sync) _context, _buf, _buf_len); } // dsssframe64sync object structure struct dsssframe64sync_s { // callback framesync_callback callback; // user-defined callback function - void * userdata; // user-defined data structure + void * context; // user-defined data structure + unsigned int m; // filter delay (symbols) + float beta; // filter excess bandwidth factor + framesyncstats_s framesyncstats; // frame statistic object (synchronizer) framedatastats_s framedatastats; // frame statistic object (packet statistics) - // synchronizer objects - unsigned int m; // filter delay (symbols) - float beta; // filter excess bandwidth factor - qdetector_cccf detector; // pre-demod detector - float tau_hat; // fractional timing offset estimate - float dphi_hat; // carrier frequency offset estimate - float phi_hat; // carrier phase offset estimate - float gamma_hat; // channel gain estimate - nco_crcf mixer; // coarse carrier frequency recovery - - // timing recovery objects, states - firpfb_crcf mf; // matched filter decimator - unsigned int npfb; // number of filters in symsync - int mf_counter; // matched filter output timer - unsigned int pfb_index; // filterbank index - // preamble - float complex preamble_pn[64]; // known 64-symbol p/n sequence - float complex preamble_rx[64]; // received p/n symbols - + float complex preamble_pn[1024]; // known 1024-symbol p/n sequence + float complex preamble_rx[1024]; // received p/n symbols + // payload decoder float complex payload_rx [630]; // received payload symbols with pilots float complex payload_sym[600]; // received payload symbols unsigned char payload_dec[ 72]; // decoded payload bytes + + qdsync_cccf detector; // frame detector + msequence ms; // spreading sequence generator + float complex sym_despread; // despread symbol + qpacketmodem dec; // packet demodulator/decoder qpilotsync pilotsync; // pilot extraction, carrier recovery - int payload_valid; // did payload pass crc? - + // status variables enum { dsssframe64sync_STATE_DETECTFRAME=0, // detect frame (seek p/n sequence) @@ -104,43 +79,37 @@ struct dsssframe64sync_s { dsssframe64sync_STATE_RXPAYLOAD, // receive payload data } state; unsigned int preamble_counter; // counter: num of p/n syms received + unsigned int chip_counter; // counter: num of payload chips received for a single symbol unsigned int payload_counter; // counter: num of payload syms received }; // create dsssframe64sync object // _callback : callback function invoked when frame is received -// _userdata : user-defined data object passed to callback +// _context : user-defined data object passed to callback dsssframe64sync dsssframe64sync_create(framesync_callback _callback, - void * _userdata) + void * _context) { dsssframe64sync q = (dsssframe64sync) malloc(sizeof(struct dsssframe64sync_s)); q->callback = _callback; - q->userdata = _userdata; - q->m = 7; // filter delay (symbols) - q->beta = 0.3f; // excess bandwidth factor + q->context = _context; + q->m = 15; // filter delay (symbols) + q->beta = 0.20f;// excess bandwidth factor unsigned int i; // generate p/n sequence - msequence ms = msequence_create(7, 0x0089, 1); - for (i=0; i<64; i++) { - q->preamble_pn[i] = (msequence_advance(ms) ? M_SQRT1_2 : -M_SQRT1_2); - q->preamble_pn[i] += (msequence_advance(ms) ? M_SQRT1_2 : -M_SQRT1_2)*_Complex_I; + q->ms = msequence_create(11, 0x0805, 1); + for (i=0; i<1024; i++) { + q->preamble_pn[i] = (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2); + q->preamble_pn[i] += (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2)*_Complex_I; } - msequence_destroy(ms); // create frame detector - unsigned int k = 2; // samples/symbol - q->detector = qdetector_cccf_create_linear(q->preamble_pn, 64, LIQUID_FIRFILT_ARKAISER, k, q->m, q->beta); - qdetector_cccf_set_threshold(q->detector, 0.5f); - - // create symbol timing recovery filters - q->npfb = 32; // number of filters in the bank - q->mf = firpfb_crcf_create_rnyquist(LIQUID_FIRFILT_ARKAISER, q->npfb,k,q->m,q->beta); + unsigned int k = 2; // samples/symbol + q->detector = qdsync_cccf_create_linear(q->preamble_pn, 1024, LIQUID_FIRFILT_ARKAISER, k, q->m, q->beta, + dsssframe64sync_callback_internal, (void*)q); + qdsync_cccf_set_threshold(q->detector, 0.5f); - // create down-coverters for carrier phase tracking - q->mixer = nco_crcf_create(LIQUID_NCO); - // create payload demodulator/decoder object int check = LIQUID_CRC_24; int fec0 = LIQUID_FEC_NONE; @@ -154,7 +123,7 @@ dsssframe64sync dsssframe64sync_create(framesync_callback _callback, // create pilot synchronizer q->pilotsync = qpilotsync_create(600, 21); assert( qpilotsync_get_frame_len(q->pilotsync)==630); - + // reset global data counters dsssframe64sync_reset_framedatastats(q); @@ -166,6 +135,7 @@ dsssframe64sync dsssframe64sync_create(framesync_callback _callback, // copy object dsssframe64sync dsssframe64sync_copy(dsssframe64sync q_orig) { +#if 0 // validate input if (q_orig == NULL) return liquid_error_config("dsssframe64sync_copy(), object cannot be NULL"); @@ -176,29 +146,29 @@ dsssframe64sync dsssframe64sync_copy(dsssframe64sync q_orig) // copy entire memory space over and overwrite values as needed memmove(q_copy, q_orig, sizeof(struct dsssframe64sync_s)); - // set callback and userdata fields + // set callback and context fields q_copy->callback = q_orig->callback; - q_copy->userdata = q_orig->userdata; + q_copy->context = q_orig->context; // copy objects - q_copy->detector = qdetector_cccf_copy(q_orig->detector); - q_copy->mixer = nco_crcf_copy (q_orig->mixer); - q_copy->mf = firpfb_crcf_copy (q_orig->mf); + q_copy->detector = qdsync_cccf_copy(q_orig->detector); q_copy->dec = qpacketmodem_copy (q_orig->dec); q_copy->pilotsync= qpilotsync_copy (q_orig->pilotsync); return q_copy; +#else + return liquid_error_config("dsssframe64sync_copy(), method not yet implemented"); +#endif } // destroy frame synchronizer object, freeing all internal memory int dsssframe64sync_destroy(dsssframe64sync _q) { // destroy synchronization objects - qdetector_cccf_destroy(_q->detector); // frame detector - firpfb_crcf_destroy (_q->mf); // matched filter - nco_crcf_destroy (_q->mixer); // coarse NCO - qpacketmodem_destroy (_q->dec); // payload demodulator - qpilotsync_destroy (_q->pilotsync); // pilot synchronizer + msequence_destroy (_q->ms); // + qdsync_cccf_destroy (_q->detector); // frame detector + qpacketmodem_destroy(_q->dec); // payload demodulator + qpilotsync_destroy (_q->pilotsync); // pilot synchronizer // free main object memory free(_q); @@ -208,27 +178,23 @@ int dsssframe64sync_destroy(dsssframe64sync _q) // print frame synchronizer object internals int dsssframe64sync_print(dsssframe64sync _q) { - printf("dsssframe64sync:\n"); - return framedatastats_print(&_q->framedatastats); + printf("\n"); + return LIQUID_OK; } // reset frame synchronizer object int dsssframe64sync_reset(dsssframe64sync _q) { // reset binary pre-demod synchronizer - qdetector_cccf_reset(_q->detector); + qdsync_cccf_reset(_q->detector); - // reset carrier recovery objects - nco_crcf_reset(_q->mixer); - - // reset symbol timing recovery state - firpfb_crcf_reset(_q->mf); - // reset state _q->state = dsssframe64sync_STATE_DETECTFRAME; _q->preamble_counter= 0; + _q->chip_counter = 0; _q->payload_counter = 0; - + _q->sym_despread = 0; + // reset frame statistics _q->framesyncstats.evm = 0.0f; @@ -236,7 +202,7 @@ int dsssframe64sync_reset(dsssframe64sync _q) } // set the callback function -int dsssframe64sync_set_callback(dsssframe64sync _q, +int dsssframe64sync_set_callback(dsssframe64sync _q, framesync_callback _callback) { _q->callback = _callback; @@ -244,10 +210,10 @@ int dsssframe64sync_set_callback(dsssframe64sync _q, } // set the user-defined data field (context) -int dsssframe64sync_set_userdata(dsssframe64sync _q, - void * _userdata) +int dsssframe64sync_set_context(dsssframe64sync _q, + void * _context) { - _q->userdata = _userdata; + _q->context= _context; return LIQUID_OK; } @@ -255,10 +221,11 @@ int dsssframe64sync_set_userdata(dsssframe64sync _q, // _q : frame synchronizer object // _x : input sample array [size: _n x 1] // _n : number of input samples -int dsssframe64sync_execute(dsssframe64sync _q, - float complex * _x, - unsigned int _n) +int dsssframe64sync_execute(dsssframe64sync _q, + float complex * _buf, + unsigned int _buf_len) { +#if 0 unsigned int i; for (i=0; i<_n; i++) { switch (_q->state) { @@ -278,222 +245,23 @@ int dsssframe64sync_execute(dsssframe64sync _q, return liquid_error(LIQUID_EINT,"dsssframe64sync_exeucte(), unknown/unsupported state"); } } - return LIQUID_OK; -} - -// -// internal methods -// - -// execute synchronizer, seeking p/n sequence -// _q : frame synchronizer object -// _x : input sample -// _sym : demodulated symbol -int dsssframe64sync_execute_seekpn(dsssframe64sync _q, - float complex _x) -{ - // push through pre-demod synchronizer - float complex * v = qdetector_cccf_execute(_q->detector, _x); - - // check if frame has been detected - if (v != NULL) { - // get estimates - _q->tau_hat = qdetector_cccf_get_tau (_q->detector); - _q->gamma_hat = qdetector_cccf_get_gamma(_q->detector); - _q->dphi_hat = qdetector_cccf_get_dphi (_q->detector); - _q->phi_hat = qdetector_cccf_get_phi (_q->detector); - //printf("***** frame detected! tau-hat:%8.4f, dphi-hat:%8.4f, gamma:%8.2f dB\n", - // _q->tau_hat, _q->dphi_hat, 20*log10f(_q->gamma_hat)); - - // set appropriate filterbank index - if (_q->tau_hat > 0) { - _q->pfb_index = (unsigned int)( _q->tau_hat * _q->npfb) % _q->npfb; - _q->mf_counter = 0; - } else { - _q->pfb_index = (unsigned int)((1.0f+_q->tau_hat) * _q->npfb) % _q->npfb; - _q->mf_counter = 1; - } - - // output filter scale - firpfb_crcf_set_scale(_q->mf, 0.5f / _q->gamma_hat); - - // set frequency/phase of mixer - nco_crcf_set_frequency(_q->mixer, _q->dphi_hat); - nco_crcf_set_phase (_q->mixer, _q->phi_hat ); - - // update state - _q->state = dsssframe64sync_STATE_RXPREAMBLE; - - // run buffered samples through synchronizer - unsigned int buf_len = qdetector_cccf_get_buf_len(_q->detector); - dsssframe64sync_execute(_q, v, buf_len); - } - return LIQUID_OK; -} - -// step receiver mixer, matched filter, decimator -// _q : frame synchronizer -// _x : input sample -// _y : output symbol -int dsssframe64sync_step(dsssframe64sync _q, - float complex _x, - float complex * _y) -{ - // mix sample down - float complex v; - nco_crcf_mix_down(_q->mixer, _x, &v); - nco_crcf_step (_q->mixer); - - // push sample into filterbank - firpfb_crcf_push (_q->mf, v); - firpfb_crcf_execute(_q->mf, _q->pfb_index, &v); - - // increment counter to determine if sample is available - _q->mf_counter++; - int sample_available = (_q->mf_counter >= 1) ? 1 : 0; - - // set output sample if available - if (sample_available) { - - // set output - *_y = v; - - // decrement counter by k=2 samples/symbol - _q->mf_counter -= 2; - } - - // return flag - return sample_available; -} - -// execute synchronizer, receiving p/n sequence -// _q : frame synchronizer object -// _x : input sample -// _sym : demodulated symbol -int dsssframe64sync_execute_rxpreamble(dsssframe64sync _q, - float complex _x) -{ - // step synchronizer - float complex mf_out = 0.0f; - int sample_available = dsssframe64sync_step(_q, _x, &mf_out); - - // compute output if timeout - if (sample_available) { - - // save output in p/n symbols buffer - unsigned int delay = 2*_q->m; // delay from matched filter - if (_q->preamble_counter >= delay) { - unsigned int index = _q->preamble_counter-delay; - - _q->preamble_rx[index] = mf_out; - } - - // update p/n counter - _q->preamble_counter++; - - // update state - if (_q->preamble_counter == 64 + delay) - _q->state = dsssframe64sync_STATE_RXPAYLOAD; - } - return LIQUID_OK; -} - -// execute synchronizer, receiving payload -// _q : frame synchronizer object -// _x : input sample -// _sym : demodulated symbol -int dsssframe64sync_execute_rxpayload(dsssframe64sync _q, - float complex _x) -{ - // step synchronizer - float complex mf_out = 0.0f; - int sample_available = dsssframe64sync_step(_q, _x, &mf_out); - - // compute output if timeout - if (sample_available) { - // save payload symbols (modem input/output) - _q->payload_rx[_q->payload_counter] = mf_out; - - // increment counter - _q->payload_counter++; - - if (_q->payload_counter == 630) { - // recover data symbols from pilots - qpilotsync_execute(_q->pilotsync, _q->payload_rx, _q->payload_sym); - - // decode payload - _q->payload_valid = qpacketmodem_decode(_q->dec, - _q->payload_sym, - _q->payload_dec); - - // update statistics - _q->framedatastats.num_frames_detected++; - _q->framedatastats.num_headers_valid += _q->payload_valid; - _q->framedatastats.num_payloads_valid += _q->payload_valid; - _q->framedatastats.num_bytes_received += _q->payload_valid ? 64 : 0; - - // invoke callback - if (_q->callback != NULL) { - // set framesyncstats internals - _q->framesyncstats.evm = qpilotsync_get_evm(_q->pilotsync); - _q->framesyncstats.rssi = 20*log10f(_q->gamma_hat); - _q->framesyncstats.cfo = nco_crcf_get_frequency(_q->mixer); - _q->framesyncstats.framesyms = _q->payload_sym; - _q->framesyncstats.num_framesyms = 600; - _q->framesyncstats.mod_scheme = LIQUID_MODEM_QPSK; - _q->framesyncstats.mod_bps = 2; - _q->framesyncstats.check = LIQUID_CRC_24; - _q->framesyncstats.fec0 = LIQUID_FEC_NONE; - _q->framesyncstats.fec1 = LIQUID_FEC_GOLAY2412; - - // invoke callback method - int rc = - _q->callback(&_q->payload_dec[0], // header is first 8 bytes - _q->payload_valid, - &_q->payload_dec[8], // payload is last 64 bytes - 64, - _q->payload_valid, - _q->framesyncstats, - _q->userdata); - } - - // reset frame synchronizer - return dsssframe64sync_reset(_q); - } - } - return LIQUID_OK; -} - -// DEPRECATED: enable debugging -int dsssframe64sync_debug_enable(dsssframe64sync _q) -{ - return LIQUID_OK; -} - -// DEPRECATED: disable debugging -int dsssframe64sync_debug_disable(dsssframe64sync _q) -{ - return LIQUID_OK; -} - -// DEPRECATED: print debugging information -int dsssframe64sync_debug_print(dsssframe64sync _q, - const char * _filename) -{ +#else + qdsync_cccf_execute(_q->detector, _buf, _buf_len); +#endif return LIQUID_OK; } // get detection threshold float dsssframe64sync_get_threshold(dsssframe64sync _q) { - return qdetector_cccf_get_threshold(_q->detector); + return qdsync_cccf_get_threshold(_q->detector); } // set detection threshold int dsssframe64sync_set_threshold(dsssframe64sync _q, float _threshold) { - return qdetector_cccf_set_threshold(_q->detector, _threshold); + return qdsync_cccf_set_threshold(_q->detector, _threshold); } // reset frame data statistics @@ -508,3 +276,84 @@ framedatastats_s dsssframe64sync_get_framedatastats(dsssframe64sync _q) return _q->framedatastats; } +// internal update +int dsssframe64sync_step(dsssframe64sync _q, + float complex * _buf, + unsigned int _buf_len) +{ + // TODO: do this more efficiently? + unsigned int i; + for (i=0; i<_buf_len; i++) { + // receive preamble + if (_q->preamble_counter < 1024) { + _q->preamble_rx[_q->preamble_counter++] = _buf[i]; + continue; + } + + // generate pseudo-random symbol + unsigned int p = msequence_generate_symbol(_q->ms, 2); + float complex s = cexpf(_Complex_I*2*M_PI*(float)p/(float)4); + _q->sym_despread += _buf[i] * conjf(s); + _q->chip_counter++; + + if (_q->chip_counter == 256) { + _q->payload_rx[_q->payload_counter] = _q->sym_despread / 256.0f; + _q->payload_counter++; + _q->chip_counter = 0; + if (_q->payload_counter == 630) { + dsssframe64sync_decode(_q); + return 1; // reset + } + } + } + + return 0; // need more data +} + +// internal decode received frame, update statistics, invoke callback +int dsssframe64sync_decode(dsssframe64sync _q) +{ + printf("dsssframe64sync: frame received!\n"); + + // recover data symbols from pilots + qpilotsync_execute(_q->pilotsync, _q->payload_rx, _q->payload_sym); + + // decode payload + int crc_pass = qpacketmodem_decode(_q->dec, _q->payload_sym, _q->payload_dec); + + // update statistics + _q->framedatastats.num_frames_detected++; + _q->framedatastats.num_headers_valid += crc_pass; + _q->framedatastats.num_payloads_valid += crc_pass; + _q->framedatastats.num_bytes_received += crc_pass ? 64 : 0; + + // invoke callback + int rc = 0; + if (_q->callback != NULL) { + // set framesyncstats internals + _q->framesyncstats.evm = qpilotsync_get_evm(_q->pilotsync); + _q->framesyncstats.rssi = 0; //20*log10f(qdsync_cccf_get_gamma(_q->detector)); + _q->framesyncstats.cfo = 0; //qdsync_cccf_get_frequency(_q->detector); + _q->framesyncstats.framesyms = _q->payload_sym; + _q->framesyncstats.num_framesyms = 600; + _q->framesyncstats.mod_scheme = LIQUID_MODEM_QPSK; + _q->framesyncstats.mod_bps = 2; + _q->framesyncstats.check = LIQUID_CRC_24; + _q->framesyncstats.fec0 = LIQUID_FEC_NONE; + _q->framesyncstats.fec1 = LIQUID_FEC_GOLAY2412; + + // invoke callback method + rc = _q->callback(&_q->payload_dec[0], // header is first 8 bytes + crc_pass, + &_q->payload_dec[8], // payload is last 64 bytes + 64, + crc_pass, + _q->framesyncstats, + _q->context); + } + + // reset frame synchronizer and return + dsssframe64sync_reset(_q); + return rc; +} + From 4b4f5c42c29d03af204638823490984fcce6c4f1 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 16 Oct 2022 16:13:09 -0400 Subject: [PATCH 05/97] dsssframe64sync: fixing frame synchronizer to properly recover data * qdetector clearly the limiting factor in speed, here * qdsync works exactly as expected, and greatly simplifies interface * can probably get away with smaller spreading rate (256) as detection with 1024-chip preamble limits packet decoding down to about -15 dB SNR * increasing preamble will likely slow down processing too much --- examples/dsssframe64sync_example.c | 56 ++++++++++++++++++------------ include/liquid.h | 22 +++++++++++- src/framing/src/dsssframe64gen.c | 1 - src/framing/src/dsssframe64sync.c | 56 +++++++++++++----------------- 4 files changed, 79 insertions(+), 56 deletions(-) diff --git a/examples/dsssframe64sync_example.c b/examples/dsssframe64sync_example.c index 7538a90c4..981669af1 100644 --- a/examples/dsssframe64sync_example.c +++ b/examples/dsssframe64sync_example.c @@ -17,17 +17,27 @@ static int callback(unsigned char * _header, unsigned int _payload_len, int _payload_valid, framesyncstats_s _stats, - void * _userdata) + void * _context) { printf("*** callback invoked (%s)***\n", _payload_valid ? "pass" : "FAIL"); framesyncstats_print(&_stats); + + // save recovered symbols to file + unsigned int i; + FILE * fid = (FILE*)_context; + for (i=0; i<_stats.num_framesyms; i++) { + fprintf(fid,"s(%3u) = %12.8f + %12.8fj;\n", i+1, + crealf(_stats.framesyms[i]), cimagf(_stats.framesyms[i])); + } return 0; } int main(int argc, char *argv[]) { // options - unsigned int nfft=2400; + unsigned int nfft = 2400; + float SNRdB = -15.0f; + const char * filename = "dsssframe64sync_example.m"; // create dsssframe64gen object dsssframe64gen fg = dsssframe64gen_create(); @@ -37,48 +47,50 @@ int main(int argc, char *argv[]) float complex buf_tx[buf_len]; // transmit buffer float complex buf_rx[buf_len]; // receive buffer (channel output) - // create spectral periodogram for displaying spectrum - spgramcf periodogram = spgramcf_create_default(nfft); + // export results to file + FILE * fid = fopen(filename,"w"); + fprintf(fid,"%% %s : auto-generated file\n", filename); + fprintf(fid,"clear all; close all;\n"); + fprintf(fid,"s=[];\n"); // generate in one step (for now) dsssframe64gen_assemble(fg, NULL, NULL); dsssframe64gen_write(fg, buf_tx, buf_len); - // TODO: apply channel - memmove(buf_rx, buf_tx, buf_len*sizeof(float complex)); + // apply channel (AWGN) + float nstd = powf(10.0f,-SNRdB/20.0f); + unsigned int i; + for (i=0; iinterp); - msequence_reset(_q->ms); // frame_assembled = 1 return LIQUID_OK; diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index b1f55d23d..417c643e3 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -108,7 +108,7 @@ dsssframe64sync dsssframe64sync_create(framesync_callback _callback, unsigned int k = 2; // samples/symbol q->detector = qdsync_cccf_create_linear(q->preamble_pn, 1024, LIQUID_FIRFILT_ARKAISER, k, q->m, q->beta, dsssframe64sync_callback_internal, (void*)q); - qdsync_cccf_set_threshold(q->detector, 0.5f); + qdsync_cccf_set_threshold(q->detector, 0.100f); // create payload demodulator/decoder object int check = LIQUID_CRC_24; @@ -201,6 +201,11 @@ int dsssframe64sync_reset(dsssframe64sync _q) return LIQUID_OK; } +int dsssframe64sync_is_frame_open(dsssframe64sync _q) +{ + return _q->preamble_counter > 0; +} + // set the callback function int dsssframe64sync_set_callback(dsssframe64sync _q, framesync_callback _callback) @@ -218,37 +223,15 @@ int dsssframe64sync_set_context(dsssframe64sync _q, } // execute frame synchronizer -// _q : frame synchronizer object -// _x : input sample array [size: _n x 1] -// _n : number of input samples +// _q : frame synchronizer object +// _buf : input sample array, shape: (_buf_len,) +// _buf_len : number of input samples int dsssframe64sync_execute(dsssframe64sync _q, float complex * _buf, unsigned int _buf_len) { -#if 0 - unsigned int i; - for (i=0; i<_n; i++) { - switch (_q->state) { - case dsssframe64sync_STATE_DETECTFRAME: - // detect frame (look for p/n sequence) - dsssframe64sync_execute_seekpn(_q, _x[i]); - break; - case dsssframe64sync_STATE_RXPREAMBLE: - // receive p/n sequence symbols - dsssframe64sync_execute_rxpreamble(_q, _x[i]); - break; - case dsssframe64sync_STATE_RXPAYLOAD: - // receive payload symbols - dsssframe64sync_execute_rxpayload(_q, _x[i]); - break; - default: - return liquid_error(LIQUID_EINT,"dsssframe64sync_exeucte(), unknown/unsupported state"); - } - } -#else - qdsync_cccf_execute(_q->detector, _buf, _buf_len); -#endif - return LIQUID_OK; + // run detector/synchronizer, invoking internal callback as needed + return qdsync_cccf_execute(_q->detector, _buf, _buf_len); } // get detection threshold @@ -259,7 +242,7 @@ float dsssframe64sync_get_threshold(dsssframe64sync _q) // set detection threshold int dsssframe64sync_set_threshold(dsssframe64sync _q, - float _threshold) + float _threshold) { return qdsync_cccf_set_threshold(_q->detector, _threshold); } @@ -300,6 +283,7 @@ int dsssframe64sync_step(dsssframe64sync _q, _q->payload_rx[_q->payload_counter] = _q->sym_despread / 256.0f; _q->payload_counter++; _q->chip_counter = 0; + _q->sym_despread = 0; if (_q->payload_counter == 630) { dsssframe64sync_decode(_q); return 1; // reset @@ -313,14 +297,22 @@ int dsssframe64sync_step(dsssframe64sync _q, // internal decode received frame, update statistics, invoke callback int dsssframe64sync_decode(dsssframe64sync _q) { - printf("dsssframe64sync: frame received!\n"); - // recover data symbols from pilots qpilotsync_execute(_q->pilotsync, _q->payload_rx, _q->payload_sym); // decode payload int crc_pass = qpacketmodem_decode(_q->dec, _q->payload_sym, _q->payload_dec); - +#if 0 + // debug: export symbols to file + unsigned int i; + FILE * fid = fopen("dsssframe64sync_debug.m","w"); + fprintf(fid,"clear all; close all; r=zeros(1,630); s=zeros(1,600);\n"); + for (i=0; i<630; i++) + fprintf(fid,"r(%3u)=%12.4e + %12.4ej;\n", i+1, crealf(_q->payload_rx[i]), cimagf(_q->payload_rx[i])); + for (i=0; i<600; i++) + fprintf(fid,"s(%3u)=%12.4e + %12.4ej;\n", i+1, crealf(_q->payload_sym[i]), cimagf(_q->payload_sym[i])); + fclose(fid); +#endif // update statistics _q->framedatastats.num_frames_detected++; _q->framedatastats.num_headers_valid += crc_pass; From 93bc2514b8e3312b4d0c84a3574f0fa3e764027b Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 16 Oct 2022 17:20:04 -0400 Subject: [PATCH 06/97] dsssframe64sync: allow setting for maximum carrier offset * causing majority of processing latency in frame detection * tightening up search range for now * run substantially faster with no frame present (nearly 10x) --- include/liquid.h | 4 ++++ src/framing/src/dsssframe64sync.c | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/include/liquid.h b/include/liquid.h index d71af6cca..36be3cea3 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -5960,6 +5960,10 @@ float dsssframe64sync_get_threshold(dsssframe64sync _q); int dsssframe64sync_set_threshold(dsssframe64sync _q, float _threshold); +// set carrier offset search range +int dsssframe64sync_set_range(dsssframe64sync _q, + float _dphi_max); + // reset frame data statistics int dsssframe64sync_reset_framedatastats(dsssframe64sync _q); diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 417c643e3..1eda10091 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -108,7 +108,8 @@ dsssframe64sync dsssframe64sync_create(framesync_callback _callback, unsigned int k = 2; // samples/symbol q->detector = qdsync_cccf_create_linear(q->preamble_pn, 1024, LIQUID_FIRFILT_ARKAISER, k, q->m, q->beta, dsssframe64sync_callback_internal, (void*)q); - qdsync_cccf_set_threshold(q->detector, 0.100f); + qdsync_cccf_set_threshold(q->detector, 0.100f); // detection threshold + qdsync_cccf_set_range (q->detector, 0.006f); // frequency offset search range [radians/sample] // create payload demodulator/decoder object int check = LIQUID_CRC_24; @@ -247,6 +248,13 @@ int dsssframe64sync_set_threshold(dsssframe64sync _q, return qdsync_cccf_set_threshold(_q->detector, _threshold); } +// set carrier offset search range +int dsssframe64sync_set_range(dsssframe64sync _q, + float _dphi_max) +{ + return qdsync_cccf_set_range(_q->detector, _dphi_max); +} + // reset frame data statistics int dsssframe64sync_reset_framedatastats(dsssframe64sync _q) { From f50b92f58250134016dd054c4084425a4db326ea Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Mon, 17 Oct 2022 08:29:44 -0400 Subject: [PATCH 07/97] dsssframe64: reseting sequence generator for each frame --- src/framing/src/dsssframe64gen.c | 1 + src/framing/src/dsssframe64sync.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index 7b095af1f..4f1fec8bb 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -141,6 +141,7 @@ int dsssframe64gen_assemble(dsssframe64gen _q, // reset objects firinterp_crcf_reset(_q->interp); + msequence_reset(_q->ms); // frame_assembled = 1 return LIQUID_OK; diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 1eda10091..29152123e 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -186,8 +186,9 @@ int dsssframe64sync_print(dsssframe64sync _q) // reset frame synchronizer object int dsssframe64sync_reset(dsssframe64sync _q) { - // reset binary pre-demod synchronizer + // reset detector/synchronizer qdsync_cccf_reset(_q->detector); + msequence_reset(_q->ms); // reset state _q->state = dsssframe64sync_STATE_DETECTFRAME; From 6a8f3e78e1d9c0510296bd7591d0d033a94db52e Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Mon, 17 Oct 2022 22:47:41 -0400 Subject: [PATCH 08/97] dsssframe64/autotest: adding basic autotest --- makefile.in | 1 + src/framing/tests/dsssframe64sync_autotest.c | 85 ++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/framing/tests/dsssframe64sync_autotest.c diff --git a/makefile.in b/makefile.in index 3ede9d924..cf8e15823 100644 --- a/makefile.in +++ b/makefile.in @@ -690,6 +690,7 @@ framing_autotests := \ src/framing/tests/bpacketsync_autotest.c \ src/framing/tests/bsync_autotest.c \ src/framing/tests/detector_autotest.c \ + src/framing/tests/dsssframe64sync_autotest.c \ src/framing/tests/dsssframesync_autotest.c \ src/framing/tests/flexframesync_autotest.c \ src/framing/tests/framesync64_autotest.c \ diff --git a/src/framing/tests/dsssframe64sync_autotest.c b/src/framing/tests/dsssframe64sync_autotest.c new file mode 100644 index 000000000..8e4a10fe4 --- /dev/null +++ b/src/framing/tests/dsssframe64sync_autotest.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2007 - 2022 Joseph Gaeddert + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include +#include +#include "autotest/autotest.h" +#include "liquid.h" + +static int callback_dsssframe64sync_autotest( + unsigned char * _header, + int _header_valid, + unsigned char * _payload, + unsigned int _payload_len, + int _payload_valid, + framesyncstats_s _stats, + void * _userdata) +{ + //printf("callback invoked, payload valid: %s\n", _payload_valid ? "yes" : "no"); + int * frames_recovered = (int*) _userdata; + + *frames_recovered += _header_valid && _payload_valid ? 1 : 0; + return 0; +} + +// AUTOTEST : test simple recovery of frame in noise +void autotest_dsssframe64sync() +{ + unsigned int i; + int frames_recovered = 0; + + // create objects + dsssframe64gen fg = dsssframe64gen_create(); + dsssframe64sync fs = dsssframe64sync_create(callback_dsssframe64sync_autotest, + (void*)&frames_recovered); + dsssframe64sync_set_threshold(fs, 0.5f); + + // generate the frame + unsigned int frame_len = dsssframe64gen_get_frame_len(fg); + float complex frame[frame_len]; + dsssframe64gen_assemble(fg, NULL, NULL); + dsssframe64gen_write (fg, frame, frame_len); + + // add some noise + for (i=0; i Date: Mon, 17 Oct 2022 22:49:07 -0400 Subject: [PATCH 09/97] dsssframe64sync: cleaning up synchronizer, removing unused state enum --- examples/dsssframe64sync_example.c | 2 +- src/framing/src/dsssframe64sync.c | 27 +++++++++++---------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/examples/dsssframe64sync_example.c b/examples/dsssframe64sync_example.c index 981669af1..c82c75adc 100644 --- a/examples/dsssframe64sync_example.c +++ b/examples/dsssframe64sync_example.c @@ -19,7 +19,7 @@ static int callback(unsigned char * _header, framesyncstats_s _stats, void * _context) { - printf("*** callback invoked (%s)***\n", _payload_valid ? "pass" : "FAIL"); + printf("*** callback invoked (%s) ***\n", _payload_valid ? "pass" : "FAIL"); framesyncstats_print(&_stats); // save recovered symbols to file diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 29152123e..70a6dca63 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -20,7 +20,8 @@ * THE SOFTWARE. */ -// basic frame synchronizer with 8 bytes header and 64 bytes payload +// basic direct sequence/spread spectrum frame synchronizer with 8 bytes header +// and 64 bytes payload #include #include @@ -50,34 +51,29 @@ struct dsssframe64sync_s { // callback framesync_callback callback; // user-defined callback function void * context; // user-defined data structure - unsigned int m; // filter delay (symbols) - float beta; // filter excess bandwidth factor + unsigned int m; // filter delay (symbols) + float beta; // filter excess bandwidth factor - framesyncstats_s framesyncstats; // frame statistic object (synchronizer) - framedatastats_s framedatastats; // frame statistic object (packet statistics) + framesyncstats_s framesyncstats;// frame statistic object (synchronizer) + framedatastats_s framedatastats;// frame statistic object (packet statistics) // preamble - float complex preamble_pn[1024]; // known 1024-symbol p/n sequence - float complex preamble_rx[1024]; // received p/n symbols + float complex preamble_pn[1024];// known 1024-symbol p/n sequence + float complex preamble_rx[1024];// received p/n symbols // payload decoder float complex payload_rx [630]; // received payload symbols with pilots float complex payload_sym[600]; // received payload symbols unsigned char payload_dec[ 72]; // decoded payload bytes - qdsync_cccf detector; // frame detector - msequence ms; // spreading sequence generator + qdsync_cccf detector; // frame detector + msequence ms; // spreading sequence generator float complex sym_despread; // despread symbol qpacketmodem dec; // packet demodulator/decoder qpilotsync pilotsync; // pilot extraction, carrier recovery // status variables - enum { - dsssframe64sync_STATE_DETECTFRAME=0, // detect frame (seek p/n sequence) - dsssframe64sync_STATE_RXPREAMBLE, // receive p/n sequence - dsssframe64sync_STATE_RXPAYLOAD, // receive payload data - } state; unsigned int preamble_counter; // counter: num of p/n syms received unsigned int chip_counter; // counter: num of payload chips received for a single symbol unsigned int payload_counter; // counter: num of payload syms received @@ -166,7 +162,7 @@ dsssframe64sync dsssframe64sync_copy(dsssframe64sync q_orig) int dsssframe64sync_destroy(dsssframe64sync _q) { // destroy synchronization objects - msequence_destroy (_q->ms); // + msequence_destroy (_q->ms); // pseudo-random sequence generator qdsync_cccf_destroy (_q->detector); // frame detector qpacketmodem_destroy(_q->dec); // payload demodulator qpilotsync_destroy (_q->pilotsync); // pilot synchronizer @@ -191,7 +187,6 @@ int dsssframe64sync_reset(dsssframe64sync _q) msequence_reset(_q->ms); // reset state - _q->state = dsssframe64sync_STATE_DETECTFRAME; _q->preamble_counter= 0; _q->chip_counter = 0; _q->payload_counter = 0; From 10bf218faf746c1b0403006cdb0f9fe6e4094c5a Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Wed, 19 Oct 2022 17:05:27 -0400 Subject: [PATCH 10/97] dsssframe64: adding performance example --- .../dsssframe64sync_performance_example.c | 93 +++++++++++++++++++ makefile.in | 1 + 2 files changed, 94 insertions(+) create mode 100644 examples/dsssframe64sync_performance_example.c diff --git a/examples/dsssframe64sync_performance_example.c b/examples/dsssframe64sync_performance_example.c new file mode 100644 index 000000000..38f394b27 --- /dev/null +++ b/examples/dsssframe64sync_performance_example.c @@ -0,0 +1,93 @@ +// This example tests the performance for detecting and decoding frames +// with the dsssframe64gen and dsssframe64sync objects. +// SEE ALSO: dsssframe64sync_example.c +#include +#include +#include +#include "liquid.h" +#define OUTPUT_FILENAME "dsssframe64sync_performance_example.m" + +// add noise to channel +void frame64_add_noise(float complex * _buf, + unsigned int _buf_len, float _SNRdB) +{ + float nstd = powf(10.0f, -_SNRdB/20.0f) * M_SQRT1_2; + unsigned int i; + for (i=0; i<_buf_len; i++) + _buf[i] += nstd*( randnf() + _Complex_I*randnf() ); +} + +int main(int argc, char*argv[]) +{ + // create frame generator, synchronizer objects + dsssframe64gen fg = dsssframe64gen_create(); + dsssframe64sync fs = dsssframe64sync_create(NULL,NULL); + unsigned int min_errors = 10; + unsigned int min_trials = 10; + unsigned int max_trials = 800; + + // create buffer for the frame samples + unsigned int frame_len = dsssframe64gen_get_frame_len(fg); + float complex frame[frame_len]; + float SNRdB = -25.0f; + FILE* fid = fopen(OUTPUT_FILENAME, "w"); + fprintf(fid,"%% %s: auto-generated file\n", OUTPUT_FILENAME); + fprintf(fid,"clear all; close all;\n"); + fprintf(fid,"SNR=[]; pdetect=[]; pvalid=[];\n"); + printf("# %8s %6s %6s %6s\n", "SNR", "detect", "valid", "trials"); + while (SNRdB < -13.0f) { + dsssframe64sync_reset_framedatastats(fs); + unsigned int num_trials = 0, num_errors = 0; + while (1) { + unsigned int i; + for (i=0; i= min_errors) + break; + if (num_trials >= max_trials) + break; + } + // print results + framedatastats_s stats = dsssframe64sync_get_framedatastats(fs); + printf(" %8.3f %6u %6u %6u\n", + SNRdB,stats.num_frames_detected,stats.num_payloads_valid,num_trials); + fprintf(fid,"SNR(end+1)=%g; pdetect(end+1)=%g; pvalid(end+1)=%g;\n", + SNRdB, + (float)stats.num_frames_detected / (float)num_trials, + (float)stats.num_payloads_valid / (float)num_trials); + if (num_errors < min_errors) + break; + SNRdB += 1.0f; + } + fprintf(fid,"figure;\n"); + fprintf(fid,"hold on;\n"); + fprintf(fid," semilogy(SNR, 1-pdetect+eps,'-o', 'LineWidth',2, 'MarkerSize',2);\n"); + fprintf(fid," semilogy(SNR, 1-pvalid +eps,'-o', 'LineWidth',2, 'MarkerSize',2);\n"); + fprintf(fid,"hold off;\n"); + fprintf(fid,"xlabel('SNR [dB]');\n"); + fprintf(fid,"ylabel('Prob. of Error');\n"); + fprintf(fid,"legend('detect','decoding','location','northeast');\n"); + fprintf(fid,"axis([-25 0 1e-3 1]);\n"); + fprintf(fid,"grid on;\n"); + fclose(fid); + printf("results written to %s\n", OUTPUT_FILENAME); + + // clean up allocated objects + dsssframe64gen_destroy(fg); + dsssframe64sync_destroy(fs); + return 0; +} diff --git a/makefile.in b/makefile.in index cf8e15823..749dac040 100644 --- a/makefile.in +++ b/makefile.in @@ -1518,6 +1518,7 @@ example_programs := \ examples/cvsd_example \ examples/detector_cccf_example \ examples/dds_cccf_example \ + examples/dsssframe64sync_performance_example \ examples/dsssframe64sync_example \ examples/dsssframesync_example \ examples/dotprod_rrrf_example \ From 06a1374e08c8b4c90b313e7c9174b39d39686a9f Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Wed, 19 Oct 2022 17:51:19 -0400 Subject: [PATCH 11/97] dsssframe64: increasing number of pilots from 30 to 50 * dramatically improves decoding performance for low SNRs * with 30 pilots: 1% PER at -12 dB SNR * with 50 pilots: 1% PER at -17 dB SNR * showing 5 dB improvement with only about 3% loss in spectral efficiency --- src/framing/src/dsssframe64gen.c | 10 +++++----- src/framing/src/dsssframe64sync.c | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index 4f1fec8bb..6732a1f0d 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -39,7 +39,7 @@ struct dsssframe64gen_s { float complex preamble_pn[1024]; // 1024-symbol p/n sequence unsigned char payload_dec[ 150]; // 600 = 150 bytes * 8 bits/bytes / 2 bits/symbol float complex payload_sym[ 600]; // modulated payload symbols - float complex payload_tx [ 630]; // modulated payload symbols with pilots + float complex payload_tx [ 650]; // modulated payload symbols with pilots unsigned int m; // filter delay (symbols) float beta; // filter excess bandwidth factor firinterp_crcf interp; // pulse-shaping filter/interpolator @@ -74,8 +74,8 @@ dsssframe64gen dsssframe64gen_create() assert( qpacketmodem_get_frame_len(q->enc)==600 ); // create pilot generator - q->pilotgen = qpilotgen_create(600, 21); - assert( qpilotgen_get_frame_len(q->pilotgen)==630 ); + q->pilotgen = qpilotgen_create(600, 13); + assert( qpilotgen_get_frame_len(q->pilotgen)==650 ); // create pulse-shaping filter (k=2) q->interp = firinterp_crcf_create_prototype(LIQUID_FIRFILT_ARKAISER,2,q->m,q->beta,0); @@ -164,7 +164,7 @@ int dsssframe64gen_write(dsssframe64gen _q, } // frame payload - for (i=0; i<630; i++) { + for (i=0; i<650; i++) { float complex sym = _q->payload_tx[i]; // strip out raw payload symbol for (j=0; j<256; j++) { // generate pseudo-random symbol @@ -194,6 +194,6 @@ int dsssframe64gen_complete(dsssframe64gen _q) // get full frame length [samples] unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q) { - return 2*(1024 + 630*256 + 2*_q->m); + return 2*(1024 + 650*256 + 2*_q->m); } diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 70a6dca63..fbd3a8201 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -62,7 +62,7 @@ struct dsssframe64sync_s { float complex preamble_rx[1024];// received p/n symbols // payload decoder - float complex payload_rx [630]; // received payload symbols with pilots + float complex payload_rx [650]; // received payload symbols with pilots float complex payload_sym[600]; // received payload symbols unsigned char payload_dec[ 72]; // decoded payload bytes @@ -118,8 +118,8 @@ dsssframe64sync dsssframe64sync_create(framesync_callback _callback, assert( qpacketmodem_get_frame_len(q->dec)==600 ); // create pilot synchronizer - q->pilotsync = qpilotsync_create(600, 21); - assert( qpilotsync_get_frame_len(q->pilotsync)==630); + q->pilotsync = qpilotsync_create(600, 13); + assert( qpilotsync_get_frame_len(q->pilotsync)==650); // reset global data counters dsssframe64sync_reset_framedatastats(q); @@ -288,7 +288,7 @@ int dsssframe64sync_step(dsssframe64sync _q, _q->payload_counter++; _q->chip_counter = 0; _q->sym_despread = 0; - if (_q->payload_counter == 630) { + if (_q->payload_counter == 650) { dsssframe64sync_decode(_q); return 1; // reset } @@ -310,8 +310,8 @@ int dsssframe64sync_decode(dsssframe64sync _q) // debug: export symbols to file unsigned int i; FILE * fid = fopen("dsssframe64sync_debug.m","w"); - fprintf(fid,"clear all; close all; r=zeros(1,630); s=zeros(1,600);\n"); - for (i=0; i<630; i++) + fprintf(fid,"clear all; close all; r=zeros(1,650); s=zeros(1,600);\n"); + for (i=0; i<650; i++) fprintf(fid,"r(%3u)=%12.4e + %12.4ej;\n", i+1, crealf(_q->payload_rx[i]), cimagf(_q->payload_rx[i])); for (i=0; i<600; i++) fprintf(fid,"s(%3u)=%12.4e + %12.4ej;\n", i+1, crealf(_q->payload_sym[i]), cimagf(_q->payload_sym[i])); From d57d6eca4fc5b68885d2d06e231c87e85d29f879 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 22 Oct 2022 07:54:05 -0400 Subject: [PATCH 12/97] dsssframe64sync: adding carrier offset estimate to callback * initial carrier offset based on preamble detection * refined carrier offset from qpilotsync object * combined estimate returned to callback --- src/framing/src/dsssframe64sync.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index fbd3a8201..b986a99f8 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -326,10 +326,14 @@ int dsssframe64sync_decode(dsssframe64sync _q) // invoke callback int rc = 0; if (_q->callback != NULL) { + // offset estimates + float dphi_hat = qdsync_cccf_get_dphi(_q->detector) + + qpilotsync_get_dphi(_q->pilotsync) / 256.0f; + // set framesyncstats internals _q->framesyncstats.evm = qpilotsync_get_evm(_q->pilotsync); _q->framesyncstats.rssi = 0; //20*log10f(qdsync_cccf_get_gamma(_q->detector)); - _q->framesyncstats.cfo = 0; //qdsync_cccf_get_frequency(_q->detector); + _q->framesyncstats.cfo = dphi_hat; _q->framesyncstats.framesyms = _q->payload_sym; _q->framesyncstats.num_framesyms = 600; _q->framesyncstats.mod_scheme = LIQUID_MODEM_QPSK; From 7361ee9c58418ec14d6d377370c342629e37127e Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 22 Oct 2022 08:45:48 -0400 Subject: [PATCH 13/97] dsssframe64sync: adding RSSI measurement to callback --- src/framing/src/dsssframe64sync.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index b986a99f8..a1c8a2855 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -332,7 +332,7 @@ int dsssframe64sync_decode(dsssframe64sync _q) // set framesyncstats internals _q->framesyncstats.evm = qpilotsync_get_evm(_q->pilotsync); - _q->framesyncstats.rssi = 0; //20*log10f(qdsync_cccf_get_gamma(_q->detector)); + _q->framesyncstats.rssi = 20*log10f(qdsync_cccf_get_gamma(_q->detector)); _q->framesyncstats.cfo = dphi_hat; _q->framesyncstats.framesyms = _q->payload_sym; _q->framesyncstats.num_framesyms = 600; From 4069c4daf715909c42690efeb4f6ba41ad04d402 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 23 Oct 2022 07:30:40 -0400 Subject: [PATCH 14/97] dsssframe64gen: replacing assemble() and write() with execute() * frame is fixed size * makes consistent with framegen64 methods * frame length should probably be defined statically somewhere --- examples/dsssframe64sync_example.c | 3 +- .../dsssframe64sync_performance_example.c | 3 +- include/liquid.h | 33 ++++--------- src/framing/src/dsssframe64gen.c | 46 ++++++++----------- src/framing/tests/dsssframe64sync_autotest.c | 3 +- 5 files changed, 32 insertions(+), 56 deletions(-) diff --git a/examples/dsssframe64sync_example.c b/examples/dsssframe64sync_example.c index c82c75adc..161403462 100644 --- a/examples/dsssframe64sync_example.c +++ b/examples/dsssframe64sync_example.c @@ -54,8 +54,7 @@ int main(int argc, char *argv[]) fprintf(fid,"s=[];\n"); // generate in one step (for now) - dsssframe64gen_assemble(fg, NULL, NULL); - dsssframe64gen_write(fg, buf_tx, buf_len); + dsssframe64gen_execute(fg, NULL, NULL, buf_tx); // apply channel (AWGN) float nstd = powf(10.0f,-SNRdB/20.0f); diff --git a/examples/dsssframe64sync_performance_example.c b/examples/dsssframe64sync_performance_example.c index 38f394b27..8e89e99d7 100644 --- a/examples/dsssframe64sync_performance_example.c +++ b/examples/dsssframe64sync_performance_example.c @@ -45,8 +45,7 @@ int main(int argc, char*argv[]) dsssframe64sync_reset(fs); // generate the frame with random header and payload - dsssframe64gen_assemble(fg, NULL, NULL); - dsssframe64gen_write (fg, frame, frame_len); + dsssframe64gen_execute(fg, NULL, NULL, frame); // add channel effects frame64_add_noise(frame, frame_len, SNRdB); diff --git a/include/liquid.h b/include/liquid.h index 3ceadac2c..821793932 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -5904,37 +5904,22 @@ int dsssframe64gen_destroy(dsssframe64gen _q); // print dsssframe64gen object internals int dsssframe64gen_print(dsssframe64gen _q); -int dsssframe64gen_print(dsssframe64gen _q); - -// reset dsssframe64gen object internals -//int dsssframe64gen_reset(dsssframe64gen _q); - -// is frame assembled? -//int dsssframe64gen_is_assembled(dsssframe64gen _q); - // get length of assembled frame (samples) unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q); -// assemble a frame from an array of data -// _q : frame generator object -// _props : frame properties -// _payload : payload data [size: _payload_len x 1] -// _payload_len : payload data length -int dsssframe64gen_assemble(dsssframe64gen _q, - const unsigned char * _header, - const unsigned char * _payload); - -int dsssframe64gen_write(dsssframe64gen _q, - liquid_float_complex * _buf, - unsigned int _buf_len); - -// is frame generation complete? -int dsssframe64gen_complete(dsssframe64gen _q); +// generate a frame +// _q : frame generator object +// _header : 8-byte header data, NULL for random +// _payload : 64-byte payload data, NULL for random +// _frame : output frame samples, [size: dsssframegen64gen_get_frame_len() x 1] +int dsssframe64gen_execute(dsssframe64gen _q, + const unsigned char * _header, + const unsigned char * _payload, + liquid_float_complex * _buf); // get full frame length [samples] unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q); - // frame synchronizer object type typedef struct dsssframe64sync_s * dsssframe64sync; diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index 6732a1f0d..afc42af58 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -32,6 +32,9 @@ #include "liquid.internal.h" +// write samples to buffer +int dsssframe64gen_write(dsssframe64gen _q, float complex * _buf); + struct dsssframe64gen_s { qpacketmodem enc; // packet encoder/modulator qpilotgen pilotgen; // pilot symbol generator @@ -43,8 +46,6 @@ struct dsssframe64gen_s { unsigned int m; // filter delay (symbols) float beta; // filter excess bandwidth factor firinterp_crcf interp; // pulse-shaping filter/interpolator - float complex buf_output[2]; // output sample buffer - // TODO: counters, etc. }; // create dsssframe64gen object @@ -116,14 +117,21 @@ int dsssframe64gen_print(dsssframe64gen _q) return LIQUID_OK; } -// assmeble frame +// get full frame length [samples] +unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q) +{ + return 2*(1024 + 650*256 + 2*_q->m); +} + +// generate a frame // _q : frame generator object // _header : 8-byte header data, NULL for random // _payload : 64-byte payload data, NULL for random -// _frame : output frame samples [size: LIQUID_FRAME64_LEN x 1] -int dsssframe64gen_assemble(dsssframe64gen _q, - const unsigned char * _header, - const unsigned char * _payload) +// _frame : output frame samples, [size: dsssframegen64gen_get_frame_len() x 1] +int dsssframe64gen_execute(dsssframe64gen _q, + const unsigned char * _header, + const unsigned char * _payload, + float complex * _buf) { unsigned int i; @@ -143,17 +151,15 @@ int dsssframe64gen_assemble(dsssframe64gen _q, firinterp_crcf_reset(_q->interp); msequence_reset(_q->ms); - // frame_assembled = 1 - return LIQUID_OK; + // write frame to buffer + return dsssframe64gen_write(_q, _buf); } // write samples to buffer -// _q : frame generator object -// _buf : output frame samples, shape: (_buf_len,) -// _buf_len : output frame buffer size +// _q : frame generator object +// _buf : output frame samples (full frame) int dsssframe64gen_write(dsssframe64gen _q, - float complex * _buf, - unsigned int _buf_len) + float complex * _buf) { unsigned int i, j, n=0; @@ -185,15 +191,3 @@ int dsssframe64gen_write(dsssframe64gen _q, return LIQUID_OK; } -// is frame generation complete? -int dsssframe64gen_complete(dsssframe64gen _q) -{ - return 1; -} - -// get full frame length [samples] -unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q) -{ - return 2*(1024 + 650*256 + 2*_q->m); -} - diff --git a/src/framing/tests/dsssframe64sync_autotest.c b/src/framing/tests/dsssframe64sync_autotest.c index 8e4a10fe4..b4b010700 100644 --- a/src/framing/tests/dsssframe64sync_autotest.c +++ b/src/framing/tests/dsssframe64sync_autotest.c @@ -58,8 +58,7 @@ void autotest_dsssframe64sync() // generate the frame unsigned int frame_len = dsssframe64gen_get_frame_len(fg); float complex frame[frame_len]; - dsssframe64gen_assemble(fg, NULL, NULL); - dsssframe64gen_write (fg, frame, frame_len); + dsssframe64gen_execute(fg, NULL, NULL, frame); // add some noise for (i=0; i Date: Sun, 21 May 2023 16:38:05 -0400 Subject: [PATCH 15/97] dsssframe64/example: fixing SNR calculation, adjusting trials --- .../dsssframe64sync_performance_example.c | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/examples/dsssframe64sync_performance_example.c b/examples/dsssframe64sync_performance_example.c index 8e89e99d7..3d73139d4 100644 --- a/examples/dsssframe64sync_performance_example.c +++ b/examples/dsssframe64sync_performance_example.c @@ -11,10 +11,11 @@ void frame64_add_noise(float complex * _buf, unsigned int _buf_len, float _SNRdB) { - float nstd = powf(10.0f, -_SNRdB/20.0f) * M_SQRT1_2; + float nstd = powf(10.0f, -_SNRdB/20.0f); + nstd *= M_SQRT2; // scale noise to account for signal being over-sampled by 2 unsigned int i; for (i=0; i<_buf_len; i++) - _buf[i] += nstd*( randnf() + _Complex_I*randnf() ); + _buf[i] += nstd*( randnf() + _Complex_I*randnf() ) * M_SQRT1_2; } int main(int argc, char*argv[]) @@ -22,9 +23,9 @@ int main(int argc, char*argv[]) // create frame generator, synchronizer objects dsssframe64gen fg = dsssframe64gen_create(); dsssframe64sync fs = dsssframe64sync_create(NULL,NULL); - unsigned int min_errors = 10; - unsigned int min_trials = 10; - unsigned int max_trials = 800; + unsigned int min_errors = 5; + unsigned int min_trials = 80; + unsigned int max_trials = 1000; // create buffer for the frame samples unsigned int frame_len = dsssframe64gen_get_frame_len(fg); @@ -35,7 +36,8 @@ int main(int argc, char*argv[]) fprintf(fid,"clear all; close all;\n"); fprintf(fid,"SNR=[]; pdetect=[]; pvalid=[];\n"); printf("# %8s %6s %6s %6s\n", "SNR", "detect", "valid", "trials"); - while (SNRdB < -13.0f) { + fclose(fid); + while (SNRdB < -5.0f) { dsssframe64sync_reset_framedatastats(fs); unsigned int num_trials = 0, num_errors = 0; while (1) { @@ -64,14 +66,17 @@ int main(int argc, char*argv[]) framedatastats_s stats = dsssframe64sync_get_framedatastats(fs); printf(" %8.3f %6u %6u %6u\n", SNRdB,stats.num_frames_detected,stats.num_payloads_valid,num_trials); - fprintf(fid,"SNR(end+1)=%g; pdetect(end+1)=%g; pvalid(end+1)=%g;\n", + fid = fopen(OUTPUT_FILENAME,"a"); + fprintf(fid,"SNR(end+1)=%g; pdetect(end+1)=%12g; pvalid(end+1)=%12g;\n", SNRdB, (float)stats.num_frames_detected / (float)num_trials, (float)stats.num_payloads_valid / (float)num_trials); + fclose(fid); if (num_errors < min_errors) break; SNRdB += 1.0f; } + fid = fopen(OUTPUT_FILENAME,"a"); fprintf(fid,"figure;\n"); fprintf(fid,"hold on;\n"); fprintf(fid," semilogy(SNR, 1-pdetect+eps,'-o', 'LineWidth',2, 'MarkerSize',2);\n"); @@ -80,7 +85,7 @@ int main(int argc, char*argv[]) fprintf(fid,"xlabel('SNR [dB]');\n"); fprintf(fid,"ylabel('Prob. of Error');\n"); fprintf(fid,"legend('detect','decoding','location','northeast');\n"); - fprintf(fid,"axis([-25 0 1e-3 1]);\n"); + fprintf(fid,"axis([-30 10 1e-3 1]);\n"); fprintf(fid,"grid on;\n"); fclose(fid); printf("results written to %s\n", OUTPUT_FILENAME); From f50e166890fd0e3f914536906350b489edabd1fe Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 May 2023 16:44:38 -0400 Subject: [PATCH 16/97] dsssframe64: reducing spreading gain from 256 to 128 * the preamble detection (1024 chips) was the limiting factor * spreading to 256 provided no gain over 128 in this case * would need to increase the preamble to be on the order of 2048 * this would have increased the computational complexity for the qdetector beyond what makes sense * the partitioned detector could solve this, but it's not yet complete --- src/framing/src/dsssframe64gen.c | 8 ++++---- src/framing/src/dsssframe64sync.c | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index afc42af58..f3ac1bbf8 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2023 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -21,7 +21,7 @@ */ // DS/SS frame generator with fixed fields: 8-byte header, 64-byte payload, -// 256-symbol spreading factor +// 128-symbol spreading factor #include #include @@ -120,7 +120,7 @@ int dsssframe64gen_print(dsssframe64gen _q) // get full frame length [samples] unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q) { - return 2*(1024 + 650*256 + 2*_q->m); + return 2*(1024 + 650*128 + 2*_q->m); } // generate a frame @@ -172,7 +172,7 @@ int dsssframe64gen_write(dsssframe64gen _q, // frame payload for (i=0; i<650; i++) { float complex sym = _q->payload_tx[i]; // strip out raw payload symbol - for (j=0; j<256; j++) { + for (j=0; j<128; j++) { // generate pseudo-random symbol unsigned int p = msequence_generate_symbol(_q->ms, 2); float complex s = cexpf(_Complex_I*2*M_PI*(float)p/(float)4); diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index a1c8a2855..e5091a970 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2023 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -283,8 +283,8 @@ int dsssframe64sync_step(dsssframe64sync _q, _q->sym_despread += _buf[i] * conjf(s); _q->chip_counter++; - if (_q->chip_counter == 256) { - _q->payload_rx[_q->payload_counter] = _q->sym_despread / 256.0f; + if (_q->chip_counter == 128) { + _q->payload_rx[_q->payload_counter] = _q->sym_despread / 128.0f; _q->payload_counter++; _q->chip_counter = 0; _q->sym_despread = 0; @@ -303,7 +303,7 @@ int dsssframe64sync_decode(dsssframe64sync _q) { // recover data symbols from pilots qpilotsync_execute(_q->pilotsync, _q->payload_rx, _q->payload_sym); - + // decode payload int crc_pass = qpacketmodem_decode(_q->dec, _q->payload_sym, _q->payload_dec); #if 0 @@ -322,13 +322,13 @@ int dsssframe64sync_decode(dsssframe64sync _q) _q->framedatastats.num_headers_valid += crc_pass; _q->framedatastats.num_payloads_valid += crc_pass; _q->framedatastats.num_bytes_received += crc_pass ? 64 : 0; - + // invoke callback int rc = 0; if (_q->callback != NULL) { // offset estimates float dphi_hat = qdsync_cccf_get_dphi(_q->detector) + - qpilotsync_get_dphi(_q->pilotsync) / 256.0f; + qpilotsync_get_dphi(_q->pilotsync) / 128.0f; // set framesyncstats internals _q->framesyncstats.evm = qpilotsync_get_evm(_q->pilotsync); @@ -341,7 +341,7 @@ int dsssframe64sync_decode(dsssframe64sync _q) _q->framesyncstats.check = LIQUID_CRC_24; _q->framesyncstats.fec0 = LIQUID_FEC_NONE; _q->framesyncstats.fec1 = LIQUID_FEC_GOLAY2412; - + // invoke callback method rc = _q->callback(&_q->payload_dec[0], // header is first 8 bytes crc_pass, @@ -351,7 +351,7 @@ int dsssframe64sync_decode(dsssframe64sync _q) _q->framesyncstats, _q->context); } - + // reset frame synchronizer and return dsssframe64sync_reset(_q); return rc; From 3496f59b0c7034264ae524d0bddc9dea0b828fa1 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Fri, 8 Mar 2024 18:57:30 -0500 Subject: [PATCH 17/97] symsync: cleaning object of old debugging macros --- src/filter/src/symsync.proto.c | 213 --------------------------------- 1 file changed, 213 deletions(-) diff --git a/src/filter/src/symsync.proto.c b/src/filter/src/symsync.proto.c index 4a7a43bb6..7a825ed9c 100644 --- a/src/filter/src/symsync.proto.c +++ b/src/filter/src/symsync.proto.c @@ -39,11 +39,6 @@ #include #include -#define DEBUG_SYMSYNC 0 -#define DEBUG_SYMSYNC_PRINT 0 -#define DEBUG_SYMSYNC_FILENAME "symsync_internal_debug.m" -#define DEBUG_BUFFER_LEN (1024) - // // forward declaration of internal methods // @@ -66,12 +61,6 @@ int SYMSYNC(_advance_internal_loop)(SYMSYNC() _q, TO _mf, TO _dmf); -// print results to output debugging file -// _q : synchronizer object -// _filename : output filename -int SYMSYNC(_output_debug_file)(SYMSYNC() _q, - const char * _filename); - // internal structure struct SYMSYNC(_s) { unsigned int h_len; // matched filter length @@ -101,15 +90,6 @@ struct SYMSYNC(_s) { unsigned int npfb; // number of filters in the bank FIRPFB() mf; // matched filter FIRPFB() dmf; // derivative matched filter - -#if DEBUG_SYMSYNC - windowf debug_rate; - windowf debug_del; - windowf debug_tau; - windowf debug_bsoft; - windowf debug_b; - windowf debug_q_hat; -#endif }; // create synchronizer object from external coefficients @@ -181,15 +161,6 @@ SYMSYNC() SYMSYNC(_create)(unsigned int _k, // unlock loop control SYMSYNC(_unlock)(q); -#if DEBUG_SYMSYNC - q->debug_rate = windowf_create(DEBUG_BUFFER_LEN); - q->debug_del = windowf_create(DEBUG_BUFFER_LEN); - q->debug_tau = windowf_create(DEBUG_BUFFER_LEN); - q->debug_bsoft = windowf_create(DEBUG_BUFFER_LEN); - q->debug_b = windowf_create(DEBUG_BUFFER_LEN); - q->debug_q_hat = windowf_create(DEBUG_BUFFER_LEN); -#endif - // return main object return q; } @@ -294,15 +265,6 @@ SYMSYNC() SYMSYNC(_copy)(SYMSYNC() q_orig) q_copy->mf = FIRPFB(_copy)(q_orig->mf); q_copy->dmf = FIRPFB(_copy)(q_orig->dmf); -#if DEBUG_SYMSYNC - // copy debugging windows - q_copy->debug_rate = windowf_copy(q_orig->debug_rate); - q_copy->debug_del = windowf_copy(q_orig->debug_del); - q_copy->debug_tau = windowf_copy(q_orig->debug_tau); - q_copy->debug_bsoft = windowf_copy(q_orig->debug_bsoft); - q_copy->debug_b = windowf_copy(q_orig->debug_b); - q_copy->debug_q_hat = windowf_copy(q_orig->debug_q_hat); -#endif // return object return q_copy; } @@ -310,19 +272,6 @@ SYMSYNC() SYMSYNC(_copy)(SYMSYNC() q_orig) // destroy symsync object, freeing all internal memory int SYMSYNC(_destroy)(SYMSYNC() _q) { -#if DEBUG_SYMSYNC - // output debugging file - SYMSYNC(_output_debug_file)(_q, DEBUG_SYMSYNC_FILENAME); - - // destroy internal window objects - windowf_destroy(_q->debug_rate); - windowf_destroy(_q->debug_del); - windowf_destroy(_q->debug_tau); - windowf_destroy(_q->debug_bsoft); - windowf_destroy(_q->debug_b); - windowf_destroy(_q->debug_q_hat); -#endif - // destroy filterbank objects FIRPFB(_destroy)(_q->mf); FIRPFB(_destroy)(_q->dmf); @@ -488,10 +437,6 @@ int SYMSYNC(_step)(SYMSYNC() _q, // continue loop until filterbank index rolls over while (_q->b < _q->npfb) { -#if DEBUG_SYMSYNC_PRINT - printf(" [%2u] : tau : %12.8f, b : %4u (%12.8f)\n", n, _q->tau, _q->b, _q->bf); -#endif - // compute filterbank output FIRPFB(_execute)(_q->mf, _q->b, &mf); @@ -503,16 +448,6 @@ int SYMSYNC(_step)(SYMSYNC() _q, // reset counter _q->decim_counter = 0; -#if DEBUG_SYMSYNC - // save debugging variables - windowf_push(_q->debug_rate, _q->rate); - windowf_push(_q->debug_del, _q->del); - windowf_push(_q->debug_tau, _q->tau); - windowf_push(_q->debug_bsoft, _q->bf); - windowf_push(_q->debug_b, _q->b); - windowf_push(_q->debug_q_hat, _q->q_hat); -#endif - // if synchronizer is locked, don't update internal timing offset if (_q->is_locked) continue; @@ -572,154 +507,6 @@ int SYMSYNC(_advance_internal_loop)(SYMSYNC() _q, _q->rate += _q->rate_adjustment * _q->q_hat; _q->del = _q->rate + _q->q_hat; -#if DEBUG_SYMSYNC_PRINT - printf("q : %12.8f, rate : %12.8f, del : %12.8f, q_hat : %12.8f\n", _q->q, _q->rate, _q->del, _q->q_hat); -#endif - return LIQUID_OK; -} - -// print results to output debugging file -// _q : synchronizer object -// _filename : output filename -int SYMSYNC(_output_debug_file)(SYMSYNC() _q, - const char * _filename) -{ - FILE * fid = fopen(_filename, "w"); - if (!fid) - return liquid_error(LIQUID_EICONFIG,"symsync_%s_output_debug_file(), could not open '%s' for writing", EXTENSION_FULL, _filename); - fprintf(fid,"%% %s, auto-generated file\n\n", DEBUG_SYMSYNC_FILENAME); - fprintf(fid,"\n"); - fprintf(fid,"clear all;\n"); - fprintf(fid,"close all;\n"); - - fprintf(fid,"npfb = %u;\n",_q->npfb); - fprintf(fid,"k = %u;\n",_q->k); - fprintf(fid,"\n\n"); - -#if DEBUG_SYMSYNC - fprintf(fid,"n = %u;\n", DEBUG_BUFFER_LEN); - float * r; - unsigned int i; - - // save filter responses - FIRPFB(_reset)(_q->mf); - FIRPFB(_reset)(_q->dmf); - fprintf(fid,"h = [];\n"); - fprintf(fid,"dh = [];\n"); - fprintf(fid,"h_len = %u;\n", _q->h_len); - for (i=0; i<_q->h_len; i++) { - // push impulse - if (i==0) { - FIRPFB(_push)(_q->mf, 1.0f); - FIRPFB(_push)(_q->dmf, 1.0f); - } else { - FIRPFB(_push)(_q->mf, 0.0f); - FIRPFB(_push)(_q->dmf, 0.0f); - } - - // compute output for all filters - TO mf; // matched filter output - TO dmf; // derivative matched filter output - - unsigned int n; - for (n=0; n<_q->npfb; n++) { - FIRPFB(_execute)(_q->mf, n, &mf); - FIRPFB(_execute)(_q->dmf, n, &dmf); - - fprintf(fid,"h(%4u) = %12.8f; dh(%4u) = %12.8f;\n", i*_q->npfb+n+1, crealf(mf), i*_q->npfb+n+1, crealf(dmf)); - } - } - // plot response - fprintf(fid,"\n"); - fprintf(fid,"figure;\n"); - fprintf(fid,"th = [0:(h_len*npfb-1)]/(k*npfb) - h_len/(2*k);\n"); - fprintf(fid,"m = abs(round(th(1)));\n"); - //fprintf(fid,"plot(t,h,t,dh);\n"); - fprintf(fid,"subplot(3,1,1),\n"); - fprintf(fid," plot(th, h, 'LineWidth', 2, 'Color', [0 0.5 0.2]);\n"); - fprintf(fid," ylabel('MF');\n"); - fprintf(fid," axis([-m m -0.25 1.25]);\n"); - fprintf(fid," grid on;\n"); - fprintf(fid,"subplot(3,1,2),\n"); - fprintf(fid," plot(th, dh, 'LineWidth', 2, 'Color', [0 0.2 0.5]);\n"); - fprintf(fid," ylabel('dMF');\n"); - fprintf(fid," axis([-m m -0.10 0.10]);\n"); - fprintf(fid," grid on;\n"); - fprintf(fid,"subplot(3,1,3),\n"); - fprintf(fid," plot(th,-h.*dh, 'LineWidth', 2, 'Color', [0.5 0 0]);\n"); - fprintf(fid," xlabel('Symbol Index');\n"); - fprintf(fid," ylabel('-MF*dMF');\n"); - fprintf(fid," axis([-m m -0.08 0.08]);\n"); - fprintf(fid," grid on;\n"); - - // print rate buffer - fprintf(fid,"rate = zeros(1,n);\n"); - windowf_read(_q->debug_rate, &r); - for (i=0; idebug_del, &r); - for (i=0; idebug_tau, &r); - for (i=0; idebug_bsoft, &r); - for (i=0; idebug_b, &r); - for (i=0; idebug_q_hat, &r); - for (i=0; i Date: Fri, 8 Mar 2024 19:02:47 -0500 Subject: [PATCH 18/97] symsync/autotest: testing configuration for create_rnyquist() --- src/filter/tests/symsync_copy_autotest.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/filter/tests/symsync_copy_autotest.c b/src/filter/tests/symsync_copy_autotest.c index 4c304b733..2514fccf2 100644 --- a/src/filter/tests/symsync_copy_autotest.c +++ b/src/filter/tests/symsync_copy_autotest.c @@ -85,13 +85,16 @@ void autotest_symsync_config() CONTEND_ISNULL( symsync_crcf_create(2, 12, NULL, 0) ); // h_len is too small CONTEND_ISNULL( symsync_crcf_create(2, 12, NULL, 47) ); // h_len is not divisible by M + CONTEND_ISNULL( symsync_crcf_create_rnyquist(LIQUID_FIRFILT_RRC, 0, 12, 0.2, 48) ); // k is too small + CONTEND_ISNULL( symsync_crcf_create_rnyquist(LIQUID_FIRFILT_RRC, 2, 0, 0.2, 48) ); // m is too small + CONTEND_ISNULL( symsync_crcf_create_rnyquist(LIQUID_FIRFILT_RRC, 2, 12, 7.2, 48) ); // beta is too large + CONTEND_ISNULL( symsync_crcf_create_rnyquist(LIQUID_FIRFILT_RRC, 2, 12, 0.2, 0) ); // M is too small + CONTEND_ISNULL( symsync_crcf_create_kaiser(0, 12, 0.2, 48) ); // k is too small CONTEND_ISNULL( symsync_crcf_create_kaiser(2, 0, 0.2, 48) ); // m is too small CONTEND_ISNULL( symsync_crcf_create_kaiser(2, 12, 7.2, 48) ); // beta is too large CONTEND_ISNULL( symsync_crcf_create_kaiser(2, 12, 0.2, 0) ); // M is too small - //CONTEND_ISNULL( symsync_crcf_create_nyquist(2, 12, NULL, 47) ); // h_len is not divisible by M - // create valid object symsync_crcf q = symsync_crcf_create_kaiser(2, 12, 0.2, 48); CONTEND_EQUALITY( LIQUID_OK, symsync_crcf_print(q) ); From 4e84cb04350853a6cc83e353fa3f3cd48d62d313 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 10 Mar 2024 11:18:25 -0400 Subject: [PATCH 19/97] build: removing unnecessary explicit framing targets --- makefile.in | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/makefile.in b/makefile.in index f5526b8e4..3fc8e9091 100644 --- a/makefile.in +++ b/makefile.in @@ -676,20 +676,6 @@ src/framing/src/framing_rrrf.o : %.o : %.c $(include_headers) ${framing_pro src/framing/src/framing_crcf.o : %.o : %.c $(include_headers) ${framing_prototypes_sync} src/framing/src/framing_cccf.o : %.o : %.c $(include_headers) ${framing_prototypes_sync} -src/framing/src/bpacketgen.o : %.o : %.c $(include_headers) -src/framing/src/bpacketsync.o : %.o : %.c $(include_headers) -src/framing/src/detector_cccf.o : %.o : %.c $(include_headers) -src/framing/src/dsssframegen.o : %.o : %.c $(include_headers) -src/framing/src/dsssframesync.o : %.o : %.c $(include_headers) -src/framing/src/framedatastats.o : %.o : %.c $(include_headers) -src/framing/src/framesyncstats.o : %.o : %.c $(include_headers) -src/framing/src/framegen64.o : %.o : %.c $(include_headers) -src/framing/src/framesync64.o : %.o : %.c $(include_headers) -src/framing/src/flexframegen.o : %.o : %.c $(include_headers) -src/framing/src/flexframesync.o : %.o : %.c $(include_headers) -src/framing/src/ofdmflexframegen.o : %.o : %.c $(include_headers) -src/framing/src/ofdmflexframesync.o : %.o : %.c $(include_headers) - framing_autotests := \ src/framing/tests/bpacketsync_autotest.c \ src/framing/tests/bsync_autotest.c \ @@ -1194,7 +1180,8 @@ objects := \ $(sequence_objects) \ $(utility_objects) \ $(vector_objects) \ - + +$(objects) : %.o : %.c $(include_headers) autotest_sources := \ autotest/null_autotest.c \ From 5001de3c7c549cc4efe90216d52df57d99dddfe9 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 10 Mar 2024 16:54:45 -0400 Subject: [PATCH 20/97] modem/autotest: moving configuration test filename --- makefile.in | 2 +- .../tests/{modem_copy_autotest.c => modem_config_autotest.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/modem/tests/{modem_copy_autotest.c => modem_config_autotest.c} (100%) diff --git a/makefile.in b/makefile.in index 3fc8e9091..c2dd443e3 100644 --- a/makefile.in +++ b/makefile.in @@ -895,7 +895,7 @@ modem_autotests := \ src/modem/tests/fskmodem_autotest.c \ src/modem/tests/gmskmodem_autotest.c \ src/modem/tests/modem_autotest.c \ - src/modem/tests/modem_copy_autotest.c \ + src/modem/tests/modem_config_autotest.c \ src/modem/tests/modem_demodsoft_autotest.c \ src/modem/tests/modem_demodstats_autotest.c \ src/modem/tests/modem_utilities_autotest.c \ diff --git a/src/modem/tests/modem_copy_autotest.c b/src/modem/tests/modem_config_autotest.c similarity index 100% rename from src/modem/tests/modem_copy_autotest.c rename to src/modem/tests/modem_config_autotest.c From 2f94f8233a0d5f06390254b4e9b978a979f029a6 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 10 Mar 2024 18:43:02 -0400 Subject: [PATCH 21/97] modem/autotest: adding configuration tests --- src/modem/tests/modem_config_autotest.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/modem/tests/modem_config_autotest.c b/src/modem/tests/modem_config_autotest.c index 619e8e330..ebc8f03fa 100644 --- a/src/modem/tests/modem_config_autotest.c +++ b/src/modem/tests/modem_config_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -132,3 +132,23 @@ void autotest_modem_copy_arb256opt() { modemcf_test_copy(LIQUID_MODEM_ARB256OPT) void autotest_modem_copy_arb64vt() { modemcf_test_copy(LIQUID_MODEM_ARB64VT); } void autotest_modem_copy_pi4dqpsk() { modemcf_test_copy(LIQUID_MODEM_PI4DQPSK); } +// test errors and invalid configuration +void autotest_modem_config() +{ +#if LIQUID_STRICT_EXIT + AUTOTEST_WARN("skipping modem config test with strict exit enabled\n"); + return; +#endif +#if !LIQUID_SUPPRESS_ERROR_OUTPUT + fprintf(stderr,"warning: ignore potential errors here; checking for invalid configurations\n"); +#endif + // test copying/creating invalid objects + CONTEND_ISNULL( modemcf_copy(NULL) ); + CONTEND_ISNULL( modemcf_create(LIQUID_MODEM_ARB) ); + + // create object and check configuration + modemcf q = modemcf_create(LIQUID_MODEM_QAM64); + CONTEND_EQUALITY( LIQUID_OK, modemcf_print(q) ); + modemcf_destroy(q); +} + From 22fa2accb572a58a9ab0568132dec25dc7174093 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 10 Mar 2024 18:53:28 -0400 Subject: [PATCH 22/97] cpfskmodem: adding configuration tests --- include/liquid.h | 1 + src/modem/src/cpfskdem.c | 6 +++--- src/modem/src/cpfskmod.c | 6 +++--- src/modem/tests/cpfskmodem_autotest.c | 28 +++++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/include/liquid.h b/include/liquid.h index bbb18914f..1a3ea760b 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -8222,6 +8222,7 @@ int gmskdem_demodulate(gmskdem _q, // CP-FSK filter prototypes typedef enum { + //LIQUID_CPFSK_UNKNOWN=0 LIQUID_CPFSK_SQUARE=0, // square pulse LIQUID_CPFSK_RCOS_FULL, // raised-cosine (full response) LIQUID_CPFSK_RCOS_PARTIAL, // raised-cosine (partial response) diff --git a/src/modem/src/cpfskdem.c b/src/modem/src/cpfskdem.c index 425400620..7b04ab130 100644 --- a/src/modem/src/cpfskdem.c +++ b/src/modem/src/cpfskdem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2020 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -138,14 +138,14 @@ cpfskdem cpfskdem_create(unsigned int _bps, // validate input if (_bps == 0) return liquid_error_config("cpfskdem_create(), bits/symbol must be greater than 0"); + if (_h <= 0.0f) + return liquid_error_config("cpfskdem_create(), modulation index must be greater than 0"); if (_k < 2 || (_k%2)) return liquid_error_config("cpfskmod_create(), samples/symbol must be greater than 2 and even"); if (_m == 0) return liquid_error_config("cpfskdem_create(), filter delay must be greater than 0"); if (_beta <= 0.0f || _beta > 1.0f) return liquid_error_config("cpfskdem_create(), filter roll-off must be in (0,1]"); - if (_h <= 0.0f) - return liquid_error_config("cpfskdem_create(), modulation index must be greater than 0"); // create main object memory cpfskdem q = (cpfskdem) malloc(sizeof(struct cpfskdem_s)); diff --git a/src/modem/src/cpfskmod.c b/src/modem/src/cpfskmod.c index 843022c75..c8c5b415b 100644 --- a/src/modem/src/cpfskmod.c +++ b/src/modem/src/cpfskmod.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -79,14 +79,14 @@ cpfskmod cpfskmod_create(unsigned int _bps, // validate input if (_bps == 0) return liquid_error_config("cpfskmod_create(), bits/symbol must be greater than 0"); + if (_h <= 0.0f) + return liquid_error_config("cpfskmod_create(), modulation index must be greater than 0"); if (_k < 2 || (_k%2)) return liquid_error_config("cpfskmod_create(), samples/symbol must be greater than 2 and even"); if (_m == 0) return liquid_error_config("cpfskmod_create(), filter delay must be greater than 0"); if (_beta <= 0.0f || _beta > 1.0f) return liquid_error_config("cpfskmod_create(), filter roll-off must be in (0,1]"); - if (_h <= 0.0f) - return liquid_error_config("cpfskmod_create(), modulation index must be greater than 0"); // create main object memory cpfskmod q = (cpfskmod) malloc(sizeof(struct cpfskmod_s)); diff --git a/src/modem/tests/cpfskmodem_autotest.c b/src/modem/tests/cpfskmodem_autotest.c index 27f57c073..e4d3932ed 100644 --- a/src/modem/tests/cpfskmodem_autotest.c +++ b/src/modem/tests/cpfskmodem_autotest.c @@ -171,3 +171,31 @@ void autotest_cpfskmodem_spectrum() liquid_autotest_verbose ? filename : NULL); } + +// test errors and invalid configuration +void autotest_cpfskmodem_config() +{ +#if LIQUID_STRICT_EXIT + AUTOTEST_WARN("skipping modem config test with strict exit enabled\n"); + return; +#endif +#if !LIQUID_SUPPRESS_ERROR_OUTPUT + fprintf(stderr,"warning: ignore potential errors here; checking for invalid configurations\n"); +#endif + // test copying/creating invalid objects + //CONTEND_ISNULL( modemcf_copy(NULL) ); + CONTEND_ISNULL( cpfskmod_create(0, 0.5f, 4, 12, 0.25f, LIQUID_CPFSK_SQUARE) ); // _bps is less than 1 + CONTEND_ISNULL( cpfskmod_create(1, 0.0f, 4, 12, 0.25f, LIQUID_CPFSK_SQUARE) ); // _h (mod index) is out of range + CONTEND_ISNULL( cpfskmod_create(1, 0.5f, 5, 12, 0.25f, LIQUID_CPFSK_SQUARE) ); // _k is not even + CONTEND_ISNULL( cpfskmod_create(1, 0.5f, 4, 0, 0.25f, LIQUID_CPFSK_SQUARE) ); // _m is too small + CONTEND_ISNULL( cpfskmod_create(1, 0.5f, 4, 12, 0.00f, LIQUID_CPFSK_SQUARE) ); // _beta is too small + + CONTEND_ISNULL( cpfskdem_create(0, 0.5f, 4, 12, 0.25f, LIQUID_CPFSK_SQUARE) ); // _bps is less than 1 + CONTEND_ISNULL( cpfskdem_create(1, 0.0f, 4, 12, 0.25f, LIQUID_CPFSK_SQUARE) ); // _h (mod index) is out of range + CONTEND_ISNULL( cpfskdem_create(1, 0.5f, 5, 12, 0.25f, LIQUID_CPFSK_SQUARE) ); // _k is not even + CONTEND_ISNULL( cpfskdem_create(1, 0.5f, 4, 0, 0.25f, LIQUID_CPFSK_SQUARE) ); // _m is too small + CONTEND_ISNULL( cpfskdem_create(1, 0.5f, 4, 12, 0.00f, LIQUID_CPFSK_SQUARE) ); // _beta is too small + + // TODO: create object and check configuration +} + From 8c0ea76eaab215b09790b01622e7c487aaf5d9cf Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Mon, 11 Mar 2024 17:36:51 -0400 Subject: [PATCH 23/97] cpfskmodem/autotest: adding more configuration tests --- src/modem/tests/cpfskmodem_autotest.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/modem/tests/cpfskmodem_autotest.c b/src/modem/tests/cpfskmodem_autotest.c index e4d3932ed..68f15f999 100644 --- a/src/modem/tests/cpfskmodem_autotest.c +++ b/src/modem/tests/cpfskmodem_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2018 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -171,7 +171,6 @@ void autotest_cpfskmodem_spectrum() liquid_autotest_verbose ? filename : NULL); } - // test errors and invalid configuration void autotest_cpfskmodem_config() { @@ -189,13 +188,23 @@ void autotest_cpfskmodem_config() CONTEND_ISNULL( cpfskmod_create(1, 0.5f, 5, 12, 0.25f, LIQUID_CPFSK_SQUARE) ); // _k is not even CONTEND_ISNULL( cpfskmod_create(1, 0.5f, 4, 0, 0.25f, LIQUID_CPFSK_SQUARE) ); // _m is too small CONTEND_ISNULL( cpfskmod_create(1, 0.5f, 4, 12, 0.00f, LIQUID_CPFSK_SQUARE) ); // _beta is too small + CONTEND_ISNULL( cpfskmod_create(1, 0.5f, 4, 12, 0.00f, -1) ); // invalid filter type CONTEND_ISNULL( cpfskdem_create(0, 0.5f, 4, 12, 0.25f, LIQUID_CPFSK_SQUARE) ); // _bps is less than 1 CONTEND_ISNULL( cpfskdem_create(1, 0.0f, 4, 12, 0.25f, LIQUID_CPFSK_SQUARE) ); // _h (mod index) is out of range CONTEND_ISNULL( cpfskdem_create(1, 0.5f, 5, 12, 0.25f, LIQUID_CPFSK_SQUARE) ); // _k is not even CONTEND_ISNULL( cpfskdem_create(1, 0.5f, 4, 0, 0.25f, LIQUID_CPFSK_SQUARE) ); // _m is too small CONTEND_ISNULL( cpfskdem_create(1, 0.5f, 4, 12, 0.00f, LIQUID_CPFSK_SQUARE) ); // _beta is too small + CONTEND_ISNULL( cpfskdem_create(1, 0.5f, 4, 12, 0.00f, -1) ); // invalid filter type + + // create modulator object and check configuration + cpfskmod mod = cpfskmod_create(1, 0.5f, 4, 12, 0.5f, LIQUID_CPFSK_SQUARE); + CONTEND_EQUALITY( LIQUID_OK, cpfskmod_print(mod) ); + cpfskmod_destroy(mod); - // TODO: create object and check configuration + // create demodulator object and check configuration + cpfskdem dem = cpfskdem_create(1, 0.5f, 4, 12, 0.5f, LIQUID_CPFSK_SQUARE); + CONTEND_EQUALITY( LIQUID_OK, cpfskdem_print(dem) ); + cpfskdem_destroy(dem); } From 9e1c40d8cf1a8a23069c9e6c1da4b70575b1683b Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 11:20:50 -0400 Subject: [PATCH 24/97] qdsync: adding method to get state, performance example --- examples/qdsync_cccf_performance_example.c | 99 ++++++++++++++++++++++ include/liquid.h | 3 + makefile.in | 1 + src/framing/src/qdsync.proto.c | 9 +- 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 examples/qdsync_cccf_performance_example.c diff --git a/examples/qdsync_cccf_performance_example.c b/examples/qdsync_cccf_performance_example.c new file mode 100644 index 000000000..6df24399f --- /dev/null +++ b/examples/qdsync_cccf_performance_example.c @@ -0,0 +1,99 @@ +// This example tests the performance for detecting and decoding frames +// with the qdsync_cccf object. +#include +#include +#include +#include "liquid.h" +#define OUTPUT_FILENAME "qdsync_cccf_performance_example.m" + +int main(int argc, char*argv[]) +{ + // options + unsigned int seq_len = 1024; // number of sync symbols + unsigned int k = 2; // samples/symbol + unsigned int m = 7; // filter delay [symbols] + float beta = 0.3f; // excess bandwidth factor + int ftype = LIQUID_FIRFILT_ARKAISER; + float threshold = 0.10f;// + unsigned int min_trials = 10; // + unsigned int max_trials = 100; // + unsigned int min_missed = 4; // + float SNRdB = -25.0f; + + // generate synchronization sequence (QPSK symbols) + float complex seq[seq_len]; + unsigned int i; + for (i=0; i= min_missed) + break; + if (num_trials >= max_trials) + break; + } + float pmd = (float)num_missed / (float)num_trials; + printf("SNR: %8.3f dB, missed %3u / %3u (%5.1f%%)\n", SNRdB, num_missed, num_trials, pmd*100); + if (num_missed < min_missed) + break; + SNRdB += 1.0f; + } + + qdsync_cccf_destroy(q); + +#if 0 + // open file for storing results + FILE * fid = fopen(OUTPUT_FILENAME,"w"); + fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME); + fprintf(fid,"clear all; close all;\n"); + + // export results + fprintf(fid,"seq_len = %u;\n", seq_len); + fprintf(fid,"figure('color','white','position',[100 100 800 800]);\n"); + fprintf(fid,"hold on;\n"); + fprintf(fid,"hold off;\n"); + fprintf(fid,"legend('Preamble','Payload');\n"); + fprintf(fid,"grid on; xlabel('real'); ylabel('imag');\n"); + fclose(fid); + printf("results written to '%s'\n", OUTPUT_FILENAME); +#endif + return 0; +} + diff --git a/include/liquid.h b/include/liquid.h index 1a3ea760b..bde0af9c7 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -6434,6 +6434,9 @@ int QDSYNC(_reset)(QDSYNC() _q); \ /* Print synchronizer object information to stdout */ \ int QDSYNC(_print)(QDSYNC() _q); \ \ +/* Get detection state */ \ +int QDSYNC(_is_detected)(QDSYNC() _q); \ + \ /* Get detection threshold */ \ float QDSYNC(_get_threshold)(QDSYNC() _q); \ \ diff --git a/makefile.in b/makefile.in index c2dd443e3..20480b5a0 100644 --- a/makefile.in +++ b/makefile.in @@ -1627,6 +1627,7 @@ example_programs := \ examples/poly_findroots_example \ examples/qdetector_cccf_example \ examples/qdsync_cccf_example \ + examples/qdsync_cccf_performance_example \ examples/qpacketmodem_performance_example \ examples/qpacketmodem_example \ examples/qpilotsync_example \ diff --git a/src/framing/src/qdsync.proto.c b/src/framing/src/qdsync.proto.c index 06f8fc0a0..afb917844 100644 --- a/src/framing/src/qdsync.proto.c +++ b/src/framing/src/qdsync.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -118,6 +118,7 @@ QDSYNC() QDSYNC(_create_linear)(TI * _seq, QDSYNC(_set_context )(q, _context ); // reset and return object + QDSYNC(_set_threshold)(q, 0.05f); // TODO: set threshold appropriate to sequence length QDSYNC(_reset)(q); return q; } @@ -180,6 +181,12 @@ int QDSYNC(_print)(QDSYNC() _q) return LIQUID_OK; } +// get detection state +int QDSYNC(_is_detected)(QDSYNC() _q) +{ + return _q->state == QDSYNC_STATE_SYNC; +} + // get detection threshold float QDSYNC(_get_threshold)(QDSYNC() _q) { From f3274d5d18d61f4aede82aeece1b0a77b9f44c76 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 11:41:47 -0400 Subject: [PATCH 25/97] dsssframe64: fixing msequence generator polynomial for preamble --- src/framing/src/dsssframe64gen.c | 4 ++-- src/framing/src/dsssframe64sync.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index f3ac1bbf8..bd6ec9348 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -58,7 +58,7 @@ dsssframe64gen dsssframe64gen_create() unsigned int i; // generate p/n sequence - q->ms = msequence_create(11, 0x0805, 1); + q->ms = msequence_create(11, 0x0500, 1); for (i=0; i<1024; i++) { q->preamble_pn[i] = (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2); q->preamble_pn[i] += (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2)*_Complex_I; diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index e5091a970..55b46a315 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -94,7 +94,7 @@ dsssframe64sync dsssframe64sync_create(framesync_callback _callback, unsigned int i; // generate p/n sequence - q->ms = msequence_create(11, 0x0805, 1); + q->ms = msequence_create(11, 0x0500, 1); for (i=0; i<1024; i++) { q->preamble_pn[i] = (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2); q->preamble_pn[i] += (msequence_advance(q->ms) ? M_SQRT1_2 : -M_SQRT1_2)*_Complex_I; From 88442ad3eba49fc43af5f2d459252437eb3f8f1b Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 11:50:47 -0400 Subject: [PATCH 26/97] dsssframe64: adjusting threshold, displaying stats in example --- examples/dsssframe64sync_performance_example.c | 9 ++++++--- src/framing/src/dsssframe64sync.c | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/examples/dsssframe64sync_performance_example.c b/examples/dsssframe64sync_performance_example.c index 3d73139d4..841027b2d 100644 --- a/examples/dsssframe64sync_performance_example.c +++ b/examples/dsssframe64sync_performance_example.c @@ -35,7 +35,7 @@ int main(int argc, char*argv[]) fprintf(fid,"%% %s: auto-generated file\n", OUTPUT_FILENAME); fprintf(fid,"clear all; close all;\n"); fprintf(fid,"SNR=[]; pdetect=[]; pvalid=[];\n"); - printf("# %8s %6s %6s %6s\n", "SNR", "detect", "valid", "trials"); + printf("# %8s %6s (%7s) %6s (%7s) %6s\n", "SNR", "missed", "percent", "errors", "percent", "trials"); fclose(fid); while (SNRdB < -5.0f) { dsssframe64sync_reset_framedatastats(fs); @@ -64,8 +64,11 @@ int main(int argc, char*argv[]) } // print results framedatastats_s stats = dsssframe64sync_get_framedatastats(fs); - printf(" %8.3f %6u %6u %6u\n", - SNRdB,stats.num_frames_detected,stats.num_payloads_valid,num_trials); + unsigned int num_misses = num_trials - stats.num_frames_detected; + float pmd = (float) num_misses / (float) num_trials; + float per = (float) num_errors / (float) num_trials; + printf(" %8.3f %6u (%6.2f%%) %6u (%6.2f%%) %6u\n", + SNRdB,num_misses,pmd*100,num_errors,per*100,num_trials); fid = fopen(OUTPUT_FILENAME,"a"); fprintf(fid,"SNR(end+1)=%g; pdetect(end+1)=%12g; pvalid(end+1)=%12g;\n", SNRdB, diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 55b46a315..774ea087c 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -104,7 +104,7 @@ dsssframe64sync dsssframe64sync_create(framesync_callback _callback, unsigned int k = 2; // samples/symbol q->detector = qdsync_cccf_create_linear(q->preamble_pn, 1024, LIQUID_FIRFILT_ARKAISER, k, q->m, q->beta, dsssframe64sync_callback_internal, (void*)q); - qdsync_cccf_set_threshold(q->detector, 0.100f); // detection threshold + qdsync_cccf_set_threshold(q->detector, 0.097f); // detection threshold qdsync_cccf_set_range (q->detector, 0.006f); // frequency offset search range [radians/sample] // create payload demodulator/decoder object From 9699a1c1aee87889a9e14ac8f6d0daa870211b1c Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 13:12:29 -0400 Subject: [PATCH 27/97] dsssframe64: making spreading factor (fixed) internal value --- src/framing/src/dsssframe64gen.c | 17 ++++++++++------- src/framing/src/dsssframe64sync.c | 19 ++++++++++++------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index bd6ec9348..81042099b 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -20,8 +20,7 @@ * THE SOFTWARE. */ -// DS/SS frame generator with fixed fields: 8-byte header, 64-byte payload, -// 128-symbol spreading factor +// DS/SS frame generator with fixed fields: 8-byte header and 64-byte payload #include #include @@ -36,16 +35,19 @@ int dsssframe64gen_write(dsssframe64gen _q, float complex * _buf); struct dsssframe64gen_s { + unsigned int m; // filter delay (symbols) + float beta; // filter excess bandwidth factor + unsigned int sf; // spreading factor (fixed) + // objects qpacketmodem enc; // packet encoder/modulator qpilotgen pilotgen; // pilot symbol generator msequence ms; // spreading sequence generator + firinterp_crcf interp; // pulse-shaping filter/interpolator + // buffers float complex preamble_pn[1024]; // 1024-symbol p/n sequence unsigned char payload_dec[ 150]; // 600 = 150 bytes * 8 bits/bytes / 2 bits/symbol float complex payload_sym[ 600]; // modulated payload symbols float complex payload_tx [ 650]; // modulated payload symbols with pilots - unsigned int m; // filter delay (symbols) - float beta; // filter excess bandwidth factor - firinterp_crcf interp; // pulse-shaping filter/interpolator }; // create dsssframe64gen object @@ -54,6 +56,7 @@ dsssframe64gen dsssframe64gen_create() dsssframe64gen q = (dsssframe64gen) malloc(sizeof(struct dsssframe64gen_s)); q->m = 15; q->beta = 0.20f; + q->sf = 128; // spreading factor unsigned int i; @@ -120,7 +123,7 @@ int dsssframe64gen_print(dsssframe64gen _q) // get full frame length [samples] unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q) { - return 2*(1024 + 650*128 + 2*_q->m); + return 2*(1024 + 650*_q->sf + 2*_q->m); } // generate a frame @@ -172,7 +175,7 @@ int dsssframe64gen_write(dsssframe64gen _q, // frame payload for (i=0; i<650; i++) { float complex sym = _q->payload_tx[i]; // strip out raw payload symbol - for (j=0; j<128; j++) { + for (j=0; j<_q->sf; j++) { // generate pseudo-random symbol unsigned int p = msequence_generate_symbol(_q->ms, 2); float complex s = cexpf(_Complex_I*2*M_PI*(float)p/(float)4); diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 774ea087c..90c7b8da1 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -22,6 +22,8 @@ // basic direct sequence/spread spectrum frame synchronizer with 8 bytes header // and 64 bytes payload +// * reliable frame detection (1% missed) down to -14 dB SNR +// * reliable frame decoding (1% errors) down to -13 dB SNR #include #include @@ -53,6 +55,7 @@ struct dsssframe64sync_s { void * context; // user-defined data structure unsigned int m; // filter delay (symbols) float beta; // filter excess bandwidth factor + unsigned int sf; // spreading factor (fixed) framesyncstats_s framesyncstats;// frame statistic object (synchronizer) framedatastats_s framedatastats;// frame statistic object (packet statistics) @@ -90,6 +93,7 @@ dsssframe64sync dsssframe64sync_create(framesync_callback _callback, q->context = _context; q->m = 15; // filter delay (symbols) q->beta = 0.20f;// excess bandwidth factor + q->sf = 128; // spreading factor unsigned int i; @@ -268,29 +272,30 @@ int dsssframe64sync_step(dsssframe64sync _q, float complex * _buf, unsigned int _buf_len) { - // TODO: do this more efficiently? unsigned int i; for (i=0; i<_buf_len; i++) { - // receive preamble + // receive preamble (not currently used) if (_q->preamble_counter < 1024) { _q->preamble_rx[_q->preamble_counter++] = _buf[i]; continue; } - // generate pseudo-random symbol + // generate pseudo-random spreading symbol and de-spread chip unsigned int p = msequence_generate_symbol(_q->ms, 2); float complex s = cexpf(_Complex_I*2*M_PI*(float)p/(float)4); _q->sym_despread += _buf[i] * conjf(s); _q->chip_counter++; - if (_q->chip_counter == 128) { - _q->payload_rx[_q->payload_counter] = _q->sym_despread / 128.0f; + // accumulate + if (_q->chip_counter == _q->sf) { + _q->payload_rx[_q->payload_counter] = _q->sym_despread / (float)(_q->sf); _q->payload_counter++; _q->chip_counter = 0; _q->sym_despread = 0; if (_q->payload_counter == 650) { dsssframe64sync_decode(_q); - return 1; // reset + msequence_reset(_q->ms); + return 1; // reset qdsync } } } @@ -328,7 +333,7 @@ int dsssframe64sync_decode(dsssframe64sync _q) if (_q->callback != NULL) { // offset estimates float dphi_hat = qdsync_cccf_get_dphi(_q->detector) + - qpilotsync_get_dphi(_q->pilotsync) / 128.0f; + qpilotsync_get_dphi(_q->pilotsync) / (float)(_q->sf); // set framesyncstats internals _q->framesyncstats.evm = qpilotsync_get_evm(_q->pilotsync); From d5db0628046c0478669c8f28d227b5ea125c9c6c Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 17:41:07 +0000 Subject: [PATCH 28/97] dsssframe64: allocating memory on heap --- examples/dsssframe64sync_example.c | 8 +++++--- examples/dsssframe64sync_performance_example.c | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/examples/dsssframe64sync_example.c b/examples/dsssframe64sync_example.c index 161403462..8af35d0d6 100644 --- a/examples/dsssframe64sync_example.c +++ b/examples/dsssframe64sync_example.c @@ -44,8 +44,8 @@ int main(int argc, char *argv[]) // generate the frame in blocks unsigned int buf_len = dsssframe64gen_get_frame_len(fg); - float complex buf_tx[buf_len]; // transmit buffer - float complex buf_rx[buf_len]; // receive buffer (channel output) + float complex * buf_tx = (float complex *)malloc(buf_len*sizeof(float complex)); + float complex * buf_rx = (float complex *)malloc(buf_len*sizeof(float complex)); // export results to file FILE * fid = fopen(filename,"w"); @@ -88,8 +88,10 @@ int main(int argc, char *argv[]) fclose(fid); printf("results written to %s\n", filename); - // destroy allocated objects + // destroy allocated objects and free memory dsssframe64gen_destroy(fg); + free(buf_tx); + free(buf_rx); return 0; } diff --git a/examples/dsssframe64sync_performance_example.c b/examples/dsssframe64sync_performance_example.c index 841027b2d..c1aff359e 100644 --- a/examples/dsssframe64sync_performance_example.c +++ b/examples/dsssframe64sync_performance_example.c @@ -29,7 +29,7 @@ int main(int argc, char*argv[]) // create buffer for the frame samples unsigned int frame_len = dsssframe64gen_get_frame_len(fg); - float complex frame[frame_len]; + float complex * frame = (float complex *)malloc(frame_len*sizeof(float complex)); float SNRdB = -25.0f; FILE* fid = fopen(OUTPUT_FILENAME, "w"); fprintf(fid,"%% %s: auto-generated file\n", OUTPUT_FILENAME); @@ -93,8 +93,9 @@ int main(int argc, char*argv[]) fclose(fid); printf("results written to %s\n", OUTPUT_FILENAME); - // clean up allocated objects + // clean up allocated objects and memory blocks dsssframe64gen_destroy(fg); dsssframe64sync_destroy(fs); + free(frame); return 0; } From 3b7828705568bbc5e72babf14a16a9b4e30456a5 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 14:13:04 -0400 Subject: [PATCH 29/97] dsssframe64: reducing spreading factor from 128 to 80 * zero-padding transmit buffer to ensure entire frame gets through synchronizer * performance is limited by detection of 1024-chip preamble * could increase the preamble, but at the cost of increased computational complexity --- examples/dsssframe64sync_example.c | 2 +- src/framing/src/dsssframe64gen.c | 10 +++++++--- src/framing/src/dsssframe64sync.c | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/examples/dsssframe64sync_example.c b/examples/dsssframe64sync_example.c index 8af35d0d6..62d844634 100644 --- a/examples/dsssframe64sync_example.c +++ b/examples/dsssframe64sync_example.c @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) { // options unsigned int nfft = 2400; - float SNRdB = -15.0f; + float SNRdB = -10.0f; const char * filename = "dsssframe64sync_example.m"; // create dsssframe64gen object diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index 81042099b..52b4bc7d8 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -56,7 +56,7 @@ dsssframe64gen dsssframe64gen_create() dsssframe64gen q = (dsssframe64gen) malloc(sizeof(struct dsssframe64gen_s)); q->m = 15; q->beta = 0.20f; - q->sf = 128; // spreading factor + q->sf = 80; // spreading factor unsigned int i; @@ -123,7 +123,8 @@ int dsssframe64gen_print(dsssframe64gen _q) // get full frame length [samples] unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q) { - return 2*(1024 + 650*_q->sf + 2*_q->m); + // add a small amount of zero-padding to ensure entire frame gets pushed through synchronizer + return 2*(1024 + 650*_q->sf + 2*_q->m) + 64; } // generate a frame @@ -190,7 +191,10 @@ int dsssframe64gen_write(dsssframe64gen _q, n+=2; } - assert(n==dsssframe64gen_get_frame_len(_q)); + // zero-pad end to ensure synchronizer can receive full payload + while (n < dsssframe64gen_get_frame_len(_q)) + _buf[n++] = 0; + return LIQUID_OK; } diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 90c7b8da1..30b87f435 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -23,7 +23,7 @@ // basic direct sequence/spread spectrum frame synchronizer with 8 bytes header // and 64 bytes payload // * reliable frame detection (1% missed) down to -14 dB SNR -// * reliable frame decoding (1% errors) down to -13 dB SNR +// * reliable frame decoding (1% errors) down to -11 dB SNR #include #include @@ -93,7 +93,7 @@ dsssframe64sync dsssframe64sync_create(framesync_callback _callback, q->context = _context; q->m = 15; // filter delay (symbols) q->beta = 0.20f;// excess bandwidth factor - q->sf = 128; // spreading factor + q->sf = 80; // spreading factor unsigned int i; From cdf0cdfab1b1560be20021c6b1b42cef59fcef32 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 14:47:22 -0400 Subject: [PATCH 30/97] dsssframe64: simplifying autotest --- src/framing/tests/dsssframe64sync_autotest.c | 36 ++++---------------- 1 file changed, 7 insertions(+), 29 deletions(-) diff --git a/src/framing/tests/dsssframe64sync_autotest.c b/src/framing/tests/dsssframe64sync_autotest.c index b4b010700..4cacce731 100644 --- a/src/framing/tests/dsssframe64sync_autotest.c +++ b/src/framing/tests/dsssframe64sync_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,49 +27,26 @@ #include "autotest/autotest.h" #include "liquid.h" -static int callback_dsssframe64sync_autotest( - unsigned char * _header, - int _header_valid, - unsigned char * _payload, - unsigned int _payload_len, - int _payload_valid, - framesyncstats_s _stats, - void * _userdata) -{ - //printf("callback invoked, payload valid: %s\n", _payload_valid ? "yes" : "no"); - int * frames_recovered = (int*) _userdata; - - *frames_recovered += _header_valid && _payload_valid ? 1 : 0; - return 0; -} - // AUTOTEST : test simple recovery of frame in noise void autotest_dsssframe64sync() { - unsigned int i; - int frames_recovered = 0; - // create objects - dsssframe64gen fg = dsssframe64gen_create(); - dsssframe64sync fs = dsssframe64sync_create(callback_dsssframe64sync_autotest, - (void*)&frames_recovered); - dsssframe64sync_set_threshold(fs, 0.5f); + dsssframe64gen fg = dsssframe64gen_create(); + dsssframe64sync fs = dsssframe64sync_create(NULL, NULL); // generate the frame unsigned int frame_len = dsssframe64gen_get_frame_len(fg); - float complex frame[frame_len]; + float complex * frame = (float complex *)malloc(frame_len*sizeof(float complex)); dsssframe64gen_execute(fg, NULL, NULL, frame); // add some noise + unsigned int i; for (i=0; i Date: Sun, 17 Mar 2024 14:55:08 -0400 Subject: [PATCH 31/97] qdsync: removing low default threshold; causing tests to fail --- src/framing/src/qdsync.proto.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/framing/src/qdsync.proto.c b/src/framing/src/qdsync.proto.c index afb917844..aee476f08 100644 --- a/src/framing/src/qdsync.proto.c +++ b/src/framing/src/qdsync.proto.c @@ -118,7 +118,6 @@ QDSYNC() QDSYNC(_create_linear)(TI * _seq, QDSYNC(_set_context )(q, _context ); // reset and return object - QDSYNC(_set_threshold)(q, 0.05f); // TODO: set threshold appropriate to sequence length QDSYNC(_reset)(q); return q; } From b4c9076f72aca737dec8be01201dcf7630ac6ebc Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 14:55:49 -0400 Subject: [PATCH 32/97] dsssframe64: renaming autotest --- makefile.in | 2 +- .../{dsssframe64sync_autotest.c => dsssframe64_autotest.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/framing/tests/{dsssframe64sync_autotest.c => dsssframe64_autotest.c} (100%) diff --git a/makefile.in b/makefile.in index 3b88e2892..0d5e2205f 100644 --- a/makefile.in +++ b/makefile.in @@ -682,7 +682,7 @@ framing_autotests := \ src/framing/tests/bpacketsync_autotest.c \ src/framing/tests/bsync_autotest.c \ src/framing/tests/detector_autotest.c \ - src/framing/tests/dsssframe64sync_autotest.c \ + src/framing/tests/dsssframe64_autotest.c \ src/framing/tests/dsssframesync_autotest.c \ src/framing/tests/flexframesync_autotest.c \ src/framing/tests/framesync64_autotest.c \ diff --git a/src/framing/tests/dsssframe64sync_autotest.c b/src/framing/tests/dsssframe64_autotest.c similarity index 100% rename from src/framing/tests/dsssframe64sync_autotest.c rename to src/framing/tests/dsssframe64_autotest.c From c4595edd1595e9d06e017037cbe56f7f1a255054 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 15:05:19 -0400 Subject: [PATCH 33/97] dsssframe64: adding interface for copy() methods, basic config testing --- include/liquid.h | 7 +++++++ src/framing/src/dsssframe64gen.c | 1 + src/framing/src/dsssframe64sync.c | 4 +++- src/framing/tests/dsssframe64_autotest.c | 24 ++++++++++++++++++++++++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/include/liquid.h b/include/liquid.h index d80ca92c8..71cc25592 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -6003,6 +6003,9 @@ typedef struct dsssframe64gen_s * dsssframe64gen; // create dsssframe64gen object dsssframe64gen dsssframe64gen_create(); +// copy object +dsssframe64gen dsssframe64gen_copy(dsssframe64gen q_orig); + // destroy dsssframe64gen object int dsssframe64gen_destroy(dsssframe64gen _q); @@ -6029,6 +6032,10 @@ unsigned int dsssframe64gen_get_frame_len(dsssframe64gen _q); typedef struct dsssframe64sync_s * dsssframe64sync; dsssframe64sync dsssframe64sync_create(framesync_callback _callback, void * _userdata); + +// copy object +dsssframe64sync dsssframe64sync_copy(dsssframe64sync q_orig); + int dsssframe64sync_destroy (dsssframe64sync _q); int dsssframe64sync_print (dsssframe64sync _q); int dsssframe64sync_reset (dsssframe64sync _q); diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index 52b4bc7d8..9cf3a137a 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -96,6 +96,7 @@ dsssframe64gen dsssframe64gen_copy(dsssframe64gen q_orig) return liquid_error_config("dsssframe64gen_copy(), object cannot be NULL"); // not yet implemented + liquid_error(LIQUID_ENOIMP, "dsssframe64gen_copy(), method not yet implemented"); return NULL; } diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 30b87f435..56bb6c92d 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -158,7 +158,9 @@ dsssframe64sync dsssframe64sync_copy(dsssframe64sync q_orig) return q_copy; #else - return liquid_error_config("dsssframe64sync_copy(), method not yet implemented"); + // not yet implemented + liquid_error(LIQUID_ENOIMP, "dsssframe64sync_copy(), method not yet implemented"); + return NULL; #endif } diff --git a/src/framing/tests/dsssframe64_autotest.c b/src/framing/tests/dsssframe64_autotest.c index 4cacce731..c6ed61518 100644 --- a/src/framing/tests/dsssframe64_autotest.c +++ b/src/framing/tests/dsssframe64_autotest.c @@ -60,3 +60,27 @@ void autotest_dsssframe64sync() free(frame); } +// test errors and invalid configuration +void autotest_dsssframe64_config() +{ +#if LIQUID_STRICT_EXIT + AUTOTEST_WARN("skipping dsssframe64 config test with strict exit enabled\n"); + return; +#endif +#if !LIQUID_SUPPRESS_ERROR_OUTPUT + fprintf(stderr,"warning: ignore potential errors here; checking for invalid configurations\n"); +#endif + // test copying/creating invalid objects + CONTEND_ISNULL( dsssframe64gen_copy(NULL) ); + CONTEND_ISNULL( dsssframe64sync_copy(NULL) ); + + // create valid objects + dsssframe64gen fg = dsssframe64gen_create(); + dsssframe64sync fs = dsssframe64sync_create(NULL, NULL); + CONTEND_EQUALITY( LIQUID_OK, dsssframe64gen_print(fg) ); + CONTEND_EQUALITY( LIQUID_OK, dsssframe64sync_print(fs) ); + + dsssframe64gen_destroy(fg); + dsssframe64sync_destroy(fs); +} + From 0172300a191b2b509e33e846b7800daf8be85561 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 16:23:58 -0400 Subject: [PATCH 34/97] qdsync,qdetector: adding methods to get frequency offset range --- include/liquid.h | 10 ++++++++-- src/framing/src/qdetector.proto.c | 8 +++++++- src/framing/src/qdsync.proto.c | 6 ++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/include/liquid.h b/include/liquid.h index bde0af9c7..55c22467a 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -6344,11 +6344,14 @@ void * QDETECTOR(_execute)(QDETECTOR() _q, TI _x); \ /* get detection threshold */ \ float QDETECTOR(_get_threshold)(QDETECTOR() _q); \ \ -/* set detection threshold (should be between 0 and 1, good starting */ \ +/* Set detection threshold (should be between 0 and 1, good starting */ \ /* point is 0.5) */ \ int QDETECTOR(_set_threshold)(QDETECTOR() _q, \ float _threshold); \ \ +/* Get carrier offset search range */ \ +float QDETECTOR(_get_range)(QDETECTOR() _q); \ + \ /* Set carrier offset search range */ \ int QDETECTOR(_set_range)(QDETECTOR() _q, \ float _dphi_max); \ @@ -6444,7 +6447,10 @@ float QDSYNC(_get_threshold)(QDSYNC() _q); \ int QDSYNC(_set_threshold)(QDSYNC() _q, \ float _threshold); \ \ -/* set carrier offset search range */ \ +/* Get carrier offset search range */ \ +float QDSYNC(_get_range)(QDSYNC() _q); \ + \ +/* Set carrier offset search range */ \ int QDSYNC(_set_range)(QDSYNC() _q, \ float _dphi_max); \ \ diff --git a/src/framing/src/qdetector.proto.c b/src/framing/src/qdetector.proto.c index 5c13f45eb..4511ea018 100644 --- a/src/framing/src/qdetector.proto.c +++ b/src/framing/src/qdetector.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -380,6 +380,12 @@ int QDETECTOR(_set_threshold)(QDETECTOR() _q, return LIQUID_OK; } +// get carrier offset search range +float QDETECTOR(_get_range)(QDETECTOR() _q) +{ + return _q->range; +} + // set carrier offset search range int QDETECTOR(_set_range)(QDETECTOR() _q, float _dphi_max) diff --git a/src/framing/src/qdsync.proto.c b/src/framing/src/qdsync.proto.c index aee476f08..0ec0877f6 100644 --- a/src/framing/src/qdsync.proto.c +++ b/src/framing/src/qdsync.proto.c @@ -198,6 +198,12 @@ int QDSYNC(_set_threshold)(QDSYNC() _q, float _threshold) return QDETECTOR(_set_threshold)(_q->detector, _threshold); } +// get carrier offset search range +float QDSYNC(_get_range)(QDSYNC() _q) +{ + return QDETECTOR(_get_range)(_q->detector); +} + // set carrier offset search range int QDSYNC(_set_range)(QDSYNC() _q, float _dphi_max) { From f8a3418bb054cf1a7a6c70f746fd65c261d31bc1 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 16:29:02 -0400 Subject: [PATCH 35/97] dsssframe64: adding methods to get/set threshold/range, tests --- include/liquid.h | 3 +++ src/framing/src/dsssframe64sync.c | 18 ++++++++++++------ src/framing/tests/dsssframe64_autotest.c | 11 +++++++++++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/include/liquid.h b/include/liquid.h index 6310ea9ee..0bd70aeba 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -6057,6 +6057,9 @@ float dsssframe64sync_get_threshold(dsssframe64sync _q); int dsssframe64sync_set_threshold(dsssframe64sync _q, float _threshold); +// get carrier offset search range [radians/sample] +float dsssframe64sync_get_range(dsssframe64sync _q); + // set carrier offset search range int dsssframe64sync_set_range(dsssframe64sync _q, float _dphi_max); diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 56bb6c92d..9d0164b6d 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -237,12 +237,6 @@ int dsssframe64sync_execute(dsssframe64sync _q, return qdsync_cccf_execute(_q->detector, _buf, _buf_len); } -// get detection threshold -float dsssframe64sync_get_threshold(dsssframe64sync _q) -{ - return qdsync_cccf_get_threshold(_q->detector); -} - // set detection threshold int dsssframe64sync_set_threshold(dsssframe64sync _q, float _threshold) @@ -250,6 +244,12 @@ int dsssframe64sync_set_threshold(dsssframe64sync _q, return qdsync_cccf_set_threshold(_q->detector, _threshold); } +// get detection threshold +float dsssframe64sync_get_threshold(dsssframe64sync _q) +{ + return qdsync_cccf_get_threshold(_q->detector); +} + // set carrier offset search range int dsssframe64sync_set_range(dsssframe64sync _q, float _dphi_max) @@ -257,6 +257,12 @@ int dsssframe64sync_set_range(dsssframe64sync _q, return qdsync_cccf_set_range(_q->detector, _dphi_max); } +// get detection threshold +float dsssframe64sync_get_range(dsssframe64sync _q) +{ + return qdsync_cccf_get_range(_q->detector); +} + // reset frame data statistics int dsssframe64sync_reset_framedatastats(dsssframe64sync _q) { diff --git a/src/framing/tests/dsssframe64_autotest.c b/src/framing/tests/dsssframe64_autotest.c index c6ed61518..03707fcc3 100644 --- a/src/framing/tests/dsssframe64_autotest.c +++ b/src/framing/tests/dsssframe64_autotest.c @@ -80,6 +80,17 @@ void autotest_dsssframe64_config() CONTEND_EQUALITY( LIQUID_OK, dsssframe64gen_print(fg) ); CONTEND_EQUALITY( LIQUID_OK, dsssframe64sync_print(fs) ); + // synchronizer parameters + CONTEND_EQUALITY( 0, dsssframe64sync_is_frame_open(fs) ); + CONTEND_EQUALITY( LIQUID_OK, dsssframe64sync_set_callback(fs, NULL) ); + CONTEND_EQUALITY( LIQUID_OK, dsssframe64sync_set_context (fs, NULL) ); + float threshold = 0.123f; + CONTEND_EQUALITY( LIQUID_OK, dsssframe64sync_set_threshold(fs, threshold) ); + CONTEND_EQUALITY( threshold, dsssframe64sync_get_threshold(fs) ); + float range = 0.00722f; + CONTEND_EQUALITY( LIQUID_OK, dsssframe64sync_set_range(fs, range) ); + //CONTEND_EQUALITY( range, dsssframe64sync_get_range(fs) ); + dsssframe64gen_destroy(fg); dsssframe64sync_destroy(fs); } From 466b6fb4192471fe76c0df6f9d58e032e8392739 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 20:55:39 -0400 Subject: [PATCH 36/97] msequence: adding copy() method --- include/liquid.h | 3 +++ src/sequence/src/msequence.c | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/include/liquid.h b/include/liquid.h index 0bd70aeba..3e9fc288c 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -9789,6 +9789,9 @@ msequence msequence_create(unsigned int _m, unsigned int _g, unsigned int _a); +// Copy maximal-length sequence (m-sequence) object +msequence msequence_copy(msequence q_orig); + // create a maximal-length sequence (m-sequence) object from a generator polynomial msequence msequence_create_genpoly(unsigned int _g); diff --git a/src/sequence/src/msequence.c b/src/sequence/src/msequence.c index ecad555ff..fe0ae1a9b 100644 --- a/src/sequence/src/msequence.c +++ b/src/sequence/src/msequence.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -71,6 +71,18 @@ msequence msequence_create(unsigned int _m, return ms; } +// Copy maximal-length sequence (m-sequence) object +msequence msequence_copy(msequence q_orig) +{ + // validate input + if (q_orig == NULL) + return liquid_error_config("msequence_copy(), object cannot be NULL"); + + // create filter object and copy base parameters + msequence q_copy = (msequence) malloc(sizeof(struct msequence_s)); + memmove(q_copy, q_orig, sizeof(struct msequence_s)); + return q_copy; +} // create a maximal-length sequence (m-sequence) object from a generator polynomial msequence msequence_create_genpoly(unsigned int _g) From d84f50dde482374da3efe03a00ed6c792e2534d9 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 21:01:50 -0400 Subject: [PATCH 37/97] dsssframe64: adding copy() method, test --- src/framing/src/dsssframe64gen.c | 13 +++++++--- src/framing/tests/dsssframe64_autotest.c | 31 ++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/framing/src/dsssframe64gen.c b/src/framing/src/dsssframe64gen.c index 9cf3a137a..4fd6f3e9c 100644 --- a/src/framing/src/dsssframe64gen.c +++ b/src/framing/src/dsssframe64gen.c @@ -95,9 +95,16 @@ dsssframe64gen dsssframe64gen_copy(dsssframe64gen q_orig) if (q_orig == NULL) return liquid_error_config("dsssframe64gen_copy(), object cannot be NULL"); - // not yet implemented - liquid_error(LIQUID_ENOIMP, "dsssframe64gen_copy(), method not yet implemented"); - return NULL; + // create filter object and copy base parameters + dsssframe64gen q_copy = (dsssframe64gen) malloc(sizeof(struct dsssframe64gen_s)); + memmove(q_copy, q_orig, sizeof(struct dsssframe64gen_s)); + + // copy objects + q_copy->enc = qpacketmodem_copy (q_orig->enc ); + q_copy->pilotgen = qpilotgen_copy (q_orig->pilotgen); + q_copy->ms = msequence_copy (q_orig->ms ); + q_copy->interp = firinterp_crcf_copy(q_orig->interp ); + return q_copy; } // destroy dsssframe64gen object diff --git a/src/framing/tests/dsssframe64_autotest.c b/src/framing/tests/dsssframe64_autotest.c index 03707fcc3..747eb8720 100644 --- a/src/framing/tests/dsssframe64_autotest.c +++ b/src/framing/tests/dsssframe64_autotest.c @@ -95,3 +95,34 @@ void autotest_dsssframe64_config() dsssframe64sync_destroy(fs); } +// test that the complete internal state of one generator can be copied to a new +// object +void autotest_dsssframe64gen_copy() +{ + // create object and copy + dsssframe64gen q0 = dsssframe64gen_create(); + dsssframe64gen q1 = dsssframe64gen_copy(q0); + + // allocate buffers for frames + unsigned int frame_len = dsssframe64gen_get_frame_len(q0); + float complex * buf_0 = (float complex *)malloc(frame_len*sizeof(float complex)); + float complex * buf_1 = (float complex *)malloc(frame_len*sizeof(float complex)); + unsigned char header [ 8] = {0,0,0,0,0,0,0,0,}; + unsigned char payload[64] = { + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,}; + + // encode + dsssframe64gen_execute(q0, header, payload, buf_0); + dsssframe64gen_execute(q1, header, payload, buf_1); + + // ensure identical outputs + CONTEND_SAME_DATA(buf_0, buf_1, frame_len*sizeof(float complex)); + + // destroy objects and free memory + dsssframe64gen_destroy(q0); + dsssframe64gen_destroy(q1); + free(buf_0); + free(buf_1); +} + From afa0d80b95cc3992bfafc881e1a94200965614b9 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 17 Mar 2024 21:46:29 -0400 Subject: [PATCH 38/97] dsssframe64sync: addinf copy() method, tests --- src/framing/src/dsssframe64sync.c | 25 ++++++------ src/framing/tests/dsssframe64_autotest.c | 49 ++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/src/framing/src/dsssframe64sync.c b/src/framing/src/dsssframe64sync.c index 9d0164b6d..27a84e620 100644 --- a/src/framing/src/dsssframe64sync.c +++ b/src/framing/src/dsssframe64sync.c @@ -136,7 +136,6 @@ dsssframe64sync dsssframe64sync_create(framesync_callback _callback, // copy object dsssframe64sync dsssframe64sync_copy(dsssframe64sync q_orig) { -#if 0 // validate input if (q_orig == NULL) return liquid_error_config("dsssframe64sync_copy(), object cannot be NULL"); @@ -147,21 +146,16 @@ dsssframe64sync dsssframe64sync_copy(dsssframe64sync q_orig) // copy entire memory space over and overwrite values as needed memmove(q_copy, q_orig, sizeof(struct dsssframe64sync_s)); - // set callback and context fields - q_copy->callback = q_orig->callback; - q_copy->context = q_orig->context; + // copy internal objects + q_copy->detector = qdsync_cccf_copy (q_orig->detector); + q_copy->ms = msequence_copy (q_orig->ms); + q_copy->dec = qpacketmodem_copy(q_orig->dec); + q_copy->pilotsync = qpilotsync_copy (q_orig->pilotsync); - // copy objects - q_copy->detector = qdsync_cccf_copy(q_orig->detector); - q_copy->dec = qpacketmodem_copy (q_orig->dec); - q_copy->pilotsync= qpilotsync_copy (q_orig->pilotsync); + // update detector callback's context to use q_copy + qdsync_cccf_set_context(q_copy->detector, (void*)q_copy); return q_copy; -#else - // not yet implemented - liquid_error(LIQUID_ENOIMP, "dsssframe64sync_copy(), method not yet implemented"); - return NULL; -#endif } // destroy frame synchronizer object, freeing all internal memory @@ -181,7 +175,10 @@ int dsssframe64sync_destroy(dsssframe64sync _q) // print frame synchronizer object internals int dsssframe64sync_print(dsssframe64sync _q) { - printf("\n"); + printf("\n", + _q->preamble_counter, + _q->chip_counter, + _q->payload_counter); return LIQUID_OK; } diff --git a/src/framing/tests/dsssframe64_autotest.c b/src/framing/tests/dsssframe64_autotest.c index 747eb8720..cfe7ae752 100644 --- a/src/framing/tests/dsssframe64_autotest.c +++ b/src/framing/tests/dsssframe64_autotest.c @@ -126,3 +126,52 @@ void autotest_dsssframe64gen_copy() free(buf_1); } +// test that the complete internal state of one synchronizer can be copied to a new +// object and it can maintain state +void autotest_dsssframe64sync_copy() +{ + // create object and generte frame + dsssframe64gen fg = dsssframe64gen_create(); + unsigned int frame_len = dsssframe64gen_get_frame_len(fg); + float complex * frame= (float complex *)malloc(frame_len*sizeof(float complex)); + dsssframe64gen_execute(fg, NULL, NULL, frame); + + // creamte original frame synchronizer + dsssframe64sync q0 = dsssframe64sync_create(NULL, NULL); + + // run half of frame through synchronizer + unsigned int n = 12000; + dsssframe64sync_execute(q0, frame, n); + + // ensure frame was not yet decoded + framedatastats_s s0, s1; + s0 = dsssframe64sync_get_framedatastats(q0); + CONTEND_EQUALITY(s0.num_frames_detected, 0); + + // copy object + dsssframe64sync q1 = dsssframe64sync_copy(q0); + + // run remaining half of frame through synchronizers + dsssframe64sync_execute(q0, frame+n, frame_len-n); + dsssframe64sync_execute(q1, frame+n, frame_len-n); + + // ensure frame was decoded by both synchronizers + s0 = dsssframe64sync_get_framedatastats(q0); + CONTEND_EQUALITY(s0.num_frames_detected, 1); + CONTEND_EQUALITY(s0.num_headers_valid, 1); + CONTEND_EQUALITY(s0.num_payloads_valid, 1); + CONTEND_EQUALITY(s0.num_bytes_received, 64); + + s1 = dsssframe64sync_get_framedatastats(q1); + CONTEND_EQUALITY(s1.num_frames_detected, 1); + CONTEND_EQUALITY(s1.num_headers_valid, 1); + CONTEND_EQUALITY(s1.num_payloads_valid, 1); + CONTEND_EQUALITY(s1.num_bytes_received, 64); + + // destroy objects and free memory + dsssframe64gen_destroy(fg); + dsssframe64sync_destroy(q0); + dsssframe64sync_destroy(q1); + free(frame); +} + From 8d75f5082ab9ce4967764095004522e53177d6de Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Mon, 18 Mar 2024 08:11:54 -0400 Subject: [PATCH 39/97] dsssframe64: ensuring callback was invoked in synchronizer --- src/framing/tests/dsssframe64_autotest.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/framing/tests/dsssframe64_autotest.c b/src/framing/tests/dsssframe64_autotest.c index cfe7ae752..31acf9877 100644 --- a/src/framing/tests/dsssframe64_autotest.c +++ b/src/framing/tests/dsssframe64_autotest.c @@ -27,12 +27,28 @@ #include "autotest/autotest.h" #include "liquid.h" -// AUTOTEST : test simple recovery of frame in noise +// static callback function +static int framing_autotest_callback( + unsigned char * _header, + int _header_valid, + unsigned char * _payload, + unsigned int _payload_len, + int _payload_valid, + framesyncstats_s _stats, + void * _context) +{ + printf("*** callback invoked (%s) ***\n", _payload_valid ? "pass" : "FAIL"); + unsigned int * secret = (unsigned int*) _context; + *secret = 0x01234567; + return 0; +} + void autotest_dsssframe64sync() { // create objects + unsigned int context = 0; dsssframe64gen fg = dsssframe64gen_create(); - dsssframe64sync fs = dsssframe64sync_create(NULL, NULL); + dsssframe64sync fs = dsssframe64sync_create(framing_autotest_callback, (void*)&context); // generate the frame unsigned int frame_len = dsssframe64gen_get_frame_len(fg); @@ -47,6 +63,9 @@ void autotest_dsssframe64sync() // try to receive the frame dsssframe64sync_execute(fs, frame, frame_len); + // ensure callback was invoked + CONTEND_EQUALITY(context, 0x01234567); + // parse statistics framedatastats_s stats = dsssframe64sync_get_framedatastats(fs); CONTEND_EQUALITY(stats.num_frames_detected, 1); From a39faff107a11e592b5146b25561e878b10f98e4 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Mon, 18 Mar 2024 17:24:13 -0400 Subject: [PATCH 40/97] qdetector: storing internal frequency offset range --- src/framing/src/qdetector.proto.c | 13 ++++++++----- src/framing/tests/dsssframe64_autotest.c | 2 +- src/framing/tests/qdsync_cccf_autotest.c | 6 +++++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/framing/src/qdetector.proto.c b/src/framing/src/qdetector.proto.c index 4511ea018..5128adb0e 100644 --- a/src/framing/src/qdetector.proto.c +++ b/src/framing/src/qdetector.proto.c @@ -57,6 +57,7 @@ struct QDETECTOR(_s) { unsigned int counter; // sample counter for determining when to compute FFTs float threshold; // detection threshold + float dphi_max; // carrier offset search range (radians/sample) int range; // carrier offset search range (subcarriers) unsigned int num_transforms; // number of transforms taken (debugging) @@ -287,6 +288,7 @@ QDETECTOR() QDETECTOR(_copy)(QDETECTOR() q_orig) // copy internal state q_copy->counter = q_orig->counter; q_copy->threshold = q_orig->threshold; + q_copy->dphi_max = q_orig->dphi_max; q_copy->range = q_orig->range; q_copy->num_transforms = q_orig->num_transforms; // buffer power magnitude @@ -324,7 +326,7 @@ int QDETECTOR(_print)(QDETECTOR() _q) printf("qdetector_%s:\n", EXTENSION_FULL); printf(" template length (time): %-u\n", _q->s_len); printf(" FFT size : %-u\n", _q->nfft); - printf(" search range (bins) : %-d\n", _q->range); + printf(" search range : %g [radians/sample], %-d [bins]\n",_q->dphi_max, _q->range); printf(" detection threshold : %6.4f\n", _q->threshold); printf(" sum{ s^2 } : %.2f\n", _q->s2_sum); return LIQUID_OK; @@ -383,19 +385,20 @@ int QDETECTOR(_set_threshold)(QDETECTOR() _q, // get carrier offset search range float QDETECTOR(_get_range)(QDETECTOR() _q) { - return _q->range; + return _q->dphi_max; } // set carrier offset search range int QDETECTOR(_set_range)(QDETECTOR() _q, - float _dphi_max) + float _dphi_max) { if (_dphi_max < 0.0f || _dphi_max > 0.5f) return liquid_error(LIQUID_EICONFIG,"carrier offset search range (%12.4e) out of range; ignoring", _dphi_max); // set internal search range - _q->range = (int)(_dphi_max * _q->nfft / (2*M_PI)); - _q->range = _q->range < 0 ? 0 : _q->range; + _q->dphi_max = _dphi_max; + _q->range = (int)(_q->dphi_max * _q->nfft / (2*M_PI)); + _q->range = _q->range < 0 ? 0 : _q->range; //printf("range: %d / %u\n", _q->range, _q->nfft); return LIQUID_OK; } diff --git a/src/framing/tests/dsssframe64_autotest.c b/src/framing/tests/dsssframe64_autotest.c index 31acf9877..030e7abf1 100644 --- a/src/framing/tests/dsssframe64_autotest.c +++ b/src/framing/tests/dsssframe64_autotest.c @@ -108,7 +108,7 @@ void autotest_dsssframe64_config() CONTEND_EQUALITY( threshold, dsssframe64sync_get_threshold(fs) ); float range = 0.00722f; CONTEND_EQUALITY( LIQUID_OK, dsssframe64sync_set_range(fs, range) ); - //CONTEND_EQUALITY( range, dsssframe64sync_get_range(fs) ); + CONTEND_EQUALITY( range, dsssframe64sync_get_range(fs) ); dsssframe64gen_destroy(fg); dsssframe64sync_destroy(fs); diff --git a/src/framing/tests/qdsync_cccf_autotest.c b/src/framing/tests/qdsync_cccf_autotest.c index 1e1c59eaf..443642399 100644 --- a/src/framing/tests/qdsync_cccf_autotest.c +++ b/src/framing/tests/qdsync_cccf_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -325,6 +325,10 @@ void autotest_qdsync_cccf_config() CONTEND_EQUALITY(LIQUID_OK, qdsync_cccf_set_threshold(q,0.654321f)) CONTEND_EQUALITY(0.654321f, qdsync_cccf_get_threshold(q)) + // set/get range + CONTEND_EQUALITY(LIQUID_OK, qdsync_cccf_set_range(q,0.007220f)) + CONTEND_EQUALITY(0.007220f, qdsync_cccf_get_range(q)) + // set invalid buffer length CONTEND_INEQUALITY(LIQUID_OK, qdsync_cccf_set_buf_len(q,0)) From 966c26be89c69ae52ab18257ad06e3207006f386 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Mon, 18 Mar 2024 17:58:41 -0400 Subject: [PATCH 41/97] framing/autotest: using consistent internal callback --- autotest/autotest.c | 18 ++++++++- autotest/autotest.h | 13 ++++++- src/framing/tests/dsssframe64_autotest.c | 18 +-------- src/framing/tests/dsssframesync_autotest.c | 27 ++------------ src/framing/tests/flexframesync_autotest.c | 8 +++- src/framing/tests/framesync64_autotest.c | 43 +++++++--------------- src/framing/tests/fskframesync_autotest.c | 25 +++---------- src/framing/tests/gmskframe_autotest.c | 29 ++------------- src/framing/tests/ofdmflexframe_autotest.c | 9 ++++- 9 files changed, 69 insertions(+), 121 deletions(-) diff --git a/autotest/autotest.c b/autotest/autotest.c index 78a62a529..ccd3cb785 100644 --- a/autotest/autotest.c +++ b/autotest/autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -362,3 +362,19 @@ int liquid_autotest_validate_psd_iirfilt_rrrf(iirfilt_rrrf _q, unsigned int _nff return liquid_autotest_validate_spectrum(psd,_nfft,_regions,num_regions,debug_filename); } +// callback function to simplify testing for framing objects +int framing_autotest_callback( + unsigned char * _header, + int _header_valid, + unsigned char * _payload, + unsigned int _payload_len, + int _payload_valid, + framesyncstats_s _stats, + void * _context) +{ + printf("*** callback invoked (%s) ***\n", _payload_valid ? "pass" : "FAIL"); + unsigned int * secret = (unsigned int*) _context; + *secret = FRAMING_AUTOTEST_SECRET; + return 0; +} + diff --git a/autotest/autotest.h b/autotest/autotest.h index 148a50311..5945ab5e2 100644 --- a/autotest/autotest.h +++ b/autotest/autotest.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -316,5 +316,16 @@ int liquid_autotest_validate_psd_firfilt_cccf(firfilt_cccf _q, unsigned int _nff int liquid_autotest_validate_psd_iirfilt_rrrf(iirfilt_rrrf _q, unsigned int _nfft, autotest_psd_s * _regions, unsigned int num_regions, const char * debug_filename); +// callback function to simplify testing for framing objects +#define FRAMING_AUTOTEST_SECRET 0x01234567 +int framing_autotest_callback( + unsigned char * _header, + int _header_valid, + unsigned char * _payload, + unsigned int _payload_len, + int _payload_valid, + framesyncstats_s _stats, + void * _context); + #endif // __LIQUID_AUTOTEST_H__ diff --git a/src/framing/tests/dsssframe64_autotest.c b/src/framing/tests/dsssframe64_autotest.c index 030e7abf1..f8b14490a 100644 --- a/src/framing/tests/dsssframe64_autotest.c +++ b/src/framing/tests/dsssframe64_autotest.c @@ -27,22 +27,6 @@ #include "autotest/autotest.h" #include "liquid.h" -// static callback function -static int framing_autotest_callback( - unsigned char * _header, - int _header_valid, - unsigned char * _payload, - unsigned int _payload_len, - int _payload_valid, - framesyncstats_s _stats, - void * _context) -{ - printf("*** callback invoked (%s) ***\n", _payload_valid ? "pass" : "FAIL"); - unsigned int * secret = (unsigned int*) _context; - *secret = 0x01234567; - return 0; -} - void autotest_dsssframe64sync() { // create objects @@ -64,7 +48,7 @@ void autotest_dsssframe64sync() dsssframe64sync_execute(fs, frame, frame_len); // ensure callback was invoked - CONTEND_EQUALITY(context, 0x01234567); + CONTEND_EQUALITY(context, FRAMING_AUTOTEST_SECRET); // parse statistics framedatastats_s stats = dsssframe64sync_get_framedatastats(fs); diff --git a/src/framing/tests/dsssframesync_autotest.c b/src/framing/tests/dsssframesync_autotest.c index bb8234c8c..1ef54d4d1 100644 --- a/src/framing/tests/dsssframesync_autotest.c +++ b/src/framing/tests/dsssframesync_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,25 +26,6 @@ #include "autotest/autotest.h" #include "liquid.h" -static int callback_dsssframe( - unsigned char * _header, - int _header_valid, - unsigned char * _payload, - unsigned int _payload_len, - int _payload_valid, - framesyncstats_s _stats, - void * _userdata) -{ - printf("*** dsssframe callback invoked ***\n"); - framesyncstats_print(&_stats); - if (_payload_valid) - *((int*)_userdata) = 1; // success - return 0; -} - -// -// AUTOTEST : test simple recovery of frame in noise -// void autotest_dsssframesync() { unsigned int _payload_len = 400; @@ -60,8 +41,8 @@ void autotest_dsssframesync() dsssframegen_assemble(fg, NULL, NULL, _payload_len); // create dsssframesync object - int success = 0; - dsssframesync fs = dsssframesync_create(callback_dsssframe,(void*)&success); + unsigned int context = 0; + dsssframesync fs = dsssframesync_create(framing_autotest_callback, (void*)&context); // generate the frame int frame_complete = 0; @@ -87,7 +68,7 @@ void autotest_dsssframesync() CONTEND_EQUALITY( stats.num_payloads_valid, 1 ); CONTEND_EQUALITY( stats.num_bytes_received, _payload_len ); #endif - CONTEND_EQUALITY( success, 1 ); + CONTEND_EQUALITY(context, FRAMING_AUTOTEST_SECRET); // destroy objects dsssframegen_destroy(fg); diff --git a/src/framing/tests/flexframesync_autotest.c b/src/framing/tests/flexframesync_autotest.c index f5e984ed4..a7546fed6 100644 --- a/src/framing/tests/flexframesync_autotest.c +++ b/src/framing/tests/flexframesync_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -49,7 +49,8 @@ void autotest_flexframesync() flexframegen fg = flexframegen_create(&fgprops); // create flexframesync object - flexframesync fs = flexframesync_create(NULL,NULL); + unsigned int context = 0; + flexframesync fs = flexframesync_create(framing_autotest_callback, (void*)&context); // initialize header and payload unsigned char header[14] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; @@ -78,6 +79,9 @@ void autotest_flexframesync() if (liquid_autotest_verbose) flexframesync_print(fs); + // ensure callback was invoked + CONTEND_EQUALITY(context, FRAMING_AUTOTEST_SECRET); + // check to see that frame was recovered CONTEND_EQUALITY( stats.num_frames_detected, 1 ); CONTEND_EQUALITY( stats.num_headers_valid, 1 ); diff --git a/src/framing/tests/framesync64_autotest.c b/src/framing/tests/framesync64_autotest.c index 7a1b78cc7..6393fe2c7 100644 --- a/src/framing/tests/framesync64_autotest.c +++ b/src/framing/tests/framesync64_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,30 +27,15 @@ #include "autotest/autotest.h" #include "liquid.h" -static int callback_framesync64_autotest( - unsigned char * _header, - int _header_valid, - unsigned char * _payload, - unsigned int _payload_len, - int _payload_valid, - framesyncstats_s _stats, - void * _userdata) -{ - //printf("callback invoked, payload valid: %s\n", _payload_valid ? "yes" : "no"); - *((int*)(_userdata)) += _header_valid && _payload_valid ? 1 : 0; - return 0; -} - // AUTOTEST : test simple recovery of frame in noise void autotest_framesync64() { unsigned int i; - int frames_recovered = 0; // create objects + unsigned int context = 0; framegen64 fg = framegen64_create(); - framesync64 fs = framesync64_create(callback_framesync64_autotest, - (void*)&frames_recovered); + framesync64 fs = framesync64_create(framing_autotest_callback, (void*)&context); // generate the frame float complex frame[LIQUID_FRAME64_LEN]; @@ -63,8 +48,8 @@ void autotest_framesync64() // try to receive the frame framesync64_execute(fs, frame, LIQUID_FRAME64_LEN); - // check to see that exactly one frame was recovered - CONTEND_EQUALITY( frames_recovered, 1 ); + // ensure callback was actually invoked + CONTEND_EQUALITY(context, FRAMING_AUTOTEST_SECRET); // parse statistics framedatastats_s stats = framesync64_get_framedatastats(fs); @@ -97,13 +82,12 @@ void autotest_framegen64_copy() void autotest_framesync64_copy() { unsigned int i; - int frames_recovered_0 = 0; - int frames_recovered_1 = 0; + int context_0 = 0; + int context_1 = 0; // create objects framegen64 fg = framegen64_create(); - framesync64 fs0 = framesync64_create(callback_framesync64_autotest, - (void*)&frames_recovered_0); + framesync64 fs0 = framesync64_create(framing_autotest_callback, (void*)&context_0); // feed random samples into synchronizer float complex buf[LIQUID_FRAME64_LEN]; @@ -120,7 +104,7 @@ void autotest_framesync64_copy() // copy object, but set different context framesync64 fs1 = framesync64_copy(fs0); - framesync64_set_userdata(fs1, (void*)&frames_recovered_1); + framesync64_set_userdata(fs1, (void*)&context_1); framesync64_print(fs0); framesync64_print(fs1); @@ -131,12 +115,12 @@ void autotest_framesync64_copy() framesync64_execute(fs1, buf+i, 1); // ensure that the frames are recovered at exactly the same time - CONTEND_EQUALITY( frames_recovered_0, frames_recovered_1 ); + CONTEND_EQUALITY( context_0, context_1 ); } // check that frame was actually recovered by each object - CONTEND_EQUALITY( frames_recovered_0, 1 ); - CONTEND_EQUALITY( frames_recovered_1, 1 ); + CONTEND_EQUALITY( context_0, 0x01234567 ); + CONTEND_EQUALITY( context_1, 0x01234567 ); // parse statistics framedatastats_s stats_0 = framesync64_get_framedatastats(fs0); @@ -174,13 +158,12 @@ void autotest_framesync64_config() framesync64 q = framesync64_create(NULL, NULL); CONTEND_EQUALITY(LIQUID_OK, framesync64_print(q)) - CONTEND_EQUALITY(LIQUID_OK, framesync64_set_callback(q,callback_framesync64_autotest)) + CONTEND_EQUALITY(LIQUID_OK, framesync64_set_callback(q,NULL)) CONTEND_EQUALITY(LIQUID_OK, framesync64_set_userdata(q,NULL)) CONTEND_EQUALITY(LIQUID_OK, framesync64_set_threshold(q,0.654321f)) CONTEND_EQUALITY(0.654321f, framesync64_get_threshold(q)) - framesync64_destroy(q); } diff --git a/src/framing/tests/fskframesync_autotest.c b/src/framing/tests/fskframesync_autotest.c index 9ffbef087..941e4d698 100644 --- a/src/framing/tests/fskframesync_autotest.c +++ b/src/framing/tests/fskframesync_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,20 +27,6 @@ #include "autotest/autotest.h" #include "liquid.h" -static int callback_fskframesync_autotest( - unsigned char * _header, - int _header_valid, - unsigned char * _payload, - unsigned int _payload_len, - int _payload_valid, - framesyncstats_s _stats, - void * _userdata) -{ - //printf("callback invoked, payload valid: %s\n", _payload_valid ? "yes" : "no"); - *((int*)(_userdata)) += _header_valid && _payload_valid ? 1 : 0; - return 0; -} - // AUTOTEST : test simple recovery of frame in noise void autotest_fskframesync() { @@ -60,12 +46,11 @@ void autotest_fskframesync() float gamma = powf(10.0f, (SNRdB+noise_floor)/20.0f); // channel gain unsigned int i; - int frames_recovered = 0; + unsigned int context = 0; // create objects fskframegen fg = fskframegen_create(); - fskframesync fs = fskframesync_create(callback_fskframesync_autotest, - (void*)&frames_recovered); + fskframesync fs = fskframesync_create(framing_autotest_callback, (void*)&context); // assemble the frame unsigned char header [ 8]; @@ -94,8 +79,8 @@ void autotest_fskframesync() fskframesync_execute_block(fs, buf_rx, buf_len); } - // check to see that exactly one frame was recovered - CONTEND_EQUALITY( frames_recovered, 1 ); + // check to see that callback was invoked + CONTEND_EQUALITY(context, FRAMING_AUTOTEST_SECRET); #if 0 // parse statistics diff --git a/src/framing/tests/gmskframe_autotest.c b/src/framing/tests/gmskframe_autotest.c index aacc80182..41d9db5c4 100644 --- a/src/framing/tests/gmskframe_autotest.c +++ b/src/framing/tests/gmskframe_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -26,26 +26,6 @@ #include "autotest/autotest.h" #include "liquid.h" -static int gmskframesync_autotest_callback( - unsigned char * _header, - int _header_valid, - unsigned char * _payload, - unsigned int _payload_len, - int _payload_valid, - framesyncstats_s _stats, - void * _userdata) -{ - // check data - unsigned int * secret = (unsigned int*) _userdata; - unsigned int i, num_errors = 0; - for (i=0; i<8; i++) - num_errors += _header[i] != i; - for (i=0; i<_payload_len; i++) - num_errors += _payload[i] != (i & 0xff); - *secret = num_errors == 0 ? 0x01234567 : 0; - return 0; -} - // test simple recovery of GMSK frame void autotest_gmskframesync_process() { @@ -54,14 +34,13 @@ void autotest_gmskframesync_process() crc_scheme crc = LIQUID_CRC_32; fec_scheme fec0 = LIQUID_FEC_NONE; fec_scheme fec1 = LIQUID_FEC_NONE; - unsigned int secret = 0; // placeholder for secret return value + unsigned int context = 0; // create objects gmskframegen fg = gmskframegen_create(); // create frame synchronizer - gmskframesync fs = gmskframesync_create( - gmskframesync_autotest_callback,(void*)&secret); + gmskframesync fs = gmskframesync_create(framing_autotest_callback, (void*)&context); if (liquid_autotest_verbose) { gmskframegen_print(fg); @@ -91,7 +70,7 @@ void autotest_gmskframesync_process() CONTEND_EQUALITY( gmskframesync_is_frame_open(fs), 0 ); // check to see that frame was recovered - CONTEND_EQUALITY( secret, 0x01234567 ); + CONTEND_EQUALITY( context, FRAMING_AUTOTEST_SECRET ); // parse statistics framedatastats_s stats = gmskframesync_get_framedatastats(fs); diff --git a/src/framing/tests/ofdmflexframe_autotest.c b/src/framing/tests/ofdmflexframe_autotest.c index 814ab0b29..ca243e437 100644 --- a/src/framing/tests/ofdmflexframe_autotest.c +++ b/src/framing/tests/ofdmflexframe_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -34,6 +34,7 @@ void testbench_ofdmflexframe(unsigned int _M, modulation_scheme _ms) { // create frame generator/synchronizer + unsigned int context = 0; ofdmflexframegenprops_s fgprops; ofdmflexframegenprops_init_default(&fgprops); fgprops.check = LIQUID_CRC_32; @@ -41,7 +42,8 @@ void testbench_ofdmflexframe(unsigned int _M, fgprops.fec1 = LIQUID_FEC_NONE; fgprops.mod_scheme = _ms; ofdmflexframegen fg = ofdmflexframegen_create( _M, _cp_len, _taper_len, NULL, &fgprops); - ofdmflexframesync fs = ofdmflexframesync_create(_M, _cp_len, _taper_len, NULL, NULL, NULL); + ofdmflexframesync fs = ofdmflexframesync_create(_M, _cp_len, _taper_len, NULL, + framing_autotest_callback, (void*)&context); // initialize header and payload unsigned char header[8] = {0, 1, 2, 3, 4, 5, 6, 7}; @@ -66,6 +68,9 @@ void testbench_ofdmflexframe(unsigned int _M, if (liquid_autotest_verbose) ofdmflexframesync_print(fs); + // verify callback was invoked + CONTEND_EQUALITY( context, FRAMING_AUTOTEST_SECRET ); + // verify frame data statistics framedatastats_s stats = ofdmflexframesync_get_framedatastats(fs); CONTEND_EQUALITY( stats.num_frames_detected, 1 ); From 52d5216a9c391b367d34eb0f3160d9639827c297 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 13 Apr 2024 09:45:41 -0400 Subject: [PATCH 42/97] build: adding example to simulate linear modem BER --- examples/modem_ber_example.c | 109 +++++++++++++++++++++++++++++++++++ makefile.in | 1 + 2 files changed, 110 insertions(+) create mode 100644 examples/modem_ber_example.c diff --git a/examples/modem_ber_example.c b/examples/modem_ber_example.c new file mode 100644 index 000000000..0ecd22cca --- /dev/null +++ b/examples/modem_ber_example.c @@ -0,0 +1,109 @@ +// This example runs a bit error rate simulation for a specified modulation +// scheme and saves the resulting data points to a file for plotting. +#include +#include +#include +#include +#include +#include "liquid.h" + +// print usage/help message +void usage() +{ + printf("modem_example [options]\n"); + printf(" -h : print help\n"); + printf(" -m : modulation scheme\n"); + liquid_print_modulation_schemes(); +} + +int main(int argc, char*argv[]) +{ + // simulation parameters + modulation_scheme ms = LIQUID_MODEM_QPSK; // modulation scheme + float SNRdB_min = -5.0f; // starting SNR value + float SNRdB_max = 40.0f; // maximum SNR value + float SNRdB_step = 1.0f; // step size + unsigned int num_trials = 1e6; // number of symbols + char filename[] = "modem_ber_example.m"; + + int dopt; + while ((dopt = getopt(argc,argv,"hm:")) != EOF) { + switch (dopt) { + case 'h': usage(); return 0; + case 'm': + ms = liquid_getopt_str2mod(optarg); + if (ms == LIQUID_MODEM_UNKNOWN) { + fprintf(stderr,"error: %s, unknown/unsupported modulation scheme '%s'\n", + argv[0], optarg); + return 1; + } + break; + default: + exit(1); + } + } + + // create modem objects + modem mod = modem_create(ms); // modulator + modem dem = modem_create(ms); // demodulator + + // compute derived values and initialize counters + unsigned int m = modem_get_bps(mod); // modulation bits/symbol + unsigned int M = 1 << m; // constellation size: 2^m + unsigned int i, sym_in, sym_out; + float complex sample; + + // iterate through SNR values + printf("# modulation scheme : %s\n", modulation_types[ms].name); + printf("# %8s %8s %8s %12s\n", "SNR [dB]", "errors", "trials", "BER"); + float SNRdB = SNRdB_min; // set SNR value + FILE * fid = fopen(filename,"w"); + fprintf(fid,"%% %s : auto-generated file\n", filename); + fprintf(fid,"clear all; close all; SNRdB=[]; BER=[]; ms='%s';\n", modulation_types[ms].name); + while (1) { + // compute noise standard deviation + float nstd = powf(10.0f, -SNRdB/20.0f); + + // reset modem objects (only necessary for differential schemes) + modem_reset(mod); + modem_reset(dem); + + // run trials + unsigned int num_bit_errors = 0; + for (i=0; i 0) + fprintf(fid,"SNRdB(end+1)=%12.3f; BER(end+1)=%12.4e;\n", SNRdB, ber); + + // stop iterating if SNR exceed maximum or no errors were detected + SNRdB += SNRdB_step; + if (SNRdB > SNRdB_max || num_bit_errors == 0) + break; + + } + fprintf(fid,"figure; semilogy(SNRdB,BER,'-x'); grid on; axis([SNRdB(1) SNRdB(end) 1e-6 1]);\n"); + fprintf(fid,"xlabel('SNR [dB]'); ylabel('BER'); title(ms)\n"); + fclose(fid); + printf("results written to %s\n", filename); + + // destroy modem objects and return + modem_destroy(mod); + modem_destroy(dem); + return 0; +} diff --git a/makefile.in b/makefile.in index 0d5e2205f..179869c1d 100644 --- a/makefile.in +++ b/makefile.in @@ -1602,6 +1602,7 @@ example_programs := \ examples/math_lngamma_example \ examples/math_primitive_root_example \ examples/modem_arb_example \ + examples/modem_ber_example \ examples/modem_example \ examples/modem_pi4dqpsk_example \ examples/modem_soft_example \ From 5441f01815dab92772104b76fd88d8f5fad4ab4d Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 13 Apr 2024 10:16:41 -0400 Subject: [PATCH 43/97] build: adding script to simulate GMSK modem performance --- examples/gmskmodem_ber_example.c | 114 +++++++++++++++++++++++++++++++ makefile.in | 1 + 2 files changed, 115 insertions(+) create mode 100644 examples/gmskmodem_ber_example.c diff --git a/examples/gmskmodem_ber_example.c b/examples/gmskmodem_ber_example.c new file mode 100644 index 000000000..f781fcd3e --- /dev/null +++ b/examples/gmskmodem_ber_example.c @@ -0,0 +1,114 @@ +// This example runs a bit error rate simulation for GMSK modulation. +#include +#include +#include +#include +#include +#include "liquid.h" + +// print usage/help message +void usage() +{ + printf("modem_example [options]\n"); + printf(" -h : print help\n"); +} + +int main(int argc, char*argv[]) +{ + // simulation parameters + unsigned int k = 4; // filter samples/symbol + unsigned int m = 3; // filter delay (symbols) + float BT = 0.3f; // bandwidth-time product + float SNRdB_min = -5.0f; // starting SNR value + float SNRdB_max = 15.0f; // maximum SNR value + float SNRdB_step = 1.0f; // step size + unsigned int num_trials = 1e6; // number of symbols + char filename[] = "gmskmodem_ber_example.m"; + + int dopt; + while ((dopt = getopt(argc,argv,"h")) != EOF) { + switch (dopt) { + case 'h': usage(); return 0; + default: + exit(1); + } + } + + // create modem objects + gmskmod mod = gmskmod_create(k, m, BT); // modulator + gmskdem dem = gmskdem_create(k, m, BT); // demodulator + + // derived values and buffers + unsigned int delay = 2*m; + unsigned int symbol_buffer[delay]; // delay between tx/rx + unsigned int symbol_index = 0; + float complex buf[k]; // sample buffer + unsigned int i, j, sym_in, sym_out, sym_buf; + + // iterate through SNR values + printf("# GMSK, k=%u, m=%u, BT=%.3f\n", k, m, BT); + printf("# %8s %8s %8s %12s %12s\n", "SNR [dB]", "errors", "trials", "BER", "theory"); + float SNRdB = SNRdB_min; // set SNR value + FILE * fid = fopen(filename,"w"); + fprintf(fid,"%% %s : auto-generated file\n", filename); + fprintf(fid,"clear all; close all; SNRdB=[]; BER=[]; theory=[];\n"); + while (1) + { + // compute noise standard deviation, compensating for over-sampling + float nstd = powf(10.0f, -SNRdB/20.0f) * sqrtf((float)k); + + // reset modem objects (only necessary for differential schemes) + gmskmod_reset(mod); + gmskdem_reset(dem); + + // run trials + unsigned int num_bit_errors = 0; + for (i=0; i delay) + num_bit_errors += count_bit_errors(sym_buf, sym_out); + } + + // compute results and print formatted results to screen + unsigned int num_bit_trials = m * num_trials; + float ber = (float)num_bit_errors / (float)(num_bit_trials); + float gamma = powf(10.0f, SNRdB/10.0f); + float theory = liquid_Qf(sqrtf(2*gamma)); + printf(" %8.2f %8u %8u %12.4e %12.4e\n", SNRdB, num_bit_errors, num_bit_trials, ber, theory); + + if (num_bit_errors > 0) { + fprintf(fid,"SNRdB(end+1)=%12.3f; BER(end+1)=%12.4e; theory(end+1)=%12.4e;\n", + SNRdB, ber, theory); + } + + // stop iterating if SNR exceed maximum or no errors were detected + SNRdB += SNRdB_step; + if (SNRdB > SNRdB_max) + break; + } + fprintf(fid,"figure; semilogy(SNRdB,BER,'-x',SNRdB,theory,'-x');grid on;\n"); + fprintf(fid,"axis([-5 15 1e-6 1]);xlabel('SNR [dB]'); ylabel('BER'); legend('sim','theory');\n"); + fclose(fid); + printf("results written to %s\n", filename); + + // destroy modem objects and return + gmskmod_destroy(mod); + gmskdem_destroy(dem); + return 0; +} diff --git a/makefile.in b/makefile.in index 179869c1d..0d9cf1a3c 100644 --- a/makefile.in +++ b/makefile.in @@ -1576,6 +1576,7 @@ example_programs := \ examples/gasearch_knapsack_example \ examples/gmskframesync_example \ examples/gmskmodem_example \ + examples/gmskmodem_ber_example \ examples/gmsk_eqlms_example \ examples/gmsk_tracking_example \ examples/gradsearch_datafit_example \ From e69f26540ef4dee7eb83488d34492af7a06fa551 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 13 Apr 2024 14:08:20 -0400 Subject: [PATCH 44/97] cpfskmodem: adjusting debugging and print statements --- examples/cpfskmodem_example.c | 1 + src/modem/src/cpfskdem.c | 33 +++++++++++++++++++++------------ src/modem/src/cpfskmod.c | 29 ++++++++--------------------- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/examples/cpfskmodem_example.c b/examples/cpfskmodem_example.c index b5fdcb1bf..23670993f 100644 --- a/examples/cpfskmodem_example.c +++ b/examples/cpfskmodem_example.c @@ -92,6 +92,7 @@ int main(int argc, char*argv[]) // print modulator cpfskmod_print(mod); + cpfskdem_print(mod); // get full symbol delay unsigned int delay = cpfskmod_get_delay(mod) + cpfskdem_get_delay(dem); diff --git a/src/modem/src/cpfskdem.c b/src/modem/src/cpfskdem.c index 7b04ab130..ed23c9a3a 100644 --- a/src/modem/src/cpfskdem.c +++ b/src/modem/src/cpfskdem.c @@ -20,9 +20,7 @@ * THE SOFTWARE. */ -// // continuous phase frequency-shift keying demodulator -// #include #include @@ -32,10 +30,6 @@ #define DEBUG_CPFSKDEM 0 -// -// internal methods -// - // initialize coherent demodulator int cpfskdem_init_coherent(cpfskdem _q); @@ -171,7 +165,9 @@ cpfskdem cpfskdem_create(unsigned int _bps, // reset modem object cpfskdem_reset(q); - +#if DEBUG_CPFSKDEM + printf("clear all; close all; y=[]; z=[];\n"); +#endif return q; } @@ -259,6 +255,11 @@ int cpfskdem_init_noncoherent(cpfskdem _q) // destroy modem object int cpfskdem_destroy(cpfskdem _q) { +#if DEBUG_CPFSKDEM + printf("figure('position',[100 100 400 400]);\n"); + printf("n=length(z); i=1:%u:n; plot(z,'-',z(i),'o');\n", _q->k); + printf("axis square; axis([-1 1 -1 1]*1.5); grid on;\n"); +#endif switch(_q->demod_type) { case CPFSKDEM_COHERENT: firfilt_crcf_destroy(_q->data.coherent.mf); @@ -275,8 +276,16 @@ int cpfskdem_destroy(cpfskdem _q) // print modulation internals int cpfskdem_print(cpfskdem _q) { - printf("cpfskdem:\n"); - printf(" k : %u\n", _q->k); + printf("bps, _q->h, _q->k, _q->m, _q->beta); + switch(_q->type) { + case LIQUID_CPFSK_SQUARE: printf(", type=\"square\""); break; + case LIQUID_CPFSK_RCOS_FULL: printf(", type=\"rcos-full\""); break; + case LIQUID_CPFSK_RCOS_PARTIAL: printf(", type=\"rcos-partial\""); break; + case LIQUID_CPFSK_GMSK: printf(", type=\"gmsk\""); break; + default:; + } + printf(">\n"); return LIQUID_OK; } @@ -424,8 +433,8 @@ unsigned int cpfskdem_demodulate_coherent(cpfskdem _q, // compute output sample float complex zp; firfilt_crcf_execute(_q->data.coherent.mf, &zp); - printf("y(end+1) = %12.8f + 1i*%12.8f;\n", crealf(_y), cimagf(_y)); - printf("z(end+1) = %12.8f + 1i*%12.8f;\n", crealf(zp), cimagf(zp)); + printf("y(end+1) = %12.8f + %12.8fj;\n", crealf(_y[i]), cimagf(_y[i])); + printf("z(end+1) = %12.8f + %12.8fj;\n", crealf( zp), cimagf( zp)); #endif // decimate output @@ -447,7 +456,7 @@ unsigned int cpfskdem_demodulate_coherent(cpfskdem _q, #if DEBUG_CPFSKDEM // print result to screen - printf(" %3u : %12.8f + j%12.8f, (%1u)\n", + printf("%% %3u : %12.8f + j%12.8f, (%1u)\n", _q->index++, crealf(z), cimagf(z), phi_hat, v, sym_out); #endif } diff --git a/src/modem/src/cpfskmod.c b/src/modem/src/cpfskmod.c index c8c5b415b..84220c902 100644 --- a/src/modem/src/cpfskmod.c +++ b/src/modem/src/cpfskmod.c @@ -28,10 +28,6 @@ #include "liquid.internal.h" -// -// internal methods -// - // design transmit filter int cpfskmod_firdes(unsigned int _k, unsigned int _m, @@ -166,25 +162,16 @@ int cpfskmod_destroy(cpfskmod _q) // print cpfskmod object internals int cpfskmod_print(cpfskmod _q) { - printf("cpfskmod : continuous-phase frequency-shift keying modem\n"); - printf(" bits/symbol : %u\n", _q->bps); - printf(" modulation index: %-6.3f\n", _q->h); - printf(" samples/symbol : %u\n", _q->k); - printf(" filter delay : %u symbols\n", _q->m); - printf(" filter roll-off : %-6.3f\n", _q->beta); - printf(" filter type : "); + printf("bps, _q->h, _q->k, _q->m, _q->beta); switch(_q->type) { - case LIQUID_CPFSK_SQUARE: printf("square\n"); break; - case LIQUID_CPFSK_RCOS_FULL: printf("rcos (full)\n"); break; - case LIQUID_CPFSK_RCOS_PARTIAL: printf("rcos (partial)\n"); break; - case LIQUID_CPFSK_GMSK: printf("gmsk\n"); break; - default: printf("unknown\n"); break; + case LIQUID_CPFSK_SQUARE: printf(", type=\"square\""); break; + case LIQUID_CPFSK_RCOS_FULL: printf(", type=\"rcos-full\""); break; + case LIQUID_CPFSK_RCOS_PARTIAL: printf(", type=\"rcos-partial\""); break; + case LIQUID_CPFSK_GMSK: printf(", type=\"gmsk\""); break; + default:; } - printf(" filter :\n"); - // print filter coefficients - unsigned int i; - for (i=0; i<_q->ht_len; i++) - printf(" h(%3u) = %12.8f;\n", i+1, _q->ht[i]); + printf(">\n"); return LIQUID_OK; } From 2bf4197dae1c0faf9e62180511d786bf80642147 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 13 Apr 2024 15:12:56 -0400 Subject: [PATCH 45/97] cpfskmod: moving definition to macro --- include/liquid.h | 84 ++++++++++--------- makefile.in | 2 +- .../src/{cpfskmod.c => cpfskmod.proto.c} | 56 ++++++------- src/modem/src/modemcf.c | 6 +- 4 files changed, 80 insertions(+), 68 deletions(-) rename src/modem/src/{cpfskmod.c => cpfskmod.proto.c} (87%) diff --git a/include/liquid.h b/include/liquid.h index 3e9fc288c..118129e83 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -8315,45 +8315,53 @@ typedef enum { LIQUID_CPFSK_GMSK, // Gauss minimum-shift keying pulse } liquid_cpfsk_filter; -// CP-FSK modulator -typedef struct cpfskmod_s * cpfskmod; - -// create cpfskmod object (frequency modulator) -// _bps : bits per symbol, _bps > 0 -// _h : modulation index, _h > 0 -// _k : samples/symbol, _k > 1, _k even -// _m : filter delay (symbols), _m > 0 -// _beta : filter bandwidth parameter, _beta > 0 -// _type : filter type (e.g. LIQUID_CPFSK_SQUARE) -cpfskmod cpfskmod_create(unsigned int _bps, - float _h, - unsigned int _k, - unsigned int _m, - float _beta, - int _type); -//cpfskmod cpfskmod_create_msk(unsigned int _k); -//cpfskmod cpfskmod_create_gmsk(unsigned int _k, float _BT); - -// destroy cpfskmod object -int cpfskmod_destroy(cpfskmod _q); - -// print cpfskmod object internals -int cpfskmod_print(cpfskmod _q); - -// reset state -int cpfskmod_reset(cpfskmod _q); - -// get transmit delay [symbols] -unsigned int cpfskmod_get_delay(cpfskmod _q); - -// modulate sample -// _q : frequency modulator object -// _s : input symbol -// _y : output sample array, [size: _k x 1] -int cpfskmod_modulate(cpfskmod _q, - unsigned int _s, - liquid_float_complex * _y); +// TODO: rename to cpfskmodcf for consistency +#define LIQUID_CPFSKMOD_MANGLE_FLOAT(name) LIQUID_CONCAT(cpfskmod,name) + +#define LIQUID_CPFSKMOD_DEFINE_API(CPFSKMOD,T,TC) \ + \ +/* Continuous-Phase Frequency-Shift Keying Modulator */ \ +typedef struct CPFSKMOD(_s) * CPFSKMOD(); \ + \ +/* create cpfskmod object (frequency modulator) */ \ +/* _bps : bits per symbol, _bps > 0 */ \ +/* _h : modulation index, _h > 0 */ \ +/* _k : samples/symbol, _k > 1, _k even */ \ +/* _m : filter delay (symbols), _m > 0 */ \ +/* _beta : filter bandwidth parameter, _beta > 0 */ \ +/* _type : filter type (e.g. LIQUID_CPFSK_SQUARE) */ \ +CPFSKMOD() CPFSKMOD(_create)(unsigned int _bps, \ + float _h, \ + unsigned int _k, \ + unsigned int _m, \ + float _beta, \ + int _type); \ + \ +/* cpfskmod cpfskmod_create_msk(unsigned int _k); */ \ +/* cpfskmod cpfskmod_create_gmsk(unsigned int _k, float _BT); */ \ + \ +/* destroy cpfskmod object */ \ +int CPFSKMOD(_destroy)(CPFSKMOD() _q); \ + \ +/* print cpfskmod object internals */ \ +int CPFSKMOD(_print)(CPFSKMOD() _q); \ + \ +/* reset state */ \ +int CPFSKMOD(_reset)(CPFSKMOD() _q); \ + \ +/* get transmit delay [symbols] */ \ +unsigned int CPFSKMOD(_get_delay)(CPFSKMOD() _q); \ + \ +/* modulate sample */ \ +/* _q : frequency modulator object */ \ +/* _s : input symbol */ \ +/* _y : output sample array, [size: _k x 1] */ \ +int CPFSKMOD(_modulate)(CPFSKMOD() _q, \ + unsigned int _s, \ + TC * _y); \ +// define cpfskmod APIs +LIQUID_CPFSKMOD_DEFINE_API(LIQUID_CPFSKMOD_MANGLE_FLOAT,float,liquid_float_complex) // CP-FSK demodulator diff --git a/makefile.in b/makefile.in index 0d9cf1a3c..54b4fa7c0 100644 --- a/makefile.in +++ b/makefile.in @@ -849,7 +849,6 @@ matrix_benchmarks := \ modem_objects := \ src/modem/src/ampmodem.o \ src/modem/src/cpfskdem.o \ - src/modem/src/cpfskmod.o \ src/modem/src/fskdem.o \ src/modem/src/fskmod.o \ src/modem/src/gmskdem.o \ @@ -862,6 +861,7 @@ modem_objects := \ # explicit targets and dependencies modem_prototypes := \ + src/modem/src/cpfskmod.proto.c \ src/modem/src/freqdem.proto.c \ src/modem/src/freqmod.proto.c \ src/modem/src/modem_common.proto.c \ diff --git a/src/modem/src/cpfskmod.c b/src/modem/src/cpfskmod.proto.c similarity index 87% rename from src/modem/src/cpfskmod.c rename to src/modem/src/cpfskmod.proto.c index 84220c902..56dede005 100644 --- a/src/modem/src/cpfskmod.c +++ b/src/modem/src/cpfskmod.proto.c @@ -29,15 +29,15 @@ #include "liquid.internal.h" // design transmit filter -int cpfskmod_firdes(unsigned int _k, - unsigned int _m, - float _beta, - int _type, - float * _h, - unsigned int _h_len); +int CPFSKMOD(_firdes)(unsigned int _k, + unsigned int _m, + float _beta, + int _type, + float * _h, + unsigned int _h_len); // cpfskmod -struct cpfskmod_s { +struct CPFSKMOD(_s) { // common unsigned int bps; // bits per symbol unsigned int k; // samples per symbol @@ -58,19 +58,19 @@ struct cpfskmod_s { float b0, b1, a1, v0, v1; // integrator }; -// create cpfskmod object (frequency modulator) +// create CPFSKMOD() object (frequency modulator) // _bps : bits per symbol, _bps > 0 // _h : modulation index, _h > 0 // _k : samples/symbol, _k > 1, _k even // _m : filter delay (symbols), _m > 0 // _beta : filter bandwidth parameter, _beta > 0 // _type : filter type (e.g. LIQUID_CPFSK_SQUARE) -cpfskmod cpfskmod_create(unsigned int _bps, - float _h, - unsigned int _k, - unsigned int _m, - float _beta, - int _type) +CPFSKMOD() CPFSKMOD(_create)(unsigned int _bps, + float _h, + unsigned int _k, + unsigned int _m, + float _beta, + int _type) { // validate input if (_bps == 0) @@ -85,7 +85,7 @@ cpfskmod cpfskmod_create(unsigned int _bps, return liquid_error_config("cpfskmod_create(), filter roll-off must be in (0,1]"); // create main object memory - cpfskmod q = (cpfskmod) malloc(sizeof(struct cpfskmod_s)); + CPFSKMOD() q = (CPFSKMOD()) malloc(sizeof(struct CPFSKMOD(_s))); // set basic internal properties q->bps = _bps; // bits per symbol @@ -146,8 +146,8 @@ cpfskmod cpfskmod_create(unsigned int _bps, return q; } -// destroy cpfskmod object -int cpfskmod_destroy(cpfskmod _q) +// destroy CPFSKMOD() object +int CPFSKMOD(_destroy)(CPFSKMOD() _q) { // destroy pulse-shaping filter/interpolator free(_q->ht); @@ -159,8 +159,8 @@ int cpfskmod_destroy(cpfskmod _q) return LIQUID_OK; } -// print cpfskmod object internals -int cpfskmod_print(cpfskmod _q) +// print CPFSKMOD() object internals +int CPFSKMOD(_print)(CPFSKMOD() _q) { printf("bps, _q->h, _q->k, _q->m, _q->beta); @@ -176,7 +176,7 @@ int cpfskmod_print(cpfskmod _q) } // reset state -int cpfskmod_reset(cpfskmod _q) +int CPFSKMOD(_reset)(CPFSKMOD() _q) { // reset interpolator firinterp_rrrf_reset(_q->interp); @@ -188,7 +188,7 @@ int cpfskmod_reset(cpfskmod _q) } // get transmit delay [symbols] -unsigned int cpfskmod_get_delay(cpfskmod _q) +unsigned int CPFSKMOD(_get_delay)(CPFSKMOD() _q) { return _q->symbol_delay; } @@ -197,7 +197,7 @@ unsigned int cpfskmod_get_delay(cpfskmod _q) // _q : frequency modulator object // _s : input symbol // _y : output sample array [size: _k x 1] -int cpfskmod_modulate(cpfskmod _q, +int CPFSKMOD(_modulate)(CPFSKMOD() _q, unsigned int _s, float complex * _y) { @@ -231,12 +231,12 @@ int cpfskmod_modulate(cpfskmod _q, // // design transmit filter -int cpfskmod_firdes(unsigned int _k, - unsigned int _m, - float _beta, - int _type, - float * _ht, - unsigned int _ht_len) +int CPFSKMOD(_firdes)(unsigned int _k, + unsigned int _m, + float _beta, + int _type, + float * _ht, + unsigned int _ht_len) { unsigned int i; // create filter based on specified type diff --git a/src/modem/src/modemcf.c b/src/modem/src/modemcf.c index f8b94686c..2d001f4c4 100644 --- a/src/modem/src/modemcf.c +++ b/src/modem/src/modemcf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -27,6 +27,7 @@ #include "liquid.internal.h" // Macro definitions +#define CPFSKMOD(name) LIQUID_CONCAT(cpfskmod,name) #define MODEM(name) LIQUID_CONCAT(modemcf,name) #define FREQMOD(name) LIQUID_CONCAT(freqmod,name) #define FREQDEM(name) LIQUID_CONCAT(freqdem,name) @@ -61,6 +62,9 @@ // arbitrary modems #include "modem_arb.proto.c" +// non-linear modems +#include "cpfskmod.proto.c" + // analog modems #include "freqmod.proto.c" #include "freqdem.proto.c" From b36c7ad9ca778ca498230c2cd8389dbfa1a37d45 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 13 Apr 2024 15:39:06 -0400 Subject: [PATCH 46/97] cpfskdem: moving definition to macro --- include/liquid.h | 94 +++++++------- makefile.in | 2 +- .../src/{cpfskdem.c => cpfskdem.proto.c} | 118 ++++++++---------- src/modem/src/modemcf.c | 2 + 4 files changed, 97 insertions(+), 119 deletions(-) rename src/modem/src/{cpfskdem.c => cpfskdem.proto.c} (80%) diff --git a/include/liquid.h b/include/liquid.h index 118129e83..45eb232eb 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -8364,58 +8364,54 @@ int CPFSKMOD(_modulate)(CPFSKMOD() _q, \ LIQUID_CPFSKMOD_DEFINE_API(LIQUID_CPFSKMOD_MANGLE_FLOAT,float,liquid_float_complex) -// CP-FSK demodulator -typedef struct cpfskdem_s * cpfskdem; - -// create cpfskdem object (frequency modulator) -// _bps : bits per symbol, _bps > 0 -// _h : modulation index, _h > 0 -// _k : samples/symbol, _k > 1, _k even -// _m : filter delay (symbols), _m > 0 -// _beta : filter bandwidth parameter, _beta > 0 -// _type : filter type (e.g. LIQUID_CPFSK_SQUARE) -cpfskdem cpfskdem_create(unsigned int _bps, - float _h, - unsigned int _k, - unsigned int _m, - float _beta, - int _type); -//cpfskdem cpfskdem_create_msk(unsigned int _k); -//cpfskdem cpfskdem_create_gmsk(unsigned int _k, float _BT); - -// destroy cpfskdem object -int cpfskdem_destroy(cpfskdem _q); - -// print cpfskdem object internals -int cpfskdem_print(cpfskdem _q); -// reset state -int cpfskdem_reset(cpfskdem _q); - -// get receive delay [symbols] -unsigned int cpfskdem_get_delay(cpfskdem _q); - -#if 0 -// demodulate array of samples -// _q : continuous-phase frequency demodulator object -// _y : input sample array, [size: _n x 1] -// _n : input sample array length -// _s : output symbol array -// _nw : number of output symbols written -int cpfskdem_demodulate(cpfskdem _q, - liquid_float_complex * _y, - unsigned int _n, - unsigned int * _s, - unsigned int * _nw); -#else -// demodulate array of samples, assuming perfect timing -// _q : continuous-phase frequency demodulator object -// _y : input sample array, [size: _k x 1] -unsigned int cpfskdem_demodulate(cpfskdem _q, - liquid_float_complex * _y); -#endif +// TODO: rename to cpfskdemcf for consistency +#define LIQUID_CPFSKDEM_MANGLE_FLOAT(name) LIQUID_CONCAT(cpfskdem,name) +#define LIQUID_CPFSKDEM_DEFINE_API(CPFSKDEM,T,TC) \ + \ +/* Continuous-Phase Frequency-Shift Keying Demodulator */ \ +typedef struct CPFSKDEM(_s) * CPFSKDEM(); \ + \ +/* create demodulator object */ \ +/* _bps : bits per symbol, _bps > 0 */ \ +/* _h : modulation index, _h > 0 */ \ +/* _k : samples/symbol, _k > 1, _k even */ \ +/* _m : filter delay (symbols), _m > 0 */ \ +/* _beta : filter bandwidth parameter, _beta > 0 */ \ +/* _type : filter type (e.g. LIQUID_CPFSK_SQUARE) */ \ +CPFSKDEM() CPFSKDEM(_create)(unsigned int _bps, \ + float _h, \ + unsigned int _k, \ + unsigned int _m, \ + float _beta, \ + int _type); \ + \ +/* CPFSKDEM() CPFSKDEM(_create_msk)(unsigned int _k); */ \ +/* CPFSKDEM() CPFSKDEM(_create_gmsk)(unsigned int _k, float _BT); */ \ + \ +/* Destroy demodulator object, freeing all internal memory */ \ +int CPFSKDEM(_destroy)(CPFSKDEM() _q); \ + \ +/* Print demodulator object internals */ \ +int CPFSKDEM(_print)(CPFSKDEM() _q); \ + \ +/* Reset state */ \ +int CPFSKDEM(_reset)(CPFSKDEM() _q); \ + \ +/* get receive delay [symbols] */ \ +unsigned int CPFSKDEM(_get_delay)(CPFSKDEM() _q); \ + \ +/* demodulate array of samples, assuming perfect timing */ \ +/* _q : continuous-phase frequency demodulator object */ \ +/* _y : input sample array, [size: _k x 1] */ \ +unsigned int CPFSKDEM(_demodulate)(CPFSKDEM() _q, \ + TC * _y); \ + \ +/* demodulate_block */ \ +// define cpfskmod APIs +LIQUID_CPFSKDEM_DEFINE_API(LIQUID_CPFSKDEM_MANGLE_FLOAT,float,liquid_float_complex) // // M-ary frequency-shift keying (MFSK) modems diff --git a/makefile.in b/makefile.in index 54b4fa7c0..ee7e2f7c1 100644 --- a/makefile.in +++ b/makefile.in @@ -848,7 +848,6 @@ matrix_benchmarks := \ modem_objects := \ src/modem/src/ampmodem.o \ - src/modem/src/cpfskdem.o \ src/modem/src/fskdem.o \ src/modem/src/fskmod.o \ src/modem/src/gmskdem.o \ @@ -861,6 +860,7 @@ modem_objects := \ # explicit targets and dependencies modem_prototypes := \ + src/modem/src/cpfskdem.proto.c \ src/modem/src/cpfskmod.proto.c \ src/modem/src/freqdem.proto.c \ src/modem/src/freqmod.proto.c \ diff --git a/src/modem/src/cpfskdem.c b/src/modem/src/cpfskdem.proto.c similarity index 80% rename from src/modem/src/cpfskdem.c rename to src/modem/src/cpfskdem.proto.c index ed23c9a3a..d641272e3 100644 --- a/src/modem/src/cpfskdem.c +++ b/src/modem/src/cpfskdem.proto.c @@ -28,38 +28,22 @@ #include "liquid.internal.h" -#define DEBUG_CPFSKDEM 0 +#define DEBUG_CPFSKDEM() 0 // initialize coherent demodulator -int cpfskdem_init_coherent(cpfskdem _q); +int CPFSKDEM(_init_coherent)(CPFSKDEM() _q); // initialize non-coherent demodulator -int cpfskdem_init_noncoherent(cpfskdem _q); +int CPFSKDEM(_init_noncoherent)(CPFSKDEM() _q); -#if 0 -// demodulate array of samples (coherent) -int cpfskdem_demodulate_coherent(cpfskdem _q, - float complex _y, - unsigned int * _s, - unsigned int * _nw); - -// demodulate array of samples (non-coherent) -int cpfskdem_demodulate_noncoherent(cpfskdem _q, - float complex _y, - unsigned int * _s, - unsigned int * _nw); -#else // demodulate array of samples (coherent) -unsigned int cpfskdem_demodulate_coherent(cpfskdem _q, - float complex * _y); +unsigned int CPFSKDEM(_demodulate_coherent)(CPFSKDEM() _q, TC * _y); // demodulate array of samples (non-coherent) -unsigned int cpfskdem_demodulate_noncoherent(cpfskdem _q, - float complex * _y); -#endif +unsigned int CPFSKDEM(_demodulate_noncoherent)(CPFSKDEM() _q, TC * _y); // cpfskdem -struct cpfskdem_s { +struct CPFSKDEM(_s) { // common unsigned int bps; // bits per symbol unsigned int k; // samples per symbol @@ -78,13 +62,12 @@ struct cpfskdem_s { // demodulation function pointer #if 0 - void (*demodulate)(cpfskdem _q, - float complex _y, - unsigned int * _s, - unsigned int * _nw); + void (*demodulate)(CPFSKDEM() _q, + TC _y, + unsigned int * _s, + unsigned int * _nw); #else - unsigned int (*demodulate)(cpfskdem _q, - float complex * _y); + unsigned int (*demodulate)(CPFSKDEM() _q, TC * _y); #endif // common data structure shared between coherent and non-coherent @@ -92,12 +75,9 @@ struct cpfskdem_s { union { // coherent demodulator struct { - /* - nco_crcf nco; // oscillator/phase-locked loop - firpfb_crcf mf; // matched filter - firpfb_crcf dmf; // matched filter (derivative) - */ - + //nco_crcf nco; // oscillator/phase-locked loop + //firpfb_crcf mf; // matched filter + //firpfb_crcf dmf; // matched filter (derivative) firfilt_crcf mf; // matched filter } coherent; @@ -115,19 +95,19 @@ struct cpfskdem_s { float complex z_prime; // (coherent only) }; -// create cpfskdem object (frequency demodulator) +// create CPFSKDEM() object (frequency demodulator) // _bps : bits per symbol, _bps > 0 // _h : modulation index, _h > 0 // _k : samples/symbol, _k > 1, _k even // _m : filter delay (symbols), _m > 0 // _beta : filter bandwidth parameter, _beta > 0 // _type : filter type (e.g. LIQUID_CPFSK_SQUARE) -cpfskdem cpfskdem_create(unsigned int _bps, - float _h, - unsigned int _k, - unsigned int _m, - float _beta, - int _type) +CPFSKDEM() CPFSKDEM(_create)(unsigned int _bps, + float _h, + unsigned int _k, + unsigned int _m, + float _beta, + int _type) { // validate input if (_bps == 0) @@ -135,14 +115,14 @@ cpfskdem cpfskdem_create(unsigned int _bps, if (_h <= 0.0f) return liquid_error_config("cpfskdem_create(), modulation index must be greater than 0"); if (_k < 2 || (_k%2)) - return liquid_error_config("cpfskmod_create(), samples/symbol must be greater than 2 and even"); + return liquid_error_config("cpfskdem_create(), samples/symbol must be greater than 2 and even"); if (_m == 0) return liquid_error_config("cpfskdem_create(), filter delay must be greater than 0"); if (_beta <= 0.0f || _beta > 1.0f) return liquid_error_config("cpfskdem_create(), filter roll-off must be in (0,1]"); // create main object memory - cpfskdem q = (cpfskdem) malloc(sizeof(struct cpfskdem_s)); + CPFSKDEM() q = (cpfskdem) malloc(sizeof(struct CPFSKDEM(_s))); // set basic internal properties q->bps = _bps; // bits per symbol @@ -161,10 +141,10 @@ cpfskdem cpfskdem_create(unsigned int _bps, //cpfskdem_init_noncoherent(q); fprintf(stderr,"warning: cpfskdem_create(), coherent demodulation with h > 2/3 not recommended\n"); } - cpfskdem_init_coherent(q); + CPFSKDEM(_init_coherent)(q); // reset modem object - cpfskdem_reset(q); + CPFSKDEM(_reset)(q); #if DEBUG_CPFSKDEM printf("clear all; close all; y=[]; z=[];\n"); #endif @@ -172,7 +152,7 @@ cpfskdem cpfskdem_create(unsigned int _bps, } // initialize coherent demodulator -int cpfskdem_init_coherent(cpfskdem _q) +int CPFSKDEM(_init_coherent)(CPFSKDEM() _q) { // specify coherent receiver _q->demod_type = CPFSKDEM_COHERENT; @@ -229,12 +209,12 @@ int cpfskdem_init_coherent(cpfskdem _q) } // initialize non-coherent demodulator -int cpfskdem_init_noncoherent(cpfskdem _q) +int CPFSKDEM(_init_noncoherent)(CPFSKDEM() _q) { #if 0 // specify non-coherent receiver _q->demod_type = CPFSKDEM_NONCOHERENT; - + // set demodulate function pointer _q->demodulate = cpfskdem_demodulate_noncoherent; @@ -253,7 +233,7 @@ int cpfskdem_init_noncoherent(cpfskdem _q) } // destroy modem object -int cpfskdem_destroy(cpfskdem _q) +int CPFSKDEM(_destroy)(CPFSKDEM() _q) { #if DEBUG_CPFSKDEM printf("figure('position',[100 100 400 400]);\n"); @@ -274,7 +254,7 @@ int cpfskdem_destroy(cpfskdem _q) } // print modulation internals -int cpfskdem_print(cpfskdem _q) +int CPFSKDEM(_print)(CPFSKDEM() _q) { printf("bps, _q->h, _q->k, _q->m, _q->beta); @@ -290,7 +270,7 @@ int cpfskdem_print(cpfskdem _q) } // reset modem object -int cpfskdem_reset(cpfskdem _q) +int CPFSKDEM(_reset)(CPFSKDEM() _q) { switch(_q->demod_type) { case CPFSKDEM_COHERENT: @@ -309,7 +289,7 @@ int cpfskdem_reset(cpfskdem _q) } // get transmit delay [symbols] -unsigned int cpfskdem_get_delay(cpfskdem _q) +unsigned int CPFSKDEM(_get_delay)(CPFSKDEM() _q) { return _q->symbol_delay; } @@ -321,11 +301,11 @@ unsigned int cpfskdem_get_delay(cpfskdem _q) // _n : input sample array length // _s : output symbol array // _nw : number of output symbols written -int cpfskdem_demodulate(cpfskdem _q, - float complex * _y, - unsigned int _n, - unsigned int * _s, - unsigned int * _nw) +int CPFSKDEM(_demodulate)(CPFSKDEM() _q, + TC * _y, + unsigned int _n, + unsigned int * _s, + unsigned int * _nw) { // iterate through each sample calling type-specific demodulation function unsigned int i; @@ -344,10 +324,10 @@ int cpfskdem_demodulate(cpfskdem _q, } // demodulate array of samples (coherent) -int cpfskdem_demodulate_coherent(cpfskdem _q, - float complex _y, - unsigned int * _s, - unsigned int * _nw) +int CPFSKDEM(_demodulate_coherent)(CPFSKDEM() _q, + TC _y, + unsigned int * _s, + unsigned int * _nw) { // clear output counter *_nw = 0; @@ -368,7 +348,7 @@ int cpfskdem_demodulate_coherent(cpfskdem _q, if ( (_q->counter % _q->k)==0 ) { // reset sample counter _q->counter = 0; - + // compute output sample float complex z; firfilt_crcf_execute(_q->data.coherent.mf, &z); @@ -398,7 +378,7 @@ int cpfskdem_demodulate_coherent(cpfskdem _q, } // demodulate array of samples (non-coherent) -int cpfskdem_demodulate_noncoherent(cpfskdem _q, +int CPFSKDEM(_demodulate_noncoherent)(CPFSKDEM() _q, float complex _y, unsigned int * _s, unsigned int * _nw) @@ -412,15 +392,15 @@ int cpfskdem_demodulate_noncoherent(cpfskdem _q, // demodulate array of samples // _q : continuous-phase frequency demodulator object // _y : input sample array [size: _k x 1] -unsigned int cpfskdem_demodulate(cpfskdem _q, - float complex * _y) +unsigned int CPFSKDEM(_demodulate)(CPFSKDEM() _q, + TC * _y) { return _q->demodulate(_q, _y); } // demodulate array of samples (coherent) -unsigned int cpfskdem_demodulate_coherent(cpfskdem _q, - float complex * _y) +unsigned int CPFSKDEM(_demodulate_coherent)(CPFSKDEM() _q, + TC * _y) { unsigned int i; unsigned int sym_out = 0; @@ -465,8 +445,8 @@ unsigned int cpfskdem_demodulate_coherent(cpfskdem _q, } // demodulate array of samples (non-coherent) -unsigned int cpfskdem_demodulate_noncoherent(cpfskdem _q, - float complex * _y) +unsigned int CPFSKDEM(_demodulate_noncoherent)(CPFSKDEM() _q, + TC * _y) { return 0; } diff --git a/src/modem/src/modemcf.c b/src/modem/src/modemcf.c index 2d001f4c4..e83b0aef0 100644 --- a/src/modem/src/modemcf.c +++ b/src/modem/src/modemcf.c @@ -27,6 +27,7 @@ #include "liquid.internal.h" // Macro definitions +#define CPFSKDEM(name) LIQUID_CONCAT(cpfskdem,name) #define CPFSKMOD(name) LIQUID_CONCAT(cpfskmod,name) #define MODEM(name) LIQUID_CONCAT(modemcf,name) #define FREQMOD(name) LIQUID_CONCAT(freqmod,name) @@ -63,6 +64,7 @@ #include "modem_arb.proto.c" // non-linear modems +#include "cpfskdem.proto.c" #include "cpfskmod.proto.c" // analog modems From 893eb9bff87b60c35ebd38b716f0ab4114963f20 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 13 Apr 2024 15:51:43 -0400 Subject: [PATCH 47/97] cpfskdem: flipping coherent and noncoherent methods * techincally the current (default) behoavior is not coherent * the demodulator applies an I/Q bandpass "matched" filter, and then observes the phase difference between adjacent symbols * a truly coherent demodulator would take the absolte phase into consideration, giving e.g. a 3 dB performance improvement for GMSK * need a way to allow the user to specify this upon object creation * probably also want time tracking, carrier tracking, at some point as well --- src/modem/src/cpfskdem.proto.c | 105 ++++++++++++++------------------- 1 file changed, 44 insertions(+), 61 deletions(-) diff --git a/src/modem/src/cpfskdem.proto.c b/src/modem/src/cpfskdem.proto.c index d641272e3..c269efaf2 100644 --- a/src/modem/src/cpfskdem.proto.c +++ b/src/modem/src/cpfskdem.proto.c @@ -78,16 +78,14 @@ struct CPFSKDEM(_s) { //nco_crcf nco; // oscillator/phase-locked loop //firpfb_crcf mf; // matched filter //firpfb_crcf dmf; // matched filter (derivative) - firfilt_crcf mf; // matched filter + //eqlms_rrrf equalizer; } coherent; // non-coherent demodulator struct { - firpfb_rrrf mf; // matched filter - firpfb_rrrf dmf; // matched filter (derivative) - eqlms_rrrf equalizer; + firfilt_crcf mf; // matched filter } noncoherent; - } data; + } demod; // state variables unsigned int index; // debug @@ -141,7 +139,7 @@ CPFSKDEM() CPFSKDEM(_create)(unsigned int _bps, //cpfskdem_init_noncoherent(q); fprintf(stderr,"warning: cpfskdem_create(), coherent demodulation with h > 2/3 not recommended\n"); } - CPFSKDEM(_init_coherent)(q); + CPFSKDEM(_init_noncoherent)(q); // reset modem object CPFSKDEM(_reset)(q); @@ -151,14 +149,20 @@ CPFSKDEM() CPFSKDEM(_create)(unsigned int _bps, return q; } -// initialize coherent demodulator +// initialize non-coherent demodulator int CPFSKDEM(_init_coherent)(CPFSKDEM() _q) +{ + return liquid_error(LIQUID_EUMODE,"cpfskdem_init_coherent(), unsupported mode"); +} + +// initialize noncoherent demodulator +int CPFSKDEM(_init_noncoherent)(CPFSKDEM() _q) { // specify coherent receiver - _q->demod_type = CPFSKDEM_COHERENT; + _q->demod_type = CPFSKDEM_NONCOHERENT; // set demodulate function pointer - _q->demodulate = cpfskdem_demodulate_coherent; + _q->demodulate = cpfskdem_demodulate_noncoherent; // create object depending upon input type float bw = 0.0f; @@ -169,28 +173,28 @@ int CPFSKDEM(_init_coherent)(CPFSKDEM() _q) //bw = 0.9f / (float)k; bw = 0.4f; _q->symbol_delay = _q->m; - _q->data.coherent.mf = firfilt_crcf_create_kaiser(2*_q->k*_q->m+1, bw, 60.0f, 0.0f); - firfilt_crcf_set_scale(_q->data.coherent.mf, 2.0f * bw); + _q->demod.noncoherent.mf = firfilt_crcf_create_kaiser(2*_q->k*_q->m+1, bw, 60.0f, 0.0f); + firfilt_crcf_set_scale(_q->demod.noncoherent.mf, 2.0f * bw); break; case LIQUID_CPFSK_RCOS_FULL: if (_q->M==2) { - _q->data.coherent.mf = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,_q->k,_q->m,0.5f,0); - firfilt_crcf_set_scale(_q->data.coherent.mf, 1.33f / (float)_q->k); + _q->demod.noncoherent.mf = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,_q->k,_q->m,0.5f,0); + firfilt_crcf_set_scale(_q->demod.noncoherent.mf, 1.33f / (float)_q->k); _q->symbol_delay = _q->m; } else { - _q->data.coherent.mf = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,_q->k/2,2*_q->m,0.9f,0); - firfilt_crcf_set_scale(_q->data.coherent.mf, 3.25f / (float)_q->k); + _q->demod.noncoherent.mf = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,_q->k/2,2*_q->m,0.9f,0); + firfilt_crcf_set_scale(_q->demod.noncoherent.mf, 3.25f / (float)_q->k); _q->symbol_delay = 0; // TODO: fix this value } break; case LIQUID_CPFSK_RCOS_PARTIAL: if (_q->M==2) { - _q->data.coherent.mf = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,_q->k,_q->m,0.3f,0); - firfilt_crcf_set_scale(_q->data.coherent.mf, 1.10f / (float)_q->k); + _q->demod.noncoherent.mf = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,_q->k,_q->m,0.3f,0); + firfilt_crcf_set_scale(_q->demod.noncoherent.mf, 1.10f / (float)_q->k); _q->symbol_delay = _q->m; } else { - _q->data.coherent.mf = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,_q->k/2,2*_q->m,0.27f,0); - firfilt_crcf_set_scale(_q->data.coherent.mf, 2.90f / (float)_q->k); + _q->demod.noncoherent.mf = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,_q->k/2,2*_q->m,0.27f,0); + firfilt_crcf_set_scale(_q->demod.noncoherent.mf, 2.90f / (float)_q->k); _q->symbol_delay = 0; // TODO: fix this value } break; @@ -198,40 +202,16 @@ int CPFSKDEM(_init_coherent)(CPFSKDEM() _q) bw = 0.5f / (float)_q->k; // TODO: figure out beta value here beta = (_q->M == 2) ? 0.8*gmsk_bt : 1.0*gmsk_bt; - _q->data.coherent.mf = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,_q->k,_q->m,beta,0); - firfilt_crcf_set_scale(_q->data.coherent.mf, 2.0f * bw); + _q->demod.noncoherent.mf = firfilt_crcf_create_rnyquist(LIQUID_FIRFILT_GMSKRX,_q->k,_q->m,beta,0); + firfilt_crcf_set_scale(_q->demod.noncoherent.mf, 2.0f * bw); _q->symbol_delay = _q->m; break; default: - return liquid_error(LIQUID_EICONFIG,"cpfskdem_init_coherent(), invalid tx filter type"); + return liquid_error(LIQUID_EICONFIG,"cpfskdem_init_noncoherent(), invalid tx filter type"); } return LIQUID_OK; } -// initialize non-coherent demodulator -int CPFSKDEM(_init_noncoherent)(CPFSKDEM() _q) -{ -#if 0 - // specify non-coherent receiver - _q->demod_type = CPFSKDEM_NONCOHERENT; - - // set demodulate function pointer - _q->demodulate = cpfskdem_demodulate_noncoherent; - - // create object depending upon input type - switch(_q->type) { - case LIQUID_CPFSK_SQUARE: - case LIQUID_CPFSK_RCOS_FULL: - case LIQUID_CPFSK_RCOS_PARTIAL: - case LIQUID_CPFSK_GMSK: - break; - } - return LIQUID_OK; -#else - return liquid_error(LIQUID_EUMODE,"cpfskdem_init_noncoherent(), unsupported mode"); -#endif -} - // destroy modem object int CPFSKDEM(_destroy)(CPFSKDEM() _q) { @@ -242,9 +222,10 @@ int CPFSKDEM(_destroy)(CPFSKDEM() _q) #endif switch(_q->demod_type) { case CPFSKDEM_COHERENT: - firfilt_crcf_destroy(_q->data.coherent.mf); + return liquid_error(LIQUID_EINT,"cpfskdem_destroy(), coherent mode not supported"); break; case CPFSKDEM_NONCOHERENT: + firfilt_crcf_destroy(_q->demod.noncoherent.mf); break; } @@ -274,7 +255,7 @@ int CPFSKDEM(_reset)(CPFSKDEM() _q) { switch(_q->demod_type) { case CPFSKDEM_COHERENT: - firfilt_crcf_reset(_q->data.coherent.mf); + firfilt_crcf_reset(_q->demod.noncoherent.mf); break; case CPFSKDEM_NONCOHERENT: break; @@ -301,7 +282,7 @@ unsigned int CPFSKDEM(_get_delay)(CPFSKDEM() _q) // _n : input sample array length // _s : output symbol array // _nw : number of output symbols written -int CPFSKDEM(_demodulate)(CPFSKDEM() _q, +int CPFSKDEM(_demodulate)(CPFSKDEM() _q, TC * _y, unsigned int _n, unsigned int * _s, @@ -333,12 +314,12 @@ int CPFSKDEM(_demodulate_coherent)(CPFSKDEM() _q, *_nw = 0; // push input sample through filter - firfilt_crcf_push(_q->data.coherent.mf, _y); + firfilt_crcf_push(_q->demod.noncoherent.mf, _y); #if DEBUG_CPFSKDEM // compute output sample float complex zp; - firfilt_crcf_execute(_q->data.coherent.mf, &zp); + firfilt_crcf_execute(_q->demod.noncoherent.mf, &zp); printf("y(end+1) = %12.8f + 1i*%12.8f;\n", crealf(_y), cimagf(_y)); printf("z(end+1) = %12.8f + 1i*%12.8f;\n", crealf(zp), cimagf(zp)); #endif @@ -351,7 +332,7 @@ int CPFSKDEM(_demodulate_coherent)(CPFSKDEM() _q, // compute output sample float complex z; - firfilt_crcf_execute(_q->data.coherent.mf, &z); + firfilt_crcf_execute(_q->demod.noncoherent.mf, &z); // compute instantaneous frequency scaled by modulation index // TODO: pre-compute scaling factor @@ -401,18 +382,26 @@ unsigned int CPFSKDEM(_demodulate)(CPFSKDEM() _q, // demodulate array of samples (coherent) unsigned int CPFSKDEM(_demodulate_coherent)(CPFSKDEM() _q, TC * _y) +{ + liquid_error(LIQUID_EINT,"cpfskdem_demodulate_coherent(), coherent mode not supported"); + return 0; +} + +// demodulate array of samples (non-coherent) +unsigned int CPFSKDEM(_demodulate_noncoherent)(CPFSKDEM() _q, + TC * _y) { unsigned int i; unsigned int sym_out = 0; for (i=0; i<_q->k; i++) { // push input sample through filter - firfilt_crcf_push(_q->data.coherent.mf, _y[i]); + firfilt_crcf_push(_q->demod.noncoherent.mf, _y[i]); #if DEBUG_CPFSKDEM // compute output sample float complex zp; - firfilt_crcf_execute(_q->data.coherent.mf, &zp); + firfilt_crcf_execute(_q->demod.noncoherent.mf, &zp); printf("y(end+1) = %12.8f + %12.8fj;\n", crealf(_y[i]), cimagf(_y[i])); printf("z(end+1) = %12.8f + %12.8fj;\n", crealf( zp), cimagf( zp)); #endif @@ -421,7 +410,7 @@ unsigned int CPFSKDEM(_demodulate_coherent)(CPFSKDEM() _q, if ( i == 0 ) { // compute output sample float complex z; - firfilt_crcf_execute(_q->data.coherent.mf, &z); + firfilt_crcf_execute(_q->demod.noncoherent.mf, &z); // compute instantaneous frequency scaled by modulation index // TODO: pre-compute scaling factor @@ -444,11 +433,5 @@ unsigned int CPFSKDEM(_demodulate_coherent)(CPFSKDEM() _q, return sym_out; } -// demodulate array of samples (non-coherent) -unsigned int CPFSKDEM(_demodulate_noncoherent)(CPFSKDEM() _q, - TC * _y) -{ - return 0; -} #endif From 2e8ecac345c5b87951ca9af44e6efe56c36aaffa Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 13 Apr 2024 16:09:24 -0400 Subject: [PATCH 48/97] cpfskmod: adding copy() method, untested --- include/liquid.h | 9 ++++--- src/modem/src/cpfskmod.proto.c | 48 ++++++++++++++++++++++++---------- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/include/liquid.h b/include/liquid.h index 45eb232eb..08ad81610 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -8340,13 +8340,16 @@ CPFSKMOD() CPFSKMOD(_create)(unsigned int _bps, \ /* cpfskmod cpfskmod_create_msk(unsigned int _k); */ \ /* cpfskmod cpfskmod_create_gmsk(unsigned int _k, float _BT); */ \ \ -/* destroy cpfskmod object */ \ +/* Copy object including all internal objects and state */ \ +CPFSKMOD() CPFSKMOD(_copy)(CPFSKMOD() _q); \ + \ +/* Destroy modulator object, freeing all allocate memory */ \ int CPFSKMOD(_destroy)(CPFSKMOD() _q); \ \ -/* print cpfskmod object internals */ \ +/* Print modulator status to stdout */ \ int CPFSKMOD(_print)(CPFSKMOD() _q); \ \ -/* reset state */ \ +/* Reset internal state of modulator object */ \ int CPFSKMOD(_reset)(CPFSKMOD() _q); \ \ /* get transmit delay [symbols] */ \ diff --git a/src/modem/src/cpfskmod.proto.c b/src/modem/src/cpfskmod.proto.c index 56dede005..5b56d260f 100644 --- a/src/modem/src/cpfskmod.proto.c +++ b/src/modem/src/cpfskmod.proto.c @@ -36,8 +36,8 @@ int CPFSKMOD(_firdes)(unsigned int _k, float * _h, unsigned int _h_len); -// cpfskmod -struct CPFSKMOD(_s) { +struct CPFSKMOD(_s) +{ // common unsigned int bps; // bits per symbol unsigned int k; // samples per symbol @@ -49,13 +49,13 @@ struct CPFSKMOD(_s) { unsigned int symbol_delay; // transmit filter delay [symbols] // pulse-shaping filter - float * ht; // filter coefficients + T * ht; // filter coefficients unsigned int ht_len; // filter length - firinterp_rrrf interp; // interpolator + firinterp_rrrf interp; // phase interpolator // phase integrator - float * phase_interp; // phase interpolation buffer - float b0, b1, a1, v0, v1; // integrator + T * phase_interp; // phase interpolation buffer + T b0, b1, a1, v0, v1; // integrator }; // create CPFSKMOD() object (frequency modulator) @@ -131,14 +131,14 @@ CPFSKMOD() CPFSKMOD(_create)(unsigned int _bps, } // create pulse-shaping filter and scale by modulation index - q->ht = (float*) malloc(q->ht_len *sizeof(float)); - cpfskmod_firdes(q->k, q->m, q->beta, q->type, q->ht, q->ht_len); + q->ht = (T*) malloc(q->ht_len *sizeof(T)); + CPFSKMOD(_firdes)(q->k, q->m, q->beta, q->type, q->ht, q->ht_len); for (i=0; iht_len; i++) q->ht[i] *= M_PI * q->h; q->interp = firinterp_rrrf_create(q->k, q->ht, q->ht_len); // allocate buffer for phase interpolation - q->phase_interp = (float*) malloc(q->k*sizeof(float)); + q->phase_interp = (T*) malloc(q->k*sizeof(T)); // reset modem object cpfskmod_reset(q); @@ -146,7 +146,27 @@ CPFSKMOD() CPFSKMOD(_create)(unsigned int _bps, return q; } -// destroy CPFSKMOD() object +// Copy object including all internal objects and state +CPFSKMOD() CPFSKMOD(_copy)(CPFSKMOD() q_orig) +{ + // validate input + if (q_orig == NULL) + return liquid_error_config("cpfskmod_copy(), object cannot be NULL"); + + // create filter object and copy base parameters + CPFSKMOD() q_copy = (CPFSKMOD()) malloc(sizeof(struct CPFSKMOD(_s))); + memmove(q_copy, q_orig, sizeof(struct CPFSKMOD(_s))); + + // copy objects, arrays + q_copy->interp = firinterp_rrrf_copy(q_orig->interp); + q_copy->ht = (T*) liquid_malloc_copy(q_orig->ht, q_orig->ht_len, sizeof(T)); + q_copy->phase_interp = (T*) liquid_malloc_copy(q_orig->phase_interp, q_orig->k, sizeof(T)); + + // return new object + return q_copy; +} + +// destroy modulator object int CPFSKMOD(_destroy)(CPFSKMOD() _q) { // destroy pulse-shaping filter/interpolator @@ -159,7 +179,7 @@ int CPFSKMOD(_destroy)(CPFSKMOD() _q) return LIQUID_OK; } -// print CPFSKMOD() object internals +// print modulator object internals int CPFSKMOD(_print)(CPFSKMOD() _q) { printf("M) + 1.0f; From d6bdff1b39c5b8b104b36ed1299e03e7f5734451 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 13 Apr 2024 16:16:40 -0400 Subject: [PATCH 49/97] cpfskdem: adding copy() method, untested --- include/liquid.h | 3 +++ src/modem/src/cpfskdem.proto.c | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/liquid.h b/include/liquid.h index 08ad81610..59fc0fd52 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -8393,6 +8393,9 @@ CPFSKDEM() CPFSKDEM(_create)(unsigned int _bps, \ /* CPFSKDEM() CPFSKDEM(_create_msk)(unsigned int _k); */ \ /* CPFSKDEM() CPFSKDEM(_create_gmsk)(unsigned int _k, float _BT); */ \ \ +/* Copy object including all internal objects and state */ \ +CPFSKDEM() CPFSKDEM(_copy)(CPFSKDEM() _q); \ + \ /* Destroy demodulator object, freeing all internal memory */ \ int CPFSKDEM(_destroy)(CPFSKDEM() _q); \ \ diff --git a/src/modem/src/cpfskdem.proto.c b/src/modem/src/cpfskdem.proto.c index c269efaf2..bbca1dd68 100644 --- a/src/modem/src/cpfskdem.proto.c +++ b/src/modem/src/cpfskdem.proto.c @@ -149,6 +149,31 @@ CPFSKDEM() CPFSKDEM(_create)(unsigned int _bps, return q; } +// Copy object including all internal objects and state +CPFSKDEM() CPFSKDEM(_copy)(CPFSKDEM() q_orig) +{ + // validate input + if (q_orig == NULL) + return liquid_error_config("cpfskdem_copy(), object cannot be NULL"); + + // create filter object and copy base parameters + CPFSKDEM() q_copy = (CPFSKDEM()) malloc(sizeof(struct CPFSKDEM(_s))); + memmove(q_copy, q_orig, sizeof(struct CPFSKDEM(_s))); + + // copy objects + if (q_orig->demod_type == CPFSKDEM_COHERENT) { + //return liquid_error_config("cpfskdem_copy(), coherent mode not supported"); + liquid_error(LIQUID_EINT,"cpfskdem_copy(), coherent mode not supported"); + return NULL; + } else { + q_copy->demod.noncoherent.mf = firfilt_crcf_copy(q_orig->demod.noncoherent.mf); + } + + // return new object + return q_copy; +} + + // initialize non-coherent demodulator int CPFSKDEM(_init_coherent)(CPFSKDEM() _q) { From 9cc889f39082fc695df95ecef26acd720c8d6686 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 07:41:22 -0400 Subject: [PATCH 50/97] cpfskmodem: adding convenience create() methods for MSK, GMSK --- include/liquid.h | 38 +++++++++++++++++++++++++--------- src/modem/src/cpfskdem.proto.c | 18 ++++++++++++++++ src/modem/src/cpfskmod.proto.c | 18 ++++++++++++++++ 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/include/liquid.h b/include/liquid.h index 59fc0fd52..f0969f0fb 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -8324,12 +8324,12 @@ typedef enum { typedef struct CPFSKMOD(_s) * CPFSKMOD(); \ \ /* create cpfskmod object (frequency modulator) */ \ -/* _bps : bits per symbol, _bps > 0 */ \ -/* _h : modulation index, _h > 0 */ \ -/* _k : samples/symbol, _k > 1, _k even */ \ -/* _m : filter delay (symbols), _m > 0 */ \ -/* _beta : filter bandwidth parameter, _beta > 0 */ \ -/* _type : filter type (e.g. LIQUID_CPFSK_SQUARE) */ \ +/* _bps : bits per symbol, _bps > 0 */ \ +/* _h : modulation index, _h > 0 */ \ +/* _k : samples/symbol, _k > 1, _k even */ \ +/* _m : filter delay (symbols), _m > 0 */ \ +/* _beta : filter bandwidth parameter, _beta > 0 */ \ +/* _type : filter type (e.g. LIQUID_CPFSK_SQUARE) */ \ CPFSKMOD() CPFSKMOD(_create)(unsigned int _bps, \ float _h, \ unsigned int _k, \ @@ -8337,8 +8337,17 @@ CPFSKMOD() CPFSKMOD(_create)(unsigned int _bps, \ float _beta, \ int _type); \ \ -/* cpfskmod cpfskmod_create_msk(unsigned int _k); */ \ -/* cpfskmod cpfskmod_create_gmsk(unsigned int _k, float _BT); */ \ +/* create modulator object for minimum-shift keying */ \ +/* _k : samples/symbol, _k > 1, _k even */ \ +CPFSKMOD() CPFSKMOD(_create_msk)(unsigned int _k); \ + \ +/* create modulator object for Gauss minimum-shift keying */ \ +/* _k : samples/symbol, _k > 1, _k even */ \ +/* _m : filter delay (symbols), _m > 0 */ \ +/* _BT : bandwidth-time factor, 0 < _BT < 1 */ \ +CPFSKMOD() CPFSKMOD(_create_gmsk)(unsigned int _k, \ + unsigned int _m, \ + float _BT); \ \ /* Copy object including all internal objects and state */ \ CPFSKMOD() CPFSKMOD(_copy)(CPFSKMOD() _q); \ @@ -8390,8 +8399,17 @@ CPFSKDEM() CPFSKDEM(_create)(unsigned int _bps, \ float _beta, \ int _type); \ \ -/* CPFSKDEM() CPFSKDEM(_create_msk)(unsigned int _k); */ \ -/* CPFSKDEM() CPFSKDEM(_create_gmsk)(unsigned int _k, float _BT); */ \ +/* create demodulator object for minimum-shift keying */ \ +/* _k : samples/symbol, _k > 1, _k even */ \ +CPFSKDEM() CPFSKDEM(_create_msk)(unsigned int _k); \ + \ +/* create demodulator object for Gauss minimum-shift keying */ \ +/* _k : samples/symbol, _k > 1, _k even */ \ +/* _m : filter delay (symbols), _m > 0 */ \ +/* _BT : bandwidth-time factor, 0 < _BT < 1 */ \ +CPFSKDEM() CPFSKDEM(_create_gmsk)(unsigned int _k, \ + unsigned int _m, \ + float _BT); \ \ /* Copy object including all internal objects and state */ \ CPFSKDEM() CPFSKDEM(_copy)(CPFSKDEM() _q); \ diff --git a/src/modem/src/cpfskdem.proto.c b/src/modem/src/cpfskdem.proto.c index bbca1dd68..3ffc7105a 100644 --- a/src/modem/src/cpfskdem.proto.c +++ b/src/modem/src/cpfskdem.proto.c @@ -173,6 +173,24 @@ CPFSKDEM() CPFSKDEM(_copy)(CPFSKDEM() q_orig) return q_copy; } +// create demodulator object for minimum-shift keying +// _k : samples/symbol, _k > 1, _k even +CPFSKDEM() CPFSKDEM(_create_msk)(unsigned int _k) +{ + return CPFSKDEM(_create)(1, 0.5f, _k, 1, 1.0f, LIQUID_CPFSK_SQUARE); +} + +// create demodulator object for Gauss minimum-shift keying +// _k : samples/symbol, _k > 1, _k even +// _m : filter delay (symbols), _m > 0 +// _BT : bandwidth-time factor, 0 < _BT < 1 +CPFSKDEM() CPFSKDEM(_create_gmsk)(unsigned int _k, + unsigned int _m, + float _BT) +{ + return CPFSKDEM(_create)(1, 0.5f, _k, _m, _BT, LIQUID_CPFSK_GMSK); +} + // initialize non-coherent demodulator int CPFSKDEM(_init_coherent)(CPFSKDEM() _q) diff --git a/src/modem/src/cpfskmod.proto.c b/src/modem/src/cpfskmod.proto.c index 5b56d260f..c96241fc7 100644 --- a/src/modem/src/cpfskmod.proto.c +++ b/src/modem/src/cpfskmod.proto.c @@ -146,6 +146,24 @@ CPFSKMOD() CPFSKMOD(_create)(unsigned int _bps, return q; } +// create modulator object for minimum-shift keying +// _k : samples/symbol, _k > 1, _k even +CPFSKMOD() CPFSKMOD(_create_msk)(unsigned int _k) +{ + return CPFSKMOD(_create)(1, 0.5f, _k, 1, 1.0f, LIQUID_CPFSK_SQUARE); +} + +// create modulator object for minimum-shift keying +// _k : samples/symbol, _k > 1, _k even +// _m : filter delay (symbols), _m > 0 +// _BT : bandwidth-time factor, 0 < _BT < 1 +CPFSKMOD() CPFSKMOD(_create_gmsk)(unsigned int _k, + unsigned int _m, + float _BT) +{ + return CPFSKMOD(_create)(1, 0.5f, _k, _m, _BT, LIQUID_CPFSK_GMSK); +} + // Copy object including all internal objects and state CPFSKMOD() CPFSKMOD(_copy)(CPFSKMOD() q_orig) { From 5c3fdf1dced7463713a9fdaf8c58550bc4c9534c Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 07:56:28 -0400 Subject: [PATCH 51/97] cpfskmodem/autotest: adding tests for various samples/symbol, cleanup --- src/modem/tests/cpfskmodem_autotest.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/modem/tests/cpfskmodem_autotest.c b/src/modem/tests/cpfskmodem_autotest.c index 68f15f999..b298615df 100644 --- a/src/modem/tests/cpfskmodem_autotest.c +++ b/src/modem/tests/cpfskmodem_autotest.c @@ -37,17 +37,14 @@ void cpfskmodem_test_mod_demod(unsigned int _bps, // derived values unsigned int delay = cpfskmod_get_delay(mod) + cpfskdem_get_delay(dem); - //unsigned int M = 1 << _m; // constellation size - - unsigned int num_symbols = 80 + delay; // number of symbols to test - - msequence ms = msequence_create_default(7); + unsigned int num_symbols = 180 + delay; // number of symbols to test float complex buf[_k]; // sample buffer unsigned int sym_in [num_symbols]; // symbol buffer unsigned int sym_out[num_symbols]; // symbol buffer // modulate, demodulate, count errors + msequence ms = msequence_create_default(7); unsigned int i; for (i=0; i Date: Sun, 14 Apr 2024 09:01:05 -0400 Subject: [PATCH 52/97] github: testing uploading with github action --- .github/workflows/coverage.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 14258ec71..46447fb45 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -45,5 +45,8 @@ jobs: - name: make coverage run: make -j 2 coverage - - name: upload report - run: bash <(curl -s https://codecov.io/bash) + - name: upload report to codecov with github action + uses: codecov/codecov-action@v4.2.0 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + From e20809b31fcdad308a7b48282dcc5e892a844472 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 09:02:24 -0400 Subject: [PATCH 53/97] github: enabling coverage workflow on coverage-dev branch --- .github/workflows/coverage.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 46447fb45..e6df2e358 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -6,6 +6,7 @@ on: push: branches: - master + - coverage-dev jobs: standard: From 1e7fccf6e1ff2a14995bce430310708bf8d4a66d Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 09:19:52 -0400 Subject: [PATCH 54/97] github: adding verbose flag to coverage upload testing --- .github/workflows/coverage.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index e6df2e358..ffb00040c 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -48,6 +48,8 @@ jobs: - name: upload report to codecov with github action uses: codecov/codecov-action@v4.2.0 + with: + verbose: true env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From bb2826d53ba38d63047748b5a756447b6549a2b0 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 09:30:28 -0400 Subject: [PATCH 55/97] github: moving token to 'with' instead of 'env' --- .github/workflows/coverage.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index ffb00040c..9e6d90f85 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -49,7 +49,5 @@ jobs: - name: upload report to codecov with github action uses: codecov/codecov-action@v4.2.0 with: - verbose: true - env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} From 9994d32ac8f3b32b540419ae920c70aaf78ec656 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 09:33:28 -0400 Subject: [PATCH 56/97] github: fixing syntax for specifying secret token, adding fail on error --- .github/workflows/coverage.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 9e6d90f85..9e94d2105 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -49,5 +49,7 @@ jobs: - name: upload report to codecov with github action uses: codecov/codecov-action@v4.2.0 with: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + From 25db8f315e355349297dc912a3047ebbfdedf391 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 09:37:31 -0400 Subject: [PATCH 57/97] github: downgrading codecov action to v4 --- .github/workflows/coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 9e94d2105..6809dcd0b 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -47,7 +47,7 @@ jobs: run: make -j 2 coverage - name: upload report to codecov with github action - uses: codecov/codecov-action@v4.2.0 + uses: codecov/codecov-action@v4 with: fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} From 486eb8e5b5f8fee6f4394c16aaa4ecfb93e2ab18 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 09:53:03 -0400 Subject: [PATCH 58/97] github: testing token key in workflow --- .github/workflows/coverage.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 6809dcd0b..6265a2294 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -50,6 +50,7 @@ jobs: uses: codecov/codecov-action@v4 with: fail_ci_if_error: true - token: ${{ secrets.CODECOV_TOKEN }} + verbose: true + token: "my-secret-token" #${{ secrets.CODECOV_TOKEN }} From c4a568557de953758d36858e8384db2b341f4649 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 10:08:19 -0400 Subject: [PATCH 59/97] github: trying to use proper token; not sure why this is not working --- .github/workflows/coverage.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml index 6265a2294..a5ea16160 100644 --- a/.github/workflows/coverage.yml +++ b/.github/workflows/coverage.yml @@ -51,6 +51,4 @@ jobs: with: fail_ci_if_error: true verbose: true - token: "my-secret-token" #${{ secrets.CODECOV_TOKEN }} - - + token: ${{ secrets.CODECOV_TOKEN }} From d1f161e0cb3d3994656d9a06954acb325fb3ec32 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 15:35:29 -0400 Subject: [PATCH 60/97] modem: including additional configuration tests --- include/liquid.internal.h | 13 ------------- src/modem/src/modem_common.proto.c | 6 +++--- src/modem/tests/modem_config_autotest.c | 14 +++++++++++++- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/include/liquid.internal.h b/include/liquid.internal.h index 1f9e027cd..15f08c1e5 100644 --- a/include/liquid.internal.h +++ b/include/liquid.internal.h @@ -1381,19 +1381,6 @@ int MODEM(_demodulate_soft_table)(MODEM() _q, \ unsigned int * _sym_out, \ unsigned char * _soft_bits); \ \ -/* Demodulate a linear symbol constellation using dynamic */ \ -/* threshold calculation */ \ -/* _v : input value */ \ -/* _m : bits per symbol */ \ -/* _alpha : scaling factor */ \ -/* _s : demodulated symbol */ \ -/* _res : residual */ \ -int MODEM(_demodulate_linear_array)(T _v, \ - unsigned int _m, \ - T _alpha, \ - unsigned int * _s, \ - T * _res); \ - \ /* Demodulate a linear symbol constellation using */ \ /* referenced lookup table */ \ /* _v : input value */ \ diff --git a/src/modem/src/modem_common.proto.c b/src/modem/src/modem_common.proto.c index d560d6068..52bc452f5 100644 --- a/src/modem/src/modem_common.proto.c +++ b/src/modem/src/modem_common.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -212,8 +212,6 @@ MODEM() MODEM(_create)(modulation_scheme _scheme) return liquid_error_config("modem%s_create(), unknown/unsupported modulation scheme : %u",EXTENSION,_scheme); } - // should never get to this point, but adding return statement - // to keep compiler happy return NULL; } @@ -578,6 +576,7 @@ T MODEM(_get_demodulator_evm)(MODEM() _q) return cabsf(_q->x_hat - _q->r); } +#if 0 // Demodulate a linear symbol constellation using dynamic threshold calculation // _v : input value // _m : bits per symbol @@ -604,6 +603,7 @@ int MODEM(_demodulate_linear_array)(T _v, *_res = _v; return LIQUID_OK; } +#endif // Demodulate a linear symbol constellation using referenced lookup table // _v : input value diff --git a/src/modem/tests/modem_config_autotest.c b/src/modem/tests/modem_config_autotest.c index ebc8f03fa..52ecb2ec4 100644 --- a/src/modem/tests/modem_config_autotest.c +++ b/src/modem/tests/modem_config_autotest.c @@ -22,7 +22,7 @@ #include #include "autotest/autotest.h" -#include "liquid.h" +#include "liquid.internal.h" // Helper function to keep code base small void modemcf_test_copy(modulation_scheme _ms) @@ -145,10 +145,22 @@ void autotest_modem_config() // test copying/creating invalid objects CONTEND_ISNULL( modemcf_copy(NULL) ); CONTEND_ISNULL( modemcf_create(LIQUID_MODEM_ARB) ); + CONTEND_ISNULL( modemcf_create(-1) ); // create object and check configuration modemcf q = modemcf_create(LIQUID_MODEM_QAM64); CONTEND_EQUALITY( LIQUID_OK, modemcf_print(q) ); + + // internal: try to initialize using invalid configuration + CONTEND_INEQUALITY( LIQUID_OK, modemcf_init(q,0) ); + CONTEND_INEQUALITY( LIQUID_OK, modemcf_init(q,77) ); + + // internal: try to modulate using invalid inputs + float complex sym; + CONTEND_INEQUALITY( LIQUID_OK, modemcf_modulate (q,8193,&sym) ); + CONTEND_INEQUALITY( LIQUID_OK, modemcf_modulate_map(q,8193,&sym) ); + CONTEND_INEQUALITY( LIQUID_OK, modemcf_demodsoft_gentab(q,227) ); + modemcf_destroy(q); } From 9de2878e0e2a7f2554f5760491a5b999abc36f58 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 16:08:09 -0400 Subject: [PATCH 61/97] cpfskmodem: adding access methods, additional testing --- include/liquid.h | 34 +++++++++- src/modem/src/cpfskdem.proto.c | 43 +++++++++++- src/modem/src/cpfskmod.proto.c | 35 +++++++++- src/modem/tests/cpfskmodem_autotest.c | 95 ++++++++++++++++----------- 4 files changed, 163 insertions(+), 44 deletions(-) diff --git a/include/liquid.h b/include/liquid.h index f0969f0fb..3d3406e07 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -8361,9 +8361,24 @@ int CPFSKMOD(_print)(CPFSKMOD() _q); \ /* Reset internal state of modulator object */ \ int CPFSKMOD(_reset)(CPFSKMOD() _q); \ \ -/* get transmit delay [symbols] */ \ +/* Get modulator's number of bits per symbol */ \ +unsigned int CPFSKMOD(_get_bits_per_symbol)(CPFSKMOD() _q); \ + \ +/* Get modulator's modulation index */ \ +float CPFSKMOD(_get_modulation_index)(CPFSKMOD() _q); \ + \ +/* Get modulator's number of samples per symbol */ \ +unsigned int CPFSKMOD(_get_samples_per_symbol)(CPFSKMOD() _q); \ + \ +/* Get modulator's filter delay [symbols] */ \ unsigned int CPFSKMOD(_get_delay)(CPFSKMOD() _q); \ \ +/* Get modulator's bandwidth parameter */ \ +float CPFSKMOD(_get_beta)(CPFSKMOD() _q); \ + \ +/* Get modulator's filter type */ \ +int CPFSKMOD(_get_type)(CPFSKMOD() _q); \ + \ /* modulate sample */ \ /* _q : frequency modulator object */ \ /* _s : input symbol */ \ @@ -8423,9 +8438,24 @@ int CPFSKDEM(_print)(CPFSKDEM() _q); \ /* Reset state */ \ int CPFSKDEM(_reset)(CPFSKDEM() _q); \ \ -/* get receive delay [symbols] */ \ +/* Get demodulator's number of bits per symbol */ \ +unsigned int CPFSKDEM(_get_bits_per_symbol)(CPFSKDEM() _q); \ + \ +/* Get demodulator's modulation index */ \ +float CPFSKDEM(_get_modulation_index)(CPFSKDEM() _q); \ + \ +/* Get demodulator's number of samples per symbol */ \ +unsigned int CPFSKDEM(_get_samples_per_symbol)(CPFSKDEM() _q); \ + \ +/* Get demodulator's transmit delay [symbols] */ \ unsigned int CPFSKDEM(_get_delay)(CPFSKDEM() _q); \ \ +/* Get demodulator's bandwidth parameter */ \ +float CPFSKDEM(_get_beta)(CPFSKDEM() _q); \ + \ +/* Get demodulator's filter type */ \ +int CPFSKDEM(_get_type)(CPFSKDEM() _q); \ + \ /* demodulate array of samples, assuming perfect timing */ \ /* _q : continuous-phase frequency demodulator object */ \ /* _y : input sample array, [size: _k x 1] */ \ diff --git a/src/modem/src/cpfskdem.proto.c b/src/modem/src/cpfskdem.proto.c index 3ffc7105a..a4f781335 100644 --- a/src/modem/src/cpfskdem.proto.c +++ b/src/modem/src/cpfskdem.proto.c @@ -130,6 +130,16 @@ CPFSKDEM() CPFSKDEM(_create)(unsigned int _bps, q->beta = _beta; // filter roll-off factor (only for certain filters) q->type = _type; // filter type + switch(q->type) { + case LIQUID_CPFSK_SQUARE: + case LIQUID_CPFSK_RCOS_FULL: + case LIQUID_CPFSK_RCOS_PARTIAL: + case LIQUID_CPFSK_GMSK: + break; + default: + return liquid_error_config("cpfskdem_create(), invalid filter type '%d'", q->type); + } + // derived values q->M = 1 << q->bps; // constellation size @@ -312,12 +322,43 @@ int CPFSKDEM(_reset)(CPFSKDEM() _q) return LIQUID_OK; } -// get transmit delay [symbols] +// Get demodulator's number of bits per symbol +unsigned int CPFSKDEM(_get_bits_per_symbol)(CPFSKDEM() _q) +{ + return _q->bps; +} + +// Get demodulator's modulation index +float CPFSKDEM(_get_modulation_index)(CPFSKDEM() _q) +{ + return _q->h; +} + +// Get demodulator's number of samples per symbol +unsigned int CPFSKDEM(_get_samples_per_symbol)(CPFSKDEM() _q) +{ + return _q->k; +} + +// Get demodulator's filter delay [symbols] unsigned int CPFSKDEM(_get_delay)(CPFSKDEM() _q) { return _q->symbol_delay; } +// Get demodulator's bandwidth parameter +float CPFSKDEM(_get_beta)(CPFSKDEM() _q) +{ + return _q->beta; +} + +// Get demodulator's filter type +int CPFSKDEM(_get_type)(CPFSKDEM() _q) +{ + return _q->type; +} + + #if 0 // demodulate array of samples // _q : continuous-phase frequency demodulator object diff --git a/src/modem/src/cpfskmod.proto.c b/src/modem/src/cpfskmod.proto.c index c96241fc7..dd3343316 100644 --- a/src/modem/src/cpfskmod.proto.c +++ b/src/modem/src/cpfskmod.proto.c @@ -127,7 +127,7 @@ CPFSKMOD() CPFSKMOD(_create)(unsigned int _bps, q->ht_len = 2*(q->k)*(q->m) + (q->k) + 1; break; default: - return liquid_error_config("cpfskmodem_create(), invalid filter type '%d'", q->type); + return liquid_error_config("cpfskmod_create(), invalid filter type '%d'", q->type); } // create pulse-shaping filter and scale by modulation index @@ -225,12 +225,43 @@ int CPFSKMOD(_reset)(CPFSKMOD() _q) return LIQUID_OK; } -// get transmit delay [symbols] +// Get modulator's number of bits per symbol +unsigned int CPFSKMOD(_get_bits_per_symbol)(CPFSKMOD() _q) +{ + return _q->bps; +} + +// Get modulator's modulation index +float CPFSKMOD(_get_modulation_index)(CPFSKMOD() _q) +{ + return _q->h; +} + +// Get modulator's number of samples per symbol +unsigned int CPFSKMOD(_get_samples_per_symbol)(CPFSKMOD() _q) +{ + return _q->k; +} + +// Get modulator's filter delay [symbols] unsigned int CPFSKMOD(_get_delay)(CPFSKMOD() _q) { return _q->symbol_delay; } +// Get modulator's bandwidth parameter +float CPFSKMOD(_get_beta)(CPFSKMOD() _q) +{ + return _q->beta; +} + +// Get modulator's filter type +int CPFSKMOD(_get_type)(CPFSKMOD() _q) +{ + return _q->type; +} + + // modulate sample // _q : frequency modulator object // _s : input symbol diff --git a/src/modem/tests/cpfskmodem_autotest.c b/src/modem/tests/cpfskmodem_autotest.c index b298615df..003cd16f1 100644 --- a/src/modem/tests/cpfskmodem_autotest.c +++ b/src/modem/tests/cpfskmodem_autotest.c @@ -24,22 +24,15 @@ #include "liquid.h" // Help function to keep code base small -void cpfskmodem_test_mod_demod(unsigned int _bps, - float _h, - unsigned int _k, - unsigned int _m, - float _beta, - int _filter_type) +void cpfskmodem_test_mod_demod(cpfskmod mod, cpfskdem dem) { - // create modulator/demodulator pair - cpfskmod mod = cpfskmod_create(_bps, _h, _k, _m, _beta, _filter_type); - cpfskdem dem = cpfskdem_create(_bps, _h, _k, _m, _beta, _filter_type); - // derived values unsigned int delay = cpfskmod_get_delay(mod) + cpfskdem_get_delay(dem); - unsigned int num_symbols = 180 + delay; // number of symbols to test + unsigned int k = cpfskmod_get_samples_per_symbol(mod); + unsigned int bps = cpfskmod_get_bits_per_symbol(mod); - float complex buf[_k]; // sample buffer + unsigned int num_symbols = 180 + delay; // number of symbols to test + float complex buf[k]; // sample buffer unsigned int sym_in [num_symbols]; // symbol buffer unsigned int sym_out[num_symbols]; // symbol buffer @@ -48,7 +41,7 @@ void cpfskmodem_test_mod_demod(unsigned int _bps, unsigned int i; for (i=0; i Date: Sun, 14 Apr 2024 19:31:42 -0400 Subject: [PATCH 62/97] gitlab: updating ci/cd script to upload to codecov.io --- .gitlab-ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a2fecff94..e3def3ab7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -79,7 +79,10 @@ coverage: - ./bootstrap.sh - ./configure --enable-coverage - make -j4 coverage - - bash <(curl -s https://codecov.io/bash) + - curl -Os https://cli.codecov.io/latest/linux/codecov + - chmod +x codecov + - ./codecov upload-process -t $CODECOV_TOKEN + coverage: '/lines: \d+\.\d+%/' artifacts: paths: [coverage.out] From 9e018d923fd1bee34de266323b785e213f3b6b8c Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 14 Apr 2024 19:45:26 -0400 Subject: [PATCH 63/97] gitlab: adding options for integrating with codecov.io --- .gitlab-ci.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e3def3ab7..39271ee0c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -79,9 +79,10 @@ coverage: - ./bootstrap.sh - ./configure --enable-coverage - make -j4 coverage - - curl -Os https://cli.codecov.io/latest/linux/codecov + - curl -Os http://cli.codecov.io/latest/linux/codecov - chmod +x codecov - - ./codecov upload-process -t $CODECOV_TOKEN + - ./codecov --version + - ./codecov upload-process -t $CODECOV_TOKEN --git-service gitlab --slug jgaeddert/liquid-dsp coverage: '/lines: \d+\.\d+%/' artifacts: From 4ae1006a54096420893e7806d21267edccb54617 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Tue, 16 Apr 2024 08:32:38 -0400 Subject: [PATCH 64/97] firpfbchr: adding initial test harness --- makefile.in | 3 +- src/multichannel/src/firpfbchr.proto.c | 10 ++-- .../tests/firpfbchr_crcf_autotest.c | 56 +++++++++++++++++++ 3 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 src/multichannel/tests/firpfbchr_crcf_autotest.c diff --git a/makefile.in b/makefile.in index ee7e2f7c1..1daf4d5d7 100644 --- a/makefile.in +++ b/makefile.in @@ -938,10 +938,11 @@ src/multichannel/src/firpfbch_cccf.o : %.o : %.c $(include_headers) $(multichann # autotests multichannel_autotests := \ - src/multichannel/tests/firpfbch2_crcf_autotest.c \ src/multichannel/tests/firpfbch_crcf_synthesizer_autotest.c \ src/multichannel/tests/firpfbch_crcf_analyzer_autotest.c \ src/multichannel/tests/firpfbch_crcf_autotest.c \ + src/multichannel/tests/firpfbch2_crcf_autotest.c \ + src/multichannel/tests/firpfbchr_crcf_autotest.c \ src/multichannel/tests/ofdmframe_autotest.c \ # benchmarks diff --git a/src/multichannel/src/firpfbchr.proto.c b/src/multichannel/src/firpfbchr.proto.c index 9507a586a..403cde46a 100644 --- a/src/multichannel/src/firpfbchr.proto.c +++ b/src/multichannel/src/firpfbchr.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,12 +20,8 @@ * THE SOFTWARE. */ -// -// firpfbchr.c -// // finite impulse response polyphase filterbank channelizer with output // rate Fs / P -// #include #include @@ -71,8 +67,12 @@ FIRPFBCHR() FIRPFBCHR(_create)(unsigned int _chans, // validate input if (_chans < 2) return liquid_error_config("firpfbchr_%s_create(), number of channels must be at least 2", EXTENSION_FULL); + if (_decim < 1) + return liquid_error_config("firpfbchr_%s_create(), decimation rate must be at least 1", EXTENSION_FULL); if (_m < 1) return liquid_error_config("firpfbchr_%s_create(), filter semi-length must be at least 1", EXTENSION_FULL); + if (_h == NULL) + return liquid_error_config("firpfbchr_%s_create(), filter coefficients cannot be null", EXTENSION_FULL); // create object FIRPFBCHR() q = (FIRPFBCHR()) malloc(sizeof(struct FIRPFBCHR(_s))); diff --git a/src/multichannel/tests/firpfbchr_crcf_autotest.c b/src/multichannel/tests/firpfbchr_crcf_autotest.c new file mode 100644 index 000000000..719f38b8d --- /dev/null +++ b/src/multichannel/tests/firpfbchr_crcf_autotest.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2007 - 2024 Joseph Gaeddert + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include "autotest/autotest.h" +#include "liquid.h" + +void autotest_firpfbchr_crcf_config() +{ +#if LIQUID_STRICT_EXIT + AUTOTEST_WARN("skipping firpfbchr_crcf config test with strict exit enabled\n"); + return; +#endif +#if !LIQUID_SUPPRESS_ERROR_OUTPUT + fprintf(stderr,"warning: ignore potential errors here; checking for invalid configurations\n"); +#endif + // design prototype filter + unsigned int h_len = 2*64*12+1; + float h[2*64*12+1]; + liquid_firdes_kaiser(h_len, 0.1f, 60.0f, 0.0f, h); + + // check invalid function calls + CONTEND_ISNULL(firpfbchr_crcf_create( 0, 76, 12, h)) // too few channels + CONTEND_ISNULL(firpfbchr_crcf_create(64, 0, 12, h)) // decimation rate too small + CONTEND_ISNULL(firpfbchr_crcf_create(64, 76, 0, h)) // filter delay too small + CONTEND_ISNULL(firpfbchr_crcf_create(64, 76, 12, NULL)) // coefficients pointer set to NULL + + //CONTEND_ISNULL(firpfbchr_crcf_copy(NULL)) + + // create proper object and test configurations + firpfbchr_crcf q = firpfbchr_crcf_create_kaiser(64, 76, 12, 60.0f); + + CONTEND_EQUALITY(LIQUID_OK, firpfbchr_crcf_print(q)) + + firpfbchr_crcf_destroy(q); +} + From 345203aa5c17a8d30aef49adb17a432450d41022 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Tue, 16 Apr 2024 17:22:04 -0400 Subject: [PATCH 65/97] firpfbchr: adding test methods for create_kaiser() --- src/multichannel/src/firpfbchr.proto.c | 4 ++++ src/multichannel/tests/firpfbchr_crcf_autotest.c | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/src/multichannel/src/firpfbchr.proto.c b/src/multichannel/src/firpfbchr.proto.c index 403cde46a..bcb3d5e30 100644 --- a/src/multichannel/src/firpfbchr.proto.c +++ b/src/multichannel/src/firpfbchr.proto.c @@ -130,8 +130,12 @@ FIRPFBCHR() FIRPFBCHR(_create_kaiser)(unsigned int _chans, // validate input if (_chans < 2) return liquid_error_config("firpfbchr_%s_create_kaiser(), number of channels must be at least 2", EXTENSION_FULL); + if (_decim < 1) + return liquid_error_config("firpfbchr_%s_create_kaiser(), decimation rate must be at least 1", EXTENSION_FULL); if (_m < 1) return liquid_error_config("firpfbchr_%s_create_kaiser(), filter semi-length must be at least 1", EXTENSION_FULL); + if (_as <= 0.0f) + return liquid_error_config("firpfbchr_%s_create_kaiser(), stop-band suppression out of range", EXTENSION_FULL); // design prototype filter unsigned int h_len = 2*_chans*_m+1; diff --git a/src/multichannel/tests/firpfbchr_crcf_autotest.c b/src/multichannel/tests/firpfbchr_crcf_autotest.c index 719f38b8d..a2e390910 100644 --- a/src/multichannel/tests/firpfbchr_crcf_autotest.c +++ b/src/multichannel/tests/firpfbchr_crcf_autotest.c @@ -44,6 +44,12 @@ void autotest_firpfbchr_crcf_config() CONTEND_ISNULL(firpfbchr_crcf_create(64, 76, 0, h)) // filter delay too small CONTEND_ISNULL(firpfbchr_crcf_create(64, 76, 12, NULL)) // coefficients pointer set to NULL + // kaiser + CONTEND_ISNULL(firpfbchr_crcf_create_kaiser( 0, 76, 12, 60.0f)) // too few channels + CONTEND_ISNULL(firpfbchr_crcf_create_kaiser(64, 0, 12, 60.0f)) // decimation rate too small + CONTEND_ISNULL(firpfbchr_crcf_create_kaiser(64, 76, 0, 60.0f)) // filter delay too small + CONTEND_ISNULL(firpfbchr_crcf_create_kaiser(64, 76, 12, -1.0f)) // stop-band suppression out of range + //CONTEND_ISNULL(firpfbchr_crcf_copy(NULL)) // create proper object and test configurations From 2ff55309ef6cba6c7bc666905d458c58f994a50c Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Tue, 16 Apr 2024 17:24:08 -0400 Subject: [PATCH 66/97] firpfbchr: adding tests for access parameters --- src/multichannel/tests/firpfbchr_crcf_autotest.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/multichannel/tests/firpfbchr_crcf_autotest.c b/src/multichannel/tests/firpfbchr_crcf_autotest.c index a2e390910..917e9c79e 100644 --- a/src/multichannel/tests/firpfbchr_crcf_autotest.c +++ b/src/multichannel/tests/firpfbchr_crcf_autotest.c @@ -56,6 +56,9 @@ void autotest_firpfbchr_crcf_config() firpfbchr_crcf q = firpfbchr_crcf_create_kaiser(64, 76, 12, 60.0f); CONTEND_EQUALITY(LIQUID_OK, firpfbchr_crcf_print(q)) + CONTEND_EQUALITY(64, firpfbchr_crcf_get_num_channels(q)) + CONTEND_EQUALITY(76, firpfbchr_crcf_get_decim_rate(q)) + CONTEND_EQUALITY(12, firpfbchr_crcf_get_m(q)) firpfbchr_crcf_destroy(q); } From baa8ac3c7ef7b2510fdd0478b6a868543620c2a1 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Tue, 16 Apr 2024 17:38:50 -0400 Subject: [PATCH 67/97] firpfbchr: adding test for output spectrum --- .../tests/firpfbchr_crcf_autotest.c | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/src/multichannel/tests/firpfbchr_crcf_autotest.c b/src/multichannel/tests/firpfbchr_crcf_autotest.c index 917e9c79e..b2f2a52a8 100644 --- a/src/multichannel/tests/firpfbchr_crcf_autotest.c +++ b/src/multichannel/tests/firpfbchr_crcf_autotest.c @@ -24,6 +24,85 @@ #include "autotest/autotest.h" #include "liquid.h" +void autotest_firpfbchr_crcf() +{ + // options + unsigned int M = 16; // number of channels + unsigned int P = 6; // output decimation rate + unsigned int m = 5; // filter semi-length (symbols) + unsigned int num_blocks=1<<16; // number of symbols + float As = 60.0f; // filter stop-band attenuation + + unsigned int i; + unsigned int channel_id = 3; + + // create filterbank objects from prototype + firpfbchr_crcf qa = firpfbchr_crcf_create_kaiser(M, P, m, As); + firpfbchr_crcf_print(qa); + + // create multi-signal source generator + msourcecf gen = msourcecf_create_default(); + + // add signals (gen, fc, bw, gain, {options}) + msourcecf_add_noise(gen, 0.00f, 1.0f, -60); // wide-band noise + msourcecf_add_noise(gen, -0.30f, 0.1f, -20); // narrow-band noise + msourcecf_add_tone (gen, 0.08f, 0.0f, 0); // tone + // modulated data + msourcecf_add_modem(gen, + (float)channel_id/(float)M, // center frequency + 0.080f, // bandwidth (symbol rate) + -20, // gain + LIQUID_MODEM_QPSK, // modulation scheme + 12, // filter semi-length + 0.3f); // modem parameters + + // create spectral periodogoram + unsigned int nfft = 2400; + spgramcf p0 = spgramcf_create_default(nfft); + spgramcf p1 = spgramcf_create_default(nfft); + + // run channelizer + float complex buf_0[P]; + float complex buf_1[M]; + for (i=0; i Date: Tue, 16 Apr 2024 17:45:48 -0400 Subject: [PATCH 68/97] autotest/psd: adding method to valid psd based on spgramcf object --- autotest/autotest.c | 10 ++++++++++ autotest/autotest.h | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/autotest/autotest.c b/autotest/autotest.c index ccd3cb785..811ea550d 100644 --- a/autotest/autotest.c +++ b/autotest/autotest.c @@ -362,6 +362,16 @@ int liquid_autotest_validate_psd_iirfilt_rrrf(iirfilt_rrrf _q, unsigned int _nff return liquid_autotest_validate_spectrum(psd,_nfft,_regions,num_regions,debug_filename); } +// validate spectral content of a spectral periodogram object +int liquid_autotest_validate_psd_spgramcf(spgramcf _q, + autotest_psd_s * _regions, unsigned int num_regions, const char * debug_filename) +{ + unsigned int nfft = spgramcf_get_nfft(_q); + float psd[nfft]; + spgramcf_get_psd(_q, psd); + return liquid_autotest_validate_spectrum(psd,nfft,_regions,num_regions,debug_filename); +} + // callback function to simplify testing for framing objects int framing_autotest_callback( unsigned char * _header, diff --git a/autotest/autotest.h b/autotest/autotest.h index 5945ab5e2..c961fa66d 100644 --- a/autotest/autotest.h +++ b/autotest/autotest.h @@ -316,6 +316,10 @@ int liquid_autotest_validate_psd_firfilt_cccf(firfilt_cccf _q, unsigned int _nff int liquid_autotest_validate_psd_iirfilt_rrrf(iirfilt_rrrf _q, unsigned int _nfft, autotest_psd_s * _regions, unsigned int num_regions, const char * debug_filename); +// validate spectral content of a spectral periodogram object +int liquid_autotest_validate_psd_spgramcf(spgramcf _q, + autotest_psd_s * _regions, unsigned int num_regions, const char * debug_filename); + // callback function to simplify testing for framing objects #define FRAMING_AUTOTEST_SECRET 0x01234567 int framing_autotest_callback( From e98f1b8eec61d61dc96c49a846877c6fb10257a9 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Tue, 16 Apr 2024 18:53:24 -0400 Subject: [PATCH 69/97] firpfbchr: extending test to include multiple output spectra --- .../tests/firpfbchr_crcf_autotest.c | 82 +++++++++++-------- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/src/multichannel/tests/firpfbchr_crcf_autotest.c b/src/multichannel/tests/firpfbchr_crcf_autotest.c index b2f2a52a8..e12acb018 100644 --- a/src/multichannel/tests/firpfbchr_crcf_autotest.c +++ b/src/multichannel/tests/firpfbchr_crcf_autotest.c @@ -29,13 +29,10 @@ void autotest_firpfbchr_crcf() // options unsigned int M = 16; // number of channels unsigned int P = 6; // output decimation rate - unsigned int m = 5; // filter semi-length (symbols) + unsigned int m = 12; // filter semi-length (symbols) unsigned int num_blocks=1<<16; // number of symbols float As = 60.0f; // filter stop-band attenuation - unsigned int i; - unsigned int channel_id = 3; - // create filterbank objects from prototype firpfbchr_crcf qa = firpfbchr_crcf_create_kaiser(M, P, m, As); firpfbchr_crcf_print(qa); @@ -43,27 +40,29 @@ void autotest_firpfbchr_crcf() // create multi-signal source generator msourcecf gen = msourcecf_create_default(); - // add signals (gen, fc, bw, gain, {options}) - msourcecf_add_noise(gen, 0.00f, 1.0f, -60); // wide-band noise - msourcecf_add_noise(gen, -0.30f, 0.1f, -20); // narrow-band noise - msourcecf_add_tone (gen, 0.08f, 0.0f, 0); // tone + // add signals (gen, fc, bw, gain, {options}) + msourcecf_add_noise(gen, 0.00f, 1.00f, -60); // wide-band noise + msourcecf_add_noise(gen, -0.30f, 0.10f, -20); // narrow-band noise + msourcecf_add_noise(gen, 0.08f, 0.01f, -30); // very narrow-band noise // modulated data msourcecf_add_modem(gen, - (float)channel_id/(float)M, // center frequency - 0.080f, // bandwidth (symbol rate) - -20, // gain - LIQUID_MODEM_QPSK, // modulation scheme - 12, // filter semi-length - 0.3f); // modem parameters + 0.1875f, // center frequency + 0.065f, // bandwidth (symbol rate) + -20, // gain + LIQUID_MODEM_QPSK, // modulation scheme + 12, // filter semi-length + 0.3f); // modem parameters // create spectral periodogoram unsigned int nfft = 2400; spgramcf p0 = spgramcf_create_default(nfft); - spgramcf p1 = spgramcf_create_default(nfft); + spgramcf c1 = spgramcf_create_default(nfft); + spgramcf c3 = spgramcf_create_default(nfft); // run channelizer float complex buf_0[P]; float complex buf_1[M]; + unsigned int i; for (i=0; i Date: Wed, 17 Apr 2024 08:14:04 -0400 Subject: [PATCH 70/97] firdes/autotest: checking edge cases in create() for arkaiser, rkaiser --- src/filter/tests/firdes_autotest.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/filter/tests/firdes_autotest.c b/src/filter/tests/firdes_autotest.c index 4fb7a9474..c2d4e6976 100644 --- a/src/filter/tests/firdes_autotest.c +++ b/src/filter/tests/firdes_autotest.c @@ -236,15 +236,19 @@ void autotest_liquid_firdes_config() CONTEND_EQUALITY(liquid_firdes_windowf(wtype, h_len, 0.0f, 0, h), LIQUID_EICONFIG); CONTEND_EQUALITY(liquid_firdes_windowf(wtype, h_len, 0.6f, 0, h), LIQUID_EICONFIG); - CONTEND_EQUALITY(liquid_firdes_rkaiser(0, 12, 0.2f, 0, NULL), LIQUID_EICONFIG); - CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 0, 0.2f, 0, NULL), LIQUID_EICONFIG); - CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 2.7f, 0, NULL), LIQUID_EICONFIG); - CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 0.2f, 3, NULL), LIQUID_EICONFIG); - - CONTEND_EQUALITY(liquid_firdes_arkaiser(0, 12, 0.2f, 0, NULL), LIQUID_EICONFIG); - CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 0, 0.2f, 0, NULL), LIQUID_EICONFIG); - CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 2.7f, 0, NULL), LIQUID_EICONFIG); - CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 0.2f, 3, NULL), LIQUID_EICONFIG); + CONTEND_EQUALITY(liquid_firdes_rkaiser(0, 12, 0.2f, 0, NULL), LIQUID_EICONFIG); // k too small + CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 0, 0.2f, 0, NULL), LIQUID_EICONFIG); // m too small + CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12,-0.7f, 0, NULL), LIQUID_EICONFIG); // beta too small + CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 2.7f, 0, NULL), LIQUID_EICONFIG); // beta too large + CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 0.2f,-2, NULL), LIQUID_EICONFIG); // dt too small + CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 0.2f, 3, NULL), LIQUID_EICONFIG); // dt too large + + CONTEND_EQUALITY(liquid_firdes_arkaiser(0, 12, 0.2f, 0, NULL), LIQUID_EICONFIG); // k too small + CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 0, 0.2f, 0, NULL), LIQUID_EICONFIG); // m too small + CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12,-0.7f, 0, NULL), LIQUID_EICONFIG); // beta too small + CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 2.7f, 0, NULL), LIQUID_EICONFIG); // beta too large + CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 0.2f,-2, NULL), LIQUID_EICONFIG); // dt too small + CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 0.2f, 3, NULL), LIQUID_EICONFIG); // dt too large CONTEND_EQUALITY(liquid_firdes_kaiser(h_len, 0.2f, 60.0f, 0.0f, h), LIQUID_OK ); CONTEND_EQUALITY(liquid_firdes_kaiser( 0, 0.2f, 60.0f, 0.0f, h), LIQUID_EICONFIG); From 34977c8d4017150315e2a61e0cc85c0b740b4258 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Wed, 17 Apr 2024 17:31:01 -0400 Subject: [PATCH 71/97] firdes/autotest: checking rkaiser for spectral response --- src/filter/tests/firdes_autotest.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/filter/tests/firdes_autotest.c b/src/filter/tests/firdes_autotest.c index c2d4e6976..ae0f5d77d 100644 --- a/src/filter/tests/firdes_autotest.c +++ b/src/filter/tests/firdes_autotest.c @@ -93,15 +93,17 @@ void autotest_liquid_firdes_rrcos() { void autotest_liquid_firdes_rkaiser() { // Initialize variables - unsigned int k=2, m=3; + unsigned int k=2, m=10; float beta=0.3f; float offset=0.0f; - float isi_test = -30.0f; + float isi_test = -60.0f; // Create filter unsigned int h_len = 2*k*m+1; float h[h_len]; liquid_firdes_rkaiser(k,m,beta,offset,h); + // scale by samples per symbol + liquid_vectorf_mulscalar(h, h_len, 1.0f/(float)k, h); // compute filter ISI float isi_max; @@ -115,6 +117,15 @@ void autotest_liquid_firdes_rkaiser() // ensure ISI is sufficiently small CONTEND_LESS_THAN(isi_max, isi_test); CONTEND_LESS_THAN(isi_rms, isi_test); + + // verify spectrum + autotest_psd_s regions[] = { + {.fmin=-0.50, .fmax=-0.35f, .pmin= 0, .pmax=-70, .test_lo=0, .test_hi=1}, + {.fmin=-0.20, .fmax= 0.20f, .pmin=-1, .pmax= +1, .test_lo=1, .test_hi=1}, + {.fmin= 0.35, .fmax= 0.50f, .pmin= 0, .pmax=-70, .test_lo=0, .test_hi=1}, + }; + liquid_autotest_validate_psd_signalf(h, h_len, regions, 3, + liquid_autotest_verbose ? "autotest/logs/firdes_rkaiser.m" : NULL); } void autotest_liquid_firdes_dcblock() @@ -319,7 +330,7 @@ void testbench_firdes_prototype(const char * _type, // scale by samples per symbol liquid_vectorf_mulscalar(h, h_len, 1.0f/(float)_k, h); - // verify interpolated spectrum + // verify spectrum float bw = 1.0f / (float)_k; float f0 = 0.45*bw*(1-_beta); float f1 = 0.55*bw*(1+_beta); From 78dd6dcb982b98ef943347cad61cebb5f90dfe6d Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Wed, 17 Apr 2024 17:42:11 -0400 Subject: [PATCH 72/97] firdes/autotest: testing frequency response for rnyquist filters --- src/filter/tests/firdes_autotest.c | 42 +++++++++++++++++------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/filter/tests/firdes_autotest.c b/src/filter/tests/firdes_autotest.c index ae0f5d77d..6de829079 100644 --- a/src/filter/tests/firdes_autotest.c +++ b/src/filter/tests/firdes_autotest.c @@ -89,45 +89,51 @@ void autotest_liquid_firdes_rrcos() { CONTEND_DELTA( h[i], h0[i], 0.00001f ); } - -void autotest_liquid_firdes_rkaiser() +void test_harness_matched_filter(int _type, + unsigned int _k, + unsigned int _m, + float _beta, + float _tol_isi, + float _tol_as) { - // Initialize variables - unsigned int k=2, m=10; - float beta=0.3f; - float offset=0.0f; - float isi_test = -60.0f; - // Create filter - unsigned int h_len = 2*k*m+1; + unsigned int h_len = 2*_k*_m+1; float h[h_len]; - liquid_firdes_rkaiser(k,m,beta,offset,h); + liquid_firdes_prototype(_type,_k,_m,_beta,0.0f,h); + // scale by samples per symbol - liquid_vectorf_mulscalar(h, h_len, 1.0f/(float)k, h); + liquid_vectorf_mulscalar(h, h_len, 1.0f/(float)_k, h); // compute filter ISI float isi_max; float isi_rms; - liquid_filter_isi(h,k,m,&isi_rms,&isi_max); + liquid_filter_isi(h,_k,_m,&isi_rms,&isi_max); // convert to log scale isi_max = 20*log10f(isi_max); isi_rms = 20*log10f(isi_rms); // ensure ISI is sufficiently small - CONTEND_LESS_THAN(isi_max, isi_test); - CONTEND_LESS_THAN(isi_rms, isi_test); + CONTEND_LESS_THAN(isi_max, _tol_isi); + CONTEND_LESS_THAN(isi_rms, _tol_isi); // verify spectrum autotest_psd_s regions[] = { - {.fmin=-0.50, .fmax=-0.35f, .pmin= 0, .pmax=-70, .test_lo=0, .test_hi=1}, - {.fmin=-0.20, .fmax= 0.20f, .pmin=-1, .pmax= +1, .test_lo=1, .test_hi=1}, - {.fmin= 0.35, .fmax= 0.50f, .pmin= 0, .pmax=-70, .test_lo=0, .test_hi=1}, + {.fmin=-0.50, .fmax=-0.35f, .pmin= 0, .pmax=_tol_as, .test_lo=0, .test_hi=1}, + {.fmin=-0.20, .fmax= 0.20f, .pmin=-1, .pmax= +1, .test_lo=1, .test_hi=1}, + {.fmin= 0.35, .fmax= 0.50f, .pmin= 0, .pmax=_tol_as, .test_lo=0, .test_hi=1}, }; + char filename[256]; + sprintf(filename,"autotest/logs/firdes_%s.m", liquid_firfilt_type_str[_type][0]); liquid_autotest_validate_psd_signalf(h, h_len, regions, 3, - liquid_autotest_verbose ? "autotest/logs/firdes_rkaiser.m" : NULL); + liquid_autotest_verbose ? filename : NULL); } +// test matched filter responses for square-root nyquist filter prototypes +void autotest_firdes_rrcos () { test_harness_matched_filter(LIQUID_FIRFILT_RRC, 2, 10, 0.3f, -60.0f, -40.0f); } +void autotest_firdes_rkaiser () { test_harness_matched_filter(LIQUID_FIRFILT_RKAISER, 2, 10, 0.3f, -60.0f, -70.0f); } +void autotest_firdes_arkaiser() { test_harness_matched_filter(LIQUID_FIRFILT_ARKAISER,2, 10, 0.3f, -60.0f, -70.0f); } + void autotest_liquid_firdes_dcblock() { // options From 831ebb447de8f39d1e5e377edcc471f5fd041806 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 20 Apr 2024 17:02:52 -0400 Subject: [PATCH 73/97] rkaiser: moving tests to separate package --- include/liquid.internal.h | 16 ---------- makefile.in | 1 + src/filter/src/rkaiser.c | 29 ++++------------- src/filter/tests/firdes_autotest.c | 26 +++------------ src/filter/tests/rkaiser_autotest.c | 49 +++++++++++++++++++++++++++++ 5 files changed, 60 insertions(+), 61 deletions(-) create mode 100644 src/filter/tests/rkaiser_autotest.c diff --git a/include/liquid.internal.h b/include/liquid.internal.h index 15f08c1e5..b35d2a643 100644 --- a/include/liquid.internal.h +++ b/include/liquid.internal.h @@ -794,22 +794,6 @@ float estimate_req_filter_len_Herrmann(float _df, float rkaiser_approximate_rho(unsigned int _m, float _beta); -// Design frequency-shifted root-Nyquist filter based on -// the Kaiser-windowed sinc using the bisection method -// -// _k : filter over-sampling rate (samples/symbol) -// _m : filter delay (symbols) -// _beta : filter excess bandwidth factor (0,1) -// _dt : filter fractional sample delay -// _h : resulting filter, [size: 2*_k*_m+1] -// _rho : transition bandwidth adjustment, 0 < _rho < 1 -int liquid_firdes_rkaiser_bisection(unsigned int _k, - unsigned int _m, - float _beta, - float _dt, - float * _h, - float * _rho); - // Design frequency-shifted root-Nyquist filter based on // the Kaiser-windowed sinc using the quadratic method. // diff --git a/makefile.in b/makefile.in index 1daf4d5d7..e8b69fa61 100644 --- a/makefile.in +++ b/makefile.in @@ -536,6 +536,7 @@ filter_autotests := \ src/filter/tests/rresamp_crcf_partition_autotest.c \ src/filter/tests/resamp_crcf_autotest.c \ src/filter/tests/resamp2_crcf_autotest.c \ + src/filter/tests/rkaiser_autotest.c \ src/filter/tests/symsync_copy_autotest.c \ src/filter/tests/symsync_crcf_autotest.c \ src/filter/tests/symsync_rrrf_autotest.c \ diff --git a/src/filter/src/rkaiser.c b/src/filter/src/rkaiser.c index 845439765..538783703 100644 --- a/src/filter/src/rkaiser.c +++ b/src/filter/src/rkaiser.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -62,7 +62,6 @@ int liquid_firdes_rkaiser(unsigned int _k, // simply call internal method and ignore output rho value float rho; - //liquid_firdes_rkaiser_bisection(_k,_m,_beta,_dt,_h,&rho); return liquid_firdes_rkaiser_quadratic(_k,_m,_beta,_dt,_h,&rho); } @@ -90,29 +89,18 @@ int liquid_firdes_arkaiser(unsigned int _k, if (_dt < -1.0f || _dt > 1.0f) return liquid_error(LIQUID_EICONFIG,"liquid_firdes_arkaiser(), dt must be in [-1,1]"); -#if 0 - // compute bandwidth adjustment estimate - float rho_hat = rkaiser_approximate_rho(_m,_beta); // bandwidth correction factor -#else - // rho ~ c0 + c1*log(_beta) + c2*log^2(_beta) - - // c0 ~ 0.762886 + 0.067663*log(m) - // c1 ~ 0.065515 - // c2 ~ log( 1 - 0.088*m^-1.6 ) - + // compute bandwidth correction factor, rho ~ c0 + c1*log(_beta) + c2*log^2(_beta) float c0 = 0.762886 + 0.067663*logf(_m); float c1 = 0.065515; float c2 = logf( 1 - 0.088*powf(_m,-1.6 ) ); - float log_beta = logf(_beta); - float rho_hat = c0 + c1*log_beta + c2*log_beta*log_beta; - // ensure range is valid + // ensure range is valid and override if approximation is out of range if (rho_hat <= 0.0f || rho_hat >= 1.0f) rho_hat = rkaiser_approximate_rho(_m,_beta); -#endif + // compute filter design parameters unsigned int n=2*_k*_m+1; // filter length float kf = (float)_k; // samples/symbol (float) float del = _beta*rho_hat / kf; // transition bandwidth @@ -199,6 +187,7 @@ float rkaiser_approximate_rho(unsigned int _m, return rho_hat; } +#if 0 // Design frequency-shifted root-Nyquist filter based on // the Kaiser-windowed sinc. // @@ -317,6 +306,7 @@ int liquid_firdes_rkaiser_bisection(unsigned int _k, *_rho = x_hat; return LIQUID_OK; } +#endif // Design frequency-shifted root-Nyquist filter based on // the Kaiser-windowed sinc using the quadratic search method. @@ -334,13 +324,6 @@ int liquid_firdes_rkaiser_quadratic(unsigned int _k, float * _h, float * _rho) { - if ( _k < 1 ) - return liquid_error(LIQUID_EICONFIG,"liquid_firdes_rkaiser_quadratic(): k must be greater than 0"); - if ( _m < 1 ) - return liquid_error(LIQUID_EICONFIG,"liquid_firdes_rkaiser_quadratic(): m must be greater than 0"); - if ( (_beta < 0.0f) || (_beta > 1.0f) ) - return liquid_error(LIQUID_EICONFIG,"liquid_firdes_rkaiser_quadratic(): beta must be in [0,1]"); - // algorithm: // 1. choose initial bounding points [x0,x2] where x0 < x2 // 2. choose x1 as bisection of [x0,x2]: x1 = 0.5*(x0+x2) diff --git a/src/filter/tests/firdes_autotest.c b/src/filter/tests/firdes_autotest.c index 6de829079..527bd0dfa 100644 --- a/src/filter/tests/firdes_autotest.c +++ b/src/filter/tests/firdes_autotest.c @@ -109,15 +109,11 @@ void test_harness_matched_filter(int _type, float isi_rms; liquid_filter_isi(h,_k,_m,&isi_rms,&isi_max); - // convert to log scale - isi_max = 20*log10f(isi_max); - isi_rms = 20*log10f(isi_rms); + // ensure ISI is sufficiently small (log scale) + CONTEND_LESS_THAN(20*log10f(isi_max), _tol_isi); + CONTEND_LESS_THAN(20*log10f(isi_rms), _tol_isi); - // ensure ISI is sufficiently small - CONTEND_LESS_THAN(isi_max, _tol_isi); - CONTEND_LESS_THAN(isi_rms, _tol_isi); - - // verify spectrum + // verify spectrum response autotest_psd_s regions[] = { {.fmin=-0.50, .fmax=-0.35f, .pmin= 0, .pmax=_tol_as, .test_lo=0, .test_hi=1}, {.fmin=-0.20, .fmax= 0.20f, .pmin=-1, .pmax= +1, .test_lo=1, .test_hi=1}, @@ -253,20 +249,6 @@ void autotest_liquid_firdes_config() CONTEND_EQUALITY(liquid_firdes_windowf(wtype, h_len, 0.0f, 0, h), LIQUID_EICONFIG); CONTEND_EQUALITY(liquid_firdes_windowf(wtype, h_len, 0.6f, 0, h), LIQUID_EICONFIG); - CONTEND_EQUALITY(liquid_firdes_rkaiser(0, 12, 0.2f, 0, NULL), LIQUID_EICONFIG); // k too small - CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 0, 0.2f, 0, NULL), LIQUID_EICONFIG); // m too small - CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12,-0.7f, 0, NULL), LIQUID_EICONFIG); // beta too small - CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 2.7f, 0, NULL), LIQUID_EICONFIG); // beta too large - CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 0.2f,-2, NULL), LIQUID_EICONFIG); // dt too small - CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 0.2f, 3, NULL), LIQUID_EICONFIG); // dt too large - - CONTEND_EQUALITY(liquid_firdes_arkaiser(0, 12, 0.2f, 0, NULL), LIQUID_EICONFIG); // k too small - CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 0, 0.2f, 0, NULL), LIQUID_EICONFIG); // m too small - CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12,-0.7f, 0, NULL), LIQUID_EICONFIG); // beta too small - CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 2.7f, 0, NULL), LIQUID_EICONFIG); // beta too large - CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 0.2f,-2, NULL), LIQUID_EICONFIG); // dt too small - CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 0.2f, 3, NULL), LIQUID_EICONFIG); // dt too large - CONTEND_EQUALITY(liquid_firdes_kaiser(h_len, 0.2f, 60.0f, 0.0f, h), LIQUID_OK ); CONTEND_EQUALITY(liquid_firdes_kaiser( 0, 0.2f, 60.0f, 0.0f, h), LIQUID_EICONFIG); CONTEND_EQUALITY(liquid_firdes_kaiser(h_len,-0.1f, 60.0f, 0.0f, h), LIQUID_EICONFIG); diff --git a/src/filter/tests/rkaiser_autotest.c b/src/filter/tests/rkaiser_autotest.c new file mode 100644 index 000000000..ce14167c7 --- /dev/null +++ b/src/filter/tests/rkaiser_autotest.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2007 - 2024 Joseph Gaeddert + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "autotest/autotest.h" +#include "liquid.internal.h" + +void autotest_liquid_rkaiser_config() +{ +#if LIQUID_STRICT_EXIT + AUTOTEST_WARN("skipping config test with strict exit enabled\n"); + return; +#endif +#if !LIQUID_SUPPRESS_ERROR_OUTPUT + fprintf(stderr,"warning: ignore potential errors here; checking for invalid configurations\n"); +#endif + CONTEND_EQUALITY(liquid_firdes_rkaiser(0, 12, 0.2f, 0, NULL), LIQUID_EICONFIG); // k too small + CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 0, 0.2f, 0, NULL), LIQUID_EICONFIG); // m too small + CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12,-0.7f, 0, NULL), LIQUID_EICONFIG); // beta too small + CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 2.7f, 0, NULL), LIQUID_EICONFIG); // beta too large + CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 0.2f,-2, NULL), LIQUID_EICONFIG); // dt too small + CONTEND_EQUALITY(liquid_firdes_rkaiser(2, 12, 0.2f, 3, NULL), LIQUID_EICONFIG); // dt too large + + CONTEND_EQUALITY(liquid_firdes_arkaiser(0, 12, 0.2f, 0, NULL), LIQUID_EICONFIG); // k too small + CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 0, 0.2f, 0, NULL), LIQUID_EICONFIG); // m too small + CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12,-0.7f, 0, NULL), LIQUID_EICONFIG); // beta too small + CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 2.7f, 0, NULL), LIQUID_EICONFIG); // beta too large + CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 0.2f,-2, NULL), LIQUID_EICONFIG); // dt too small + CONTEND_EQUALITY(liquid_firdes_arkaiser(2, 12, 0.2f, 3, NULL), LIQUID_EICONFIG); // dt too large +} + From 7d685087f92c2667067a4dbe91cc60ded8c9cef2 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 20 Apr 2024 17:52:47 -0400 Subject: [PATCH 74/97] cleaning up print statements, reducing verbosity --- src/audio/src/cvsd.c | 9 ++++---- src/buffer/src/cbuffer.proto.c | 11 ++-------- src/buffer/src/wdelay.proto.c | 11 ++-------- src/buffer/tests/window_autotest.c | 11 +--------- src/equalization/src/eqlms.proto.c | 5 ----- src/fft/src/spwaterfall.proto.c | 4 ++-- src/filter/src/dds.proto.c | 27 ++++++++++------------- src/filter/src/firdespm.c | 31 +++++++++++++-------------- src/filter/src/firfilt.proto.c | 21 ++++-------------- src/multichannel/src/firpfbch.proto.c | 11 ++++------ 10 files changed, 45 insertions(+), 96 deletions(-) diff --git a/src/audio/src/cvsd.c b/src/audio/src/cvsd.c index 11f3218dd..1c62fda02 100644 --- a/src/audio/src/cvsd.c +++ b/src/audio/src/cvsd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2021 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -112,12 +112,11 @@ int cvsd_destroy(cvsd _q) // print cvsd object parameters int cvsd_print(cvsd _q) { - printf("cvsd codec:\n"); - printf(" num bits: %u\n", _q->num_bits); - printf(" zeta : %8.4f\n", _q->zeta); + printf("num_bits, _q->zeta); #if CVSD_ENABLE_SIGNAL_CONDITIONING - printf(" alpha : %8.4f\n", _q->alpha); + printf(", alpha=%g", _q->alpha); #endif + printf(">\n"); return LIQUID_OK; } diff --git a/src/buffer/src/cbuffer.proto.c b/src/buffer/src/cbuffer.proto.c index f7d8e5928..5e13ceb9b 100644 --- a/src/buffer/src/cbuffer.proto.c +++ b/src/buffer/src/cbuffer.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -123,18 +123,11 @@ int CBUFFER(_destroy)(CBUFFER() _q) // print cbuffer object properties int CBUFFER(_print)(CBUFFER() _q) { - printf("cbuffer%s [max size: %u, max read: %u, elements: %u]\n", + printf("\n", EXTENSION, _q->max_size, _q->max_read, _q->num_elements); - - unsigned int i; - for (i=0; i<_q->num_elements; i++) { - printf("%u", i); - BUFFER_PRINT_LINE(_q,(_q->read_index+i)%(_q->max_size)) - printf("\n"); - } return LIQUID_OK; } diff --git a/src/buffer/src/wdelay.proto.c b/src/buffer/src/wdelay.proto.c index 71f694058..243cba317 100644 --- a/src/buffer/src/wdelay.proto.c +++ b/src/buffer/src/wdelay.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -116,14 +116,7 @@ int WDELAY(_destroy)(WDELAY() _q) // print delay buffer object's state to stdout int WDELAY(_print)(WDELAY() _q) { - printf("wdelay [%u elements] :\n", _q->delay+1); - unsigned int i, j; - for (i=0; i<_q->delay+1; i++) { - j = (i + _q->read_index) % (_q->delay+1); - printf("%4u", i); - BUFFER_PRINT_VALUE(_q->v[j]); - printf("\n"); - } + printf("\n", _q->delay); return LIQUID_OK; } diff --git a/src/buffer/tests/window_autotest.c b/src/buffer/tests/window_autotest.c index 3ad6fd7d9..96a8be087 100644 --- a/src/buffer/tests/window_autotest.c +++ b/src/buffer/tests/window_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2021 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -138,15 +138,6 @@ void autotest_windowf() windowf_read(w, &r); CONTEND_SAME_DATA(r,test8,10*sizeof(float)); - if (liquid_autotest_verbose) { - // manual print - printf("manual output:\n"); - for (i=0; i<10; i++) - printf("%6u : %f\n", i, r[i]); - - windowf_debug_print(w); - } - windowf_destroy(w); } diff --git a/src/equalization/src/eqlms.proto.c b/src/equalization/src/eqlms.proto.c index 9737adb44..780b3b0fa 100644 --- a/src/equalization/src/eqlms.proto.c +++ b/src/equalization/src/eqlms.proto.c @@ -236,11 +236,6 @@ int EQLMS(_reset)(EQLMS() _q) int EQLMS(_print)(EQLMS() _q) { printf("\n", EXTENSION_FULL, _q->h_len, _q->mu); - unsigned int i, j; - for (i=0; i<_q->h_len; i++) { - j = _q->h_len - i - 1; - printf(" w[%3u] = %12.4e + j*%12.4e;\n", i, creal(_q->w0[j]), cimag(_q->w0[j])); - } return LIQUID_OK; } diff --git a/src/fft/src/spwaterfall.proto.c b/src/fft/src/spwaterfall.proto.c index 38f1fda52..e47783acd 100644 --- a/src/fft/src/spwaterfall.proto.c +++ b/src/fft/src/spwaterfall.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -196,7 +196,7 @@ int SPWATERFALL(_reset)(SPWATERFALL() _q) // prints the spwaterfall object's parameters int SPWATERFALL(_print)(SPWATERFALL() _q) { - printf("spwaterfall%s: nfft=%u, time=%u\n", EXTENSION, _q->nfft, _q->time); + printf("\n", EXTENSION, _q->nfft, _q->time); return LIQUID_OK; } diff --git a/src/filter/src/dds.proto.c b/src/filter/src/dds.proto.c index cbd88826d..2fce7cbd9 100644 --- a/src/filter/src/dds.proto.c +++ b/src/filter/src/dds.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -205,22 +205,17 @@ int DDS(_destroy)(DDS() _q) // print dds object internals int DDS(_print)(DDS() _q) { - printf("direct digital synthesizer (dds), rate : %u\n", _q->rate); - printf(" fc : %8.5f\n", _q->fc0); - printf(" bw : %8.5f\n", _q->bw0); - printf(" nco/f : %8.4f\n", nco_crcf_get_frequency(_q->ncox) / (2.0f*M_PI)); - printf(" as : %8.2f [dB]\n", _q->as0); - printf(" halfband stages (low rate -> high rate) :\n"); + printf("rate, + _q->fc0, + _q->bw0, + nco_crcf_get_frequency(_q->ncox) / (2.0f*M_PI), + _q->as0, + _q->num_stages); unsigned int i; - for (i=0; i<_q->num_stages; i++) { - printf(" [%3u] : fc = %8.5f, ft = %8.5f, m = %3u\n", - i, - _q->fc[i], - _q->ft[i], - _q->m[i]); - //RESAMP2(_print)(_q->halfband_resamp[i]); - } - printf(" complexity : %12.4f\n",0.0f); + for (i=0; i<_q->num_stages; i++) + printf("{fc=%.5f, ft=%.5f, m=%u},",_q->fc[i],_q->ft[i],_q->m[i]); + printf("]>\n"); return LIQUID_OK; } diff --git a/src/filter/src/firdespm.c b/src/filter/src/firdespm.c index 00b19439b..c7e942a26 100644 --- a/src/filter/src/firdespm.c +++ b/src/filter/src/firdespm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -466,26 +466,25 @@ int firdespm_destroy(firdespm _q) int firdespm_print(firdespm _q) { unsigned int i; + printf("num_bands; i++) printf(" band %-5u", i); - printf("\n"); + printf(", lo=["); + for (i=0; i<_q->num_bands; i++) printf("%g,", _q->bands[2*i+0]); + printf("]"); - printf(" lower band edge "); - for (i=0; i<_q->num_bands; i++) printf("%16.8f", _q->bands[2*i+0]); - printf("\n"); + printf(", hi=["); + for (i=0; i<_q->num_bands; i++) printf("%g,", _q->bands[2*i+1]); + printf("]"); - printf(" upper band edge "); - for (i=0; i<_q->num_bands; i++) printf("%16.8f", _q->bands[2*i+1]); - printf("\n"); + printf(", des=["); + for (i=0; i<_q->num_bands; i++) printf("%g,", _q->des[i]); + printf("]"); - printf(" desired value "); - for (i=0; i<_q->num_bands; i++) printf("%16.8f", _q->des[i]); - printf("\n"); + printf(", w=["); + for (i=0; i<_q->num_bands; i++) printf("%g,", _q->weights[i]); + printf("]"); - printf(" weighting "); - for (i=0; i<_q->num_bands; i++) printf("%16.8f", _q->weights[i]); - printf("\n"); + printf(">\n"); return LIQUID_OK; } diff --git a/src/filter/src/firfilt.proto.c b/src/filter/src/firfilt.proto.c index aaea94b29..c7b09e4d4 100644 --- a/src/filter/src/firfilt.proto.c +++ b/src/filter/src/firfilt.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -348,23 +348,10 @@ int FIRFILT(_reset)(FIRFILT() _q) // print filter object internals (taps, buffer) int FIRFILT(_print)(FIRFILT() _q) { - printf("firfilt_%s:\n", EXTENSION_FULL); - unsigned int i; - unsigned int n = _q->h_len; - for (i=0; ih_len); + printf(", scale="); PRINTVAL_TC(_q->scale,%12.8f); - printf("\n"); - -#if LIQUID_FIRFILT_USE_WINDOW - WINDOW(_print)(_q->w); -#endif + printf(">\n"); return LIQUID_OK; } diff --git a/src/multichannel/src/firpfbch.proto.c b/src/multichannel/src/firpfbch.proto.c index 0683c3a1a..9e80f450a 100644 --- a/src/multichannel/src/firpfbch.proto.c +++ b/src/multichannel/src/firpfbch.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -263,12 +263,9 @@ int FIRPFBCH(_reset)(FIRPFBCH() _q) // print firpfbch object int FIRPFBCH(_print)(FIRPFBCH() _q) { - unsigned int i; - printf("firpfbch (%s) [%u channels]:\n", - _q->type == LIQUID_ANALYZER ? "analyzer" : "synthesizer", - _q->num_channels); - for (i=0; i<_q->h_len; i++) - printf(" h[%3u] = %12.8f + %12.8f*j\n", i, crealf(_q->h[i]), cimagf(_q->h[i])); + printf("\n", + _q->type == LIQUID_ANALYZER ? "analyzer" : "synthesizer", + _q->num_channels); return LIQUID_OK; } From be241bcc84b390649f73167467221809d8fb12be Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 08:30:41 -0400 Subject: [PATCH 75/97] ofdmflexframe: reducing print() verbosity --- src/framing/src/ofdmflexframegen.c | 43 ++++++----------------------- src/framing/src/ofdmflexframesync.c | 23 +++++++-------- 2 files changed, 19 insertions(+), 47 deletions(-) diff --git a/src/framing/src/ofdmflexframegen.c b/src/framing/src/ofdmflexframegen.c index 90191a814..6fa6b8ab0 100644 --- a/src/framing/src/ofdmflexframegen.c +++ b/src/framing/src/ofdmflexframegen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,11 +20,7 @@ * THE SOFTWARE. */ -// -// ofdmflexframegen.c -// // OFDM flexible frame generator -// #include #include @@ -273,35 +269,14 @@ int ofdmflexframegen_is_assembled(ofdmflexframegen _q) int ofdmflexframegen_print(ofdmflexframegen _q) { - printf("ofdmflexframegen:\n"); - printf(" num subcarriers : %-u\n", _q->M); - printf(" * NULL : %-u\n", _q->M_null); - printf(" * pilot : %-u\n", _q->M_pilot); - printf(" * data : %-u\n", _q->M_data); - printf(" cyclic prefix len : %-u\n", _q->cp_len); - printf(" taper len : %-u\n", _q->taper_len); - printf(" properties:\n"); - printf(" * mod scheme : %s\n", modulation_types[_q->props.mod_scheme].fullname); - printf(" * fec (inner) : %s\n", fec_scheme_str[_q->props.fec0][1]); - printf(" * fec (outer) : %s\n", fec_scheme_str[_q->props.fec1][1]); - printf(" * CRC scheme : %s\n", crc_scheme_str[_q->props.check][1]); - printf(" frame assembled : %s\n", _q->frame_assembled ? "yes" : "no"); - if (_q->frame_assembled) { - printf(" payload:\n"); - printf(" * decoded bytes : %-u\n", _q->payload_dec_len); - printf(" * encoded bytes : %-u\n", _q->payload_enc_len); - printf(" * modulated syms : %-u\n", _q->payload_mod_len); - printf(" total OFDM symbols : %-u\n", ofdmflexframegen_getframelen(_q)); - printf(" * S0 symbols : %-u @ %u\n", 2, _q->M+_q->cp_len); - printf(" * S1 symbols : %-u @ %u\n", 1, _q->M+_q->cp_len); - printf(" * header symbols : %-u @ %u\n", _q->num_symbols_header, _q->M+_q->cp_len); - printf(" * payload symbols : %-u @ %u\n", _q->num_symbols_payload, _q->M+_q->cp_len); - - // compute asymptotic spectral efficiency - unsigned int num_bits = 8*_q->payload_dec_len; - unsigned int num_samples = (_q->M+_q->cp_len)*(3 + _q->num_symbols_header + _q->num_symbols_payload); - printf(" spectral efficiency : %-6.4f b/s/Hz\n", (float)num_bits / (float)num_samples); - } + printf("M); + printf(", null=%u", _q->M_null); + printf(", pilot=%u", _q->M_pilot); + printf(", data=%u", _q->M_data); + printf(", cp=%u", _q->cp_len); + printf(", taper=%u", _q->taper_len); + printf(">\n"); return LIQUID_OK; } diff --git a/src/framing/src/ofdmflexframesync.c b/src/framing/src/ofdmflexframesync.c index 44f9fcedc..92b6c1fab 100644 --- a/src/framing/src/ofdmflexframesync.c +++ b/src/framing/src/ofdmflexframesync.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,11 +20,7 @@ * THE SOFTWARE. */ -// -// ofdmflexframesync.c -// // OFDM frame synchronizer -// #include #include @@ -243,14 +239,15 @@ int ofdmflexframesync_destroy(ofdmflexframesync _q) int ofdmflexframesync_print(ofdmflexframesync _q) { - printf("ofdmflexframesync:\n"); - printf(" num subcarriers : %-u\n", _q->M); - printf(" * NULL : %-u\n", _q->M_null); - printf(" * pilot : %-u\n", _q->M_pilot); - printf(" * data : %-u\n", _q->M_data); - printf(" cyclic prefix len : %-u\n", _q->cp_len); - printf(" taper len : %-u\n", _q->taper_len); - return framedatastats_print(&_q->framedatastats); + printf("M); + printf(", null=%u", _q->M_null); + printf(", pilot=%u", _q->M_pilot); + printf(", data=%u", _q->M_data); + printf(", cp=%u", _q->cp_len); + printf(", taper=%u", _q->taper_len); + printf(">\n"); + return LIQUID_OK; } int ofdmflexframesync_set_header_len(ofdmflexframesync _q, From a11dd45fdfd99eb0e780776252e6bf19e542d1d0 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 08:47:36 -0400 Subject: [PATCH 76/97] qdsync: cleaning print() method --- src/framing/src/qdsync.proto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/framing/src/qdsync.proto.c b/src/framing/src/qdsync.proto.c index 0ec0877f6..a2c0b5dea 100644 --- a/src/framing/src/qdsync.proto.c +++ b/src/framing/src/qdsync.proto.c @@ -176,7 +176,7 @@ int QDSYNC(_reset)(QDSYNC() _q) int QDSYNC(_print)(QDSYNC() _q) { - printf("\n"); + printf("\n", _q->seq_len); return LIQUID_OK; } From 587a3619e4c9e52170a197c132b1e0dea0abbff1 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 08:49:53 -0400 Subject: [PATCH 77/97] qpilotgen/sync: reducing print() verbosity --- src/framing/src/qpilotgen.c | 9 +++------ src/framing/src/qpilotsync.c | 10 +++------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/framing/src/qpilotgen.c b/src/framing/src/qpilotgen.c index 99dc23c61..e77adbf3a 100644 --- a/src/framing/src/qpilotgen.c +++ b/src/framing/src/qpilotgen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -144,11 +144,8 @@ int qpilotgen_reset(qpilotgen _q) int qpilotgen_print(qpilotgen _q) { - printf("qpilotgen:\n"); - printf(" payload len : %u\n", _q->payload_len); - printf(" pilot spacing : %u\n", _q->pilot_spacing); - printf(" num pilots : %u\n", _q->num_pilots); - printf(" frame len : %u\n", _q->frame_len); + printf("\n", + _q->payload_len, _q->frame_len, _q->num_pilots); return LIQUID_OK; } diff --git a/src/framing/src/qpilotsync.c b/src/framing/src/qpilotsync.c index b1e6cd814..92b1941a8 100644 --- a/src/framing/src/qpilotsync.c +++ b/src/framing/src/qpilotsync.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -161,12 +161,8 @@ int qpilotsync_reset(qpilotsync _q) int qpilotsync_print(qpilotsync _q) { - printf("qpilotsync:\n"); - printf(" payload len : %u\n", _q->payload_len); - printf(" pilot spacing : %u\n", _q->pilot_spacing); - printf(" num pilots : %u\n", _q->num_pilots); - printf(" frame len : %u\n", _q->frame_len); - printf(" nfft : %u\n", _q->nfft); + printf("\n", + _q->payload_len, _q->frame_len, _q->num_pilots, _q->nfft); return LIQUID_OK; } From 2f9dbe8dd0a8f0d5d10b3f8b4c6ce612d1756841 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 08:58:13 -0400 Subject: [PATCH 78/97] firpfb: reducing verbosity in print() method --- examples/firpfb_rrrf_example.c | 1 + src/filter/src/firpfb.proto.c | 13 ++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/firpfb_rrrf_example.c b/examples/firpfb_rrrf_example.c index 43a8e7c85..6d2df1f4a 100644 --- a/examples/firpfb_rrrf_example.c +++ b/examples/firpfb_rrrf_example.c @@ -12,6 +12,7 @@ int main(int argc, char*argv[]) { // create object firpfb_rrrf pfb = firpfb_rrrf_create_default(M, m); + firpfb_rrrf_print(pfb); // generate and interpolate signal (windowed sinc pulse) float buf_0[ num_samples]; diff --git a/src/filter/src/firpfb.proto.c b/src/filter/src/firpfb.proto.c index 9bdd223cc..20d8cb813 100644 --- a/src/filter/src/firpfb.proto.c +++ b/src/filter/src/firpfb.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -297,12 +297,11 @@ int FIRPFB(_destroy)(FIRPFB() _q) // print firpfb object's parameters int FIRPFB(_print)(FIRPFB() _q) { - printf("fir polyphase filterbank [%u] :\n", _q->num_filters); - unsigned int i; - for (i=0; i<_q->num_filters; i++) { - printf(" bank %3u: ",i); - DOTPROD(_print)(_q->dp[i]); - } + printf("num_filters, _q->h_sub_len); + printf(", scale="); + PRINTVAL_TC(_q->scale,%g); + printf(">\n"); return LIQUID_OK; } From 343e6dbf0fec37bc841e2cc7bbb29ac718b17e2f Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 09:01:45 -0400 Subject: [PATCH 79/97] firpfbch{,2,r}: cleaning print() methods --- src/multichannel/src/firpfbch.proto.c | 4 ++-- src/multichannel/src/firpfbch2.proto.c | 15 ++++----------- src/multichannel/src/firpfbchr.proto.c | 7 ++----- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/multichannel/src/firpfbch.proto.c b/src/multichannel/src/firpfbch.proto.c index 9e80f450a..25a7e420d 100644 --- a/src/multichannel/src/firpfbch.proto.c +++ b/src/multichannel/src/firpfbch.proto.c @@ -263,9 +263,9 @@ int FIRPFBCH(_reset)(FIRPFBCH() _q) // print firpfbch object int FIRPFBCH(_print)(FIRPFBCH() _q) { - printf("\n", + printf("\n", _q->type == LIQUID_ANALYZER ? "analyzer" : "synthesizer", - _q->num_channels); + _q->num_channels, _q->p); return LIQUID_OK; } diff --git a/src/multichannel/src/firpfbch2.proto.c b/src/multichannel/src/firpfbch2.proto.c index 5221b4bab..4575fe842 100644 --- a/src/multichannel/src/firpfbch2.proto.c +++ b/src/multichannel/src/firpfbch2.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -255,16 +255,9 @@ int FIRPFBCH2(_reset)(FIRPFBCH2() _q) // print firpfbch2 object internals int FIRPFBCH2(_print)(FIRPFBCH2() _q) { - printf("firpfbch2_%s:\n", EXTENSION_FULL); - printf(" type : %s\n", _q->type==LIQUID_ANALYZER ? "analysis" : "synthesis"); - printf(" channels : %u\n", _q->M); - printf(" h_len : %u\n", _q->h_len); - printf(" semi-length : %u\n", _q->m); - - // TODO: print filter coefficients... - unsigned int i; - for (i=0; i<_q->M; i++) - DOTPROD(_print)(_q->dp[i]); + printf("\n", + _q->type == LIQUID_ANALYZER ? "analyzer" : "synthesizer", + _q->M, _q->m); return LIQUID_OK; } diff --git a/src/multichannel/src/firpfbchr.proto.c b/src/multichannel/src/firpfbchr.proto.c index bcb3d5e30..f31ca9cfc 100644 --- a/src/multichannel/src/firpfbchr.proto.c +++ b/src/multichannel/src/firpfbchr.proto.c @@ -211,11 +211,8 @@ int FIRPFBCHR(_reset)(FIRPFBCHR() _q) // print firpfbchr object internals int FIRPFBCHR(_print)(FIRPFBCHR() _q) { - printf("firpfbchr_%s:\n", EXTENSION_FULL); - printf(" channels : %u\n", _q->M); - printf(" decim (P) : %u\n", _q->P); - printf(" h_len : %u\n", _q->h_len); - printf(" semi-length : %u\n", _q->m); + printf("\n", + _q->M, _q->P, _q->m); return LIQUID_OK; } From a86cca804c02b8a5797daef148cb9685734babe5 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 09:06:33 -0400 Subject: [PATCH 80/97] ofdmframe{gen,sync}: cleaning print() methods --- examples/ofdmframesync_example.c | 4 ++-- src/framing/src/ofdmflexframegen.c | 2 +- src/framing/src/ofdmflexframesync.c | 2 +- src/multichannel/src/ofdmframegen.c | 20 ++++++++++---------- src/multichannel/src/ofdmframesync.c | 16 +++++++++++----- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/examples/ofdmframesync_example.c b/examples/ofdmframesync_example.c index 5464d617f..5c2d6eee0 100644 --- a/examples/ofdmframesync_example.c +++ b/examples/ofdmframesync_example.c @@ -102,11 +102,11 @@ int main(int argc, char*argv[]) // create frame generator ofdmframegen fg = ofdmframegen_create(M, cp_len, taper_len, p); - //ofdmframegen_print(fg); + ofdmframegen_print(fg); // create frame synchronizer ofdmframesync fs = ofdmframesync_create(M, cp_len, taper_len, p, callback, (void*)&data); - //ofdmframesync_print(fs); + ofdmframesync_print(fs); unsigned int n=0; diff --git a/src/framing/src/ofdmflexframegen.c b/src/framing/src/ofdmflexframegen.c index 6fa6b8ab0..38f71b9f9 100644 --- a/src/framing/src/ofdmflexframegen.c +++ b/src/framing/src/ofdmflexframegen.c @@ -269,7 +269,7 @@ int ofdmflexframegen_is_assembled(ofdmflexframegen _q) int ofdmflexframegen_print(ofdmflexframegen _q) { - printf("M); printf(", null=%u", _q->M_null); printf(", pilot=%u", _q->M_pilot); diff --git a/src/framing/src/ofdmflexframesync.c b/src/framing/src/ofdmflexframesync.c index 92b6c1fab..29057b923 100644 --- a/src/framing/src/ofdmflexframesync.c +++ b/src/framing/src/ofdmflexframesync.c @@ -239,7 +239,7 @@ int ofdmflexframesync_destroy(ofdmflexframesync _q) int ofdmflexframesync_print(ofdmflexframesync _q) { - printf("M); printf(", null=%u", _q->M_null); printf(", pilot=%u", _q->M_pilot); diff --git a/src/multichannel/src/ofdmframegen.c b/src/multichannel/src/ofdmframegen.c index 150cb8532..55af8072f 100644 --- a/src/multichannel/src/ofdmframegen.c +++ b/src/multichannel/src/ofdmframegen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -187,15 +187,15 @@ int ofdmframegen_destroy(ofdmframegen _q) int ofdmframegen_print(ofdmframegen _q) { - printf("ofdmframegen:\n"); - printf(" num subcarriers : %-u\n", _q->M); - printf(" - NULL : %-u\n", _q->M_null); - printf(" - pilot : %-u\n", _q->M_pilot); - printf(" - data : %-u\n", _q->M_data); - printf(" cyclic prefix len : %-u\n", _q->cp_len); - printf(" taper len : %-u\n", _q->taper_len); - printf(" "); - return ofdmframe_print_sctype(_q->p, _q->M); + printf("M); + printf(", null=%u", _q->M_null); + printf(", pilot=%u", _q->M_pilot); + printf(", data=%u", _q->M_data); + printf(", cp=%u", _q->cp_len); + printf(", taper=%u", _q->taper_len); + printf(">\n"); + return LIQUID_OK; } int ofdmframegen_reset(ofdmframegen _q) diff --git a/src/multichannel/src/ofdmframesync.c b/src/multichannel/src/ofdmframesync.c index 515c5c7df..7426baf52 100644 --- a/src/multichannel/src/ofdmframesync.c +++ b/src/multichannel/src/ofdmframesync.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -84,6 +84,7 @@ struct ofdmframesync_s { unsigned int M2; // number of subcarriers (divided by 2) unsigned int cp_len; // cyclic prefix length unsigned char * p; // subcarrier allocation (null, pilot, data) + unsigned int taper_len; // number of samples in tapering window/overlap // constants unsigned int M_null; // number of null subcarriers @@ -197,6 +198,7 @@ ofdmframesync ofdmframesync_create(unsigned int _M, q->M = _M; q->cp_len = _cp_len; + q->taper_len = _taper_len; // derived values q->M2 = _M/2; @@ -346,10 +348,14 @@ int ofdmframesync_destroy(ofdmframesync _q) int ofdmframesync_print(ofdmframesync _q) { - printf("ofdmframesync:\n"); - printf(" num subcarriers : %-u\n", _q->M); - printf(" cyclic prefix len : %-u\n", _q->cp_len); - //printf(" taper len : %-u\n", _q->taper_len); + printf("M); + printf(", null=%u", _q->M_null); + printf(", pilot=%u", _q->M_pilot); + printf(", data=%u", _q->M_data); + printf(", cp=%u", _q->cp_len); + printf(", taper=%u", _q->taper_len); + printf(">\n"); return LIQUID_OK; } From ad70aa1c1e5bb1de794fdb767a4219b57937d2b2 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 09:10:50 -0400 Subject: [PATCH 81/97] optim/gasearch: cleaning print() methods for gasearch, chromosome --- src/optim/src/chromosome.c | 14 ++++++-------- src/optim/src/gasearch.c | 21 ++++++++------------- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/src/optim/src/chromosome.c b/src/optim/src/chromosome.c index ea1147a52..32719ec3b 100644 --- a/src/optim/src/chromosome.c +++ b/src/optim/src/chromosome.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,9 +20,7 @@ * THE SOFTWARE. */ -// -// chromosome.c -// +// chromosome object for genetic algorithm search #include #include @@ -138,7 +136,7 @@ unsigned int chromosome_get_num_traits(chromosome _q) int chromosome_print(chromosome _q) { unsigned int i,j; - printf("chromosome: "); + printf("num_traits; i++) { for (j=0; j<_q->bits_per_trait[i]; j++) { @@ -149,17 +147,17 @@ int chromosome_print(chromosome _q) if (i != _q->num_traits-1) printf("."); } - printf("\n"); + printf(">\n"); return LIQUID_OK; } int chromosome_printf(chromosome _q) { unsigned int i; - printf("chromosome: "); + printf("num_traits; i++) printf("%6.3f", chromosome_valuef(_q,i)); - printf("\n"); + printf(">\n"); return LIQUID_OK; } diff --git a/src/optim/src/gasearch.c b/src/optim/src/gasearch.c index a846aabdf..e84376faa 100644 --- a/src/optim/src/gasearch.c +++ b/src/optim/src/gasearch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -141,18 +141,13 @@ int gasearch_destroy(gasearch _g) // print search parameter internals int gasearch_print(gasearch _g) { - printf("ga search :\n"); - printf(" num traits : %u\n", _g->num_parameters); - printf(" bits/chromosome : %u\n", _g->bits_per_chromosome); - printf(" population size : %u\n", _g->population_size); - printf(" selection size : %u\n", _g->selection_size); - printf(" mutation rate : %12.8f\n", _g->mutation_rate); - printf("population:\n"); - unsigned int i; - for (i=0; i<_g->population_size; i++) { - printf("%4u: [%8.4f] ", i, _g->utility[i]); - chromosome_printf( _g->population[i] ); - } + printf("num_parameters); + printf(", bits=%u", _g->bits_per_chromosome); + printf(", population=%u", _g->population_size); + printf(", selection=%u", _g->selection_size); + printf(", mutation=%g", _g->mutation_rate); + printf(">\n"); return LIQUID_OK; } From 6391d4cb5c3bc92b2f4dfaa9ad792342d67f3d06 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 09:25:05 -0400 Subject: [PATCH 82/97] modem: cleaning print() method for consistency --- src/modem/src/modem_common.proto.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/modem/src/modem_common.proto.c b/src/modem/src/modem_common.proto.c index 52bc452f5..6af604b63 100644 --- a/src/modem/src/modem_common.proto.c +++ b/src/modem/src/modem_common.proto.c @@ -300,9 +300,8 @@ int MODEM(_destroy)(MODEM() _q) // print a modem object int MODEM(_print)(MODEM() _q) { - printf("linear modem:\n"); - printf(" scheme: %s\n", modulation_types[_q->scheme].name); - printf(" bits/symbol: %u\n", _q->m); + printf("\n", + EXTENSION, modulation_types[_q->scheme].name, 1 << (_q->m)); return LIQUID_OK; } From 9370f9ea1e24b3ca2b44a5c11a09ac955f6f6b21 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 09:39:22 -0400 Subject: [PATCH 83/97] iirfiltsos: cleaning print() method for consistency --- src/filter/src/iirfiltsos.proto.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/filter/src/iirfiltsos.proto.c b/src/filter/src/iirfiltsos.proto.c index fce6a47c5..a5b89e186 100644 --- a/src/filter/src/iirfiltsos.proto.c +++ b/src/filter/src/iirfiltsos.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -134,17 +134,19 @@ int IIRFILTSOS(_destroy)(IIRFILTSOS() _q) // print iirfiltsos object properties to stdout int IIRFILTSOS(_print)(IIRFILTSOS() _q) { - printf("iir filter | sos:\n"); + printf("b[0],%12.8f); printf(","); - PRINTVAL_TC(_q->b[1],%12.8f); printf(","); - PRINTVAL_TC(_q->b[2],%12.8f); printf("\n"); + printf(", b=["); + PRINTVAL_TC(_q->b[0],%g); printf(","); + PRINTVAL_TC(_q->b[1],%g); printf(","); + PRINTVAL_TC(_q->b[2],%g); printf("]"); - printf(" a : "); - PRINTVAL_TC(_q->a[0],%12.8f); printf(","); - PRINTVAL_TC(_q->a[1],%12.8f); printf(","); - PRINTVAL_TC(_q->a[2],%12.8f); printf("\n"); + printf(", a=["); + PRINTVAL_TC(_q->a[0],%g); printf(","); + PRINTVAL_TC(_q->a[1],%g); printf(","); + PRINTVAL_TC(_q->a[2],%g); printf("]"); + + printf(">\n"); return LIQUID_OK; } From 34532777341249267329152f8f5eb64f1002f5c2 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 09:44:22 -0400 Subject: [PATCH 84/97] iirfilt: cleaning print() method for consistency --- src/filter/src/iirfilt.proto.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/filter/src/iirfilt.proto.c b/src/filter/src/iirfilt.proto.c index c89cbfa82..3411a1f94 100644 --- a/src/filter/src/iirfilt.proto.c +++ b/src/filter/src/iirfilt.proto.c @@ -504,9 +504,13 @@ int IIRFILT(_destroy)(IIRFILT() _q) // print iirfilt object internals int IIRFILT(_print)(IIRFILT() _q) { - printf("iir filter [%s]:\n", _q->type == IIRFILT_TYPE_NORM ? "normal" : "sos"); - unsigned int i; + printf("type == IIRFILT_TYPE_NORM ? "normal" : "sos"); + printf(", order=%u", _q->n-1); + printf(">\n"); +#if 0 + unsigned int i; if (_q->type == IIRFILT_TYPE_SOS) { for (i=0; i<_q->nsos; i++) IIRFILTSOS(_print)(_q->qsos[i]); @@ -521,14 +525,8 @@ int IIRFILT(_print)(IIRFILT() _q) for (i=0; i<_q->na; i++) PRINTVAL_TC(_q->a[i],%12.8f); printf("\n"); - -#if 0 - printf(" v :"); - for (i=0; i<_q->n; i++) - PRINTVAL(_q->v[i]); - printf("\n"); -#endif } +#endif return LIQUID_OK; } From eb4d54678de0c05d1e241bbcfbb4ee35631d2a17 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 09:47:19 -0400 Subject: [PATCH 85/97] fftfilt: cleaning print() method for consistency --- src/filter/src/fftfilt.proto.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/filter/src/fftfilt.proto.c b/src/filter/src/fftfilt.proto.c index bbf000943..eb52ba612 100644 --- a/src/filter/src/fftfilt.proto.c +++ b/src/filter/src/fftfilt.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,9 +20,7 @@ * THE SOFTWARE. */ -// // finite impulse response (FIR) filter using fast Fourier transforms (FFTs) -// #include #include @@ -162,19 +160,12 @@ int FFTFILT(_reset)(FFTFILT() _q) // print filter object internals (taps, buffer) int FFTFILT(_print)(FFTFILT() _q) { - printf("fftfilt_%s: [h_len=%u, n=%u]\n", EXTENSION_FULL, _q->h_len, _q->n); - unsigned int i; - unsigned int n = _q->h_len; - for (i=0; ih_len, _q->n); - // print scaling - printf(" scale = "); - PRINTVAL_TC(_q->scale,%12.8f); - printf("\n"); + printf(", scale="); + PRINTVAL_TC(_q->scale,%g); + printf(">\n"); return LIQUID_OK; } From 89310391d7febfdee72c6152a8fe7d14d93008d2 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 09:49:57 -0400 Subject: [PATCH 86/97] cbuffer: removing antiquated debug print method --- examples/cbufferf_example.c | 4 --- include/liquid.h | 3 -- src/buffer/src/cbuffer.proto.c | 43 +---------------------------- src/buffer/tests/cbuffer_autotest.c | 5 ++-- 4 files changed, 3 insertions(+), 52 deletions(-) diff --git a/examples/cbufferf_example.c b/examples/cbufferf_example.c index b660f1958..d4d850d6d 100644 --- a/examples/cbufferf_example.c +++ b/examples/cbufferf_example.c @@ -1,6 +1,3 @@ -// -// cbufferf_example.c -// // This example demonstrates the circular buffer object on // floating-point data. // @@ -35,7 +32,6 @@ int main() { cbufferf_write(cb, v, 8); // print - cbufferf_debug_print(cb); cbufferf_print(cb); // destroy object diff --git a/include/liquid.h b/include/liquid.h index 3d3406e07..3be8080e8 100644 --- a/include/liquid.h +++ b/include/liquid.h @@ -420,9 +420,6 @@ int CBUFFER(_destroy)(CBUFFER() _q); \ /* Print cbuffer object properties to stdout */ \ int CBUFFER(_print)(CBUFFER() _q); \ \ -/* Print cbuffer object properties and internal state */ \ -int CBUFFER(_debug_print)(CBUFFER() _q); \ - \ /* Clear internal buffer */ \ int CBUFFER(_reset)(CBUFFER() _q); \ \ diff --git a/src/buffer/src/cbuffer.proto.c b/src/buffer/src/cbuffer.proto.c index 5e13ceb9b..d13364be4 100644 --- a/src/buffer/src/cbuffer.proto.c +++ b/src/buffer/src/cbuffer.proto.c @@ -124,48 +124,7 @@ int CBUFFER(_destroy)(CBUFFER() _q) int CBUFFER(_print)(CBUFFER() _q) { printf("\n", - EXTENSION, - _q->max_size, - _q->max_read, - _q->num_elements); - return LIQUID_OK; -} - -// print cbuffer object properties and internal state -int CBUFFER(_debug_print)(CBUFFER() _q) -{ - printf("cbuffer%s [max size: %u, max read: %u, elements: %u]\n", - EXTENSION, - _q->max_size, - _q->max_read, - _q->num_elements); - - unsigned int i; - for (i=0; i<_q->max_size; i++) { - // print read index pointer - if (i==_q->read_index) - printf(""); - else - printf(" "); - - // print write index pointer - if (i==_q->write_index) - printf(""); - else - printf(" "); - - // print buffer value - BUFFER_PRINT_LINE(_q,i) - printf("\n"); - } - printf("----------------------------------\n"); - - // print excess buffer memory - for (i=_q->max_size; i<_q->num_allocated; i++) { - printf(" "); - BUFFER_PRINT_LINE(_q,i) - printf("\n"); - } + EXTENSION, _q->max_size, _q->max_read, _q->num_elements); return LIQUID_OK; } diff --git a/src/buffer/tests/cbuffer_autotest.c b/src/buffer/tests/cbuffer_autotest.c index edcac8ccd..16986100a 100644 --- a/src/buffer/tests/cbuffer_autotest.c +++ b/src/buffer/tests/cbuffer_autotest.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -315,8 +315,7 @@ void autotest_cbufferf_config() CONTEND_EQUALITY(cbufferf_push(q,0), LIQUID_OK); // ensure no errors with printing - CONTEND_EQUALITY(cbufferf_print(q), LIQUID_OK); - CONTEND_EQUALITY(cbufferf_debug_print(q), LIQUID_OK); + CONTEND_EQUALITY(cbufferf_print(q), LIQUID_OK); // buffer full; cannot write more CONTEND_INEQUALITY(cbufferf_push(q,0), LIQUID_OK); From cfc869d80501da3a11f7802ad0ddcec6f3648ada Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sun, 21 Apr 2024 09:54:26 -0400 Subject: [PATCH 87/97] agc: cleaning print() statement for consistency --- src/agc/src/agc.proto.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/agc/src/agc.proto.c b/src/agc/src/agc.proto.c index 02eb6ef7f..a654c7910 100644 --- a/src/agc/src/agc.proto.c +++ b/src/agc/src/agc.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -113,12 +113,12 @@ int AGC(_destroy)(AGC() _q) // print agc object internals int AGC(_print)(AGC() _q) { - printf("agc [rssi: %12.4f dB, output gain: %.3f dB, bw: %12.4e, locked: %s, squelch: %s]:\n", - AGC(_get_rssi)(_q), - _q->scale > 0 ? 10.*log10f(_q->scale) : -100.0f, - _q->bandwidth, - _q->is_locked ? "yes" : "no", - _q->squelch_mode == LIQUID_AGC_SQUELCH_DISABLED ? "disabled" : "enabled"); + printf("\n", + AGC(_get_rssi)(_q), + _q->scale > 0 ? 10.*log10f(_q->scale) : -100.0f, + _q->bandwidth, + _q->is_locked ? "true" : "false", + _q->squelch_mode == LIQUID_AGC_SQUELCH_DISABLED ? "disabled" : "enabled"); return LIQUID_OK; } From 155bf9a4d767888175e7d63142fcbb83ea9513ed Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Wed, 24 Apr 2024 07:57:37 -0400 Subject: [PATCH 88/97] cleaning up print statements for consistency in agc, audio, eq, filter --- src/audio/src/cvsd.c | 2 +- src/buffer/src/wdelay.proto.c | 2 +- src/equalization/src/eqlms.proto.c | 2 +- src/equalization/src/eqrls.proto.c | 41 ++---------------------------- src/filter/src/autocorr.proto.c | 2 +- src/filter/src/dds.proto.c | 2 +- src/filter/src/fdelay.proto.c | 2 +- src/filter/src/firdecim.proto.c | 10 +++----- src/filter/src/firdespm.c | 2 +- src/filter/src/firfarrow.proto.c | 6 +++-- src/filter/src/firfilt.proto.c | 2 +- src/filter/src/firhilb.proto.c | 14 +--------- src/filter/src/firinterp.proto.c | 7 ++--- src/filter/src/firpfb.proto.c | 2 +- src/filter/src/iirdecim.proto.c | 2 +- src/filter/src/iirhilb.proto.c | 2 +- src/filter/src/iirinterp.proto.c | 2 +- src/filter/src/msresamp.proto.c | 7 +++++ src/filter/src/msresamp2.proto.c | 7 +++++ src/filter/src/ordfilt.proto.c | 2 +- src/filter/src/resamp.proto.c | 3 ++- src/filter/src/resamp2.proto.c | 2 +- src/filter/src/rresamp.proto.c | 2 +- src/filter/src/symsync.proto.c | 3 ++- 24 files changed, 48 insertions(+), 80 deletions(-) diff --git a/src/audio/src/cvsd.c b/src/audio/src/cvsd.c index 1c62fda02..370976cb0 100644 --- a/src/audio/src/cvsd.c +++ b/src/audio/src/cvsd.c @@ -112,7 +112,7 @@ int cvsd_destroy(cvsd _q) // print cvsd object parameters int cvsd_print(cvsd _q) { - printf("num_bits, _q->zeta); + printf("num_bits, _q->zeta); #if CVSD_ENABLE_SIGNAL_CONDITIONING printf(", alpha=%g", _q->alpha); #endif diff --git a/src/buffer/src/wdelay.proto.c b/src/buffer/src/wdelay.proto.c index 243cba317..d4a9735c9 100644 --- a/src/buffer/src/wdelay.proto.c +++ b/src/buffer/src/wdelay.proto.c @@ -116,7 +116,7 @@ int WDELAY(_destroy)(WDELAY() _q) // print delay buffer object's state to stdout int WDELAY(_print)(WDELAY() _q) { - printf("\n", _q->delay); + printf("\n", _q->delay); return LIQUID_OK; } diff --git a/src/equalization/src/eqlms.proto.c b/src/equalization/src/eqlms.proto.c index 780b3b0fa..7d1162cb5 100644 --- a/src/equalization/src/eqlms.proto.c +++ b/src/equalization/src/eqlms.proto.c @@ -235,7 +235,7 @@ int EQLMS(_reset)(EQLMS() _q) // print eqlms object internals int EQLMS(_print)(EQLMS() _q) { - printf("\n", EXTENSION_FULL, _q->h_len, _q->mu); + printf("\n", EXTENSION_FULL, _q->h_len, _q->mu); return LIQUID_OK; } diff --git a/src/equalization/src/eqrls.proto.c b/src/equalization/src/eqrls.proto.c index b0488e191..c7c189623 100644 --- a/src/equalization/src/eqrls.proto.c +++ b/src/equalization/src/eqrls.proto.c @@ -20,9 +20,7 @@ * THE SOFTWARE. */ -// // Recursive least-squares (RLS) equalizer -// #include #include @@ -181,43 +179,8 @@ int EQRLS(_destroy)(EQRLS() _q) // print eqrls object internals int EQRLS(_print)(EQRLS() _q) { - printf("equalizer (RLS):\n"); - printf(" order: %u\n", _q->p); - unsigned int i; - for (i=0; i<_q->p; i++) { -#if T_COMPLEX - printf(" %3u: w = %12.8f + j%12.8f\n", i, crealf(_q->w1[_q->p-i-1]), cimagf(_q->w1[_q->p-i-1])); -#else - printf(" %3u: w = %12.8f\n", i, _q->w1[_q->p-i-1]); -#endif - } - -#ifdef DEBUG - unsigned int r,c,p=_q->p; - printf("P0:\n"); - for (r=0; rP0,p,p,r,c)); - } - printf("\n"); - } - - printf("P1:\n"); - for (r=0; rP1,p,p,r,c)); - } - printf("\n"); - } - - printf("gxl:\n"); - for (r=0; rgxl,p,p,r,c)); - } - printf("\n"); - } -#endif + printf("\n", + EXTENSION_FULL, _q->p, _q->lambda, _q->delta); return LIQUID_OK; } diff --git a/src/filter/src/autocorr.proto.c b/src/filter/src/autocorr.proto.c index 22796462b..c2cbf2ebb 100644 --- a/src/filter/src/autocorr.proto.c +++ b/src/filter/src/autocorr.proto.c @@ -111,7 +111,7 @@ int AUTOCORR(_reset)(AUTOCORR() _q) // print auto-correlator parameters to stdout int AUTOCORR(_print)(AUTOCORR() _q) { - printf("autocorr [%u window, %u delay]\n", _q->window_size, _q->delay); + printf("\n", _q->window_size, _q->delay); return LIQUID_OK; } diff --git a/src/filter/src/dds.proto.c b/src/filter/src/dds.proto.c index 2fce7cbd9..b85b2b531 100644 --- a/src/filter/src/dds.proto.c +++ b/src/filter/src/dds.proto.c @@ -205,7 +205,7 @@ int DDS(_destroy)(DDS() _q) // print dds object internals int DDS(_print)(DDS() _q) { - printf("rate, _q->fc0, _q->bw0, diff --git a/src/filter/src/fdelay.proto.c b/src/filter/src/fdelay.proto.c index 3a5af351a..ac21cc535 100644 --- a/src/filter/src/fdelay.proto.c +++ b/src/filter/src/fdelay.proto.c @@ -105,7 +105,7 @@ int FDELAY(_reset)(FDELAY() _q) // Print delay object internals int FDELAY(_print)(FDELAY() _q) { - printf("\n", + printf("\n", _q->nmax, _q->m, _q->npfb, _q->delay); return LIQUID_OK; } diff --git a/src/filter/src/firdecim.proto.c b/src/filter/src/firdecim.proto.c index ab7ae2f09..c52006d2f 100644 --- a/src/filter/src/firdecim.proto.c +++ b/src/filter/src/firdecim.proto.c @@ -182,13 +182,11 @@ int FIRDECIM(_destroy)(FIRDECIM() _q) // print decimator object internals int FIRDECIM(_print)(FIRDECIM() _q) { - printf("FIRDECIM() [%u] :\n", _q->M); - printf(" window:\n"); - WINDOW(_print)(_q->w); + printf("M); // print scaling - printf(" scale = "); - PRINTVAL_TC(_q->scale,%12.8f); - printf("\n"); + printf(", scale="); + PRINTVAL_TC(_q->scale,%g); + printf(">\n"); return LIQUID_OK; } diff --git a/src/filter/src/firdespm.c b/src/filter/src/firdespm.c index c7e942a26..3c0fdcee1 100644 --- a/src/filter/src/firdespm.c +++ b/src/filter/src/firdespm.c @@ -466,7 +466,7 @@ int firdespm_destroy(firdespm _q) int firdespm_print(firdespm _q) { unsigned int i; - printf("num_bands; i++) printf("%g,", _q->bands[2*i+0]); diff --git a/src/filter/src/firfarrow.proto.c b/src/filter/src/firfarrow.proto.c index 3cca5a33a..38c0da14f 100644 --- a/src/filter/src/firfarrow.proto.c +++ b/src/filter/src/firfarrow.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -136,7 +136,8 @@ int FIRFARROW(_destroy)(FIRFARROW() _q) // print firfarrow object's internal properties int FIRFARROW(_print)(FIRFARROW() _q) { - printf("firfarrow [len : %u, poly-order : %u]\n", _q->h_len, _q->Q); + printf("\n", _q->h_len, _q->Q); +#if 0 printf("polynomial coefficients:\n"); // print coefficients @@ -155,6 +156,7 @@ int FIRFARROW(_print)(FIRFARROW() _q) PRINTVAL_TC(_q->h[n-i-1],%12.8f); printf(";\n"); } +#endif return LIQUID_OK; } diff --git a/src/filter/src/firfilt.proto.c b/src/filter/src/firfilt.proto.c index c7b09e4d4..c70e235f1 100644 --- a/src/filter/src/firfilt.proto.c +++ b/src/filter/src/firfilt.proto.c @@ -348,7 +348,7 @@ int FIRFILT(_reset)(FIRFILT() _q) // print filter object internals (taps, buffer) int FIRFILT(_print)(FIRFILT() _q) { - printf("h_len); + printf("h_len); printf(", scale="); PRINTVAL_TC(_q->scale,%12.8f); printf(">\n"); diff --git a/src/filter/src/firhilb.proto.c b/src/filter/src/firhilb.proto.c index cb083d476..f5da32f39 100644 --- a/src/filter/src/firhilb.proto.c +++ b/src/filter/src/firhilb.proto.c @@ -157,19 +157,7 @@ int FIRHILB(_destroy)(FIRHILB() _q) // print firhilb object internals int FIRHILB(_print)(FIRHILB() _q) { - printf("fir hilbert transform: [%u]\n", _q->h_len); - unsigned int i; - for (i=0; i<_q->h_len; i++) { - printf(" hc(%4u) = %8.4f + j*%8.4f;\n", i+1, crealf(_q->hc[i]), cimagf(_q->hc[i])); - } - printf("---\n"); - for (i=0; i<_q->h_len; i++) { - printf(" h(%4u) = %8.4f;\n", i+1, _q->h[i]); - } - printf("---\n"); - for (i=0; i<_q->hq_len; i++) { - printf(" hq(%4u) = %8.4f;\n", i+1, _q->hq[i]); - } + printf("\n", EXTENSION_SHORT, _q->h_len); return LIQUID_OK; } diff --git a/src/filter/src/firinterp.proto.c b/src/filter/src/firinterp.proto.c index 98f605bc5..655326aa0 100644 --- a/src/filter/src/firinterp.proto.c +++ b/src/filter/src/firinterp.proto.c @@ -212,9 +212,10 @@ int FIRINTERP(_destroy)(FIRINTERP() _q) // print interpolator state int FIRINTERP(_print)(FIRINTERP() _q) { - printf("interp():\n"); - printf(" interp : %u\n", _q->M); - printf(" h_len : %u\n", _q->h_len); + printf("M); + printf(", h_len=%u", _q->h_len); + printf(">\n"); return FIRPFB(_print)(_q->filterbank); } diff --git a/src/filter/src/firpfb.proto.c b/src/filter/src/firpfb.proto.c index 20d8cb813..a13b3815c 100644 --- a/src/filter/src/firpfb.proto.c +++ b/src/filter/src/firpfb.proto.c @@ -297,7 +297,7 @@ int FIRPFB(_destroy)(FIRPFB() _q) // print firpfb object's parameters int FIRPFB(_print)(FIRPFB() _q) { - printf("num_filters, _q->h_sub_len); printf(", scale="); PRINTVAL_TC(_q->scale,%g); diff --git a/src/filter/src/iirdecim.proto.c b/src/filter/src/iirdecim.proto.c index 08e29e57d..7303148d5 100644 --- a/src/filter/src/iirdecim.proto.c +++ b/src/filter/src/iirdecim.proto.c @@ -136,7 +136,7 @@ int IIRDECIM(_destroy)(IIRDECIM() _q) // print interpolator state int IIRDECIM(_print)(IIRDECIM() _q) { - printf("\n", EXTENSION_FULL, _q->M); + printf("\n", EXTENSION_FULL, _q->M); return LIQUID_OK; } diff --git a/src/filter/src/iirhilb.proto.c b/src/filter/src/iirhilb.proto.c index 51fcf6e22..d55756eb8 100644 --- a/src/filter/src/iirhilb.proto.c +++ b/src/filter/src/iirhilb.proto.c @@ -113,7 +113,7 @@ int IIRHILB(_destroy)(IIRHILB() _q) // print iirhilb object internals int IIRHILB(_print)(IIRHILB() _q) { - printf("\n"); + printf("\n"); return LIQUID_OK; } diff --git a/src/filter/src/iirinterp.proto.c b/src/filter/src/iirinterp.proto.c index d60b56552..e54f35b57 100644 --- a/src/filter/src/iirinterp.proto.c +++ b/src/filter/src/iirinterp.proto.c @@ -138,7 +138,7 @@ int IIRINTERP(_destroy)(IIRINTERP() _q) // print interpolator state int IIRINTERP(_print)(IIRINTERP() _q) { - printf("\n", EXTENSION_FULL, _q->M); + printf("\n", EXTENSION_FULL, _q->M); return LIQUID_OK; } diff --git a/src/filter/src/msresamp.proto.c b/src/filter/src/msresamp.proto.c index 940fd5cd7..36475764b 100644 --- a/src/filter/src/msresamp.proto.c +++ b/src/filter/src/msresamp.proto.c @@ -187,6 +187,12 @@ int MSRESAMP(_destroy)(MSRESAMP() _q) // print msresamp object internals int MSRESAMP(_print)(MSRESAMP() _q) { + printf("\n", + EXTENSION_FULL, + _q->type == LIQUID_RESAMP_INTERP ? "interp" : "decim", + _q->num_halfband_stages, + _q->rate); +#if 0 printf("multi-stage resampler\n"); printf(" composite rate : %12.10f\n", _q->rate); printf(" type : %s\n", _q->type == LIQUID_RESAMP_INTERP ? "interp" : "decim"); @@ -227,6 +233,7 @@ int MSRESAMP(_print)(MSRESAMP() _q) printf(" [%2u, r=%11.7f] : arbitrary, r=%12.8f\n", stage, r, rate); stage++; } +#endif return LIQUID_OK; } diff --git a/src/filter/src/msresamp2.proto.c b/src/filter/src/msresamp2.proto.c index bb46a2625..f2884297a 100644 --- a/src/filter/src/msresamp2.proto.c +++ b/src/filter/src/msresamp2.proto.c @@ -228,6 +228,12 @@ int MSRESAMP2(_destroy)(MSRESAMP2() _q) // print msresamp2 object internals int MSRESAMP2(_print)(MSRESAMP2() _q) { + printf("\n", + EXTENSION_FULL, + _q->type == LIQUID_RESAMP_INTERP ? "interp" : "decim", + _q->num_stages, + MSRESAMP2(_get_rate)(_q)); +#if 0 printf("multi-stage half-band resampler:\n"); printf(" type : %s\n", _q->type == LIQUID_RESAMP_DECIM ? "decimator" : "interpolator"); printf(" number of stages : %u stage%s\n", _q->num_stages, _q->num_stages == 1 ? "" : "s"); @@ -246,6 +252,7 @@ int MSRESAMP2(_print)(MSRESAMP2() _q) printf(" stage[%2u] {m=%3u, as=%6.2f dB, fc=%6.3f, f0=%6.3f}\n", i, _q->m_stage[g], _q->as_stage[g], _q->fc_stage[g], _q->f0_stage[g]); } +#endif return LIQUID_OK; } diff --git a/src/filter/src/ordfilt.proto.c b/src/filter/src/ordfilt.proto.c index da81c8a26..43a794dfc 100644 --- a/src/filter/src/ordfilt.proto.c +++ b/src/filter/src/ordfilt.proto.c @@ -145,7 +145,7 @@ int ORDFILT(_reset)(ORDFILT() _q) // print filter object internals (taps, buffer) int ORDFILT(_print)(ORDFILT() _q) { - printf("ordfilt_%s:\n", EXTENSION_FULL); + printf("\n", EXTENSION_FULL, _q->n, _q->k); return LIQUID_OK; } diff --git a/src/filter/src/resamp.proto.c b/src/filter/src/resamp.proto.c index 3a7866968..1b22faedb 100644 --- a/src/filter/src/resamp.proto.c +++ b/src/filter/src/resamp.proto.c @@ -185,7 +185,8 @@ int RESAMP(_destroy)(RESAMP() _q) // print resampler object int RESAMP(_print)(RESAMP() _q) { - printf("resampler [rate: %f]\n", _q->rate); + printf("\n", + EXTENSION_FULL, _q->r, _q->m, _q->as, _q->fc, _q->npfb); return FIRPFB(_print)(_q->f); } diff --git a/src/filter/src/resamp2.proto.c b/src/filter/src/resamp2.proto.c index 0122ff4e5..98256ffdc 100644 --- a/src/filter/src/resamp2.proto.c +++ b/src/filter/src/resamp2.proto.c @@ -211,7 +211,7 @@ int RESAMP2(_destroy)(RESAMP2() _q) // print a resamp2 object's internals int RESAMP2(_print)(RESAMP2() _q) { - printf("\n", + printf("\n", EXTENSION_FULL, _q->h_len,_q->f0); return LIQUID_OK; } diff --git a/src/filter/src/rresamp.proto.c b/src/filter/src/rresamp.proto.c index 2fc6177b3..bb3484e56 100644 --- a/src/filter/src/rresamp.proto.c +++ b/src/filter/src/rresamp.proto.c @@ -209,7 +209,7 @@ int RRESAMP(_destroy)(RRESAMP() _q) // print resampler object int RRESAMP(_print)(RRESAMP() _q) { - printf("\n", EXTENSION_FULL, + printf("\n", EXTENSION_FULL, _q->P, _q->Q, (float)(_q->P) / (float)(_q->Q), _q->block_len, _q->m); return LIQUID_OK; } diff --git a/src/filter/src/symsync.proto.c b/src/filter/src/symsync.proto.c index 7a825ed9c..7f2723755 100644 --- a/src/filter/src/symsync.proto.c +++ b/src/filter/src/symsync.proto.c @@ -287,7 +287,8 @@ int SYMSYNC(_destroy)(SYMSYNC() _q) // print symsync object's parameters int SYMSYNC(_print)(SYMSYNC() _q) { - printf("symsync_%s [rate: %f]\n", EXTENSION_FULL, _q->rate); + printf("\n", + EXTENSION_FULL, _q->rate, _q->k, _q->k_out); return FIRPFB(_print)(_q->mf); } From d35019f8c191b220705ec580d71818fbcc198f8f Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Wed, 24 Apr 2024 08:14:56 -0400 Subject: [PATCH 89/97] bpacket{gen,sync}: fixing print statements to be consistent --- examples/bpacketsync_example.c | 1 + src/framing/src/bpacketgen.c | 21 +++++++++++---------- src/framing/src/bpacketsync.c | 21 +++++++++++---------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/examples/bpacketsync_example.c b/examples/bpacketsync_example.c index cd7850757..4a2a07c23 100644 --- a/examples/bpacketsync_example.c +++ b/examples/bpacketsync_example.c @@ -118,6 +118,7 @@ int main(int argc, char*argv[]) { // create packet synchronizer bpacketsync ps = bpacketsync_create(0, callback, (void*)msg_dec); + bpacketsync_print(ps); // initialize original data message for (i=0; ig); - printf(" p/n len : %u bytes\n", _q->pnsequence_len); - printf(" header len : %u bytes\n", _q->header_len); - printf(" payload len : %u bytes\n", _q->dec_msg_len); - printf(" crc : %s\n", crc_scheme_str[_q->crc][1]); - printf(" fec (inner) : %s\n", fec_scheme_str[_q->fec0][1]); - printf(" fec (outer) : %s\n", fec_scheme_str[_q->fec1][1]); - printf(" packet len : %u bytes\n", _q->packet_len); - printf(" efficiency : %8.2f %%\n", 100.0f*(float)_q->dec_msg_len/(float)_q->packet_len); + printf("g); + printf(", pn_len%u", _q->pnsequence_len); + printf(", header=%u", _q->header_len); + printf(", payload=%u", _q->dec_msg_len); + printf(", crc=\"%s\"", crc_scheme_str[_q->crc][0]); + printf(", fec_0=\"%s\"", fec_scheme_str[_q->fec0][0]); + printf(", fec_1=\"%s\"", fec_scheme_str[_q->fec1][0]); + printf(", packet=%u", _q->packet_len); + printf(", efficiency=%g", (float)_q->dec_msg_len/(float)_q->packet_len); + printf(">\n"); } // return length of full packet diff --git a/src/framing/src/bpacketsync.c b/src/framing/src/bpacketsync.c index df403b7d0..e22e3330c 100644 --- a/src/framing/src/bpacketsync.c +++ b/src/framing/src/bpacketsync.c @@ -179,16 +179,17 @@ int bpacketsync_destroy(bpacketsync _q) int bpacketsync_print(bpacketsync _q) { - printf("bpacketsync:\n"); - printf(" p/n poly : 0x%.4x\n", _q->g); - printf(" p/n len : %u bytes\n", _q->pnsequence_len); - printf(" header len : %u bytes\n", _q->header_len); - printf(" payload len : %u bytes\n", _q->dec_msg_len); - printf(" crc : %s\n", crc_scheme_str[_q->crc][1]); - printf(" fec (inner) : %s\n", fec_scheme_str[_q->fec0][1]); - printf(" fec (outer) : %s\n", fec_scheme_str[_q->fec1][1]); - printf(" packet len : %u bytes\n", _q->packet_len); - printf(" efficiency : %8.2f %%\n", 100.0f*(float)_q->dec_msg_len/(float)_q->packet_len); + printf("g); + printf(", pn_len%u", _q->pnsequence_len); + printf(", header=%u", _q->header_len); + printf(", payload=%u", _q->dec_msg_len); + printf(", crc=\"%s\"", crc_scheme_str[_q->crc][0]); + printf(", fec_0=\"%s\"", fec_scheme_str[_q->fec0][0]); + printf(", fec_1=\"%s\"", fec_scheme_str[_q->fec1][0]); + printf(", packet=%u", _q->packet_len); + printf(", efficiency=%g", (float)_q->dec_msg_len/(float)_q->packet_len); + printf(">\n"); return LIQUID_OK; } From b999c4703d169751ac17cfbd0b2c1904ce1f574c Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Wed, 24 Apr 2024 18:58:03 -0400 Subject: [PATCH 90/97] framing: cleaning print() methods for consistency --- examples/symstreamcf_example.c | 1 + src/framing/src/bpresync.proto.c | 2 +- src/framing/src/bsync.proto.c | 2 +- src/framing/src/detector_cccf.c | 11 ++++++----- src/framing/src/dsssframegen.c | 2 +- src/framing/src/dsssframesync.c | 4 ++-- src/framing/src/flexframegen.c | 9 ++++----- src/framing/src/flexframesync.c | 6 +++--- src/framing/src/framegen64.c | 4 ++++ src/framing/src/framesync64.c | 4 ++-- src/framing/src/fskframegen.c | 4 ++++ src/framing/src/fskframesync.c | 4 ++++ src/framing/src/gmskframegen.c | 5 ++++- src/framing/src/gmskframesync.c | 4 ++-- src/framing/src/msource.proto.c | 4 +++- src/framing/src/presync.proto.c | 2 +- src/framing/src/qdetector.proto.c | 13 +++++++------ src/framing/src/qpacketmodem.proto.c | 19 ++++++++++--------- src/framing/src/qsource.proto.c | 20 ++++++++++---------- src/framing/src/symstream.proto.c | 12 ++++++++---- src/framing/src/symstreamr.proto.c | 16 ++++++++-------- src/framing/src/symtrack.proto.c | 6 ++++++ 22 files changed, 92 insertions(+), 62 deletions(-) diff --git a/examples/symstreamcf_example.c b/examples/symstreamcf_example.c index c3a4b743f..6bbf60ac7 100644 --- a/examples/symstreamcf_example.c +++ b/examples/symstreamcf_example.c @@ -33,6 +33,7 @@ int main() // create stream generator symstreamcf gen = symstreamcf_create_linear(ftype,k,m,beta,ms); + symstreamcf_print(gen); unsigned int total_samples = 0; while (total_samples < num_samples) { diff --git a/src/framing/src/bpresync.proto.c b/src/framing/src/bpresync.proto.c index 5bbb6f2fd..c182ffd4a 100644 --- a/src/framing/src/bpresync.proto.c +++ b/src/framing/src/bpresync.proto.c @@ -146,7 +146,7 @@ int BPRESYNC(_destroy)(BPRESYNC() _q) int BPRESYNC(_print)(BPRESYNC() _q) { - printf("bpresync_%s: %u samples\n", EXTENSION_FULL, _q->n); + printf("\n", EXTENSION_FULL, _q->n); return LIQUID_OK; } diff --git a/src/framing/src/bsync.proto.c b/src/framing/src/bsync.proto.c index ad271d163..f007befbb 100644 --- a/src/framing/src/bsync.proto.c +++ b/src/framing/src/bsync.proto.c @@ -145,7 +145,7 @@ int BSYNC(_destroy)(BSYNC() _fs) int BSYNC(_print)(BSYNC() _fs) { - printf("\n", EXTENSION_FULL, _fs->n); + printf("\n", EXTENSION_FULL, _fs->n); return LIQUID_OK; } diff --git a/src/framing/src/detector_cccf.c b/src/framing/src/detector_cccf.c index 9465821cb..39e890341 100644 --- a/src/framing/src/detector_cccf.c +++ b/src/framing/src/detector_cccf.c @@ -209,11 +209,12 @@ void detector_cccf_destroy(detector_cccf _q) void detector_cccf_print(detector_cccf _q) { - printf("detector_cccf:\n"); - printf(" sequence length : %-u\n", _q->n); - printf(" threshold : %8.4f\n", _q->threshold); - printf(" maximum carrier : %8.4f rad/sample\n", _q->dphi_max); - printf(" num. correlators : %u\n", _q->m); + printf("n); + printf(", thresh=%g", _q->threshold); + printf(", dphi_max=%8.4f", _q->dphi_max); + printf(", ncorrs=%u", _q->m); + printf(">\n"); } void detector_cccf_reset(detector_cccf _q) diff --git a/src/framing/src/dsssframegen.c b/src/framing/src/dsssframegen.c index fa4ba37b3..f7f8da18c 100644 --- a/src/framing/src/dsssframegen.c +++ b/src/framing/src/dsssframegen.c @@ -21,7 +21,7 @@ */ // -// dsssdsssframegen.c +// dsssframegen.c // // dsss flexible frame generator // diff --git a/src/framing/src/dsssframesync.c b/src/framing/src/dsssframesync.c index 62a0ee079..71fe5eff7 100644 --- a/src/framing/src/dsssframesync.c +++ b/src/framing/src/dsssframesync.c @@ -190,8 +190,8 @@ int dsssframesync_destroy(dsssframesync _q) int dsssframesync_print(dsssframesync _q) { - printf("dsssframesync:\n"); - return framedatastats_print(&_q->framedatastats); + printf("\n"); + return LIQUID_OK; } int dsssframesync_reset(dsssframesync _q) diff --git a/src/framing/src/flexframegen.c b/src/framing/src/flexframegen.c index 045b84ccc..4b91e17da 100644 --- a/src/framing/src/flexframegen.c +++ b/src/framing/src/flexframegen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2020 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,11 +20,7 @@ * THE SOFTWARE. */ -// -// flexframegen.c -// // flexible frame generator -// #include #include @@ -178,6 +174,8 @@ int flexframegen_destroy(flexframegen _q) // print flexframegen object internals int flexframegen_print(flexframegen _q) { + printf("\n"); +#if 0 unsigned int num_frame_symbols = 64 + // preamble p/n sequence length _q->header_sym_len + // header symbols @@ -198,6 +196,7 @@ int flexframegen_print(flexframegen _q) printf(" tail : %u symbols\n", _q->m); printf(" total : %u symbols\n", num_frame_symbols); printf(" efficiency : %.2f bits/second/Hz\n", eta); +#endif return LIQUID_OK; } diff --git a/src/framing/src/flexframesync.c b/src/framing/src/flexframesync.c index 4b0e513a1..8d3ffed5a 100644 --- a/src/framing/src/flexframesync.c +++ b/src/framing/src/flexframesync.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2023 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -281,8 +281,8 @@ int flexframesync_destroy(flexframesync _q) // print frame synchronizer object internals int flexframesync_print(flexframesync _q) { - printf("flexframesync:\n"); - return framedatastats_print(&_q->framedatastats); + printf("\n"); + return LIQUID_OK; } // reset frame synchronizer object diff --git a/src/framing/src/framegen64.c b/src/framing/src/framegen64.c index d3ce6c93e..3bba4921c 100644 --- a/src/framing/src/framegen64.c +++ b/src/framing/src/framegen64.c @@ -112,6 +112,7 @@ int framegen64_destroy(framegen64 _q) // print framegen64 object internals int framegen64_print(framegen64 _q) { +#if 0 float eta = (float) (8*(64 + 8)) / (float) (LIQUID_FRAME64_LEN/2); printf("framegen64 [m=%u, beta=%4.2f]:\n", _q->m, _q->beta); printf(" preamble/etc.\n"); @@ -133,6 +134,9 @@ int framegen64_print(framegen64 _q) printf(" summary\n"); printf(" * total symbols : %3u\n", LIQUID_FRAME64_LEN/2); printf(" * spectral efficiency : %6.4f b/s/Hz\n", eta); +#else + printf("\n", _q->m, _q->beta); +#endif return LIQUID_OK; } diff --git a/src/framing/src/framesync64.c b/src/framing/src/framesync64.c index 6eca7a759..4c002433a 100644 --- a/src/framing/src/framesync64.c +++ b/src/framing/src/framesync64.c @@ -181,8 +181,8 @@ int framesync64_destroy(framesync64 _q) // print frame synchronizer object internals int framesync64_print(framesync64 _q) { - printf("framesync64:\n"); - return framedatastats_print(&_q->framedatastats); + printf("\n"); + return LIQUID_OK; } // reset frame synchronizer object diff --git a/src/framing/src/fskframegen.c b/src/framing/src/fskframegen.c index 1c5df8e52..32306e25f 100644 --- a/src/framing/src/fskframegen.c +++ b/src/framing/src/fskframegen.c @@ -253,6 +253,7 @@ int fskframegen_reset(fskframegen _q) // print fskframegen object internals int fskframegen_print(fskframegen _q) { +#if 0 printf("fskframegen:\n"); printf(" physical properties\n"); printf(" bits/symbol : %u\n", _q->m); @@ -267,6 +268,9 @@ int fskframegen_print(fskframegen _q) printf(" fec (inner) : %s\n", fec_scheme_str[_q->payload_fec0][1]); printf(" fec (outer) : %s\n", fec_scheme_str[_q->payload_fec1][1]); printf(" total samples : %-4u samples\n", fskframegen_getframelen(_q)); +#else + printf("\n"); +#endif return LIQUID_OK; } diff --git a/src/framing/src/fskframesync.c b/src/framing/src/fskframesync.c index 8d30274e6..7113f1c94 100644 --- a/src/framing/src/fskframesync.c +++ b/src/framing/src/fskframesync.c @@ -309,6 +309,7 @@ int fskframesync_destroy(fskframesync _q) // print frame synchronizer object internals int fskframesync_print(fskframesync _q) { +#if 0 printf("fskframesync:\n"); printf(" physical properties\n"); printf(" bits/symbol : %u\n", _q->m); @@ -323,6 +324,9 @@ int fskframesync_print(fskframesync _q) printf(" fec (inner) : %s\n", fec_scheme_str[_q->payload_fec0][1]); printf(" fec (outer) : %s\n", fec_scheme_str[_q->payload_fec1][1]); printf(" total samples : %-4u samples\n", 0); +#else + printf("\n"); +#endif return LIQUID_OK; } diff --git a/src/framing/src/gmskframegen.c b/src/framing/src/gmskframegen.c index aee09a8a9..ce33baafc 100644 --- a/src/framing/src/gmskframegen.c +++ b/src/framing/src/gmskframegen.c @@ -205,7 +205,7 @@ int gmskframegen_is_assembled(gmskframegen _q) // print gmskframegen object internals int gmskframegen_print(gmskframegen _q) { - // plot +#if 0 printf("gmskframegen:\n"); printf(" physical properties\n"); printf(" samples/symbol : %u\n", _q->k); @@ -221,6 +221,9 @@ int gmskframegen_print(gmskframegen _q) printf(" fec (inner) : %s\n", fec_scheme_str[_q->fec0][1]); printf(" fec (outer) : %s\n", fec_scheme_str[_q->fec1][1]); printf(" total samples : %-4u samples\n", gmskframegen_getframelen(_q)); +#else + printf("\n"); +#endif return LIQUID_OK; } diff --git a/src/framing/src/gmskframesync.c b/src/framing/src/gmskframesync.c index 34c521f9d..23d12d4e6 100644 --- a/src/framing/src/gmskframesync.c +++ b/src/framing/src/gmskframesync.c @@ -282,8 +282,8 @@ int gmskframesync_destroy(gmskframesync _q) // print frame synchronizer object internals int gmskframesync_print(gmskframesync _q) { - printf("gmskframesync:\n"); - return framedatastats_print(&_q->framedatastats); + printf("\n"); + return LIQUID_OK; } int gmskframesync_set_header_len(gmskframesync _q, diff --git a/src/framing/src/msource.proto.c b/src/framing/src/msource.proto.c index 7697b25b7..9d5d44eff 100644 --- a/src/framing/src/msource.proto.c +++ b/src/framing/src/msource.proto.c @@ -175,11 +175,13 @@ int MSOURCE(_reset)(MSOURCE() _q) // print int MSOURCE(_print)(MSOURCE() _q) { - printf("msource%s, M=%u, m=%u, as=%.1f dB, %llu samples:\n", + printf("\n", EXTENSION, _q->M, _q->m, _q->as, _q->num_samples); +#if 0 unsigned int i; for (i=0; i<_q->num_sources; i++) QSOURCE(_print)(_q->sources[i]); +#endif return LIQUID_OK; } diff --git a/src/framing/src/presync.proto.c b/src/framing/src/presync.proto.c index facc0ec6a..ada1e0e16 100644 --- a/src/framing/src/presync.proto.c +++ b/src/framing/src/presync.proto.c @@ -148,7 +148,7 @@ int PRESYNC(_destroy)(PRESYNC() _q) int PRESYNC(_print)(PRESYNC() _q) { - printf("bpresync_%s: %u samples\n", EXTENSION_FULL, _q->n); + printf("\n", EXTENSION_FULL, _q->n); return LIQUID_OK; } diff --git a/src/framing/src/qdetector.proto.c b/src/framing/src/qdetector.proto.c index 5128adb0e..b42f1b20b 100644 --- a/src/framing/src/qdetector.proto.c +++ b/src/framing/src/qdetector.proto.c @@ -323,12 +323,13 @@ int QDETECTOR(_destroy)(QDETECTOR() _q) int QDETECTOR(_print)(QDETECTOR() _q) { - printf("qdetector_%s:\n", EXTENSION_FULL); - printf(" template length (time): %-u\n", _q->s_len); - printf(" FFT size : %-u\n", _q->nfft); - printf(" search range : %g [radians/sample], %-d [bins]\n",_q->dphi_max, _q->range); - printf(" detection threshold : %6.4f\n", _q->threshold); - printf(" sum{ s^2 } : %.2f\n", _q->s2_sum); + printf("s_len); + printf(", nfft=%u", _q->nfft); + printf(", dphi_max=%g",_q->dphi_max); + printf(", thresh=%g", _q->threshold); + printf(", energy=%g\n", _q->s2_sum); + printf(">\n"); return LIQUID_OK; } diff --git a/src/framing/src/qpacketmodem.proto.c b/src/framing/src/qpacketmodem.proto.c index 6f4a1ef9e..6e3ec3d4f 100644 --- a/src/framing/src/qpacketmodem.proto.c +++ b/src/framing/src/qpacketmodem.proto.c @@ -133,15 +133,16 @@ int QPACKETMODEM(_reset)(QPACKETMODEM() _q) // print object internals int QPACKETMODEM(_print)(QPACKETMODEM() _q) { - printf("qpacketmodem:\n"); - printf(" check : %s\n", crc_scheme_str[packetizer_get_crc(_q->p)][1]); - printf(" fec (inner) : %s\n", fec_scheme_str[packetizer_get_fec0(_q->p)][1]); - printf(" fec (outer) : %s\n", fec_scheme_str[packetizer_get_fec1(_q->p)][1]); - printf(" modulation scheme : %s\n", modulation_types[MODEM(_get_scheme)(_q->mod_payload)].name); - printf(" payload dec len : %u\n", _q->payload_dec_len); - printf(" payload enc len : %u\n", _q->payload_enc_len); - printf(" payload bit len : %u\n", _q->payload_bit_len); - printf(" payload mod len : %u\n", _q->payload_mod_len); + printf("p)][0]); + printf(", fec_0=\"%s\"", fec_scheme_str[packetizer_get_fec0(_q->p)][0]); + printf(", fec_1=\"%s\"", fec_scheme_str[packetizer_get_fec1(_q->p)][0]); + printf(", ms=\"%s\"", modulation_types[MODEM(_get_scheme)(_q->mod_payload)].name); + printf(", dec=%u", _q->payload_dec_len); + printf(", enc=%u", _q->payload_enc_len); + printf(", bit=%u", _q->payload_bit_len); + printf(", mod=%u", _q->payload_mod_len); + printf(">\n"); return LIQUID_OK; } diff --git a/src/framing/src/qsource.proto.c b/src/framing/src/qsource.proto.c index ca72fb8fc..26000fe61 100644 --- a/src/framing/src/qsource.proto.c +++ b/src/framing/src/qsource.proto.c @@ -317,22 +317,22 @@ int QSOURCE(_init_gmsk)(QSOURCE() _q, int QSOURCE(_print)(QSOURCE() _q) { // TODO: print generic parameters - printf(" qsource%s[%3d] : ", EXTENSION, _q->id); + printf("id); // print type-specific parameters float bw = _q->bw; switch (_q->type) { - case QSOURCE_USER: printf("user "); break; - case QSOURCE_TONE: printf("tone "); break; - case QSOURCE_CHIRP: printf("chirp"); break; - case QSOURCE_NOISE: printf("noise"); break; - case QSOURCE_MODEM: printf("modem"); bw *= 0.5f; break; - case QSOURCE_FSK: printf("fsk "); bw *= 0.5f; break; - case QSOURCE_GMSK: printf("gmsk "); bw *= 0.5f; break; + case QSOURCE_USER: printf(", type=\"user\""); break; + case QSOURCE_TONE: printf(", type=\"tone\""); break; + case QSOURCE_CHIRP: printf(", type=\"chirp\""); break; + case QSOURCE_NOISE: printf(", type=\"noise\""); break; + case QSOURCE_MODEM: printf(", type=\"modem\""); bw *= 0.5f; break; + case QSOURCE_FSK: printf(", type=\"fsk\""); bw *= 0.5f; break; + case QSOURCE_GMSK: printf(", type=\"gmsk\""); bw *= 0.5f; break; default: return liquid_error(LIQUID_EINT,"qsource%s_print(), invalid internal state",EXTENSION); } - printf(" : fc=%6.3f, bw=%5.3f, P=%4u, m=%2u, as=%5.1f dB, gain=%5.1f dB %c\n", - _q->fc, bw, _q->P, _q->m, _q->as, QSOURCE(_get_gain)(_q), _q->enabled ? '*' : ' '); + printf(", fc=%g, bw=%g, P=%u, m=%u, as=%g, gain=%g, enabled=%u>\n", + _q->fc, bw, _q->P, _q->m, _q->as, QSOURCE(_get_gain)(_q), _q->enabled); return LIQUID_OK; } diff --git a/src/framing/src/symstream.proto.c b/src/framing/src/symstream.proto.c index 08c06db6d..317d34eeb 100644 --- a/src/framing/src/symstream.proto.c +++ b/src/framing/src/symstream.proto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2022 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,9 +20,7 @@ * THE SOFTWARE. */ -// // Symbol streaming generator -// #include #include @@ -138,7 +136,13 @@ int SYMSTREAM(_destroy)(SYMSTREAM() _q) // print symstream object's parameters int SYMSTREAM(_print)(SYMSTREAM() _q) { - printf("symstream_%s:\n", EXTENSION); + printf("k); + printf(", m=%u", _q->m); + printf(", beta=%.3f", _q->beta); + printf(", ms=\"%s\"", modulation_types[_q->mod_scheme].name); + printf(", gain=%g", _q->gain); + printf(">\n"); return LIQUID_OK; } diff --git a/src/framing/src/symstreamr.proto.c b/src/framing/src/symstreamr.proto.c index c9046d10c..cbf7e2b27 100644 --- a/src/framing/src/symstreamr.proto.c +++ b/src/framing/src/symstreamr.proto.c @@ -126,14 +126,14 @@ int SYMSTREAMR(_destroy)(SYMSTREAMR() _q) // print symstream object's parameters int SYMSTREAMR(_print)(SYMSTREAMR() _q) { - printf("\n", - EXTENSION, - liquid_firfilt_type_str[SYMSTREAMR(_get_ftype)(_q)][0], - SYMSTREAMR(_get_bw) (_q), - SYMSTREAMR(_get_m) (_q), - SYMSTREAMR(_get_beta)(_q), - modulation_types[SYMSTREAMR(_get_scheme)(_q)].name, - SYMSTREAMR(_get_gain)(_q)); + printf("\n", + EXTENSION, + liquid_firfilt_type_str[SYMSTREAMR(_get_ftype)(_q)][0], + SYMSTREAMR(_get_bw) (_q), + SYMSTREAMR(_get_m) (_q), + SYMSTREAMR(_get_beta)(_q), + modulation_types[SYMSTREAMR(_get_scheme)(_q)].name, + SYMSTREAMR(_get_gain)(_q)); return LIQUID_OK; } diff --git a/src/framing/src/symtrack.proto.c b/src/framing/src/symtrack.proto.c index d8154383a..872d930a9 100644 --- a/src/framing/src/symtrack.proto.c +++ b/src/framing/src/symtrack.proto.c @@ -169,6 +169,7 @@ int SYMTRACK(_destroy)(SYMTRACK() _q) // print symtrack object's parameters int SYMTRACK(_print)(SYMTRACK() _q) { +#if 0 printf("symtrack_%s:\n", EXTENSION_FULL); printf(" k:%u, m:%u, beta:%.3f, ms:%s\n", _q->k, _q->m, _q->beta, modulation_types[_q->mod_scheme].name); @@ -181,6 +182,11 @@ int SYMTRACK(_print)(SYMTRACK() _q) printf("?\n"); return liquid_error(LIQUID_EINT,"symtrack_%s_print(), invalid equalization strategy"); } +#else + printf("\n", + _q->k, _q->m, _q->beta, modulation_types[_q->mod_scheme].name); +#endif return LIQUID_OK; } From 965216f5954147116e121b56b03b1651a5bbb02c Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Fri, 26 Apr 2024 08:32:34 -0400 Subject: [PATCH 91/97] modem: cleaning print() methods for consistency --- src/modem/src/ampmodem.c | 16 ++++++++-------- src/modem/src/cpfskdem.proto.c | 2 +- src/modem/src/cpfskmod.proto.c | 2 +- src/modem/src/freqdem.proto.c | 3 +-- src/modem/src/freqmod.proto.c | 7 ++++--- src/modem/src/fskdem.c | 9 +++++---- src/modem/src/fskmod.c | 9 +++++---- src/modem/src/gmskdem.c | 11 ++++++----- src/modem/src/gmskmod.c | 4 +++- 9 files changed, 34 insertions(+), 29 deletions(-) diff --git a/src/modem/src/ampmodem.c b/src/modem/src/ampmodem.c index 43683691d..2828f272d 100644 --- a/src/modem/src/ampmodem.c +++ b/src/modem/src/ampmodem.c @@ -136,16 +136,16 @@ int ampmodem_destroy(ampmodem _q) int ampmodem_print(ampmodem _q) { - printf("ampmodem:\n"); - printf(" type : "); + printf("type) { - case LIQUID_AMPMODEM_DSB: printf("double side-band\n"); break; - case LIQUID_AMPMODEM_USB: printf("single side-band (upper)\n"); break; - case LIQUID_AMPMODEM_LSB: printf("single side-band (lower)\n"); break; - default: printf("unknown\n"); + case LIQUID_AMPMODEM_DSB: printf(", type=\"DSB\""); break; + case LIQUID_AMPMODEM_USB: printf(", type=\"USB\""); break; + case LIQUID_AMPMODEM_LSB: printf(", type=\"LSB\""); break; + default: printf(", type=\"?\""); } - printf(" supp. carrier : %s\n", _q->suppressed_carrier ? "yes" : "no"); - printf(" mod. index : %-8.4f\n", _q->mod_index); + printf(", carrier_suppressed=%s", _q->suppressed_carrier ? "true" : "false"); + printf(", mod_index=%g", _q->mod_index); + printf(">\n"); return LIQUID_OK; } diff --git a/src/modem/src/cpfskdem.proto.c b/src/modem/src/cpfskdem.proto.c index a4f781335..daa97067d 100644 --- a/src/modem/src/cpfskdem.proto.c +++ b/src/modem/src/cpfskdem.proto.c @@ -290,7 +290,7 @@ int CPFSKDEM(_destroy)(CPFSKDEM() _q) // print modulation internals int CPFSKDEM(_print)(CPFSKDEM() _q) { - printf("bps, _q->h, _q->k, _q->m, _q->beta); switch(_q->type) { case LIQUID_CPFSK_SQUARE: printf(", type=\"square\""); break; diff --git a/src/modem/src/cpfskmod.proto.c b/src/modem/src/cpfskmod.proto.c index dd3343316..676026244 100644 --- a/src/modem/src/cpfskmod.proto.c +++ b/src/modem/src/cpfskmod.proto.c @@ -200,7 +200,7 @@ int CPFSKMOD(_destroy)(CPFSKMOD() _q) // print modulator object internals int CPFSKMOD(_print)(CPFSKMOD() _q) { - printf("bps, _q->h, _q->k, _q->m, _q->beta); switch(_q->type) { case LIQUID_CPFSK_SQUARE: printf(", type=\"square\""); break; diff --git a/src/modem/src/freqdem.proto.c b/src/modem/src/freqdem.proto.c index a5b3b8e9c..8c8c8685d 100644 --- a/src/modem/src/freqdem.proto.c +++ b/src/modem/src/freqdem.proto.c @@ -74,8 +74,7 @@ int FREQDEM(_destroy)(FREQDEM() _q) // print modulation internals int FREQDEM(_print)(FREQDEM() _q) { - printf("freqdem:\n"); - printf(" mod. factor : %8.4f\n", _q->kf); + printf("\n", _q->kf); return LIQUID_OK; } diff --git a/src/modem/src/freqmod.proto.c b/src/modem/src/freqmod.proto.c index 66de42a39..2bcdd3d77 100644 --- a/src/modem/src/freqmod.proto.c +++ b/src/modem/src/freqmod.proto.c @@ -86,9 +86,10 @@ int FREQMOD(_destroy)(FREQMOD() _q) // print modulation internals int FREQMOD(_print)(FREQMOD() _q) { - printf("freqmod:\n"); - printf(" mod. factor : %8.4f\n", _q->kf); - printf(" sincos table len : %u\n", _q->sincos_table_len); + printf("kf); + printf(", tablen=%u", _q->sincos_table_len); + printf(">\n"); return LIQUID_OK; } diff --git a/src/modem/src/fskdem.c b/src/modem/src/fskdem.c index eb95aea0a..5d5129f6a 100644 --- a/src/modem/src/fskdem.c +++ b/src/modem/src/fskdem.c @@ -186,10 +186,11 @@ int fskdem_destroy(fskdem _q) // print fskdem object internals int fskdem_print(fskdem _q) { - printf("fskdem : frequency-shift keying demodulator\n"); - printf(" bits/symbol : %u\n", _q->m); - printf(" samples/symbol : %u\n", _q->k); - printf(" bandwidth : %8.5f\n", _q->bandwidth); + printf("m); + printf(", samples/symbol=%u", _q->k); + printf(", bandwidth=%g", _q->bandwidth); + printf(">\n"); return LIQUID_OK; } diff --git a/src/modem/src/fskmod.c b/src/modem/src/fskmod.c index fae96bd6a..35d306fa6 100644 --- a/src/modem/src/fskmod.c +++ b/src/modem/src/fskmod.c @@ -110,10 +110,11 @@ int fskmod_destroy(fskmod _q) // print fskmod object internals int fskmod_print(fskmod _q) { - printf("fskmod : frequency-shift keying modulator\n"); - printf(" bits/symbol : %u\n", _q->m); - printf(" samples/symbol : %u\n", _q->k); - printf(" bandwidth : %8.5f\n", _q->bandwidth); + printf("m); + printf(", samples/symbol=%u", _q->k); + printf(", bandwidth=%g", _q->bandwidth); + printf(">\n"); return LIQUID_OK; } diff --git a/src/modem/src/gmskdem.c b/src/modem/src/gmskdem.c index f837d29be..6dd07790a 100644 --- a/src/modem/src/gmskdem.c +++ b/src/modem/src/gmskdem.c @@ -173,13 +173,14 @@ int gmskdem_destroy(gmskdem _q) int gmskdem_print(gmskdem _q) { - printf("gmskdem [k=%u, m=%u, BT=%8.3f]\n", _q->k, _q->m, _q->BT); + printf("k, _q->m, _q->BT); #if GMSKDEM_USE_EQUALIZER - printf(" equalizer bandwidth : %12.8f\n", eqlms_rrrf_get_bw(_q->eq)); + printf(", eq_bw=%g", eqlms_rrrf_get_bw(_q->eq)); #endif - unsigned int i; - for (i=0; i<_q->h_len; i++) - printf(" hr(%4u) = %12.8f;\n", i+1, _q->h[i]); + //unsigned int i; + //for (i=0; i<_q->h_len; i++) + // printf(" hr(%4u) = %12.8f;\n", i+1, _q->h[i]); + printf(">\n"); return LIQUID_OK; } diff --git a/src/modem/src/gmskmod.c b/src/modem/src/gmskmod.c index 2602812d4..b85e57c11 100644 --- a/src/modem/src/gmskmod.c +++ b/src/modem/src/gmskmod.c @@ -122,10 +122,12 @@ int gmskmod_destroy(gmskmod _q) int gmskmod_print(gmskmod _q) { - printf("gmskmod [k=%u, m=%u, BT=%8.3f]\n", _q->k, _q->m, _q->BT); + printf("\n", _q->k, _q->m, _q->BT); +#if 0 unsigned int i; for (i=0; i<_q->h_len; i++) printf(" ht(%4u) = %12.8f;\n", i+1, _q->h[i]); +#endif return LIQUID_OK; } From d7152173ae6744e618e32c7307df4964ff3754d8 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 27 Apr 2024 11:29:14 -0400 Subject: [PATCH 92/97] bsequence: cleaning print() methods for consistency --- src/sequence/src/bsequence.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sequence/src/bsequence.c b/src/sequence/src/bsequence.c index 41014b6e9..065c41622 100644 --- a/src/sequence/src/bsequence.c +++ b/src/sequence/src/bsequence.c @@ -116,6 +116,7 @@ int bsequence_init(bsequence _bs, // Print sequence to the screen int bsequence_print(bsequence _bs) { +#if 0 unsigned int i, j; unsigned int chunk; unsigned int p = 8*sizeof(unsigned int); @@ -136,6 +137,9 @@ int bsequence_print(bsequence _bs) } } printf("\n"); +#else + printf("", _bs->num_bits); +#endif return LIQUID_OK; } From b4460c42ffdafad92e586e8e745cca0b44a24542 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Fri, 26 Apr 2024 16:56:14 -0400 Subject: [PATCH 93/97] nco: cleaning print() methods for consistency --- src/nco/src/nco.proto.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nco/src/nco.proto.c b/src/nco/src/nco.proto.c index c85bbf3da..036b71860 100644 --- a/src/nco/src/nco.proto.c +++ b/src/nco/src/nco.proto.c @@ -111,8 +111,8 @@ int NCO(_destroy)(NCO() _q) // Print nco object internals to stdout int NCO(_print)(NCO() _q) { - printf("nco [phase: 0x%.8x rad, freq: 0x%.8x rad/sample]\n", - _q->theta, _q->d_theta); + printf("\n", + EXTENSION, _q->theta, _q->d_theta); #if LIQUID_DEBUG_NCO // print entire table unsigned int i; From 96317f58e836eed63e7aeb9507e9032ded074db5 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 27 Apr 2024 13:36:08 -0400 Subject: [PATCH 94/97] optim: cleaning print() methods for consistency --- src/optim/src/gradsearch.c | 13 +++++++++++-- src/optim/src/qnsearch.c | 10 ++++++++++ src/optim/src/qs1dsearch.c | 2 +- src/optim/src/utilities.c | 6 ++---- 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/optim/src/gradsearch.c b/src/optim/src/gradsearch.c index d079f4b9c..269d7f775 100644 --- a/src/optim/src/gradsearch.c +++ b/src/optim/src/gradsearch.c @@ -92,13 +92,12 @@ void gradsearch_destroy(gradsearch _q) // print status void gradsearch_print(gradsearch _q) { +#if 0 //printf("gradient search:\n"); printf("u=%12.4e ", _q->u); // utility -#if 0 // enable more verbose output printf("|p|=%7.1e ", _q->pnorm); // norm(p) printf("del=%7.1e ", _q->delta); // delta -#endif printf("step=%7.1e ", _q->alpha); // alpha (step size) unsigned int i; @@ -106,6 +105,16 @@ void gradsearch_print(gradsearch _q) for (i=0; i<_q->num_parameters; i++) printf("%8.4f", _q->v[i]); printf("}\n"); +#else + printf("num_parameters); + printf(", dir=\"%s\"", _q->direction == LIQUID_OPTIM_MAXIMIZE ? "max" : "min"); + printf(", pnorm=%g", _q->pnorm); // norm(p) + printf(", delta=%g", _q->delta); // delta + printf(", u=%g", _q->u); + printf(">\n"); +#endif + // return LIQUID_OK; } float gradsearch_step(gradsearch _q) diff --git a/src/optim/src/qnsearch.c b/src/optim/src/qnsearch.c index 61bef0556..9786f6467 100644 --- a/src/optim/src/qnsearch.c +++ b/src/optim/src/qnsearch.c @@ -120,11 +120,21 @@ int qnsearch_destroy(qnsearch _q) int qnsearch_print(qnsearch _q) { +#if 0 printf("[%.3f] ", _q->utility); unsigned int i; for (i=0; i<_q->num_parameters; i++) printf("%.3f ", _q->v[i]); printf("\n"); +#else + printf("num_parameters); + printf(", dir=\"%s\"", _q->minimize ? "min" : "max"); + printf(", gamma=%g", _q->gamma); + printf(", delta=%g", _q->delta); // delta + printf(", u=%g", _q->utility); + printf(">\n"); +#endif return LIQUID_OK; } diff --git a/src/optim/src/qs1dsearch.c b/src/optim/src/qs1dsearch.c index 16600b829..abf8a1f71 100644 --- a/src/optim/src/qs1dsearch.c +++ b/src/optim/src/qs1dsearch.c @@ -71,7 +71,7 @@ int qs1dsearch_destroy(qs1dsearch _q) int qs1dsearch_print(qs1dsearch _q) { - printf("\n", + printf("\n", _q->vn, _q->v0, _q->vp, _q->un, _q->u0, _q->up); return LIQUID_OK; } diff --git a/src/optim/src/utilities.c b/src/optim/src/utilities.c index a8d1be351..61c5d835d 100644 --- a/src/optim/src/utilities.c +++ b/src/optim/src/utilities.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2020 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,9 +20,7 @@ * THE SOFTWARE. */ -// -// utilities.c : n-dimensional utility functions -// +// n-dimensional utility functions #include #include From 8b31f3e2805f57623017d196279f9a0379bc957b Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 27 Apr 2024 13:39:37 -0400 Subject: [PATCH 95/97] random/scramble: fixing incorrect description in comment --- src/random/src/scramble.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/random/src/scramble.c b/src/random/src/scramble.c index a675dcb7b..1483f3748 100644 --- a/src/random/src/scramble.c +++ b/src/random/src/scramble.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007 - 2015 Joseph Gaeddert + * Copyright (c) 2007 - 2024 Joseph Gaeddert * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -20,9 +20,7 @@ * THE SOFTWARE. */ -// -// Finite impulse response filter design -// +// data scrambler #include #include From 231df906ea87a26c2c78740a4a73fc7ad0248df0 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Sat, 27 Apr 2024 13:45:46 -0400 Subject: [PATCH 96/97] rresamp/autotest: reducing verbosity --- src/filter/tests/rresamp_crcf_autotest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/filter/tests/rresamp_crcf_autotest.c b/src/filter/tests/rresamp_crcf_autotest.c index 9e7299060..2c376bc35 100644 --- a/src/filter/tests/rresamp_crcf_autotest.c +++ b/src/filter/tests/rresamp_crcf_autotest.c @@ -45,7 +45,7 @@ void test_rresamp_crcf(const char * _method, } else if (strcmp(_method,"default")==0) { resamp = rresamp_crcf_create_default(_interp, _decim); } else { - printf("creating resampler using %s\n", _method); + //printf("creating resampler using %s\n", _method); int ftype = liquid_getopt_str2firfilt(_method); float beta = _bw; // rename to avoid confusion resamp = rresamp_crcf_create_prototype(ftype, _interp, _decim, _m, beta); From 030b5b4c79a42568c88e0489fcf6d998a79b4ea0 Mon Sep 17 00:00:00 2001 From: "Joseph D. Gaeddert" Date: Mon, 29 Apr 2024 16:59:06 -0400 Subject: [PATCH 97/97] github/ci: bumping checkout action, using brew to install autoconf deps --- .github/workflows/core.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml index 06228c93f..bed00a020 100644 --- a/.github/workflows/core.yml +++ b/.github/workflows/core.yml @@ -16,7 +16,13 @@ jobs: runs-on: ${{ matrix.runs-on }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 + + - name: setup + if: runner.os == 'macos' + run: | + brew update + brew install autoconf automake #- name: Setup libfec # run: git clone https://github.com/jgaeddert/libfec.git && cd libfec && ./configure && make && sudo make install