diff options
Diffstat (limited to 'gr-analog')
95 files changed, 2666 insertions, 1093 deletions
diff --git a/gr-analog/CMakeLists.txt b/gr-analog/CMakeLists.txt index 4769ce7ac1..10a9976496 100644 --- a/gr-analog/CMakeLists.txt +++ b/gr-analog/CMakeLists.txt @@ -29,7 +29,7 @@ include(GrComponent) GR_REGISTER_COMPONENT("gr-analog" ENABLE_GR_ANALOG Boost_FOUND ENABLE_VOLK - ENABLE_GR_CORE + ENABLE_GNURADIO_RUNTIME ENABLE_GR_FFT ENABLE_GR_FILTER ) @@ -60,28 +60,28 @@ CPACK_COMPONENT("analog_runtime" GROUP "Analog" DISPLAY_NAME "Runtime" DESCRIPTION "Dynamic link libraries" - DEPENDS "core_runtime" + DEPENDS "runtime_runtime" ) CPACK_COMPONENT("analog_devel" GROUP "Analog" DISPLAY_NAME "Development" DESCRIPTION "C++ headers, package config, import libraries" - DEPENDS "core_devel" + DEPENDS "runtime_devel" ) CPACK_COMPONENT("analog_python" GROUP "Analog" DISPLAY_NAME "Python" DESCRIPTION "Python modules for runtime" - DEPENDS "core_python;analog_runtime" + DEPENDS "runtime_python;analog_runtime" ) CPACK_COMPONENT("analog_swig" GROUP "Analog" DISPLAY_NAME "SWIG" DESCRIPTION "SWIG development .i files" - DEPENDS "core_swig;analog_python;analog_devel" + DEPENDS "runtime_swig;analog_python;analog_devel" ) ######################################################################## @@ -95,6 +95,7 @@ if(ENABLE_PYTHON) add_subdirectory(python) add_subdirectory(grc) add_subdirectory(examples) + add_subdirectory(examples/tags) endif(ENABLE_PYTHON) ######################################################################## diff --git a/gr-analog/examples/CMakeLists.txt b/gr-analog/examples/CMakeLists.txt index 9476009869..f0f55b50c8 100644 --- a/gr-analog/examples/CMakeLists.txt +++ b/gr-analog/examples/CMakeLists.txt @@ -21,6 +21,7 @@ include(GrPython) # Base stuff GR_PYTHON_INSTALL(PROGRAMS + fmtest.py DESTINATION ${GR_PKG_ANALOG_EXAMPLES_DIR} COMPONENT "analog_python" ) diff --git a/gr-analog/examples/fmtest.py b/gr-analog/examples/fmtest.py new file mode 100755 index 0000000000..327da8eacb --- /dev/null +++ b/gr-analog/examples/fmtest.py @@ -0,0 +1,229 @@ +#!/usr/bin/env python +# +# Copyright 2009,2012,2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr +from gnuradio import blocks +from gnuradio import filter +from gnuradio import analog +from gnuradio import channels +import sys, math, time + +try: + import scipy + from scipy import fftpack +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + +try: + import pylab +except ImportError: + print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)." + sys.exit(1) + + +class fmtx(gr.hier_block2): + def __init__(self, lo_freq, audio_rate, if_rate): + + gr.hier_block2.__init__(self, "build_fm", + gr.io_signature(1, 1, gr.sizeof_float), + gr.io_signature(1, 1, gr.sizeof_gr_complex)) + + fmtx = analog.nbfm_tx(audio_rate, if_rate, max_dev=5e3, tau=75e-6) + + # Local oscillator + lo = analog.sig_source_c(if_rate, # sample rate + analog.GR_SIN_WAVE, # waveform type + lo_freq, # frequency + 1.0, # amplitude + 0) # DC Offset + mixer = blocks.multiply_cc() + + self.connect(self, fmtx, (mixer, 0)) + self.connect(lo, (mixer, 1)) + self.connect(mixer, self) + +class fmtest(gr.top_block): + def __init__(self): + gr.top_block.__init__(self) + + self._nsamples = 1000000 + self._audio_rate = 8000 + + # Set up N channels with their own baseband and IF frequencies + self._N = 5 + chspacing = 16000 + freq = [10, 20, 30, 40, 50] + f_lo = [0, 1*chspacing, -1*chspacing, 2*chspacing, -2*chspacing] + + self._if_rate = 4*self._N*self._audio_rate + + # Create a signal source and frequency modulate it + self.sum = blocks.add_cc() + for n in xrange(self._N): + sig = analog.sig_source_f(self._audio_rate, analog.GR_SIN_WAVE, freq[n], 0.5) + fm = fmtx(f_lo[n], self._audio_rate, self._if_rate) + self.connect(sig, fm) + self.connect(fm, (self.sum, n)) + + self.head = blocks.head(gr.sizeof_gr_complex, self._nsamples) + self.snk_tx = blocks.vector_sink_c() + self.channel = channels.channel_model(0.1) + + self.connect(self.sum, self.head, self.channel, self.snk_tx) + + + # Design the channlizer + self._M = 10 + bw = chspacing/2.0 + t_bw = chspacing/10.0 + self._chan_rate = self._if_rate / self._M + self._taps = filter.firdes.low_pass_2(1, self._if_rate, bw, t_bw, + attenuation_dB=100, + window=filter.firdes.WIN_BLACKMAN_hARRIS) + tpc = math.ceil(float(len(self._taps)) / float(self._M)) + + print "Number of taps: ", len(self._taps) + print "Number of channels: ", self._M + print "Taps per channel: ", tpc + + self.pfb = filter.pfb.channelizer_ccf(self._M, self._taps) + + self.connect(self.channel, self.pfb) + + # Create a file sink for each of M output channels of the filter and connect it + self.fmdet = list() + self.squelch = list() + self.snks = list() + for i in xrange(self._M): + self.fmdet.append(analog.nbfm_rx(self._audio_rate, self._chan_rate)) + self.squelch.append(analog.standard_squelch(self._audio_rate*10)) + self.snks.append(blocks.vector_sink_f()) + self.connect((self.pfb, i), self.fmdet[i], self.squelch[i], self.snks[i]) + + def num_tx_channels(self): + return self._N + + def num_rx_channels(self): + return self._M + +def main(): + + fm = fmtest() + + tstart = time.time() + fm.run() + tend = time.time() + + if 1: + fig1 = pylab.figure(1, figsize=(12,10), facecolor="w") + fig2 = pylab.figure(2, figsize=(12,10), facecolor="w") + fig3 = pylab.figure(3, figsize=(12,10), facecolor="w") + + Ns = 10000 + Ne = 100000 + + fftlen = 8192 + winfunc = scipy.blackman + + # Plot transmitted signal + fs = fm._if_rate + + d = fm.snk_tx.data()[Ns:Ns+Ne] + sp1_f = fig1.add_subplot(2, 1, 1) + + X,freq = sp1_f.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs, + window = lambda d: d*winfunc(fftlen), + visible=False) + X_in = 10.0*scipy.log10(abs(fftpack.fftshift(X))) + f_in = scipy.arange(-fs/2.0, fs/2.0, fs/float(X_in.size)) + p1_f = sp1_f.plot(f_in, X_in, "b") + sp1_f.set_xlim([min(f_in), max(f_in)+1]) + sp1_f.set_ylim([-120.0, 20.0]) + + sp1_f.set_title("Input Signal", weight="bold") + sp1_f.set_xlabel("Frequency (Hz)") + sp1_f.set_ylabel("Power (dBW)") + + Ts = 1.0/fs + Tmax = len(d)*Ts + + t_in = scipy.arange(0, Tmax, Ts) + x_in = scipy.array(d) + sp1_t = fig1.add_subplot(2, 1, 2) + p1_t = sp1_t.plot(t_in, x_in.real, "b-o") + #p1_t = sp1_t.plot(t_in, x_in.imag, "r-o") + sp1_t.set_ylim([-5, 5]) + + # Set up the number of rows and columns for plotting the subfigures + Ncols = int(scipy.floor(scipy.sqrt(fm.num_rx_channels()))) + Nrows = int(scipy.floor(fm.num_rx_channels() / Ncols)) + if(fm.num_rx_channels() % Ncols != 0): + Nrows += 1 + + # Plot each of the channels outputs. Frequencies on Figure 2 and + # time signals on Figure 3 + fs_o = fm._audio_rate + for i in xrange(len(fm.snks)): + # remove issues with the transients at the beginning + # also remove some corruption at the end of the stream + # this is a bug, probably due to the corner cases + d = fm.snks[i].data()[Ns:Ne] + + sp2_f = fig2.add_subplot(Nrows, Ncols, 1+i) + X,freq = sp2_f.psd(d, NFFT=fftlen, noverlap=fftlen/4, Fs=fs_o, + window = lambda d: d*winfunc(fftlen), + visible=False) + #X_o = 10.0*scipy.log10(abs(fftpack.fftshift(X))) + X_o = 10.0*scipy.log10(abs(X)) + #f_o = scipy.arange(-fs_o/2.0, fs_o/2.0, fs_o/float(X_o.size)) + f_o = scipy.arange(0, fs_o/2.0, fs_o/2.0/float(X_o.size)) + p2_f = sp2_f.plot(f_o, X_o, "b") + sp2_f.set_xlim([min(f_o), max(f_o)+0.1]) + sp2_f.set_ylim([-120.0, 20.0]) + sp2_f.grid(True) + + sp2_f.set_title(("Channel %d" % i), weight="bold") + sp2_f.set_xlabel("Frequency (kHz)") + sp2_f.set_ylabel("Power (dBW)") + + + Ts = 1.0/fs_o + Tmax = len(d)*Ts + t_o = scipy.arange(0, Tmax, Ts) + + x_t = scipy.array(d) + sp2_t = fig3.add_subplot(Nrows, Ncols, 1+i) + p2_t = sp2_t.plot(t_o, x_t.real, "b") + p2_t = sp2_t.plot(t_o, x_t.imag, "r") + sp2_t.set_xlim([min(t_o), max(t_o)+1]) + sp2_t.set_ylim([-1, 1]) + + sp2_t.set_xlabel("Time (s)") + sp2_t.set_ylabel("Amplitude") + + + pylab.show() + + +if __name__ == "__main__": + main() diff --git a/gr-analog/python/qa_lfsr.py b/gr-analog/examples/tags/CMakeLists.txt index 2a8167a571..ba95100665 100755..100644 --- a/gr-analog/python/qa_lfsr.py +++ b/gr-analog/examples/tags/CMakeLists.txt @@ -1,5 +1,3 @@ -#!/usr/bin/env python -# # Copyright 2012 Free Software Foundation, Inc. # # This file is part of GNU Radio @@ -18,32 +16,11 @@ # along with GNU Radio; see the file COPYING. If not, write to # the Free Software Foundation, Inc., 51 Franklin Street, # Boston, MA 02110-1301, USA. -# - -from gnuradio import gr, gr_unittest -import analog_swig as analog -import math - - -class test_lfsr(gr_unittest.TestCase): - - def setUp(self): - pass - - def tearDown(self): - pass - - def test_lfsr_001(self): - reglen = 8 - l = analog.lfsr(1, 1, reglen) - - result_data = [] - for i in xrange(4*(reglen+1)): - result_data.append(l.next_bit()) - - expected_result = 4*([1,] + reglen*[0,]) - self.assertFloatTuplesAlmostEqual(expected_result, result_data, 5) -if __name__ == '__main__': - gr_unittest.run(test_lfsr, "test_lfsr.xml") +include(GrPython) +GR_PYTHON_INSTALL(PROGRAMS + uhd_burst_detector.py + DESTINATION ${GR_PKG_DATA_DIR}/examples/tags + COMPONENT "runtime_python" +) diff --git a/gr-analog/examples/tags/uhd_burst_detector.py b/gr-analog/examples/tags/uhd_burst_detector.py new file mode 100755 index 0000000000..b1bb15b974 --- /dev/null +++ b/gr-analog/examples/tags/uhd_burst_detector.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python +# +# Copyright 2012,2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import eng_notation +from gnuradio import gr +from gnuradio import filter, analog, blocks +from gnuradio import uhd +from gnuradio.fft import window +from gnuradio.eng_option import eng_option +from gnuradio.filter import firdes +from optparse import OptionParser + +class uhd_burst_detector(gr.top_block): + def __init__(self, uhd_address, options): + + gr.top_block.__init__(self) + + self.uhd_addr = uhd_address + self.freq = options.freq + self.samp_rate = options.samp_rate + self.gain = options.gain + self.threshold = options.threshold + self.trigger = options.trigger + + self.uhd_src = uhd.single_usrp_source( + device_addr=self.uhd_addr, + stream_args=uhd.stream_args('fc32')) + + self.uhd_src.set_samp_rate(self.samp_rate) + self.uhd_src.set_center_freq(self.freq, 0) + self.uhd_src.set_gain(self.gain, 0) + + taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60) + self.chanfilt = filter.fir_filter_ccc(10, taps) + self.tagger = blocks.burst_tagger(gr.sizeof_gr_complex) + + # Dummy signaler to collect a burst on known periods + data = 1000*[0,] + 1000*[1,] + self.signal = blocks.vector_source_s(data, True) + + # Energy detector to get signal burst + ## use squelch to detect energy + self.det = analog.simple_squelch_cc(self.threshold, 0.01) + ## convert to mag squared (float) + self.c2m = blocks.complex_to_mag_squared() + ## average to debounce + self.avg = filter.single_pole_iir_filter_ff(0.01) + ## rescale signal for conversion to short + self.scale = blocks.multiply_const_ff(2**16) + ## signal input uses shorts + self.f2s = blocks.float_to_short() + + # Use file sink burst tagger to capture bursts + self.fsnk = blocks.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate) + + + ################################################## + # Connections + ################################################## + self.connect((self.uhd_src, 0), (self.tagger, 0)) + self.connect((self.tagger, 0), (self.fsnk, 0)) + + if self.trigger: + # Connect a dummy signaler to the burst tagger + self.connect((self.signal, 0), (self.tagger, 1)) + + else: + # Connect an energy detector signaler to the burst tagger + self.connect(self.uhd_src, self.det) + self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s) + self.connect(self.f2s, (self.tagger, 1)) + + def set_samp_rate(self, samp_rate): + self.samp_rate = samp_rate + self.uhd_src_0.set_samp_rate(self.samp_rate) + +if __name__ == '__main__': + parser = OptionParser(option_class=eng_option, usage="%prog: [options]") + parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2", + help="select address of the device [default=%default]") + #parser.add_option("-A", "--antenna", default=None, + # help="select Rx Antenna (only on RFX-series boards)") + parser.add_option("-f", "--freq", type="eng_float", default=450e6, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=0, + help="set gain in dB [default=%default]") + parser.add_option("-R", "--samp-rate", type="eng_float", default=200000, + help="set USRP sample rate [default=%default]") + parser.add_option("-t", "--threshold", type="float", default=-60, + help="Set the detection power threshold (dBm) [default=%default") + parser.add_option("-T", "--trigger", action="store_true", default=False, + help="Use internal trigger instead of detector [default=%default]") + (options, args) = parser.parse_args() + + uhd_addr = options.address + + tb = uhd_burst_detector(uhd_addr, options) + tb.run() diff --git a/gr-analog/gnuradio-analog.pc.in b/gr-analog/gnuradio-analog.pc.in index 675c7ee20a..2461fc3fdd 100644 --- a/gr-analog/gnuradio-analog.pc.in +++ b/gr-analog/gnuradio-analog.pc.in @@ -5,7 +5,7 @@ includedir=@includedir@ Name: gnuradio-analog Description: GNU Radio blocks for analog communications -Requires: gnuradio-core +Requires: gnuradio-runtime Version: @LIBVER@ Libs: -L${libdir} -lgnuradio-analog Cflags: -I${includedir} diff --git a/gr-analog/grc/analog_am_demod_cf.xml b/gr-analog/grc/analog_am_demod_cf.xml new file mode 100644 index 0000000000..b066882bda --- /dev/null +++ b/gr-analog/grc/analog_am_demod_cf.xml @@ -0,0 +1,47 @@ +<?xml version="1.0"?> +<!-- +################################################### +##AM Demod +################################################### + --> +<block> + <name>AM Demod</name> + <key>analog_am_demod_cf</key> + <import>from gnuradio import analog</import> + <make>analog.am_demod_cf( + channel_rate=$chan_rate, + audio_decim=$audio_decim, + audio_pass=$audio_pass, + audio_stop=$audio_stop, +)</make> + <param> + <name>Channel Rate</name> + <key>chan_rate</key> + <type>real</type> + </param> + <param> + <name>Audio Decimation</name> + <key>audio_decim</key> + <type>int</type> + </param> + <param> + <name>Audio Pass</name> + <key>audio_pass</key> + <value>5000</value> + <type>real</type> + </param> + <param> + <name>Audio Stop</name> + <key>audio_stop</key> + <value>5500</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_block_tree.xml b/gr-analog/grc/analog_block_tree.xml index 3991aee915..cf58b3696b 100644 --- a/gr-analog/grc/analog_block_tree.xml +++ b/gr-analog/grc/analog_block_tree.xml @@ -36,6 +36,7 @@ <block>analog_ctcss_squelch_ff</block> <block>analog_pwr_squelch_xx</block> <block>analog_simple_squelch_cc</block> + <block>analog_standard_squelch</block> <block>analog_rail_ff</block> </cat> <cat> @@ -44,10 +45,20 @@ <block>analog_frequency_modulator_fc</block> <block>analog_phase_modulator_fc</block> <block>analog_quadrature_demod_cf</block> + <block>analog_nbfm_tx</block> + <block>analog_nbfm_rx</block> + <block>analog_wfm_tx</block> + <block>analog_wfm_rcv</block> + <block>analog_wfm_rcv_pll</block> + <block>analog_am_demod_cf</block> + <block>analog_fm_demod_cf</block> + <block>analog_fm_deemph</block> + <block>analog_fm_preemph</block> </cat> <cat> <name>Waveform Generators</name> <block>analog_sig_source_x</block> + <block>analog_const_source_x</block> <block>analog_noise_source_x</block> </cat> <cat> diff --git a/gr-analog/grc/analog_const_source_x.xml b/gr-analog/grc/analog_const_source_x.xml new file mode 100644 index 0000000000..de8c306264 --- /dev/null +++ b/gr-analog/grc/analog_const_source_x.xml @@ -0,0 +1,52 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Constant Source: Custom wrapper +################################################### + --> +<block> + <name>Constant Source</name> + <key>analog_const_source_x</key> + <import>from gnuradio import analog</import> + <make>analog.sig_source_$(type.fcn)(0, analog.GR_CONST_WAVE, 0, 0, $const)</make> + <callback>set_offset($const)</callback> + <param> + <name>Output Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>complex</key> + <opt>fcn:c</opt> + <opt>const_type:complex</opt> + </option> + <option> + <name>Float</name> + <key>float</key> + <opt>fcn:f</opt> + <opt>const_type:real</opt> + </option> + <option> + <name>Int</name> + <key>int</key> + <opt>fcn:i</opt> + <opt>const_type:int</opt> + </option> + <option> + <name>Short</name> + <key>short</key> + <opt>fcn:s</opt> + <opt>const_type:int</opt> + </option> + </param> + <param> + <name>Constant</name> + <key>const</key> + <value>0</value> + <type>$type.const_type</type> + </param> + <source> + <name>out</name> + <type>$type</type> + </source> +</block> diff --git a/gr-analog/grc/analog_fm_deemph.xml b/gr-analog/grc/analog_fm_deemph.xml new file mode 100644 index 0000000000..0fcb5a87d4 --- /dev/null +++ b/gr-analog/grc/analog_fm_deemph.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- +################################################### +##FM Deemphasis +################################################### + --> +<block> + <name>FM Deemphasis</name> + <key>analog_fm_deemph</key> + <import>from gnuradio import analog</import> + <make>analog.fm_deemph(fs=$samp_rate, tau=$tau)</make> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <type>real</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_fm_demod_cf.xml b/gr-analog/grc/analog_fm_demod_cf.xml new file mode 100644 index 0000000000..c903ddfc73 --- /dev/null +++ b/gr-analog/grc/analog_fm_demod_cf.xml @@ -0,0 +1,68 @@ +<?xml version="1.0"?> +<!-- +################################################### +##FM Demod +################################################### + --> +<block> + <name>FM Demod</name> + <key>analog_fm_demod_cf</key> + <import>from gnuradio import analog</import> + <make>analog.fm_demod_cf( + channel_rate=$chan_rate, + audio_decim=$audio_decim, + deviation=$deviation, + audio_pass=$audio_pass, + audio_stop=$audio_stop, + gain=$gain, + tau=$tau, +)</make> + <param> + <name>Channel Rate</name> + <key>chan_rate</key> + <type>real</type> + </param> + <param> + <name>Audio Decimation</name> + <key>audio_decim</key> + <type>int</type> + </param> + <param> + <name>Deviation</name> + <key>deviation</key> + <value>75000</value> + <type>real</type> + </param> + <param> + <name>Audio Pass</name> + <key>audio_pass</key> + <value>15000</value> + <type>real</type> + </param> + <param> + <name>Audio Stop</name> + <key>audio_stop</key> + <value>16000</value> + <type>real</type> + </param> + <param> + <name>Gain</name> + <key>gain</key> + <value>1.0</value> + <type>real</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_fm_preemph.xml b/gr-analog/grc/analog_fm_preemph.xml new file mode 100644 index 0000000000..fb898b87f3 --- /dev/null +++ b/gr-analog/grc/analog_fm_preemph.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> +<!-- +################################################### +##FM Preemphasis +################################################### + --> +<block> + <name>FM Preemphasis</name> + <key>analog_fm_preemph</key> + <import>from gnuradio import analog</import> + <make>analog.fm_preemph(fs=$samp_rate, tau=$tau)</make> + <param> + <name>Sample Rate</name> + <key>samp_rate</key> + <type>real</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_nbfm_rx.xml b/gr-analog/grc/analog_nbfm_rx.xml new file mode 100644 index 0000000000..cc690c7b6b --- /dev/null +++ b/gr-analog/grc/analog_nbfm_rx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##NBFM Receive +################################################### + --> +<block> + <name>NBFM Receive</name> + <key>analog_nbfm_rx</key> + <import>from gnuradio import analog</import> + <make>analog.nbfm_rx( + audio_rate=$audio_rate, + quad_rate=$quad_rate, + tau=$tau, + max_dev=$max_dev, +)</make> + <param> + <name>Audio Rate</name> + <key>audio_rate</key> + <type>int</type> + </param> + <param> + <name>Quadrature Rate</name> + <key>quad_rate</key> + <type>int</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <param> + <name>Max Deviation</name> + <key>max_dev</key> + <value>5e3</value> + <type>real</type> + </param> + <check>$quad_rate%$audio_rate == 0</check> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_nbfm_tx.xml b/gr-analog/grc/analog_nbfm_tx.xml new file mode 100644 index 0000000000..b3d3451cf7 --- /dev/null +++ b/gr-analog/grc/analog_nbfm_tx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##NBFM Transmit +################################################### + --> +<block> + <name>NBFM Transmit</name> + <key>analog_nbfm_tx</key> + <import>from gnuradio import analog</import> + <make>analog.nbfm_tx( + audio_rate=$audio_rate, + quad_rate=$quad_rate, + tau=$tau, + max_dev=$max_dev, +)</make> + <param> + <name>Audio Rate</name> + <key>audio_rate</key> + <type>int</type> + </param> + <param> + <name>Quadrature Rate</name> + <key>quad_rate</key> + <type>int</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <param> + <name>Max Deviation</name> + <key>max_dev</key> + <value>5e3</value> + <type>real</type> + </param> + <check>$quad_rate%$audio_rate == 0</check> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-analog/grc/analog_plateau_detector_fb.xml b/gr-analog/grc/analog_plateau_detector_fb.xml deleted file mode 100644 index f14efc97f4..0000000000 --- a/gr-analog/grc/analog_plateau_detector_fb.xml +++ /dev/null @@ -1,26 +0,0 @@ -<?xml version="1.0"?> -<block> - <name>Plateau Detector</name> - <key>analog_plateau_detector_fb</key> - <import>from gnuradio import analog</import> - <make>analog.plateau_detector_fb($max_len, $threshold)</make> - <param> - <name>Max. plateau length</name> - <key>max_len</key> - <type>int</type> - </param> - <param> - <name>Threshold</name> - <key>threshold</key> - <value>0.9</value> - <type>real</type> - </param> - <sink> - <name>in</name> - <type>real</type> - </sink> - <source> - <name>out</name> - <type>byte</type> - </source> -</block> diff --git a/gr-analog/grc/analog_standard_squelch.xml b/gr-analog/grc/analog_standard_squelch.xml new file mode 100644 index 0000000000..264c57ab56 --- /dev/null +++ b/gr-analog/grc/analog_standard_squelch.xml @@ -0,0 +1,32 @@ +<?xml version="1.0"?> +<!-- +################################################### +##Standard Squelch +################################################### + --> +<block> + <name>Standard Squelch</name> + <key>analog_standard_squelch</key> + <import>from gnuradio import analog</import> + <make>analog.standard_squelch(audio_rate=$audio_rate) +self.$(id).set_threshold($threshold)</make> + <callback>set_threshold($threshold)</callback> + <param> + <name>Audio Rate</name> + <key>audio_rate</key> + <type>real</type> + </param> + <param> + <name>Threshold</name> + <key>threshold</key> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_wfm_rcv.xml b/gr-analog/grc/analog_wfm_rcv.xml new file mode 100644 index 0000000000..ce2abb92de --- /dev/null +++ b/gr-analog/grc/analog_wfm_rcv.xml @@ -0,0 +1,33 @@ +<?xml version="1.0"?> +<!-- +################################################### +##WBFM Receive +################################################### + --> +<block> + <name>WBFM Receive</name> + <key>analog_wfm_rcv</key> + <import>from gnuradio import analog</import> + <make>analog.wfm_rcv( + quad_rate=$quad_rate, + audio_decimation=$audio_decimation, +)</make> + <param> + <name>Quadrature Rate</name> + <key>quad_rate</key> + <type>real</type> + </param> + <param> + <name>Audio Decimation</name> + <key>audio_decimation</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_wfm_rcv_pll.xml b/gr-analog/grc/analog_wfm_rcv_pll.xml new file mode 100644 index 0000000000..db31ed9bee --- /dev/null +++ b/gr-analog/grc/analog_wfm_rcv_pll.xml @@ -0,0 +1,37 @@ +<?xml version="1.0"?> +<!-- +################################################### +##WBFM Receive PLL +################################################### + --> +<block> + <name>WBFM Receive PLL</name> + <key>analog_wfm_rcv_pll</key> + <import>from gnuradio import analog</import> + <make>analog.wfm_rcv_pll( + demod_rate=$quad_rate, + audio_decimation=$audio_decimation, +)</make> + <param> + <name>Quadrature Rate</name> + <key>quad_rate</key> + <type>real</type> + </param> + <param> + <name>Audio Decimation</name> + <key>audio_decimation</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>complex</type> + </sink> + <source> + <name>Lout</name> + <type>float</type> + </source> + <source> + <name>Rout</name> + <type>float</type> + </source> +</block> diff --git a/gr-analog/grc/analog_wfm_tx.xml b/gr-analog/grc/analog_wfm_tx.xml new file mode 100644 index 0000000000..0e00f05fb2 --- /dev/null +++ b/gr-analog/grc/analog_wfm_tx.xml @@ -0,0 +1,48 @@ +<?xml version="1.0"?> +<!-- +################################################### +##WBFM Transmit +################################################### + --> +<block> + <name>WBFM Transmit</name> + <key>analog_wfm_tx</key> + <import>from gnuradio import analog</import> + <make>analog.wfm_tx( + audio_rate=$audio_rate, + quad_rate=$quad_rate, + tau=$tau, + max_dev=$max_dev, +)</make> + <param> + <name>Audio Rate</name> + <key>audio_rate</key> + <type>int</type> + </param> + <param> + <name>Quadrature Rate</name> + <key>quad_rate</key> + <type>int</type> + </param> + <param> + <name>Tau</name> + <key>tau</key> + <value>75e-6</value> + <type>real</type> + </param> + <param> + <name>Max Deviation</name> + <key>max_dev</key> + <value>75e3</value> + <type>real</type> + </param> + <check>$quad_rate%$audio_rate == 0</check> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>complex</type> + </source> +</block> diff --git a/gr-analog/include/analog/CMakeLists.txt b/gr-analog/include/analog/CMakeLists.txt index f46960c984..0343abcd85 100644 --- a/gr-analog/include/analog/CMakeLists.txt +++ b/gr-analog/include/analog/CMakeLists.txt @@ -26,7 +26,7 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py " #!${PYTHON_EXECUTABLE} import sys, os, re -sys.path.append('${GR_CORE_PYTHONPATH}') +sys.path.append('${GR_RUNTIME_PYTHONPATH}') os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' os.chdir('${CMAKE_CURRENT_BINARY_DIR}') @@ -65,6 +65,7 @@ endmacro(expand_h) # Invoke macro to generate various sources ####################################################################### expand_h(noise_source_X s i f c) +expand_h(fastnoise_source_X s i f c) expand_h(sig_source_X s i f c) add_custom_target(analog_generated_includes DEPENDS @@ -78,6 +79,7 @@ install(FILES ${generated_includes} api.h cpm.h + noise_type.h agc.h agc2.h noise_type.h @@ -93,7 +95,6 @@ install(FILES fmdet_cf.h frequency_modulator_fc.h phase_modulator_fc.h - plateau_detector_fb.h pll_carriertracking_cc.h pll_freqdet_cf.h pll_refout_cc.h @@ -104,7 +105,6 @@ install(FILES pwr_squelch_ff.h quadrature_demod_cf.h rail_ff.h - rotator.h sig_source_waveform.h simple_squelch_cc.h DESTINATION ${GR_INCLUDE_DIR}/gnuradio/analog diff --git a/gr-analog/include/analog/agc.h b/gr-analog/include/analog/agc.h index c939431fe4..9418c1f8fb 100644 --- a/gr-analog/include/analog/agc.h +++ b/gr-analog/include/analog/agc.h @@ -40,6 +40,14 @@ namespace gr { class ANALOG_API agc_cc { public: + /*! + * Construct a complex value AGC loop implementation object. + * + * \param rate the update rate of the loop. + * \param reference reference value to adjust signal power to. + * \param gain initial gain value. + * \param max_gain maximum gain value (0 for unlimited). + */ agc_cc(float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0) : _rate(rate), _reference(reference), @@ -91,6 +99,14 @@ namespace gr { class ANALOG_API agc_ff { public: + /*! + * Construct a floating point value AGC loop implementation object. + * + * \param rate the update rate of the loop. + * \param reference reference value to adjust signal power to. + * \param gain initial gain value. + * \param max_gain maximum gain value (0 for unlimited). + */ agc_ff(float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0) : _rate(rate), _reference(reference), _gain(gain), diff --git a/gr-analog/include/analog/agc2.h b/gr-analog/include/analog/agc2.h index be28301070..89d4b43694 100644 --- a/gr-analog/include/analog/agc2.h +++ b/gr-analog/include/analog/agc2.h @@ -40,6 +40,15 @@ namespace gr { class ANALOG_API agc2_cc { public: + /*! + * Construct a comple value AGC loop implementation object. + * + * \param attack_rate the update rate of the loop when in attack mode. + * \param decay_rate the update rate of the loop when in decay mode. + * \param reference reference value to adjust signal power to. + * \param gain initial gain value. + * \param max_gain maximum gain value (0 for unlimited). + */ agc2_cc(float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0, float gain = 1.0, float max_gain = 0.0) @@ -100,6 +109,15 @@ namespace gr { class ANALOG_API agc2_ff { public: + /*! + * Construct a floating point value AGC loop implementation object. + * + * \param attack_rate the update rate of the loop when in attack mode. + * \param decay_rate the update rate of the loop when in decay mode. + * \param reference reference value to adjust signal power to. + * \param gain initial gain value. + * \param max_gain maximum gain value (0 for unlimited). + */ agc2_ff(float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0, float gain = 1.0, float max_gain = 0.0) diff --git a/gr-analog/include/analog/agc2_cc.h b/gr-analog/include/analog/agc2_cc.h index 87e6200346..82efe914d8 100644 --- a/gr-analog/include/analog/agc2_cc.h +++ b/gr-analog/include/analog/agc2_cc.h @@ -31,7 +31,8 @@ namespace gr { namespace analog { /*! - * \brief high performance Automatic Gain Control class + * \brief high performance Automatic Gain Control class with + * attack and decay rates. * \ingroup level_controllers_blk * * \details @@ -43,6 +44,15 @@ namespace gr { // gr::analog::agc2_cc::sptr typedef boost::shared_ptr<agc2_cc> sptr; + /*! + * Build a complex value AGC loop block with attack and decay rates. + * + * \param attack_rate the update rate of the loop when in attack mode. + * \param decay_rate the update rate of the loop when in decay mode. + * \param reference reference value to adjust signal power to. + * \param gain initial gain value. + * \param max_gain maximum gain value (0 for unlimited). + */ static sptr make(float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0, float gain = 1.0, float max_gain = 0.0); diff --git a/gr-analog/include/analog/agc2_ff.h b/gr-analog/include/analog/agc2_ff.h index b960493dca..dd2507e33d 100644 --- a/gr-analog/include/analog/agc2_ff.h +++ b/gr-analog/include/analog/agc2_ff.h @@ -31,7 +31,8 @@ namespace gr { namespace analog { /*! - * \brief high performance Automatic Gain Control class + * \brief high performance Automatic Gain Control class with + * attack and decay rates. * \ingroup level_controllers_blk * * \details @@ -43,6 +44,15 @@ namespace gr { // gr::analog::agc2_ff::sptr typedef boost::shared_ptr<agc2_ff> sptr; + /*! + * Build a floating point AGC loop block with attack and decay rates. + * + * \param attack_rate the update rate of the loop when in attack mode. + * \param decay_rate the update rate of the loop when in decay mode. + * \param reference reference value to adjust signal power to. + * \param gain initial gain value. + * \param max_gain maximum gain value (0 for unlimited). + */ static sptr make(float attack_rate = 1e-1, float decay_rate = 1e-2, float reference = 1.0, float gain = 1.0, float max_gain = 0.0); diff --git a/gr-analog/include/analog/agc_cc.h b/gr-analog/include/analog/agc_cc.h index d516af4565..0c2e831b0c 100644 --- a/gr-analog/include/analog/agc_cc.h +++ b/gr-analog/include/analog/agc_cc.h @@ -43,6 +43,14 @@ namespace gr { // gr::analog::agc_cc::sptr typedef boost::shared_ptr<agc_cc> sptr; + /*! + * Build a complex value AGC loop block. + * + * \param rate the update rate of the loop. + * \param reference reference value to adjust signal power to. + * \param gain initial gain value. + * \param max_gain maximum gain value (0 for unlimited). + */ static sptr make(float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0); diff --git a/gr-analog/include/analog/agc_ff.h b/gr-analog/include/analog/agc_ff.h index 3056b96476..ffcafaa642 100644 --- a/gr-analog/include/analog/agc_ff.h +++ b/gr-analog/include/analog/agc_ff.h @@ -43,6 +43,14 @@ namespace gr { // gr::analog::agc_ff::sptr typedef boost::shared_ptr<agc_ff> sptr; + /*! + * Build a floating point AGC loop block. + * + * \param rate the update rate of the loop. + * \param reference reference value to adjust signal power to. + * \param gain initial gain value. + * \param max_gain maximum gain value (0 for unlimited). + */ static sptr make(float rate = 1e-4, float reference = 1.0, float gain = 1.0, float max_gain = 0.0); diff --git a/gr-analog/include/analog/api.h b/gr-analog/include/analog/api.h index b7dee46933..2459ace614 100644 --- a/gr-analog/include/analog/api.h +++ b/gr-analog/include/analog/api.h @@ -22,7 +22,7 @@ #ifndef INCLUDED_ANALOG_API_H #define INCLUDED_ANALOG_API_H -#include <gruel/attributes.h> +#include <attributes.h> #ifdef gnuradio_analog_EXPORTS # define ANALOG_API __GR_ATTR_EXPORT diff --git a/gr-analog/include/analog/cpm.h b/gr-analog/include/analog/cpm.h index 205fcfe809..43dd0b3729 100644 --- a/gr-analog/include/analog/cpm.h +++ b/gr-analog/include/analog/cpm.h @@ -28,6 +28,9 @@ namespace gr { namespace analog { + /*! \brief Return the taps for an interpolating FIR filter + * (gr::filter::interp_fir_filter_fff). + */ class ANALOG_API cpm { public: @@ -40,26 +43,31 @@ namespace gr { GENERIC = 999 }; - /*! \brief Return the taps for an interpolating FIR filter (gr_interp_fir_filter_fff). + /*! \brief Return the taps for an interpolating FIR filter + * (gr::filter::interp_fir_filter_fff). * * \details * These taps represent the phase response \f$g(k)\f$ for use in a CPM modulator, * see also gr_cpmmod_bc. * - * \param type The CPM type (Rectangular, Raised Cosine, Spectral Raised Cosine, - * Tamed FM or Gaussian). + * \param type The CPM type (Rectangular, Raised Cosine, + * Spectral Raised Cosine, Tamed FM or Gaussian). * \param samples_per_sym Samples per symbol. * \param L The length of the phase response in symbols. - * \param beta For Spectral Raised Cosine, this is the rolloff factor. For Gaussian - * phase responses, this the 3dB-time-bandwidth product. For all other - * cases, it is ignored. + * \param beta For Spectral Raised Cosine, this is the rolloff + * factor. For Gaussian phase responses, this the + * 3dB-time-bandwidth product. For all other cases, + * it is ignored. * - * Output: returns a vector of length \a K = \p samples_per_sym x \p L. - * This can be used directly in an interpolating FIR filter such as - * gr_interp_fir_filter_fff with interpolation factor \p samples_per_sym. + * Output: returns a vector of length \a K = \p samples_per_sym + * x \p L. This can be used directly in an + * interpolating FIR filter such as + * gr_interp_fir_filter_fff with interpolation factor \p + * samples_per_sym. * - * All phase responses are normalised s.t. \f$ \sum_{k=0}^{K-1} g(k) = 1\f$; this will cause - * a maximum phase change of \f$ h \cdot \pi\f$ between two symbols, where \a h is the + * All phase responses are normalised s.t. \f$ \sum_{k=0}^{K-1} + * g(k) = 1\f$; this will cause a maximum phase change of \f$ h + * \cdot \pi\f$ between two symbols, where \a h is the * modulation index. * * The following phase responses can be generated: @@ -78,7 +86,8 @@ namespace gr { * [1]: Anderson, Aulin and Sundberg; Digital Phase Modulation */ static std::vector<float> - phase_response(cpm_type type, unsigned samples_per_sym, unsigned L, double beta=0.3); + phase_response(cpm_type type, unsigned samples_per_sym, + unsigned L, double beta=0.3); }; } // namespace analog } // namespace gr diff --git a/gr-analog/include/analog/ctcss_squelch_ff.h b/gr-analog/include/analog/ctcss_squelch_ff.h index 471021d008..f8c551d291 100644 --- a/gr-analog/include/analog/ctcss_squelch_ff.h +++ b/gr-analog/include/analog/ctcss_squelch_ff.h @@ -31,7 +31,7 @@ namespace gr { namespace analog { /*! - * \brief gate or zero output if ctcss tone not present + * \brief gate or zero output if CTCSS tone not present * \ingroup level_controllers_blk */ class ANALOG_API ctcss_squelch_ff : @@ -47,6 +47,14 @@ namespace gr { /*! * \brief Make CTCSS tone squelch block. + * + * \param rate gain of the internal frequency filters. + * \param freq frequency value to use as the squelch tone. + * \param level threshold level for the squelch tone. + * \param len length of the frequency filters. + * \param ramp sets response characteristic. + * \param gate if true, no output if no squelch tone. + * if false, output 0's if no squelch tone. */ static sptr make(int rate, float freq, float level, int len, int ramp, bool gate); diff --git a/gr-analog/include/analog/fastnoise_source_X.h.t b/gr-analog/include/analog/fastnoise_source_X.h.t new file mode 100644 index 0000000000..e1c606692c --- /dev/null +++ b/gr-analog/include/analog/fastnoise_source_X.h.t @@ -0,0 +1,70 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <analog/api.h> +#include <analog/noise_type.h> +#include <gr_sync_block.h> + +namespace gr { + namespace analog { + + /*! + * \brief Random number source + * \ingroup source_blk + * + * \details + * Generate random values from different distributions. + * Currently, only Gaussian and uniform are enabled. + */ + class ANALOG_API @BASE_NAME@ : virtual public gr_sync_block + { + public: + // gr::analog::@BASE_NAME@::sptr + typedef boost::shared_ptr<@BASE_NAME@> sptr; + + /*! \brief Make a fast noise source + * \param type the random distribution to use (see analog/noise_type.h) + * \param ampl a scaling factor for the output + * \param seed seed for random generators. Note that for uniform and + * \param samples Number of samples to pre-generate + * Gaussian distributions, this should be a negative number. + */ + static sptr make(noise_type_t type, float ampl, + long seed = 0, long samples=1024*16); + + virtual void set_type(noise_type_t type) = 0; + virtual void set_amplitude(float ampl) = 0; + + virtual noise_type_t type() const = 0; + virtual float amplitude() const = 0; + }; + + } /* namespace analog */ +} /* namespace gr */ + + +#endif /* @GUARD_NAME@ */ diff --git a/gr-analog/include/analog/feedforward_agc_cc.h b/gr-analog/include/analog/feedforward_agc_cc.h index 13b4fe0486..0a688ccdde 100644 --- a/gr-analog/include/analog/feedforward_agc_cc.h +++ b/gr-analog/include/analog/feedforward_agc_cc.h @@ -30,7 +30,8 @@ namespace gr { namespace analog { /*! - * \brief Non-causal AGC which computes required gain based on max absolute value over nsamples + * \brief Non-causal AGC which computes required gain based on max + * absolute value over nsamples * \ingroup level_controllers_blk */ class ANALOG_API feedforward_agc_cc : virtual public gr_sync_block @@ -38,7 +39,13 @@ namespace gr { public: // gr::analog::feedforward_agc_cc::sptr typedef boost::shared_ptr<feedforward_agc_cc> sptr; - + + /*! + * Build a complex valued feed-forward AGC loop block. + * + * \param nsamples number of samples to look ahead. + * \param reference reference value to adjust signal power to. + */ static sptr make(int nsamples, float reference); }; diff --git a/gr-analog/include/analog/frequency_modulator_fc.h b/gr-analog/include/analog/frequency_modulator_fc.h index 86f6d20d98..a0d4404729 100644 --- a/gr-analog/include/analog/frequency_modulator_fc.h +++ b/gr-analog/include/analog/frequency_modulator_fc.h @@ -42,6 +42,11 @@ namespace gr { // gr::analog::frequency_modulator_fc::sptr typedef boost::shared_ptr<frequency_modulator_fc> sptr; + /*! + * Build a frequency modulator block. + * + * \param sensitivity radians/sample = amplitude * sensitivity + */ static sptr make(double sensitivity); virtual void set_sensitivity(float sens) = 0; diff --git a/gr-analog/include/analog/lfsr.h b/gr-analog/include/analog/lfsr.h deleted file mode 100644 index bb5c4b0ea4..0000000000 --- a/gr-analog/include/analog/lfsr.h +++ /dev/null @@ -1,163 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2008,2010,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_ANALOG_LFSR_H -#define INCLUDED_ANALOG_LFSR_H - -#include <analog/api.h> -#include <stdexcept> -#include <stdint.h> - -namespace gr { - namespace analog { - - /*! - * \brief Fibonacci Linear Feedback Shift Register using specified - * polynomial mask - * \ingroup misc - * - * \details - * Generates a maximal length pseudo-random sequence of length - * 2^degree-1 - * - * Constructor: analog::lfsr(int mask, int seed, int reg_len); - * - * \param mask - polynomial coefficients representing the - * locations of feedback taps from a shift register - * which are xor'ed together to form the new high - * order bit. - * - * Some common masks might be: - * x^4 + x^3 + x^0 = 0x19 - * x^5 + x^3 + x^0 = 0x29 - * x^6 + x^5 + x^0 = 0x61 - * - * \param seed - the initialization vector placed into the - * register durring initialization. Low order bit - * corresponds to x^0 coefficient -- the first to be - * shifted as output. - * - * \param reg_len - specifies the length of the feedback shift - * register to be used. Durring each iteration, the - * register is rightshifted one and the new bit is - * placed in bit reg_len. reg_len should generally be - * at least order(mask) + 1 - * - * - * see http://en.wikipedia.org/wiki/Linear_feedback_shift_register - * for more explanation. - * - * next_bit() - Standard LFSR operation - * - * Perform one cycle of the LFSR. The output bit is taken from - * the shift register LSB. The shift register MSB is assigned from - * the modulo 2 sum of the masked shift register. - * - * next_bit_scramble(unsigned char input) - Scramble an input stream - * - * Perform one cycle of the LFSR. The output bit is taken from - * the shift register LSB. The shift register MSB is assigned from - * the modulo 2 sum of the masked shift register and the input LSB. - * - * next_bit_descramble(unsigned char input) - Descramble an input stream - * - * Perform one cycle of the LFSR. The output bit is taken from - * the modulo 2 sum of the masked shift register and the input LSB. - * The shift register MSB is assigned from the LSB of the input. - * - * See http://en.wikipedia.org/wiki/Scrambler for operation of these - * last two functions (see multiplicative scrambler.) - */ - class lfsr - { - private: - uint32_t d_shift_register; - uint32_t d_mask; - uint32_t d_seed; - uint32_t d_shift_register_length; // less than 32 - - static uint32_t - popCount(uint32_t x) - { - uint32_t r = x - ((x >> 1) & 033333333333) - - ((x >> 2) & 011111111111); - return ((r + (r >> 3)) & 030707070707) % 63; - } - - public: - lfsr(uint32_t mask, uint32_t seed, uint32_t reg_len) - : d_shift_register(seed), - d_mask(mask), - d_seed(seed), - d_shift_register_length(reg_len) - { - if(reg_len > 31) - throw std::invalid_argument("reg_len must be <= 31"); - } - - unsigned char next_bit() - { - unsigned char output = d_shift_register & 1; - unsigned char newbit = popCount( d_shift_register & d_mask )%2; - d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length)); - return output; - } - - unsigned char next_bit_scramble(unsigned char input) - { - unsigned char output = d_shift_register & 1; - unsigned char newbit = (popCount( d_shift_register & d_mask )%2)^(input & 1); - d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length)); - return output; - } - - unsigned char next_bit_descramble(unsigned char input) - { - unsigned char output = (popCount( d_shift_register & d_mask )%2)^(input & 1); - unsigned char newbit = input & 1; - d_shift_register = ((d_shift_register>>1) | (newbit<<d_shift_register_length)); - return output; - } - - /*! - * Reset shift register to initial seed value - */ - void reset() { d_shift_register = d_seed; } - - /*! - * Rotate the register through x number of bits - * where we are just throwing away the results to get queued up correctly - */ - void pre_shift(int num) - { - for(int i=0; i<num; i++) { - next_bit(); - } - } - - int mask() const { return d_mask; } - }; - - } /* namespace analog */ -} /* namespace gr */ - -#endif /* INCLUDED_ANALOG_LFSR_H */ diff --git a/gr-analog/include/analog/noise_source_X.h.t b/gr-analog/include/analog/noise_source_X.h.t index 9fa470c47d..1a9630dfdf 100644 --- a/gr-analog/include/analog/noise_source_X.h.t +++ b/gr-analog/include/analog/noise_source_X.h.t @@ -53,7 +53,7 @@ namespace gr { * \param seed seed for random generators. Note that for uniform and * Gaussian distributions, this should be a negative number. */ - static sptr make(noise_type_t type, float ampl, long seed); + static sptr make(noise_type_t type, float ampl, long seed=0); virtual void set_type(noise_type_t type) = 0; virtual void set_amplitude(float ampl) = 0; diff --git a/gr-analog/include/analog/plateau_detector_fb.h b/gr-analog/include/analog/plateau_detector_fb.h deleted file mode 100644 index 767aafe23a..0000000000 --- a/gr-analog/include/analog/plateau_detector_fb.h +++ /dev/null @@ -1,69 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - - -#ifndef INCLUDED_ANALOG_PLATEAU_DETECTOR_FB_H -#define INCLUDED_ANALOG_PLATEAU_DETECTOR_FB_H - -#include <analog/api.h> -#include <gr_sync_block.h> - -namespace gr { - namespace analog { - - /*! - * \brief Detects a plateau and marks the middle. - * - * \details - * Detect a plateau of a-priori known height. Input is a stream of floats, - * the output is a stream of bytes. Whenever a plateau is detected, the - * middle of that plateau is marked with a '1' on the output stream (all - * other samples are left at zero). - * - * You can use this in a Schmidl & Cox synchronisation algorithm to interpret - * the output of the normalized correlator. Just pass the length of the cyclic - * prefix (in samples) as the max_len parameter). - * - * Unlike the peak detectors, you must the now the absolute height of the plateau. - * Whenever the amplitude exceeds the given threshold, it starts assuming the - * presence of a plateau. - * - * An implicit hysteresis is provided by the fact that after detecting one plateau, - * it waits at least max_len samples before the next plateau can be detected. - */ - class ANALOG_API plateau_detector_fb : virtual public gr_sync_block - { - public: - typedef boost::shared_ptr<plateau_detector_fb> sptr; - - /*! - * \param max_len Maximum length of the plateau - * \param threshold Anything above this value is considered a plateau - */ - static sptr make(int max_len, float threshold=0.9); - }; - - } // namespace analog -} // namespace gr - -#endif /* INCLUDED_ANALOG_PLATEAU_DETECTOR_FB_H */ - diff --git a/gr-analog/include/analog/pll_carriertracking_cc.h b/gr-analog/include/analog/pll_carriertracking_cc.h index bb92673185..520a2f57da 100644 --- a/gr-analog/include/analog/pll_carriertracking_cc.h +++ b/gr-analog/include/analog/pll_carriertracking_cc.h @@ -24,6 +24,7 @@ #define INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_H #include <analog/api.h> +#include <blocks/control_loop.h> #include <gr_sync_block.h> namespace gr { @@ -46,7 +47,9 @@ namespace gr { * and should be set around pi/200 -- 2pi/100. \sa * pll_freqdet_cf, pll_carriertracking_cc */ - class ANALOG_API pll_carriertracking_cc : virtual public gr_sync_block + class ANALOG_API pll_carriertracking_cc + : virtual public gr_sync_block, + virtual public blocks::control_loop { public: // gr::analog::pll_carriertracking_cc::sptr diff --git a/gr-analog/include/analog/pll_freqdet_cf.h b/gr-analog/include/analog/pll_freqdet_cf.h index a653261c30..b33fb909ba 100644 --- a/gr-analog/include/analog/pll_freqdet_cf.h +++ b/gr-analog/include/analog/pll_freqdet_cf.h @@ -24,6 +24,7 @@ #define INCLUDED_ANALOG_PLL_FREQDET_CF_H #include <analog/api.h> +#include <blocks/control_loop.h> #include <gr_sync_block.h> namespace gr { @@ -45,7 +46,9 @@ namespace gr { * around pi/200 -- 2pi/100. * \sa pll_refout_cc, pll_carriertracking_cc */ - class ANALOG_API pll_freqdet_cf : virtual public gr_sync_block + class ANALOG_API pll_freqdet_cf + : virtual public gr_sync_block, + virtual public blocks::control_loop { public: // gr::analog::pll_freqdet_cf::sptr diff --git a/gr-analog/include/analog/pll_refout_cc.h b/gr-analog/include/analog/pll_refout_cc.h index da15762779..9c713749c7 100644 --- a/gr-analog/include/analog/pll_refout_cc.h +++ b/gr-analog/include/analog/pll_refout_cc.h @@ -24,6 +24,7 @@ #define INCLUDED_ANALOG_PLL_REFOUT_CC_H #include <analog/api.h> +#include <blocks/control_loop.h> #include <gr_sync_block.h> namespace gr { @@ -46,7 +47,9 @@ namespace gr { * and should be set around pi/200 -- 2pi/100. \sa * pll_freqdet_cf, pll_carriertracking_cc */ - class ANALOG_API pll_refout_cc : virtual public gr_sync_block + class ANALOG_API pll_refout_cc + : virtual public gr_sync_block, + virtual public blocks::control_loop { public: // gr::analog::pll_refout_cc::sptr diff --git a/gr-analog/include/analog/pwr_squelch_cc.h b/gr-analog/include/analog/pwr_squelch_cc.h index 840669b6b7..73b89f0db6 100644 --- a/gr-analog/include/analog/pwr_squelch_cc.h +++ b/gr-analog/include/analog/pwr_squelch_cc.h @@ -50,8 +50,9 @@ namespace gr { * * \param db threshold (in dB) for power squelch * \param alpha Gain of averaging filter - * \param ramp - * \param gate + * \param ramp sets response characteristic. + * \param gate if true, no output if no squelch tone. + * if false, output 0's if no squelch tone. */ static sptr make(double db, double alpha=0.0001, int ramp=0, bool gate=false); diff --git a/gr-analog/include/analog/pwr_squelch_ff.h b/gr-analog/include/analog/pwr_squelch_ff.h index 9aca73a175..5490827390 100644 --- a/gr-analog/include/analog/pwr_squelch_ff.h +++ b/gr-analog/include/analog/pwr_squelch_ff.h @@ -50,8 +50,9 @@ namespace gr { * * \param db threshold (in dB) for power squelch * \param alpha Gain of averaging filter - * \param ramp - * \param gate + * \param ramp sets response characteristic. + * \param gate if true, no output if no squelch tone. + * if false, output 0's if no squelch tone. */ static sptr make(double db, double alpha=0.0001, int ramp=0, bool gate=false); diff --git a/gr-analog/include/analog/quadrature_demod_cf.h b/gr-analog/include/analog/quadrature_demod_cf.h index 919cf779f7..c7682649b8 100644 --- a/gr-analog/include/analog/quadrature_demod_cf.h +++ b/gr-analog/include/analog/quadrature_demod_cf.h @@ -43,6 +43,12 @@ namespace gr { // gr::analog::quadrature_demod_cf::sptr typedef boost::shared_ptr<quadrature_demod_cf> sptr; + /* \brief Make a quadrature demodulator block. + * + * \param gain Gain setting to adjust the output amplitude. Set + * based on converting the phase difference between + * samples to a nominal output value. + */ static sptr make(float gain); virtual void set_gain(float gain) = 0; diff --git a/gr-analog/include/analog/rail_ff.h b/gr-analog/include/analog/rail_ff.h index 7771fd9e8e..2018017935 100644 --- a/gr-analog/include/analog/rail_ff.h +++ b/gr-analog/include/analog/rail_ff.h @@ -39,6 +39,12 @@ namespace gr { // gr::analog::rail_ff::sptr typedef boost::shared_ptr<rail_ff> sptr; + /*! + * Build a rail block. + * + * \param lo the low value to clip to. + * \param hi the high value to clip to. + */ static sptr make(float lo, float hi); virtual float lo() const = 0; diff --git a/gr-analog/include/analog/rotator.h b/gr-analog/include/analog/rotator.h deleted file mode 100644 index ee3849eae7..0000000000 --- a/gr-analog/include/analog/rotator.h +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003,2008,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _ANALOG_ROTATOR_H_ -#define _ANALOG_ROTATOR_H_ - -#include <analog/api.h> -#include <gr_complex.h> - -namespace gr { - namespace analog { - - class rotator - { - private: - gr_complex d_phase; - gr_complex d_phase_incr; - unsigned int d_counter; - - public: - rotator() : d_phase (1), d_phase_incr (1), d_counter(0) - { } - - void set_phase(gr_complex phase) { d_phase = phase / abs(phase); } - void set_phase_incr(gr_complex incr) { d_phase_incr = incr / abs(incr); } - - gr_complex rotate (gr_complex in) - { - d_counter++; - - gr_complex z = in * d_phase; // rotate in by phase - d_phase *= d_phase_incr; // incr our phase (complex mult == add phases) - - if((d_counter % 512) == 0) - d_phase /= abs(d_phase); // Normalize to ensure multiplication is rotation - - return z; - } - }; - - } /* namespace analog */ -} /* namespace gr */ - -#endif /* _ANALOG_ROTATOR_H_ */ diff --git a/gr-analog/include/analog/sincos.h b/gr-analog/include/analog/sincos.h deleted file mode 100644 index 38b9d96da0..0000000000 --- a/gr-analog/include/analog/sincos.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2002,2004,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_ANALOG_SINCOS_H -#define INCLUDED_ANALOG_SINCOS_H - -#include <analog/api.h> - -namespace gr { - namespace analog { - - // compute sine and cosine at the same time - ANALOG_API void sincos(double x, double *sin, double *cos); - ANALOG_API void sincosf(float x, float *sin, float *cos); - - } /* namespace analog */ -} /* namespace gr */ - -#endif /* INCLUDED_ANALOG_SINCOS_H */ diff --git a/gr-analog/lib/CMakeLists.txt b/gr-analog/lib/CMakeLists.txt index 396ff04654..5719eac7a5 100644 --- a/gr-analog/lib/CMakeLists.txt +++ b/gr-analog/lib/CMakeLists.txt @@ -27,14 +27,19 @@ include_directories( ${GR_ANALOG_INCLUDE_DIRS} ${GR_FILTER_INCLUDE_DIRS} ${GR_FFT_INCLUDE_DIRS} - ${GNURADIO_CORE_INCLUDE_DIRS} + ${GR_BLOCKS_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_INCLUDE_DIRS} ${VOLK_INCLUDE_DIRS} - ${GRUEL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ) link_directories(${Boost_LIBRARY_DIRS}) +if(ENABLE_GR_CTRLPORT) + ADD_DEFINITIONS(-DGR_CTRLPORT) + include_directories(${ICE_INCLUDE_DIR}) +endif(ENABLE_GR_CTRLPORT) + ######################################################################## # generate helper scripts to expand templated files ######################################################################## @@ -44,7 +49,7 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py " #!${PYTHON_EXECUTABLE} import sys, os, re -sys.path.append('${GR_CORE_PYTHONPATH}') +sys.path.append('${GR_RUNTIME_PYTHONPATH}') os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}' os.chdir('${CMAKE_CURRENT_BINARY_DIR}') @@ -100,6 +105,7 @@ endmacro(expand_cc) # Invoke macro to generate various sources ######################################################################## expand_cc(noise_source_X_impl s i f c) +expand_cc(fastnoise_source_X_impl s i f c) expand_cc(sig_source_X_impl s i f c) ######################################################################## @@ -121,7 +127,6 @@ list(APPEND analog_sources fmdet_cf_impl.cc frequency_modulator_fc_impl.cc phase_modulator_fc_impl.cc - plateau_detector_fb_impl.cc pll_carriertracking_cc_impl.cc pll_freqdet_cf_impl.cc pll_refout_cc_impl.cc @@ -133,7 +138,6 @@ list(APPEND analog_sources quadrature_demod_cf_impl.cc rail_ff_impl.cc simple_squelch_cc_impl.cc - sincos.cc ) #Add Windows DLL resource file if using MSVC @@ -153,7 +157,7 @@ ENDIF(MSVC) list(APPEND analog_libs volk - gnuradio-core + gnuradio-runtime gnuradio-filter ${Boost_LIBRARIES} ) @@ -176,15 +180,13 @@ if(ENABLE_TESTING) list(APPEND test_gr_analog_sources ${CMAKE_CURRENT_SOURCE_DIR}/test_gr_analog.cc ${CMAKE_CURRENT_SOURCE_DIR}/qa_analog.cc - ${CMAKE_CURRENT_SOURCE_DIR}/qa_sincos.cc - ${CMAKE_CURRENT_SOURCE_DIR}/qa_rotator.cc ) add_executable(test-gr-analog ${test_gr_analog_sources}) target_link_libraries( test-gr-analog - gnuradio-core + gnuradio-runtime gnuradio-analog ${Boost_LIBRARIES} ${CPPUNIT_LIBRARIES} @@ -194,11 +196,3 @@ if(ENABLE_TESTING) GR_ADD_TEST(test_gr_analog test-gr-analog) endif(ENABLE_TESTING) - -CHECK_CXX_SOURCE_COMPILES(" - #define _GNU_SOURCE - #include <math.h> - int main(){double x, sin, cos; sincos(x, &sin, &cos); return 0;} - " HAVE_SINCOS -) -GR_ADD_COND_DEF(HAVE_SINCOS) diff --git a/gr-analog/lib/fastnoise_source_X_impl.cc.t b/gr-analog/lib/fastnoise_source_X_impl.cc.t new file mode 100644 index 0000000000..706ddbbf84 --- /dev/null +++ b/gr-analog/lib/fastnoise_source_X_impl.cc.t @@ -0,0 +1,144 @@ +/* -*- c++ -*- */ +/* + * Copyright 2013 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio 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, or (at your option) + * any later version. + * + * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +/* @WARNING@ */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "@IMPL_NAME@.h" +#include <gr_io_signature.h> +#include <stdexcept> + +namespace gr { + namespace analog { + + @BASE_NAME@::sptr + @BASE_NAME@::make(noise_type_t type, float ampl, long seed, long samples) + { + return gnuradio::get_initial_sptr + (new @IMPL_NAME@(type, ampl, seed, samples)); + } + + @IMPL_NAME@::@IMPL_NAME@(noise_type_t type, float ampl, long seed, long samples) + : gr_sync_block("@BASE_NAME@", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, sizeof(@TYPE@))), + d_type(type), + d_ampl(ampl), + d_rng(seed) + { + d_samples.resize(samples); + generate(); + } + + @IMPL_NAME@::~@IMPL_NAME@() + { + } + + void + @IMPL_NAME@::set_type(noise_type_t type) + { + gr::thread::scoped_lock l(d_setlock); + d_type = type; + generate(); + } + + void + @IMPL_NAME@::set_amplitude(float ampl) + { + gr::thread::scoped_lock l(d_setlock); + d_ampl = ampl; + generate(); + } + + void + @IMPL_NAME@::generate() + { + int noutput_items = d_samples.size(); + switch(d_type){ +#if @IS_COMPLEX@ // complex? + + case GR_UNIFORM: + for(int i = 0; i < noutput_items; i++) + d_samples[i] = gr_complex(d_ampl * ((d_rng.ran1() * 2.0) - 1.0), + d_ampl * ((d_rng.ran1() * 2.0) - 1.0)); + break; + + case GR_GAUSSIAN: + for(int i = 0; i < noutput_items; i++) + d_samples[i] = d_ampl * d_rng.rayleigh_complex(); + break; + +#else // nope... + + case GR_UNIFORM: + for(int i = 0; i < noutput_items; i++) + d_samples[i] = (@TYPE@)(d_ampl * ((d_rng.ran1() * 2.0) - 1.0)); + break; + + case GR_GAUSSIAN: + for(int i = 0; i < noutput_items; i++) + d_samples[i] = (@TYPE@)(d_ampl * d_rng.gasdev()); + break; + + case GR_LAPLACIAN: + for(int i = 0; i < noutput_items; i++) + d_samples[i] = (@TYPE@)(d_ampl * d_rng.laplacian()); + break; + + case GR_IMPULSE: // FIXME changeable impulse settings + for(int i = 0; i < noutput_items; i++) + d_samples[i] = (@TYPE@)(d_ampl * d_rng.impulse(9)); + break; +#endif + + default: + throw std::runtime_error("invalid type"); + } + } + + int + @IMPL_NAME@::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr::thread::scoped_lock l(d_setlock); + + @TYPE@ *out = (@TYPE@*)output_items[0]; + + for(int i=0; i<noutput_items; i++) { +#ifdef __USE_GNU + size_t idx = lrand48() % d_samples.size(); +#else + size_t idx = rand() % d_samples.size(); +#endif + out[i] = d_samples[idx]; + } + + return noutput_items; + } + + } /* namespace analog */ +} /* namespace gr */ + diff --git a/gr-analog/lib/qa_rotator.h b/gr-analog/lib/fastnoise_source_X_impl.h.t index a22e41ec26..3c5dc106a2 100644 --- a/gr-analog/lib/qa_rotator.h +++ b/gr-analog/lib/fastnoise_source_X_impl.h.t @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008,2012 Free Software Foundation, Inc. + * Copyright 2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,26 +20,42 @@ * Boston, MA 02110-1301, USA. */ -#ifndef _QA_ANALOG_ROTATOR_H_ -#define _QA_ANALOG_ROTATOR_H_ +// @WARNING@ -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCase.h> +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include <analog/@BASE_NAME@.h> +#include <gr_random.h> namespace gr { namespace analog { - class qa_rotator : public CppUnit::TestCase + class @IMPL_NAME@ : public @BASE_NAME@ { - CPPUNIT_TEST_SUITE(qa_rotator); - CPPUNIT_TEST(t1); - CPPUNIT_TEST_SUITE_END(); - private: - void t1(); + noise_type_t d_type; + float d_ampl; + gr_random d_rng; + std::vector<@TYPE@> d_samples; + + public: + @IMPL_NAME@(noise_type_t type, float ampl, long seed, long samples); + ~@IMPL_NAME@(); + + void set_type(noise_type_t type); + void set_amplitude(float ampl); + void generate(); + + noise_type_t type() const { return d_type; } + float amplitude() const { return d_ampl; } + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; - } /* namespace analog */ + } /* namespace filter */ } /* namespace gr */ -#endif /* _QA_ANALOG_ROTATOR_H_ */ +#endif /* @GUARD_NAME@ */ diff --git a/gr-analog/lib/noise_source_X_impl.cc.t b/gr-analog/lib/noise_source_X_impl.cc.t index 40e2517d2e..7f371b2cfd 100644 --- a/gr-analog/lib/noise_source_X_impl.cc.t +++ b/gr-analog/lib/noise_source_X_impl.cc.t @@ -57,14 +57,14 @@ namespace gr { void @IMPL_NAME@::set_type(noise_type_t type) { - gruel::scoped_lock l(d_setlock); + gr::thread::scoped_lock l(d_setlock); d_type = type; } void @IMPL_NAME@::set_amplitude(float ampl) { - gruel::scoped_lock l(d_setlock); + gr::thread::scoped_lock l(d_setlock); d_ampl = ampl; } @@ -73,7 +73,7 @@ namespace gr { gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { - gruel::scoped_lock l(d_setlock); + gr::thread::scoped_lock l(d_setlock); @TYPE@ *out = (@TYPE@*)output_items[0]; diff --git a/gr-analog/lib/plateau_detector_fb_impl.cc b/gr-analog/lib/plateau_detector_fb_impl.cc deleted file mode 100644 index 0d2890bc55..0000000000 --- a/gr-analog/lib/plateau_detector_fb_impl.cc +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <gr_io_signature.h> -#include "plateau_detector_fb_impl.h" - -namespace gr { - namespace analog { - -plateau_detector_fb::sptr -plateau_detector_fb::make(int max_len, float threshold) -{ - return gnuradio::get_initial_sptr (new plateau_detector_fb_impl(max_len, threshold)); -} - -plateau_detector_fb_impl::plateau_detector_fb_impl(int max_len, float threshold) - : gr_sync_block("plateau_detector_fb", - gr_make_io_signature(1, 1, sizeof (float)), - gr_make_io_signature(1, 1, sizeof (char))), - d_max_len(max_len), - d_threshold(threshold) -{} - -plateau_detector_fb_impl::~plateau_detector_fb_impl() -{ -} - -int -plateau_detector_fb_impl::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const float *in = (const float *) input_items[0]; - unsigned char *out = (unsigned char *) output_items[0]; - int flank_start; - - memset((void *) out, 0x00, noutput_items); - int i; - for (i = 0; i < noutput_items; i++) { - if (in[i] >= d_threshold) { - if (noutput_items-i < 2*d_max_len) { // If we can't finish, come back later - break; - } - flank_start = i; - while (i < noutput_items && in[i] >= d_threshold) - i++; - if ((i - flank_start) > 1) { // 1 Sample is not a plateau - out[flank_start + (i-flank_start)/2] = 1; - i = std::min(i+d_max_len, noutput_items-1); - } - } - } - - return i; -} - - } /* namespace analog */ -} /* namespace gr */ - diff --git a/gr-analog/lib/plateau_detector_fb_impl.h b/gr-analog/lib/plateau_detector_fb_impl.h deleted file mode 100644 index daf1dd56d9..0000000000 --- a/gr-analog/lib/plateau_detector_fb_impl.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef INCLUDED_ANALOG_PLATEAU_DETECTOR_FB_IMPL_H -#define INCLUDED_ANALOG_PLATEAU_DETECTOR_FB_IMPL_H - -#include <analog/plateau_detector_fb.h> - -namespace gr { - namespace analog { - -class plateau_detector_fb_impl : public plateau_detector_fb -{ - private: - int d_max_len; - float d_threshold; - - public: - plateau_detector_fb_impl(int max_len, float threshold); - ~plateau_detector_fb_impl(); - - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - - } // namespace analog -} // namespace gr - -#endif /* INCLUDED_ANALOG_PLATEAU_DETECTOR_FB_IMPL_H */ - diff --git a/gr-analog/lib/pll_carriertracking_cc_impl.cc b/gr-analog/lib/pll_carriertracking_cc_impl.cc index c53e0f4332..9213a5e681 100644 --- a/gr-analog/lib/pll_carriertracking_cc_impl.cc +++ b/gr-analog/lib/pll_carriertracking_cc_impl.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2010-2012 Free Software Foundation, Inc. + * Copyright 2006,2010-2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -50,7 +50,7 @@ namespace gr { : gr_sync_block("pll_carriertracking_cc", gr_make_io_signature(1, 1, sizeof(gr_complex)), gr_make_io_signature(1, 1, sizeof(gr_complex))), - gri_control_loop(loop_bw, max_freq, min_freq), + blocks::control_loop(loop_bw, max_freq, min_freq), d_locksig(0), d_lock_threshold(0), d_squelch_enable(false) { } @@ -130,98 +130,98 @@ namespace gr { void pll_carriertracking_cc_impl::set_loop_bandwidth(float bw) { - gri_control_loop::set_loop_bandwidth(bw); + blocks::control_loop::set_loop_bandwidth(bw); } void pll_carriertracking_cc_impl::set_damping_factor(float df) { - gri_control_loop::set_damping_factor(df); + blocks::control_loop::set_damping_factor(df); } void pll_carriertracking_cc_impl::set_alpha(float alpha) { - gri_control_loop::set_alpha(alpha); + blocks::control_loop::set_alpha(alpha); } void pll_carriertracking_cc_impl::set_beta(float beta) { - gri_control_loop::set_beta(beta); + blocks::control_loop::set_beta(beta); } void pll_carriertracking_cc_impl::set_frequency(float freq) { - gri_control_loop::set_frequency(freq); + blocks::control_loop::set_frequency(freq); } void pll_carriertracking_cc_impl::set_phase(float phase) { - gri_control_loop::set_phase(phase); + blocks::control_loop::set_phase(phase); } void pll_carriertracking_cc_impl::set_min_freq(float freq) { - gri_control_loop::set_min_freq(freq); + blocks::control_loop::set_min_freq(freq); } void pll_carriertracking_cc_impl::set_max_freq(float freq) { - gri_control_loop::set_max_freq(freq); + blocks::control_loop::set_max_freq(freq); } float pll_carriertracking_cc_impl::get_loop_bandwidth() const { - return gri_control_loop::get_loop_bandwidth(); + return blocks::control_loop::get_loop_bandwidth(); } float pll_carriertracking_cc_impl::get_damping_factor() const { - return gri_control_loop::get_damping_factor(); + return blocks::control_loop::get_damping_factor(); } float pll_carriertracking_cc_impl::get_alpha() const { - return gri_control_loop::get_alpha(); + return blocks::control_loop::get_alpha(); } float pll_carriertracking_cc_impl::get_beta() const { - return gri_control_loop::get_beta(); + return blocks::control_loop::get_beta(); } float pll_carriertracking_cc_impl::get_frequency() const { - return gri_control_loop::get_frequency(); + return blocks::control_loop::get_frequency(); } float pll_carriertracking_cc_impl::get_phase() const { - return gri_control_loop::get_phase(); + return blocks::control_loop::get_phase(); } float pll_carriertracking_cc_impl::get_min_freq() const { - return gri_control_loop::get_min_freq(); + return blocks::control_loop::get_min_freq(); } float pll_carriertracking_cc_impl::get_max_freq() const { - return gri_control_loop::get_max_freq(); + return blocks::control_loop::get_max_freq(); } } /* namespace analog */ diff --git a/gr-analog/lib/pll_carriertracking_cc_impl.h b/gr-analog/lib/pll_carriertracking_cc_impl.h index d67223db82..c809736709 100644 --- a/gr-analog/lib/pll_carriertracking_cc_impl.h +++ b/gr-analog/lib/pll_carriertracking_cc_impl.h @@ -24,13 +24,11 @@ #define INCLUDED_ANALOG_PLL_CARRIERTRACKING_CC_IMPL_H #include <analog/pll_carriertracking_cc.h> -#include <gri_control_loop.h> namespace gr { namespace analog { - class pll_carriertracking_cc_impl - : public pll_carriertracking_cc, public gri_control_loop + class pll_carriertracking_cc_impl : public pll_carriertracking_cc { private: float d_locksig,d_lock_threshold; diff --git a/gr-analog/lib/pll_freqdet_cf_impl.cc b/gr-analog/lib/pll_freqdet_cf_impl.cc index 27e8d02aa4..9e55d9bedb 100644 --- a/gr-analog/lib/pll_freqdet_cf_impl.cc +++ b/gr-analog/lib/pll_freqdet_cf_impl.cc @@ -47,7 +47,7 @@ namespace gr { : gr_sync_block("pll_freqdet_cf", gr_make_io_signature(1, 1, sizeof(gr_complex)), gr_make_io_signature(1, 1, sizeof(float))), - gri_control_loop(loop_bw, max_freq, min_freq) + blocks::control_loop(loop_bw, max_freq, min_freq) { } @@ -100,98 +100,98 @@ namespace gr { void pll_freqdet_cf_impl::set_loop_bandwidth(float bw) { - gri_control_loop::set_loop_bandwidth(bw); + blocks::control_loop::set_loop_bandwidth(bw); } void pll_freqdet_cf_impl::set_damping_factor(float df) { - gri_control_loop::set_damping_factor(df); + blocks::control_loop::set_damping_factor(df); } void pll_freqdet_cf_impl::set_alpha(float alpha) { - gri_control_loop::set_alpha(alpha); + blocks::control_loop::set_alpha(alpha); } void pll_freqdet_cf_impl::set_beta(float beta) { - gri_control_loop::set_beta(beta); + blocks::control_loop::set_beta(beta); } void pll_freqdet_cf_impl::set_frequency(float freq) { - gri_control_loop::set_frequency(freq); + blocks::control_loop::set_frequency(freq); } void pll_freqdet_cf_impl::set_phase(float phase) { - gri_control_loop::set_phase(phase); + blocks::control_loop::set_phase(phase); } void pll_freqdet_cf_impl::set_min_freq(float freq) { - gri_control_loop::set_min_freq(freq); + blocks::control_loop::set_min_freq(freq); } void pll_freqdet_cf_impl::set_max_freq(float freq) { - gri_control_loop::set_max_freq(freq); + blocks::control_loop::set_max_freq(freq); } float pll_freqdet_cf_impl::get_loop_bandwidth() const { - return gri_control_loop::get_loop_bandwidth(); + return blocks::control_loop::get_loop_bandwidth(); } float pll_freqdet_cf_impl::get_damping_factor() const { - return gri_control_loop::get_damping_factor(); + return blocks::control_loop::get_damping_factor(); } float pll_freqdet_cf_impl::get_alpha() const { - return gri_control_loop::get_alpha(); + return blocks::control_loop::get_alpha(); } float pll_freqdet_cf_impl::get_beta() const { - return gri_control_loop::get_beta(); + return blocks::control_loop::get_beta(); } float pll_freqdet_cf_impl::get_frequency() const { - return gri_control_loop::get_frequency(); + return blocks::control_loop::get_frequency(); } float pll_freqdet_cf_impl::get_phase() const { - return gri_control_loop::get_phase(); + return blocks::control_loop::get_phase(); } float pll_freqdet_cf_impl::get_min_freq() const { - return gri_control_loop::get_min_freq(); + return blocks::control_loop::get_min_freq(); } float pll_freqdet_cf_impl::get_max_freq() const { - return gri_control_loop::get_max_freq(); + return blocks::control_loop::get_max_freq(); } } /* namespace analog */ diff --git a/gr-analog/lib/pll_freqdet_cf_impl.h b/gr-analog/lib/pll_freqdet_cf_impl.h index 7acf53ebbf..3170d819b6 100644 --- a/gr-analog/lib/pll_freqdet_cf_impl.h +++ b/gr-analog/lib/pll_freqdet_cf_impl.h @@ -24,13 +24,11 @@ #define INCLUDED_ANALOG_PLL_FREQDET_CF_IMPL_H #include <analog/pll_freqdet_cf.h> -#include <gri_control_loop.h> namespace gr { namespace analog { - class pll_freqdet_cf_impl : - public pll_freqdet_cf, public gri_control_loop + class pll_freqdet_cf_impl : public pll_freqdet_cf { private: float phase_detector(gr_complex sample,float ref_phase); diff --git a/gr-analog/lib/pll_refout_cc_impl.cc b/gr-analog/lib/pll_refout_cc_impl.cc index b94e3660a3..3f0ccc7df5 100644 --- a/gr-analog/lib/pll_refout_cc_impl.cc +++ b/gr-analog/lib/pll_refout_cc_impl.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010-2012 Free Software Foundation, Inc. + * Copyright 2004,2010-2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -48,7 +48,7 @@ namespace gr { : gr_sync_block("pll_refout_cc", gr_make_io_signature(1, 1, sizeof(gr_complex)), gr_make_io_signature(1, 1, sizeof(gr_complex))), - gri_control_loop(loop_bw, max_freq, min_freq) + blocks::control_loop(loop_bw, max_freq, min_freq) { } @@ -103,98 +103,98 @@ namespace gr { void pll_refout_cc_impl::set_loop_bandwidth(float bw) { - gri_control_loop::set_loop_bandwidth(bw); + blocks::control_loop::set_loop_bandwidth(bw); } void pll_refout_cc_impl::set_damping_factor(float df) { - gri_control_loop::set_damping_factor(df); + blocks::control_loop::set_damping_factor(df); } void pll_refout_cc_impl::set_alpha(float alpha) { - gri_control_loop::set_alpha(alpha); + blocks::control_loop::set_alpha(alpha); } void pll_refout_cc_impl::set_beta(float beta) { - gri_control_loop::set_beta(beta); + blocks::control_loop::set_beta(beta); } void pll_refout_cc_impl::set_frequency(float freq) { - gri_control_loop::set_frequency(freq); + blocks::control_loop::set_frequency(freq); } void pll_refout_cc_impl::set_phase(float phase) { - gri_control_loop::set_phase(phase); + blocks::control_loop::set_phase(phase); } void pll_refout_cc_impl::set_min_freq(float freq) { - gri_control_loop::set_min_freq(freq); + blocks::control_loop::set_min_freq(freq); } void pll_refout_cc_impl::set_max_freq(float freq) { - gri_control_loop::set_max_freq(freq); + blocks::control_loop::set_max_freq(freq); } float pll_refout_cc_impl::get_loop_bandwidth() const { - return gri_control_loop::get_loop_bandwidth(); + return blocks::control_loop::get_loop_bandwidth(); } float pll_refout_cc_impl::get_damping_factor() const { - return gri_control_loop::get_damping_factor(); + return blocks::control_loop::get_damping_factor(); } float pll_refout_cc_impl::get_alpha() const { - return gri_control_loop::get_alpha(); + return blocks::control_loop::get_alpha(); } float pll_refout_cc_impl::get_beta() const { - return gri_control_loop::get_beta(); + return blocks::control_loop::get_beta(); } float pll_refout_cc_impl::get_frequency() const { - return gri_control_loop::get_frequency(); + return blocks::control_loop::get_frequency(); } float pll_refout_cc_impl::get_phase() const { - return gri_control_loop::get_phase(); + return blocks::control_loop::get_phase(); } float pll_refout_cc_impl::get_min_freq() const { - return gri_control_loop::get_min_freq(); + return blocks::control_loop::get_min_freq(); } float pll_refout_cc_impl::get_max_freq() const { - return gri_control_loop::get_max_freq(); + return blocks::control_loop::get_max_freq(); } } /* namespace analog */ diff --git a/gr-analog/lib/pll_refout_cc_impl.h b/gr-analog/lib/pll_refout_cc_impl.h index 9e8ae286b1..1734b6e138 100644 --- a/gr-analog/lib/pll_refout_cc_impl.h +++ b/gr-analog/lib/pll_refout_cc_impl.h @@ -24,13 +24,11 @@ #define INCLUDED_ANALOG_PLL_REFOUT_CC_IMPL_H #include <analog/pll_refout_cc.h> -#include <gri_control_loop.h> namespace gr { namespace analog { - class pll_refout_cc_impl - : public pll_refout_cc, public gri_control_loop + class pll_refout_cc_impl : public pll_refout_cc { private: float mod_2pi (float in); diff --git a/gr-analog/lib/qa_analog.cc b/gr-analog/lib/qa_analog.cc index c3d51863bd..c7c975a3e5 100644 --- a/gr-analog/lib/qa_analog.cc +++ b/gr-analog/lib/qa_analog.cc @@ -26,16 +26,11 @@ */ #include <qa_analog.h> -#include <qa_sincos.h> -#include <qa_rotator.h> CppUnit::TestSuite * qa_gr_analog::suite() { CppUnit::TestSuite *s = new CppUnit::TestSuite("gr-analog"); - s->addTest(gr::analog::qa_sincos::suite()); - s->addTest(gr::analog::qa_rotator::suite()); - return s; } diff --git a/gr-analog/lib/qa_analog.h b/gr-analog/lib/qa_analog.h index 458861cc91..b66b62b5fe 100644 --- a/gr-analog/lib/qa_analog.h +++ b/gr-analog/lib/qa_analog.h @@ -23,7 +23,7 @@ #ifndef _QA_GR_ANALOG_H_ #define _QA_GR_ANALOG_H_ -#include <gruel/attributes.h> +#include <attributes.h> #include <cppunit/TestSuite.h> //! collect all the tests for the gr-analog directory diff --git a/gr-analog/lib/qa_rotator.cc b/gr-analog/lib/qa_rotator.cc deleted file mode 100644 index b722f32c43..0000000000 --- a/gr-analog/lib/qa_rotator.cc +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2002,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <gruel/attributes.h> -#include <cppunit/TestAssert.h> -#include <qa_rotator.h> -#include <analog/rotator.h> -#include <stdio.h> -#include <cmath> -#include <gr_expj.h> - -namespace gr { - namespace analog { - - // error vector magnitude - __GR_ATTR_UNUSED static float - error_vector_mag(gr_complex a, gr_complex b) - { - return abs(a-b); - } - - void - qa_rotator::t1() - { - static const unsigned int N = 100000; - - rotator r; - - double phase_incr = 2*M_PI / 1003; - double phase = 0; - - // Old code: We increment then return the rotated value, thus we - // need to start one tick back - // r.set_phase(gr_complex(1,0) * conj(gr_expj(phase_incr))); - - r.set_phase(gr_complex(1,0)); - r.set_phase_incr(gr_expj(phase_incr)); - - for(unsigned i = 0; i < N; i++) { - gr_complex expected = gr_expj(phase); - gr_complex actual = r.rotate(gr_complex(1, 0)); - -#if 0 - float evm = error_vector_mag(expected, actual); - printf("[%6d] expected: (%8.6f, %8.6f) actual: (%8.6f, %8.6f) evm: %8.6f\n", - i, expected.real(), expected.imag(), actual.real(), actual.imag(), evm); -#endif - - CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected, actual, 0.0001); - - phase += phase_incr; - if(phase >= 2*M_PI) - phase -= 2*M_PI; - } - } - - } /* namespace analog */ -} /* namespace gr */ diff --git a/gr-analog/lib/qa_sincos.cc b/gr-analog/lib/qa_sincos.cc deleted file mode 100644 index 62642c1171..0000000000 --- a/gr-analog/lib/qa_sincos.cc +++ /dev/null @@ -1,75 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <qa_sincos.h> -#include <analog/sincos.h> -#include <gruel/attributes.h> -#include <cppunit/TestAssert.h> -#include <cmath> - -namespace gr { - namespace analog { - - void - qa_sincos::t1() - { - static const unsigned int N = 1000; - double c_sin, c_cos; - double gr_sin, gr_cos; - - for(unsigned i = 0; i < N; i++) { - double x = i/100.0; - c_sin = sin(x); - c_cos = cos(x); - - analog::sincos(x, &gr_sin, &gr_cos); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(c_sin, gr_sin, 0.0001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(c_cos, gr_cos, 0.0001); - } - } - - void - qa_sincos::t2() - { - static const unsigned int N = 1000; - float c_sin, c_cos; - float gr_sin, gr_cos; - - for(unsigned i = 0; i < N; i++) { - float x = i/100.0; - c_sin = sinf(x); - c_cos = cosf(x); - - analog::sincosf(x, &gr_sin, &gr_cos); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(c_sin, gr_sin, 0.0001); - CPPUNIT_ASSERT_DOUBLES_EQUAL(c_cos, gr_cos, 0.0001); - } - } - - } /* namespace analog */ -} /* namespace gr */ diff --git a/gr-analog/lib/qa_sincos.h b/gr-analog/lib/qa_sincos.h deleted file mode 100644 index f18e879dd8..0000000000 --- a/gr-analog/lib/qa_sincos.h +++ /dev/null @@ -1,47 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifndef _QA_ANALOG_SINCOS_H_ -#define _QA_ANALOG_SINCOS_H_ - -#include <cppunit/extensions/HelperMacros.h> -#include <cppunit/TestCase.h> - -namespace gr { - namespace analog { - - class qa_sincos : public CppUnit::TestCase - { - CPPUNIT_TEST_SUITE(qa_sincos); - CPPUNIT_TEST(t1); - CPPUNIT_TEST(t2); - CPPUNIT_TEST_SUITE_END(); - - private: - void t1(); - void t2(); - }; - - } /* namespace analog */ -} /* namespace gr */ - -#endif /* _QA_ANALOG_SINCOS_H_ */ diff --git a/gr-analog/lib/sig_source_X_impl.cc.t b/gr-analog/lib/sig_source_X_impl.cc.t index 60653dc1bb..ad8b7e4b0c 100644 --- a/gr-analog/lib/sig_source_X_impl.cc.t +++ b/gr-analog/lib/sig_source_X_impl.cc.t @@ -211,7 +211,7 @@ namespace gr { #endif default: - throw std::runtime_error("gr_sig_source: invalid waveform"); + throw std::runtime_error("analog::sig_source: invalid waveform"); } return noutput_items; diff --git a/gr-analog/lib/sincos.cc b/gr-analog/lib/sincos.cc deleted file mode 100644 index 14ceeb3a29..0000000000 --- a/gr-analog/lib/sincos.cc +++ /dev/null @@ -1,89 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2010,2012 Free Software Foundation, Inc. - * - * This file is part of GNU Radio - * - * GNU Radio 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, or (at your option) - * any later version. - * - * GNU Radio 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 GNU Radio; see the file COPYING. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, - * Boston, MA 02110-1301, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE // ask for GNU extensions if available -#endif - -#include <analog/sincos.h> -#include <math.h> - -namespace gr { - namespace analog { - -// ---------------------------------------------------------------- - -#if defined (HAVE_SINCOS) - - void - sincos(double x, double *sinx, double *cosx) - { - ::sincos(x, sinx, cosx); - } - -#else - - void - sincos(double x, double *sinx, double *cosx) - { - *sinx = sin(x); - *cosx = cos(x); - } - -#endif - -// ---------------------------------------------------------------- - -#if defined (HAVE_SINCOSF) - - void - sincosf(float x, float *sinx, float *cosx) - { - sincosf(x, sinx, cosx); - } - -#elif defined (HAVE_SINF) && defined (HAVE_COSF) - - void - sincosf(float x, float *sinx, float *cosx) - { - *sinx = sinf(x); - *cosx = cosf(x); - } - -#else - - void - sincosf(float x, float *sinx, float *cosx) - { - *sinx = sin(x); - *cosx = cos(x); - } - -#endif - - } /* namespace analog */ -} /* namespace gr */ diff --git a/gr-analog/lib/test_gr_analog.cc b/gr-analog/lib/test_gr_analog.cc index 00d6242699..95ee3aa8cb 100644 --- a/gr-analog/lib/test_gr_analog.cc +++ b/gr-analog/lib/test_gr_analog.cc @@ -20,6 +20,10 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <cppunit/TextTestRunner.h> #include <cppunit/XmlOutputter.h> diff --git a/gr-analog/python/CMakeLists.txt b/gr-analog/python/CMakeLists.txt index af4ed578f3..e4d1d0aa74 100644 --- a/gr-analog/python/CMakeLists.txt +++ b/gr-analog/python/CMakeLists.txt @@ -25,6 +25,16 @@ include(GrPython) GR_PYTHON_INSTALL( FILES __init__.py + am_demod.py + fm_demod.py + fm_emph.py + nbfm_rx.py + nbfm_tx.py + standard_squelch.py + wfm_rcv.py + wfm_rcv_fmdet.py + wfm_rcv_pll.py + wfm_tx.py DESTINATION ${GR_PYTHON_DIR}/gnuradio/analog COMPONENT "analog_python" ) @@ -37,6 +47,8 @@ if(ENABLE_TESTING) list(APPEND GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/gr-analog/python ${CMAKE_BINARY_DIR}/gr-analog/swig + ${CMAKE_BINARY_DIR}/gr-blocks/python + ${CMAKE_BINARY_DIR}/gr-blocks/swig ${CMAKE_BINARY_DIR}/gr-filter/python ${CMAKE_BINARY_DIR}/gr-filter/swig ) diff --git a/gr-analog/python/__init__.py b/gr-analog/python/__init__.py index fc345028b9..a5ab5715d7 100644 --- a/gr-analog/python/__init__.py +++ b/gr-analog/python/__init__.py @@ -25,3 +25,14 @@ Blocks and utilities for analog modulation and demodulation. # The presence of this file turns this directory into a Python package from analog_swig import * + +from am_demod import * +from fm_demod import * +from fm_emph import * +from nbfm_rx import * +from nbfm_tx import * +from standard_squelch import * +from wfm_rcv import * +from wfm_rcv_fmdet import * +from wfm_rcv_pll import * +from wfm_tx import * diff --git a/gr-analog/python/am_demod.py b/gr-analog/python/am_demod.py new file mode 100644 index 0000000000..3459e825f4 --- /dev/null +++ b/gr-analog/python/am_demod.py @@ -0,0 +1,73 @@ +# +# Copyright 2006,2007,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr +from gnuradio import blocks +from gnuradio import filter + +class am_demod_cf(gr.hier_block2): + """ + Generalized AM demodulation block with audio filtering. + + This block demodulates a band-limited, complex down-converted AM + channel into the the original baseband signal, applying low pass + filtering to the audio output. It produces a float stream in the + range [-1.0, +1.0]. + + Args: + channel_rate: incoming sample rate of the AM baseband (integer) + audio_decim: input to output decimation rate (integer) + audio_pass: audio low pass filter passband frequency (float) + audio_stop: audio low pass filter stop frequency (float) + """ + def __init__(self, channel_rate, audio_decim, audio_pass, audio_stop): + gr.hier_block2.__init__(self, "am_demod_cf", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Input signature + + MAG = blocks.complex_to_mag() + DCR = blocks.add_const_ff(-1.0) + + audio_taps = filter.optfir.low_pass(0.5, # Filter gain + channel_rate, # Sample rate + audio_pass, # Audio passband + audio_stop, # Audio stopband + 0.1, # Passband ripple + 60) # Stopband attenuation + LPF = filter.fir_filter_fff(audio_decim, audio_taps) + + self.connect(self, MAG, DCR, LPF, self) + +class demod_10k0a3e_cf(am_demod_cf): + """ + AM demodulation block, 10 KHz channel. + + This block demodulates an AM channel conformant to 10K0A3E emission + standards, such as broadcast band AM transmissions. + + Args: + channel_rate: incoming sample rate of the AM baseband (integer) + audio_decim: input to output decimation rate (integer) + """ + def __init__(self, channel_rate, audio_decim): + am_demod_cf.__init__(self, channel_rate, audio_decim, + 5000, # Audio passband + 5500) # Audio stopband diff --git a/gr-analog/python/fm_demod.py b/gr-analog/python/fm_demod.py new file mode 100644 index 0000000000..1976a076ca --- /dev/null +++ b/gr-analog/python/fm_demod.py @@ -0,0 +1,108 @@ +# +# Copyright 2006,2007,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, filter +from fm_emph import fm_deemph +from math import pi + +try: + from gnuradio import analog +except ImportError: + import analog_swig as analog + +class fm_demod_cf(gr.hier_block2): + """ + Generalized FM demodulation block with deemphasis and audio + filtering. + + This block demodulates a band-limited, complex down-converted FM + channel into the the original baseband signal, optionally applying + deemphasis. Low pass filtering is done on the resultant signal. It + produces an output float strem in the range of [-1.0, +1.0]. + + Args: + channel_rate: incoming sample rate of the FM baseband (integer) + deviation: maximum FM deviation (default = 5000) (float) + audio_decim: input to output decimation rate (integer) + audio_pass: audio low pass filter passband frequency (float) + audio_stop: audio low pass filter stop frequency (float) + gain: gain applied to audio output (default = 1.0) (float) + tau: deemphasis time constant (default = 75e-6), specify 'None' to prevent deemphasis + """ + def __init__(self, channel_rate, audio_decim, deviation, + audio_pass, audio_stop, gain=1.0, tau=75e-6): + gr.hier_block2.__init__(self, "fm_demod_cf", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + k = channel_rate/(2*pi*deviation) + QUAD = analog.quadrature_demod_cf(k) + + audio_taps = filter.optfir.low_pass(gain, # Filter gain + channel_rate, # Sample rate + audio_pass, # Audio passband + audio_stop, # Audio stopband + 0.1, # Passband ripple + 60) # Stopband attenuation + LPF = filter.fir_filter_fff(audio_decim, audio_taps) + + if tau is not None: + DEEMPH = fm_deemph(channel_rate, tau) + self.connect(self, QUAD, DEEMPH, LPF, self) + else: + self.connect(self, QUAD, LPF, self) + +class demod_20k0f3e_cf(fm_demod_cf): + """ + NBFM demodulation block, 20 KHz channels + + This block demodulates a complex, downconverted, narrowband FM + channel conforming to 20K0F3E emission standards, outputting + floats in the range [-1.0, +1.0]. + + Args: + sample_rate: incoming sample rate of the FM baseband (integer) + audio_decim: input to output decimation rate (integer) + """ + def __init__(self, channel_rate, audio_decim): + fm_demod_cf.__init__(self, channel_rate, audio_decim, + 5000, # Deviation + 3000, # Audio passband frequency + 4500) # Audio stopband frequency + +class demod_200kf3e_cf(fm_demod_cf): + """ + WFM demodulation block, mono. + + This block demodulates a complex, downconverted, wideband FM + channel conforming to 200KF3E emission standards, outputting + floats in the range [-1.0, +1.0]. + + Args: + sample_rate: incoming sample rate of the FM baseband (integer) + audio_decim: input to output decimation rate (integer) + """ + def __init__(self, channel_rate, audio_decim): + fm_demod_cf.__init__(self, channel_rate, audio_decim, + 75000, # Deviation + 15000, # Audio passband + 16000, # Audio stopband + 20.0) # Audio gain diff --git a/gr-analog/python/fm_emph.py b/gr-analog/python/fm_emph.py new file mode 100644 index 0000000000..2821f6e3cd --- /dev/null +++ b/gr-analog/python/fm_emph.py @@ -0,0 +1,150 @@ +# +# Copyright 2005,2007,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, filter +import math + +# +# 1 +# H(s) = ------- +# 1 + s +# +# tau is the RC time constant. +# critical frequency: w_p = 1/tau +# +# We prewarp and use the bilinear z-transform to get our IIR coefficients. +# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis +# + +class fm_deemph(gr.hier_block2): + """ + FM Deemphasis IIR filter. + """ + + + def __init__(self, fs, tau=75e-6): + """ + + Args: + fs: sampling frequency in Hz (float) + tau: Time constant in seconds (75us in US, 50us in EUR) (float) + """ + gr.hier_block2.__init__(self, "fm_deemph", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + w_p = 1/tau + w_pp = math.tan(w_p / (fs * 2)) # prewarped analog freq + + a1 = (w_pp - 1)/(w_pp + 1) + b0 = w_pp/(1 + w_pp) + b1 = b0 + + btaps = [b0, b1] + ataps = [1, a1] + + if 0: + print "btaps =", btaps + print "ataps =", ataps + global plot1 + plot1 = gru.gnuplot_freqz(gru.freqz(btaps, ataps), fs, True) + + deemph = filter.iir_filter_ffd(btaps, ataps) + self.connect(self, deemph, self) + +# +# 1 + s*t1 +# H(s) = ---------- +# 1 + s*t2 +# +# I think this is the right transfer function. +# +# +# This fine ASCII rendition is based on Figure 5-15 +# in "Digital and Analog Communication Systems", Leon W. Couch II +# +# +# R1 +# +-----||------+ +# | | +# o------+ +-----+--------o +# | C1 | | +# +----/\/\/\/--+ \ +# / +# \ R2 +# / +# \ +# | +# o--------------------------+--------o +# +# f1 = 1/(2*pi*t1) = 1/(2*pi*R1*C) +# +# 1 R1 + R2 +# f2 = ------- = ------------ +# 2*pi*t2 2*pi*R1*R2*C +# +# t1 is 75us in US, 50us in EUR +# f2 should be higher than our audio bandwidth. +# +# +# The Bode plot looks like this: +# +# +# /---------------- +# / +# / <-- slope = 20dB/decade +# / +# -------------/ +# f1 f2 +# +# We prewarp and use the bilinear z-transform to get our IIR coefficients. +# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis +# + +class fm_preemph(gr.hier_block2): + """ + FM Preemphasis IIR filter. + """ + def __init__(self, fs, tau=75e-6): + """ + + Args: + fs: sampling frequency in Hz (float) + tau: Time constant in seconds (75us in US, 50us in EUR) (float) + """ + + gr.hier_block2.__init__(self, "fm_deemph", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + # FIXME make this compute the right answer + + btaps = [1] + ataps = [1] + + if 0: + print "btaps =", btaps + print "ataps =", ataps + global plot2 + plot2 = gru.gnuplot_freqz(gru.freqz(btaps, ataps), fs, True) + + preemph = filter.iir_filter_ffd(btaps, ataps) + self.connect(self, preemph, self) diff --git a/gr-analog/python/nbfm_rx.py b/gr-analog/python/nbfm_rx.py new file mode 100644 index 0000000000..b2c86db70f --- /dev/null +++ b/gr-analog/python/nbfm_rx.py @@ -0,0 +1,90 @@ +# +# Copyright 2005,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import math +from gnuradio import gr +from gnuradio import filter +from fm_emph import fm_deemph + +try: + from gnuradio import analog +except ImportError: + import analog_swig as analog + +class nbfm_rx(gr.hier_block2): + def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=5e3): + """ + Narrow Band FM Receiver. + + Takes a single complex baseband input stream and produces a single + float output stream of audio sample in the range [-1, +1]. + + Args: + audio_rate: sample rate of audio stream, >= 16k (integer) + quad_rate: sample rate of output stream (integer) + tau: preemphasis time constant (default 75e-6) (float) + max_dev: maximum deviation in Hz (default 5e3) (float) + + quad_rate must be an integer multiple of audio_rate. + + Exported sub-blocks (attributes): + squelch + quad_demod + deemph + audio_filter + """ + + gr.hier_block2.__init__(self, "nbfm_rx", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + # FIXME audio_rate and quad_rate ought to be exact rationals + audio_rate = int(audio_rate) + quad_rate = int(quad_rate) + + if quad_rate % audio_rate != 0: + raise ValueError, "quad_rate is not an integer multiple of audio_rate" + + squelch_threshold = 20 # dB + #self.squelch = analog.simple_squelch_cc(squelch_threshold, 0.001) + + # FM Demodulator input: complex; output: float + k = quad_rate/(2*math.pi*max_dev) + self.quad_demod = analog.quadrature_demod_cf(k) + + # FM Deemphasis IIR filter + self.deemph = fm_deemph(quad_rate, tau=tau) + + # compute FIR taps for audio filter + audio_decim = quad_rate // audio_rate + audio_taps = filter.firdes.low_pass(1.0, # gain + quad_rate, # sampling rate + 2.7e3, # Audio LPF cutoff + 0.5e3, # Transition band + filter.firdes.WIN_HAMMING) # filter type + + print "len(audio_taps) =", len(audio_taps) + + # Decimating audio filter + # input: float; output: float; taps: float + self.audio_filter = filter.fir_filter_fff(audio_decim, audio_taps) + + self.connect(self, self.quad_demod, self.deemph, self.audio_filter, self) diff --git a/gr-analog/python/nbfm_tx.py b/gr-analog/python/nbfm_tx.py new file mode 100644 index 0000000000..62b56bae52 --- /dev/null +++ b/gr-analog/python/nbfm_tx.py @@ -0,0 +1,93 @@ +# +# Copyright 2005,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import math +from gnuradio import gr, filter +from fm_emph import fm_preemph + +try: + from gnuradio import analog +except ImportError: + import analog_swig as analog + +class nbfm_tx(gr.hier_block2): + def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=5e3): + """ + Narrow Band FM Transmitter. + + Takes a single float input stream of audio samples in the range [-1,+1] + and produces a single FM modulated complex baseband output. + + Args: + audio_rate: sample rate of audio stream, >= 16k (integer) + quad_rate: sample rate of output stream (integer) + tau: preemphasis time constant (default 75e-6) (float) + max_dev: maximum deviation in Hz (default 5e3) (float) + + quad_rate must be an integer multiple of audio_rate. + """ + + gr.hier_block2.__init__(self, "nbfm_tx", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + + # FIXME audio_rate and quad_rate ought to be exact rationals + audio_rate = int(audio_rate) + quad_rate = int(quad_rate) + + if quad_rate % audio_rate != 0: + raise ValueError, "quad_rate is not an integer multiple of audio_rate" + + + do_interp = audio_rate != quad_rate + + if do_interp: + interp_factor = quad_rate / audio_rate + interp_taps = filter.optfir.low_pass(interp_factor, # gain + quad_rate, # Fs + 4500, # passband cutoff + 7000, # stopband cutoff + 0.1, # passband ripple dB + 40) # stopband atten dB + + #print "len(interp_taps) =", len(interp_taps) + self.interpolator = filter.interp_fir_filter_fff (interp_factor, interp_taps) + + self.preemph = fm_preemph(quad_rate, tau=tau) + + k = 2 * math.pi * max_dev / quad_rate + self.modulator = analog.frequency_modulator_fc(k) + + if do_interp: + self.connect(self, self.interpolator, self.preemph, self.modulator, self) + else: + self.connect(self, self.preemph, self.modulator, self) + + +class ctcss_gen_f(gr.hier_block2): + def __init__(self, sample_rate, tone_freq): + gr.hier_block2.__init__(self, "ctcss_gen_f", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + self.plgen = analog.sig_source_f(sample_rate, analog.GR_SIN_WAVE, + tone_freq, 0.1, 0.0) + self.connect(self.plgen, self) diff --git a/gr-analog/python/qa_agc.py b/gr-analog/python/qa_agc.py index dc4922cf84..0d8a7bfb5d 100755 --- a/gr-analog/python/qa_agc.py +++ b/gr-analog/python/qa_agc.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc. +# Copyright 2004,2007,2010,2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,16 +22,15 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math -test_output = False +class test_agc(gr_unittest.TestCase): -class test_agc (gr_unittest.TestCase): + def setUp(self): + self.tb = gr.top_block() - def setUp (self): - self.tb = gr.top_block () - - def tearDown (self): + def tearDown(self): self.tb = None @@ -105,10 +104,10 @@ class test_agc (gr_unittest.TestCase): (1.26766037940979-0.92100900411605835j)) sampling_freq = 100 - src1 = gr.sig_source_c(sampling_freq, gr.GR_SIN_WAVE, - sampling_freq * 0.10, 100.0) - dst1 = gr.vector_sink_c() - head = gr.head(gr.sizeof_gr_complex, int (5*sampling_freq * 0.10)) + src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, + sampling_freq * 0.10, 100.0) + dst1 = blocks.vector_sink_c() + head = blocks.head(gr.sizeof_gr_complex, int (5*sampling_freq * 0.10)) agc = analog.agc_cc(1e-3, 1, 1, 1000) @@ -116,9 +115,6 @@ class test_agc (gr_unittest.TestCase): tb.connect(head, agc) tb.connect(agc, dst1) - if test_output == True: - tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc_cc.dat")) - tb.run() dst_data = dst1.data() self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) @@ -193,10 +189,10 @@ class test_agc (gr_unittest.TestCase): -3.3931560516357422) sampling_freq = 100 - src1 = gr.sig_source_f (sampling_freq, gr.GR_SIN_WAVE, - sampling_freq * 0.10, 100.0) - dst1 = gr.vector_sink_f () - head = gr.head (gr.sizeof_float, int (5*sampling_freq * 0.10)) + src1 = analog.sig_source_f(sampling_freq, analog.GR_SIN_WAVE, + sampling_freq * 0.10, 100.0) + dst1 = blocks.vector_sink_f () + head = blocks.head (gr.sizeof_float, int (5*sampling_freq * 0.10)) agc = analog.agc_ff(1e-3, 1, 1, 1000) @@ -204,9 +200,6 @@ class test_agc (gr_unittest.TestCase): tb.connect (head, agc) tb.connect (agc, dst1) - if test_output == True: - tb.connect (agc, gr.file_sink(gr.sizeof_float, "test_agc_ff.dat")) - tb.run () dst_data = dst1.data () self.assertFloatTuplesAlmostEqual (expected_result, dst_data, 4) @@ -283,10 +276,10 @@ class test_agc (gr_unittest.TestCase): (0.80901449918746948-0.5877833366394043j)) sampling_freq = 100 - src1 = gr.sig_source_c(sampling_freq, gr.GR_SIN_WAVE, - sampling_freq * 0.10, 100) - dst1 = gr.vector_sink_c() - head = gr.head(gr.sizeof_gr_complex, int(5*sampling_freq * 0.10)) + src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, + sampling_freq * 0.10, 100) + dst1 = blocks.vector_sink_c() + head = blocks.head(gr.sizeof_gr_complex, int(5*sampling_freq * 0.10)) agc = analog.agc2_cc(1e-2, 1e-3, 1, 1, 1000) @@ -294,9 +287,6 @@ class test_agc (gr_unittest.TestCase): tb.connect(head, agc) tb.connect(agc, dst1) - if test_output == True: - tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc2_cc.dat")) - tb.run() dst_data = dst1.data() self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) @@ -373,10 +363,10 @@ class test_agc (gr_unittest.TestCase): -0.61937344074249268) sampling_freq = 100 - src1 = gr.sig_source_f(sampling_freq, gr.GR_SIN_WAVE, - sampling_freq * 0.10, 100) - dst1 = gr.vector_sink_f() - head = gr.head(gr.sizeof_float, int(5*sampling_freq * 0.10)) + src1 = analog.sig_source_f(sampling_freq, analog.GR_SIN_WAVE, + sampling_freq * 0.10, 100) + dst1 = blocks.vector_sink_f() + head = blocks.head(gr.sizeof_float, int(5*sampling_freq * 0.10)) agc = analog.agc2_ff(1e-2, 1e-3, 1, 1, 1000) @@ -384,9 +374,6 @@ class test_agc (gr_unittest.TestCase): tb.connect(head, agc) tb.connect(agc, dst1) - if test_output == True: - tb.connect(agc, gr.file_sink(gr.sizeof_float, "test_agc2_ff.dat")) - tb.run() dst_data = dst1.data() self.assertFloatTuplesAlmostEqual(expected_result, dst_data, 4) @@ -449,10 +436,10 @@ class test_agc (gr_unittest.TestCase): (0.80901449918746948-0.5877833366394043j)) sampling_freq = 100 - src1 = gr.sig_source_c(sampling_freq, gr.GR_SIN_WAVE, - sampling_freq * 0.10, 100) - dst1 = gr.vector_sink_c() - head = gr.head(gr.sizeof_gr_complex, int(5*sampling_freq * 0.10)) + src1 = analog.sig_source_c(sampling_freq, analog.GR_SIN_WAVE, + sampling_freq * 0.10, 100) + dst1 = blocks.vector_sink_c() + head = blocks.head(gr.sizeof_gr_complex, int(5*sampling_freq * 0.10)) agc = analog.agc2_cc(1e-2, 1e-3, 1, 1, 1000) @@ -460,9 +447,6 @@ class test_agc (gr_unittest.TestCase): tb.connect(head, agc) tb.connect(agc, dst1) - if test_output == True: - tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, "test_agc2_cc.dat")) - tb.run() dst_data = dst1.data() self.assertComplexTuplesAlmostEqual(expected_result, dst_data, 4) @@ -476,15 +460,11 @@ class test_agc (gr_unittest.TestCase): input_data = 8*(0.0,) + 24*(1.0,) + 24*(0.0,) expected_result = (8+length-1)*(0.0,) + 24*(gain*1.0,) + (0,) - src = gr.vector_source_c(input_data) + src = blocks.vector_source_c(input_data) agc = analog.feedforward_agc_cc(8, 2.0) - dst = gr.vector_sink_c() + dst = blocks.vector_sink_c() self.tb.connect(src, agc, dst) - if test_output == True: - self.tb.connect(agc, gr.file_sink(gr.sizeof_gr_complex, - "test_feedforward_cc.dat")) - self.tb.run() dst_data = dst.data()[0:len(expected_result)] diff --git a/gr-analog/python/qa_cpfsk.py b/gr-analog/python/qa_cpfsk.py index decf94ea3f..7998d8079d 100755 --- a/gr-analog/python/qa_cpfsk.py +++ b/gr-analog/python/qa_cpfsk.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math class test_cpfsk_bc(gr_unittest.TestCase): @@ -52,9 +53,9 @@ class test_cpfsk_bc(gr_unittest.TestCase): src_data = 10*[0, 1] expected_result = map(lambda x: complex(2*x-1,0), src_data) - src = gr.vector_source_b(src_data) + src = blocks.vector_source_b(src_data) op = analog.cpfsk_bc(2, 1, 2) - dst = gr.vector_sink_c() + dst = blocks.vector_sink_c() self.tb.connect(src, op) self.tb.connect(op, dst) diff --git a/gr-analog/python/qa_ctcss_squelch.py b/gr-analog/python/qa_ctcss_squelch.py index 08d3dbfef8..622cca234f 100755 --- a/gr-analog/python/qa_ctcss_squelch.py +++ b/gr-analog/python/qa_ctcss_squelch.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks class test_ctcss_squelch(gr_unittest.TestCase): @@ -68,10 +69,10 @@ class test_ctcss_squelch(gr_unittest.TestCase): expected_result = src_data expected_result[0] = 0 - src = gr.vector_source_f(src_data) + src = blocks.vector_source_f(src_data) op = analog.ctcss_squelch_ff(rate, freq, level, length, ramp, gate) - dst = gr.vector_sink_f() + dst = blocks.vector_sink_f() self.tb.connect(src, op) self.tb.connect(op, dst) @@ -90,10 +91,10 @@ class test_ctcss_squelch(gr_unittest.TestCase): gate = False src_data = map(lambda x: float(x)/10.0, range(1, 40)) - src = gr.vector_source_f(src_data) + src = blocks.vector_source_f(src_data) op = analog.ctcss_squelch_ff(rate, freq, level, length, ramp, gate) - dst = gr.vector_sink_f() + dst = blocks.vector_sink_f() self.tb.connect(src, op) self.tb.connect(op, dst) diff --git a/gr-analog/python/qa_dpll.py b/gr-analog/python/qa_dpll.py index 3ef8a6e285..98ddf83eff 100755 --- a/gr-analog/python/qa_dpll.py +++ b/gr-analog/python/qa_dpll.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math class test_dpll_bb(gr_unittest.TestCase): @@ -60,9 +61,9 @@ class test_dpll_bb(gr_unittest.TestCase): src_data = 10*((period-1)*[0,] + [1,]) expected_result = src_data - src = gr.vector_source_b(src_data) + src = blocks.vector_source_b(src_data) op = analog.dpll_bb(period, gain) - dst = gr.vector_sink_b() + dst = blocks.vector_sink_b() self.tb.connect(src, op) self.tb.connect(op, dst) diff --git a/gr-analog/python/qa_plateau_detector_fb.py b/gr-analog/python/qa_fastnoise.py index 5f8abc74ec..040cf47522 100755..100644 --- a/gr-analog/python/qa_plateau_detector_fb.py +++ b/gr-analog/python/qa_fastnoise.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2007,2010,2012 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -23,7 +23,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog -class qa_plateau_detector_fb (gr_unittest.TestCase): +class test_fastnoise_source(gr_unittest.TestCase): def setUp (self): self.tb = gr.top_block () @@ -31,16 +31,22 @@ class qa_plateau_detector_fb (gr_unittest.TestCase): def tearDown (self): self.tb = None - def test_001_t (self): - # | Spur spike 1 | Plateau | Spur spike 2 - test_signal = (0, 1, .2, .4, .6, .8, 1, 1, 1, 1, 1, .8, .6, .4, 1, 0) - expected_sig = (0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0) - # | Center of Plateau - sink = gr.vector_sink_b() - self.tb.connect(gr.vector_source_f(test_signal), analog.plateau_detector_fb(5), sink) - self.tb.run () - self.assertEqual(expected_sig, sink.data()) + def test_001(self): + # Just confirm that we can instantiate a noise source + op = analog.fastnoise_source_f(analog.GR_GAUSSIAN, 10, 10) + + def test_002(self): + # Test get methods + set_type = analog.GR_GAUSSIAN + set_ampl = 10 + op = analog.fastnoise_source_f(set_type, set_ampl, 10) + get_type = op.type() + get_ampl = op.amplitude() + + self.assertEqual(get_type, set_type) + self.assertEqual(get_ampl, set_ampl) if __name__ == '__main__': - gr_unittest.run(qa_plateau_detector_fb, "qa_plateau_detector_fb.xml") + gr_unittest.run(test_fastnoise_source, "test_fastnoise_source.xml") + diff --git a/gr-analog/python/qa_fmdet.py b/gr-analog/python/qa_fmdet.py index b90ef2ffa4..6c99b08803 100755 --- a/gr-analog/python/qa_fmdet.py +++ b/gr-analog/python/qa_fmdet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math class test_fmdet_cf(gr_unittest.TestCase): @@ -62,10 +63,10 @@ class test_fmdet_cf(gr_unittest.TestCase): # block is saying, not what the values should actually be. def est_fmdet_cf_002(self): N = 100 - src = gr.sig_source_c(1, gr.GR_SIN_WAVE, 0.2, 1) - head = gr.head(gr.sizeof_gr_complex, N) + src = analog.sig_source_c(1, analog.GR_SIN_WAVE, 0.2, 1) + head = blocks.head(gr.sizeof_gr_complex, N) op = analog.fmdet_cf(1, 0.1, 0.3, 0.1) - dst = gr.vector_sink_f() + dst = blocks.vector_sink_f() self.tb.connect(src, head, op) self.tb.connect(op, dst) diff --git a/gr-analog/python/qa_frequency_modulator.py b/gr-analog/python/qa_frequency_modulator.py index b673b3275c..7d6cff3fea 100755 --- a/gr-analog/python/qa_frequency_modulator.py +++ b/gr-analog/python/qa_frequency_modulator.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc. +# Copyright 2004,2007,2010,2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math def sincos(x): @@ -42,9 +43,9 @@ class test_frequency_modulator(gr_unittest.TestCase): src_data = (1.0/4, 1.0/2, 1.0/4, -1.0/4, -1.0/2, -1/4.0) running_sum = (pi/16, 3*pi/16, pi/4, 3*pi/16, pi/16, 0) expected_result = tuple([sincos(x) for x in running_sum]) - src = gr.vector_source_f(src_data) + src = blocks.vector_source_f(src_data) op = analog.frequency_modulator_fc(sensitivity) - dst = gr.vector_sink_c() + dst = blocks.vector_sink_c() self.tb.connect(src, op) self.tb.connect(op, dst) self.tb.run() diff --git a/gr-analog/python/qa_phase_modulator.py b/gr-analog/python/qa_phase_modulator.py index a9c8c84597..81334177db 100755 --- a/gr-analog/python/qa_phase_modulator.py +++ b/gr-analog/python/qa_phase_modulator.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math def sincos(x): @@ -42,9 +43,9 @@ class test_phase_modulator(gr_unittest.TestCase): src_data = (1.0/4, 1.0/2, 1.0/4, -1.0/4, -1.0/2, -1/4.0) expected_result = tuple([sincos(sensitivity*x) for x in src_data]) - src = gr.vector_source_f(src_data) + src = blocks.vector_source_f(src_data) op = analog.phase_modulator_fc(sensitivity) - dst = gr.vector_sink_c() + dst = blocks.vector_sink_c() self.tb.connect(src, op) self.tb.connect(op, dst) diff --git a/gr-analog/python/qa_pll_carriertracking.py b/gr-analog/python/qa_pll_carriertracking.py index a292059d1b..2a6bb9f0b3 100755 --- a/gr-analog/python/qa_pll_carriertracking.py +++ b/gr-analog/python/qa_pll_carriertracking.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2007,2010-2012 Free Software Foundation, Inc. +# Copyright 2004,2007,2010-2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math class test_pll_carriertracking(gr_unittest.TestCase): @@ -141,10 +142,10 @@ class test_pll_carriertracking(gr_unittest.TestCase): maxf = 1 minf = -1 - src = gr.sig_source_c(sampling_freq, gr.GR_COS_WAVE, freq, 1.0) + src = analog.sig_source_c(sampling_freq, analog.GR_COS_WAVE, freq, 1.0) pll = analog.pll_carriertracking_cc(loop_bw, maxf, minf) - head = gr.head(gr.sizeof_gr_complex, int (freq)) - dst = gr.vector_sink_c() + head = blocks.head(gr.sizeof_gr_complex, int (freq)) + dst = blocks.vector_sink_c() self.tb.connect(src, pll, head) self.tb.connect(head, dst) diff --git a/gr-analog/python/qa_pll_freqdet.py b/gr-analog/python/qa_pll_freqdet.py index 1f808afa61..11f2a9b959 100755 --- a/gr-analog/python/qa_pll_freqdet.py +++ b/gr-analog/python/qa_pll_freqdet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2007,2010-2012 Free Software Foundation, Inc. +# Copyright 2004,2007,2010-2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math class test_pll_freqdet(gr_unittest.TestCase): @@ -141,10 +142,10 @@ class test_pll_freqdet(gr_unittest.TestCase): maxf = 1 minf = -1 - src = gr.sig_source_c(sampling_freq, gr.GR_COS_WAVE, freq, 1.0) + src = analog.sig_source_c(sampling_freq, analog.GR_COS_WAVE, freq, 1.0) pll = analog.pll_freqdet_cf(loop_bw, maxf, minf) - head = gr.head(gr.sizeof_float, int (freq)) - dst = gr.vector_sink_f() + head = blocks.head(gr.sizeof_float, int (freq)) + dst = blocks.vector_sink_f() self.tb.connect(src, pll, head) self.tb.connect(head, dst) diff --git a/gr-analog/python/qa_pll_refout.py b/gr-analog/python/qa_pll_refout.py index 2831b2909d..f90e7c3ada 100755 --- a/gr-analog/python/qa_pll_refout.py +++ b/gr-analog/python/qa_pll_refout.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2010,2012 Free Software Foundation, Inc. +# Copyright 2004,2010,2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math class test_pll_refout(gr_unittest.TestCase): @@ -141,10 +142,10 @@ class test_pll_refout(gr_unittest.TestCase): maxf = 1 minf = -1 - src = gr.sig_source_c(sampling_freq, gr.GR_COS_WAVE, freq, 1.0) + src = analog.sig_source_c(sampling_freq, analog.GR_COS_WAVE, freq, 1.0) pll = analog.pll_refout_cc(loop_bw, maxf, minf) - head = gr.head(gr.sizeof_gr_complex, int (freq)) - dst = gr.vector_sink_c() + head = blocks.head(gr.sizeof_gr_complex, int (freq)) + dst = blocks.vector_sink_c() self.tb.connect(src, pll, head) self.tb.connect(head, dst) diff --git a/gr-analog/python/qa_probe_avg_mag_sqrd.py b/gr-analog/python/qa_probe_avg_mag_sqrd.py index 5c6c97e450..930077c9c0 100755 --- a/gr-analog/python/qa_probe_avg_mag_sqrd.py +++ b/gr-analog/python/qa_probe_avg_mag_sqrd.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math def avg_mag_sqrd_c(x, alpha): @@ -52,7 +53,7 @@ class test_probe_avg_mag_sqrd(gr_unittest.TestCase): 6.0+6.0j, 7.0+7.0j, 8.0+8.0j, 9.0+9.0j, 10.0+10.0j] expected_result = avg_mag_sqrd_c(src_data, alpha)[-1] - src = gr.vector_source_c(src_data) + src = blocks.vector_source_c(src_data) op = analog.probe_avg_mag_sqrd_c(0, alpha) self.tb.connect(src, op) @@ -67,9 +68,9 @@ class test_probe_avg_mag_sqrd(gr_unittest.TestCase): 6.0+6.0j, 7.0+7.0j, 8.0+8.0j, 9.0+9.0j, 10.0+10.0j] expected_result = avg_mag_sqrd_c(src_data, alpha)[0:-1] - src = gr.vector_source_c(src_data) + src = blocks.vector_source_c(src_data) op = analog.probe_avg_mag_sqrd_cf(0, alpha) - dst = gr.vector_sink_f() + dst = blocks.vector_sink_f() self.tb.connect(src, op) self.tb.connect(op, dst) @@ -84,7 +85,7 @@ class test_probe_avg_mag_sqrd(gr_unittest.TestCase): 6.0, 7.0, 8.0, 9.0, 10.0] expected_result = avg_mag_sqrd_f(src_data, alpha)[-1] - src = gr.vector_source_f(src_data) + src = blocks.vector_source_f(src_data) op = analog.probe_avg_mag_sqrd_f(0, alpha) self.tb.connect(src, op) diff --git a/gr-analog/python/qa_pwr_squelch.py b/gr-analog/python/qa_pwr_squelch.py index dd42c7fb90..238723ba3c 100755 --- a/gr-analog/python/qa_pwr_squelch.py +++ b/gr-analog/python/qa_pwr_squelch.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks class test_pwr_squelch(gr_unittest.TestCase): @@ -63,9 +64,9 @@ class test_pwr_squelch(gr_unittest.TestCase): thr = -25 src_data = map(lambda x: float(x)/10.0, range(1, 40)) - src = gr.vector_source_c(src_data) + src = blocks.vector_source_c(src_data) op = analog.pwr_squelch_cc(thr, alpha) - dst = gr.vector_sink_c() + dst = blocks.vector_sink_c() self.tb.connect(src, op) self.tb.connect(op, dst) @@ -109,9 +110,9 @@ class test_pwr_squelch(gr_unittest.TestCase): thr = -25 src_data = map(lambda x: float(x)/10.0, range(1, 40)) - src = gr.vector_source_f(src_data) + src = blocks.vector_source_f(src_data) op = analog.pwr_squelch_ff(thr, alpha) - dst = gr.vector_sink_f() + dst = blocks.vector_sink_f() self.tb.connect(src, op) self.tb.connect(op, dst) diff --git a/gr-analog/python/qa_quadrature_demod.py b/gr-analog/python/qa_quadrature_demod.py index e38ea72a7d..0a92bb12a5 100755 --- a/gr-analog/python/qa_quadrature_demod.py +++ b/gr-analog/python/qa_quadrature_demod.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import cmath class test_quadrature_demod(gr_unittest.TestCase): @@ -47,9 +48,9 @@ class test_quadrature_demod(gr_unittest.TestCase): expected_result = [0,] + 199*[1.0] - src = gr.vector_source_c(src_data) + src = blocks.vector_source_c(src_data) op = analog.quadrature_demod_cf(gain) - dst = gr.vector_sink_f() + dst = blocks.vector_sink_f() self.tb.connect(src, op) self.tb.connect(op, dst) diff --git a/gr-analog/python/qa_rail_ff.py b/gr-analog/python/qa_rail_ff.py index 5bcf01c6b7..58ac01d7a6 100755 --- a/gr-analog/python/qa_rail_ff.py +++ b/gr-analog/python/qa_rail_ff.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks def clip(x, lo, hi): if(x < lo): @@ -63,9 +64,9 @@ class test_rail(gr_unittest.TestCase): src_data = [-2, -1, -0.5, -0.25, 0, 0.25, 0.5, 1, 2] expected_result = map(lambda x: clip(x, lo, hi), src_data) - src = gr.vector_source_f(src_data) + src = blocks.vector_source_f(src_data) op = analog.rail_ff(lo, hi) - dst = gr.vector_sink_f() + dst = blocks.vector_sink_f() self.tb.connect(src, op) self.tb.connect(op, dst) diff --git a/gr-analog/python/qa_sig_source.py b/gr-analog/python/qa_sig_source.py index bc48333ed1..0aa03c7402 100755 --- a/gr-analog/python/qa_sig_source.py +++ b/gr-analog/python/qa_sig_source.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2007,2010,2012 Free Software Foundation, Inc. +# Copyright 2004,2007,2010,2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks import math class test_sig_source(gr_unittest.TestCase): @@ -36,8 +37,8 @@ class test_sig_source(gr_unittest.TestCase): tb = self.tb expected_result = (1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5) src1 = analog.sig_source_f(1e6, analog.GR_CONST_WAVE, 0, 1.5) - op = gr.head(gr.sizeof_float, 10) - dst1 = gr.vector_sink_f() + op = blocks.head(gr.sizeof_float, 10) + dst1 = blocks.vector_sink_f() tb.connect(src1, op) tb.connect(op, dst1) tb.run() @@ -48,8 +49,8 @@ class test_sig_source(gr_unittest.TestCase): tb = self.tb expected_result = (1, 1, 1, 1) src1 = analog.sig_source_i(1e6, analog.GR_CONST_WAVE, 0, 1) - op = gr.head(gr.sizeof_int, 4) - dst1 = gr.vector_sink_i() + op = blocks.head(gr.sizeof_int, 4) + dst1 = blocks.vector_sink_i() tb.connect(src1, op) tb.connect(op, dst1) tb.run() @@ -61,8 +62,8 @@ class test_sig_source(gr_unittest.TestCase): sqrt2 = math.sqrt(2) / 2 expected_result = (0, sqrt2, 1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0) src1 = analog.sig_source_f(8, analog.GR_SIN_WAVE, 1.0, 1.0) - op = gr.head(gr.sizeof_float, 9) - dst1 = gr.vector_sink_f() + op = blocks.head(gr.sizeof_float, 9) + dst1 = blocks.vector_sink_f() tb.connect(src1, op) tb.connect(op, dst1) tb.run() @@ -74,8 +75,8 @@ class test_sig_source(gr_unittest.TestCase): sqrt2 = math.sqrt(2) / 2 expected_result = (1, sqrt2, 0, -sqrt2, -1, -sqrt2, 0, sqrt2, 1) src1 = analog.sig_source_f(8, analog.GR_COS_WAVE, 1.0, 1.0) - op = gr.head(gr.sizeof_float, 9) - dst1 = gr.vector_sink_f() + op = blocks.head(gr.sizeof_float, 9) + dst1 = blocks.vector_sink_f() tb.connect(src1, op) tb.connect(op, dst1) tb.run() @@ -86,8 +87,8 @@ class test_sig_source(gr_unittest.TestCase): tb = self.tb #arg6 is a bit before -PI/2 expected_result = (1j, 1j, 0, 0, 1, 1, 1+0j, 1+1j, 1j) src1 = analog.sig_source_c(8, analog.GR_SQR_WAVE, 1.0, 1.0) - op = gr.head(gr.sizeof_gr_complex, 9) - dst1 = gr.vector_sink_c() + op = blocks.head(gr.sizeof_gr_complex, 9) + dst1 = blocks.vector_sink_c() tb.connect(src1, op) tb.connect(op, dst1) tb.run() @@ -99,8 +100,8 @@ class test_sig_source(gr_unittest.TestCase): expected_result = (1+.5j, .75+.75j, .5+1j, .25+.75j, 0+.5j, .25+.25j, .5+0j, .75+.25j, 1+.5j) src1 = analog.sig_source_c(8, analog.GR_TRI_WAVE, 1.0, 1.0) - op = gr.head(gr.sizeof_gr_complex, 9) - dst1 = gr.vector_sink_c() + op = blocks.head(gr.sizeof_gr_complex, 9) + dst1 = blocks.vector_sink_c() tb.connect(src1, op) tb.connect(op, dst1) tb.run() @@ -112,8 +113,8 @@ class test_sig_source(gr_unittest.TestCase): expected_result = (.5+.25j, .625+.375j, .75+.5j, .875+.625j, 0+.75j, .125+.875j, .25+1j, .375+.125j, .5+.25j) src1 = analog.sig_source_c(8, analog.GR_SAW_WAVE, 1.0, 1.0) - op = gr.head(gr.sizeof_gr_complex, 9) - dst1 = gr.vector_sink_c() + op = blocks.head(gr.sizeof_gr_complex, 9) + dst1 = blocks.vector_sink_c() tb.connect(src1, op) tb.connect(op, dst1) tb.run() @@ -124,8 +125,8 @@ class test_sig_source(gr_unittest.TestCase): tb = self.tb expected_result = (0, 0, 0, 0, 1, 1, 1, 1, 0) src1 = analog.sig_source_f(8, analog.GR_SQR_WAVE, 1.0, 1.0) - op = gr.head(gr.sizeof_float, 9) - dst1 = gr.vector_sink_f() + op = blocks.head(gr.sizeof_float, 9) + dst1 = blocks.vector_sink_f() tb.connect(src1, op) tb.connect(op, dst1) tb.run() @@ -136,8 +137,8 @@ class test_sig_source(gr_unittest.TestCase): tb = self.tb expected_result = (1, .75, .5, .25, 0, .25, .5, .75, 1) src1 = analog.sig_source_f(8, analog.GR_TRI_WAVE, 1.0, 1.0) - op = gr.head(gr.sizeof_float, 9) - dst1 = gr.vector_sink_f() + op = blocks.head(gr.sizeof_float, 9) + dst1 = blocks.vector_sink_f() tb.connect(src1, op) tb.connect(op, dst1) tb.run() @@ -148,8 +149,8 @@ class test_sig_source(gr_unittest.TestCase): tb = self.tb expected_result = (.5, .625, .75, .875, 0, .125, .25, .375, .5) src1 = analog.sig_source_f(8, analog.GR_SAW_WAVE, 1.0, 1.0) - op = gr.head(gr.sizeof_float, 9) - dst1 = gr.vector_sink_f() + op = blocks.head(gr.sizeof_float, 9) + dst1 = blocks.vector_sink_f() tb.connect(src1, op) tb.connect(op, dst1) tb.run() diff --git a/gr-analog/python/qa_simple_squelch.py b/gr-analog/python/qa_simple_squelch.py index 9fa112864f..2bd88e1489 100755 --- a/gr-analog/python/qa_simple_squelch.py +++ b/gr-analog/python/qa_simple_squelch.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2012 Free Software Foundation, Inc. +# Copyright 2012,2013 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,6 +22,7 @@ from gnuradio import gr, gr_unittest import analog_swig as analog +import blocks_swig as blocks class test_simple_squelch(gr_unittest.TestCase): @@ -50,9 +51,9 @@ class test_simple_squelch(gr_unittest.TestCase): thr = -25 src_data = map(lambda x: float(x)/10.0, range(1, 40)) - src = gr.vector_source_c(src_data) + src = blocks.vector_source_c(src_data) op = analog.simple_squelch_cc(thr, alpha) - dst = gr.vector_sink_c() + dst = blocks.vector_sink_c() self.tb.connect(src, op) self.tb.connect(op, dst) diff --git a/gr-analog/python/standard_squelch.py b/gr-analog/python/standard_squelch.py new file mode 100644 index 0000000000..3ed9ebceaa --- /dev/null +++ b/gr-analog/python/standard_squelch.py @@ -0,0 +1,78 @@ +# +# Copyright 2005,2007,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import math +from gnuradio import gr +from gnuradio import blocks +from gnuradio import filter + +class standard_squelch(gr.hier_block2): + def __init__(self, audio_rate): + gr.hier_block2.__init__(self, "standard_squelch", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + self.input_node = blocks.add_const_ff(0) # FIXME kludge + + self.low_iir = filter.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615)) + self.low_square = blocks.multiply_ff() + self.low_smooth = filter.single_pole_iir_filter_ff(1/(0.01*audio_rate)) # 100ms time constant + + self.hi_iir = filter.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615)) + self.hi_square = blocks.multiply_ff() + self.hi_smooth = filter.single_pole_iir_filter_ff(1/(0.01*audio_rate)) + + self.sub = blocks.sub_ff(); + self.add = blocks.add_ff(); + self.gate = blocks.threshold_ff(0.3,0.43,0) + self.squelch_lpf = filter.single_pole_iir_filter_ff(1/(0.01*audio_rate)) + + self.div = blocks.divide_ff() + self.squelch_mult = blocks.multiply_ff() + + self.connect(self, self.input_node) + self.connect(self.input_node, (self.squelch_mult, 0)) + + self.connect(self.input_node,self.low_iir) + self.connect(self.low_iir,(self.low_square,0)) + self.connect(self.low_iir,(self.low_square,1)) + self.connect(self.low_square,self.low_smooth,(self.sub,0)) + self.connect(self.low_smooth, (self.add,0)) + + self.connect(self.input_node,self.hi_iir) + self.connect(self.hi_iir,(self.hi_square,0)) + self.connect(self.hi_iir,(self.hi_square,1)) + self.connect(self.hi_square,self.hi_smooth,(self.sub,1)) + self.connect(self.hi_smooth, (self.add,1)) + + self.connect(self.sub, (self.div, 0)) + self.connect(self.add, (self.div, 1)) + self.connect(self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1)) + self.connect(self.squelch_mult, self) + + def set_threshold(self, threshold): + self.gate.set_hi(threshold) + + def threshold(self): + return self.gate.hi() + + def squelch_range(self): + return (0.0, 1.0, 1.0/100) diff --git a/gr-analog/python/wfm_rcv.py b/gr-analog/python/wfm_rcv.py new file mode 100644 index 0000000000..d35d219275 --- /dev/null +++ b/gr-analog/python/wfm_rcv.py @@ -0,0 +1,73 @@ +# +# Copyright 2005,2007,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr, filter +from fm_emph import fm_deemph +import math + +try: + from gnuradio import analog +except ImportError: + import analog_swig as analog + +class wfm_rcv(gr.hier_block2): + def __init__ (self, quad_rate, audio_decimation): + """ + Hierarchical block for demodulating a broadcast FM signal. + + The input is the downconverted complex baseband signal (gr_complex). + The output is the demodulated audio (float). + + Args: + quad_rate: input sample rate of complex baseband input. (float) + audio_decimation: how much to decimate quad_rate to get to audio. (integer) + """ + gr.hier_block2.__init__(self, "wfm_rcv", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_float)) # Output signature + + volume = 20. + + max_dev = 75e3 + fm_demod_gain = quad_rate/(2*math.pi*max_dev) + audio_rate = quad_rate / audio_decimation + + + # We assign to self so that outsiders can grab the demodulator + # if they need to. E.g., to plot its output. + # + # input: complex; output: float + self.fm_demod = analog.quadrature_demod_cf(fm_demod_gain) + + # input: float; output: float + self.deemph = fm_deemph(audio_rate) + + # compute FIR filter taps for audio filter + width_of_transition_band = audio_rate / 32 + audio_coeffs = filter.firdes.low_pass(1.0, # gain + quad_rate, # sampling rate + audio_rate/2 - width_of_transition_band, + width_of_transition_band, + filter.firdes.WIN_HAMMING) + # input: float; output: float + self.audio_filter = filter.fir_filter_fff(audio_decimation, audio_coeffs) + + self.connect (self, self.fm_demod, self.audio_filter, self.deemph, self) diff --git a/gr-analog/python/wfm_rcv_fmdet.py b/gr-analog/python/wfm_rcv_fmdet.py new file mode 100644 index 0000000000..b7cd1458fb --- /dev/null +++ b/gr-analog/python/wfm_rcv_fmdet.py @@ -0,0 +1,228 @@ +# +# Copyright 2005,2006,2012-2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr +from gnuradio import blocks +from gnuradio import filter +from fm_emph import fm_deemph +import math + +try: + from gnuradio import analog +except ImportError: + import analog_swig as analog + +class wfm_rcv_fmdet(gr.hier_block2): + def __init__ (self, demod_rate, audio_decimation): + """ + Hierarchical block for demodulating a broadcast FM signal. + + The input is the downconverted complex baseband signal + (gr_complex). The output is two streams of the demodulated + audio (float) 0=Left, 1=Right. + + Args: + demod_rate: input sample rate of complex baseband input. (float) + audio_decimation: how much to decimate demod_rate to get to audio. (integer) + """ + gr.hier_block2.__init__(self, "wfm_rcv_fmdet", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(2, 2, gr.sizeof_float)) # Output signature + lowfreq = -125e3/demod_rate + highfreq = 125e3/demod_rate + audio_rate = demod_rate / audio_decimation + + # We assign to self so that outsiders can grab the demodulator + # if they need to. E.g., to plot its output. + # + # input: complex; output: float + + self.fm_demod = analog.fmdet_cf(demod_rate, lowfreq, highfreq, 0.05) + + # input: float; output: float + self.deemph_Left = fm_deemph(audio_rate) + self.deemph_Right = fm_deemph(audio_rate) + + # compute FIR filter taps for audio filter + width_of_transition_band = audio_rate / 32 + audio_coeffs = filter.firdes.low_pass(1.0 , # gain + demod_rate, # sampling rate + 15000 , + width_of_transition_band, + filter.firdes.WIN_HAMMING) + + # input: float; output: float + self.audio_filter = filter.fir_filter_fff(audio_decimation, audio_coeffs) + if 1: + # Pick off the stereo carrier/2 with this filter. It + # attenuated 10 dB so apply 10 dB gain We pick off the + # negative frequency half because we want to base band by + # it! + ## NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO + ## DEEMPHASIS + + stereo_carrier_filter_coeffs = \ + filter.firdes.complex_band_pass(10.0, + demod_rate, + -19020, + -18980, + width_of_transition_band, + filter.firdes.WIN_HAMMING) + + #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs) + #print "stereo carrier filter ", stereo_carrier_filter_coeffs + #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate + + # Pick off the double side band suppressed carrier + # Left-Right audio. It is attenuated 10 dB so apply 10 dB + # gain + + stereo_dsbsc_filter_coeffs = \ + filter.firdes.complex_band_pass(20.0, + demod_rate, + 38000-15000/2, + 38000+15000/2, + width_of_transition_band, + filter.firdes.WIN_HAMMING) + #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) + #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs + + # construct overlap add filter system from coefficients + # for stereo carrier + self.stereo_carrier_filter = \ + filter.fir_filter_fcc(audio_decimation, + stereo_carrier_filter_coeffs) + + # carrier is twice the picked off carrier so arrange to do + # a commplex multiply + self.stereo_carrier_generator = blocks.multiply_cc(); + + # Pick off the rds signal + stereo_rds_filter_coeffs = \ + filter.firdes.complex_band_pass(30.0, + demod_rate, + 57000 - 1500, + 57000 + 1500, + width_of_transition_band, + filter.firdes.WIN_HAMMING) + #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) + #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs + # construct overlap add filter system from coefficients for stereo carrier + + self.rds_signal_filter = \ + filter.fir_filter_fcc(audio_decimation, + stereo_rds_filter_coeffs) + self.rds_carrier_generator = blocks.multiply_cc(); + self.rds_signal_generator = blocks.multiply_cc(); + self_rds_signal_processor = blocks.null_sink(gr.sizeof_gr_complex); + + loop_bw = 2*math.pi/100.0 + max_freq = -2.0*math.pi*18990/audio_rate; + min_freq = -2.0*math.pi*19010/audio_rate; + self.stereo_carrier_pll_recovery = analog.pll_refout_cc(loop_bw, + max_freq, + min_freq); + + #self.stereo_carrier_pll_recovery.squelch_enable(False) + ##pll_refout does not have squelch yet, so disabled for + #now + + # set up mixer (multiplier) to get the L-R signal at + # baseband + + self.stereo_basebander = blocks.multiply_cc(); + + # pick off the real component of the basebanded L-R + # signal. The imaginary SHOULD be zero + + self.LmR_real = blocks.complex_to_real(); + self.Make_Left = blocks.add_ff(); + self.Make_Right = blocks.sub_ff(); + + self.stereo_dsbsc_filter = \ + filter.fir_filter_fcc(audio_decimation, + stereo_dsbsc_filter_coeffs) + + + if 1: + + # send the real signal to complex filter to pick off the + # carrier and then to one side of a multiplier + self.connect(self, self.fm_demod, self.stereo_carrier_filter, + self.stereo_carrier_pll_recovery, + (self.stereo_carrier_generator,0)) + + # send the already filtered carrier to the otherside of the carrier + # the resulting signal from this multiplier is the carrier + # with correct phase but at -38000 Hz. + self.connect(self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1)) + + # send the new carrier to one side of the mixer (multiplier) + self.connect(self.stereo_carrier_generator, (self.stereo_basebander,0)) + + # send the demphasized audio to the DSBSC pick off filter, the complex + # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier + # the result is BASEBANDED DSBSC with phase zero! + self.connect(self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1)) + + # Pick off the real part since the imaginary is + # theoretically zero and then to one side of a summer + self.connect(self.stereo_basebander, self.LmR_real, (self.Make_Left,0)) + + #take the same real part of the DSBSC baseband signal and + #send it to negative side of a subtracter + self.connect(self.LmR_real,(self.Make_Right,1)) + + # Make rds carrier by taking the squared pilot tone and + # multiplying by pilot tone + self.connect(self.stereo_basebander,(self.rds_carrier_generator,0)) + self.connect(self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1)) + + # take signal, filter off rds, send into mixer 0 channel + self.connect(self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0)) + + # take rds_carrier_generator output and send into mixer 1 + # channel + self.connect(self.rds_carrier_generator,(self.rds_signal_generator,1)) + + # send basebanded rds signal and send into "processor" + # which for now is a null sink + self.connect(self.rds_signal_generator,self_rds_signal_processor) + + + if 1: + # pick off the audio, L+R that is what we used to have and + # send it to the summer + self.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1)) + + # take the picked off L+R audio and send it to the PLUS + # side of the subtractor + self.connect(self.audio_filter,(self.Make_Right, 0)) + + # The result of Make_Left gets (L+R) + (L-R) and results in 2*L + # The result of Make_Right gets (L+R) - (L-R) and results in 2*R + self.connect(self.Make_Left , self.deemph_Left, (self, 0)) + self.connect(self.Make_Right, self.deemph_Right, (self, 1)) + + # NOTE: mono support will require variable number of outputs in hier_block2s + # See ticket:174 in Trac database + #else: + # self.connect (self.fm_demod, self.audio_filter, self) diff --git a/gr-analog/python/wfm_rcv_pll.py b/gr-analog/python/wfm_rcv_pll.py new file mode 100644 index 0000000000..282e2b14be --- /dev/null +++ b/gr-analog/python/wfm_rcv_pll.py @@ -0,0 +1,195 @@ +# +# Copyright 2005,2006,2012-2013 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +from gnuradio import gr +from gnuradio import blocks +from gnuradio import filter +from fm_emph import fm_deemph +import math + +try: + from gnuradio import analog +except ImportError: + import analog_swig as analog + +class wfm_rcv_pll(gr.hier_block2): + def __init__(self, demod_rate, audio_decimation): + """ + Hierarchical block for demodulating a broadcast FM signal. + + The input is the downconverted complex baseband signal (gr_complex). + The output is two streams of the demodulated audio (float) 0=Left, 1=Right. + + Args: + demod_rate: input sample rate of complex baseband input. (float) + audio_decimation: how much to decimate demod_rate to get to audio. (integer) + """ + gr.hier_block2.__init__(self, "wfm_rcv_pll", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(2, 2, gr.sizeof_float)) # Output signature + bandwidth = 250e3 + audio_rate = demod_rate / audio_decimation + + + # We assign to self so that outsiders can grab the demodulator + # if they need to. E.g., to plot its output. + # + # input: complex; output: float + loop_bw = 2*math.pi/100.0 + max_freq = 2.0*math.pi*90e3/demod_rate + self.fm_demod = analog.pll_freqdet_cf(loop_bw, max_freq,-max_freq) + + # input: float; output: float + self.deemph_Left = fm_deemph(audio_rate) + self.deemph_Right = fm_deemph(audio_rate) + + # compute FIR filter taps for audio filter + width_of_transition_band = audio_rate / 32 + audio_coeffs = filter.firdes.low_pass(1.0 , # gain + demod_rate, # sampling rate + 15000 , + width_of_transition_band, + filter.firdes.WIN_HAMMING) + # input: float; output: float + self.audio_filter = filter.fir_filter_fff(audio_decimation, audio_coeffs) + if 1: + # Pick off the stereo carrier/2 with this filter. It attenuated 10 dB so apply 10 dB gain + # We pick off the negative frequency half because we want to base band by it! + ## NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO DEEMPHASIS + + stereo_carrier_filter_coeffs = \ + filter.firdes.complex_band_pass(10.0, + demod_rate, + -19020, + -18980, + width_of_transition_band, + filter.firdes.WIN_HAMMING) + + #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs) + #print "stereo carrier filter ", stereo_carrier_filter_coeffs + #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate + + # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain + + stereo_dsbsc_filter_coeffs = \ + filter.firdes.complex_band_pass(20.0, + demod_rate, + 38000-15000/2, + 38000+15000/2, + width_of_transition_band, + filter.firdes.WIN_HAMMING) + #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) + #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs + # construct overlap add filter system from coefficients for stereo carrier + + self.stereo_carrier_filter = \ + filter.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs) + + # carrier is twice the picked off carrier so arrange to do a commplex multiply + + self.stereo_carrier_generator = blocks.multiply_cc(); + + # Pick off the rds signal + + stereo_rds_filter_coeffs = \ + filter.firdes.complex_band_pass(30.0, + demod_rate, + 57000 - 1500, + 57000 + 1500, + width_of_transition_band, + filter.firdes.WIN_HAMMING) + #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) + #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs + # construct overlap add filter system from coefficients for stereo carrier + + self.rds_signal_filter = \ + filter.fir_filter_fcc(audio_decimation, stereo_rds_filter_coeffs) + + self.rds_carrier_generator = blocks.multiply_cc(); + self.rds_signal_generator = blocks.multiply_cc(); + self_rds_signal_processor = blocks.null_sink(gr.sizeof_gr_complex); + + loop_bw = 2*math.pi/100.0 + max_freq = -2.0*math.pi*18990/audio_rate; + min_freq = -2.0*math.pi*19010/audio_rate; + + self.stereo_carrier_pll_recovery = \ + analog.pll_refout_cc(loop_bw, max_freq, min_freq); + #self.stereo_carrier_pll_recovery.squelch_enable(False) #pll_refout does not have squelch yet, so disabled for now + + # set up mixer (multiplier) to get the L-R signal at baseband + + self.stereo_basebander = blocks.multiply_cc(); + + # pick off the real component of the basebanded L-R signal. The imaginary SHOULD be zero + + self.LmR_real = blocks.complex_to_real(); + self.Make_Left = blocks.add_ff(); + self.Make_Right = blocks.sub_ff(); + + self.stereo_dsbsc_filter = \ + filter.fir_filter_fcc(audio_decimation, stereo_dsbsc_filter_coeffs) + + if 1: + + # send the real signal to complex filter to pick off the carrier and then to one side of a multiplier + self.connect(self, self.fm_demod, self.stereo_carrier_filter, + self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,0)) + # send the already filtered carrier to the otherside of the carrier + self.connect(self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1)) + # the resulting signal from this multiplier is the carrier with correct phase but at -38000 Hz. + + # send the new carrier to one side of the mixer (multiplier) + self.connect(self.stereo_carrier_generator, (self.stereo_basebander,0)) + # send the demphasized audio to the DSBSC pick off filter, the complex + # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier + self.connect(self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1)) + # the result is BASEBANDED DSBSC with phase zero! + + # Pick off the real part since the imaginary is theoretically zero and then to one side of a summer + self.connect(self.stereo_basebander, self.LmR_real, (self.Make_Left,0)) + #take the same real part of the DSBSC baseband signal and send it to negative side of a subtracter + self.connect(self.LmR_real,(self.Make_Right,1)) + + # Make rds carrier by taking the squared pilot tone and multiplying by pilot tone + self.connect(self.stereo_basebander,(self.rds_carrier_generator,0)) + self.connect(self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1)) + # take signal, filter off rds, send into mixer 0 channel + self.connect(self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0)) + # take rds_carrier_generator output and send into mixer 1 channel + self.connect(self.rds_carrier_generator,(self.rds_signal_generator,1)) + # send basebanded rds signal and send into "processor" which for now is a null sink + self.connect(self.rds_signal_generator,self_rds_signal_processor) + + + if 1: + # pick off the audio, L+R that is what we used to have and send it to the summer + self.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1)) + # take the picked off L+R audio and send it to the PLUS side of the subtractor + self.connect(self.audio_filter,(self.Make_Right, 0)) + # The result of Make_Left gets (L+R) + (L-R) and results in 2*L + # The result of Make_Right gets (L+R) - (L-R) and results in 2*R + self.connect(self.Make_Left , self.deemph_Left, (self, 0)) + self.connect(self.Make_Right, self.deemph_Right, (self, 1)) + # NOTE: mono support will require variable number of outputs in hier_block2s + # See ticket:174 in Trac database + #else: + # self.connect (self.fm_demod, self.audio_filter, self) diff --git a/gr-analog/python/wfm_tx.py b/gr-analog/python/wfm_tx.py new file mode 100644 index 0000000000..be662310db --- /dev/null +++ b/gr-analog/python/wfm_tx.py @@ -0,0 +1,82 @@ +# +# Copyright 2005,2007,2012 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio 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, or (at your option) +# any later version. +# +# GNU Radio 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 GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import math +from gnuradio import gr +from gnuradio import filter +from fm_emph import fm_preemph + +try: + from gnuradio import analog +except ImportError: + import analog_swig as analog + +class wfm_tx(gr.hier_block2): + def __init__(self, audio_rate, quad_rate, tau=75e-6, max_dev=75e3): + """ + Wide Band FM Transmitter. + + Takes a single float input stream of audio samples in the range [-1,+1] + and produces a single FM modulated complex baseband output. + + Args: + audio_rate: sample rate of audio stream, >= 16k (integer) + quad_rate: sample rate of output stream (integer) + tau: preemphasis time constant (default 75e-6) (float) + max_dev: maximum deviation in Hz (default 75e3) (float) + + quad_rate must be an integer multiple of audio_rate. + """ + gr.hier_block2.__init__(self, "wfm_tx", + gr.io_signature(1, 1, gr.sizeof_float), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + + # FIXME audio_rate and quad_rate ought to be exact rationals + audio_rate = int(audio_rate) + quad_rate = int(quad_rate) + + if quad_rate % audio_rate != 0: + raise ValueError, "quad_rate is not an integer multiple of audio_rate" + + + do_interp = audio_rate != quad_rate + + if do_interp: + interp_factor = quad_rate / audio_rate + interp_taps = filter.optfir.low_pass(interp_factor, # gain + quad_rate, # Fs + 16000, # passband cutoff + 18000, # stopband cutoff + 0.1, # passband ripple dB + 40) # stopband atten dB + + print "len(interp_taps) =", len(interp_taps) + self.interpolator = filter.interp_fir_filter_fff (interp_factor, interp_taps) + + self.preemph = fm_preemph(quad_rate, tau=tau) + + k = 2 * math.pi * max_dev / quad_rate + self.modulator = analog.frequency_modulator_fc (k) + + if do_interp: + self.connect(self, self.interpolator, self.preemph, self.modulator, self) + else: + self.connect(self, self.preemph, self.modulator, self) diff --git a/gr-analog/swig/CMakeLists.txt b/gr-analog/swig/CMakeLists.txt index 4391e5e09a..5c940e66af 100644 --- a/gr-analog/swig/CMakeLists.txt +++ b/gr-analog/swig/CMakeLists.txt @@ -24,15 +24,16 @@ include(GrPython) include(GrSwig) set(GR_SWIG_INCLUDE_DIRS + ${GR_BLOCKS_INCLUDE_DIRS} ${GR_ANALOG_INCLUDE_DIRS} ${GR_FILTER_INCLUDE_DIRS} - ${GNURADIO_CORE_SWIG_INCLUDE_DIRS} - ${GRUEL_INCLUDE_DIRS} + ${GNURADIO_RUNTIME_SWIG_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ) set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/analog_swig_doc.i) -set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../lib) +set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include/analog) +set(GR_SWIG_DOCS_TARGET_DEPS runtime_swig_swig_doc) set(GR_SWIG_TARGET_DEPS analog_generated_includes) set(GR_SWIG_LIBRARIES gnuradio-analog gnuradio-filter) diff --git a/gr-analog/swig/analog_swig.i b/gr-analog/swig/analog_swig.i index 96f4e23a8c..9ae019ad8e 100644 --- a/gr-analog/swig/analog_swig.i +++ b/gr-analog/swig/analog_swig.i @@ -20,14 +20,20 @@ */ #define ANALOG_API +#define BLOCKS_API -%include "gnuradio.i" +%include "runtime_swig.i" %include "stdint.i" //load generated python docstrings %include "analog_swig_doc.i" %{ +#include <blocks/control_loop.h> +%} +%include <blocks/control_loop.h> + +%{ #include "analog/cpm.h" #include "analog/noise_type.h" #include "analog/agc_cc.h" @@ -40,13 +46,15 @@ #include "analog/feedforward_agc_cc.h" #include "analog/fmdet_cf.h" #include "analog/frequency_modulator_fc.h" -#include "analog/lfsr.h" +#include "analog/fastnoise_source_s.h" +#include "analog/fastnoise_source_i.h" +#include "analog/fastnoise_source_f.h" +#include "analog/fastnoise_source_c.h" #include "analog/noise_source_s.h" #include "analog/noise_source_i.h" #include "analog/noise_source_f.h" #include "analog/noise_source_c.h" #include "analog/phase_modulator_fc.h" -#include "analog/plateau_detector_fb.h" #include "analog/pll_carriertracking_cc.h" #include "analog/pll_freqdet_cf.h" #include "analog/pll_refout_cc.h" @@ -57,7 +65,6 @@ #include "analog/pwr_squelch_ff.h" #include "analog/quadrature_demod_cf.h" #include "analog/rail_ff.h" -#include "analog/sincos.h" #include "analog/sig_source_s.h" #include "analog/sig_source_i.h" #include "analog/sig_source_f.h" @@ -80,13 +87,15 @@ %include "analog/feedforward_agc_cc.h" %include "analog/fmdet_cf.h" %include "analog/frequency_modulator_fc.h" -%include "analog/lfsr.h" +%include "analog/fastnoise_source_s.h" +%include "analog/fastnoise_source_i.h" +%include "analog/fastnoise_source_f.h" +%include "analog/fastnoise_source_c.h" %include "analog/noise_source_s.h" %include "analog/noise_source_i.h" %include "analog/noise_source_f.h" %include "analog/noise_source_c.h" %include "analog/phase_modulator_fc.h" -%include "analog/plateau_detector_fb.h" %include "analog/pll_carriertracking_cc.h" %include "analog/pll_freqdet_cf.h" %include "analog/pll_refout_cc.h" @@ -97,7 +106,6 @@ %include "analog/pwr_squelch_ff.h" %include "analog/quadrature_demod_cf.h" %include "analog/rail_ff.h" -%include "analog/sincos.h" %include "analog/sig_source_s.h" %include "analog/sig_source_i.h" %include "analog/sig_source_f.h" @@ -117,12 +125,15 @@ GR_SWIG_BLOCK_MAGIC2(analog, dpll_bb); GR_SWIG_BLOCK_MAGIC2(analog, feedforward_agc_cc); GR_SWIG_BLOCK_MAGIC2(analog, fmdet_cf); GR_SWIG_BLOCK_MAGIC2(analog, frequency_modulator_fc); +GR_SWIG_BLOCK_MAGIC2(analog, fastnoise_source_s); +GR_SWIG_BLOCK_MAGIC2(analog, fastnoise_source_i); +GR_SWIG_BLOCK_MAGIC2(analog, fastnoise_source_f); +GR_SWIG_BLOCK_MAGIC2(analog, fastnoise_source_c); GR_SWIG_BLOCK_MAGIC2(analog, noise_source_s); GR_SWIG_BLOCK_MAGIC2(analog, noise_source_i); GR_SWIG_BLOCK_MAGIC2(analog, noise_source_f); GR_SWIG_BLOCK_MAGIC2(analog, noise_source_c); GR_SWIG_BLOCK_MAGIC2(analog, phase_modulator_fc); -GR_SWIG_BLOCK_MAGIC2(analog, plateau_detector_fb); GR_SWIG_BLOCK_MAGIC2(analog, pll_carriertracking_cc); GR_SWIG_BLOCK_MAGIC2(analog, pll_freqdet_cf); GR_SWIG_BLOCK_MAGIC2(analog, pll_refout_cc); |