WIP DSSS decoding

This commit is contained in:
jaseg 2020-03-06 11:09:35 +01:00
parent 4b419bd1ad
commit ad9e17c35c
18 changed files with 578 additions and 31753 deletions

File diff suppressed because one or more lines are too long

View file

@ -1795,7 +1795,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.5"
"version": "3.7.6"
}
},
"nbformat": 4,

View file

@ -46,12 +46,16 @@ FMEAS_ADC_MAX ?= 4096
FMEAS_FFT_LEN ?= 256
FMEAS_FFT_WINDOW ?= gaussian
FMEAS_FFT_WINDOW_SIGMA ?= 16.0
# TODO: validate
FMEAS_SAMPLING_RATE ?= 10.0
DSSS_GOLD_CODE_NBITS ?= 5
DSSS_DECIMATION ?= 10
DSSS_THESHOLD_FACTOR ?= 4.0f
DSSS_WAVELET_WIDTH ?= 7.3
DSSS_WAVELET_LUT_SIZE ?= 69
DSSS_FILTER_FC ?= 20e-3
DSSS_FILTER_ORDER ?= 8
CC := $(PREFIX)gcc
CXX := $(PREFIX)g++
@ -122,7 +126,7 @@ LDFLAGS += -L$(OPENCM3_DIR_ABS)/lib -l$(OPENCM3_LIB) $(shell $(CC) -print-libg
all: $(BUILDDIR)/$(BINARY)
src/dsss_demod.c: $(BUILDDIR)/generated/dsss_gold_code.h
src/dsss_demod.c: $(BUILDDIR)/generated/dsss_gold_code.h $(BUILDDIR)/generated/dsss_butter_filter.h
$(BUILDDIR)/generated/dsss_gold_code.h: $(BUILDDIR)/generated/gold_code_$(DSSS_GOLD_CODE_NBITS).h
ln -srf $< $@
@ -139,6 +143,10 @@ $(BUILDDIR)/generated/fmeas_fft_window.c: | $(BUILDDIR)/generated
$(BUILDDIR)/generated/dsss_cwt_wavelet.c: | $(BUILDDIR)/generated
$(PYTHON3) tools/cwt_wavelet_header_gen.py -v dsss_cwt_wavelet_table $(DSSS_WAVELET_LUT_SIZE) $(DSSS_WAVELET_WIDTH) > $@
.PRECIOUS: $(BUILDDIR)/generated/dsss_butter_filter.h
$(BUILDDIR)/generated/dsss_butter_filter.h: | $(BUILDDIR)/generated
$(PYTHON3) tools/butter_filter_gen.py -m dsss_filter $(DSSS_FILTER_FC) $(FMEAS_SAMPLING_RATE) $(DSSS_FILTER_ORDER) > $@
$(BUILDDIR)/generated: ; mkdir -p $@
OBJS := $(addprefix $(BUILDDIR)/,$(C_SOURCES:.c=.o) $(CXX_SOURCES:.cpp=.o))

@ -1 +1 @@
Subproject commit 6a86f4ca00d2b96b82879e1e5bd9e89c5750dd22
Subproject commit 4a65d88011a1595b7c8b42fa0d70b7bdfc132acc

@ -1 +1 @@
Subproject commit afae623190f025e7cf2fb0222bfe796b69a36941
Subproject commit a0a8706c9dc9e43bc51d16334cd6c0f6ae084ce9

View file

@ -11,17 +11,14 @@
#include "simulation.h"
#include "generated/dsss_gold_code.h"
#include "generated/dsss_butter_filter.h"
/* Generated CWT wavelet LUT */
extern const float * const dsss_cwt_wavelet_table;
struct iir_biquad cwt_filter_bq[3] = {
{.a = {-1.993939440f, 0.993949280f}, .b = {0.2459934300683e-5, 0.4919868601367e-5, 0.2459934300683e-5}},
{.a = {-1.995557124f, 0.995566972f}, .b = {0.2461930046414e-5, 0.4923860092828e-5, 0.2461930046414e-5}},
{.a = {-1.998365254f, 0.998375115f}, .b = {0.2465394452097e-5, 0.4930788904195e-5, 0.2465394452097e-5}},
};
struct iir_biquad cwt_filter_bq[DSSS_FILTER_CLEN] = {DSSS_FILTER_COEFF};
float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx);
float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx, bool debug);
float cwt_convolve_step(const float v[DSSS_WAVELET_LUT_SIZE], size_t offx);
float run_iir(const float x, const int order, const struct iir_biquad q[order], struct iir_biquad_state st[order]);
float run_biquad(float x, const struct iir_biquad *const q, struct iir_biquad_state *const restrict st);
@ -34,7 +31,7 @@ void dsss_demod_step(struct dsss_demod_state *st, float new_value) {
//#define DEBUG_PRINT(...) ((void)0)
//#define DEBUG_PRINTN(...) ((void)0)
bool debug = sim_pos % DSSS_CORRELATION_LENGTH == 0;
bool debug = sim_pos % DSSS_CORRELATION_LENGTH == DSSS_CORRELATION_LENGTH-1;
if (debug) DEBUG_PRINT("Iteration %zd", sim_pos);
//const float peak_group_threshold = 0.05 * DSSS_CORRELATION_LENGTH;
//const float hole_patching_threshold = 0.01 * DSSS_CORRELATION_LENGTH;
@ -45,14 +42,14 @@ void dsss_demod_step(struct dsss_demod_state *st, float new_value) {
/* use new, incremented wpos for gold_correlate_step as first element of old data in ring buffer */
for (size_t i=0; i<DSSS_GOLD_CODE_COUNT; i++)
st->correlation[i][st->correlation_wpos] = gold_correlate_step(i, st->signal, st->correlation_wpos);
st->correlation[i][st->correlation_wpos] = gold_correlate_step(i, st->signal, st->signal_wpos, debug);
/* debug */
/*
DEBUG_PRINTN(" correlation: [");
for (size_t i=0; i<DSSS_GOLD_CODE_COUNT; i++)
DEBUG_PRINTN("%f, ", st->correlation[i][st->correlation_wpos]);
DEBUG_PRINTN("]\n");
*/
if (debug) {
DEBUG_PRINTN(" correlation: [");
for (size_t i=0; i<DSSS_GOLD_CODE_COUNT; i++)
DEBUG_PRINTN("%f, ", st->correlation[i][st->correlation_wpos]);
DEBUG_PRINTN("]\n");
}
/* end */
st->correlation_wpos = (st->correlation_wpos + 1) % ARRAY_LENGTH(st->correlation[0]);
@ -60,10 +57,12 @@ void dsss_demod_step(struct dsss_demod_state *st, float new_value) {
for (size_t i=0; i<DSSS_GOLD_CODE_COUNT; i++)
cwt[i] = cwt_convolve_step(st->correlation[i], st->correlation_wpos);
/* debug */
/*
if (debug) DEBUG_PRINTN(" cwt: [");
for (size_t i=0; i<DSSS_GOLD_CODE_COUNT; i++)
if (debug) DEBUG_PRINTN("%f, ", cwt[i]);
if (debug) DEBUG_PRINTN("]\n");
*/
/* end */
float avg[DSSS_GOLD_CODE_COUNT];
@ -82,10 +81,10 @@ void dsss_demod_step(struct dsss_demod_state *st, float new_value) {
int max_ch = st->group.max_ch;
int max_idx = st->group.max_idx + 1;
bool found = false;
if (debug) DEBUG_PRINTN(" rel: [");
//if (debug) DEBUG_PRINTN(" rel: [");
for (size_t i=0; i<DSSS_GOLD_CODE_COUNT; i++) {
float val = cwt[i] / avg[i];
if (debug) DEBUG_PRINTN("%f, ", val);
//if (debug) DEBUG_PRINTN("%f, ", val);
if (fabs(val) > DSSS_THESHOLD_FACTOR)
found = true;
@ -96,7 +95,7 @@ void dsss_demod_step(struct dsss_demod_state *st, float new_value) {
max_idx = st->group.len;
}
}
if (debug) DEBUG_PRINTN("]\n");
//if (debug) DEBUG_PRINTN("]\n");
/* debug */
if (debug) DEBUG_PRINT(" found=%d len=%d idx=%d ch=%d max=%f",
@ -162,19 +161,27 @@ float cwt_convolve_step(const float v[DSSS_WAVELET_LUT_SIZE], size_t offx) {
*
* [0] https://docs.scipy.org/doc/numpy/reference/generated/numpy.correlate.html
*/
float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx) {
float gold_correlate_step(const size_t ncode, const float a[DSSS_CORRELATION_LENGTH], size_t offx, bool debug) {
float acc_outer = 0.0f;
uint8_t table_byte = 0;
for (size_t i=0, pos=0; i<DSSS_GOLD_CODE_LENGTH; i++, pos += DSSS_DECIMATION) {
float acc_inner = 0.0f;
for (size_t j=0; j<DSSS_DECIMATION; j++) {
if ((pos&7) == 0)
table_byte = dsss_gold_code_table[ncode][pos>>3]; /* Fetch sequence table item */
int bv = table_byte & (1<<(pos&7)); /* Extract bit */
bv = !!bv*2 - 1; /* Map 0, 1 -> -1, 1 */
acc_inner += a[(offx + i + j) % DSSS_CORRELATION_LENGTH] * bv; /* Multiply item */
if (debug) DEBUG_PRINTN("Correlate n=%d: ", ncode);
for (size_t i=0; i<DSSS_GOLD_CODE_LENGTH; i++) {
if ((i&7) == 0) {
table_byte = dsss_gold_code_table[ncode][i>>3]; /* Fetch sequence table item */
if (debug) DEBUG_PRINTN("|");
}
acc_outer += acc_inner;
int bv = table_byte & (0x80>>(i&7)); /* Extract bit */
bv = !!bv*2 - 1; /* Map 0, 1 -> -1, 1 */
if (debug) DEBUG_PRINTN("%s%d\033[0m", bv == 1 ? "\033[92m" : "\033[91m", (bv+1)/2);
float acc_inner = 0.0f;
for (size_t j=0; j<DSSS_DECIMATION; j++)
acc_inner += a[(offx + i*DSSS_DECIMATION + j) % DSSS_CORRELATION_LENGTH]; /* Multiply item */
//if (debug) DEBUG_PRINTN("%.2f ", acc_inner);
acc_outer += acc_inner * bv;
}
if (debug) DEBUG_PRINTN("\n");
return acc_outer / DSSS_CORRELATION_LENGTH;
}

View file

@ -0,0 +1,50 @@
#!/usr/bin/env python3
import sys
import contextlib
import scipy.signal as sig
@contextlib.contextmanager
def wrap(left='{', right='}', file=None, end=''):
print(left, file=file, end=end)
yield
print(right, file=file, end=end)
@contextlib.contextmanager
def print_include_guards(macro_name):
print(f'#ifndef {macro_name}')
print(f'#define {macro_name}')
yield
print(f'#endif /* {macro_name} */')
macro_float = lambda f: f'{f}'.replace('.', 'F').replace('-', 'N').replace('+', 'P')
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-m', '--macro-name', default='butter_filter', help='Prefix for output macro names')
parser.add_argument('fc', type=float, help='Corner frequency [Hz]')
parser.add_argument('fs', type=float, help='Sampling rate [Hz]')
parser.add_argument('n', type=int, nargs='?', default=6, help='Filter order')
args = parser.parse_args()
sos = sig.butter(args.n, args.fc, fs=args.fs, output='sos')
print('/* THIS IS A GENERATED FILE. DO NOT EDIT! */')
with print_include_guards(f'__BUTTER_FILTER_GENERATED_{args.n}_{macro_float(args.fc)}_{macro_float(args.fs)}__'):
print(f'#define {args.macro_name.upper()}_ORDER {args.n}')
print(f'#define {args.macro_name.upper()}_CLEN {(args.n+1)//2}')
print(f'#define {args.macro_name.upper()}_COEFF ', end='')
for sec in sos:
with wrap():
print('.b=', end='')
with wrap():
print(', '.join(f'{v}' for v in sec[:3]), end='')
print(', .a=', end='')
with wrap():
print(', '.join(f'{v}' for v in sec[4:6]), end='')
print(', ', end='')
print()

View file

@ -58,19 +58,13 @@ if __name__ == '__main__':
print(f' *')
print(f' * Each code is packed left-aligned into {nbytes} bytes in big-endian byte order.')
print(f' */')
print(f'const uint8_t gold_code_{args.n}bit[{2**args.n+1}][{nbytes}] = {{')
print(f'const uint8_t {args.variable}[{2**args.n+1}][{nbytes}] = {{')
for i, code in enumerate(gold(args.n)):
par = '{' + ' '.join(f'0x{d:02x},' for d in np.packbits(code)) + f'}}, /* {i: 3d} "{"".join(str(x) for x in code)}" */'
print(textwrap.fill(par, initial_indent=' '*4, subsequent_indent=' '*4, width=120))
print('};')
print()
print(f'const uint8_t * const {args.variable} __attribute__((weak)) = (uint8_t *const)gold_code_{args.n}bit;')
print(f'const size_t {args.variable}_nbits __attribute__((weak)) = {args.n};')
else:
print('/* THIS IS A GENERATED FILE. DO NOT EDIT! */')
with print_include_guards(f'__GOLD_CODE_GENERATED_HEADER_{args.n}__'):
print(f'extern const uint8_t gold_code_{args.n}bit[{2**args.n+1}][{nbytes}];')
with print_include_guards(f'__GOLD_CODE_GENERATED_HEADER_GLOBAL_SYM_{args.variable.upper()}__'):
print(f'extern const uint8_t {args.variable}[{2**args.n+1}][{nbytes}];')
print(f'extern const size_t {args.variable}_nbits;')

View file

@ -2380,6 +2380,373 @@
<value>-1</value>
</param>
</block>
<block>
<key>qtgui_time_sink_x</key>
<param>
<key>autoscale</key>
<value>True</value>
</param>
<param>
<key>axislabels</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>ctrlpanel</key>
<value>False</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>entags</key>
<value>True</value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(1144, 16)</value>
</param>
<param>
<key>gui_hint</key>
<value></value>
</param>
<param>
<key>_rotation</key>
<value>90</value>
</param>
<param>
<key>grid</key>
<value>False</value>
</param>
<param>
<key>id</key>
<value>qtgui_time_sink_x_0_1_0</value>
</param>
<param>
<key>legend</key>
<value>True</value>
</param>
<param>
<key>alpha1</key>
<value>1.0</value>
</param>
<param>
<key>color1</key>
<value>"blue"</value>
</param>
<param>
<key>label1</key>
<value></value>
</param>
<param>
<key>marker1</key>
<value>-1</value>
</param>
<param>
<key>style1</key>
<value>1</value>
</param>
<param>
<key>width1</key>
<value>1</value>
</param>
<param>
<key>alpha10</key>
<value>1.0</value>
</param>
<param>
<key>color10</key>
<value>"blue"</value>
</param>
<param>
<key>label10</key>
<value></value>
</param>
<param>
<key>marker10</key>
<value>-1</value>
</param>
<param>
<key>style10</key>
<value>1</value>
</param>
<param>
<key>width10</key>
<value>1</value>
</param>
<param>
<key>alpha2</key>
<value>1.0</value>
</param>
<param>
<key>color2</key>
<value>"red"</value>
</param>
<param>
<key>label2</key>
<value></value>
</param>
<param>
<key>marker2</key>
<value>-1</value>
</param>
<param>
<key>style2</key>
<value>1</value>
</param>
<param>
<key>width2</key>
<value>1</value>
</param>
<param>
<key>alpha3</key>
<value>1.0</value>
</param>
<param>
<key>color3</key>
<value>"green"</value>
</param>
<param>
<key>label3</key>
<value></value>
</param>
<param>
<key>marker3</key>
<value>-1</value>
</param>
<param>
<key>style3</key>
<value>1</value>
</param>
<param>
<key>width3</key>
<value>1</value>
</param>
<param>
<key>alpha4</key>
<value>1.0</value>
</param>
<param>
<key>color4</key>
<value>"black"</value>
</param>
<param>
<key>label4</key>
<value></value>
</param>
<param>
<key>marker4</key>
<value>-1</value>
</param>
<param>
<key>style4</key>
<value>1</value>
</param>
<param>
<key>width4</key>
<value>1</value>
</param>
<param>
<key>alpha5</key>
<value>1.0</value>
</param>
<param>
<key>color5</key>
<value>"cyan"</value>
</param>
<param>
<key>label5</key>
<value></value>
</param>
<param>
<key>marker5</key>
<value>-1</value>
</param>
<param>
<key>style5</key>
<value>1</value>
</param>
<param>
<key>width5</key>
<value>1</value>
</param>
<param>
<key>alpha6</key>
<value>1.0</value>
</param>
<param>
<key>color6</key>
<value>"magenta"</value>
</param>
<param>
<key>label6</key>
<value></value>
</param>
<param>
<key>marker6</key>
<value>-1</value>
</param>
<param>
<key>style6</key>
<value>1</value>
</param>
<param>
<key>width6</key>
<value>1</value>
</param>
<param>
<key>alpha7</key>
<value>1.0</value>
</param>
<param>
<key>color7</key>
<value>"yellow"</value>
</param>
<param>
<key>label7</key>
<value></value>
</param>
<param>
<key>marker7</key>
<value>-1</value>
</param>
<param>
<key>style7</key>
<value>1</value>
</param>
<param>
<key>width7</key>
<value>1</value>
</param>
<param>
<key>alpha8</key>
<value>1.0</value>
</param>
<param>
<key>color8</key>
<value>"dark red"</value>
</param>
<param>
<key>label8</key>
<value></value>
</param>
<param>
<key>marker8</key>
<value>-1</value>
</param>
<param>
<key>style8</key>
<value>1</value>
</param>
<param>
<key>width8</key>
<value>1</value>
</param>
<param>
<key>alpha9</key>
<value>1.0</value>
</param>
<param>
<key>color9</key>
<value>"dark green"</value>
</param>
<param>
<key>label9</key>
<value></value>
</param>
<param>
<key>marker9</key>
<value>-1</value>
</param>
<param>
<key>style9</key>
<value>1</value>
</param>
<param>
<key>width9</key>
<value>1</value>
</param>
<param>
<key>name</key>
<value>"mod"</value>
</param>
<param>
<key>nconnections</key>
<value>3</value>
</param>
<param>
<key>size</key>
<value>19500</value>
</param>
<param>
<key>srate</key>
<value>samp_rate</value>
</param>
<param>
<key>stemplot</key>
<value>False</value>
</param>
<param>
<key>tr_chan</key>
<value>0</value>
</param>
<param>
<key>tr_delay</key>
<value>0.007</value>
</param>
<param>
<key>tr_level</key>
<value>0.1</value>
</param>
<param>
<key>tr_mode</key>
<value>qtgui.TRIG_MODE_TAG</value>
</param>
<param>
<key>tr_slope</key>
<value>qtgui.TRIG_SLOPE_POS</value>
</param>
<param>
<key>tr_tag</key>
<value>"start"</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>update_time</key>
<value>0.10</value>
</param>
<param>
<key>ylabel</key>
<value>Amplitude</value>
</param>
<param>
<key>yunit</key>
<value>""</value>
</param>
<param>
<key>ymax</key>
<value>1</value>
</param>
<param>
<key>ymin</key>
<value>-1</value>
</param>
</block>
<block>
<key>parameter</key>
<param>
@ -2481,6 +2848,24 @@
<source_key>0</source_key>
<sink_key>2</sink_key>
</connection>
<connection>
<source_block_id>blocks_float_to_complex_0</source_block_id>
<sink_block_id>qtgui_time_sink_x_0_1_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_float_to_complex_0</source_block_id>
<sink_block_id>qtgui_time_sink_x_0_1_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>blocks_float_to_complex_0</source_block_id>
<sink_block_id>qtgui_time_sink_x_0_1_0</sink_block_id>
<source_key>0</source_key>
<sink_key>2</sink_key>
</connection>
<connection>
<source_block_id>blocks_multiply_const_vxx_1</source_block_id>
<sink_block_id>blocks_add_const_vxx_1</sink_block_id>

View file

@ -898,7 +898,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.5"
"version": "3.7.6"
}
},
"nbformat": 4,

View file

@ -125,7 +125,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "ba042a79e76742dfae88bd0a5913cb1f",
"model_id": "afc732c0ada8419e89a7ff2551212c00",
"version_major": 2,
"version_minor": 0
},
@ -196,7 +196,7 @@
},
{
"cell_type": "code",
"execution_count": 124,
"execution_count": 8,
"metadata": {
"scrolled": false
},
@ -1045,7 +1045,7 @@
},
{
"cell_type": "code",
"execution_count": 46,
"execution_count": 10,
"metadata": {
"scrolled": false
},
@ -1858,7 +1858,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 11,
"metadata": {
"scrolled": false
},
@ -1866,7 +1866,7 @@
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "bb14b5b4747148898f1d8f046318bb55",
"model_id": "36ffcac30c8b4b378d3c422d3ef0698b",
"version_major": 2,
"version_minor": 0
},
@ -1937,7 +1937,7 @@
},
{
"cell_type": "code",
"execution_count": 119,
"execution_count": 12,
"metadata": {
"scrolled": false
},
@ -2773,7 +2773,7 @@
},
{
"cell_type": "code",
"execution_count": 115,
"execution_count": 13,
"metadata": {
"scrolled": false
},
@ -3637,7 +3637,7 @@
},
{
"cell_type": "code",
"execution_count": 127,
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
@ -3656,22 +3656,22 @@
},
{
"cell_type": "code",
"execution_count": 128,
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"54.0"
"(160118,)"
]
},
"execution_count": 128,
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"27000 * 2e-3"
"def modulate(sequences, data)"
]
}
],

