Skip to content

Commit

Permalink
Merge branch 'master' into symtrack-dev
Browse files Browse the repository at this point in the history
  • Loading branch information
jgaeddert committed Jun 14, 2015
2 parents e09257f + 9bad3e6 commit 1433a9c
Show file tree
Hide file tree
Showing 11 changed files with 396 additions and 50 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,10 @@ Available Modules

### License ###

liquid projects are released under the MIT license.
Short version: this code is copyrighted to me (Joseph D. Gaeddert), I give you
permission to do what you want with it except remove my name from the credits.
See the LICENSE file for specific terms.
liquid projects are released under the X11/MIT license.
Short version: this code is copyrighted to me (Joseph D. Gaeddert),
I give you permission to do wantever you want with it except remove my name
from the credits. See the LICENSE file or
[http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT)
for specific terms.

22 changes: 22 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,28 @@ This directory contains all the examples for interfacing the liquid modules.
SEE ALSO: `bsequence_example.c`
`msequence_example.c`

* `conversion_example.c`:

This example demonstrates conversion from complex baseband to a real-valued
signal, and then down-conversion back to complex baseband while removing the
negative image.

STEP 1: A signal is generated at complex baseband consisting of narrow-band
filtered noise and an offset tone (to show asymmetry in the transmit
spectrum).

STEP 2: The signal is mixed up to a carrier 'fc' (relative to the sampling
frequency) and the real-component of the result is retained. This is
the DAC output. The spectrum of this signal has two images: one at
+fc, the other at -fc.

STEP 3: The DAC output is mixed back down to complex baseband and the lower
image is (mostly) filtered off. Reminants of the lower frequency
component are still visible due to the wide-band and low-order
filter on the receiver. The received complex baseband signal also
has a reduction in power by 2 because half the signal's energy (the
negative image) is filtered off.

