diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2671857 --- /dev/null +++ b/Makefile @@ -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 +# 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 + + + diff --git a/README.md b/README.md index 1276ae0..776b27d 100644 --- a/README.md +++ b/README.md @@ -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 rtl_sdr from Osmocom, and the following packages (at least on Debian): `mplayer octave gnuplot gnuplot-x11` + +Credits +------- +The library was written by Andras Retzler, HA7ILM <>. + +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__` +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 ``, 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 ` + +It multiplies all samples by `gain`. + +##### `clone` + +It copies the input to the output. + +##### `yes_f [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 ` + +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 ` + +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 ` + +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 ` + +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 [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 [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 [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 [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 [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 [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 [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 [--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 ` + +By writing to the given FIFO file with the syntax below, you can control the 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 [window]` + +By writing to the given FIFO file with the syntax below, you can control the shift rate: + + \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. + diff --git a/csdr-fm b/csdr-fm new file mode 100755 index 0000000..183df50 --- /dev/null +++ b/csdr-fm @@ -0,0 +1,41 @@ +#!/bin/bash +: ' +Copyright (c) 2014, Andras Retzler +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 - diff --git a/csdr.c b/csdr.c new file mode 100644 index 0000000..b0040ee --- /dev/null +++ b/csdr.c @@ -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 +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 [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 \n" +" clone\n" +" yes_f [buf_times]\n" +" shift_math_cc \n" +" shift_addition_cc \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 " +" deemphasis_nfm_ff " +" amdemod_cf\n" +" amdemod_estimator_cf\n" +" fir_decimate_cc [transition_bw [window]]\n" +" firdes_lowpass_f [window [--octave]]\n" +" firdes_bandpass_c [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 [transition_bw [window]]\n" +" fractional_decimator_ff [transition_bw [window]]\n" +" fft_cc [window [--octave] [--benchmark]]\n" +" logpower_cf [add_db]\n" +" fft_benchmark [--benchmark]\n" +" bandpass_fir_fft_cc [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;i1.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=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/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=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=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 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=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=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;ioutput,i)=qof(plan_inverse_2->output,i)=0; + + for(int i=input_size;ioutput + 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."); + +} + + diff --git a/fft_fftw.c b/fft_fftw.c new file mode 100644 index 0000000..abc9aaf --- /dev/null +++ b/fft_fftw.c @@ -0,0 +1,47 @@ +#ifdef USE_FFTW + +#include "fft_fftw.h" +#include + +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 diff --git a/fft_fftw.h b/fft_fftw.h new file mode 100644 index 0000000..f528a85 --- /dev/null +++ b/fft_fftw.h @@ -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 +#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 diff --git a/fft_rpi.c b/fft_rpi.c new file mode 100644 index 0000000..d90a9ee --- /dev/null +++ b/fft_rpi.c @@ -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 diff --git a/fft_rpi.h b/fft_rpi.h new file mode 100644 index 0000000..fcb00be --- /dev/null +++ b/fft_rpi.h @@ -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 diff --git a/grc_tests/test_agc_gen.grc b/grc_tests/test_agc_gen.grc new file mode 100644 index 0000000..70d0113 --- /dev/null +++ b/grc_tests/test_agc_gen.grc @@ -0,0 +1,593 @@ + + + + Sat Nov 15 19:16:25 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 48000 + + + alias + + + + _coordinate + (184, 11) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_SQR_WAVE + + + freq + 1 + + + amp + 0.9 + + + offset + 0.1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (152, 131) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + ff + + + commandline + csdr agc_ff + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (864, 323) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + float + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (688, 283) + + + _rotation + 0 + + + + blocks_multiply_xx + + id + blocks_multiply_xx_0 + + + _enabled + True + + + type + float + + + num_inputs + 2 + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (440, 256) + + + _rotation + 0 + + + + blocks_add_xx + + id + blocks_add_xx_0 + + + _enabled + True + + + type + float + + + num_inputs + 2 + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (576, 304) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + 5000 + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (48, 251) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + float + + + title + Scope Plot + + + samp_rate + samp_rate + + + v_scale + 0.3 + + + v_offset + 0 + + + t_scale + 0.1 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 3 + + + win_size + + + + grid_pos + + + + notebook + + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (1048, 128) + + + _rotation + 0 + + + + blocks_vector_source_x + + id + blocks_vector_source_x_0 + + + _enabled + True + + + type + float + + + vector + [1]*8+[0,]*(samp_rate/15) + + + tags + [] + + + repeat + True + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (288, 379) + + + _rotation + 0 + + + + analog_sig_source_x_0_0 + blocks_multiply_xx_0 + 0 + 0 + + + analog_sig_source_x_0_0 + wxgui_scopesink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0 + 0 + 2 + + + blocks_throttle_0 + wxgui_scopesink2_0 + 0 + 1 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + blocks_multiply_xx_0 + blocks_add_xx_0 + 0 + 0 + + + blocks_add_xx_0 + blocks_throttle_0 + 0 + 0 + + + blocks_vector_source_x_0 + blocks_add_xx_0 + 0 + 1 + + + analog_sig_source_x_0 + blocks_multiply_xx_0 + 0 + 1 + + diff --git a/grc_tests/test_agc_get_testfile.sh b/grc_tests/test_agc_get_testfile.sh new file mode 100755 index 0000000..9c9ca62 --- /dev/null +++ b/grc_tests/test_agc_get_testfile.sh @@ -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 diff --git a/grc_tests/test_agc_wav.grc b/grc_tests/test_agc_wav.grc new file mode 100644 index 0000000..8910238 --- /dev/null +++ b/grc_tests/test_agc_wav.grc @@ -0,0 +1,519 @@ + + + Sun Nov 16 15:12:31 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 48000 + + + _coordinate + (10, 170) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + float + + + title + FFT Plot + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + + + + freqvar + None + + + affinity + + + + _coordinate + (1104, 403) + + + _rotation + 0 + + + + band_reject_filter + + id + band_reject_filter_0 + + + _enabled + True + + + type + fir_filter_fff + + + decim + 1 + + + interp + 1 + + + gain + 1 + + + samp_rate + samp_rate + + + low_cutoff_freq + 1600 + + + high_cutoff_freq + 2000 + + + width + 50 + + + win + firdes.WIN_HAMMING + + + beta + 6.76 + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (392, 35) + + + _rotation + 0 + + + + blocks_multiply_const_vxx + + id + blocks_multiply_const_vxx_0 + + + _enabled + True + + + type + float + + + const + 0.2 + + + vlen + 1 + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (984, 219) + + + _rotation + 0 + + + + audio_sink + + id + audio_sink_0 + + + _enabled + True + + + samp_rate + samp_rate + + + device_name + + + + ok_to_block + True + + + num_inputs + 1 + + + affinity + + + + _coordinate + (1152, 219) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + ff + + + commandline + csdr agc_ff + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (616, 283) + + + _rotation + 0 + + + + low_pass_filter + + id + low_pass_filter_0 + + + _enabled + True + + + type + fir_filter_fff + + + decim + 1 + + + interp + 1 + + + gain + 1 + + + samp_rate + samp_rate + + + cutoff_freq + 3000 + + + width + 50 + + + win + firdes.WIN_HAMMING + + + beta + 6.76 + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (584, 43) + + + _rotation + 0 + + + + blocks_wavfile_source + + id + blocks_wavfile_source_0 + + + _enabled + True + + + file + /home/ha5kfu/Dokumentumok/ddcdemod/grc_tests/agctest.wav + + + repeat + True + + + nchan + 1 + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (152, 163) + + + _rotation + 0 + + + + blocks_multiply_const_vxx_0 + audio_sink_0 + 0 + 0 + + + band_reject_filter_0 + low_pass_filter_0 + 0 + 0 + + + blocks_wavfile_source_0 + band_reject_filter_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + blocks_multiply_const_vxx_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + low_pass_filter_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + diff --git a/grc_tests/test_amdemod.grc b/grc_tests/test_amdemod.grc new file mode 100644 index 0000000..c05cfb6 --- /dev/null +++ b/grc_tests/test_amdemod.grc @@ -0,0 +1,1435 @@ + + + + Sat Nov 15 20:00:43 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 250000 + + + alias + + + + _coordinate + (184, 11) + + + _rotation + 0 + + + + variable + + id + decimation + + + _enabled + True + + + value + 4 + + + alias + + + + _coordinate + (808, 11) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + fmod + + + amp + 0.4 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (16, 83) + + + _rotation + 0 + + + + variable_slider + + id + fmod + + + _enabled + True + + + label + Modulation frequency + + + value + 7e3 + + + min + 0 + + + max + 40e3 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (344, 11) + + + _rotation + 0 + + + + blocks_add_const_vxx + + id + blocks_add_const_vxx_0 + + + _enabled + True + + + type + float + + + const + 0.5 + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (184, 115) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + fcarr + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (16, 195) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + float + + + title + FFT Plot of Real AM Source + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (1080, 139) + + + _rotation + 0 + + + + freq_xlating_fir_filter_xxx + + id + freq_xlating_fir_filter_xxx_0 + + + _enabled + True + + + type + fcf + + + decim + decimation + + + taps + firdes.low_pass(1,1,.5/decimation-0.05,0.01) + + + center_freq + fcarr + + + samp_rate + samp_rate + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (88, 379) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + cf + + + commandline + csdr amdemod_cf + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (336, 523) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + float + + + title + Scope Plot after amdemod_cf + + + samp_rate + samp_rate/decimation + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb0,2 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (848, 587) + + + _rotation + 0 + + + + blocks_multiply_xx + + id + blocks_multiply_xx_0 + + + _enabled + True + + + type + float + + + num_inputs + 2 + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (224, 200) + + + _rotation + 0 + + + + blocks_multiply_const_vxx + + id + blocks_multiply_const_vxx_0 + + + _enabled + True + + + type + float + + + const + gain + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (352, 211) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + float + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (512, 211) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + complex + + + title + FFT Plot of Downconverted AM Source + + + samp_rate + samp_rate/decimation + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (672, 323) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0_0 + + + _enabled + True + + + type + float + + + title + FFT Plot after amdemod_cf + + + samp_rate + samp_rate/decimation + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (1040, 443) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0_0_0 + + + _enabled + True + + + type + float + + + title + FFT Plot after amdemod_estimator_cf + + + samp_rate + samp_rate/decimation + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (1040, 667) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0_0 + + + _enabled + True + + + type + float + + + title + Scope Plot after amdemod_estimator_cf + + + samp_rate + samp_rate/decimation + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb0,2 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (856, 795) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['AM source', 'demod', 'demod scope'] + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (904, 11) + + + _rotation + 0 + + + + variable_slider + + id + fcarr + + + _enabled + True + + + label + Carrier frequency + + + value + 40e3 + + + min + 0 + + + max + samp_rate/2 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (512, 11) + + + _rotation + 0 + + + + variable_slider + + id + gain + + + _enabled + True + + + label + Gain + + + value + 1.0 + + + min + 0 + + + max + 1.0 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (664, 11) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0_0 + + + _enabled + True + + + type + cf + + + commandline + csdr amdemod_estimator_cf + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (336, 747) + + + _rotation + 0 + + + + analog_sig_source_x_0 + blocks_add_const_vxx_0 + 0 + 0 + + + analog_sig_source_x_0_0 + blocks_multiply_xx_0 + 0 + 1 + + + blocks_add_const_vxx_0 + blocks_multiply_xx_0 + 0 + 0 + + + blocks_throttle_0 + freq_xlating_fir_filter_xxx_0 + 0 + 0 + + + freq_xlating_fir_filter_xxx_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_0 + 0 + 0 + + + freq_xlating_fir_filter_xxx_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0_0_0 + 0 + 0 + + + ha5kfu_execproc_xx_0_0 + wxgui_fftsink2_0_0_0_0 + 0 + 0 + + + freq_xlating_fir_filter_xxx_0 + ha5kfu_execproc_xx_0_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0_0 + wxgui_scopesink2_0_0 + 0 + 0 + + + blocks_multiply_xx_0 + blocks_multiply_const_vxx_0 + 0 + 0 + + + blocks_multiply_const_vxx_0 + blocks_throttle_0 + 0 + 0 + + diff --git a/grc_tests/test_bandpass_fir_fft.grc b/grc_tests/test_bandpass_fir_fft.grc new file mode 100644 index 0000000..0d2bc4d --- /dev/null +++ b/grc_tests/test_bandpass_fir_fft.grc @@ -0,0 +1,785 @@ + + + + Sat Nov 22 11:19:26 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (24, 11) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 24e3 + + + alias + + + + _coordinate + (184, 11) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + complex + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + freq + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (128, 83) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + complex + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (312, 147) + + + _rotation + 0 + + + + variable_slider + + id + freq + + + _enabled + True + + + label + + + + value + 1e3 + + + min + -samp_rate/2 + + + max + samp_rate/2 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (8, 83) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + complex + + + title + FFT Plot of original signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (504, 219) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + complex + + + title + Scope Plot of original signal + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (504, 435) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0_0 + + + _enabled + True + + + type + complex + + + title + Scope Plot of new signal + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb1,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (784, 283) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + complex + + + title + FFT Plot of new signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb1,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (784, 67) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 1,1,1,1 + + + notebook + + + + alias + + + + _coordinate + (272, 11) + + + _rotation + 0 + + + + notebook + + id + nb1 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 1,2,1,1 + + + notebook + + + + alias + + + + _coordinate + (416, 11) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + cc + + + commandline + csdr bandpass_fir_fft_cc 0.1 0.5 0.05 HAMMING + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (488, 147) + + + _rotation + 0 + + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_scopesink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0_0 + 0 + 0 + + diff --git a/grc_tests/test_bandpass_fir_fft_via_fifo.grc b/grc_tests/test_bandpass_fir_fft_via_fifo.grc new file mode 100644 index 0000000..f28732a --- /dev/null +++ b/grc_tests/test_bandpass_fir_fft_via_fifo.grc @@ -0,0 +1,812 @@ + + + + Tue Nov 18 16:42:38 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (24, 11) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 24e3 + + + alias + + + + _coordinate + (184, 11) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + complex + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + freq + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (128, 83) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + complex + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (312, 147) + + + _rotation + 0 + + + + variable_slider + + id + freq + + + _enabled + True + + + label + + + + value + 1e3 + + + min + -samp_rate/2 + + + max + samp_rate/2 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (8, 83) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + complex + + + title + FFT Plot of original signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (504, 219) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + complex + + + title + Scope Plot of original signal + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (504, 435) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0_0 + + + _enabled + True + + + type + complex + + + title + Scope Plot of new signal + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb1,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (784, 283) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + complex + + + title + FFT Plot of new signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb1,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (784, 67) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 1,1,1,1 + + + notebook + + + + alias + + + + _coordinate + (272, 11) + + + _rotation + 0 + + + + notebook + + id + nb1 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 1,2,1,1 + + + notebook + + + + alias + + + + _coordinate + (416, 11) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + cc + + + commandline + csdr bandpass_fir_fft_cc --fifo /tmp/csdr-fifo 0.05 HAMMING + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (488, 147) + + + _rotation + 0 + + + + note + + id + note_0 + + + _enabled + True + + + note + /tmp/csdr-fifo + + + alias + + + + _coordinate + (968, 67) + + + _rotation + 0 + + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_scopesink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0_0 + 0 + 0 + + diff --git a/grc_tests/test_conversions.grc b/grc_tests/test_conversions.grc new file mode 100644 index 0000000..0f4a9ae --- /dev/null +++ b/grc_tests/test_conversions.grc @@ -0,0 +1,846 @@ + + + + Sat Nov 15 20:02:09 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 32000 + + + alias + + + + _coordinate + (184, 11) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + frequency + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (56, 139) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + float + + + title + FFT Plot (float -> u8 -> float conversion) + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + window.hamming + + + win_size + + + + grid_pos + + + + notebook + nb1,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (680, 579) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0_0 + + + _enabled + True + + + type + float + + + title + Scope Plot (float -> u8 -> float conversion) + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 2 + + + win_size + + + + grid_pos + + + + notebook + nb1,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (680, 459) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + float + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (224, 171) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + float + + + title + FFT Plot (float -> i16 -> float conversion) + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (680, 251) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + float + + + title + Scope Plot (float -> i16 -> float conversion) + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 2 + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (680, 131) + + + _rotation + 0 + + + + notebook + + id + nb1 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (536, 11) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (400, 11) + + + _rotation + 0 + + + + variable_slider + + id + frequency + + + _enabled + True + + + label + + + + value + 4e3 + + + min + 0 + + + max + samp_rate/2 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (280, 11) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + ff + + + commandline + csdr convert_f_i16 | csdr convert_i16_f + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (384, 171) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0_0 + + + _enabled + True + + + type + ff + + + commandline + csdr convert_f_u8 | csdr convert_u8_f + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (384, 499) + + + _rotation + 0 + + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_scopesink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0 + 0 + 1 + + + ha5kfu_execproc_xx_0_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + ha5kfu_execproc_xx_0_0 + wxgui_scopesink2_0_0 + 0 + 1 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_scopesink2_0_0 + 0 + 0 + + diff --git a/grc_tests/test_dcblock.grc b/grc_tests/test_dcblock.grc new file mode 100644 index 0000000..2950698 --- /dev/null +++ b/grc_tests/test_dcblock.grc @@ -0,0 +1,708 @@ + + + + Sun Nov 23 19:16:09 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 250e3 + + + alias + + + + _coordinate + (10, 170) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['dcblock_ff processed','fastdcblock_ff processed', 'original'] + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (256, 27) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + float + + + title + FFT Plot + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 512 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,2 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (592, 27) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + float + + + title + FFT Plot + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 512 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (592, 259) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_1 + + + _enabled + True + + + type + float + + + title + FFT Plot + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 512 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (592, 475) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + float + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (152, 211) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0_0 + + + _enabled + True + + + type + ff + + + commandline + csdr fastdcblock_ff + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (336, 555) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + ff + + + commandline + csdr dcblock_ff + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (336, 331) + + + _rotation + 0 + + + + blocks_add_const_vxx + + id + blocks_add_const_vxx_0 + + + _enabled + True + + + type + float + + + const + 0.8 + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (136, 291) + + + _rotation + 0 + + + + analog_noise_source_x + + id + analog_noise_source_x_0 + + + _enabled + True + + + type + float + + + noise_type + analog.GR_GAUSSIAN + + + amp + 0.1 + + + seed + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (112, 379) + + + _rotation + 0 + + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + analog_noise_source_x_0 + blocks_add_const_vxx_0 + 0 + 0 + + + blocks_add_const_vxx_0 + blocks_throttle_0 + 0 + 0 + + + ha5kfu_execproc_xx_0_0 + wxgui_fftsink2_0_1 + 0 + 0 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0_0 + 0 + 0 + + diff --git a/grc_tests/test_debug_gr_agc2.grc b/grc_tests/test_debug_gr_agc2.grc new file mode 100644 index 0000000..f25d0d4 --- /dev/null +++ b/grc_tests/test_debug_gr_agc2.grc @@ -0,0 +1,491 @@ + + + + Tue Oct 14 22:43:27 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 48000 + + + alias + + + + _coordinate + (10, 170) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + 5000 + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (32, 267) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_SQR_WAVE + + + freq + 1 + + + amp + 0.9 + + + offset + 0.1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (152, 131) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + float + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (264, 299) + + + _rotation + 0 + + + + blocks_multiply_xx + + id + blocks_multiply_xx_0 + + + _enabled + True + + + type + float + + + num_inputs + 2 + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (488, 256) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + float + + + title + Scope Plot + + + samp_rate + samp_rate + + + v_scale + 0.3 + + + v_offset + 0 + + + t_scale + 0.1 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 3 + + + win_size + + + + grid_pos + + + + notebook + + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (1048, 128) + + + _rotation + 0 + + + + ha5kfu_agc2_debug + + id + ha5kfu_agc2_debug_0 + + + _enabled + True + + + attack_rate + 0.100 + + + decay_rate + 0.01 + + + ref + 1 + + + gain + 1 + + + max_gain + 65536 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (712, 331) + + + _rotation + 0 + + + + analog_sig_source_x_0_0 + blocks_multiply_xx_0 + 0 + 0 + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + blocks_multiply_xx_0 + 0 + 1 + + + analog_sig_source_x_0_0 + wxgui_scopesink2_0 + 0 + 0 + + + blocks_multiply_xx_0 + wxgui_scopesink2_0 + 0 + 1 + + + blocks_multiply_xx_0 + ha5kfu_agc2_debug_0 + 0 + 0 + + + ha5kfu_agc2_debug_0 + wxgui_scopesink2_0 + 0 + 2 + + diff --git a/grc_tests/test_deemphasis_nfm.grc b/grc_tests/test_deemphasis_nfm.grc new file mode 100644 index 0000000..4066144 --- /dev/null +++ b/grc_tests/test_deemphasis_nfm.grc @@ -0,0 +1,808 @@ + + + + Sat Nov 15 22:44:05 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (24, 11) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 48000 + + + alias + + + + _coordinate + (184, 11) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 1,1,1,1 + + + notebook + + + + alias + + + + _coordinate + (272, 11) + + + _rotation + 0 + + + + notebook + + id + nb1 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 1,2,1,1 + + + notebook + + + + alias + + + + _coordinate + (416, 11) + + + _rotation + 0 + + + + variable_slider + + id + freq + + + _enabled + True + + + label + + + + value + 1e3 + + + min + 0 + + + max + samp_rate/2 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (8, 83) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + float + + + title + FFT Plot of new signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb1,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (784, 67) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0_0 + + + _enabled + True + + + type + float + + + title + Scope Plot of new signal + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb1,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (784, 283) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + float + + + title + FFT Plot of original signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (504, 219) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + float + + + title + Scope Plot of original signal + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (504, 435) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + ff + + + commandline + "csdr deemphasis_nfm_ff %d"%samp_rate + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (488, 147) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + float + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (312, 147) + + + _rotation + 0 + + + + analog_fastnoise_source_x + + id + analog_fastnoise_source_x_0 + + + _enabled + True + + + type + float + + + noise_type + analog.GR_GAUSSIAN + + + amp + 1 + + + seed + 0 + + + samples + 8192 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (120, 123) + + + _rotation + 0 + + + + note + + id + note_0 + + + _enabled + True + + + note + set Peak Hold on the FFT plot of new signal, so you will see the filter characteristics + + + alias + + + + _coordinate + (784, 19) + + + _rotation + 0 + + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_scopesink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0_0 + 0 + 0 + + + analog_fastnoise_source_x_0 + blocks_throttle_0 + 0 + 0 + + diff --git a/grc_tests/test_deemphasis_wfm.grc b/grc_tests/test_deemphasis_wfm.grc new file mode 100644 index 0000000..b26ce7f --- /dev/null +++ b/grc_tests/test_deemphasis_wfm.grc @@ -0,0 +1,785 @@ + + + + Sat Nov 15 22:23:43 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (24, 11) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 32e3 + + + alias + + + + _coordinate + (184, 11) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 1,1,1,1 + + + notebook + + + + alias + + + + _coordinate + (272, 11) + + + _rotation + 0 + + + + notebook + + id + nb1 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 1,2,1,1 + + + notebook + + + + alias + + + + _coordinate + (416, 11) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + freq + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (128, 83) + + + _rotation + 0 + + + + variable_slider + + id + freq + + + _enabled + True + + + label + + + + value + 1e3 + + + min + 0 + + + max + samp_rate/2 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (8, 83) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + float + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (312, 147) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + float + + + title + FFT Plot of new signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb1,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (784, 67) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0_0 + + + _enabled + True + + + type + float + + + title + Scope Plot of new signal + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb1,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (784, 283) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + float + + + title + FFT Plot of original signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (504, 219) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + float + + + title + Scope Plot of original signal + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (504, 435) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + ff + + + commandline + "csdr deemphasis_wfm_ff %d 75e-6"%samp_rate + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (488, 147) + + + _rotation + 0 + + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_scopesink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0_0 + 0 + 0 + + diff --git a/grc_tests/test_fft_grc.grc b/grc_tests/test_fft_grc.grc new file mode 100644 index 0000000..7e764ea --- /dev/null +++ b/grc_tests/test_fft_grc.grc @@ -0,0 +1,520 @@ + + + + Sat Nov 15 20:04:47 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 32000 + + + alias + + + + _coordinate + (10, 170) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + complex + + + samp_rate + samp_rate + + + waveform + analog.GR_SIN_WAVE + + + freq + frequency + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (56, 299) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + complex + + + title + FFT Plot + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (488, 75) + + + _rotation + 0 + + + + blocks_complex_to_float + + id + blocks_complex_to_float_0 + + + _enabled + True + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (464, 320) + + + _rotation + 0 + + + + blocks_stream_mux + + id + blocks_stream_mux_0 + + + _enabled + True + + + type + float + + + lengths + 1, 1 + + + num_inputs + 2 + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (632, 320) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + complex + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (248, 331) + + + _rotation + 0 + + + + variable_slider + + id + frequency + + + _enabled + True + + + label + + + + value + 1e3 + + + min + -samp_rate/2 + + + max + samp_rate/2 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (184, 11) + + + _rotation + 0 + + + + ha5kfu_execproc_sink_f + + id + ha5kfu_execproc_sink_f_0 + + + _enabled + True + + + commandline + csdr fft_cc 512 5120 HAMMING --octave | octave -i + + + alias + + + + affinity + + + + _coordinate + (808, 331) + + + _rotation + 0 + + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_0 + 0 + 0 + + + blocks_throttle_0 + blocks_complex_to_float_0 + 0 + 0 + + + blocks_complex_to_float_0 + blocks_stream_mux_0 + 0 + 0 + + + blocks_complex_to_float_0 + blocks_stream_mux_0 + 1 + 1 + + + blocks_stream_mux_0 + ha5kfu_execproc_sink_f_0 + 0 + 0 + + diff --git a/grc_tests/test_fmdemod.grc b/grc_tests/test_fmdemod.grc new file mode 100644 index 0000000..6892efc --- /dev/null +++ b/grc_tests/test_fmdemod.grc @@ -0,0 +1,719 @@ + + + + Sat Nov 15 20:06:19 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 250000 + + + alias + + + + _coordinate + (9, 170) + + + _rotation + 0 + + + + wxgui_waterfallsink2 + + id + wxgui_waterfallsink2_0 + + + _enabled + True + + + type + complex + + + title + Waterfall Plot + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + dynamic_range + 100 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 512 + + + fft_rate + 500 + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (713, 407) + + + _rotation + 0 + + + + analog_fm_demod_cf + + id + analog_fm_demod_cf_0 + + + _enabled + True + + + chan_rate + samp_rate + + + audio_decim + 1 + + + deviation + 75000 + + + audio_pass + 15000 + + + audio_stop + 16000 + + + gain + 27 + + + tau + 75e-6 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (725, 248) + + + _rotation + 0 + + + + analog_frequency_modulator_fc + + id + analog_frequency_modulator_fc_0 + + + _enabled + True + + + sensitivity + 3.141592654 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (510, 403) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + float + + + title + Scope Plot + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 5 + + + win_size + + + + grid_pos + + + + notebook + + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (1117, 9) + + + _rotation + 0 + + + + ha5kfu_debug_minmax_f + + id + ha5kfu_debug_minmax_f_0 + + + _enabled + True + + + samplecount + 0 + + + alias + + + + affinity + + + + _coordinate + (1056, 427) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + 1000 + + + amp + 0.2 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (224, 29) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + float + + + samples_per_second + samp_rate/5 + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (684, 27) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0_1 + + + _enabled + True + + + type + cf + + + commandline + csdr fmdemod_quadri_novect_cf + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (760, 723) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0_0 + + + _enabled + True + + + type + cf + + + commandline + csdr fmdemod_quadri_cf + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (760, 667) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + cf + + + commandline + csdr fmdemod_atan_cf + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (760, 611) + + + _rotation + 0 + + + + blocks_throttle_0 + analog_frequency_modulator_fc_0 + 0 + 0 + + + analog_frequency_modulator_fc_0 + wxgui_waterfallsink2_0 + 0 + 0 + + + analog_frequency_modulator_fc_0 + analog_fm_demod_cf_0 + 0 + 0 + + + analog_fm_demod_cf_0 + wxgui_scopesink2_0 + 0 + 1 + + + blocks_throttle_0 + wxgui_scopesink2_0 + 0 + 0 + + + analog_frequency_modulator_fc_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + analog_frequency_modulator_fc_0 + ha5kfu_execproc_xx_0_0 + 0 + 0 + + + analog_frequency_modulator_fc_0 + ha5kfu_execproc_xx_0_1 + 0 + 0 + + + ha5kfu_execproc_xx_0 + ha5kfu_debug_minmax_f_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0 + 0 + 2 + + + ha5kfu_execproc_xx_0_0 + wxgui_scopesink2_0 + 0 + 3 + + + ha5kfu_execproc_xx_0_1 + wxgui_scopesink2_0 + 0 + 4 + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + diff --git a/grc_tests/test_fractional_decimator.grc b/grc_tests/test_fractional_decimator.grc new file mode 100644 index 0000000..3b587fe --- /dev/null +++ b/grc_tests/test_fractional_decimator.grc @@ -0,0 +1,1125 @@ + + + + Tue Nov 25 18:16:05 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + decimation + + + _enabled + True + + + value + 3.2 + + + alias + + + + _coordinate + (376, 11) + + + _rotation + 0 + + + + variable + + id + samp_rate_2 + + + _enabled + True + + + value + samp_rate/decimation + + + alias + + + + _coordinate + (272, 11) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 240000 + + + alias + + + + _coordinate + (176, 11) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + input_freq + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (8, 83) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_1 + + + _enabled + True + + + type + float + + + title + Original signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb1,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (360, 355) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + ff + + + commandline + "csdr fractional_decimator_ff "+str(decimation) + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (352, 115) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0_0 + + + _enabled + True + + + type + float + + + title + Original signal + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb1,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (360, 235) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + float + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (168, 115) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + float + + + title + Resampled signal (csdr) + + + samp_rate + samp_rate_2 + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (640, 235) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + float + + + title + Resampled signal (csdr) + + + samp_rate + samp_rate_2 + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (640, 115) + + + _rotation + 0 + + + + fractional_resampler_xx + + id + fractional_resampler_xx_0 + + + _enabled + True + + + type + float + + + phase_shift + 0 + + + resamp_ratio + decimation + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (360, 608) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0_1 + + + _enabled + True + + + type + float + + + title + Resampled signal (GNU Radio) + + + samp_rate + samp_rate_2 + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb2,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (640, 459) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + float + + + title + Resampled signal (GNU Radio) + + + samp_rate + samp_rate_2 + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb2,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (640, 579) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope','fft'] + + + grid_pos + 1,2,1,1 + + + notebook + + + + alias + + + + _coordinate + (16, 683) + + + _rotation + 0 + + + + notebook + + id + nb1 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope','fft'] + + + grid_pos + 1,1,1,1 + + + notebook + + + + alias + + + + _coordinate + (16, 579) + + + _rotation + 0 + + + + notebook + + id + nb2 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope','fft'] + + + grid_pos + 2,2,1,1 + + + notebook + + + + alias + + + + _coordinate + (16, 475) + + + _rotation + 0 + + + + variable_slider + + id + input_freq + + + _enabled + True + + + label + + + + value + 4e3 + + + min + 0 + + + max + samp_rate/2 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (16, 355) + + + _rotation + 0 + + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0 + 0 + 0 + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_scopesink2_0_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_1 + 0 + 0 + + + blocks_throttle_0 + fractional_resampler_xx_0 + 0 + 0 + + + fractional_resampler_xx_0 + wxgui_scopesink2_0_1 + 0 + 0 + + + fractional_resampler_xx_0 + wxgui_fftsink2_0_0 + 0 + 0 + + diff --git a/grc_tests/test_rational_resampler.grc b/grc_tests/test_rational_resampler.grc new file mode 100644 index 0000000..7bb2e71 --- /dev/null +++ b/grc_tests/test_rational_resampler.grc @@ -0,0 +1,1133 @@ + + + + Tue Nov 25 18:15:25 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + decimation + + + _enabled + True + + + value + 2 + + + alias + + + + _coordinate + (376, 11) + + + _rotation + 0 + + + + variable + + id + interpolation + + + _enabled + True + + + value + 5 + + + alias + + + + _coordinate + (272, 11) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 32000 + + + alias + + + + _coordinate + (176, 11) + + + _rotation + 0 + + + + variable_slider + + id + frequency + + + _enabled + True + + + label + + + + value + 1e3 + + + min + 0 + + + max + samp_rate/2 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (480, 11) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + float + + + title + Original signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (752, 379) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + float + + + title + Original signal + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (752, 259) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + float + + + title + Resampled signal (csdr) + + + samp_rate + samp_rate*(interpolation/float(decimation)) + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb1,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (984, 195) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_1 + + + _enabled + True + + + type + float + + + title + Resampled signal (csdr) + + + samp_rate + samp_rate*(interpolation/float(decimation)) + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb1,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (984, 75) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + float + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (312, 243) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + float + + + samp_rate + samp_rate + + + waveform + analog.GR_SIN_WAVE + + + freq + frequency + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (104, 211) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 1,1,1,1 + + + notebook + + + + alias + + + + _coordinate + (8, 75) + + + _rotation + 0 + + + + notebook + + id + nb1 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 1,2,1,1 + + + notebook + + + + alias + + + + _coordinate + (152, 75) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_1_0 + + + _enabled + True + + + type + float + + + title + Resampled signal (GNU Radio) + + + samp_rate + samp_rate*(interpolation/float(decimation)) + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb2,0 + + + trig_mode + wxgui.TRIG_MODE_AUTO + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (760, 603) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0_0 + + + _enabled + True + + + type + float + + + title + Resampled signal (GNU Radio) + + + samp_rate + samp_rate*(interpolation/float(decimation)) + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb2,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (760, 723) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + ff + + + commandline + "csdr rational_resampler_ff %d %d 0.05"%(interpolation,decimation) + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (752, 195) + + + _rotation + 0 + + + + notebook + + id + nb2 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['scope', 'fft'] + + + grid_pos + 2,2,1,1 + + + notebook + + + + alias + + + + _coordinate + (296, 75) + + + _rotation + 0 + + + + rational_resampler_xxx + + id + rational_resampler_xxx_0 + + + _enabled + True + + + type + fff + + + interp + interpolation + + + decim + decimation + + + taps + firdes.low_pass(5,1,0.5*min(1./interpolation,1./decimation),0.05) + + + fbw + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (496, 611) + + + _rotation + 0 + + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_1 + 0 + 0 + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_scopesink2_0 + 0 + 0 + + + blocks_throttle_0 + rational_resampler_xxx_0 + 0 + 0 + + + rational_resampler_xxx_0 + wxgui_scopesink2_1_0 + 0 + 0 + + + rational_resampler_xxx_0 + wxgui_fftsink2_0_0_0 + 0 + 0 + + diff --git a/grc_tests/test_shift.grc b/grc_tests/test_shift.grc new file mode 100644 index 0000000..5f5a9ab --- /dev/null +++ b/grc_tests/test_shift.grc @@ -0,0 +1,841 @@ + + + + Sat Nov 15 22:24:14 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 250e3 + + + alias + + + + _coordinate + (10, 170) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + complex + + + samp_rate + samp_rate + + + waveform + analog.GR_CONST_WAVE + + + freq + 20000 + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (56, 243) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + complex + + + title + FFT Plot + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (952, 275) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['shift_math_ff', 'shift_addition_ff', 'original'] + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (256, 27) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + complex + + + title + FFT Plot + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,2 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (952, 59) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_1 + + + _enabled + True + + + type + complex + + + title + FFT Plot + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (952, 635) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + complex + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (232, 275) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0 + + + _enabled + True + + + type + complex + + + title + Scope Plot + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + trig_mode + wxgui.TRIG_MODE_NORM + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (952, 491) + + + _rotation + 0 + + + + wxgui_scopesink2 + + id + wxgui_scopesink2_0_0 + + + _enabled + True + + + type + complex + + + title + Scope Plot + + + samp_rate + samp_rate + + + v_scale + 0 + + + v_offset + 0 + + + t_scale + 0 + + + ac_couple + False + + + xy_mode + False + + + num_inputs + 1 + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + trig_mode + wxgui.TRIG_MODE_NORM + + + y_axis_label + Counts + + + alias + + + + affinity + + + + _coordinate + (952, 875) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0 + + + _enabled + True + + + type + cc + + + commandline + csdr shift_math_cc -0.25 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (496, 483) + + + _rotation + 0 + + + + ha5kfu_execproc_xx + + id + ha5kfu_execproc_xx_0_0 + + + _enabled + True + + + type + cc + + + commandline + csdr shift_addition_cc -0.25 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (504, 635) + + + _rotation + 0 + + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_scopesink2_0 + 0 + 0 + + + ha5kfu_execproc_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0 + 0 + 0 + + + ha5kfu_execproc_xx_0_0 + wxgui_fftsink2_0_1 + 0 + 0 + + + blocks_throttle_0 + ha5kfu_execproc_xx_0_0 + 0 + 0 + + + ha5kfu_execproc_xx_0_0 + wxgui_scopesink2_0_0 + 0 + 0 + + diff --git a/grc_tests/test_ssb_concepts.grc b/grc_tests/test_ssb_concepts.grc new file mode 100644 index 0000000..0a27abd --- /dev/null +++ b/grc_tests/test_ssb_concepts.grc @@ -0,0 +1,1516 @@ + + + + Mon Oct 13 20:03:23 2014 + + options + + id + top_block + + + _enabled + True + + + title + + + + author + + + + description + + + + window_size + 1280, 1024 + + + generate_options + wx_gui + + + category + Custom + + + run_options + prompt + + + run + True + + + max_nouts + 0 + + + realtime_scheduling + + + + alias + + + + _coordinate + (10, 10) + + + _rotation + 0 + + + + variable + + id + samp_rate + + + _enabled + True + + + value + 100e3 + + + alias + + + + _coordinate + (184, 11) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0_0 + + + _enabled + True + + + type + complex + + + title + FIR filter with complex taps (complex output) + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,2 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (1112, 235) + + + _rotation + 0 + + + + blocks_complex_to_float + + id + blocks_complex_to_float_0 + + + _enabled + True + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (496, 64) + + + _rotation + 0 + + + + hilbert_fc + + id + hilbert_fc_0 + + + _enabled + True + + + num_taps + 65 + + + win + firdes.WIN_HAMMING + + + beta + 6.76 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (672, 91) + + + _rotation + 0 + + + + blocks_null_sink + + id + blocks_null_sink_0 + + + _enabled + True + + + type + float + + + vlen + 1 + + + num_inputs + 1 + + + bus_conns + [[0,],] + + + alias + + + + affinity + + + + _coordinate + (1016, 24) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0 + + + _enabled + True + + + type + float + + + title + Hilbert transformer + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,0 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (1128, 11) + + + _rotation + 0 + + + + blocks_complex_to_float + + id + blocks_complex_to_float_0_0 + + + _enabled + True + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (816, 80) + + + _rotation + 0 + + + + blocks_sub_xx + + id + blocks_sub_xx_0 + + + _enabled + True + + + type + float + + + vlen + 1 + + + num_inputs + 2 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (1016, 80) + + + _rotation + 0 + + + + blocks_delay + + id + blocks_delay_0 + + + _enabled + True + + + type + float + + + delay + 65/2 + + + num_ports + 1 + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (888, 155) + + + _rotation + 0 + + + + blocks_throttle + + id + blocks_throttle_0 + + + _enabled + True + + + type + complex + + + samples_per_second + samp_rate + + + vlen + 1 + + + ignoretag + True + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (312, 147) + + + _rotation + 0 + + + + band_pass_filter + + id + band_pass_filter_0 + + + _enabled + True + + + type + fir_filter_ccc + + + decim + 1 + + + interp + 1 + + + gain + 1 + + + samp_rate + samp_rate + + + low_cutoff_freq + 0 + + + high_cutoff_freq + samp_rate/2-1 + + + width + 0.1*samp_rate + + + win + firdes.WIN_HAMMING + + + beta + 6.76 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (696, 259) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_0 + + + _enabled + True + + + type + complex + + + title + Input signal + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (280, 291) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_1 + + + _enabled + True + + + type + float + + + title + Hilbert transformer + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,1 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (1112, 459) + + + _rotation + 0 + + + + blocks_complex_to_real + + id + blocks_complex_to_real_0 + + + _enabled + True + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (928, 544) + + + _rotation + 0 + + + + blocks_complex_to_real + + id + blocks_complex_to_real_0_0 + + + _enabled + True + + + vlen + 1 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (784, 960) + + + _rotation + 0 + + + + wxgui_fftsink2 + + id + wxgui_fftsink2_0_1_0 + + + _enabled + True + + + type + float + + + title + Weaver output + + + samp_rate + samp_rate + + + baseband_freq + 0 + + + y_per_div + 10 + + + y_divs + 10 + + + ref_level + 0 + + + ref_scale + 2.0 + + + fft_size + 1024 + + + fft_rate + 15 + + + peak_hold + False + + + average + False + + + avg_alpha + 0 + + + win + None + + + win_size + + + + grid_pos + + + + notebook + nb0,3 + + + freqvar + None + + + alias + + + + affinity + + + + _coordinate + (960, 875) + + + _rotation + 0 + + + + freq_xlating_fir_filter_xxx + + id + freq_xlating_fir_filter_xxx_0 + + + _enabled + True + + + type + ccc + + + decim + 1 + + + taps + [1] + + + center_freq + samp_rate/4 + + + samp_rate + samp_rate + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (488, 707) + + + _rotation + 0 + + + + freq_xlating_fir_filter_xxx + + id + freq_xlating_fir_filter_xxx_0_0 + + + _enabled + True + + + type + ccc + + + decim + 1 + + + taps + [1] + + + center_freq + -samp_rate/4 + + + samp_rate + samp_rate + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (928, 723) + + + _rotation + 0 + + + + band_pass_filter + + id + band_pass_filter_0_0 + + + _enabled + True + + + type + fir_filter_ccf + + + decim + 1 + + + interp + 1 + + + gain + 1 + + + samp_rate + samp_rate + + + low_cutoff_freq + 1 + + + high_cutoff_freq + samp_rate/4 + + + width + 0.1*samp_rate + + + win + firdes.WIN_HAMMING + + + beta + 6.77 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (736, 675) + + + _rotation + 0 + + + + variable_slider + + id + freq + + + _enabled + True + + + label + + + + value + 50 + + + min + -samp_rate/2 + + + max + samp_rate/2 + + + num_steps + 100 + + + style + wx.SL_HORIZONTAL + + + converver + float_converter + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (8, 83) + + + _rotation + 0 + + + + analog_sig_source_x + + id + analog_sig_source_x_0 + + + _enabled + True + + + type + complex + + + samp_rate + samp_rate + + + waveform + analog.GR_COS_WAVE + + + freq + freq + + + amp + 1 + + + offset + 0 + + + alias + + + + affinity + + + + minoutbuf + 0 + + + maxoutbuf + 0 + + + _coordinate + (128, 83) + + + _rotation + 0 + + + + notebook + + id + nb0 + + + _enabled + True + + + style + wx.NB_TOP + + + labels + ['Hilbert', 'Complex FIR (cf)','Complex FIR (cc)','Weaver method'] + + + grid_pos + + + + notebook + + + + alias + + + + _coordinate + (280, 11) + + + _rotation + 0 + + + + analog_sig_source_x_0 + blocks_throttle_0 + 0 + 0 + + + blocks_throttle_0 + wxgui_fftsink2_0_0 + 0 + 0 + + + blocks_throttle_0 + blocks_complex_to_float_0 + 0 + 0 + + + band_pass_filter_0 + wxgui_fftsink2_0_0_0 + 0 + 0 + + + blocks_throttle_0 + band_pass_filter_0 + 0 + 0 + + + hilbert_fc_0 + blocks_complex_to_float_0_0 + 0 + 0 + + + blocks_sub_xx_0 + wxgui_fftsink2_0 + 0 + 0 + + + band_pass_filter_0 + blocks_complex_to_real_0 + 0 + 0 + + + blocks_complex_to_real_0 + wxgui_fftsink2_0_1 + 0 + 0 + + + blocks_complex_to_float_0 + blocks_delay_0 + 0 + 0 + + + blocks_complex_to_float_0 + hilbert_fc_0 + 1 + 0 + + + blocks_complex_to_float_0_0 + blocks_null_sink_0 + 0 + 0 + + + blocks_complex_to_float_0_0 + blocks_sub_xx_0 + 1 + 1 + + + blocks_delay_0 + blocks_sub_xx_0 + 0 + 0 + + + blocks_throttle_0 + freq_xlating_fir_filter_xxx_0 + 0 + 0 + + + freq_xlating_fir_filter_xxx_0 + band_pass_filter_0_0 + 0 + 0 + + + band_pass_filter_0_0 + freq_xlating_fir_filter_xxx_0_0 + 0 + 0 + + + blocks_complex_to_real_0_0 + wxgui_fftsink2_0_1_0 + 0 + 0 + + + freq_xlating_fir_filter_xxx_0_0 + blocks_complex_to_real_0_0 + 0 + 0 + + diff --git a/libcsdr.c b/libcsdr.c new file mode 100644 index 0000000..b90fe2a --- /dev/null +++ b/libcsdr.c @@ -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 +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 +#include +#include +#include +#include +#include +#include +#include "libcsdr.h" +#include "predefined.h" +#include + +/* + _ _ __ _ _ + (_) | | / _| | | (_) + __ ___ _ __ __| | _____ __ | |_ _ _ _ __ ___| |_ _ ___ _ __ ___ + \ \ /\ / / | '_ \ / _` |/ _ \ \ /\ / / | _| | | | '_ \ / __| __| |/ _ \| '_ \/ __| + \ 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;i2*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;i2*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; iinput_size) break; + float acci=0; + for(int ti=0; tiinput_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_interpolationoutput; + complexf* out = plan_inverse->input; + + for(int i=0;isize;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;isize;i++) //@apply_fir_fft_cc: normalize by fft_size + { + iof(result,i)/=plan->size; + qof(result,i)/=plan->size; + } + + for(int i=0;imax_iq) max_iq=abs_q; + float min_iq=abs_i; + if(abs_qinput_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_peakpeak_2) target_peak=input->peak_2; + if(target_peakpeak_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;iinput_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; iPI) 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 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;ioutput[i])?-max_amplitude:output[i]; + } +} + +void gain_ff(float* input, float* output, int input_size, float gain) +{ + for(int i=0;i>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< convert_u8_f +} + +void convert_f_i16(float* input, short* output, int input_size) +{ + /*for(int i=0;i1.0) input[i]=1.0; + if(input[i]<-1.0) input[i]=-1.0; + }*/ + for(int i=0;i +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); + + + + diff --git a/libcsdr_gpl.c b/libcsdr_gpl.c new file mode 100644 index 0000000..27a80ce --- /dev/null +++ b/libcsdr_gpl.c @@ -0,0 +1,197 @@ +/* +This file is part of libcsdr. + + Copyright (c) Andras Retzler, HA7ILM + Copyright (c) Warren Pratt, NR0V + 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 . + +*/ + +#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;iPI) 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;i2*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;i0) + { + 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 + diff --git a/libcsdr_gpl.h b/libcsdr_gpl.h new file mode 100644 index 0000000..98c0feb --- /dev/null +++ b/libcsdr_gpl.h @@ -0,0 +1,39 @@ +/* +This file is part of libcsdr. + + Copyright (c) Andras Retzler, HA7ILM + Copyright (c) Warren Pratt, NR0V + 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 . +*/ + +#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 + diff --git a/libcsdr_wrapper.c b/libcsdr_wrapper.c new file mode 100644 index 0000000..4ab53e3 --- /dev/null +++ b/libcsdr_wrapper.c @@ -0,0 +1,3 @@ +#include "libcsdr.c" +#include "libcsdr_gpl.c" +//this wrapper helps parsevect.py to generate better output diff --git a/parsevect b/parsevect new file mode 100755 index 0000000..f380e3b --- /dev/null +++ b/parsevect @@ -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 +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" + diff --git a/predefined.h b/predefined.h new file mode 100644 index 0000000..cc2d4da --- /dev/null +++ b/predefined.h @@ -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 +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 }; + diff --git a/recomp b/recomp new file mode 100755 index 0000000..3abafe6 --- /dev/null +++ b/recomp @@ -0,0 +1,4 @@ +#!/bin/bash +sudo killall csdr +make +sudo make install