Skip to content

Commit

Permalink
Merge branch 'master' into bind-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
jgaeddert committed May 3, 2024
2 parents 420d161 + 030b5b4 commit 8a544fa
Show file tree
Hide file tree
Showing 123 changed files with 2,772 additions and 1,282 deletions.
8 changes: 7 additions & 1 deletion .github/workflows/core.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
push:
branches:
- master
- coverage-dev

jobs:
standard:
Expand Down Expand Up @@ -45,5 +46,9 @@ 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
with:
fail_ci_if_error: true
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}
6 changes: 5 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ coverage:
- ./bootstrap.sh
- ./configure --enable-coverage
- make -j4 coverage
- bash <(curl -s https://codecov.io/bash)
- curl -Os http://cli.codecov.io/latest/linux/codecov
- chmod +x codecov
- ./codecov --version
- ./codecov upload-process -t $CODECOV_TOKEN --git-service gitlab --slug jgaeddert/liquid-dsp

coverage: '/lines: \d+\.\d+%/'
artifacts:
paths: [coverage.out]
Expand Down
28 changes: 27 additions & 1 deletion autotest/autotest.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -362,3 +362,29 @@ 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,
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;
}

17 changes: 16 additions & 1 deletion autotest/autotest.h
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -316,5 +316,20 @@ 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(
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__

1 change: 1 addition & 0 deletions examples/bpacketsync_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -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; i<n; i++)
Expand Down
4 changes: 0 additions & 4 deletions examples/cbufferf_example.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
//
// cbufferf_example.c
//
// This example demonstrates the circular buffer object on
// floating-point data.
//
Expand Down Expand Up @@ -35,7 +32,6 @@ int main() {
cbufferf_write(cb, v, 8);

// print
cbufferf_debug_print(cb);
cbufferf_print(cb);

// destroy object
Expand Down
1 change: 1 addition & 0 deletions examples/cpfskmodem_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
97 changes: 97 additions & 0 deletions examples/dsssframe64sync_example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// This example demonstrates the basic interface to the dsssframe64gen and
// dsssframe64sync objects.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <getopt.h>
#include <assert.h>

#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 * _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;
float SNRdB = -10.0f;
const char * filename = "dsssframe64sync_example.m";

// 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 = (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");
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_execute(fg, NULL, NULL, buf_tx);

// apply channel (AWGN)
float nstd = powf(10.0f,-SNRdB/20.0f);
unsigned int i;
for (i=0; i<buf_len; i++)
buf_rx[i] = buf_tx[i]*M_SQRT1_2 + nstd*(randnf() + _Complex_I*randnf())/M_SQRT2;

// run through sync
dsssframe64sync fs = dsssframe64sync_create(callback, (void*)fid);
dsssframe64sync_execute(fs, buf_rx, buf_len);
dsssframe64sync_destroy(fs);

// push resulting sample through periodogram
spgramcf periodogram = spgramcf_create_default(nfft);
spgramcf_write(periodogram, buf_rx, buf_len);
float psd[nfft];
spgramcf_get_psd(periodogram, psd);
spgramcf_destroy(periodogram);

// plot results
fprintf(fid,"nfft=%u; Y=zeros(1,nfft);\n", nfft);
for (i=0; i<nfft; i++)
fprintf(fid,"Y(%4u) = %12.8f;\n", i+1, psd[i]);
fprintf(fid,"figure('position',[100 100 1200 400]);\n");
fprintf(fid,"subplot(1,5,1:3);\n");
fprintf(fid," f=[0:(nfft-1)]/nfft-0.5; plot(f,Y); xlim([-0.5 0.5]); grid on;\n");
fprintf(fid," xlabel('Normalized Frequency [f/Fs]'); ylabel('PSD [dB]');\n");
fprintf(fid,"subplot(1,5,4:5);\n");
fprintf(fid," plot(real(s),imag(s),'.','MarkerSize',6); grid on; axis([-1 1 -1 1]*1.5)\n");
fprintf(fid," axis('square'); xlabel('I'); ylabel('Q');\n");
fclose(fid);
printf("results written to %s\n", filename);

// destroy allocated objects and free memory
dsssframe64gen_destroy(fg);
free(buf_tx);
free(buf_rx);
return 0;
}

101 changes: 101 additions & 0 deletions examples/dsssframe64sync_performance_example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// This example tests the performance for detecting and decoding frames
// with the dsssframe64gen and dsssframe64sync objects.
// SEE ALSO: dsssframe64sync_example.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#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);
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() ) * M_SQRT1_2;
}

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 = 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);
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);
fprintf(fid,"clear all; close all;\n");
fprintf(fid,"SNR=[]; pdetect=[]; pvalid=[];\n");
printf("# %8s %6s (%7s) %6s (%7s) %6s\n", "SNR", "missed", "percent", "errors", "percent", "trials");
fclose(fid);
while (SNRdB < -5.0f) {
dsssframe64sync_reset_framedatastats(fs);
unsigned int num_trials = 0, num_errors = 0;
while (1) {
unsigned int i;
for (i=0; i<min_trials; i++) {
// reset frame synchronizer
dsssframe64sync_reset(fs);

// generate the frame with random header and payload
dsssframe64gen_execute(fg, NULL, NULL, frame);

// add channel effects
frame64_add_noise(frame, frame_len, SNRdB);

// synchronize/receive the frame
dsssframe64sync_execute(fs, frame, frame_len);
}
num_trials += min_trials;
num_errors = num_trials - dsssframe64sync_get_framedatastats(fs).num_payloads_valid;
if (num_errors >= min_errors)
break;
if (num_trials >= max_trials)
break;
}
// print results
framedatastats_s stats = dsssframe64sync_get_framedatastats(fs);
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,
(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");
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([-30 10 1e-3 1]);\n");
fprintf(fid,"grid on;\n");
fclose(fid);
printf("results written to %s\n", OUTPUT_FILENAME);

// clean up allocated objects and memory blocks
dsssframe64gen_destroy(fg);
dsssframe64sync_destroy(fs);
free(frame);
return 0;
}
1 change: 1 addition & 0 deletions examples/firpfb_rrrf_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
Loading

0 comments on commit 8a544fa

Please sign in to comment.