* `crc_example.c`:
Cyclic redundancy check (CRC) example. This example demonstrates how a
CRC can be used to validate data received through un-reliable means (e.g.
Expand Down
140 changes: 140 additions & 0 deletions examples/conversion_example.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
//
// conversion_example.c
//
// This example demonstrates conversion from complex baseband to a real-valued
// signal, and then down-conversion back to complex baseband while removing the
// negative image.
//
// STEP 1: A signal is generated at complex baseband consisting of narrow-band
// filtered noise and an offset tone (to show asymmetry in the transmit
// spectrum).
//
// STEP 2: The signal is mixed up to a carrier 'fc' (relative to the sampling
// frequency) and the real-component of the result is retained. This is
// the DAC output. The spectrum of this signal has two images: one at
// +fc, the other at -fc.
//
// STEP 3: The DAC output is mixed back down to complex baseband and the lower
// image is (mostly) filtered off. Reminants of the lower frequency
// component are still visible due to the wide-band and low-order
// filter on the receiver. The received complex baseband signal also
// has a reduction in power by 2 because half the signal's energy (the
// negative image) is filtered off.
//

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "liquid.h"

#define OUTPUT_FILENAME "conversion_example.m"

int main()
{
// spectral periodogram options
unsigned int nfft = 1200; // spectral periodogram FFT size
unsigned int num_samples = 64000; // number of samples
float alpha = 0.02f; // bandwidth factor for estimating PSD
float fc = 0.20f; // carrier (relative to sampling rate)

// create objects
iirfilt_crcf filter_tx = iirfilt_crcf_create_lowpass(15, 0.05);
nco_crcf mixer_tx = nco_crcf_create(LIQUID_VCO);
nco_crcf mixer_rx = nco_crcf_create(LIQUID_VCO);
iirfilt_crcf filter_rx = iirfilt_crcf_create_lowpass(7, 0.2);

// set carrier frequencies
nco_crcf_set_frequency(mixer_tx, fc * 2*M_PI);
nco_crcf_set_frequency(mixer_rx, fc * 2*M_PI);

// create objects for measuring power spectral density
spgramcf spgram_tx = spgramcf_create_default(nfft);
spgramf spgram_dac = spgramf_create_default(nfft);
spgramcf spgram_rx = spgramcf_create_default(nfft);

// run through loop one step at a time
unsigned int i;
for (i=0; i<num_samples; i++) {
// STEP 1: generate input signal (filtered noise with offset tone)
float complex v1 = (randnf() + randnf()*_Complex_I) + 3.0f*cexpf(-_Complex_I*0.2f*i);
iirfilt_crcf_execute(filter_tx, v1, &v1);

// save spectrum
spgramcf_accumulate_psd(spgram_tx, &v1, alpha, 1);

// STEP 2: mix signal up and save real part (DAC output)
nco_crcf_mix_up(mixer_tx, v1, &v1);
float v2 = crealf(v1);
nco_crcf_step(mixer_tx);

// save spectrum
spgramf_accumulate_psd(spgram_dac, &v2, alpha, 1);

// STEP 3: mix signal down and filter off image
float complex v3;
nco_crcf_mix_down(mixer_rx, v2, &v3);
iirfilt_crcf_execute(filter_rx, v3, &v3);
nco_crcf_step(mixer_rx);

// save spectrum
spgramcf_accumulate_psd(spgram_rx, &v3, alpha, 1);
}

// compute power spectral density output
float psd_tx [nfft];
float psd_dac [nfft];
float psd_rx [nfft];
spgramcf_write_accumulation(spgram_tx, psd_tx);
spgramf_write_accumulation( spgram_dac, psd_dac);
spgramcf_write_accumulation(spgram_rx, psd_rx);

// destroy objects
spgramcf_destroy(spgram_tx);
spgramf_destroy(spgram_dac);
spgramcf_destroy(spgram_rx);

iirfilt_crcf_destroy(filter_tx);
nco_crcf_destroy(mixer_tx);
nco_crcf_destroy(mixer_rx);
iirfilt_crcf_destroy(filter_rx);

//
// export output file
//
FILE * fid = fopen(OUTPUT_FILENAME,"w");
fprintf(fid,"%% %s : auto-generated file\n", OUTPUT_FILENAME);
fprintf(fid,"clear all;\n");
fprintf(fid,"close all;\n\n");

fprintf(fid,"nfft = %u;\n", nfft);
fprintf(fid,"f = [0:(nfft-1)]/nfft - 0.5;\n");
fprintf(fid,"psd_tx = zeros(1,nfft);\n");
fprintf(fid,"psd_dac= zeros(1,nfft);\n");
fprintf(fid,"psd_rx = zeros(1,nfft);\n");

for (i=0; i<nfft; i++) {
fprintf(fid,"psd_tx (%6u) = %12.4e;\n", i+1, psd_tx [i]);
fprintf(fid,"psd_dac(%6u) = %12.4e;\n", i+1, psd_dac[i]);
fprintf(fid,"psd_rx (%6u) = %12.4e;\n", i+1, psd_rx [i]);
}

fprintf(fid,"figure;\n");
fprintf(fid,"hold on;\n");
fprintf(fid," plot(f, psd_tx, '-', 'LineWidth',1.5,'Color',[0.7 0.7 0.7]);\n");
fprintf(fid," plot(f, psd_dac, '-', 'LineWidth',1.5,'Color',[0.0 0.5 0.3]);\n");
fprintf(fid," plot(f, psd_rx, '-', 'LineWidth',1.5,'Color',[0.0 0.3 0.5]);\n");
fprintf(fid,"hold off;\n");
fprintf(fid,"xlabel('Normalized Frequency [f/F_s]');\n");
fprintf(fid,"ylabel('Power Spectral Density [dB]');\n");
fprintf(fid,"grid on;\n");
fprintf(fid,"axis([-0.5 0.5 -100 60]);\n");
fprintf(fid,"legend('transmit (complex)','DAC output (real)','receive (complex)','location','northeast');\n");

fclose(fid);
printf("results written to %s.\n", OUTPUT_FILENAME);

printf("done.\n");
return 0;
}

29 changes: 11 additions & 18 deletions examples/crc_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ void usage()
int main(int argc, char*argv[])
{
// options
unsigned int n = 32; // data length (bytes)
crc_scheme check = LIQUID_CRC_32; // error-detection scheme
unsigned int n = 32; // data length (bytes)
crc_scheme check = LIQUID_CRC_32; // error-detection scheme

int dopt;
while((dopt = getopt(argc,argv,"uhn:v:")) != EOF){
Expand All @@ -55,27 +55,20 @@ int main(int argc, char*argv[])

unsigned int i;

// initialize data arra
unsigned char data[n];
// initialize data array, leaving space for key at the end
unsigned char data[n+4];
for (i=0; i<n; i++)
data[i] = rand() % 256;
data[i] = rand() & 0xff;

// compute key on original data
unsigned int key = crc_generate_key(check, data, n);
printf("key: 0x%.8x\n", (unsigned int) key);
// append key to data message
crc_append_key(check, data, n);

printf("testing uncorrupted data... ");
if (crc_validate_message(check, data, n, key))
printf(" pass\n");
else
printf(" FAIL\n");
// check uncorrupted data
printf("testing uncorrupted data... %s\n", crc_check_key(check, data, n) ? "pass" : "FAIL");

printf("testing corrupted data... ");
// corrupt message and check data again
data[0]++;
if (crc_validate_message(check, data, n, key))
printf(" pass\n");
else
printf(" FAIL\n");
printf("testing corrupted data... %s\n", crc_check_key(check, data, n) ? "pass" : "FAIL (ok)");

printf("done.\n");
return 0;
Expand Down
8 changes: 4 additions & 4 deletions examples/firpfbch_crcf_analysis_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

int main() {
// options
unsigned int num_channels=8; // number of channels
unsigned int m=4; // filter delay
float As=60; // stop-band attenuation
unsigned int num_frames=25; // number of frames
unsigned int num_channels = 8; // number of channels
unsigned int m = 4; // filter delay
float As = 60; // stop-band attenuation
unsigned int num_frames = 25; // number of frames

//
unsigned int i;
Expand Down
20 changes: 10 additions & 10 deletions examples/firpfbch_crcf_synthesis_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

int main() {
// options
unsigned int num_channels=16; // number of channels
unsigned int m=5; // filter delay
float As=60; // stop-band attenuation
unsigned int num_frames=25; // number of frames
unsigned int num_channels = 16; // number of channels
unsigned int m = 5; // filter delay
float As = 60; // stop-band attenuation
unsigned int num_frames = 25; // number of frames

//
unsigned int i;
Expand All @@ -33,19 +33,19 @@ int main() {
float complex x[num_channels][num_frames]; // channelized input
float complex y[num_samples]; // time-domain output [size: num_samples x 1]

// create narrow-band pulse
unsigned int pulse_len = 17; // pulse length [samples]
float bw = 0.30f; // pulse width (bandwidth)
float pulse[pulse_len]; // buffer
liquid_firdes_kaiser(pulse_len, bw, 50.0f, 0.0f, pulse);

// generate input signal(s)
int enabled[num_channels]; // signal enabled?
unsigned int pulse_len = 17;
float pulse[pulse_len];
for (i=0; i<num_channels; i++) {
// pseudo-random channel enabled flag
enabled[i] = ((i*37)%101)%2;

if (enabled[i]) {
// create pulse
float bw = 0.30f; // pulse width
liquid_firdes_kaiser(pulse_len, bw, 50.0f, 0.0f, pulse);

// move pulse to input buffer
for (k=0; k<num_frames; k++)
x[i][k] = k < pulse_len ? bw*pulse[k] : 0.0f;
Expand Down
34 changes: 27 additions & 7 deletions include/liquid.h
Original file line number Diff line number Diff line change
Expand Up @@ -769,24 +769,41 @@ crc_scheme liquid_getopt_str2crc(const char * _str);
unsigned int crc_get_length(crc_scheme _scheme);

// generate error-detection key
//
// _scheme : error-detection scheme
// _msg : input data message, [size: _n x 1]
// _n : input data message size
unsigned int crc_generate_key(crc_scheme _scheme,
unsigned int crc_generate_key(crc_scheme _scheme,
unsigned char * _msg,
unsigned int _n);
unsigned int _n);

// generate error-detection key and append to end of message
// _scheme : error-detection scheme (resulting in 'p' bytes)
// _msg : input data message, [size: _n+p x 1]
// _n : input data message size (excluding key at end)
void crc_append_key(crc_scheme _scheme,
unsigned char * _msg,
unsigned int _n);

// validate message using error-detection key
//
// _scheme : error-detection scheme
// _msg : input data message, [size: _n x 1]
// _n : input data message size
// _key : error-detection key
int crc_validate_message(crc_scheme _scheme,
int crc_validate_message(crc_scheme _scheme,
unsigned char * _msg,
unsigned int _n,
unsigned int _key);
unsigned int _n,
unsigned int _key);

// check message with key appended to end of array
// _scheme : error-detection scheme (resulting in 'p' bytes)
// _msg : input data message, [size: _n+p x 1]
// _n : input data message size (excluding key at end)
int crc_check_key(crc_scheme _scheme,
unsigned char * _msg,
unsigned int _n);

// get size of key (bytes)
unsigned int crc_sizeof_key(crc_scheme _scheme);


// available FEC schemes
Expand Down Expand Up @@ -1203,6 +1220,9 @@ SPGRAM() SPGRAM(_create_kaiser)(unsigned int _nfft, \
unsigned int _window_len, \
float _beta); \
\
/* create default spgram object (Kaiser-Bessel window) */ \
SPGRAM() SPGRAM(_create_default)(unsigned int _nfft); \
\
/* destroy spgram object */ \
void SPGRAM(_destroy)(SPGRAM() _q); \
\
Expand Down
1 change: 1 addition & 0 deletions makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,7 @@ example_programs := \
examples/compand_example \
examples/compand_cf_example \
examples/complementary_codes_example \
examples/conversion_example \
examples/crc_example \
examples/cgsolve_example \
examples/cvsd_example \
Expand Down
Loading

0 comments on commit 1433a9c

Please sign in to comment.