View file

@ -73,11 +73,11 @@
},
{
"cell_type": "code",
"execution_count": 5,
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"def modulate(data, nbits=5):\n",
"def modulate(data, nbits=5, pad=True):\n",
" # 0, 1 -> -1, 1\n",
" mask = np.array(gold(nbits))*2 - 1\n",
" \n",
@ -85,7 +85,10 @@
" data_lsb_centered = ((data&1)*2 - 1)\n",
"\n",
" signal = (np.multiply(sel, np.tile(data_lsb_centered, (2**nbits-1, 1)).T).flatten() + 1) // 2\n",
" return np.hstack([ np.zeros(len(mask)), signal, np.zeros(len(mask)) ])"
" if pad:\n",
" return np.hstack([ np.zeros(len(mask)), signal, np.zeros(len(mask)) ])\n",
" else:\n",
" return signal"
]
},
{
@ -124,7 +127,7 @@
},
{
"cell_type": "code",
"execution_count": 8,
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
@ -139,18 +142,19 @@
},
{
"cell_type": "code",
"execution_count": 73,
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"test_duration = 300\n",
"test_duration = 200\n",
"test_nbits = 5\n",
"test_signal_amplitude=2.0e-3\n",
"test_decimation=10\n",
"\n",
"for test_signal_amplitude in [2.0e-3, 20e-3, 200e-3, 2]:\n",
" test_data = np.random.RandomState(seed=0).randint(0, 2 * (2**test_nbits), test_duration)\n",
" signal = np.repeat(modulate(test_data, test_nbits) * 2.0 - 1, test_decimation) * test_signal_amplitude\n",
" #test_data = np.array([0, 1, 2, 3] * 50)\n",
" signal = np.repeat(modulate(test_data, test_nbits, pad=False) * 2.0 - 1, test_decimation) * test_signal_amplitude\n",
" with open(f'dsss_test_signals/dsss_test_noiseless_{test_signal_amplitude*1000:.0f}mHz.bin', 'wb') as f:\n",
" for e in signal:\n",
" f.write(struct.pack('<f', e))"
@ -1174,9 +1178,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "labenv",
"display_name": "winlabenv",
"language": "python",
"name": "labenv"
"name": "winlabenv"
},
"language_info": {
"codemirror_mode": {
@ -1188,7 +1192,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.1"
"version": "3.7.6"
}
},
"nbformat": 4,

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -722,9 +722,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "labenv",
"display_name": "winlabenv",
"language": "python",
"name": "labenv"
"name": "winlabenv"
},
"language_info": {
"codemirror_mode": {
@ -736,7 +736,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.1"
"version": "3.7.6"
}
},
"nbformat": 4,

