initial commit

This commit is contained in:
ha7ilm 2014-11-28 16:44:41 +01:00
parent 0496edca12
commit 07c6a7df3a
33 changed files with 16481 additions and 2 deletions

66
Makefile Normal file
View file

@ -0,0 +1,66 @@
# This software is part of libcsdr, a set of simple DSP routines for
# Software Defined Radio under BSD license.
#
# Copyright (c) 2014, Andras Retzler <randras@sdr.hu>
# 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 ANDRAS RETZLER 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.
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,sse4,-msse4) $(call cpufeature,sse4_1,-msse4.1) $(call cpufeature,sse4_2,-msse4.2) -mfpmath=sse
PARAMS_NEON = -fshort-double -mfloat-abi=softfp -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mvectorize-with-neon-quad -Wformat=0
PARAMS_SIMD = $(if $(call cpufeature,sse,dummy-text),$(PARAMS_SSE),$(PARAMS_NEON))
PARAMS_LOOPVECT = -O3 -ffast-math -fdump-tree-vect-details -dumpbase dumpvect
PARAMS_LIBS = -g -lm -lfftw3f -DUSE_FFTW -DLIBCSDR_GPL
PARAMS_SO = -fpic
PARAMS_MISC = -Wno-unused-result
all: clean-vect
@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
c99 $(PARAMS_LOOPVECT) $(PARAMS_SIMD) $(LIBSOURCES) $(PARAMS_LIBS) $(PARAMS_MISC) -fpic -shared -o libcsdr.so
./parsevect dumpvect*.vect libcsdr.c
c99 $(PARAMS_LOOPVECT) $(PARAMS_SIMD) csdr.c $(PARAMS_LIBS) -L. -lcsdr $(PARAMS_MISC) -o csdr
arm-cross: clean-vect
#note: this doesn't work since having added FFTW
arm-linux-gnueabihf-gcc -std=c99 -O3 -fshort-double -ffast-math -dumpbase dumpvect-arm -fdump-tree-vect-details -mfloat-abi=softfp -march=armv7-a -mtune=cortex-a9 -mfpu=neon -mvectorize-with-neon-quad -Wno-unused-result -Wformat=0 $(SOURCES) -lm -o ./csdr
clean-vect:
rm -f dumpvect*.vect
clean: clean-vect
rm libcsdr.so csdr
install:
install -m 0755 libcsdr.so /usr/lib
install -m 0755 csdr /usr/bin
install -m 0755 csdr-fm /usr/bin
ldconfig
uninstall:
rm /usr/lib/libcsdr.so /usr/bin/csdr /usr/bin/csdr-fm
ldconfig

336
README.md
View file

