Compare commits

...

94 commits

Author SHA1 Message Date
MeFisto94
69bfc62890 Fix Architecture Detection 2019-05-29 21:31:37 +00:00
MeFisto94
022e3419d8 Try to improve the platform detection and offload it to a shell script 2019-05-28 21:07:00 +02:00
Andras Retzler
6ef2a74206 Now calling pthread_detach for each thread 2019-02-27 17:07:58 +01:00
Andras Retzler
17b8c7b3c0 Fixed missing entry from varicode table 2019-01-25 19:03:58 +01:00
Andras Retzler
055127ca31 Attempting to fix nmux crash (#40) 2019-01-24 15:37:14 +01:00
András Retzler
eabc2c50dc
Update README.md 2018-12-09 11:13:10 +01:00
András Retzler
f5ef7b0c70
Update README.md 2018-11-19 08:50:42 +01:00
András Retzler
f565d2a4bf Delete nmux-todo.md 2017-10-16 15:23:32 +02:00
ha7ilm
07236afacd Merged feature/digitalmods 2017-07-12 18:55:16 +02:00
ha7ilm
32c7e3b52c README.md 2017-07-07 13:19:57 +02:00
ha7ilm
146bb6e383 README 2017-07-07 13:10:30 +02:00
ha7ilm
7825fc5d0f Added a lot of docs 2017-07-06 19:17:58 +02:00
ha7ilm
d8b47f6ad2 Added test_m_fsk.grc 2017-06-25 12:22:43 +02:00
ha7ilm
09bcde5b4e Updated README and added bpsk31_ber.py 2017-06-14 11:57:32 +02:00
ha7ilm
ee5b546439 Fixed generic slicer, etc. 2017-05-20 21:02:18 +02:00
ha7ilm
978289e76b Some modifications to the S-curve 2017-05-19 14:55:11 +02:00
ha7ilm
f9a6535e10 Edited Makefile
Changed functionality of pack_bits_8to1_u8_u8
Added pack_bits_1to8_u8_u8, pattern_search_u8_u8, dbpsk_decoder_c_u8, bfsk_demod_cf
2017-05-18 23:43:40 +02:00
ha7ilm
117ee8e3a8 I've actually seen this version doing as well as Fldigi in a simulation 2017-05-16 17:02:55 +02:00
ha7ilm
c6d5287d82 Fixed timing_recovery_cc docs and tedvar graph generator 2017-05-15 23:07:26 +02:00
ha7ilm
50528abd71 Fixed CLI for timing recovery, added max_dphase for Costas 2017-05-15 21:35:58 +02:00
ha7ilm
fe46aba98d Costas loop looks working again 2017-05-14 23:39:11 +02:00
ha7ilm
7718eda15b costas loop --octave changed to --output_combined 2017-05-14 22:03:18 +02:00
ha7ilm
2a3c210250 Working on the Costas loop 2017-05-14 17:37:54 +02:00
András Retzler
d76ea6378e Merge pull request #27 from ckuethe/soname-fix
make the library file name match the soname
2017-05-12 00:15:59 +02:00
Chris Kuethe
d8a7723051 make the library file name match the soname 2017-05-11 15:07:32 -07:00
ha7ilm
2450ed3439 Renamed some functions, e.g. reso->peak, matched filter -> pulse shaping filter 2017-05-11 16:04:55 +02:00
ha7ilm
d1c5628f50 Added SONAME 2017-05-11 10:29:06 +02:00
ha7ilm
1baa45ab05 Added @ before ldconfig in Makefile 2017-05-11 10:16:00 +02:00
András Retzler
a0e796326c Merge pull request #12 from ckuethe/master
respect PREFIX to allow alternate destinations
2017-05-11 10:04:47 +02:00
Chris Kuethe
fbf4ffbd32 respect PREFIX to allow alternate destinations 2017-05-10 20:21:37 -07:00
ha7ilm
dbaa973354 grc hangs from too much info on stderr 2017-05-07 23:46:37 +02:00
ha7ilm
b749e78925 Added psk31_sigmodel.m 2017-05-05 12:06:28 +02:00
ha7ilm
d526744d0c Added "csdr tee" and unified how csdr messages start 2017-05-05 11:34:40 +02:00
ha7ilm
b6143ad4f8 Merge remote-tracking branch 'origin/master' into feature/digitalmods 2017-05-03 21:49:12 +02:00
ha7ilm
574dd91e7e Merged teejez -> feature/digitalmods 2017-05-03 21:48:55 +02:00
ha7ilm
66eaef4e7d Added new functions to --help 2017-05-03 21:35:45 +02:00
András Retzler
03724f3a7a Merge pull request #21 from tejeez/master
Support for receivers providing real signal
2017-05-03 18:33:11 +02:00
ha7ilm
ac8e1b61b4 bpsk_costas_loop_cc now locks to +1+0j and -1+0j 2017-05-02 19:31:29 +02:00
ha7ilm
36eb0c3481 Working bpsk_costas_loop_cc 2017-05-02 19:23:05 +02:00
ha7ilm
efbe28cbfd Made new bpsk_costas_loop_cc, added add_const_cc, added new parameters to timing_recvery_cc 2017-05-02 18:37:54 +02:00
ha7ilm
84d23227f3 Added plain_interpolate_cc 2017-05-01 13:09:42 +02:00
ha7ilm
bfc6f5dea0 Working RRC filter design 2017-04-30 22:23:21 +02:00
ha7ilm
d1af45a588 Added matched filter 2017-04-30 17:51:35 +02:00
ha7ilm
0878d3bd43 Retabbed most source files to 4 spaces 2017-04-30 14:30:13 +02:00
ha7ilm
d7d36a70a8 Actually this plot now looks OK 2017-04-30 13:51:12 +02:00
ha7ilm
2a4e2ce190 Added code quality check, --awgnfile and gaussian_noise_c 2017-04-30 11:41:14 +02:00
ha7ilm
3464174c07 Current version 2017-04-30 10:18:40 +02:00
ha7ilm
addd52f148 Now showing E_b/N_0 in the plot 2017-04-30 10:06:31 +02:00
ha7ilm
5934d1f7a3 Now graph is acceptable 2017-04-30 00:16:56 +02:00
ha7ilm
35f059aecc Diagram almost OK for thesis 2017-04-30 00:05:04 +02:00
ha7ilm
3f527311d6 Very detailed, but correct looking phase variance diagram 2017-04-29 23:56:29 +02:00
ha7ilm
ec38e3be7d We process a higher amount of data 2017-04-29 23:27:39 +02:00
ha7ilm
bfd3004106 Added tedvar Octave script 2017-04-29 22:48:43 +02:00
ha7ilm
80ee1645ec Added normalized_timing_variance_u32_f, ??, etc. 2017-04-29 18:11:02 +02:00
ha7ilm
a9dc49c8d9 Added S-curve for Gardner 2017-04-29 12:28:56 +02:00
ha7ilm
e426ef65d1 Better font for S-curve graph 2017-04-29 11:44:19 +02:00
ha7ilm
57790eb9af Added agwn_cc 2017-04-28 19:34:55 +02:00
ha7ilm
e31c7648a5 Added noise_f 2017-04-28 15:34:14 +02:00
ha7ilm
d391ea2ef6 Added BPSK31 S-curve generator script, added repeat_u8 and error output fortiming_recovery_cc 2017-04-28 14:20:14 +02:00
ha7ilm
22bd8baa15 Added a --octave to help 2017-04-28 10:20:13 +02:00
ha7ilm
6a5c76f6a4 Added fft one side 2017-04-20 16:51:34 +02:00
ha7ilm
82ff09acc0 Added RTTY tests 2017-04-20 16:48:57 +02:00
ha7ilm
2c3fa2fde9 Merged origin/master into feature/digitalmods 2017-04-18 11:34:13 +02:00
ha7ilm
9c5b050560 Changed labels in Costas GRC 2017-04-18 11:22:26 +02:00
ha7ilm
bfe88c1e10 Working FIR resonator and related GRC test 2017-04-09 19:00:07 +02:00
ha7ilm
c1e953cd4e Added resonator FIR 2017-04-09 14:53:22 +02:00
ha7ilm
874d6b7c06 firdes_carrier_c to firdes_add_carrier_c 2017-04-08 16:36:10 +02:00
ha7ilm
cdc2996dcc Added firdes_carrier_c 2017-04-08 12:39:52 +02:00
ha7ilm
50c885748e Working BPSK31 demodulator 2017-04-07 16:05:38 +02:00
ha7ilm
dd0d20921b Added simple_agc_cc GRC test 2017-04-06 22:03:09 +02:00
ha7ilm
fc350d594c Added simple_agc_cc 2017-04-06 20:38:44 +02:00
ha7ilm
e7f9be41c2 Fixed function name 2017-04-06 15:41:52 +02:00
ha7ilm
93b996412a Fixed bug that prevented many functions to work; this came from a previous commit 2017-04-06 15:35:52 +02:00
ha7ilm
ad36d1160e Removed all _sy functions, renamed to u8. 2017-04-05 20:06:04 +02:00
ha7ilm
52a225d791 Varied the bufsizes to produce output with PSK31 2017-04-05 19:59:29 +02:00
ha7ilm
47333b6690 Make OpenWebRX be more responsive and load faster! 2017-04-05 13:07:17 +02:00
Andras Retzler
d56fc2d799 Fixed segmentation fault in fractional_decimator_ff 2017-04-02 21:23:47 +00:00
András Retzler
c3e5d3f433 Merge pull request #17 from ricovangenugten/master
Fixed issue simonyiszk/csdr#15
2017-03-05 10:32:58 +01:00
ha7ilm
c8eac34110 Added *.swp to .gitignore 2017-02-28 17:08:18 +01:00
ha7ilm
59513fc306 Fixed even more docs 2017-02-28 17:03:21 +01:00
ha7ilm
86cedde53f Fixed some more docs 2017-02-28 16:27:04 +01:00
ha7ilm
c7d9aa05e7 Fixed a lot of things related to fractional decimator 2017-02-28 00:27:41 +01:00
ha7ilm
875434bf96 added comment 2017-02-18 16:37:49 +01:00
ha7ilm
5f772ec3e3 made that spectrum even better 2017-02-18 16:36:36 +01:00
ha7ilm
1fab87af1d haha, fixed that artifact too. Strange flickering line in the spectrum at -100 dB was caused by reading some samples out of region 2017-02-18 16:26:51 +01:00
ha7ilm
0306b5b5bf fixed fractional_decimator_ff for N=6 interpolator, still interesting effect on the spectrum 2017-02-18 16:24:19 +01:00
ha7ilm
5f8f8695d3 fixed fractional_decimator_ff 2017-02-18 16:17:53 +01:00
ha7ilm
139d3d731b single samples bad, possibly at the beginning 2017-02-18 16:01:14 +01:00
ha7ilm
f4da40ffa7 fractional_decimator_ff gets new algorithm based on Lagrange interpolator formula 2017-02-18 15:49:04 +01:00
Tatu Peltola
b6f50cbf06 Changed every_n_samples in fft_fc to be based on actual input samples 2016-10-31 19:14:16 +02:00
Tatu Peltola
1446b62959 Implement shift_addition_fc for downconversion of real signal 2016-10-31 18:29:25 +02:00
Tatu Peltola
5a46f15d1b Add fft_fc: FFT for real input signal 2016-10-31 18:29:19 +02:00
Rico van Genugten
12d7db8b49 Fixed issue simonyiszk/csdr#15 by fixing allocating size in bytes instead of size in amount of taps 2016-10-06 11:28:34 +00:00
Rico van Genugten
7ba726af5b Fixed issue simonyiszk/csdr#15 by using veor instead of vmov to zero accumulators in fir_decimate_cc. Also removed some unused variables 2016-10-06 09:12:34 +00:00
31 changed files with 14223 additions and 6077 deletions

1
.gitignore vendored
View file

@ -3,6 +3,7 @@ nmux
ddcd
*.o
*.so
*.so.*
tags
dumpvect.*.vect
*.swp

View file

@ -28,13 +28,7 @@
LIBSOURCES = fft_fftw.c libcsdr_wrapper.c
#SOURCES = csdr.c $(LIBSOURCES)
cpufeature = $(if $(findstring $(1),$(shell cat /proc/cpuinfo)),$(2))
PARAMS_SSE = $(call cpufeature,sse,-msse) $(call cpufeature,sse2,-msse2) $(call cpufeature,sse3,-msse3) $(call cpufeature,sse4a,-msse4a) $(call cpufeature,sse4_1,-msse4.1) $(call cpufeature,sse4_2,-msse4.2 -msse4) -mfpmath=sse
PARAMS_NEON = -mfloat-abi=hard -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mvectorize-with-neon-quad -funsafe-math-optimizations -Wformat=0 -DNEON_OPTS
#tnx Jan Szumiec for the Raspberry Pi support
PARAMS_RASPI = -mfloat-abi=hard -mcpu=arm1176jzf-s -mfpu=vfp -funsafe-math-optimizations -Wformat=0
PARAMS_ARM = $(if $(call cpufeature,BCM2708,dummy-text),$(PARAMS_RASPI),$(PARAMS_NEON))
PARAMS_SIMD = $(if $(call cpufeature,sse,dummy-text),$(PARAMS_SSE),$(PARAMS_ARM))
PARAMS_SIMD = $(shell ./detect_params.sh)
PARAMS_LOOPVECT = -O3 -ffast-math -fdump-tree-vect-details -dumpbase dumpvect
PARAMS_LIBS = -g -lm -lrt -lfftw3f -DUSE_FFTW -DLIBCSDR_GPL -DUSE_IMA_ADPCM
PARAMS_SO = -fpic
@ -42,16 +36,22 @@ PARAMS_MISC = -Wno-unused-result
#DEBUG_ON = 0 #debug is always on by now (anyway it could be compiled with `make DEBUG_ON=1`)
#PARAMS_DEBUG = $(if $(DEBUG_ON),-g,)
FFTW_PACKAGE = fftw-3.3.3
PREFIX ?= /usr
SOVERSION = 0.15
PARSEVECT ?= yes
.PHONY: clean-vect clean
all: csdr nmux
.PHONY: clean-vect clean codequality checkdocs v
all: codequality csdr nmux
libcsdr.so: fft_fftw.c fft_rpi.c libcsdr_wrapper.c libcsdr.c libcsdr_gpl.c fastddc.c fastddc.h fft_fftw.h fft_rpi.h ima_adpcm.h libcsdr_gpl.h libcsdr.h predefined.h
@echo NOTE: you may have to manually edit Makefile to optimize for your CPU \(especially if you compile on ARM, please edit PARAMS_NEON\).
@echo Auto-detected optimization parameters: $(PARAMS_SIMD)
@echo
rm -f dumpvect*.vect
gcc -std=gnu99 $(PARAMS_LOOPVECT) $(PARAMS_SIMD) $(LIBSOURCES) $(PARAMS_LIBS) $(PARAMS_MISC) -fpic -shared -o libcsdr.so
gcc -std=gnu99 $(PARAMS_LOOPVECT) $(PARAMS_SIMD) $(LIBSOURCES) $(PARAMS_LIBS) $(PARAMS_MISC) -fpic -shared -Wl,-soname,libcsdr.so.$(SOVERSION) -o libcsdr.so.$(SOVERSION)
@ln -fs libcsdr.so.$(SOVERSION) libcsdr.so
ifeq ($(PARSEVECT),yes)
-./parsevect dumpvect*.vect
endif
csdr: csdr.c libcsdr.so
gcc -std=gnu99 $(PARAMS_LOOPVECT) $(PARAMS_SIMD) csdr.c $(PARAMS_LIBS) -L. -lcsdr $(PARAMS_MISC) -o csdr
ddcd: ddcd.cpp libcsdr.so ddcd.h
@ -64,19 +64,19 @@ arm-cross: clean-vect
clean-vect:
rm -f dumpvect*.vect
clean: clean-vect
rm -f libcsdr.so csdr ddcd nmux
rm -f libcsdr.so.$(SOVERSION) csdr ddcd nmux *.o *.so
install: all
install -m 0755 libcsdr.so /usr/lib
install -m 0755 csdr /usr/bin
install -m 0755 csdr-fm /usr/bin
install -m 0755 nmux /usr/bin
#-install -m 0755 ddcd /usr/bin
ldconfig
install -m 0755 libcsdr.so.$(SOVERSION) $(PREFIX)/lib
install -m 0755 csdr $(PREFIX)/bin
install -m 0755 csdr-fm $(PREFIX)/bin
install -m 0755 nmux $(PREFIX)/bin
#-install -m 0755 ddcd $(PREFIX)/bin
@ldconfig || echo please run ldconfig
uninstall:
rm /usr/lib/libcsdr.so /usr/bin/csdr /usr/bin/csdr-fm
rm $(PREFIX)/lib/libcsdr.so.$(SOVERSION) $(PREFIX)/bin/csdr $(PREFIX)/bin/csdr-fm
ldconfig
disasm:
objdump -S libcsdr.so > libcsdr.disasm
objdump -S libcsdr.so.$(SOVERSION) > libcsdr.disasm
emcc-clean:
-rm sdr.js/sdr.js
-rm sdr.js/sdrjs-compiled.js
@ -96,3 +96,12 @@ emcc:
cat sdr.js/sdrjs-header.js sdr.js/sdrjs-compiled.js sdr.js/sdrjs-footer.js > sdr.js/sdr.js
emcc-beautify:
bash -c 'type js-beautify >/dev/null 2>&1; if [ $$? -eq 0 ]; then js-beautify sdr.js/sdr.js >sdr.js/sdr.js.beautiful; mv sdr.js/sdr.js.beautiful sdr.js/sdr.js; fi'
codequality:
@bash -c 'if [ `cat csdr.c | grep badsyntax | grep -v return | wc -l` -ne 1 ]; then echo "error at code quality check: badsyntax() used in csdr.c without return."; exit 1; else exit 0; fi'
checkdocs:
@cat csdr.c | grep strcmp | egrep 'argv\[1\]' | awk -F'"' '$$0=$$2' > /tmp/csdr-list-of-functions
@cat /tmp/csdr-list-of-functions | xargs -I{} bash -c 'if ! cat csdr.c | grep \"\ \ \ \ {} >/dev/null ; then echo "warning: \"{}\" is in csdr.c code, but not in usage string"; fi'
@cat /tmp/csdr-list-of-functions | xargs -I{} bash -c 'if ! cat README.md | grep {} >/dev/null ; then echo "warning: \"{}\" is in csdr.c code, but not in README.md"; fi'
@rm /tmp/csdr-list-of-functions
v:
vim csdr.c libcsdr.c

575
README.md Normal file → Executable file
View file

@ -1,14 +1,26 @@
libcsdr
=======
CSDR
====
`csdr` is a command line tool to carry out DSP tasks for Software Defined Radio.
It can be used to build simple signal processing flow graphs, right from the command line.
The included `libcsdr` library contains the DSP functions that `csdr` makes use of. It was designed to use auto-vectorization available in `gcc`, and also has some functions optimized with inline assembly for ARM NEON to achieve some speedup by taking advantage of SIMD command sets available in today's CPUs.
*libcsdr* is a set of simple DSP routines for Software Defined Radio.
It is mostly useful for AM/FM/SSB demodulation and spectrum display.
Feel free to use it in your projects.
Most of the code is available under the permissive BSD license, with some optional parts under GPL. For additional details, see <a href="#licensing">licensing</a>.
- The package comes with a command-line tool `csdr`, which lets you build DSP processing chains by shell pipes.
- The code of *libcsdr* was intended to be easy to follow.
- *libcsdr* was designed to use auto-vectorization available in *gcc*. It means that it can achieve some speedup by taking advantage of SIMD command sets available in today's CPUs (e.g. SSE on x86 and NEON on ARM).
`csdr` has already been used to build:
- AM, FM, SSB, CW and BPSK31 demodulators and waterfall display in [OpenWebRX](https://github.com/simonyiszk/openwebrx),
- AM, FM, SSB modulators in [qtcsdr](https://github.com/ha7ilm/qtcsdr) that can also be used standalone with [rpitx](https://github.com/ha7ilm/rpitx-app-note),
- a demodulator for FSK transmissions sent with the CC1111 wireless MCU, and also a standalone RTTY demodulator.
This animation shows the Gardner timing recovery algorithm in `csdr` locking on a baseband BPSK signal:
![Gardner](https://raw.githubusercontent.com/wiki/simonyiszk/csdr/gardner.gif)
(The symbol is sampled at the left red dot. The algorithm moves the middle dot as close to the symbol transition center, as possible.)
How to compile
--------------
@ -22,11 +34,11 @@ If you compile on ARM, please edit the Makefile and tailor `PARAMS_NEON` for you
To run the examples, you will also need <a href="http://sdr.osmocom.org/trac/wiki/rtl-sdr">rtl_sdr</a> from Osmocom, and the following packages (at least on Debian): `mplayer octave gnuplot gnuplot-x11`
If you compile *fftw3* from sources for use with *libcsdr*, you need to configure it with 32-bit float support enabled:
If you compile `fftw3` from sources for use with `libcsdr`, you need to configure it with 32-bit float support enabled:
./configure --enable-float
(This is for *fftw3*, not *libcsdr*. You do not need to run the configure script before compiling *libcsdr*.)
(This is for `fftw3`, not `libcsdr`. You do not need to run the configure script before compiling `libcsdr`.)
Credits
-------
@ -97,7 +109,7 @@ The first parameter is the frequency in MHz, and the second optional parameter i
rtl_sdr -s 2400000 -f 145000000 -g 20 - | csdr convert_u8_f | csdr shift_addition_cc `python -c "print float(145000000-144400000)/2400000"` | csdr fir_decimate_cc 50 0.005 HAMMING | csdr bandpass_fir_fft_cc 0 0.1 0.05 | csdr realpart_cf | csdr agc_ff | csdr limit_ff | csdr convert_f_s16 | mplayer -cache 1024 -quiet -rawaudio samplesize=2:channels=1:rate=48000 -demuxer rawaudio -
- It is a modified Weaver-demodulator. The complex FIR filter removes the lower sideband and lets only the upper pass (USB). If you want to demodulate LSB, change `bandpass_fir_fft_cc 0 0.05` to `bandpass_fir_fft_cc -0.05 0`.
- It is a modified Weaver-demodulator. The complex FIR filter removes the lower sideband and lets only the upper pass (USB). If you want to demodulate LSB, change `bandpass_fir_fft_cc 0 0.1` to `bandpass_fir_fft_cc -0.1 0`.
### Draw FFT
@ -134,12 +146,15 @@ The following commands are available:
- `csdr convert_f_s8`
- `csdr convert_s16_f`
- `csdr convert_f_s16`
- `csdr convert_s24_f [--bigendian]`
- `csdr convert_f_s24 [--bigendian]`
How to interpret: `csdr convert_<src>_<dst>`
You can use these commands on complex streams, too, as they are only interleaved values (I,Q,I,Q,I,Q... coming after each other).
> Note: The the functions with `i16` in their names have been renamed, but still work (e.g. `csdr convert_f_i16`).
### csdr commands
`csdr` should be considered as a reference implementation on using `libcsdr`. For additional details on how to use the library, check `csdr.c` and `libcsdr.c`.
@ -375,6 +390,16 @@ It cannot be used as a channelizer by itself, use `fir_decimate_cc` instead.
----
### [shift_addition_fc](#shift_addition_fc)
Syntax:
csdr shift_addition_fc <rate>
It converts the real input signal to complex, and then shifts it in the frequency domain by `rate`.
----
### [dcblock_ff](#dcblock_ff)
Syntax:
@ -554,11 +579,28 @@ The output sample rate will be `interpolation / decimation × input_sample_rate`
Syntax:
csdr fractional_decimator_ff <decimation_rate> [transition_bw [window]]
csdr fractional_decimator_ff <decimation_rate> [num_poly_points ( [transition_bw [window]] | --prefilter )]
It can decimate by a floating point ratio.
`transition_bw` and `window` are the parameters of the filter.
It uses Lagrance interpolation, where `num_poly_points` (12 by default) input samples are taken into consideration while calculating one output sample.
It can filter the signal with an anti-aliasing FIR filter before applying the Lagrange interpolation. This filter is inactive by default, but can be activated by:
* passing only the `transition_bw`, or both the `transition_bw` and the `window` parameters of the filter,
* using the `--prefilter` switch after `num_poly_points` to switch this filter on with the default parameters.
----
### [old_fractional_decimator_ff](#old_fractional_decimator_ff)
Syntax:
csdr old_fractional_decimator_ff <decimation_rate> [transition_bw [window]]
This is the deprecated, old algorithm to decimate by a floating point ratio, superseded by `fractional_decimator_ff`.
(It uses linear interpolation, and its filter cuts at 59% of the passband.)
----
@ -582,7 +624,7 @@ Syntax:
It is an automatic gain control function.
- `hang_time` is the number of samples to wait before strating to increase the gain after a peak.
- `hang_time` is the number of samples to wait before starting to increase the gain after a peak.
- `reference` is the reference level for the AGC. It tries to keep the amplitude of the output signal close to that.
- `attack_rate` is the rate of decreasing the signal level if it gets higher than it used to be before.
- `decay_rate` is the rate of increasing the signal level if it gets lower than it used to be before.
@ -618,6 +660,20 @@ FFTW can be faster if we let it optimalize a while before starting the first tra
----
### [fft_fc](#fft_fc)
Syntax:
csdr fft_fc <fft_out_size> <out_of_every_n_samples> [--benchmark]
It works similarly to <a href="#fft_cc">fft_cc</a>, but on real input samples.
For real FFT, the `fft_out_size` parameter is the number of output complex bins instead of the actual FFT size.
Number of input samples used for each FFT is `2 × fft_out_size`. This makes it easier to replace `fft_cc` by `fft_fc` in some applications.
----
### [fft_benchmark](#fft_benchmark)
Syntax:
@ -641,12 +697,6 @@ Calculates `10*log10(i^2+q^2)+add_db` for the input complex samples. It is usefu
### [encode_ima_adpcm_i16_u8](#encode_ima_adpcm_i16_u8)
Syntax:
----
### [csdr](#csdr)
Syntax:
csdr csdr encode_ima_adpcm_i16_u8
@ -811,6 +861,483 @@ For this input, the output of `psk31_varicode_encoder_u8_u8` will be the followi
----
### [repeat_u8](#repeat_u8)
Syntax:
csdr repeat_u8 <data_bytes × N>
It repeatedly outputs a set of data bytes (given with decimal numbers).
For example, `csdr repeat_u8 1 1 0 0` will output:
```
01 01 00 00 01 01 00 00
01 01 00 00 01 01 00 00
```
----
### [uniform_noise_f](#uniform_noise_f)
Syntax:
csdr uniform_noise_f
It outputs uniform white noise. All samples are within the range [-1.0, 1.0].
----
### [gaussian_noise_c](#gaussian_noise_c)
Syntax:
csdr gaussian_noise_c
It outputs Gaussian white noise. All samples are within the unit circle.
----
### [pack_bits_8to1_u8_u8](#pack_bits_8to1_u8_u8)
Syntax:
csdr pack_bits_8to1_u8_u8
TODO
----
### [pack_bits_1to8_u8_u8](#pack_bits_1to8_u8_u8)
Syntax:
csdr pack_bits_1to8_u8_u8
It serializes the bytes on the input: it outputs each bit of the input byte as a single byte valued 0x00 or 0x01, starting from the lowest bit and going to the highest bit.
The output is 8 times as large in size as the input.
For example, the input byte 0x43 will result in eight bytes at the output:
```
01 01 00 00 00 00 01 00
```
For consequtive 0x02, 0x03, 0xff bytes on the input, the output will be:
```
00 01 00 00 00 00 00 00
01 01 00 00 00 00 00 00
01 01 01 01 01 01 01 01
```
----
### [awgn_cc](#awgn_cc)
Syntax:
csdr awgn_cc <snr_db> [--snrshow]
It adds white noise with the given SNR to a signal assumed to be of 0 dB power.
If the `--snrshow` switch is given, it also shows the actual SNR based on the calculated power of signal and noise components.
----
### [add_n_zero_samples_at_beginning_f](#add_n_zero_samples_at_beginning_f)
Syntax:
csdr add_n_zero_samples_at_beginning_f <n_zero_samples>
When the function is executed, it furst writes `<n_zero_samples>` 32-bit floating point zeros at the output, after that it just clones the input at the output.
----
### [fft_one_side_ff](#fft_one_side_ff)
Syntax:
csdr fft_one_side_ff <fft_size>
If the frequency domain signal spans between frequencies -fs/2 to fs/2, this function removes the part from -fs/2 to DC. This can be useful if the FFT of a real signal has been taken (so that the spectrum is mirrored to DC).
----
### [logaveragepower_cf](#logaveragepower_cf)
Syntax:
csdr logaveragepower_cf <add_db> <fft_size> <avgnumber>
It works like <a href="#logpower_cf">logpower_cf </a>, but it calculates the average of every `avgnumber` FFTs.
----
### [mono2stereo_s16](#mono2stereo_s16)
Syntax:
csdr mono2stereo_s16
It duplicates each 16-bit integer input sample.
----
### [psk31_varicode_decoder_u8_u8](#psk31_varicode_decoder_u8_u8)
Syntax:
csdr psk31_varicode_decoder_u8_u8
It expects symbols encoded as 0x00 and 0x01 bytes on the input, and extracts Varicode characters from them.
----
### [_fft2octave](#_fft2octave)
Syntax:
csdr _fft2octave <fft_size>
It is used for plotting FFT data with a GNU Octave session, piping its output to `octave -i`.
----
### [invert_u8_u8](#invert_u8_u8)
Syntax:
csdr invert_u8_u8
It maps
* each 0x00 to 0x01,
* each 0x01 to 0x00.
----
### [rtty_baudot2ascii_u8_u8](#rtty_baudot2ascii_u8_u8)
Syntax:
csdr rtty_baudot2ascii_u8_u8
This function awaits baudot code characters on its input (ranging from 0b00000000 to 0b00011111), and converts them into ASCII characters. It has an internal state to switch between letters and figures.
----
### [binary_slicer_f_u8](#binary_slicer_f_u8)
Syntax:
csdr binary_slicer_f_u8
* If the input sample is below or equals to 0.0, it outputs a 0x00.
* If the input sample is above 0.0, it outputs a 0x01.
----
### [serial_line_decoder_f_u8](#serial_line_decoder_f_u8)
Syntax:
csdr serial_line_decoder_f_u8 <samples_per_bits> [databits [stopbits]]
It decodes bits from a sampled serial line. It does so by finding the appropriate start and stop bits, and extracts the data bits in between.
----
### [pll_cc](#pll_cc)
Syntax:
csdr pll_cc (1 [alpha] |2 [bandwidth [damping_factor [ko [kd]]]])
It implements a PLL that can lock onto a sinusoidal input signal.
The first parameter corresponds to the order of the PLL loop filter (first or second order), others are parameters of the loop filter.
----
### [timing_recovery_cc](#timing_recovery_cc)
Syntax:
csdr timing_recovery_cc <algorithm> <decimation> [mu [max_error [--add_q [--output_error | --output_indexes | --octave <show_every_nth> | --octave_save <show_every_nth> <directory> ]]]]
It implements non-data aided timing recovery (Gardner and early-late gate algorithms).
[More information](http://openwebrx.org/msc-thesis.pdf#page=34) (section 4.4 from page 34)
----
### [octave_complex_c](#octave_complex_c)
Syntax:
csdr octave_complex_c <samples_to_plot> <out_of_n_samples> [--2d]
It generates octave commands to plot a complex time domain signal. Its output can be piped into `octave -i`. It plots every `samples_to_plot` samples `out_of_n_samples`.
----
### [psk_modulator_u8_c](#psk_modulator_u8_c)
Syntax:
csdr psk_modulator_u8_c <n_psk>
It generates an N-PSK modulated signal from the input symbols.
As an example, for `n_psk`=4, it will translate:
* any 0x00 byte on the input into 1+0j on the output,
* any 0x01 byte on the input into 0+1j on the output,
* any 0x02 byte on the input into -1+0j on the output,
* any 0x03 byte on the input into 0-1j on the output.
----
### [duplicate_samples_ntimes_u8_u8](#duplicate_samples_ntimes_u8_u8)
Syntax:
csdr duplicate_samples_ntimes_u8_u8 <sample_size_bytes> <ntimes>
It duplicates each sample of `sample_size_bytes` the given `ntimes` times.
----
### [psk31_interpolate_sine_cc](#psk31_interpolate_sine_cc)
Syntax:
csdr psk31_interpolate_sine_cc <interpolation>
The input to this function is one complex sample per symbol, the output is `interpolation` samples per symbol, interpolated using a cosine envelope (which is used for PSK31).
----
### [differential_encoder_u8_u8](#differential_encoder_u8_u8)
Syntax:
csdr differential_encoder_u8_u8
It can be used while generating e.g. differential BPSK modulation.
* If the input is 0x01, the output remains the same as the last output.
* If the input is 0x00, the output changes from 0x00 to 0x01, or 0x01 to 0x00.
----
### [differential_decoder_u8_u8](#differential_decoder_u8_u8)
Syntax:
csdr differential_decoder_u8_u8
It can be used while demodulating e.g. differential BPSK modulation. The following table show the logic function it performs:
| Last input | Current input | Output |
| ---------- | ------------- | ------ |
| 0x00 | 0x00 | 0x01 |
| 0x00 | 0x01 | 0x00 |
| 0x01 | 0x00 | 0x00 |
| 0x01 | 0x01 | 0x01 |
----
### [bpsk_costas_loop_cc](#bpsk_costas_loop_cc)
Syntax:
csdr bpsk_costas_loop_cc <loop_bandwidth> <damping_factor> [--dd | --decision_directed] [--output_error | --output_dphase | --output_nco | --output_combined <error_file> <dphase_file> <nco_file>]
It implements a Costas loop for BPSK signals.
[More information](http://openwebrx.org/msc-thesis.pdf#page=55) (section 5.4 from page 55)
----
### [simple_agc_cc](#simple_agc_cc)
Syntax:
csdr simple_agc_cc <rate> [reference [max_gain]]
It is an automatic gain control function with a single pole IIR loop filter.
- `reference` is the reference level for the AGC. It tries to keep the amplitude of the output signal close to that.
- AGC won't increase the gain over `max_gain`.
- `rate` is the parameter of the loop filter.
The block diagram of this function follows:
![simple_agc_cc block diagram](https://raw.githubusercontent.com/wiki/simonyiszk/csdr/simple-agc-dataflow.png)
----
### [peaks_fir_cc](#peaks_fir_cc)
Syntax:
csdr peaks_fir_cc <taps_length> <peak_rate × N>
It applies a peak filter to the input signal. The peak filter is a very narrow bandpass filter, the opposite of a notch filter. The higher the `taps_length` is, the sharper the filter frequency transfer function is.
`peak_rate` is the center of the passband, in proportion to the sampling rate.
----
### [firdes_peak_c](#firdes_peak_c)
Syntax:
csdr firdes_peak_c <rate> <length> [window [--octave]]
It designs a FIR peak filter, and writes the taps to the output. More about this filter at <a href="#peaks_fir_cc">peaks_fir_cc</a>.
This command also supports GNU Octave-friendly output that can be piped into the Octave interpreter `octave -i`.
----
### [normalized_timing_variance_u32_f](#normalized_timing_variance_u32_f)
Syntax:
csdr normalized_timing_variance_u32_f <samples_per_symbol> <initial_sample_offset> [--debug]
It calculates the normalized timing variance. It works on the sample indexes output from the `timing_recovery_cc` function.
----
### [pulse_shaping_filter_cc](#pulse_shaping_filter_cc)
Syntax:
csdr pulse_shaping_filter_cc (RRC <samples_per_symbol> <num_taps> <beta> | COSINE <samples_per_symbol>)
It runs a pulse shaping FIR filter on the signal.
* `RRC` stands for Root-Raised-Cosine filter, a design parameter of which is `beta`.
* The `COSINE` filter is the one used for BPSK31.
* `samples_per_symbol` is the number of input samples per symbol.
* `num_taps` is the filter length.
----
### [firdes_pulse_shaping_filter_f](#firdes_pulse_shaping_filter_f)
Syntax:
csdr firdes_pulse_shaping_filter_f (RRC <samples_per_symbol> <num_taps> <beta> | COSINE <samples_per_symbol>)
It designs a pulse shaping filter, and outputs the taps. It has the same parameters as `pulse_shaping_filter_cc`.
----
### [generic_slicer_f_u8](#generic_slicer_f_u8)
Syntax:
csdr generic_slicer_f_u8 <n_symbols>
It decides which symbol the sample corresponds to, where the highest symbol corresponds to 1.0, and the lowest symbol corresponds to -1.0.
As an example, if N=3, the 3 symbols to choose from are: -1, 0, 1. The algorithm will output:
* 0x00 for any input sample between -infinity and -0.5.
* 0x01 for any input sample between -0.5 and 0.5.
* 0x02 for any input sample between 0.5 and infinity.
----
### [plain_interpolate_cc](#plain_interpolate_cc)
Syntax:
csdr plain_interpolate_cc <interpolation>
It interpolates the signal by writing `interpolation - 1` zero samples between each input sample. You need to run an anti-aliasing filter on its output.
----
### [dbpsk_decoder_c_u8](#dbpsk_decoder_c_u8)
Syntax:
csdr dbpsk_decoder_c_u8
It implements a differential BPSK demodulator, with the following data flow:
![DBPSK dataflow](https://raw.githubusercontent.com/wiki/simonyiszk/csdr/dbpsk-dataflow.png)
The output is 0x00 or 0x01.
----
### [bfsk_demod_cf](#bfsk_demod_cf)
Syntax:
csdr bfsk_demod_cf <spacing> <filter_length>
It implements a 2-FSK demodulator, with the following data flow:
![BFSK dataflow](https://raw.githubusercontent.com/wiki/simonyiszk/csdr/bfsk-dataflow.png)
You can calculate the expected frequencies of the two tones on the input by the following formulas: `+(spacing/sampling_rate)` and `-(spacing/sampling_rate)`.
Filter length is the length of the peak filters (FIR) applied to the input för each tone.
----
### [add_const_cc](#add_const_cc)
Syntax:
csdr add_const_cc <i> <q>
It adds a constant value of `i+q*j` to each input sample.
----
### [pattern_search_u8_u8](#pattern_search_u8_u8)
Syntax:
csdr pattern_search_u8_u8 <values_after> <pattern_values × N>
It can be used for preamble search. It looks for a given sequence of N bytes (`<pattern_values × N>`) in the input data, and if the sequence is found, it reads the following `<values_after>` bytes and outputs them. The `<pattern_values × N>` parameter is read as unsigned integers.
----
### [tee](#tee)
Syntax:
csdr tee <path> [buffers]
Similarly to the `tee` command, it reads data from the standard input, and writes it to both a file and the standard output.
Unlike `tee`, if it fails to flush the data to the file, it still flushes it to the standard output. This allows us to have less glitches / better response time if we use this as a way to put branches in the data flow. Example:
mkfifo /tmp/csdr_fifo
rtl_sdr - | csdr tee /tmp/csdr_fifo | csdr dump_u8
cat /tmp/csdr_fifo | csdr convert_u8_f | csdr dump_f
How the data flow looks like:
rtl_sdr --> tee --> dump_u8
|
\/
convert_u8_f --> dump_f
### [?](#search_the_function_list)
Syntax:
@ -845,6 +1372,16 @@ Another solution is using single quotes to wrap the expression:
csdr shift_addition_cc $(csdr '=(1200+300)/2400000.')
Current version of `csdr` executes the following python script for this function:
```python
import os, sys
from math import *
print <evaluate_python_expression>
```
This means that one can also call math functions like `sqrt()`.
#### Control via pipes
Some parameters can be changed while the `csdr` process is running. To achieve this, some `csdr` functions have special parameters. You have to supply a fifo previously created by the `mkfifo` command. Processing will only start after the first control command has been received by `csdr` over the FIFO.

1153
csdr.c

File diff suppressed because it is too large Load diff

80
detect_params.sh Executable file
View file

@ -0,0 +1,80 @@
#!/bin/sh
# This software is part of libcsdr, a set of simple DSP routines for
# Software Defined Radio.
#
# Copyright (c) 2014, Andras Retzler <randras@sdr.hu>
# Copyright (c) 2019, MeFisto94
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of the copyright holder nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# This file will try to detect the correct GCC optimization parameters, especially when running on ARM Platforms such as the Raspberry Pi
# Desktop Processors
if grep -q sse /proc/cpuinfo; then
if grep -q sse /proc/cpuinfo; then
PARAMS_SSE="$PARAMS_SSE-msse"
fi
if grep -q sse2 /proc/cpuinfo; then
PARAMS_SSE="$PARAMS_SSE -msse2"
fi
if grep -q sse3 /proc/cpuinfo; then
PARAMS_SSE="$PARAMS_SSE -msse3"
fi
if grep -q sse4a /proc/cpuinfo; then
PARAMS_SSE="$PARAMS_SSE -msse4a"
fi
if grep -q sse4_1 /proc/cpuinfo; then
PARAMS_SSE="$PARAMS_SSE -msse4.1"
fi
# TODO: Is this "-msse4" only for sse4_2 intended?
if grep -q sse4_2 /proc/cpuinfo; then
PARAMS_SSE="$PARAMS_SSE -msse4.2 -msse4"
fi
echo "$PARAMS_SSE -mfpmath=sse"
return 0
else
ARCH=$(uname -m)
# Detect Raspberry Pi
if grep -q 'Raspberry' /proc/device-tree/model; then
if [ "$ARCH" = "aarch64" ]; then # Probably RPi 3+ on 64bit
# Float ABI is always hard on AARCH64. TODO: Does RPi 1 or 2 also have aarch64?
PARAMS_PI="-mcpu=cortex-a53 -mtune=cortex-a53"
else # note -mcpu replaces -march
# See https://gist.github.com/fm4dd/c663217935dc17f0fc73c9c81b0aa845
if grep -q 3 /proc/device-tree/model; then
PARAMS_PI="-mcpu=cortex-a53 -mfloat-abi=hard -mfpu=neon-fp-armv8 -mneon-for-64bits"
elif grep -q 2 /proc/device-tree/model; then
PARAMS_PI="-mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4"
elif grep -q 1 /proc/device-tree/model; then
PARAMS_PI="-mcpu=arm1176jzf-s -mfloat-abi=hard -mfpu=vfp"
fi
fi
PARAMS_ARM="$PARAMS_PI -funsafe-math-optimizations -Wformat=0"
else # Generic ARM Device
# Most likely mtune is incorrect here
PARAMS_ARM = "-mfloat-abi=hard -march=`uname -m` -mtune=cortex-a8 -mfpu=neon -mvectorize-with-neon-quad -funsafe-math-optimizations -Wformat=0 -DNEON_OPTS"
fi
echo $PARAMS_ARM
return 0
fi

View file

@ -22,6 +22,7 @@ struct fft_plan_s
#include "libcsdr.h"
FFT_PLAN_T* make_fft_c2c(int size, complexf* input, complexf* output, int forward, int benchmark);
FFT_PLAN_T* make_fft_r2c(int size, float* input, complexf* output, int benchmark);
void fft_execute(FFT_PLAN_T* plan);
void fft_destroy(FFT_PLAN_T* plan);

53
grc_tests/bpsk31_ber.py Executable file
View file

@ -0,0 +1,53 @@
#!/usr/bin/python
import os, time, signal
from subprocess import *
#https://bugs.python.org/issue1652
def p(x):
global printcmds
if printcmds: print x
return check_output(x, shell=True)
printcmds=True
def genfiles(snr):
cmd="""(while true; do echo -n 'CQ CQ CQ DE HA7ILM HA7ILM HA7ILM PSE K '; done) | \
csdr psk31_varicode_encoder_u8_u8 | \
tee /s/bpsk31_testin | \
csdr differential_encoder_u8_u8 | \
csdr psk_modulator_u8_c 2 | \
csdr psk31_interpolate_sine_cc 256 | \
csdr awgn_cc %d | \
csdr timing_recovery_cc GARDNER 256 0.5 2 --add_q | \
csdr dbpsk_decoder_c_u8 | \
dd bs=1024 count=10 of=/s/bpsk31_testout
"""%snr
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
if printcmds: print cmd
os.system(cmd)
def getminsize():
return min(os.path.getsize("/s/bpsk31_testout"), os.path.getsize("/s/bpsk31_testin"))
def mkdiff(shift):
if shift==0:
return int(p("cmp -l /s/bpsk31_testin /s/bpsk31_testout | wc -l"))
elif shift<0:
return int(p("(dd if=/dev/zero bs=%d count=1; cat /s/bpsk31_testin)>/s/bpsk31_testin0; cmp -l /s/bpsk31_testin0 /s/bpsk31_testout | wc -l"%-shift))
elif shift>0:
return int(p("(dd if=/dev/zero bs=%d count=1; cat /s/bpsk31_testout)>/s/bpsk31_testout0; cmp -l /s/bpsk31_testin /s/bpsk31_testout0 | wc -l"%shift))
lf=open("/s/output_results","w")
for snr in range(0,20,2):
genfiles(snr)
num_totalbits=getminsize()
num_errors=None
for shift in range(-5,5):
curr_num_errors = mkdiff(shift)
if not num_errors or (num_errors and num_errors > curr_num_errors):
num_errors = curr_num_errors
lf.write("%d; %d; %d; %d\n" %(snr, num_errors, num_totalbits, num_errors/float(num_totalbits)))

67
grc_tests/bpsk31_scurve.m Executable file
View file

@ -0,0 +1,67 @@
#!/usr/bin/octave
%{
function [output]=fgc(path, type)
if(type(1)=='f')
elseif(type(1)=='c')
end
end
%}
function output=shrunf(cmd)
SIGTERM=15;
output=[];
[pin, pout, pid]=popen2('bash',{'-c', cmd});
%fclose(pin);
sleep(0.1)
do
current_output=fread(pout, Inf, 'float32');
output=[output; current_output];
until(feof(pout))
waitpid(pid);
%kill(pid, SIGTERM);
fclose(pin);
fclose(pout);
end
function error_value=run_tr(skip, which_ted)
out_vect=shrunf(sprintf('dd bs=8 skip=%d if=bpsk31_baseband_sample_complex_8000_sps_010101.raw | csdr timing_recovery_cc %s 256 --add_q --output_error', skip, which_ted));
error_value=out_vect(2);
end
function error_values=mkscurve(which_ted, skips)
error_values=[]
for skip=skips
error_values=[error_values run_tr(skip, which_ted)];
end
end
function fmtplot(h)
FN = findall(h,'-property','FontName');
set(FN,'FontName','/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerifCondensed.ttf');
set(FN,'FontName','times');
FS = findall(h,'-property','FontSize');
set(FS,'FontSize',18);
xlabel('Phase offset in number of samples');
ylabel('Error value (TED output)');
end
skips_gardner=0:16:256
error_values_gardner=mkscurve('GARDNER',skips_gardner);
skips_earlylate=0:16:256
error_values_earlylate=mkscurve('EARLYLATE',skips_earlylate);
%graphics_toolkit("gnuplot")
h=figure(1);
plot((skips_gardner-128)/256, -error_values_gardner, 'linewidth', 2);
title('S-curve for Gardner TED');
fmtplot(h)
grid on
pause
plot((skips_earlylate-128)/256, error_values_earlylate, 'linewidth', 2);
title('S-curve for early-late TED');
fmtplot(h)
grid on
pause

99
grc_tests/bpsk31_tedvar.m Executable file
View file

@ -0,0 +1,99 @@
#!/usr/bin/octave
%you need to first install the parallel and struct packages:
%pkg install -forge struct
%pkg install -forge parallel
pkg load parallel
function y=inarg(x)
for i=1:length(argv())
if strcmp(argv(){i},x)
y=1;
return
end
end
y=0;
end
bpfcmd="csdr bandpass_fir_fft_cc $(csdr \"=-31.25/8e3\") $(csdr \"=31.25/8e3\") $(csdr \"=31.25/8e3\") | ";
if !inarg('--nogen')
fwrite(stdout, "===========================================\nGenerating baseband signal from random data\n===========================================\n");
system(["cat /dev/urandom | csdr pack_bits_8to1_u8_u8 | csdr psk_modulator_u8_c 2 | csdr gain_ff 0.25 | csdr psk31_interpolate_sine_cc 256 | " bpfcmd "csdr add_n_zero_samples_at_beginning_f 170 | pv -ps 2g | dd iflag=fullblock bs=128M count=16 of=/tmp/psk31-raw-data"]);
fwrite(stdout, "===========================================\nGenerating Gaussian white noise for agwn_cc\n===========================================\n");
system(["csdr gaussian_noise_c | " bpfcmd "pv -ps 256m | dd of=/tmp/psk31-gaussian-noise iflag=fullblock bs=256M count=1"]);
end
if inarg('--onlygen')
exit(0)
end
fwrite(stdout, "===========================================\nCalculating variance graph data \n===========================================\n");
function output=shrun(cmd, type, minsize)
SIGTERM=15;
output=[];
cmd
[pin, pout, pid]=popen2('bash',{'-c', cmd});
%fclose(pin);
do
sleep(0.3)
fwrite(stdout,'.');
%size(output)
%output
current_output=fread(pout, Inf, type);
frewind(pout);
output=[output; current_output];
until(size(output)(1)>=minsize)
waitpid(pid);
kill(pid, SIGTERM);
fclose(pin);
fclose(pout);
end
function variance=run_var(snr, which_ted)
disp('ran a command')
out_vect=shrun(sprintf('cat /tmp/psk31-raw-data | csdr awgn_cc %d --awgnfile /tmp/psk31-gaussian-noise | csdr simple_agc_cc 0.0001 0.5 | csdr timing_recovery_cc %s 256 0.5 2 --add_q --output_indexes | CSDR_FIXED_BUFSIZE=1048576 csdr normalized_timing_variance_u32_f 256 85', snr, which_ted), 'float32', 1);
disp('run_var output:');
out_vect'
variance=out_vect(1);
end
function variances=mkvarplot(which_ted, snrs)
fun = @(x) run_var(x, which_ted);
variances=pararrayfun(nproc, fun, snrs);
%{
variances=[]
for snr=snrs
snr
variances=[variances run_var(snr, which_ted)];
end
%}
end
function fmtplot(h)
FN = findall(h,'-property','FontName');
set(FN,'FontName','/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerifCondensed.ttf');
set(FN,'FontName','times');
FS = findall(h,'-property','FontSize');
set(FS,'FontSize',18);
xlabel('E_b/N_0 [dB]');
ylabel('Phase error variance [rad^2]');
end
%snrs=-10:5:10
snrs=-10:5:25
%snrs=[10]
error_values=mkvarplot('EARLYLATE',snrs);
%graphics_toolkit("gnuplot")
h=figure(1);
ebn0=snrs+9.7
semilogy(ebn0, error_values, 'linewidth', 2);
title('Estimation variance');
fmtplot(h)
pause
if !inarg('--nogen')
system('rm /tmp/psk31-raw-data /tmp/psk31-gaussian-noise');
end

70
grc_tests/psk31_sigmodel.m Executable file
View file

@ -0,0 +1,70 @@
#!/usr/bin/octave
global Tb=20
function g=gbb(t) %impulse response of pulse shaping filter
global Tb
g=t;
for i = 1:size(t)(2)
if (t(i)>1*Tb || t(i)<=-1*Tb)
g(i) = 0;
else
g(i) = 0.5+cos((t(i)/(Tb*1))*pi)/2; %this is not RRC, rather a sinusoidal pulse shape
end
end
end
global padding=[-2 2];
function [toreturny, plotrange]=y(s)
global Tb
global padding
slen=size(s)(2)
plotrange=((padding(1)-1)*Tb):(slen+padding(2))*Tb-1;
plotlen=size(plotrange)(2)
toreturny=zeros(1,plotlen);
for i=1:slen %sum of (symbol[i] * filter impulse response) for all symbols
toreturny+=s(i)*gbb(plotrange.-(i-1)*Tb);
end
plotrange=plotrange/Tb
end
function fmtplot(h)
FN = findall(h,'-property','FontName');
set(FN,'FontName','/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerifCondensed.ttf');
set(FN,'FontName','times');
FS = findall(h,'-property','FontSize');
set(FS,'FontSize',18);
set(FS,'FontSize',18);
end
h=figure(1);
subplot(2, 1, 1);
[a b]=y([1]);
plot(b, a, 'linewidth', 2)
title(sprintf("Impulse response of pulse shaping filter"))
xlabel('t/Ts')
ylabel('h(t)')
subplot(2, 1, 2);
[a b]=y([1 1 -1 -1 1 1 1 -1 1 -1 1 1]);
plot(b, a, 'linewidth', 2)
title("Baseband signal for modulator input\nbit sequence: 110011101011") %assuming that differential encoding has already been performed
xlabel('t/Ts')
ylabel('s(t)')
xbounds = xlim;
set(gca,'XTick',xbounds(1):xbounds(2));
fmtplot(h);
pause
exit
%fourier analisys of baseband signal
h2=figure(2);
padding=[-1 1]
plot(y([1]))
h3=figure(3);
fftvals=abs(fft(y([1])));
sizefftvals=size(fftvals)(2)
fftvals=[fftvals(sizefftvals/2:sizefftvals) fftvals(2:sizefftvals/2)]
plot(fftvals, "-")
pause

669
grc_tests/test_awgn.grc Normal file
View file

@ -0,0 +1,669 @@
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.8'?>
<flow_graph>
<timestamp>Sun Nov 16 15:12:31 2014</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>thread_safe_setters</key>
<value></value>
</param>
<param>
<key>title</key>
<value></value>
</param>
</block>
<block>
<key>variable_slider</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>converver</key>
<value>float_converter</value>
</param>
<param>
<key>value</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(120, 147)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>amplitude</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>max</key>
<value>2</value>
</param>
<param>
<key>min</key>
<value>0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>num_steps</key>
<value>100</value>
</param>
<param>
<key>style</key>
<value>wx.SL_HORIZONTAL</value>
</param>
</block>
<block>
<key>variable_slider</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>converver</key>
<value>float_converter</value>
</param>
<param>
<key>value</key>
<value>0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 147)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>frequency</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>max</key>
<value>samp_rate/2</value>
</param>
<param>
<key>min</key>
<value>-samp_rate/2</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>num_steps</key>
<value>100</value>
</param>
<param>
<key>style</key>
<value>wx.SL_HORIZONTAL</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 83)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>value</key>
<value>40e3</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>amp</key>
<value>1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>freq</key>
<value>frequency</value>
</param>
<param>
<key>_coordinate</key>
<value>(184, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>waveform</key>
<value>analog.GR_COS_WAVE</value>
</param>
</block>
<block>
<key>blocks_multiply_const_vxx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>const</key>
<value>amplitude</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(344, 43)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_multiply_const_vxx_0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(496, 43)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_throttle_0_0</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr awgn_cc 10 --snrshow</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(344, 275)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(616, 203)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(856, 75)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<connection>
<source_block_id>analog_sig_source_x_0</source_block_id>
<sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
<sink_block_id>blocks_throttle_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

View file

@ -304,7 +304,7 @@
</param>
<param>
<key>commandline</key>
<value>csdr bpsk_costas_loop_cc 48</value>
<value>csdr bpsk_costas_loop_cc 0.05 0.707</value>
</param>
<param>
<key>comment</key>
@ -316,7 +316,7 @@
</param>
<param>
<key>_enabled</key>
<value>True</value>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
@ -363,7 +363,7 @@
</param>
<param>
<key>_enabled</key>
<value>1</value>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
@ -390,6 +390,53 @@
<value>cc</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr bandpass_fir_fft_cc $(csdr '=-(31.25)/1.5e3') $(csdr '=(31.25)/1.5e3') $(csdr '=31.25/1.5e3') | csdr simple_agc_cc 0.0001 0.5 </value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(568, 643)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0_1</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
@ -422,7 +469,7 @@
</param>
<param>
<key>labels</key>
<value>['tab1', 'tab2', 'tab3', 'tab4']</value>
<value>['tab1', 'channel', 'tab3', 'tab4','bpf']</value>
</param>
<param>
<key>notebook</key>
@ -667,7 +714,7 @@
</param>
<param>
<key>_enabled</key>
<value>True</value>
<value>0</value>
</param>
<param>
<key>fft_size</key>
@ -742,6 +789,109 @@
<value>10</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(832, 563)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_1_0</value>
</param>
<param>
<key>notebook</key>
<value>nb, 4</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate/32</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>window.hamming</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
@ -762,7 +912,7 @@
</param>
<param>
<key>_enabled</key>
<value>True</value>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
@ -849,7 +999,7 @@
</param>
<param>
<key>_enabled</key>
<value>1</value>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
@ -916,6 +1066,283 @@
<value>Counts</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(832, 787)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_scopesink2_0_0_0</value>
</param>
<param>
<key>notebook</key>
<value>nb,4</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate/32</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>title</key>
<value>Scope Plot</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
</block>
<block>
<key>wxgui_waterfallsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>dynamic_range</key>
<value>100</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>fft_size</key>
<value>512</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(840, 907)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_waterfallsink2_0</value>
</param>
<param>
<key>notebook</key>
<value>nb,4</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate/32</value>
</param>
<param>
<key>title</key>
<value>Waterfall Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
</block>
<block>
<key>wxgui_waterfallsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>dynamic_range</key>
<value>100</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>fft_size</key>
<value>512</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(1120, 43)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_waterfallsink2_0_0</value>
</param>
<param>
<key>notebook</key>
<value>nb,1</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate/32</value>
</param>
<param>
<key>title</key>
<value>Waterfall Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
</block>
<connection>
<source_block_id>audio_source_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0</sink_block_id>
@ -946,12 +1373,24 @@
<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>ha5kfu_execproc_xx_0_1</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>wxgui_fftsink2_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>wxgui_waterfallsink2_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0</source_block_id>
<sink_block_id>blocks_deinterleave_0</sink_block_id>
@ -982,4 +1421,22 @@
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0_1</source_block_id>
<sink_block_id>wxgui_fftsink2_0_1_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0_1</source_block_id>
<sink_block_id>wxgui_scopesink2_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0_1</source_block_id>
<sink_block_id>wxgui_waterfallsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

View file

@ -0,0 +1,675 @@
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.8'?>
<flow_graph>
<timestamp>Mon Oct 13 20:03:23 2014</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>thread_safe_setters</key>
<value></value>
</param>
<param>
<key>title</key>
<value></value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(184, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>value</key>
<value>48e3</value>
</param>
</block>
<block>
<key>audio_source</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>device_name</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(56, 107)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>audio_source_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_outputs</key>
<value>1</value>
</param>
<param>
<key>ok_to_block</key>
<value>True</value>
</param>
<param>
<key>samp_rate</key>
<value>int(samp_rate)</value>
</param>
</block>
<block>
<key>blocks_file_sink</key>
<param>
<key>append</key>
<value>False</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>file</key>
<value>/home/pcfl/Asztal/szakdoga/dipterv1/bpsk31_input_f.raw</value>
</param>
<param>
<key>_coordinate</key>
<value>(232, 251)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_file_sink_0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>unbuffered</key>
<value>False</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_file_sink</key>
<param>
<key>append</key>
<value>False</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>file</key>
<value>/home/pcfl/Asztal/szakdoga/dipterv1/bpsk31_baseband_c.raw</value>
</param>
<param>
<key>_coordinate</key>
<value>(1032, 91)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_file_sink_0_0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>unbuffered</key>
<value>False</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>freq_xlating_fir_filter_xxx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>center_freq</key>
<value>2000</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(296, 123)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>freq_xlating_fir_filter_xxx_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>taps</key>
<value>[1]</value>
</param>
<param>
<key>type</key>
<value>fcc</value>
</param>
</block>
<block>
<key>low_pass_filter</key>
<param>
<key>beta</key>
<value>6.76</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>cutoff_freq</key>
<value>1000</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>fir_filter_ccf</value>
</param>
<param>
<key>_coordinate</key>
<value>(536, 99)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>id</key>
<value>low_pass_filter_0</value>
</param>
<param>
<key>interp</key>
<value>1</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>width</key>
<value>100</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(280, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>nb</value>
</param>
<param>
<key>labels</key>
<value>['tab1', 'tab2', 'tab3', 'tab4']</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(1032, 187)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(232, 339)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<connection>
<source_block_id>audio_source_0</source_block_id>
<sink_block_id>blocks_file_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>audio_source_0</source_block_id>
<sink_block_id>freq_xlating_fir_filter_xxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>audio_source_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>freq_xlating_fir_filter_xxx_0</source_block_id>
<sink_block_id>low_pass_filter_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0</source_block_id>
<sink_block_id>blocks_file_sink_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,10 @@
#!/bin/bash
sox -r 48k -t f32 -c 2 /s/costas_nco -t wav -e floating-point /s/costas_nco.wav
sox -r 48k -t f32 -c 1 /s/costas_error -t wav -e floating-point /s/costas_error.wav
sox -r 48k -t f32 -c 1 /s/costas_dphase -t wav -e floating-point --norm=-6 /s/costas_dphase.wav
sox -r 48k -t f32 -c 2 /s/costas_input -t wav -e floating-point /s/costas_input.wav
sox -r 48k -t f32 -c 2 /s/costas_output -t wav -e floating-point /s/costas_output.wav
sox -r 48k -t f32 -c 2 /s/tr_input -t wav -e floating-point /s/tr_input.wav
ls -al /s/costas_nco.wav /s/costas_error.wav /s/costas_dphase.wav /s/costas_output.wav /s/costas_input.wav

File diff suppressed because it is too large Load diff

816
grc_tests/test_m_fsk.grc Normal file
View file

@ -0,0 +1,816 @@
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.8'?>
<flow_graph>
<timestamp>Sat Oct 31 16:06:38 2015</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280*2, 1024*4</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>thread_safe_setters</key>
<value></value>
</param>
<param>
<key>title</key>
<value></value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(272, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>interp</value>
</param>
<param>
<key>value</key>
<value>1024*4</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(176, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>value</key>
<value>2**16</value>
</param>
</block>
<block>
<key>blocks_complex_to_float</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(656, 65)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_complex_to_float_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_interleave</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>blocksize</key>
<value>1</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(904, 65)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_interleave_0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_streams</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(496, 155)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_vco_c</key>
<param>
<key>amplitude</key>
<value>1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(248, 139)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_vco_c_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>sensitivity</key>
<value>samp_rate*0.9</value>
</param>
</block>
<block>
<key>blocks_vector_source_x</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 139)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_vector_source_x_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>repeat</key>
<value>True</value>
</param>
<param>
<key>tags</key>
<value>[]</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>vector</key>
<value>[2]*interp+[-2]*interp+[0.333*2]*interp+[-0.333*2]*interp</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_sink_f</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr fmdemod_quadri_cf | csdr dsb_fc | csdr fir_decimate_cc 40 | csdr timing_recovery_cc GARDNER 100 0.5 2 --add_q | CSDR_FIXED_BUFSIZE=64 csdr realpart_cf | CSDR_FIXED_BUFSIZE=64 csdr gain_ff 2.5 | CSDR_FIXED_BUFSIZE=64 csdr generic_slicer_f_u8 4 &gt; /s/mfsksymbols</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(1040, 75)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_sink_f_0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr fmdemod_quadri_cf | csdr dsb_fc | csdr bandpass_fir_fft_cc -0.1 0.1 0.001 | csdr timing_recovery_cc GARDNER 1024 0.5 2 --add_q | csdr realpart_cf | csdr generic_slicer_f_u8 4 &gt; /s/sliced</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(528, 467)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(1040, 115)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(864, 443)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>title</key>
<value>Scope Plot</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
</block>
<block>
<key>wxgui_waterfallsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>dynamic_range</key>
<value>100</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>fft_size</key>
<value>512</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(864, 251)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_waterfallsink2_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>Waterfall Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
</block>
<connection>
<source_block_id>blocks_complex_to_float_0</source_block_id>
<sink_block_id>blocks_interleave_0</sink_block_id>
<source_key>1</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>blocks_complex_to_float_0</source_block_id>
<sink_block_id>blocks_interleave_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_interleave_0</source_block_id>
<sink_block_id>ha5kfu_execproc_sink_f_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>blocks_complex_to_float_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>wxgui_waterfallsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_vco_c_0</source_block_id>
<sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_vector_source_x_0</source_block_id>
<sink_block_id>blocks_vco_c_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

702
grc_tests/test_noise.grc Normal file
View file

@ -0,0 +1,702 @@
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.8'?>
<flow_graph>
<timestamp>Sun Nov 16 15:12:31 2014</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>thread_safe_setters</key>
<value></value>
</param>
<param>
<key>title</key>
<value></value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 83)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>value</key>
<value>100e3</value>
</param>
</block>
<block>
<key>analog_const_source_x</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>const</key>
<value>0</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(40, 179)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>analog_const_source_x_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
</block>
<block>
<key>blocks_complex_to_float</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(392, 313)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_complex_to_float_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(216, 179)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samples_per_second</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(680, 91)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_throttle_0_0</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(800, 331)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_throttle_0_0_0</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr noise_f</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(400, 227)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr noise_f</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(568, 307)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(896, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(976, 259)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<connection>
<source_block_id>analog_const_source_x_0</source_block_id>
<sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_complex_to_float_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>blocks_complex_to_float_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0_0_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0</source_block_id>
<sink_block_id>blocks_throttle_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0_0</source_block_id>
<sink_block_id>blocks_throttle_0_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

View file

@ -0,0 +1,752 @@
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.8'?>
<flow_graph>
<timestamp>Sun Nov 16 15:12:31 2014</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>thread_safe_setters</key>
<value></value>
</param>
<param>
<key>title</key>
<value></value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 83)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>value</key>
<value>1e3</value>
</param>
</block>
<block>
<key>analog_random_source_x</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 155)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>analog_random_source_x_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>max</key>
<value>2147483647</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>min</key>
<value>-2147483648</value>
</param>
<param>
<key>num_samps</key>
<value>1000</value>
</param>
<param>
<key>type</key>
<value>int</value>
</param>
<param>
<key>repeat</key>
<value>True</value>
</param>
</block>
<block>
<key>blocks_deinterleave</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>blocksize</key>
<value>1</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(384, 169)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_deinterleave_0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_streams</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_float_to_complex</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(544, 169)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_float_to_complex_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_int_to_float</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(208, 179)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_int_to_float_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>scale</key>
<value>2147483647.</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(736, 179)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate*10</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr peaks_fir_cc 101 -0.2 -0.1 0 0.1 0.2</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(168, 339)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(472, 435)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(976, 107)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(480, 299)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>title</key>
<value>Scope Plot</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
</block>
<connection>
<source_block_id>analog_random_source_x_0</source_block_id>
<sink_block_id>blocks_int_to_float_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_deinterleave_0</source_block_id>
<sink_block_id>blocks_float_to_complex_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_deinterleave_0</source_block_id>
<sink_block_id>blocks_float_to_complex_0</sink_block_id>
<source_key>1</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>blocks_float_to_complex_0</source_block_id>
<sink_block_id>blocks_throttle_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_int_to_float_0</source_block_id>
<sink_block_id>blocks_deinterleave_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,746 @@
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.8'?>
<flow_graph>
<timestamp>Mon Oct 13 20:03:23 2014</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>thread_safe_setters</key>
<value></value>
</param>
<param>
<key>title</key>
<value></value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(184, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>value</key>
<value>48e3</value>
</param>
</block>
<block>
<key>audio_source</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>device_name</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(56, 107)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>audio_source_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_outputs</key>
<value>1</value>
</param>
<param>
<key>ok_to_block</key>
<value>True</value>
</param>
<param>
<key>samp_rate</key>
<value>int(samp_rate)</value>
</param>
</block>
<block>
<key>blocks_deinterleave</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>blocksize</key>
<value>1</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(656, 113)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_deinterleave_0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>num_streams</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_float_to_complex</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(808, 113)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_float_to_complex_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr dsb_fc | csdr shift_addition_cc $(csdr =-2000/48e3) | csdr fir_decimate_cc 48 </value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(384, 123)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr resonators_fir_cc 31 $(csdr =85/1e3) $(csdr =-85/1e3) | CSDR_FIXED_BUFSIZE=128 csdr simple_agc_cc 0.0001 0.5</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(752, 275)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(400, 40)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>nb</value>
</param>
<param>
<key>labels</key>
<value>['input signal', 'decimated', 'filtered', 'tab4']</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(1048, 251)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>notebook</key>
<value>nb, 2</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate/48</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(280, 227)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>notebook</key>
<value>nb, 0</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>Input signal</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(1048, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_1</value>
</param>
<param>
<key>notebook</key>
<value>nb, 1</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate/48</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<connection>
<source_block_id>audio_source_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>audio_source_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_deinterleave_0</source_block_id>
<sink_block_id>blocks_float_to_complex_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_deinterleave_0</source_block_id>
<sink_block_id>blocks_float_to_complex_0</sink_block_id>
<source_key>1</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>blocks_float_to_complex_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0_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>wxgui_fftsink2_0_1</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0</source_block_id>
<sink_block_id>blocks_deinterleave_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

View file

@ -0,0 +1,844 @@
<?xml version='1.0' encoding='utf-8'?>
<?grc format='1' created='3.7.8'?>
<flow_graph>
<timestamp>Sun Nov 16 15:12:31 2014</timestamp>
<block>
<key>options</key>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>thread_safe_setters</key>
<value></value>
</param>
<param>
<key>title</key>
<value></value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 170)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>value</key>
<value>48000</value>
</param>
</block>
<block>
<key>analog_agc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(432, 355)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>id</key>
<value>analog_agc_xx_0</value>
</param>
<param>
<key>max_gain</key>
<value>65536</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>rate</key>
<value>1e-2</value>
</param>
<param>
<key>reference</key>
<value>0.1</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
</block>
<block>
<key>audio_sink</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>device_name</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(1152, 427)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>audio_sink_0</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>ok_to_block</key>
<value>True</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
</block>
<block>
<key>band_reject_filter</key>
<param>
<key>beta</key>
<value>6.76</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>fir_filter_fff</value>
</param>
<param>
<key>_coordinate</key>
<value>(392, 35)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>high_cutoff_freq</key>
<value>2000</value>
</param>
<param>
<key>id</key>
<value>band_reject_filter_0</value>
</param>
<param>
<key>interp</key>
<value>1</value>
</param>
<param>
<key>low_cutoff_freq</key>
<value>1600</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>width</key>
<value>50</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>blocks_complex_to_float</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(928, 289)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_complex_to_float_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_multiply_const_vxx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>const</key>
<value>0.2</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(968, 427)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_multiply_const_vxx_0</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
</block>
<block>
<key>blocks_wavfile_source</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>file</key>
<value>/home/pcfl/Asztal/szakdoga/dipterv1/csdr-varicode/grc_tests/outfile.wav</value>
</param>
<param>
<key>_coordinate</key>
<value>(152, 163)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>blocks_wavfile_source_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>nchan</key>
<value>1</value>
</param>
<param>
<key>repeat</key>
<value>True</value>
</param>
</block>
<block>
<key>freq_xlating_fir_filter_xxx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>center_freq</key>
<value>2000</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(832, 75)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>freq_xlating_fir_filter_xxx_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>taps</key>
<value>[1]</value>
</param>
<param>
<key>type</key>
<value>fcc</value>
</param>
</block>
<block>
<key>freq_xlating_fir_filter_xxx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>center_freq</key>
<value>-2000</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>_coordinate</key>
<value>(696, 275)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>freq_xlating_fir_filter_xxx_0_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>taps</key>
<value>[1]</value>
</param>
<param>
<key>type</key>
<value>ccc</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>commandline</key>
<value>csdr simple_agc_cc 0.001 0.05</value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>1</value>
</param>
<param>
<key>_coordinate</key>
<value>(384, 291)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
</block>
<block>
<key>low_pass_filter</key>
<param>
<key>beta</key>
<value>6.76</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>cutoff_freq</key>
<value>3000</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>fir_filter_fff</value>
</param>
<param>
<key>_coordinate</key>
<value>(584, 43)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>id</key>
<value>low_pass_filter_0</value>
</param>
<param>
<key>interp</key>
<value>1</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>width</key>
<value>50</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>comment</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>_coordinate</key>
<value>(688, 403)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
</block>
<connection>
<source_block_id>analog_agc_xx_0</source_block_id>
<sink_block_id>freq_xlating_fir_filter_xxx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_agc_xx_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>band_reject_filter_0</source_block_id>
<sink_block_id>low_pass_filter_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_complex_to_float_0</source_block_id>
<sink_block_id>blocks_multiply_const_vxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_multiply_const_vxx_0</source_block_id>
<sink_block_id>audio_sink_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_wavfile_source_0</source_block_id>
<sink_block_id>band_reject_filter_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>freq_xlating_fir_filter_xxx_0</source_block_id>
<sink_block_id>analog_agc_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>freq_xlating_fir_filter_xxx_0</source_block_id>
<sink_block_id>ha5kfu_execproc_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>freq_xlating_fir_filter_xxx_0_0</source_block_id>
<sink_block_id>blocks_complex_to_float_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0</source_block_id>
<sink_block_id>freq_xlating_fir_filter_xxx_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0</source_block_id>
<sink_block_id>wxgui_fftsink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>low_pass_filter_0</source_block_id>
<sink_block_id>freq_xlating_fir_filter_xxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

542
libcsdr.c Normal file → Executable file
View file

@ -114,6 +114,16 @@ float (*firdes_get_window_kernel(window_t window))(float)
|___/
*/
void normalize_fir_f(float* input, float* output, int length)
{
//Normalize filter kernel
float sum=0;
for(int i=0;i<length;i++) //@normalize_fir_f: normalize pass 1
sum+=input[i];
for(int i=0;i<length;i++) //@normalize_fir_f: normalize pass 2
output[i]=input[i]/sum;
}
void firdes_lowpass_f(float *output, int length, float cutoff_rate, window_t window)
{ //Generates symmetric windowed sinc FIR filter real taps
// length should be odd
@ -128,17 +138,7 @@ void firdes_lowpass_f(float *output, int length, float cutoff_rate, window_t win
output[middle-i]=output[middle+i]=(sin(2*PI*cutoff_rate*i)/i)*window_function((float)i/middle);
//printf("%g %d %d %d %d | %g\n",output[middle-i],i,middle,middle+i,middle-i,sin(2*PI*cutoff_rate*i));
}
//Normalize filter kernel
float sum=0;
for(int i=0;i<length;i++) //@firdes_lowpass_f: normalize pass 1
{
sum+=output[i];
}
for(int i=0;i<length;i++) //@firdes_lowpass_f: normalize pass 2
{
output[i]/=sum;
}
normalize_fir_f(output,output,length);
}
void firdes_bandpass_c(complexf *output, int length, float lowcut, float highcut, window_t window)
@ -481,11 +481,7 @@ int fir_decimate_cc(complexf *input, complexf *output, int input_size, int decim
for(int i=0; i<input_size; i+=decimation) //@fir_decimate_cc: outer loop
{
if(i+taps_length>input_size) break;
register float acci=0;
register float accq=0;
register int ti=0;
register float* pinput=(float*)&(input[i+ti]);
register float* pinput=(float*)&(input[i]);
register float* ptaps=taps;
register float* ptaps_end=taps+taps_length;
float quad_acciq [8];
@ -498,8 +494,8 @@ q4, q5: accumulator for I branch and Q branch (will be the output)
*/
asm volatile(
" vmov.f32 q4, #0.0\n\t" //another way to null the accumulators
" vmov.f32 q5, #0.0\n\t"
" veor q4, q4\n\t"
" veor q5, q5\n\t"
"for_fdccasm: vld2.32 {q0-q1}, [%[pinput]]!\n\t" //load q0 and q1 directly from the memory address stored in pinput, with interleaving (so that we get the I samples in q0 and the Q samples in q1), also increment the memory address in pinput (hence the "!" mark) //http://community.arm.com/groups/processors/blog/2010/03/17/coding-for-neon--part-1-load-and-stores
" vld1.32 {q2}, [%[ptaps]]!\n\t"
" vmla.f32 q4, q0, q2\n\t" //quad_acc_i += quad_input_i * quad_taps_1 //http://stackoverflow.com/questions/3240440/how-to-use-the-multiply-and-accumulate-intrinsics-in-arm-cortex-a8 //http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489e/CIHEJBIE.html
@ -683,7 +679,7 @@ float inline fir_one_pass_ff(float* input, float* taps, int taps_length)
return acc;
}
fractional_decimator_ff_t fractional_decimator_ff(float* input, float* output, int input_size, float rate, float *taps, int taps_length, fractional_decimator_ff_t d)
old_fractional_decimator_ff_t old_fractional_decimator_ff(float* input, float* output, int input_size, float rate, float *taps, int taps_length, old_fractional_decimator_ff_t d)
{
if(rate<=1.0) return d; //sanity check, can't decimate <=1.0
//This routine can handle floating point decimation rates.
@ -716,6 +712,104 @@ fractional_decimator_ff_t fractional_decimator_ff(float* input, float* output, i
return d;
}
fractional_decimator_ff_t fractional_decimator_ff_init(float rate, int num_poly_points, float* taps, int taps_length)
{
fractional_decimator_ff_t d;
d.num_poly_points = num_poly_points&~1; //num_poly_points needs to be even!
d.poly_precalc_denomiator = (float*)malloc(d.num_poly_points*sizeof(float));
//x0..x3
//-1,0,1,2
//-(4/2)+1
//x0..x5
//-2,-1,0,1,2,3
d.xifirst=-(num_poly_points/2)+1, d.xilast=num_poly_points/2;
int id = 0; //index in poly_precalc_denomiator
for(int xi=d.xifirst;xi<=d.xilast;xi++)
{
d.poly_precalc_denomiator[id]=1;
for(int xj=d.xifirst;xj<=d.xilast;xj++)
{
if(xi!=xj) d.poly_precalc_denomiator[id] *= (xi-xj); //poly_precalc_denomiator could be integer as well. But that would later add a necessary conversion.
}
id++;
}
d.where=-d.xifirst;
d.coeffs_buf=(float*)malloc(d.num_poly_points*sizeof(float));
d.filtered_buf=(float*)malloc(d.num_poly_points*sizeof(float));
//d.last_inputs_circbuf = (float)malloc(d.num_poly_points*sizeof(float));
//d.last_inputs_startsat = 0;
//d.last_inputs_samplewhere = -1;
//for(int i=0;i<num_poly_points; i++) d.last_inputs_circbuf[i] = 0;
d.rate = rate;
d.taps = taps;
d.taps_length = taps_length;
d.input_processed = 0;
return d;
}
#define DEBUG_ASSERT 1
void fractional_decimator_ff(float* input, float* output, int input_size, fractional_decimator_ff_t* d)
{
//This routine can handle floating point decimation rates.
//It applies polynomial interpolation to samples that are taken into consideration from a pre-filtered input.
//The pre-filter can be switched off by applying taps=NULL.
//fprintf(stderr, "drate=%f\n", d->rate);
if(DEBUG_ASSERT) assert(d->rate > 1.0);
if(DEBUG_ASSERT) assert(d->where >= -d->xifirst);
int oi=0; //output index
int index_high;
#define FD_INDEX_LOW (index_high-1)
//we optimize to calculate ceilf(where) only once every iteration, so we do it here:
for(;(index_high=ceilf(d->where))+d->num_poly_points+d->taps_length<input_size;d->where+=d->rate) //@fractional_decimator_ff
{
//d->num_poly_points above is theoretically more than we could have here, but this makes the spectrum look good
int sxifirst = FD_INDEX_LOW + d->xifirst;
int sxilast = FD_INDEX_LOW + d->xilast;
if(d->taps)
for(int wi=0;wi<d->num_poly_points;wi++) d->filtered_buf[wi] = fir_one_pass_ff(input+FD_INDEX_LOW+wi, d->taps, d->taps_length);
else
for(int wi=0;wi<d->num_poly_points;wi++) d->filtered_buf[wi] = *(input+FD_INDEX_LOW+wi);
int id=0;
float xwhere = d->where - FD_INDEX_LOW;
for(int xi=d->xifirst;xi<=d->xilast;xi++)
{
d->coeffs_buf[id]=1;
for(int xj=d->xifirst;xj<=d->xilast;xj++)
{
if(xi!=xj) d->coeffs_buf[id] *= (xwhere-xj);
}
id++;
}
float acc = 0;
for(int i=0;i<d->num_poly_points;i++)
{
acc += (d->coeffs_buf[i]/d->poly_precalc_denomiator[i])*d->filtered_buf[i]; //(xnom/xden)*yn
}
output[oi++]=acc;
}
d->input_processed = FD_INDEX_LOW + d->xifirst;
d->where -= d->input_processed;
d->output_size = oi;
}
/*
* Some notes to myself on the circular buffer I wanted to implement here:
int last_input_samplewhere_shouldbe = (index_high-1)+xifirst;
int last_input_offset = last_input_samplewhere_shouldbe - d->last_input_samplewhere;
if(last_input_offset < num_poly_points)
{
//if we can move the last_input circular buffer, we move, and add the new samples at the end
d->last_inputs_startsat += last_input_offset;
d->last_inputs_startsat %= num_poly_points;
int num_copied_samples = 0;
for(int i=0; i<last_input_offset; i++)
{
d->last_inputs_circbuf[i]=
}
d->last_input_samplewhere = d->las
}
However, I think I should just rather do a continuous big buffer.
*/
void apply_fir_fft_cc(FFT_PLAN_T* plan, FFT_PLAN_T* plan_inverse, complexf* taps_fft, complexf* last_overlap, int overlap_size)
{
@ -1181,6 +1275,13 @@ void apply_precalculated_window_c(complexf* input, complexf* output, int size, f
}
}
void apply_precalculated_window_f(float* input, float* output, int size, float *windowt)
{
for(int i=0;i<size;i++) //@apply_precalculated_window_f
{
output[i] = input[i] * windowt[i];
}
}
void apply_window_f(float* input, float* output, int size, window_t window)
{
@ -1212,6 +1313,12 @@ void log_ff(float* input, float* output, int size, float add_db) {
for(int i=0;i<size;i++) output[i]=10*output[i]+add_db; //@logpower_cf: pass 3
}
float total_logpower_cf(complexf* input, int input_size)
{
float acc = 0;
for(int i=0;i<input_size;i++) acc+=(iof(input,i)*iof(input,i) + qof(input,i)*qof(input,i));
return 10*log10(acc/input_size);
}
/*
_____ _ _ _ _ _ _
@ -1318,7 +1425,7 @@ psk31_varicode_item_t psk31_varicode_items[] =
{ .code = 0b101111011, .bitcount=9, .ascii=0x59 }, //Y
{ .code = 0b1010101101, .bitcount=10, .ascii=0x5a }, //Z
{ .code = 0b111110111, .bitcount=9, .ascii=0x5b }, //[
{ .code = 0b111101111, .bitcount=9, .ascii=0x5c }, //\
{ .code = 0b111101111, .bitcount=9, .ascii=0x5c }, //backslash
{ .code = 0b111111011, .bitcount=9, .ascii=0x5d }, //]
{ .code = 0b1010111111, .bitcount=10, .ascii=0x5e }, //^
{ .code = 0b101101101, .bitcount=9, .ascii=0x5f }, //_
@ -1621,6 +1728,42 @@ void serial_line_decoder_f_u8(serial_line_t* s, float* input, unsigned char* out
DEBUG_SERIAL_LINE_DECODER && fprintf(stderr, "sld: >> output_size = %d (+%d)\n", s->output_size, s->input_used);
}
void generic_slicer_f_u8(float* input, unsigned char* output, int input_size, int n_symbols)
{
float symbol_distance = 2.0/(n_symbols-1);
for(int i=0;i<input_size;i++)
for(int j=0;j<n_symbols;j++)
{
float symbol_center = -1+j*symbol_distance;
float symbol_low_limit = symbol_center-(symbol_distance/2);
float symbol_high_limit = symbol_center+(symbol_distance/2);
if(j==0)
{
if(input[i]<symbol_high_limit)
{
output[i]=j;
break;
}
}
else if (j==n_symbols-1)
{
if(input[i]>=symbol_low_limit)
{
output[i]=j;
break;
}
}
else
{
if(input[i]>=symbol_low_limit && input[i]<symbol_high_limit)
{
output[i]=j;
break;
}
}
}
}
void binary_slicer_f_u8(float* input, unsigned char* output, int input_size)
{
for(int i=0;i<input_size;i++) output[i] = input[i] > 0;
@ -1664,13 +1807,24 @@ complexf psk31_interpolate_sine_cc(complexf* input, complexf* output, int input_
return last_input;
}
void pack_bits_8to1_u8_u8(unsigned char* input, unsigned char* output, int input_size)
void pack_bits_1to8_u8_u8(unsigned char* input, unsigned char* output, int input_size)
{ //output size should be input_size × 8
for(int i=0; i<input_size; i++)
for(int bi=0; bi<8; bi++) //bi: bit index
*(output++)=(input[i]>>bi)&1;
}
unsigned char pack_bits_8to1_u8_u8(unsigned char* input)
{
unsigned char output;
for(int i=0;i<8;i++)
{
output<<=1;
output|=!!input[i];
}
return output;
}
unsigned char differential_codec(unsigned char* input, unsigned char* output, int input_size, int encode, unsigned char state)
{
if(!encode)
@ -1685,6 +1839,7 @@ unsigned char differential_codec(unsigned char* input, unsigned char* output, in
if(!input[i]) state=!state;
output[i] = state;
}
return state;
}
/*
@ -1759,7 +1914,7 @@ void pll_cc(pll_t* p, complexf* input, float* output_dphase, complexf* output_nc
}
}
void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error, int index, int correction_offset, int writefiles, int points_size, ...)
void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error, int index, int correction_offset, char* writefiles_path, int points_size, ...)
{
static int figure_output_counter = 0;
int* points_z = (int*)malloc(sizeof(int)*points_size);
@ -1771,7 +1926,7 @@ void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error
points_z[i] = va_arg(vl, int);
points_color[i] = va_arg(vl, int);
}
if(writefiles && !figure_output_counter) fprintf(stderr, "cf=figure();\n");
if(writefiles_path && !figure_output_counter) fprintf(stderr, "cf=figure();\n");
fprintf(stderr, "N = %d;\nisig = [", signal_size);
for(int i=0;i<signal_size;i++) fprintf(stderr, "%f ", iof(signal,i));
fprintf(stderr, "];\nqsig = [");
@ -1796,35 +1951,30 @@ void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error
(char)points_color[i]&0xff, (i<points_size-1)?',':' '
);
fprintf(stderr, ");\n");
if(writefiles) fprintf(stderr, "print(cf, \"figs/%05d.png\", \"-S1024,1024\");\n", figure_output_counter++);
if(writefiles_path) fprintf(stderr, "print(cf, \"%s/%05d.png\", \"-S1024,1024\");\n", writefiles_path, figure_output_counter++);
fflush(stderr);
free(points_z);
free(points_color);
}
timing_recovery_state_t timing_recovery_init(timing_recovery_algorithm_t algorithm, int decimation_rate, int use_q)
timing_recovery_state_t timing_recovery_init(timing_recovery_algorithm_t algorithm, int decimation_rate, int use_q, float loop_gain, float max_error, int debug_every_nth, char* debug_writefiles_path)
{
timing_recovery_state_t to_return;
to_return.algorithm = algorithm;
to_return.decimation_rate = decimation_rate;
to_return.loop_gain = loop_gain;
to_return.max_error = max_error;
to_return.use_q = use_q;
to_return.debug_phase = -1;
to_return.debug_count = 3;
to_return.debug_force = 0;
to_return.debug_writefiles = 0;
to_return.debug_phase = to_return.debug_every_nth = debug_every_nth; //debug is effective if it is >=0
to_return.last_correction_offset = 0;
to_return.earlylate_ratio = 0.25; //0..0.5
to_return.debug_writefiles_path = debug_writefiles_path;
return to_return;
}
void timing_recovery_trigger_debug(timing_recovery_state_t* state, int debug_phase)
{
state->debug_phase=debug_phase;
}
#define MTIMINGR_HDEBUG 0
void timing_recovery_cc(complexf* input, complexf* output, int input_size, timing_recovery_state_t* state)
void timing_recovery_cc(complexf* input, complexf* output, int input_size, float* timing_error, int* sampled_indexes, timing_recovery_state_t* state)
{
//We always assume that the input starts at center of the first symbol cross before the first symbol.
//Last time we consumed that much from the input samples that it is there.
@ -1834,11 +1984,10 @@ void timing_recovery_cc(complexf* input, complexf* output, int input_size, timin
int num_samples_halfbit = state->decimation_rate / 2;
int num_samples_quarterbit = state->decimation_rate / 4;
int num_samples_earlylate_wing = num_samples_bit * state->earlylate_ratio;
int debug_i = state->debug_count;
float error;
int el_point_left_index, el_point_right_index, el_point_mid_index;
int si = 0;
if(state->debug_force) fprintf(stderr, "disp(\"begin timing_recovery_cc\");\n");
if(state->debug_every_nth>=0) fprintf(stderr, "disp(\"begin timing_recovery_cc\");\n");
if(MTIMINGR_HDEBUG) fprintf(stderr, "timing_recovery_cc started, nsb = %d, nshb = %d, nsqb = %d\n", num_samples_bit, num_samples_halfbit, num_samples_quarterbit);
{
for(;;)
@ -1862,6 +2011,7 @@ void timing_recovery_cc(complexf* input, complexf* output, int input_size, timin
el_point_right_index = current_bitstart_index + num_samples_earlylate_wing * 3;
el_point_left_index = current_bitstart_index + num_samples_earlylate_wing * 1 - correction_offset;
el_point_mid_index = current_bitstart_index + num_samples_halfbit;
if(sampled_indexes) sampled_indexes[si]=el_point_mid_index;
output[si++] = input[el_point_mid_index];
}
else if(state->algorithm == TIMING_RECOVERY_ALGORITHM_GARDNER)
@ -1870,6 +2020,7 @@ void timing_recovery_cc(complexf* input, complexf* output, int input_size, timin
el_point_right_index = current_bitstart_index + num_samples_halfbit * 3;
el_point_left_index = current_bitstart_index + num_samples_halfbit * 1;
el_point_mid_index = current_bitstart_index + num_samples_halfbit * 2;
if(sampled_indexes) sampled_indexes[si]=el_point_left_index;
output[si++] = input[el_point_left_index];
}
else break;
@ -1883,25 +2034,30 @@ void timing_recovery_cc(complexf* input, complexf* output, int input_size, timin
//Original correction method: this version can only move a single sample in any direction
//current_bitstart_index += num_samples_halfbit * 2 + (error)?((error<0)?1:-1):0;
if(error>2) error=2;
if(error<-2) error=-2;
if( state->debug_force || (state->debug_phase >= si && debug_i) )
if(timing_error) timing_error[si-1]=error; //it is not written if NULL
if(error>state->max_error) error=state->max_error;
if(error<-state->max_error) error=-state->max_error;
if(state->debug_every_nth>=0)
{
debug_i--;
if(!debug_i) state->debug_phase = -1;
if(state->debug_every_nth==0 || state->debug_phase==0)
{
state->debug_phase = state->debug_every_nth;
octave_plot_point_on_cplxsig(input+current_bitstart_index, state->decimation_rate*2,
error,
current_bitstart_index,
correction_offset,
state->debug_writefiles,
state->debug_writefiles_path,
3,
el_point_left_index - current_bitstart_index, 'r',
el_point_right_index - current_bitstart_index, 'r',
el_point_mid_index - current_bitstart_index, 'r',
0);
}
else state->debug_phase--;
}
int error_sign = (state->algorithm == TIMING_RECOVERY_ALGORITHM_GARDNER) ? -1 : 1;
correction_offset = num_samples_halfbit * error_sign * (error/2);
correction_offset = num_samples_halfbit * error_sign * error * state->loop_gain;
current_bitstart_index += num_samples_bit + correction_offset;
if(si>=input_size)
{
@ -1935,6 +2091,57 @@ char* timing_recovery_get_string_from_algorithm(timing_recovery_algorithm_t algo
return "INVALID";
}
void init_bpsk_costas_loop_cc(bpsk_costas_loop_state_t* s, int decision_directed, float damping_factor, float bandwidth)
{
//fprintf(stderr, "init_bpsk_costas_loop_cc: bandwidth = %f, damping_factor = %f\n", bandwidth, damping_factor);
//based on: http://gnuradio.squarespace.com/blog/2011/8/13/control-loop-gain-values.html
float bandwidth_omega = 2*PI*bandwidth; //so that the bandwidth should be around 0.01 by default (2pi/100), and the damping_factor should be default 0.707
float denomiator = 1+2*damping_factor*bandwidth_omega+bandwidth_omega*bandwidth_omega;
fprintf(stderr, "damp = %f, bw = %f, bwomega = %f\n", damping_factor, bandwidth, bandwidth_omega);
s->alpha = (4*damping_factor*bandwidth_omega)/denomiator;
s->beta = (4*bandwidth_omega*bandwidth_omega)/denomiator;
s->current_freq = s->dphase = s->nco_phase = 0;
s->dphase_max=bandwidth_omega; //this has been determined by experiment: if dphase is out of [-dphase_max; dphase_max] it might actually hang and not come back
s->dphase_max_reset_to_zero=0;
}
void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, float* output_error, float* output_dphase, complexf* output_nco, bpsk_costas_loop_state_t* s)
{
for(int i=0;i<input_size;i++)
{
complexf nco_sample;
e_powj(&nco_sample, s->nco_phase);
cmult(&output[i], &input[i], &nco_sample);
if(output_nco) output_nco[i]=nco_sample;
float error = 0;
if(s->decision_directed)
{
float output_phase = atan2(qof(output,i),iof(output,i));
if (fabs(output_phase)<PI/2)
error = -output_phase;
else
{
error = PI-output_phase;
while(error>PI) error -= 2*PI;
}
}
else error = PI*iof(output,i)*qof(output,i);
if(output_error) output_error[i]=error;
s->current_freq += error * s->beta;
s->dphase = error * s->alpha + s->current_freq;
if(s->dphase>s->dphase_max) s->dphase = (s->dphase_max_reset_to_zero) ? 0 : s->dphase_max;
if(s->dphase<-s->dphase_max) s->dphase = (s->dphase_max_reset_to_zero) ? 0 : -s->dphase_max;
if(output_dphase) output_dphase[i]=s->dphase;
//fprintf(stderr, " error = %f; dphase = %f; nco_phase = %f;\n", error, s->dphase, s->nco_phase);
//step NCO
s->nco_phase += s->dphase;
while(s->nco_phase>2*PI) s->nco_phase-=2*PI;
while(s->nco_phase<=0) s->nco_phase+=2*PI;
}
}
#if 0
bpsk_costas_loop_state_t init_bpsk_costas_loop_cc(float samples_per_bits)
{
bpsk_costas_loop_state_t state;
@ -1956,7 +2163,7 @@ bpsk_costas_loop_state_t init_bpsk_costas_loop_cc(float samples_per_bits)
return state;
}
void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, bpsk_costas_loop_state_t* state)
void bpsk_costas_loop_c1mc(complexf* input, complexf* output, int input_size, bpsk_costas_loop_state_t* state)
{
int debug = 0;
if(debug) fprintf(stderr, "costas:\n");
@ -1989,7 +2196,159 @@ void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, bpsk
cmult(&output[i], &input[i], &vco_sample);
}
}
#endif
void simple_agc_cc(complexf* input, complexf* output, int input_size, float rate, float reference, float max_gain, float* current_gain)
{
float rate_1minus=1-rate;
int debugn = 0;
for(int i=0;i<input_size;i++)
{
float amplitude = sqrt(input[i].i*input[i].i+input[i].q*input[i].q);
float ideal_gain = (reference/amplitude);
if(ideal_gain>max_gain) ideal_gain = max_gain;
if(ideal_gain<=0) ideal_gain = 0;
//*current_gain += (ideal_gain-(*current_gain))*rate;
*current_gain = (ideal_gain-(*current_gain))*rate + (*current_gain)*rate_1minus;
//if(debugn<100) fprintf(stderr, "cgain: %g\n", *current_gain), debugn++;
output[i].i=(*current_gain)*input[i].i;
output[i].q=(*current_gain)*input[i].q;
}
}
void firdes_add_peak_c(complexf* output, int length, float rate, window_t window, int add, int normalize)
{
//add=0: malloc output previously
//add=1: calloc output previously
complexf* taps = (complexf*)malloc(sizeof(complexf)*length);
int middle=length/2;
float phase = 0, phase_addition = -rate*M_PI*2;
float (*window_function)(float) = firdes_get_window_kernel(window);
for(int i=0; i<length; i++) //@@firdes_add_peak_c: calculate taps
{
e_powj(&taps[i], phase);
float window_multiplier = window_function(fabs((float)(middle-i)/middle));
taps[i].i *= window_multiplier;
taps[i].q *= window_multiplier;
phase += phase_addition;
while(phase>2*M_PI) phase-=2*M_PI;
while(phase<0) phase+=2*M_PI;
}
//Normalize filter kernel
if(add)
for(int i=0;i<length;i++)
{
output[i].i += taps[i].i;
output[i].q += taps[i].q;
}
else for(int i=0;i<length;i++) output[i] = taps[i];
if(normalize)
{
float sum=0;
for(int i=0;i<length;i++) //@firdes_add_peak_c: normalize pass 1
{
sum+=sqrt(output[i].i*output[i].i + output[i].q*output[i].q);
}
for(int i=0;i<length;i++) //@firdes_add_peak_c: normalize pass 2
{
output[i].i/=sum;
output[i].q/=sum;
}
}
}
int apply_fir_cc(complexf* input, complexf* output, int input_size, complexf* taps, int taps_length)
{
int i;
for(i=0; i<input_size-taps_length+1; i++)
{
csetnull(&output[i]);
for(int ti=0;ti<taps_length;ti++)
{
cmultadd(&output[i], &input[i+ti], &taps[ti]);
}
}
return i;
}
int apply_real_fir_cc(complexf* input, complexf* output, int input_size, float* taps, int taps_length)
{
int i;
for(i=0; i<input_size-taps_length+1; i++)
{
float acci = 0, accq = 0;
for(int ti=0;ti<taps_length;ti++)
{
acci += iof(input,i+ti)*taps[ti];
accq += qof(input,i+ti)*taps[ti];
}
iof(output,i)=acci;
qof(output,i)=accq;
}
return i;
}
float normalized_timing_variance_u32_f(unsigned* input, float* temp, int input_size, int samples_per_symbol, int initial_sample_offset, int debug_print)
{
float *ndiff_rad = temp;
float ndiff_rad_mean = 0;
for(int i=0;i<input_size;i++)
{
//find out which real sample index this input sample index is the nearest to.
unsigned sinearest = (input[i]-initial_sample_offset) / samples_per_symbol;
unsigned sinearest_remain = (input[i]-initial_sample_offset) % samples_per_symbol;
if(sinearest_remain>samples_per_symbol/2) sinearest++;
unsigned socorrect = initial_sample_offset+(sinearest*samples_per_symbol); //the sample offset which input[i] should have been, in order to sample at the maximum effect point
int sodiff = abs(socorrect-input[i]);
float ndiff = (float)sodiff/samples_per_symbol;
ndiff_rad[i] = ndiff*PI;
ndiff_rad_mean = ndiff_rad_mean*(((float)i)/(i+1))+(ndiff_rad[i]/(i+1));
if(debug_print) fprintf(stderr, "input[%d] = %u, sinearest = %u, socorrect = %u, sodiff = %u, ndiff = %f, ndiff_rad[i] = %f, ndiff_rad_mean = %f\n", i, input[i], sinearest, socorrect, sodiff, ndiff, ndiff_rad[i], ndiff_rad_mean);
}
fprintf(stderr, "ndiff_rad_mean = %f\n", ndiff_rad_mean);
float result = 0;
for(int i=0;i<input_size;i++) result+=(powf(ndiff_rad[i]-ndiff_rad_mean,2))/(input_size-1);
//fprintf(stderr, "nv = %f\n", result);
return result;
}
void dbpsk_decoder_c_u8(complexf* input, unsigned char* output, int input_size)
{
static complexf last_input;
for(int i=0;i<input_size;i++)
{
float phase = atan2(qof(input,i), iof(input,i));
float last_phase = atan2(qofv(last_input), iofv(last_input));
float dphase = phase-last_phase;
while(dphase<-PI) dphase+=2*PI;
while(dphase>=PI) dphase-=2*PI;
if( (dphase>(PI/2)) || (dphase<(-PI/2)) ) output[i]=0;
else output[i]=1;
last_input = input[i];
}
}
int bfsk_demod_cf(complexf* input, float* output, int input_size, complexf* mark_filter, complexf* space_filter, int taps_length)
{
complexf acc_space, acc_mark;
for(int i=0; i<input_size-taps_length+1; i++)
{
csetnull(&acc_space);
csetnull(&acc_mark);
for(int ti=0;ti<taps_length;ti++)
{
cmultadd(&acc_space, &input[i+ti], &space_filter[ti]);
cmultadd(&acc_mark, &input[i+ti], &mark_filter[ti]);
}
output[i] = - ( iofv(acc_space)*iofv(acc_space)+qofv(acc_space)*qofv(acc_space) ) +
( iofv(acc_mark)*iofv(acc_mark)+qofv(acc_mark)*qofv(acc_mark) );
}
return input_size-taps_length+1;
}
/*
_____ _ _
@ -2077,6 +2436,99 @@ void convert_s24_f(unsigned char* input, float* output, int input_size, int bige
}
}
FILE* init_get_random_samples_f()
{
return fopen("/dev/urandom", "r");
}
void get_random_samples_f(float* output, int output_size, FILE* status)
{
int* pioutput = (int*)output;
fread((unsigned char*)output, sizeof(float), output_size, status);
for(int i=0;i<output_size;i++)
{
float tempi = pioutput[i];
output[i] = tempi/((float)(INT_MAX)); //*0.82
}
}
void get_random_gaussian_samples_c(complexf* output, int output_size, FILE* status)
{
int* pioutput = (int*)output;
fread((unsigned char*)output, sizeof(complexf), output_size, status);
for(int i=0;i<output_size;i++)
{
float u1 = 0.5+0.49999999*(((float)pioutput[2*i])/(float)INT_MAX);
float u2 = 0.5+0.49999999*(((float)pioutput[2*i+1])/(float)INT_MAX);
iof(output, i)=sqrt(-2*log(u1))*cos(2*PI*u2);
qof(output, i)=sqrt(-2*log(u1))*sin(2*PI*u2);
}
}
int deinit_get_random_samples_f(FILE* status)
{
return fclose(status);
}
int firdes_cosine_f(float* taps, int taps_length, int samples_per_symbol)
{
//needs a taps_length 2 × samples_per_symbol + 1
int middle_i=taps_length/2;
for(int i=0;i<samples_per_symbol;i++) taps[middle_i+i]=taps[middle_i-i]=(1+cos(PI*i/(float)samples_per_symbol))/2;
//for(int i=0;i<taps_length;i++) taps[i]=powf(taps[i],2);
normalize_fir_f(taps, taps, taps_length);
}
int firdes_rrc_f(float* taps, int taps_length, int samples_per_symbol, float beta)
{
//needs an odd taps_length
int middle_i=taps_length/2;
taps[middle_i]=(1/(float)samples_per_symbol)*(1+beta*(4/PI-1));
for(int i=1;i<1+taps_length/2;i++)
{
if(i==samples_per_symbol/(4*beta))
taps[middle_i+i]=taps[middle_i-i]=(beta/(samples_per_symbol*sqrt(2)))*((1+(2/PI))*sin(PI/(4*beta))+(1-(2/PI))*cos(PI/(4*beta)));
else
taps[middle_i+i]=taps[middle_i-i]=(1/(float)samples_per_symbol)*
(sin(PI*(i/(float)samples_per_symbol)*(1-beta)) + 4*beta*(i/(float)samples_per_symbol)*cos(PI*(i/(float)samples_per_symbol)*(1+beta)))/
(PI*(i/(float)samples_per_symbol)*(1-powf(4*beta*(i/(float)samples_per_symbol),2)));
}
normalize_fir_f(taps, taps, taps_length);
}
void plain_interpolate_cc(complexf* input, complexf* output, int input_size, int interpolation)
{
for(int i=0;i<input_size;i++)
{
output[i*interpolation]=input[i];
bzero(output+(interpolation*i)+1, (interpolation-1)*sizeof(complexf));
}
}
#define MMATCHEDFILT_GAS(NAME) \
if(!strcmp( #NAME , input )) return MATCHED_FILTER_ ## NAME;
matched_filter_type_t matched_filter_get_type_from_string(char* input)
{
MMATCHEDFILT_GAS(RRC);
MMATCHEDFILT_GAS(COSINE);
return MATCHED_FILTER_DEFAULT;
}
float* add_ff(float* input1, float* input2, float* output, int input_size)
{
for(int i=0;i<input_size;i++) output[i]=input1[i]+input2[i];
}
float* add_const_cc(complexf* input, complexf* output, int input_size, complexf x)
{
for(int i=0;i<input_size;i++)
{
iof(output,i)=iof(input,i)+iofv(x);
qof(output,i)=iof(input,i)+qofv(x);
}
}
int trivial_vectorize()
{
//this function is trivial to vectorize and should pass on both NEON and SSE

View file

@ -142,18 +142,40 @@ void rational_resampler_get_lowpass_f(float* output, int output_size, int interp
float *precalculate_window(int size, window_t window);
void apply_window_c(complexf* input, complexf* output, int size, window_t window);
void apply_precalculated_window_c(complexf* input, complexf* output, int size, float *windowt);
void apply_precalculated_window_f(float* input, float* output, int size, float *windowt);
void apply_window_f(float* input, float* output, int size, window_t window);
void logpower_cf(complexf* input, float* output, int size, float add_db);
void accumulate_power_cf(complexf* input, float* output, int size);
void log_ff(float* input, float* output, int size, float add_db);
typedef struct fractional_decimator_ff_s
{
float where;
int input_processed;
int output_size;
int num_poly_points; //number of samples that the Lagrange interpolator will use
float* poly_precalc_denomiator; //while we don't precalculate coefficients here as in a Farrow structure, because it is a fractional interpolator, but we rather precaculate part of the interpolator expression
//float* last_inputs_circbuf; //circular buffer to store the last (num_poly_points) number of input samples.
//int last_inputs_startsat; //where the circular buffer starts now
//int last_inputs_samplewhere;
float* coeffs_buf;
float* filtered_buf;
int xifirst;
int xilast;
float rate;
float *taps;
int taps_length;
} fractional_decimator_ff_t;
fractional_decimator_ff_t fractional_decimator_ff_init(float rate, int num_poly_points, float* taps, int taps_length);
void fractional_decimator_ff(float* input, float* output, int input_size, fractional_decimator_ff_t* d);
typedef struct old_fractional_decimator_ff_s
{
float remain;
int input_processed;
int output_size;
} fractional_decimator_ff_t;
fractional_decimator_ff_t fractional_decimator_ff(float* input, float* output, int input_size, float rate, float *taps, int taps_length, fractional_decimator_ff_t d);
} old_fractional_decimator_ff_t;
old_fractional_decimator_ff_t old_fractional_decimator_ff(float* input, float* output, int input_size, float rate, float *taps, int taps_length, old_fractional_decimator_ff_t d);
typedef struct shift_table_data_s
{
@ -305,26 +327,26 @@ typedef struct timing_recovery_state_s
int input_processed;
int use_q; //use both I and Q for calculating the error
int debug_phase;
int debug_count;
int debug_force;
int debug_writefiles;
int debug_every_nth;
char* debug_writefiles_path;
int last_correction_offset;
float earlylate_ratio;
float loop_gain;
float max_error;
} timing_recovery_state_t;
timing_recovery_state_t timing_recovery_init(timing_recovery_algorithm_t algorithm, int decimation_rate, int use_q);
void timing_recovery_cc(complexf* input, complexf* output, int input_length, timing_recovery_state_t* state);
timing_recovery_state_t timing_recovery_init(timing_recovery_algorithm_t algorithm, int decimation_rate, int use_q, float loop_gain, float max_error, int debug_every_nth, char* debug_writefiles_path);
void timing_recovery_cc(complexf* input, complexf* output, int input_size, float* timing_error, int* sampled_indexes, timing_recovery_state_t* state);
timing_recovery_algorithm_t timing_recovery_get_algorithm_from_string(char* input);
char* timing_recovery_get_string_from_algorithm(timing_recovery_algorithm_t algorithm);
void timing_recovery_trigger_debug(timing_recovery_state_t* state, int debug_phase);
void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error, int index, int correction_offset, int writefiles, int points_size, ...);
void octave_plot_point_on_cplxsig(complexf* signal, int signal_size, float error, int index, int correction_offset, char* writefiles_path, int points_size, ...);
void psk_modulator_u8_c(unsigned char* input, complexf* output, int input_size, int n_psk);
void duplicate_samples_ntimes_u8_u8(unsigned char* input, unsigned char* output, int input_size_bytes, int sample_size_bytes, int ntimes);
complexf psk31_interpolate_sine_cc(complexf* input, complexf* output, int input_size, int interpolation, complexf last_input);
void pack_bits_8to1_u8_u8(unsigned char* input, unsigned char* output, int input_size);
void psk31_varicode_encoder_u8_u8(unsigned char* input, unsigned char* output, int input_size, int output_max_size, int* input_processed, int* output_size);
unsigned char differential_codec(unsigned char* input, unsigned char* output, int input_size, int encode, unsigned char state);
#if 0
typedef struct bpsk_costas_loop_state_s
{
float rc_filter_alpha;
@ -337,3 +359,54 @@ typedef struct bpsk_costas_loop_state_s
bpsk_costas_loop_state_t init_bpsk_costas_loop_cc(float samples_per_bits);
void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, bpsk_costas_loop_state_t* state);
#endif
typedef struct bpsk_costas_loop_state_s
{
float alpha;
float beta;
int decision_directed;
float current_freq;
float dphase;
float nco_phase;
float dphase_max;
int dphase_max_reset_to_zero;
} bpsk_costas_loop_state_t;
void plain_interpolate_cc(complexf* input, complexf* output, int input_size, int interpolation);
void bpsk_costas_loop_cc(complexf* input, complexf* output, int input_size, float* output_error, float* output_dphase, complexf* output_nco, bpsk_costas_loop_state_t* s);
void init_bpsk_costas_loop_cc(bpsk_costas_loop_state_t* s, int decision_directed, float damping_factor, float bandwidth);
void simple_agc_cc(complexf* input, complexf* output, int input_size, float rate, float reference, float max_gain, float* current_gain);
void firdes_add_peak_c(complexf* output, int length, float rate, window_t window, int add, int normalize);
int apply_fir_cc(complexf* input, complexf* output, int input_size, complexf* taps, int taps_length);
FILE* init_get_random_samples_f();
void get_random_samples_f(float* output, int output_size, FILE* status);
void get_random_gaussian_samples_c(complexf* output, int output_size, FILE* status);
int deinit_get_random_samples_f(FILE* status);
float* add_ff(float* input1, float* input2, float* output, int input_size);
float total_logpower_cf(complexf* input, int input_size);
float normalized_timing_variance_u32_f(unsigned* input, float* temp, int input_size, int samples_per_symbol, int initial_sample_offset, int debug_print);
typedef enum matched_filter_type_e
{
MATCHED_FILTER_RRC,
MATCHED_FILTER_COSINE
} matched_filter_type_t;
#define MATCHED_FILTER_DEFAULT MATCHED_FILTER_RRC
int firdes_cosine_f(float* taps, int taps_length, int samples_per_symbol);
int firdes_rrc_f(float* taps, int taps_length, int samples_per_symbol, float beta);
matched_filter_type_t matched_filter_get_type_from_string(char* input);
int apply_real_fir_cc(complexf* input, complexf* output, int input_size, float* taps, int taps_length);
void generic_slicer_f_u8(float* input, unsigned char* output, int input_size, int n_symbols);
void plain_interpolate_cc(complexf* input, complexf* output, int input_size, int interpolation);;
void normalize_fir_f(float* input, float* output, int length);
float* add_const_cc(complexf* input, complexf* output, int input_size, complexf x);
void pack_bits_1to8_u8_u8(unsigned char* input, unsigned char* output, int input_size);
unsigned char pack_bits_8to1_u8_u8(unsigned char* input);
void dbpsk_decoder_c_u8(complexf* input, unsigned char* output, int input_size);
int bfsk_demod_cf(complexf* input, float* output, int input_size, complexf* mark_filter, complexf* space_filter, int taps_length);

View file

@ -51,6 +51,33 @@ float shift_addition_cc(complexf *input, complexf* output, int input_size, shift
return starting_phase;
}
float shift_addition_fc(float *input, complexf* output, int input_size, shift_addition_data_t d, float starting_phase)
{
//The original idea was taken from wdsp:
//http://svn.tapr.org/repos_sdr_hpsdr/trunk/W5WC/PowerSDR_HPSDR_mRX_PS/Source/wdsp/shift.c
//However, this method introduces noise (from floating point rounding errors), which increases until the end of the buffer.
//fprintf(stderr, "cosd=%g sind=%g\n", d.cosdelta, d.sindelta);
float cosphi=cos(starting_phase);
float sinphi=sin(starting_phase);
float cosphi_last, sinphi_last;
for(int i=0;i<input_size;i++) //@shift_addition_cc: work
{
iof(output,i)=cosphi*input[i];
qof(output,i)=sinphi*input[i];
//using the trigonometric addition formulas
//cos(phi+delta)=cos(phi)cos(delta)-sin(phi)*sin(delta)
cosphi_last=cosphi;
sinphi_last=sinphi;
cosphi=cosphi_last*d.cosdelta-sinphi_last*d.sindelta;
sinphi=sinphi_last*d.cosdelta+cosphi_last*d.sindelta;
}
starting_phase+=d.rate*PI*input_size;
while(starting_phase>PI) starting_phase-=2*PI; //@shift_addition_cc: normalize starting_phase
while(starting_phase<-PI) starting_phase+=2*PI;
return starting_phase;
}
shift_addition_data_t shift_addition_init(float rate)
{
rate*=2;

View file

@ -31,6 +31,7 @@ typedef struct shift_addition_data_s
} shift_addition_data_t;
shift_addition_data_t shift_addition_init(float rate);
float shift_addition_cc(complexf *input, complexf* output, int input_size, shift_addition_data_t d, float starting_phase);
float shift_addition_fc(float *input, complexf* output, int input_size, shift_addition_data_t d, float starting_phase);
void shift_addition_cc_test(shift_addition_data_t d);
float agc_ff(float* input, float* output, int input_size, float reference, float attack_rate, float decay_rate, float max_gain, short hang_time, short attack_wait_time, float gain_filter_alpha, float last_gain);

View file

@ -1,7 +0,0 @@
Remove nmux repo, it will rather be part of csdr
Try in OpenWebRX
Add UDP support
Evaluate performance against ncat
Remove debug messages
Document README.md
Test with a limited number of people

View file

@ -192,7 +192,7 @@ int main(int argc, char* argv[])
if(NMUX_DEBUG)
{
fprintf(stderr, "\x1b[1m\x1b[33mmainfor: clients before closing: ");
for(int i=0;i<clients.size();i++) fprintf(stderr, "0x%x ", (intptr_t)clients[i]);
for(int i=0;i<clients.size();i++) fprintf(stderr, "%p ", clients[i]);
fprintf(stderr, "\x1b[0m\n");
}
if(NMUX_DEBUG) fprintf(stderr, "mainfor: accepted (socket = %d).\n", new_socket);
@ -201,6 +201,12 @@ int main(int argc, char* argv[])
{
if(clients[i]->status == CS_THREAD_FINISHED)
{
if(pthread_detach(clients[i]->thread)!=0)
{
fprintf(stderr,"nmux pthread_detach failed for client %d\n", i);
continue;
}
if(NMUX_DEBUG) fprintf(stderr, "mainfor: client removed: %d\n", i);
//client destructor
pool->remove_thread(clients[i]->tsmthread);
@ -211,7 +217,7 @@ int main(int argc, char* argv[])
if(NMUX_DEBUG)
{
fprintf(stderr, "\x1b[1m\x1b[33mmainfor: clients after closing: ");
for(int i=0;i<clients.size();i++) fprintf(stderr, "0x%x ", (intptr_t)clients[i]);
for(int i=0;i<clients.size();i++) fprintf(stderr, "%p ", clients[i]);
fprintf(stderr, "\x1b[0m\n");
}
@ -227,7 +233,7 @@ int main(int argc, char* argv[])
if(pthread_create(&new_client->thread, NULL, client_thread, (void*)new_client)==0)
{
clients.push_back(new_client);
fprintf(stderr, MSG_START "pthread_create() done, clients now: %d\n", clients.size());
fprintf(stderr, MSG_START "pthread_create() done, clients now: %d\n", (int)clients.size());
}
else
{
@ -278,14 +284,14 @@ int main(int argc, char* argv[])
void* client_thread (void* param)
{
fprintf(stderr, "client 0x%x: started!\n", (intptr_t)param);
fprintf(stderr, "client %p: started!\n", param);
client_t* this_client = (client_t*)param;
this_client->status = CS_THREAD_RUNNING;
int retval;
tsmpool* lpool = this_client->lpool;
if(NMUX_DEBUG) fprintf(stderr, "client 0x%x: socket = %d!\n", (intptr_t)param, this_client->socket);
if(NMUX_DEBUG) fprintf(stderr, "client %p: socket = %d!\n", param, this_client->socket);
if(NMUX_DEBUG) fprintf(stderr, "client 0x%x: poll init...", (intptr_t)param);
if(NMUX_DEBUG) fprintf(stderr, "client %p: poll init...", param);
struct pollfd pollfds[1];
pollfds[0].fd = this_client->socket;
pollfds[0].events = POLLOUT;
@ -307,10 +313,10 @@ void* client_thread (void* param)
// (Wait for the server process to wake me up.)
while(!pool_read_buffer || client_buffer_index >= lpool->size)
{
if(NMUX_DEBUG) fprintf(stderr, "client 0x%x: trying to grb\n", (intptr_t)param);
if(NMUX_DEBUG) fprintf(stderr, "client %p: trying to grb\n", param);
pool_read_buffer = (char*)lpool->get_read_buffer(this_client->tsmthread);
if(pool_read_buffer) { client_buffer_index = 0; break; }
if(NMUX_DEBUG) fprintf(stderr, "client 0x%x: cond_waiting for more data\n", (intptr_t)param);
if(NMUX_DEBUG) fprintf(stderr, "client %p: cond_waiting for more data\n", param);
pthread_mutex_lock(&wait_mutex);
this_client->sleeping = 1;
pthread_cond_wait(&wait_condition, &wait_mutex);
@ -318,14 +324,14 @@ void* client_thread (void* param)
}
//Wait for the socket to be available for write.
if(NMUX_DEBUG) fprintf(stderr, "client 0x%x: polling for socket write...", (intptr_t)param);
if(NMUX_DEBUG) fprintf(stderr, "client %p: polling for socket write...", param);
int ret = poll(pollfds, 1, -1);
if(NMUX_DEBUG) fprintf(stderr, "client polled for socket write.\n");
if(ret == 0) continue;
else if (ret == -1) { client_goto_source = 1; goto client_thread_exit; }
//Read data from global tsmpool and write it to client socket
if(NMUX_DEBUG) fprintf(stderr, "client 0x%x: sending...", (intptr_t)param);
if(NMUX_DEBUG) fprintf(stderr, "client %p: sending...", param);
ret = send(this_client->socket, pool_read_buffer + client_buffer_index, lpool->size - client_buffer_index, MSG_NOSIGNAL);
if(NMUX_DEBUG) fprintf(stderr, "client sent.\n");
if(ret == -1)
@ -340,7 +346,7 @@ void* client_thread (void* param)
}
client_thread_exit:
fprintf(stderr, "client 0x%x: CS_THREAD_FINISHED, client_goto_source = %d, errno = %d", (intptr_t)param, client_goto_source, errno);
fprintf(stderr, "client %p: CS_THREAD_FINISHED, client_goto_source = %d, errno = %d", param, client_goto_source, errno);
this_client->status = CS_THREAD_FINISHED;
pthread_exit(NULL);
return NULL;

View file

@ -42,7 +42,7 @@ tsmthread_t* tsmpool::register_thread()
return thread;
}
int tsmpool::remove_thread(tsmthread_t* thread)
void tsmpool::remove_thread(tsmthread_t* thread)
{
pthread_mutex_lock(&this->mutex);
for(int i=0;i<threads.size();i++)

View file

@ -36,7 +36,7 @@ public:
tsmpool(size_t size, int num);
void* get_write_buffer();
tsmthread_t* register_thread();
int remove_thread(tsmthread_t* thread);
void remove_thread(tsmthread_t* thread);
void* get_read_buffer(tsmthread_t* thread);
int index_next(int index) { return (index+1==num)?0:index+1; }
int index_before(int index) { return (index-1<0)?num-1:index-1; }