View file

@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 3,
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
@ -10,7 +10,9 @@
"\n",
"import numpy as np\n",
"from matplotlib import pyplot as plt\n",
"import matplotlib"
"import matplotlib\n",
"\n",
"import scipy.signal as sig"
]
},
{
@ -141,13 +143,40 @@
" ax.text(0.2, 0.2, f'mean={mean:.3}Hz, rms={rms*1e3:.3}mHz', ha='center', va='center', transform=ax.transAxes,\n",
" bbox=dict(boxstyle=\"square\", ec=(0,0,0,0), fc=(1,1,1,0.8)))"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 2.35232554e-18, 4.70465108e-18, 2.35232554e-18,\n",
" 1.00000000e+00, -1.97549493e+00, 9.75650918e-01],\n",
" [ 1.00000000e+00, 2.00000000e+00, 1.00000000e+00,\n",
" 1.00000000e+00, -1.97916324e+00, 9.79319515e-01],\n",
" [ 1.00000000e+00, 2.00000000e+00, 1.00000000e+00,\n",
" 1.00000000e+00, -1.98597735e+00, 9.86134166e-01],\n",
" [ 1.00000000e+00, 2.00000000e+00, 1.00000000e+00,\n",
" 1.00000000e+00, -1.99495144e+00, 9.95108965e-01]])"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sig.butter(8, 20e-3, output='sos', fs=10.0)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "labenv",
"display_name": "winlabenv",
"language": "python",
"name": "labenv"
"name": "winlabenv"
},
"language_info": {
"codemirror_mode": {
@ -159,7 +188,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.1"
"version": "3.7.6"
}
},
"nbformat": 4,