@ -1,2 +1,334 @@
csdr
====
libcsdr
=======
*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 [Licensing].
- 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).
How to compile
--------------
The project was only tested on Linux. It has the following dependencies: `libfftw3-dev`
make
sudo make install
If you compile on ARM, please edit the Makefile and tailor `PARAMS_NEON` for your CPU.
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`
Credits
-------
The library was written by Andras Retzler, HA7ILM &lt;<randras@sdr.hu>&gt;.
I would like to say special thanks to Péter Horváth, HA5CQA and János Selmeczi, HA5FT for their continous help and support.
Usage by example
----------------
### Demodulate WFM
rtl_sdr -s 240000 -f 89500000 -g 20 - | csdr convert_u8_f | csdr fmdemod_quadri_cf | csdr fractional_decimator_ff 5 | csdr deemphasis_wfm_ff 48000 50e-6 | csdr convert_f_i16 | mplayer -cache 1024 -quiet -rawaudio samplesize=2:channels=1:rate=48000 -demuxer rawaudio -
- Baseband I/Q signal is coming from an RTL-SDR USB dongle, with a center frequency of `-f 104300000` Hz, a sampling rate of `-s 240000` samples per second.
- The `rtl_sdr` tool outputs an unsigned 8-bit I/Q signal (one byte of I sample and one byte of Q coming after each other), but `libcsdr` DSP routines internally use floating point data type, so we convert the data stream of `unsigned char` to `float` by `csdr convert_u8_f`.
- We want to listen one radio station at the frequency `-f 89500000` Hz (89.5 MHz).
- No other radio station is within the sampled bandwidth, so we send the signal directly to the demodulator. (This is an easy, but not perfect solution as the anti-aliasing filter at RTL-SDR DDC is too short.)
- After FM demodulation we decimate the signal by a factor of 5 to match the rate of the audio card (240000 / 5 = 48000).
- A de-emphasis filter is used, because pre-emphasis is applied at the transmitter to compensate noise at higher frequencies. The time constant for de-emphasis for FM broadcasting in Europe is 50 microseconds (hence the `50e-6`).
- Also, `mplayer` cannot play floating point audio, so we convert our signal to a stream of 16-bit integers.
### Demodulate WFM: advanced
rtl_sdr -s 2400000 -f 89300000 -g 20 - | csdr convert_u8_f | csdr shift_addition_cc -0.17 | csdr fir_decimate_cc 10 0.05 HAMMING | csdr fmdemod_quadri_cf | csdr fractional_decimator_ff 5 | csdr deemphasis_wfm_ff 48000 50e-6 | csdr convert_f_i16 | mplayer -cache 1024 -quiet -rawaudio samplesize=2:channels=1:rate=48000 -demuxer rawaudio -
- We want to listen to one radio station, but input signal contains multiple stations, and its bandwidth is too large for sending it directly to the FM demodulator.
- We shift the signal to the center frequency of the station we want to receive: `-0.17*2400000*0.5 = -204000`, so basically we will listen to the radio station centered at 89504000 Hz.
- We decimate the signal by a factor of 10. The rolloff for the FIR filter used for decimation will be 10% of total bandwidth (as of parameter 0.05 is 10% of 0.5). Hamming window will be used for windowed FIR filter design.
- Sample rates look like this:
2.4 Msps 240 ksps 48 ksps
I/Q source ------------> FIR decimation ------------> FM demod -> frac. decimation ---------> deemphasis -> sound card
*Note:* there is an example shell script that does this for you (without the unnecessary shift operation). If you just want to listen to FM radio, type:
csdr-fm 89.5 20
The first parameter is the frequency in MHz, and the second optional parameter is the RTL-SDR tuner gain in dB.
### Demodulate NFM
rtl_sdr -s 2400000 -f 145000000 -g 20 - | csdr convert_u8_f | csdr shift_addition_cc `python -c "print (145000000-145350000)/(0.5*2400000)"` | csdr fir_decimate_cc 50 0.005 HAMMING | csdr fmdemod_quadri_cf | csdr limit_ff | csdr deemphasis_nfm_ff 48000 | csdr fastagc_ff | csdr convert_f_i16 | mplayer -cache 1024 -quiet -rawaudio samplesize=2:channels=1:rate=48000 -demuxer rawaudio -
- Note that the decimation factor is higher (we want to select a ~25 kHz channel).
- Also there is a python hack to calculate the relative shift offset. The real receiver frequency is `145350000` Hz.
- The de-emphasis filter is a fixed FIR filter that has a passband of 400-4000 Hz, also with a roll-off of -20 dB/decade.
### Demodulate AM
rtl_sdr -s 2400000 -f 145000000 -g 20 - | csdr convert_u8_f | csdr shift_addition_cc `python -c "print (145000000-144400000)/(0.5*2400000)"` | csdr fir_decimate_cc 50 0.005 HAMMING | csdr amdemod_cf | csdr fastdcblock_ff | csdr agc_ff | csdr limit_ff | csdr convert_f_i16 | mplayer -cache 1024 -quiet -rawaudio samplesize=2:channels=1:rate=48000 -demuxer rawaudio -
- `amdemod_cf` is used as demodulator.
- `agc_ff` should be used for AM and SSB.
### Design FIR band-pass filter (with complex taps)
csdr firdes_bandpass_c 0 0.5 59 HAMMING --octave | octave -i
- ...and then plot its frequency response with octave.
- It will design a filter that lets only the positive frequencies pass (low cut is 0, high cut is 0.5 - these are relative to the sampling rate).
- If `--octave` and everything that follows is removed from the command, you get only the taps. E. g. the raw output of `firdes_lowpass_f` can be easily copied to C code.
### Demodulate SSB
rtl_sdr -s 2400000 -f 145000000 -g 20 - | csdr convert_u8_f | csdr shift_addition_cc `python -c "print (145000000-144400000)/(0.5*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_i16 | 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`.
### Draw FFT
rtl_sdr -s 2400000 -f 104300000 -g 20 - | csdr convert_u8_f | csdr fft_cc 1024 1200000 HAMMING --octave | octave -i > /dev/null
- We calculate the Fast Fourier Transform by `csdr fft_cc` on the first 1024 samples of every block of 1200000 complex samples coming after each other. (We calculate FFT from 1024 samples and then skip 1200000-1024=1198976 samples. This way we will calculate FFT two times every second.)
- The window used for FFT is the Hamming window, and the output consists of commands that can be directly interpreted by GNU Octave which plots us the spectrum.
Usage
-----
Some basic concepts on using *libcsdr*:
### Data types
Function name endings found in *libcsdr* mean the input and output data types of the particular function. (This is similar to GNU Radio naming conventions).
Data types are noted as it follows:
- `f` is `float` (single percision)
- `c` is `complexf` (two single precision floating point values in a struct)
- `u8` is `unsigned char` of 1 byte/8 bits (e. g. the output of `rtl_sdr` is of `u8`)
- `i16` is `signed short` of 2 bytes/16 bits (e. g. sound card input is usually `i16`)
Functions usually end as:
- `_ff` float input, float output
- `_cf` complex input, float output
- `_cc` complex input, complex output
Regarding *csdr*, it can convert a real/complex stream from one data format to another, to interface it with other SDR tools and the sound card.
The following commands are available:
- `csdr convert_u8_f`
- `csdr convert_f_u8`
- `csdr convert_i16_f`
- `csdr convert_f_i16`
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).
#### 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`.
Regarding `csdr`, the first command-line parameter is the name of a function, others are the parameters for the given function. Compulsory parameters are noted as `<parameter>`, optional parameters are noted as `[parameter]`.
Optional parameters have safe defaults, for more info look at the code.
##### `realpart_cf`
It takes the real part of the complex signal, and throws away the imaginary part.
##### `clipdetect_ff`
It clones the signal (the input and the output is the same), but it prints a warning on `stderr` if any sample value is out of the -1.0 ... 1.0 range.
##### `limit_ff [max_amplitude]`
The input signal amplitude will not be let out of the `-max_amplitude ... max_amplitude` range.
##### `gain_ff <gain>`
It multiplies all samples by `gain`.
##### `clone`
It copies the input to the output.
##### `yes_f <to_repeat> [buf_times]`
It outputs continously the `to_repeat` float number.
If `buf_times` is not given, it never stops.
Else, after outputing `buf_times` number of buffers (the size of which is stated in the `BUFSIZE` macro), it exits.
##### `shift_math_cc <rate>`
It shifts the complex spectrum by `rate`.
`rate` is a floating point number between -0.5 and 0.5.
`rate` is relative to the sampling rate.
Internally, a sine and cosine wave is generated to perform this function, and this function uses `math.h` for this purpose, which is quite accurate, but not always very fast.
##### `shift_addition_cc <rate>`
Operation is the same as with `shift_math_cc`.
Internally, this function uses trigonometric addition formulas to generate sine and cosine, which is a bit faster. (About 4 times on the machine I have tested it on.)
##### `shift_addition_cc_test`
This function was used to test the accuracy of the method above.
##### `dcblock_ff`
This is a DC blocking IIR filter.
##### `fastdcblock_ff`
This is a DC blocker that works based on the average of the buffer.
##### `fmdemod_atan_cf`
It is an FM demodulator that internally uses the `atan` function in `math.h`, so it is not so fast.
##### `fmdemod_quadri_cf`
It is an FM demodulator that is based on the quadri-correlator method, and it can be effectively auto-vectorized, so it should be faster.
##### `fmdemod_quadri_novect_cf`
It has more easily understandable code than the previous one, but can't be auto-vectorized.
##### `deemphasis_wfm_ff <sample_rate> <tau>`
It does de-emphasis with the given RC time constant `tau`.
Different parts of the world use different pre-emphasis filters for FM broadcasting.
In Europe, `tau` should be chosen as `50e-6`, and in the USA, `tau` should be `75e-6`.
##### `deemphasis_nfm_ff <one_of_the_predefined_sample_rates>`
It does de-emphasis on narrow-band FM for communication equipment (e.g. two-way radios).
It uses fixed filters so it works only on predefined sample rates, for the actual list of them run: `cat libcsdr.c | grep DNFMFF_ADD_ARRAY`
##### `amdemod_cf`
It is an AM demodulator that uses `sqrt`. On some architectures `sqrt` can be directly calculated by dedicated CPU instructions, but on others it may be slower.
##### `amdemod_estimator_cf`
It is an AM demodulator that uses an estimation method that is faster but less accurate than `amdemod_cf`.
##### `firdes_lowpass_f <cutoff_rate> <length> [window [--octave]]`
Low-pass FIR filter design function to output real taps, with a `cutoff_rate` proportional to the sampling frequency, using the windowed sinc filter design method.
`cutoff_rate` can be between 0 and 0.5.
`length` is the number of filter taps to output, and should be odd.
The longer the filter kernel is, the shorter the transition bandwidth is, but the more CPU time it takes to process the filter.
The transition bandwidth (proportional to the sampling rate) can be calculated as: `transition_bw = 4 / length`.
Some functions (below) require the `transition_bw` to be given instead of filter `length`. Try to find the best compromise between speed and accuracy by changing this parameter.
`window` is the window function used to compensate finite filter length. Its typical values are: `HAMMING`, `BLACKMAN`, `BOXCAR`. For the actual list of values, run: `cpp libcsdr.c | grep window\ ==`
The `--octave` parameter lets you directly view the filter response in `octave`. For more information, look at the [Usage by example] section.
##### `firdes_bandpass_c <low_cut> <high_cut> <length> [window [--octave]]`
Band-pass FIR filter design function to output complex taps.
`low_cut` and ` high_cut` both may be between -0.5 and 0.5, and are also proportional to the sampling frequency.
Other parameters were explained above at `firdes_lowpass_f`.
##### `fir_decimate_cc <decimation_factor> [transition_bw [window]]`
It is a decimator that keeps one sample out of `decimation_factor` samples.
To avoid aliasing, it runs a filter on the signal and removes spectral components above `0.5 × nyquist_frequency × decimation_factor`.
`transition_bw` and `window` are the parameters of the filter.
##### `rational_resampler_ff <interpolation> <decimation> [transition_bw [window]]`
It is a resampler that takes integer values of `interpolation` and `decimation`.
The output sample rate will be `interpolation / decimation × input_sample_rate`.
`transition_bw` and `window` are the parameters of the filter.
##### `fractional_decimator_ff <decimation_rate> [transition_bw [window]]`
It can decimate by a floating point ratio.
`transition_bw` and `window` are the parameters of the filter.
#### `bandpass_fir_fft_cc <low_cut> <high_cut> <transition_bw> [window]`
It performs a bandpass FIR filter on complex samples, using FFT and the overlap-add method.
Parameters are described under `firdes_bandpass_c` and `firdes_lowpass_f`.
##### `agc_ff [hang_time [reference [attack_rate [decay_rate [max_gain [attack_wait [filter_alpha]]]]]]]`
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.
- `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.
- AGC won't increase the gain over `max_gain`.
- `attack_wait` is the number of sampels to wait before starting to decrease the gain, because sometimes very short peaks happen, and we don't want them to spoil the reception by substantially decreasing the gain of the AGC.
- `filter_alpha` is the parameter of the loop filter.
Its default parameters work best for an audio signal sampled at 48000 Hz.
##### `fastagc_ff [block_size [reference]]`
It is a faster AGC that linearly changes the gain, taking the highest amplitude peak in the buffer into consideration. Its output will never exceed `-reference ... reference`.
##### `fft_cc <fft_size> <out_of_every_n_samples> [window [--octave] [--benchmark]]`
It performs an FFT on the first `fft_size` samples out of `out_of_every_n_samples`, thus skipping `out_of_every_n_samples - fft_size` samples in the input.
It can draw the spectrum by using `--octave`, for more information, look at the [Usage by example] section.
FFTW can be faster if we let it optimalize a while before starting the first transform, hence the `--benchmark` switch.
##### `fft_benchmark <fft_size> <fft_cycles> [--benchmark]`
It measures the time taken to process `fft_cycles` transforms of `fft_size`.
It lets FFTW optimalize if used with the `--benchmark` switch.
##### `lowpower_cf [add_db]`
Calculates `10*log10(i^2+q^2)+add_db` for the input complex samples. It is useful for drawing power spectrum graphs.
#### 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.
##### `shift_addition_cc --fifo <fifo_path>`
By writing to the given FIFO file with the syntax below, you can control the shift rate:
<shift_rate>\n
E.g. you can send `-0.3\n`
Processing will only start after the first control command has been received by `csdr` over the FIFO.
##### `bandpass_fir_fft_cc --fifo <fifo_path> <transition_bw> [window]`
By writing to the given FIFO file with the syntax below, you can control the shift rate:
<low_cut> <high_cut>\n
E.g. you can send `-0.05 0.02\n`
#### Testbench
`csdr` was tested with GNU Radio Companion flowgraphs. These flowgraphs are available under the directory `grc_tests`, and they require the `gr-ha5kfu` set of blocks for GNU Radio.
Licensing
---------
Before the implementation of some algoritms, GPL-licensed code from other applications have been reviewed.
In order to eliminate any licesing issues, these parts are placed under a different file.
However, the library is still fully functional with BSD-only code, altough having only less-optimized versions of some algorithms.
It should also be noted that if you compile with `-DUSE_FFTW` and `-DLIBCSDR_GPL` (as default), the GPL license would apply on the whole result.

41
csdr-fm Executable file
View file

@ -0,0 +1,41 @@
#!/bin/bash
: '
Copyright (c) 2014, Andras Retzler <ha7ilm@sdr.hu>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. 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.
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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
'
USAGE="csdr-fm: a script to listen to FM radio with RTL-SDR and csdr.
usage:
csdr-fm frequency_mhz [gain_db]
example:
csdr-fm 89.5
csdr-fm 89.5 30
"
GAIN=30
if [ $# -eq 2 ]; then GAIN="$2"; fi
if [ $# -eq 0 ]; then echo "$USAGE"; exit -1; fi
rtl_sdr -s 2400000 -f `python -c "print int($1*1e6)"` -g $GAIN - | csdr convert_u8_f | csdr fir_decimate_cc 10 0.05 HAMMING | csdr fmdemod_quadri_cf | csdr fractional_decimator_ff 5 | csdr deemphasis_wfm_ff 48000 50e-6 | csdr convert_f_i16 | mplayer -cache 1024 -quiet -rawaudio samplesize=2:channels=1:rate=48000 -demuxer rawaudio -

976
csdr.c Normal file
View file

@ -0,0 +1,976 @@
/*
This software is part of libcsdr, a set of simple DSP routines for
Software Defined Radio.
Copyright (c) 2014, Andras Retzler <randras@sdr.hu>
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 ANDRAS RETZLER 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.
*/
#define _POSIX_C_SOURCE 199309L
#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <time.h>
#include <stdarg.h>
#include "libcsdr.h"
#include "libcsdr_gpl.h"
/*
example chains defined:
rtl_sdr -f 90000000 -s 2400000 - | csdr convert_u8_c | csdr shift_cc -0.20833 | csdr decimate_cc 5 0.1 | \
csdr fmdemod | csdr resample_rr 240000 48000 | csdr audio 48000
*/
char usage[]=
"csdr - a simple commandline tool for Software Defined Radio receiver DSP.\n\n"
"usage: \n\n"
" csdr function_name <function_param1> <function_param2> [optional_param] ...\n\n"
"list of functions:\n\n"
" convert_u8_f\n"
" convert_f_u8\n"
" convert_f_i16\n"
" convert_i16_f\n"
" realpart_cf\n"
" clipdetect_ff\n"
" limit_ff [max_amplitude]\n"
" gain_ff <gain>\n"
" clone\n"
" yes_f <to_repeat> [buf_times]\n"
" shift_math_cc <rate>\n"
" shift_addition_cc <rate>\n"
" shift_addition_cc_test\n"
" dcblock_ff\n"
" fastdcblock_ff\n"
" fmdemod_atan_cf\n"
" fmdemod_quadri_cf\n"
" fmdemod_quadri_novect_cf\n"
" deemphasis_wfm_ff <sample_rate> <tau>"
" deemphasis_nfm_ff <one_of_the_predefined_sample_rates>"
" amdemod_cf\n"
" amdemod_estimator_cf\n"
" fir_decimate_cc <decimation_factor> [transition_bw [window]]\n"
" firdes_lowpass_f <cutoff_rate> <length> [window [--octave]]\n"
" firdes_bandpass_c <low_cut> <high_cut> <length> [window [--octave]]\n"
" agc_ff [hang_time [reference [attack_rate [decay_rate [max_gain [attack_wait [filter_alpha]]]]]]]\n"
" fastagc_ff [block_size [reference]]"
" rational_resampler_ff <interpolation> <decimation> [transition_bw [window]]\n"
" fractional_decimator_ff <decimation_rate> [transition_bw [window]]\n"
" fft_cc <fft_size> <out_of_every_n_samples> [window [--octave] [--benchmark]]\n"
" logpower_cf [add_db]\n"
" fft_benchmark <fft_size> <fft_cycles> [--benchmark]\n"
" bandpass_fir_fft_cc <low_cut> <high_cut> <transition_bw> [window]\n"
;
#define BUFSIZE (1024*8)
//should be multiple of 16! (size of double complex)
//also, keep in mind that shift_addition_cc works better the smaller this buffer is.
int badsyntax(char* why)
{
if(why==0) fprintf(stderr, "%s", usage);
else fprintf(stderr, "%s\n\n", why);
return -1;
}
int clipdetect_ff(float* input, int input_size)
{
for(int i=0;i<input_size;i++)
{
if(input[i]<-1.0) { fprintf(stderr, "clipdetect_ff: Signal value below -1.0!\n"); return -1; }
if(input[i]>1.0) { fprintf(stderr, "clipdetect_ff: Signal value above 1.0!\n"); return 1; }
}
return 0;
}
int clone()
{
static unsigned char clone_buffer[BUFSIZE];
for(;;)
{
fread(clone_buffer, sizeof(unsigned char), BUFSIZE, stdin);
fwrite(clone_buffer, sizeof(unsigned char), BUFSIZE, stdout);
}
}
#define FREAD_R fread(input_buffer, sizeof(float), BUFSIZE, stdin)
#define FREAD_C fread(input_buffer, sizeof(float)*2, BUFSIZE, stdin)
#define FWRITE_R fwrite(output_buffer, sizeof(float), BUFSIZE, stdout)
#define FWRITE_C fwrite(output_buffer, sizeof(float)*2, BUFSIZE, stdout)
#define FEOF_CHECK if(feof(stdin)) return 0
int init_fifo(int argc, char *argv[])
{
if(argc>=4)
{
if(!strcmp(argv[2],"--fifo"))
{
fprintf(stderr,"csdr: fifo control mode on\n");
int fd = open(argv[3], O_RDONLY);
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
return fd;
}
}
return 0;
}
#define RFCTL_BUFSIZE 1024
int read_fifo_ctl(int fd, char* format, ...)
{
if(!fd) return 0;
static char buffer[RFCTL_BUFSIZE];
static int buffer_index=0;
int bytes_read=read(fd,buffer+buffer_index,(RFCTL_BUFSIZE-buffer_index)*sizeof(char));
if(bytes_read<=0) return 0;
int prev_newline_at=0;
int last_newline_at=0;
for(int i=0;i<buffer_index+bytes_read;i++)
{
if(buffer[i]=='\n')
{
prev_newline_at=last_newline_at;
last_newline_at=i+1;
}
}
if(last_newline_at)
{
//fprintf(stderr,"pna=%d lna=%d\n",prev_newline_at,last_newline_at);
va_list vl;
va_start(vl,format);
vsscanf(buffer+prev_newline_at,format,vl);
va_end(vl);
memmove(buffer,buffer+last_newline_at,buffer_index+bytes_read-last_newline_at);
buffer_index=bytes_read-last_newline_at;
return 1;
}
else
{
buffer_index+=bytes_read;
return 0;
}
}
int main(int argc, char *argv[])
{
static float input_buffer[BUFSIZE*2];
static unsigned char buffer_u8[BUFSIZE*2];
static float output_buffer[BUFSIZE*2];
static short buffer_i16[BUFSIZE*2];
static float temp_f[BUFSIZE*4];
if(argc<=1) return badsyntax(0);
if(!strcmp(argv[1],"--help")) return badsyntax(0);
if(!strcmp(argv[1],"convert_u8_f"))
{
for(;;)
{
FEOF_CHECK;
fread(buffer_u8, sizeof(unsigned char), BUFSIZE, stdin);
convert_u8_f(buffer_u8, output_buffer, BUFSIZE);
FWRITE_R;
}
}
if(!strcmp(argv[1],"convert_f_u8")) //not tested
{
for(;;)
{
FEOF_CHECK;
FREAD_R;
convert_f_u8(input_buffer, buffer_u8, BUFSIZE);
fwrite(buffer_u8, sizeof(unsigned char), BUFSIZE, stdout);
}
}
if(!strcmp(argv[1],"convert_f_i16"))
{
for(;;)
{
FEOF_CHECK;
FREAD_R;
convert_f_i16(input_buffer, buffer_i16, BUFSIZE);
fwrite(buffer_i16, sizeof(short), BUFSIZE, stdout);
}
}
if(!strcmp(argv[1],"convert_i16_f")) //not tested
{
for(;;)
{
FEOF_CHECK;
fread(buffer_i16, sizeof(short), BUFSIZE, stdin);
convert_i16_f(buffer_i16, output_buffer, BUFSIZE);
FWRITE_R;
}
}
if(!strcmp(argv[1],"realpart_cf"))
{
for(;;)
{
FEOF_CHECK;
FREAD_C;
for(int i=0;i<BUFSIZE;i++) output_buffer[i]=iof(input_buffer,i);
FWRITE_R;
}
}
if(!strcmp(argv[1],"clipdetect_ff"))
{
for(;;)
{
FEOF_CHECK;
FREAD_R;
clipdetect_ff(input_buffer, BUFSIZE);
fwrite(input_buffer, sizeof(float), BUFSIZE, stdout);
}
}
if(!strcmp(argv[1],"gain_ff"))
{
if(argc<=2) return badsyntax("need required parameter (gain)");
float gain;
sscanf(argv[2],"%g",&gain);
for(;;)
{
FEOF_CHECK;
FREAD_R;
gain_ff(input_buffer, output_buffer, BUFSIZE, gain);
FWRITE_R;
}
}
if(!strcmp(argv[1],"clone"))
{
clone();
}
if(!strcmp(argv[1],"limit_ff"))
{
float max_amplitude=1.0;
if(argc>=3) sscanf(argv[2],"%g",&max_amplitude);
for(;;)
{
FEOF_CHECK;
FREAD_R;
limit_ff(input_buffer, output_buffer, BUFSIZE, max_amplitude);
FWRITE_R;
}
}
if(!strcmp(argv[1],"yes_f"))
{
if(argc<=2) return badsyntax("need required parameter (to_repeat)");
float to_repeat;
sscanf(argv[2],"%g",&to_repeat);
int buf_times = 0;
if(argc>=4) sscanf(argv[3],"%d",&buf_times);
for(int i=0;i<BUFSIZE;i++) output_buffer[i]=to_repeat;
for(int i=0;(!buf_times)||i<buf_times;i++) fwrite(output_buffer, sizeof(float), BUFSIZE, stdout);
return 0;
}
if(!strcmp(argv[1],"shift_math_cc"))
{
if(argc<=2) return badsyntax("need required parameter (rate)");
float starting_phase=0;
float rate;
sscanf(argv[2],"%g",&rate);
for(;;)
{
FEOF_CHECK;
if(!FREAD_C) break;
starting_phase=shift_math_cc((complexf*)input_buffer, (complexf*)output_buffer, BUFSIZE, rate, starting_phase);
FWRITE_C;
}
return 0;
}
//speed tests:
//csdr yes_f 1 1000000 | time csdr shift_math_cc 0.2 >/dev/null
//csdr yes_f 1 1000000 | time csdr shift_addition_cc 0.2 >/dev/null
#ifdef LIBCSDR_GPL
if(!strcmp(argv[1],"shift_addition_cc"))
{
float starting_phase=0;
float rate;
int fd;
if(fd=init_fifo(argc,argv))
{
while(!read_fifo_ctl(fd,"%g\n",&rate)) usleep(10000);
}
else
{
if(argc<=2) return badsyntax("need required parameter (rate)");
sscanf(argv[2],"%g",&rate);
}
for(;;)
{
shift_addition_data_t data=shift_addition_init(rate);
fprintf(stderr,"shift_addition_cc: reinitialized to %g\n",rate);
for(;;)
{
FEOF_CHECK;
if(!FREAD_C) break;
starting_phase=shift_addition_cc((complexf*)input_buffer, (complexf*)output_buffer, BUFSIZE, data, starting_phase);
FWRITE_C;
if(read_fifo_ctl(fd,"%g\n",&rate)) break;
}
}
return 0;
}
if(!strcmp(argv[1],"shift_addition_cc_test"))
{
if(argc<=2) return badsyntax("need required parameter (rate)");
float rate;
sscanf(argv[2],"%g",&rate);
shift_addition_data_t data=shift_addition_init(rate);
shift_addition_cc_test(data);
return 0;
}
#endif
if(!strcmp(argv[1],"dcblock_ff"))
{
static dcblock_preserve_t dcp; //will be 0 as .bss is set to 0
for(;;)
{
FEOF_CHECK;
FREAD_R;
dcp=dcblock_ff(input_buffer, output_buffer, BUFSIZE, 0, dcp);
FWRITE_R;
}
}
if(!strcmp(argv[1],"fastdcblock_ff"))
{
int dcblock_bufsize=BUFSIZE;
if(argc>=3) sscanf(argv[2],"%d",&dcblock_bufsize);
float* dcblock_buffer=(float*)malloc(sizeof(float)*dcblock_bufsize);
static float last_dc_level=0.0;
for(;;)
{
FEOF_CHECK;
fread(dcblock_buffer, sizeof(float), dcblock_bufsize, stdin);
last_dc_level=fastdcblock_ff(dcblock_buffer, dcblock_buffer, dcblock_bufsize, last_dc_level);
fwrite(dcblock_buffer, sizeof(float), dcblock_bufsize, stdout);
}
}
if(!strcmp(argv[1],"fmdemod_atan_cf"))
{
float last_phase=0;
for(;;)
{
FEOF_CHECK;
FREAD_C;
if(feof(stdin)) return 0;
last_phase=fmdemod_atan_cf((complexf*)input_buffer, output_buffer, BUFSIZE, last_phase);
FWRITE_R;
}
}
if(!strcmp(argv[1],"fmdemod_quadri_cf"))
{
complexf last_sample;
last_sample.i=0.;
last_sample.q=0.;
for(;;)
{
FEOF_CHECK;
FREAD_C;
last_sample=fmdemod_quadri_cf((complexf*)input_buffer, output_buffer, BUFSIZE, temp_f, last_sample);
FWRITE_R;
}
}
if(!strcmp(argv[1],"fmdemod_quadri_novect_cf"))
{
complexf last_sample;
last_sample.i=0.;
last_sample.q=0.;
for(;;)
{
FEOF_CHECK;
FREAD_C;
last_sample=fmdemod_quadri_novect_cf((complexf*)input_buffer, output_buffer, BUFSIZE, last_sample);
FWRITE_R;
}
}
if(!strcmp(argv[1],"deemphasis_wfm_ff"))
{
if(argc<=3) return badsyntax("need required parameters (sample rate, tau)");
int sample_rate;
sscanf(argv[2],"%d",&sample_rate);
float tau;
sscanf(argv[3],"%g",&tau);
fprintf(stderr,"deemphasis_wfm_ff: tau = %g, sample_rate = %d\n",tau,sample_rate);
float last_output=0;
for(;;)
{
FEOF_CHECK;
FREAD_R;
last_output=deemphasis_wfm_ff(input_buffer, output_buffer, BUFSIZE, tau, sample_rate, last_output);
FWRITE_R;
}
}
if(!strcmp(argv[1],"deemphasis_nfm_ff"))
{
if(argc<=2) return badsyntax("need required parameter (sample rate)");
int sample_rate;
sscanf(argv[2],"%d",&sample_rate);
int processed=0;
for(;;)
{
FEOF_CHECK;
fread(input_buffer+BUFSIZE-processed, sizeof(float), processed, stdin);
processed=deemphasis_nfm_ff(input_buffer, output_buffer, BUFSIZE, sample_rate);
memmove(input_buffer,input_buffer+processed,(BUFSIZE-processed)*sizeof(float)); //memmove lets the source and destination overlap
fwrite(output_buffer, sizeof(float), processed, stdout);
}
}
if(!strcmp(argv[1],"amdemod_cf"))
{
for(;;)
{
FEOF_CHECK;
FREAD_C;
amdemod_cf((complexf*)input_buffer, output_buffer, BUFSIZE);
FWRITE_R;
}
}
if(!strcmp(argv[1],"amdemod_estimator_cf"))
{
for(;;)
{
FEOF_CHECK;
FREAD_C;
amdemod_estimator_cf((complexf*)input_buffer, output_buffer, BUFSIZE, 0., 0.);
FWRITE_R;
}
}
if(!strcmp(argv[1],"fir_decimate_cc"))
{
if(argc<=2) return badsyntax("need required parameter (decimation factor)");
int factor;
sscanf(argv[2],"%d",&factor);
float transition_bw = 0.05;
if(argc>=4) sscanf(argv[3],"%g",&transition_bw);
window_t window = WINDOW_DEFAULT;
if(argc>=5)
{
window=firdes_get_window_from_string(argv[4]);
}
else fprintf(stderr,"fir_decimate_cc: window = %s\n",firdes_get_string_from_window(window));
int taps_length=firdes_filter_len(transition_bw);
fprintf(stderr,"fir_decimate_cc: taps_length = %d\n",taps_length);
float *taps=(float*)malloc(taps_length*sizeof(float));
firdes_lowpass_f(taps,taps_length,0.5/(float)factor,window);
int input_skip=0;
int output_size=0;
FREAD_C;
for(;;)
{
FEOF_CHECK;
output_size=fir_decimate_cc((complexf*)input_buffer, (complexf*)output_buffer, BUFSIZE, factor, taps, taps_length);
fwrite(output_buffer, sizeof(complexf), output_size, stdout);
fflush(stdout);
input_skip=factor*output_size;
memmove((complexf*)input_buffer,((complexf*)input_buffer)+input_skip,(BUFSIZE-input_skip)*sizeof(complexf)); //memmove lets the source and destination overlap
fread(((complexf*)input_buffer)+(BUFSIZE-input_skip), sizeof(complexf), input_skip, stdin);
//fprintf(stderr,"iskip=%d output_size=%d start=%x target=%x skipcount=%x \n",input_skip,output_size,input_buffer, ((complexf*)input_buffer)+(BUFSIZE-input_skip),(BUFSIZE-input_skip));
}
}
/*if(!strcmp(argv[1],"ejw_test"))
{
printf("ejqd=[");
complexf ejw;
float phase=0;
for(int i=0;i<63;i++)
{
e_powj(&ejw,phase);
phase+=PI*0.3;
printf("%g+(%g)*i ",iof(&ejw,0),qof(&ejw,0));
}
printf("];");
return 0;
}*/
if(!strcmp(argv[1],"firdes_lowpass_f"))
{
//Process the params
if(argc<=3) return badsyntax("need required parameters (cutoff_rate, length)");
float cutoff_rate;
sscanf(argv[2],"%g",&cutoff_rate);
int length;
sscanf(argv[3],"%d",&length);
if(length%2==0) return badsyntax("number of symmetric FIR filter taps should be odd");
window_t window = WINDOW_DEFAULT;
if(argc>=5)
{
window=firdes_get_window_from_string(argv[4]);
}
else fprintf(stderr,"firdes_lowpass_f: window = %s\n",firdes_get_string_from_window(window));
int octave=(argc>=6 && !strcmp("--octave",argv[5]));
float* taps=(float*)malloc(sizeof(float)*length);
//Make the filter
firdes_lowpass_f(taps,length,cutoff_rate,window);
//Do the output
if(octave) printf("taps=[");
for(int i=0;i<length;i++) printf("%f ",taps[i]);
if(octave) printf("];plot(taps);figure(2);freqz(taps);\n");
//Wait forever, so that octave won't close just after popping up the window.
//You can close it with ^C.
if(octave) { fflush(stdout); getchar(); }
return 0;
}
if(!strcmp(argv[1],"firdes_bandpass_c"))
{
//Process the params
if(argc<=4) return badsyntax("need required parameters (low_cut, high_cut, length)");
float low_cut;
sscanf(argv[2],"%g",&low_cut);
float high_cut;
sscanf(argv[3],"%g",&high_cut);
int length;
sscanf(argv[4],"%d",&length);
if(length%2==0) return badsyntax("number of symmetric FIR filter taps should be odd");
window_t window = WINDOW_DEFAULT;
if(argc>=6)
{
window=firdes_get_window_from_string(argv[5]);
}
else fprintf(stderr,"firdes_bandpass_c: window = %s\n",firdes_get_string_from_window(window));
int octave=(argc>=7 && !strcmp("--octave",argv[6]));
complexf* taps=(complexf*)malloc(sizeof(complexf)*length);
//Make the filter
firdes_bandpass_c(taps, length, low_cut, high_cut, window);
//Do the output
if(octave) printf("taps=[");
for(int i=0;i<length;i++) printf("(%g)+(%g)*i ",iof(taps,i),qof(taps,i));
int fft_length=1024;
while(fft_length<length) fft_length*=2;
//if(octave) printf("];\n");
if(octave) printf(
"];figure(\"Position\",[0 0 1000 1000]);fser=fft([taps,zeros(1,%d)]);ampl=abs(fser).^2;halfindex=floor(1+size(ampl)(2)/2);\n"
"amplrev=[ampl(halfindex:end),ampl(1:halfindex)];\n" //we have to swap the output of FFT
"subplot(2,1,1);plot(amplrev);\n"
"subplot(2,1,2);plot(arg(fser));\n"
"#figure(2);freqz(taps);\n"
"#figur(3);plot3(taps);\n",fft_length-length);
//Wait forever, so that octave won't close just after popping up the window.
//You can close it with ^C.
if(octave) { fflush(stdout); getchar(); }
return 0;
}
#ifdef LIBCSDR_GPL
if(!strcmp(argv[1],"agc_ff"))
{
//Process the params
//Explanation of what these actually do is in the DSP source.
//These good default values are for SSB sampled at 48000 kHz.
short hang_time=200;
if(argc>=3) sscanf(argv[2],"%hd",&hang_time);
float reference=0.5;
if(argc>=4) sscanf(argv[3],"%g",&reference);
float attack_rate=0.01;
if(argc>=5) sscanf(argv[4],"%g",&attack_rate);
float decay_rate=0.0001;
if(argc>=6) sscanf(argv[5],"%g",&decay_rate);
float max_gain=65536;
if(argc>=7) sscanf(argv[6],"%g",&max_gain);
short attack_wait=0;
if(argc>=8) sscanf(argv[7],"%hd",&attack_wait);
float filter_alpha=0.999;//0.001;
if(argc>=9) sscanf(argv[8],"%g",&filter_alpha);
float last_gain=1.0;
for(;;)
{
FEOF_CHECK;
FREAD_R;
last_gain=agc_ff(input_buffer, output_buffer, BUFSIZE, reference, attack_rate, decay_rate, max_gain, hang_time, attack_wait, filter_alpha, last_gain);
FWRITE_R;
}
}
#endif
if(!strcmp(argv[1],"fastagc_ff"))
{
static fastagc_ff_t input; //is in .bss and gets cleared to zero before main()
input.input_size=1024;
if(argc>=3) sscanf(argv[2],"%d",&input.input_size);
input.reference=1.0;
if(argc>=4) sscanf(argv[3],"%g",&input.reference);
input.buffer_1=(float*)calloc(input.input_size,sizeof(float));
input.buffer_2=(float*)calloc(input.input_size,sizeof(float));
input.buffer_input=(float*)malloc(sizeof(float)*input.input_size);
float* agc_output_buffer=(float*)malloc(sizeof(float)*input.input_size);
for(;;)
{
FEOF_CHECK;
fread(input.buffer_input, sizeof(float), input.input_size, stdin);
fastagc_ff(&input, agc_output_buffer);
fwrite(agc_output_buffer, sizeof(float), input.input_size, stdout);
}
}
int suboptimal;
if( (suboptimal=!strcmp(argv[1],"suboptimal_rational_resampler_ff"))||(!strcmp(argv[1],"rational_resampler_ff")) )
{
//last@2014-11-06: ./docompile; ./csdr yes_f 1.0 | ./csdr suboptimal_rational_resampler_ff 5 2
//Process the params
if(argc<=3) return badsyntax("need required parameters (interpolation, decimation)");
int interpolation;
sscanf(argv[2],"%d",&interpolation);
int decimation;
sscanf(argv[3],"%d",&decimation);
float transition_bw=0.05;
if(argc>=5) sscanf(argv[4],"%g",&transition_bw);
window_t window = WINDOW_DEFAULT;
if(argc>=6)
{
window=firdes_get_window_from_string(argv[5]);
}
else fprintf(stderr,"rational_resampler_ff: window = %s\n",firdes_get_string_from_window(window));
if(suboptimal) fprintf(stderr,"note: suboptimal rational resampler chosen.\n");
if(decimation==1&&interpolation==1) clone(); //copy input to output in this special case (and stick in this function).
//Alloc output buffer
int resampler_output_buffer_size=(BUFSIZE*interpolation)/decimation;
float* resampler_output_buffer=(float*)malloc(sizeof(float)*resampler_output_buffer_size);
float* suboptimal_resampler_temp_buffer = (suboptimal)?(float*)malloc(sizeof(float)*BUFSIZE*interpolation):NULL;
//Generate filter taps
int taps_length = firdes_filter_len(transition_bw);
float* taps = (float*)malloc(sizeof(float)*taps_length);
rational_resampler_get_lowpass_f(taps, taps_length, interpolation, decimation, window);
static rational_resampler_ff_t d; //in .bss => initialized to zero
for(;;)
{
FEOF_CHECK;
if(d.input_processed==0) d.input_processed=BUFSIZE;
else memcpy(input_buffer, input_buffer+d.input_processed, sizeof(float)*(BUFSIZE-d.input_processed));
fread(input_buffer+(BUFSIZE-d.input_processed), sizeof(float), d.input_processed, stdin);
//if(suboptimal) d=suboptimal_rational_resampler_ff(input_buffer, resampler_output_buffer, BUFSIZE, interpolation, decimation, taps, taps_length, suboptimal_resampler_temp_buffer); else
d=rational_resampler_ff(input_buffer, resampler_output_buffer, BUFSIZE, interpolation, decimation, taps, taps_length, d.last_taps_delay);
//fprintf(stderr,"resampled %d %d, %d\n",d.output_size, d.input_processed, d.input_processed);
fwrite(resampler_output_buffer, sizeof(float), d.output_size, stdout);
}
}
if(!strcmp(argv[1],"fractional_decimator_ff"))
{
//Process the params
if(argc<=2) return badsyntax("need required parameters (rate)");
float rate;
sscanf(argv[2],"%g",&rate);
float transition_bw=0.03;
if(argc>=4) sscanf(argv[3],"%g",&transition_bw);
window_t window = WINDOW_DEFAULT;
if(argc>=5)
{
window = firdes_get_window_from_string(argv[4]);
}
else fprintf(stderr,"fractional_decimator_ff: window = %s\n",firdes_get_string_from_window(window));
if(rate==1) clone(); //copy input to output in this special case (and stick in this function).
//Generate filter taps
int taps_length = firdes_filter_len(transition_bw);
fprintf(stderr,"fractional_decimator_ff: taps_length = %d\n",taps_length);
float* taps = (float*)malloc(sizeof(float)*taps_length);
firdes_lowpass_f(taps, taps_length, 0.59*0.5/(rate-transition_bw), window); //0.6 const to compensate rolloff
//for(int=0;i<taps_length; i++) fprintf(stderr,"%g ",taps[i]);
static fractional_decimator_ff_t d; //in .bss => initialized to zero
for(;;)
{
FEOF_CHECK;
if(d.input_processed==0) d.input_processed=BUFSIZE;
else memcpy(input_buffer, input_buffer+d.input_processed, sizeof(float)*(BUFSIZE-d.input_processed));
fread(input_buffer+(BUFSIZE-d.input_processed), sizeof(float), d.input_processed, stdin);
d = fractional_decimator_ff(input_buffer, output_buffer, BUFSIZE, rate, taps, taps_length, d);
fwrite(output_buffer, sizeof(float), d.output_size, stdout);
}
}
if(!strcmp(argv[1],"fft_cc"))
{
if(argc<=3) return badsyntax("need required parameters (fft_size, out_of_every_n_samples)");
int fft_size;
sscanf(argv[2],"%d",&fft_size);
if(log2n(fft_size)==-1) return badsyntax("fft_size should be power of 2");
int every_n_samples;
sscanf(argv[3],"%d",&every_n_samples);
int benchmark=0;
int octave=0;
window_t window = WINDOW_DEFAULT;
if(argc>=5)
{
window=firdes_get_window_from_string(argv[4]);
}
if(argc>=6)
{
benchmark|=!strcmp("--benchmark",argv[5]);
octave|=!strcmp("--octave",argv[5]);
}
if(argc>=7)
{
benchmark|=!strcmp("--benchmark",argv[6]);
octave|=!strcmp("--octave",argv[6]);
}
//make FFT plan
complexf* input=(complexf*)fft_malloc(sizeof(complexf)*fft_size);
complexf* windowed=(complexf*)fft_malloc(sizeof(complexf)*fft_size);
complexf* output=(complexf*)fft_malloc(sizeof(complexf)*fft_size);
if(benchmark) fprintf(stderr,"fft_cc: benchmarking...");
FFT_PLAN_T* plan=make_fft_c2c(fft_size, windowed, output, 1, benchmark);
if(benchmark) fprintf(stderr," done\n");
if(octave) printf("setenv(\"GNUTERM\",\"X11 noraise\");y=zeros(1,%d);semilogy(y,\"ydatasource\",\"y\");\n",fft_size);
for(;;)
{
FEOF_CHECK;
if(every_n_samples>fft_size)
{
fread(input, sizeof(complexf), fft_size, stdin);
//skipping samples before next FFT (but fseek doesn't work for pipes)
for(int seek_remain=every_n_samples-fft_size;seek_remain>0;seek_remain-=BUFSIZE)
{
fread(temp_f, sizeof(complexf), MIN_M(BUFSIZE,seek_remain), stdin);
}
}
else
{
//overlapped FFT
for(int i=0;i<fft_size-every_n_samples;i++) input[i]=input[i+every_n_samples];
fread(input+fft_size-every_n_samples, sizeof(complexf), every_n_samples, stdin);
}
apply_window_c(input,windowed,fft_size,window);
fft_execute(plan);
if(octave)
{
printf("fftdata=[");
//we have to swap the two parts of the array to get a valid spectrum
for(int i=fft_size/2;i<fft_size;i++) printf("(%g)+(%g)*i ",iof(output,i),qof(output,i));
for(int i=0;i<fft_size/2;i++) printf("(%g)+(%g)*i ",iof(output,i),qof(output,i));
printf(
"];\n"
"y=abs(fftdata);\n"
"refreshdata;\n"
);
}
else fwrite(output, sizeof(complexf), fft_size, stdout);
}
}
#define LOGPOWERCF_BUFSIZE 64
if(!strcmp(argv[1],"logpower_cf"))
{
float add_db=0;
if(argc>=3) sscanf(argv[2],"%g",&add_db);
for(;;)
{
FEOF_CHECK;
fread(input_buffer, sizeof(complexf), LOGPOWERCF_BUFSIZE, stdin);
logpower_cf((complexf*)input_buffer,output_buffer,LOGPOWERCF_BUFSIZE,add_db);
fwrite(output_buffer, sizeof(float), LOGPOWERCF_BUFSIZE, stdout);
}
}
#define TIME_TAKEN(start,end) ((end.tv_sec-start.tv_sec)+(end.tv_nsec-start.tv_nsec)/1e9)
if(!strcmp(argv[1],"fft_benchmark"))
{
if(argc<=3) return badsyntax("need required parameters (fft_size, fft_cycles)");
int fft_size;
sscanf(argv[2],"%d",&fft_size);
int fft_cycles;
sscanf(argv[3],"%d",&fft_cycles);
int benchmark=(argc>=5)&&!strcmp(argv[4],"--benchmark");
fprintf(stderr,"fft_benchmark: FFT library used: %s\n",FFT_LIBRARY_USED);
complexf* input=(complexf*)fft_malloc(sizeof(complexf)*fft_size);
complexf* output=(complexf*)fft_malloc(sizeof(complexf)*fft_size);
//fill input with random data
srand(time(NULL));
for(int i=0;i<fft_size;i++)
{
iof(input,i)=rand()/(float)INT_MAX;
qof(input,i)=rand()/(float)INT_MAX;
}
//initialize FFT library, and measure time
fprintf(stderr,"fft_benchmark: initializing... ");
struct timespec start_time, end_time;
clock_gettime(CLOCK_MONOTONIC_RAW, &start_time);
FFT_PLAN_T* plan=make_fft_c2c(fft_size,input,output,1,benchmark);
clock_gettime(CLOCK_MONOTONIC_RAW, &end_time);
fprintf(stderr,"done in %g seconds.\n",TIME_TAKEN(start_time,end_time));
//do the actual measurement about the FFT
clock_gettime(CLOCK_MONOTONIC_RAW, &start_time);
for(int i=0;i<fft_cycles;i++) fft_execute(plan);
clock_gettime(CLOCK_MONOTONIC_RAW, &end_time);
float time_taken_fft = TIME_TAKEN(start_time,end_time);
fprintf(stderr,"fft_benchmark: %d transforms of %d processed in %g seconds, %g seconds each.\n",fft_cycles,fft_size,time_taken_fft,time_taken_fft/fft_cycles);
return 0;
}
if(!strcmp(argv[1],"bandpass_fir_fft_cc")) //this command does not exist as a separate function
{
float low_cut;
float high_cut;
float transition_bw;
window_t window = WINDOW_DEFAULT;
char window_string[100]; //TODO: nice buffer overflow opportunity
int fd;
if(fd=init_fifo(argc,argv))
{
while(!read_fifo_ctl(fd,"%g %g\n",&low_cut,&high_cut)) usleep(10000);
if(argc<=4) return badsyntax("need more required parameters (transition_bw)");
}
else
{
if(argc<=4) return badsyntax("need required parameters (low_cut, high_cut, transition_bw)");
sscanf(argv[2],"%g",&low_cut);
sscanf(argv[3],"%g",&high_cut);
}
sscanf(argv[4],"%g",&transition_bw);
if(argc>=6) window=firdes_get_window_from_string(argv[5]);
else fprintf(stderr,"bandpass_fir_fft_cc: window = %s\n",firdes_get_string_from_window(window));
//calculate the FFT size and the other length parameters
int taps_length=firdes_filter_len(transition_bw); //the number of non-zero taps
int fft_size=next_pow2(taps_length); //we will have to pad the taps with zeros until the next power of 2 for FFT
//the number of padding zeros is the number of output samples we will be able to take away after every processing step, and it looks sane to check if it is large enough.
if (fft_size-taps_length<200) fft_size<<=1;
int input_size = fft_size - taps_length + 1;
int overlap_length = taps_length - 1;
fprintf(stderr,"bandpass_fir_fft_cc: (fft_size = %d) = (taps_length = %d) + (input_size = %d) - 1\n(overlap_length = %d) = taps_length - 1\n", fft_size, taps_length, input_size, overlap_length);
if (fft_size<=2) return badsyntax("FFT size error.");
//prepare making the filter and doing FFT on it
complexf* taps=(complexf*)calloc(sizeof(complexf),fft_size); //initialize to zero
complexf* taps_fft=(complexf*)malloc(sizeof(complexf)*fft_size);
FFT_PLAN_T* plan_taps = make_fft_c2c(fft_size, taps, taps_fft, 1, 0); //forward, don't benchmark (we need this only once)
//make FFT plans for continously processing the input
complexf* input = fft_malloc(fft_size*sizeof(complexf));
complexf* input_fourier = fft_malloc(fft_size*sizeof(complexf));
FFT_PLAN_T* plan_forward = make_fft_c2c(fft_size, input, input_fourier, 1, 1); //forward, do benchmark
complexf* output_fourier = fft_malloc(fft_size*sizeof(complexf));
complexf* output_1 = fft_malloc(fft_size*sizeof(complexf));
complexf* output_2 = fft_malloc(fft_size*sizeof(complexf));
//we create 2x output buffers so that one will preserve the previous overlap:
FFT_PLAN_T* plan_inverse_1 = make_fft_c2c(fft_size, output_fourier, output_1, 0, 1); //inverse, do benchmark
FFT_PLAN_T* plan_inverse_2 = make_fft_c2c(fft_size, output_fourier, output_2, 0, 1);
//we initialize this buffer to 0 as it will be taken as the overlap source for the first time:
for(int i=0;i<fft_size;i++) iof(plan_inverse_2->output,i)=qof(plan_inverse_2->output,i)=0;
for(int i=input_size;i<fft_size;i++) iof(input,i)=qof(input,i)=0; //we pre-pad the input buffer with zeros
for(;;)
{
//make the filter
fprintf(stderr,"bandpass_fir_fft_cc: filter initialized, low_cut = %g, high_cut = %g\n",low_cut,high_cut);
firdes_bandpass_c(taps, taps_length, low_cut, high_cut, window);
fft_execute(plan_taps);
for(int odd=0;;odd=!odd) //the processing loop
{
FEOF_CHECK;
fread(input, sizeof(complexf), input_size, stdin);
FFT_PLAN_T* plan_inverse = (odd)?plan_inverse_2:plan_inverse_1;
FFT_PLAN_T* plan_contains_last_overlap = (odd)?plan_inverse_1:plan_inverse_2; //the other
complexf* last_overlap = (complexf*)plan_contains_last_overlap->output + input_size; //+ fft_size - overlap_length;
apply_fir_fft_cc (plan_forward, plan_inverse, taps_fft, last_overlap, overlap_length);
int returned=fwrite(plan_inverse->output, sizeof(complexf), input_size, stdout);
if(read_fifo_ctl(fd,"%g %g\n",&low_cut,&high_cut)) break;
}
}
}
if(!strcmp(argv[1],"none"))
{
return 0;
}
return badsyntax("function name given in argument 1 does not exist.");
}

47
fft_fftw.c Normal file
View file

@ -0,0 +1,47 @@
#ifdef USE_FFTW
#include "fft_fftw.h"
#include <stdlib.h>
FFT_PLAN_T* make_fft_c2c(int size, complexf* input, complexf* output, int forward, int benchmark)
{
FFT_PLAN_T* plan=(FFT_PLAN_T*)malloc(sizeof(FFT_PLAN_T));
plan->plan = fftwf_plan_dft_1d(size, (fftwf_complex*)input, (fftwf_complex*)output, (forward)?FFTW_FORWARD:FFTW_BACKWARD, (benchmark)?FFTW_MEASURE:FFTW_ESTIMATE);
plan->size=size;
plan->input=(void*)input;
plan->output=(void*)output;
return plan;
}
FFT_PLAN_T* make_fft_r2c(int size, float* input, complexf* output, int benchmark) //always forward DFT
{
FFT_PLAN_T* plan=(FFT_PLAN_T*)malloc(sizeof(FFT_PLAN_T));
plan->plan = fftwf_plan_dft_r2c_1d(size, input, (fftwf_complex*)output, (benchmark)?FFTW_MEASURE:FFTW_ESTIMATE);
plan->size=size;
plan->input=(void*)input;
plan->output=(void*)output;
return plan;
}
FFT_PLAN_T* make_fft_c2r(int size, complexf* input, float* output, int benchmark) //always backward DFT
{
FFT_PLAN_T* plan=(FFT_PLAN_T*)malloc(sizeof(FFT_PLAN_T));
plan->plan = fftwf_plan_dft_c2r_1d(size, (fftwf_complex*)input, output, (benchmark)?FFTW_MEASURE:FFTW_ESTIMATE);
plan->size=size;
plan->input=(void*)input;
plan->output=(void*)output;
return plan;
}
void fft_execute(FFT_PLAN_T* plan)
{
fftwf_execute(plan->plan);
}
void fft_destroy(FFT_PLAN_T* plan)
{
fftwf_destroy_plan(plan->plan);
free(plan);
}
#endif

28
fft_fftw.h Normal file
View file

@ -0,0 +1,28 @@
#pragma once
#ifdef USE_FFTW
//http://www.fftw.org/doc/Complex-One_002dDimensional-DFTs.html
//http://www.fftw.org/doc/Precision.html
#include <fftw3.h>
#define FFT_LIBRARY_USED "fftw3"
#define FFT_PLAN_T struct fft_plan_s
#define fft_malloc fftwf_malloc
#define fft_free fftwf_free
struct fft_plan_s
{
int size;
void* input;
void* output;
fftwf_plan plan;
};
#include "libcsdr.h"
FFT_PLAN_T* make_fft_c2c(int size, complexf* input, complexf* output, int forward, int benchmark);
void fft_execute(FFT_PLAN_T* plan);
void fft_destroy(FFT_PLAN_T* plan);
#endif

21
fft_rpi.c Normal file
View file

@ -0,0 +1,21 @@
#ifdef USE_RPI_FFT
//I had an idea to use the GPU based FFT on Raspberry Pi boards.
//It would speed up filtering and spectrum display.
//However, this feature is not implemented yet. I've just started to work on it.
FFT_PLAN_T* make_fft_c(int size, complexf* input, complexf* output, int forward, int benchmark)
{
int hmailbox = mbox_open();
int returned = gpu_fft_prepare(hmailbox, log2N, (forward)?GPU_FFT_FWD:GPU_FFT_REV, jobs, &fft);
}
void fft_execute(FFT_PLAN_T* plan)
{
}
void fft_destroy(FFT_PLAN_T* plan)
{
}
#endif

11
fft_rpi.h Normal file
View file

@ -0,0 +1,11 @@
#pragma once
#ifdef USE_RPI_FFT
#include "mailbox.h"
#include "gpu_fft.h"
#define FFT_PLAN_T (struct GPU_FFT)
//reference: https://github.com/raspberrypi/userland/blob/master/host_applications/linux/apps/hello_pi/hello_fft/hello_fft.c
#endif

593
grc_tests/test_agc_gen.grc Normal file
View file

@ -0,0 +1,593 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Sat Nov 15 19:16:25 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>48000</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(184, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>waveform</key>
<value>analog.GR_SQR_WAVE</value>
</param>
<param>
<key>freq</key>
<value>1</value>
</param>
<param>
<key>amp</key>
<value>0.9</value>
</param>
<param>
<key>offset</key>
<value>0.1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(152, 131)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
<param>
<key>commandline</key>
<value>csdr agc_ff</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(864, 323)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(688, 283)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_multiply_xx</key>
<param>
<key>id</key>
<value>blocks_multiply_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>num_inputs</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(440, 256)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_add_xx</key>
<param>
<key>id</key>
<value>blocks_add_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>num_inputs</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(576, 304)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>waveform</key>
<value>analog.GR_COS_WAVE</value>
</param>
<param>
<key>freq</key>
<value>5000</value>
</param>
<param>
<key>amp</key>
<value>1</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(48, 251)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Scope Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0.3</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0.1</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>3</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(1048, 128)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_vector_source_x</key>
<param>
<key>id</key>
<value>blocks_vector_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>vector</key>
<value>[1]*8+[0,]*(samp_rate/15)</value>
</param>
<param>
<key>tags</key>
<value>[]</value>
</param>
<param>
<key>repeat</key>
<value>True</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(288, 379)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>analog_sig_source_x_0_0</source_block_id>
<sink_block_id>blocks_multiply_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_sig_source_x_0_0</source_block_id>
<sink_block_id>wxgui_scopesink2_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>2</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</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_multiply_xx_0</source_block_id>
<sink_block_id>blocks_add_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_add_xx_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_add_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>analog_sig_source_x_0</source_block_id>
<sink_block_id>blocks_multiply_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
</flow_graph>

View file

@ -0,0 +1,11 @@
#!/bin/bash
echo \"agctest\" signal was made by SM5BSZ.
echo downloading...
wget -O agctest-125.zip http://sm5bsz.com/lir/agctest/agctest-125.zip
echo unzipping...
unzip agctest-125.zip
echo converting wav to 48000 kHz Mono...
sox agctest-125.wav -r48000 -c1 agctest.wav
echo deleting temporary files...
rm agctest-125.zip
rm agctest-125.wav

519
grc_tests/test_agc_wav.grc Normal file
View file

@ -0,0 +1,519 @@
<?xml version='1.0' encoding='ASCII'?>
<flow_graph>
<timestamp>Sun Nov 16 15:12:31 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>48000</value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 170)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(1104, 403)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>band_reject_filter</key>
<param>
<key>id</key>
<value>band_reject_filter_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>fir_filter_fff</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>interp</key>
<value>1</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>low_cutoff_freq</key>
<value>1600</value>
</param>
<param>
<key>high_cutoff_freq</key>
<value>2000</value>
</param>
<param>
<key>width</key>
<value>50</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
<param>
<key>beta</key>
<value>6.76</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(392, 35)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_multiply_const_vxx</key>
<param>
<key>id</key>
<value>blocks_multiply_const_vxx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>const</key>
<value>0.2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(984, 219)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>audio_sink</key>
<param>
<key>id</key>
<value>audio_sink_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>device_name</key>
<value></value>
</param>
<param>
<key>ok_to_block</key>
<value>True</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(1152, 219)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
<param>
<key>commandline</key>
<value>csdr agc_ff</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(616, 283)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>low_pass_filter</key>
<param>
<key>id</key>
<value>low_pass_filter_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>fir_filter_fff</value>
</param>
<param>
<key>decim</key>
<value>1</value>
</param>
<param>
<key>interp</key>
<value>1</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>cutoff_freq</key>
<value>3000</value>
</param>
<param>
<key>width</key>
<value>50</value>
</param>
<param>
<key>win</key>
<value>firdes.WIN_HAMMING</value>
</param>
<param>
<key>beta</key>
<value>6.76</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(584, 43)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_wavfile_source</key>
<param>
<key>id</key>
<value>blocks_wavfile_source_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>file</key>
<value>/home/ha5kfu/Dokumentumok/ddcdemod/grc_tests/agctest.wav</value>
</param>
<param>
<key>repeat</key>
<value>True</value>
</param>
<param>
<key>nchan</key>
<value>1</value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(152, 163)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<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>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_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>ha5kfu_execproc_xx_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>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>ha5kfu_execproc_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

1435
grc_tests/test_amdemod.grc Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,785 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Sat Nov 22 11:19:26 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(24, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>24e3</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(184, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</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>
<param>
<key>freq</key>
<value>freq</value>
</param>
<param>
<key>amp</key>
<value>1</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(128, 83)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(312, 147)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable_slider</key>
<param>
<key>id</key>
<value>freq</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>1e3</value>
</param>
<param>
<key>min</key>
<value>-samp_rate/2</value>
</param>
<param>
<key>max</key>
<value>samp_rate/2</value>
</param>
<param>
<key>num_steps</key>
<value>100</value>
</param>
<param>
<key>style</key>
<value>wx.SL_HORIZONTAL</value>
</param>
<param>
<key>converver</key>
<value>float_converter</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 83)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>FFT Plot of original signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(504, 219)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>Scope Plot of original signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(504, 435)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>Scope Plot of new signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb1,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(784, 283)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>FFT Plot of new signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb1,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(784, 67)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['scope', 'fft']</value>
</param>
<param>
<key>grid_pos</key>
<value>1,1,1,1</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(272, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['scope', 'fft']</value>
</param>
<param>
<key>grid_pos</key>
<value>1,2,1,1</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(416, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
<param>
<key>commandline</key>
<value>csdr bandpass_fir_fft_cc 0.1 0.5 0.05 HAMMING</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(488, 147)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>analog_sig_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_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>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>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>blocks_throttle_0</source_block_id>
<sink_block_id>wxgui_scopesink2_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_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

View file

@ -0,0 +1,812 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Tue Nov 18 16:42:38 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(24, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>24e3</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(184, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</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>
<param>
<key>freq</key>
<value>freq</value>
</param>
<param>
<key>amp</key>
<value>1</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(128, 83)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(312, 147)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable_slider</key>
<param>
<key>id</key>
<value>freq</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>1e3</value>
</param>
<param>
<key>min</key>
<value>-samp_rate/2</value>
</param>
<param>
<key>max</key>
<value>samp_rate/2</value>
</param>
<param>
<key>num_steps</key>
<value>100</value>
</param>
<param>
<key>style</key>
<value>wx.SL_HORIZONTAL</value>
</param>
<param>
<key>converver</key>
<value>float_converter</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 83)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>FFT Plot of original signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(504, 219)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>Scope Plot of original signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(504, 435)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>Scope Plot of new signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb1,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(784, 283)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>FFT Plot of new signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb1,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(784, 67)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['scope', 'fft']</value>
</param>
<param>
<key>grid_pos</key>
<value>1,1,1,1</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(272, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['scope', 'fft']</value>
</param>
<param>
<key>grid_pos</key>
<value>1,2,1,1</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(416, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
<param>
<key>commandline</key>
<value>csdr bandpass_fir_fft_cc --fifo /tmp/csdr-fifo 0.05 HAMMING</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(488, 147)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>note</key>
<param>
<key>id</key>
<value>note_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>note</key>
<value>/tmp/csdr-fifo</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(968, 67)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>analog_sig_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_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>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>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>blocks_throttle_0</source_block_id>
<sink_block_id>wxgui_scopesink2_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_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

View file

@ -0,0 +1,846 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Sat Nov 15 20:02:09 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>32000</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(184, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>waveform</key>
<value>analog.GR_COS_WAVE</value>
</param>
<param>
<key>freq</key>
<value>frequency</value>
</param>
<param>
<key>amp</key>
<value>1</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(56, 139)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>FFT Plot (float -&gt; u8 -&gt; float conversion)</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>window.hamming</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb1,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(680, 579)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Scope Plot (float -&gt; u8 -&gt; float conversion)</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>2</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb1,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(680, 459)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(224, 171)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>FFT Plot (float -&gt; i16 -&gt; float conversion)</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(680, 251)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Scope Plot (float -&gt; i16 -&gt; float conversion)</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>2</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(680, 131)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['scope', 'fft']</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(536, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['scope', 'fft']</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(400, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable_slider</key>
<param>
<key>id</key>
<value>frequency</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>4e3</value>
</param>
<param>
<key>min</key>
<value>0</value>
</param>
<param>
<key>max</key>
<value>samp_rate/2</value>
</param>
<param>
<key>num_steps</key>
<value>100</value>
</param>
<param>
<key>style</key>
<value>wx.SL_HORIZONTAL</value>
</param>
<param>
<key>converver</key>
<value>float_converter</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(280, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
<param>
<key>commandline</key>
<value>csdr convert_f_i16 | csdr convert_i16_f</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(384, 171)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
<param>
<key>commandline</key>
<value>csdr convert_f_u8 | csdr convert_u8_f</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(384, 499)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>analog_sig_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_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_scopesink2_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>1</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>
<connection>
<source_block_id>ha5kfu_execproc_xx_0_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_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>wxgui_scopesink2_0_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

708
grc_tests/test_dcblock.grc Normal file
View file

@ -0,0 +1,708 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Sun Nov 23 19:16:09 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>250e3</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 170)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['dcblock_ff processed','fastdcblock_ff processed', 'original']</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(256, 27)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>512</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,2</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(592, 27)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>512</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,0</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(592, 259)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>512</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(592, 475)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(152, 211)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
<param>
<key>commandline</key>
<value>csdr fastdcblock_ff</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(336, 555)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
<param>
<key>commandline</key>
<value>csdr dcblock_ff</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(336, 331)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_add_const_vxx</key>
<param>
<key>id</key>
<value>blocks_add_const_vxx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>const</key>
<value>0.8</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(136, 291)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_noise_source_x</key>
<param>
<key>id</key>
<value>analog_noise_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>noise_type</key>
<value>analog.GR_GAUSSIAN</value>
</param>
<param>
<key>amp</key>
<value>0.1</value>
</param>
<param>
<key>seed</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(112, 379)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<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>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>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>analog_noise_source_x_0</source_block_id>
<sink_block_id>blocks_add_const_vxx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_add_const_vxx_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>ha5kfu_execproc_xx_0_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>blocks_throttle_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>
</flow_graph>

View file

@ -0,0 +1,491 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Tue Oct 14 22:43:27 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>48000</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 170)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>waveform</key>
<value>analog.GR_COS_WAVE</value>
</param>
<param>
<key>freq</key>
<value>5000</value>
</param>
<param>
<key>amp</key>
<value>1</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(32, 267)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>waveform</key>
<value>analog.GR_SQR_WAVE</value>
</param>
<param>
<key>freq</key>
<value>1</value>
</param>
<param>
<key>amp</key>
<value>0.9</value>
</param>
<param>
<key>offset</key>
<value>0.1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(152, 131)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(264, 299)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_multiply_xx</key>
<param>
<key>id</key>
<value>blocks_multiply_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>num_inputs</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(488, 256)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Scope Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0.3</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0.1</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>3</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(1048, 128)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_agc2_debug</key>
<param>
<key>id</key>
<value>ha5kfu_agc2_debug_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>attack_rate</key>
<value>0.100</value>
</param>
<param>
<key>decay_rate</key>
<value>0.01</value>
</param>
<param>
<key>ref</key>
<value>1</value>
</param>
<param>
<key>gain</key>
<value>1</value>
</param>
<param>
<key>max_gain</key>
<value>65536</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(712, 331)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>analog_sig_source_x_0_0</source_block_id>
<sink_block_id>blocks_multiply_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_sig_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_throttle_0</source_block_id>
<sink_block_id>blocks_multiply_xx_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>analog_sig_source_x_0_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>blocks_multiply_xx_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>blocks_multiply_xx_0</source_block_id>
<sink_block_id>ha5kfu_agc2_debug_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_agc2_debug_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>2</sink_key>
</connection>
</flow_graph>

View file

@ -0,0 +1,808 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Sat Nov 15 22:44:05 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(24, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>48000</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(184, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['scope', 'fft']</value>
</param>
<param>
<key>grid_pos</key>
<value>1,1,1,1</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(272, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['scope', 'fft']</value>
</param>
<param>
<key>grid_pos</key>
<value>1,2,1,1</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(416, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable_slider</key>
<param>
<key>id</key>
<value>freq</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>1e3</value>
</param>
<param>
<key>min</key>
<value>0</value>
</param>
<param>
<key>max</key>
<value>samp_rate/2</value>
</param>
<param>
<key>num_steps</key>
<value>100</value>
</param>
<param>
<key>style</key>
<value>wx.SL_HORIZONTAL</value>
</param>
<param>
<key>converver</key>
<value>float_converter</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 83)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>FFT Plot of new signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb1,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(784, 67)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Scope Plot of new signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb1,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(784, 283)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>FFT Plot of original signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(504, 219)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Scope Plot of original signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(504, 435)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
<param>
<key>commandline</key>
<value>"csdr deemphasis_nfm_ff %d"%samp_rate</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(488, 147)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(312, 147)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_fastnoise_source_x</key>
<param>
<key>id</key>
<value>analog_fastnoise_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>noise_type</key>
<value>analog.GR_GAUSSIAN</value>
</param>
<param>
<key>amp</key>
<value>1</value>
</param>
<param>
<key>seed</key>
<value>0</value>
</param>
<param>
<key>samples</key>
<value>8192</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(120, 123)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>note</key>
<param>
<key>id</key>
<value>note_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>note</key>
<value>set Peak Hold on the FFT plot of new signal, so you will see the filter characteristics</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(784, 19)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<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>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>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>blocks_throttle_0</source_block_id>
<sink_block_id>wxgui_scopesink2_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_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_fastnoise_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>
</flow_graph>

View file

@ -0,0 +1,785 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Sat Nov 15 22:23:43 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(24, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>32e3</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(184, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['scope', 'fft']</value>
</param>
<param>
<key>grid_pos</key>
<value>1,1,1,1</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(272, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['scope', 'fft']</value>
</param>
<param>
<key>grid_pos</key>
<value>1,2,1,1</value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(416, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>waveform</key>
<value>analog.GR_COS_WAVE</value>
</param>
<param>
<key>freq</key>
<value>freq</value>
</param>
<param>
<key>amp</key>
<value>1</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(128, 83)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable_slider</key>
<param>
<key>id</key>
<value>freq</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>1e3</value>
</param>
<param>
<key>min</key>
<value>0</value>
</param>
<param>
<key>max</key>
<value>samp_rate/2</value>
</param>
<param>
<key>num_steps</key>
<value>100</value>
</param>
<param>
<key>style</key>
<value>wx.SL_HORIZONTAL</value>
</param>
<param>
<key>converver</key>
<value>float_converter</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(8, 83)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(312, 147)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>FFT Plot of new signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb1,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(784, 67)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Scope Plot of new signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb1,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(784, 283)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>FFT Plot of original signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(504, 219)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Scope Plot of original signal</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(504, 435)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>ff</value>
</param>
<param>
<key>commandline</key>
<value>"csdr deemphasis_wfm_ff %d 75e-6"%samp_rate</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(488, 147)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>analog_sig_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_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>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>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>blocks_throttle_0</source_block_id>
<sink_block_id>wxgui_scopesink2_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_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
</flow_graph>

520
grc_tests/test_fft_grc.grc Normal file
View file

@ -0,0 +1,520 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Sat Nov 15 20:04:47 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>32000</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 170)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</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_SIN_WAVE</value>
</param>
<param>
<key>freq</key>
<value>frequency</value>
</param>
<param>
<key>amp</key>
<value>1</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(56, 299)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(488, 75)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_complex_to_float</key>
<param>
<key>id</key>
<value>blocks_complex_to_float_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(464, 320)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_stream_mux</key>
<param>
<key>id</key>
<value>blocks_stream_mux_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>lengths</key>
<value>1, 1</value>
</param>
<param>
<key>num_inputs</key>
<value>2</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(632, 320)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(248, 331)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable_slider</key>
<param>
<key>id</key>
<value>frequency</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>label</key>
<value></value>
</param>
<param>
<key>value</key>
<value>1e3</value>
</param>
<param>
<key>min</key>
<value>-samp_rate/2</value>
</param>
<param>
<key>max</key>
<value>samp_rate/2</value>
</param>
<param>
<key>num_steps</key>
<value>100</value>
</param>
<param>
<key>style</key>
<value>wx.SL_HORIZONTAL</value>
</param>
<param>
<key>converver</key>
<value>float_converter</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(184, 11)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_sink_f</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_sink_f_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>commandline</key>
<value>csdr fft_cc 512 5120 HAMMING --octave | octave -i</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(808, 331)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>analog_sig_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_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>blocks_complex_to_float_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_stream_mux_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_stream_mux_0</sink_block_id>
<source_key>1</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>blocks_stream_mux_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>
</flow_graph>

719
grc_tests/test_fmdemod.grc Normal file
View file

@ -0,0 +1,719 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Sat Nov 15 20:06:19 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>250000</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(9, 170)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_waterfallsink2</key>
<param>
<key>id</key>
<value>wxgui_waterfallsink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>Waterfall Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>dynamic_range</key>
<value>100</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>512</value>
</param>
<param>
<key>fft_rate</key>
<value>500</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(713, 407)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_fm_demod_cf</key>
<param>
<key>id</key>
<value>analog_fm_demod_cf_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>chan_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>audio_decim</key>
<value>1</value>
</param>
<param>
<key>deviation</key>
<value>75000</value>
</param>
<param>
<key>audio_pass</key>
<value>15000</value>
</param>
<param>
<key>audio_stop</key>
<value>16000</value>
</param>
<param>
<key>gain</key>
<value>27</value>
</param>
<param>
<key>tau</key>
<value>75e-6</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(725, 248)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_frequency_modulator_fc</key>
<param>
<key>id</key>
<value>analog_frequency_modulator_fc_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>sensitivity</key>
<value>3.141592654</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(510, 403)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>title</key>
<value>Scope Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>5</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_AUTO</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(1117, 9)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_debug_minmax_f</key>
<param>
<key>id</key>
<value>ha5kfu_debug_minmax_f_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>samplecount</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(1056, 427)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>waveform</key>
<value>analog.GR_COS_WAVE</value>
</param>
<param>
<key>freq</key>
<value>1000</value>
</param>
<param>
<key>amp</key>
<value>0.2</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(224, 29)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>float</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate/5</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(684, 27)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>cf</value>
</param>
<param>
<key>commandline</key>
<value>csdr fmdemod_quadri_novect_cf</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(760, 723)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>cf</value>
</param>
<param>
<key>commandline</key>
<value>csdr fmdemod_quadri_cf</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(760, 667)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>cf</value>
</param>
<param>
<key>commandline</key>
<value>csdr fmdemod_atan_cf</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(760, 611)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>analog_frequency_modulator_fc_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_frequency_modulator_fc_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>analog_frequency_modulator_fc_0</source_block_id>
<sink_block_id>analog_fm_demod_cf_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_fm_demod_cf_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>1</sink_key>
</connection>
<connection>
<source_block_id>blocks_throttle_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>0</sink_key>
</connection>
<connection>
<source_block_id>analog_frequency_modulator_fc_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>analog_frequency_modulator_fc_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>analog_frequency_modulator_fc_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>ha5kfu_execproc_xx_0</source_block_id>
<sink_block_id>ha5kfu_debug_minmax_f_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>2</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>3</sink_key>
</connection>
<connection>
<source_block_id>ha5kfu_execproc_xx_0_1</source_block_id>
<sink_block_id>wxgui_scopesink2_0</sink_block_id>
<source_key>0</source_key>
<sink_key>4</sink_key>
</connection>
<connection>
<source_block_id>analog_sig_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>
</flow_graph>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

841
grc_tests/test_shift.grc Normal file
View file

@ -0,0 +1,841 @@
<?xml version='1.0' encoding='ASCII'?>
<?grc format='1' created='3.7.5'?>
<flow_graph>
<timestamp>Sat Nov 15 22:24:14 2014</timestamp>
<block>
<key>options</key>
<param>
<key>id</key>
<value>top_block</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>title</key>
<value></value>
</param>
<param>
<key>author</key>
<value></value>
</param>
<param>
<key>description</key>
<value></value>
</param>
<param>
<key>window_size</key>
<value>1280, 1024</value>
</param>
<param>
<key>generate_options</key>
<value>wx_gui</value>
</param>
<param>
<key>category</key>
<value>Custom</value>
</param>
<param>
<key>run_options</key>
<value>prompt</value>
</param>
<param>
<key>run</key>
<value>True</value>
</param>
<param>
<key>max_nouts</key>
<value>0</value>
</param>
<param>
<key>realtime_scheduling</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 10)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>variable</key>
<param>
<key>id</key>
<value>samp_rate</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>value</key>
<value>250e3</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(10, 170)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>analog_sig_source_x</key>
<param>
<key>id</key>
<value>analog_sig_source_x_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</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_CONST_WAVE</value>
</param>
<param>
<key>freq</key>
<value>20000</value>
</param>
<param>
<key>amp</key>
<value>1</value>
</param>
<param>
<key>offset</key>
<value>0</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(56, 243)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,0</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(952, 275)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>notebook</key>
<param>
<key>id</key>
<value>nb0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>style</key>
<value>wx.NB_TOP</value>
</param>
<param>
<key>labels</key>
<value>['shift_math_ff', 'shift_addition_ff', 'original']</value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value></value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(256, 27)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,2</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(952, 59)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_fftsink2</key>
<param>
<key>id</key>
<value>wxgui_fftsink2_0_1</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>FFT Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>baseband_freq</key>
<value>0</value>
</param>
<param>
<key>y_per_div</key>
<value>10</value>
</param>
<param>
<key>y_divs</key>
<value>10</value>
</param>
<param>
<key>ref_level</key>
<value>0</value>
</param>
<param>
<key>ref_scale</key>
<value>2.0</value>
</param>
<param>
<key>fft_size</key>
<value>1024</value>
</param>
<param>
<key>fft_rate</key>
<value>15</value>
</param>
<param>
<key>peak_hold</key>
<value>False</value>
</param>
<param>
<key>average</key>
<value>False</value>
</param>
<param>
<key>avg_alpha</key>
<value>0</value>
</param>
<param>
<key>win</key>
<value>None</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,1</value>
</param>
<param>
<key>freqvar</key>
<value>None</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(952, 635)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>blocks_throttle</key>
<param>
<key>id</key>
<value>blocks_throttle_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>samples_per_second</key>
<value>samp_rate</value>
</param>
<param>
<key>vlen</key>
<value>1</value>
</param>
<param>
<key>ignoretag</key>
<value>True</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(232, 275)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>Scope Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,0</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_NORM</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(952, 491)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>wxgui_scopesink2</key>
<param>
<key>id</key>
<value>wxgui_scopesink2_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>complex</value>
</param>
<param>
<key>title</key>
<value>Scope Plot</value>
</param>
<param>
<key>samp_rate</key>
<value>samp_rate</value>
</param>
<param>
<key>v_scale</key>
<value>0</value>
</param>
<param>
<key>v_offset</key>
<value>0</value>
</param>
<param>
<key>t_scale</key>
<value>0</value>
</param>
<param>
<key>ac_couple</key>
<value>False</value>
</param>
<param>
<key>xy_mode</key>
<value>False</value>
</param>
<param>
<key>num_inputs</key>
<value>1</value>
</param>
<param>
<key>win_size</key>
<value></value>
</param>
<param>
<key>grid_pos</key>
<value></value>
</param>
<param>
<key>notebook</key>
<value>nb0,1</value>
</param>
<param>
<key>trig_mode</key>
<value>wxgui.TRIG_MODE_NORM</value>
</param>
<param>
<key>y_axis_label</key>
<value>Counts</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>_coordinate</key>
<value>(952, 875)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
<param>
<key>commandline</key>
<value>csdr shift_math_cc -0.25</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(496, 483)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<block>
<key>ha5kfu_execproc_xx</key>
<param>
<key>id</key>
<value>ha5kfu_execproc_xx_0_0</value>
</param>
<param>
<key>_enabled</key>
<value>True</value>
</param>
<param>
<key>type</key>
<value>cc</value>
</param>
<param>
<key>commandline</key>
<value>csdr shift_addition_cc -0.25</value>
</param>
<param>
<key>alias</key>
<value></value>
</param>
<param>
<key>affinity</key>
<value></value>
</param>
<param>
<key>minoutbuf</key>
<value>0</value>
</param>
<param>
<key>maxoutbuf</key>
<value>0</value>
</param>
<param>
<key>_coordinate</key>
<value>(504, 635)</value>
</param>
<param>
<key>_rotation</key>
<value>0</value>
</param>
</block>
<connection>
<source_block_id>analog_sig_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_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_scopesink2_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>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>ha5kfu_execproc_xx_0_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>blocks_throttle_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>ha5kfu_execproc_xx_0_0</source_block_id>
<sink_block_id>wxgui_scopesink2_0_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

768
libcsdr.c Normal file
View file

@ -0,0 +1,768 @@
/*
This software is part of libcsdr, a set of simple DSP routines for
Software Defined Radio.
Copyright (c) 2014, Andras Retzler <randras@sdr.hu>
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 ANDRAS RETZLER 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.
*/
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include "libcsdr.h"
#include "predefined.h"
#include <assert.h>
/*
_ _ __ _ _
(_) | | / _| | | (_)
__ ___ _ __ __| | _____ __ | |_ _ _ _ __ ___| |_ _ ___ _ __ ___
\ \ /\ / / | '_ \ / _` |/ _ \ \ /\ / / | _| | | | '_ \ / __| __| |/ _ \| '_ \/ __|
\ V V /| | | | | (_| | (_) \ V V / | | | |_| | | | | (__| |_| | (_) | | | \__ \
\_/\_/ |_|_| |_|\__,_|\___/ \_/\_/ |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|___/
*/
#define MFIRDES_GWS(NAME) \
if(!strcmp( #NAME , input )) return WINDOW_ ## NAME;
window_t firdes_get_window_from_string(char* input)
{
MFIRDES_GWS(BOXCAR);
MFIRDES_GWS(BLACKMAN);
MFIRDES_GWS(HAMMING);
return WINDOW_DEFAULT;
}
#define MFIRDES_GSW(NAME) \
if(window == WINDOW_ ## NAME) return #NAME;
char* firdes_get_string_from_window(window_t window)
{
MFIRDES_GSW(BOXCAR);
MFIRDES_GSW(BLACKMAN);
MFIRDES_GSW(HAMMING);
return "INVALID";
}
float firdes_wkernel_blackman(float rate)
{
//Explanation at Chapter 16 of dspguide.com, page 2
//Blackman window has better stopband attentuation and passband ripple than Hamming, but it has slower rolloff.
rate=0.5+rate/2;
return 0.42-0.5*cos(2*PI*rate)+0.08*cos(4*PI*rate);
}
float firdes_wkernel_hamming(float rate)
{
//Explanation at Chapter 16 of dspguide.com, page 2
//Hamming window has worse stopband attentuation and passband ripple than Blackman, but it has faster rolloff.
rate=0.5+rate/2;
return 0.54-0.46*cos(2*PI*rate);
}
float firdes_wkernel_boxcar(float rate)
{ //"Dummy" window kernel, do not use; an unwindowed FIR filter may have bad frequency response
return 1.0;
}
float (*firdes_get_window_kernel(window_t window))(float)
{
if(window==WINDOW_HAMMING) return firdes_wkernel_hamming;
else if(window==WINDOW_BLACKMAN) return firdes_wkernel_blackman;
else if(window==WINDOW_BOXCAR) return firdes_wkernel_boxcar;
else return firdes_get_window_kernel(WINDOW_DEFAULT);
}
/*
______ _____ _____ __ _ _ _ _ _
| ____|_ _| __ \ / _(_) | | | | (_)
| |__ | | | |__) | | |_ _| | |_ ___ _ __ __| | ___ ___ _ __ _ _ __
| __| | | | _ / | _| | | __/ _ \ '__| / _` |/ _ \/ __| |/ _` | '_ \
| | _| |_| | \ \ | | | | | || __/ | | (_| | __/\__ \ | (_| | | | |
|_| |_____|_| \_\ |_| |_|_|\__\___|_| \__,_|\___||___/_|\__, |_| |_|
__/ |
|___/
*/
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
// cutoff_rate is (cutoff frequency/sampling frequency)
//Explanation at Chapter 16 of dspguide.com
int middle=length/2;
float temp;
float (*window_function)(float) = firdes_get_window_kernel(window);
output[middle]=2*PI*cutoff_rate*window_function(0);
for(int i=1; i<=middle; i++) //@@firdes_lowpass_f: calculate taps
{
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;
}
}
void firdes_bandpass_c(complexf *output, int length, float lowcut, float highcut, window_t window)
{
//To generate a complex filter:
// 1. we generate a real lowpass filter with a bandwidth of highcut-lowcut
// 2. we shift the filter taps spectrally by multiplying with e^(j*w), so we get complex taps
//(tnx HA5FT)
float* realtaps = (float*)malloc(sizeof(float)*length);
firdes_lowpass_f(realtaps, length, (highcut-lowcut)/2, window);
float filter_center=(highcut+lowcut)/2;
float phase=0, sinval, cosval;
for(int i=0; i<length; i++) //@@firdes_bandpass_c
{
cosval=cos(phase);
sinval=sin(phase);
phase+=2*PI*filter_center;
while(phase>2*PI) phase-=2*PI; //@@firdes_bandpass_c
while(phase<0) phase+=2*PI;
iof(output,i)=cosval*realtaps[i];
qof(output,i)=sinval*realtaps[i];
//output[i] := realtaps[i] * e^j*w
}
}
int firdes_filter_len(float rolloff)
{
int result=4.0/rolloff;
if (result%2==0) result++; //number of symmetric FIR filter taps should be odd
return result;
}
/*
_____ _____ _____ __ _ _
| __ \ / ____| __ \ / _| | | (_)
| | | | (___ | |__) | | |_ _ _ _ __ ___| |_ _ ___ _ __ ___
| | | |\___ \| ___/ | _| | | | '_ \ / __| __| |/ _ \| '_ \/ __|
| |__| |____) | | | | | |_| | | | | (__| |_| | (_) | | | \__ \
|_____/|_____/|_| |_| \__,_|_| |_|\___|\__|_|\___/|_| |_|___/
*/
float shift_math_cc(complexf *input, complexf* output, int input_size, float rate, float starting_phase)
{
rate*=2;
//Shifts the complex spectrum. Basically a complex mixer. This version uses cmath.
float phase=starting_phase;
float phase_increment=rate*PI;
float cosval, sinval;
for(int i=0;i<input_size; i++) //@shift_math_cc
{
cosval=cos(phase);
sinval=sin(phase);
//we multiply two complex numbers.
//how? enter this to maxima (software) for explanation:
// (a+b*%i)*(c+d*%i), rectform;
iof(output,i)=cosval*iof(input,i)-sinval*qof(input,i);
qof(output,i)=sinval*iof(input,i)+cosval*qof(input,i);
phase+=phase_increment;
while(phase>2*PI) phase-=2*PI; //@shift_math_cc: normalize phase
while(phase<0) phase+=2*PI;
}
return phase;
}
int fir_decimate_cc(complexf *input, complexf *output, int input_size, int decimation, float *taps, int taps_length)
{
//Theory: http://www.dspguru.com/dsp/faqs/multirate/decimation
//It uses real taps. It returns the number of output samples actually written.
//It needs overlapping input based on its returned value:
//number of processed input samples = returned value * decimation factor
//The output buffer should be at least input_length / 3.
// i: input index | ti: tap index | oi: output index
int oi=0;
for(int i=0; i<input_size; i+=decimation) //@fir_decimate_cc: outer loop
{
if(i+taps_length>input_size) break;
float acci=0;
for(int ti=0; ti<taps_length; ti++) acci += (iof(input,i+ti)) * taps[ti]; //@fir_decimate_cc: i loop
float accq=0;
for(int ti=0; ti<taps_length; ti++) accq += (qof(input,i+ti)) * taps[ti]; //@fir_decimate_cc: q loop
iof(output,oi)=acci;
qof(output,oi)=accq;
oi++;
}
return oi;
}
rational_resampler_ff_t rational_resampler_ff(float *input, float *output, int input_size, int interpolation, int decimation, float *taps, int taps_length, int last_taps_delay)
{
//Theory: http://www.dspguru.com/dsp/faqs/multirate/resampling
//oi: output index, i: tap index
int output_size=input_size*interpolation/decimation;
int oi;
int startingi, delayi;
//fprintf(stderr,"rational_resampler_ff | interpolation = %d | decimation = %d\ntaps_length = %d | input_size = %d | output_size = %d | last_taps_delay = %d\n",interpolation,decimation,taps_length,input_size,output_size,last_taps_delay);
for (oi=0; oi<output_size; oi++) //@rational_resampler_ff (outer loop)
{
float acc=0;
startingi=(oi*decimation+interpolation-1-last_taps_delay)/interpolation; //index of first input item to apply FIR on
//delayi=startingi*interpolation-oi*decimation; //delay on FIR taps
delayi=(last_taps_delay+startingi*interpolation-oi*decimation)%interpolation; //delay on FIR taps
if(startingi+taps_length/interpolation+1>input_size) break; //we can't compute the FIR filter to some input samples at the end
//fprintf(stderr,"outer loop | oi = %d | startingi = %d | taps delay = %d\n",oi,startingi,delayi);
for(int i=0; i<(taps_length-delayi)/interpolation; i++) //@rational_resampler_ff (inner loop)
{
//fprintf(stderr,"inner loop | input index = %d | tap index = %d | acc = %g\n",startingi+ii,i,acc);
acc+=input[startingi+i]*taps[delayi+i*interpolation];
}
output[oi]=acc*interpolation;
}
rational_resampler_ff_t d;
d.input_processed=startingi;
d.output_size=oi;
d.last_taps_delay=delayi;
return d;
}
/*
The greatest challenge in resampling is figuring out which tap should be applied to which sample.
Typical test patterns for rational_resampler_ff:
interpolation = 3, decimation = 1
values of [oi, startingi, taps delay] in the outer loop should be:
0 0 0
1 1 2
2 1 1
3 1 0
4 2 2
5 2 1
interpolation = 3, decimation = 2
values of [oi, startingi, taps delay] in the outer loop should be:
0 0 0
1 1 1
2 2 2
3 2 0
4 3 1
5 4 2
*/
void rational_resampler_get_lowpass_f(float* output, int output_size, int interpolation, int decimation, window_t window)
{
//See 4.1.6 at: http://www.dspguru.com/dsp/faqs/multirate/resampling
float cutoff_for_interpolation=1.0/interpolation;
float cutoff_for_decimation=1.0/decimation;
float cutoff = (cutoff_for_interpolation<cutoff_for_decimation)?cutoff_for_interpolation:cutoff_for_decimation; //get the lower
firdes_lowpass_f(output, output_size, cutoff/2, window);
}
float inline fir_one_pass_ff(float* input, float* taps, int taps_length)
{
float acc=0;
for(int i=0;i<taps_length;i++) acc+=taps[i]*input[i]; //@fir_one_pass_ff
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)
{
if(rate<=1.0) return d; //sanity check, can't decimate <=1.0
//This routine can handle floating point decimation rates.
//It linearly interpolates between two samples that are taken into consideration from the filtered input.
int oi=0;
int index_high;
float where=d.remain;
float result_high, result_low;
if(where==0.0) //in the first iteration index_high may be zero (so using the item index_high-1 would lead to invalid memory access).
{
output[oi++]=fir_one_pass_ff(input,taps,taps_length);
where+=rate;
}
int previous_index_high=-1;
//we optimize to calculate ceilf(where) only once every iteration, so we do it here:
for(;(index_high=ceilf(where))+taps_length<input_size;where+=rate) //@fractional_decimator_ff
{
if(previous_index_high==index_high-1) result_low=result_high; //if we step less than 2.0 then we do already have the result for the FIR filter for that index
else result_low=fir_one_pass_ff(input+index_high-1,taps,taps_length);
result_high=fir_one_pass_ff(input+index_high,taps,taps_length);
float register rate_between_samples=where-index_high+1;
output[oi++]=result_low*(1-rate_between_samples)+result_high*rate_between_samples;
previous_index_high=index_high;
}
d.input_processed=index_high-1;
d.remain=where-d.input_processed;
d.output_size=oi;
return d;
}
void apply_fir_fft_cc(FFT_PLAN_T* plan, FFT_PLAN_T* plan_inverse, complexf* taps_fft, complexf* last_overlap, int overlap_size)
{
//calculate FFT on input buffer
fft_execute(plan);
//multiply the filter and the input
complexf* in = plan->output;
complexf* out = plan_inverse->input;
for(int i=0;i<plan->size;i++) //@apply_fir_fft_cc: multiplication
{
iof(out,i)=iof(in,i)*iof(taps_fft,i)-qof(in,i)*qof(taps_fft,i);
qof(out,i)=iof(in,i)*qof(taps_fft,i)+qof(in,i)*iof(taps_fft,i);
}
//calculate inverse FFT on multiplied buffer
fft_execute(plan_inverse);
//add the overlap of the previous segment
complexf* result = plan_inverse->output;
for(int i=0;i<plan->size;i++) //@apply_fir_fft_cc: normalize by fft_size
{
iof(result,i)/=plan->size;
qof(result,i)/=plan->size;
}
for(int i=0;i<overlap_size;i++) //@apply_fir_fft_cc: add overlap
{
iof(result,i)=iof(result,i)+iof(last_overlap,i);
qof(result,i)=qof(result,i)+qof(last_overlap,i);
}
}
/*
__ __ _ _ _ _
/\ | \/ | | | | | | | | |
/ \ | \ / | __| | ___ _ __ ___ ___ __| |_ _| | __ _| |_ ___ _ __ ___
/ /\ \ | |\/| | / _` |/ _ \ '_ ` _ \ / _ \ / _` | | | | |/ _` | __/ _ \| '__/ __|
/ ____ \| | | | | (_| | __/ | | | | | (_) | (_| | |_| | | (_| | || (_) | | \__ \
/_/ \_\_| |_| \__,_|\___|_| |_| |_|\___/ \__,_|\__,_|_|\__,_|\__\___/|_| |___/
*/
void amdemod_cf(complexf* input, float *output, int input_size)
{
//@amdemod: i*i+q*q
for (int i=0; i<input_size; i++)
{
output[i]=iof(input,i)*iof(input,i)+qof(input,i)*qof(input,i);
}
//@amdemod: sqrt
for (int i=0; i<input_size; i++)
{
output[i]=sqrt(output[i]);
}
}
void amdemod_estimator_cf(complexf* input, float *output, int input_size, float alpha, float beta)
{
//concept is explained here:
//http://www.dspguru.com/dsp/tricks/magnitude-estimator
//default: optimize for min RMS error
if(alpha==0)
{
alpha=0.947543636291;
beta=0.392485425092;
}
//@amdemod_estimator
for (int i=0; i<input_size; i++)
{
float abs_i=iof(input,i);
if(abs_i<0) abs_i=-abs_i;
float abs_q=qof(input,i);
if(abs_q<0) abs_q=-abs_q;
float max_iq=abs_i;
if(abs_q>max_iq) max_iq=abs_q;
float min_iq=abs_i;
if(abs_q<min_iq) min_iq=abs_q;
output[i]=alpha*max_iq+beta*min_iq;
}
}
dcblock_preserve_t dcblock_ff(float* input, float* output, int input_size, float a, dcblock_preserve_t preserved)
{
//after AM demodulation, a DC blocking filter should be used to remove the DC component from the signal.
//Concept: http://peabody.sapp.org/class/dmp2/lab/dcblock/
//output size equals to input_size;
//preserve can be initialized to zero on first run.
if(a==0) a=0.999; //default value, simulate in octave: freqz([1 -1],[1 -0.99])
output[0]=input[0]-preserved.last_input+a*preserved.last_output;
for(int i=1; i<input_size; i++) //@dcblock_f
{
output[i]=input[i]-input[i-1]+a*output[i-1];
}
preserved.last_input=input[input_size-1];
preserved.last_output=output[input_size-1];
return preserved;
}
float fastdcblock_ff(float* input, float* output, int input_size, float last_dc_level)
{
//this DC block filter does moving average block-by-block.
//this is the most computationally efficient
//input and output buffer is allowed to be the same
//http://www.digitalsignallabs.com/dcblock.pdf
float avg=0.0;
for(int i=0;i<input_size;i++) //@fastdcblock_ff: calculate block average
{
avg+=input[i];
}
avg/=input_size;
float avgdiff=avg-last_dc_level;
//DC removal level will change lineraly from last_dc_level to avg.
for(int i=0;i<input_size;i++) //@fastdcblock_ff: remove DC component
{
float dc_removal_level=last_dc_level+avgdiff*((float)i/input_size);
output[i]=input[i]-dc_removal_level;
}
return avg;
}
#define FASTAGC_MAX_GAIN (65e3)
void fastagc_ff(fastagc_ff_t* input, float* output)
{
//Gain is processed on blocks of samples.
//You have to supply three blocks of samples before the first block comes out.
//AGC reaction speed equals input_size*samp_rate*2
//The algorithm calculates target gain at the end of the first block out of the peak value of all the three blocks.
//This way the gain change can easily react if there is any peak in the third block.
//Pros: can be easily speeded up with loop vectorization, easy to implement
//Cons: needs 3 buffers, dos not behave similarly to real AGC circuits
//Get the peak value of new input buffer
float peak_input=0;
for(int i=0;i<input->input_size;i++) //@fastagc_ff: peak search
{
float val=fabs(input->buffer_input[i]);
if(val>peak_input) peak_input=val;
}
//Determine the maximal peak out of the three blocks
float target_peak=peak_input;
if(target_peak<input->peak_2) target_peak=input->peak_2;
if(target_peak<input->peak_1) target_peak=input->peak_1;
//we change the gain linearly on the apply_block from the last_gain to target_gain.
float target_gain=input->reference/target_peak;
if(target_gain>FASTAGC_MAX_GAIN) target_gain=FASTAGC_MAX_GAIN;
for(int i=0;i<input->input_size;i++) //@fastagc_ff: apply gain
{
float rate=(float)i/input->input_size;
float gain=input->last_gain*(1.0-rate)+target_gain*rate;
output[i]=input->buffer_1[i]*gain;
}
//Shift the three buffers
float* temp_pointer=input->buffer_1;
input->buffer_1=input->buffer_2;
input->peak_1=input->peak_2;
input->buffer_2=input->buffer_input;
input->peak_2=peak_input;
input->buffer_input=temp_pointer;
input->last_gain=target_gain;
//fprintf(stderr,"target_gain=%g\n", target_gain);
}
/*
______ __ __ _ _ _ _
| ____| \/ | | | | | | | | |
| |__ | \ / | __| | ___ _ __ ___ ___ __| |_ _| | __ _| |_ ___ _ __ ___
| __| | |\/| | / _` |/ _ \ '_ ` _ \ / _ \ / _` | | | | |/ _` | __/ _ \| '__/ __|
| | | | | | | (_| | __/ | | | | | (_) | (_| | |_| | | (_| | || (_) | | \__ \
|_| |_| |_| \__,_|\___|_| |_| |_|\___/ \__,_|\__,_|_|\__,_|\__\___/|_| |___/
*/
float fmdemod_atan_cf(complexf* input, float *output, int input_size, float last_phase)
{
//GCC most likely won't vectorize nor atan, nor atan2.
//For more comments, look at: https://github.com/simonyiszk/minidemod/blob/master/minidemod-wfm-atan.c
float phase, dphase;
for (int i=0; i<input_size; i++) //@fmdemod_atan_novect
{
phase=argof(input,i);
dphase=phase-last_phase;
if(dphase<-PI) dphase+=2*PI;
if(dphase>PI) dphase-=2*PI;
output[i]=dphase/PI;
last_phase=phase;
}
return last_phase;
}
#define fmdemod_quadri_K 0.340447550238101026565118445432744920253753662109375
//this constant ensures proper scaling for qa_fmemod testcases for SNR calculation and more.
complexf fmdemod_quadri_novect_cf(complexf* input, float* output, int input_size, complexf last_sample)
{
output[0]=fmdemod_quadri_K*(iof(input,0)*(qof(input,0)-last_sample.q)-qof(input,0)*(iof(input,0)-last_sample.i))/(iof(input,0)*iof(input,0)+qof(input,0)*qof(input,0));
for (int i=1; i<input_size; i++) //@fmdemod_quadri_novect_cf
{
float qnow=qof(input,i);
float qlast=qof(input,i-1);
float inow=iof(input,i);
float ilast=iof(input,i-1);
output[i]=fmdemod_quadri_K*(inow*(qnow-qlast)-qnow*(inow-ilast))/(inow*inow+qnow*qnow);
//TODO: expression can be simplified as: (qnow*ilast-inow*qlast)/(inow*inow+qnow*qnow)
}
return input[input_size-1];
}
complexf fmdemod_quadri_cf(complexf* input, float* output, int input_size, float *temp, complexf last_sample)
{
float* temp_dq=temp;
float* temp_di=temp+input_size;
temp_dq[0]=qof(input,0)-last_sample.q;
for (int i=1; i<input_size; i++) //@fmdemod_quadri_cf: dq
{
temp_dq[i]=qof(input,i)-qof(input,i-1);
}
temp_di[0]=iof(input,0)-last_sample.i;
for (int i=1; i<input_size; i++) //@fmdemod_quadri_cf: di
{
temp_di[i]=iof(input,i)-iof(input,i-1);
}
for (int i=0; i<input_size; i++) //@fmdemod_quadri_cf: output numerator
{
output[i]=(iof(input,i)*temp_dq[i]-qof(input,i)*temp_di[i]);
}
for (int i=0; i<input_size; i++) //@fmdemod_quadri_cf: output denomiator
{
temp[i]=iof(input,i)*iof(input,i)+qof(input,i)*qof(input,i);
}
for (int i=0; i<input_size; i++) //@fmdemod_quadri_cf: output division
{
output[i]=fmdemod_quadri_K*output[i]/temp[i];
}
return input[input_size-1];
}
float deemphasis_wfm_ff (float* input, float* output, int input_size, float tau, int sample_rate, float last_output)
{
/*
typical time constant (tau) values:
WFM transmission in USA: 75 us -> tau = 75e-6
WFM transmission in EU: 50 us -> tau = 50e-6
More info at: http://www.cliftonlaboratories.com/fm_receivers_and_de-emphasis.htm
Simulate in octave: tau=75e-6; dt=1/48000; alpha = dt/(tau+dt); freqz([alpha],[1 -(1-alpha)])
*/
float dt = 1.0/sample_rate;
float alpha = dt/(tau+dt);
output[0]=alpha*input[0]+(1-alpha)*last_output;
for (int i=1;i<input_size;i++) //@deemphasis_wfm_ff
output[i]=alpha*input[i]+(1-alpha)*output[i-1]; //this is the simplest IIR LPF
return output[input_size-1];
}
#define DNFMFF_ADD_ARRAY(x) if(sample_rate==x) { taps=deemphasis_nfm_predefined_fir_##x; taps_length=sizeof(deemphasis_nfm_predefined_fir_##x)/sizeof(float); }
int deemphasis_nfm_ff (float* input, float* output, int input_size, int sample_rate)
{
/*
Warning! This only works on predefined samplerates, as it uses fixed FIR coefficients defined in predefined.h
However, there are the octave commands to generate the taps for your custom (fixed) sample rate.
What it does:
- reject below 400 Hz
- passband between 400 HZ - 4 kHz, but with 20 dB/decade rolloff (for deemphasis)
- reject everything above 4 kHz
*/
float* taps;
int taps_length=0;
DNFMFF_ADD_ARRAY(48000)
DNFMFF_ADD_ARRAY(8000)
if(!taps_length) return 0; //sample rate n
int i;
for(i=0;i<input_size-taps_length;i++) //@deemphasis_nfm_ff: outer loop
{
float acc=0;
for(int ti=0;ti<taps_length;ti++) acc+=taps[ti]*input[i+ti]; //@deemphasis_nfm_ff: inner loop
output[i]=acc;
}
return i; //number of samples processed (and output samples)
}
void limit_ff(float* input, float* output, int input_size, float max_amplitude)
{
for (int i=0; i<input_size; i++) //@limit_ff
{
output[i]=(max_amplitude<input[i])?max_amplitude:input[i];
output[i]=(-max_amplitude>output[i])?-max_amplitude:output[i];
}
}
void gain_ff(float* input, float* output, int input_size, float gain)
{
for(int i=0;i<input_size;i++) output[i]=gain*input[i]; //@gain_ff
}
/*
______ _ ______ _ _______ __
| ____| | | | ____| (_) |__ __| / _|
| |__ __ _ ___| |_ | |__ ___ _ _ _ __ _ ___ _ __ | |_ __ __ _ _ __ ___| |_ ___ _ __ _ __ ___
| __/ _` / __| __| | __/ _ \| | | | '__| |/ _ \ '__| | | '__/ _` | '_ \/ __| _/ _ \| '__| '_ ` _ \
| | | (_| \__ \ |_ | | | (_) | |_| | | | | __/ | | | | | (_| | | | \__ \ || (_) | | | | | | | |
|_| \__,_|___/\__| |_| \___/ \__,_|_| |_|\___|_| |_|_| \__,_|_| |_|___/_| \___/|_| |_| |_| |_|
*/
int log2n(int x)
{
int result=-1;
for(int i=0;i<31;i++)
{
if((x>>i)&1) //@@log2n
{
if (result==-1) result=i;
else return -1;
}
}
return result;
}
int next_pow2(int x)
{
int pow2;
//portability? (31 is the problem)
for(int i=0;i<31;i++)
{
if(x<(pow2=1<<i)) return pow2; //@@next_pow2
}
return -1;
}
void apply_window_c(complexf* input, complexf* output, int size, window_t window)
{
float (*window_function)(float)=firdes_get_window_kernel(window);
for(int i=0;i<size;i++) //@apply_window_c
{
float rate=(float)i/(size-1);
iof(output,i)=iof(input,i)*window_function(2.0*rate+1.0);
qof(output,i)=qof(input,i)*window_function(2.0*rate+1.0);
}
}
void apply_window_f(float* input, float* output, int size, window_t window)
{
float (*window_function)(float)=firdes_get_window_kernel(window);
for(int i=0;i<size;i++) //@apply_window_f
{
float rate=(float)i/(size-1);
output[i]=input[i]*window_function(2.0*rate+1.0);
}
}
void logpower_cf(complexf* input, float* output, int size, float add_db)
{
for(int i=0;i<size;i++) output[i]=iof(input,i)*iof(input,i) + qof(input,i)*qof(input,i); //@logpower_cf: pass 1
for(int i=0;i<size;i++) output[i]=log10(output[i]); //@logpower_cf: pass 2
for(int i=0;i<size;i++) output[i]=10*output[i]+add_db; //@logpower_cf: pass 3
}
/*
_____ _ _
| __ \ | | (_)
| | | | __ _| |_ __ _ ___ ___ _ ____ _____ _ __ ___ _ ___ _ __
| | | |/ _` | __/ _` | / __/ _ \| '_ \ \ / / _ \ '__/ __| |/ _ \| '_ \
| |__| | (_| | || (_| | | (_| (_) | | | \ V / __/ | \__ \ | (_) | | | |
|_____/ \__,_|\__\__,_| \___\___/|_| |_|\_/ \___|_| |___/_|\___/|_| |_|
*/
void convert_u8_f(unsigned char* input, float* output, int input_size)
{
for(int i=0;i<input_size;i++) output[i]=((float)input[i])/(UCHAR_MAX/2.0)-1.0; //@convert_u8_f
}
void convert_i16_f(short* input, float* output, int input_size)
{
for(int i=0;i<input_size;i++) output[i]=(float)input[i]/SHRT_MAX; //@convert_i16_f
}
void convert_f_u8(float* input, unsigned char* output, int input_size)
{
for(int i=0;i<input_size;i++) output[i]=input[i]*UCHAR_MAX*0.5+128; //@convert_f_u8
//128 above is the correct value to add. In any other case a DC component
//of at least -60 dB is shown on the FFT plot after convert_f_u8 -> convert_u8_f
}
void convert_f_i16(float* input, short* output, int input_size)
{
/*for(int i=0;i<input_size;i++)
{
if(input[i]>1.0) input[i]=1.0;
if(input[i]<-1.0) input[i]=-1.0;
}*/
for(int i=0;i<input_size;i++) output[i]=input[i]*SHRT_MAX; //@convert_f_i16
}
int trivial_vectorize()
{
//this function is trivial to vectorize and should pass on both NEON and SSE
int a[1024], b[1024], c[1024];
for(int i=0; i<1024; i++) //@trivial_vectorize: should pass :-)
{
c[i]=a[i]*b[i];
}
return c[0];
}

161
libcsdr.h Normal file
View file

@ -0,0 +1,161 @@
/*
This software is part of libcsdr, a set of simple DSP routines for
Software Defined Radio.
Copyright (c) 2014, Andras Retzler <randras@sdr.hu>
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 ANDRAS RETZLER 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.
*/
#pragma once
#define MIN_M(x,y) (((x)>(y))?(y):(x))
/*
_____ _
/ ____| | |
| | ___ _ __ ___ _ __ | | _____ __
| | / _ \| '_ ` _ \| '_ \| |/ _ \ \/ /
| |___| (_) | | | | | | |_) | | __/> <
\_____\___/|_| |_| |_| .__/|_|\___/_/\_\
| |
|_|
*/
typedef struct complexf_s { float i; float q; } complexf;
//apply to pointers:
#define iof(complexf_input_p,i) (*(((float*)complexf_input_p)+2*(i)))
#define qof(complexf_input_p,i) (*(((float*)complexf_input_p)+2*(i)+1))
#define absof(complexf_input_p,i) (sqrt(iof(complexf_input_p,i)*iof(complexf_input_p,i)+qof(complexf_input_p,i)*qof(complexf_input_p,i)))
#define argof(complexf_input_p,i) (atan2(qof(complexf_input_p,i),iof(complexf_input_p,i)))
#define cmult(cfo, cfi1, cfi2) iof(cfo,0)=iof(cfi1,0)*iof(cfi2,0)-qof(cfi1,0)*qof(cfi2,0);qof(cfo,0)=iof(cfi1,0)*qof(cfi2,0)+iof(cfi2,0)*qof(cfi1,0)
//(ai+aq*j)*(bi+bq*j)=ai*bi-aq*bq+(aq*bi+ai*bq)*j
#define cmultadd(cfo, cfi1, cfi2) { iof(cfo,0)+=iof(cfi1,0)*iof(cfi2,0)-qof(cfi1,0)*qof(cfi2,0);qof(cfo,0)+=iof(cfi1,0)*qof(cfi2,0)+iof(cfi2,0)*qof(cfi1,0); }
#define csetnull(cf) { iof(cf,0)=0.0; qof(cf,0)=0.0; }
#define e_powj(cf,w) { iof(cf,0)=cos(w); qof(cf,0)=sin(w); }
#define ccopy(dst,src) { iof(dst,0)=iof(src,0); qof(dst,0)=qof(src,0); }
//apply to values
#define iofv(complexf_input) (*((float*)&complexf_input))
#define qofv(complexf_input) (*(((float*)&complexf_input)+1))
//they dropped M_PI in C99, so we define it:
#define PI ((float)3.14159265358979323846)
//window
typedef enum window_s
{
WINDOW_BOXCAR, WINDOW_BLACKMAN, WINDOW_HAMMING
} window_t;
#define WINDOW_DEFAULT WINDOW_HAMMING
//FFT
//Note: these reference to things in this file (e.g. complexf):
#include "fft_fftw.h"
#include "fft_rpi.h"
// =================================================================================
//filter design
void firdes_lowpass_f(float *output, int length, float cutoff_rate, window_t window);
void firdes_bandpass_c(complexf *output, int length, float lowcut, float highcut, window_t window);
float firdes_wkernel_blackman(float input);
float firdes_wkernel_hamming(float input);
float firdes_wkernel_boxcar(float input);
window_t firdes_get_window_from_string(char* input);
char* firdes_get_string_from_window(window_t window);
int firdes_filter_len(float rolloff);
//demodulators
complexf fmdemod_quadri_cf(complexf* input, float* output, int input_size, float *temp, complexf last_sample);
complexf fmdemod_quadri_novect_cf(complexf* input, float* output, int input_size, complexf last_sample);
float fmdemod_atan_cf(complexf* input, float *output, int input_size, float last_phase);
void amdemod_cf(complexf* input, float *output, int input_size);
void amdemod_estimator_cf(complexf* input, float *output, int input_size, float alpha, float beta);
void limit_ff(float* input, float* output, int input_size, float max_amplitude);
//filters, decimators, resamplers, shift, etc.
int fir_decimate_cc(complexf *input, complexf *output, int input_size, int decimation, float *taps, int taps_length);
int deemphasis_nfm_ff (float* input, float* output, int input_size, int sample_rate);
float deemphasis_wfm_ff (float* input, float* output, int input_size, float tau, int sample_rate, float last_output);
float shift_math_cc(complexf *input, complexf* output, int input_size, float rate, float starting_phase);
typedef struct dcblock_preserve_s
{
float last_input;
float last_output;
} dcblock_preserve_t;
dcblock_preserve_t dcblock_ff(float* input, float* output, int input_size, float a, dcblock_preserve_t preserved);
float fastdcblock_ff(float* input, float* output, int input_size, float last_dc_level);
typedef struct fastagc_ff_s
{
float* buffer_1;
float* buffer_2;
float* buffer_input; //it is the actual input buffer to fill
float peak_1;
float peak_2;
int input_size;
float reference;
float last_gain;
} fastagc_ff_t;
void fastagc_ff(fastagc_ff_t* input, float* output);
typedef struct rational_resampler_ff_s
{
int input_processed;
int output_size;
int last_taps_delay;
} rational_resampler_ff_t;
rational_resampler_ff_t rational_resampler_ff(float *input, float *output, int input_size, int interpolation, int decimation, float *taps, int taps_length, int last_taps_delay);
void rational_resampler_get_lowpass_f(float* output, int output_size, int interpolation, int decimation, window_t window);
void apply_window_c(complexf* input, complexf* output, int size, window_t window);
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);
typedef struct 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);
int log2n(int x);
int next_pow2(int x);
void apply_fir_fft_cc(FFT_PLAN_T* plan, FFT_PLAN_T* plan_inverse, complexf* taps_fft, complexf* last_overlap, int overlap_size);
void gain_ff(float* input, float* output, int input_size, float gain);
void convert_u8_f(unsigned char* input, float* output, int input_size);
void convert_f_u8(float* input, unsigned char* output, int input_size);
void convert_f_i16(float* input, short* output, int input_size);
void convert_i16_f(short* input, float* output, int input_size);

197
libcsdr_gpl.c Normal file
View file

@ -0,0 +1,197 @@
/*
This file is part of libcsdr.
Copyright (c) Andras Retzler, HA7ILM <randras@sdr.hu>
Copyright (c) Warren Pratt, NR0V <warren@wpratt.com>
Copyright 2006,2010,2012 Free Software Foundation, Inc.
libcsdr is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
libcsdr is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with libcsdr. If not, see <http://www.gnu.org/licenses/>.
*/
#include "libcsdr_gpl.h"
#ifdef LIBCSDR_GPL
float shift_addition_cc(complexf *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*iof(input,i)-sinphi*qof(input,i);
qof(output,i)=sinphi*iof(input,i)+cosphi*qof(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;
shift_addition_data_t out;
out.sindelta=sin(rate*PI);
out.cosdelta=cos(rate*PI);
out.rate=rate;
return out;
}
#define SACCTEST_LOOPS 50
#define SACCTEST_STEP 10000
void shift_addition_cc_test(shift_addition_data_t d)
{
float phi=0;
float cosphi=cos(phi);
float sinphi=sin(phi);
float cosphi_last, sinphi_last;
int avg_size=(int)(2.0/d.rate+1.0); //average one period of sine
int avg_counter=0;
float avg=0;
printf("error_vector=[");
for(unsigned i=0;i<SACCTEST_STEP*SACCTEST_LOOPS;i++) //@shift_addition_cc: work
{
cosphi_last=cosphi;
sinphi_last=sinphi;
cosphi=cosphi_last*d.cosdelta-sinphi_last*d.sindelta;
sinphi=sinphi_last*d.cosdelta+cosphi_last*d.sindelta;
phi+=d.rate*PI;
while(phi>2*PI) phi-=2*PI; //@shift_addition_cc: normalize phase
if(i%SACCTEST_STEP==0)
{
avg_counter=avg_size;
avg=0;
}
if(avg_counter)
{
avg+=fabs(cosphi-cos(phi));
if(!--avg_counter) printf("%g ", avg/avg_size);
}
}
printf("]; error_vector_db=20*log10(error_vector); plot(error_vector_db);\n");
}
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)
{
/*
Default working parameter values for voice:
attack_rate = 0.001
decay_rate = 0.01
hang_time = (hang_time_ms / 1000) * sample_rate
hang_time is given in samples, and should be about 4ms.
hang_time can be switched off by setting it to zero (not recommended).
max_gain = pow(2, adc_bits)
max_gain should be no more than the dynamic range of your A/D converter.
gain_filter_alpha = 1 / ((fs/(2*PI*fc))+1)
>>> 1 / ((48000./(2*3.141592654*100))+1)
0.012920836043344543
>>> 1 / ((48000./(2*3.141592654*10))+1)
0.0013072857061786625
Literature:
ww.qsl.net/va3iul/Files/Automatic_Gain_Control.pdf
page 7 of http://www.arrl.org/files/file/Technology/tis/info/pdf/021112qex027.pdf
Examples:
http://svn.tapr.org/repos_sdr_hpsdr/trunk/W5WC/PowerSDR_HPSDR_mRX_PS/Source/wdsp/wcpAGC.c
GNU Radio's agc,agc2,agc3 have quite good ideas about this.
*/
register short hang_counter=0;
register short attack_wait_counter=0;
float gain=last_gain;
float last_peak=reference/last_gain; //approx.
float input_abs;
float error, dgain;
output[0]=last_gain*input[0]; //we skip this one sample, because it is easier this way
for(int i=1;i<input_size;i++) //@agc_ff
{
//The error is the difference between the required gain at the actual sample, and the previous gain value.
//We actually use an envelope detector.
input_abs=fabs(input[i]);
error=reference/input_abs-gain;
if(input[i]!=0) //We skip samples containing 0, as the gain would be infinity for those to keep up with the reference.
{
//An AGC is something nonlinear that's easier to implement in software:
//if the amplitude decreases, we increase the gain by minimizing the gain error by attack_rate.
//We also have a decay_rate that comes into consideration when the amplitude increases.
//The higher these rates are, the faster is the response of the AGC to amplitude changes.
//However, attack_rate should be higher than the decay_rate as we want to avoid clipping signals.
//that had a sudden increase in their amplitude.
//It's also important to note that this algorithm has an exponential gain ramp.
if(error<0) //INCREASE IN SIGNAL LEVEL
{
if(last_peak<input_abs)
{
attack_wait_counter=attack_wait_time;
last_peak=input_abs;
}
if(attack_wait_counter>0)
{
attack_wait_counter--;
dgain=0;
}
else
{
//If the signal level increases, we decrease the gain quite fast.
dgain=error*attack_rate;
//Before starting to increase the gain next time, we will be waiting until hang_time for sure.
hang_counter=hang_time;
}
}
else //DECREASE IN SIGNAL LEVEL
{
if(hang_counter>0) //Before starting to increase the gain, we will be waiting until hang_time.
{
hang_counter--;
dgain=0; //..until then, AGC is inactive and gain doesn't change.
}
else dgain=error*decay_rate; //If the signal level decreases, we increase the gain quite slowly.
}
gain=gain+dgain;
//fprintf(stderr,"g=%f dg=%f\n",gain,dgain);
if(gain>max_gain) gain=max_gain; //We also have to limit our gain, it can't be infinity.
if(gain<0) gain=0;
}
//output[i]=gain*input[i]; //Here we do the actual scaling of the samples.
//Here we do the actual scaling of the samples, but we run an IIR filter on the gain values:
output[i]=(gain+last_gain-gain_filter_alpha*last_gain)*input[i]; //dc-pass-filter: freqz([1 -1],[1 -0.99]) y[i]=x[i]+y[i-1]-alpha*x[i-1]
//output[i]=input[i]*(last_gain+gain_filter_alpha*(gain-last_gain)); //LPF
last_gain=gain;
}
return gain; //this will be the last_gain next time
}
#endif

39
libcsdr_gpl.h Normal file
View file

@ -0,0 +1,39 @@
/*
This file is part of libcsdr.
Copyright (c) Andras Retzler, HA7ILM <randras@sdr.hu>
Copyright (c) Warren Pratt, NR0V <warren@wpratt.com>
Copyright 2006,2010,2012 Free Software Foundation, Inc.
libcsdr is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
libcsdr is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with libcsdr. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifdef LIBCSDR_GPL
typedef struct shift_addition_data_s
{
float sindelta;
float cosdelta;
float rate;
} 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);
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);
#endif

3
libcsdr_wrapper.c Normal file
View file

@ -0,0 +1,3 @@
#include "libcsdr.c"
#include "libcsdr_gpl.c"
//this wrapper helps parsevect.py to generate better output

74
parsevect Executable file
View file

@ -0,0 +1,74 @@
#!/usr/bin/python
"""
This software is part of libcsdr, a set of simple DSP routines for
Software Defined Radio.
Copyright (c) 2014, Andras Retzler <randras@sdr.hu>
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 ANDRAS RETZLER 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.
"""
import sys
try:
vectfile=open(sys.argv[1],"r").readlines()
except:
print "parsevect: can't open input file"
quit()
lastcfile=""
cfile=[]
def loadcfile(what):
global lastcfile, cfile
if lastcfile!=what:
cfile=open(what,"r").readlines()
lastcfile=what
print """
Auto-vectorization built into gcc can increase the execution speed of algorithms with automatic
generation of SIMD instructions if the CPU is capable.
We parse the output of the vectorizer to analyze which loops could be optimized (thus speeded up) this way.
Warning! The result may be different on different CPU architectures...
Colors:
\033[1;31m - can't be vectorized
\033[1;32m - successfully vectorized
\033[1;33m - not intended to be vectorized (not important)
\033[1;0m"""
checkline = lambda k: cfile[linenum-k] if "//@" in cfile[linenum-k] else corresponds
for row in vectfile:
if "LOOP VECTORIZED" in row or "not vectorized" in row:
filename=row.split(":")[0]
loadcfile(filename)
linenum=int(row.split(":")[1])
corresponds="//@"
corresponds=checkline(1)
corresponds=checkline(2)
corresponds=corresponds.split("//@")[1][:-1]
yellow=corresponds.startswith("@")
if yellow: corresponds=corresponds[1:]
print row[:-1], "\033[1;33m" if yellow else "\033[1;31m" if "not " in row else "\033[1;32m", corresponds, "\033[1;0m"

64
predefined.h Normal file
View file

@ -0,0 +1,64 @@
#pragma once
/*
This software is part of libcsdr, a set of simple DSP routines for
Software Defined Radio.
Copyright (c) 2014, Andras Retzler <randras@sdr.hu>
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 ANDRAS RETZLER 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.
*/
//predefined large arrays come here
//De-emphasis FIR filters:
//I chose not to implement a filter design algoritm for these, because:
// - they are defined by their frequency envelope, and I didn't want to implement the least squares or similar algorithm to design such filters
// - they are most likely needed at given fixed sample rates
/*octave>
function mkdeemph(sr,tapnum,norm_freq)
% Make NFM deemphasis filter. Parameters: samplerate, filter length, frequency to normalize at (filter gain will be 0dB at this frequency)
normalize_at_freq = @(vect,freq) vect/dot(vect,sin(2*pi*freq*[0:1/sr:size(vect)(1)/sr]));
freqvect=[0,200, 200,400, 400,3700, 3700,sr/2];
coeffs=firls(tapnum,freqvect/(sr/2),[0,0,0,1,1,0.1,0,0]);
coeffs=normalize_at_freq(coeffs,norm_freq);
freqz(coeffs);
printf("%g, ",coeffs);
printf("\n")
end
mkdeemph(48000,199,500)
*/
float deemphasis_nfm_predefined_fir_48000[] =
{ 0.00172568, 0.00179665, 0.00191952, 0.00205318, 0.00215178, 0.00217534, 0.00209924, 0.00192026, 0.00165789, 0.0013502, 0.00104545, 0.000790927, 0.000621911, 0.000553077, 0.000574554, 0.000653624, 0.000741816, 0.000785877, 0.000740151, 0.000577506, 0.000296217, -7.89273e-05, -0.0005017, -0.000914683, -0.00126243, -0.00150456, -0.00162564, -0.0016396, -0.00158725, -0.00152751, -0.00152401, -0.00163025, -0.00187658, -0.00226223, -0.00275443, -0.003295, -0.0038132, -0.00424193, -0.00453375, -0.00467274, -0.00467943, -0.00460728, -0.00453119, -0.00453056, -0.00467051, -0.00498574, -0.00547096, -0.00608027, -0.00673627, -0.00734698, -0.00782705, -0.00811841, -0.00820539, -0.00812057, -0.00793936, -0.00776415, -0.00770111, -0.00783479, -0.00820643, -0.00880131, -0.00954878, -0.0103356, -0.0110303, -0.011514, -0.0117094, -0.0116029, -0.0112526, -0.0107795, -0.010343, -0.0101053, -0.0101917, -0.0106561, -0.0114608, -0.0124761, -0.0135018, -0.0143081, -0.0146885, -0.0145126, -0.0137683, -0.0125796, -0.0111959, -0.00994914, -0.00918404, -0.00917447, -0.0100402, -0.0116822, -0.0137533, -0.0156723, -0.0166881, -0.0159848, -0.0128153, -0.00664117, 0.00274383, 0.0151313, 0.0298729, 0.0459219, 0.0619393, 0.076451, 0.0880348, 0.0955087, 0.098091, 0.0955087, 0.0880348, 0.076451, 0.0619393, 0.0459219, 0.0298729, 0.0151313, 0.00274383, -0.00664117, -0.0128153, -0.0159848, -0.0166881, -0.0156723, -0.0137533, -0.0116822, -0.0100402, -0.00917447, -0.00918404, -0.00994914, -0.0111959, -0.0125796, -0.0137683, -0.0145126, -0.0146885, -0.0143081, -0.0135018, -0.0124761, -0.0114608, -0.0106561, -0.0101917, -0.0101053, -0.010343, -0.0107795, -0.0112526, -0.0116029, -0.0117094, -0.011514, -0.0110303, -0.0103356, -0.00954878, -0.00880131, -0.00820643, -0.00783479, -0.00770111, -0.00776415, -0.00793936, -0.00812057, -0.00820539, -0.00811841, -0.00782705, -0.00734698, -0.00673627, -0.00608027, -0.00547096, -0.00498574, -0.00467051, -0.00453056, -0.00453119, -0.00460728, -0.00467943, -0.00467274, -0.00453375, -0.00424193, -0.0038132, -0.003295, -0.00275443, -0.00226223, -0.00187658, -0.00163025, -0.00152401, -0.00152751, -0.00158725, -0.0016396, -0.00162564, -0.00150456, -0.00126243, -0.000914683, -0.0005017, -7.89273e-05, 0.000296217, 0.000577506, 0.000740151, 0.000785877, 0.000741816, 0.000653624, 0.000574554, 0.000553077, 0.000621911, 0.000790927, 0.00104545, 0.0013502, 0.00165789, 0.00192026, 0.00209924, 0.00217534, 0.00215178, 0.00205318, 0.00191952, 0.00179665, 0.00172568 };
//mkdeemph(8000,79,500)
float deemphasis_nfm_predefined_fir_8000[] =
{ 1.43777e+11, 1.45874e+11, -4.67746e+11, 9.98433e+10, -1.47835e+12, -3.78799e+11, -2.61333e+12, -1.07042e+12, -3.41242e+12, -1.57042e+12, -3.34195e+12, -1.4091e+12, -1.96864e+12, -2.26212e+11, 8.48259e+11, 2.04875e+12, 4.80451e+12, 5.06875e+12, 9.09434e+12, 8.04571e+12, 1.24874e+13, 9.85837e+12, 1.35433e+13, 9.28407e+12, 1.09287e+13, 5.30975e+12, 3.76762e+12, -2.54809e+12, -8.06152e+12, -1.39895e+13, -2.37664e+13, -2.77865e+13, -4.16745e+13, -4.16797e+13, -5.94708e+13, -5.17628e+13, -7.46014e+13, -4.66449e+13, -8.47575e+13, 1.51722e+14, 4.98196e+14, 1.51722e+14, -8.47575e+13, -4.66449e+13, -7.46014e+13, -5.17628e+13, -5.94708e+13, -4.16797e+13, -4.16745e+13, -2.77865e+13, -2.37664e+13, -1.39895e+13, -8.06152e+12, -2.54809e+12, 3.76762e+12, 5.30975e+12, 1.09287e+13, 9.28407e+12, 1.35433e+13, 9.85837e+12, 1.24874e+13, 8.04571e+12, 9.09434e+12, 5.06875e+12, 4.80451e+12, 2.04875e+12, 8.48259e+11, -2.26212e+11, -1.96864e+12, -1.4091e+12, -3.34195e+12, -1.57042e+12, -3.41242e+12, -1.07042e+12, -2.61333e+12, -3.78799e+11, -1.47835e+12, 9.98433e+10, -4.67746e+11, 1.45874e+11, 1.43777e+11 };

4
recomp Executable file
View file

@ -0,0 +1,4 @@
#!/bin/bash
sudo killall csdr
make
sudo make install