diff options
Diffstat (limited to 'gnuradio-core')
295 files changed, 10339 insertions, 10303 deletions
diff --git a/gnuradio-core/Makefile.am b/gnuradio-core/Makefile.am index 107ff785b..0a4e7e151 100644 --- a/gnuradio-core/Makefile.am +++ b/gnuradio-core/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST = \ +EXTRA_DIST += \ gnuradio-core.pc.in SUBDIRS = src diff --git a/gnuradio-core/gnuradio-core.conf b/gnuradio-core/gnuradio-core.conf index d64f58401..178b288e8 100644 --- a/gnuradio-core/gnuradio-core.conf +++ b/gnuradio-core/gnuradio-core.conf @@ -5,15 +5,3 @@ [DEFAULT] verbose = False - - -[audio] - -# specify which audio module to load, or use "auto" to have the system -# select one. Valid choices depend on your OS and which modules -# you've installed, but typically include: auto, audio_alsa, -# audio_oss, audio_portaudio, audio_jack, audio_osx, audio_windows - -audio_module = auto - - diff --git a/gnuradio-core/gnuradio-core.pc.in b/gnuradio-core/gnuradio-core.pc.in index 5d743a4e9..40c26a129 100644 --- a/gnuradio-core/gnuradio-core.pc.in +++ b/gnuradio-core/gnuradio-core.pc.in @@ -2,6 +2,7 @@ prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@/gnuradio +guile_load_path=@prefix@/share/guile/site Name: gnuradio-core Description: GNU Software Radio toolkit diff --git a/gnuradio-core/src/Makefile.am b/gnuradio-core/src/Makefile.am index eb979fe58..1717d373a 100644 --- a/gnuradio-core/src/Makefile.am +++ b/gnuradio-core/src/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2001,2004,2009 Free Software Foundation, Inc. +# Copyright 2001,2004,2009,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,9 +21,6 @@ include $(top_srcdir)/Makefile.common -SUBDIRS = gen_interpolator_taps lib tests -if PYTHON -SUBDIRS += python -endif +SUBDIRS = gen_interpolator_taps lib tests python guile -DIST_SUBDIRS = gen_interpolator_taps lib tests python utils +DIST_SUBDIRS = gen_interpolator_taps lib tests python guile utils diff --git a/gnuradio-core/src/gen_interpolator_taps/Makefile.am b/gnuradio-core/src/gen_interpolator_taps/Makefile.am index d244e7f54..1b54af5e7 100644 --- a/gnuradio-core/src/gen_interpolator_taps/Makefile.am +++ b/gnuradio-core/src/gen_interpolator_taps/Makefile.am @@ -21,7 +21,13 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST = praxis.txt simpson.h objective_fct.c gen_interpolator_taps.c simpson.c praxis.f +EXTRA_DIST += \ + praxis.txt \ + simpson.h \ + objective_fct.c \ + gen_interpolator_taps.c \ + simpson.c \ + praxis.f # if ENABLE_FORTRAN # noinst_PROGRAMS = gen_interpolator_taps diff --git a/gnuradio-core/src/guile/.gitignore b/gnuradio-core/src/guile/.gitignore new file mode 100644 index 000000000..ea2593923 --- /dev/null +++ b/gnuradio-core/src/guile/.gitignore @@ -0,0 +1,5 @@ +/Makefile +/Makefile.in +/run_guile_tests +/guile.log +/gr-run-waveform-script diff --git a/gnuradio-core/src/guile/Makefile.am b/gnuradio-core/src/guile/Makefile.am new file mode 100644 index 000000000..122f05d97 --- /dev/null +++ b/gnuradio-core/src/guile/Makefile.am @@ -0,0 +1,80 @@ +# +# Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +# + +include $(top_srcdir)/Makefile.common + +if GUILE + +TESTS = run_guile_tests + +EXTRA_DIST += \ + run_guile_tests.in \ + $(nobase_guile_DATA) \ + $(GUILE_TESTS) + +bin_SCRIPTS = \ + gr-run-waveform-script + +# These are the hand-coded guile files for gnuradio-core. +# +# Swig/common.scm is glue that's required for the goops wrappers. +# gnuradio/export-safely.scm works around some problems in the goops generated wrappers. +# gnuradio/core.scm glues the 5 pieces of gnuradio_core_* into a single module. +# gnuradio/runtime-shim implements "guile friendly" versions of connect & disconnect. + +nobase_guile_DATA = \ + Swig/common.scm \ + gnuradio/core.scm \ + gnuradio/export-safely.scm \ + gnuradio/run-waveform.scm \ + gnuradio/runtime-shim.scm \ + gnuradio/waveform.scm \ + gnuradio/test-suite/guile-test \ + gnuradio/test-suite/lib.scm + +GUILE_TESTS = \ + tests/00_runtime_basics.test \ + tests/00_runtime_ctors.test \ + tests/filter_ctors.test \ + tests/general_ctors.test \ + tests/gengen_ctors.test \ + tests/hier_ctors.test \ + tests/io_ctors.test + +CLEANFILES = guile.log + + +scmlibdir = $(libdir) +scmdir = $(guiledir) + +scmlib_LTLIBRARIES = libguile-gnuradio-dynl-global.la + +libguile_gnuradio_dynl_global_la_SOURCES = dynl-global.c +libguile_gnuradio_dynl_global_la_CPPFLAGS = $(GUILE_CFLAGS) +libguile_gnuradio_dynl_global_la_LIBADD = $(GUILE_LIBS) + +# Create a symlink from gr-run-waveform-script to gr-run-waveform +install-exec-local: + -$(RM) $(DESTDIR)$(bindir)/gr-run-waveform + (cd $(DESTDIR)$(bindir) && $(LN_S) gr-run-waveform-script gr-run-waveform) + +uninstall-local: + -$(RM) $(DESTDIR)$(bindir)/gr-run-waveform + +endif diff --git a/gnuradio-core/src/guile/Swig/common.scm b/gnuradio-core/src/guile/Swig/common.scm new file mode 100644 index 000000000..a51d3a71d --- /dev/null +++ b/gnuradio-core/src/guile/Swig/common.scm @@ -0,0 +1,76 @@ +;;;************************************************************************ +;;;*common.scm +;;;* +;;;* This file contains generic SWIG GOOPS classes for generated +;;;* GOOPS file support +;;;* +;;;* Copyright (C) 2003 John Lenz (jelenz@wisc.edu) +;;;* Copyright (C) 2004 Matthias Koeppe (mkoeppe@mail.math.uni-magdeburg.de) +;;;* +;;;* This file may be freely redistributed without license or fee provided +;;;* this copyright message remains intact. +;;;************************************************************************ + +(define-module (Swig swigrun)) + +(define-module (Swig common) + #:use-module (oop goops) + #:use-module (Swig swigrun)) + +(define-class <swig-metaclass> (<class>) + (new-function #:init-value #f)) + +(define-method (initialize (class <swig-metaclass>) initargs) + (slot-set! class 'new-function (get-keyword #:new-function initargs #f)) + (next-method)) + +(define-class <swig> () + (swig-smob #:init-value #f) + #:metaclass <swig-metaclass> +) + +(define-method (initialize (obj <swig>) initargs) + (next-method) + (slot-set! obj 'swig-smob + (let ((arg (get-keyword #:init-smob initargs #f))) + (if arg + arg + (let ((ret (apply (slot-ref (class-of obj) 'new-function) (get-keyword #:args initargs '())))) + ;; if the class is registered with runtime environment, + ;; new-Function will return a <swig> goops class. In that case, extract the smob + ;; from that goops class and set it as the current smob. + (if (slot-exists? ret 'swig-smob) + (slot-ref ret 'swig-smob) + ret)))))) + +(define (display-address o file) + (display (number->string (object-address o) 16) file)) + +(define (display-pointer-address o file) + ;; Don't fail if the function SWIG-PointerAddress is not present. + (let ((address (false-if-exception (SWIG-PointerAddress o)))) + (if address + (begin + (display " @ " file) + (display (number->string address 16) file))))) + +(define-method (write (o <swig>) file) + ;; We display _two_ addresses to show the object's identity: + ;; * first the address of the GOOPS proxy object, + ;; * second the pointer address. + ;; The reason is that proxy objects are created and discarded on the + ;; fly, so different proxy objects for the same C object will appear. + (let ((class (class-of o))) + (if (slot-bound? class 'name) + (begin + (display "#<" file) + (display (class-name class) file) + (display #\space file) + (display-address o file) + (display-pointer-address o file) + (display ">" file)) + (next-method)))) + +(export <swig-metaclass> <swig>) + +;;; common.scm ends here diff --git a/gnuradio-core/src/guile/dynl-global.c b/gnuradio-core/src/guile/dynl-global.c new file mode 100644 index 000000000..3bf2741b1 --- /dev/null +++ b/gnuradio-core/src/guile/dynl-global.c @@ -0,0 +1,123 @@ +/* -*- c -*- */ +/* + * Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* + * This file is an attempt to work around a problem that appears on + * certain Ubuntu (and perhaps other) systems. On those systems + * (10.04 is known to have the problem, while 10.10 and later work OK + * without this kludge), we end up with a situation where exceptions + * are not caught by the swig code, even though the swig generated + * code "looks right" and "is right". Details of the issue can be + * found in swig bug 1863647, + * http://sourceforge.net/tracker/index.php?func=detail&aid=1863647&group_id=1645&atid=101645 + * + * We work around the problem by loading swig generated guile modules + * using the equivalent of the dlopen's RTLD_GLOBAL flag. This is + * only possible on systems using libtool-2.*. Those systems contain + * the lt_dlavise_global function. + */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <ltdl.h> +#include <libguile.h> + +extern scm_t_bits scm_tc16_dynamic_obj; + +#ifdef HAVE_LT_DLADVISE_GLOBAL +/* + * Load shared module using the equivalent of the RTLD_GLOBAL flag + */ +static lt_dlhandle +dlopenext_global (const char *filename) +{ + lt_dlhandle handle = 0; + lt_dladvise advise; + + if (!lt_dladvise_init (&advise) + && !lt_dladvise_ext (&advise) + && !lt_dladvise_global(&advise)) + handle = lt_dlopenadvise (filename, advise); + + lt_dladvise_destroy (&advise); + return handle; +} + +#else + +/* + * We don't have lt_dladvise_global. Fall back to lt_dlopenext. + */ +static lt_dlhandle +dlopenext_global (const char *filename) +{ + return lt_dlopenext (filename); +} +#endif + + +static void * +sysdep_dynl_link_global (const char *fname, const char *subr) +{ + lt_dlhandle handle; + handle = dlopenext_global (fname); + if (NULL == handle) + { + SCM fn; + SCM msg; + + fn = scm_from_locale_string (fname); + msg = scm_from_locale_string (lt_dlerror ()); + scm_misc_error (subr, "file: ~S, message: ~S", scm_list_2 (fn, msg)); + } + return (void *) handle; +} + +SCM_DEFINE (scm_dynamic_link_global, "dynamic-link-global", 1, 0, 0, + (SCM filename), + "Find the shared object (shared library) denoted by\n" + "@var{filename} and link it into the running Guile\n" + "application. The returned\n" + "scheme object is a ``handle'' for the library which can\n" + "be passed to @code{dynamic-func}, @code{dynamic-call} etc.\n\n" + "Searching for object files is system dependent. Normally,\n" + "if @var{filename} does have an explicit directory it will\n" + "be searched for in locations\n" + "such as @file{/usr/lib} and @file{/usr/local/lib}.") +#define FUNC_NAME s_scm_dynamic_link_global +{ + void *handle; + char *file; + + scm_dynwind_begin (0); + file = scm_to_locale_string (filename); + scm_dynwind_free (file); + handle = sysdep_dynl_link_global (file, FUNC_NAME); + scm_dynwind_end (); + SCM_RETURN_NEWSMOB2 (scm_tc16_dynamic_obj, SCM_UNPACK (filename), handle); +} +#undef FUNC_NAME + +void +scm_init_gnuradio_dynl_global_module(void) +{ + scm_c_define_gsubr (s_scm_dynamic_link_global, 1, 0, 0, (SCM (*)()) scm_dynamic_link_global); +} diff --git a/gnuradio-core/src/guile/gnuradio/core.scm b/gnuradio-core/src/guile/gnuradio/core.scm new file mode 100644 index 000000000..9c69cea42 --- /dev/null +++ b/gnuradio-core/src/guile/gnuradio/core.scm @@ -0,0 +1,32 @@ +;;; Glue the separate pieces of gnuradio-core into a single module + +(define-module (gnuradio core) + #:use-module (oop goops) + #:use-module (gnuradio gnuradio_core_runtime) + #:use-module (gnuradio runtime-shim) + #:use-module (gnuradio gnuradio_core_filter) + #:use-module (gnuradio gnuradio_core_io) + #:use-module (gnuradio gnuradio_core_general) + #:use-module (gnuradio gnuradio_core_gengen) + #:use-module (gnuradio gnuradio_core_hier) + #:duplicates (merge-generics replace check)) + +(re-export-all '(gnuradio gnuradio_core_runtime)) +(re-export-all '(gnuradio runtime-shim)) +(re-export-all '(gnuradio gnuradio_core_filter)) +(re-export-all '(gnuradio gnuradio_core_io)) +(re-export-all '(gnuradio gnuradio_core_general)) +(re-export-all '(gnuradio gnuradio_core_gengen)) +(re-export-all '(gnuradio gnuradio_core_hier)) + +;; Work around problem with gr:message-source +(define-generic gr:message-source) +(define-method (gr:message-source itemsize (msgq <gr-msg-queue-sptr>)) + (gr:message-source-msgq-ctor itemsize msgq)) +(define-method (gr:message-source itemsize (limit <integer>)) + (gr:message-source-limit-ctor itemsize limit)) +(export gr:message-source) + +;;; Return #t if x is not #f +(define-public (true? x) + (and x #t)) diff --git a/gnuradio-core/src/guile/gnuradio/export-safely.scm b/gnuradio-core/src/guile/gnuradio/export-safely.scm new file mode 100644 index 000000000..664292d2b --- /dev/null +++ b/gnuradio-core/src/guile/gnuradio/export-safely.scm @@ -0,0 +1,90 @@ +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; This module implements a macro, export-safely, that avoids +;;; exporting symbols that are actually generic-functions imported +;;; (explicity or implicitly) from elsewhere. +;;; +;;; This hackery is required so that the swig generated goops wrappers +;;; don't stomp on each other. For background on what this is about +;;; see this thread: +;;; +;;; http://lists.gnu.org/archive/html/guile-user/2006-05/msg00007.html +;;; +;;; Don't expect to understand what's going on here without looking at +;;; the guts of the module system (implemented in ice-9/boot-9.scm) and +;;; having a pretty good understanding of goops and generic-functions. + + +(define-module (gnuradio export-safely) + #:use-module (oop goops) + #:use-module (srfi srfi-1) + #:export-syntax (export-safely)) + +(define-public (generics-in-module module) + (let ((lst '())) + (module-for-each (lambda (sym var) + (if (variable-bound? var) + (let ((v (variable-ref var))) + (cond ((is-a? v <generic>) + (set! lst (cons v lst))))))) + module) + lst)) + +(define-public (generic-function-names-in-module module) + (map generic-function-name (generics-in-module module))) + +(define-public (generic-function-names-in-imported-modules module) + (concatenate (map generic-function-names-in-module (module-uses module)))) + +(define-public (export-syms-if-not-imported-gf list-of-syms) + (let ((gf-names (generic-function-names-in-imported-modules (current-module)))) + (let ((to-export (filter (lambda (sym) + (not (memq sym gf-names))) + (delete-duplicates list-of-syms)))) + (module-export! (current-module) to-export)))) + +(defmacro export-safely names + `(export-syms-if-not-imported-gf ',names)) + + +(define-public (names-in-module module) + (let ((lst '())) + (module-for-each (lambda (sym var) + (if (variable-bound? var) + (set! lst (cons sym lst)))) + module) + lst)) + +(define-public (names-in-imported-modules module) + (delete-duplicates (concatenate (map names-in-module (module-uses module))))) + +(define-public (re-export-all src-module-name) + (let ((current (current-module)) + (src-module (resolve-interface src-module-name))) + + (define (ok-to-re-export? name) + (let ((var (module-variable current name))) + (cond ((not var) #f) ; Undefined var + ((eq? var (module-local-variable current name)) #f) ; local var + (else #t)))) ; OK + + (module-re-export! current + (filter ok-to-re-export? + (names-in-module src-module))))) diff --git a/gnuradio-core/src/guile/gnuradio/run-waveform.scm b/gnuradio-core/src/guile/gnuradio/run-waveform.scm new file mode 100644 index 000000000..01930521c --- /dev/null +++ b/gnuradio-core/src/guile/gnuradio/run-waveform.scm @@ -0,0 +1,55 @@ +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; Load and run a waveform defined with define-waveform + + +;; I don't seem to be able to make this work... +;; I think it's some kind of interaction with the syntax-case +;; macro, define-waveform, and the module system. +;; +;;(define-module (gnuradio run-waveform) +;; #:use-module (oop goops) +;; #:use-module (gnuradio core) +;; #:use-module (gnuradio waveform) +;; #:duplicates (merge-generics replace check)) + +(use-modules (oop goops) + (gnuradio core) + (gnuradio waveform)) + + +(define (load-into-module filename module) + (let ((f (open-file filename "r"))) + (let loop ((form (read f))) + (cond ((eof-object? form) #t) + (else (eval form module) + (loop (read f))))))) + + +(define-public (run-waveform waveform-filename . args) + (debug-enable 'backtrace 'debug) + (load waveform-filename) + ;;(load-into-module waveform-filename (current-module)) + (let ((f (waveform-last-registered))) + (if (not f) + (error "No define-waveform found in file \n" filename)) + (gr:run (f args)) + ;; Attempt to get block destructors called now. + (gc))) diff --git a/gnuradio-core/src/guile/gnuradio/runtime-shim.scm b/gnuradio-core/src/guile/gnuradio/runtime-shim.scm new file mode 100644 index 000000000..bba702670 --- /dev/null +++ b/gnuradio-core/src/guile/gnuradio/runtime-shim.scm @@ -0,0 +1,129 @@ +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +(define-module (gnuradio runtime-shim) + #:use-module (oop goops) + #:use-module (ice-9 threads) + #:use-module (gnuradio gnuradio_core_runtime) + #:duplicates (merge-generics replace check)) + +(define-class <gr-endpoint> (<object>) + (block #:accessor block #:init-keyword #:block) + (port #:init-value 0 #:accessor port #:init-keyword #:port)) + +(define (gr:ep block port) + (make <gr-endpoint> + #:block (coerce-to-basic-block block) #:port port)) + +(define (coerce-to-endpoint ep) + (cond ((is-a? ep <gr-endpoint>) ep) + ((false-if-exception (gr:to-basic-block ep)) + => (lambda (x) (gr:ep x 0))) + ((and (pair? ep) (= 2 (length ep)) + (false-if-exception (gr:to-basic-block (car ep)))) + => (lambda (x) (gr:ep x (cadr ep)))) + (else (error "Cannot coerce to an endpoint: " ep)))) + +(define (coerce-to-basic-block block) + (cond ((is-a? block <gr-basic-block-sptr>) block) + ((false-if-exception (gr:to-basic-block block)) => (lambda (x) x)) + (else (error "Cannot coerce to a gr_basic_block: " block)))) + +(define (coerce-to-top-block block) + (cond ((is-a? block <gr-top-block-sptr>) block) + ((false-if-exception (gr:to-top-block block)) => (lambda (x) x)) + (else (error "Cannot coerce to a gr_top_block: " block)))) + +(define (coerce-to-hier-block2 block) + (cond ((is-a? block <gr-hier-block2-sptr>) block) + ((false-if-exception (gr:to-hier-block2 block)) => (lambda (x) x)) + (else (error "Cannot coerce to a gr_hier_block2: " block)))) + + +;;; Connect one or more block endpoints. An endpoint is either a <gr-endpoint>, +;;; a 2-list (block port), or a block instance. In the latter case, the port number +;;; is assumed to be zero. +;;; +;;; If multiple arguments are provided, connect will attempt to wire them in series, +;;; interpreting the endpoints as inputs or outputs as appropriate. +(define-method (gr:connect hb . points) + (dis/connect "connect" gr:primitive-connect hb points)) + +;;; Disconnect one or more block endpoints... +(define-method (gr:disconnect hb . points) + (dis/connect "disconnect" gr:primitive-disconnect hb points)) + +(define (dis/connect name gf hb points) + (let ((hb (coerce-to-hier-block2 hb)) + (points (list->vector (map coerce-to-endpoint points)))) + + (define (op2 p0 p1) + (gf hb (block p0) (port p0) (block p1) (port p1))) + + (let ((len (vector-length points))) + (case len + ((0) (error (string-append name " requires at least 1 endpoint; None provided."))) + ((1) (gf hb (vector-ref points 0))) + (else + (let loop ((n 1)) + (cond ((< n len) + (op2 (vector-ref points (1- n)) (vector-ref points n)) + (loop (1+ n)))))))))) + + + + +(define-method (gr:run (self <gr-top-block-sptr>)) + (gr:start self) + (gr:wait self)) + + +(define-method (gr:wait (tb <gr-top-block-sptr>)) + + (define (sigint-handler sig) + ;;(display "\nSIGINT!\n" (current-error-port)) + ;; tell flow graph to stop + (gr:stop tb)) + + (let ((old-handler #f)) + (dynamic-wind + + ;; Called at entry + (lambda () + ;; Install SIGINT handler + (set! old-handler (sigaction SIGINT sigint-handler))) + + ;; Protected thunk + (lambda () + (let ((waiter (begin-thread (gr:top-block-wait-unlocked tb)))) + (join-thread waiter) + ;;(display "\nAfter join-thread\n" (current-error-port)) + )) + + ;; Called at exit + (lambda () + ;; Restore SIGINT handler + (if (not (car old-handler)) + ;; restore original C handler + (sigaction SIGINT #f) + ;; restore Scheme handler, SIG_IGN or SIG_DFL + (sigaction SIGINT (car old-handler) (cdr old-handler))))))) + + +(export-safely <gr-endpoint> gr:ep gr:connect gr:disconnect gr:run gr:wait) diff --git a/gnuradio-core/src/guile/gnuradio/test-suite/guile-test b/gnuradio-core/src/guile/gnuradio/test-suite/guile-test new file mode 100644 index 000000000..6dc1a9658 --- /dev/null +++ b/gnuradio-core/src/guile/gnuradio/test-suite/guile-test @@ -0,0 +1,241 @@ +#!/usr/bin/guile \ +-e main -s +!# + +;;;; guile-test --- run the Guile test suite +;;;; Jim Blandy <jimb@red-bean.com> --- May 1999 +;;;; +;;;; Copyright (C) 1999, 2001, 2006 Free Software Foundation, Inc. +;;;; +;;;; This program 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 2, or (at your option) +;;;; any later version. +;;;; +;;;; This program 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 this software; see the file COPYING. If not, write to +;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;;;; Boston, MA 02110-1301 USA + + +;;;; Usage: [guile -e main -s] guile-test [OPTIONS] [TEST ...] +;;;; +;;;; Run tests from the Guile test suite. Report failures and +;;;; unexpected passes to the standard output, along with a summary of +;;;; all the results. Record each reported test outcome in the log +;;;; file, `guile.log'. The exit status is #f if any of the tests +;;;; fail or pass unexpectedly. +;;;; +;;;; Normally, guile-test scans the test directory, and executes all +;;;; files whose names end in `.test'. (It assumes they contain +;;;; Scheme code.) However, you can have it execute specific tests by +;;;; listing their filenames on the command line. +;;;; +;;;; The option `--test-suite' can be given to specify the test +;;;; directory. If no such option is given, the test directory is +;;;; taken from the environment variable TEST_SUITE_DIR (if defined), +;;;; otherwise a default directory that is hardcoded in this file is +;;;; used (see "Installation" below). +;;;; +;;;; If present, the `--log-file LOG' option tells `guile-test' to put +;;;; the log output in a file named LOG. +;;;; +;;;; If present, the `--debug' option will enable a debugging mode. +;;;; +;;;; If present, the `--flag-unresolved' option will cause guile-test +;;;; to exit with failure status if any tests are UNRESOLVED. +;;;; +;;;; +;;;; Installation: +;;;; +;;;; If you change the #! line at the top of this script to point at +;;;; the Guile interpreter you want to test, you can call this script +;;;; as an executable instead of having to pass it as a parameter to +;;;; guile via "guile -e main -s guile-test". Further, you can edit +;;;; the definition of default-test-suite to point to the parent +;;;; directory of the `tests' tree, which makes it unnecessary to set +;;;; the environment variable `TEST_SUITE_DIR'. +;;;; +;;;; +;;;; Shortcomings: +;;;; +;;;; At the moment, due to a simple-minded implementation, test files +;;;; must live in the test directory, and you must specify their names +;;;; relative to the top of the test directory. If you want to send +;;;; me a patch that fixes this, but still leaves sane test names in +;;;; the log file, that would be great. At the moment, all the tests +;;;; I care about are in the test directory, though. +;;;; +;;;; It would be nice if you could specify the Guile interpreter you +;;;; want to test on the command line. As it stands, if you want to +;;;; change which Guile interpreter you're testing, you need to edit +;;;; the #! line at the top of this file, which is stupid. + +(define (main . args) + (let ((module (resolve-module '(gnuradio test-suite guile-test)))) + (apply (module-ref module 'main) args))) + +(define-module (gnuradio test-suite guile-test) + :use-module (gnuradio test-suite lib) + :use-module (ice-9 getopt-long) + :use-module (ice-9 and-let-star) + :use-module (ice-9 rdelim) + :export (main data-file-name test-file-name)) + + +;;; User configurable settings: +(define default-test-suite + (string-append (getenv "HOME") "/bogus-path/test-suite")) + + +;;; Variables that will receive their actual values later. +(define test-suite default-test-suite) + +(define tmp-dir #f) + + +;;; General utilities, that probably should be in a library somewhere. + +;;; Enable debugging +(define (enable-debug-mode) + (write-line %load-path) + (set! %load-verbosely #t) + (debug-enable 'backtrace 'debug)) + +;;; Traverse the directory tree at ROOT, applying F to the name of +;;; each file in the tree, including ROOT itself. For a subdirectory +;;; SUB, if (F SUB) is true, we recurse into SUB. Do not follow +;;; symlinks. +(define (for-each-file f root) + + ;; A "hard directory" is a path that denotes a directory and is not a + ;; symlink. + (define (file-is-hard-directory? filename) + (eq? (stat:type (lstat filename)) 'directory)) + + (let visit ((root root)) + (let ((should-recur (f root))) + (if (and should-recur (file-is-hard-directory? root)) + (let ((dir (opendir root))) + (let loop () + (let ((entry (readdir dir))) + (cond + ((eof-object? entry) #f) + ((or (string=? entry ".") + (string=? entry "..") + (string=? entry "CVS") + (string=? entry "RCS")) + (loop)) + (else + (visit (string-append root "/" entry)) + (loop)))))))))) + + +;;; The test driver. + + +;;; Localizing test files and temporary data files. + +(define (data-file-name filename) + (in-vicinity tmp-dir filename)) + +(define (test-file-name test) + (in-vicinity test-suite test)) + +;;; Return a list of all the test files in the test tree. +(define (enumerate-tests test-dir) + (let ((root-len (+ 1 (string-length test-dir))) + (tests '())) + (for-each-file (lambda (file) + (if (has-suffix? file ".test") + (let ((short-name + (substring file root-len))) + (set! tests (cons short-name tests)))) + #t) + test-dir) + + ;; for-each-file presents the files in whatever order it finds + ;; them in the directory. We sort them here, so they'll always + ;; appear in the same order. This makes it easier to compare test + ;; log files mechanically. + (sort tests string<?))) + +(define (main args) + (let ((options (getopt-long args + `((test-suite + (single-char #\t) + (value #t)) + (flag-unresolved + (single-char #\u)) + (log-file + (single-char #\l) + (value #t)) + (debug + (single-char #\d)))))) + (define (opt tag default) + (let ((pair (assq tag options))) + (if pair (cdr pair) default))) + + (if (opt 'debug #f) + (enable-debug-mode)) + + (set! test-suite + (or (opt 'test-suite #f) + (getenv "TEST_SUITE_DIR") + default-test-suite)) + + ;; directory where temporary files are created. + ;; when run from "make check", this must be under the build-dir, + ;; not the src-dir. + (set! tmp-dir (getcwd)) + + (let* ((tests + (let ((foo (opt '() '()))) + (if (null? foo) + (enumerate-tests test-suite) + foo))) + (log-file + (opt 'log-file "guile.log"))) + + ;; Open the log file. + (let ((log-port (open-output-file log-file))) + + ;; Register some reporters. + (let ((global-pass #t) + (counter (make-count-reporter))) + (register-reporter (car counter)) + (register-reporter (make-log-reporter log-port)) + (register-reporter user-reporter) + (register-reporter (lambda results + (case (car results) + ((unresolved) + (and (opt 'flag-unresolved #f) + (set! global-pass #f))) + ((fail upass error) + (set! global-pass #f))))) + + ;; Run the tests. + (for-each (lambda (test) + (display (string-append "Running " test "\n")) + (with-test-prefix test + (load (test-file-name test)))) + tests) + + ;; Display the final counts, both to the user and in the log + ;; file. + (let ((counts ((cadr counter)))) + (print-counts counts) + (print-counts counts log-port)) + + (close-port log-port) + (quit global-pass)))))) + + +;;; Local Variables: +;;; mode: scheme +;;; End: diff --git a/gnuradio-core/src/guile/gnuradio/test-suite/lib.scm b/gnuradio-core/src/guile/gnuradio/test-suite/lib.scm new file mode 100644 index 000000000..abdc89632 --- /dev/null +++ b/gnuradio-core/src/guile/gnuradio/test-suite/lib.scm @@ -0,0 +1,627 @@ +;;;; test-suite/lib.scm --- generic support for testing +;;;; Copyright (C) 1999, 2000, 2001, 2004, 2006, 2007 Free Software Foundation, Inc. +;;;; +;;;; This program 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 2, or (at your option) +;;;; any later version. +;;;; +;;;; This program 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 this software; see the file COPYING. If not, write to +;;;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +;;;; Boston, MA 02110-1301 USA + +(define-module (gnuradio test-suite lib) + :use-module (ice-9 stack-catch) + :use-module (ice-9 regex) + :use-module (ice-9 syncase) + :use-module (ice-9 format) + :export ( + + ;; Exceptions which are commonly being tested for. + exception:bad-variable + exception:missing-expression + exception:out-of-range exception:unbound-var + exception:used-before-defined + exception:wrong-num-args exception:wrong-type-arg + exception:numerical-overflow + exception:struct-set!-denied + exception:system-error + exception:miscellaneous-error + exception:string-contains-nul + + ;; Reporting passes and failures. + run-test + pass-if expect-fail + pass-if-exception expect-fail-exception + pass-if-throw expect-fail-throw + + ;; Naming groups of tests in a regular fashion. + with-test-prefix with-test-prefix* current-test-prefix + format-test-name + + ;; Using the debugging evaluator. + with-debugging-evaluator with-debugging-evaluator* + + ;; Reporting results in various ways. + register-reporter unregister-reporter reporter-registered? + make-count-reporter print-counts + make-log-reporter + full-reporter + user-reporter + + ;; srfi-64 compatibility macros + test-equal + test-eqv + test-eq +)) + + +;;;; If you're using Emacs's Scheme mode: +;;;; (put 'with-test-prefix 'scheme-indent-function 1) + + +;;;; CORE FUNCTIONS +;;;; +;;;; The function (run-test name expected-result thunk) is the heart of the +;;;; testing environment. The first parameter NAME is a unique name for the +;;;; test to be executed (for an explanation of this parameter see below under +;;;; TEST NAMES). The second parameter EXPECTED-RESULT is a boolean value +;;;; that indicates whether the corresponding test is expected to pass. If +;;;; EXPECTED-RESULT is #t the test is expected to pass, if EXPECTED-RESULT is +;;;; #f the test is expected to fail. Finally, THUNK is the function that +;;;; actually performs the test. For example: +;;;; +;;;; (run-test "integer addition" #t (lambda () (= 2 (+ 1 1)))) +;;;; +;;;; To report success, THUNK should either return #t or throw 'pass. To +;;;; report failure, THUNK should either return #f or throw 'fail. If THUNK +;;;; returns a non boolean value or throws 'unresolved, this indicates that +;;;; the test did not perform as expected. For example the property that was +;;;; to be tested could not be tested because something else went wrong. +;;;; THUNK may also throw 'untested to indicate that the test was deliberately +;;;; not performed, for example because the test case is not complete yet. +;;;; Finally, if THUNK throws 'unsupported, this indicates that this test +;;;; requires some feature that is not available in the configured testing +;;;; environment. All other exceptions thrown by THUNK are considered as +;;;; errors. +;;;; +;;;; +;;;; Convenience macros for tests expected to pass or fail +;;;; +;;;; * (pass-if name body) is a short form for +;;;; (run-test name #t (lambda () body)) +;;;; * (expect-fail name body) is a short form for +;;;; (run-test name #f (lambda () body)) +;;;; +;;;; For example: +;;;; +;;;; (pass-if "integer addition" (= 2 (+ 1 1))) +;;;; +;;;; +;;;; Convenience macros to test for exceptions +;;;; +;;;; The following macros take exception parameters which are pairs +;;;; (type . message), where type is a symbol that denotes an exception type +;;;; like 'wrong-type-arg or 'out-of-range, and message is a string holding a +;;;; regular expression that describes the error message for the exception +;;;; like "Argument .* out of range". +;;;; +;;;; * (pass-if-exception name exception body) will pass if the execution of +;;;; body causes the given exception to be thrown. If no exception is +;;;; thrown, the test fails. If some other exception is thrown, is is an +;;;; error. +;;;; * (expect-fail-exception name exception body) will pass unexpectedly if +;;;; the execution of body causes the given exception to be thrown. If no +;;;; exception is thrown, the test fails expectedly. If some other +;;;; exception is thrown, it is an error. + + +;;;; TEST NAMES +;;;; +;;;; Every test in the test suite has a unique name, to help +;;;; developers find tests that are failing (or unexpectedly passing), +;;;; and to help gather statistics. +;;;; +;;;; A test name is a list of printable objects. For example: +;;;; ("ports.scm" "file" "read and write back list of strings") +;;;; ("ports.scm" "pipe" "read") +;;;; +;;;; Test names may contain arbitrary objects, but they always have +;;;; the following properties: +;;;; - Test names can be compared with EQUAL?. +;;;; - Test names can be reliably stored and retrieved with the standard WRITE +;;;; and READ procedures; doing so preserves their identity. +;;;; +;;;; For example: +;;;; +;;;; (pass-if "simple addition" (= 4 (+ 2 2))) +;;;; +;;;; In that case, the test name is the list ("simple addition"). +;;;; +;;;; In the case of simple tests the expression that is tested would often +;;;; suffice as a test name by itself. Therefore, the convenience macros +;;;; pass-if and expect-fail provide a shorthand notation that allows to omit +;;;; a test name in such cases. +;;;; +;;;; * (pass-if expression) is a short form for +;;;; (run-test 'expression #t (lambda () expression)) +;;;; * (expect-fail expression) is a short form for +;;;; (run-test 'expression #f (lambda () expression)) +;;;; +;;;; For example: +;;;; +;;;; (pass-if (= 2 (+ 1 1))) +;;;; +;;;; The WITH-TEST-PREFIX syntax and WITH-TEST-PREFIX* procedure establish +;;;; a prefix for the names of all tests whose results are reported +;;;; within their dynamic scope. For example: +;;;; +;;;; (begin +;;;; (with-test-prefix "basic arithmetic" +;;;; (pass-if "addition" (= (+ 2 2) 4)) +;;;; (pass-if "subtraction" (= (- 4 2) 2))) +;;;; (pass-if "multiplication" (= (* 2 2) 4))) +;;;; +;;;; In that example, the three test names are: +;;;; ("basic arithmetic" "addition"), +;;;; ("basic arithmetic" "subtraction"), and +;;;; ("multiplication"). +;;;; +;;;; WITH-TEST-PREFIX can be nested. Each WITH-TEST-PREFIX postpends +;;;; a new element to the current prefix: +;;;; +;;;; (with-test-prefix "arithmetic" +;;;; (with-test-prefix "addition" +;;;; (pass-if "integer" (= (+ 2 2) 4)) +;;;; (pass-if "complex" (= (+ 2+3i 4+5i) 6+8i))) +;;;; (with-test-prefix "subtraction" +;;;; (pass-if "integer" (= (- 2 2) 0)) +;;;; (pass-if "complex" (= (- 2+3i 1+2i) 1+1i)))) +;;;; +;;;; The four test names here are: +;;;; ("arithmetic" "addition" "integer") +;;;; ("arithmetic" "addition" "complex") +;;;; ("arithmetic" "subtraction" "integer") +;;;; ("arithmetic" "subtraction" "complex") +;;;; +;;;; To print a name for a human reader, we DISPLAY its elements, +;;;; separated by ": ". So, the last set of test names would be +;;;; reported as: +;;;; +;;;; arithmetic: addition: integer +;;;; arithmetic: addition: complex +;;;; arithmetic: subtraction: integer +;;;; arithmetic: subtraction: complex +;;;; +;;;; The Guile benchmarks use with-test-prefix to include the name of +;;;; the source file containing the test in the test name, to help +;;;; developers to find failing tests, and to provide each file with its +;;;; own namespace. + + +;;;; REPORTERS +;;;; +;;;; A reporter is a function which we apply to each test outcome. +;;;; Reporters can log results, print interesting results to the +;;;; standard output, collect statistics, etc. +;;;; +;;;; A reporter function takes two mandatory arguments, RESULT and TEST, and +;;;; possibly additional arguments depending on RESULT; its return value +;;;; is ignored. RESULT has one of the following forms: +;;;; +;;;; pass - The test named TEST passed. +;;;; Additional arguments are ignored. +;;;; upass - The test named TEST passed unexpectedly. +;;;; Additional arguments are ignored. +;;;; fail - The test named TEST failed. +;;;; Additional arguments are ignored. +;;;; xfail - The test named TEST failed, as expected. +;;;; Additional arguments are ignored. +;;;; unresolved - The test named TEST did not perform as expected, for +;;;; example the property that was to be tested could not be +;;;; tested because something else went wrong. +;;;; Additional arguments are ignored. +;;;; untested - The test named TEST was not actually performed, for +;;;; example because the test case is not complete yet. +;;;; Additional arguments are ignored. +;;;; unsupported - The test named TEST requires some feature that is not +;;;; available in the configured testing environment. +;;;; Additional arguments are ignored. +;;;; error - An error occurred while the test named TEST was +;;;; performed. Since this result means that the system caught +;;;; an exception it could not handle, the exception arguments +;;;; are passed as additional arguments. +;;;; +;;;; This library provides some standard reporters for logging results +;;;; to a file, reporting interesting results to the user, and +;;;; collecting totals. +;;;; +;;;; You can use the REGISTER-REPORTER function and friends to add +;;;; whatever reporting functions you like. If you don't register any +;;;; reporters, the library uses FULL-REPORTER, which simply writes +;;;; all results to the standard output. + + +;;;; MISCELLANEOUS +;;;; + +;;; Define some exceptions which are commonly being tested for. +(define exception:bad-variable + (cons 'syntax-error "Bad variable")) +(define exception:missing-expression + (cons 'misc-error "^missing or extra expression")) +(define exception:out-of-range + (cons 'out-of-range "^.*out of range")) +(define exception:unbound-var + (cons 'unbound-variable "^Unbound variable")) +(define exception:used-before-defined + (cons 'unbound-variable "^Variable used before given a value")) +(define exception:wrong-num-args + (cons 'wrong-number-of-args "^Wrong number of arguments")) +(define exception:wrong-type-arg + (cons 'wrong-type-arg "^Wrong type")) +(define exception:numerical-overflow + (cons 'numerical-overflow "^Numerical overflow")) +(define exception:struct-set!-denied + (cons 'misc-error "^set! denied for field")) +(define exception:system-error + (cons 'system-error ".*")) +(define exception:miscellaneous-error + (cons 'misc-error "^.*")) + +;; as per throw in scm_to_locale_stringn() +(define exception:string-contains-nul + (cons 'misc-error "^string contains #\\\\nul character")) + + +;;; Display all parameters to the default output port, followed by a newline. +(define (display-line . objs) + (for-each display objs) + (newline)) + +;;; Display all parameters to the given output port, followed by a newline. +(define (display-line-port port . objs) + (for-each (lambda (obj) (display obj port)) objs) + (newline port)) + + +;;;; CORE FUNCTIONS +;;;; + +;;; The central testing routine. +;;; The idea is taken from Greg, the GNUstep regression test environment. +(define run-test #f) +(let ((test-running #f)) + (define (local-run-test name expect-pass thunk) + (if test-running + (error "Nested calls to run-test are not permitted.") + (let ((test-name (full-name name))) + (set! test-running #t) + (catch #t + (lambda () + (let ((result (thunk))) + (if (eq? result #t) (throw 'pass)) + (if (eq? result #f) (throw 'fail)) + (throw 'unresolved))) + (lambda (key . args) + (case key + ((pass) + (report (if expect-pass 'pass 'upass) test-name)) + ((fail) + (report (if expect-pass 'fail 'xfail) test-name)) + ((unresolved untested unsupported) + (report key test-name)) + ((quit) + (report 'unresolved test-name) + (quit)) + (else + (report 'error test-name (cons key args)))))) + (set! test-running #f)))) + (set! run-test local-run-test)) + +;;; A short form for tests that are expected to pass, taken from Greg. +(defmacro pass-if (name . rest) + (if (and (null? rest) (pair? name)) + ;; presume this is a simple test, i.e. (pass-if (even? 2)) + ;; where the body should also be the name. + `(run-test ',name #t (lambda () ,name)) + `(run-test ,name #t (lambda () ,@rest)))) + +;;; A short form for tests that are expected to fail, taken from Greg. +(defmacro expect-fail (name . rest) + (if (and (null? rest) (pair? name)) + ;; presume this is a simple test, i.e. (expect-fail (even? 2)) + ;; where the body should also be the name. + `(run-test ',name #f (lambda () ,name)) + `(run-test ,name #f (lambda () ,@rest)))) + +;;; A helper function to implement the macros that test for exceptions. +;;; +;;; This doesn't work for all exceptions, just those that were +;;; raised by scm-error or error. This doesn't include those +;;; raised by throw in the general case, or SWIG in particular. +;;; +;;; See also run-raise-exception, pass-if-throw and expect-fail-throw +;;; for alternatives that work with all exceptions. +(define (run-test-exception name exception expect-pass thunk) + (run-test name expect-pass + (lambda () + (stack-catch (car exception) + (lambda () (thunk) #f) + (lambda (key proc message . rest) + (cond + ;; handle explicit key + ((string-match (cdr exception) message) + #t) + ;; handle `(error ...)' which uses `misc-error' for key and doesn't + ;; yet format the message and args (we have to do it here). + ((and (eq? 'misc-error (car exception)) + (list? rest) + (string-match (cdr exception) + (apply simple-format #f message (car rest)))) + #t) + ;; handle syntax errors which use `syntax-error' for key and don't + ;; yet format the message and args (we have to do it here). + ((and (eq? 'syntax-error (car exception)) + (list? rest) + (string-match (cdr exception) + (apply simple-format #f message (car rest)))) + #t) + ;; unhandled; throw again + (else + (apply throw key proc message rest)))))))) + +;;; A short form for tests that expect a certain exception to be thrown. +(defmacro pass-if-exception (name exception body . rest) + `(,run-test-exception ,name ,exception #t (lambda () ,body ,@rest))) + +;;; A short form for tests expected to fail to throw a certain exception. +(defmacro expect-fail-exception (name exception body . rest) + `(,run-test-exception ,name ,exception #f (lambda () ,body ,@rest))) + + +;;; Helper for macros below +(define (run-test-throw name exception-key expect-pass thunk) + (run-test name expect-pass + (lambda () + (stack-catch exception-key + (lambda () (thunk) #f) + (lambda (key . rest) #t))))) + +;;; A short form for tests that expect a certain exception to be thrown, +;;; where the exception is specified only by the exception-key symbol. +(defmacro pass-if-throw (name exception-key body . rest) + `(,run-test-throw ,name ,exception-key #t (lambda () ,body ,@rest))) + +;;; A short form for tests that expect a certain exception to be thrown, +;;; where the exception is specified only by the exception-key symbol. +(defmacro expect-fail-throw (name exception-key body . rest) + `(,run-test-throw ,name ,exception-key #f (lambda () ,body ,@rest))) + +;;;; TEST NAMES +;;;; + +;;;; Turn a test name into a nice human-readable string. +(define (format-test-name name) + (call-with-output-string + (lambda (port) + (let loop ((name name) + (separator "")) + (if (pair? name) + (begin + (display separator port) + (display (car name) port) + (loop (cdr name) ": "))))))) + +;;;; For a given test-name, deliver the full name including all prefixes. +(define (full-name name) + (append (current-test-prefix) (list name))) + +;;; A fluid containing the current test prefix, as a list. +(define prefix-fluid (make-fluid)) +(fluid-set! prefix-fluid '()) +(define (current-test-prefix) + (fluid-ref prefix-fluid)) + +;;; Postpend PREFIX to the current name prefix while evaluting THUNK. +;;; The name prefix is only changed within the dynamic scope of the +;;; call to with-test-prefix*. Return the value returned by THUNK. +(define (with-test-prefix* prefix thunk) + (with-fluids ((prefix-fluid + (append (fluid-ref prefix-fluid) (list prefix)))) + (thunk))) + +;;; (with-test-prefix PREFIX BODY ...) +;;; Postpend PREFIX to the current name prefix while evaluating BODY ... +;;; The name prefix is only changed within the dynamic scope of the +;;; with-test-prefix expression. Return the value returned by the last +;;; BODY expression. +(defmacro with-test-prefix (prefix . body) + `(with-test-prefix* ,prefix (lambda () ,@body))) + +;;; Call THUNK using the debugging evaluator. +(define (with-debugging-evaluator* thunk) + (let ((dopts #f)) + (dynamic-wind + (lambda () + (set! dopts (debug-options)) + (debug-enable 'debug)) + thunk + (lambda () + (debug-options dopts))))) + +;;; Evaluate BODY... using the debugging evaluator. +(define-macro (with-debugging-evaluator . body) + `(with-debugging-evaluator* (lambda () ,@body))) + + + +;;;; REPORTERS +;;;; + +;;; The global list of reporters. +(define reporters '()) + +;;; The default reporter, to be used only if no others exist. +(define default-reporter #f) + +;;; Add the procedure REPORTER to the current set of reporter functions. +;;; Signal an error if that reporter procedure object is already registered. +(define (register-reporter reporter) + (if (memq reporter reporters) + (error "register-reporter: reporter already registered: " reporter)) + (set! reporters (cons reporter reporters))) + +;;; Remove the procedure REPORTER from the current set of reporter +;;; functions. Signal an error if REPORTER is not currently registered. +(define (unregister-reporter reporter) + (if (memq reporter reporters) + (set! reporters (delq! reporter reporters)) + (error "unregister-reporter: reporter not registered: " reporter))) + +;;; Return true iff REPORTER is in the current set of reporter functions. +(define (reporter-registered? reporter) + (if (memq reporter reporters) #t #f)) + +;;; Send RESULT to all currently registered reporter functions. +(define (report . args) + (if (pair? reporters) + (for-each (lambda (reporter) (apply reporter args)) + reporters) + (apply default-reporter args))) + + +;;;; Some useful standard reporters: +;;;; Count reporters count the occurrence of each test result type. +;;;; Log reporters write all test results to a given log file. +;;;; Full reporters write all test results to the standard output. +;;;; User reporters write interesting test results to the standard output. + +;;; The complete list of possible test results. +(define result-tags + '((pass "PASS" "passes: ") + (fail "FAIL" "failures: ") + (upass "UPASS" "unexpected passes: ") + (xfail "XFAIL" "expected failures: ") + (unresolved "UNRESOLVED" "unresolved test cases: ") + (untested "UNTESTED" "untested test cases: ") + (unsupported "UNSUPPORTED" "unsupported test cases: ") + (error "ERROR" "errors: "))) + +;;; The list of important test results. +(define important-result-tags + '(fail upass unresolved error)) + +;;; Display a single test result in formatted form to the given port +(define (print-result port result name . args) + (let* ((tag (assq result result-tags)) + (label (if tag (cadr tag) #f))) + (if label + (begin + (display label port) + (display ": " port) + (display (format-test-name name) port) + (if (pair? args) + (begin + (display " - arguments: " port) + (write args port))) + (newline port)) + (error "(test-suite lib) FULL-REPORTER: unrecognized result: " + result)))) + +;;; Return a list of the form (COUNTER RESULTS), where: +;;; - COUNTER is a reporter procedure, and +;;; - RESULTS is a procedure taking no arguments which returns the +;;; results seen so far by COUNTER. The return value is an alist +;;; mapping outcome symbols (`pass', `fail', etc.) onto counts. +(define (make-count-reporter) + (let ((counts (map (lambda (tag) (cons (car tag) 0)) result-tags))) + (list + (lambda (result name . args) + (let ((pair (assq result counts))) + (if pair + (set-cdr! pair (+ 1 (cdr pair))) + (error "count-reporter: unexpected test result: " + (cons result (cons name args)))))) + (lambda () + (append counts '()))))) + +;;; Print a count reporter's results nicely. Pass this function the value +;;; returned by a count reporter's RESULTS procedure. +(define (print-counts results . port?) + (let ((port (if (pair? port?) + (car port?) + (current-output-port)))) + (newline port) + (display-line-port port "Totals for this test run:") + (for-each + (lambda (tag) + (let ((result (assq (car tag) results))) + (if result + (display-line-port port (caddr tag) (cdr result)) + (display-line-port port + "Test suite bug: " + "no total available for `" (car tag) "'")))) + result-tags) + (newline port))) + +;;; Return a reporter procedure which prints all results to the file +;;; FILE, in human-readable form. FILE may be a filename, or a port. +(define (make-log-reporter file) + (let ((port (if (output-port? file) file + (open-output-file file)))) + (lambda args + (apply print-result port args) + (force-output port)))) + +;;; A reporter that reports all results to the user. +(define (full-reporter . args) + (apply print-result (current-output-port) args)) + +;;; A reporter procedure which shows interesting results (failures, +;;; unexpected passes etc.) to the user. +(define (user-reporter result name . args) + (if (memq result important-result-tags) + (apply full-reporter result name args))) + +(set! default-reporter full-reporter) + + +;;; Macros for a bit of compatibility with srfi-64 +;;; (test-equal [name] expected test-expr) +(define-syntax test-equal + (syntax-rules () + ((_ expected test-expr) + (pass-if (verbose-equal? expected test-expr))) + ((_ name expected test-exprt) + (pass-if name (verbose-equal? expected test-expr))))) + +;;; (test-eqv [name] expected test-expr) +(define-syntax test-eqv + (syntax-rules () + ((_ expected test-expr) + (pass-if (eqv? expected test-expr))) + ((_ name expected test-exprt) + (pass-if name (eqv? expected test-expr))))) + +;;; (test-eq [name] expected test-expr) +(define-syntax test-eq + (syntax-rules () + ((_ expected test-expr) + (pass-if (eq? expected test-expr))) + ((_ name expected test-exprt) + (pass-if name (eq? expected test-expr))))) + + +(define-public (verbose-equal? expected actual) + (cond ((equal? expected actual) #t) + (else + (format #t "Expected:\n~y\n" expected) + (format #t "Actual:\n~y\n" actual) + #f))) diff --git a/gnuradio-core/src/guile/gnuradio/waveform.scm b/gnuradio-core/src/guile/gnuradio/waveform.scm new file mode 100644 index 000000000..0031be931 --- /dev/null +++ b/gnuradio-core/src/guile/gnuradio/waveform.scm @@ -0,0 +1,54 @@ +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +(define-module (gnuradio waveform) + #:use-module (ice-9 syncase) + #:export-syntax (define-waveform)) + + +(define *registry* '()) ; alist +(define *last-registered* #f) + + +(define-syntax define-waveform + (syntax-rules (vars blocks connections) + ((_ (name cmd-line-args) + (vars (v-name v-val) ...) + (blocks (b-name b-val) ...) + (connections (endpoint1 endpoint2 ...) ...)) + (waveform-register 'name + (lambda (cmd-line-args) + (let* ((v-name v-val) ... + (b-name b-val) ... + (tb (gr:top-block-swig "waveform-top-block"))) + (gr:connect tb endpoint1 endpoint2 ...) ... + tb)))))) + + +(define-public (waveform-register name thunk) + (set! *registry* (assoc-set! *registry* name thunk)) + (set! *last-registered* thunk) + #t) + +(define-public (waveform-lookup name) + (let ((r (assoc name *registry*))) + (and r (cdr r)))) + +(define-public (waveform-last-registered) + *last-registered*) diff --git a/gnuradio-core/src/guile/gr-run-waveform-script.in b/gnuradio-core/src/guile/gr-run-waveform-script.in new file mode 100644 index 000000000..651b387e9 --- /dev/null +++ b/gnuradio-core/src/guile/gr-run-waveform-script.in @@ -0,0 +1,51 @@ +#!/bin/sh + +# usage: prepend <path-varname> <dir> +prepend() { + if [ $# -ne 2 ] + then + echo "$0: prepend needs 2 args" 1>&2 + exit 1 + fi + local path="$1" dir="$2" contents="" + eval "contents=\$$path" + if [ "$dir" != "" ] + then + if [ "$contents" = "" ] + then + eval "$path=\"$dir\"" + else + eval "$path=\"$dir:$contents\"" + fi + fi + #echo end-of-prepend: $path=${!path} +} + +prefix="@prefix@" +exec_prefix="@exec_prefix@" + +prepend GUILE_LOAD_PATH "${prefix}/share/guile/site" +prepend LTDL_LIBRARY_PATH "@libdir@" +prepend DYLD_LIBRARY_PATH "@libdir@" + +export GUILE_LOAD_PATH LTDL_LIBRARY_PATH DYLD_LIBRARY_PATH + +export GUILE_WARN_DEPRECATED="no" + +exec @GUILE@ -e main -s $0 "$@" +!# + +;;; Load and run a waveform defined with define-waveform +;;; +;;; usage: gr-run-waveform filename.wfd [args...] + +(load-from-path "gnuradio/run-waveform") + +(define (main args) + (if (not (>= (length args) 2)) + (let ((port (current-error-port))) + (display "usage: " port) + (display (car args) port) + (display " filename.wfd [args...]\n" port) + (exit 1))) + (apply run-waveform (cdr args))) diff --git a/gnuradio-core/src/guile/run_guile_tests.in b/gnuradio-core/src/guile/run_guile_tests.in new file mode 100644 index 000000000..61968065e --- /dev/null +++ b/gnuradio-core/src/guile/run_guile_tests.in @@ -0,0 +1,17 @@ +#!/bin/sh + +. @top_builddir@/setup_guile_test_env + +# Since we're in gnuradio-core, we don't need to add anything, +# but we do need to call add_local_paths to set everything up + +# 1st argument is absolute path to hand coded guile source directory +# 2nd argument is absolute path to component C++ shared library build directory +# 3nd argument is absolute path to component SWIG build directory + +add_local_paths \ + "" \ + "" \ + "" + +@GUILE@ -e main -c '(use-modules (gnuradio test-suite guile-test))' -t @srcdir@/tests diff --git a/gnuradio-core/src/guile/tests/00_runtime_basics.test b/gnuradio-core/src/guile/tests/00_runtime_basics.test new file mode 100644 index 000000000..4a5d967a1 --- /dev/null +++ b/gnuradio-core/src/guile/tests/00_runtime_basics.test @@ -0,0 +1,159 @@ +;;; -*- Scheme -*- +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; If you're using Emacs's Scheme mode: +;;; (put 'with-test-prefix 'scheme-indent-function 1) + +;;; See the comments in gnuradio/test-suite/lib.scm for info on writing tests. +;;; See also the very end of the file, where the test-equal, test-eqv +;;; and test-eq macros are defined. + +(use-modules (gnuradio test-suite lib)) +(use-modules (gnuradio core)) +(use-modules (oop goops)) + +(define (vector-map f v) + (list->vector (map f (vector->list v)))) + +(pass-if "Guile was built with threads" (not (not (memq 'threads *features*)))) + +(with-test-prefix "connect-1" + (let* ((src-data #(-5 -4 -3 -2 -1 0 1 2 3 4 5)) + (expected-result (vector-map (lambda (x) (* x 2)) src-data)) + (tb (gr:top-block-swig "QA top block")) + (src (gr:vector-source-i src-data #f)) + (op (gr:multiply-const-ii 2)) + (dst (gr:vector-sink-i))) + + ;; using gr:ep to create endpoints + (gr:connect tb (gr:ep src 0) (gr:ep op 0)) + (gr:connect tb (gr:ep op 0) (gr:ep dst 0)) + + (gr:run tb) + ;;(pass-if (equal? expected-result (gr:data dst))) + (test-equal expected-result (gr:data dst)) + )) + +(with-test-prefix "connect-2" + (let* ((src-data #(-5 -4 -3 -2 -1 0 1 2 3 4 5)) + (expected-result (vector-map (lambda (x) (* x 2)) src-data)) + (tb (gr:top-block-swig "QA top block")) + (src (gr:vector-source-i src-data #f)) + (op (gr:multiply-const-ii 2)) + (dst (gr:vector-sink-i))) + + ;; using just blocks + (gr:connect tb src op) + (gr:connect tb op dst) + + (gr:run tb) + (test-equal expected-result (gr:data dst)))) + + +(with-test-prefix "connect-3" + (let* ((src-data #(-5 -4 -3 -2 -1 0 1 2 3 4 5)) + (expected-result (vector-map (lambda (x) (* x 2)) src-data)) + (tb (gr:top-block-swig "QA top block")) + (src (gr:vector-source-i src-data #f)) + (op (gr:multiply-const-ii 2)) + (dst (gr:vector-sink-i))) + + ;; using lists to represent endpoints + (gr:connect tb `(,src 0) `(,op 0)) + (gr:connect tb `(,op 0) `(,dst 0)) + + (gr:run tb) + (test-equal expected-result (gr:data dst)))) + + +(with-test-prefix "connect-4" + (let* ((src-data #(-5 -4 -3 -2 -1 0 1 2 3 4 5)) + (expected-result (vector-map (lambda (x) (* x 2)) src-data)) + (tb (gr:top-block-swig "QA top block")) + (src (gr:vector-source-i src-data #f)) + (op (gr:multiply-const-ii 2)) + (dst (gr:vector-sink-i))) + + ;; using multiple endpoints + (gr:connect tb src op dst) + + (gr:run tb) + (test-equal expected-result (gr:data dst)))) + +(with-test-prefix "connect-5" + (let* ((src-data #(-5 -4 -3 -2 -1 0 1 2 3 4 5)) + (expected-result (vector-map (lambda (x) (* x 2)) src-data)) + (tb (gr:top-block-swig "QA top block")) + (src (gr:vector-source-i src-data #f)) + (op (gr:multiply-const-ii 2)) + (dst (gr:vector-sink-i))) + + (pass-if-throw "bad port exception" 'swig-exception + (gr:connect tb src op (gr:ep dst 1))) + )) + +(with-test-prefix "gr_top_block::start throw" + (let* ((src-data #(-5 -4 -3 -2 -1 0 1 2 3 4 5)) + (expected-result (vector-map (lambda (x) (* x 2)) src-data)) + (tb (gr:top-block-swig "QA top block")) + (src (gr:vector-source-i src-data #f)) + (op (gr:multiply-const-ii 2)) + (dst (gr:vector-sink-i))) + + ;; We deliberately don't connect op's output + (gr:connect tb src op) + + ;; Which will lead to an exception here... + (pass-if-throw "throws std::runtime_error" 'swig-exception + (gr:run tb)) + )) + +(with-test-prefix "io-signature-1" + (let ((ios1 (gr:io-signature 1 2 8)) + (ios2 (gr:io-signature2 1 2 16 32)) + (ios3 (gr:io-signature3 1 -1 14 32 48)) + (iosv (gr:io-signaturev 1 4 '(1 2 3)))) + + (test-equal 1 (gr:min-streams ios1)) + (test-equal 2 (gr:max-streams ios1)) + (test-equal 8 (gr:sizeof-stream-item ios1 0)) + (test-equal 8 (gr:sizeof-stream-item ios1 1)) + + (test-equal 1 (gr:min-streams ios2)) + (test-equal 2 (gr:max-streams ios2)) + (test-equal 16 (gr:sizeof-stream-item ios2 0)) + (test-equal 32 (gr:sizeof-stream-item ios2 1)) + + (test-equal 1 (gr:min-streams ios3)) + (test-equal -1 (gr:max-streams ios3)) + (test-equal 14 (gr:sizeof-stream-item ios3 0)) + (test-equal 32 (gr:sizeof-stream-item ios3 1)) + (test-equal 48 (gr:sizeof-stream-item ios3 2)) + (test-equal '#(14 32 48) (gr:sizeof-stream-items ios3)) + + (test-equal 1 (gr:min-streams iosv)) + (test-equal 4 (gr:max-streams iosv)) + (test-equal 1 (gr:sizeof-stream-item iosv 0)) + (test-equal 2 (gr:sizeof-stream-item iosv 1)) + (test-equal 3 (gr:sizeof-stream-item iosv 2)) + (test-equal 3 (gr:sizeof-stream-item iosv 3)) + (test-equal '#(1 2 3) (gr:sizeof-stream-items iosv)) + )) + diff --git a/gnuradio-core/src/guile/tests/00_runtime_ctors.test b/gnuradio-core/src/guile/tests/00_runtime_ctors.test new file mode 100644 index 000000000..966d8c909 --- /dev/null +++ b/gnuradio-core/src/guile/tests/00_runtime_ctors.test @@ -0,0 +1,54 @@ +;;; -*- Scheme -*- +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; If you're using Emacs's Scheme mode: +;;; (put 'with-test-prefix 'scheme-indent-function 1) + +;;; See the comments in gnuradio/test-suite/lib.scm for info on writing tests. +;;; See also the very end of the file where the test-equal, test-eqv +;;; and test-eq macros are defined. + +(use-modules (gnuradio test-suite lib)) +(use-modules (gnuradio core)) +(use-modules (oop goops)) + +;;; Add test code for all constructors in these files +;;; +;;; ./runtime/gr_hier_block2.h + +;;; ./runtime/gr_msg_queue.h + +(define (equal-message? a b) + (equal? (gr:to-string a) (gr:to-string b))) + +(with-test-prefix "gr:message/gr:msg-queue" + (let ((msg1 (gr:message-from-string "Hello")) + (msg2 (gr:message-from-string "World!")) + (q (gr:msg-queue))) + (pass-if (equal? "Hello" (gr:to-string msg1))) + (pass-if (equal? "World!" (gr:to-string msg2))) + (pass-if (gr:empty-p q)) + (gr:insert-tail q msg1) + (pass-if (not (gr:empty-p q))) + (gr:insert-tail q msg2) + (let ((r1 (gr:delete-head q)) + (r2 (gr:delete-head q))) + (pass-if (equal-message? r1 msg1)) + (pass-if (equal-message? r2 msg2))))) diff --git a/gnuradio-core/src/guile/tests/filter_ctors.test b/gnuradio-core/src/guile/tests/filter_ctors.test new file mode 100644 index 000000000..fe1d9421d --- /dev/null +++ b/gnuradio-core/src/guile/tests/filter_ctors.test @@ -0,0 +1,245 @@ +;;; -*- Scheme -*- +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; If you're using Emacs's Scheme mode: +;;; (put 'with-test-prefix 'scheme-indent-function 1) + +;;; See the comments in gnuradio/test-suite/lib.scm for info on writing tests. +;;; See also the very end of the file, where the test-equal, test-eqv +;;; and test-eq macros are defined. + +(use-modules (gnuradio test-suite lib)) +(use-modules (gnuradio core)) +(use-modules (oop goops)) + +;;; Add test code for all constructors in these files +;;; + +;;; ./filter/gr_adaptive_fir_ccf.h WONTFIX: not wrapped +;; gr_adaptive_fir_ccf(char *name, int decimation, const std::vector<float> &taps); +;; (pass-if (true? (gr:adaptive-fir-ccf "foo" 0 #(1.0 2.0 3.0 4.0)))) + +;;; ./filter/gr_fft_filter_ccc.h +(pass-if (true? (gr:fft-filter-ccc 0 #(1+3i 23+5i)))) + +;;; ./filter/gr_fft_filter_fff.h +(pass-if (true? (gr:fft-filter-fff 0 #(1.0 2.0)))) + +;;; ./filter/gr_filter_delay_fc.h +(pass-if (true? (gr:filter-delay-fc #(1.0 2.0)))) + +;;; ./filter/gr_fir_ccc_generic. FIXME: Unbound variable: ~S" (gr:fir-ccc-generic) #f)) +;; (pass-if (true? (gr:fir-ccc-generic))) +;; (pass-if (true? (gr:fir-ccc-generic #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_ccc_simd.h FIXME: not found +;; (pass-if (true? (gr:fir-ccc-simd))) +;; (pass-if (true? (gr:fir-ccc-simd #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_ccc_x86.h FIXME: not found +;; (pass-if (true? (gr:fir-ccc-x86))) +;; (pass-if (true? (gr:fir-ccc-x86 #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_ccf_generic.h FIXME: not found +;; (pass-if (true? (gr:fir-ccf-generic))) +;; (pass-if (true? (gr:fir-ccf-generic #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_ccf_simd.h FIXME: not found +;; (pass-if (true? (gr:fir-ccf-simd 0 0 0 0))) + +;;; ./filter/gr_fir_ccf_x86.h FIXME: not found +;; (pass-if (true? (gr:fir-ccf-x86))) +;; (pass-if (true? (gr:fir-ccf-x86 #(1.0 2.0)))) + +;;; ./filter/gr_fir_fcc_generic.h FIXME: not found +;; (pass-if (true? (gr:fir-fcc-generic))) +;; (pass-if (true? (gr:fir-fcc-generic #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_fcc_simd.h FIXME: not found +;; (pass-if (true? (gr:fir-fcc-simd 0 0 0 0))) + +;;; ./filter/gr_fir_fcc_x86.h FIXME: not found +;; (pass-if (true? (gr:fir-fcc-x86))) +;; (pass-if (true? (gr:fir-fcc-x86 #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_fff_altivec.h FIXME: not found +;; (pass-if (true? (gr:fir-fff-altivec))) +;; (pass-if (true? (gr:fir-fff-altivec #(1.0 2.0)))) + +;;; ./filter/gr_fir_fff_armv7_a.h FIXME: not found +;; (pass-if (true? (gr:fir-fff-armv7-a))) +;; (pass-if (true? (gr:fir-fff-armv7-a #(1.0 2.0)))) + +;;; ./filter/gr_fir_fff_generic.h FIXME: not found +;; (pass-if (true? (gr:fir-fff-generic))) +;; (pass-if (true? (gr:fir-fff-generic #(1.0 2.0)))) + +;;; ./filter/gr_fir_fff_simd.h FIXME: not found +;; (pass-if (true? (gr:fir-fff-simd 0 0 0))) + +;;; ./filter/gr_fir_fff_x86.h FIXME: not found +;; (pass-if (true? (gr:fir-fff-x86))) +;; (pass-if (true? (gr:fir-fff-x86 #(1.0 2.0)))) + +;;; ./filter/gr_fir_filter_ccc.h FIXME: not found +;; (pass-if (true? (gr:fir-filter-ccc 1 #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_filter_ccf.h +(pass-if (true? (gr:fir-filter-ccf 1 #(1.0 2.0)))) + +;;; ./filter/gr_fir_filter_fcc.h +(pass-if (true? (gr:fir-filter-fcc 1 #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_filter_fff.h +(pass-if (true? (gr:fir-filter-fff 1 #(1.0 2.0)))) + +;;; ./filter/gr_fir_filter_fsf.h +(pass-if (true? (gr:fir-filter-fsf 1 #(1.0 2.0)))) + +;;; ./filter/gr_fir_filter_scc.h +(pass-if (true? (gr:fir-filter-scc 1 #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_fsf_generic.h FIXME: "Unbound variable: ~S" (gr:fir-fsf-generic) #f)) +;; (pass-if (true? (gr:fir-fsf-generic))) +;; (pass-if (true? (gr:fir-fsf-generic #(1.0 2.0)))) + +;;; ./filter/gr_fir_fsf_simd.h FIXME: not found +;; (pass-if (true? (gr:fir-fsf-simd 0 0 0))) + +;;; ./filter/gr_fir_fsf_x86.h FIXME: "Unbound variable: ~S" (gr:fir-fsf-x86) #f)) +;; (pass-if (true? (gr:fir-fsf-x86))) +;; (pass-if (true? (gr:fir-fsf-x86 #(1.0 2.0)))) + +;;; ./filter/gr_fir_scc_generic.h FIXME: file not found +;; (pass-if (true? (gr:fir-scc-generic))) +;; (pass-if (true? (gr:fir-scc-generic #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_scc_simd.h FIXME: Unbound variable: ~S" (gr:fir-scc-simd) #f)) +;; (pass-if (true? (gr:fir-scc-simd))) +;; (pass-if (true? (gr:fir-scc-simd #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_scc_x86.h FIXME: "Unbound variable: ~S" (gr:fir-scc-x86) #f)) +;; (pass-if (true? (gr:fir-scc-x86))) +;; (pass-if (true? (gr:fir-scc-x86 #(1+3i 23+5i)))) + +;;; ./filter/gr_fir_sysconfig_armv7_a.h FIXME: virtual methods +;; (pass-if (true? (gr:fir-sysconfig-armv7-a ))) + +;;; ./filter/gr_fir_sysconfig_generic.h FIXME: virtual methods +;; (pass-if (true? (gr:fir-sysconfig-generic ))) + +;;; ./filter/gr_fir_sysconfig_powerpc.h FIXME: virtual methods +;; (pass-if (true? (gr:fir-sysconfig-powerpc ))) + +;;; ./filter/gr_fir_sysconfig_x86.h FIXME: virtual methods +;; (pass-if (true? (gr:fir-sysconfig-x86 #(1+3i 23+5i)))) + +;;; ./filter/gr_fractional_interpolator_cc.h +(pass-if (true? (gr:fractional-interpolator-cc 1.0 1.0))) + +;;; ./filter/gr_fractional_interpolator_ff.h +(pass-if (true? (gr:fractional-interpolator-ff 1.0 1.0))) + +;;; ./filter/gr_freq_xlating_fir_filter_ccc.h +(pass-if (true? (gr:freq-xlating-fir-filter-ccc 1 #(1+3i 23+5i) 1.0 1.0))) + +;;; ./filter/gr_freq_xlating_fir_filter_ccf.h +(pass-if (true? (gr:freq-xlating-fir-filter-ccf 1 #(1.0 2.0) 1.0 1.0))) + +;;; ./filter/gr_freq_xlating_fir_filter_fcc.h +(pass-if (true? (gr:freq-xlating-fir-filter-fcc 1 #(1.0 2.0) 1.0 1.0))) + +;;; ./filter/gr_freq_xlating_fir_filter_fcf.h +(pass-if (true? (gr:freq-xlating-fir-filter-fcf 1 #(1.0 2.0) 1.0 1.0))) + +;;; ./filter/gr_freq_xlating_fir_filter_scc.h +(pass-if (true? (gr:freq-xlating-fir-filter-scc 1 #(1.0 2.0) 1.0 1.0))) + +;;; ./filter/gr_freq_xlating_fir_filter_scf.h +(pass-if (true? (gr:freq-xlating-fir-filter-scf 1 #(1.0 2.0) 1.0 1.0))) + +;;; ./filter/gr_goertzel_fc.h +(pass-if (true? (gr:goertzel-fc 1 1 1))) + +;;; ./filter/gr_hilbert_fc.h +(pass-if (true? (gr:hilbert-fc 1))) + +;;; ./filter/gr_iir_filter_ffd.h +(pass-if (true? (gr:iir-filter-ffd #(1.0 2.0) #(1.0 2.0)))) + +;;; ./filter/gr_interp_fir_filter_ccc.h FIXME: not found +;; (pass-if (true? (gr:interp-fir-filter-ccc #(1+3i 23+5i)))) + +;;; ./filter/gr_interp_fir_filter_ccf.h FIXME: not found +;; (pass-if (true? (gr:interp-fir-filter-ccf ))) + +;;; ./filter/gr_interp_fir_filter_fcc.h FIXME: not found +;; (pass-if (true? (gr:interp-fir-filter-fcc ))) + +;;; ./filter/gr_interp_fir_filter_fff.h FIXME: not found +;; (pass-if (true? (gr:interp-fir-filter-fff ))) + +;;; ./filter/gr_interp_fir_filter_fsf.h FIXME: not found +;; (pass-if (true? (gr:interp-fir-filter-fsf ))) + +;;; ./filter/gr_interp_fir_filter_scc.h FIXME: not found +;; (pass-if (true? (gr:interp-fir-filter-scc ))) + +;;; ./filter/gr_pfb_arb_resampler_ccf.h +(pass-if (true? (gr:pfb-arb-resampler-ccf 1.0 #(1.0 2.0) 32))) + +;;; ./filter/gr_pfb_channelizer_ccf.h +(pass-if (true? (gr:pfb-channelizer-ccf 1 #(1.0 2.0) 1))) + +;;; ./filter/gr_pfb_clock_sync_ccf.h +(pass-if (true? (gr:pfb-clock-sync-ccf 1.0 1.0 #(1.0 2.0) 32 0 1.5))) + +;;; ./filter/gr_pfb_clock_sync_fff.h +(pass-if (true? (gr:pfb-clock-sync-fff 1.0 1.0 #(1.0 2.0) 32 0 1.5))) + +;;; ./filter/gr_pfb_decimator_ccf.h +(pass-if (true? (gr:pfb-decimator-ccf 1 #(1.0 2.0) 0))) + +;;; ./filter/gr_pfb_interpolator_ccf.h +(pass-if (true? (gr:pfb-interpolator-ccf 1 #(1.0 2.0)))) + +;;; ./filter/gr_rational_resampler_base_ccc.h FIXME: not found +;; (pass-if (true? (gr:rational-resampler-base-ccc 1 1 #(1+3i 23+5i)))) + +;;; ./filter/gr_rational_resampler_base_ccf.h FIXME: not found +;; (pass-if (true? (gr:rational-resampler-base-ccf ))) + +;;; ./filter/gr_rational_resampler_base_fcc.h FIXME: not found +;; (pass-if (true? (gr:rational-resampler-base-fcc ))) + +;;; ./filter/gr_rational_resampler_base_fff.h FIXME: not found +;; (pass-if (true? (gr:rational-resampler-base-fff ))) + +;;; ./filter/gr_rational_resampler_base_fsf.h FIXME: not found +;; (pass-if (true? (gr:rational-resampler-base-fsf ))) + +;;; ./filter/gr_rational_resampler_base_scc.h FIXME: not found +;; (pass-if (true? (gr:rational-resampler-base-scc ))) + +;;; ./filter/gr_single_pole_iir_filter_cc.h +(pass-if (true? (gr:single-pole-iir-filter-cc 1.0 1))) + +;;; ./filter/gr_single_pole_iir_filter_ff.h +(pass-if (true? (gr:single-pole-iir-filter-ff 1.0 1))) diff --git a/gnuradio-core/src/guile/tests/general_ctors.test b/gnuradio-core/src/guile/tests/general_ctors.test new file mode 100644 index 000000000..a0e39855c --- /dev/null +++ b/gnuradio-core/src/guile/tests/general_ctors.test @@ -0,0 +1,370 @@ +;;; -*- Scheme -*- +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; If you're using Emacs's Scheme mode: +;;; (put 'with-test-prefix 'scheme-indent-function 1) + +;;; See the comments in gnuradio/test-suite/lib.scm for info on writing tests. +;;; See also the very end of the file, where the test-equal, test-eqv +;;; and test-eq macros are defined. + +(use-modules (gnuradio test-suite lib)) +(use-modules (gnuradio core)) +(use-modules (oop goops)) +(use-modules (ice-9 format)) + + +;;; Test complex<float> scalars +(pass-if (equal? 5.0+5.0i (gr:complex-scalar-test0))) +(pass-if (equal? 1.5+0.5i (gr:complex-scalar-test1 1+1i))) + +;;; Test complex<float> vectors +(pass-if (verbose-equal? #(0+0i 1+1i 2+2i 3+3i 4+4i) + (gr:complex-vec-test0))) + +(pass-if (verbose-equal? #(1.5+0.5i 2.5+1.5i 3.5+2.5i) + (gr:complex-vec-test1 #(1+1i 2+2i 3+3i)))) + + +;;; Add test code for all constructors in these files + +;;; ./general/gr_additive_scrambler_bb.h +(pass-if (true? (gr:additive-scrambler-bb 0 0 0 0))) + +;; Here's one that will throw if its arg is 0 +(pass-if (true? (gr:unpack-k-bits-bb 10))) +(pass-if-throw "confirm throw gr:unpack-k-bits-bb" #t (true? (gr:unpack-k-bits-bb 0))) + +;;; ./general/gr_agc2_cc.h +(pass-if (true? (gr:agc2-cc 1e-1 1e-2 1.0 1.0 0.0))) + +;;; ./general/gr_agc2_ff.h +(pass-if (true? (gr:agc2-ff 0 0 0 0 0))) + +;;; ./general/gr_agc_cc.h +(pass-if (true? (gr:agc-cc 0 0 0 0))) + +;;; ./general/gr_agc_ff.h +(pass-if (true? (gr:agc-ff 0 0 0 0))) + +;;; ./general/gr_align_on_samplenumbers_ss.h +(pass-if (true? (gr:align-on-samplenumbers-ss 2 128))) +(pass-if-throw "confirm throw gr:align-on-samplenumbers-ss" #t (true? (gr:align-on-samplenumbers-ss 0 0))) + +;;; ./general/gr_bin_statistics_f.h WONTFIX: requires gr_feval_dd & swig directors +;;;(pass-if (true? (gr:bin-statistics-f 1 (gr:msg-queue) 0 0 0))) + +;;; ./general/gr_bytes_to_syms.h +(pass-if (true? (gr:bytes-to-syms))) + +;;; ./general/gr_char_to_float.h +(pass-if (true? (gr:char-to-float))) + +;;; ./general/gr_check_counting_s.h +(pass-if (true? (gr:check-counting-s #f))) + +;;; ./general/gr_check_lfsr_32k_s.h +(pass-if (true? (gr:check-lfsr-32k-s))) + +;;; ./general/gr_complex_to_interleaved_short.h +(pass-if (true? (gr:complex-to-interleaved-short))) + +;;; ./general/gr_complex_to_xxx.h +(pass-if (true? (gr:complex-to-float 1))) +(pass-if (true? (gr:complex-to-real 1))) +(pass-if (true? (gr:complex-to-imag 1))) +(pass-if (true? (gr:complex-to-mag 1))) +(pass-if (true? (gr:complex-to-mag-squared 1))) +(pass-if (true? (gr:complex-to-arg 1))) + +;;; ./general/gr_conjugate_cc.h +(pass-if (true? (gr:conjugate-cc))) + +;;; ./general/gr_copy.h +(pass-if (true? (gr:copy 1))) + +;;; ./general/gr_cpfsk_bc.h +(pass-if (true? (gr:cpfsk-bc 1 1 1))) + +;;; ./general/gr_ctcss_squelch_ff.h +(pass-if (true? (gr:ctcss-squelch-ff 0 0 0 0 0 #t))) + +;;; ./general/gr_decode_ccsds_27_fb.h +(pass-if (true? (gr:decode-ccsds-27-fb))) + +;;; ./general/gr_deinterleave.h +(pass-if (true? (gr:deinterleave 1))) + +;;; ./general/gr_delay.h +(pass-if (true? (gr:delay 1 1))) + +;;; ./general/gr_descrambler_bb.h +(pass-if (true? (gr:descrambler-bb 0 0 0))) + +;;; ./general/gr_diff_decoder_bb.h +(pass-if (true? (gr:diff-decoder-bb 0))) + +;;; ./general/gr_diff_encoder_bb.h +(pass-if (true? (gr:diff-encoder-bb 0))) + +;;; ./general/gr_diff_phasor_cc.h +(pass-if (true? (gr:diff-phasor-cc))) + +;;; ./general/gr_dpll_bb.h +(pass-if (true? (gr:dpll-bb 0 0))) + +;;; ./general/gr_encode_ccsds_27_bb.h +(pass-if (true? (gr:encode-ccsds-27-bb))) + +;;; ./general/gr_fake_channel_coder_pp.h +(pass-if (true? (gr:fake-channel-encoder-pp 1 1))) +(pass-if-throw "confirm throw" #t (true? (gr:fake-channel-encoder-pp -1 1))) + +;;; ./general/gr_feedforward_agc_cc.h +(pass-if (true? (gr:feedforward-agc-cc 1 1))) + +;;; ./general/gr_fft_vcc.h +(pass-if (true? (gr:fft-vcc 1 #f #(1.0 2.0) #t))) + +;;; ./general/gr_fft_vfc.h +(pass-if (true? (gr:fft-vfc 4 #t #(1.0 2.0 3.0 4.0)))) +(pass-if-throw "confirm throw gr:fft-vfc" #t (true? (gr:fft-vfc 4 #f #(1.0 2.0 3.0 4.0)))) + +;; ;;; ./general/gr_float_to_char.h +(pass-if (true? (gr:float-to-char))) + +;; ;;; ./general/gr_float_to_complex.h +(pass-if (true? (gr:float-to-complex 1))) + +;;; ./general/gr_float_to_short.h +(pass-if (true? (gr:float-to-short))) + +;;; ./general/gr_float_to_uchar.h +(pass-if (true? (gr:float-to-uchar))) + +;;; ./general/gr_fmdet_cf.h +(pass-if (true? (gr:fmdet-cf 0 0 0 0))) + +;;; ./general/gr_framer_sink_1.h +(pass-if (true? (gr:framer-sink-1 (gr:msg-queue)))) + +;;; ./general/gr_frequency_modulator_fc.h +(pass-if (true? (gr:frequency-modulator-fc 0))) + +;;; ./general/gr_glfsr_source_b.h +(pass-if (true? (gr:glfsr-source-b 1 #t 0 1))) +(pass-if-throw "confirm throw" #t (true? (gr:glfsr_source_b 33 #t 0 0))) + +;;; ./general/gr_glfsr_source_f.h +(pass-if (true? (gr:glfsr-source-f 1 #t 1 1))) +(pass-if-throw "confirm throw" #t (true? (gr:glfsr_source_f 33 #t 0 0))) + +;;; ./general/gr_head.h +(pass-if (true? (gr:head 1 1))) + +;;; ./general/gr_interleave.h +(pass-if (true? (gr:interleave 1))) + +;;; ./general/gr_interleaved_short_to_complex.h +(pass-if (true? (gr:interleaved-short-to-complex))) + +;;; ./general/gr_keep_one_in_n.h +(pass-if (true? (gr:keep-one-in-n 1 1))) + +;;; ./general/gr_kludge_copy.h +(pass-if (true? (gr:kludge-copy 1))) + +;;; ./general/gr_lfsr_32k_source_s.h +(pass-if (true? (gr:lfsr-32k-source-s))) + +;;; ./general/gr_map_bb.h +(pass-if (true? (gr:map-bb #(1 2)))) + +;;; ./general/gr_nlog10_ff.h +(pass-if (true? (gr:nlog10-ff 1 1 1))) + +;;; ./general/gr_nop.h +(pass-if (true? (gr:nop 1))) + +;;; ./general/gr_null_sink.h +(pass-if (true? (gr:null-sink 1))) + +;;; ./general/gr_null_source.h +(pass-if (true? (gr:null-source 1))) + +;;; ./general/gr_ofdm_cyclic_prefixer.h +(pass-if (true? (gr:ofdm-cyclic-prefixer 1 1))) + +;;; ./general/gr_ofdm_frame_acquisition.h +(pass-if (true? (gr:ofdm-frame-acquisition 1 1 1 #(1+3i 23+5i) 1))) + +;;; ./general/gr_ofdm_frame_sink.h +(pass-if (true? (gr:ofdm-frame-sink #(1+3i 23+5i) #(0 1) (gr:msg-queue) 128 0.25 0))) + +;;; ./general/gr_ofdm_insert_preamble.h FIXME: "Wrong type argument in position ~A: ~S" +;;; WONTFIX: Need vector<vector<complex<float>>> +;;(pass-if (true? (gr:ofdm-insert-preamble 2 #(#(1+3i 23+5i) #(1+3i 23+5i))))) + +;;; ./general/gr_ofdm_mapper_bcv.h +(pass-if (true? (gr:ofdm-mapper-bcv #(0+1i 0-1i) 1 100 128))) +(pass-if-throw "confirm throw gr:ofdm-mapper-bcv" #t + (true? (gr:ofdm-mapper-bcv #(0+1i 0-1i) 1 10 128))) + + +;;; ./general/gr_ofdm_sampler.h +(pass-if (true? (gr:ofdm-sampler 1 1 1))) + +;;; ./general/gr_pa_2x2_phase_combiner.h +(pass-if (true? (gr:pa-2x2-phase-combiner))) + +;;; ./general/gr_packet_sink.h +(pass-if (true? (gr:packet-sink #(1 2) (gr:msg-queue) -1))) + +;;; ./general/gr_peak_detector2_fb.h +(pass-if (true? (gr:peak-detector2-fb 0 0 0))) + +;;; ./general/gr_phase_modulator_fc.h +(pass-if (true? (gr:phase-modulator-fc 0))) + +;;; ./general/gr_pll_carriertracking_cc.h +(pass-if (true? (gr:pll-carriertracking-cc 0 0 0))) + +;;; ./general/gr_pll_freqdet_cf.h +(pass-if (true? (gr:pll-freqdet-cf 0 0 0))) + +;;; ./general/gr_pll_refout_cc.h +(pass-if (true? (gr:pll-refout-cc 0 0 0))) + +;;; ./general/gr_pn_correlator_cc.h +(pass-if (true? (gr:pn-correlator-cc 1 1 1))) + +;;; ./general/gr_probe_avg_mag_sqrd_c.h +(pass-if (true? (gr:probe-avg-mag-sqrd-c 0 0))) + +;;; ./general/gr_probe_avg_mag_sqrd_cf.h +(pass-if (true? (gr:probe-avg-mag-sqrd-cf 0 0))) + +;;; ./general/gr_probe_avg_mag_sqrd_f.h +(pass-if (true? (gr:probe-avg-mag-sqrd-f 0 0))) + +;;; ./general/gr_probe_density_b.h +(pass-if (true? (gr:probe-density-b 0))) + +;;; ./general/gr_probe_mpsk_snr_c.h +(pass-if (true? (gr:probe-mpsk-snr-c 0))) + +;;; ./general/gr_probe_signal_f.h +(pass-if (true? (gr:probe-signal-f))) + +;;; ./general/gr_pwr_squelch_cc.h +(pass-if (true? (gr:pwr-squelch-cc 0 0 0 #f))) + +;;; ./general/gr_pwr_squelch_ff.h +(pass-if (true? (gr:pwr-squelch-ff 0.0 0.0 0 #f))) + +;;; ./general/gr_quadrature_demod_cf.h +(pass-if (true? (gr:quadrature-demod-cf 0))) + +;;; ./general/gr_rail_ff.h +(pass-if (true? (gr:rail-ff 0 0))) + +;;; ./general/gr_regenerate_bb.h +(pass-if (true? (gr:regenerate-bb 0 0))) + +;;; ./general/gr_repeat.h +(pass-if (true? (gr:repeat 1 1))) + +;;; ./general/gr_rms_cf.h +(pass-if (true? (gr:rms-cf 0))) + +;;; ./general/gr_rms_ff.h +(pass-if (true? (gr:rms-ff 0))) + +;;; ./general/gr_scrambler_bb.h +(pass-if (true? (gr:scrambler-bb 0 0 0))) + +;;; ./general/gr_short_to_float.h +(pass-if (true? (gr:short-to-float))) + +;;; ./general/gr_simple_correlator.h +(pass-if (true? (gr:simple-correlator 0))) + +;;; ./general/gr_simple_framer.h +(pass-if (true? (gr:simple-framer 0))) + +;;; ./general/gr_simple_squelch_cc.h +(pass-if (true? (gr:simple-squelch-cc 0 0))) + +;;; ./general/gr_skiphead.h +(pass-if (true? (gr:skiphead 1 1))) + +;;; ./general/gr_squash_ff.h +(pass-if (true? (gr:squash-ff #(1.0 2.0 3.0 4.0 5.0) #(1.0 2.0 3.0 4.0 5.0)))) + +;;; ./general/gr_squelch_base_cc.h WONTFIX: not wrapped +;;; (pass-if (true? (gr:squelch-base-cc "foo" 0 #f))) + +;;; ./general/gr_squelch_base_ff.h WONTFIX: not wrapped +;; (pass-if (true? (gr:squelch-base-ff "foo" 0 #f))) + +;;; ./general/gr_stream_mux.h +(pass-if (true? (gr:stream-mux 1 #(1 2)))) + +;;; ./general/gr_stream_to_streams.h +(pass-if (true? (gr:stream-to-streams 1 1))) + +;;; ./general/gr_stream_to_vector.h +(pass-if (true? (gr:stream-to-vector 1 1))) + +;;; ./general/gr_streams_to_stream.h +(pass-if (true? (gr:streams-to-stream 1 1))) + +;;; ./general/gr_streams_to_vector.h +(pass-if (true? (gr:streams-to-vector 1 1))) + +;;; ./general/gr_stretch_ff.h +(pass-if (true? (gr:stretch-ff 1 1))) + +;;; ./general/gr_test.h +(pass-if (true? (gr:test "foo" 1 1 1 1 1 1 1 1))) + +;;; ./general/gr_threshold_ff.h +(pass-if (true? (gr:threshold-ff 0 0))) + +;;; ./general/gr_throttle.h +(pass-if (true? (gr:throttle 1 1))) + +;;; ./general/gr_uchar_to_float.h +(pass-if (true? (gr:uchar-to-float))) + +;;; ./general/gr_vco_f.h +(pass-if (true? (gr:vco-f 0 0 0))) + +;;; ./general/gr_vector_to_stream.h +(pass-if (true? (gr:vector-to-stream 1 1))) + +;;; ./general/gr_vector_to_streams.h +(pass-if (true? (gr:vector-to-streams 1 1))) + +;;; ./general/gr_wavelet_ff.h +(pass-if (true? (gr:wavelet-ff 1024 20 #t))) + +;;; ./general/gr_wvps_ff.h +(pass-if (true? (gr:wvps-ff 2))) diff --git a/gnuradio-core/src/guile/tests/gengen_ctors.test b/gnuradio-core/src/guile/tests/gengen_ctors.test new file mode 100644 index 000000000..6e1213c63 --- /dev/null +++ b/gnuradio-core/src/guile/tests/gengen_ctors.test @@ -0,0 +1,342 @@ +;;; -*- Scheme -*- +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; If you're using Emacs's Scheme mode: +;;; (put 'with-test-prefix 'scheme-indent-function 1) + +;;; See the comments in gnuradio/test-suite/lib.scm for info on writing tests. +;;; See also the very end of the file, where the test-equal, test-eqv +;;; and test-eq macros are defined. + +(use-modules (gnuradio test-suite lib)) +(use-modules (gnuradio core)) +(use-modules (oop goops)) + +;;; Add test code for all constructors in these files +;;; + +;;; ./gengen/gr_add_cc.h +(pass-if (true? (gr:add-cc 1))) + +;;; ./gengen/gr_add_const_cc.h +(pass-if (true? (gr:add-const-cc 0))) + +;;; ./gengen/gr_add_const_ff.h +(pass-if (true? (gr:add-const-ff 0))) + +;;; ./gengen/gr_add_const_ii.h +(pass-if (true? (gr:add-const-ii 0))) + +;;; ./gengen/gr_add_const_sf.h +(pass-if (true? (gr:add-const-sf 0))) + +;;; ./gengen/gr_add_const_ss.h +(pass-if (true? (gr:add-const-ss 0))) + +;;; ./gengen/gr_add_const_vcc.h +(pass-if (true? (gr:add-const-vcc #(1+3i 23+5i)))) + +;;; ./gengen/gr_add_const_vff.h +(pass-if (true? (gr:add-const-vff #(1.0 2.0)))) + +;;; ./gengen/gr_add_const_vii.h +(pass-if (true? (gr:add-const-vii #(1 2)))) + +;;; ./gengen/gr_add_const_vss.h +(pass-if (true? (gr:add-const-vss #(1 2)))) + +;;; ./gengen/gr_add_ff.h +(pass-if (true? (gr:add-ff 1))) + +;;; ./gengen/gr_add_ii.h +(pass-if (true? (gr:add-ii 1))) + +;;; ./gengen/gr_add_ss.h +(pass-if (true? (gr:add-ss 1))) + +;;; ./gengen/gr_and_bb.h +(pass-if (true? (gr:and-bb))) + +;;; ./gengen/gr_and_const_bb.h +(pass-if (true? (gr:and-const-bb 0))) + +;;; ./gengen/gr_and_const_ii.h +(pass-if (true? (gr:and-const-ii 0))) + +;;; ./gengen/gr_and_const_ss.h +(pass-if (true? (gr:and-const-ss 0))) + +;;; ./gengen/gr_and_ii.h +(pass-if (true? (gr:and-ii))) + +;;; ./gengen/gr_and_ss.h +(pass-if (true? (gr:and-ss))) + +;;; ./gengen/gr_argmax_fs.h +(pass-if (true? (gr:argmax-fs 1))) + +;;; ./gengen/gr_argmax_is.h +(pass-if (true? (gr:argmax-is 1))) + +;;; ./gengen/gr_argmax_ss.h +(pass-if (true? (gr:argmax-ss 1))) + +;;; ./gengen/gr_chunks_to_symbols_bc.h +(pass-if (true? (gr:chunks-to-symbols-bc #(1+3i 23+5i) 1))) + +;;; ./gengen/gr_chunks_to_symbols_bf.h +(pass-if (true? (gr:chunks-to-symbols-bf #(1.0 2.0) 1))) + +;;; ./gengen/gr_chunks_to_symbols_ic.h +(pass-if (true? (gr:chunks-to-symbols-ic #(1+3i 23+5i) 1))) + +;;; ./gengen/gr_chunks_to_symbols_if.h +(pass-if (true? (gr:chunks-to-symbols-if #(1.0 2.0) 1))) + +;;; ./gengen/gr_chunks_to_symbols_sc.h +(pass-if (true? (gr:chunks-to-symbols-sc #(1.0 2.0) 1))) + +;;; ./gengen/gr_chunks_to_symbols_sf.h +(pass-if (true? (gr:chunks-to-symbols-sf #(1.0 2.0) 1))) + +;;; ./gengen/gr_divide_cc.h +(pass-if (true? (gr:divide-cc 1))) + +;;; ./gengen/gr_divide_ff.h +(pass-if (true? (gr:divide-ff 1))) + +;;; ./gengen/gr_divide_ii.h +(pass-if (true? (gr:divide-ii 1))) + +;;; ./gengen/gr_divide_ss.h +(pass-if (true? (gr:divide-ss 1))) + +;;; ./gengen/gr_integrate_cc.h +(pass-if (true? (gr:integrate-cc 0))) + +;;; ./gengen/gr_integrate_ff.h +(pass-if (true? (gr:integrate-ff 0))) + +;;; ./gengen/gr_integrate_ii.h +(pass-if (true? (gr:integrate-ii 0))) + +;;; ./gengen/gr_integrate_ss.h +(pass-if (true? (gr:integrate-ss 0))) + +;;; ./gengen/gr_max_ff.h +(pass-if (true? (gr:max-ff 1))) + +;;; ./gengen/gr_max_ii.h +(pass-if (true? (gr:max-ii 1))) + +;;; ./gengen/gr_max_ss.h +(pass-if (true? (gr:max-ss 1))) + +;;; ./gengen/gr_moving_average_cc.h +(pass-if (true? (gr:moving-average-cc 1 1+3i 4096))) + +;;; ./gengen/gr_moving_average_ff.h +(pass-if (true? (gr:moving-average-ff 1 0 4096))) + +;;; ./gengen/gr_moving_average_ii.h +(pass-if (true? (gr:moving-average-ii 1 0 4096))) + +;;; ./gengen/gr_moving_average_ss.h +(pass-if (true? (gr:moving-average-ss 1 0 4096))) + +;;; ./gengen/gr_multiply_cc.h +(pass-if (true? (gr:multiply-cc 1))) + +;;; ./gengen/gr_multiply_const_cc.h +(pass-if (true? (gr:multiply-const-cc 1))) + +;;; ./gengen/gr_multiply_const_ff.h +(pass-if (true? (gr:multiply-const-ff 1))) + +;;; ./gengen/gr_multiply_const_ii.h +(pass-if (true? (gr:multiply-const-ii 1))) + +;;; ./gengen/gr_multiply_const_ss.h +(pass-if (true? (gr:multiply-const-ss 1))) + +;;; ./gengen/gr_multiply_const_vcc.h +(pass-if (true? (gr:multiply-const-vcc #(1+3i 23+5i)))) + +;;; ./gengen/gr_multiply_const_vff.h +(pass-if (true? (gr:multiply-const-vff #(1.0 2.0)))) + +;;; ./gengen/gr_multiply_const_vii.h +(pass-if (true? (gr:multiply-const-vii #(1 2)))) + +;;; ./gengen/gr_multiply_const_vss.h +(pass-if (true? (gr:multiply-const-vss #(1 2)))) + +;;; ./gengen/gr_multiply_ff.h +(pass-if (true? (gr:multiply-ff 1))) + +;;; ./gengen/gr_multiply_ii.h +(pass-if (true? (gr:multiply-ii 1))) + +;;; ./gengen/gr_multiply_ss.h +(pass-if (true? (gr:multiply-ss 1))) + +;;; ./gengen/gr_mute_cc.h FIXME: not found +(pass-if (true? (gr:mute-cc #f))) + +;;; ./gengen/gr_mute_ff.h FIXME: not found +(pass-if (true? (gr:mute-ff #f))) + +;;; ./gengen/gr_mute_ii.h FIXME: not found +(pass-if (true? (gr:mute-ii #f))) + +;;; ./gengen/gr_mute_ss.h FIXME: not found +(pass-if (true? (gr:mute-ss #f))) + +;;; ./gengen/gr_noise_source_c.h +(pass-if (true? (gr:noise-source-c 1 0 3021))) + +;;; ./gengen/gr_noise_source_f.h +(pass-if (true? (gr:noise-source-f 1 0 3021))) + +;;; ./gengen/gr_noise_source_i.h +(pass-if (true? (gr:noise-source-i 1 0 3021))) + +;;; ./gengen/gr_noise_source_s.h +(pass-if (true? (gr:noise-source-s 1 0 3021))) + +;;; ./gengen/gr_not_bb.h +(pass-if (true? (gr:not-bb))) + +;;; ./gengen/gr_not_ii.h +(pass-if (true? (gr:not-ii))) + +;;; ./gengen/gr_not_ss.h +(pass-if (true? (gr:not-ss))) + +;;; ./gengen/gr_or_bb.h +(pass-if (true? (gr:or-bb))) + +;;; ./gengen/gr_or_ii.h +(pass-if (true? (gr:or-ii))) + +;;; ./gengen/gr_or_ss.h +(pass-if (true? (gr:or-ss))) + +;;; ./gengen/gr_packed_to_unpacked_bb.h +(pass-if (true? (gr:packed-to-unpacked-bb 1 1))) + +;;; ./gengen/gr_packed_to_unpacked_ii.h +(pass-if (true? (gr:packed-to-unpacked-ii 1 1))) + +;;; ./gengen/gr_packed_to_unpacked_ss.h +(pass-if (true? (gr:packed-to-unpacked-ss 1 1))) + +;;; ./gengen/gr_peak_detector_fb.h +(pass-if (true? (gr:peak-detector-fb 0.25 0.40 10 0.001))) + +;;; ./gengen/gr_peak_detector_ib.h +(pass-if (true? (gr:peak-detector-ib 0.25 0.40 10 0.001))) + +;;; ./gengen/gr_peak_detector_sb.h +(pass-if (true? (gr:peak-detector-sb 0.25 0.40 10 0.001))) + +;;; ./gengen/gr_sample_and_hold_bb.h +(pass-if (true? (gr:sample-and-hold-bb))) + +;;; ./gengen/gr_sample_and_hold_ff.h +(pass-if (true? (gr:sample-and-hold-ff))) + +;;; ./gengen/gr_sample_and_hold_ii.h +(pass-if (true? (gr:sample-and-hold-ii))) + +;;; ./gengen/gr_sample_and_hold_ss.h +(pass-if (true? (gr:sample-and-hold-ss))) + +;;; ./gengen/gr_sig_source_c.h +(pass-if (true? (gr:sig-source-c 0 0 0 0 0))) + +;;; ./gengen/gr_sig_source_f.h +(pass-if (true? (gr:sig-source-f 0 0 0 0 0))) + +;;; ./gengen/gr_sig_source_i.h +(pass-if (true? (gr:sig-source-i 0 0 0 0 0))) + +;;; ./gengen/gr_sig_source_s.h +(pass-if (true? (gr:sig-source-s 0 0 0 0 0))) + +;;; ./gengen/gr_sub_cc.h +(pass-if (true? (gr:sub-cc 1))) + +;;; ./gengen/gr_sub_ff.h +(pass-if (true? (gr:sub-ff 1))) + +;;; ./gengen/gr_sub_ii.h +(pass-if (true? (gr:sub-ii 1))) + +;;; ./gengen/gr_sub_ss.h +(pass-if (true? (gr:sub-ss 1))) + +;;; ./gengen/gr_unpacked_to_packed_bb.h +(pass-if (true? (gr:unpacked-to-packed-bb 1 1))) + +;;; ./gengen/gr_unpacked_to_packed_ii.h +(pass-if (true? (gr:unpacked-to-packed-ii 1 1))) + +;;; ./gengen/gr_unpacked_to_packed_ss.h +(pass-if (true? (gr:unpacked-to-packed-ss 1 1))) + +;;; ./gengen/gr_vector_sink_b.h +(pass-if (true? (gr:vector-sink-b 1))) + +;;; ./gengen/gr_vector_sink_c.h +(pass-if (true? (gr:vector-sink-c 1))) + +;;; ./gengen/gr_vector_sink_f.h +(pass-if (true? (gr:vector-sink-f 1))) + +;;; ./gengen/gr_vector_sink_i.h +(pass-if (true? (gr:vector-sink-i 1))) + +;;; ./gengen/gr_vector_sink_s.h +(pass-if (true? (gr:vector-sink-s 1))) + +;;; ./gengen/gr_vector_source_b.h +;; (pass-if (true? (gr:vector-source-b #(1 2) #f 1))) + +;; ;;; ./gengen/gr_vector_source_c.h +;; (pass-if (true? (gr:vector-source-c #(1+3i 23+5i) #f 1))) + +;; ;;; ./gengen/gr_vector_source_f.h +;; (pass-if (true? (gr:vector-source-f #(1.0 2.0) #f 1))) + +;;; ./gengen/gr_vector_source_i.h +;; (pass-if (true? (gr:vector-source-i #(1 2) #f 1))) + +;;; ./gengen/gr_vector_source_s.h FIXME: not found +;; (pass-if (true? (gr:vector-source-s #(1 2) #f 1))) + +;;; ./gengen/gr_xor_bb.h +(pass-if (true? (gr:xor-bb))) + +;;; ./gengen/gr_xor_ii.h +(pass-if (true? (gr:xor-ii))) + +;;; ./gengen/gr_xor_ss.h +(pass-if (true? (gr:xor-ss))) diff --git a/gnuradio-core/src/guile/tests/hier_ctors.test b/gnuradio-core/src/guile/tests/hier_ctors.test new file mode 100644 index 000000000..b79ee0f15 --- /dev/null +++ b/gnuradio-core/src/guile/tests/hier_ctors.test @@ -0,0 +1,40 @@ +;;; -*- Scheme -*- +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; If you're using Emacs's Scheme mode: +;;; (put 'with-test-prefix 'scheme-indent-function 1) + +;;; See the comments in gnuradio/test-suite/lib.scm for info on writing tests. +;;; See also the very end of the file, where the test-equal, test-eqv +;;; and test-eq macros are defined. + +(use-modules (gnuradio test-suite lib)) +(use-modules (gnuradio core)) +(use-modules (oop goops)) + +;;; Add test code for all constructors in these files +;;; + +;;; ./hier/gr_channel_model.h FIXME: Unbound variable: ~S" (gr:channel_model) #f)) +;; gr_make_channel_model(double noise_voltage=0.0, double frequency_offset=0.0, +;; double epsilon=1.0, +;; const std::vector<gr_complex> &taps=std::vector<gr_complex>(1, 1), +;; double noise_seed=3021); +;; (pass-if (true? (gr:channel_model 0.0 0.0 1.0 #(1 1) 3021))) diff --git a/gnuradio-core/src/guile/tests/io_ctors.test b/gnuradio-core/src/guile/tests/io_ctors.test new file mode 100644 index 000000000..5f40d321c --- /dev/null +++ b/gnuradio-core/src/guile/tests/io_ctors.test @@ -0,0 +1,82 @@ +;;; -*- Scheme -*- +;;; +;;; Copyright 2010 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 this program. If not, see <http://www.gnu.org/licenses/>. +;;; + +;;; If you're using Emacs's Scheme mode: +;;; (put 'with-test-prefix 'scheme-indent-function 1) + +;;; See the comments in gnuradio/test-suite/lib.scm for info on writing tests. +;;; See also the very end of the file, where the test-equal, test-eqv +;;; and test-eq macros are defined. + +(use-modules (gnuradio test-suite lib)) +(use-modules (gnuradio core)) +(use-modules (oop goops)) + + +(define (rm-foo) + (false-if-exception (delete-file "foo"))) + +;;; Add test code for all constructors in these files +;;; + +;;; ./io/gr_file_descriptor_sink.h +(pass-if (true? (gr:file-descriptor-sink 1 (dup 1)))) + +;;; ./io/gr_file_descriptor_source.h +(pass-if (true? (gr:file-descriptor-source 1 (dup 0) #f))) + +;;; ./io/gr_file_sink.h +(pass-if (true? (gr:file-sink 1 "foo"))) + +;;; ./io/gr_file_source.h +(pass-if (true? (gr:file-source 1 "foo" #f))) +(rm-foo) + +;;; ./io/gr_histo_sink_f.h +;; gr_make_histo_sink_f (gr_msg_queue_sptr msgq); +(pass-if (true? (gr:histo-sink-f (gr:msg-queue)))) + +;;; ./io/gr_message_sink.h +(pass-if (true? (gr:message-sink 1 (gr:msg-queue) #f))) + +;;; ./io/gr_message_source.h +(pass-if (true? (gr:message-source 1 1))) +(pass-if (true? (gr:message-source 1 (gr:msg-queue)))) + +;;; ./io/gr_oscope_sink_f.h +(pass-if (true? (gr:oscope-sink-f 1000 (gr:msg-queue)))) + +;;; ./io/gr_udp_sink.h +;;(pass-if (true? (gr:udp-sink 4 "localhost" 80 1472 #f))) +;;(pass-if-throw "confirm throw gr:udp-sink" #t +;; (true? (gr:udp-sink 4 "localhostx" 80 1472 #f))) + +;;; ./io/gr_udp_source.h +;;(pass-if (true? (gr:udp-source 4 "localhost" 0 1472 #f #t))) +;;(pass-if-throw "confirm throw gr:udp-source" #t +;; (true? (gr:udp-source 4 "localhostx" 0 1472 #f #t))) + +;;; ./io/gr_wavfile_sink.h +(pass-if (true? (gr:wavfile-sink "foo" 2 48000 16))) + +;;; ./io/gr_wavfile_source.h WONTFIX: buggy source won't accept file +;;; created immediately above. +;;(pass-if (true? (gr:wavfile-source "foo" #f))) +(rm-foo) diff --git a/gnuradio-core/src/lib/.gitignore b/gnuradio-core/src/lib/.gitignore index e3bc1ee6a..0d5077da5 100644 --- a/gnuradio-core/src/lib/.gitignore +++ b/gnuradio-core/src/lib/.gitignore @@ -1,7 +1,5 @@ /Makefile /Makefile.in -/.la -/.lo /.deps /.libs /*.la diff --git a/gnuradio-core/src/lib/Makefile.am b/gnuradio-core/src/lib/Makefile.am index f3a3accdb..4db2ff167 100644 --- a/gnuradio-core/src/lib/Makefile.am +++ b/gnuradio-core/src/lib/Makefile.am @@ -24,10 +24,7 @@ include $(top_srcdir)/Makefile.common ## Process this file with automake to produce Makefile.in # We've got to build . before swig -SUBDIRS = missing runtime filter viterbi general gengen g72x reed-solomon io hier . -if PYTHON -SUBDIRS += swig -endif +SUBDIRS = missing runtime filter viterbi general gengen g72x reed-solomon io hier . swig AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) @@ -69,4 +66,7 @@ libgnuradio_core_qa_la_LIBADD = \ bin_PROGRAMS = gnuradio-config-info gnuradio_config_info_SOURCES = gnuradio-config-info.cc -gnuradio_config_info_LDADD = libgnuradio-core.la $(BOOST_LDFLAGS) $(BOOST_PROGRAM_OPTIONS_LIB) +gnuradio_config_info_LDADD = libgnuradio-core.la \ + $(BOOST_LDFLAGS) \ + $(BOOST_PROGRAM_OPTIONS_LIB) \ + $(BOOST_FILESYSTEM_LIB) diff --git a/gnuradio-core/src/lib/bug_work_around_6.cc b/gnuradio-core/src/lib/bug_work_around_6.cc index b829360fc..f8012af0d 100644 --- a/gnuradio-core/src/lib/bug_work_around_6.cc +++ b/gnuradio-core/src/lib/bug_work_around_6.cc @@ -1,3 +1,3 @@ // if libgrio has no sources, it doesn't get built correctly - -static int gr_bug_work_around_6 __attribute__((unused)); +#include <gruel/attributes.h> +static int gr_bug_work_around_6 __GR_ATTR_UNUSED; diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am index 6d2ec1c7e..48ec55a62 100644 --- a/gnuradio-core/src/lib/filter/Makefile.am +++ b/gnuradio-core/src/lib/filter/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2001,2002,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. +# Copyright 2001,2002,2004-2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -26,7 +26,9 @@ include $(top_srcdir)/Makefile.common # other performance critical items # -AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) +# $(WITH_INCLUDES) must _always_ be last +AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) \ + $(FFTW3F_CPPFLAGS) $(WITH_INCLUDES) noinst_LTLIBRARIES = libfilter.la libfilter-qa.la @@ -67,7 +69,7 @@ code_generator = \ # Source built by Python into $(builddir) -BUILT_SOURCES = \ +BUILT_SOURCES += \ $(GENERATED_H) \ $(GENERATED_I) \ $(GENERATED_CC) \ @@ -118,8 +120,7 @@ x86_SUBCODE = \ ccomplex_dotprod_sse.S \ fcomplex_dotprod_3dnow.S \ fcomplex_dotprod_sse.S \ - short_dotprod_mmx.S \ - cpuid_x86.S + short_dotprod_mmx.S x86_64_SUBCODE = \ float_dotprod_sse64.S \ @@ -132,8 +133,7 @@ x86_64_SUBCODE = \ ccomplex_dotprod_sse64.S \ fcomplex_dotprod_3dnow64.S \ fcomplex_dotprod_sse64.S \ - short_dotprod_mmx64.S \ - cpuid_x86_64.S + short_dotprod_mmx64.S x86_qa_CODE = \ qa_dotprod_x86.cc \ @@ -157,7 +157,9 @@ armv7_a_CODE = \ gr_fir_sysconfig_armv7_a.cc \ gr_cpu_armv7_a.cc \ gr_fir_fff_armv7_a.cc \ - dotprod_fff_armv7_a.c + dotprod_fff_armv7_a.c \ + gr_fir_ccf_armv7_a.cc \ + dotprod_ccf_armv7_a.c armv7_a_qa_CODE = \ qa_dotprod_armv7_a.cc @@ -178,7 +180,7 @@ EXTRA_libfilter_la_SOURCES = \ $(armv7_a_qa_CODE) -EXTRA_DIST = \ +EXTRA_DIST += \ 3dnow_float_dotprod_really_simple.S \ 3dnow_float_dotprod_simple.S \ $(code_generator) @@ -186,8 +188,8 @@ EXTRA_DIST = \ # work around automake deficiency libfilter_la_common_SOURCES = \ $(GENERATED_CC) \ + gr_adaptive_fir_ccc.cc \ gr_adaptive_fir_ccf.cc \ - gr_cma_equalizer_cc.cc \ gri_fft_filter_fff_generic.cc \ gri_fft_filter_ccc_generic.cc \ gr_fft_filter_ccc.cc \ @@ -214,7 +216,9 @@ libfilter_la_common_SOURCES = \ gr_pfb_interpolator_ccf.cc \ gr_pfb_arb_resampler_ccf.cc \ gr_pfb_clock_sync_ccf.cc \ - gr_pfb_clock_sync_fff.cc + gr_pfb_clock_sync_fff.cc \ + gr_dc_blocker_cc.cc \ + gr_dc_blocker_ff.cc libfilter_qa_la_common_SOURCES = \ qa_filter.cc \ @@ -268,9 +272,9 @@ grinclude_HEADERS = \ ccomplex_dotprod_x86.h \ float_dotprod_generic.h \ float_dotprod_x86.h \ + gr_adaptive_fir_ccc.h \ gr_adaptive_fir_ccf.h \ gr_altivec.h \ - gr_cma_equalizer_cc.h \ gr_cpu.h \ gri_fft_filter_fff_generic.h \ gri_fft_filter_ccc_generic.h \ @@ -304,12 +308,16 @@ grinclude_HEADERS = \ gr_pfb_interpolator_ccf.h \ gr_pfb_arb_resampler_ccf.h \ gr_pfb_clock_sync_ccf.h \ - gr_pfb_clock_sync_fff.h + gr_pfb_clock_sync_fff.h \ + gr_dc_blocker_cc.h \ + gr_dc_blocker_ff.h noinst_HEADERS = \ assembly.h \ + gcc_x86_cpuid.h \ dotprod_fff_altivec.h \ dotprod_fff_armv7_a.h \ + dotprod_ccf_armv7_a.h \ gr_fir_scc_simd.h \ gr_fir_scc_x86.h \ gr_fir_fcc_simd.h \ @@ -320,6 +328,7 @@ noinst_HEADERS = \ gr_fir_ccc_x86.h \ gr_fir_fff_altivec.h \ gr_fir_fff_armv7_a.h \ + gr_fir_ccf_armv7_a.h \ gr_fir_fff_simd.h \ gr_fir_fff_x86.h \ gr_fir_fsf_simd.h \ @@ -345,12 +354,11 @@ noinst_HEADERS = \ qa_gri_fir_filter_with_buffer_scc.h -if PYTHON swiginclude_HEADERS = \ filter.i \ filter_generated.i \ + gr_adaptive_fir_ccc.i \ gr_adaptive_fir_ccf.i \ - gr_cma_equalizer_cc.i \ gr_fft_filter_ccc.i \ gr_fft_filter_fff.i \ gr_filter_delay_fc.i \ @@ -368,8 +376,10 @@ swiginclude_HEADERS = \ gr_pfb_arb_resampler_ccf.i \ gr_pfb_clock_sync_ccf.i \ gr_pfb_clock_sync_fff.i \ + gr_dc_blocker_cc.i \ + gr_dc_blocker_ff.i \ $(GENERATED_I) -endif + # Do creation and inclusion of other Makefiles last diff --git a/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc b/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc index 5fc04271a..0dc0c38b7 100644 --- a/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc +++ b/gnuradio-core/src/lib/filter/ccomplex_dotprod_generic.cc @@ -24,7 +24,6 @@ #include <config.h> #endif #include <gr_complex.h> -#include "gr_fir_ccc_simd.h" #include "ccomplex_dotprod_generic.h" #include <iostream> diff --git a/gnuradio-core/src/lib/filter/complex_dotprod_generic.cc b/gnuradio-core/src/lib/filter/complex_dotprod_generic.cc index 89eb6db87..8cbc4aa70 100644 --- a/gnuradio-core/src/lib/filter/complex_dotprod_generic.cc +++ b/gnuradio-core/src/lib/filter/complex_dotprod_generic.cc @@ -24,7 +24,6 @@ #include <config.h> #endif #include <gr_complex.h> -#include "gr_fir_scc_simd.h" #include "complex_dotprod_generic.h" diff --git a/gnuradio-core/src/lib/filter/cpuid_x86.S b/gnuradio-core/src/lib/filter/cpuid_x86.S deleted file mode 100644 index 4e1a9404f..000000000 --- a/gnuradio-core/src/lib/filter/cpuid_x86.S +++ /dev/null @@ -1,60 +0,0 @@ -# -# Copyright 2003 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. -# - -# -# execute CPUID instruction, return EAX, EBX, ECX and EDX values in result -# -# void cpuid_x86 (unsigned int op, unsigned int result[4]); -# - -#include "assembly.h" - -.file "cpuid_x86.S" - .version "01.01" -.text -.globl GLOB_SYMB(cpuid_x86) - DEF_FUNC_HEAD(cpuid_x86) -GLOB_SYMB(cpuid_x86): - pushl %ebp - movl %esp, %ebp - pushl %ebx # must save in PIC mode, holds GOT pointer - pushl %esi - - movl 8(%ebp), %eax # op - movl 12(%ebp), %esi # result - cpuid - movl %eax, 0(%esi) - movl %ebx, 4(%esi) - movl %ecx, 8(%esi) - movl %edx, 12(%esi) - - popl %esi - popl %ebx - popl %ebp - ret - -FUNC_TAIL(cpuid_x86) - .ident "Hand coded cpuid assembly" - - -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif diff --git a/gnuradio-core/src/lib/filter/cpuid_x86_64.S b/gnuradio-core/src/lib/filter/cpuid_x86_64.S deleted file mode 100644 index 32b1847cd..000000000 --- a/gnuradio-core/src/lib/filter/cpuid_x86_64.S +++ /dev/null @@ -1,54 +0,0 @@ -# -# Copyright 2003,2005 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. -# - -# -# execute CPUID instruction, return EAX, EBX, ECX and EDX values in result -# -# void cpuid_x86 (unsigned int op, unsigned int result[4]); -# - -#include "assembly.h" - -.file "cpuid_x86_64.S" - .version "01.01" -.text -.globl GLOB_SYMB(cpuid_x86) - DEF_FUNC_HEAD(cpuid_x86) -GLOB_SYMB(cpuid_x86): - mov %rbx, %r11 # must save in PIC mode, holds GOT pointer - - mov %rdi, %rax # op - cpuid - movl %eax, 0(%rsi) # result - movl %ebx, 4(%rsi) - movl %ecx, 8(%rsi) - movl %edx, 12(%rsi) - - mov %r11, %rbx - retq - -FUNC_TAIL(cpuid_x86) - .ident "Hand coded cpuid64 assembly" - - -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif diff --git a/gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.c b/gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.c new file mode 100644 index 000000000..90bd2ee10 --- /dev/null +++ b/gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.c @@ -0,0 +1,90 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2011 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 this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <dotprod_ccf_armv7_a.h> + +/*! + * \param x any value + * \param pow2 must be a power of 2 + * \returns \p x rounded down to a multiple of \p pow2. + */ +static inline size_t +gr_p2_round_down(size_t x, size_t pow2) +{ + return x & -pow2; +} + + +#if 0 + +void +dotprod_ccf_armv7_a(const float *a, const float *b, float *res, size_t n) +{ + size_t i; + res[0] = 0; + res[1] = 0; + + for (i = 0; i < n; i++){ + res[0] += a[2*i] * b[i]; + res[1] += a[2*i+1] * b[i]; + } +} + +#else + +/* + * preconditions: + * + * n > 0 and a multiple of 4 + * a 4-byte aligned + * b 16-byte aligned + */ +void +dotprod_ccf_armv7_a(const float *a, const float *b, float *res, size_t n) +{ + + asm volatile( + "vmov.f32 q14, #0.0 \n\t" + "vmov.f32 q15, #0.0 \n\t" + "1: \n\t" + "subs %2, %2, #4 \n\t" + "vld2.f32 {q0-q1}, [%0]! \n\t" + "vld1.f32 {q2}, [%1]! \n\t" + "vmla.f32 q14, q0, q2 \n\t" + "vmla.f32 q15, q1, q2 \n\t" + "bgt 1b \n\t" + "vpadd.f32 d0, d28, d29 \n\t" + "vpadd.f32 d1, d30, d31 \n\t" + "vpadd.f32 d0, d0, d1 \n\t" + "vst1.f32 {d0}, [%3] \n\t" + + : "+&r"(a), "+&r"(b), "+&r"(n) + : "r"(res) + : "memory", "d0", "d1", "d2", "d3", "d4", "d5", + "d28", "d29", "d30", "d31" ); +} + + +#endif diff --git a/gnuradio-core/src/lib/swig/gnuradio_swig_py_general.i b/gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.h index 3ab1b056a..7ee728ac4 100644 --- a/gnuradio-core/src/lib/swig/gnuradio_swig_py_general.i +++ b/gnuradio-core/src/lib/filter/dotprod_ccf_armv7_a.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. + * Copyright 2008,2009,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -18,13 +18,30 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#ifndef INCLUDED_DOTPROD_CCF_ARMV7_A_H +#define INCLUDED_DOTPROD_CCF_ARMV7_A_H -#ifndef SWIGIMPORTED -%module(directors="1") gnuradio_swig_py_general +#include <stddef.h> + +#ifdef __cplusplus +extern "C" { #endif - //%feature("autodoc", "1"); // generate python docstrings +/*! + * <pre> + * + * preconditions: + * + * n > 0 and a multiple of 4 + * a 4-byte aligned + * b 16-byte aligned + * + * </pre> + */ +void dotprod_ccf_armv7_a(const float *a, const float *b, float *res, size_t n); -%include "gnuradio.i" // the common stuff +#ifdef __cplusplus +} +#endif -%include "general.i" +#endif /* INCLUDED_DOTPROD_CCF_ARMV7_A_H */ diff --git a/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c b/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c index bd1b88e22..c3275c331 100644 --- a/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c +++ b/gnuradio-core/src/lib/filter/dotprod_fff_armv7_a.c @@ -77,7 +77,8 @@ dotprod_fff_armv7_a(const float *a, const float *b, size_t n) "vpadd.f32 d0, d16, d17 \n\t" "vadd.f32 %0, s0, s1 \n\t" : "=w"(s), "+r"(a), "+r"(b), "+r"(n) - :: "q0", "q1", "q2", "q3", "q8", "q9"); + :: "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", + "d16", "d17", "d18", "d19"); return s; diff --git a/gnuradio-core/src/lib/filter/filter.i b/gnuradio-core/src/lib/filter/filter.i index 645607cba..2af7fcc5c 100644 --- a/gnuradio-core/src/lib/filter/filter.i +++ b/gnuradio-core/src/lib/filter/filter.i @@ -31,7 +31,6 @@ #include <gr_fractional_interpolator_ff.h> #include <gr_fractional_interpolator_cc.h> #include <gr_goertzel_fc.h> -#include <gr_cma_equalizer_cc.h> #include <gr_pfb_channelizer_ccf.h> #include <gr_pfb_synthesis_filterbank_ccf.h> #include <gr_pfb_decimator_ccf.h> @@ -39,6 +38,8 @@ #include <gr_pfb_arb_resampler_ccf.h> #include <gr_pfb_clock_sync_ccf.h> #include <gr_pfb_clock_sync_fff.h> +#include <gr_dc_blocker_cc.h> +#include <gr_dc_blocker_ff.h> %} %include "gr_iir_filter_ffd.i" @@ -51,7 +52,6 @@ %include "gr_fractional_interpolator_ff.i" %include "gr_fractional_interpolator_cc.i" %include "gr_goertzel_fc.i" -%include "gr_cma_equalizer_cc.i" %include "gr_pfb_channelizer_ccf.i" %include "gr_pfb_synthesis_filterbank_ccf.i" %include "gr_pfb_decimator_ccf.i" @@ -62,5 +62,7 @@ %include "gr_pfb_arb_resampler_ccf.i" %include "gr_pfb_clock_sync_ccf.i" %include "gr_pfb_clock_sync_fff.i" +%include "gr_dc_blocker_cc.i" +%include "gr_dc_blocker_ff.i" %include "filter_generated.i" diff --git a/gnuradio-core/src/lib/filter/gcc_x86_cpuid.h b/gnuradio-core/src/lib/filter/gcc_x86_cpuid.h new file mode 100644 index 000000000..2d0916fb3 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gcc_x86_cpuid.h @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. + * + * This file 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. + * + * This file 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. + * + * Under Section 7 of GPL version 3, you are granted additional + * permissions described in the GCC Runtime Library Exception, version + * 3.1, as published by the Free Software Foundation. + * + * You should have received a copy of the GNU General Public License and + * a copy of the GCC Runtime Library Exception along with this program; + * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + * <http://www.gnu.org/licenses/>. + */ + +/* %ecx */ +#define bit_SSE3 (1 << 0) +#define bit_PCLMUL (1 << 1) +#define bit_SSSE3 (1 << 9) +#define bit_FMA (1 << 12) +#define bit_CMPXCHG16B (1 << 13) +#define bit_SSE4_1 (1 << 19) +#define bit_SSE4_2 (1 << 20) +#define bit_MOVBE (1 << 22) +#define bit_POPCNT (1 << 23) +#define bit_AES (1 << 25) +#define bit_XSAVE (1 << 26) +#define bit_OSXSAVE (1 << 27) +#define bit_AVX (1 << 28) + +/* %edx */ +#define bit_CMPXCHG8B (1 << 8) +#define bit_CMOV (1 << 15) +#define bit_MMX (1 << 23) +#define bit_FXSAVE (1 << 24) +#define bit_SSE (1 << 25) +#define bit_SSE2 (1 << 26) + +/* Extended Features */ +/* %ecx */ +#define bit_LAHF_LM (1 << 0) +#define bit_SSE4a (1 << 6) +#define bit_SSE5 (1 << 11) + +/* %edx */ +#define bit_LM (1 << 29) +#define bit_3DNOWP (1 << 30) +#define bit_3DNOW (1 << 31) + + +#if defined(__i386__) && defined(__PIC__) +/* %ebx may be the PIC register. */ +#if __GNUC__ >= 3 +#define __cpuid(level, a, b, c, d) \ + __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ + "cpuid\n\t" \ + "xchg{l}\t{%%}ebx, %1\n\t" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (level)) + +#define __cpuid_count(level, count, a, b, c, d) \ + __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \ + "cpuid\n\t" \ + "xchg{l}\t{%%}ebx, %1\n\t" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (level), "2" (count)) +#else +/* Host GCCs older than 3.0 weren't supporting Intel asm syntax + nor alternatives in i386 code. */ +#define __cpuid(level, a, b, c, d) \ + __asm__ ("xchgl\t%%ebx, %1\n\t" \ + "cpuid\n\t" \ + "xchgl\t%%ebx, %1\n\t" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (level)) + +#define __cpuid_count(level, count, a, b, c, d) \ + __asm__ ("xchgl\t%%ebx, %1\n\t" \ + "cpuid\n\t" \ + "xchgl\t%%ebx, %1\n\t" \ + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \ + : "0" (level), "2" (count)) +#endif +#else +#define __cpuid(level, a, b, c, d) \ + __asm__ ("cpuid\n\t" \ + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ + : "0" (level)) + +#define __cpuid_count(level, count, a, b, c, d) \ + __asm__ ("cpuid\n\t" \ + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ + : "0" (level), "2" (count)) +#endif + +/* Return highest supported input value for cpuid instruction. ext can + be either 0x0 or 0x8000000 to return highest supported value for + basic or extended cpuid information. Function returns 0 if cpuid + is not supported or whatever cpuid returns in eax register. If sig + pointer is non-null, then first four bytes of the signature + (as found in ebx register) are returned in location pointed by sig. */ + +static __inline unsigned int +__get_cpuid_max (unsigned int __ext, unsigned int *__sig) +{ + unsigned int __eax, __ebx, __ecx, __edx; + +#ifndef __x86_64__ +#if __GNUC__ >= 3 + /* See if we can use cpuid. On AMD64 we always can. */ + __asm__ ("pushf{l|d}\n\t" + "pushf{l|d}\n\t" + "pop{l}\t%0\n\t" + "mov{l}\t{%0, %1|%1, %0}\n\t" + "xor{l}\t{%2, %0|%0, %2}\n\t" + "push{l}\t%0\n\t" + "popf{l|d}\n\t" + "pushf{l|d}\n\t" + "pop{l}\t%0\n\t" + "popf{l|d}\n\t" + : "=&r" (__eax), "=&r" (__ebx) + : "i" (0x00200000)); +#else +/* Host GCCs older than 3.0 weren't supporting Intel asm syntax + nor alternatives in i386 code. */ + __asm__ ("pushfl\n\t" + "pushfl\n\t" + "popl\t%0\n\t" + "movl\t%0, %1\n\t" + "xorl\t%2, %0\n\t" + "pushl\t%0\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl\t%0\n\t" + "popfl\n\t" + : "=&r" (__eax), "=&r" (__ebx) + : "i" (0x00200000)); +#endif + + if (!((__eax ^ __ebx) & 0x00200000)) + return 0; +#endif + + /* Host supports cpuid. Return highest supported cpuid input value. */ + __cpuid (__ext, __eax, __ebx, __ecx, __edx); + + if (__sig) + *__sig = __ebx; + + return __eax; +} + +/* Return cpuid data for requested cpuid level, as found in returned + eax, ebx, ecx and edx registers. The function checks if cpuid is + supported and returns 1 for valid cpuid information or 0 for + unsupported cpuid level. All pointers are required to be non-null. */ + +static __inline int +__get_cpuid (unsigned int __level, + unsigned int *__eax, unsigned int *__ebx, + unsigned int *__ecx, unsigned int *__edx) +{ + unsigned int __ext = __level & 0x80000000; + + if (__get_cpuid_max (__ext, 0) < __level) + return 0; + + __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx); + return 1; +} diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc new file mode 100644 index 000000000..884caf29c --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc @@ -0,0 +1,88 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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_adaptive_fir_ccc.h> +#include <gr_io_signature.h> + +gr_adaptive_fir_ccc::gr_adaptive_fir_ccc(const char *name, int decimation, + const std::vector<gr_complex> &taps) + : gr_sync_decimator (name, + gr_make_io_signature (1, 1, sizeof(gr_complex)), + gr_make_io_signature (1, 1, sizeof(gr_complex)), + decimation), + d_taps(taps), d_updated(false) +{ + set_history(d_taps.size()); +} + +void +gr_adaptive_fir_ccc::set_taps(const std::vector<gr_complex> &taps) +{ + d_new_taps = taps; + d_updated = true; +} + +gr_complex +gr_adaptive_fir_ccc::filter(gr_complex *x) +{ + // Generic dot product of d_taps[] and in[] + gr_complex acc(0.0, 0.0); + int l = d_taps.size(); + for (int k = 0; k < l; k++) + acc += d_taps[l-k-1] * x[k]; + return acc; +} + +int +gr_adaptive_fir_ccc::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + gr_complex *in = (gr_complex *)input_items[0]; + gr_complex *out = (gr_complex *)output_items[0]; + + if (d_updated) { + d_taps = d_new_taps; + set_history(d_taps.size()); + d_updated = false; + return 0; // history requirements may have changed. + } + + int j = 0, k, l = d_taps.size(); + for (int i = 0; i < noutput_items; i++) { + out[i] = filter(&in[j]); + + // Adjust taps + d_error = error(out[i]); + for (k = 0; k < l; k++) { + update_tap(d_taps[l-k-1], in[j+k]); + } + + j += decimation(); + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.h b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.h new file mode 100644 index 000000000..8678255b7 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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_GR_ADAPTIVE_FIR_CCC_H +#define INCLUDED_GR_ADAPTIVE_FIR_CCC_H + +#include <gr_sync_decimator.h> + +/*! + * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps + * \ingroup filter_blk + */ +class gr_adaptive_fir_ccc : public gr_sync_decimator +{ +private: + std::vector<gr_complex> d_new_taps; + bool d_updated; + +protected: + gr_complex d_error; + std::vector<gr_complex> d_taps; + + // Override to calculate error signal per output + virtual gr_complex error(const gr_complex &out) = 0; + + // Override to calculate new weight from old, corresponding input + virtual void update_tap(gr_complex &tap, const gr_complex &in) = 0; + + gr_complex filter(gr_complex *x); + + gr_adaptive_fir_ccc(const char *name, int decimation, + const std::vector<gr_complex> &taps); + +public: + void set_taps(const std::vector<gr_complex> &taps); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gnuradio-core/src/lib/swig/gnuradio_swig_py_runtime.i b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.i index 8f444f9c5..7e9a3fac3 100644 --- a/gnuradio-core/src/lib/swig/gnuradio_swig_py_runtime.i +++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2009 Free Software Foundation, Inc. + * Copyright 2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,13 +20,12 @@ * Boston, MA 02110-1301, USA. */ -#ifndef SWIGIMPORTED -%module(directors="1") gnuradio_swig_py_runtime -#endif +class gr_adaptive_fir_ccc : public gr_sync_decimator +{ +protected: + gr_adaptive_fir_ccc(char *name, int decimation, + const std::vector<gr_complex> &taps); - //%feature("autodoc", "1"); // generate python docstrings - -#define SW_RUNTIME -%include "gnuradio.i" // the common stuff - -%include "runtime.i" +public: + void set_taps(const std::vector<gr_complex> &taps); +}; diff --git a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.h b/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.h deleted file mode 100644 index c78047c16..000000000 --- a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006 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_GR_CMA_EQUALIZER_CC_H -#define INCLUDED_GR_CMA_EQUALIZER_CC_H - -#include <gr_adaptive_fir_ccf.h> - -class gr_cma_equalizer_cc; -typedef boost::shared_ptr<gr_cma_equalizer_cc> gr_cma_equalizer_cc_sptr; - -gr_cma_equalizer_cc_sptr -gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu); - -/*! - * \brief Implements constant modulus adaptive filter on complex stream - * \ingroup eq_blk - */ -class gr_cma_equalizer_cc : public gr_adaptive_fir_ccf -{ -private: - float d_modulus; - float d_mu; - - friend gr_cma_equalizer_cc_sptr gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu); - gr_cma_equalizer_cc(int num_taps, float modulus, float mu); - -protected: - - virtual float error(const gr_complex &out) - { - return (d_modulus - norm(out)); - } - - virtual void update_tap(float &tap, const gr_complex &in) - { - tap += d_mu*d_error*abs(in); - } - -public: -}; - -#endif diff --git a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.i b/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.i deleted file mode 100644 index 30e2fb8bd..000000000 --- a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.i +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2009 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. - */ - -GR_SWIG_BLOCK_MAGIC(gr,cma_equalizer_cc) - -// retrieve info on the base class, without generating wrappers since -// the base class has a pure virual method. -%import "gr_adaptive_fir_ccf.i" - -gr_cma_equalizer_cc_sptr gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu); - -class gr_cma_equalizer_cc : public gr_adaptive_fir_ccf -{ -private: - gr_cma_equalizer_cc(int num_taps, float modulus, float mu); - -public: -}; diff --git a/gnuradio-core/src/lib/filter/gr_cpu_x86.cc b/gnuradio-core/src/lib/filter/gr_cpu_x86.cc index ac8a2eeb7..da970e133 100644 --- a/gnuradio-core/src/lib/filter/gr_cpu_x86.cc +++ b/gnuradio-core/src/lib/filter/gr_cpu_x86.cc @@ -21,13 +21,12 @@ */ #include <gr_cpu.h> +#include "gcc_x86_cpuid.h" /* * execute CPUID instruction, return EAX, EBX, ECX and EDX values in result */ -extern "C" { -void cpuid_x86 (unsigned int op, unsigned int result[4]); -}; +#define cpuid_x86(op, r) __get_cpuid(op, r+0, r+1, r+2, r+3) /* * CPUID functions returning a single datum @@ -35,28 +34,28 @@ void cpuid_x86 (unsigned int op, unsigned int result[4]); static inline unsigned int cpuid_eax(unsigned int op) { - unsigned int regs[4]; + unsigned int regs[4] = {0,0,0,0}; cpuid_x86 (op, regs); return regs[0]; } static inline unsigned int cpuid_ebx(unsigned int op) { - unsigned int regs[4]; + unsigned int regs[4] = {0,0,0,0}; cpuid_x86 (op, regs); return regs[1]; } static inline unsigned int cpuid_ecx(unsigned int op) { - unsigned int regs[4]; + unsigned int regs[4] = {0,0,0,0}; cpuid_x86 (op, regs); return regs[2]; } static inline unsigned int cpuid_edx(unsigned int op) { - unsigned int regs[4]; + unsigned int regs[4] = {0,0,0,0}; cpuid_x86 (op, regs); return regs[3]; } diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc new file mode 100644 index 000000000..e7d5ced25 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc @@ -0,0 +1,138 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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_dc_blocker_cc.h> +#include <gr_io_signature.h> +#include <cstdio> + +moving_averager_c::moving_averager_c(int D) + : d_length(D), d_out(0), d_out_d1(0), d_out_d2(0) +{ + d_delay_line = std::deque<gr_complex>(d_length-1, gr_complex(0,0)); +} + +moving_averager_c::~moving_averager_c() +{ +} + +gr_complex +moving_averager_c::filter(gr_complex x) +{ + d_out_d1 = d_out; + d_delay_line.push_back(x); + d_out = d_delay_line[0]; + d_delay_line.pop_front(); + + gr_complex y = x - d_out_d1 + d_out_d2; + d_out_d2 = y; + + return (y / (float)(d_length)); +} + + + +gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D, bool long_form) +{ + return gnuradio::get_initial_sptr(new gr_dc_blocker_cc(D, long_form)); +} + + +gr_dc_blocker_cc::gr_dc_blocker_cc (int D, bool long_form) + : gr_sync_block ("dc_blocker_cc", + gr_make_io_signature (1, 1, sizeof(gr_complex)), + gr_make_io_signature (1, 1, sizeof(gr_complex))), + d_length(D), d_long_form(long_form) +{ + if(d_long_form) { + d_ma_0 = new moving_averager_c(D); + d_ma_1 = new moving_averager_c(D); + d_ma_2 = new moving_averager_c(D); + d_ma_3 = new moving_averager_c(D); + d_delay_line = std::deque<gr_complex>(d_length-1, gr_complex(0,0)); + } + else { + d_ma_0 = new moving_averager_c(D); + d_ma_1 = new moving_averager_c(D); + } +} + +gr_dc_blocker_cc::~gr_dc_blocker_cc() +{ + if(d_long_form) { + delete d_ma_0; + delete d_ma_1; + delete d_ma_2; + delete d_ma_3; + } + else { + delete d_ma_0; + delete d_ma_1; + } +} + +int +gr_dc_blocker_cc::get_group_delay() +{ + if(d_long_form) + return (2*d_length-2); + else + return d_length - 1; +} + +int +gr_dc_blocker_cc::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + if(d_long_form) { + gr_complex y1, y2, y3, y4, d; + for(int i = 0; i < noutput_items; i++) { + y1 = d_ma_0->filter(in[i]); + y2 = d_ma_1->filter(y1); + y3 = d_ma_2->filter(y2); + y4 = d_ma_3->filter(y3); + + d_delay_line.push_back(d_ma_0->delayed_sig()); + d = d_delay_line[0]; + d_delay_line.pop_front(); + + out[i] = d - y4; + } + } + else { + gr_complex y1, y2; + for(int i = 0; i < noutput_items; i++) { + y1 = d_ma_0->filter(in[i]); + y2 = d_ma_1->filter(y1); + out[i] = d_ma_0->delayed_sig() - y2; + } + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h new file mode 100644 index 000000000..de9ccc0ea --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h @@ -0,0 +1,111 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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_GR_DC_BLOCKER_CC_H +#define INCLUDED_GR_DC_BLOCKER_CC_H + +#include <gr_sync_block.h> +#include <deque> + +class gr_dc_blocker_cc; +typedef boost::shared_ptr<gr_dc_blocker_cc> gr_dc_blocker_cc_sptr; +gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D=32, bool long_form=true); + +/*! + * \class gr_dc_blocker_cc + * \brief a computationally efficient controllabel DC blocker + * + * \ingroup filter_blk + * + * This block implements a computationally efficient DC blocker that produces + * a tigher notch filter around DC for a smaller group delay than an + * equivalent FIR filter or using a single pole IIR filter (though the IIR + * filter is computationally cheaper). + * + * The block defaults to using a delay line of length 32 and the long form + * of the filter. Optionally, the delay line length can be changed to alter + * the width of the DC notch (longer lines will decrease the width). + * + * The long form of the filter produces a nearly flat response outside of + * the notch but at the cost of a group delay of 2D-2. + * + * The short form of the filter does not have as flat a response in the + * passband but has a group delay of only D-1 and is cheaper to compute. + * + * The theory behind this block can be found in the paper: + * + * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine, + * Mar. 2008, pp 132-134.</EM></B> + */ +class moving_averager_c +{ +public: + moving_averager_c(int D); + ~moving_averager_c(); + + gr_complex filter(gr_complex x); + gr_complex delayed_sig() { return d_out; } + +private: + int d_length; + gr_complex d_out, d_out_d1, d_out_d2; + std::deque<gr_complex> d_delay_line; +}; + +class gr_dc_blocker_cc : public gr_sync_block +{ + private: + /*! + * Build the DC blocker. + * \param D (int) the length of the delay line + * \param long_form (bool) whether to use long (true, default) or short form + * \param channel (unsigned integer) Selects the channel to return [default=0]. + */ + friend gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D, bool long_form); + + int d_length; + bool d_long_form; + moving_averager_c *d_ma_0; + moving_averager_c *d_ma_1; + moving_averager_c *d_ma_2; + moving_averager_c *d_ma_3; + std::deque<gr_complex> d_delay_line; + + gr_dc_blocker_cc (int D, bool long_form); + +public: + ~gr_dc_blocker_cc (); + + /*! + * Get the blocker's group delay that is based on length of delay lines + */ + int get_group_delay(); + + //int set_length(int D); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i new file mode 100644 index 000000000..b88fecbde --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,dc_blocker_cc); + +gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D=32, bool long_form=true); + +class gr_dc_blocker_cc : public gr_sync_block +{ + private: + gr_dc_blocker_cc (int D, bool long_form); + + public: + ~gr_dc_blocker_cc (); +}; diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc new file mode 100644 index 000000000..d684bc7e8 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc @@ -0,0 +1,138 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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_dc_blocker_ff.h> +#include <gr_io_signature.h> +#include <cstdio> + +moving_averager_f::moving_averager_f(int D) + : d_length(D), d_out(0), d_out_d1(0), d_out_d2(0) +{ + d_delay_line = std::deque<float>(d_length-1, 0); +} + +moving_averager_f::~moving_averager_f() +{ +} + +float +moving_averager_f::filter(float x) +{ + d_out_d1 = d_out; + d_delay_line.push_back(x); + d_out = d_delay_line[0]; + d_delay_line.pop_front(); + + float y = x - d_out_d1 + d_out_d2; + d_out_d2 = y; + + return (y / (float)(d_length)); +} + + + +gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D, bool long_form) +{ + return gnuradio::get_initial_sptr(new gr_dc_blocker_ff(D, long_form)); +} + + +gr_dc_blocker_ff::gr_dc_blocker_ff (int D, bool long_form) + : gr_sync_block ("dc_blocker_ff", + gr_make_io_signature (1, 1, sizeof(float)), + gr_make_io_signature (1, 1, sizeof(float))), + d_length(D), d_long_form(long_form) +{ + if(d_long_form) { + d_ma_0 = new moving_averager_f(D); + d_ma_1 = new moving_averager_f(D); + d_ma_2 = new moving_averager_f(D); + d_ma_3 = new moving_averager_f(D); + d_delay_line = std::deque<float>(d_length-1, 0); + } + else { + d_ma_0 = new moving_averager_f(D); + d_ma_1 = new moving_averager_f(D); + } +} + +gr_dc_blocker_ff::~gr_dc_blocker_ff() +{ + if(d_long_form) { + delete d_ma_0; + delete d_ma_1; + delete d_ma_2; + delete d_ma_3; + } + else { + delete d_ma_0; + delete d_ma_1; + } +} + +int +gr_dc_blocker_ff::get_group_delay() +{ + if(d_long_form) + return (2*d_length-2); + else + return d_length - 1; +} + +int +gr_dc_blocker_ff::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]; + float *out = (float*)output_items[0]; + + if(d_long_form) { + float y1, y2, y3, y4, d; + for(int i = 0; i < noutput_items; i++) { + y1 = d_ma_0->filter(in[i]); + y2 = d_ma_1->filter(y1); + y3 = d_ma_2->filter(y2); + y4 = d_ma_3->filter(y3); + + d_delay_line.push_back(d_ma_0->delayed_sig()); + d = d_delay_line[0]; + d_delay_line.pop_front(); + + out[i] = d - y4; + } + } + else { + float y1, y2; + for(int i = 0; i < noutput_items; i++) { + y1 = d_ma_0->filter(in[i]); + y2 = d_ma_1->filter(y1); + out[i] = d_ma_0->delayed_sig() - y2; + } + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h new file mode 100644 index 000000000..b632d81da --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h @@ -0,0 +1,111 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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_GR_DC_BLOCKER_FF_H +#define INCLUDED_GR_DC_BLOCKER_FF_H + +#include <gr_sync_block.h> +#include <deque> + +class gr_dc_blocker_ff; +typedef boost::shared_ptr<gr_dc_blocker_ff> gr_dc_blocker_ff_sptr; +gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D=32, bool long_form=true); + +/*! + * \class gr_dc_blocker_ff + * \brief a computationally efficient controllabel DC blocker + * + * \ingroup filter_blk + * + * This block implements a computationally efficient DC blocker that produces + * a tigher notch filter around DC for a smaller group delay than an + * equivalent FIR filter or using a single pole IIR filter (though the IIR + * filter is computationally cheaper). + * + * The block defaults to using a delay line of length 32 and the long form + * of the filter. Optionally, the delay line length can be changed to alter + * the width of the DC notch (longer lines will decrease the width). + * + * The long form of the filter produces a nearly flat response outside of + * the notch but at the cost of a group delay of 2D-2. + * + * The short form of the filter does not have as flat a response in the + * passband but has a group delay of only D-1 and is cheaper to compute. + * + * The theory behind this block can be found in the paper: + * + * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine, + * Mar. 2008, pp 132-134.</EM></B> + */ +class moving_averager_f +{ +public: + moving_averager_f(int D); + ~moving_averager_f(); + + float filter(float x); + float delayed_sig() { return d_out; } + +private: + int d_length; + float d_out, d_out_d1, d_out_d2; + std::deque<float> d_delay_line; +}; + +class gr_dc_blocker_ff : public gr_sync_block +{ + private: + /*! + * Build the DC blocker. + * \param D (int) the length of the delay line + * \param long_form (bool) whether to use long (true, default) or short form + * \param channel (unsigned integer) Selects the channel to return [default=0]. + */ + friend gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D, bool long_form); + + int d_length; + bool d_long_form; + moving_averager_f *d_ma_0; + moving_averager_f *d_ma_1; + moving_averager_f *d_ma_2; + moving_averager_f *d_ma_3; + std::deque<float> d_delay_line; + + gr_dc_blocker_ff (int D, bool long_form); + +public: + ~gr_dc_blocker_ff (); + + /*! + * Get the blocker's group delay that is based on length of delay lines + */ + int get_group_delay(); + + //int set_length(int D); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i new file mode 100644 index 000000000..032145c9e --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,dc_blocker_ff); + +gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D=32, bool long_form=true); + +class gr_dc_blocker_ff : public gr_sync_block +{ + private: + gr_dc_blocker_ff (int D, bool long_form); + + public: + ~gr_dc_blocker_ff (); +}; diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.cc b/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.cc new file mode 100644 index 000000000..ac42b57b7 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.cc @@ -0,0 +1,91 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2011 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 this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gr_fir_ccf_armv7_a.h> +#include <stdlib.h> +#include <string.h> +#include <stdexcept> +#include <assert.h> +#include <gr_math.h> +#include <dotprod_ccf_armv7_a.h> + +#define FLOATS_PER_VEC 4 + +gr_fir_ccf_armv7_a::gr_fir_ccf_armv7_a() + : gr_fir_ccf_generic(), + d_naligned_taps(0), d_aligned_taps(0) +{ +} + +gr_fir_ccf_armv7_a::gr_fir_ccf_armv7_a (const std::vector<float> &new_taps) + : gr_fir_ccf_generic(new_taps), + d_naligned_taps(0), d_aligned_taps(0) +{ + set_taps(new_taps); +} + +gr_fir_ccf_armv7_a::~gr_fir_ccf_armv7_a() +{ + if (d_aligned_taps){ + free(d_aligned_taps); + d_aligned_taps = 0; + } +} + +void +gr_fir_ccf_armv7_a::set_taps(const std::vector<float> &inew_taps) +{ + gr_fir_ccf_generic::set_taps(inew_taps); // call superclass + d_naligned_taps = gr_p2_round_up(ntaps(), FLOATS_PER_VEC); + + if (d_aligned_taps){ + free(d_aligned_taps); + d_aligned_taps = 0; + } + void *p; + int r = posix_memalign(&p, sizeof(float), d_naligned_taps * sizeof(d_aligned_taps[0])); + if (r != 0){ + throw std::bad_alloc(); + } + d_aligned_taps = (float *) p; + memcpy(d_aligned_taps, &d_taps[0], ntaps() * sizeof(d_aligned_taps[0])); + for (size_t i = ntaps(); i < d_naligned_taps; i++) + d_aligned_taps[i] = 0.0; +} + + +gr_complex +gr_fir_ccf_armv7_a::filter (const gr_complex input[]) +{ + if (d_naligned_taps == 0) + return 0.0; + + gr_complex result; + float *presult = reinterpret_cast<float *>(&result); + const float *pinput = reinterpret_cast<const float *>(input); + + dotprod_ccf_armv7_a(pinput, d_aligned_taps, presult, d_naligned_taps); + return result; +} diff --git a/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.h b/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.h new file mode 100644 index 000000000..719ff4010 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_fir_ccf_armv7_a.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +/* + * Copyright 2008,2009,2011 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 this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#ifndef INCLUDED_GR_FIR_CCF_ARMV7_A_H +#define INCLUDED_GR_FIR_CCF_ARMV7_A_H + +#include <gr_fir_ccf_generic.h> + +/*! + * \brief armv7_a using NEON coprocessor version of gr_fir_ccf + */ +class gr_fir_ccf_armv7_a : public gr_fir_ccf_generic +{ +protected: + + size_t d_naligned_taps; // number of taps (multiple of 4) + float *d_aligned_taps; // 16-byte aligned, and zero padded to multiple of 4 + +public: + gr_fir_ccf_armv7_a(); + gr_fir_ccf_armv7_a(const std::vector<float> &taps); + ~gr_fir_ccf_armv7_a(); + + virtual void set_taps (const std::vector<float> &taps); + virtual gr_complex filter (const gr_complex input[]); +}; + +#endif /* INCLUDED_GR_FIR_CCF_ARMV7_A*_H */ diff --git a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.cc b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.cc index 34c7d4c01..71e622d37 100644 --- a/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.cc +++ b/gnuradio-core/src/lib/filter/gr_fir_sysconfig_armv7_a.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002,2008,2009 Free Software Foundation, Inc. + * Copyright 2002,2008,2009,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -28,6 +28,7 @@ #include <gr_fir_ccf.h> #include <gr_fir_ccf_generic.h> +#include <gr_fir_ccf_armv7_a.h> #include <gr_fir_fcc.h> #include <gr_fir_fcc_generic.h> #include <gr_fir_fff.h> @@ -51,13 +52,13 @@ using std::cerr; * ---------------------------------------------------------------- */ -#if 0 static gr_fir_ccf * -make_gr_fir_ccf_altivec(const std::vector<float> &taps) +make_gr_fir_ccf_armv7_a (const std::vector<float> &taps) { - return new gr_fir_ccf_altivec(taps); + return new gr_fir_ccf_armv7_a(taps); } +#if 0 static gr_fir_fcc * make_gr_fir_fcc_altivec(const std::vector<gr_complex> &taps) { @@ -107,15 +108,13 @@ gr_fir_sysconfig_armv7_a::create_gr_fir_ccf (const std::vector<float> &taps) { static bool first = true; -#if 0 - if (gr_cpu::has_altivec ()){ + if (gr_cpu::has_armv7_a ()){ if (first){ - cerr << ">>> gr_fir_ccf: using altivec\n"; + cerr << ">>> gr_fir_ccf: using armv7_a\n"; first = false; } - return make_gr_fir_ccf_altivec (taps); + return make_gr_fir_ccf_armv7_a (taps); } -#endif if (0 && first){ cerr << ">>> gr_fir_ccf: handing off to parent class\n"; @@ -245,15 +244,13 @@ gr_fir_sysconfig_armv7_a::get_gr_fir_ccf_info (std::vector<gr_fir_ccf_info> *inf // invoke parent.. gr_fir_sysconfig_generic::get_gr_fir_ccf_info (info); -#if 0 // add our stuff... gr_fir_ccf_info t; - if (gr_cpu::has_altivec ()){ - t.name = "altivec"; - t.create = make_gr_fir_ccf_altivec; + if (gr_cpu::has_armv7_a ()){ + t.name = "armv7_a"; + t.create = make_gr_fir_ccf_armv7_a; (*info).push_back (t); } -#endif } void diff --git a/gnuradio-core/src/lib/filter/gr_goertzel_fc.cc b/gnuradio-core/src/lib/filter/gr_goertzel_fc.cc index a93751b2f..938a522f4 100644 --- a/gnuradio-core/src/lib/filter/gr_goertzel_fc.cc +++ b/gnuradio-core/src/lib/filter/gr_goertzel_fc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2010 Free Software Foundation, Inc. + * Copyright 2006,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -42,6 +42,8 @@ gr_goertzel_fc::gr_goertzel_fc(int rate, int len, float freq) d_goertzel(rate, len, freq) { d_len = len; + d_rate = rate; + d_freq = freq; } int gr_goertzel_fc::work(int noutput_items, @@ -58,3 +60,17 @@ int gr_goertzel_fc::work(int noutput_items, return noutput_items; } + +void +gr_goertzel_fc::set_freq(float freq) +{ + d_freq = freq; + d_goertzel.gri_setparms(d_rate, d_len, d_freq); +} + +void +gr_goertzel_fc::set_rate(int rate) +{ + d_rate = rate; + d_goertzel.gri_setparms(d_rate, d_len, d_freq); +} diff --git a/gnuradio-core/src/lib/filter/gr_goertzel_fc.h b/gnuradio-core/src/lib/filter/gr_goertzel_fc.h index 9518c5c92..c60b63d88 100644 --- a/gnuradio-core/src/lib/filter/gr_goertzel_fc.h +++ b/gnuradio-core/src/lib/filter/gr_goertzel_fc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -44,11 +44,16 @@ private: gr_goertzel_fc(int rate, int len, float freq); gri_goertzel d_goertzel; int d_len; + float d_freq; + int d_rate; public: int work(int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); + + void set_freq (float freq); + void set_rate (int rate); }; #endif /* INCLUDED_GR_GOERTZEL_FC_H */ diff --git a/gnuradio-core/src/lib/filter/gr_goertzel_fc.i b/gnuradio-core/src/lib/filter/gr_goertzel_fc.i index 4cbc1dece..775c78cc8 100644 --- a/gnuradio-core/src/lib/filter/gr_goertzel_fc.i +++ b/gnuradio-core/src/lib/filter/gr_goertzel_fc.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -28,4 +28,8 @@ class gr_goertzel_fc : public gr_sync_decimator { private: gr_goertzel_fc(); + +public: + void set_freq (float freq); + void set_rate (int rate); }; diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc index 59b76a6f0..834450436 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.cc @@ -58,8 +58,7 @@ gr_pfb_arb_resampler_ccf::gr_pfb_arb_resampler_ccf (float rate, process. */ d_int_rate = filter_size; - d_dec_rate = (unsigned int)floor(d_int_rate/rate); - d_flt_rate = (d_int_rate/rate) - d_dec_rate; + set_rate(rate); // Store the last filter between calls to work d_last_filter = 0; @@ -81,8 +80,6 @@ gr_pfb_arb_resampler_ccf::gr_pfb_arb_resampler_ccf (float rate, create_diff_taps(taps, dtaps); create_taps(taps, d_taps, d_filters); create_taps(dtaps, d_dtaps, d_diff_filters); - - set_relative_rate(rate); } gr_pfb_arb_resampler_ccf::~gr_pfb_arb_resampler_ccf () @@ -179,8 +176,8 @@ gr_pfb_arb_resampler_ccf::general_work (int noutput_items, j = d_last_filter; // produce output as long as we can and there are enough input samples - while((i < noutput_items) && (count < ninput_items[0]-1)) { - + int max_input = ninput_items[0]-(int)d_taps_per_filter; + while((i < noutput_items) && (count < max_input)) { // start j by wrapping around mod the number of channels while((j < d_int_rate) && (i < noutput_items)) { // Take the current filter and derivative filter output diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h index cf5a79d4e..2c36c95f9 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.h @@ -161,7 +161,12 @@ public: * Print all of the filterbank taps to screen. */ void print_taps(); - + void set_rate (float rate) { + d_dec_rate = (unsigned int)floor(d_int_rate/rate); + d_flt_rate = (d_int_rate/rate) - d_dec_rate; + set_relative_rate(rate); + } + int general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i index 4f07af861..77f28acdf 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i +++ b/gnuradio-core/src/lib/filter/gr_pfb_arb_resampler_ccf.i @@ -38,4 +38,5 @@ class gr_pfb_arb_resampler_ccf : public gr_block //void set_taps (const std::vector<float> &taps); void print_taps(); + void set_rate (float rate); }; diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc index 937899c0d..b5a5aed7d 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2009,2010 Free Software Foundation, Inc. + * Copyright 2009-2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -33,39 +33,47 @@ #include <gr_io_signature.h> #include <gr_math.h> -gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain, +gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float loop_bw, const std::vector<float> &taps, unsigned int filter_size, float init_phase, - float max_rate_deviation) + float max_rate_deviation, + int osps) { - return gnuradio::get_initial_sptr(new gr_pfb_clock_sync_ccf (sps, gain, taps, - filter_size, - init_phase, - max_rate_deviation)); + return gnuradio::get_initial_sptr(new gr_pfb_clock_sync_ccf (sps, loop_bw, taps, + filter_size, + init_phase, + max_rate_deviation, + osps)); } static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(float)}; static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int)); -gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (double sps, float gain, +gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (double sps, float loop_bw, const std::vector<float> &taps, unsigned int filter_size, float init_phase, - float max_rate_deviation) + float max_rate_deviation, + int osps) : gr_block ("pfb_clock_sync_ccf", gr_make_io_signature (1, 1, sizeof(gr_complex)), gr_make_io_signaturev (1, 4, iosig)), d_updated (false), d_nfilters(filter_size), - d_max_dev(max_rate_deviation) + d_max_dev(max_rate_deviation), + d_osps(osps) { d_nfilters = filter_size; d_sps = floor(sps); + // Set the damping factor for a critically damped system + d_damping = sqrtf(2.0f)/2.0f; + + // Set the bandwidth, which will then call update_gains() + set_loop_bandwidth(loop_bw); + // Store the last filter between calls to work // The accumulator keeps track of overflow to increment the stride correctly. // set it here to the fractional difference based on the initial phaes - set_alpha(gain); - set_beta(0.25*gain*gain); d_k = init_phase; d_rate = (sps-floor(sps))*(double)d_nfilters; d_rate_i = (int)floor(d_rate); @@ -103,6 +111,94 @@ gr_pfb_clock_sync_ccf::check_topology(int ninputs, int noutputs) return noutputs == 1 || noutputs == 4; } + + +/******************************************************************* + SET FUNCTIONS +*******************************************************************/ + + +void +gr_pfb_clock_sync_ccf::set_loop_bandwidth(float bw) +{ + if(bw < 0) { + throw std::out_of_range ("gr_pfb_clock_sync_cc: invalid bandwidth. Must be >= 0."); + } + + d_loop_bw = bw; + update_gains(); +} + +void +gr_pfb_clock_sync_ccf::set_damping_factor(float df) +{ + if(df < 0 || df > 1.0) { + throw std::out_of_range ("gr_pfb_clock_sync_cc: invalid damping factor. Must be in [0,1]."); + } + + d_damping = df; + update_gains(); +} + +void +gr_pfb_clock_sync_ccf::set_alpha(float alpha) +{ + if(alpha < 0 || alpha > 1.0) { + throw std::out_of_range ("gr_pfb_clock_sync_cc: invalid alpha. Must be in [0,1]."); + } + d_alpha = alpha; +} + +void +gr_pfb_clock_sync_ccf::set_beta(float beta) +{ + if(beta < 0 || beta > 1.0) { + throw std::out_of_range ("gr_pfb_clock_sync_cc: invalid beta. Must be in [0,1]."); + } + d_beta = beta; +} + +/******************************************************************* + GET FUNCTIONS +*******************************************************************/ + + +float +gr_pfb_clock_sync_ccf::get_loop_bandwidth() const +{ + return d_loop_bw; +} + +float +gr_pfb_clock_sync_ccf::get_damping_factor() const +{ + return d_damping; +} + +float +gr_pfb_clock_sync_ccf::get_alpha() const +{ + return d_alpha; +} + +float +gr_pfb_clock_sync_ccf::get_beta() const +{ + return d_beta; +} + +/******************************************************************* +*******************************************************************/ + +void +gr_pfb_clock_sync_ccf::update_gains() +{ + float denom = (1.0 + 2.0*d_damping*d_loop_bw + d_loop_bw*d_loop_bw); + d_alpha = (4*d_damping*d_loop_bw) / denom; + d_beta = (4*d_loop_bw*d_loop_bw) / denom; +} + + void gr_pfb_clock_sync_ccf::set_taps (const std::vector<float> &newtaps, std::vector< std::vector<float> > &ourtaps, @@ -127,13 +223,16 @@ gr_pfb_clock_sync_ccf::set_taps (const std::vector<float> &newtaps, // Partition the filter for(i = 0; i < d_nfilters; i++) { // Each channel uses all d_taps_per_filter with 0's if not enough taps to fill out - ourtaps[d_nfilters-1-i] = std::vector<float>(d_taps_per_filter, 0); + //ourtaps[d_nfilters-1-i] = std::vector<float>(d_taps_per_filter, 0); + ourtaps[i] = std::vector<float>(d_taps_per_filter, 0); for(j = 0; j < d_taps_per_filter; j++) { - ourtaps[d_nfilters - 1 - i][j] = tmp_taps[i + j*d_nfilters]; + //ourtaps[d_nfilters - 1 - i][j] = tmp_taps[i + j*d_nfilters]; + ourtaps[i][j] = tmp_taps[i + j*d_nfilters]; } // Build a filter for each channel and add it's taps to it - ourfilter[i]->set_taps(ourtaps[d_nfilters-1-i]); + //ourfilter[i]->set_taps(ourtaps[d_nfilters-1-i]); + ourfilter[i]->set_taps(ourtaps[i]); } // Set the history to ensure enough input items for each filter @@ -146,58 +245,84 @@ void gr_pfb_clock_sync_ccf::create_diff_taps(const std::vector<float> &newtaps, std::vector<float> &difftaps) { - float maxtap = 1e-20; - difftaps.clear(); - difftaps.push_back(0); //newtaps[0]); - for(unsigned int i = 1; i < newtaps.size()-1; i++) { - float tap = newtaps[i+1] - newtaps[i-1]; - difftaps.push_back(tap); - if(tap > maxtap) { - maxtap = tap; + std::vector<float> diff_filter(3); + diff_filter[0] = -1; + diff_filter[1] = 0; + diff_filter[2] = 1; + + float pwr = 0; + difftaps.push_back(0); + for(unsigned int i = 0; i < newtaps.size()-2; i++) { + float tap = 0; + for(int j = 0; j < 3; j++) { + tap += diff_filter[j]*newtaps[i+j]; + pwr += fabsf(tap); } + difftaps.push_back(tap); } - difftaps.push_back(0);//-newtaps[newtaps.size()-1]); + difftaps.push_back(0); - // Scale the differential taps; helps scale error term to better update state - // FIXME: should this be scaled this way or use the same gain as the taps? for(unsigned int i = 0; i < difftaps.size(); i++) { - difftaps[i] /= maxtap; + difftaps[i] *= pwr; } } -void -gr_pfb_clock_sync_ccf::print_taps() +std::string +gr_pfb_clock_sync_ccf::get_taps_as_string() { int i, j; - printf("[ "); + std::stringstream str; + str.precision(4); + str.setf(std::ios::scientific); + + str << "[ "; for(i = 0; i < d_nfilters; i++) { - printf("[%.4e, ", d_taps[i][0]); + str << "[" << d_taps[i][0] << ", "; for(j = 1; j < d_taps_per_filter-1; j++) { - printf("%.4e,", d_taps[i][j]); + str << d_taps[i][j] << ", "; } - printf("%.4e],", d_taps[i][j]); + str << d_taps[i][j] << "],"; } - printf(" ]\n"); + str << " ]" << std::endl; + + return str.str(); } -void -gr_pfb_clock_sync_ccf::print_diff_taps() +std::string +gr_pfb_clock_sync_ccf::get_diff_taps_as_string() { int i, j; - printf("[ "); + std::stringstream str; + str.precision(4); + str.setf(std::ios::scientific); + + str << "[ "; for(i = 0; i < d_nfilters; i++) { - printf("[%.4e, ", d_dtaps[i][0]); + str << "[" << d_dtaps[i][0] << ", "; for(j = 1; j < d_taps_per_filter-1; j++) { - printf("%.4e,", d_dtaps[i][j]); + str << d_dtaps[i][j] << ", "; } - printf("%.4e],", d_dtaps[i][j]); + str << d_dtaps[i][j] << "],"; } - printf(" ]\n"); + str << " ]" << std::endl; + + return str.str(); } +std::vector< std::vector<float> > +gr_pfb_clock_sync_ccf::get_taps() +{ + return d_taps; +} + +std::vector< std::vector<float> > +gr_pfb_clock_sync_ccf::get_diff_taps() +{ + return d_dtaps; +} std::vector<float> -gr_pfb_clock_sync_ccf::channel_taps(int channel) +gr_pfb_clock_sync_ccf::get_channel_taps(int channel) { std::vector<float> taps; for(int i = 0; i < d_taps_per_filter; i++) { @@ -207,7 +332,7 @@ gr_pfb_clock_sync_ccf::channel_taps(int channel) } std::vector<float> -gr_pfb_clock_sync_ccf::diff_channel_taps(int channel) +gr_pfb_clock_sync_ccf::get_diff_channel_taps(int channel) { std::vector<float> taps; for(int i = 0; i < d_taps_per_filter; i++) { @@ -226,7 +351,7 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, gr_complex *in = (gr_complex *) input_items[0]; gr_complex *out = (gr_complex *) output_items[0]; - float *err = 0, *outrate = 0, *outk = 0; + float *err = NULL, *outrate = NULL, *outk = NULL; if(output_items.size() == 4) { err = (float *) output_items[1]; outrate = (float*)output_items[2]; @@ -239,13 +364,13 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, } // We need this many to process one output - int nrequired = ninput_items[0] - d_taps_per_filter; + int nrequired = ninput_items[0] - d_taps_per_filter - d_osps; int i = 0, count = 0; float error, error_r, error_i; // produce output as long as we can and there are enough input samples - while((i < noutput_items) && (count < nrequired)) { + while((i < noutput_items-d_osps) && (count < nrequired)) { d_filtnum = (int)floor(d_k); // Keep the current filter number in [0, d_nfilters] @@ -262,27 +387,33 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, count -= 1; } - out[i] = d_filters[d_filtnum]->filter(&in[count]); + for(int k = 0; k < d_osps; k++) { + out[i+k] = d_filters[d_filtnum]->filter(&in[count+k]); + } + gr_complex diff = d_diff_filters[d_filtnum]->filter(&in[count]); - error_r = out[i].real() * diff.real(); - error_i = out[i].imag() * diff.imag(); + error_r = out[i].real() * diff.real(); + error_i = out[i].imag() * diff.imag(); error = (error_i + error_r) / 2.0; // average error from I&Q channel // Run the control loop to update the current phase (k) and tracking rate - d_k = d_k + d_alpha*error + d_rate_i + d_rate_f; d_rate_f = d_rate_f + d_beta*error; + d_k = d_k + d_alpha*error + d_rate_i + d_rate_f; // Keep our rate within a good range d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev); - i++; - count += (int)floor(d_sps); - if(output_items.size() == 4) { - err[i] = error; - outrate[i] = d_rate_f; - outk[i] = d_k; + // FIXME: don't really know what to do about d_osps>1 + for(int k = 0; k < d_osps; k++) { + err[i] = diff.real(); + outrate[i] = d_rate_f; + outk[i] = d_k; + } } + + i+=d_osps; + count += (int)floor(d_sps); } consume_each(count); diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h index 4e6ef5fc4..0909220e0 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h @@ -28,11 +28,12 @@ class gr_pfb_clock_sync_ccf; typedef boost::shared_ptr<gr_pfb_clock_sync_ccf> gr_pfb_clock_sync_ccf_sptr; -gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain, +gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float loop_bw, const std::vector<float> &taps, unsigned int filter_size=32, float init_phase=0, - float max_rate_deviation=1.5); + float max_rate_deviation=1.5, + int osps=1); class gr_fir_ccf; @@ -47,7 +48,7 @@ class gr_fir_ccf; * derivative of the filtered signal, which in turn maximizes the SNR and * minimizes ISI. * - * This approach works by setting up two filterbanks; one filterbanke contains the + * This approach works by setting up two filterbanks; one filterbank contains the * signal's pulse shaping matched filter (such as a root raised cosine filter), * where each branch of the filterbank contains a different phase of the filter. * The second filterbank contains the derivatives of the filters in the first @@ -84,8 +85,8 @@ class gr_fir_ccf; * the block constructor, we just ask for "gain," which is d_alpha while d_beta is * equal to (gain^2)/4. * - * The clock sync block needs to know the number of samples per second (sps), because it - * only returns a single point representing the sample. The sps can be any positive real + * The clock sync block needs to know the number of samples per symbol (sps), because it + * only returns a single point representing the symbol. The sps can be any positive real * number and does not need to be an integer. The filter taps must also be specified. The * taps are generated by first conceiving of the prototype filter that would be the signal's * matched filter. Then interpolate this by the number of filters in the filterbank. These @@ -115,8 +116,8 @@ class gr_pfb_clock_sync_ccf : public gr_block private: /*! * Build the polyphase filterbank timing synchronizer. - * \param sps (double) The number of samples per second in the incoming signal - * \param gain (float) The alpha gain of the control loop; beta = (gain^2)/4 by default. + * \param sps (double) The number of samples per symbol in the incoming signal + * \param loop_bw (float) The bandwidth of the control loop; set's alpha and beta. * \param taps (vector<int>) The filter taps. * \param filter_size (uint) The number of filters in the filterbank (default = 32). * \param init_phase (float) The initial phase to look at, or which filter to start @@ -124,44 +125,60 @@ class gr_pfb_clock_sync_ccf : public gr_block * \param max_rate_deviation (float) Distance from 0 d_rate can get (default = 1.5). * */ - friend gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain, + friend gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float loop_bw, const std::vector<float> &taps, unsigned int filter_size, float init_phase, - float max_rate_deviation); - - bool d_updated; - double d_sps; - double d_sample_num; - float d_alpha; - float d_beta; - int d_nfilters; - std::vector<gr_fir_ccf*> d_filters; - std::vector<gr_fir_ccf*> d_diff_filters; + float max_rate_deviation, + int osps); + + bool d_updated; + double d_sps; + double d_sample_num; + float d_loop_bw; + float d_damping; + float d_alpha; + float d_beta; + + int d_nfilters; + int d_taps_per_filter; + std::vector<gr_fir_ccf*> d_filters; + std::vector<gr_fir_ccf*> d_diff_filters; std::vector< std::vector<float> > d_taps; std::vector< std::vector<float> > d_dtaps; - float d_k; - float d_rate; - float d_rate_i; - float d_rate_f; - float d_max_dev; - int d_filtnum; - int d_taps_per_filter; + + float d_k; + float d_rate; + float d_rate_i; + float d_rate_f; + float d_max_dev; + int d_filtnum; + int d_osps; /*! * Build the polyphase filterbank timing synchronizer. */ - gr_pfb_clock_sync_ccf (double sps, float gain, + gr_pfb_clock_sync_ccf (double sps, float loop_bw, const std::vector<float> &taps, unsigned int filter_size, float init_phase, - float max_rate_deviation); + float max_rate_deviation, + int osps); void create_diff_taps(const std::vector<float> &newtaps, std::vector<float> &difftaps); public: ~gr_pfb_clock_sync_ccf (); + + /*! \brief update the system gains from omega and eta + * + * This function updates the system gains based on the loop + * bandwidth and damping factor of the system. + * These two factors can be set separately through their own + * set functions. + */ + void update_gains(); /*! * Resets the filterbank's filter taps with the new prototype filter @@ -171,40 +188,97 @@ public: std::vector<gr_fir_ccf*> &ourfilter); /*! - * Returns the taps of the matched filter + * Returns all of the taps of the matched filter */ - std::vector<float> channel_taps(int channel); + std::vector< std::vector<float> > get_taps(); /*! - * Returns the taps in the derivative filter + * Returns all of the taps of the derivative filter */ - std::vector<float> diff_channel_taps(int channel); + std::vector< std::vector<float> > get_diff_taps(); /*! - * Print all of the filterbank taps to screen. + * Returns the taps of the matched filter for a particular channel */ - void print_taps(); + std::vector<float> get_channel_taps(int channel); /*! - * Print all of the filterbank taps of the derivative filter to screen. + * Returns the taps in the derivative filter for a particular channel */ - void print_diff_taps(); + std::vector<float> get_diff_channel_taps(int channel); /*! - * Set the gain value alpha for the control loop - */ - void set_alpha(float alpha) - { - d_alpha = alpha; - } + * Return the taps as a formatted string for printing + */ + std::string get_taps_as_string(); /*! - * Set the gain value beta for the control loop - */ - void set_beta(float beta) - { - d_beta = beta; - } + * Return the derivative filter taps as a formatted string for printing + */ + std::string get_diff_taps_as_string(); + + + /******************************************************************* + SET FUNCTIONS + *******************************************************************/ + + + /*! + * \brief Set the loop bandwidth + * + * Set the loop filter's bandwidth to \p bw. This should be between + * 2*pi/200 and 2*pi/100 (in rads/samp). It must also be a positive + * number. + * + * When a new damping factor is set, the gains, alpha and beta, of the loop + * are recalculated by a call to update_gains(). + * + * \param bw (float) new bandwidth + * + */ + void set_loop_bandwidth(float bw); + + /*! + * \brief Set the loop damping factor + * + * Set the loop filter's damping factor to \p df. The damping factor + * should be sqrt(2)/2.0 for critically damped systems. + * Set it to anything else only if you know what you are doing. It must + * be a number between 0 and 1. + * + * When a new damping factor is set, the gains, alpha and beta, of the loop + * are recalculated by a call to update_gains(). + * + * \param df (float) new damping factor + * + */ + void set_damping_factor(float df); + + /*! + * \brief Set the loop gain alpha + * + * Set's the loop filter's alpha gain parameter. + * + * This value should really only be set by adjusting the loop bandwidth + * and damping factor. + * + * \param alpha (float) new alpha gain + * + */ + void set_alpha(float alpha); + + /*! + * \brief Set the loop gain beta + * + * Set's the loop filter's beta gain parameter. + * + * This value should really only be set by adjusting the loop bandwidth + * and damping factor. + * + * \param beta (float) new beta gain + * + */ + void set_beta(float beta); /*! * Set the maximum deviation from 0 d_rate can have @@ -214,6 +288,33 @@ public: d_max_dev = m; } + /******************************************************************* + GET FUNCTIONS + *******************************************************************/ + + /*! + * \brief Returns the loop bandwidth + */ + float get_loop_bandwidth() const; + + /*! + * \brief Returns the loop damping factor + */ + float get_damping_factor() const; + + /*! + * \brief Returns the loop gain alpha + */ + float get_alpha() const; + + /*! + * \brief Returns the loop gain beta + */ + float get_beta() const; + + /******************************************************************* + *******************************************************************/ + bool check_topology(int ninputs, int noutputs); int general_work (int noutput_items, diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i index 197984287..78b9a6589 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i @@ -22,20 +22,22 @@ GR_SWIG_BLOCK_MAGIC(gr,pfb_clock_sync_ccf); -gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain, +gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float loop_bw, const std::vector<float> &taps, unsigned int filter_size=32, float init_phase=0, - float max_rate_deviation=1.5); + float max_rate_deviation=1.5, + int osps=1); class gr_pfb_clock_sync_ccf : public gr_block { private: - gr_pfb_clock_sync_ccf (double sps, float gain, + gr_pfb_clock_sync_ccf (double sps, float loop_bw, const std::vector<float> &taps, unsigned int filter_size, float init_phase, - float max_rate_deviation); + float max_rate_deviation, + int osps); public: ~gr_pfb_clock_sync_ccf (); @@ -44,11 +46,22 @@ class gr_pfb_clock_sync_ccf : public gr_block std::vector< std::vector<float> > &ourtaps, std::vector<gr_fir_ccf*> &ourfilter); - std::vector<float> channel_taps(int channel); - std::vector<float> diff_channel_taps(int channel); - void print_taps(); - void print_diff_taps(); + std::vector< std::vector<float> > get_taps(); + std::vector< std::vector<float> > get_diff_taps(); + std::vector<float> get_channel_taps(int channel); + std::vector<float> get_diff_channel_taps(int channel); + std::string get_taps_as_string(); + std::string get_diff_taps_as_string(); + + void set_loop_bandwidth(float bw); + void set_damping_factor(float df); void set_alpha(float alpha); void set_beta(float beta); void set_max_rate_deviation(float m); + + float get_loop_bandwidth() const; + float get_damping_factor() const; + float get_alpha() const; + float get_beta() const; + }; diff --git a/gnuradio-core/src/lib/filter/gr_single_pole_iir.h b/gnuradio-core/src/lib/filter/gr_single_pole_iir.h index da919b35c..8781065d4 100644 --- a/gnuradio-core/src/lib/filter/gr_single_pole_iir.h +++ b/gnuradio-core/src/lib/filter/gr_single_pole_iir.h @@ -71,7 +71,7 @@ public: d_prev_output = 0; } - o_type prev_output () { return d_prev_output; } + o_type prev_output () const { return d_prev_output; } protected: tap_type d_alpha; @@ -155,7 +155,7 @@ public: d_prev_output = 0; } - gr_complexd prev_output () { return d_prev_output; } + gr_complexd prev_output () const { return d_prev_output; } protected: double d_alpha; diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc index 1bf4a6f4b..891905dd0 100644 --- a/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc +++ b/gnuradio-core/src/lib/filter/gri_fft_filter_ccc_generic.cc @@ -99,7 +99,7 @@ gri_fft_filter_ccc_generic::compute_sizes(int ntaps) { int old_fftsize = d_fftsize; d_ntaps = ntaps; - d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2)))); + d_fftsize = (int) (2 * pow(2.0, ceil(log(double(ntaps)) / log(2.0)))); d_nsamples = d_fftsize - d_ntaps + 1; if (0) diff --git a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc index 74058fa93..b3fbe1d1a 100644 --- a/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc +++ b/gnuradio-core/src/lib/filter/gri_fft_filter_fff_generic.cc @@ -86,7 +86,7 @@ gri_fft_filter_fff_generic::compute_sizes(int ntaps) { int old_fftsize = d_fftsize; d_ntaps = ntaps; - d_fftsize = (int) (2 * pow(2.0, ceil(log(ntaps) / log(2)))); + d_fftsize = (int) (2 * pow(2.0, ceil(log(double(ntaps)) / log(2.0)))); d_nsamples = d_fftsize - d_ntaps + 1; if (0) diff --git a/gnuradio-core/src/lib/filter/gri_goertzel.cc b/gnuradio-core/src/lib/filter/gri_goertzel.cc index f0314e400..85e66c069 100644 --- a/gnuradio-core/src/lib/filter/gri_goertzel.cc +++ b/gnuradio-core/src/lib/filter/gri_goertzel.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002 Free Software Foundation, Inc. + * Copyright 2002,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,15 +26,21 @@ gri_goertzel::gri_goertzel(int rate, int len, float freq) { + gri_setparms(rate, len, freq); +} + +void +gri_goertzel::gri_setparms(int rate, int len, float freq) +{ d_d1 = 0.0; d_d2 = 0.0; float w = 2.0*M_PI*freq/rate; d_wr = 2.0*std::cos(w); d_wi = std::sin(w); - d_len = len; d_processed = 0; + } gr_complex gri_goertzel::batch(float *in) diff --git a/gnuradio-core/src/lib/filter/gri_goertzel.h b/gnuradio-core/src/lib/filter/gri_goertzel.h index 86d3d34d3..e062f000e 100644 --- a/gnuradio-core/src/lib/filter/gri_goertzel.h +++ b/gnuradio-core/src/lib/filter/gri_goertzel.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -34,6 +34,7 @@ class gri_goertzel public: gri_goertzel() {} gri_goertzel(int rate, int len, float freq); + void gri_setparms(int rate, int len, float freq); // Process a input array gr_complex batch(float *in); diff --git a/gnuradio-core/src/lib/filter/qa_gr_rotator.cc b/gnuradio-core/src/lib/filter/qa_gr_rotator.cc index ce71a3d88..ef41127fd 100644 --- a/gnuradio-core/src/lib/filter/qa_gr_rotator.cc +++ b/gnuradio-core/src/lib/filter/qa_gr_rotator.cc @@ -20,6 +20,11 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gruel/attributes.h> #include <cppunit/TestAssert.h> #include <qa_gr_rotator.h> #include <gr_rotator.h> @@ -29,7 +34,7 @@ // error vector magnitude -__attribute__((unused)) static float +__GR_ATTR_UNUSED static float error_vector_mag(gr_complex a, gr_complex b) { return abs(a-b); diff --git a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.cc b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.cc index e87d93ebf..ca76c8eb8 100644 --- a/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.cc +++ b/gnuradio-core/src/lib/filter/qa_gri_fir_filter_with_buffer_ccc.cc @@ -42,6 +42,7 @@ typedef gr_complex acc_type; using std::vector; +#define MAX_DATA (32767) #define ERR_DELTA (1e-5) #define NELEM(x) (sizeof (x) / sizeof (x[0])) @@ -56,8 +57,8 @@ static void random_complex (gr_complex *buf, unsigned n) { for (unsigned i = 0; i < n; i++){ - float re = rint (uniform () * 32767); - float im = rint (uniform () * 32767); + float re = rint (uniform () * MAX_DATA); + float im = rint (uniform () * MAX_DATA); buf[i] = gr_complex (re, im); } } @@ -151,7 +152,7 @@ qa_gri_fir_filter_with_buffer_ccc::test_decimate(unsigned int decimate) for (int o = 0; o < (int)(ol/decimate); o++){ CPPUNIT_ASSERT_COMPLEXES_EQUAL(expected_output[o], actual_output[o], - abs (expected_output[o]) * ERR_DELTA); + sqrt((float)n)*0.25*MAX_DATA*MAX_DATA * ERR_DELTA); } delete f1; } diff --git a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc index 3c379ea25..2fc97a78a 100644 --- a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc +++ b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator_cc.cc @@ -20,6 +20,11 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gruel/attributes.h> #include <cppunit/TestAssert.h> #include <qa_gri_mmse_fir_interpolator_cc.h> #include <gri_mmse_fir_interpolator_cc.h> @@ -55,7 +60,7 @@ void qa_gri_mmse_fir_interpolator_cc::t1() { static const unsigned N = 100; - gr_complex input[N + 10] __attribute__ ((aligned (8))); + __GR_ATTR_ALIGNED(8) gr_complex input[N + 10]; for (unsigned i = 0; i < NELEM(input); i++) input[i] = test_fcn ((double) i); diff --git a/gnuradio-core/src/lib/g72x/Makefile.am b/gnuradio-core/src/lib/g72x/Makefile.am index 6c41f1911..d2700376f 100644 --- a/gnuradio-core/src/lib/g72x/Makefile.am +++ b/gnuradio-core/src/lib/g72x/Makefile.am @@ -24,4 +24,4 @@ include $(top_srcdir)/Makefile.common noinst_LTLIBRARIES = libccitt.la libccitt_la_SOURCES = g711.c g72x.c g721.c g723_24.c g723_40.c g72x.h -EXTRA_DIST = encode.c decode.c +EXTRA_DIST += encode.c decode.c diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am index de1df9ffc..fe545f98c 100644 --- a/gnuradio-core/src/lib/general/Makefile.am +++ b/gnuradio-core/src/lib/general/Makefile.am @@ -21,7 +21,9 @@ include $(top_srcdir)/Makefile.common -AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) +# $(WITH_INCLUDES) must _always_ be last +AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) \ + $(FFTW3F_CPPFLAGS) $(GSL_CPPFLAGS) $(WITH_INCLUDES) noinst_LTLIBRARIES = libgeneral.la libgeneral-qa.la @@ -29,11 +31,12 @@ BUILT_SOURCES = # ---------------------------------------------------------------- -EXTRA_DIST = \ +EXTRA_DIST += \ gen_sine_table.py \ gr_constants.cc.in libgeneral_la_SOURCES = \ + complex_vec_test.cc \ gr_additive_scrambler_bb.cc \ gr_agc_cc.cc \ gr_agc_ff.cc \ @@ -41,25 +44,18 @@ libgeneral_la_SOURCES = \ gr_agc2_ff.cc \ gr_align_on_samplenumbers_ss.cc \ gr_bin_statistics_f.cc \ - gr_binary_slicer_fb.cc \ gr_bytes_to_syms.cc \ gr_char_to_float.cc \ gr_check_counting_s.cc \ gr_check_lfsr_32k_s.cc \ gr_circular_file.cc \ - gr_clock_recovery_mm_cc.cc \ - gr_clock_recovery_mm_ff.cc \ gr_complex_to_interleaved_short.cc \ gr_complex_to_xxx.cc \ gr_conjugate_cc.cc \ gr_copy.cc \ - gr_constellation_decoder_cb.cc \ - gr_correlate_access_code_bb.cc \ - gr_costas_loop_cc.cc \ gr_count_bits.cc \ gr_cpfsk_bc.cc \ gr_cpm.cc \ - gr_crc32.cc \ gr_ctcss_squelch_ff.cc \ gr_decode_ccsds_27_fb.cc \ gr_deinterleave.cc \ @@ -77,7 +73,6 @@ libgeneral_la_SOURCES = \ gr_fft_vcc_fftw.cc \ gr_fft_vfc.cc \ gr_firdes.cc \ - gr_fll_band_edge_cc.cc \ gr_float_to_char.cc \ gr_float_to_complex.cc \ gr_float_to_short.cc \ @@ -95,12 +90,8 @@ libgeneral_la_SOURCES = \ gr_keep_one_in_n.cc \ gr_kludge_copy.cc \ gr_lfsr_32k_source_s.cc \ - gr_lms_dfe_cc.cc \ - gr_lms_dfe_ff.cc \ gr_map_bb.cc \ - gr_math.cc \ gr_misc.cc \ - gr_mpsk_receiver_cc.cc \ gr_nlog10_ff.cc \ gr_nop.cc \ gr_null_sink.cc \ @@ -138,6 +129,7 @@ libgeneral_la_SOURCES = \ gr_rms_cf.cc \ gr_rms_ff.cc \ gr_short_to_float.cc \ + gr_int_to_float.cc \ gr_simple_correlator.cc \ gr_simple_framer.cc \ gr_simple_squelch_cc.cc \ @@ -162,6 +154,7 @@ libgeneral_la_SOURCES = \ gr_wvps_ff.cc \ gri_add_const_ss_generic.cc \ gri_char_to_float.cc \ + gri_control_loop.cc \ gri_debugger_hook.cc \ gri_fft.cc \ gri_float_to_char.cc \ @@ -176,7 +169,10 @@ libgeneral_la_SOURCES = \ gr_descrambler_bb.cc \ gr_scrambler_bb.cc \ gr_probe_mpsk_snr_c.cc \ - gr_probe_density_b.cc + gr_probe_density_b.cc \ + gr_annotator_alltoall.cc \ + gr_annotator_1to1.cc \ + gr_burst_tagger.cc libgeneral_qa_la_SOURCES = \ qa_general.cc \ @@ -190,6 +186,7 @@ libgeneral_qa_la_SOURCES = \ qa_gri_lfsr.cc grinclude_HEADERS = \ + complex_vec_test.h \ gr_additive_scrambler_bb.h \ gr_agc_cc.h \ gr_agc_ff.h \ @@ -197,25 +194,18 @@ grinclude_HEADERS = \ gr_agc2_ff.h \ gr_align_on_samplenumbers_ss.h \ gr_bin_statistics_f.h \ - gr_binary_slicer_fb.h \ gr_bytes_to_syms.h \ gr_char_to_float.h \ gr_check_counting_s.h \ gr_check_lfsr_32k_s.h \ gr_circular_file.h \ - gr_clock_recovery_mm_cc.h \ - gr_clock_recovery_mm_ff.h \ gr_complex_to_interleaved_short.h \ gr_complex_to_xxx.h \ gr_conjugate_cc.h \ - gr_constellation_decoder_cb.h \ gr_copy.h \ - gr_correlate_access_code_bb.h \ - gr_costas_loop_cc.h \ gr_count_bits.h \ gr_cpfsk_bc.h \ gr_cpm.h \ - gr_crc32.h \ gr_ctcss_squelch_ff.h \ gr_decode_ccsds_27_fb.h \ gr_diff_decoder_bb.h \ @@ -233,7 +223,6 @@ grinclude_HEADERS = \ gr_fft_vcc_fftw.h \ gr_fft_vfc.h \ gr_firdes.h \ - gr_fll_band_edge_cc.h \ gr_float_to_char.h \ gr_float_to_complex.h \ gr_float_to_short.h \ @@ -253,13 +242,10 @@ grinclude_HEADERS = \ gr_keep_one_in_n.h \ gr_kludge_copy.h \ gr_lfsr_32k_source_s.h \ - gr_lms_dfe_cc.h \ - gr_lms_dfe_ff.h \ gr_log2_const.h \ gr_map_bb.h \ gr_math.h \ gr_misc.h \ - gr_mpsk_receiver_cc.h \ gr_nco.h \ gr_nlog10_ff.h \ gr_nop.h \ @@ -298,6 +284,7 @@ grinclude_HEADERS = \ gr_rms_cf.h \ gr_rms_ff.h \ gr_short_to_float.h \ + gr_int_to_float.h \ gr_simple_correlator.h \ gr_simple_framer.h \ gr_simple_framer_sync.h \ @@ -329,6 +316,7 @@ grinclude_HEADERS = \ gri_agc2_cc.h \ gri_agc2_ff.h \ gri_char_to_float.h \ + gri_control_loop.h \ gri_debugger_hook.h \ gri_fft.h \ gri_float_to_char.h \ @@ -347,7 +335,10 @@ grinclude_HEADERS = \ gr_descrambler_bb.h \ gr_scrambler_bb.h \ gr_probe_mpsk_snr_c.h \ - gr_probe_density_b.h + gr_probe_density_b.h \ + gr_annotator_alltoall.h \ + gr_annotator_1to1.h \ + gr_burst_tagger.h noinst_HEADERS = \ qa_general.h \ @@ -361,8 +352,8 @@ noinst_HEADERS = \ sine_table.h \ qa_gr_math.h -if PYTHON swiginclude_HEADERS = \ + complex_vec_test.i \ general.i \ gr_additive_scrambler_bb.i \ gr_agc_cc.i \ @@ -371,23 +362,16 @@ swiginclude_HEADERS = \ gr_agc2_ff.i \ gr_align_on_samplenumbers_ss.i \ gr_bin_statistics_f.i \ - gr_binary_slicer_fb.i \ gr_bytes_to_syms.i \ gr_char_to_float.i \ gr_check_counting_s.i \ gr_check_lfsr_32k_s.i \ - gr_clock_recovery_mm_cc.i \ - gr_clock_recovery_mm_ff.i \ gr_complex_to_interleaved_short.i \ gr_complex_to_xxx.i \ gr_conjugate_cc.i \ - gr_constellation_decoder_cb.i \ gr_copy.i \ - gr_correlate_access_code_bb.i \ - gr_costas_loop_cc.i \ gr_cpfsk_bc.i \ gr_cpm.i \ - gr_crc32.i \ gr_ctcss_squelch_ff.i \ gr_decode_ccsds_27_fb.i \ gr_diff_decoder_bb.i \ @@ -403,7 +387,6 @@ swiginclude_HEADERS = \ gr_fft_vcc.i \ gr_fft_vfc.i \ gr_firdes.i \ - gr_fll_band_edge_cc.i \ gr_float_to_char.i \ gr_float_to_complex.i \ gr_float_to_short.i \ @@ -414,16 +397,14 @@ swiginclude_HEADERS = \ gr_glfsr_source_b.i \ gr_glfsr_source_f.i \ gr_head.i \ + gr_int_to_float.i \ gr_interleave.i \ gr_interleaved_short_to_complex.i \ gr_iqcomp_cc.i \ gr_keep_one_in_n.i \ gr_kludge_copy.i \ gr_lfsr_32k_source_s.i \ - gr_lms_dfe_cc.i \ - gr_lms_dfe_ff.i \ gr_map_bb.i \ - gr_mpsk_receiver_cc.i \ gr_nlog10_ff.i \ gr_nop.i \ gr_null_sink.i \ @@ -486,8 +467,11 @@ swiginclude_HEADERS = \ gri_agc_ff.i \ gri_agc2_cc.i \ gri_agc2_ff.i \ + gri_control_loop.i \ gr_descrambler_bb.i \ gr_scrambler_bb.i \ gr_probe_mpsk_snr_c.i \ - gr_probe_density_b.i -endif + gr_probe_density_b.i \ + gr_annotator_alltoall.i \ + gr_annotator_1to1.i \ + gr_burst_tagger.i diff --git a/gnuradio-core/src/lib/general/complex_vec_test.cc b/gnuradio-core/src/lib/general/complex_vec_test.cc new file mode 100644 index 000000000..df25c325e --- /dev/null +++ b/gnuradio-core/src/lib/general/complex_vec_test.cc @@ -0,0 +1,82 @@ +#include <complex_vec_test.h> +#include <stddef.h> + +std::vector<std::complex<float> > +complex_vec_test0() +{ + std::vector<std::complex<float> > r(5); + + for (size_t i = 0; i < r.size(); i++) + r[i] = std::complex<float>(i, i); + + return r; +} + +std::vector<std::complex<float> > +complex_vec_test1(const std::vector<std::complex<float> > &input) +{ + std::vector<std::complex<float> > r(input.size()); + + for (size_t i = 0; i < input.size(); i++) + r[i] = std::complex<float>(input[i].real()+0.5, input[i].imag()-0.5); + + return r; +} + +std::complex<float> +complex_scalar_test0() +{ + return std::complex<float>(5, 5); +} + +std::complex<float> +complex_scalar_test1(std::complex<float> input) +{ + return std::complex<float>(input.real()+0.5, input.imag()-0.5); +} + + +std::vector<float> +float_vec_test0() +{ + std::vector<float> r(5); + + for (size_t i = 0; i < r.size(); i++) + r[i] = (float) i; + + return r; +} + +std::vector<float> +float_vec_test1(const std::vector<float> &input) +{ + std::vector<float> r(input.size()); + + for (size_t i = 0; i < input.size(); i++) + r[i] = input[i] + 0.5; + + return r; +} + +std::vector<int> +int_vec_test0() +{ + std::vector<int> r(5); + + for (size_t i = 0; i < r.size(); i++) + r[i] = (int) i; + + return r; +} + +std::vector<int> +int_vec_test1(const std::vector<int> &input) +{ + std::vector<int> r(input.size()); + + for (size_t i = 0; i < input.size(); i++) + r[i] = input[i] + 1; + + return r; +} + diff --git a/gnuradio-core/src/lib/general/complex_vec_test.h b/gnuradio-core/src/lib/general/complex_vec_test.h new file mode 100644 index 000000000..d13dedf63 --- /dev/null +++ b/gnuradio-core/src/lib/general/complex_vec_test.h @@ -0,0 +1,27 @@ +#include <vector> +#include <complex> + +std::vector<std::complex<float> > +complex_vec_test0(); + +std::vector<std::complex<float> > +complex_vec_test1(const std::vector<std::complex<float> > &input); + +std::complex<float> +complex_scalar_test0(); + +std::complex<float> +complex_scalar_test1(std::complex<float> input); + +std::vector<int> +int_vec_test0(); + +std::vector<int> +int_vec_test1(const std::vector<int> &input); + +std::vector<float> +float_vec_test0(); + +std::vector<float> +float_vec_test1(const std::vector<float> &input); + diff --git a/gnuradio-core/src/lib/general/complex_vec_test.i b/gnuradio-core/src/lib/general/complex_vec_test.i new file mode 100644 index 000000000..4b95633be --- /dev/null +++ b/gnuradio-core/src/lib/general/complex_vec_test.i @@ -0,0 +1,25 @@ + +std::vector<std::complex<float> > +complex_vec_test0(); + +std::vector<std::complex<float> > +complex_vec_test1(const std::vector<std::complex<float> > &input); + +std::complex<float> +complex_scalar_test0(); + +std::complex<float> +complex_scalar_test1(std::complex<float> input); + +std::vector<int> +int_vec_test0(); + +std::vector<int> +int_vec_test1(const std::vector<int> &input); + +std::vector<float> +float_vec_test0(); + +std::vector<float> +float_vec_test1(const std::vector<float> &input); + diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index 8c7f31c62..e965eea64 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -22,6 +22,7 @@ %{ +#include <gri_control_loop.h> #include <gr_nop.h> #include <gr_null_sink.h> #include <gr_null_source.h> @@ -42,6 +43,7 @@ #include <gr_float_to_char.h> #include <gr_float_to_uchar.h> #include <gr_short_to_float.h> +#include <gr_int_to_float.h> #include <gr_char_to_float.h> #include <gr_uchar_to_float.h> #include <gr_frequency_modulator_fc.h> @@ -53,7 +55,7 @@ #include <gr_complex_to_xxx.h> #include <gr_complex_to_interleaved_short.h> #include <gr_interleaved_short_to_complex.h> -#include <gr_endianness.h> +//#include <gr_endianness.h> #include <gr_firdes.h> #include <gr_interleave.h> #include <gr_deinterleave.h> @@ -68,7 +70,6 @@ #include <gr_nlog10_ff.h> #include <gr_fake_channel_coder_pp.h> #include <gr_throttle.h> -#include <gr_mpsk_receiver_cc.h> #include <gr_stream_mux.h> #include <gr_stream_to_streams.h> #include <gr_streams_to_stream.h> @@ -76,13 +77,8 @@ #include <gr_vector_to_streams.h> #include <gr_conjugate_cc.h> #include <gr_vco_f.h> -#include <gr_crc32.h> #include <gr_threshold_ff.h> -#include <gr_clock_recovery_mm_ff.h> -#include <gr_clock_recovery_mm_cc.h> #include <gr_packet_sink.h> -#include <gr_lms_dfe_cc.h> -#include <gr_lms_dfe_ff.h> #include <gr_dpll_bb.h> #include <gr_fmdet_cf.h> #include <gr_pll_freqdet_cf.h> @@ -97,10 +93,10 @@ #include <gr_ofdm_cyclic_prefixer.h> #include <gr_ofdm_mapper_bcv.h> #include <gr_ofdm_frame_sink.h> + //#include <gr_ofdm_frame_sink2.h> #include <gr_ofdm_insert_preamble.h> #include <gr_ofdm_sampler.h> #include <gr_regenerate_bb.h> -#include <gr_costas_loop_cc.h> #include <gr_pa_2x2_phase_combiner.h> #include <gr_kludge_copy.h> #include <gr_prefs.h> @@ -108,10 +104,7 @@ #include <gr_test_types.h> #include <gr_test.h> #include <gr_unpack_k_bits_bb.h> -#include <gr_correlate_access_code_bb.h> #include <gr_diff_phasor_cc.h> -#include <gr_constellation_decoder_cb.h> -#include <gr_binary_slicer_fb.h> #include <gr_diff_encoder_bb.h> #include <gr_diff_decoder_bb.h> #include <gr_framer_sink_1.h> @@ -139,11 +132,15 @@ #include <gr_wavelet_ff.h> #include <gr_wvps_ff.h> #include <gr_copy.h> -#include <gr_fll_band_edge_cc.h> #include <gr_additive_scrambler_bb.h> +#include <complex_vec_test.h> +#include <gr_annotator_alltoall.h> +#include <gr_annotator_1to1.h> +#include <gr_burst_tagger.h> #include <gr_cpm.h> %} +%include "gri_control_loop.i" %include "gr_nop.i" %include "gr_null_sink.i" %include "gr_null_source.i" @@ -164,6 +161,7 @@ %include "gr_float_to_char.i" %include "gr_float_to_uchar.i" %include "gr_short_to_float.i" +%include "gr_int_to_float.i" %include "gr_char_to_float.i" %include "gr_uchar_to_float.i" %include "gr_frequency_modulator_fc.i" @@ -174,7 +172,7 @@ %include "gr_align_on_samplenumbers_ss.i" %include "gr_complex_to_xxx.i" %include "gr_complex_to_interleaved_short.i" -%include "gr_endianness.i" +//%include "gr_endianness.i" %include "gr_interleaved_short_to_complex.i" %include "gr_firdes.i" %include "gr_interleave.i" @@ -190,7 +188,6 @@ %include "gr_nlog10_ff.i" %include "gr_fake_channel_coder_pp.i" %include "gr_throttle.i" -%include "gr_mpsk_receiver_cc.i" %include "gr_stream_mux.i" %include "gr_stream_to_streams.i" %include "gr_streams_to_stream.i" @@ -198,13 +195,8 @@ %include "gr_vector_to_streams.i" %include "gr_conjugate_cc.i" %include "gr_vco_f.i" -%include "gr_crc32.i" %include "gr_threshold_ff.i" -%include "gr_clock_recovery_mm_ff.i" -%include "gr_clock_recovery_mm_cc.i" %include "gr_packet_sink.i" -%include "gr_lms_dfe_cc.i" -%include "gr_lms_dfe_ff.i" %include "gr_dpll_bb.i" %include "gr_fmdet_cf.i" %include "gr_pll_freqdet_cf.i" @@ -219,10 +211,10 @@ %include "gr_ofdm_cyclic_prefixer.i" %include "gr_ofdm_mapper_bcv.i" %include "gr_ofdm_frame_sink.i" + //%include "gr_ofdm_frame_sink2.i" %include "gr_ofdm_insert_preamble.i" %include "gr_ofdm_sampler.i" %include "gr_regenerate_bb.i" -%include "gr_costas_loop_cc.i" %include "gr_pa_2x2_phase_combiner.i" %include "gr_kludge_copy.i" %include "gr_prefs.i" @@ -230,10 +222,7 @@ %include "gr_test_types.h" %include "gr_test.i" %include "gr_unpack_k_bits_bb.i" -%include "gr_correlate_access_code_bb.i" %include "gr_diff_phasor_cc.i" -%include "gr_constellation_decoder_cb.i" -%include "gr_binary_slicer_fb.i" %include "gr_diff_encoder_bb.i" %include "gr_diff_decoder_bb.i" %include "gr_framer_sink_1.i" @@ -261,6 +250,9 @@ %include "gr_wavelet_ff.i" %include "gr_wvps_ff.i" %include "gr_copy.i" -%include "gr_fll_band_edge_cc.i" %include "gr_additive_scrambler_bb.i" +%include "complex_vec_test.i" +%include "gr_annotator_alltoall.i" +%include "gr_annotator_1to1.i" +%include "gr_burst_tagger.i" %include "gr_cpm.i" diff --git a/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i index 841613ca6..ea73dd46d 100644 --- a/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i +++ b/gnuradio-core/src/lib/general/gr_align_on_samplenumbers_ss.i @@ -22,7 +22,8 @@ GR_SWIG_BLOCK_MAGIC(gr,align_on_samplenumbers_ss); -gr_align_on_samplenumbers_ss_sptr gr_make_align_on_samplenumbers_ss(int nchan=2, int align_interval=128); +gr_align_on_samplenumbers_ss_sptr +gr_make_align_on_samplenumbers_ss(int nchan=2, int align_interval=128) throw (std::exception); class gr_align_on_samplenumbers_ss : public gr_block { diff --git a/gnuradio-core/src/lib/general/gr_annotator_1to1.cc b/gnuradio-core/src/lib/general/gr_annotator_1to1.cc new file mode 100644 index 000000000..511b356e5 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_annotator_1to1.cc @@ -0,0 +1,107 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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_annotator_1to1.h> +#include <gr_io_signature.h> +#include <string.h> +#include <iostream> +#include <iomanip> + +gr_annotator_1to1_sptr +gr_make_annotator_1to1 (int when, size_t sizeof_stream_item) +{ + return gnuradio::get_initial_sptr (new gr_annotator_1to1 + (when, sizeof_stream_item)); +} + +gr_annotator_1to1::gr_annotator_1to1 (int when, size_t sizeof_stream_item) + : gr_sync_block ("annotator_1to1", + gr_make_io_signature (1, -1, sizeof_stream_item), + gr_make_io_signature (1, -1, sizeof_stream_item)), + d_itemsize(sizeof_stream_item), d_when((uint64_t)when) +{ + set_tag_propagation_policy(TPP_ONE_TO_ONE); + + d_tag_counter = 0; + set_relative_rate(1.0); +} + +gr_annotator_1to1::~gr_annotator_1to1 () +{ +} + +int +gr_annotator_1to1::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]; + float *out = (float*)output_items[0]; + + std::stringstream str; + str << name() << unique_id(); + + uint64_t abs_N = 0; + int ninputs = input_items.size(); + for(int i = 0; i < ninputs; i++) { + abs_N = nitems_read(i); + + std::vector<pmt::pmt_t> all_tags; + get_tags_in_range(all_tags, i, abs_N, abs_N + noutput_items); + + std::vector<pmt::pmt_t>::iterator itr; + for(itr = all_tags.begin(); itr != all_tags.end(); itr++) { + d_stored_tags.push_back(*itr); + } + } + + // Storing the current noutput_items as the value to the "noutput_items" key + pmt::pmt_t srcid = pmt::pmt_string_to_symbol(str.str()); + pmt::pmt_t key = pmt::pmt_string_to_symbol("seq"); + + // Work does nothing to the data stream; just copy all inputs to outputs + // Adds a new tag when the number of items read is a multiple of d_when + abs_N = nitems_read(0); + int noutputs = output_items.size(); + for(int j = 0; j < noutput_items; j++) { + // the min() is a hack to make sure this doesn't segfault if there are a + // different number of ins and outs. This is specifically designed to test + // the 1-to-1 propagation policy. + for(int i = 0; i < std::min(noutputs, ninputs); i++) { + if(abs_N % d_when == 0) { + pmt::pmt_t value = pmt::pmt_from_uint64(d_tag_counter++); + add_item_tag(i, abs_N, key, value, srcid); + } + + in = (const float*)input_items[i]; + out = (float*)output_items[i]; + out[j] = in[j]; + } + abs_N++; + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_annotator_1to1.h b/gnuradio-core/src/lib/general/gr_annotator_1to1.h new file mode 100644 index 000000000..4abc5b051 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_annotator_1to1.h @@ -0,0 +1,74 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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_GR_ANNOTATOR_1TO1_H +#define INCLUDED_GR_ANNOTATOR_1TO1_H + +#include <gr_sync_block.h> + +class gr_annotator_1to1; +typedef boost::shared_ptr<gr_annotator_1to1> gr_annotator_1to1_sptr; + +// public constructor +gr_annotator_1to1_sptr +gr_make_annotator_1to1 (int when, size_t sizeof_stream_item); + +/*! + * \brief 1-to-1 stream annotator testing block. FOR TESTING PURPOSES ONLY. + * + * This block creates tags to be sent downstream every 10,000 items it sees. The + * tags contain the name and ID of the instantiated block, use "seq" as a key, + * and have a counter that increments by 1 for every tag produced that is used + * as the tag's value. The tags are propagated using the 1-to-1 policy. + * + * It also stores a copy of all tags it sees flow past it. These tags can be + * recalled externally with the data() member. + * + * This block is only meant for testing and showing how to use the tags. + */ +class gr_annotator_1to1 : public gr_sync_block +{ + public: + ~gr_annotator_1to1 (); + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + std::vector<pmt::pmt_t> data() const + { + return d_stored_tags; + } + +protected: + gr_annotator_1to1 (int when, size_t sizeof_stream_item); + + private: + size_t d_itemsize; + uint64_t d_when; + uint64_t d_tag_counter; + std::vector<pmt::pmt_t> d_stored_tags; + + friend gr_annotator_1to1_sptr + gr_make_annotator_1to1 (int when, size_t sizeof_stream_item); +}; + +#endif diff --git a/gnuradio-core/src/lib/general/gr_annotator_1to1.i b/gnuradio-core/src/lib/general/gr_annotator_1to1.i new file mode 100644 index 000000000..f29ecbf53 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_annotator_1to1.i @@ -0,0 +1,36 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,annotator_1to1); + +gr_annotator_1to1_sptr gr_make_annotator_1to1 (int when, + size_t sizeof_stream_item); + +class gr_annotator_1to1 : public gr_sync_block +{ +public: + std::vector<pmt::pmt_t> data() const; + +private: + gr_annotator_1to1 (int when, size_t sizeof_stream_item); +}; + diff --git a/gnuradio-core/src/lib/general/gr_annotator_alltoall.cc b/gnuradio-core/src/lib/general/gr_annotator_alltoall.cc new file mode 100644 index 000000000..344fd088b --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_annotator_alltoall.cc @@ -0,0 +1,110 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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_annotator_alltoall.h> +#include <gr_io_signature.h> +#include <string.h> +#include <iostream> +#include <iomanip> + +gr_annotator_alltoall_sptr +gr_make_annotator_alltoall (int when, size_t sizeof_stream_item) +{ + return gnuradio::get_initial_sptr (new gr_annotator_alltoall + (when, sizeof_stream_item)); +} + +gr_annotator_alltoall::gr_annotator_alltoall (int when, + size_t sizeof_stream_item) + : gr_sync_block ("annotator_alltoall", + gr_make_io_signature (1, -1, sizeof_stream_item), + gr_make_io_signature (1, -1, sizeof_stream_item)), + d_itemsize(sizeof_stream_item), d_when((uint64_t)when) +{ + set_tag_propagation_policy(TPP_ALL_TO_ALL); + + d_tag_counter = 0; +} + +gr_annotator_alltoall::~gr_annotator_alltoall () +{ +} + +int +gr_annotator_alltoall::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]; + float *out = (float *) output_items[0]; + + std::stringstream str; + str << name() << unique_id(); + + uint64_t abs_N = 0, end_N; + int ninputs = input_items.size(); + for(int i = 0; i < ninputs; i++) { + abs_N = nitems_read(i); + end_N = abs_N + (uint64_t)(noutput_items); + + std::vector<pmt::pmt_t> all_tags; + get_tags_in_range(all_tags, i, abs_N, end_N); + + std::vector<pmt::pmt_t>::iterator itr; + for(itr = all_tags.begin(); itr != all_tags.end(); itr++) { + d_stored_tags.push_back(*itr); + } + } + + // Source ID and key for any tag that might get applied from this block + pmt::pmt_t srcid = pmt::pmt_string_to_symbol(str.str()); + pmt::pmt_t key = pmt::pmt_string_to_symbol("seq"); + + // Work does nothing to the data stream; just copy all inputs to outputs + // Adds a new tag when the number of items read is a multiple of d_when + abs_N = nitems_written(0); + int noutputs = output_items.size(); + + for(int j = 0; j < noutput_items; j++) { + for(int i = 0; i < noutputs; i++) { + if(abs_N % d_when == 0) { + pmt::pmt_t value = pmt::pmt_from_uint64(d_tag_counter++); + add_item_tag(i, abs_N, key, value, srcid); + } + + // Sum all of the inputs together for each output. Just 'cause. + out = (float*)output_items[i]; + out[j] = 0; + for(int ins = 0; ins < ninputs; ins++) { + in = (const float*)input_items[ins]; + out[j] += in[j]; + } + } + abs_N++; + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_annotator_alltoall.h b/gnuradio-core/src/lib/general/gr_annotator_alltoall.h new file mode 100644 index 000000000..e1e51ebf3 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_annotator_alltoall.h @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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_GR_ANNOTATOR_ALLTOALL_H +#define INCLUDED_GR_ANNOTATOR_ALLTOALL_H + +#include <gr_sync_block.h> + +class gr_annotator_alltoall; +typedef boost::shared_ptr<gr_annotator_alltoall> gr_annotator_alltoall_sptr; + +// public constructor +gr_annotator_alltoall_sptr +gr_make_annotator_alltoall (int when, size_t sizeof_stream_item); + +/*! + * \brief All-to-all stream annotator testing block. FOR TESTING PURPOSES ONLY. + * + * This block creates tags to be sent downstream every 10,000 items it sees. The + * tags contain the name and ID of the instantiated block, use "seq" as a key, + * and have a counter that increments by 1 for every tag produced that is used + * as the tag's value. The tags are propagated using the all-to-all policy. + * + * It also stores a copy of all tags it sees flow past it. These tags can be + * recalled externally with the data() member. + * + * This block is only meant for testing and showing how to use the tags. + */ +class gr_annotator_alltoall : public gr_sync_block +{ + public: + ~gr_annotator_alltoall (); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + + std::vector<pmt::pmt_t> data() const + { + return d_stored_tags; + } + +protected: + gr_annotator_alltoall (int when, size_t sizeof_stream_item); + + private: + size_t d_itemsize; + uint64_t d_when; + uint64_t d_tag_counter; + std::vector<pmt::pmt_t> d_stored_tags; + + friend gr_annotator_alltoall_sptr + gr_make_annotator_alltoall (int when, size_t sizeof_stream_item); +}; + +#endif diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.i b/gnuradio-core/src/lib/general/gr_annotator_alltoall.i index 3ca488b52..f9bf6dd9a 100644 --- a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.i +++ b/gnuradio-core/src/lib/general/gr_annotator_alltoall.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,15 +20,17 @@ * Boston, MA 02110-1301, USA. */ +GR_SWIG_BLOCK_MAGIC(gr,annotator_alltoall); -GR_SWIG_BLOCK_MAGIC(gr,lms_dfe_ff) +gr_annotator_alltoall_sptr gr_make_annotator_alltoall (int when, + size_t sizeof_stream_item); -gr_lms_dfe_ff_sptr gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps); - -class gr_lms_dfe_ff : public gr_sync_block +class gr_annotator_alltoall : public gr_sync_block { - private: - gr_lms_dfe_ff (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps); +public: + std::vector<pmt::pmt_t> data() const; + +private: + gr_annotator_alltoall (int when, size_t sizeof_stream_item); }; + diff --git a/gnuradio-core/src/lib/general/gr_bin_statistics_f.i b/gnuradio-core/src/lib/general/gr_bin_statistics_f.i index 5cec882f0..be98a464b 100644 --- a/gnuradio-core/src/lib/general/gr_bin_statistics_f.i +++ b/gnuradio-core/src/lib/general/gr_bin_statistics_f.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -19,6 +19,9 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +// Directors are only supported in Python, Java and C#. gr_feval_dd uses directors +#ifdef SWIGPYTHON + GR_SWIG_BLOCK_MAGIC(gr,bin_statistics_f); gr_bin_statistics_f_sptr @@ -40,3 +43,5 @@ private: public: ~gr_bin_statistics_f(); }; + +#endif diff --git a/gnuradio-core/src/lib/general/gr_burst_tagger.cc b/gnuradio-core/src/lib/general/gr_burst_tagger.cc new file mode 100644 index 000000000..4b3847b08 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_burst_tagger.cc @@ -0,0 +1,83 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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_burst_tagger.h> +#include <gr_io_signature.h> +#include <string.h> + +gr_burst_tagger_sptr +gr_make_burst_tagger(size_t itemsize) +{ + return gnuradio::get_initial_sptr(new gr_burst_tagger(itemsize)); +} + +gr_burst_tagger::gr_burst_tagger(size_t itemsize) + : gr_sync_block ("burst_tagger", + gr_make_io_signature2 (2, 2, itemsize, sizeof(short)), + gr_make_io_signature (1, 1, itemsize)), + d_itemsize(itemsize), d_state(false) +{ + std::stringstream str; + str << name() << unique_id(); + + d_key = pmt::pmt_string_to_symbol("burst"); + d_id = pmt::pmt_string_to_symbol(str.str()); +} + +gr_burst_tagger::~gr_burst_tagger() +{ +} + +int +gr_burst_tagger::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const char *signal = (const char*)input_items[0]; + const short *trigger = (const short*)input_items[1]; + char *out = (char*)output_items[0]; + + memcpy(out, signal, noutput_items * d_itemsize); + + for(int i = 0; i < noutput_items; i++) { + if(trigger[i] > 0) { + if(d_state == false) { + d_state = true; + pmt::pmt_t value = pmt::PMT_T; + add_item_tag(0, nitems_written(0)+i, d_key, value, d_id); + } + } + else { + if(d_state == true) { + d_state = false; + pmt::pmt_t value = pmt::PMT_F; + add_item_tag(0, nitems_written(0)+i, d_key, value, d_id); + } + } + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.i b/gnuradio-core/src/lib/general/gr_burst_tagger.h index c9c792c8a..8f814bea0 100644 --- a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.i +++ b/gnuradio-core/src/lib/general/gr_burst_tagger.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2009 Free Software Foundation, Inc. + * Copyright 2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,22 +20,37 @@ * Boston, MA 02110-1301, USA. */ -GR_SWIG_BLOCK_MAGIC(gr,fll_band_edge_cc); +#ifndef INCLUDED_GR_BURST_TAGGER_H +#define INCLUDED_GR_BURST_TAGGER_H -gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff, - int filter_size, float alpha, float beta); +#include <gr_sync_block.h> -class gr_fll_band_edge_cc : public gr_sync_block +class gr_burst_tagger; +typedef boost::shared_ptr<gr_burst_tagger> gr_burst_tagger_sptr; + +gr_burst_tagger_sptr gr_make_burst_tagger(size_t itemsize); + +/*! + * \brief output[i] = input[i] + * \ingroup misc_blk + * + */ +class gr_burst_tagger : public gr_sync_block { - private: - gr_fll_band_edge_cc (float samps_per_sym, float rolloff, - int filter_size, float alpha, float beta); + size_t d_itemsize; + bool d_state; + pmt::pmt_t d_key; + pmt::pmt_t d_id; + + friend gr_burst_tagger_sptr gr_make_burst_tagger(size_t itemsize); + gr_burst_tagger(size_t itemsize); public: - ~gr_fll_band_edge_cc (); + ~gr_burst_tagger(); - void set_alpha (float alpha); - void set_beta (float beta); - void design_filter(float samps_per_sym, float rolloff, int filter_size); - void print_taps(); + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; + +#endif diff --git a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.i b/gnuradio-core/src/lib/general/gr_burst_tagger.i index b6f4e9312..ebf1eea8c 100644 --- a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.i +++ b/gnuradio-core/src/lib/general/gr_burst_tagger.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,14 +20,12 @@ * Boston, MA 02110-1301, USA. */ -GR_SWIG_BLOCK_MAGIC(gr,binary_slicer_fb); +GR_SWIG_BLOCK_MAGIC(gr,burst_tagger) -gr_binary_slicer_fb_sptr gr_make_binary_slicer_fb (); +gr_burst_tagger_sptr gr_make_burst_tagger(size_t itemsize); -class gr_binary_slicer_fb : public gr_sync_block +class gr_burst_tagger : public gr_sync_block { private: - gr_binary_slicer_fb (); - - public: + gr_burst_tagger(size_t itemsize); }; diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc deleted file mode 100644 index 23bbf821f..000000000 --- a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.cc +++ /dev/null @@ -1,217 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005,2006,2010 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 <gr_prefs.h> -#include <gr_clock_recovery_mm_cc.h> -#include <gri_mmse_fir_interpolator_cc.h> -#include <stdexcept> -#include <cstdio> - - -// Public constructor - - -gr_clock_recovery_mm_cc_sptr -gr_make_clock_recovery_mm_cc(float omega, float gain_omega, float mu, float gain_mu, - float omega_relative_limit) -{ - return gnuradio::get_initial_sptr(new gr_clock_recovery_mm_cc (omega, - gain_omega, - mu, - gain_mu, - omega_relative_limit)); -} - -gr_clock_recovery_mm_cc::gr_clock_recovery_mm_cc (float omega, float gain_omega, float mu, - float gain_mu, float omega_relative_limit) - : gr_block ("clock_recovery_mm_cc", - gr_make_io_signature (1, 1, sizeof (gr_complex)), - gr_make_io_signature (1, 2, sizeof (gr_complex))), - d_mu (mu), d_omega(omega), d_gain_omega(gain_omega), - d_omega_relative_limit(omega_relative_limit), - d_gain_mu(gain_mu), d_last_sample(0), d_interp(new gri_mmse_fir_interpolator_cc()), - d_verbose(gr_prefs::singleton()->get_bool("clock_recovery_mm_cc", "verbose", false)), - d_p_2T(0), d_p_1T(0), d_p_0T(0), d_c_2T(0), d_c_1T(0), d_c_0T(0) -{ - if (omega <= 0.0) - throw std::out_of_range ("clock rate must be > 0"); - if (gain_mu < 0 || gain_omega < 0) - throw std::out_of_range ("Gains must be non-negative"); - - set_omega(omega); // also sets min and max omega - set_relative_rate (1.0 / omega); - set_history(3); // ensure 2 extra input sample is available -} - -gr_clock_recovery_mm_cc::~gr_clock_recovery_mm_cc () -{ - delete d_interp; -} - -void -gr_clock_recovery_mm_cc::forecast(int noutput_items, gr_vector_int &ninput_items_required) -{ - unsigned ninputs = ninput_items_required.size(); - for (unsigned i=0; i < ninputs; i++) - ninput_items_required[i] = - (int) ceil((noutput_items * d_omega) + d_interp->ntaps()); -} - -gr_complex -gr_clock_recovery_mm_cc::slicer_0deg (gr_complex sample) -{ - float real=0, imag=0; - - if(sample.real() > 0) - real = 1; - if(sample.imag() > 0) - imag = 1; - return gr_complex(real,imag); -} - -gr_complex -gr_clock_recovery_mm_cc::slicer_45deg (gr_complex sample) -{ - float real= -1, imag = -1; - if(sample.real() > 0) - real=1; - if(sample.imag() > 0) - imag = 1; - return gr_complex(real,imag); -} - -/* - Modified Mueller and Muller clock recovery circuit - Based: - G. R. Danesfahani, T.G. Jeans, "Optimisation of modified Mueller and Muller - algorithm," Electronics Letters, Vol. 31, no. 13, 22 June 1995, pp. 1032 - 1033. -*/ - -static const int FUDGE = 16; - -int -gr_clock_recovery_mm_cc::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - gr_complex *foptr = (gr_complex *) output_items[1]; - - bool write_foptr = output_items.size() >= 2; - - int ii = 0; // input index - int oo = 0; // output index - int ni = ninput_items[0] - d_interp->ntaps() - FUDGE; // don't use more input than this - - assert(d_mu >= 0.0); - assert(d_mu <= 1.0); - - float mm_val=0; - gr_complex u, x, y; - - // This loop writes the error to the second output, if it exists - if (write_foptr) { - while(oo < noutput_items && ii < ni) { - d_p_2T = d_p_1T; - d_p_1T = d_p_0T; - d_p_0T = d_interp->interpolate (&in[ii], d_mu); - - d_c_2T = d_c_1T; - d_c_1T = d_c_0T; - d_c_0T = slicer_0deg(d_p_0T); - - x = (d_c_0T - d_c_2T) * conj(d_p_1T); - y = (d_p_0T - d_p_2T) * conj(d_c_1T); - u = y - x; - mm_val = u.real(); - out[oo++] = d_p_0T; - - // limit mm_val - mm_val = gr_branchless_clip(mm_val,1.0); - d_omega = d_omega + d_gain_omega * mm_val; - d_omega = d_omega_mid + gr_branchless_clip(d_omega-d_omega_mid, d_omega_relative_limit); // make sure we don't walk away - - d_mu = d_mu + d_omega + d_gain_mu * mm_val; - ii += (int)floor(d_mu); - d_mu -= floor(d_mu); - - // write the error signal to the second output - foptr[oo-1] = gr_complex(d_mu,0); - - if (ii < 0) // clamp it. This should only happen with bogus input - ii = 0; - } - } - // This loop does not write to the second output (ugly, but faster) - else { - while(oo < noutput_items && ii < ni) { - d_p_2T = d_p_1T; - d_p_1T = d_p_0T; - d_p_0T = d_interp->interpolate (&in[ii], d_mu); - - d_c_2T = d_c_1T; - d_c_1T = d_c_0T; - d_c_0T = slicer_0deg(d_p_0T); - - x = (d_c_0T - d_c_2T) * conj(d_p_1T); - y = (d_p_0T - d_p_2T) * conj(d_c_1T); - u = y - x; - mm_val = u.real(); - out[oo++] = d_p_0T; - - // limit mm_val - mm_val = gr_branchless_clip(mm_val,1.0); - - d_omega = d_omega + d_gain_omega * mm_val; - d_omega = d_omega_mid + gr_branchless_clip(d_omega-d_omega_mid, d_omega_relative_limit); // make sure we don't walk away - - d_mu = d_mu + d_omega + d_gain_mu * mm_val; - ii += (int)floor(d_mu); - d_mu -= floor(d_mu); - - if(d_verbose) { - printf("%f\t%f\n", d_omega, d_mu); - } - - if (ii < 0) // clamp it. This should only happen with bogus input - ii = 0; - } - } - - if (ii > 0){ - if (ii > ninput_items[0]){ - fprintf(stderr, "gr_clock_recovery_mm_cc: ii > ninput_items[0] (%d > %d)\n", - ii, ninput_items[0]); - assert(0); - } - consume_each (ii); - } - - return oo; -} diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h deleted file mode 100644 index 04227a145..000000000 --- a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.h +++ /dev/null @@ -1,109 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 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_GR_CLOCK_RECOVERY_MM_CC_H -#define INCLUDED_GR_CLOCK_RECOVERY_MM_CC_H - -#include <gr_block.h> -#include <gr_complex.h> -#include <gr_math.h> - -class gri_mmse_fir_interpolator_cc; - -class gr_clock_recovery_mm_cc; -typedef boost::shared_ptr<gr_clock_recovery_mm_cc> gr_clock_recovery_mm_cc_sptr; - -// public constructor -gr_clock_recovery_mm_cc_sptr -gr_make_clock_recovery_mm_cc (float omega, float gain_omega, float mu, float gain_mu, - float omega_relative_limit=0.001); - -/*! - * \brief Mueller and Müller (M&M) based clock recovery block with complex input, complex output. - * \ingroup sync_blk - * - * This implements the Mueller and Müller (M&M) discrete-time error-tracking synchronizer. - * The complex version here is based on: - * Modified Mueller and Muller clock recovery circuit - * Based: - * G. R. Danesfahani, T.G. Jeans, "Optimisation of modified Mueller and Muller - * algorithm," Electronics Letters, Vol. 31, no. 13, 22 June 1995, pp. 1032 - 1033. - */ -class gr_clock_recovery_mm_cc : public gr_block -{ - public: - ~gr_clock_recovery_mm_cc (); - void forecast(int noutput_items, gr_vector_int &ninput_items_required); - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - float mu() const { return d_mu;} - float omega() const { return d_omega;} - float gain_mu() const { return d_gain_mu;} - float gain_omega() const { return d_gain_omega;} - void set_verbose (bool verbose) { d_verbose = verbose; } - - void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; } - void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; } - void set_mu (float mu) { d_mu = mu; } - void set_omega (float omega) { - d_omega = omega; - d_min_omega = omega*(1.0 - d_omega_relative_limit); - d_max_omega = omega*(1.0 + d_omega_relative_limit); - d_omega_mid = 0.5*(d_min_omega+d_max_omega); - } - -protected: - gr_clock_recovery_mm_cc (float omega, float gain_omega, float mu, float gain_mu, - float omega_relative_limi); - - private: - float d_mu; - float d_omega; - float d_gain_omega; - float d_min_omega; // minimum allowed omega - float d_max_omega; // maximum allowed omeg - float d_omega_relative_limit; // used to compute min and max omega - float d_omega_mid; - float d_gain_mu; - gr_complex d_last_sample; - gri_mmse_fir_interpolator_cc *d_interp; - bool d_verbose; - - gr_complex d_p_2T; - gr_complex d_p_1T; - gr_complex d_p_0T; - - gr_complex d_c_2T; - gr_complex d_c_1T; - gr_complex d_c_0T; - - gr_complex slicer_0deg (gr_complex sample); - gr_complex slicer_45deg (gr_complex sample); - - friend gr_clock_recovery_mm_cc_sptr - gr_make_clock_recovery_mm_cc (float omega, float gain_omega, float mu, float gain_mu, - float omega_relative_limit); -}; - -#endif diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.i b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.i deleted file mode 100644 index 98d326b28..000000000 --- a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_cc.i +++ /dev/null @@ -1,49 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 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. - */ - -GR_SWIG_BLOCK_MAGIC(gr,clock_recovery_mm_cc); - -gr_clock_recovery_mm_cc_sptr gr_make_clock_recovery_mm_cc (float omega, float gain_omega, - float mu, float gain_mu, - float omega_relative_limit); - -class gr_clock_recovery_mm_cc : public gr_sync_block -{ - private: - gr_clock_recovery_mm_cc (float omega, float gain_omega, float mu, - float gain_mu, float omega_relative_limit); - -public: - float mu() const { return d_mu;} - float omega() const { return d_omega;} - float gain_mu() const { return d_gain_mu;} - float gain_omega() const { return d_gain_omega;} - - void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; } - void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; } - void set_mu (float omega) { d_mu = mu; } - void set_omega (float omega) { d_omega = omega; - d_min_omega = omega*(1.0 - d_omega_relative_limit); - d_max_omega = omega*(1.0 + d_omega_relative_limit); - } - void set_verbose (bool verbose) { d_verbose = verbose; } -}; diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc deleted file mode 100644 index bb5a27071..000000000 --- a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.cc +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2010 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 <gr_clock_recovery_mm_ff.h> -#include <gri_mmse_fir_interpolator.h> -#include <stdexcept> - -#define DEBUG_CR_MM_FF 0 // must be defined as 0 or 1 - -// Public constructor - -gr_clock_recovery_mm_ff_sptr -gr_make_clock_recovery_mm_ff(float omega, float gain_omega, float mu, float gain_mu, - float omega_relative_limit) -{ - return gnuradio::get_initial_sptr(new gr_clock_recovery_mm_ff (omega, - gain_omega, - mu, - gain_mu, - omega_relative_limit)); -} - -gr_clock_recovery_mm_ff::gr_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu, - float omega_relative_limit) - : gr_block ("clock_recovery_mm_ff", - gr_make_io_signature (1, 1, sizeof (float)), - gr_make_io_signature (1, 1, sizeof (float))), - d_mu (mu), d_gain_omega(gain_omega), d_gain_mu(gain_mu), - d_last_sample(0), d_interp(new gri_mmse_fir_interpolator()), - d_logfile(0), d_omega_relative_limit(omega_relative_limit) -{ - if (omega < 1) - throw std::out_of_range ("clock rate must be > 0"); - if (gain_mu < 0 || gain_omega < 0) - throw std::out_of_range ("Gains must be non-negative"); - - set_omega(omega); // also sets min and max omega - set_relative_rate (1.0 / omega); - - if (DEBUG_CR_MM_FF) - d_logfile = fopen("cr_mm_ff.dat", "wb"); -} - -gr_clock_recovery_mm_ff::~gr_clock_recovery_mm_ff () -{ - delete d_interp; - - if (DEBUG_CR_MM_FF && d_logfile){ - fclose(d_logfile); - d_logfile = 0; - } -} - -void -gr_clock_recovery_mm_ff::forecast(int noutput_items, gr_vector_int &ninput_items_required) -{ - unsigned ninputs = ninput_items_required.size(); - for (unsigned i=0; i < ninputs; i++) - ninput_items_required[i] = - (int) ceil((noutput_items * d_omega) + d_interp->ntaps()); -} - -static inline float -slice(float x) -{ - return x < 0 ? -1.0F : 1.0F; -} - -/* - * This implements the Mueller and Müller (M&M) discrete-time error-tracking synchronizer. - * - * See "Digital Communication Receivers: Synchronization, Channel - * Estimation and Signal Processing" by Heinrich Meyr, Marc Moeneclaey, & Stefan Fechtel. - * ISBN 0-471-50275-8. - */ -int -gr_clock_recovery_mm_ff::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const float *in = (const float *) input_items[0]; - float *out = (float *) output_items[0]; - - int ii = 0; // input index - int oo = 0; // output index - int ni = ninput_items[0] - d_interp->ntaps(); // don't use more input than this - float mm_val; - - while (oo < noutput_items && ii < ni ){ - - // produce output sample - out[oo] = d_interp->interpolate (&in[ii], d_mu); - mm_val = slice(d_last_sample) * out[oo] - slice(out[oo]) * d_last_sample; - d_last_sample = out[oo]; - - d_omega = d_omega + d_gain_omega * mm_val; - d_omega = d_omega_mid + gr_branchless_clip(d_omega-d_omega_mid, d_omega_relative_limit); // make sure we don't walk away - d_mu = d_mu + d_omega + d_gain_mu * mm_val; - - ii += (int) floor(d_mu); - d_mu = d_mu - floor(d_mu); - oo++; - - if (DEBUG_CR_MM_FF && d_logfile){ - fwrite(&d_omega, sizeof(d_omega), 1, d_logfile); - } - } - - consume_each (ii); - - return oo; -} diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h b/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h deleted file mode 100644 index d2ec6d3e6..000000000 --- a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.h +++ /dev/null @@ -1,96 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 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_GR_CLOCK_RECOVERY_MM_FF_H -#define INCLUDED_GR_CLOCK_RECOVERY_MM_FF_H - -#include <gr_block.h> -#include <gr_math.h> -#include <stdio.h> - -class gri_mmse_fir_interpolator; - -class gr_clock_recovery_mm_ff; -typedef boost::shared_ptr<gr_clock_recovery_mm_ff> gr_clock_recovery_mm_ff_sptr; - -// public constructor -gr_clock_recovery_mm_ff_sptr -gr_make_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu, - float omega_relative_limit=0.001); - -/*! - * \brief Mueller and Müller (M&M) based clock recovery block with float input, float output. - * \ingroup sync_blk - * - * This implements the Mueller and Müller (M&M) discrete-time error-tracking synchronizer. - * - * See "Digital Communication Receivers: Synchronization, Channel - * Estimation and Signal Processing" by Heinrich Meyr, Marc Moeneclaey, & Stefan Fechtel. - * ISBN 0-471-50275-8. - */ -class gr_clock_recovery_mm_ff : public gr_block -{ - public: - ~gr_clock_recovery_mm_ff (); - void forecast(int noutput_items, gr_vector_int &ninput_items_required); - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - float mu() const { return d_mu;} - float omega() const { return d_omega;} - float gain_mu() const { return d_gain_mu;} - float gain_omega() const { return d_gain_omega;} - - void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; } - void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; } - void set_mu (float mu) { d_mu = mu; } - void set_omega (float omega){ - d_omega = omega; - d_min_omega = omega*(1.0 - d_omega_relative_limit); - d_max_omega = omega*(1.0 + d_omega_relative_limit); - d_omega_mid = 0.5*(d_min_omega+d_max_omega); - } - -protected: - gr_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu, - float omega_relative_limit); - - private: - float d_mu; // fractional sample position [0.0, 1.0] - float d_omega; // nominal frequency - float d_min_omega; // minimum allowed omega - float d_omega_mid; // average omega - float d_max_omega; // maximum allowed omega - float d_gain_omega; // gain for adjusting omega - float d_gain_mu; // gain for adjusting mu - float d_last_sample; - gri_mmse_fir_interpolator *d_interp; - FILE *d_logfile; - float d_omega_relative_limit; // used to compute min and max omega - - friend gr_clock_recovery_mm_ff_sptr - gr_make_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu, - float omega_relative_limit); -}; - -#endif diff --git a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.cc b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.cc deleted file mode 100644 index 5b87f1430..000000000 --- a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.cc +++ /dev/null @@ -1,114 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006 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_constellation_decoder_cb.h> -#include <gr_io_signature.h> -#include <stdexcept> - -#include <cstdio> -#include <iostream> -using std::cout; -using std::endl; - -static const bool compute_EVM = false; - -gr_constellation_decoder_cb_sptr -gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out) -{ - return gr_constellation_decoder_cb_sptr - (new gr_constellation_decoder_cb(sym_position, sym_value_out)); -} - -gr_constellation_decoder_cb:: -gr_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out) - : gr_sync_block ("constellation_decoder_cb", - gr_make_io_signature (1, 1, sizeof (gr_complex)), - gr_make_io_signature (1, 1, sizeof (unsigned char))) -{ - if (!set_constellation(sym_position,sym_value_out)) - throw std::invalid_argument("constellation_decoder_cb"); -} - - -gr_constellation_decoder_cb::~gr_constellation_decoder_cb(){} - - -bool -gr_constellation_decoder_cb::set_constellation(const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out) -{ - if (sym_position.size() != sym_value_out.size()) - return false; - - if (sym_position.size()<1) - return false; - - d_sym_position = sym_position; - d_sym_value_out = sym_value_out; - return true; -} - - -int -gr_constellation_decoder_cb::work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - gr_complex const *in = (const gr_complex *) input_items[0]; - unsigned char *out = (unsigned char *) output_items[0]; - unsigned int table_size = d_sym_value_out.size(); - unsigned int min_index = 0; - float min_euclid_dist = 0; - float euclid_dist = 0; - double total_error = 0; - - for(int i = 0; i < noutput_items; i++){ - min_euclid_dist = norm(in[i] - d_sym_position[0]); - min_index = 0; - for (unsigned int j = 1; j < table_size; j++){ - euclid_dist = norm(in[i] - d_sym_position[j]); - if (euclid_dist < min_euclid_dist){ - min_euclid_dist = euclid_dist; - min_index = j; - } - } - - out[i] = d_sym_value_out[min_index]; - - if (compute_EVM) - total_error += sqrtf(min_euclid_dist); - } - - if (compute_EVM){ - double mean = total_error / noutput_items; - double rms = sqrt(mean * mean); - fprintf(stderr, "EVM = %8.4f\n", rms); - } - - return noutput_items; -} diff --git a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.h b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.h deleted file mode 100644 index fd7079c12..000000000 --- a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006 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_GR_CONSTELLATION_DECODER_CB_H -#define INCLUDED_GR_CONSTELLATION_DECODER_CB_H - -#include <gr_sync_block.h> -#include <vector> - -class gr_constellation_decoder_cb; -typedef boost::shared_ptr<gr_constellation_decoder_cb> gr_constellation_decoder_cb_sptr; - -gr_constellation_decoder_cb_sptr - gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out); - -/*! - * \brief Constellation Decoder - * \ingroup coding_blk - * - */ -class gr_constellation_decoder_cb : public gr_sync_block -{ - - private: - std::vector<gr_complex> d_sym_position; - std::vector<unsigned char> d_sym_value_out; - - friend gr_constellation_decoder_cb_sptr - gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, const std::vector<unsigned char> &sym_value_out); - - gr_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out); //constructor - - public: - bool set_constellation(const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out); - - ~gr_constellation_decoder_cb(); //destructor - - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif diff --git a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.i b/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.i deleted file mode 100644 index 8d9c9b56e..000000000 --- a/gnuradio-core/src/lib/general/gr_constellation_decoder_cb.i +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006 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. - */ - -GR_SWIG_BLOCK_MAGIC(gr,constellation_decoder_cb) - -gr_constellation_decoder_cb_sptr - gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out); - -class gr_constellation_decoder_cb : public gr_sync_block -{ - private: - gr_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out); - - friend gr_constellation_decoder_cb_sptr - gr_make_constellation_decoder_cb (const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out); - - public: - int set_constellation(const std::vector<gr_complex> &sym_position, - const std::vector<unsigned char> &sym_value_out); - ~gr_constellation_decoder_cb(); -}; diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.cc b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.cc deleted file mode 100644 index 15f673411..000000000 --- a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.cc +++ /dev/null @@ -1,133 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2006,2010 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_correlate_access_code_bb.h> -#include <gr_io_signature.h> -#include <stdexcept> -#include <gr_count_bits.h> -#include <cstdio> - - -#define VERBOSE 0 - - -gr_correlate_access_code_bb_sptr -gr_make_correlate_access_code_bb (const std::string &access_code, int threshold) -{ - return gnuradio::get_initial_sptr(new gr_correlate_access_code_bb (access_code, threshold)); -} - - -gr_correlate_access_code_bb::gr_correlate_access_code_bb ( - const std::string &access_code, int threshold) - : gr_sync_block ("correlate_access_code_bb", - gr_make_io_signature (1, 1, sizeof(char)), - gr_make_io_signature (1, 1, sizeof(char))), - d_data_reg(0), d_flag_reg(0), d_flag_bit(0), d_mask(0), - d_threshold(threshold) - -{ - if (!set_access_code(access_code)){ - fprintf(stderr, "gr_correlate_access_code_bb: access_code is > 64 bits\n"); - throw std::out_of_range ("access_code is > 64 bits"); - } -} - -gr_correlate_access_code_bb::~gr_correlate_access_code_bb () -{ -} - -bool -gr_correlate_access_code_bb::set_access_code( - const std::string &access_code) -{ - unsigned len = access_code.length(); // # of bytes in string - if (len > 64) - return false; - - // set len top bits to 1. - d_mask = ((~0ULL) >> (64 - len)) << (64 - len); - - d_flag_bit = 1LL << (64 - len); // Where we or-in new flag values. - // new data always goes in 0x0000000000000001 - d_access_code = 0; - for (unsigned i=0; i < 64; i++){ - d_access_code <<= 1; - if (i < len) - d_access_code |= access_code[i] & 1; // look at LSB only - } - - return true; -} - -int -gr_correlate_access_code_bb::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const unsigned char *in = (const unsigned char *) input_items[0]; - unsigned char *out = (unsigned char *) output_items[0]; - - for (int i = 0; i < noutput_items; i++){ - - // compute output value - unsigned int t = 0; - - t |= ((d_data_reg >> 63) & 0x1) << 0; - t |= ((d_flag_reg >> 63) & 0x1) << 1; // flag bit - out[i] = t; - - // compute hamming distance between desired access code and current data - unsigned long long wrong_bits = 0; - unsigned int nwrong = d_threshold+1; - int new_flag = 0; - - wrong_bits = (d_data_reg ^ d_access_code) & d_mask; - nwrong = gr_count_bits64(wrong_bits); - - // test for access code with up to threshold errors - new_flag = (nwrong <= d_threshold); - -#if VERBOSE - if(new_flag) { - fprintf(stderr, "access code found: %llx\n", d_access_code); - } - else { - fprintf(stderr, "%llx ==> %llx\n", d_access_code, d_data_reg); - } -#endif - - // shift in new data and new flag - d_data_reg = (d_data_reg << 1) | (in[i] & 0x1); - d_flag_reg = (d_flag_reg << 1); - if (new_flag) { - d_flag_reg |= d_flag_bit; - } - } - - return noutput_items; -} - diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.h b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.h deleted file mode 100644 index 581713c14..000000000 --- a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005,2006 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_GR_CORRELATE_ACCESS_CODE_BB_H -#define INCLUDED_GR_CORRELATE_ACCESS_CODE_BB_H - -#include <gr_sync_block.h> -#include <string> - -class gr_correlate_access_code_bb; -typedef boost::shared_ptr<gr_correlate_access_code_bb> gr_correlate_access_code_bb_sptr; - -/*! - * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100" - * \param threshold maximum number of bits that may be wrong - */ -gr_correlate_access_code_bb_sptr -gr_make_correlate_access_code_bb (const std::string &access_code, int threshold); - -/*! - * \brief Examine input for specified access code, one bit at a time. - * \ingroup sync_blk - * - * input: stream of bits, 1 bit per input byte (data in LSB) - * output: stream of bits, 2 bits per output byte (data in LSB, flag in next higher bit) - * - * Each output byte contains two valid bits, the data bit, and the - * flag bit. The LSB (bit 0) is the data bit, and is the original - * input data, delayed 64 bits. Bit 1 is the - * flag bit and is 1 if the corresponding data bit is the first data - * bit following the access code. Otherwise the flag bit is 0. - */ -class gr_correlate_access_code_bb : public gr_sync_block -{ - friend gr_correlate_access_code_bb_sptr - gr_make_correlate_access_code_bb (const std::string &access_code, int threshold); - private: - unsigned long long d_access_code; // access code to locate start of packet - // access code is left justified in the word - unsigned long long d_data_reg; // used to look for access_code - unsigned long long d_flag_reg; // keep track of decisions - unsigned long long d_flag_bit; // mask containing 1 bit which is location of new flag - unsigned long long d_mask; // masks access_code bits (top N bits are set where - // N is the number of bits in the access code) - unsigned int d_threshold; // how many bits may be wrong in sync vector - - protected: - gr_correlate_access_code_bb(const std::string &access_code, int threshold); - - public: - ~gr_correlate_access_code_bb(); - - int work(int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - - - /*! - * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100" - */ - bool set_access_code (const std::string &access_code); -}; - -#endif /* INCLUDED_GR_CORRELATE_ACCESS_CODE_BB_H */ diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.i b/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.i deleted file mode 100644 index bec4282f1..000000000 --- a/gnuradio-core/src/lib/general/gr_correlate_access_code_bb.i +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006 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. - */ - -GR_SWIG_BLOCK_MAGIC(gr,correlate_access_code_bb); - -/*! - * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100" - * \param threshold maximum number of bits that may be wrong - */ -gr_correlate_access_code_bb_sptr -gr_make_correlate_access_code_bb (const std::string &access_code, int threshold) - throw(std::out_of_range); - -/*! - * \brief Examine input for specified access code, one bit at a time. - * \ingroup block - * - * input: stream of bits, 1 bit per input byte (data in LSB) - * output: stream of bits, 2 bits per output byte (data in LSB, flag in next higher bit) - * - * Each output byte contains two valid bits, the data bit, and the - * flag bit. The LSB (bit 0) is the data bit, and is the original - * input data, delayed 64 bits. Bit 1 is the - * flag bit and is 1 if the corresponding data bit is the first data - * bit following the access code. Otherwise the flag bit is 0. - */ -class gr_correlate_access_code_bb : public gr_sync_block -{ - friend gr_correlate_access_code_bb_sptr - gr_make_correlate_access_code_bb (const std::string &access_code, int threshold); - protected: - gr_correlate_access_code_bb(const std::string &access_code, int threshold); - - public: - ~gr_correlate_access_code_bb(); - - /*! - * \param access_code is represented with 1 byte per bit, e.g., "010101010111000100" - */ - bool set_access_code (const std::string &access_code); -}; diff --git a/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc b/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc deleted file mode 100644 index f3bfd0951..000000000 --- a/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc +++ /dev/null @@ -1,168 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006,2010 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_costas_loop_cc.h> -#include <gr_io_signature.h> -#include <gr_expj.h> -#include <gr_sincos.h> -#include <math.h> - -#define M_TWOPI (2*M_PI) - -gr_costas_loop_cc_sptr -gr_make_costas_loop_cc (float alpha, float beta, - float max_freq, float min_freq, - int order - ) throw (std::invalid_argument) -{ - return gnuradio::get_initial_sptr(new gr_costas_loop_cc (alpha, beta, - max_freq, min_freq, - order)); -} - -gr_costas_loop_cc::gr_costas_loop_cc (float alpha, float beta, - float max_freq, float min_freq, - int order - ) throw (std::invalid_argument) - : gr_sync_block ("costas_loop_cc", - gr_make_io_signature (1, 1, sizeof (gr_complex)), - gr_make_io_signature (1, 2, sizeof (gr_complex))), - d_alpha(alpha), d_beta(beta), - d_max_freq(max_freq), d_min_freq(min_freq), - d_phase(0), d_freq((max_freq+min_freq)/2), - d_order(order), d_phase_detector(0) -{ - switch(d_order) { - case 2: - d_phase_detector = &gr_costas_loop_cc::phase_detector_2; - break; - - case 4: - d_phase_detector = &gr_costas_loop_cc::phase_detector_4; - break; - - default: - throw std::invalid_argument("order must be 2 or 4"); - break; - } -} - - -float -gr_costas_loop_cc::phase_detector_4(gr_complex sample) const -{ - - return ((sample.real()>0 ? 1.0 : -1.0) * sample.imag() - - (sample.imag()>0 ? 1.0 : -1.0) * sample.real()); -} - -float -gr_costas_loop_cc::phase_detector_2(gr_complex sample) const -{ - return (sample.real()*sample.imag()); -} - -void -gr_costas_loop_cc::set_alpha(float alpha) -{ - d_alpha = alpha; -} - -void -gr_costas_loop_cc::set_beta(float beta) -{ - d_beta = beta; -} - -int -gr_costas_loop_cc::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *iptr = (gr_complex *) input_items[0]; - gr_complex *optr = (gr_complex *) output_items[0]; - gr_complex *foptr = (gr_complex *) output_items[1]; - - bool write_foptr = output_items.size() >= 2; - - float error; - gr_complex nco_out; - - if (write_foptr) { - - for (int i = 0; i < noutput_items; i++){ - nco_out = gr_expj(-d_phase); - optr[i] = iptr[i] * nco_out; - - error = (*this.*d_phase_detector)(optr[i]); - if (error > 1) - error = 1; - else if (error < -1) - error = -1; - - d_freq = d_freq + d_beta * error; - d_phase = d_phase + d_freq + d_alpha * error; - - while(d_phase>M_TWOPI) - d_phase -= M_TWOPI; - while(d_phase<-M_TWOPI) - d_phase += M_TWOPI; - - if (d_freq > d_max_freq) - d_freq = d_max_freq; - else if (d_freq < d_min_freq) - d_freq = d_min_freq; - - foptr[i] = gr_complex(d_freq,0); - } - } else { - for (int i = 0; i < noutput_items; i++){ - nco_out = gr_expj(-d_phase); - optr[i] = iptr[i] * nco_out; - - error = (*this.*d_phase_detector)(optr[i]); - if (error > 1) - error = 1; - else if (error < -1) - error = -1; - - d_freq = d_freq + d_beta * error; - d_phase = d_phase + d_freq + d_alpha * error; - - while(d_phase>M_TWOPI) - d_phase -= M_TWOPI; - while(d_phase<-M_TWOPI) - d_phase += M_TWOPI; - - if (d_freq > d_max_freq) - d_freq = d_max_freq; - else if (d_freq < d_min_freq) - d_freq = d_min_freq; - - } - } - return noutput_items; -} diff --git a/gnuradio-core/src/lib/general/gr_costas_loop_cc.h b/gnuradio-core/src/lib/general/gr_costas_loop_cc.h deleted file mode 100644 index 3b4aab86c..000000000 --- a/gnuradio-core/src/lib/general/gr_costas_loop_cc.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2006 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_GR_COSTAS_LOOP_CC_H -#define INCLUDED_GR_COSTAS_LOOP_CC_H - -#include <gr_sync_block.h> -#include <stdexcept> -#include <fstream> - - -/*! \brief A Costas loop carrier recovery module. - * \ingroup sync_blk - * - * The Costas loop locks to the center frequency of a signal and - * downconverts it to baseband. The second (order=2) order loop is - * used for BPSK where the real part of the output signal is the - * baseband BPSK signal and the imaginary part is the error - * signal. When order=4, it can be used for quadrature modulations - * where both I and Q (real and imaginary) are outputted. - * - * More details can be found online: - * - * J. Feigin, "Practical Costas loop design: Designing a simple and inexpensive - * BPSK Costas loop carrier recovery circuit," RF signal processing, pp. 20-36, - * 2002. - * - * http://rfdesign.com/images/archive/0102Feigin20.pdf - * - * \param alpha the loop gain used for phase adjustment - * \param beta the loop gain for frequency adjustments - * \param max_freq the maximum frequency deviation (radians/sample) the loop can handle - * \param min_freq the minimum frequency deviation (radians/sample) the loop can handle - * \param order the loop order, either 2 or 4 - */ -class gr_costas_loop_cc; -typedef boost::shared_ptr<gr_costas_loop_cc> gr_costas_loop_cc_sptr; - - -gr_costas_loop_cc_sptr -gr_make_costas_loop_cc (float alpha, float beta, - float max_freq, float min_freq, - int order - ) throw (std::invalid_argument); - - -/*! - * \brief Carrier tracking PLL for QPSK - * \ingroup sync_blk - * input: complex; output: complex - * <br>The Costas loop can have two output streams: - * stream 1 is the baseband I and Q; - * stream 2 is the normalized frequency of the loop - * - * \p order must be 2 or 4. - */ -class gr_costas_loop_cc : public gr_sync_block -{ - friend gr_costas_loop_cc_sptr gr_make_costas_loop_cc (float alpha, float beta, - float max_freq, float min_freq, - int order - ) throw (std::invalid_argument); - - float d_alpha, d_beta, d_max_freq, d_min_freq, d_phase, d_freq; - int d_order; - - gr_costas_loop_cc (float alpha, float beta, - float max_freq, float min_freq, - int order - ) throw (std::invalid_argument); - - /*! \brief the phase detector circuit for fourth-order loops - * \param sample complex sample - * \return the phase error - */ - float phase_detector_4(gr_complex sample) const; // for QPSK - - /*! \brief the phase detector circuit for second-order loops - * \param sample a complex sample - * \return the phase error - */ - float phase_detector_2(gr_complex sample) const; // for BPSK - - - float (gr_costas_loop_cc::*d_phase_detector)(gr_complex sample) const; - -public: - - /*! \brief set the first order gain - * \param alpha - */ - void set_alpha(float alpha); - - /*! \brief get the first order gain - * - */ - float alpha() const { return d_alpha; } - - /*! \brief set the second order gain - * \param beta - */ - void set_beta(float beta); - - /*! \brief get the second order gain - * - */ - float beta() const { return d_beta; } - - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - - /*! \brief returns the current NCO frequency in radians/sample - * - */ - float freq() const { return d_freq; } -}; - -#endif diff --git a/gnuradio-core/src/lib/general/gr_crc32.cc b/gnuradio-core/src/lib/general/gr_crc32.cc deleted file mode 100644 index d4e843528..000000000 --- a/gnuradio-core/src/lib/general/gr_crc32.cc +++ /dev/null @@ -1,130 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005 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. - */ - -/* - * See also ISO 3309 [ISO-3309] or ITU-T V.42 [ITU-V42] for a formal specification. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <gr_crc32.h> - - -// Automatically generated CRC function -// polynomial: 0x104C11DB7 -unsigned int -gr_update_crc32(unsigned int crc, const unsigned char *data, size_t len) -{ - static const unsigned int table[256] = { - 0x00000000U,0x04C11DB7U,0x09823B6EU,0x0D4326D9U, - 0x130476DCU,0x17C56B6BU,0x1A864DB2U,0x1E475005U, - 0x2608EDB8U,0x22C9F00FU,0x2F8AD6D6U,0x2B4BCB61U, - 0x350C9B64U,0x31CD86D3U,0x3C8EA00AU,0x384FBDBDU, - 0x4C11DB70U,0x48D0C6C7U,0x4593E01EU,0x4152FDA9U, - 0x5F15ADACU,0x5BD4B01BU,0x569796C2U,0x52568B75U, - 0x6A1936C8U,0x6ED82B7FU,0x639B0DA6U,0x675A1011U, - 0x791D4014U,0x7DDC5DA3U,0x709F7B7AU,0x745E66CDU, - 0x9823B6E0U,0x9CE2AB57U,0x91A18D8EU,0x95609039U, - 0x8B27C03CU,0x8FE6DD8BU,0x82A5FB52U,0x8664E6E5U, - 0xBE2B5B58U,0xBAEA46EFU,0xB7A96036U,0xB3687D81U, - 0xAD2F2D84U,0xA9EE3033U,0xA4AD16EAU,0xA06C0B5DU, - 0xD4326D90U,0xD0F37027U,0xDDB056FEU,0xD9714B49U, - 0xC7361B4CU,0xC3F706FBU,0xCEB42022U,0xCA753D95U, - 0xF23A8028U,0xF6FB9D9FU,0xFBB8BB46U,0xFF79A6F1U, - 0xE13EF6F4U,0xE5FFEB43U,0xE8BCCD9AU,0xEC7DD02DU, - 0x34867077U,0x30476DC0U,0x3D044B19U,0x39C556AEU, - 0x278206ABU,0x23431B1CU,0x2E003DC5U,0x2AC12072U, - 0x128E9DCFU,0x164F8078U,0x1B0CA6A1U,0x1FCDBB16U, - 0x018AEB13U,0x054BF6A4U,0x0808D07DU,0x0CC9CDCAU, - 0x7897AB07U,0x7C56B6B0U,0x71159069U,0x75D48DDEU, - 0x6B93DDDBU,0x6F52C06CU,0x6211E6B5U,0x66D0FB02U, - 0x5E9F46BFU,0x5A5E5B08U,0x571D7DD1U,0x53DC6066U, - 0x4D9B3063U,0x495A2DD4U,0x44190B0DU,0x40D816BAU, - 0xACA5C697U,0xA864DB20U,0xA527FDF9U,0xA1E6E04EU, - 0xBFA1B04BU,0xBB60ADFCU,0xB6238B25U,0xB2E29692U, - 0x8AAD2B2FU,0x8E6C3698U,0x832F1041U,0x87EE0DF6U, - 0x99A95DF3U,0x9D684044U,0x902B669DU,0x94EA7B2AU, - 0xE0B41DE7U,0xE4750050U,0xE9362689U,0xEDF73B3EU, - 0xF3B06B3BU,0xF771768CU,0xFA325055U,0xFEF34DE2U, - 0xC6BCF05FU,0xC27DEDE8U,0xCF3ECB31U,0xCBFFD686U, - 0xD5B88683U,0xD1799B34U,0xDC3ABDEDU,0xD8FBA05AU, - 0x690CE0EEU,0x6DCDFD59U,0x608EDB80U,0x644FC637U, - 0x7A089632U,0x7EC98B85U,0x738AAD5CU,0x774BB0EBU, - 0x4F040D56U,0x4BC510E1U,0x46863638U,0x42472B8FU, - 0x5C007B8AU,0x58C1663DU,0x558240E4U,0x51435D53U, - 0x251D3B9EU,0x21DC2629U,0x2C9F00F0U,0x285E1D47U, - 0x36194D42U,0x32D850F5U,0x3F9B762CU,0x3B5A6B9BU, - 0x0315D626U,0x07D4CB91U,0x0A97ED48U,0x0E56F0FFU, - 0x1011A0FAU,0x14D0BD4DU,0x19939B94U,0x1D528623U, - 0xF12F560EU,0xF5EE4BB9U,0xF8AD6D60U,0xFC6C70D7U, - 0xE22B20D2U,0xE6EA3D65U,0xEBA91BBCU,0xEF68060BU, - 0xD727BBB6U,0xD3E6A601U,0xDEA580D8U,0xDA649D6FU, - 0xC423CD6AU,0xC0E2D0DDU,0xCDA1F604U,0xC960EBB3U, - 0xBD3E8D7EU,0xB9FF90C9U,0xB4BCB610U,0xB07DABA7U, - 0xAE3AFBA2U,0xAAFBE615U,0xA7B8C0CCU,0xA379DD7BU, - 0x9B3660C6U,0x9FF77D71U,0x92B45BA8U,0x9675461FU, - 0x8832161AU,0x8CF30BADU,0x81B02D74U,0x857130C3U, - 0x5D8A9099U,0x594B8D2EU,0x5408ABF7U,0x50C9B640U, - 0x4E8EE645U,0x4A4FFBF2U,0x470CDD2BU,0x43CDC09CU, - 0x7B827D21U,0x7F436096U,0x7200464FU,0x76C15BF8U, - 0x68860BFDU,0x6C47164AU,0x61043093U,0x65C52D24U, - 0x119B4BE9U,0x155A565EU,0x18197087U,0x1CD86D30U, - 0x029F3D35U,0x065E2082U,0x0B1D065BU,0x0FDC1BECU, - 0x3793A651U,0x3352BBE6U,0x3E119D3FU,0x3AD08088U, - 0x2497D08DU,0x2056CD3AU,0x2D15EBE3U,0x29D4F654U, - 0xC5A92679U,0xC1683BCEU,0xCC2B1D17U,0xC8EA00A0U, - 0xD6AD50A5U,0xD26C4D12U,0xDF2F6BCBU,0xDBEE767CU, - 0xE3A1CBC1U,0xE760D676U,0xEA23F0AFU,0xEEE2ED18U, - 0xF0A5BD1DU,0xF464A0AAU,0xF9278673U,0xFDE69BC4U, - 0x89B8FD09U,0x8D79E0BEU,0x803AC667U,0x84FBDBD0U, - 0x9ABC8BD5U,0x9E7D9662U,0x933EB0BBU,0x97FFAD0CU, - 0xAFB010B1U,0xAB710D06U,0xA6322BDFU,0xA2F33668U, - 0xBCB4666DU,0xB8757BDAU,0xB5365D03U,0xB1F740B4U, - }; - - while (len > 0) - { - crc = table[*data ^ ((crc >> 24) & 0xff)] ^ (crc << 8); - data++; - len--; - } - return crc; -} - -unsigned int -gr_update_crc32(unsigned int crc, const std::string s) -{ - return gr_update_crc32(crc, (const unsigned char *) s.data(), s.size()); -} - -unsigned int -gr_crc32(const unsigned char *buf, size_t len) -{ - return gr_update_crc32(0xffffffff, buf, len) ^ 0xffffffff; -} - -unsigned int -gr_crc32(const std::string s) -{ - return gr_crc32((const unsigned char *) s.data(), s.size()); -} diff --git a/gnuradio-core/src/lib/general/gr_crc32.h b/gnuradio-core/src/lib/general/gr_crc32.h deleted file mode 100644 index 87a8d15f2..000000000 --- a/gnuradio-core/src/lib/general/gr_crc32.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005 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_GR_CRC32_H -#define INCLUDED_GR_CRC32_H - -#include <string> -#include <gr_types.h> - -/*! - * \brief update running CRC-32 - * \ingroup misc - * - * Update a running CRC with the bytes buf[0..len-1] The CRC should be - * initialized to all 1's, and the transmitted value is the 1's - * complement of the final running CRC. The resulting CRC should be - * transmitted in big endian order. - */ -unsigned int -gr_update_crc32(unsigned int crc, const unsigned char *buf, size_t len); - -unsigned int -gr_update_crc32(unsigned int crc, const std::string buf); - -unsigned int -gr_crc32(const unsigned char *buf, size_t len); - -unsigned int -gr_crc32(const std::string buf); - -#endif /* INCLUDED_CRC32_H */ diff --git a/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.cc b/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.cc index d5425bfc8..c5e1320a3 100644 --- a/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.cc +++ b/gnuradio-core/src/lib/general/gr_decode_ccsds_27_fb.cc @@ -39,7 +39,7 @@ gr_decode_ccsds_27_fb::gr_decode_ccsds_27_fb() { float RATE = 0.5; float ebn0 = 12.0; - float esn0 = RATE*pow(10.0, ebn0/10); + float esn0 = RATE*pow(10.0, ebn0/10.0); gen_met(d_mettab, 100, esn0, 0.0, 256); viterbi_chunks_init(d_state0); diff --git a/gnuradio-core/src/lib/general/gr_feval.i b/gnuradio-core/src/lib/general/gr_feval.i index 8594a6fa1..c5522805d 100644 --- a/gnuradio-core/src/lib/general/gr_feval.i +++ b/gnuradio-core/src/lib/general/gr_feval.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -43,6 +43,9 @@ */ +// Directors are only supported in Python, Java and C# +#ifdef SWIGPYTHON + // Enable SWIG directors for these classes %feature("director") gr_py_feval_dd; %feature("director") gr_py_feval_cc; @@ -197,3 +200,5 @@ long gr_feval_ll_example(gr_feval_ll *f, long x); %rename(feval_example) gr_feval_example; void gr_feval_example(gr_feval *f); + +#endif // SWIGPYTHON diff --git a/gnuradio-core/src/lib/general/gr_fft_vcc.i b/gnuradio-core/src/lib/general/gr_fft_vcc.i index 247571374..f35316e70 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vcc.i +++ b/gnuradio-core/src/lib/general/gr_fft_vcc.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2007,2008 Free Software Foundation, Inc. + * Copyright 2004,2007,2008,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -23,7 +23,7 @@ GR_SWIG_BLOCK_MAGIC(gr, fft_vcc) gr_fft_vcc_sptr -gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> window, bool shift=false); +gr_make_fft_vcc (int fft_size, bool forward, const std::vector<float> &window, bool shift=false); class gr_fft_vcc : public gr_sync_block { diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.cc b/gnuradio-core/src/lib/general/gr_fft_vfc.cc index 608161efe..561c63740 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vfc.cc +++ b/gnuradio-core/src/lib/general/gr_fft_vfc.cc @@ -40,12 +40,12 @@ gr_fft_vfc_sptr -gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> window) +gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window) { return gnuradio::get_initial_sptr(new gr_fft_vfc (fft_size, forward, window)); } -gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward, const std::vector<float> window) +gr_fft_vfc::gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &window) : gr_sync_block ("fft_vfc", gr_make_io_signature (1, 1, fft_size * sizeof (float)), gr_make_io_signature (1, 1, fft_size * sizeof (gr_complex))), @@ -107,7 +107,7 @@ gr_fft_vfc::work (int noutput_items, } bool -gr_fft_vfc::set_window(const std::vector<float> window) +gr_fft_vfc::set_window(const std::vector<float> &window) { if(window.size()==0 || window.size()==d_fft_size) { d_window=window; diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.h b/gnuradio-core/src/lib/general/gr_fft_vfc.h index 054a383ef..074574477 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vfc.h +++ b/gnuradio-core/src/lib/general/gr_fft_vfc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -31,7 +31,7 @@ class gr_fft_vfc; typedef boost::shared_ptr<gr_fft_vfc> gr_fft_vfc_sptr; gr_fft_vfc_sptr -gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float>); +gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window); /*! * \brief Compute forward FFT. float vector in / complex vector out. @@ -41,13 +41,13 @@ gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float>); class gr_fft_vfc : public gr_sync_block { friend gr_fft_vfc_sptr - gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> window); + gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window); unsigned int d_fft_size; std::vector<float> d_window; gri_fft_complex *d_fft; - gr_fft_vfc (int fft_size, bool forward, const std::vector<float> window); + gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &window); public: ~gr_fft_vfc (); @@ -55,7 +55,7 @@ class gr_fft_vfc : public gr_sync_block int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); - bool set_window(const std::vector<float> window); + bool set_window(const std::vector<float> &window); }; diff --git a/gnuradio-core/src/lib/general/gr_fft_vfc.i b/gnuradio-core/src/lib/general/gr_fft_vfc.i index 90c368fe6..149745b58 100644 --- a/gnuradio-core/src/lib/general/gr_fft_vfc.i +++ b/gnuradio-core/src/lib/general/gr_fft_vfc.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -23,13 +23,14 @@ GR_SWIG_BLOCK_MAGIC(gr, fft_vfc) gr_fft_vfc_sptr -gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> window); +gr_make_fft_vfc (int fft_size, bool forward, const std::vector<float> &window) +throw(std::exception); class gr_fft_vfc : public gr_sync_block { protected: - gr_fft_vfc (int fft_size, bool forward, const std::vector<float> window); + gr_fft_vfc (int fft_size, bool forward, const std::vector<float> &window); public: - bool set_window(const std::vector<float> window); + bool set_window(const std::vector<float> &window); }; diff --git a/gnuradio-core/src/lib/general/gr_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index 8efeb3438..5d192d67e 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -574,7 +574,7 @@ gr_firdes::gaussian (double gain, vector<float> taps(ntaps); double scale = 0; double dt = 1.0/spb; - double s = 1.0/(sqrt(log(2)) / (2*M_PI*bt)); + double s = 1.0/(sqrt(log(2.0)) / (2*M_PI*bt)); double t0 = -0.5 * ntaps; double ts; for(int i=0;i<ntaps;i++) diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc deleted file mode 100644 index c32398e6d..000000000 --- a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.cc +++ /dev/null @@ -1,214 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2009,2010 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_fll_band_edge_cc.h> -#include <gr_fir_ccc.h> -#include <gr_fir_util.h> -#include <gri_fft.h> -#include <gr_io_signature.h> -#include <gr_expj.h> -#include <gr_math.h> -#include <cstdio> - -#define M_TWOPI (2*M_PI) - -float sinc(float x) -{ - if(x == 0) - return 1; - else - return sin(M_PI*x)/(M_PI*x); -} - - - -gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff, - int filter_size, float gain_alpha, float gain_beta) -{ - return gnuradio::get_initial_sptr(new gr_fll_band_edge_cc (samps_per_sym, rolloff, - filter_size, gain_alpha, gain_beta)); -} - - -static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(gr_complex)}; -static std::vector<int> iosig(ios, ios+sizeof(ios)/sizeof(int)); -gr_fll_band_edge_cc::gr_fll_band_edge_cc (float samps_per_sym, float rolloff, - int filter_size, float alpha, float beta) - : gr_sync_block ("fll_band_edge_cc", - gr_make_io_signature (1, 1, sizeof(gr_complex)), - gr_make_io_signaturev (1, 4, iosig)), - d_alpha(alpha), d_beta(beta), d_updated (false) -{ - // base this on the number of samples per symbol - d_max_freq = M_TWOPI * (2.0/samps_per_sym); - d_min_freq = -M_TWOPI * (2.0/samps_per_sym); - - d_freq = 0; - d_phase = 0; - - set_alpha(alpha); - - design_filter(samps_per_sym, rolloff, filter_size); -} - -gr_fll_band_edge_cc::~gr_fll_band_edge_cc () -{ - delete d_filter_lower; - delete d_filter_upper; -} - -void -gr_fll_band_edge_cc::set_alpha(float alpha) -{ - //float eta = sqrt(2.0)/2.0; - //float theta = alpha; - //d_alpha = (4*eta*theta) / (1.0 + 2.0*eta*theta + theta*theta); - //d_beta = (4*theta*theta) / (1.0 + 2.0*eta*theta + theta*theta); - d_alpha = alpha; -} - -void -gr_fll_band_edge_cc::design_filter(float samps_per_sym, float rolloff, int filter_size) -{ - int M = rint(filter_size / samps_per_sym); - float power = 0; - std::vector<float> bb_taps; - for(int i = 0; i < filter_size; i++) { - float k = -M + i*2.0/samps_per_sym; - float tap = sinc(rolloff*k - 0.5) + sinc(rolloff*k + 0.5); - power += tap; - - bb_taps.push_back(tap); - } - - int N = (bb_taps.size() - 1.0)/2.0; - std::vector<gr_complex> taps_lower; - std::vector<gr_complex> taps_upper; - for(unsigned int i = 0; i < bb_taps.size(); i++) { - float tap = bb_taps[i] / power; - - float k = (-N + (int)i)/(2.0*samps_per_sym); - - gr_complex t1 = tap * gr_expj(-2*M_PI*(1+rolloff)*k); - gr_complex t2 = tap * gr_expj(2*M_PI*(1+rolloff)*k); - - taps_lower.push_back(t1); - taps_upper.push_back(t2); - } - - std::vector<gr_complex> vtaps(0, taps_lower.size()); - d_filter_upper = gr_fir_util::create_gr_fir_ccc(vtaps); - d_filter_lower = gr_fir_util::create_gr_fir_ccc(vtaps); - - d_filter_lower->set_taps(taps_lower); - d_filter_upper->set_taps(taps_upper); - - d_updated = true; - - // Set the history to ensure enough input items for each filter - set_history(filter_size+1); - -} - -void -gr_fll_band_edge_cc::print_taps() -{ - unsigned int i; - std::vector<gr_complex> taps_upper = d_filter_upper->get_taps(); - std::vector<gr_complex> taps_lower = d_filter_lower->get_taps(); - - printf("Upper Band-edge: ["); - for(i = 0; i < taps_upper.size(); i++) { - printf(" %.4e + %.4ej,", taps_upper[i].real(), taps_upper[i].imag()); - } - printf("]\n\n"); - - printf("Lower Band-edge: ["); - for(i = 0; i < taps_lower.size(); i++) { - printf(" %.4e + %.4ej,", taps_lower[i].real(), taps_lower[i].imag()); - } - printf("]\n\n"); -} - -int -gr_fll_band_edge_cc::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - - float *frq = NULL; - float *phs = NULL; - gr_complex *err = NULL; - if(output_items.size() > 2) { - frq = (float *) output_items[1]; - phs = (float *) output_items[2]; - err = (gr_complex *) output_items[3]; - } - - if (d_updated) { - d_updated = false; - return 0; // history requirements may have changed. - } - - int i; - gr_complex nco_out; - gr_complex out_upper, out_lower; - float error; - float avg_k = 0.1; - for(i = 0; i < noutput_items; i++) { - nco_out = gr_expj(d_phase); - out[i] = in[i] * nco_out; - - out_upper = (d_filter_upper->filter(&out[i])); - out_lower = (d_filter_lower->filter(&out[i])); - error = -real((out_upper + out_lower) * conj(out_upper - out_lower)); - d_error = avg_k*error + avg_k*d_error; // average error - - d_freq = d_freq + d_beta * d_error; - d_phase = d_phase + d_freq + d_alpha * d_error; - - if(d_phase > M_PI) - d_phase -= M_TWOPI; - else if(d_phase < -M_PI) - d_phase += M_TWOPI; - - if (d_freq > d_max_freq) - d_freq = d_max_freq; - else if (d_freq < d_min_freq) - d_freq = d_min_freq; - - if(output_items.size() > 2) { - frq[i] = d_freq; - phs[i] = d_phase; - err[i] = d_error; - } - } - - - return noutput_items; -} diff --git a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h b/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h deleted file mode 100644 index db060793e..000000000 --- a/gnuradio-core/src/lib/general/gr_fll_band_edge_cc.h +++ /dev/null @@ -1,139 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2009 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_GR_FLL_BAND_EDGE_CC_H -#define INCLUDED_GR_FLL_BAND_EDGE_CC_H - -#include <gr_sync_block.h> - -class gr_fll_band_edge_cc; -typedef boost::shared_ptr<gr_fll_band_edge_cc> gr_fll_band_edge_cc_sptr; -gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff, - int filter_size, float alpha, float beta); - -class gr_fir_ccc; -class gri_fft_complex; - -/*! - * \class gr_fll_band_edge_cc - * \brief Frequency Lock Loop using band-edge filters - * - * \ingroup general - * - * The frequency lock loop derives a band-edge filter that covers the upper and lower bandwidths - * of a digitally-modulated signal. The bandwidth range is determined by the excess bandwidth - * (e.g., rolloff factor) of the modulated signal. The placement in frequency of the band-edges - * is determined by the oversampling ratio (number of samples per symbol) and the excess bandwidth. - * The size of the filters should be fairly large so as to average over a number of symbols. - * - * The FLL works by filtering the upper and lower band edges into x_u(t) and x_l(t), respectively. - * These are combined to form cc(t) = x_u(t) + x_l(t) and ss(t) = x_u(t) - x_l(t). Combining - * these to form the signal e(t) = Re{cc(t) \\times ss(t)^*} (where ^* is the complex conjugate) - * provides an error signal at the DC term that is directly proportional to the carrier frequency. - * We then make a second-order loop using the error signal that is the running average of e(t). - * - * In theory, the band-edge filter is the derivative of the matched filter in frequency, - * (H_be(f) = \\frac{H(f)}{df}. In practice, this comes down to a quarter sine wave at the point - * of the matched filter's rolloff (if it's a raised-cosine, the derivative of a cosine is a sine). - * Extend this sine by another quarter wave to make a half wave around the band-edges is equivalent - * in time to the sum of two sinc functions. The baseband filter fot the band edges is therefore - * derived from this sum of sincs. The band edge filters are then just the baseband signal - * modulated to the correct place in frequency. All of these calculations are done in the - * 'design_filter' function. - * - * Note: We use FIR filters here because the filters have to have a flat phase response over the - * entire frequency range to allow their comparisons to be valid. - */ - -class gr_fll_band_edge_cc : public gr_sync_block -{ - private: - /*! - * Build the FLL - * \param samps_per_sym (float) Number of samples per symbol of signal - * \param rolloff (float) Rolloff factor of signal - * \param filter_size (int) Size (in taps) of the filter - * \param alpha (float) Loop gain 1 - * \param beta (float) Loop gain 2 - */ - friend gr_fll_band_edge_cc_sptr gr_make_fll_band_edge_cc (float samps_per_sym, float rolloff, - int filter_size, float alpha, float beta); - - float d_alpha; - float d_beta; - float d_max_freq; - float d_min_freq; - - gr_fir_ccc* d_filter_upper; - gr_fir_ccc* d_filter_lower; - bool d_updated; - float d_error; - float d_freq; - float d_phase; - - /*! - * Build the FLL - * \param samps_per_sym (float) number of samples per symbol - * \param rolloff (float) Rolloff (excess bandwidth) of signal filter - * \param filter_size (int) number of filter taps to generate - * \param alpha (float) Alpha gain in the control loop - * \param beta (float) Beta gain in the control loop - */ - gr_fll_band_edge_cc(float samps_per_sym, float rolloff, - int filter_size, float alpha, float beta); - -public: - ~gr_fll_band_edge_cc (); - - /*! - * Design the band-edge filter based on the number of samples per symbol, - * filter rolloff factor, and the filter size - * \param samps_per_sym (float) Number of samples per symbol of signal - * \param rolloff (float) Rolloff factor of signal - * \param filter_size (int) Size (in taps) of the filter - */ - void design_filter(float samps_per_sym, float rolloff, int filter_size); - - /*! - * Set the alpha gainvalue - * \param alpha (float) new gain value - */ - void set_alpha(float alpha); - - /*! - * Set the beta gain value - * \param beta (float) new gain value - */ - void set_beta(float beta) { d_beta = beta; } - - /*! - * Print the taps to screen. - */ - void print_taps(); - - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc index 0f6f0d719..bff22be25 100644 --- a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc +++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -28,6 +28,7 @@ #include <gr_io_signature.h> #include <gr_sincos.h> #include <math.h> +#include <boost/math/special_functions/trunc.hpp> gr_frequency_modulator_fc_sptr gr_make_frequency_modulator_fc (double sensitivity) @@ -62,7 +63,7 @@ gr_frequency_modulator_fc::work (int noutput_items, // to avoid loss of precision in the addition above. if (fabs (d_phase) > 16 * M_PI){ - double ii = trunc (d_phase / (2 * M_PI)); + double ii = boost::math::trunc (d_phase / (2 * M_PI)); d_phase = d_phase - (ii * 2 * M_PI); } diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h index 4ba05d709..385f447b7 100644 --- a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h +++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h @@ -47,7 +47,9 @@ class gr_frequency_modulator_fc : public gr_sync_block gr_frequency_modulator_fc (double sensitivity); public: - + void set_sensitivity(float sens) { d_sensitivity = sens; } + float sensitivity() const { return d_sensitivity; } + int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i index 612b59026..7dfb82f1f 100644 --- a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i +++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i @@ -28,4 +28,7 @@ class gr_frequency_modulator_fc : public gr_sync_block { private: gr_frequency_modulator_fc (double sensitivity); +public: + void set_sensitivity(float sens) { d_sensitivity = sens; } + float sensitivity() const { return d_sensitivity; } }; diff --git a/gnuradio-core/src/lib/general/gr_fxpt.cc b/gnuradio-core/src/lib/general/gr_fxpt.cc index e752364a5..fae02c71e 100644 --- a/gnuradio-core/src/lib/general/gr_fxpt.cc +++ b/gnuradio-core/src/lib/general/gr_fxpt.cc @@ -30,9 +30,8 @@ const float gr_fxpt::s_sine_table[1 << NBITS][2] = { #include "sine_table.h" }; -// gcc 4.x fix -const float gr_fxpt::TWO_TO_THE_31; -const float gr_fxpt::PI; +const float gr_fxpt::PI = 3.14159265358979323846; +const float gr_fxpt::TWO_TO_THE_31 = 2147483648.0; #if 0 /* diff --git a/gnuradio-core/src/lib/general/gr_fxpt.h b/gnuradio-core/src/lib/general/gr_fxpt.h index 520729f8d..c98d31b27 100644 --- a/gnuradio-core/src/lib/general/gr_fxpt.h +++ b/gnuradio-core/src/lib/general/gr_fxpt.h @@ -40,8 +40,8 @@ class gr_fxpt static const int WORDBITS = 32; static const int NBITS = 10; static const float s_sine_table[1 << NBITS][2]; - static const float PI = 3.14159265358979323846; - static const float TWO_TO_THE_31 = 2147483648.0; + static const float PI; + static const float TWO_TO_THE_31; public: static gr_int32 diff --git a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.cc b/gnuradio-core/src/lib/general/gr_int_to_float.cc index ae8903abb..b5a19e5c0 100644 --- a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.cc +++ b/gnuradio-core/src/lib/general/gr_int_to_float.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2010 Free Software Foundation, Inc. + * Copyright 2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,41 +24,36 @@ #include "config.h" #endif -#include <gr_binary_slicer_fb.h> +#include <gr_int_to_float.h> #include <gr_io_signature.h> -#include <stdexcept> -gr_binary_slicer_fb_sptr -gr_make_binary_slicer_fb () +gr_int_to_float_sptr +gr_make_int_to_float () { - return gnuradio::get_initial_sptr(new gr_binary_slicer_fb ()); + return gnuradio::get_initial_sptr(new gr_int_to_float ()); } -gr_binary_slicer_fb::gr_binary_slicer_fb () - : gr_sync_block ("binary_slicer_fb", - gr_make_io_signature (1, 1, sizeof (float)), - gr_make_io_signature (1, 1, sizeof (unsigned char))) +gr_int_to_float::gr_int_to_float () + : gr_sync_block ("gr_int_to_float", + gr_make_io_signature (1, 1, sizeof (int32_t)), + gr_make_io_signature (1, 1, sizeof (float))) { } -static inline int -slice(float x) -{ - return x < 0 ? 0 : 1; -} - int -gr_binary_slicer_fb::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) +gr_int_to_float::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]; - + const int32_t *in = (const int32_t *) input_items[0]; + float *out = (float *) output_items[0]; - for (int i = 0; i < noutput_items; i++){ - out[i] = slice(in[i]); + for(int i=0; i < noutput_items; i++) { + out[i] = (float)in[i]; } return noutput_items; } + + + diff --git a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.h b/gnuradio-core/src/lib/general/gr_int_to_float.h index 2aa4a0828..cf1223be5 100644 --- a/gnuradio-core/src/lib/general/gr_binary_slicer_fb.h +++ b/gnuradio-core/src/lib/general/gr_int_to_float.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,32 +20,32 @@ * Boston, MA 02110-1301, USA. */ -#ifndef INCLUDED_GR_BINARY_SLICER_FB_H -#define INCLUDED_GR_BINARY_SLICER_FB_H +#ifndef INCLUDED_GR_INT_TO_FLOAT_H +#define INCLUDED_GR_INT_TO_FLOAT_H #include <gr_sync_block.h> -class gr_binary_slicer_fb; -typedef boost::shared_ptr<gr_binary_slicer_fb> gr_binary_slicer_fb_sptr; +class gr_int_to_float; +typedef boost::shared_ptr<gr_int_to_float> gr_int_to_float_sptr; -gr_binary_slicer_fb_sptr gr_make_binary_slicer_fb (); +gr_int_to_float_sptr +gr_make_int_to_float (); /*! - * \brief slice float binary symbol outputting 1 bit output + * \brief Convert stream of short to a stream of float * \ingroup converter_blk - * - * x < 0 --> 0 - * x >= 0 --> 1 */ -class gr_binary_slicer_fb : public gr_sync_block + +class gr_int_to_float : public gr_sync_block { - friend gr_binary_slicer_fb_sptr gr_make_binary_slicer_fb (); - gr_binary_slicer_fb (); + friend gr_int_to_float_sptr gr_make_int_to_float (); + gr_int_to_float (); public: - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + virtual int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); }; -#endif + +#endif /* INCLUDED_GR_INT_TO_FLOAT_H */ diff --git a/gnuradio-core/src/lib/general/gr_crc32.i b/gnuradio-core/src/lib/general/gr_int_to_float.i index 7dca5c6a1..8cb9e35b5 100644 --- a/gnuradio-core/src/lib/general/gr_crc32.i +++ b/gnuradio-core/src/lib/general/gr_int_to_float.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,8 +20,11 @@ * Boston, MA 02110-1301, USA. */ -%rename(update_crc32) gr_update_crc32; -%rename(crc32) gr_crc32; +GR_SWIG_BLOCK_MAGIC(gr,int_to_float) -unsigned int gr_update_crc32(unsigned int crc, const std::string buf); -unsigned int gr_crc32(const std::string buf); +gr_int_to_float_sptr gr_make_int_to_float (); + +class gr_int_to_float : public gr_sync_block +{ + gr_int_to_float (); +}; diff --git a/gnuradio-core/src/lib/general/gr_keep_one_in_n.cc b/gnuradio-core/src/lib/general/gr_keep_one_in_n.cc index c07e177fe..85495e277 100644 --- a/gnuradio-core/src/lib/general/gr_keep_one_in_n.cc +++ b/gnuradio-core/src/lib/general/gr_keep_one_in_n.cc @@ -38,8 +38,9 @@ gr_keep_one_in_n::gr_keep_one_in_n (size_t item_size, int n) : gr_block ("keep_one_in_n", gr_make_io_signature (1, 1, item_size), gr_make_io_signature (1, 1, item_size)), - d_n (n), d_count(n) + d_count(n) { + set_n(n); } void @@ -50,6 +51,8 @@ gr_keep_one_in_n::set_n(int n) d_n = n; d_count = n; + + set_relative_rate(1.0 / (float)n); } int diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.cc b/gnuradio-core/src/lib/general/gr_lms_dfe_cc.cc deleted file mode 100644 index 8659386d5..000000000 --- a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.cc +++ /dev/null @@ -1,148 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005,2010 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_lms_dfe_cc.h> -#include <gr_io_signature.h> -#include <gr_misc.h> -#include <iostream> - -gr_complex -gr_lms_dfe_cc::slicer_0deg (gr_complex sample) -{ - gr_complex out; - if(fabs(real(sample))>fabs(imag(sample))) { - if(real(sample) > 0) - out = gr_complex(1,0); - else - out = gr_complex(-1,0); - } - else { - if(imag(sample) > 0) - out = gr_complex(0,1); - else - out = gr_complex(0,-1); - } - return out; -} - -gr_complex -gr_lms_dfe_cc::slicer_45deg (gr_complex sample) -{ - gr_complex out; - if(real(sample) > 0) - out = gr_complex(1,0); - else - out = gr_complex(-1,0); - if(imag(sample) > 0) - out += gr_complex(0,1); - else - out += gr_complex(0,-1); - return out; -} - -gr_lms_dfe_cc_sptr -gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps) -{ - return gnuradio::get_initial_sptr(new gr_lms_dfe_cc (lambda_ff, lambda_fb, - num_fftaps, num_fbtaps)); -} - -gr_lms_dfe_cc::gr_lms_dfe_cc (float lambda_ff, float lambda_fb , - unsigned int num_fftaps, unsigned int num_fbtaps) - : gr_sync_block ("lms_dfe_cc", - gr_make_io_signature (1, 1, sizeof (gr_complex)), - gr_make_io_signature (1, 1, sizeof (gr_complex))), - d_lambda_ff (lambda_ff), d_lambda_fb (lambda_fb), - d_ff_delayline(gr_rounduppow2(num_fftaps)), - d_fb_delayline(gr_rounduppow2(num_fbtaps)), - d_ff_taps(num_fftaps),d_fb_taps(num_fbtaps), - d_ff_index(0), d_fb_index(0) -{ - gr_zero_vector(d_ff_taps); - d_ff_taps [d_ff_taps.size()/2] = 1; - - gr_zero_vector(d_fb_taps); - gr_zero_vector(d_ff_delayline); - gr_zero_vector(d_fb_delayline); -} - -int -gr_lms_dfe_cc::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *iptr = (const gr_complex *) input_items[0]; - gr_complex *optr = (gr_complex *) output_items[0]; - - gr_complex acc, decision, error; - unsigned int i; - - unsigned int ff_mask = d_ff_delayline.size() - 1; // size is power of 2 - unsigned int fb_mask = d_fb_delayline.size() - 1; - - int size = noutput_items; - while (size-- > 0){ - acc = 0; - d_ff_delayline[d_ff_index] = *iptr++; - - // Compute output - for (i=0; i < d_ff_taps.size(); i++) - acc += conj(d_ff_delayline[(i+d_ff_index) & ff_mask]) * d_ff_taps[i]; - - for (i=0; i < d_fb_taps.size(); i++) - acc -= conj(d_fb_delayline[(i+d_fb_index) & fb_mask]) * d_fb_taps[i]; - - decision = slicer_45deg(acc); - error = decision - acc; - - // Update taps - for (i=0; i < d_ff_taps.size(); i++) - d_ff_taps[i] += d_lambda_ff * conj(error) * d_ff_delayline[(i+d_ff_index) & ff_mask]; - - for (i=0; i < d_fb_taps.size(); i++) - d_fb_taps[i] -= d_lambda_fb * conj(error) * d_fb_delayline[(i+d_fb_index) & fb_mask]; - - d_fb_index = (d_fb_index - 1) & fb_mask; // Decrement index - d_ff_index = (d_ff_index - 1) & ff_mask; // Decrement index - - d_fb_delayline[d_fb_index] = decision; // Save decision in feedback - - *optr++ = acc; // Output decision - } - - if (0){ - std::cout << "FF Taps\t"; - for(i=0;i<d_ff_taps.size();i++) - std::cout << d_ff_taps[i] << "\t"; - std::cout << std::endl << "FB Taps\t"; - for(i=0;i<d_fb_taps.size();i++) - std::cout << d_fb_taps[i] << "\t"; - std::cout << std::endl; - } - - return noutput_items; -} diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.h b/gnuradio-core/src/lib/general/gr_lms_dfe_cc.h deleted file mode 100644 index 7b3a2c84e..000000000 --- a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005 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_GR_LMS_DFE_CC_H -#define INCLUDED_GR_LMS_DFE_CC_H - -#include <gr_sync_block.h> - -class gr_lms_dfe_cc; -typedef boost::shared_ptr<gr_lms_dfe_cc> gr_lms_dfe_cc_sptr; - -gr_lms_dfe_cc_sptr gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps); - -/*! - * \brief Least-Mean-Square Decision Feedback Equalizer (complex in/out) - * \ingroup eq_blk - */ -class gr_lms_dfe_cc : public gr_sync_block -{ - friend gr_lms_dfe_cc_sptr gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps); - - float d_lambda_ff; - float d_lambda_fb; - std::vector<gr_complex> d_ff_delayline; - std::vector<gr_complex> d_fb_delayline; - std::vector<gr_complex> d_ff_taps; - std::vector<gr_complex> d_fb_taps; - unsigned int d_ff_index; - unsigned int d_fb_index; - - gr_lms_dfe_cc (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps); - gr_complex slicer_0deg(gr_complex baud); - gr_complex slicer_45deg(gr_complex baud); - - public: - - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.cc b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.cc deleted file mode 100644 index 8a5e22c2f..000000000 --- a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.cc +++ /dev/null @@ -1,122 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005,2010 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_lms_dfe_ff.h> -#include <gr_io_signature.h> -#include <gr_misc.h> -#include <iostream> - -float -slice(float val) -{ - if (val>0) - return 1; - else - return -1; -} - -gr_lms_dfe_ff_sptr -gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps) -{ - return gnuradio::get_initial_sptr(new gr_lms_dfe_ff (lambda_ff,lambda_fb,num_fftaps,num_fbtaps)); -} - -gr_lms_dfe_ff::gr_lms_dfe_ff (float lambda_ff, float lambda_fb , - unsigned int num_fftaps, unsigned int num_fbtaps) - : gr_sync_block ("lms_dfe_ff", - gr_make_io_signature (1, 1, sizeof (float)), - gr_make_io_signature (1, 1, sizeof (float))), - d_lambda_ff (lambda_ff), d_lambda_fb (lambda_fb), - d_ff_delayline(gr_rounduppow2(num_fftaps)), - d_fb_delayline(gr_rounduppow2(num_fbtaps)), - d_ff_taps(num_fftaps), d_fb_taps(num_fbtaps), - d_ff_index(0), d_fb_index(0) -{ - gr_zero_vector(d_ff_taps); - d_ff_taps [d_ff_taps.size()/2] = 1; - - gr_zero_vector(d_fb_taps); - gr_zero_vector(d_ff_delayline); - gr_zero_vector(d_fb_delayline); -} - -int -gr_lms_dfe_ff::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const float *iptr = (const float *) input_items[0]; - float *optr = (float *) output_items[0]; - - float acc, decision, error; - unsigned int i; - - unsigned int ff_mask = d_ff_delayline.size() - 1; // size is power of 2 - unsigned int fb_mask = d_fb_delayline.size() - 1; - - int size = noutput_items; - while(size-- > 0) { - acc = 0; - d_ff_delayline[d_ff_index] = *iptr++; - - // Compute output - for (i=0; i < d_ff_taps.size(); i++) - acc += d_ff_delayline[(i+d_ff_index) & ff_mask] * d_ff_taps[i]; - - for (i=0; i < d_fb_taps.size(); i++) - acc -= d_fb_delayline[(i+d_fb_index) & fb_mask] * d_fb_taps[i]; - - decision = slice(acc); - error = decision - acc; - - // Update taps - for (i=0; i < d_ff_taps.size(); i++) - d_ff_taps[i] += d_lambda_ff * error * d_ff_delayline[(i+d_ff_index) & ff_mask]; - - for (i=0; i < d_fb_taps.size(); i++) - d_fb_taps[i] -= d_lambda_fb * error * d_fb_delayline[(i+d_fb_index) & fb_mask]; - - d_fb_index = (d_fb_index - 1) & fb_mask; // Decrement index - d_ff_index = (d_ff_index - 1) & ff_mask; // Decrement index - - d_fb_delayline[d_fb_index] = decision; // Save decision in feedback - - *optr++ = acc; // Output decision - } - - if (0){ - std::cout << "FF Taps\t"; - for(i=0;i<d_ff_taps.size();i++) - std::cout << d_ff_taps[i] << "\t"; - std::cout << std::endl << "FB Taps\t"; - for(i=0;i<d_fb_taps.size();i++) - std::cout << d_fb_taps[i] << "\t"; - std::cout << std::endl; - } - - return noutput_items; -} diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.h b/gnuradio-core/src/lib/general/gr_lms_dfe_ff.h deleted file mode 100644 index dd610c470..000000000 --- a/gnuradio-core/src/lib/general/gr_lms_dfe_ff.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005 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_GR_LMS_DFE_FF_H -#define INCLUDED_GR_LMS_DFE_FF_H - -#include <gr_sync_block.h> - -class gr_lms_dfe_ff; -typedef boost::shared_ptr<gr_lms_dfe_ff> gr_lms_dfe_ff_sptr; - -gr_lms_dfe_ff_sptr gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps); - -/*! - * \brief Least-Mean-Square Decision Feedback Equalizer (float in/out) - * \ingroup eq_blk - */ -class gr_lms_dfe_ff : public gr_sync_block -{ - friend gr_lms_dfe_ff_sptr gr_make_lms_dfe_ff (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps); - - float d_lambda_ff; - float d_lambda_fb; - std::vector<float> d_ff_delayline; - std::vector<float> d_fb_delayline; - std::vector<float> d_ff_taps; - std::vector<float> d_fb_taps; - unsigned int d_ff_index; - unsigned int d_fb_index; - - gr_lms_dfe_ff (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps); - - public: - - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); -}; - -#endif diff --git a/gnuradio-core/src/lib/general/gr_math.cc b/gnuradio-core/src/lib/general/gr_math.cc deleted file mode 100644 index 82dff469c..000000000 --- a/gnuradio-core/src/lib/general/gr_math.cc +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2003 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_math.h> -#include <math.h> - -/* - * Greatest Common Divisor, using Euclid's algorithm. - * [There are faster algorithms. See Knuth 4.5.2 if you care] - */ - -long -gr_gcd (long m, long n) -{ - if (m < 0) - m = -m; - - if (n < 0) - n = -n; - - while (n != 0){ - long t = m % n; - m = n; - n = t; - } - - return m; -} - - -/* - * These really need some configure hacking to figure out the right answer. - * As a stop gap, try for a macro, and if not that, then try std:: - */ - -// returns a non-zero value if value is "not-a-number" (NaN), and 0 otherwise - -#if defined(isnan) || !defined(CXX_HAS_STD_ISNAN) - -int -gr_isnan (double value) -{ - return isnan (value); -} - -#else - -int -gr_isnan (double value) -{ - return std::isnan (value); -} - -#endif - -// returns a non-zero value if the value of x has its sign bit set. -// -// This is not the same as `x < 0.0', because IEEE 754 floating point -// allows zero to be signed. The comparison `-0.0 < 0.0' is false, but -// `gr_signbit (-0.0)' will return a nonzero value. - -#ifdef signbit - -int -gr_signbit (double x) -{ - return signbit (x); -} - -#else - -int -gr_signbit (double x) -{ - return std::signbit (x); -} - - -#endif diff --git a/gnuradio-core/src/lib/general/gr_math.h b/gnuradio-core/src/lib/general/gr_math.h index ea0f20027..f5935c1da 100644 --- a/gnuradio-core/src/lib/general/gr_math.h +++ b/gnuradio-core/src/lib/general/gr_math.h @@ -35,19 +35,6 @@ gr_is_power_of_2(long x) return x != 0 && (x & (x-1)) == 0; } -long gr_gcd (long m, long n); - -// returns a non-zero value if value is "not-a-number" (NaN), and 0 otherwise -int gr_isnan (double value); - -// returns a non-zero value if the value of x has its sign bit set. -// -// This is not the same as `x < 0.0', because IEEE 754 floating point -// allows zero to be signed. The comparison `-0.0 < 0.0' is false, but -// `gr_signbit (-0.0)' will return a nonzero value. - -int gr_signbit (double x); - /*! * \brief Fast arc tangent using table lookup and linear interpolation * \ingroup misc diff --git a/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.cc b/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.cc deleted file mode 100644 index bc51c6769..000000000 --- a/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.cc +++ /dev/null @@ -1,322 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2005,2006,2007,2010 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 <gr_prefs.h> -#include <gr_mpsk_receiver_cc.h> -#include <stdexcept> -#include <gr_math.h> -#include <gr_expj.h> -#include <gri_mmse_fir_interpolator_cc.h> - - -#define M_TWOPI (2*M_PI) -#define VERBOSE_MM 0 // Used for debugging symbol timing loop -#define VERBOSE_COSTAS 0 // Used for debugging phase and frequency tracking - -// Public constructor - -gr_mpsk_receiver_cc_sptr -gr_make_mpsk_receiver_cc(unsigned int M, float theta, - float alpha, float beta, - float fmin, float fmax, - float mu, float gain_mu, - float omega, float gain_omega, float omega_rel) -{ - return gnuradio::get_initial_sptr(new gr_mpsk_receiver_cc (M, theta, - alpha, beta, - fmin, fmax, - mu, gain_mu, - omega, gain_omega, omega_rel)); -} - -gr_mpsk_receiver_cc::gr_mpsk_receiver_cc (unsigned int M, float theta, - float alpha, float beta, - float fmin, float fmax, - float mu, float gain_mu, - float omega, float gain_omega, float omega_rel) - : gr_block ("mpsk_receiver_cc", - gr_make_io_signature (1, 1, sizeof (gr_complex)), - gr_make_io_signature (1, 1, sizeof (gr_complex))), - d_M(M), d_theta(theta), - d_alpha(alpha), d_beta(beta), d_freq(0), d_max_freq(fmax), d_min_freq(fmin), d_phase(0), - d_current_const_point(0), - d_mu(mu), d_gain_mu(gain_mu), d_gain_omega(gain_omega), - d_omega_rel(omega_rel), d_max_omega(0), d_min_omega(0), - d_p_2T(0), d_p_1T(0), d_p_0T(0), d_c_2T(0), d_c_1T(0), d_c_0T(0) -{ - d_interp = new gri_mmse_fir_interpolator_cc(); - d_dl_idx = 0; - - set_omega(omega); - - if (omega <= 0.0) - throw std::out_of_range ("clock rate must be > 0"); - if (gain_mu < 0 || gain_omega < 0) - throw std::out_of_range ("Gains must be non-negative"); - - assert(d_interp->ntaps() <= DLLEN); - - // zero double length delay line. - for (unsigned int i = 0; i < 2 * DLLEN; i++) - d_dl[i] = gr_complex(0.0,0.0); - - // build the constellation vector from M - make_constellation(); - - // Select a phase detector and a decision maker for the modulation order - switch(d_M) { - case 2: // optimized algorithms for BPSK - d_phase_error_detector = &gr_mpsk_receiver_cc::phase_error_detector_bpsk; //bpsk; - d_decision = &gr_mpsk_receiver_cc::decision_bpsk; - break; - - case 4: // optimized algorithms for QPSK - d_phase_error_detector = &gr_mpsk_receiver_cc::phase_error_detector_qpsk; //qpsk; - d_decision = &gr_mpsk_receiver_cc::decision_qpsk; - break; - - default: // generic algorithms for any M (power of 2?) but not pretty - d_phase_error_detector = &gr_mpsk_receiver_cc::phase_error_detector_generic; - d_decision = &gr_mpsk_receiver_cc::decision_generic; - break; - } -} - -gr_mpsk_receiver_cc::~gr_mpsk_receiver_cc () -{ - delete d_interp; -} - -void -gr_mpsk_receiver_cc::forecast(int noutput_items, gr_vector_int &ninput_items_required) -{ - unsigned ninputs = ninput_items_required.size(); - for (unsigned i=0; i < ninputs; i++) - ninput_items_required[i] = (int) ceil((noutput_items * d_omega) + d_interp->ntaps()); -} - -// FIXME add these back in an test difference in performance -float -gr_mpsk_receiver_cc::phase_error_detector_qpsk(gr_complex sample) const -{ - float phase_error = 0; - if(fabsf(sample.real()) > fabsf(sample.imag())) { - if(sample.real() > 0) - phase_error = -sample.imag(); - else - phase_error = sample.imag(); - } - else { - if(sample.imag() > 0) - phase_error = sample.real(); - else - phase_error = -sample.real(); - } - - return phase_error; -} - -float -gr_mpsk_receiver_cc::phase_error_detector_bpsk(gr_complex sample) const -{ - return -(sample.real()*sample.imag()); -} - -float gr_mpsk_receiver_cc::phase_error_detector_generic(gr_complex sample) const -{ - //return gr_fast_atan2f(sample*conj(d_constellation[d_current_const_point])); - return -arg(sample*conj(d_constellation[d_current_const_point])); -} - -unsigned int -gr_mpsk_receiver_cc::decision_bpsk(gr_complex sample) const -{ - return (gr_branchless_binary_slicer(sample.real()) ^ 1); - //return gr_binary_slicer(sample.real()) ^ 1; -} - -unsigned int -gr_mpsk_receiver_cc::decision_qpsk(gr_complex sample) const -{ - unsigned int index; - - //index = gr_branchless_quad_0deg_slicer(sample); - index = gr_quad_0deg_slicer(sample); - return index; -} - -unsigned int -gr_mpsk_receiver_cc::decision_generic(gr_complex sample) const -{ - unsigned int min_m = 0; - float min_s = 65535; - - // Develop all possible constellation points and find the one that minimizes - // the Euclidean distance (error) with the sample - for(unsigned int m=0; m < d_M; m++) { - gr_complex diff = norm(d_constellation[m] - sample); - - if(fabs(diff.real()) < min_s) { - min_s = fabs(diff.real()); - min_m = m; - } - } - // Return the index of the constellation point that minimizes the error - return min_m; -} - - -void -gr_mpsk_receiver_cc::make_constellation() -{ - for(unsigned int m=0; m < d_M; m++) { - d_constellation.push_back(gr_expj((M_TWOPI/d_M)*m)); - } -} - -void -gr_mpsk_receiver_cc::mm_sampler(const gr_complex symbol) -{ - gr_complex sample, nco; - - d_mu--; // skip a number of symbols between sampling - d_phase += d_freq; // increment the phase based on the frequency of the rotation - - // Keep phase clamped and not walk to infinity - while(d_phase > M_TWOPI) - d_phase -= M_TWOPI; - while(d_phase < -M_TWOPI) - d_phase += M_TWOPI; - - nco = gr_expj(d_phase+d_theta); // get the NCO value for derotating the current sample - sample = nco*symbol; // get the downconverted symbol - - // Fill up the delay line for the interpolator - d_dl[d_dl_idx] = sample; - d_dl[(d_dl_idx + DLLEN)] = sample; // put this in the second half of the buffer for overflows - d_dl_idx = (d_dl_idx+1) % DLLEN; // Keep the delay line index in bounds -} - -void -gr_mpsk_receiver_cc::mm_error_tracking(gr_complex sample) -{ - gr_complex u, x, y; - float mm_error = 0; - - // Make sample timing corrections - - // set the delayed samples - d_p_2T = d_p_1T; - d_p_1T = d_p_0T; - d_p_0T = sample; - d_c_2T = d_c_1T; - d_c_1T = d_c_0T; - - d_current_const_point = (*this.*d_decision)(d_p_0T); // make a decision on the sample value - d_c_0T = d_constellation[d_current_const_point]; - - x = (d_c_0T - d_c_2T) * conj(d_p_1T); - y = (d_p_0T - d_p_2T) * conj(d_c_1T); - u = y - x; - mm_error = u.real(); // the error signal is in the real part - mm_error = gr_branchless_clip(mm_error, 1.0); // limit mm_val - - d_omega = d_omega + d_gain_omega * mm_error; // update omega based on loop error - d_omega = d_omega_mid + gr_branchless_clip(d_omega-d_omega_mid, d_omega_rel); // make sure we don't walk away - - d_mu += d_omega + d_gain_mu * mm_error; // update mu based on loop error - -#if VERBOSE_MM - printf("mm: mu: %f omega: %f mm_error: %f sample: %f+j%f constellation: %f+j%f\n", - d_mu, d_omega, mm_error, sample.real(), sample.imag(), - d_constellation[d_current_const_point].real(), d_constellation[d_current_const_point].imag()); -#endif -} - - -void -gr_mpsk_receiver_cc::phase_error_tracking(gr_complex sample) -{ - float phase_error = 0; - - // Make phase and frequency corrections based on sampled value - phase_error = (*this.*d_phase_error_detector)(sample); - - d_freq += d_beta*phase_error; // adjust frequency based on error - d_phase += d_freq + d_alpha*phase_error; // adjust phase based on error - - // Make sure we stay within +-2pi - while(d_phase > M_TWOPI) - d_phase -= M_TWOPI; - while(d_phase < -M_TWOPI) - d_phase += M_TWOPI; - - // Limit the frequency range - d_freq = gr_branchless_clip(d_freq, d_max_freq); - -#if VERBOSE_COSTAS - printf("cl: phase_error: %f phase: %f freq: %f sample: %f+j%f constellation: %f+j%f\n", - phase_error, d_phase, d_freq, sample.real(), sample.imag(), - d_constellation[d_current_const_point].real(), d_constellation[d_current_const_point].imag()); -#endif -} - -int -gr_mpsk_receiver_cc::general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const gr_complex *in = (const gr_complex *) input_items[0]; - gr_complex *out = (gr_complex *) output_items[0]; - - int i=0, o=0; - - while((o < noutput_items) && (i < ninput_items[0])) { - while((d_mu > 1) && (i < ninput_items[0])) { - mm_sampler(in[i]); // puts symbols into a buffer and adjusts d_mu - i++; - } - - if(i < ninput_items[0]) { - gr_complex interp_sample = d_interp->interpolate(&d_dl[d_dl_idx], d_mu); - - mm_error_tracking(interp_sample); // corrects M&M sample time - phase_error_tracking(interp_sample); // corrects phase and frequency offsets - - out[o++] = interp_sample; - } - } - - #if 0 - printf("ninput_items: %d noutput_items: %d consuming: %d returning: %d\n", - ninput_items[0], noutput_items, i, o); - #endif - - consume_each(i); - return o; -} diff --git a/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.h b/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.h deleted file mode 100644 index 024d74ada..000000000 --- a/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.h +++ /dev/null @@ -1,315 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004,2007 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_GR_MPSK_RECEIVER_CC_H -#define INCLUDED_GR_MPSK_RECEIVER_CC_H - -#include <gr_block.h> -#include <gr_complex.h> -#include <fstream> - -class gri_mmse_fir_interpolator_cc; - -class gr_mpsk_receiver_cc; -typedef boost::shared_ptr<gr_mpsk_receiver_cc> gr_mpsk_receiver_cc_sptr; - -// public constructor -gr_mpsk_receiver_cc_sptr -gr_make_mpsk_receiver_cc (unsigned int M, float theta, - float alpha, float beta, - float fmin, float fmax, - float mu, float gain_mu, - float omega, float gain_omega, float omega_rel); - -/*! - * \brief This block takes care of receiving M-PSK modulated signals through phase, frequency, and symbol - * synchronization. - * \ingroup sync_blk - * \ingroup demod_blk - * - * This block takes care of receiving M-PSK modulated signals through phase, frequency, and symbol - * synchronization. It performs carrier frequency and phase locking as well as symbol timing recovery. - * It works with (D)BPSK, (D)QPSK, and (D)8PSK as tested currently. It should also work for OQPSK and - * PI/4 DQPSK. - * - * The phase and frequency synchronization are based on a Costas loop that finds the error of the incoming - * signal point compared to its nearest constellation point. The frequency and phase of the NCO are - * updated according to this error. There are optimized phase error detectors for BPSK and QPSK, but 8PSK - * is done using a brute-force computation of the constellation points to find the minimum. - * - * The symbol synchronization is done using a modified Mueller and Muller circuit from the paper: - * - * G. R. Danesfahani, T.G. Jeans, "Optimisation of modified Mueller and Muller - * algorithm," Electronics Letters, Vol. 31, no. 13, 22 June 1995, pp. 1032 - 1033. - * - * This circuit interpolates the downconverted sample (using the NCO developed by the Costas loop) - * every mu samples, then it finds the sampling error based on this and the past symbols and the decision - * made on the samples. Like the phase error detector, there are optimized decision algorithms for BPSK - * and QPKS, but 8PSK uses another brute force computation against all possible symbols. The modifications - * to the M&M used here reduce self-noise. - * - */ - -class gr_mpsk_receiver_cc : public gr_block -{ - public: - ~gr_mpsk_receiver_cc (); - void forecast(int noutput_items, gr_vector_int &ninput_items_required); - int general_work (int noutput_items, - gr_vector_int &ninput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); - - - // Member functions related to the symbol tracking portion of the receiver - //! (M&M) Returns current value of mu - float mu() const { return d_mu;} - - //! (M&M) Returns current value of omega - float omega() const { return d_omega;} - - //! (M&M) Returns mu gain factor - float gain_mu() const { return d_gain_mu;} - - //! (M&M) Returns omega gain factor - float gain_omega() const { return d_gain_omega;} - - //! (M&M) Sets value of mu - void set_mu (float mu) { d_mu = mu; } - - //! (M&M) Sets value of omega and its min and max values - void set_omega (float omega) { - d_omega = omega; - d_min_omega = omega*(1.0 - d_omega_rel); - d_max_omega = omega*(1.0 + d_omega_rel); - d_omega_mid = 0.5*(d_min_omega+d_max_omega); - } - - //! (M&M) Sets value for mu gain factor - void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; } - - //! (M&M) Sets value for omega gain factor - void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; } - - - - // Member function related to the phase/frequency tracking portion of the receiver - //! (CL) Returns the value for alpha (the phase gain term) - float alpha() const { return d_alpha; } - - //! (CL) Returns the value of beta (the frequency gain term) - float beta() const { return d_beta; } - - //! (CL) Returns the current value of the frequency of the NCO in the Costas loop - float freq() const { return d_freq; } - - //! (CL) Returns the current value of the phase of the NCO in the Costal loop - float phase() const { return d_phase; } - - //! (CL) Sets the value for alpha (the phase gain term) - void set_alpha(float alpha) { d_alpha = alpha; } - - //! (CL) Setss the value of beta (the frequency gain term) - void set_beta(float beta) { d_beta = beta; } - - //! (CL) Sets the current value of the frequency of the NCO in the Costas loop - void set_freq(float freq) { d_freq = freq; } - - //! (CL) Setss the current value of the phase of the NCO in the Costal loop - void set_phase(float phase) { d_phase = phase; } - - -protected: - - /*! - * \brief Constructor to synchronize incoming M-PSK symbols - * - * \param M modulation order of the M-PSK modulation - * \param theta any constant phase rotation from the real axis of the constellation - * \param alpha gain parameter to adjust the phase in the Costas loop (~0.01) - * \param beta gain parameter to adjust the frequency in the Costas loop (~alpha^2/4) - * \param fmin minimum normalized frequency value the loop can achieve - * \param fmax maximum normalized frequency value the loop can achieve - * \param mu initial parameter for the interpolator [0,1] - * \param gain_mu gain parameter of the M&M error signal to adjust mu (~0.05) - * \param omega initial value for the number of symbols between samples (~number of samples/symbol) - * \param gain_omega gain parameter to adjust omega based on the error (~omega^2/4) - * \param omega_rel sets the maximum (omega*(1+omega_rel)) and minimum (omega*(1+omega_rel)) omega (~0.005) - * - * The constructor also chooses which phase detector and decision maker to use in the work loop based on the - * value of M. - */ - gr_mpsk_receiver_cc (unsigned int M, float theta, - float alpha, float beta, - float fmin, float fmax, - float mu, float gain_mu, - float omega, float gain_omega, float omega_rel); - - void make_constellation(); - void mm_sampler(const gr_complex symbol); - void mm_error_tracking(gr_complex sample); - void phase_error_tracking(gr_complex sample); - - -/*! - * \brief Phase error detector for MPSK modulations. - * - * \param sample the I&Q sample from which to determine the phase error - * - * This function determines the phase error for any MPSK signal by creating a set of PSK constellation points - * and doing a brute-force search to see which point minimizes the Euclidean distance. This point is then used - * to derotate the sample to the real-axis and a atan (using the fast approximation function) to determine the - * phase difference between the incoming sample and the real constellation point - * - * This should be cleaned up and made more efficient. - * - * \returns the approximated phase error. - */ - float phase_error_detector_generic(gr_complex sample) const; // generic for M but more costly - - /*! - * \brief Phase error detector for BPSK modulation. - * - * \param sample the I&Q sample from which to determine the phase error - * - * This function determines the phase error using a simple BPSK phase error detector by multiplying the real - * and imaginary (the error signal) components together. As the imaginary part goes to 0, so does this error. - * - * \returns the approximated phase error. - */ - float phase_error_detector_bpsk(gr_complex sample) const; // optimized for BPSK - - /*! - * \brief Phase error detector for QPSK modulation. - * - * \param sample the I&Q sample from which to determine the phase error - * - * This function determines the phase error using the limiter approach in a standard 4th order Costas loop - * - * \returns the approximated phase error. - */ - float phase_error_detector_qpsk(gr_complex sample) const; - - - - /*! - * \brief Decision maker for a generic MPSK constellation. - * - * \param sample the baseband I&Q sample from which to make the decision - * - * This decision maker is a generic implementation that does a brute-force search - * for the constellation point that minimizes the error between it and the incoming signal. - * - * \returns the index to d_constellation that minimizes the error/ - */ - unsigned int decision_generic(gr_complex sample) const; - - - /*! - * \brief Decision maker for BPSK constellation. - * - * \param sample the baseband I&Q sample from which to make the decision - * - * This decision maker is a simple slicer function that makes a decision on the symbol based on its - * placement on the real axis of greater than 0 or less than 0; the quadrature component is always 0. - * - * \returns the index to d_constellation that minimizes the error/ - */ - unsigned int decision_bpsk(gr_complex sample) const; - - - /*! - * \brief Decision maker for QPSK constellation. - * - * \param sample the baseband I&Q sample from which to make the decision - * - * This decision maker is a simple slicer function that makes a decision on the symbol based on its - * placement versus both axes and returns which quadrant the symbol is in. - * - * \returns the index to d_constellation that minimizes the error/ - */ - unsigned int decision_qpsk(gr_complex sample) const; - - private: - unsigned int d_M; - float d_theta; - - // Members related to carrier and phase tracking - float d_alpha; - float d_beta; - float d_freq, d_max_freq, d_min_freq; - float d_phase; - -/*! - * \brief Decision maker function pointer - * - * \param sample the baseband I&Q sample from which to make the decision - * - * This is a function pointer that is set in the constructor to point to the proper decision function - * for the specified constellation order. - * - * \return index into d_constellation point that is the closest to the recieved sample - */ - unsigned int (gr_mpsk_receiver_cc::*d_decision)(gr_complex sample) const; // pointer to decision function - - - std::vector<gr_complex> d_constellation; - unsigned int d_current_const_point; - - // Members related to symbol timing - float d_mu, d_gain_mu; - float d_omega, d_gain_omega, d_omega_rel, d_max_omega, d_min_omega, d_omega_mid; - gr_complex d_p_2T, d_p_1T, d_p_0T; - gr_complex d_c_2T, d_c_1T, d_c_0T; - - /*! - * \brief Phase error detector function pointer - * - * \param sample the I&Q sample from which to determine the phase error - * - * This is a function pointer that is set in the constructor to point to the proper phase error detector - * function for the specified constellation order. - */ - float (gr_mpsk_receiver_cc::*d_phase_error_detector)(gr_complex sample) const; - - - //! get interpolated value - gri_mmse_fir_interpolator_cc *d_interp; - - //! delay line length. - static const unsigned int DLLEN = 8; - - //! delay line plus some length for overflow protection - gr_complex d_dl[2*DLLEN] __attribute__ ((aligned(8))); - - //! index to delay line - unsigned int d_dl_idx; - - friend gr_mpsk_receiver_cc_sptr - gr_make_mpsk_receiver_cc (unsigned int M, float theta, - float alpha, float beta, - float fmin, float fmax, - float mu, float gain_mu, - float omega, float gain_omega, float omega_rel); -}; - -#endif diff --git a/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.i b/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.i deleted file mode 100644 index 88cb43e04..000000000 --- a/gnuradio-core/src/lib/general/gr_mpsk_receiver_cc.i +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 2004 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. - */ - -GR_SWIG_BLOCK_MAGIC(gr,mpsk_receiver_cc); - -gr_mpsk_receiver_cc_sptr gr_make_mpsk_receiver_cc (unsigned int M, float theta, - float alpha, float beta, - float fmin, float fmax, - float mu, float gain_mu, - float omega, float gain_omega, float omega_rel); -class gr_mpsk_receiver_cc : public gr_block -{ - private: - gr_mpsk_receiver_cc (unsigned int M,float theta, - float alpha, float beta, - float fmin, float fmax, - float mu, float gain_mu, - float omega, float gain_omega, float omega_rel); -public: - float mu() const { return d_mu;} - float omega() const { return d_omega;} - float gain_mu() const { return d_gain_mu;} - float gain_omega() const { return d_gain_omega;} - void set_mu (float mu) { d_mu = mu; } - void set_omega (float omega) { - d_omega = omega; - d_min_omega = omega*(1.0 - d_omega_rel); - d_max_omega = omega*(1.0 + d_omega_rel); - } - void set_gain_mu (float gain_mu) { d_gain_mu = gain_mu; } - void set_gain_omega (float gain_omega) { d_gain_omega = gain_omega; } - float alpha() const { return d_alpha; } - float beta() const { return d_beta; } - float freq() const { return d_freq; } - float phase() const { return d_phase; } - void set_alpha(float alpha) { d_alpha = alpha; } - void set_beta(float beta) { d_beta = beta; } - void set_freq(float freq) { d_freq = freq; } - void set_phase(float phase) { d_phase = phase; } -}; diff --git a/gnuradio-core/src/lib/general/gr_nop.cc b/gnuradio-core/src/lib/general/gr_nop.cc index e69c8b340..bd5e4fd81 100644 --- a/gnuradio-core/src/lib/general/gr_nop.cc +++ b/gnuradio-core/src/lib/general/gr_nop.cc @@ -25,18 +25,30 @@ #endif #include <gr_nop.h> #include <gr_io_signature.h> +#include <boost/bind.hpp> + +gr_nop_sptr +gr_make_nop (size_t sizeof_stream_item) +{ + return gnuradio::get_initial_sptr (new gr_nop (sizeof_stream_item)); +} gr_nop::gr_nop (size_t sizeof_stream_item) : gr_block ("nop", - gr_make_io_signature (0, -1, sizeof_stream_item), - gr_make_io_signature (0, -1, sizeof_stream_item)) + gr_make_io_signature (0, -1, sizeof_stream_item), + gr_make_io_signature (0, -1, sizeof_stream_item)), + d_nmsgs_recvd(0) { + // Arrange to have count_received_msgs called when messages are received. + set_msg_handler(boost::bind(&gr_nop::count_received_msgs, this, _1)); } -gr_block_sptr -gr_make_nop (size_t sizeof_stream_item) +// Trivial message handler that just counts them. +// (N.B., This feature is used in qa_set_msg_handler) +void +gr_nop::count_received_msgs(pmt::pmt_t msg) { - return gnuradio::get_initial_sptr (new gr_nop (sizeof_stream_item)); + d_nmsgs_recvd++; } int @@ -51,5 +63,3 @@ gr_nop::general_work (int noutput_items, return noutput_items; } - - diff --git a/gnuradio-core/src/lib/general/gr_nop.h b/gnuradio-core/src/lib/general/gr_nop.h index 60b20c5ab..354c2f9fc 100644 --- a/gnuradio-core/src/lib/general/gr_nop.h +++ b/gnuradio-core/src/lib/general/gr_nop.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,24 +26,35 @@ #include <gr_block.h> #include <stddef.h> // size_t +class gr_nop; +typedef boost::shared_ptr<gr_nop> gr_nop_sptr; + +gr_nop_sptr +gr_make_nop (size_t sizeof_stream_item); + /*! * \brief Does nothing. Used for testing only. * \ingroup misc_blk */ class gr_nop : public gr_block { - friend gr_block_sptr gr_make_nop (size_t sizeof_stream_item); - + friend gr_nop_sptr gr_make_nop (size_t sizeof_stream_item); gr_nop (size_t sizeof_stream_item); +protected: + int d_nmsgs_recvd; + + // Method that just counts any received messages. + void count_received_msgs(pmt::pmt_t msg); + public: virtual int general_work (int noutput_items, gr_vector_int &ninput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); -}; -gr_block_sptr -gr_make_nop (size_t sizeof_stream_item); + int nmsgs_received() const { return d_nmsgs_recvd; } + +}; #endif /* INCLUDED_GR_NOP_H */ diff --git a/gnuradio-core/src/lib/general/gr_nop.i b/gnuradio-core/src/lib/general/gr_nop.i index 8220e5c6c..85354d421 100644 --- a/gnuradio-core/src/lib/general/gr_nop.i +++ b/gnuradio-core/src/lib/general/gr_nop.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,11 +20,12 @@ * Boston, MA 02110-1301, USA. */ -%ignore gr_nop; +GR_SWIG_BLOCK_MAGIC(gr,nop) + +gr_nop_sptr gr_make_nop (size_t sizeof_stream_item); + class gr_nop : public gr_block { - friend gr_block_sptr gr_make_nop (size_t sizeof_stream_item); +private: gr_nop (size_t sizeof_stream_item); }; -%rename(nop) gr_make_nop; -gr_block_sptr gr_make_nop (size_t sizeof_stream_item); diff --git a/gnuradio-core/src/lib/general/gr_null_sink.cc b/gnuradio-core/src/lib/general/gr_null_sink.cc index 0b7f2d9e8..67ef57a46 100644 --- a/gnuradio-core/src/lib/general/gr_null_sink.cc +++ b/gnuradio-core/src/lib/general/gr_null_sink.cc @@ -34,7 +34,7 @@ gr_null_sink::gr_null_sink (size_t sizeof_stream_item) { } -gr_block_sptr +gr_null_sink_sptr gr_make_null_sink (size_t sizeof_stream_item) { return gnuradio::get_initial_sptr (new gr_null_sink (sizeof_stream_item)); diff --git a/gnuradio-core/src/lib/general/gr_null_sink.h b/gnuradio-core/src/lib/general/gr_null_sink.h index 66df5d138..6d00382a5 100644 --- a/gnuradio-core/src/lib/general/gr_null_sink.h +++ b/gnuradio-core/src/lib/general/gr_null_sink.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,15 +26,20 @@ #include <gr_sync_block.h> #include <stddef.h> // size_t +class gr_null_sink; +typedef boost::shared_ptr<gr_null_sink> gr_null_sink_sptr; + +gr_null_sink_sptr +gr_make_null_sink (size_t sizeof_stream_item); + + /*! * \brief Bit bucket * \ingroup sink_blk */ - class gr_null_sink : public gr_sync_block { - friend gr_block_sptr gr_make_null_sink (size_t sizeof_stream_item); - + friend gr_null_sink_sptr gr_make_null_sink (size_t sizeof_stream_item); gr_null_sink (size_t sizeof_stream_item); public: @@ -45,7 +50,4 @@ class gr_null_sink : public gr_sync_block }; -gr_block_sptr -gr_make_null_sink (size_t sizeof_stream_item); - #endif /* INCLUDED_GR_NULL_SINK_H */ diff --git a/gnuradio-core/src/lib/general/gr_null_sink.i b/gnuradio-core/src/lib/general/gr_null_sink.i index fc4bcffda..e739ce118 100644 --- a/gnuradio-core/src/lib/general/gr_null_sink.i +++ b/gnuradio-core/src/lib/general/gr_null_sink.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,11 +20,12 @@ * Boston, MA 02110-1301, USA. */ -%ignore gr_null_sink; +GR_SWIG_BLOCK_MAGIC(gr,null_sink) + +gr_null_sink_sptr gr_make_null_sink (size_t sizeof_stream_item); + class gr_null_sink : public gr_sync_block { - friend gr_block_sptr gr_make_null_sink (size_t sizeof_stream_item); +private: gr_null_sink (size_t sizeof_stream_item); }; -%rename(null_sink) gr_make_null_sink; -gr_block_sptr gr_make_null_sink (size_t sizeof_stream_item); diff --git a/gnuradio-core/src/lib/general/gr_null_source.cc b/gnuradio-core/src/lib/general/gr_null_source.cc index b65c39035..85fd2db4b 100644 --- a/gnuradio-core/src/lib/general/gr_null_source.cc +++ b/gnuradio-core/src/lib/general/gr_null_source.cc @@ -35,7 +35,7 @@ gr_null_source::gr_null_source (size_t sizeof_stream_item) { } -gr_block_sptr +gr_null_source_sptr gr_make_null_source (size_t sizeof_stream_item) { return gnuradio::get_initial_sptr (new gr_null_source (sizeof_stream_item)); diff --git a/gnuradio-core/src/lib/general/gr_null_source.h b/gnuradio-core/src/lib/general/gr_null_source.h index 63b1939bf..b1a46a195 100644 --- a/gnuradio-core/src/lib/general/gr_null_source.h +++ b/gnuradio-core/src/lib/general/gr_null_source.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -25,14 +25,19 @@ #include <gr_sync_block.h> +class gr_null_source; +typedef boost::shared_ptr<gr_null_source> gr_null_source_sptr; + +gr_null_source_sptr +gr_make_null_source (size_t sizeof_stream_item); + /*! * \brief A source of zeros. * \ingroup source_blk */ - class gr_null_source : public gr_sync_block { - friend gr_block_sptr gr_make_null_source (size_t sizeof_stream_item); + friend gr_null_source_sptr gr_make_null_source (size_t sizeof_stream_item); gr_null_source (size_t sizeof_stream_item); @@ -43,7 +48,4 @@ class gr_null_source : public gr_sync_block }; -gr_block_sptr -gr_make_null_source (size_t sizeof_stream_item); - #endif /* INCLUDED_GR_NULL_SOURCE_H */ diff --git a/gnuradio-core/src/lib/general/gr_null_source.i b/gnuradio-core/src/lib/general/gr_null_source.i index f9ddef86f..133161d0a 100644 --- a/gnuradio-core/src/lib/general/gr_null_source.i +++ b/gnuradio-core/src/lib/general/gr_null_source.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,11 +20,12 @@ * Boston, MA 02110-1301, USA. */ -%ignore gr_null_source; +GR_SWIG_BLOCK_MAGIC(gr,null_source) + +gr_null_source_sptr gr_make_null_source (size_t sizeof_stream_item); + class gr_null_source : public gr_sync_block { - friend gr_block_sptr gr_make_null_source (size_t sizeof_stream_item); +private: gr_null_source (size_t sizeof_stream_item); }; -%rename(null_source) gr_make_null_source; -gr_block_sptr gr_make_null_source (size_t sizeof_stream_item); diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc index 3457370eb..279945766 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink.cc @@ -281,7 +281,7 @@ gr_ofdm_frame_sink::set_sym_value_out(const std::vector<gr_complex> &sym_positio d_sym_position = sym_position; d_sym_value_out = sym_value_out; - d_nbits = (unsigned long)ceil(log10(d_sym_value_out.size()) / log10(2.0)); + d_nbits = (unsigned long)ceil(log10(float(d_sym_value_out.size())) / log10(2.0)); return true; } diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.cc b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.cc new file mode 100644 index 000000000..40574b4e9 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.cc @@ -0,0 +1,374 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2008,2010,2011 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_ofdm_frame_sink2.h> +#include <gr_io_signature.h> +#include <gr_expj.h> +#include <gr_math.h> +#include <math.h> +#include <cstdio> +#include <stdexcept> +#include <iostream> +#include <string.h> +#include <gr_constellation.h> + +#define VERBOSE 0 + +inline void +gr_ofdm_frame_sink2::enter_search() +{ + if (VERBOSE) + fprintf(stderr, "@ enter_search\n"); + + d_state = STATE_SYNC_SEARCH; + +} + +inline void +gr_ofdm_frame_sink2::enter_have_sync() +{ + if (VERBOSE) + fprintf(stderr, "@ enter_have_sync\n"); + + d_state = STATE_HAVE_SYNC; + + // clear state of demapper + d_byte_offset = 0; + d_partial_byte = 0; + + d_header = 0; + d_headerbytelen_cnt = 0; + + // Resetting PLL + d_freq = 0.0; + d_phase = 0.0; + fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0)); +} + +inline void +gr_ofdm_frame_sink2::enter_have_header() +{ + d_state = STATE_HAVE_HEADER; + + // header consists of two 16-bit shorts in network byte order + // payload length is lower 12 bits + // whitener offset is upper 4 bits + d_packetlen = (d_header >> 16) & 0x0fff; + d_packet_whitener_offset = (d_header >> 28) & 0x000f; + d_packetlen_cnt = 0; + + if (VERBOSE) + fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n", + d_packetlen, d_packet_whitener_offset); +} + + +unsigned int gr_ofdm_frame_sink2::demapper(const gr_complex *in, + unsigned char *out) +{ + unsigned int i=0, bytes_produced=0; + gr_complex carrier; + + carrier=gr_expj(d_phase); + + gr_complex accum_error = 0.0; + //while(i < d_occupied_carriers) { + while(i < d_subcarrier_map.size()) { + if(d_nresid > 0) { + d_partial_byte |= d_resid; + d_byte_offset += d_nresid; + d_nresid = 0; + d_resid = 0; + } + + //while((d_byte_offset < 8) && (i < d_occupied_carriers)) { + while((d_byte_offset < 8) && (i < d_subcarrier_map.size())) { + //gr_complex sigrot = in[i]*carrier*d_dfe[i]; + gr_complex sigrot = in[d_subcarrier_map[i]]*carrier*d_dfe[i]; + + if(d_derotated_output != NULL){ + d_derotated_output[i] = sigrot; + } + + unsigned char bits = d_constell->decision_maker(&sigrot); + + gr_complex closest_sym = d_constell->points()[bits]; + + accum_error += sigrot * conj(closest_sym); + + // FIX THE FOLLOWING STATEMENT + if (norm(sigrot)> 0.001) d_dfe[i] += d_eq_gain*(closest_sym/sigrot-d_dfe[i]); + + i++; + + if((8 - d_byte_offset) >= d_nbits) { + d_partial_byte |= bits << (d_byte_offset); + d_byte_offset += d_nbits; + } + else { + d_nresid = d_nbits-(8-d_byte_offset); + int mask = ((1<<(8-d_byte_offset))-1); + d_partial_byte |= (bits & mask) << d_byte_offset; + d_resid = bits >> (8-d_byte_offset); + d_byte_offset += (d_nbits - d_nresid); + } + //printf("demod symbol: %.4f + j%.4f bits: %x partial_byte: %x byte_offset: %d resid: %x nresid: %d\n", + // in[i-1].real(), in[i-1].imag(), bits, d_partial_byte, d_byte_offset, d_resid, d_nresid); + } + + if(d_byte_offset == 8) { + //printf("demod byte: %x \n\n", d_partial_byte); + out[bytes_produced++] = d_partial_byte; + d_byte_offset = 0; + d_partial_byte = 0; + } + } + //std::cerr << "accum_error " << accum_error << std::endl; + + float angle = arg(accum_error); + + d_freq = d_freq - d_freq_gain*angle; + d_phase = d_phase + d_freq - d_phase_gain*angle; + if (d_phase >= 2*M_PI) d_phase -= 2*M_PI; + if (d_phase <0) d_phase += 2*M_PI; + + //if(VERBOSE) + // std::cerr << angle << "\t" << d_freq << "\t" << d_phase << "\t" << std::endl; + + return bytes_produced; +} + + +gr_ofdm_frame_sink2_sptr +gr_make_ofdm_frame_sink2(gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_carriers, + float phase_gain, float freq_gain) +{ + return gnuradio::get_initial_sptr(new gr_ofdm_frame_sink2(constell, + target_queue, occupied_carriers, + phase_gain, freq_gain)); +} + + +gr_ofdm_frame_sink2::gr_ofdm_frame_sink2(gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_carriers, + float phase_gain, float freq_gain) + : gr_sync_block ("ofdm_frame_sink2", + gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char)), + gr_make_io_signature (1, 1, sizeof(gr_complex)*occupied_carriers)), + d_constell(constell), + d_target_queue(target_queue), d_occupied_carriers(occupied_carriers), + d_byte_offset(0), d_partial_byte(0), + d_resid(0), d_nresid(0),d_phase(0),d_freq(0),d_phase_gain(phase_gain),d_freq_gain(freq_gain), + d_eq_gain(0.05) +{ + if (d_constell->dimensionality() != 1) + throw std::runtime_error ("This receiver only works with constellations of dimension 1."); + + std::string carriers = "FE7F"; + + // A bit hacky to fill out carriers to occupied_carriers length + int diff = (d_occupied_carriers - 4*carriers.length()); + while(diff > 7) { + carriers.insert(0, "f"); + carriers.insert(carriers.length(), "f"); + diff -= 8; + } + + // if there's extras left to be processed + // divide remaining to put on either side of current map + // all of this is done to stick with the concept of a carrier map string that + // can be later passed by the user, even though it'd be cleaner to just do this + // on the carrier map itself + int diff_left=0; + int diff_right=0; + + // dictionary to convert from integers to ascii hex representation + char abc[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + if(diff > 0) { + char c[2] = {0,0}; + + diff_left = (int)ceil((float)diff/2.0f); // number of carriers to put on the left side + c[0] = abc[(1 << diff_left) - 1]; // convert to bits and move to ASCI integer + carriers.insert(0, c); + + diff_right = diff - diff_left; // number of carriers to put on the right side + c[0] = abc[0xF^((1 << diff_right) - 1)]; // convert to bits and move to ASCI integer + carriers.insert(carriers.length(), c); + } + + // It seemed like such a good idea at the time... + // because we are only dealing with the occupied_carriers + // at this point, the diff_left in the following compensates + // for any offset from the 0th carrier introduced + unsigned int i,j,k; + for(i = 0; i < (d_occupied_carriers/4)+diff_left; i++) { + char c = carriers[i]; + for(j = 0; j < 4; j++) { + k = (strtol(&c, NULL, 16) >> (3-j)) & 0x1; + if(k) { + d_subcarrier_map.push_back(4*i + j - diff_left); + } + } + } + + // make sure we stay in the limit currently imposed by the occupied_carriers + if(d_subcarrier_map.size() > d_occupied_carriers) { + throw std::invalid_argument("gr_ofdm_mapper_bcv: subcarriers allocated exceeds size of occupied carriers"); + } + + d_bytes_out = new unsigned char[d_occupied_carriers]; + d_dfe.resize(occupied_carriers); + fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0)); + + d_nbits = d_constell->bits_per_symbol(); + + enter_search(); +} + +gr_ofdm_frame_sink2::~gr_ofdm_frame_sink2 () +{ + delete [] d_bytes_out; +} + + +int +gr_ofdm_frame_sink2::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const gr_complex *in = (const gr_complex *) input_items[0]; + const char *sig = (const char *) input_items[1]; + unsigned int j = 0; + unsigned int bytes=0; + + // If the output is connected, send it the derotated symbols + if(output_items.size() >= 1) + d_derotated_output = (gr_complex *)output_items[0]; + else + d_derotated_output = NULL; + + if (VERBOSE) + fprintf(stderr,">>> Entering state machine\n"); + + switch(d_state) { + + case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt + if (VERBOSE) + fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items); + + if (sig[0]) { // Found it, set up for header decode + enter_have_sync(); + } + break; + + case STATE_HAVE_SYNC: + // only demod after getting the preamble signal; otherwise, the + // equalizer taps will screw with the PLL performance + bytes = demapper(&in[0], d_bytes_out); + + if (VERBOSE) { + if(sig[0]) + printf("ERROR -- Found SYNC in HAVE_SYNC\n"); + fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n", + d_headerbytelen_cnt, d_header); + } + + j = 0; + while(j < bytes) { + d_header = (d_header << 8) | (d_bytes_out[j] & 0xFF); + j++; + + if (++d_headerbytelen_cnt == HEADERBYTELEN) { + + if (VERBOSE) + fprintf(stderr, "got header: 0x%08x\n", d_header); + + // we have a full header, check to see if it has been received properly + if (header_ok()){ + enter_have_header(); + + if (VERBOSE) + printf("\nPacket Length: %d\n", d_packetlen); + + while((j < bytes) && (d_packetlen_cnt < d_packetlen)) { + d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; + } + + if(d_packetlen_cnt == d_packetlen) { + gr_message_sptr msg = + gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen); + memcpy(msg->msg(), d_packet, d_packetlen_cnt); + d_target_queue->insert_tail(msg); // send it + msg.reset(); // free it up + + enter_search(); + } + } + else { + enter_search(); // bad header + } + } + } + break; + + case STATE_HAVE_HEADER: + bytes = demapper(&in[0], d_bytes_out); + + if (VERBOSE) { + if(sig[0]) + printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen); + fprintf(stderr,"Packet Build\n"); + } + + j = 0; + while(j < bytes) { + d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; + + if (d_packetlen_cnt == d_packetlen){ // packet is filled + // build a message + // NOTE: passing header field as arg1 is not scalable + gr_message_sptr msg = + gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt); + memcpy(msg->msg(), d_packet, d_packetlen_cnt); + + d_target_queue->insert_tail(msg); // send it + msg.reset(); // free it up + + enter_search(); + break; + } + } + break; + + default: + assert(0); + + } // switch + + return 1; +} diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.h b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.h new file mode 100644 index 000000000..de8c6a37e --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.h @@ -0,0 +1,120 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2011 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_GR_OFDM_FRAME_SINK2_H +#define INCLUDED_GR_OFDM_FRAME_SINK2_H + +#include <gr_sync_block.h> +#include <gr_msg_queue.h> +#include <gr_constellation.h> + +class gr_ofdm_frame_sink2; +typedef boost::shared_ptr<gr_ofdm_frame_sink2> gr_ofdm_frame_sink2_sptr; + +gr_ofdm_frame_sink2_sptr +gr_make_ofdm_frame_sink2 (gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + float phase_gain=0.25, float freq_gain=0.25*0.25/4.0); + +/*! + * \brief Takes an OFDM symbol in, demaps it into bits of 0's and 1's, packs + * them into packets, and sends to to a message queue sink. + * \ingroup sink_blk + * \ingroup ofdm_blk + * + * NOTE: The mod input parameter simply chooses a pre-defined demapper/slicer. Eventually, + * we want to be able to pass in a reference to an object to do the demapping and slicing + * for a given modulation type. + */ +class gr_ofdm_frame_sink2 : public gr_sync_block +{ + friend gr_ofdm_frame_sink2_sptr + gr_make_ofdm_frame_sink2 (gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + float phase_gain, float freq_gain); + + private: + enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER}; + + static const int MAX_PKT_LEN = 4096; + static const int HEADERBYTELEN = 4; + + gr_msg_queue_sptr d_target_queue; // where to send the packet when received + state_t d_state; + unsigned int d_header; // header bits + int d_headerbytelen_cnt; // how many so far + + unsigned char *d_bytes_out; // hold the current bytes produced by the demapper + + unsigned int d_occupied_carriers; + unsigned int d_byte_offset; + unsigned int d_partial_byte; + + unsigned char d_packet[MAX_PKT_LEN]; // assembled payload + int d_packetlen; // length of packet + int d_packet_whitener_offset; // offset into whitener string to use + int d_packetlen_cnt; // how many so far + + gr_complex * d_derotated_output; // Pointer to output stream to send deroated symbols out + + gr_constellation_sptr d_constell; + std::vector<gr_complex> d_dfe; + unsigned int d_nbits; + + unsigned char d_resid; + unsigned int d_nresid; + float d_phase; + float d_freq; + float d_phase_gain; + float d_freq_gain; + float d_eq_gain; + + std::vector<int> d_subcarrier_map; + + protected: + gr_ofdm_frame_sink2(gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + float phase_gain, float freq_gain); + + void enter_search(); + void enter_have_sync(); + void enter_have_header(); + + bool header_ok() + { + // confirm that two copies of header info are identical + return ((d_header >> 16) ^ (d_header & 0xffff)) == 0; + } + + unsigned char slicer(const gr_complex x); + unsigned int demapper(const gr_complex *in, + unsigned char *out); + + public: + ~gr_ofdm_frame_sink2(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_GR_OFDM_FRAME_SINK2_H */ diff --git a/gnuradio-core/src/lib/general/gr_costas_loop_cc.i b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.i index 488cab370..8fa320089 100644 --- a/gnuradio-core/src/lib/general/gr_costas_loop_cc.i +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005,2006 Free Software Foundation, Inc. + * Copyright 2007,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,25 +20,20 @@ * Boston, MA 02110-1301, USA. */ -GR_SWIG_BLOCK_MAGIC(gr,costas_loop_cc); +GR_SWIG_BLOCK_MAGIC(gr,ofdm_frame_sink2); -gr_costas_loop_cc_sptr -gr_make_costas_loop_cc (float alpha, float beta, - float max_freq, float min_freq, - int order - ) throw (std::invalid_argument); +gr_ofdm_frame_sink2_sptr +gr_make_ofdm_frame_sink2(gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + float phase_gain=0.25, float freq_gain=0.25*0.25/4); - -class gr_costas_loop_cc : public gr_sync_block +class gr_ofdm_frame_sink2 : public gr_sync_block { - private: - gr_costas_loop_cc (float alpha, float beta, - float max_freq, float min_freq, int order); + protected: + gr_ofdm_frame_sink2(gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + float phase_gain, float freq_gain); public: - void set_alpha(float alpha); - float alpha(); - void set_beta(float beta); - float beta(); - float freq(); + ~gr_ofdm_frame_sink2(); }; diff --git a/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc b/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc index 370b029cd..cc4aba0cb 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc +++ b/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.cc @@ -113,7 +113,7 @@ gr_ofdm_mapper_bcv::gr_ofdm_mapper_bcv (const std::vector<gr_complex> &constella throw std::invalid_argument("gr_ofdm_mapper_bcv: subcarriers allocated exceeds size of occupied carriers"); } - d_nbits = (unsigned long)ceil(log10(d_constellation.size()) / log10(2.0)); + d_nbits = (unsigned long)ceil(log10(float(d_constellation.size())) / log10(2.0)); } gr_ofdm_mapper_bcv::~gr_ofdm_mapper_bcv(void) diff --git a/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i b/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i index 30c692926..3850220ba 100644 --- a/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i +++ b/gnuradio-core/src/lib/general/gr_ofdm_mapper_bcv.i @@ -26,7 +26,7 @@ gr_ofdm_mapper_bcv_sptr gr_make_ofdm_mapper_bcv (const std::vector<gr_complex> &constellation, unsigned int msgq_limit, unsigned int bits_per_symbol, - unsigned int fft_length); + unsigned int fft_length) throw(std::exception); class gr_ofdm_mapper_bcv : public gr_sync_block diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc index 19ab316a1..583e0eb70 100644 --- a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc +++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2010 Free Software Foundation, Inc. + * Copyright 2006,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,22 +30,24 @@ #include <math.h> #include <gr_math.h> -#define M_TWOPI (2*M_PI) +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif gr_pll_carriertracking_cc_sptr -gr_make_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq) +gr_make_pll_carriertracking_cc (float loop_bw, float max_freq, float min_freq) { - return gnuradio::get_initial_sptr(new gr_pll_carriertracking_cc (alpha, beta, max_freq, min_freq)); + return gnuradio::get_initial_sptr(new gr_pll_carriertracking_cc (loop_bw, max_freq, min_freq)); } -gr_pll_carriertracking_cc::gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq) +gr_pll_carriertracking_cc::gr_pll_carriertracking_cc (float loop_bw, + float max_freq, + float min_freq) : gr_sync_block ("pll_carriertracking_cc", gr_make_io_signature (1, 1, sizeof (gr_complex)), gr_make_io_signature (1, 1, sizeof (gr_complex))), - d_alpha(alpha), d_beta(beta), - d_max_freq(max_freq), d_min_freq(min_freq), - d_phase(0), d_freq((max_freq+min_freq)/2), - d_locksig(0),d_lock_threshold(0),d_squelch_enable(false) + gri_control_loop(loop_bw, max_freq, min_freq), + d_locksig(0), d_lock_threshold(0), d_squelch_enable(false) { } @@ -72,7 +74,7 @@ gr_pll_carriertracking_cc::phase_detector(gr_complex sample,float ref_phase) bool gr_pll_carriertracking_cc::lock_detector(void) { - return (fabs(d_locksig) > d_lock_threshold); + return (fabsf(d_locksig) > d_lock_threshold); } bool @@ -100,17 +102,16 @@ gr_pll_carriertracking_cc::work (int noutput_items, for (int i = 0; i < noutput_items; i++){ error = phase_detector(iptr[i],d_phase); - - d_freq = d_freq + d_beta * error; - d_phase = mod_2pi(d_phase + d_freq + d_alpha * error); - - if (d_freq > d_max_freq) - d_freq = d_max_freq; - else if (d_freq < d_min_freq) - d_freq = d_min_freq; - gr_sincosf(d_phase,&t_imag,&t_real); - optr[i] = iptr[i] * gr_complex(t_real,-t_imag); - d_locksig = d_locksig * (1.0 - d_alpha) + d_alpha*(iptr[i].real() * t_real + iptr[i].imag() * t_imag); + + advance_loop(error); + phase_wrap(); + frequency_limit(); + + gr_sincosf(d_phase, &t_imag, &t_real); + optr[i] = iptr[i] * gr_complex(t_real, -t_imag); + + d_locksig = d_locksig * (1.0 - d_alpha) + \ + d_alpha*(iptr[i].real() * t_real + iptr[i].imag() * t_imag); if ((d_squelch_enable) && !lock_detector()) optr[i] = 0; diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h index 195f06016..bcdf543a4 100644 --- a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h +++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,206 Free Software Foundation, Inc. + * Copyright 2004,2006,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,12 +24,14 @@ #define INCLUDED_GR_PLL_CARRIERTRACKING_CC_H #include <gr_sync_block.h> +#include <gri_control_loop.h> class gr_pll_carriertracking_cc; typedef boost::shared_ptr<gr_pll_carriertracking_cc> gr_pll_carriertracking_cc_sptr; -gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float alpha, float beta, - float max_freq, float min_freq); +gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float loop_bw, + float max_freq, + float min_freq); /*! * \brief Implements a PLL which locks to the input frequency and outputs the * input signal mixed with that carrier. @@ -41,19 +43,20 @@ gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float alpha, floa * the input and outputs that signal, downconverted to DC * * All settings max_freq and min_freq are in terms of radians per sample, - * NOT HERTZ. Alpha is the phase gain (first order, units of radians per radian) - * and beta is the frequency gain (second order, units of radians per sample per radian) + * NOT HERTZ. The loop bandwidth determins the lock range and should be set + * around pi/200 -- 2pi/100. * \sa gr_pll_freqdet_cf, gr_pll_carriertracking_cc */ -class gr_pll_carriertracking_cc : public gr_sync_block +class gr_pll_carriertracking_cc : public gr_sync_block, public gri_control_loop { - friend gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float alpha, float beta, - float max_freq, float min_freq); + friend gr_pll_carriertracking_cc_sptr gr_make_pll_carriertracking_cc (float loop_bw, + float max_freq, + float min_freq); - float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq,d_locksig,d_lock_threshold; + float d_locksig,d_lock_threshold; bool d_squelch_enable; - gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq); + gr_pll_carriertracking_cc (float loop_bw, float max_freq, float min_freq); int work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i index 3e84fccbe..d309111b2 100644 --- a/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i +++ b/gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2005,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -23,13 +23,14 @@ GR_SWIG_BLOCK_MAGIC(gr,pll_carriertracking_cc); gr_pll_carriertracking_cc_sptr -gr_make_pll_carriertracking_cc (float alpha, float beta, - float max_freq, float min_freq); +gr_make_pll_carriertracking_cc (float loop_bw, + float max_freq, + float min_freq); -class gr_pll_carriertracking_cc : public gr_sync_block +class gr_pll_carriertracking_cc : public gr_sync_block, public gri_control_loop { private: - gr_pll_carriertracking_cc (float alpha, float beta, float max_freq, float min_freq); + gr_pll_carriertracking_cc (float loop_bw, float max_freq, float min_freq); public: bool lock_detector(void); bool squelch_enable(bool); diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc index 1f17f2afc..0ae773e6e 100644 --- a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc +++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,8 +20,6 @@ * Boston, MA 02110-1301, USA. */ -// WARNING: this file is machine generated. Edits will be over written - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -31,21 +29,21 @@ #include <math.h> #include <gr_math.h> -#define M_TWOPI (2*M_PI) +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif gr_pll_freqdet_cf_sptr -gr_make_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq) +gr_make_pll_freqdet_cf (float loop_bw, float max_freq, float min_freq) { - return gnuradio::get_initial_sptr(new gr_pll_freqdet_cf (alpha, beta, max_freq, min_freq)); + return gnuradio::get_initial_sptr(new gr_pll_freqdet_cf (loop_bw, max_freq, min_freq)); } -gr_pll_freqdet_cf::gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq) +gr_pll_freqdet_cf::gr_pll_freqdet_cf (float loop_bw, float max_freq, float min_freq) : gr_sync_block ("pll_freqdet_cf", gr_make_io_signature (1, 1, sizeof (gr_complex)), gr_make_io_signature (1, 1, sizeof (float))), - d_alpha(alpha), d_beta(beta), - d_max_freq(max_freq), d_min_freq(min_freq), - d_phase(0), d_freq((max_freq+min_freq)/2) + gri_control_loop(loop_bw, max_freq, min_freq) { } @@ -70,8 +68,8 @@ gr_pll_freqdet_cf::phase_detector(gr_complex sample,float ref_phase) int gr_pll_freqdet_cf::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { const gr_complex *iptr = (gr_complex *) input_items[0]; float *optr = (float *) output_items[0]; @@ -82,13 +80,10 @@ gr_pll_freqdet_cf::work (int noutput_items, while (size-- > 0) { error = phase_detector(*iptr++,d_phase); - d_freq = d_freq + d_beta * error; - d_phase = mod_2pi(d_phase + d_freq + d_alpha * error); - - if (d_freq > d_max_freq) - d_freq = d_max_freq; - else if (d_freq < d_min_freq) - d_freq = d_min_freq; + advance_loop(error); + phase_wrap(); + frequency_limit(); + *optr++ = d_freq; } return noutput_items; diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h index 0581c8724..0da9fc5c7 100644 --- a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h +++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,12 +24,14 @@ #define INCLUDED_GR_PLL_FREQDET_CF_H #include <gr_sync_block.h> +#include <gri_control_loop.h> class gr_pll_freqdet_cf; typedef boost::shared_ptr<gr_pll_freqdet_cf> gr_pll_freqdet_cf_sptr; -gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta, - float max_freq, float min_freq); +gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float loop_bw, + float max_freq, + float min_freq); /*! * \brief Implements a PLL which locks to the input frequency and outputs * an estimate of that frequency. Useful for FM Demod. @@ -40,24 +42,24 @@ gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta, * This PLL locks onto a [possibly noisy] reference carrier on * the input and outputs an estimate of that frequency in radians per sample. * All settings max_freq and min_freq are in terms of radians per sample, - * NOT HERTZ. Alpha is the phase gain (first order, units of radians per radian) - * and beta is the frequency gain (second order, units of radians per sample per radian) + * NOT HERTZ. The loop bandwidth determins the lock range and should be set + * around pi/200 -- 2pi/100. * \sa gr_pll_refout_cc, gr_pll_carriertracking_cc */ -class gr_pll_freqdet_cf : public gr_sync_block +class gr_pll_freqdet_cf : public gr_sync_block, public gri_control_loop { - friend gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta, - float max_freq, float min_freq); + friend gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float loop_bw, + float max_freq, + float min_freq); - float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq; - gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq); + float mod_2pi (float in); + gr_pll_freqdet_cf (float loop_bw, float max_freq, float min_freq); int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); private: - float mod_2pi (float in); float phase_detector(gr_complex sample,float ref_phase); }; diff --git a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i index b730f037a..f93e6e37e 100644 --- a/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i +++ b/gnuradio-core/src/lib/general/gr_pll_freqdet_cf.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2005,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,11 +22,12 @@ GR_SWIG_BLOCK_MAGIC(gr,pll_freqdet_cf) - gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float alpha, float beta, - float max_freq, float min_freq); + gr_pll_freqdet_cf_sptr gr_make_pll_freqdet_cf (float loop_bw, + float max_freq, + float min_freq); -class gr_pll_freqdet_cf : public gr_sync_block +class gr_pll_freqdet_cf : public gr_sync_block, public gri_control_loop { private: - gr_pll_freqdet_cf (float alpha, float beta, float max_freq, float min_freq); + gr_pll_freqdet_cf (float loop_bw, float max_freq, float min_freq); }; diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc b/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc index 8a7fbf88b..2b480fcf1 100644 --- a/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc +++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2010 Free Software Foundation, Inc. + * Copyright 2004,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,8 +20,6 @@ * Boston, MA 02110-1301, USA. */ -// WARNING: this file is machine generated. Edits will be over written - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -32,21 +30,21 @@ #include <math.h> #include <gr_math.h> -#define M_TWOPI (2*M_PI) +#ifndef M_TWOPI +#define M_TWOPI (2.0f*M_PI) +#endif gr_pll_refout_cc_sptr -gr_make_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq) +gr_make_pll_refout_cc (float loop_bw, float max_freq, float min_freq) { - return gnuradio::get_initial_sptr(new gr_pll_refout_cc (alpha, beta, max_freq, min_freq)); + return gnuradio::get_initial_sptr(new gr_pll_refout_cc (loop_bw, max_freq, min_freq)); } -gr_pll_refout_cc::gr_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq) +gr_pll_refout_cc::gr_pll_refout_cc (float loop_bw, float max_freq, float min_freq) : gr_sync_block ("pll_refout_cc", gr_make_io_signature (1, 1, sizeof (gr_complex)), gr_make_io_signature (1, 1, sizeof (gr_complex))), - d_alpha(alpha), d_beta(beta), - d_max_freq(max_freq), d_min_freq(min_freq), - d_phase(0), d_freq((max_freq+min_freq)/2) + gri_control_loop(loop_bw, max_freq, min_freq) { } @@ -84,13 +82,10 @@ gr_pll_refout_cc::work (int noutput_items, while (size-- > 0) { error = phase_detector(*iptr++,d_phase); - d_freq = d_freq + d_beta * error; - d_phase = mod_2pi(d_phase + d_freq + d_alpha * error); + advance_loop(error); + phase_wrap(); + frequency_limit(); - if (d_freq > d_max_freq) - d_freq = d_max_freq; - else if (d_freq < d_min_freq) - d_freq = d_min_freq; gr_sincosf(d_phase,&t_imag,&t_real); *optr++ = gr_complex(t_real,t_imag); } diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.h b/gnuradio-core/src/lib/general/gr_pll_refout_cc.h index 3263c957f..d3e45882b 100644 --- a/gnuradio-core/src/lib/general/gr_pll_refout_cc.h +++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,18 +20,17 @@ * Boston, MA 02110-1301, USA. */ - - #ifndef INCLUDED_GR_PLL_REFOUT_CC_H #define INCLUDED_GR_PLL_REFOUT_CC_H #include <gr_sync_block.h> +#include <gri_control_loop.h> class gr_pll_refout_cc; typedef boost::shared_ptr<gr_pll_refout_cc> gr_pll_refout_cc_sptr; -gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float alpha, float beta, - float max_freq, float min_freq); +gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float loop_bw, + float max_freq, float min_freq); /*! * \brief Implements a PLL which locks to the input frequency and outputs a carrier * \ingroup sync_blk @@ -43,24 +42,23 @@ gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float alpha, float beta, * aligned to it. * * All settings max_freq and min_freq are in terms of radians per sample, - * NOT HERTZ. Alpha is the phase gain (first order, units of radians per radian) - * and beta is the frequency gain (second order, units of radians per sample per radian) + * NOT HERTZ. The loop bandwidth determins the lock range and should be set + * around pi/200 -- 2pi/100. * \sa gr_pll_freqdet_cf, gr_pll_carriertracking_cc */ -class gr_pll_refout_cc : public gr_sync_block +class gr_pll_refout_cc : public gr_sync_block, public gri_control_loop { - friend gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float alpha, float beta, - float max_freq, float min_freq); + friend gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float loop_bw, + float max_freq, float min_freq); - float d_alpha,d_beta,d_max_freq,d_min_freq,d_phase,d_freq; - gr_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq); + gr_pll_refout_cc (float loop_bw, float max_freq, float min_freq); int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); private: float mod_2pi (float in); - float phase_detector(gr_complex sample,float ref_phase); + float phase_detector(gr_complex sample, float ref_phase); }; #endif diff --git a/gnuradio-core/src/lib/general/gr_pll_refout_cc.i b/gnuradio-core/src/lib/general/gr_pll_refout_cc.i index 026a684ed..834ea1e36 100644 --- a/gnuradio-core/src/lib/general/gr_pll_refout_cc.i +++ b/gnuradio-core/src/lib/general/gr_pll_refout_cc.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2005,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,11 +22,11 @@ GR_SWIG_BLOCK_MAGIC(gr,pll_refout_cc) - gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float alpha, float beta, - float max_freq, float min_freq); +gr_pll_refout_cc_sptr gr_make_pll_refout_cc (float loop_bw, + float max_freq, float min_freq); -class gr_pll_refout_cc : public gr_sync_block +class gr_pll_refout_cc : public gr_sync_block, public gri_control_loop { private: - gr_pll_refout_cc (float alpha, float beta, float max_freq, float min_freq); + gr_pll_refout_cc (float loop_bw, float max_freq, float min_freq); }; diff --git a/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h index a29acd628..df6de93d5 100644 --- a/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h +++ b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.h @@ -44,6 +44,8 @@ class gr_quadrature_demod_cf : public gr_sync_block float d_gain; public: + void set_gain(float gain) { d_gain = gain; } + float gain() const { return d_gain; } int work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i index fbd45dcf8..d9f338daa 100644 --- a/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i +++ b/gnuradio-core/src/lib/general/gr_quadrature_demod_cf.i @@ -27,4 +27,8 @@ gr_quadrature_demod_cf_sptr gr_make_quadrature_demod_cf (float gain); class gr_quadrature_demod_cf : public gr_sync_block { gr_quadrature_demod_cf (float gain); + +public: + void set_gain(float gain) { d_gain = gain; } + float gain() const { return d_gain; } }; diff --git a/gnuradio-core/src/lib/general/gr_throttle.cc b/gnuradio-core/src/lib/general/gr_throttle.cc index 3189e01c0..a24b1da8c 100644 --- a/gnuradio-core/src/lib/general/gr_throttle.cc +++ b/gnuradio-core/src/lib/general/gr_throttle.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005,2010 Free Software Foundation, Inc. + * Copyright 2005-2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,92 +26,64 @@ #include <gr_throttle.h> #include <gr_io_signature.h> -#include <errno.h> -#include <stdio.h> -#include <math.h> -#include <string.h> -#ifdef HAVE_TIME_H -#include <time.h> -#endif -#if !defined(HAVE_NANOSLEEP) && defined(HAVE_SSLEEP) -#include <windows.h> -#endif - +#include <cstring> +#include <boost/thread/thread.hpp> -#ifdef HAVE_NANOSLEEP -void -gr_nanosleep(struct timespec *ts) -{ - struct timespec *req = ts; - struct timespec rem; - int r = nanosleep(req, &rem); - while (r < 0 && errno == EINTR){ - req = &rem; - r = nanosleep(req, &rem); - } - if (r < 0) - perror ("gr_nanosleep"); -} -#endif - -gr_throttle_sptr -gr_make_throttle(size_t itemsize, double samples_per_sec) -{ - return gnuradio::get_initial_sptr(new gr_throttle(itemsize, samples_per_sec)); -} +class gr_throttle_impl : public gr_throttle{ +public: + gr_throttle_impl(size_t itemsize): + gr_sync_block("throttle", + gr_make_io_signature(1, 1, itemsize), + gr_make_io_signature(1, 1, itemsize)), + d_itemsize(itemsize) + { + /* NOP */ + } -gr_throttle::gr_throttle(size_t itemsize, double samples_per_sec) - : gr_sync_block("throttle", - gr_make_io_signature(1, 1, itemsize), - gr_make_io_signature(1, 1, itemsize)), - d_itemsize(itemsize), d_samples_per_sec(samples_per_sec), - d_total_samples(0) -{ -#ifdef HAVE_GETTIMEOFDAY - gettimeofday(&d_start, 0); -#endif -} + void set_sample_rate(double rate){ + //changing the sample rate performs a reset of state params + d_start = boost::get_system_time(); + d_total_samples = 0; + d_samps_per_tick = rate/boost::posix_time::time_duration::ticks_per_second(); + d_samps_per_us = rate/1e6; + } -gr_throttle::~gr_throttle() -{ -} + int work ( + int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ){ + //calculate the expected number of samples to have passed through + boost::system_time now = boost::get_system_time(); + boost::int64_t ticks = (now - d_start).ticks(); + uint64_t expected_samps = uint64_t(d_samps_per_tick*ticks); -int -gr_throttle::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) -{ - const char *in = (const char *) input_items[0]; - char *out = (char *) output_items[0]; + //if the expected samples was less, we need to throttle back + if (d_total_samples > expected_samps){ + boost::this_thread::sleep(boost::posix_time::microseconds( + long((d_total_samples - expected_samps)/d_samps_per_us) + )); + } -#if defined(HAVE_GETTIMEOFDAY) - // - // If our average sample rate exceeds our target sample rate, - // delay long enough to reduce to our target rate. - // - struct timeval now; - gettimeofday(&now, 0); - long t_usec = now.tv_usec - d_start.tv_usec; - long t_sec = now.tv_sec - d_start.tv_sec; - double t = (double)t_sec + (double)t_usec * 1e-6; - if (t < 1e-6) // avoid unlikely divide by zero - t = 1e-6; + //copy all samples output[i] <= input[i] + const char *in = (const char *) input_items[0]; + char *out = (char *) output_items[0]; + std::memcpy(out, in, noutput_items * d_itemsize); + d_total_samples += noutput_items; + return noutput_items; + } - double actual_samples_per_sec = d_total_samples / t; - if (actual_samples_per_sec > d_samples_per_sec){ // need to delay - double delay = d_total_samples / d_samples_per_sec - t; -#ifdef HAVE_NANOSLEEP - struct timespec ts; - ts.tv_sec = (time_t)floor(delay); - ts.tv_nsec = (long)((delay - floor(delay)) * 1e9); - gr_nanosleep(&ts); -#elif HAVE_SSLEEP - Sleep( (DWORD)(delay*1000) ); -#endif - } -#endif +private: + boost::system_time d_start; + size_t d_itemsize; + uint64_t d_total_samples; + double d_samps_per_tick, d_samps_per_us; +}; - memcpy(out, in, noutput_items * d_itemsize); - d_total_samples += noutput_items; - return noutput_items; +gr_throttle::sptr +gr_make_throttle(size_t itemsize, double samples_per_sec) +{ + gr_throttle::sptr throttle(new gr_throttle_impl(itemsize)); + throttle->set_sample_rate(samples_per_sec); + return throttle; } diff --git a/gnuradio-core/src/lib/general/gr_throttle.h b/gnuradio-core/src/lib/general/gr_throttle.h index a1c9773c9..a82821f77 100644 --- a/gnuradio-core/src/lib/general/gr_throttle.h +++ b/gnuradio-core/src/lib/general/gr_throttle.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2005-2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -23,15 +23,6 @@ #define INCLUDED_GR_THROTTLE_H #include <gr_sync_block.h> -#ifdef HAVE_SYS_TIME_H -#include <sys/time.h> -#endif - -class gr_throttle; -typedef boost::shared_ptr<gr_throttle> gr_throttle_sptr; - - -gr_throttle_sptr gr_make_throttle(size_t itemsize, double samples_per_sec); /*! * \brief throttle flow of samples such that the average rate does not exceed samples_per_sec. @@ -44,25 +35,15 @@ gr_throttle_sptr gr_make_throttle(size_t itemsize, double samples_per_sec); * controlling the rate of samples. That should be controlled by a * source or sink tied to sample clock. E.g., a USRP or audio card. */ -class gr_throttle : public gr_sync_block +class gr_throttle : virtual public gr_sync_block { - friend gr_throttle_sptr gr_make_throttle(size_t itemsize, double samples_per_sec); - size_t d_itemsize; - double d_samples_per_sec; - double d_total_samples; -#ifdef HAVE_SYS_TIME_H - struct timeval d_start; -#endif - - gr_throttle(size_t itemsize, double samples_per_sec); - public: - ~gr_throttle(); + typedef boost::shared_ptr<gr_throttle> sptr; - int work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items); + //! Sets the sample rate in samples per second + virtual void set_sample_rate(double rate) = 0; }; - + +gr_throttle::sptr gr_make_throttle(size_t itemsize, double samples_per_sec); #endif /* INCLUDED_GR_THROTTLE_H */ diff --git a/gnuradio-core/src/lib/general/gr_throttle.i b/gnuradio-core/src/lib/general/gr_throttle.i index 21f7703ef..0b1ec165f 100644 --- a/gnuradio-core/src/lib/general/gr_throttle.i +++ b/gnuradio-core/src/lib/general/gr_throttle.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2005-2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,11 +20,10 @@ * Boston, MA 02110-1301, USA. */ -GR_SWIG_BLOCK_MAGIC(gr,throttle); +%{ +#include <gr_throttle.h> +%} -gr_throttle_sptr gr_make_throttle (size_t itemsize, double samples_per_sec); +GR_SWIG_BLOCK_MAGIC(gr,throttle); -class gr_throttle : public gr_sync_block -{ - gr_throttle (size_t itemsize, double samples_per_sec); -}; +%include <gr_throttle.h> diff --git a/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i index 5f9a8f134..2e9aa406b 100644 --- a/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i +++ b/gnuradio-core/src/lib/general/gr_unpack_k_bits_bb.i @@ -22,7 +22,7 @@ GR_SWIG_BLOCK_MAGIC(gr,unpack_k_bits_bb) -gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (int k); +gr_unpack_k_bits_bb_sptr gr_make_unpack_k_bits_bb (int k) throw(std::exception); class gr_unpack_k_bits_bb : public gr_sync_interpolator { diff --git a/gnuradio-core/src/lib/general/gri_control_loop.cc b/gnuradio-core/src/lib/general/gri_control_loop.cc new file mode 100644 index 000000000..affdeefc9 --- /dev/null +++ b/gnuradio-core/src/lib/general/gri_control_loop.cc @@ -0,0 +1,183 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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. + */ + +#include <gri_control_loop.h> +#include <gr_math.h> +#include <stdexcept> + +#define M_TWOPI (2.0f*M_PI) + +gri_control_loop::gri_control_loop(float loop_bw, + float max_freq, float min_freq) + : d_phase(0), d_freq(0), d_max_freq(max_freq), d_min_freq(min_freq) +{ + // Set the damping factor for a critically damped system + d_damping = sqrtf(2.0f)/2.0f; + + // Set the bandwidth, which will then call update_gains() + set_loop_bandwidth(loop_bw); +} + +gri_control_loop::~gri_control_loop() +{ +} + +void +gri_control_loop::update_gains() +{ + float denom = (1.0 + 2.0*d_damping*d_loop_bw + d_loop_bw*d_loop_bw); + d_alpha = (4*d_damping*d_loop_bw) / denom; + d_beta = (4*d_loop_bw*d_loop_bw) / denom; +} + +void +gri_control_loop::advance_loop(float error) +{ + d_freq = d_freq + d_beta * error; + d_phase = d_phase + d_freq + d_alpha * error; +} + + +void +gri_control_loop::phase_wrap() +{ + while(d_phase>M_TWOPI) + d_phase -= M_TWOPI; + while(d_phase<-M_TWOPI) + d_phase += M_TWOPI; +} + +void +gri_control_loop::frequency_limit() +{ + if (d_freq > d_max_freq) + d_freq = d_max_freq; + else if (d_freq < d_min_freq) + d_freq = d_min_freq; +} + +/******************************************************************* + SET FUNCTIONS +*******************************************************************/ + +void +gri_control_loop::set_loop_bandwidth(float bw) +{ + if(bw < 0) { + throw std::out_of_range ("gri_control_loop: invalid bandwidth. Must be >= 0."); + } + + d_loop_bw = bw; + update_gains(); +} + +void +gri_control_loop::set_damping_factor(float df) +{ + if(df < 0 || df > 1.0) { + throw std::out_of_range ("gri_control_loop: invalid damping factor. Must be in [0,1]."); + } + + d_damping = df; + update_gains(); +} + +void +gri_control_loop::set_alpha(float alpha) +{ + if(alpha < 0 || alpha > 1.0) { + throw std::out_of_range ("gri_control_loop: invalid alpha. Must be in [0,1]."); + } + d_alpha = alpha; +} + +void +gri_control_loop::set_beta(float beta) +{ + if(beta < 0 || beta > 1.0) { + throw std::out_of_range ("gri_control_loop: invalid beta. Must be in [0,1]."); + } + d_beta = beta; +} + +void +gri_control_loop::set_frequency(float freq) +{ + if(freq > d_max_freq) + d_freq = d_min_freq; + else if(freq < d_min_freq) + d_freq = d_max_freq; + else + d_freq = freq; +} + +void +gri_control_loop::set_phase(float phase) +{ + d_phase = phase; + while(d_phase>M_TWOPI) + d_phase -= M_TWOPI; + while(d_phase<-M_TWOPI) + d_phase += M_TWOPI; +} + + +/******************************************************************* + GET FUNCTIONS +*******************************************************************/ + + +float +gri_control_loop::get_loop_bandwidth() const +{ + return d_loop_bw; +} + +float +gri_control_loop::get_damping_factor() const +{ + return d_damping; +} + +float +gri_control_loop::get_alpha() const +{ + return d_alpha; +} + +float +gri_control_loop::get_beta() const +{ + return d_beta; +} + +float +gri_control_loop::get_frequency() const +{ + return d_freq; +} + +float +gri_control_loop::get_phase() const +{ + return d_phase; +} diff --git a/gnuradio-core/src/lib/general/gri_control_loop.h b/gnuradio-core/src/lib/general/gri_control_loop.h new file mode 100644 index 000000000..a85625bbd --- /dev/null +++ b/gnuradio-core/src/lib/general/gri_control_loop.h @@ -0,0 +1,201 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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 GRI_CONTROL_LOOP +#define GRI_CONTROL_LOOP + +class gri_control_loop +{ + protected: + float d_phase, d_freq; + float d_max_freq, d_min_freq; + float d_damping, d_loop_bw; + float d_alpha, d_beta; + + public: + gri_control_loop(float loop_bw, float max_freq, float min_freq); + virtual ~gri_control_loop(); + + /*! \brief update the system gains from the loop bandwidth and damping factor + * + * This function updates the system gains based on the loop + * bandwidth and damping factor of the system. + * These two factors can be set separately through their own + * set functions. + */ + void update_gains(); + + /*! \brief update the system gains from the loop bandwidth and damping factor + * + * This function updates the system gains based on the loop + * bandwidth and damping factor of the system. + * These two factors can be set separately through their own + * set functions. + */ + void advance_loop(float error); + + /*! \brief Keep the phase between -2pi and 2pi + * + * This function keeps the phase between -2pi and 2pi. If the phase + * is greater than 2pi by d, it wraps around to be -2pi+d; similarly if + * it is less than -2pi by d, it wraps around to 2pi-d. + * + * This function should be called after advance_loop to keep the phase + * in a good operating region. It is set as a separate method in case + * another way is desired as this is fairly heavy-handed. + */ + void phase_wrap(); + + /*! \brief Keep the frequency between d_min_freq and d_max_freq + * + * This function keeps the frequency between d_min_freq and d_max_freq. + * If the frequency is greater than d_max_freq, it is set to d_max_freq. + * If the frequency is less than d_min_freq, it is set to d_min_freq. + * + * This function should be called after advance_loop to keep the frequency + * in the specified region. It is set as a separate method in case + * another way is desired as this is fairly heavy-handed. + */ + void frequency_limit(); + + /******************************************************************* + SET FUNCTIONS + *******************************************************************/ + + /*! + * \brief Set the loop bandwidth + * + * Set the loop filter's bandwidth to \p bw. This should be between + * 2*pi/200 and 2*pi/100 (in rads/samp). It must also be a positive + * number. + * + * When a new damping factor is set, the gains, alpha and beta, of the loop + * are recalculated by a call to update_gains(). + * + * \param bw (float) new bandwidth + * + */ + void set_loop_bandwidth(float bw); + + /*! + * \brief Set the loop damping factor + * + * Set the loop filter's damping factor to \p df. The damping factor + * should be sqrt(2)/2.0 for critically damped systems. + * Set it to anything else only if you know what you are doing. It must + * be a number between 0 and 1. + * + * When a new damping factor is set, the gains, alpha and beta, of the loop + * are recalculated by a call to update_gains(). + * + * \param df (float) new damping factor + * + */ + void set_damping_factor(float df); + + /*! + * \brief Set the loop gain alpha + * + * Set's the loop filter's alpha gain parameter. + * + * This value should really only be set by adjusting the loop bandwidth + * and damping factor. + * + * \param alpha (float) new alpha gain + * + */ + void set_alpha(float alpha); + + /*! + * \brief Set the loop gain beta + * + * Set's the loop filter's beta gain parameter. + * + * This value should really only be set by adjusting the loop bandwidth + * and damping factor. + * + * \param beta (float) new beta gain + * + */ + void set_beta(float beta); + + /*! + * \brief Set the Costas loop's frequency. + * + * Set's the Costas Loop's frequency. While this is normally updated by the + * inner loop of the algorithm, it could be useful to manually initialize, + * set, or reset this under certain circumstances. + * + * \param freq (float) new frequency + * + */ + void set_frequency(float freq); + + /*! + * \brief Set the Costas loop's phase. + * + * Set's the Costas Loop's phase. While this is normally updated by the + * inner loop of the algorithm, it could be useful to manually initialize, + * set, or reset this under certain circumstances. + * + * \param phase (float) new phase + * + */ + void set_phase(float phase); + + + /******************************************************************* + GET FUNCTIONS + *******************************************************************/ + + /*! + * \brief Returns the loop bandwidth + */ + float get_loop_bandwidth() const; + + /*! + * \brief Returns the loop damping factor + */ + float get_damping_factor() const; + + /*! + * \brief Returns the loop gain alpha + */ + float get_alpha() const; + + /*! + * \brief Returns the loop gain beta + */ + float get_beta() const; + + /*! + * \brief Get the Costas loop's frequency estimate + */ + float get_frequency() const; + + /*! + * \brief Get the Costas loop's phase estimate + */ + float get_phase() const; +}; + +#endif /* GRI_CONTROL_LOOP */ diff --git a/gnuradio-core/src/lib/general/gri_control_loop.i b/gnuradio-core/src/lib/general/gri_control_loop.i new file mode 100644 index 000000000..67f8838cb --- /dev/null +++ b/gnuradio-core/src/lib/general/gri_control_loop.i @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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. + */ + + +class gri_control_loop +{ + public: + gri_control_loop(float loop_bw, float max_freq, float min_freq); + virtual ~gri_control_loop(); + + void update_gains(); + void advance_loop(float error); + void phase_wrap(); + void frequency_limit(); + + /******************************************************************* + SET FUNCTIONS + *******************************************************************/ + + void set_loop_bandwidth(float bw); + void set_damping_factor(float df); + void set_alpha(float alpha); + void set_beta(float beta); + void set_frequency(float freq); + void set_phase(float phase); + + + /******************************************************************* + GET FUNCTIONS + *******************************************************************/ + + float get_loop_bandwidth() const; + float get_damping_factor() const; + float get_alpha() const; + float get_beta() const; + float get_frequency() const; + float get_phase() const; +}; diff --git a/gnuradio-core/src/lib/general/gri_fft.cc b/gnuradio-core/src/lib/general/gri_fft.cc index e535f28c7..f20b15ca0 100644 --- a/gnuradio-core/src/lib/general/gri_fft.cc +++ b/gnuradio-core/src/lib/general/gri_fft.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2003,2008 Free Software Foundation, Inc. + * Copyright 2003,2008,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -21,6 +21,7 @@ */ #include <gri_fft.h> +#include <gr_sys_paths.h> #include <fftw3.h> #include <gr_complex.h> #include <stdlib.h> @@ -29,6 +30,9 @@ #include <cassert> #include <stdexcept> +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> +namespace fs = boost::filesystem; boost::mutex & gri_fft_planner::mutex() @@ -38,26 +42,18 @@ gri_fft_planner::mutex() return s_planning_mutex; } -static char * +static const char * wisdom_filename () { - static const char *filename = ".gr_fftw_wisdom"; - - char *home = getenv ("HOME"); - if (home){ - char *p = new char[strlen (home) + strlen (filename) + 2]; - strcpy (p, home); - strcat (p, "/"); - strcat (p, filename); - return p; - } - return 0; + static fs::path path; + path = fs::path(gr_appdata_path()) / ".gr_fftw_wisdom"; + return path.string().c_str(); } static void gri_fftw_import_wisdom () { - char *filename = wisdom_filename (); + const char *filename = wisdom_filename (); FILE *fp = fopen (filename, "r"); if (fp != 0){ int r = fftwf_import_wisdom_from_file (fp); @@ -66,13 +62,12 @@ gri_fftw_import_wisdom () fprintf (stderr, "gri_fftw: can't import wisdom from %s\n", filename); } } - delete [] filename; } static void gri_fftw_export_wisdom () { - char *filename = wisdom_filename (); + const char *filename = wisdom_filename (); FILE *fp = fopen (filename, "w"); if (fp != 0){ fftwf_export_wisdom_to_file (fp); @@ -82,7 +77,6 @@ gri_fftw_export_wisdom () fprintf (stderr, "gri_fftw: "); perror (filename); } - delete [] filename; } // ---------------------------------------------------------------- diff --git a/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc b/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc index 9885b3852..113006a22 100644 --- a/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc +++ b/gnuradio-core/src/lib/general/qa_gr_fxpt_vco.cc @@ -53,7 +53,7 @@ qa_gr_fxpt_vco::t0 () float input[SIN_COS_BLOCK_SIZE]; for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){ - input[i] = sin(i); + input[i] = sin(double(i)); } for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){ @@ -85,7 +85,7 @@ qa_gr_fxpt_vco::t1 () double max_error = 0; for (int i = 0; i < SIN_COS_BLOCK_SIZE; i++){ - input[i] = sin(i); + input[i] = sin(double(i)); } ref_vco.cos (ref_block, input, SIN_COS_BLOCK_SIZE, SIN_COS_K, SIN_COS_AMPL); diff --git a/gnuradio-core/src/lib/gengen/Makefile.am b/gnuradio-core/src/lib/gengen/Makefile.am index 4978ad1c5..5fbb6f52c 100644 --- a/gnuradio-core/src/lib/gengen/Makefile.am +++ b/gnuradio-core/src/lib/gengen/Makefile.am @@ -115,7 +115,7 @@ core_generator = \ gr_moving_average_XX.i.t # Source built by Python into $(builddir) -BUILT_SOURCES = \ +BUILT_SOURCES += \ $(GENERATED_H) \ $(GENERATED_I) \ $(GENERATED_CC) \ @@ -123,7 +123,7 @@ BUILT_SOURCES = \ # ---------------------------------------------------------------- -EXTRA_DIST = \ +EXTRA_DIST += \ $(core_generator) libgengen_la_SOURCES = \ @@ -135,13 +135,11 @@ grinclude_HEADERS = \ gr_noise_type.h \ gr_sig_source_waveform.h -if PYTHON swiginclude_HEADERS = \ $(GENERATED_I) \ gr_endianness.i \ gengen.i \ gengen_generated.i -endif # Do creation and inclusion of other Makefiles last diff --git a/gnuradio-core/src/lib/gengen/gr_add_const_vXX.cc.t b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.cc.t index 2a0a3ba3f..f49be062e 100755 --- a/gnuradio-core/src/lib/gengen/gr_add_const_vXX.cc.t +++ b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.cc.t @@ -30,12 +30,12 @@ #include <gr_io_signature.h> @SPTR_NAME@ -gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k) +gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> &k) { return gnuradio::get_initial_sptr (new @NAME@ (k)); } -@NAME@::@NAME@ (const std::vector<@I_TYPE@> k) +@NAME@::@NAME@ (const std::vector<@I_TYPE@> &k) : gr_sync_block ("@BASE_NAME@", gr_make_io_signature (1, 1, sizeof(@I_TYPE@)*k.size()), gr_make_io_signature (1, 1, sizeof(@O_TYPE@)*k.size())) diff --git a/gnuradio-core/src/lib/gengen/gr_add_const_vXX.h.t b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.h.t index 33b6fc396..574fc686c 100755 --- a/gnuradio-core/src/lib/gengen/gr_add_const_vXX.h.t +++ b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.h.t @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2006 Free Software Foundation, Inc. + * Copyright 2004,2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,7 +30,7 @@ class @NAME@; typedef boost::shared_ptr<@NAME@> @SPTR_NAME@; -@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k); +@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> &k); /*! * \brief output vector = input vector + constant vector @@ -38,14 +38,14 @@ typedef boost::shared_ptr<@NAME@> @SPTR_NAME@; */ class @NAME@ : public gr_sync_block { - friend @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k); + friend @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> &k); std::vector<@I_TYPE@> d_k; // the constant - @NAME@ (const std::vector<@I_TYPE@> k); + @NAME@ (const std::vector<@I_TYPE@> &k); public: const std::vector<@I_TYPE@> k () const { return d_k; } - void set_k (const std::vector<@I_TYPE@> k) { d_k = k; } + void set_k (const std::vector<@I_TYPE@> &k) { d_k = k; } int work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/gengen/gr_add_const_vXX.i.t b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.i.t index a2e7dd70b..ad1643a7e 100755 --- a/gnuradio-core/src/lib/gengen/gr_add_const_vXX.i.t +++ b/gnuradio-core/src/lib/gengen/gr_add_const_vXX.i.t @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2006 Free Software Foundation, Inc. + * Copyright 2004,2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,14 +24,14 @@ GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@) -@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k); +@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> &k); class @NAME@ : public gr_sync_block { private: - @NAME@ (const std::vector<@I_TYPE@> k); + @NAME@ (const std::vector<@I_TYPE@> &k); public: std::vector<@I_TYPE@> k () const { return d_k; } - void set_k (const std::vector<@I_TYPE@> k) { d_k = k; } + void set_k (const std::vector<@I_TYPE@> &k) { d_k = k; } }; diff --git a/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.cc.t b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.cc.t index 8286453f1..5725c1c46 100755 --- a/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.cc.t +++ b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.cc.t @@ -30,12 +30,12 @@ #include <gr_io_signature.h> @SPTR_NAME@ -gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k) +gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> &k) { return gnuradio::get_initial_sptr (new @NAME@ (k)); } -@NAME@::@NAME@ (const std::vector<@I_TYPE@> k) +@NAME@::@NAME@ (const std::vector<@I_TYPE@> &k) : gr_sync_block ("@BASE_NAME@", gr_make_io_signature (1, 1, sizeof(@I_TYPE@)*k.size()), gr_make_io_signature (1, 1, sizeof(@O_TYPE@)*k.size())) diff --git a/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.h.t b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.h.t index 22334505a..81e781895 100755 --- a/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.h.t +++ b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.h.t @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2006 Free Software Foundation, Inc. + * Copyright 2004,2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -30,7 +30,7 @@ class @NAME@; typedef boost::shared_ptr<@NAME@> @SPTR_NAME@; -@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k); +@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> &k); /*! * \brief output vector = input vector * constant vector (element-wise) @@ -38,14 +38,14 @@ typedef boost::shared_ptr<@NAME@> @SPTR_NAME@; */ class @NAME@ : public gr_sync_block { - friend @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k); + friend @SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> &k); std::vector<@I_TYPE@> d_k; // the constant - @NAME@ (const std::vector<@I_TYPE@> k); + @NAME@ (const std::vector<@I_TYPE@> &k); public: const std::vector<@I_TYPE@> k () const { return d_k; } - void set_k (const std::vector<@I_TYPE@> k) { d_k = k; } + void set_k (const std::vector<@I_TYPE@> &k) { d_k = k; } int work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.i.t b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.i.t index a2e7dd70b..ad1643a7e 100755 --- a/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.i.t +++ b/gnuradio-core/src/lib/gengen/gr_multiply_const_vXX.i.t @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2006 Free Software Foundation, Inc. + * Copyright 2004,2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -24,14 +24,14 @@ GR_SWIG_BLOCK_MAGIC(gr,@BASE_NAME@) -@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> k); +@SPTR_NAME@ gr_make_@BASE_NAME@ (const std::vector<@I_TYPE@> &k); class @NAME@ : public gr_sync_block { private: - @NAME@ (const std::vector<@I_TYPE@> k); + @NAME@ (const std::vector<@I_TYPE@> &k); public: std::vector<@I_TYPE@> k () const { return d_k; } - void set_k (const std::vector<@I_TYPE@> k) { d_k = k; } + void set_k (const std::vector<@I_TYPE@> &k) { d_k = k; } }; diff --git a/gnuradio-core/src/lib/hier/Makefile.am b/gnuradio-core/src/lib/hier/Makefile.am index d46fb8fd9..8d56be7a3 100644 --- a/gnuradio-core/src/lib/hier/Makefile.am +++ b/gnuradio-core/src/lib/hier/Makefile.am @@ -37,11 +37,9 @@ grinclude_HEADERS = \ gr_cpmmod_bc.h -if PYTHON swiginclude_HEADERS = \ hier.i \ + gr_channel_model.i gr_channel_model.i \ gr_gmskmod_bc.i \ gr_cpmmod_bc.i -endif - diff --git a/gnuradio-core/src/lib/io/Makefile.am b/gnuradio-core/src/lib/io/Makefile.am index c52554645..442d5e3a9 100644 --- a/gnuradio-core/src/lib/io/Makefile.am +++ b/gnuradio-core/src/lib/io/Makefile.am @@ -56,7 +56,8 @@ libio_la_SOURCES = \ gr_udp_source.cc \ gr_wavfile_sink.cc \ gr_wavfile_source.cc \ - gri_wavfile.cc + gri_wavfile.cc \ + gr_tagged_file_sink.cc grinclude_HEADERS = \ gr_file_sink.h \ @@ -89,9 +90,9 @@ grinclude_HEADERS = \ gr_udp_source.h \ gr_wavfile_source.h \ gr_wavfile_sink.h \ - gri_wavfile.h + gri_wavfile.h \ + gr_tagged_file_sink.h -if PYTHON swiginclude_HEADERS = \ io.i \ gr_file_sink.i \ @@ -111,5 +112,5 @@ swiginclude_HEADERS = \ gr_udp_sink.i \ gr_udp_source.i \ gr_wavfile_source.i \ - gr_wavfile_sink.i -endif + gr_wavfile_sink.i \ + gr_tagged_file_sink.i diff --git a/gnuradio-core/src/lib/io/gr_histo_sink_f.cc b/gnuradio-core/src/lib/io/gr_histo_sink_f.cc index a37189c24..fc0c12ce6 100644 --- a/gnuradio-core/src/lib/io/gr_histo_sink_f.cc +++ b/gnuradio-core/src/lib/io/gr_histo_sink_f.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2009,2010 Free Software Foundation, Inc. + * Copyright 2009,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,6 +26,7 @@ #include <gr_histo_sink_f.h> #include <gr_io_signature.h> +#include <boost/math/special_functions/round.hpp> static float get_clean_num(float num){ if (num == 0) return 0; @@ -101,7 +102,7 @@ gr_histo_sink_f::send_frame(void){ int index; float bin_width = (maximum - minimum)/(d_num_bins-1); for (unsigned int i = 0; i < d_sample_count; i++){ - index = round((d_samps[i] - minimum)/bin_width); + index = boost::math::iround((d_samps[i] - minimum)/bin_width); /* ensure the index range in case a small floating point error is involed */ if (index < 0) index = 0; if (index >= (int)d_num_bins) index = d_num_bins-1; diff --git a/gnuradio-core/src/lib/io/gr_message_source.i b/gnuradio-core/src/lib/io/gr_message_source.i index 8a9c762d0..e4e2016d0 100644 --- a/gnuradio-core/src/lib/io/gr_message_source.i +++ b/gnuradio-core/src/lib/io/gr_message_source.i @@ -22,6 +22,14 @@ GR_SWIG_BLOCK_MAGIC(gr,message_source); +#ifdef SWIGGUILE +// Rename these. Without this, the primitive bindings are OK, but the +// goops bindings try to create a bogus generic-function... +// See core.scm for the second part of the workaround. +%rename(message_source_limit_ctor) gr_make_message_source(size_t itemsize, int msgq_limit); +%rename(message_source_msgq_ctor) gr_make_message_source(size_t itemsize, gr_msg_queue_sptr msgq); +#endif + gr_message_source_sptr gr_make_message_source (size_t itemsize, int msgq_limit=0); gr_message_source_sptr gr_make_message_source (size_t itemsize, gr_msg_queue_sptr msgq); diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc b/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc new file mode 100644 index 000000000..154611c32 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc @@ -0,0 +1,211 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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_tagged_file_sink.h> +#include <gr_io_signature.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <stdexcept> +#include <iostream> +#include <gr_tag_info.h> + +#ifdef O_BINARY +#define OUR_O_BINARY O_BINARY +#else +#define OUR_O_BINARY 0 +#endif + +// should be handled via configure +#ifdef O_LARGEFILE +#define OUR_O_LARGEFILE O_LARGEFILE +#else +#define OUR_O_LARGEFILE 0 +#endif + + +gr_tagged_file_sink::gr_tagged_file_sink (size_t itemsize, double samp_rate) + : gr_sync_block ("tagged_file_sink", + gr_make_io_signature (1, 1, itemsize), + gr_make_io_signature (0, 0, 0)), + d_itemsize (itemsize), d_n(0), d_sample_rate(samp_rate) +{ + d_state = NOT_IN_BURST; + d_last_N = 0; + d_timeval = 0; +} + +gr_tagged_file_sink_sptr +gr_make_tagged_file_sink (size_t itemsize, double samp_rate) +{ + return gnuradio::get_initial_sptr(new gr_tagged_file_sink (itemsize, samp_rate)); +} + +gr_tagged_file_sink::~gr_tagged_file_sink () +{ +} + +int +gr_tagged_file_sink::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + char *inbuf = (char *) input_items[0]; + + uint64_t start_N = nitems_read(0); + uint64_t end_N = start_N + (uint64_t)(noutput_items); + pmt::pmt_t bkey = pmt::pmt_string_to_symbol("burst"); + //pmt::pmt_t tkey = pmt::pmt_string_to_symbol("time"); // use gr_tags::key_time + + std::vector<pmt::pmt_t> all_tags; + get_tags_in_range(all_tags, 0, start_N, end_N); + + std::sort(all_tags.begin(), all_tags.end(), gr_tags::nitems_compare); + + std::vector<pmt::pmt_t>::iterator vitr = all_tags.begin(); + + int idx = 0, idx_stop = 0; + while(idx < noutput_items) { + if(d_state == NOT_IN_BURST) { + while(vitr != all_tags.end()) { + if((pmt::pmt_eqv(gr_tags::get_key(*vitr), bkey)) && + pmt::pmt_is_true(gr_tags::get_value(*vitr))) { + + uint64_t N = gr_tags::get_nitems(*vitr); + idx = (int)(N - start_N); + + //std::cout << std::endl << "Found start of burst: " + // << idx << ", " << N << std::endl; + + // Find time burst occurred by getting latest time tag and extrapolating + // to new time based on sample rate of this block. + std::vector<pmt::pmt_t> time_tags; + //get_tags_in_range(time_tags, 0, d_last_N, N, gr_tags::key_time); + get_tags_in_range(time_tags, 0, d_last_N, N, + pmt::pmt_string_to_symbol("time")); + if(time_tags.size() > 0) { + pmt::pmt_t tag = time_tags[time_tags.size()-1]; + + uint64_t time_nitems = gr_tags::get_nitems(tag); + + // Get time based on last time tag from USRP + pmt::pmt_t time = gr_tags::get_value(tag); + int tsecs = pmt::pmt_to_long(pmt::pmt_tuple_ref(time, 0)); + double tfrac = pmt::pmt_to_double(pmt::pmt_tuple_ref(time, 1)); + + // Get new time from last time tag + difference in time to when + // burst tag occured based on the sample rate + double delta = (double)(N - time_nitems) / d_sample_rate; + d_timeval = (double)tsecs + tfrac + delta; + + //std::cout.setf(std::ios::fixed, std::ios::floatfield); + //std::cout.precision(8); + //std::cout << "Time found: " << (double)tsecs + tfrac << std::endl; + //std::cout << " time: " << d_timeval << std::endl; + //std::cout << " time at N = " << time_nitems << " burst N = " << N << std::endl; + } + else { + // if no time tag, use last seen tag and update time based on + // sample rate of the block + d_timeval += (double)(N - d_last_N) / d_sample_rate; + //std::cout << "Time not found" << std::endl; + //std::cout << " time: " << d_timeval << std::endl; + } + d_last_N = N; + + std::stringstream filename; + filename.setf(std::ios::fixed, std::ios::floatfield); + filename.precision(8); + filename << "file" << d_n << "_" << d_timeval << ".dat"; + d_n++; + + int fd; + if ((fd = ::open (filename.str().c_str(), + O_WRONLY|O_CREAT|O_TRUNC|OUR_O_LARGEFILE|OUR_O_BINARY, + 0664)) < 0){ + perror (filename.str().c_str()); + return -1; + } + + // FIXME: + //if ((d_handle = fdopen (fd, d_is_binary ? "wb" : "w")) == NULL){ + if ((d_handle = fdopen (fd, "wb")) == NULL){ + perror (filename.str().c_str()); + ::close(fd); // don't leak file descriptor if fdopen fails. + } + + //std::cout << "Created new file: " << filename.str() << std::endl; + + d_state = IN_BURST; + break; + } + + vitr++; + } + if(d_state == NOT_IN_BURST) + return noutput_items; + } + else { // In burst + while(vitr != all_tags.end()) { + if((pmt::pmt_eqv(gr_tags::get_key(*vitr), bkey)) && + pmt::pmt_is_false(gr_tags::get_value(*vitr))) { + uint64_t N = gr_tags::get_nitems(*vitr); + idx_stop = (int)N - start_N; + + //std::cout << "Found end of burst: " + // << idx_stop << ", " << N << std::endl; + + int count = fwrite (&inbuf[d_itemsize*idx], d_itemsize, idx_stop-idx, d_handle); + if (count == 0) { + if(ferror(d_handle)) { + perror("gr_tagged_file_sink: error writing file"); + } + } + idx = idx_stop; + d_state = NOT_IN_BURST; + vitr++; + fclose(d_handle); + break; + } + else { + vitr++; + } + } + if(d_state == IN_BURST) { + int count = fwrite (&inbuf[idx], d_itemsize, noutput_items-idx, d_handle); + if (count == 0) { + if(ferror(d_handle)) { + perror("gr_tagged_file_sink: error writing file"); + } + } + idx = noutput_items; + } + } + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.h b/gnuradio-core/src/lib/io/gr_tagged_file_sink.h new file mode 100644 index 000000000..2e0a5c63a --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.h @@ -0,0 +1,71 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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_GR_TAGGED_FILE_SINK_H +#define INCLUDED_GR_TAGGED_FILE_SINK_H + +#include <gr_sync_block.h> +#include <cstdio> // for FILE + +class gr_tagged_file_sink; +typedef boost::shared_ptr<gr_tagged_file_sink> gr_tagged_file_sink_sptr; + +gr_tagged_file_sink_sptr gr_make_tagged_file_sink (size_t itemsize, + double samp_rate); + +/*! + * \brief Write stream to file descriptor. + * \ingroup sink_blk + */ + +class gr_tagged_file_sink : public gr_sync_block +{ + friend gr_tagged_file_sink_sptr gr_make_tagged_file_sink (size_t itemsize, + double samp_rate); + + private: + enum { + NOT_IN_BURST = 0, + IN_BURST + }; + + size_t d_itemsize; + int d_state; + FILE *d_handle; + int d_n; + double d_sample_rate; + uint64_t d_last_N; + double d_timeval; + + protected: + gr_tagged_file_sink (size_t itemsize, double samp_rate); + + public: + ~gr_tagged_file_sink (); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + + +#endif /* INCLUDED_GR_TAGGED_FILE_SINK_H */ diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.i b/gnuradio-core/src/lib/io/gr_tagged_file_sink.i new file mode 100644 index 000000000..1408adfc1 --- /dev/null +++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.i @@ -0,0 +1,35 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,tagged_file_sink) + +gr_tagged_file_sink_sptr +gr_make_tagged_file_sink (size_t itemsize, double samp_rate); + +class gr_tagged_file_sink : public gr_sync_block +{ + protected: + gr_tagged_file_sink (size_t itemsize, double samp_rate); + + public: + ~gr_tagged_file_sink (); +}; diff --git a/gnuradio-core/src/lib/io/gr_wavfile_sink.cc b/gnuradio-core/src/lib/io/gr_wavfile_sink.cc index b60a6e3ab..a96aadc72 100644 --- a/gnuradio-core/src/lib/io/gr_wavfile_sink.cc +++ b/gnuradio-core/src/lib/io/gr_wavfile_sink.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * Copyright 2004,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -33,6 +33,7 @@ #include <cmath> #include <fcntl.h> #include <gruel/thread.h> +#include <boost/math/special_functions/round.hpp> // win32 (mingw/msvc) specific #ifdef HAVE_IO_H @@ -224,7 +225,7 @@ gr_wavfile_sink::convert_to_short(float sample) sample = d_min_sample_val; } - return (short int) roundf(sample); + return (short int) boost::math::iround(sample); } diff --git a/gnuradio-core/src/lib/io/gr_wavfile_source.cc b/gnuradio-core/src/lib/io/gr_wavfile_source.cc index d00dd3028..136e52611 100644 --- a/gnuradio-core/src/lib/io/gr_wavfile_source.cc +++ b/gnuradio-core/src/lib/io/gr_wavfile_source.cc @@ -27,7 +27,6 @@ #include <gr_wavfile_source.h> #include <gr_io_signature.h> #include <gri_wavfile.h> -#include <cstdio> #include <sys/types.h> #include <fcntl.h> #include <stdexcept> diff --git a/gnuradio-core/src/lib/io/gr_wavfile_source.h b/gnuradio-core/src/lib/io/gr_wavfile_source.h index 0c663f0a0..e434a6b4c 100644 --- a/gnuradio-core/src/lib/io/gr_wavfile_source.h +++ b/gnuradio-core/src/lib/io/gr_wavfile_source.h @@ -24,6 +24,7 @@ #define INCLUDED_GR_WAVFILE_SOURCE_H #include <gr_sync_block.h> +#include <cstdio> // for FILE class gr_wavfile_source; typedef boost::shared_ptr<gr_wavfile_source> gr_wavfile_source_sptr; diff --git a/gnuradio-core/src/lib/io/io.i b/gnuradio-core/src/lib/io/io.i index 3538942ca..365577cd4 100644 --- a/gnuradio-core/src/lib/io/io.i +++ b/gnuradio-core/src/lib/io/io.i @@ -43,7 +43,7 @@ #include <gr_udp_source.h> #include <gr_wavfile_sink.h> #include <gr_wavfile_source.h> - +#include <gr_tagged_file_sink.h> %} %include "gr_file_sink_base.i" @@ -64,4 +64,5 @@ %include "gr_udp_source.i" %include "gr_wavfile_sink.i" %include "gr_wavfile_source.i" +%include "gr_tagged_file_sink.i" diff --git a/gnuradio-core/src/lib/missing/Makefile.am b/gnuradio-core/src/lib/missing/Makefile.am index 238370910..1cc6014a1 100644 --- a/gnuradio-core/src/lib/missing/Makefile.am +++ b/gnuradio-core/src/lib/missing/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2003,2004,2008,2009 Free Software Foundation, Inc. +# Copyright 2003,2004,2008,2009,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,9 +21,9 @@ include $(top_srcdir)/Makefile.common -AM_CPPFLAGS = $(GNURADIO_INCLUDES) $(WITH_INCLUDES) +AM_CPPFLAGS = $(GRUEL_INCLUDES) $(GNURADIO_INCLUDES) $(WITH_INCLUDES) -EXTRA_DIST = \ +EXTRA_DIST += \ getopt.h \ getopt.c \ gettimeofday.c \ diff --git a/gnuradio-core/src/lib/missing/bug_work_around_8.cc b/gnuradio-core/src/lib/missing/bug_work_around_8.cc index b2cbdb3d9..5e431a210 100644 --- a/gnuradio-core/src/lib/missing/bug_work_around_8.cc +++ b/gnuradio-core/src/lib/missing/bug_work_around_8.cc @@ -1,2 +1,3 @@ // if libmisc has no sources, it doesn't get built correctly -static int gr_bug_work_around_8 __attribute__((unused)); +#include <gruel/attributes.h> +static int gr_bug_work_around_8 __GR_ATTR_UNUSED; diff --git a/gnuradio-core/src/lib/reed-solomon/Makefile.am b/gnuradio-core/src/lib/reed-solomon/Makefile.am index b7bd939b0..5548f4280 100644 --- a/gnuradio-core/src/lib/reed-solomon/Makefile.am +++ b/gnuradio-core/src/lib/reed-solomon/Makefile.am @@ -29,7 +29,7 @@ AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) TESTS = rstest -EXTRA_DIST = \ +EXTRA_DIST += \ README.karn noinst_LTLIBRARIES = librs.la diff --git a/gnuradio-core/src/lib/runtime/Makefile.am b/gnuradio-core/src/lib/runtime/Makefile.am index f67e8843d..eca92e526 100644 --- a/gnuradio-core/src/lib/runtime/Makefile.am +++ b/gnuradio-core/src/lib/runtime/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2003,2004,2007,2008,2009,2010 Free Software Foundation, Inc. +# Copyright 2003,2004,2007,2008,2009,2010,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -58,7 +58,7 @@ libruntime_la_SOURCES = \ gr_sync_block.cc \ gr_sync_decimator.cc \ gr_sync_interpolator.cc \ - gr_tmp_path.cc \ + gr_sys_paths.cc \ gr_top_block.cc \ gr_top_block_impl.cc \ gr_tpb_detail.cc \ @@ -68,7 +68,8 @@ libruntime_la_SOURCES = \ gr_vmcircbuf_mmap_tmpfile.cc \ gr_vmcircbuf_createfilemapping.cc \ gr_vmcircbuf_sysv_shm.cc \ - gr_select_handler.cc + gr_select_handler.cc \ + gr_tag_info.cc libruntime_qa_la_SOURCES = \ qa_gr_block.cc \ @@ -79,6 +80,8 @@ libruntime_qa_la_SOURCES = \ qa_gr_top_block.cc \ qa_gr_io_signature.cc \ qa_gr_vmcircbuf.cc \ + qa_block_tags.cc \ + qa_set_msg_handler.cc \ qa_runtime.cc grinclude_HEADERS = \ @@ -118,10 +121,11 @@ grinclude_HEADERS = \ gr_tpb_detail.h \ gr_tpb_thread_body.h \ gr_timer.h \ - gr_tmp_path.h \ + gr_sys_paths.h \ gr_types.h \ gr_unittests.h \ - gr_vmcircbuf.h + gr_vmcircbuf.h \ + gr_tag_info.h noinst_HEADERS = \ gr_vmcircbuf_mmap_shm_open.h \ @@ -136,9 +140,10 @@ noinst_HEADERS = \ qa_gr_io_signature.h \ qa_gr_top_block.h \ qa_gr_vmcircbuf.h \ + qa_block_tags.h \ + qa_set_msg_handler.h \ qa_runtime.h -if PYTHON swiginclude_HEADERS = \ gr_basic_block.i \ gr_block.i \ @@ -158,4 +163,3 @@ swiginclude_HEADERS = \ gr_sync_interpolator.i \ gr_top_block.i \ runtime.i -endif diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.cc b/gnuradio-core/src/lib/runtime/gr_basic_block.cc index 2fa1066cb..0e0dad16b 100644 --- a/gnuradio-core/src/lib/runtime/gr_basic_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_basic_block.cc @@ -56,7 +56,7 @@ gr_basic_block::~gr_basic_block() } gr_basic_block_sptr -gr_basic_block::basic_block() +gr_basic_block::to_basic_block() { return shared_from_this(); } diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.h b/gnuradio-core/src/lib/runtime/gr_basic_block.h index b8797fdc6..3b0cd51dd 100644 --- a/gnuradio-core/src/lib/runtime/gr_basic_block.h +++ b/gnuradio-core/src/lib/runtime/gr_basic_block.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2008,2009 Free Software Foundation, Inc. + * Copyright 2006,2008,2009,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,6 +26,7 @@ #include <gr_runtime_types.h> #include <gr_sptr_magic.h> #include <boost/enable_shared_from_this.hpp> +#include <boost/function.hpp> #include <gr_msg_accepter.h> #include <string> @@ -42,9 +43,27 @@ class gr_basic_block : public gr_msg_accepter, public boost::enable_shared_from_this<gr_basic_block> { + typedef boost::function<void(pmt::pmt_t)> msg_handler_t; + +private: + /* + * This function is called by the runtime system to dispatch messages. + * + * The thread-safety guarantees mentioned in set_msg_handler are implemented + * by the callers of this method. + */ + void dispatch_msg(pmt::pmt_t msg) + { + if (d_msg_handler) // Is there a handler? + d_msg_handler(msg); // Yes, invoke it. + }; + + msg_handler_t d_msg_handler; + protected: friend class gr_flowgraph; friend class gr_flat_flowgraph; // TODO: will be redundant + friend class gr_tpb_thread_body; enum vcolor { WHITE, GREY, BLACK }; @@ -54,6 +73,8 @@ protected: long d_unique_id; vcolor d_color; + gr_basic_block(void){} //allows pure virtual interface sub-classes + //! Protected constructor prevents instantiation by non-derived classes gr_basic_block(const std::string &name, gr_io_signature_sptr input_signature, @@ -81,7 +102,7 @@ public: std::string name() const { return d_name; } gr_io_signature_sptr input_signature() const { return d_input_signature; } gr_io_signature_sptr output_signature() const { return d_output_signature; } - gr_basic_block_sptr basic_block(); // Needed for Python type coercion + gr_basic_block_sptr to_basic_block(); // Needed for Python/Guile type coercion /*! * \brief Confirm that ninputs and noutputs is an acceptable combination. @@ -99,15 +120,34 @@ public: virtual bool check_topology(int ninputs, int noutputs) { return true; } /*! - * \brief Block message handler. - * - * \param msg Arbitrary message encapsulated as pmt::pmt_t + * \brief Set the callback that is fired when messages are available. * - * This function is called by the runtime system whenever there are - * messages in its queue. Blocks should override this to receive - * messages; the default behavior is to drop them on the floor. + * \p msg_handler can be any kind of function pointer or function object + * that has the signature: + * <pre> + * void msg_handler(pmt::pmt msg); + * </pre> + * + * (You may want to use boost::bind to massage your callable into the + * correct form. See gr_nop.{h,cc} for an example that sets up a class + * method as the callback.) + * + * Blocks that desire to handle messages must call this method in their + * constructors to register the handler that will be invoked when messages + * are available. + * + * If the block inherits from gr_block, the runtime system will ensure that + * msg_handler is called in a thread-safe manner, such that work and + * msg_handler will never be called concurrently. This allows msg_handler + * to update state variables without having to worry about thread-safety + * issues with work, general_work or another invocation of msg_handler. + * + * If the block inherits from gr_hier_block2, the runtime system will + * ensure that no reentrant calls are made to msg_handler. */ - virtual void handle_msg(pmt::pmt_t msg) { }; + template <typename T> void set_msg_handler(T msg_handler){ + d_msg_handler = msg_handler_t(msg_handler); + } }; inline bool operator<(gr_basic_block_sptr lhs, gr_basic_block_sptr rhs) diff --git a/gnuradio-core/src/lib/runtime/gr_basic_block.i b/gnuradio-core/src/lib/runtime/gr_basic_block.i index 60e08aac3..03d4725d5 100644 --- a/gnuradio-core/src/lib/runtime/gr_basic_block.i +++ b/gnuradio-core/src/lib/runtime/gr_basic_block.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006 Free Software Foundation, Inc. + * Copyright 2006,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -40,13 +40,15 @@ public: gr_io_signature_sptr input_signature() const; gr_io_signature_sptr output_signature() const; long unique_id() const; - gr_basic_block_sptr basic_block(); + gr_basic_block_sptr to_basic_block(); bool check_topology (int ninputs, int noutputs); }; %rename(block_ncurrently_allocated) gr_basic_block_ncurrently_allocated; long gr_basic_block_ncurrently_allocated(); +#ifdef SWIGPYTHON %pythoncode %{ gr_basic_block_sptr.__repr__ = lambda self: "<gr_basic_block %s (%d)>" % (self.name(), self.unique_id ()) %} +#endif diff --git a/gnuradio-core/src/lib/runtime/gr_block.cc b/gnuradio-core/src/lib/runtime/gr_block.cc index 8915f3360..81a55af9d 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_block.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2009 Free Software Foundation, Inc. + * Copyright 2004,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -36,7 +36,8 @@ gr_block::gr_block (const std::string &name, d_output_multiple (1), d_relative_rate (1.0), d_history(1), - d_fixed_rate(false) + d_fixed_rate(false), + d_tag_propagation_policy(TPP_ALL_TO_ALL) { } @@ -117,6 +118,69 @@ gr_block::fixed_rate_noutput_to_ninput(int noutput) throw std::runtime_error("Unimplemented"); } +uint64_t +gr_block::nitems_read(unsigned int which_input) +{ + if(d_detail) { + return d_detail->nitems_read(which_input); + } + else { + //throw std::runtime_error("No block_detail associated with block yet"); + return 0; + } +} + +uint64_t +gr_block::nitems_written(unsigned int which_output) +{ + if(d_detail) { + return d_detail->nitems_written(which_output); + } + else { + //throw std::runtime_error("No block_detail associated with block yet"); + return 0; + } +} + +void +gr_block::add_item_tag(unsigned int which_output, + uint64_t offset, + const pmt::pmt_t &key, + const pmt::pmt_t &value, + const pmt::pmt_t &srcid) +{ + d_detail->add_item_tag(which_output, offset, key, value, srcid); +} + +void +gr_block::get_tags_in_range(std::vector<pmt::pmt_t> &v, + unsigned int which_output, + uint64_t start, uint64_t end) +{ + d_detail->get_tags_in_range(v, which_output, start, end); +} + +void +gr_block::get_tags_in_range(std::vector<pmt::pmt_t> &v, + unsigned int which_output, + uint64_t start, uint64_t end, + const pmt::pmt_t &key) +{ + d_detail->get_tags_in_range(v, which_output, start, end, key); +} + +gr_block::tag_propagation_policy_t +gr_block::tag_propagation_policy() +{ + return d_tag_propagation_policy; +} + +void +gr_block::set_tag_propagation_policy(tag_propagation_policy_t p) +{ + d_tag_propagation_policy = p; +} + std::ostream& operator << (std::ostream& os, const gr_block *m) { diff --git a/gnuradio-core/src/lib/runtime/gr_block.h b/gnuradio-core/src/lib/runtime/gr_block.h index b6f724dde..fc22f9ea8 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.h +++ b/gnuradio-core/src/lib/runtime/gr_block.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2007,2009 Free Software Foundation, Inc. + * Copyright 2004,2007,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -63,6 +63,12 @@ class gr_block : public gr_basic_block { WORK_DONE = -1 }; + enum tag_propagation_policy_t { + TPP_DONT = 0, + TPP_ALL_TO_ALL = 1, + TPP_ONE_TO_ONE = 2 + }; + virtual ~gr_block (); /*! @@ -198,6 +204,26 @@ class gr_block : public gr_basic_block { */ virtual int fixed_rate_noutput_to_ninput(int noutput); + /*! + * \brief Return the number of items read on input stream which_input + */ + uint64_t nitems_read(unsigned int which_input); + + /*! + * \brief Return the number of items written on output stream which_output + */ + uint64_t nitems_written(unsigned int which_output); + + /*! + * \brief Asks for the policy used by the scheduler to moved tags downstream. + */ + tag_propagation_policy_t tag_propagation_policy(); + + /*! + * \brief Set the policy by the scheduler to determine how tags are moved downstream. + */ + void set_tag_propagation_policy(tag_propagation_policy_t p); + // ---------------------------------------------------------------------------- private: @@ -207,15 +233,72 @@ class gr_block : public gr_basic_block { gr_block_detail_sptr d_detail; // implementation details unsigned d_history; bool d_fixed_rate; + tag_propagation_policy_t d_tag_propagation_policy; // policy for moving tags downstream protected: - + gr_block (void){} //allows pure virtual interface sub-classes gr_block (const std::string &name, gr_io_signature_sptr input_signature, gr_io_signature_sptr output_signature); void set_fixed_rate(bool fixed_rate){ d_fixed_rate = fixed_rate; } + + /*! + * \brief Adds a new tag onto the given output buffer. + * + * \param which_output an integer of which output stream to attach the tag + * \param abs_offset a uint64 number of the absolute item number + * assicated with the tag. Can get from nitems_written. + * \param key the tag key as a PMT symbol + * \param value any PMT holding any value for the given key + * \param srcid optional source ID specifier; defaults to PMT_F + */ + void add_item_tag(unsigned int which_output, + uint64_t abs_offset, + const pmt::pmt_t &key, + const pmt::pmt_t &value, + const pmt::pmt_t &srcid=pmt::PMT_F); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the range. + * + * Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + */ + void get_tags_in_range(std::vector<pmt::pmt_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the range + * with a given key. + * + * Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + * \param key a PMT symbol key to filter only tags of this key + */ + void get_tags_in_range(std::vector<pmt::pmt_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end, + const pmt::pmt_t &key); + // These are really only for internal use, but leaving them public avoids // having to work up an ever-varying list of friends diff --git a/gnuradio-core/src/lib/runtime/gr_block.i b/gnuradio-core/src/lib/runtime/gr_block.i index c2e2aa4b8..bb0c5f221 100644 --- a/gnuradio-core/src/lib/runtime/gr_block.i +++ b/gnuradio-core/src/lib/runtime/gr_block.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -49,12 +49,10 @@ class gr_block : public gr_basic_block { bool start(); bool stop(); + uint64_t nitems_read(unsigned int which_input); + uint64_t nitems_written(unsigned int which_output); + // internal use gr_block_detail_sptr detail () const { return d_detail; } void set_detail (gr_block_detail_sptr detail) { d_detail = detail; } }; - -%pythoncode %{ -gr_block_sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ()) -gr_block_sptr.block = lambda self: self -%} diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.cc b/gnuradio-core/src/lib/runtime/gr_block_detail.cc index 38d4a13ca..a360240c0 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.cc +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2009 Free Software Foundation, Inc. + * Copyright 2004,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -27,6 +27,8 @@ #include <gr_block_detail.h> #include <gr_buffer.h> +using namespace pmt; + static long s_ncurrently_allocated = 0; long @@ -88,16 +90,20 @@ gr_block_detail::set_done (bool done) void gr_block_detail::consume (int which_input, int how_many_items) { - if (how_many_items > 0) + if (how_many_items > 0) { input (which_input)->update_read_pointer (how_many_items); + } } + void gr_block_detail::consume_each (int how_many_items) { - if (how_many_items > 0) - for (int i = 0; i < ninputs (); i++) + if (how_many_items > 0) { + for (int i = 0; i < ninputs (); i++) { d_input[i]->update_read_pointer (how_many_items); + } + } } void @@ -112,16 +118,88 @@ gr_block_detail::produce (int which_output, int how_many_items) void gr_block_detail::produce_each (int how_many_items) { - if (how_many_items > 0){ - for (int i = 0; i < noutputs (); i++) + if (how_many_items > 0) { + for (int i = 0; i < noutputs (); i++) { d_output[i]->update_write_pointer (how_many_items); + } d_produce_or |= how_many_items; } } void -gr_block_detail::_post(pmt::pmt_t msg) +gr_block_detail::_post(pmt_t msg) { d_tpb.insert_tail(msg); } + +uint64_t +gr_block_detail::nitems_read(unsigned int which_input) +{ + if(which_input >= d_ninputs) + throw std::invalid_argument ("gr_block_detail::n_input_items"); + return d_input[which_input]->nitems_read(); +} + +uint64_t +gr_block_detail::nitems_written(unsigned int which_output) +{ + if(which_output >= d_noutputs) + throw std::invalid_argument ("gr_block_detail::n_output_items"); + return d_output[which_output]->nitems_written(); +} + +void +gr_block_detail::add_item_tag(unsigned int which_output, + uint64_t abs_offset, + const pmt_t &key, + const pmt_t &value, + const pmt_t &srcid) +{ + if(!pmt_is_symbol(key)) { + throw pmt_wrong_type("gr_block_detail::add_item_tag key", key); + } + else { + // build tag tuple + pmt_t nitem = pmt_from_uint64(abs_offset); + pmt_t tuple = pmt_make_tuple(nitem, srcid, key, value); + + // Add tag to gr_buffer's deque tags + d_output[which_output]->add_item_tag(tuple); + } +} + +void +gr_block_detail::get_tags_in_range(std::vector<pmt::pmt_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end) +{ + // get from gr_buffer_reader's deque of tags + d_input[which_input]->get_tags_in_range(v, abs_start, abs_end); +} + +void +gr_block_detail::get_tags_in_range(std::vector<pmt_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end, + const pmt_t &key) +{ + std::vector<pmt_t> found_items; + + v.resize(0); + + // get from gr_buffer_reader's deque of tags + d_input[which_input]->get_tags_in_range(found_items, abs_start, abs_end); + + // Filter further by key name + pmt_t itemkey; + std::vector<pmt_t>::iterator itr; + for(itr = found_items.begin(); itr != found_items.end(); itr++) { + itemkey = pmt_tuple_ref(*itr, 2); + if(pmt_eqv(key, itemkey)) { + v.push_back(*itr); + } + } +} diff --git a/gnuradio-core/src/lib/runtime/gr_block_detail.h b/gnuradio-core/src/lib/runtime/gr_block_detail.h index c5787a5ad..d7ec3b136 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_detail.h +++ b/gnuradio-core/src/lib/runtime/gr_block_detail.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2009 Free Software Foundation, Inc. + * Copyright 2004,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -25,6 +25,7 @@ #include <gr_runtime_types.h> #include <gr_tpb_detail.h> +#include <gr_tag_info.h> #include <stdexcept> /*! @@ -88,6 +89,75 @@ class gr_block_detail { */ void _post(pmt::pmt_t msg); + // Return the number of items read on input stream which_input + uint64_t nitems_read(unsigned int which_input); + + // Return the number of items written on output stream which_output + uint64_t nitems_written(unsigned int which_output); + + + /*! + * \brief Adds a new tag to the given output stream. + * + * This takes the input parameters and builds a PMT tuple + * from it. It then calls gr_buffer::add_item_tag(pmt::pmt_t t), + * which appends the tag onto its deque. + * + * \param which_output an integer of which output stream to attach the tag + * \param abs_offset a uint64 number of the absolute item number + * assicated with the tag. Can get from nitems_written. + * \param key the tag key as a PMT symbol + * \param value any PMT holding any value for the given key + * \param srcid a PMT source ID specifier + */ + void add_item_tag(unsigned int which_output, + uint64_t abs_offset, + const pmt::pmt_t &key, + const pmt::pmt_t &value, + const pmt::pmt_t &srcid); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the range. + * + * Pass-through function to gr_buffer_reader to get a vector of tags + * in given range. Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + */ + void get_tags_in_range(std::vector<pmt::pmt_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end); + + /*! + * \brief Given a [start,end), returns a vector of all tags in the range + * with a given key. + * + * Calls get_tags_in_range(which_input, abs_start, abs_end) to get a vector of + * tags from the buffers. This function then provides a secondary filter to + * the tags to extract only tags with the given 'key'. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param which_input an integer of which input stream to pull from + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + * \param key a PMT symbol to select only tags of this key + */ + void get_tags_in_range(std::vector<pmt::pmt_t> &v, + unsigned int which_input, + uint64_t abs_start, + uint64_t abs_end, + const pmt::pmt_t &key); + gr_tpb_detail d_tpb; // used by thread-per-block scheduler int d_produce_or; @@ -100,7 +170,6 @@ class gr_block_detail { std::vector<gr_buffer_sptr> d_output; bool d_done; - gr_block_detail (unsigned int ninputs, unsigned int noutputs); friend class gr_tpb_detail; diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.cc b/gnuradio-core/src/lib/runtime/gr_block_executor.cc index 2c21a0b0f..a8d0bc1c8 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_executor.cc +++ b/gnuradio-core/src/lib/runtime/gr_block_executor.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2008,2009 Free Software Foundation, Inc. + * Copyright 2004,2008,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -87,7 +87,79 @@ min_available_space (gr_block_detail *d, int output_multiple) return min_space; } +static bool +propagate_tags(gr_block::tag_propagation_policy_t policy, gr_block_detail *d, + const std::vector<uint64_t> &start_nitems_read, double rrate, + std::vector<pmt::pmt_t> &rtags) +{ + // Move tags downstream + // if a sink, we don't need to move downstream + if(d->sink_p()) { + return true; + } + switch(policy) { + case gr_block::TPP_DONT: + return true; + break; + case gr_block::TPP_ALL_TO_ALL: + // every tag on every input propogates to everyone downstream + for(int i = 0; i < d->ninputs(); i++) { + d->get_tags_in_range(rtags, i, start_nitems_read[i], + d->nitems_read(i)); + + std::vector<pmt::pmt_t>::iterator t; + if(rrate == 1.0) { + for(t = rtags.begin(); t != rtags.end(); t++) { + for(int o = 0; o < d->noutputs(); o++) + d->output(o)->add_item_tag(*t); + } + } + else { + for(t = rtags.begin(); t != rtags.end(); t++) { + uint64_t newcount = pmt::pmt_to_uint64(pmt::pmt_tuple_ref(*t, 0)); + pmt::pmt_t newtup = pmt::mp(pmt::pmt_from_uint64(newcount * rrate), + pmt::pmt_tuple_ref(*t, 1), + pmt::pmt_tuple_ref(*t, 2), + pmt::pmt_tuple_ref(*t, 3)); + + for(int o = 0; o < d->noutputs(); o++) + d->output(o)->add_item_tag(newtup); + } + } + } + break; + case gr_block::TPP_ONE_TO_ONE: + // tags from input i only go to output i + // this requires d->ninputs() == d->noutputs; this is checked when this + // type of tag-propagation system is selected in gr_block_detail + if(d->ninputs() == d->noutputs()) { + for(int i = 0; i < d->ninputs(); i++) { + d->get_tags_in_range(rtags, i, start_nitems_read[i], + d->nitems_read(i)); + + std::vector<pmt::pmt_t>::iterator t; + for(t = rtags.begin(); t != rtags.end(); t++) { + uint64_t newcount = pmt::pmt_to_uint64(pmt::pmt_tuple_ref(*t, 0)); + pmt::pmt_t newtup = pmt::mp(pmt::pmt_from_uint64(newcount * rrate), + pmt::pmt_tuple_ref(*t, 1), + pmt::pmt_tuple_ref(*t, 2), + pmt::pmt_tuple_ref(*t, 3)); + d->output(i)->add_item_tag(newtup); + } + } + } + else { + std::cerr << "Error: gr_block_executor: propagation_policy 'ONE-TO-ONE' requires ninputs == noutputs" << std::endl; + return false; + } + + break; + default: + return true; + } + return true; +} gr_block_executor::gr_block_executor (gr_block_sptr block) : d_block(block), d_log(0) @@ -134,6 +206,7 @@ gr_block_executor::run_one_iteration() d_input_items.resize (0); d_input_done.resize(0); d_output_items.resize (d->noutputs ()); + d_start_nitems_read.resize(0); // determine the minimum available output space noutput_items = min_available_space (d, m->output_multiple ()); @@ -155,6 +228,7 @@ gr_block_executor::run_one_iteration() d_input_items.resize (d->ninputs ()); d_input_done.resize(d->ninputs()); d_output_items.resize (0); + d_start_nitems_read.resize(d->ninputs()); LOG(*d_log << " sink\n"); max_items_avail = 0; @@ -198,6 +272,7 @@ gr_block_executor::run_one_iteration() d_input_items.resize (d->ninputs ()); d_input_done.resize(d->ninputs()); d_output_items.resize (d->noutputs ()); + d_start_nitems_read.resize(d->ninputs()); max_items_avail = 0; for (int i = 0; i < d->ninputs (); i++){ @@ -294,12 +369,21 @@ gr_block_executor::run_one_iteration() for (int i = 0; i < d->noutputs (); i++) d_output_items[i] = d->output(i)->write_pointer(); + // determine where to start looking for new tags + for (int i = 0; i < d->ninputs(); i++) + d_start_nitems_read[i] = d->nitems_read(i); + // Do the actual work of the block int n = m->general_work (noutput_items, d_ninput_items, d_input_items, d_output_items); LOG(*d_log << " general_work: noutput_items = " << noutput_items << " result = " << n << std::endl); + if(!propagate_tags(m->tag_propagation_policy(), d, + d_start_nitems_read, m->relative_rate(), + d_returned_tags)) + goto were_done; + if (n == gr_block::WORK_DONE) goto were_done; diff --git a/gnuradio-core/src/lib/runtime/gr_block_executor.h b/gnuradio-core/src/lib/runtime/gr_block_executor.h index 41b5ede7c..77ace5522 100644 --- a/gnuradio-core/src/lib/runtime/gr_block_executor.h +++ b/gnuradio-core/src/lib/runtime/gr_block_executor.h @@ -25,6 +25,7 @@ #include <gr_runtime_types.h> #include <fstream> +#include <gruel/pmt.h> //class gr_block_executor; //typedef boost::shared_ptr<gr_block_executor> gr_block_executor_sptr; @@ -47,6 +48,8 @@ protected: gr_vector_const_void_star d_input_items; std::vector<bool> d_input_done; gr_vector_void_star d_output_items; + std::vector<uint64_t> d_start_nitems_read; //stores where tag counts are before work + std::vector<pmt::pmt_t> d_returned_tags; public: gr_block_executor(gr_block_sptr block); diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.cc b/gnuradio-core/src/lib/runtime/gr_buffer.cc index db2db5d6d..fa3722714 100644 --- a/gnuradio-core/src/lib/runtime/gr_buffer.cc +++ b/gnuradio-core/src/lib/runtime/gr_buffer.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2009 Free Software Foundation, Inc. + * Copyright 2004,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -31,6 +31,7 @@ #include <iostream> #include <assert.h> #include <algorithm> +#include <boost/math/common_factor_rt.hpp> static long s_buffer_count = 0; // counts for debugging storage mgmt static long s_buffer_reader_count = 0; @@ -73,14 +74,15 @@ static long s_buffer_reader_count = 0; static long minimum_buffer_items (long type_size, long page_size) { - return page_size / gr_gcd (type_size, page_size); + return page_size / boost::math::gcd (type_size, page_size); } gr_buffer::gr_buffer (int nitems, size_t sizeof_item, gr_block_sptr link) : d_base (0), d_bufsize (0), d_vmcircbuf (0), d_sizeof_item (sizeof_item), d_link(link), - d_write_index (0), d_done (false) + d_write_index (0), d_abs_write_offset(0), d_done (false), + d_last_min_items_read(0) { if (!allocate_buffer (nitems, sizeof_item)) throw std::bad_alloc (); @@ -156,8 +158,16 @@ gr_buffer::space_available () // Find out the maximum amount of data available to our readers int most_data = d_readers[0]->items_available (); - for (unsigned int i = 1; i < d_readers.size (); i++) + uint64_t min_items_read = d_readers[0]->nitems_read(); + for (size_t i = 1; i < d_readers.size (); i++) { most_data = std::max (most_data, d_readers[i]->items_available ()); + min_items_read = std::min(min_items_read, d_readers[i]->nitems_read()); + } + + if(min_items_read != d_last_min_items_read) { + prune_tags(d_last_min_items_read); + d_last_min_items_read = min_items_read; + } // The -1 ensures that the case d_write_index == d_read_index is // unambiguous. It indicates that there is no data for the reader @@ -177,6 +187,7 @@ gr_buffer::update_write_pointer (int nitems) { gruel::scoped_lock guard(*mutex()); d_write_index = index_add (d_write_index, nitems); + d_abs_write_offset += nitems; } void @@ -215,6 +226,45 @@ gr_buffer::drop_reader (gr_buffer_reader *reader) d_readers.erase (result); } +void +gr_buffer::add_item_tag(const pmt::pmt_t &tag) +{ + gruel::scoped_lock guard(*mutex()); + d_item_tags.push_back(tag); +} + +void +gr_buffer::prune_tags(uint64_t max_time) +{ + /* NOTE: this function _should_ lock the mutex before editing + d_item_tags. In practice, this function is only called at + runtime by min_available_space in gr_block_executor.cc, + which locks the mutex itself. + + If this function is used elsewhere, remember to lock the + buffer's mutex al la the scoped_lock line below. + */ + //gruel::scoped_lock guard(*mutex()); + std::deque<pmt::pmt_t>::iterator itr = d_item_tags.begin(); + + uint64_t item_time; + + // Since tags are not guarenteed to be in any particular order, + // we need to erase here instead of pop_front. An erase in the + // middle invalidates all iterators; so this resets the iterator + // to find more. Mostly, we wil be erasing from the front and + // therefore lose little time this way. + while(itr != d_item_tags.end()) { + item_time = pmt::pmt_to_uint64(pmt::pmt_tuple_ref(*itr, 0)); + if(item_time < max_time) { + d_item_tags.erase(itr); + itr = d_item_tags.begin(); + } + else + itr++; + } +} + long gr_buffer_ncurrently_allocated () { @@ -225,7 +275,7 @@ gr_buffer_ncurrently_allocated () gr_buffer_reader::gr_buffer_reader(gr_buffer_sptr buffer, unsigned int read_index, gr_block_sptr link) - : d_buffer(buffer), d_read_index(read_index), d_link(link) + : d_buffer(buffer), d_read_index(read_index), d_abs_read_offset(0), d_link(link) { s_buffer_reader_count++; } @@ -253,6 +303,29 @@ gr_buffer_reader::update_read_pointer (int nitems) { gruel::scoped_lock guard(*mutex()); d_read_index = d_buffer->index_add (d_read_index, nitems); + d_abs_read_offset += nitems; +} + +void +gr_buffer_reader::get_tags_in_range(std::vector<pmt::pmt_t> &v, + uint64_t abs_start, + uint64_t abs_end) +{ + gruel::scoped_lock guard(*mutex()); + + v.resize(0); + std::deque<pmt::pmt_t>::iterator itr = d_buffer->get_tags_begin(); + + uint64_t item_time; + while(itr != d_buffer->get_tags_end()) { + item_time = pmt::pmt_to_uint64(pmt::pmt_tuple_ref(*itr, 0)); + + if((item_time >= abs_start) && (item_time < abs_end)) { + v.push_back(*itr); + } + + itr++; + } } long diff --git a/gnuradio-core/src/lib/runtime/gr_buffer.h b/gnuradio-core/src/lib/runtime/gr_buffer.h index 207bfe7c5..e5725d386 100644 --- a/gnuradio-core/src/lib/runtime/gr_buffer.h +++ b/gnuradio-core/src/lib/runtime/gr_buffer.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004,2009 Free Software Foundation, Inc. + * Copyright 2004,2009,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -26,6 +26,8 @@ #include <gr_runtime_types.h> #include <boost/weak_ptr.hpp> #include <gruel/thread.h> +#include <gruel/pmt.h> +#include <deque> class gr_vmcircbuf; @@ -88,6 +90,26 @@ class gr_buffer { gruel::mutex *mutex() { return &d_mutex; } + uint64_t nitems_written() { return d_abs_write_offset; } + + + /*! + * \brief Adds a new tag to the buffer. + * + * \param tag a PMT tuple containing the new tag + */ + void add_item_tag(const pmt::pmt_t &tag); + + /*! + * \brief Removes all tags before \p max_time from buffer + * + * \param max_time the time (item number) to trim up until. + */ + void prune_tags(uint64_t max_time); + + std::deque<pmt::pmt_t>::iterator get_tags_begin() { return d_item_tags.begin(); } + std::deque<pmt::pmt_t>::iterator get_tags_end() { return d_item_tags.end(); } + // ------------------------------------------------------------------------- private: @@ -106,11 +128,15 @@ class gr_buffer { boost::weak_ptr<gr_block> d_link; // block that writes to this buffer // - // The mutex protects d_write_index, d_done and the d_read_index's in the buffer readers. + // The mutex protects d_write_index, d_abs_write_offset, d_done, d_item_tags + // and the d_read_index's and d_abs_read_offset's in the buffer readers. // gruel::mutex d_mutex; unsigned int d_write_index; // in items [0,d_bufsize) + uint64_t d_abs_write_offset; // num items written since the start bool d_done; + std::deque<pmt::pmt_t> d_item_tags; + uint64_t d_last_min_items_read; unsigned index_add (unsigned a, unsigned b) @@ -220,11 +246,31 @@ class gr_buffer_reader { gruel::mutex *mutex() { return d_buffer->mutex(); } + uint64_t nitems_read() { return d_abs_read_offset; } + /*! * \brief Return the block that reads via this reader. + * */ gr_block_sptr link() { return gr_block_sptr(d_link); } + + /*! + * \brief Given a [start,end), returns a vector all tags in the range. + * + * Get a vector of tags in given range. Range of counts is from start to end-1. + * + * Tags are tuples of: + * (item count, source id, key, value) + * + * \param v a vector reference to return tags into + * \param abs_start a uint64 count of the start of the range of interest + * \param abs_end a uint64 count of the end of the range of interest + */ + void get_tags_in_range(std::vector<pmt::pmt_t> &v, + uint64_t abs_start, + uint64_t abs_end); + // ------------------------------------------------------------------------- private: @@ -236,6 +282,7 @@ class gr_buffer_reader { gr_buffer_sptr d_buffer; unsigned int d_read_index; // in items [0,d->buffer.d_bufsize) + uint64_t d_abs_read_offset; // num items seen since the start boost::weak_ptr<gr_block> d_link; // block that reads via this buffer reader //! constructor is private. Use gr_buffer::add_reader to create instances diff --git a/gnuradio-core/src/lib/runtime/gr_error_handler.cc b/gnuradio-core/src/lib/runtime/gr_error_handler.cc index 6dbb0a5d2..4b4cdacef 100644 --- a/gnuradio-core/src/lib/runtime/gr_error_handler.cc +++ b/gnuradio-core/src/lib/runtime/gr_error_handler.cc @@ -48,7 +48,6 @@ #include <assert.h> #include <stdexcept> #include <unistd.h> -#include <stdio.h> #ifdef HAVE_IO_H #include <io.h> diff --git a/gnuradio-core/src/lib/runtime/gr_error_handler.h b/gnuradio-core/src/lib/runtime/gr_error_handler.h index 530a2c23c..aedb6f41f 100644 --- a/gnuradio-core/src/lib/runtime/gr_error_handler.h +++ b/gnuradio-core/src/lib/runtime/gr_error_handler.h @@ -45,6 +45,7 @@ #include <stdarg.h> #include <string> +#include <cstdio> // for FILE /*! * \brief abstract error handler diff --git a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc index 031eb6dfd..5d1057e0f 100644 --- a/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc +++ b/gnuradio-core/src/lib/runtime/gr_flat_flowgraph.cc @@ -264,16 +264,13 @@ void gr_flat_flowgraph::dump() int no = detail->noutputs(); for (int i = 0; i < no; i++) { gr_buffer_sptr buffer = detail->output(i); - std::cout << " output " << i << ": " << buffer - << " space=" << buffer->space_available() << std::endl; + std::cout << " output " << i << ": " << buffer << std::endl; } for (int i = 0; i < ni; i++) { gr_buffer_reader_sptr reader = detail->input(i); std::cout << " reader " << i << ": " << reader - << " reading from buffer=" << reader->buffer() - << " avail=" << reader->items_available() << " items" - << std::endl; + << " reading from buffer=" << reader->buffer() << std::endl; } } diff --git a/gnuradio-core/src/lib/runtime/gr_flowgraph.cc b/gnuradio-core/src/lib/runtime/gr_flowgraph.cc index 27f6257cc..0d3bbb011 100644 --- a/gnuradio-core/src/lib/runtime/gr_flowgraph.cc +++ b/gnuradio-core/src/lib/runtime/gr_flowgraph.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007 Free Software Foundation, Inc. + * Copyright 2007,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -28,6 +28,7 @@ #include <gr_io_signature.h> #include <stdexcept> #include <sstream> +#include <iterator> #define GR_FLOWGRAPH_DEBUG 0 diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc index e3a25e1a8..d6e317136 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc @@ -61,6 +61,11 @@ gr_hier_block2::self() return shared_from_this(); } +gr_hier_block2_sptr +gr_hier_block2::to_hier_block2() +{ + return cast_to_hier_block2_sptr(shared_from_this()); +} void gr_hier_block2::connect(gr_basic_block_sptr block) diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.h b/gnuradio-core/src/lib/runtime/gr_hier_block2.h index f50b1cb94..0a40c36b7 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2.h +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.h @@ -147,6 +147,8 @@ public: // This is a public method for ease of code organization, but should be // ignored by the user. gr_flat_flowgraph_sptr flatten() const; + + gr_hier_block2_sptr to_hier_block2(); // Needed for Python/Guile type coercion }; inline gr_hier_block2_sptr cast_to_hier_block2_sptr(gr_basic_block_sptr block) { diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.i b/gnuradio-core/src/lib/runtime/gr_hier_block2.i index a62f50e84..32b656e24 100644 --- a/gnuradio-core/src/lib/runtime/gr_hier_block2.i +++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.i @@ -34,6 +34,11 @@ gr_hier_block2_sptr gr_make_hier_block2(const std::string name, gr_io_signature_sptr output_signature) throw (std::runtime_error); +// Rename connect and disconnect so that we can more easily build a +// better interface in scripting land. +%rename(primitive_connect) gr_hier_block2::connect; +%rename(primitive_disconnect) gr_hier_block2::disconnect; + class gr_hier_block2 : public gr_basic_block { private: @@ -57,4 +62,6 @@ public: void disconnect_all(); void lock(); void unlock(); + + gr_hier_block2_sptr to_hier_block2(); // Needed for Python/Guile type coercion }; diff --git a/gnuradio-core/src/lib/runtime/gr_msg_queue.i b/gnuradio-core/src/lib/runtime/gr_msg_queue.i index 9ca92b6ec..c9214bef3 100644 --- a/gnuradio-core/src/lib/runtime/gr_msg_queue.i +++ b/gnuradio-core/src/lib/runtime/gr_msg_queue.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005,2009 Free Software Foundation, Inc. + * Copyright 2005,2009,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -81,6 +81,7 @@ public: * functions into the gr.msg_queue wrapper class, so that everything * appears normal. (An evil laugh is heard in the distance...) */ +#ifdef SWIGPYTHON %inline %{ gr_message_sptr gr_py_msg_queue__delete_head(gr_msg_queue_sptr q) { gr_message_sptr msg; @@ -103,3 +104,65 @@ gr_msg_queue_sptr.delete_head = gr_py_msg_queue__delete_head gr_msg_queue_sptr.insert_tail = gr_py_msg_queue__insert_tail gr_msg_queue_sptr.handle = gr_py_msg_queue__insert_tail %} +#endif // SWIGPYTHON + +/* + * Similar trickery as above, only this time for Guile + */ +#ifdef SWIGGUILE + +%{ + struct arg_holder { + gr_msg_queue_sptr q; + gr_message_sptr msg; + }; + + static void * + insert_tail_shim(void *arg) + { + arg_holder *a = (arg_holder *)arg; + a->q->insert_tail(a->msg); + return 0; + } + + static void * + delete_head_shim(void *arg) + { + arg_holder *a = (arg_holder *)arg; + a->msg = a->q->delete_head(); + return 0; + } +%} + +%inline %{ + + // handle and insert_tail are equivalent + static void + handle(gr_msg_queue_sptr q, gr_message_sptr msg) + { + arg_holder a; + a.q = q; + a.msg = msg; + scm_without_guile(insert_tail_shim, (void *) &a); + } + + static void + insert_tail(gr_msg_queue_sptr q, gr_message_sptr msg) + { + arg_holder a; + a.q = q; + a.msg = msg; + scm_without_guile(insert_tail_shim, (void *) &a); + } + + static gr_message_sptr + delete_head(gr_msg_queue_sptr q) + { + arg_holder a; + a.q = q; + scm_without_guile(delete_head_shim, (void *) &a); + return a.msg; + } +%} + +#endif // SWIGGUILE diff --git a/gnuradio-core/src/lib/runtime/gr_preferences.cc b/gnuradio-core/src/lib/runtime/gr_preferences.cc index 5f7412248..c2ca047a8 100644 --- a/gnuradio-core/src/lib/runtime/gr_preferences.cc +++ b/gnuradio-core/src/lib/runtime/gr_preferences.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2003,2010 Free Software Foundation, Inc. + * Copyright 2003,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -25,6 +25,7 @@ #endif #include <gr_preferences.h> +#include <gr_sys_paths.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -33,12 +34,9 @@ #include <unistd.h> #include <string.h> - -#ifdef MKDIR_TAKES_ONE_ARG -#define gr_mkdir(pathname, mode) mkdir(pathname) -#else -#define gr_mkdir(pathname, mode) mkdir((pathname), (mode)) -#endif +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> +namespace fs = boost::filesystem; /* * The simplest thing that could possibly work: @@ -48,27 +46,19 @@ static const char * pathname (const char *key) { - static char buf[200]; - snprintf (buf, sizeof (buf), "%s/.gnuradio/prefs/%s", getenv ("HOME"), key); - return buf; + static fs::path path; + path = fs::path(gr_appdata_path()) / ".gnuradio" / "prefs" / key; + return path.string().c_str(); } static void ensure_dir_path () { - char path[200]; - struct stat statbuf; - - snprintf (path, sizeof (path), "%s/.gnuradio/prefs", getenv ("HOME")); - if (stat (path, &statbuf) == 0 && S_ISDIR (statbuf.st_mode)) - return; - - // blindly try to make it // FIXME make this robust. C++ SUCKS! + fs::path path = fs::path(gr_appdata_path()) / ".gnuradio"; + if (!fs::is_directory(path)) fs::create_directory(path); - snprintf (path, sizeof (path), "%s/.gnuradio", getenv ("HOME")); - gr_mkdir (path, 0750); - snprintf (path, sizeof (path), "%s/.gnuradio/prefs", getenv ("HOME")); - gr_mkdir (path, 0750); + path = path / "prefs"; + if (!fs::is_directory(path)) fs::create_directory(path); } const char * diff --git a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i index 5e9032449..2378a1880 100644 --- a/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i +++ b/gnuradio-core/src/lib/runtime/gr_single_threaded_scheduler.i @@ -42,6 +42,7 @@ class gr_single_threaded_scheduler { gr_single_threaded_scheduler (const std::vector<gr_block_sptr> &modules); }; +#ifdef SWIGPYTHON %inline %{ void sts_pyrun (gr_single_threaded_scheduler_sptr s) { Py_BEGIN_ALLOW_THREADS; // release global interpreter lock @@ -49,3 +50,5 @@ class gr_single_threaded_scheduler { Py_END_ALLOW_THREADS; // acquire global interpreter lock } %} +#endif + diff --git a/gnuradio-core/src/lib/runtime/gr_sync_block.h b/gnuradio-core/src/lib/runtime/gr_sync_block.h index 3a5d89d19..c5a6a50f1 100644 --- a/gnuradio-core/src/lib/runtime/gr_sync_block.h +++ b/gnuradio-core/src/lib/runtime/gr_sync_block.h @@ -34,7 +34,7 @@ class gr_sync_block : public gr_block { protected: - + gr_sync_block (void){} //allows pure virtual interface sub-classes gr_sync_block (const std::string &name, gr_io_signature_sptr input_signature, gr_io_signature_sptr output_signature); diff --git a/gnuradio-core/src/lib/runtime/gr_sys_paths.cc b/gnuradio-core/src/lib/runtime/gr_sys_paths.cc new file mode 100644 index 000000000..9d10a3ccd --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_sys_paths.cc @@ -0,0 +1,55 @@ +/* + * Copyright 2011 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. + */ + +#include <gr_sys_paths.h> +#include <cstdlib> //getenv +#include <cstdio> //P_tmpdir (maybe) + +const char *gr_tmp_path(){ + const char *path; + + //first case, try TMP environment variable + path = getenv("TMP"); + if (path) return path; + + //second case, try P_tmpdir when its defined + #ifdef P_tmpdir + if (P_tmpdir) return P_tmpdir; + #endif /*P_tmpdir*/ + + //fall-through case, nothing worked + return "/tmp"; +} + +const char *gr_appdata_path(){ + const char *path; + + //first case, try HOME environment variable (unix) + path = getenv("HOME"); + if (path) return path; + + //second case, try APPDATA environment variable (windows) + path = getenv("APPDATA"); + if (path) return path; + + //fall-through case, nothing worked + return gr_tmp_path(); +} diff --git a/gnuradio-core/src/lib/runtime/gr_tmp_path.h b/gnuradio-core/src/lib/runtime/gr_sys_paths.h index 3d02043c7..aa8249775 100644 --- a/gnuradio-core/src/lib/runtime/gr_tmp_path.h +++ b/gnuradio-core/src/lib/runtime/gr_sys_paths.h @@ -1,6 +1,5 @@ -/* -*- c++ -*- */ /* - * Copyright 2003 Free Software Foundation, Inc. + * Copyright 2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,12 +19,13 @@ * Boston, MA 02110-1301, USA. */ -#ifndef _GR_TMP_PATH_H_ -#define _GR_TMP_PATH_H_ +#ifndef _GR_SYS_PATHS_H_ +#define _GR_SYS_PATHS_H_ -/*! - * \brief return directory portion of pathname used for temporary files. - */ -const char *gr_tmp_path (); +//! directory to create temporary files +const char *gr_tmp_path(); + +//! directory to store application data +const char *gr_appdata_path(); -#endif /* _GR_TMP_PATH_H_ */ +#endif /* _GR_SYS_PATHS_H_ */ diff --git a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.cc b/gnuradio-core/src/lib/runtime/gr_tag_info.cc index 8252509bb..f15329f9b 100644 --- a/gnuradio-core/src/lib/filter/gr_cma_equalizer_cc.cc +++ b/gnuradio-core/src/lib/runtime/gr_tag_info.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2010 Free Software Foundation, Inc. + * Copyright 2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -21,21 +21,18 @@ */ #ifdef HAVE_CONFIG_H -#include "config.h" +#include <config.h> #endif -#include <gr_cma_equalizer_cc.h> +#include <gr_tag_info.h> +#include <gruel/pmt.h> -gr_cma_equalizer_cc_sptr -gr_make_cma_equalizer_cc(int num_taps, float modulus, float mu) -{ - return gnuradio::get_initial_sptr(new gr_cma_equalizer_cc(num_taps, modulus, mu)); -} - -gr_cma_equalizer_cc::gr_cma_equalizer_cc(int num_taps, float modulus, float mu) - : gr_adaptive_fir_ccf("cma_equalizer_cc", 1, std::vector<float>(num_taps)), - d_modulus(modulus), d_mu(mu) -{ - d_taps[0] = 1.0; +namespace gr_tags { +/* + const pmt::pmt_t key_time = pmt::pmt_string_to_symbol("time"); + const pmt::pmt_t key_sample_rate = pmt::pmt_string_to_symbol("sample_rate"); + const pmt::pmt_t key_frequency = pmt::pmt_string_to_symbol("frequency"); + const pmt::pmt_t key_rssi = pmt::pmt_string_to_symbol("rssi"); + const pmt::pmt_t key_rx_gain = pmt::pmt_string_to_symbol("gain"); +*/ } - diff --git a/gnuradio-core/src/lib/runtime/gr_tag_info.h b/gnuradio-core/src/lib/runtime/gr_tag_info.h new file mode 100644 index 000000000..5a1e1555a --- /dev/null +++ b/gnuradio-core/src/lib/runtime/gr_tag_info.h @@ -0,0 +1,87 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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_GR_TAG_INFO_H +#define INCLUDED_GR_TAG_INFO_H + +#include <gruel/pmt.h> + +namespace gr_tags { + + enum { + TAG_NITEM_REF = 0, + TAG_SRCID_REF, + TAG_KEY_REF, + TAG_VALUE_REF + }; + + /* + extern const pmt::pmt_t key_time; + extern const pmt::pmt_t key_sample_rate; + extern const pmt::pmt_t key_frequency; + extern const pmt::pmt_t key_rssi; + extern const pmt::pmt_t key_gain; + */ + + /*! + * \brief Returns the item \p tag occurred at (as a uint64_t) + */ + static inline uint64_t + get_nitems(const pmt::pmt_t &tag) { + return pmt::pmt_to_uint64(pmt::pmt_tuple_ref(tag, TAG_NITEM_REF)); + } + + /*! + * \brief Returns the source ID of \p tag (as a PMT) + */ + static inline pmt::pmt_t + get_srcid(const pmt::pmt_t &tag) { + return pmt::pmt_tuple_ref(tag, TAG_SRCID_REF); + } + + /*! + * \brief Returns the key of \p tag (as a PMT symbol) + */ + static inline pmt::pmt_t + get_key(const pmt::pmt_t &tag) { + return pmt::pmt_tuple_ref(tag, TAG_KEY_REF); + } + + /*! + * \brief Returns the value of \p tag (as a PMT) + */ + static inline pmt::pmt_t + get_value(const pmt::pmt_t &tag) { + return pmt::pmt_tuple_ref(tag, TAG_VALUE_REF); + } + + /*! + * \brief Comparison function to test which tag, \p x or \p y, came first in time + */ + static inline bool + nitems_compare(pmt::pmt_t x, pmt::pmt_t y) { + return get_nitems(x) < get_nitems(y); + } + +}; /* namespace tags */ + +#endif /* GR_TAG_INFO */ diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.cc b/gnuradio-core/src/lib/runtime/gr_top_block.cc index 09e46dfbb..f341525c0 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block.cc +++ b/gnuradio-core/src/lib/runtime/gr_top_block.cc @@ -95,3 +95,9 @@ gr_top_block::dump() { d_impl->dump(); } + +gr_top_block_sptr +gr_top_block::to_top_block() +{ + return cast_to_top_block_sptr(shared_from_this()); +} diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.h b/gnuradio-core/src/lib/runtime/gr_top_block.h index 8052954e3..ed244cb7c 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block.h +++ b/gnuradio-core/src/lib/runtime/gr_top_block.h @@ -105,6 +105,13 @@ public: * Displays flattened flowgraph edges and block connectivity */ void dump(); + + gr_top_block_sptr to_top_block(); // Needed for Python/Guile type coercion }; +inline gr_top_block_sptr cast_to_top_block_sptr(gr_basic_block_sptr block) { + return boost::dynamic_pointer_cast<gr_top_block, gr_basic_block>(block); +} + + #endif /* INCLUDED_GR_TOP_BLOCK_H */ diff --git a/gnuradio-core/src/lib/runtime/gr_top_block.i b/gnuradio-core/src/lib/runtime/gr_top_block.i index 670e5b5e5..90fa18b94 100644 --- a/gnuradio-core/src/lib/runtime/gr_top_block.i +++ b/gnuradio-core/src/lib/runtime/gr_top_block.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007,2008 Free Software Foundation, Inc. + * Copyright 2007,2008,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -42,13 +42,17 @@ public: void start() throw (std::runtime_error); void stop(); - void wait(); - void run(); + //void wait(); + //void run() throw (std::runtime_error); void lock(); void unlock() throw (std::runtime_error); void dump(); + + gr_top_block_sptr to_top_block(); // Needed for Python/Guile type coercion }; +#ifdef SWIGPYTHON + %inline %{ void top_block_run_unlocked(gr_top_block_sptr r) throw (std::runtime_error) { @@ -64,3 +68,36 @@ void top_block_wait_unlocked(gr_top_block_sptr r) throw (std::runtime_error) Py_END_ALLOW_THREADS; // acquire global interpreter lock } %} + +#endif + +#ifdef SWIGGUILE + +%{ + struct tb_arg_holder { + gr_top_block_sptr tb; + }; + + static void * + tb_wait_shim(void *arg) + { + tb_arg_holder *a = (tb_arg_holder *)arg; + a->tb->wait(); + return 0; + } + +%} + +%inline %{ + + static void + top_block_wait_unlocked(gr_top_block_sptr r) throw (std::runtime_error) + { + tb_arg_holder a; + a.tb = r; + scm_without_guile(tb_wait_shim, (void *) &a); + } + +%} + +#endif diff --git a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc index 03eef17d9..faa888697 100644 --- a/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc +++ b/gnuradio-core/src/lib/runtime/gr_tpb_thread_body.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2008,2009 Free Software Foundation, Inc. + * Copyright 2008,2009,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -43,7 +43,7 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block) // handle any queued up messages while ((msg = d->d_tpb.delete_head_nowait())) - block->handle_msg(msg); + block->dispatch_msg(msg); d->d_tpb.clear_changed(); s = d_exec.run_one_iteration(); @@ -73,7 +73,7 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block) // handle all pending messages while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){ guard.unlock(); // release lock while processing msg - block->handle_msg(msg); + block->dispatch_msg(msg); guard.lock(); } } @@ -93,7 +93,7 @@ gr_tpb_thread_body::gr_tpb_thread_body(gr_block_sptr block) // handle all pending messages while ((msg = d->d_tpb.delete_head_nowait_already_holding_mutex())){ guard.unlock(); // release lock while processing msg - block->handle_msg(msg); + block->dispatch_msg(msg); guard.lock(); } } diff --git a/gnuradio-core/src/lib/runtime/gr_unittests.h b/gnuradio-core/src/lib/runtime/gr_unittests.h index 680e59ca4..59149bb2e 100644 --- a/gnuradio-core/src/lib/runtime/gr_unittests.h +++ b/gnuradio-core/src/lib/runtime/gr_unittests.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2010 Free Software Foundation, Inc. + * Copyright 2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -31,40 +31,11 @@ #include <sys/stat.h> #include <unistd.h> +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> -#ifdef MKDIR_TAKES_ONE_ARG -#define gr_mkdir(pathname, mode) mkdir(pathname) -#else -#define gr_mkdir(pathname, mode) mkdir((pathname), (mode)) -#endif - -/* - * Mostly taken from gr_preferences.cc/h - * The simplest thing that could possibly work: - * the key is the filename; the value is the file contents. - */ - -static void -ensure_unittest_path (const char *grpath, const char *path) -{ - struct stat statbuf; - if (stat (path, &statbuf) == 0 && S_ISDIR (statbuf.st_mode)) - return; - - // blindly try to make it // FIXME make this robust. C++ SUCKS! - gr_mkdir (grpath, 0750); - gr_mkdir (path, 0750); +static std::string get_unittest_path(const std::string &filename){ + boost::filesystem::path path = boost::filesystem::current_path() / ".unittests"; + if (!boost::filesystem::is_directory(path)) boost::filesystem::create_directory(path); + return (path / filename).string(); } - -static void -get_unittest_path (const char *filename, char *fullpath, size_t pathsize) -{ - char path[200]; - char grpath[200]; - snprintf (grpath, sizeof(grpath), "%s/.gnuradio", getenv ("HOME")); - snprintf (path, sizeof(path), "%s/unittests", grpath); - snprintf (fullpath, pathsize, "%s/%s", path, filename); - - ensure_unittest_path(grpath, path); -} - diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc index abcf5b2a6..3b8a6e617 100644 --- a/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc +++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf.cc @@ -100,8 +100,10 @@ gr_vmcircbuf_sysconfig::all_factories () std::vector<gr_vmcircbuf_factory *> result; result.push_back (gr_vmcircbuf_createfilemapping_factory::singleton ()); +#ifdef TRY_SHM_VMCIRCBUF result.push_back (gr_vmcircbuf_sysv_shm_factory::singleton ()); result.push_back (gr_vmcircbuf_mmap_shm_open_factory::singleton ()); +#endif result.push_back (gr_vmcircbuf_mmap_tmpfile_factory::singleton ()); return result; diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc index 65fe0c488..42c459484 100644 --- a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc +++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_createfilemapping.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2003,2005 Free Software Foundation, Inc. + * Copyright 2003,2005,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -36,7 +36,6 @@ #include <errno.h> #include <stdio.h> #include <gr_pagesize.h> -#include <gr_tmp_path.h> #include <gr_vmcircbuf_createfilemapping.h> #ifdef HAVE_CREATEFILEMAPPING diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc index 3017036ef..4f7ae39cd 100644 --- a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc +++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_shm_open.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2003 Free Software Foundation, Inc. + * Copyright 2003,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -37,7 +37,7 @@ #include <errno.h> #include <stdio.h> #include <gr_pagesize.h> -#include <gr_tmp_path.h> +#include <gr_sys_paths.h> gr_vmcircbuf_mmap_shm_open::gr_vmcircbuf_mmap_shm_open (int size) diff --git a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc index faae4b396..ee8b0c485 100644 --- a/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc +++ b/gnuradio-core/src/lib/runtime/gr_vmcircbuf_mmap_tmpfile.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2003 Free Software Foundation, Inc. + * Copyright 2003,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -39,7 +39,7 @@ #include <stdio.h> #include <string.h> #include <gr_pagesize.h> -#include <gr_tmp_path.h> +#include <gr_sys_paths.h> gr_vmcircbuf_mmap_tmpfile::gr_vmcircbuf_mmap_tmpfile (int size) : gr_vmcircbuf (size) diff --git a/gnuradio-core/src/lib/runtime/qa_block_tags.cc b/gnuradio-core/src/lib/runtime/qa_block_tags.cc new file mode 100644 index 000000000..07ce5c276 --- /dev/null +++ b/gnuradio-core/src/lib/runtime/qa_block_tags.cc @@ -0,0 +1,450 @@ +/* -*- c++ -*- */ +/* + * Copyright 2010 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_block_tags.h> +#include <gr_block.h> +#include <gr_top_block.h> +#include <gr_null_source.h> +#include <gr_null_sink.h> +#include <gr_head.h> +#include <gr_annotator_alltoall.h> +#include <gr_annotator_1to1.h> +#include <gr_keep_one_in_n.h> +#include <gr_firdes.h> +#include <gruel/pmt.h> + + +// ---------------------------------------------------------------- + +using namespace pmt; + +// set to 1 to turn on debug output +// The debug output fully checks that the tags seen are what are expected. While +// this behavior currently works with our implementation, there is no guarentee +// that the tags will be coming in this specific order, so it's dangerous to +// rely on this as a test of the tag system working. We would really want to +// tags we know we should see and then test that they all occur once, but in no +// particular order. +#define QA_TAGS_DEBUG 0 + +void +qa_block_tags::t0 () +{ + unsigned int N = 1000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(int))); + gr_block_sptr head (gr_make_head(sizeof(int), N)); + gr_block_sptr snk (gr_make_null_sink(sizeof(int))); + + tb->connect(src, 0, head, 0); + tb->connect(head, 0, snk, 0); + + //CPPUNIT_ASSERT_THROW(src->nitems_read(0), std::runtime_error); + //CPPUNIT_ASSERT_THROW(src->nitems_written(0), std::runtime_error); + CPPUNIT_ASSERT_EQUAL(src->nitems_read(0), (uint64_t)0); + CPPUNIT_ASSERT_EQUAL(src->nitems_written(0), (uint64_t)0); + + tb->run(); + + CPPUNIT_ASSERT_THROW(src->nitems_read(0), std::invalid_argument); + CPPUNIT_ASSERT(src->nitems_written(0) >= N); + CPPUNIT_ASSERT_EQUAL(snk->nitems_read(0), (uint64_t)1000); + CPPUNIT_ASSERT_THROW(snk->nitems_written(0), std::invalid_argument); +} + + +void +qa_block_tags::t1 () +{ + int N = 40000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(int))); + gr_block_sptr head (gr_make_head(sizeof(int), N)); + gr_annotator_alltoall_sptr ann0 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_annotator_alltoall_sptr ann1 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_annotator_alltoall_sptr ann2 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_annotator_alltoall_sptr ann3 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_annotator_alltoall_sptr ann4 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_block_sptr snk0 (gr_make_null_sink(sizeof(int))); + gr_block_sptr snk1 (gr_make_null_sink(sizeof(int))); + + tb->connect(src, 0, head, 0); + tb->connect(head, 0, ann0, 0); + + tb->connect(ann0, 0, ann1, 0); + tb->connect(ann0, 1, ann2, 0); + tb->connect(ann1, 0, ann3, 0); + tb->connect(ann2, 0, ann4, 0); + + tb->connect(ann3, 0, snk0, 0); + tb->connect(ann4, 0, snk1, 0); + + tb->run(); + + std::vector<pmt::pmt_t> tags0 = ann0->data(); + std::vector<pmt::pmt_t> tags3 = ann3->data(); + std::vector<pmt::pmt_t> tags4 = ann4->data(); + + // The first annotator does not receive any tags from the null sink upstream + CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0); + CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)8); + CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)8); + +#if QA_TAGS_DEBUG + // Kludge together the tags that we know should result from the above graph + std::stringstream str0, str1, str2; + str0 << ann0->name() << ann0->unique_id(); + str1 << ann1->name() << ann1->unique_id(); + str2 << ann2->name() << ann2->unique_id(); + + pmt_t expected_tags3[8]; + expected_tags3[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0)); + expected_tags3[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags3[2] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(1)); + expected_tags3[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags3[4] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(2)); + expected_tags3[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4)); + expected_tags3[6] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(3)); + expected_tags3[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6)); + + pmt_t expected_tags4[8]; + expected_tags4[0] = mp(pmt_from_uint64(0), mp(str2.str()), mp("seq"), mp(0)); + expected_tags4[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1)); + expected_tags4[2] = mp(pmt_from_uint64(10000), mp(str2.str()), mp("seq"), mp(1)); + expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3)); + expected_tags4[4] = mp(pmt_from_uint64(20000), mp(str2.str()), mp("seq"), mp(2)); + expected_tags4[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5)); + expected_tags4[6] = mp(pmt_from_uint64(30000), mp(str2.str()), mp("seq"), mp(3)); + expected_tags4[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7)); + + std::cout << std::endl << "qa_block_tags::t1" << std::endl; + + // For annotator 3, we know it gets tags from ann0 and ann1, test this + for(size_t i = 0; i < tags3.size(); i++) { + std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags3[i]), pmt_write_string(expected_tags3[i])); + } + + // For annotator 4, we know it gets tags from ann0 and ann2, test this + std::cout << std::endl; + for(size_t i = 0; i < tags4.size(); i++) { + std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i])); + } +#endif +} + +void +qa_block_tags::t2 () +{ + int N = 40000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(int))); + gr_block_sptr head (gr_make_head(sizeof(int), N)); + gr_annotator_alltoall_sptr ann0 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_annotator_alltoall_sptr ann1 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_annotator_alltoall_sptr ann2 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_annotator_alltoall_sptr ann3 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_annotator_alltoall_sptr ann4 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_block_sptr snk0 (gr_make_null_sink(sizeof(int))); + gr_block_sptr snk1 (gr_make_null_sink(sizeof(int))); + gr_block_sptr snk2 (gr_make_null_sink(sizeof(int))); + + tb->connect(src, 0, head, 0); + tb->connect(head, 0, ann0, 0); + + tb->connect(ann0, 0, ann1, 0); + tb->connect(ann0, 1, ann1, 1); + tb->connect(ann1, 0, ann2, 0); + tb->connect(ann1, 1, ann3, 0); + tb->connect(ann1, 2, ann4, 0); + + tb->connect(ann2, 0, snk0, 0); + tb->connect(ann3, 0, snk1, 0); + tb->connect(ann4, 0, snk2, 0); + + tb->run(); + + std::vector<pmt::pmt_t> tags0 = ann0->data(); + std::vector<pmt::pmt_t> tags1 = ann1->data(); + std::vector<pmt::pmt_t> tags2 = ann2->data(); + std::vector<pmt::pmt_t> tags3 = ann4->data(); + std::vector<pmt::pmt_t> tags4 = ann4->data(); + + // The first annotator does not receive any tags from the null sink upstream + CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0); + CPPUNIT_ASSERT_EQUAL(tags1.size(), (size_t)8); + + // Make sure the rest all have 12 tags + CPPUNIT_ASSERT_EQUAL(tags2.size(), (size_t)12); + CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)12); + CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)12); + + +#if QA_TAGS_DEBUG + // Kludge together the tags that we know should result from the above graph + std::stringstream str0, str1; + str0 << ann0->name() << ann0->unique_id(); + str1 << ann1->name() << ann1->unique_id(); + + pmt_t expected_tags2[12]; + expected_tags2[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0)); + expected_tags2[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags2[2] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1)); + expected_tags2[3] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(3)); + expected_tags2[4] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags2[5] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3)); + expected_tags2[6] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(6)); + expected_tags2[7] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4)); + expected_tags2[8] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5)); + expected_tags2[9] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(9)); + expected_tags2[10] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6)); + expected_tags2[11] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7)); + + pmt_t expected_tags4[12]; + expected_tags4[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(2)); + expected_tags4[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags4[2] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1)); + expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(5)); + expected_tags4[4] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags4[5] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3)); + expected_tags4[6] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(8)); + expected_tags4[7] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4)); + expected_tags4[8] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5)); + expected_tags4[9] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(11)); + expected_tags4[10] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6)); + expected_tags4[11] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7)); + + std::cout << std::endl << "qa_block_tags::t2" << std::endl; + + // For annotator[2-4], we know it gets tags from ann0 and ann1 + // but the tags from the different outputs of ann1 are different for each. + // Just testing ann2 and ann4; if they are correct it would be + // inconceivable for ann3 to have it wrong. + for(size_t i = 0; i < tags2.size(); i++) { + std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags2[i]), pmt_write_string(expected_tags2[i])); + } + + std::cout << std::endl; + for(size_t i = 0; i < tags4.size(); i++) { + std::cout << "tags2[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i])); + } +#endif +} + + +void +qa_block_tags::t3 () +{ + int N = 40000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(int))); + gr_block_sptr head (gr_make_head(sizeof(int), N)); + gr_annotator_1to1_sptr ann0 (gr_make_annotator_1to1(10000, sizeof(int))); + gr_annotator_alltoall_sptr ann1 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_annotator_alltoall_sptr ann2 (gr_make_annotator_alltoall(10000, sizeof(int))); + gr_annotator_1to1_sptr ann3 (gr_make_annotator_1to1(10000, sizeof(int))); + gr_annotator_1to1_sptr ann4 (gr_make_annotator_1to1(10000, sizeof(int))); + gr_block_sptr snk0 (gr_make_null_sink(sizeof(int))); + gr_block_sptr snk1 (gr_make_null_sink(sizeof(int))); + + tb->connect(src, 0, head, 0); + tb->connect(head, 0, ann0, 0); + tb->connect(head, 0, ann0, 1); + + tb->connect(ann0, 0, ann1, 0); + tb->connect(ann0, 1, ann2, 0); + tb->connect(ann1, 0, ann3, 0); + tb->connect(ann2, 0, ann4, 0); + + tb->connect(ann3, 0, snk0, 0); + tb->connect(ann4, 0, snk1, 0); + + tb->run(); + + + std::vector<pmt::pmt_t> tags0 = ann0->data(); + std::vector<pmt::pmt_t> tags3 = ann3->data(); + std::vector<pmt::pmt_t> tags4 = ann4->data(); + + // The first annotator does not receive any tags from the null sink upstream + CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0); + CPPUNIT_ASSERT_EQUAL(tags3.size(), (size_t)8); + CPPUNIT_ASSERT_EQUAL(tags4.size(), (size_t)8); + +#if QA_TAGS_DEBUG + // Kludge together the tags that we know should result from the above graph + std::stringstream str0, str1, str2; + str0 << ann0->name() << ann0->unique_id(); + str1 << ann1->name() << ann1->unique_id(); + str2 << ann2->name() << ann2->unique_id(); + + pmt_t expected_tags3[8]; + expected_tags3[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0)); + expected_tags3[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags3[2] = mp(pmt_from_uint64(10000), mp(str1.str()), mp("seq"), mp(1)); + expected_tags3[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags3[4] = mp(pmt_from_uint64(20000), mp(str1.str()), mp("seq"), mp(2)); + expected_tags3[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(4)); + expected_tags3[6] = mp(pmt_from_uint64(30000), mp(str1.str()), mp("seq"), mp(3)); + expected_tags3[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(6)); + + pmt_t expected_tags4[8]; + expected_tags4[0] = mp(pmt_from_uint64(0), mp(str2.str()), mp("seq"), mp(0)); + expected_tags4[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(1)); + expected_tags4[2] = mp(pmt_from_uint64(10000), mp(str2.str()), mp("seq"), mp(1)); + expected_tags4[3] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(3)); + expected_tags4[4] = mp(pmt_from_uint64(20000), mp(str2.str()), mp("seq"), mp(2)); + expected_tags4[5] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(5)); + expected_tags4[6] = mp(pmt_from_uint64(30000), mp(str2.str()), mp("seq"), mp(3)); + expected_tags4[7] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(7)); + + std::cout << std::endl << "qa_block_tags::t3" << std::endl; + + // For annotator 3, we know it gets tags from ann0 and ann1, test this + for(size_t i = 0; i < tags3.size(); i++) { + std::cout << "tags3[" << i << "] = " << tags3[i] << "\t\t" << expected_tags3[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags3[i]), pmt_write_string(expected_tags3[i])); + } + + // For annotator 4, we know it gets tags from ann0 and ann2, test this + std::cout << std::endl; + for(size_t i = 0; i < tags4.size(); i++) { + std::cout << "tags4[" << i << "] = " << tags4[i] << "\t\t" << expected_tags4[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags4[i]), pmt_write_string(expected_tags4[i])); + } +#endif +} + + +void +qa_block_tags::t4 () +{ + int N = 40000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(int))); + gr_block_sptr head (gr_make_head(sizeof(int), N)); + gr_annotator_1to1_sptr ann0 (gr_make_annotator_1to1(10000, sizeof(int))); + gr_annotator_1to1_sptr ann1 (gr_make_annotator_1to1(10000, sizeof(int))); + gr_annotator_1to1_sptr ann2 (gr_make_annotator_1to1(10000, sizeof(int))); + gr_block_sptr snk0 (gr_make_null_sink(sizeof(int))); + gr_block_sptr snk1 (gr_make_null_sink(sizeof(int))); + + // using 1-to-1 tag propagation without having equal number of + // ins and outs. Make sure this works; will just exit run early. + tb->connect(src, 0, head, 0); + tb->connect(head, 0, ann0, 0); + tb->connect(ann0, 0, ann1, 0); + tb->connect(ann0, 1, ann2, 0); + tb->connect(ann1, 0, snk0, 0); + tb->connect(ann2, 0, snk1, 0); + + std::cerr << std::endl + << "NOTE: This is supposed to produce an error from gr_block_executor" + << std::endl; + tb->run(); +} + + +void +qa_block_tags::t5 () +{ + int N = 40000; + gr_top_block_sptr tb = gr_make_top_block("top"); + gr_block_sptr src (gr_make_null_source(sizeof(float))); + gr_block_sptr head (gr_make_head(sizeof(float), N)); + gr_annotator_alltoall_sptr ann0 (gr_make_annotator_alltoall(10000, sizeof(float))); + gr_annotator_alltoall_sptr ann1 (gr_make_annotator_alltoall(10000, sizeof(float))); + gr_annotator_alltoall_sptr ann2 (gr_make_annotator_alltoall(1000, sizeof(float))); + gr_block_sptr snk0 (gr_make_null_sink(sizeof(float))); + + // Rate change blocks + gr_keep_one_in_n_sptr dec10 (gr_make_keep_one_in_n(sizeof(float), 10)); + + tb->connect(src, 0, head, 0); + tb->connect(head, 0, ann0, 0); + tb->connect(ann0, 0, ann1, 0); + tb->connect(ann1, 0, dec10, 0); + tb->connect(dec10, 0, ann2, 0); + tb->connect(ann2, 0, snk0, 0); + + tb->run(); + + std::vector<pmt::pmt_t> tags0 = ann0->data(); + std::vector<pmt::pmt_t> tags1 = ann1->data(); + std::vector<pmt::pmt_t> tags2 = ann2->data(); + + // The first annotator does not receive any tags from the null sink upstream + CPPUNIT_ASSERT_EQUAL(tags0.size(), (size_t)0); + CPPUNIT_ASSERT_EQUAL(tags1.size(), (size_t)4); + CPPUNIT_ASSERT_EQUAL(tags2.size(), (size_t)8); + + +#if QA_TAGS_DEBUG + // Kludge together the tags that we know should result from the above graph + std::stringstream str0, str1, str2; + str0 << ann0->name() << ann0->unique_id(); + str1 << ann1->name() << ann1->unique_id(); + str2 << ann2->name() << ann2->unique_id(); + + pmt_t expected_tags1[5]; + expected_tags1[0] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags1[1] = mp(pmt_from_uint64(10000), mp(str0.str()), mp("seq"), mp(1)); + expected_tags1[2] = mp(pmt_from_uint64(20000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags1[3] = mp(pmt_from_uint64(30000), mp(str0.str()), mp("seq"), mp(3)); + + pmt_t expected_tags2[10]; + expected_tags2[0] = mp(pmt_from_uint64(0), mp(str1.str()), mp("seq"), mp(0)); + expected_tags2[1] = mp(pmt_from_uint64(0), mp(str0.str()), mp("seq"), mp(0)); + expected_tags2[2] = mp(pmt_from_uint64(1000), mp(str1.str()), mp("seq"), mp(1)); + expected_tags2[3] = mp(pmt_from_uint64(1000), mp(str0.str()), mp("seq"), mp(1)); + expected_tags2[4] = mp(pmt_from_uint64(2000), mp(str1.str()), mp("seq"), mp(2)); + expected_tags2[5] = mp(pmt_from_uint64(2000), mp(str0.str()), mp("seq"), mp(2)); + expected_tags2[6] = mp(pmt_from_uint64(3000), mp(str1.str()), mp("seq"), mp(3)); + expected_tags2[7] = mp(pmt_from_uint64(3000), mp(str0.str()), mp("seq"), mp(3)); + expected_tags2[8] = mp(pmt_from_uint64(4000), mp(str1.str()), mp("seq"), mp(4)); + expected_tags2[9] = mp(pmt_from_uint64(4000), mp(str0.str()), mp("seq"), mp(4)); + + std::cout << std::endl << "qa_block_tags::t5" << std::endl; + + // annotator 1 gets tags from annotator 0 + std::cout << "tags1.size(): " << tags1.size() << std::endl; + for(size_t i = 0; i < tags1.size(); i++) { + std::cout << "tags1[" << i << "] = " << tags1[i] << "\t\t" << expected_tags1[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags1[i]), pmt_write_string(expected_tags1[i])); + } + + // annotator 2 gets tags from annotators 0 and 1 + std::cout << std::endl; + std::cout << "tags2.size(): " << tags2.size() << std::endl; + for(size_t i = 0; i < tags2.size(); i++) { + std::cout << "tags2[" << i << "] = " << tags2[i] << "\t\t" << expected_tags2[i] << std::endl; + CPPUNIT_ASSERT_EQUAL(pmt_write_string(tags2[i]), pmt_write_string(expected_tags2[i])); + } +#endif +} + diff --git a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.i b/gnuradio-core/src/lib/runtime/qa_block_tags.h index 9a9f22b6e..b0d211390 100644 --- a/gnuradio-core/src/lib/general/gr_lms_dfe_cc.i +++ b/gnuradio-core/src/lib/runtime/qa_block_tags.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005 Free Software Foundation, Inc. + * Copyright 2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,18 +20,33 @@ * Boston, MA 02110-1301, USA. */ +#ifndef INCLUDED_QA_BLOCK_TAGS_H +#define INCLUDED_QA_BLOCK_TAGS_H -GR_SWIG_BLOCK_MAGIC(gr,lms_dfe_cc) +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> +#include <stdexcept> -gr_lms_dfe_cc_sptr gr_make_lms_dfe_cc (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps); +class qa_block_tags : public CppUnit::TestCase { + + CPPUNIT_TEST_SUITE (qa_block_tags); + CPPUNIT_TEST (t0); + CPPUNIT_TEST (t1); + CPPUNIT_TEST (t2); + CPPUNIT_TEST (t3); + CPPUNIT_TEST (t4); + CPPUNIT_TEST (t5); + CPPUNIT_TEST_SUITE_END (); -class gr_lms_dfe_cc : public gr_sync_block -{ private: - gr_lms_dfe_cc (float lambda_ff, float lambda_fb, - unsigned int num_fftaps, unsigned int num_fbtaps); - gr_complex slicer_0deg(gr_complex baud); - gr_complex slicer_45deg(gr_complex baud); - gr_complex conjg(gr_complex val); + void t0 (); + void t1 (); + void t2 (); + void t3 (); + void t4 (); + void t5 (); + }; + + +#endif /* INCLUDED_QA_BLOCK_TAGS_H */ diff --git a/gnuradio-core/src/lib/runtime/qa_runtime.cc b/gnuradio-core/src/lib/runtime/qa_runtime.cc index 31e3a82d6..c0bee8ea0 100644 --- a/gnuradio-core/src/lib/runtime/qa_runtime.cc +++ b/gnuradio-core/src/lib/runtime/qa_runtime.cc @@ -1,5 +1,5 @@ /* - * Copyright 2002,2007 Free Software Foundation, Inc. + * Copyright 2002,2007,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -38,6 +38,8 @@ #include <qa_gr_hier_block2.h> #include <qa_gr_hier_block2_derived.h> #include <qa_gr_buffer.h> +#include <qa_block_tags.h> +#include <qa_set_msg_handler.h> CppUnit::TestSuite * qa_runtime::suite () @@ -52,6 +54,8 @@ qa_runtime::suite () s->addTest (qa_gr_hier_block2::suite ()); s->addTest (qa_gr_hier_block2_derived::suite ()); s->addTest (qa_gr_buffer::suite ()); + s->addTest (qa_block_tags::suite ()); + s->addTest (qa_set_msg_handler::suite ()); return s; } diff --git a/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc new file mode 100644 index 000000000..35ef5527e --- /dev/null +++ b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.cc @@ -0,0 +1,85 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2011 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_set_msg_handler.h> +#include <gr_top_block.h> +#include <gr_head.h> +#include <gr_null_source.h> +#include <gr_null_sink.h> +#include <gr_nop.h> +#include <gruel/msg_passing.h> +#include <iostream> +#include <boost/thread/thread.hpp> + + +#define VERBOSE 0 + +using namespace pmt; + +/* + * The gr_nop block has been instrumented so that it counts + * the number of messages sent to it. We use this feature + * to confirm that gr_nop's call to set_msg_handler is working + * correctly. + */ + +void qa_set_msg_handler::t0() +{ + static const int NMSGS = 10; + + if (VERBOSE) std::cout << "qa_set_msg_handler::t0()\n"; + + gr_top_block_sptr tb = gr_make_top_block("top"); + + gr_block_sptr src = gr_make_null_source(sizeof(int)); + gr_nop_sptr nop = gr_make_nop(sizeof(int)); + gr_block_sptr dst = gr_make_null_sink(sizeof(int)); + + tb->connect(src, 0, nop, 0); + tb->connect(nop, 0, dst, 0); + + // Must start graph before sending messages + tb->start(); + + // Send them... + for (int i = 0; i < NMSGS; i++){ + send(nop, mp(mp("example-msg"), mp(i))); + } + + // And send a message to null_source to confirm that the default + // message handling action (which should be a nop) doesn't dump + // core. + send(src, mp(mp("example-msg"), mp(0))); + + // Give the messages a chance to be processed + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); + + tb->stop(); + tb->wait(); + + // Confirm that the nop block received the right number of messages. + CPPUNIT_ASSERT_EQUAL(NMSGS, nop->nmsgs_received()); +} diff --git a/gnuradio-core/src/lib/runtime/gr_tmp_path.cc b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.h index 1f0c830cd..e73fffbcd 100644 --- a/gnuradio-core/src/lib/runtime/gr_tmp_path.cc +++ b/gnuradio-core/src/lib/runtime/qa_set_msg_handler.h @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2003 Free Software Foundation, Inc. + * Copyright 2007,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -20,33 +20,24 @@ * Boston, MA 02110-1301, USA. */ -#include <gr_tmp_path.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> +#ifndef INCLUDED_QA_SET_MSG_HANDLER_H +#define INCLUDED_QA_SET_MSG_HANDLER_H -const char * -gr_tmp_path () -{ - static char *pp = 0; +#include <cppunit/extensions/HelperMacros.h> +#include <cppunit/TestCase.h> +#include <stdexcept> - if (pp) - return pp; +class qa_set_msg_handler : public CppUnit::TestCase +{ + CPPUNIT_TEST_SUITE(qa_set_msg_handler); + + CPPUNIT_TEST(t0); - char *s = getenv ("TMP"); - if (s){ - pp = strdup (s); - return pp; - } + CPPUNIT_TEST_SUITE_END(); -#ifdef P_tmpdir - if (P_tmpdir){ - pp = strdup (P_tmpdir); - return pp; - } -#endif +private: - pp = strdup ("/tmp"); - return pp; -} + void t0(); +}; +#endif /* INCLUDED_QA_SET_MSG_HANDLER_H */ diff --git a/gnuradio-core/src/lib/runtime/runtime.i b/gnuradio-core/src/lib/runtime/runtime.i index 20cf68a03..ca89b8fbd 100644 --- a/gnuradio-core/src/lib/runtime/runtime.i +++ b/gnuradio-core/src/lib/runtime/runtime.i @@ -40,6 +40,13 @@ #include <gr_top_block.h> %} +%constant int sizeof_char = sizeof(char); +%constant int sizeof_short = sizeof(short); +%constant int sizeof_int = sizeof(int); +%constant int sizeof_float = sizeof(float); +%constant int sizeof_double = sizeof(double); +%constant int sizeof_gr_complex = sizeof(gr_complex); + %include <gr_io_signature.i> %include <gr_buffer.i> %include <gr_basic_block.i> diff --git a/gnuradio-core/src/lib/swig/.gitignore b/gnuradio-core/src/lib/swig/.gitignore index 9d7d01056..a6f145618 100644 --- a/gnuradio-core/src/lib/swig/.gitignore +++ b/gnuradio-core/src/lib/swig/.gitignore @@ -10,27 +10,40 @@ /swigrun.py /swigrun_wrap.c /Makefile.swigdeps.new -/gnuradio_swig_py_runtime.d -/gnuradio_swig_py_general.d -/gnuradio_swig_py_gengen.d -/gnuradio_swig_py_filter.d -/gnuradio_swig_py_io.d -/gnuradio_swig_bug_workaround.h -/gnuradio_swig_py_runtime.cc -/gnuradio_swig_py_runtime.h -/gnuradio_swig_py_runtime.py -/gnuradio_swig_py_general.cc -/gnuradio_swig_py_general.h -/gnuradio_swig_py_general.py -/gnuradio_swig_py_gengen.cc -/gnuradio_swig_py_gengen.h -/gnuradio_swig_py_gengen.py -/gnuradio_swig_py_filter.cc -/gnuradio_swig_py_filter.h -/gnuradio_swig_py_filter.py -/gnuradio_swig_py_io.cc -/gnuradio_swig_py_io.h -/gnuradio_swig_py_io.py -/gnuradio_swig_py_hier.cc -/gnuradio_swig_py_hier.h -/gnuradio_swig_py_hier.py +gnuradio_core_filter.cc +gnuradio_core_filter.d +gnuradio_core_filter.h +gnuradio_core_filter.py +gnuradio_core_filter.scm +gnuradio_core_filter-primitive.scm +gnuradio_core_general.cc +gnuradio_core_general.d +gnuradio_core_general.h +gnuradio_core_general.py +gnuradio_core_general.scm +gnuradio_core_general-primitive.scm +gnuradio_core_gengen.cc +gnuradio_core_gengen.d +gnuradio_core_gengen.h +gnuradio_core_gengen.py +gnuradio_core_gengen.scm +gnuradio_core_gengen-primitive.scm +gnuradio_core_hier.cc +gnuradio_core_hier.d +gnuradio_core_hier.h +gnuradio_core_hier.py +gnuradio_core_hier.scm +gnuradio_core_hier-primitive.scm +gnuradio_core_io.cc +gnuradio_core_io.d +gnuradio_core_io.h +gnuradio_core_io.py +gnuradio_core_io.scm +gnuradio_core_io-primitive.scm +gnuradio_core_runtime.cc +gnuradio_core_runtime.d +gnuradio_core_runtime.h +gnuradio_core_runtime.py +gnuradio_core_runtime.scm +gnuradio_core_runtime-primitive.scm + diff --git a/gnuradio-core/src/lib/swig/Makefile.am b/gnuradio-core/src/lib/swig/Makefile.am index 1a50b8c8e..d304a2123 100644 --- a/gnuradio-core/src/lib/swig/Makefile.am +++ b/gnuradio-core/src/lib/swig/Makefile.am @@ -20,84 +20,72 @@ # include $(top_srcdir)/Makefile.common +include $(top_srcdir)/Makefile.swig -if PYTHON AM_CPPFLAGS = -I$(srcdir) $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) \ $(WITH_INCLUDES) -EXTRA_DIST = gen-swig-bug-fix +# ---------------------------------------------------------------- +# We've split the previously monstrous gnuradio_core into 6 +# smaller pieces. This reduces compile time coupling and creates +# smaller pieces for the compiler to digest. prior to this change, on +# X86_64, g++'s resident set size was 650MB! +# ---------------------------------------------------------------- + +TOP_SWIG_IFILES = \ + gnuradio_core_runtime.i \ + gnuradio_core_general.i \ + gnuradio_core_gengen.i \ + gnuradio_core_filter.i \ + gnuradio_core_io.i \ + gnuradio_core_hier.i + # SWIG headers get installed in ${prefix}/include/gnuradio/swig swiginclude_HEADERS = \ gnuradio.i \ gr_swig_block_magic.i \ - gr_shared_ptr.i + gr_shared_ptr.i + +# SWIG headers that get installed in ${prefix}/include/gnuradio/swig/... +nobase_swiginclude_HEADERS = \ + guile/std_complex.i \ + guile/std_vector.i + # special install for this top-level Python script which includes all # of the split Python libraries. ourpythondir = $(grpythondir)/gr -ourpython_PYTHON = gnuradio_swig_python.py +ourpython_PYTHON = gnuradio_core.py # ---------------------------------------------------------------- # FIXME As of swig 1.3.31, this still seems to be required... +# gnuradio_swig_bug_workaround.h : gnuradio_core_runtime.py $(srcdir)/gen-swig-bug-fix +# $(PYTHON) $(srcdir)/gen-swig-bug-fix python/gnuradio_core_runtime.cc $@ -gnuradio_swig_bug_workaround.h : gnuradio_swig_py_runtime.cc $(srcdir)/gen-swig-bug-fix - $(PYTHON) $(srcdir)/gen-swig-bug-fix gnuradio_swig_py_runtime.cc $@ +EXTRA_DIST += gen-swig-bug-fix # C/C++ headers get installed in ${prefix}/include/gnuradio -grinclude_HEADERS = \ - gnuradio_swig_bug_workaround.h +grinclude_HEADERS = gnuradio_swig_bug_workaround.h -# ---------------------------------------------------------------- -# We've split the previously monstrous gnuradio_swig_python into 6 -# smaller pieces. This reduces compile time coupling and creates -# smaller pieces for the compiler to digest. prior to this change, on -# X86_64, g++'s resident set size was 650MB! -# ---------------------------------------------------------------- - -TOP_SWIG_IFILES = \ - gnuradio_swig_py_runtime.i \ - gnuradio_swig_py_general.i \ - gnuradio_swig_py_gengen.i \ - gnuradio_swig_py_filter.i \ - gnuradio_swig_py_io.i \ - gnuradio_swig_py_hier.i # Install so that they end up available as: # import gnuradio.gr # This ends up at: # ${prefix}/lib/python${python_version}/site-packages/gnuradio/gr -gnuradio_swig_py_runtime_pythondir_category = gnuradio/gr -gnuradio_swig_py_general_pythondir_category = gnuradio/gr -gnuradio_swig_py_gengen_pythondir_category = gnuradio/gr -gnuradio_swig_py_filter_pythondir_category = gnuradio/gr -gnuradio_swig_py_io_pythondir_category = gnuradio/gr -gnuradio_swig_py_hier_pythondir_category = gnuradio/gr +gnuradio_core_runtime_pythondir_category = gnuradio/gr +gnuradio_core_general_pythondir_category = gnuradio/gr +gnuradio_core_gengen_pythondir_category = gnuradio/gr +gnuradio_core_filter_pythondir_category = gnuradio/gr +gnuradio_core_io_pythondir_category = gnuradio/gr +gnuradio_core_hier_pythondir_category = gnuradio/gr # additional libraries for linking with each SWIG-generated library -gnuradio_swig_py_runtime_la_swig_libadd = $(GNURADIO_CORE_LA) -gnuradio_swig_py_general_la_swig_libadd = $(GNURADIO_CORE_LA) -gnuradio_swig_py_gengen_la_swig_libadd = $(GNURADIO_CORE_LA) -gnuradio_swig_py_filter_la_swig_libadd = $(GNURADIO_CORE_LA) -gnuradio_swig_py_io_la_swig_libadd = $(GNURADIO_CORE_LA) -gnuradio_swig_py_hier_la_swig_libadd = $(GNURADIO_CORE_LA) - -include $(top_srcdir)/Makefile.swig - -# add some of the variables generated inside the Makefile.swig - -# include the SWIG-generated .h files in the BUILT SOURCES, since they -# aren't by default when using Makefile.swig; order doesn't matter. -BUILT_SOURCES = \ - gnuradio_swig_py_runtime.h \ - gnuradio_swig_py_general.h \ - gnuradio_swig_py_gengen.h \ - gnuradio_swig_py_filter.h \ - gnuradio_swig_py_io.h \ - gnuradio_swig_py_hier.h \ - $(grinclude_HEADERS) \ - $(swig_built_sources) - -# Do not distribute the output of SWIG -no_dist_files = $(swig_built_sources) -endif +gnuradio_core_runtime_la_swig_libadd = $(GNURADIO_CORE_LA) +gnuradio_core_general_la_swig_libadd = $(GNURADIO_CORE_LA) +gnuradio_core_gengen_la_swig_libadd = $(GNURADIO_CORE_LA) +gnuradio_core_filter_la_swig_libadd = $(GNURADIO_CORE_LA) +gnuradio_core_io_la_swig_libadd = $(GNURADIO_CORE_LA) +gnuradio_core_hier_la_swig_libadd = $(GNURADIO_CORE_LA) + +SWIG_GUILE_FLAGS += -DIN_GNURADIO_CORE diff --git a/gnuradio-core/src/lib/swig/Makefile.swig.gen b/gnuradio-core/src/lib/swig/Makefile.swig.gen index e24ba5a96..cede68817 100644 --- a/gnuradio-core/src/lib/swig/Makefile.swig.gen +++ b/gnuradio-core/src/lib/swig/Makefile.swig.gen @@ -20,27 +20,37 @@ # Boston, MA 02110-1301, USA. # -# Makefile.swig.gen for gnuradio_swig_py_runtime.i +# Makefile.swig.gen for gnuradio_core_runtime.i ## Default install locations for these files: ## ## Default location for the Python directory is: -## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_runtime +## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_runtime ## Default location for the Python exec directory is: -## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_runtime +## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_runtime ## ## The following can be overloaded to change the install location, but ## this has to be done in the including Makefile.am -before- ## Makefile.swig is included. -gnuradio_swig_py_runtime_pythondir_category ?= gnuradio/gnuradio_swig_py_runtime -gnuradio_swig_py_runtime_pylibdir_category ?= $(gnuradio_swig_py_runtime_pythondir_category) -gnuradio_swig_py_runtime_pythondir = $(pythondir)/$(gnuradio_swig_py_runtime_pythondir_category) -gnuradio_swig_py_runtime_pylibdir = $(pyexecdir)/$(gnuradio_swig_py_runtime_pylibdir_category) +gnuradio_core_runtime_pythondir_category ?= gnuradio/gnuradio_core_runtime +gnuradio_core_runtime_pylibdir_category ?= $(gnuradio_core_runtime_pythondir_category) +gnuradio_core_runtime_pythondir = $(pythondir)/$(gnuradio_core_runtime_pythondir_category) +gnuradio_core_runtime_pylibdir = $(pyexecdir)/$(gnuradio_core_runtime_pylibdir_category) + +# The .so libraries for the guile modules get installed whereever guile +# is installed, usually /usr/lib/guile/gnuradio/ +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_runtime_scmlibdir = $(libdir) + +# The scm files for the guile modules get installed where ever guile +# is installed, usually /usr/share/guile/site/gnuradio_core_runtime +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_runtime_scmdir = $(guiledir) ## SWIG headers are always installed into the same directory. -gnuradio_swig_py_runtime_swigincludedir = $(swigincludedir) +gnuradio_core_runtime_swigincludedir = $(swigincludedir) ## This is a template file for a "generated" Makefile addition (in ## this case, "Makefile.swig.gen"). By including the top-level @@ -57,205 +67,81 @@ gnuradio_swig_py_runtime_swigincludedir = $(swigincludedir) ## right thing. For more info, see < ## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > -## Stamps used to ensure parallel make does the right thing. These -## are removed by "make clean", but otherwise unused except during the -## parallel built. These will not be included in a tarball, because -## the SWIG-generated files will be removed from the distribution. - -STAMPS += $(DEPDIR)/gnuradio_swig_py_runtime-generate-* - ## Other cleaned files: dependency files generated by SWIG or this Makefile MOSTLYCLEANFILES += $(DEPDIR)/*.S* -## Add the .py and .cc files to the list of SWIG built sources. The -## .h file is sometimes built, but not always ... so that one has to -## be added manually by the including Makefile.am . - -swig_built_sources += gnuradio_swig_py_runtime.py gnuradio_swig_py_runtime.cc - ## Various SWIG variables. These can be overloaded in the including ## Makefile.am by setting the variable value there, then including ## Makefile.swig . -gnuradio_swig_py_runtime_swiginclude_HEADERS = \ - gnuradio_swig_py_runtime.i \ - $(gnuradio_swig_py_runtime_swiginclude_headers) +gnuradio_core_runtime_swiginclude_HEADERS = \ + gnuradio_core_runtime.i \ + $(gnuradio_core_runtime_swiginclude_headers) + +if PYTHON +gnuradio_core_runtime_pylib_LTLIBRARIES = \ + _gnuradio_core_runtime.la -gnuradio_swig_py_runtime_pylib_LTLIBRARIES = \ - _gnuradio_swig_py_runtime.la +_gnuradio_core_runtime_la_SOURCES = \ + python/gnuradio_core_runtime.cc \ + $(gnuradio_core_runtime_la_swig_sources) -_gnuradio_swig_py_runtime_la_SOURCES = \ - gnuradio_swig_py_runtime.cc \ - $(gnuradio_swig_py_runtime_la_swig_sources) +gnuradio_core_runtime_python_PYTHON = \ + gnuradio_core_runtime.py \ + $(gnuradio_core_runtime_python) -_gnuradio_swig_py_runtime_la_LIBADD = \ +_gnuradio_core_runtime_la_LIBADD = \ $(STD_SWIG_LA_LIB_ADD) \ - $(gnuradio_swig_py_runtime_la_swig_libadd) + $(gnuradio_core_runtime_la_swig_libadd) -_gnuradio_swig_py_runtime_la_LDFLAGS = \ +_gnuradio_core_runtime_la_LDFLAGS = \ $(STD_SWIG_LA_LD_FLAGS) \ - $(gnuradio_swig_py_runtime_la_swig_ldflags) + $(gnuradio_core_runtime_la_swig_ldflags) -_gnuradio_swig_py_runtime_la_CXXFLAGS = \ +_gnuradio_core_runtime_la_CXXFLAGS = \ $(STD_SWIG_CXX_FLAGS) \ - $(gnuradio_swig_py_runtime_la_swig_cxxflags) + -I$(top_builddir) \ + $(gnuradio_core_runtime_la_swig_cxxflags) -gnuradio_swig_py_runtime_python_PYTHON = \ - gnuradio_swig_py_runtime.py \ - $(gnuradio_swig_py_runtime_python) +python/gnuradio_core_runtime.cc: gnuradio_core_runtime.py +gnuradio_core_runtime.py: gnuradio_core_runtime.i -## Entry rule for running SWIG +# Include the python dependencies for this file +-include python/gnuradio_core_runtime.d -gnuradio_swig_py_runtime.h gnuradio_swig_py_runtime.py gnuradio_swig_py_runtime.cc: gnuradio_swig_py_runtime.i -## This rule will get called only when MAKE decides that one of the -## targets needs to be created or re-created, because: -## -## * The .i file is newer than any or all of the generated files; -## -## * Any or all of the .cc, .h, or .py files does not exist and is -## needed (in the case this file is not needed, the rule for it is -## ignored); or -## -## * Some SWIG-based dependecy of the .cc file isn't met and hence the -## .cc file needs be be regenerated. Explanation: Because MAKE -## knows how to handle dependencies for .cc files (regardless of -## their name or extension), then the .cc file is used as a target -## instead of the .i file -- but with the dependencies of the .i -## file. It is this last reason why the line: -## -## if test -f $@; then :; else -## -## cannot be used in this case: If a .i file dependecy is not met, -## then the .cc file needs to be rebuilt. But if the stamp is newer -## than the .cc file, and the .cc file exists, then in the original -## version (with the 'test' above) the internal MAKE call will not -## be issued and hence the .cc file will not be rebuilt. -## -## Once execution gets to here, it should always proceed no matter the -## state of a stamp (as discussed in link above). The -## $(DEPDIR)/gnuradio_swig_py_runtime-generate stuff is used to allow for parallel -## builds to "do the right thing". The stamp has no relationship with -## either the target files or dependency file; it is used solely for -## the protection of multiple builds during a given call to MAKE. -## -## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM -## (15). At a caught signal, the quoted command will be issued before -## exiting. In this case, remove any stamp, whether temporary of not. -## The trap is valid until the process exits; the process includes all -## commands appended via "\"s. -## - trap 'rm -rf $(DEPDIR)/gnuradio_swig_py_runtime-generate-*' 1 2 13 15; \ -## -## Create a temporary directory, which acts as a lock. The first -## process to create the directory will succeed and issue the MAKE -## command to do the actual work, while all subsequent processes will -## fail -- leading them to wait for the first process to finish. -## - if mkdir $(DEPDIR)/gnuradio_swig_py_runtime-generate-lock 2>/dev/null; then \ -## -## This code is being executed by the first process to succeed in -## creating the directory lock. -## -## Remove the stamp associated with this filename. -## - rm -f $(DEPDIR)/gnuradio_swig_py_runtime-generate-stamp; \ -## -## Tell MAKE to run the rule for creating this stamp. -## - $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/gnuradio_swig_py_runtime-generate-stamp WHAT=$<; \ -## -## Now that the .cc, .h, and .py files have been (re)created from the -## .i file, future checking of this rule during the same MAKE -## execution will come back that the rule doesn't need to be executed -## because none of the conditions mentioned at the start of this rule -## will be positive. Remove the the directory lock, which frees up -## any waiting process(es) to continue. -## - rmdir $(DEPDIR)/gnuradio_swig_py_runtime-generate-lock; \ - else \ -## -## This code is being executed by any follower processes while the -## directory lock is in place. -## -## Wait until the first process is done, testing once per second. -## - while test -d $(DEPDIR)/gnuradio_swig_py_runtime-generate-lock; do \ - sleep 1; \ - done; \ -## -## Succeed if and only if the first process succeeded; exit this -## process returning the status of the generated stamp. -## - test -f $(DEPDIR)/gnuradio_swig_py_runtime-generate-stamp; \ - exit $$?; \ - fi; - -$(DEPDIR)/gnuradio_swig_py_runtime-generate-stamp: -## This rule will be called only by the first process issuing the -## above rule to succeed in creating the lock directory, after -## removing the actual stamp file in order to guarantee that MAKE will -## execute this rule. -## -## Call SWIG to generate the various output files; special -## post-processing on 'mingw32' host OS for the dependency file. -## - if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(gnuradio_swig_py_runtime_swig_args) \ - -MD -MF $(DEPDIR)/gnuradio_swig_py_runtime.Std \ - -module gnuradio_swig_py_runtime -o gnuradio_swig_py_runtime.cc $(WHAT); then \ - if test $(host_os) = mingw32; then \ - $(RM) $(DEPDIR)/gnuradio_swig_py_runtime.Sd; \ - $(SED) 's,\\\\,/,g' < $(DEPDIR)/gnuradio_swig_py_runtime.Std \ - > $(DEPDIR)/gnuradio_swig_py_runtime.Sd; \ - $(RM) $(DEPDIR)/gnuradio_swig_py_runtime.Std; \ - $(MV) $(DEPDIR)/gnuradio_swig_py_runtime.Sd $(DEPDIR)/gnuradio_swig_py_runtime.Std; \ - fi; \ - else \ - $(RM) $(DEPDIR)/gnuradio_swig_py_runtime.S*; exit 1; \ - fi; -## -## Mess with the SWIG output .Std dependency file, to create a -## dependecy file valid for the input .i file: Basically, simulate the -## dependency file created for libraries by GNU's libtool for C++, -## where all of the dependencies for the target are first listed, then -## each individual dependency is listed as a target with no further -## dependencies. -## -## (1) remove the current dependency file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_runtime.d -## -## (2) Copy the whole SWIG file: -## - cp $(DEPDIR)/gnuradio_swig_py_runtime.Std $(DEPDIR)/gnuradio_swig_py_runtime.d -## -## (3) all a carriage return to the end of the dependency file. -## - echo "" >> $(DEPDIR)/gnuradio_swig_py_runtime.d -## -## (4) from the SWIG file, remove the first line (the target); remove -## trailing " \" and " " from each line. Append ":" to each line, -## followed by 2 carriage returns, then append this to the end of -## the dependency file. -## - $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/gnuradio_swig_py_runtime.Std | \ - awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/gnuradio_swig_py_runtime.d -## -## (5) remove the SWIG-generated file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_runtime.Std -## -## Create the stamp for this filename generation, to signal success in -## executing this rule; allows other threads waiting on this process -## to continue. -## - touch $(DEPDIR)/gnuradio_swig_py_runtime-generate-stamp +endif # end of if python + +if GUILE + +gnuradio_core_runtime_scmlib_LTLIBRARIES = \ + libguile-gnuradio-gnuradio_core_runtime.la +libguile_gnuradio_gnuradio_core_runtime_la_SOURCES = \ + guile/gnuradio_core_runtime.cc \ + $(gnuradio_core_runtime_la_swig_sources) +nobase_gnuradio_core_runtime_scm_DATA = \ + gnuradio/gnuradio_core_runtime.scm \ + gnuradio/gnuradio_core_runtime-primitive.scm +libguile_gnuradio_gnuradio_core_runtime_la_LIBADD = \ + $(STD_SWIG_LA_LIB_ADD) \ + $(gnuradio_core_runtime_la_swig_libadd) +libguile_gnuradio_gnuradio_core_runtime_la_LDFLAGS = \ + $(STD_SWIG_LA_LD_FLAGS) \ + $(gnuradio_core_runtime_la_swig_ldflags) +libguile_gnuradio_gnuradio_core_runtime_la_CXXFLAGS = \ + $(STD_SWIG_CXX_FLAGS) \ + -I$(top_builddir) \ + $(gnuradio_core_runtime_la_swig_cxxflags) -# KLUDGE: Force runtime include of a SWIG dependency file. This is -# not guaranteed to be portable, but will probably work. If it works, -# we have accurate dependencies for our swig stuff, which is good. +guile/gnuradio_core_runtime.cc: gnuradio/gnuradio_core_runtime.scm +gnuradio/gnuradio_core_runtime.scm: gnuradio_core_runtime.i +gnuradio/gnuradio_core_runtime-primitive.scm: gnuradio/gnuradio_core_runtime.scm + +# Include the guile dependencies for this file +-include guile/gnuradio_core_runtime.d + +endif # end of GUILE -@am__include@ @am__quote@./$(DEPDIR)/gnuradio_swig_py_runtime.d@am__quote@ # -*- Makefile -*- # @@ -279,27 +165,37 @@ $(DEPDIR)/gnuradio_swig_py_runtime-generate-stamp: # Boston, MA 02110-1301, USA. # -# Makefile.swig.gen for gnuradio_swig_py_general.i +# Makefile.swig.gen for gnuradio_core_general.i ## Default install locations for these files: ## ## Default location for the Python directory is: -## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_general +## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_general ## Default location for the Python exec directory is: -## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_general +## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_general ## ## The following can be overloaded to change the install location, but ## this has to be done in the including Makefile.am -before- ## Makefile.swig is included. -gnuradio_swig_py_general_pythondir_category ?= gnuradio/gnuradio_swig_py_general -gnuradio_swig_py_general_pylibdir_category ?= $(gnuradio_swig_py_general_pythondir_category) -gnuradio_swig_py_general_pythondir = $(pythondir)/$(gnuradio_swig_py_general_pythondir_category) -gnuradio_swig_py_general_pylibdir = $(pyexecdir)/$(gnuradio_swig_py_general_pylibdir_category) +gnuradio_core_general_pythondir_category ?= gnuradio/gnuradio_core_general +gnuradio_core_general_pylibdir_category ?= $(gnuradio_core_general_pythondir_category) +gnuradio_core_general_pythondir = $(pythondir)/$(gnuradio_core_general_pythondir_category) +gnuradio_core_general_pylibdir = $(pyexecdir)/$(gnuradio_core_general_pylibdir_category) + +# The .so libraries for the guile modules get installed whereever guile +# is installed, usually /usr/lib/guile/gnuradio/ +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_general_scmlibdir = $(libdir) + +# The scm files for the guile modules get installed where ever guile +# is installed, usually /usr/share/guile/site/gnuradio_core_general +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_general_scmdir = $(guiledir) ## SWIG headers are always installed into the same directory. -gnuradio_swig_py_general_swigincludedir = $(swigincludedir) +gnuradio_core_general_swigincludedir = $(swigincludedir) ## This is a template file for a "generated" Makefile addition (in ## this case, "Makefile.swig.gen"). By including the top-level @@ -316,205 +212,81 @@ gnuradio_swig_py_general_swigincludedir = $(swigincludedir) ## right thing. For more info, see < ## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > -## Stamps used to ensure parallel make does the right thing. These -## are removed by "make clean", but otherwise unused except during the -## parallel built. These will not be included in a tarball, because -## the SWIG-generated files will be removed from the distribution. - -STAMPS += $(DEPDIR)/gnuradio_swig_py_general-generate-* - ## Other cleaned files: dependency files generated by SWIG or this Makefile MOSTLYCLEANFILES += $(DEPDIR)/*.S* -## Add the .py and .cc files to the list of SWIG built sources. The -## .h file is sometimes built, but not always ... so that one has to -## be added manually by the including Makefile.am . - -swig_built_sources += gnuradio_swig_py_general.py gnuradio_swig_py_general.cc - ## Various SWIG variables. These can be overloaded in the including ## Makefile.am by setting the variable value there, then including ## Makefile.swig . -gnuradio_swig_py_general_swiginclude_HEADERS = \ - gnuradio_swig_py_general.i \ - $(gnuradio_swig_py_general_swiginclude_headers) +gnuradio_core_general_swiginclude_HEADERS = \ + gnuradio_core_general.i \ + $(gnuradio_core_general_swiginclude_headers) + +if PYTHON +gnuradio_core_general_pylib_LTLIBRARIES = \ + _gnuradio_core_general.la -gnuradio_swig_py_general_pylib_LTLIBRARIES = \ - _gnuradio_swig_py_general.la +_gnuradio_core_general_la_SOURCES = \ + python/gnuradio_core_general.cc \ + $(gnuradio_core_general_la_swig_sources) -_gnuradio_swig_py_general_la_SOURCES = \ - gnuradio_swig_py_general.cc \ - $(gnuradio_swig_py_general_la_swig_sources) +gnuradio_core_general_python_PYTHON = \ + gnuradio_core_general.py \ + $(gnuradio_core_general_python) -_gnuradio_swig_py_general_la_LIBADD = \ +_gnuradio_core_general_la_LIBADD = \ $(STD_SWIG_LA_LIB_ADD) \ - $(gnuradio_swig_py_general_la_swig_libadd) + $(gnuradio_core_general_la_swig_libadd) -_gnuradio_swig_py_general_la_LDFLAGS = \ +_gnuradio_core_general_la_LDFLAGS = \ $(STD_SWIG_LA_LD_FLAGS) \ - $(gnuradio_swig_py_general_la_swig_ldflags) + $(gnuradio_core_general_la_swig_ldflags) -_gnuradio_swig_py_general_la_CXXFLAGS = \ +_gnuradio_core_general_la_CXXFLAGS = \ $(STD_SWIG_CXX_FLAGS) \ - $(gnuradio_swig_py_general_la_swig_cxxflags) + -I$(top_builddir) \ + $(gnuradio_core_general_la_swig_cxxflags) -gnuradio_swig_py_general_python_PYTHON = \ - gnuradio_swig_py_general.py \ - $(gnuradio_swig_py_general_python) +python/gnuradio_core_general.cc: gnuradio_core_general.py +gnuradio_core_general.py: gnuradio_core_general.i -## Entry rule for running SWIG +# Include the python dependencies for this file +-include python/gnuradio_core_general.d -gnuradio_swig_py_general.h gnuradio_swig_py_general.py gnuradio_swig_py_general.cc: gnuradio_swig_py_general.i -## This rule will get called only when MAKE decides that one of the -## targets needs to be created or re-created, because: -## -## * The .i file is newer than any or all of the generated files; -## -## * Any or all of the .cc, .h, or .py files does not exist and is -## needed (in the case this file is not needed, the rule for it is -## ignored); or -## -## * Some SWIG-based dependecy of the .cc file isn't met and hence the -## .cc file needs be be regenerated. Explanation: Because MAKE -## knows how to handle dependencies for .cc files (regardless of -## their name or extension), then the .cc file is used as a target -## instead of the .i file -- but with the dependencies of the .i -## file. It is this last reason why the line: -## -## if test -f $@; then :; else -## -## cannot be used in this case: If a .i file dependecy is not met, -## then the .cc file needs to be rebuilt. But if the stamp is newer -## than the .cc file, and the .cc file exists, then in the original -## version (with the 'test' above) the internal MAKE call will not -## be issued and hence the .cc file will not be rebuilt. -## -## Once execution gets to here, it should always proceed no matter the -## state of a stamp (as discussed in link above). The -## $(DEPDIR)/gnuradio_swig_py_general-generate stuff is used to allow for parallel -## builds to "do the right thing". The stamp has no relationship with -## either the target files or dependency file; it is used solely for -## the protection of multiple builds during a given call to MAKE. -## -## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM -## (15). At a caught signal, the quoted command will be issued before -## exiting. In this case, remove any stamp, whether temporary of not. -## The trap is valid until the process exits; the process includes all -## commands appended via "\"s. -## - trap 'rm -rf $(DEPDIR)/gnuradio_swig_py_general-generate-*' 1 2 13 15; \ -## -## Create a temporary directory, which acts as a lock. The first -## process to create the directory will succeed and issue the MAKE -## command to do the actual work, while all subsequent processes will -## fail -- leading them to wait for the first process to finish. -## - if mkdir $(DEPDIR)/gnuradio_swig_py_general-generate-lock 2>/dev/null; then \ -## -## This code is being executed by the first process to succeed in -## creating the directory lock. -## -## Remove the stamp associated with this filename. -## - rm -f $(DEPDIR)/gnuradio_swig_py_general-generate-stamp; \ -## -## Tell MAKE to run the rule for creating this stamp. -## - $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/gnuradio_swig_py_general-generate-stamp WHAT=$<; \ -## -## Now that the .cc, .h, and .py files have been (re)created from the -## .i file, future checking of this rule during the same MAKE -## execution will come back that the rule doesn't need to be executed -## because none of the conditions mentioned at the start of this rule -## will be positive. Remove the the directory lock, which frees up -## any waiting process(es) to continue. -## - rmdir $(DEPDIR)/gnuradio_swig_py_general-generate-lock; \ - else \ -## -## This code is being executed by any follower processes while the -## directory lock is in place. -## -## Wait until the first process is done, testing once per second. -## - while test -d $(DEPDIR)/gnuradio_swig_py_general-generate-lock; do \ - sleep 1; \ - done; \ -## -## Succeed if and only if the first process succeeded; exit this -## process returning the status of the generated stamp. -## - test -f $(DEPDIR)/gnuradio_swig_py_general-generate-stamp; \ - exit $$?; \ - fi; - -$(DEPDIR)/gnuradio_swig_py_general-generate-stamp: -## This rule will be called only by the first process issuing the -## above rule to succeed in creating the lock directory, after -## removing the actual stamp file in order to guarantee that MAKE will -## execute this rule. -## -## Call SWIG to generate the various output files; special -## post-processing on 'mingw32' host OS for the dependency file. -## - if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(gnuradio_swig_py_general_swig_args) \ - -MD -MF $(DEPDIR)/gnuradio_swig_py_general.Std \ - -module gnuradio_swig_py_general -o gnuradio_swig_py_general.cc $(WHAT); then \ - if test $(host_os) = mingw32; then \ - $(RM) $(DEPDIR)/gnuradio_swig_py_general.Sd; \ - $(SED) 's,\\\\,/,g' < $(DEPDIR)/gnuradio_swig_py_general.Std \ - > $(DEPDIR)/gnuradio_swig_py_general.Sd; \ - $(RM) $(DEPDIR)/gnuradio_swig_py_general.Std; \ - $(MV) $(DEPDIR)/gnuradio_swig_py_general.Sd $(DEPDIR)/gnuradio_swig_py_general.Std; \ - fi; \ - else \ - $(RM) $(DEPDIR)/gnuradio_swig_py_general.S*; exit 1; \ - fi; -## -## Mess with the SWIG output .Std dependency file, to create a -## dependecy file valid for the input .i file: Basically, simulate the -## dependency file created for libraries by GNU's libtool for C++, -## where all of the dependencies for the target are first listed, then -## each individual dependency is listed as a target with no further -## dependencies. -## -## (1) remove the current dependency file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_general.d -## -## (2) Copy the whole SWIG file: -## - cp $(DEPDIR)/gnuradio_swig_py_general.Std $(DEPDIR)/gnuradio_swig_py_general.d -## -## (3) all a carriage return to the end of the dependency file. -## - echo "" >> $(DEPDIR)/gnuradio_swig_py_general.d -## -## (4) from the SWIG file, remove the first line (the target); remove -## trailing " \" and " " from each line. Append ":" to each line, -## followed by 2 carriage returns, then append this to the end of -## the dependency file. -## - $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/gnuradio_swig_py_general.Std | \ - awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/gnuradio_swig_py_general.d -## -## (5) remove the SWIG-generated file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_general.Std -## -## Create the stamp for this filename generation, to signal success in -## executing this rule; allows other threads waiting on this process -## to continue. -## - touch $(DEPDIR)/gnuradio_swig_py_general-generate-stamp +endif # end of if python + +if GUILE -# KLUDGE: Force runtime include of a SWIG dependency file. This is -# not guaranteed to be portable, but will probably work. If it works, -# we have accurate dependencies for our swig stuff, which is good. +gnuradio_core_general_scmlib_LTLIBRARIES = \ + libguile-gnuradio-gnuradio_core_general.la +libguile_gnuradio_gnuradio_core_general_la_SOURCES = \ + guile/gnuradio_core_general.cc \ + $(gnuradio_core_general_la_swig_sources) +nobase_gnuradio_core_general_scm_DATA = \ + gnuradio/gnuradio_core_general.scm \ + gnuradio/gnuradio_core_general-primitive.scm +libguile_gnuradio_gnuradio_core_general_la_LIBADD = \ + $(STD_SWIG_LA_LIB_ADD) \ + $(gnuradio_core_general_la_swig_libadd) +libguile_gnuradio_gnuradio_core_general_la_LDFLAGS = \ + $(STD_SWIG_LA_LD_FLAGS) \ + $(gnuradio_core_general_la_swig_ldflags) +libguile_gnuradio_gnuradio_core_general_la_CXXFLAGS = \ + $(STD_SWIG_CXX_FLAGS) \ + -I$(top_builddir) \ + $(gnuradio_core_general_la_swig_cxxflags) + +guile/gnuradio_core_general.cc: gnuradio/gnuradio_core_general.scm +gnuradio/gnuradio_core_general.scm: gnuradio_core_general.i +gnuradio/gnuradio_core_general-primitive.scm: gnuradio/gnuradio_core_general.scm + +# Include the guile dependencies for this file +-include guile/gnuradio_core_general.d + +endif # end of GUILE -@am__include@ @am__quote@./$(DEPDIR)/gnuradio_swig_py_general.d@am__quote@ # -*- Makefile -*- # @@ -538,27 +310,37 @@ $(DEPDIR)/gnuradio_swig_py_general-generate-stamp: # Boston, MA 02110-1301, USA. # -# Makefile.swig.gen for gnuradio_swig_py_gengen.i +# Makefile.swig.gen for gnuradio_core_gengen.i ## Default install locations for these files: ## ## Default location for the Python directory is: -## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_gengen +## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_gengen ## Default location for the Python exec directory is: -## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_gengen +## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_gengen ## ## The following can be overloaded to change the install location, but ## this has to be done in the including Makefile.am -before- ## Makefile.swig is included. -gnuradio_swig_py_gengen_pythondir_category ?= gnuradio/gnuradio_swig_py_gengen -gnuradio_swig_py_gengen_pylibdir_category ?= $(gnuradio_swig_py_gengen_pythondir_category) -gnuradio_swig_py_gengen_pythondir = $(pythondir)/$(gnuradio_swig_py_gengen_pythondir_category) -gnuradio_swig_py_gengen_pylibdir = $(pyexecdir)/$(gnuradio_swig_py_gengen_pylibdir_category) +gnuradio_core_gengen_pythondir_category ?= gnuradio/gnuradio_core_gengen +gnuradio_core_gengen_pylibdir_category ?= $(gnuradio_core_gengen_pythondir_category) +gnuradio_core_gengen_pythondir = $(pythondir)/$(gnuradio_core_gengen_pythondir_category) +gnuradio_core_gengen_pylibdir = $(pyexecdir)/$(gnuradio_core_gengen_pylibdir_category) + +# The .so libraries for the guile modules get installed whereever guile +# is installed, usually /usr/lib/guile/gnuradio/ +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_gengen_scmlibdir = $(libdir) + +# The scm files for the guile modules get installed where ever guile +# is installed, usually /usr/share/guile/site/gnuradio_core_gengen +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_gengen_scmdir = $(guiledir) ## SWIG headers are always installed into the same directory. -gnuradio_swig_py_gengen_swigincludedir = $(swigincludedir) +gnuradio_core_gengen_swigincludedir = $(swigincludedir) ## This is a template file for a "generated" Makefile addition (in ## this case, "Makefile.swig.gen"). By including the top-level @@ -575,205 +357,81 @@ gnuradio_swig_py_gengen_swigincludedir = $(swigincludedir) ## right thing. For more info, see < ## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > -## Stamps used to ensure parallel make does the right thing. These -## are removed by "make clean", but otherwise unused except during the -## parallel built. These will not be included in a tarball, because -## the SWIG-generated files will be removed from the distribution. - -STAMPS += $(DEPDIR)/gnuradio_swig_py_gengen-generate-* - ## Other cleaned files: dependency files generated by SWIG or this Makefile MOSTLYCLEANFILES += $(DEPDIR)/*.S* -## Add the .py and .cc files to the list of SWIG built sources. The -## .h file is sometimes built, but not always ... so that one has to -## be added manually by the including Makefile.am . - -swig_built_sources += gnuradio_swig_py_gengen.py gnuradio_swig_py_gengen.cc - ## Various SWIG variables. These can be overloaded in the including ## Makefile.am by setting the variable value there, then including ## Makefile.swig . -gnuradio_swig_py_gengen_swiginclude_HEADERS = \ - gnuradio_swig_py_gengen.i \ - $(gnuradio_swig_py_gengen_swiginclude_headers) +gnuradio_core_gengen_swiginclude_HEADERS = \ + gnuradio_core_gengen.i \ + $(gnuradio_core_gengen_swiginclude_headers) + +if PYTHON +gnuradio_core_gengen_pylib_LTLIBRARIES = \ + _gnuradio_core_gengen.la -gnuradio_swig_py_gengen_pylib_LTLIBRARIES = \ - _gnuradio_swig_py_gengen.la +_gnuradio_core_gengen_la_SOURCES = \ + python/gnuradio_core_gengen.cc \ + $(gnuradio_core_gengen_la_swig_sources) -_gnuradio_swig_py_gengen_la_SOURCES = \ - gnuradio_swig_py_gengen.cc \ - $(gnuradio_swig_py_gengen_la_swig_sources) +gnuradio_core_gengen_python_PYTHON = \ + gnuradio_core_gengen.py \ + $(gnuradio_core_gengen_python) -_gnuradio_swig_py_gengen_la_LIBADD = \ +_gnuradio_core_gengen_la_LIBADD = \ $(STD_SWIG_LA_LIB_ADD) \ - $(gnuradio_swig_py_gengen_la_swig_libadd) + $(gnuradio_core_gengen_la_swig_libadd) -_gnuradio_swig_py_gengen_la_LDFLAGS = \ +_gnuradio_core_gengen_la_LDFLAGS = \ $(STD_SWIG_LA_LD_FLAGS) \ - $(gnuradio_swig_py_gengen_la_swig_ldflags) + $(gnuradio_core_gengen_la_swig_ldflags) -_gnuradio_swig_py_gengen_la_CXXFLAGS = \ +_gnuradio_core_gengen_la_CXXFLAGS = \ $(STD_SWIG_CXX_FLAGS) \ - $(gnuradio_swig_py_gengen_la_swig_cxxflags) + -I$(top_builddir) \ + $(gnuradio_core_gengen_la_swig_cxxflags) -gnuradio_swig_py_gengen_python_PYTHON = \ - gnuradio_swig_py_gengen.py \ - $(gnuradio_swig_py_gengen_python) +python/gnuradio_core_gengen.cc: gnuradio_core_gengen.py +gnuradio_core_gengen.py: gnuradio_core_gengen.i -## Entry rule for running SWIG +# Include the python dependencies for this file +-include python/gnuradio_core_gengen.d -gnuradio_swig_py_gengen.h gnuradio_swig_py_gengen.py gnuradio_swig_py_gengen.cc: gnuradio_swig_py_gengen.i -## This rule will get called only when MAKE decides that one of the -## targets needs to be created or re-created, because: -## -## * The .i file is newer than any or all of the generated files; -## -## * Any or all of the .cc, .h, or .py files does not exist and is -## needed (in the case this file is not needed, the rule for it is -## ignored); or -## -## * Some SWIG-based dependecy of the .cc file isn't met and hence the -## .cc file needs be be regenerated. Explanation: Because MAKE -## knows how to handle dependencies for .cc files (regardless of -## their name or extension), then the .cc file is used as a target -## instead of the .i file -- but with the dependencies of the .i -## file. It is this last reason why the line: -## -## if test -f $@; then :; else -## -## cannot be used in this case: If a .i file dependecy is not met, -## then the .cc file needs to be rebuilt. But if the stamp is newer -## than the .cc file, and the .cc file exists, then in the original -## version (with the 'test' above) the internal MAKE call will not -## be issued and hence the .cc file will not be rebuilt. -## -## Once execution gets to here, it should always proceed no matter the -## state of a stamp (as discussed in link above). The -## $(DEPDIR)/gnuradio_swig_py_gengen-generate stuff is used to allow for parallel -## builds to "do the right thing". The stamp has no relationship with -## either the target files or dependency file; it is used solely for -## the protection of multiple builds during a given call to MAKE. -## -## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM -## (15). At a caught signal, the quoted command will be issued before -## exiting. In this case, remove any stamp, whether temporary of not. -## The trap is valid until the process exits; the process includes all -## commands appended via "\"s. -## - trap 'rm -rf $(DEPDIR)/gnuradio_swig_py_gengen-generate-*' 1 2 13 15; \ -## -## Create a temporary directory, which acts as a lock. The first -## process to create the directory will succeed and issue the MAKE -## command to do the actual work, while all subsequent processes will -## fail -- leading them to wait for the first process to finish. -## - if mkdir $(DEPDIR)/gnuradio_swig_py_gengen-generate-lock 2>/dev/null; then \ -## -## This code is being executed by the first process to succeed in -## creating the directory lock. -## -## Remove the stamp associated with this filename. -## - rm -f $(DEPDIR)/gnuradio_swig_py_gengen-generate-stamp; \ -## -## Tell MAKE to run the rule for creating this stamp. -## - $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/gnuradio_swig_py_gengen-generate-stamp WHAT=$<; \ -## -## Now that the .cc, .h, and .py files have been (re)created from the -## .i file, future checking of this rule during the same MAKE -## execution will come back that the rule doesn't need to be executed -## because none of the conditions mentioned at the start of this rule -## will be positive. Remove the the directory lock, which frees up -## any waiting process(es) to continue. -## - rmdir $(DEPDIR)/gnuradio_swig_py_gengen-generate-lock; \ - else \ -## -## This code is being executed by any follower processes while the -## directory lock is in place. -## -## Wait until the first process is done, testing once per second. -## - while test -d $(DEPDIR)/gnuradio_swig_py_gengen-generate-lock; do \ - sleep 1; \ - done; \ -## -## Succeed if and only if the first process succeeded; exit this -## process returning the status of the generated stamp. -## - test -f $(DEPDIR)/gnuradio_swig_py_gengen-generate-stamp; \ - exit $$?; \ - fi; - -$(DEPDIR)/gnuradio_swig_py_gengen-generate-stamp: -## This rule will be called only by the first process issuing the -## above rule to succeed in creating the lock directory, after -## removing the actual stamp file in order to guarantee that MAKE will -## execute this rule. -## -## Call SWIG to generate the various output files; special -## post-processing on 'mingw32' host OS for the dependency file. -## - if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(gnuradio_swig_py_gengen_swig_args) \ - -MD -MF $(DEPDIR)/gnuradio_swig_py_gengen.Std \ - -module gnuradio_swig_py_gengen -o gnuradio_swig_py_gengen.cc $(WHAT); then \ - if test $(host_os) = mingw32; then \ - $(RM) $(DEPDIR)/gnuradio_swig_py_gengen.Sd; \ - $(SED) 's,\\\\,/,g' < $(DEPDIR)/gnuradio_swig_py_gengen.Std \ - > $(DEPDIR)/gnuradio_swig_py_gengen.Sd; \ - $(RM) $(DEPDIR)/gnuradio_swig_py_gengen.Std; \ - $(MV) $(DEPDIR)/gnuradio_swig_py_gengen.Sd $(DEPDIR)/gnuradio_swig_py_gengen.Std; \ - fi; \ - else \ - $(RM) $(DEPDIR)/gnuradio_swig_py_gengen.S*; exit 1; \ - fi; -## -## Mess with the SWIG output .Std dependency file, to create a -## dependecy file valid for the input .i file: Basically, simulate the -## dependency file created for libraries by GNU's libtool for C++, -## where all of the dependencies for the target are first listed, then -## each individual dependency is listed as a target with no further -## dependencies. -## -## (1) remove the current dependency file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_gengen.d -## -## (2) Copy the whole SWIG file: -## - cp $(DEPDIR)/gnuradio_swig_py_gengen.Std $(DEPDIR)/gnuradio_swig_py_gengen.d -## -## (3) all a carriage return to the end of the dependency file. -## - echo "" >> $(DEPDIR)/gnuradio_swig_py_gengen.d -## -## (4) from the SWIG file, remove the first line (the target); remove -## trailing " \" and " " from each line. Append ":" to each line, -## followed by 2 carriage returns, then append this to the end of -## the dependency file. -## - $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/gnuradio_swig_py_gengen.Std | \ - awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/gnuradio_swig_py_gengen.d -## -## (5) remove the SWIG-generated file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_gengen.Std -## -## Create the stamp for this filename generation, to signal success in -## executing this rule; allows other threads waiting on this process -## to continue. -## - touch $(DEPDIR)/gnuradio_swig_py_gengen-generate-stamp +endif # end of if python + +if GUILE + +gnuradio_core_gengen_scmlib_LTLIBRARIES = \ + libguile-gnuradio-gnuradio_core_gengen.la +libguile_gnuradio_gnuradio_core_gengen_la_SOURCES = \ + guile/gnuradio_core_gengen.cc \ + $(gnuradio_core_gengen_la_swig_sources) +nobase_gnuradio_core_gengen_scm_DATA = \ + gnuradio/gnuradio_core_gengen.scm \ + gnuradio/gnuradio_core_gengen-primitive.scm +libguile_gnuradio_gnuradio_core_gengen_la_LIBADD = \ + $(STD_SWIG_LA_LIB_ADD) \ + $(gnuradio_core_gengen_la_swig_libadd) +libguile_gnuradio_gnuradio_core_gengen_la_LDFLAGS = \ + $(STD_SWIG_LA_LD_FLAGS) \ + $(gnuradio_core_gengen_la_swig_ldflags) +libguile_gnuradio_gnuradio_core_gengen_la_CXXFLAGS = \ + $(STD_SWIG_CXX_FLAGS) \ + -I$(top_builddir) \ + $(gnuradio_core_gengen_la_swig_cxxflags) + +guile/gnuradio_core_gengen.cc: gnuradio/gnuradio_core_gengen.scm +gnuradio/gnuradio_core_gengen.scm: gnuradio_core_gengen.i +gnuradio/gnuradio_core_gengen-primitive.scm: gnuradio/gnuradio_core_gengen.scm + +# Include the guile dependencies for this file +-include guile/gnuradio_core_gengen.d -# KLUDGE: Force runtime include of a SWIG dependency file. This is -# not guaranteed to be portable, but will probably work. If it works, -# we have accurate dependencies for our swig stuff, which is good. +endif # end of GUILE -@am__include@ @am__quote@./$(DEPDIR)/gnuradio_swig_py_gengen.d@am__quote@ # -*- Makefile -*- # @@ -797,27 +455,37 @@ $(DEPDIR)/gnuradio_swig_py_gengen-generate-stamp: # Boston, MA 02110-1301, USA. # -# Makefile.swig.gen for gnuradio_swig_py_filter.i +# Makefile.swig.gen for gnuradio_core_filter.i ## Default install locations for these files: ## ## Default location for the Python directory is: -## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_filter +## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_filter ## Default location for the Python exec directory is: -## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_filter +## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_filter ## ## The following can be overloaded to change the install location, but ## this has to be done in the including Makefile.am -before- ## Makefile.swig is included. -gnuradio_swig_py_filter_pythondir_category ?= gnuradio/gnuradio_swig_py_filter -gnuradio_swig_py_filter_pylibdir_category ?= $(gnuradio_swig_py_filter_pythondir_category) -gnuradio_swig_py_filter_pythondir = $(pythondir)/$(gnuradio_swig_py_filter_pythondir_category) -gnuradio_swig_py_filter_pylibdir = $(pyexecdir)/$(gnuradio_swig_py_filter_pylibdir_category) +gnuradio_core_filter_pythondir_category ?= gnuradio/gnuradio_core_filter +gnuradio_core_filter_pylibdir_category ?= $(gnuradio_core_filter_pythondir_category) +gnuradio_core_filter_pythondir = $(pythondir)/$(gnuradio_core_filter_pythondir_category) +gnuradio_core_filter_pylibdir = $(pyexecdir)/$(gnuradio_core_filter_pylibdir_category) + +# The .so libraries for the guile modules get installed whereever guile +# is installed, usually /usr/lib/guile/gnuradio/ +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_filter_scmlibdir = $(libdir) + +# The scm files for the guile modules get installed where ever guile +# is installed, usually /usr/share/guile/site/gnuradio_core_filter +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_filter_scmdir = $(guiledir) ## SWIG headers are always installed into the same directory. -gnuradio_swig_py_filter_swigincludedir = $(swigincludedir) +gnuradio_core_filter_swigincludedir = $(swigincludedir) ## This is a template file for a "generated" Makefile addition (in ## this case, "Makefile.swig.gen"). By including the top-level @@ -834,205 +502,81 @@ gnuradio_swig_py_filter_swigincludedir = $(swigincludedir) ## right thing. For more info, see < ## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > -## Stamps used to ensure parallel make does the right thing. These -## are removed by "make clean", but otherwise unused except during the -## parallel built. These will not be included in a tarball, because -## the SWIG-generated files will be removed from the distribution. - -STAMPS += $(DEPDIR)/gnuradio_swig_py_filter-generate-* - ## Other cleaned files: dependency files generated by SWIG or this Makefile MOSTLYCLEANFILES += $(DEPDIR)/*.S* -## Add the .py and .cc files to the list of SWIG built sources. The -## .h file is sometimes built, but not always ... so that one has to -## be added manually by the including Makefile.am . - -swig_built_sources += gnuradio_swig_py_filter.py gnuradio_swig_py_filter.cc - ## Various SWIG variables. These can be overloaded in the including ## Makefile.am by setting the variable value there, then including ## Makefile.swig . -gnuradio_swig_py_filter_swiginclude_HEADERS = \ - gnuradio_swig_py_filter.i \ - $(gnuradio_swig_py_filter_swiginclude_headers) +gnuradio_core_filter_swiginclude_HEADERS = \ + gnuradio_core_filter.i \ + $(gnuradio_core_filter_swiginclude_headers) + +if PYTHON +gnuradio_core_filter_pylib_LTLIBRARIES = \ + _gnuradio_core_filter.la -gnuradio_swig_py_filter_pylib_LTLIBRARIES = \ - _gnuradio_swig_py_filter.la +_gnuradio_core_filter_la_SOURCES = \ + python/gnuradio_core_filter.cc \ + $(gnuradio_core_filter_la_swig_sources) -_gnuradio_swig_py_filter_la_SOURCES = \ - gnuradio_swig_py_filter.cc \ - $(gnuradio_swig_py_filter_la_swig_sources) +gnuradio_core_filter_python_PYTHON = \ + gnuradio_core_filter.py \ + $(gnuradio_core_filter_python) -_gnuradio_swig_py_filter_la_LIBADD = \ +_gnuradio_core_filter_la_LIBADD = \ $(STD_SWIG_LA_LIB_ADD) \ - $(gnuradio_swig_py_filter_la_swig_libadd) + $(gnuradio_core_filter_la_swig_libadd) -_gnuradio_swig_py_filter_la_LDFLAGS = \ +_gnuradio_core_filter_la_LDFLAGS = \ $(STD_SWIG_LA_LD_FLAGS) \ - $(gnuradio_swig_py_filter_la_swig_ldflags) + $(gnuradio_core_filter_la_swig_ldflags) -_gnuradio_swig_py_filter_la_CXXFLAGS = \ +_gnuradio_core_filter_la_CXXFLAGS = \ $(STD_SWIG_CXX_FLAGS) \ - $(gnuradio_swig_py_filter_la_swig_cxxflags) + -I$(top_builddir) \ + $(gnuradio_core_filter_la_swig_cxxflags) -gnuradio_swig_py_filter_python_PYTHON = \ - gnuradio_swig_py_filter.py \ - $(gnuradio_swig_py_filter_python) +python/gnuradio_core_filter.cc: gnuradio_core_filter.py +gnuradio_core_filter.py: gnuradio_core_filter.i -## Entry rule for running SWIG +# Include the python dependencies for this file +-include python/gnuradio_core_filter.d -gnuradio_swig_py_filter.h gnuradio_swig_py_filter.py gnuradio_swig_py_filter.cc: gnuradio_swig_py_filter.i -## This rule will get called only when MAKE decides that one of the -## targets needs to be created or re-created, because: -## -## * The .i file is newer than any or all of the generated files; -## -## * Any or all of the .cc, .h, or .py files does not exist and is -## needed (in the case this file is not needed, the rule for it is -## ignored); or -## -## * Some SWIG-based dependecy of the .cc file isn't met and hence the -## .cc file needs be be regenerated. Explanation: Because MAKE -## knows how to handle dependencies for .cc files (regardless of -## their name or extension), then the .cc file is used as a target -## instead of the .i file -- but with the dependencies of the .i -## file. It is this last reason why the line: -## -## if test -f $@; then :; else -## -## cannot be used in this case: If a .i file dependecy is not met, -## then the .cc file needs to be rebuilt. But if the stamp is newer -## than the .cc file, and the .cc file exists, then in the original -## version (with the 'test' above) the internal MAKE call will not -## be issued and hence the .cc file will not be rebuilt. -## -## Once execution gets to here, it should always proceed no matter the -## state of a stamp (as discussed in link above). The -## $(DEPDIR)/gnuradio_swig_py_filter-generate stuff is used to allow for parallel -## builds to "do the right thing". The stamp has no relationship with -## either the target files or dependency file; it is used solely for -## the protection of multiple builds during a given call to MAKE. -## -## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM -## (15). At a caught signal, the quoted command will be issued before -## exiting. In this case, remove any stamp, whether temporary of not. -## The trap is valid until the process exits; the process includes all -## commands appended via "\"s. -## - trap 'rm -rf $(DEPDIR)/gnuradio_swig_py_filter-generate-*' 1 2 13 15; \ -## -## Create a temporary directory, which acts as a lock. The first -## process to create the directory will succeed and issue the MAKE -## command to do the actual work, while all subsequent processes will -## fail -- leading them to wait for the first process to finish. -## - if mkdir $(DEPDIR)/gnuradio_swig_py_filter-generate-lock 2>/dev/null; then \ -## -## This code is being executed by the first process to succeed in -## creating the directory lock. -## -## Remove the stamp associated with this filename. -## - rm -f $(DEPDIR)/gnuradio_swig_py_filter-generate-stamp; \ -## -## Tell MAKE to run the rule for creating this stamp. -## - $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/gnuradio_swig_py_filter-generate-stamp WHAT=$<; \ -## -## Now that the .cc, .h, and .py files have been (re)created from the -## .i file, future checking of this rule during the same MAKE -## execution will come back that the rule doesn't need to be executed -## because none of the conditions mentioned at the start of this rule -## will be positive. Remove the the directory lock, which frees up -## any waiting process(es) to continue. -## - rmdir $(DEPDIR)/gnuradio_swig_py_filter-generate-lock; \ - else \ -## -## This code is being executed by any follower processes while the -## directory lock is in place. -## -## Wait until the first process is done, testing once per second. -## - while test -d $(DEPDIR)/gnuradio_swig_py_filter-generate-lock; do \ - sleep 1; \ - done; \ -## -## Succeed if and only if the first process succeeded; exit this -## process returning the status of the generated stamp. -## - test -f $(DEPDIR)/gnuradio_swig_py_filter-generate-stamp; \ - exit $$?; \ - fi; - -$(DEPDIR)/gnuradio_swig_py_filter-generate-stamp: -## This rule will be called only by the first process issuing the -## above rule to succeed in creating the lock directory, after -## removing the actual stamp file in order to guarantee that MAKE will -## execute this rule. -## -## Call SWIG to generate the various output files; special -## post-processing on 'mingw32' host OS for the dependency file. -## - if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(gnuradio_swig_py_filter_swig_args) \ - -MD -MF $(DEPDIR)/gnuradio_swig_py_filter.Std \ - -module gnuradio_swig_py_filter -o gnuradio_swig_py_filter.cc $(WHAT); then \ - if test $(host_os) = mingw32; then \ - $(RM) $(DEPDIR)/gnuradio_swig_py_filter.Sd; \ - $(SED) 's,\\\\,/,g' < $(DEPDIR)/gnuradio_swig_py_filter.Std \ - > $(DEPDIR)/gnuradio_swig_py_filter.Sd; \ - $(RM) $(DEPDIR)/gnuradio_swig_py_filter.Std; \ - $(MV) $(DEPDIR)/gnuradio_swig_py_filter.Sd $(DEPDIR)/gnuradio_swig_py_filter.Std; \ - fi; \ - else \ - $(RM) $(DEPDIR)/gnuradio_swig_py_filter.S*; exit 1; \ - fi; -## -## Mess with the SWIG output .Std dependency file, to create a -## dependecy file valid for the input .i file: Basically, simulate the -## dependency file created for libraries by GNU's libtool for C++, -## where all of the dependencies for the target are first listed, then -## each individual dependency is listed as a target with no further -## dependencies. -## -## (1) remove the current dependency file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_filter.d -## -## (2) Copy the whole SWIG file: -## - cp $(DEPDIR)/gnuradio_swig_py_filter.Std $(DEPDIR)/gnuradio_swig_py_filter.d -## -## (3) all a carriage return to the end of the dependency file. -## - echo "" >> $(DEPDIR)/gnuradio_swig_py_filter.d -## -## (4) from the SWIG file, remove the first line (the target); remove -## trailing " \" and " " from each line. Append ":" to each line, -## followed by 2 carriage returns, then append this to the end of -## the dependency file. -## - $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/gnuradio_swig_py_filter.Std | \ - awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/gnuradio_swig_py_filter.d -## -## (5) remove the SWIG-generated file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_filter.Std -## -## Create the stamp for this filename generation, to signal success in -## executing this rule; allows other threads waiting on this process -## to continue. -## - touch $(DEPDIR)/gnuradio_swig_py_filter-generate-stamp +endif # end of if python + +if GUILE + +gnuradio_core_filter_scmlib_LTLIBRARIES = \ + libguile-gnuradio-gnuradio_core_filter.la +libguile_gnuradio_gnuradio_core_filter_la_SOURCES = \ + guile/gnuradio_core_filter.cc \ + $(gnuradio_core_filter_la_swig_sources) +nobase_gnuradio_core_filter_scm_DATA = \ + gnuradio/gnuradio_core_filter.scm \ + gnuradio/gnuradio_core_filter-primitive.scm +libguile_gnuradio_gnuradio_core_filter_la_LIBADD = \ + $(STD_SWIG_LA_LIB_ADD) \ + $(gnuradio_core_filter_la_swig_libadd) +libguile_gnuradio_gnuradio_core_filter_la_LDFLAGS = \ + $(STD_SWIG_LA_LD_FLAGS) \ + $(gnuradio_core_filter_la_swig_ldflags) +libguile_gnuradio_gnuradio_core_filter_la_CXXFLAGS = \ + $(STD_SWIG_CXX_FLAGS) \ + -I$(top_builddir) \ + $(gnuradio_core_filter_la_swig_cxxflags) -# KLUDGE: Force runtime include of a SWIG dependency file. This is -# not guaranteed to be portable, but will probably work. If it works, -# we have accurate dependencies for our swig stuff, which is good. +guile/gnuradio_core_filter.cc: gnuradio/gnuradio_core_filter.scm +gnuradio/gnuradio_core_filter.scm: gnuradio_core_filter.i +gnuradio/gnuradio_core_filter-primitive.scm: gnuradio/gnuradio_core_filter.scm + +# Include the guile dependencies for this file +-include guile/gnuradio_core_filter.d + +endif # end of GUILE -@am__include@ @am__quote@./$(DEPDIR)/gnuradio_swig_py_filter.d@am__quote@ # -*- Makefile -*- # @@ -1056,27 +600,37 @@ $(DEPDIR)/gnuradio_swig_py_filter-generate-stamp: # Boston, MA 02110-1301, USA. # -# Makefile.swig.gen for gnuradio_swig_py_io.i +# Makefile.swig.gen for gnuradio_core_io.i ## Default install locations for these files: ## ## Default location for the Python directory is: -## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_io +## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_io ## Default location for the Python exec directory is: -## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_io +## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_io ## ## The following can be overloaded to change the install location, but ## this has to be done in the including Makefile.am -before- ## Makefile.swig is included. -gnuradio_swig_py_io_pythondir_category ?= gnuradio/gnuradio_swig_py_io -gnuradio_swig_py_io_pylibdir_category ?= $(gnuradio_swig_py_io_pythondir_category) -gnuradio_swig_py_io_pythondir = $(pythondir)/$(gnuradio_swig_py_io_pythondir_category) -gnuradio_swig_py_io_pylibdir = $(pyexecdir)/$(gnuradio_swig_py_io_pylibdir_category) +gnuradio_core_io_pythondir_category ?= gnuradio/gnuradio_core_io +gnuradio_core_io_pylibdir_category ?= $(gnuradio_core_io_pythondir_category) +gnuradio_core_io_pythondir = $(pythondir)/$(gnuradio_core_io_pythondir_category) +gnuradio_core_io_pylibdir = $(pyexecdir)/$(gnuradio_core_io_pylibdir_category) + +# The .so libraries for the guile modules get installed whereever guile +# is installed, usually /usr/lib/guile/gnuradio/ +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_io_scmlibdir = $(libdir) + +# The scm files for the guile modules get installed where ever guile +# is installed, usually /usr/share/guile/site/gnuradio_core_io +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_io_scmdir = $(guiledir) ## SWIG headers are always installed into the same directory. -gnuradio_swig_py_io_swigincludedir = $(swigincludedir) +gnuradio_core_io_swigincludedir = $(swigincludedir) ## This is a template file for a "generated" Makefile addition (in ## this case, "Makefile.swig.gen"). By including the top-level @@ -1093,205 +647,81 @@ gnuradio_swig_py_io_swigincludedir = $(swigincludedir) ## right thing. For more info, see < ## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > -## Stamps used to ensure parallel make does the right thing. These -## are removed by "make clean", but otherwise unused except during the -## parallel built. These will not be included in a tarball, because -## the SWIG-generated files will be removed from the distribution. - -STAMPS += $(DEPDIR)/gnuradio_swig_py_io-generate-* - ## Other cleaned files: dependency files generated by SWIG or this Makefile MOSTLYCLEANFILES += $(DEPDIR)/*.S* -## Add the .py and .cc files to the list of SWIG built sources. The -## .h file is sometimes built, but not always ... so that one has to -## be added manually by the including Makefile.am . - -swig_built_sources += gnuradio_swig_py_io.py gnuradio_swig_py_io.cc - ## Various SWIG variables. These can be overloaded in the including ## Makefile.am by setting the variable value there, then including ## Makefile.swig . -gnuradio_swig_py_io_swiginclude_HEADERS = \ - gnuradio_swig_py_io.i \ - $(gnuradio_swig_py_io_swiginclude_headers) +gnuradio_core_io_swiginclude_HEADERS = \ + gnuradio_core_io.i \ + $(gnuradio_core_io_swiginclude_headers) + +if PYTHON +gnuradio_core_io_pylib_LTLIBRARIES = \ + _gnuradio_core_io.la -gnuradio_swig_py_io_pylib_LTLIBRARIES = \ - _gnuradio_swig_py_io.la +_gnuradio_core_io_la_SOURCES = \ + python/gnuradio_core_io.cc \ + $(gnuradio_core_io_la_swig_sources) -_gnuradio_swig_py_io_la_SOURCES = \ - gnuradio_swig_py_io.cc \ - $(gnuradio_swig_py_io_la_swig_sources) +gnuradio_core_io_python_PYTHON = \ + gnuradio_core_io.py \ + $(gnuradio_core_io_python) -_gnuradio_swig_py_io_la_LIBADD = \ +_gnuradio_core_io_la_LIBADD = \ $(STD_SWIG_LA_LIB_ADD) \ - $(gnuradio_swig_py_io_la_swig_libadd) + $(gnuradio_core_io_la_swig_libadd) -_gnuradio_swig_py_io_la_LDFLAGS = \ +_gnuradio_core_io_la_LDFLAGS = \ $(STD_SWIG_LA_LD_FLAGS) \ - $(gnuradio_swig_py_io_la_swig_ldflags) + $(gnuradio_core_io_la_swig_ldflags) -_gnuradio_swig_py_io_la_CXXFLAGS = \ +_gnuradio_core_io_la_CXXFLAGS = \ $(STD_SWIG_CXX_FLAGS) \ - $(gnuradio_swig_py_io_la_swig_cxxflags) + -I$(top_builddir) \ + $(gnuradio_core_io_la_swig_cxxflags) -gnuradio_swig_py_io_python_PYTHON = \ - gnuradio_swig_py_io.py \ - $(gnuradio_swig_py_io_python) +python/gnuradio_core_io.cc: gnuradio_core_io.py +gnuradio_core_io.py: gnuradio_core_io.i -## Entry rule for running SWIG +# Include the python dependencies for this file +-include python/gnuradio_core_io.d -gnuradio_swig_py_io.h gnuradio_swig_py_io.py gnuradio_swig_py_io.cc: gnuradio_swig_py_io.i -## This rule will get called only when MAKE decides that one of the -## targets needs to be created or re-created, because: -## -## * The .i file is newer than any or all of the generated files; -## -## * Any or all of the .cc, .h, or .py files does not exist and is -## needed (in the case this file is not needed, the rule for it is -## ignored); or -## -## * Some SWIG-based dependecy of the .cc file isn't met and hence the -## .cc file needs be be regenerated. Explanation: Because MAKE -## knows how to handle dependencies for .cc files (regardless of -## their name or extension), then the .cc file is used as a target -## instead of the .i file -- but with the dependencies of the .i -## file. It is this last reason why the line: -## -## if test -f $@; then :; else -## -## cannot be used in this case: If a .i file dependecy is not met, -## then the .cc file needs to be rebuilt. But if the stamp is newer -## than the .cc file, and the .cc file exists, then in the original -## version (with the 'test' above) the internal MAKE call will not -## be issued and hence the .cc file will not be rebuilt. -## -## Once execution gets to here, it should always proceed no matter the -## state of a stamp (as discussed in link above). The -## $(DEPDIR)/gnuradio_swig_py_io-generate stuff is used to allow for parallel -## builds to "do the right thing". The stamp has no relationship with -## either the target files or dependency file; it is used solely for -## the protection of multiple builds during a given call to MAKE. -## -## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM -## (15). At a caught signal, the quoted command will be issued before -## exiting. In this case, remove any stamp, whether temporary of not. -## The trap is valid until the process exits; the process includes all -## commands appended via "\"s. -## - trap 'rm -rf $(DEPDIR)/gnuradio_swig_py_io-generate-*' 1 2 13 15; \ -## -## Create a temporary directory, which acts as a lock. The first -## process to create the directory will succeed and issue the MAKE -## command to do the actual work, while all subsequent processes will -## fail -- leading them to wait for the first process to finish. -## - if mkdir $(DEPDIR)/gnuradio_swig_py_io-generate-lock 2>/dev/null; then \ -## -## This code is being executed by the first process to succeed in -## creating the directory lock. -## -## Remove the stamp associated with this filename. -## - rm -f $(DEPDIR)/gnuradio_swig_py_io-generate-stamp; \ -## -## Tell MAKE to run the rule for creating this stamp. -## - $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/gnuradio_swig_py_io-generate-stamp WHAT=$<; \ -## -## Now that the .cc, .h, and .py files have been (re)created from the -## .i file, future checking of this rule during the same MAKE -## execution will come back that the rule doesn't need to be executed -## because none of the conditions mentioned at the start of this rule -## will be positive. Remove the the directory lock, which frees up -## any waiting process(es) to continue. -## - rmdir $(DEPDIR)/gnuradio_swig_py_io-generate-lock; \ - else \ -## -## This code is being executed by any follower processes while the -## directory lock is in place. -## -## Wait until the first process is done, testing once per second. -## - while test -d $(DEPDIR)/gnuradio_swig_py_io-generate-lock; do \ - sleep 1; \ - done; \ -## -## Succeed if and only if the first process succeeded; exit this -## process returning the status of the generated stamp. -## - test -f $(DEPDIR)/gnuradio_swig_py_io-generate-stamp; \ - exit $$?; \ - fi; - -$(DEPDIR)/gnuradio_swig_py_io-generate-stamp: -## This rule will be called only by the first process issuing the -## above rule to succeed in creating the lock directory, after -## removing the actual stamp file in order to guarantee that MAKE will -## execute this rule. -## -## Call SWIG to generate the various output files; special -## post-processing on 'mingw32' host OS for the dependency file. -## - if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(gnuradio_swig_py_io_swig_args) \ - -MD -MF $(DEPDIR)/gnuradio_swig_py_io.Std \ - -module gnuradio_swig_py_io -o gnuradio_swig_py_io.cc $(WHAT); then \ - if test $(host_os) = mingw32; then \ - $(RM) $(DEPDIR)/gnuradio_swig_py_io.Sd; \ - $(SED) 's,\\\\,/,g' < $(DEPDIR)/gnuradio_swig_py_io.Std \ - > $(DEPDIR)/gnuradio_swig_py_io.Sd; \ - $(RM) $(DEPDIR)/gnuradio_swig_py_io.Std; \ - $(MV) $(DEPDIR)/gnuradio_swig_py_io.Sd $(DEPDIR)/gnuradio_swig_py_io.Std; \ - fi; \ - else \ - $(RM) $(DEPDIR)/gnuradio_swig_py_io.S*; exit 1; \ - fi; -## -## Mess with the SWIG output .Std dependency file, to create a -## dependecy file valid for the input .i file: Basically, simulate the -## dependency file created for libraries by GNU's libtool for C++, -## where all of the dependencies for the target are first listed, then -## each individual dependency is listed as a target with no further -## dependencies. -## -## (1) remove the current dependency file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_io.d -## -## (2) Copy the whole SWIG file: -## - cp $(DEPDIR)/gnuradio_swig_py_io.Std $(DEPDIR)/gnuradio_swig_py_io.d -## -## (3) all a carriage return to the end of the dependency file. -## - echo "" >> $(DEPDIR)/gnuradio_swig_py_io.d -## -## (4) from the SWIG file, remove the first line (the target); remove -## trailing " \" and " " from each line. Append ":" to each line, -## followed by 2 carriage returns, then append this to the end of -## the dependency file. -## - $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/gnuradio_swig_py_io.Std | \ - awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/gnuradio_swig_py_io.d -## -## (5) remove the SWIG-generated file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_io.Std -## -## Create the stamp for this filename generation, to signal success in -## executing this rule; allows other threads waiting on this process -## to continue. -## - touch $(DEPDIR)/gnuradio_swig_py_io-generate-stamp +endif # end of if python + +if GUILE -# KLUDGE: Force runtime include of a SWIG dependency file. This is -# not guaranteed to be portable, but will probably work. If it works, -# we have accurate dependencies for our swig stuff, which is good. +gnuradio_core_io_scmlib_LTLIBRARIES = \ + libguile-gnuradio-gnuradio_core_io.la +libguile_gnuradio_gnuradio_core_io_la_SOURCES = \ + guile/gnuradio_core_io.cc \ + $(gnuradio_core_io_la_swig_sources) +nobase_gnuradio_core_io_scm_DATA = \ + gnuradio/gnuradio_core_io.scm \ + gnuradio/gnuradio_core_io-primitive.scm +libguile_gnuradio_gnuradio_core_io_la_LIBADD = \ + $(STD_SWIG_LA_LIB_ADD) \ + $(gnuradio_core_io_la_swig_libadd) +libguile_gnuradio_gnuradio_core_io_la_LDFLAGS = \ + $(STD_SWIG_LA_LD_FLAGS) \ + $(gnuradio_core_io_la_swig_ldflags) +libguile_gnuradio_gnuradio_core_io_la_CXXFLAGS = \ + $(STD_SWIG_CXX_FLAGS) \ + -I$(top_builddir) \ + $(gnuradio_core_io_la_swig_cxxflags) + +guile/gnuradio_core_io.cc: gnuradio/gnuradio_core_io.scm +gnuradio/gnuradio_core_io.scm: gnuradio_core_io.i +gnuradio/gnuradio_core_io-primitive.scm: gnuradio/gnuradio_core_io.scm + +# Include the guile dependencies for this file +-include guile/gnuradio_core_io.d + +endif # end of GUILE -@am__include@ @am__quote@./$(DEPDIR)/gnuradio_swig_py_io.d@am__quote@ # -*- Makefile -*- # @@ -1315,27 +745,37 @@ $(DEPDIR)/gnuradio_swig_py_io-generate-stamp: # Boston, MA 02110-1301, USA. # -# Makefile.swig.gen for gnuradio_swig_py_hier.i +# Makefile.swig.gen for gnuradio_core_hier.i ## Default install locations for these files: ## ## Default location for the Python directory is: -## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_hier +## ${prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_hier ## Default location for the Python exec directory is: -## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_swig_py_hier +## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gnuradio_core_hier ## ## The following can be overloaded to change the install location, but ## this has to be done in the including Makefile.am -before- ## Makefile.swig is included. -gnuradio_swig_py_hier_pythondir_category ?= gnuradio/gnuradio_swig_py_hier -gnuradio_swig_py_hier_pylibdir_category ?= $(gnuradio_swig_py_hier_pythondir_category) -gnuradio_swig_py_hier_pythondir = $(pythondir)/$(gnuradio_swig_py_hier_pythondir_category) -gnuradio_swig_py_hier_pylibdir = $(pyexecdir)/$(gnuradio_swig_py_hier_pylibdir_category) +gnuradio_core_hier_pythondir_category ?= gnuradio/gnuradio_core_hier +gnuradio_core_hier_pylibdir_category ?= $(gnuradio_core_hier_pythondir_category) +gnuradio_core_hier_pythondir = $(pythondir)/$(gnuradio_core_hier_pythondir_category) +gnuradio_core_hier_pylibdir = $(pyexecdir)/$(gnuradio_core_hier_pylibdir_category) + +# The .so libraries for the guile modules get installed whereever guile +# is installed, usually /usr/lib/guile/gnuradio/ +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_hier_scmlibdir = $(libdir) + +# The scm files for the guile modules get installed where ever guile +# is installed, usually /usr/share/guile/site/gnuradio_core_hier +# FIXME: determince whether these should be installed with gnuradio. +gnuradio_core_hier_scmdir = $(guiledir) ## SWIG headers are always installed into the same directory. -gnuradio_swig_py_hier_swigincludedir = $(swigincludedir) +gnuradio_core_hier_swigincludedir = $(swigincludedir) ## This is a template file for a "generated" Makefile addition (in ## this case, "Makefile.swig.gen"). By including the top-level @@ -1352,203 +792,79 @@ gnuradio_swig_py_hier_swigincludedir = $(swigincludedir) ## right thing. For more info, see < ## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > -## Stamps used to ensure parallel make does the right thing. These -## are removed by "make clean", but otherwise unused except during the -## parallel built. These will not be included in a tarball, because -## the SWIG-generated files will be removed from the distribution. - -STAMPS += $(DEPDIR)/gnuradio_swig_py_hier-generate-* - ## Other cleaned files: dependency files generated by SWIG or this Makefile MOSTLYCLEANFILES += $(DEPDIR)/*.S* -## Add the .py and .cc files to the list of SWIG built sources. The -## .h file is sometimes built, but not always ... so that one has to -## be added manually by the including Makefile.am . - -swig_built_sources += gnuradio_swig_py_hier.py gnuradio_swig_py_hier.cc - ## Various SWIG variables. These can be overloaded in the including ## Makefile.am by setting the variable value there, then including ## Makefile.swig . -gnuradio_swig_py_hier_swiginclude_HEADERS = \ - gnuradio_swig_py_hier.i \ - $(gnuradio_swig_py_hier_swiginclude_headers) +gnuradio_core_hier_swiginclude_HEADERS = \ + gnuradio_core_hier.i \ + $(gnuradio_core_hier_swiginclude_headers) + +if PYTHON +gnuradio_core_hier_pylib_LTLIBRARIES = \ + _gnuradio_core_hier.la -gnuradio_swig_py_hier_pylib_LTLIBRARIES = \ - _gnuradio_swig_py_hier.la +_gnuradio_core_hier_la_SOURCES = \ + python/gnuradio_core_hier.cc \ + $(gnuradio_core_hier_la_swig_sources) -_gnuradio_swig_py_hier_la_SOURCES = \ - gnuradio_swig_py_hier.cc \ - $(gnuradio_swig_py_hier_la_swig_sources) +gnuradio_core_hier_python_PYTHON = \ + gnuradio_core_hier.py \ + $(gnuradio_core_hier_python) -_gnuradio_swig_py_hier_la_LIBADD = \ +_gnuradio_core_hier_la_LIBADD = \ $(STD_SWIG_LA_LIB_ADD) \ - $(gnuradio_swig_py_hier_la_swig_libadd) + $(gnuradio_core_hier_la_swig_libadd) -_gnuradio_swig_py_hier_la_LDFLAGS = \ +_gnuradio_core_hier_la_LDFLAGS = \ $(STD_SWIG_LA_LD_FLAGS) \ - $(gnuradio_swig_py_hier_la_swig_ldflags) + $(gnuradio_core_hier_la_swig_ldflags) -_gnuradio_swig_py_hier_la_CXXFLAGS = \ +_gnuradio_core_hier_la_CXXFLAGS = \ $(STD_SWIG_CXX_FLAGS) \ - $(gnuradio_swig_py_hier_la_swig_cxxflags) + -I$(top_builddir) \ + $(gnuradio_core_hier_la_swig_cxxflags) -gnuradio_swig_py_hier_python_PYTHON = \ - gnuradio_swig_py_hier.py \ - $(gnuradio_swig_py_hier_python) +python/gnuradio_core_hier.cc: gnuradio_core_hier.py +gnuradio_core_hier.py: gnuradio_core_hier.i -## Entry rule for running SWIG +# Include the python dependencies for this file +-include python/gnuradio_core_hier.d -gnuradio_swig_py_hier.h gnuradio_swig_py_hier.py gnuradio_swig_py_hier.cc: gnuradio_swig_py_hier.i -## This rule will get called only when MAKE decides that one of the -## targets needs to be created or re-created, because: -## -## * The .i file is newer than any or all of the generated files; -## -## * Any or all of the .cc, .h, or .py files does not exist and is -## needed (in the case this file is not needed, the rule for it is -## ignored); or -## -## * Some SWIG-based dependecy of the .cc file isn't met and hence the -## .cc file needs be be regenerated. Explanation: Because MAKE -## knows how to handle dependencies for .cc files (regardless of -## their name or extension), then the .cc file is used as a target -## instead of the .i file -- but with the dependencies of the .i -## file. It is this last reason why the line: -## -## if test -f $@; then :; else -## -## cannot be used in this case: If a .i file dependecy is not met, -## then the .cc file needs to be rebuilt. But if the stamp is newer -## than the .cc file, and the .cc file exists, then in the original -## version (with the 'test' above) the internal MAKE call will not -## be issued and hence the .cc file will not be rebuilt. -## -## Once execution gets to here, it should always proceed no matter the -## state of a stamp (as discussed in link above). The -## $(DEPDIR)/gnuradio_swig_py_hier-generate stuff is used to allow for parallel -## builds to "do the right thing". The stamp has no relationship with -## either the target files or dependency file; it is used solely for -## the protection of multiple builds during a given call to MAKE. -## -## Catch signals SIGHUP (1), SIGINT (2), SIGPIPE (13), and SIGTERM -## (15). At a caught signal, the quoted command will be issued before -## exiting. In this case, remove any stamp, whether temporary of not. -## The trap is valid until the process exits; the process includes all -## commands appended via "\"s. -## - trap 'rm -rf $(DEPDIR)/gnuradio_swig_py_hier-generate-*' 1 2 13 15; \ -## -## Create a temporary directory, which acts as a lock. The first -## process to create the directory will succeed and issue the MAKE -## command to do the actual work, while all subsequent processes will -## fail -- leading them to wait for the first process to finish. -## - if mkdir $(DEPDIR)/gnuradio_swig_py_hier-generate-lock 2>/dev/null; then \ -## -## This code is being executed by the first process to succeed in -## creating the directory lock. -## -## Remove the stamp associated with this filename. -## - rm -f $(DEPDIR)/gnuradio_swig_py_hier-generate-stamp; \ -## -## Tell MAKE to run the rule for creating this stamp. -## - $(MAKE) $(AM_MAKEFLAGS) $(DEPDIR)/gnuradio_swig_py_hier-generate-stamp WHAT=$<; \ -## -## Now that the .cc, .h, and .py files have been (re)created from the -## .i file, future checking of this rule during the same MAKE -## execution will come back that the rule doesn't need to be executed -## because none of the conditions mentioned at the start of this rule -## will be positive. Remove the the directory lock, which frees up -## any waiting process(es) to continue. -## - rmdir $(DEPDIR)/gnuradio_swig_py_hier-generate-lock; \ - else \ -## -## This code is being executed by any follower processes while the -## directory lock is in place. -## -## Wait until the first process is done, testing once per second. -## - while test -d $(DEPDIR)/gnuradio_swig_py_hier-generate-lock; do \ - sleep 1; \ - done; \ -## -## Succeed if and only if the first process succeeded; exit this -## process returning the status of the generated stamp. -## - test -f $(DEPDIR)/gnuradio_swig_py_hier-generate-stamp; \ - exit $$?; \ - fi; - -$(DEPDIR)/gnuradio_swig_py_hier-generate-stamp: -## This rule will be called only by the first process issuing the -## above rule to succeed in creating the lock directory, after -## removing the actual stamp file in order to guarantee that MAKE will -## execute this rule. -## -## Call SWIG to generate the various output files; special -## post-processing on 'mingw32' host OS for the dependency file. -## - if $(SWIG) $(STD_SWIG_PYTHON_ARGS) $(gnuradio_swig_py_hier_swig_args) \ - -MD -MF $(DEPDIR)/gnuradio_swig_py_hier.Std \ - -module gnuradio_swig_py_hier -o gnuradio_swig_py_hier.cc $(WHAT); then \ - if test $(host_os) = mingw32; then \ - $(RM) $(DEPDIR)/gnuradio_swig_py_hier.Sd; \ - $(SED) 's,\\\\,/,g' < $(DEPDIR)/gnuradio_swig_py_hier.Std \ - > $(DEPDIR)/gnuradio_swig_py_hier.Sd; \ - $(RM) $(DEPDIR)/gnuradio_swig_py_hier.Std; \ - $(MV) $(DEPDIR)/gnuradio_swig_py_hier.Sd $(DEPDIR)/gnuradio_swig_py_hier.Std; \ - fi; \ - else \ - $(RM) $(DEPDIR)/gnuradio_swig_py_hier.S*; exit 1; \ - fi; -## -## Mess with the SWIG output .Std dependency file, to create a -## dependecy file valid for the input .i file: Basically, simulate the -## dependency file created for libraries by GNU's libtool for C++, -## where all of the dependencies for the target are first listed, then -## each individual dependency is listed as a target with no further -## dependencies. -## -## (1) remove the current dependency file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_hier.d -## -## (2) Copy the whole SWIG file: -## - cp $(DEPDIR)/gnuradio_swig_py_hier.Std $(DEPDIR)/gnuradio_swig_py_hier.d -## -## (3) all a carriage return to the end of the dependency file. -## - echo "" >> $(DEPDIR)/gnuradio_swig_py_hier.d -## -## (4) from the SWIG file, remove the first line (the target); remove -## trailing " \" and " " from each line. Append ":" to each line, -## followed by 2 carriage returns, then append this to the end of -## the dependency file. -## - $(SED) -e '1d;s, \\,,g;s, ,,g' < $(DEPDIR)/gnuradio_swig_py_hier.Std | \ - awk '{ printf "%s:\n\n", $$0 }' >> $(DEPDIR)/gnuradio_swig_py_hier.d -## -## (5) remove the SWIG-generated file -## - $(RM) $(DEPDIR)/gnuradio_swig_py_hier.Std -## -## Create the stamp for this filename generation, to signal success in -## executing this rule; allows other threads waiting on this process -## to continue. -## - touch $(DEPDIR)/gnuradio_swig_py_hier-generate-stamp +endif # end of if python + +if GUILE + +gnuradio_core_hier_scmlib_LTLIBRARIES = \ + libguile-gnuradio-gnuradio_core_hier.la +libguile_gnuradio_gnuradio_core_hier_la_SOURCES = \ + guile/gnuradio_core_hier.cc \ + $(gnuradio_core_hier_la_swig_sources) +nobase_gnuradio_core_hier_scm_DATA = \ + gnuradio/gnuradio_core_hier.scm \ + gnuradio/gnuradio_core_hier-primitive.scm +libguile_gnuradio_gnuradio_core_hier_la_LIBADD = \ + $(STD_SWIG_LA_LIB_ADD) \ + $(gnuradio_core_hier_la_swig_libadd) +libguile_gnuradio_gnuradio_core_hier_la_LDFLAGS = \ + $(STD_SWIG_LA_LD_FLAGS) \ + $(gnuradio_core_hier_la_swig_ldflags) +libguile_gnuradio_gnuradio_core_hier_la_CXXFLAGS = \ + $(STD_SWIG_CXX_FLAGS) \ + -I$(top_builddir) \ + $(gnuradio_core_hier_la_swig_cxxflags) + +guile/gnuradio_core_hier.cc: gnuradio/gnuradio_core_hier.scm +gnuradio/gnuradio_core_hier.scm: gnuradio_core_hier.i +gnuradio/gnuradio_core_hier-primitive.scm: gnuradio/gnuradio_core_hier.scm + +# Include the guile dependencies for this file +-include guile/gnuradio_core_hier.d -# KLUDGE: Force runtime include of a SWIG dependency file. This is -# not guaranteed to be portable, but will probably work. If it works, -# we have accurate dependencies for our swig stuff, which is good. +endif # end of GUILE -@am__include@ @am__quote@./$(DEPDIR)/gnuradio_swig_py_hier.d@am__quote@ diff --git a/gnuradio-core/src/lib/swig/gnuradio.i b/gnuradio-core/src/lib/swig/gnuradio.i index e15a0059c..1856d5007 100644 --- a/gnuradio-core/src/lib/swig/gnuradio.i +++ b/gnuradio-core/src/lib/swig/gnuradio.i @@ -32,16 +32,35 @@ #include "gnuradio_swig_bug_workaround.h" // mandatory bug fix #include <gr_types.h> #include <stddef.h> // size_t +#include <complex> %} %feature("autodoc","1"); +#ifdef SWIGGUILE +// Export constants and enums as scheme variables, not functions. +%feature("constasvar"); +#endif + // local file %include <gr_shared_ptr.i> // non-local SWIG files -%include <stl.i> +#ifdef SWIGGUILE // Local overrides to support complex +// It's kind of screwy, but the target language subdir isn't +// searched automatically except for under ./swig_lib which +// doesn't really help us since we run swig in many directories +%include <guile/std_complex.i> +%include <guile/std_vector.i> +%include <std_common.i> +%include <std_string.i> +%include <std_map.i> +%include <std_pair.i> +#else %include <std_complex.i> +%include <std_vector.i> +%include <stl.i> +#endif %include <std_except.i> typedef std::complex<float> gr_complex; @@ -59,6 +78,7 @@ namespace std { %template() vector<int>; %template() vector<float>; %template() vector<double>; + // %template() std::complex<float>; %template() vector< std::complex<float> >; %template() vector< std::vector< unsigned char > >; @@ -72,15 +92,6 @@ namespace std { //////////////////////////////////////////////////////////////////////// -%constant int sizeof_char = sizeof(char); -%constant int sizeof_short = sizeof(short); -%constant int sizeof_int = sizeof(int); -%constant int sizeof_float = sizeof(float); -%constant int sizeof_double = sizeof(double); -%constant int sizeof_gr_complex = sizeof(gr_complex); - -//////////////////////////////////////////////////////////////////////// - #ifndef SW_RUNTIME // import runtime.i for all but sw_runtime, since it needs to %include %import <runtime.i> diff --git a/gnuradio-core/src/lib/swig/gnuradio_swig_python.py b/gnuradio-core/src/lib/swig/gnuradio_core.py index 5324b2309..172051013 100644 --- a/gnuradio-core/src/lib/swig/gnuradio_swig_python.py +++ b/gnuradio-core/src/lib/swig/gnuradio_core.py @@ -1,5 +1,5 @@ # -# Copyright 2006,2009 Free Software Foundation, Inc. +# Copyright 2006,2009,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -18,11 +18,11 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # -# This file implements the old gnuradio_swig_python namespace +# This file implements the old gnuradio_core namespace -from gnuradio_swig_py_runtime import * -from gnuradio_swig_py_general import * -from gnuradio_swig_py_gengen import * -from gnuradio_swig_py_filter import * -from gnuradio_swig_py_io import * -from gnuradio_swig_py_hier import * +from gnuradio_core_runtime import * +from gnuradio_core_general import * +from gnuradio_core_gengen import * +from gnuradio_core_filter import * +from gnuradio_core_io import * +from gnuradio_core_hier import * diff --git a/gnuradio-core/src/lib/swig/gnuradio_swig_py_filter.i b/gnuradio-core/src/lib/swig/gnuradio_core_filter.i index 6396a97d0..e825467db 100644 --- a/gnuradio-core/src/lib/swig/gnuradio_swig_py_filter.i +++ b/gnuradio-core/src/lib/swig/gnuradio_core_filter.i @@ -1,26 +1,26 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. - * + * Copyright 2006,2009,2010 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 this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SWIGIMPORTED -%module(directors="1") gnuradio_swig_py_filter +%module(directors="1") gnuradio_core_filter #endif //%feature("autodoc", "1"); // generate python docstrings @@ -28,3 +28,13 @@ %include "gnuradio.i" // the common stuff %include "filter.i" + +#if SWIGGUILE +%scheme %{ +(load-extension-global "libguile-gnuradio-gnuradio_core_filter" "scm_init_gnuradio_gnuradio_core_filter_module") +%} + +%goops %{ + (use-modules (gnuradio gnuradio_core_runtime)) +%} +#endif diff --git a/gnuradio-core/src/lib/swig/gnuradio_core_general.i b/gnuradio-core/src/lib/swig/gnuradio_core_general.i new file mode 100644 index 000000000..adf6b469a --- /dev/null +++ b/gnuradio-core/src/lib/swig/gnuradio_core_general.i @@ -0,0 +1,60 @@ +/* -*- c++ -*- */ +/* + * Copyright 2006,2009,2010 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 this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef SWIGIMPORTED +%module(directors="1") gnuradio_core_general +#endif + + //%feature("autodoc", "1"); // generate python docstrings + +%include "gnuradio.i" // the common stuff + +%include "general.i" + + // Simple test case for complex input and output +%inline +%{ + std::complex<float> complexf_add_2j(std::complex<float> x) + { + return std::complex<float>(x.real(), x.imag() + 2); + } + + std::complex<double> complexd_add_2j(std::complex<double> x) + { + return std::complex<double>(x.real(), x.imag() + 2); + } + + std::complex<float> complexf_add_x_2j(float x, std::complex<float> y) + { + return std::complex<float>(x + y.real(), y.imag() + 2); + } + +%} + +#if SWIGGUILE +%scheme %{ +(load-extension-global "libguile-gnuradio-gnuradio_core_general" "scm_init_gnuradio_gnuradio_core_general_module") +%} + +%goops %{ +(use-modules (gnuradio gnuradio_core_runtime)) +%} +#endif diff --git a/gnuradio-core/src/lib/swig/gnuradio_swig_py_gengen.i b/gnuradio-core/src/lib/swig/gnuradio_core_gengen.i index 95e85cf6b..496ced077 100644 --- a/gnuradio-core/src/lib/swig/gnuradio_swig_py_gengen.i +++ b/gnuradio-core/src/lib/swig/gnuradio_core_gengen.i @@ -1,26 +1,26 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. - * + * Copyright 2006,2009,2010 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 this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SWIGIMPORTED -%module(directors="1") gnuradio_swig_py_gengen +%module(directors="1") gnuradio_core_gengen #endif //%feature("autodoc", "1"); // generate python docstrings @@ -28,3 +28,13 @@ %include "gnuradio.i" // the common stuff %include "gengen.i" + +#if SWIGGUILE +%scheme %{ +(load-extension-global "libguile-gnuradio-gnuradio_core_gengen" "scm_init_gnuradio_gnuradio_core_gengen_module") +%} + +%goops %{ + (use-modules (gnuradio gnuradio_core_runtime)) +%} +#endif diff --git a/gnuradio-core/src/lib/swig/gnuradio_swig_py_hier.i b/gnuradio-core/src/lib/swig/gnuradio_core_hier.i index a82b5ae41..0b8161c5d 100644 --- a/gnuradio-core/src/lib/swig/gnuradio_swig_py_hier.i +++ b/gnuradio-core/src/lib/swig/gnuradio_core_hier.i @@ -1,26 +1,26 @@ /* -*- c++ -*- */ /* - * Copyright 2009 Free Software Foundation, Inc. - * + * Copyright 2009,2010 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 this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SWIGIMPORTED -%module(directors="1") gnuradio_swig_py_hier +%module(directors="1") gnuradio_hier_hier #endif //%feature("autodoc", "1"); // generate python docstrings @@ -28,3 +28,13 @@ %include "gnuradio.i" // the common stuff %include "hier.i" + +#if SWIGGUILE +%scheme %{ +(load-extension-global "libguile-gnuradio-gnuradio_core_hier" "scm_init_gnuradio_gnuradio_core_hier_module") +%} + +%goops %{ + (use-modules (gnuradio gnuradio_core_runtime)) +%} +#endif diff --git a/gnuradio-core/src/lib/swig/gnuradio_swig_py_io.i b/gnuradio-core/src/lib/swig/gnuradio_core_io.i index 9318f5d86..0d989ea87 100644 --- a/gnuradio-core/src/lib/swig/gnuradio_swig_py_io.i +++ b/gnuradio-core/src/lib/swig/gnuradio_core_io.i @@ -1,26 +1,26 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2009 Free Software Foundation, Inc. - * + * Copyright 2006,2009,2010 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 this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef SWIGIMPORTED -%module(directors="1") gnuradio_swig_py_io +%module(directors="1") gnuradio_core_io #endif //%feature("autodoc", "1"); // generate python docstrings @@ -28,3 +28,13 @@ %include "gnuradio.i" // the common stuff %include "io.i" + +#if SWIGGUILE +%scheme %{ +(load-extension-global "libguile-gnuradio-gnuradio_core_io" "scm_init_gnuradio_gnuradio_core_io_module") +%} + +%goops %{ + (use-modules (gnuradio gnuradio_core_runtime)) +%} +#endif diff --git a/gnuradio-core/src/lib/swig/gnuradio_core_runtime.i b/gnuradio-core/src/lib/swig/gnuradio_core_runtime.i new file mode 100644 index 000000000..579c51ce5 --- /dev/null +++ b/gnuradio-core/src/lib/swig/gnuradio_core_runtime.i @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2009,2010 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 SWIGIMPORTED +%module(directors="1") gnuradio_core_runtime +#endif + + //%feature("autodoc", "1"); // generate python docstrings + +#define SW_RUNTIME +%include "gnuradio.i" // the common stuff + +%include "runtime.i" + + +#if SWIGGUILE +%scheme %{ + +;; Load our gsubr that loads libraries using the RTLD_GLOBAL option +(load-extension "libguile-gnuradio-dynl-global" "scm_init_gnuradio_dynl_global_module") + +;; Define load-extension-global in module '(guile) +(module-define! (resolve-module '(guile)) + 'load-extension-global + (lambda (lib init) + (dynamic-call init (dynamic-link-global lib)))) + +;; Use load-extension-global to load our swig modules +(load-extension-global "libguile-gnuradio-gnuradio_core_runtime" "scm_init_gnuradio_gnuradio_core_runtime_module") +%} + +%goops %{ +(use-modules (gnuradio export-safely)) +(re-export export-syms-if-not-imported-gf) +(re-export-syntax export-safely) +(re-export re-export-all) +%} +#endif diff --git a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.i b/gnuradio-core/src/lib/swig/gnuradio_swig_bug_workaround.h index 4f08aa760..8f7eea0bf 100644 --- a/gnuradio-core/src/lib/general/gr_clock_recovery_mm_ff.i +++ b/gnuradio-core/src/lib/swig/gnuradio_swig_bug_workaround.h @@ -20,26 +20,26 @@ * Boston, MA 02110-1301, USA. */ -GR_SWIG_BLOCK_MAGIC(gr,clock_recovery_mm_ff); +#ifndef INCLUDED_GNURADIO_SWIG_BUG_WORKAROUND_H +#define INCLUDED_GNURADIO_SWIG_BUG_WORKAROUND_H -gr_clock_recovery_mm_ff_sptr gr_make_clock_recovery_mm_ff (float omega, float gain_omega, - float mu, float gain_mu, - float omega_relative_limit=0.001); - -class gr_clock_recovery_mm_ff : public gr_sync_block -{ - private: - gr_clock_recovery_mm_ff (float omega, float gain_omega, float mu, float gain_mu, - float omega_relative_limit); +/* + * This include files works around a bug in SWIG 1.3.21 and 22 + * where it fails to emit these declarations when doing + * %import "gnuradio.i" + */ -public: - float mu() const; - float omega() const; - float gain_mu() const; - float gain_omega() const; +class gr_base_error_handler; +class gr_basic_block; +class gr_block; +class gr_error_handler; +class gr_file_error_handler; +class gr_hier_block2; +class gr_msg_handler; +class gr_msg_queue; +class gr_sync_block; +class gr_sync_decimator; +class gr_sync_interpolator; +class gr_top_block; - void set_gain_mu (float gain_mu); - void set_gain_omega (float gain_omega); - void set_mu (float omega); - void set_omega (float omega); -}; +#endif /* INCLUDED_GNURADIO_SWIG_BUG_WORKAROUND_H */ diff --git a/gnuradio-core/src/lib/swig/gr_swig_block_magic.i b/gnuradio-core/src/lib/swig/gr_swig_block_magic.i index 78e838012..a080c2b27 100644 --- a/gnuradio-core/src/lib/swig/gr_swig_block_magic.i +++ b/gnuradio-core/src/lib/swig/gr_swig_block_magic.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2004 Free Software Foundation, Inc. + * Copyright 2004,2010 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -21,19 +21,40 @@ */ %define GR_SWIG_BLOCK_MAGIC(PKG, BASE_NAME) -_GR_SWIG_BLOCK_MAGIC_HELPER(PKG, PKG ## _ ## BASE_NAME, BASE_NAME) +_GR_SWIG_BLOCK_MAGIC_HELPER(PKG, BASE_NAME, PKG ## _ ## BASE_NAME) %enddef -%define _GR_SWIG_BLOCK_MAGIC_HELPER(PKG, NAME, BASE_NAME) -class NAME; -typedef boost::shared_ptr<NAME> NAME ## _sptr; -%template(NAME ## _sptr) boost::shared_ptr<NAME>; +%define _GR_SWIG_BLOCK_MAGIC_HELPER_COMMON(PKG, BASE_NAME, FULL_NAME) +class FULL_NAME; +typedef boost::shared_ptr<FULL_NAME> FULL_NAME ## _sptr; +%template(FULL_NAME ## _sptr) boost::shared_ptr<FULL_NAME>; %rename(BASE_NAME) PKG ## _make_ ## BASE_NAME; +%ignore FULL_NAME; +%enddef +#ifdef SWIGPYTHON +%define _GR_SWIG_BLOCK_MAGIC_HELPER(PKG, BASE_NAME, FULL_NAME) +_GR_SWIG_BLOCK_MAGIC_HELPER_COMMON(PKG, BASE_NAME, FULL_NAME) %pythoncode %{ -NAME ## _sptr.block = lambda self: NAME ## _block (self) -NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ()) +FULL_NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id ()) %} +%enddef +#endif -%ignore NAME; +#ifdef SWIGGUILE +#ifdef IN_GNURADIO_CORE // normal behavior +%define _GR_SWIG_BLOCK_MAGIC_HELPER(PKG, BASE_NAME, FULL_NAME) +_GR_SWIG_BLOCK_MAGIC_HELPER_COMMON(PKG, BASE_NAME, FULL_NAME) +/* FIXME May want to add something here to get a friendlier printed representation */ +%enddef +#else // Don't strip PKG from name +%define _GR_SWIG_BLOCK_MAGIC_HELPER(PKG, BASE_NAME, FULL_NAME) +class FULL_NAME; +typedef boost::shared_ptr<FULL_NAME> FULL_NAME ## _sptr; +%template(FULL_NAME ## _sptr) boost::shared_ptr<FULL_NAME>; +%ignore FULL_NAME; +%rename(FULL_NAME) PKG ## _make_ ## BASE_NAME; +/* FIXME May want to add something here to get a friendlier printed representation */ %enddef +#endif +#endif diff --git a/gnuradio-core/src/lib/swig/guile/std_complex.i b/gnuradio-core/src/lib/swig/guile/std_complex.i new file mode 100644 index 000000000..2a5c72aa2 --- /dev/null +++ b/gnuradio-core/src/lib/swig/guile/std_complex.i @@ -0,0 +1,37 @@ +%{ +#include <complex> +%} + +// To the target language, complex number conversion +%typemap(out) complex, complex<double>, std::complex<double> { + $result = scm_make_rectangular( gh_double2scm ($1.real ()), + gh_double2scm ($1.imag ()) ); +} + +// To the target language, complex number conversion +%typemap(out) complex, complex<float>, std::complex<float> { + $result = scm_make_rectangular( gh_double2scm ($1.real ()), + gh_double2scm ($1.imag ()) ); +} + +// From the target language, complex number conversion +%typemap(in) complex, complex<double>, std::complex<double> { + $1 = std::complex<double>( gh_scm2double (scm_real_part ($input)), + gh_scm2double (scm_imag_part ($input)) ); +} + +// From the target language, complex number conversion +%typemap(in) complex, complex<float>, std::complex<float> { + $1 = std::complex<float>( gh_scm2double (scm_real_part ($input)), + gh_scm2double (scm_imag_part ($input)) ); +} + +%typemaps_primitive(%checkcode(CPLXDBL), std::complex<double>); +%typemaps_primitive(%checkcode(CPLXFLT), std::complex<float>); + +%typecheck(SWIG_TYPECHECK_COMPLEX) + std::complex<float>, std::complex<double>, + const std::complex<float> &, const std::complex<double> & +{ + $1 = scm_is_complex($input) ? 1 : 0; +} diff --git a/gnuradio-core/src/lib/swig/guile/std_vector.i b/gnuradio-core/src/lib/swig/guile/std_vector.i new file mode 100644 index 000000000..ef1f20667 --- /dev/null +++ b/gnuradio-core/src/lib/swig/guile/std_vector.i @@ -0,0 +1,437 @@ +/* ----------------------------------------------------------------------------- + * See the LICENSE file for information on copyright, usage and redistribution + * of SWIG, and the README file for authors - http://www.swig.org/release.html. + * + * std_vector.i + * + * SWIG typemaps for std::vector + * ----------------------------------------------------------------------------- */ + +%include <std_common.i> + +// ------------------------------------------------------------------------ +// std::vector +// +// The aim of all that follows would be to integrate std::vector with +// Guile as much as possible, namely, to allow the user to pass and +// be returned Guile vectors or lists. +// const declarations are used to guess the intent of the function being +// exported; therefore, the following rationale is applied: +// +// -- f(std::vector<T>), f(const std::vector<T>&), f(const std::vector<T>*): +// the parameter being read-only, either a Guile sequence or a +// previously wrapped std::vector<T> can be passed. +// -- f(std::vector<T>&), f(std::vector<T>*): +// the parameter must be modified; therefore, only a wrapped std::vector +// can be passed. +// -- std::vector<T> f(): +// the vector is returned by copy; therefore, a Guile vector of T:s +// is returned which is most easily used in other Guile functions +// -- std::vector<T>& f(), std::vector<T>* f(), const std::vector<T>& f(), +// const std::vector<T>* f(): +// the vector is returned by reference; therefore, a wrapped std::vector +// is returned +// ------------------------------------------------------------------------ + +%{ +#include <vector> +#include <algorithm> +#include <stdexcept> +#include <complex> +%} + +%{ + inline std::complex<float> SWIG_scm2cmplxfloat(SCM x){ + return std::complex<float>(scm_c_real_part(x), scm_c_imag_part(x)); + } + + inline std::complex<double> SWIG_scm2cmplxdouble(SCM x){ + return std::complex<double>(scm_c_real_part(x), scm_c_imag_part(x)); + } + + inline SCM SWIG_cmplxfloat2scm(std::complex<float> x){ + return scm_c_make_rectangular(x.real(), x.imag()); + } + + inline SCM SWIG_cmplxdouble2scm(std::complex<double> x){ + return scm_c_make_rectangular(x.real(), x.imag()); + } +%} + +// exported class + +namespace std { + + template<class T> class vector { + %typemap(in) vector<T> { + if (gh_vector_p($input)) { + unsigned long size = gh_vector_length($input); + $1 = std::vector<T >(size); + for (unsigned long i=0; i<size; i++) { + SCM o = gh_vector_ref($input,gh_ulong2scm(i)); + (($1_type &)$1)[i] = + *((T*) SWIG_MustGetPtr(o,$descriptor(T *),$argnum, 0)); + } + } else if (gh_null_p($input)) { + $1 = std::vector<T >(); + } else if (gh_pair_p($input)) { + SCM head, tail; + $1 = std::vector<T >(); + tail = $input; + while (!gh_null_p(tail)) { + head = gh_car(tail); + tail = gh_cdr(tail); + $1.push_back(*((T*)SWIG_MustGetPtr(head, + $descriptor(T *), + $argnum, 0))); + } + } else { + $1 = *(($&1_type) + SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); + } + } + %typemap(in) const vector<T>& (std::vector<T> temp), + const vector<T>* (std::vector<T> temp) { + if (gh_vector_p($input)) { + unsigned long size = gh_vector_length($input); + temp = std::vector<T >(size); + $1 = &temp; + for (unsigned long i=0; i<size; i++) { + SCM o = gh_vector_ref($input,gh_ulong2scm(i)); + temp[i] = *((T*) SWIG_MustGetPtr(o, + $descriptor(T *), + $argnum, 0)); + } + } else if (gh_null_p($input)) { + temp = std::vector<T >(); + $1 = &temp; + } else if (gh_pair_p($input)) { + temp = std::vector<T >(); + $1 = &temp; + SCM head, tail; + tail = $input; + while (!gh_null_p(tail)) { + head = gh_car(tail); + tail = gh_cdr(tail); + temp.push_back(*((T*) SWIG_MustGetPtr(head, + $descriptor(T *), + $argnum, 0))); + } + } else { + $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); + } + } + %typemap(out) vector<T> { + $result = gh_make_vector(gh_long2scm($1.size()),SCM_UNSPECIFIED); + for (unsigned int i=0; i<$1.size(); i++) { + T* x = new T((($1_type &)$1)[i]); + gh_vector_set_x($result,gh_long2scm(i), + SWIG_NewPointerObj(x, $descriptor(T *), 1)); + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector<T> { + /* native sequence? */ + if (gh_vector_p($input)) { + unsigned int size = gh_vector_length($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + SCM o = gh_vector_ref($input,gh_ulong2scm(0)); + T* x; + if (SWIG_ConvertPtr(o,(void**) &x, + $descriptor(T *), 0) != -1) + $1 = 1; + else + $1 = 0; + } + } else if (gh_null_p($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (gh_pair_p($input)) { + /* check the first element only */ + T* x; + SCM head = gh_car($input); + if (SWIG_ConvertPtr(head,(void**) &x, + $descriptor(T *), 0) != -1) + $1 = 1; + else + $1 = 0; + } else { + /* wrapped vector? */ + std::vector<T >* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor, 0) != -1) + $1 = 1; + else + $1 = 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T>&, + const vector<T>* { + /* native sequence? */ + if (gh_vector_p($input)) { + unsigned int size = gh_vector_length($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + SCM o = gh_vector_ref($input,gh_ulong2scm(0)); + if (SWIG_ConvertPtr(o,(void**) &x, + $descriptor(T *), 0) != -1) + $1 = 1; + else + $1 = 0; + } + } else if (gh_null_p($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (gh_pair_p($input)) { + /* check the first element only */ + T* x; + SCM head = gh_car($input); + if (SWIG_ConvertPtr(head,(void**) &x, + $descriptor(T *), 0) != -1) + $1 = 1; + else + $1 = 0; + } else { + /* wrapped vector? */ + std::vector<T >* v; + if (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor, 0) != -1) + $1 = 1; + else + $1 = 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector<T>&); + %rename(length) size; + unsigned int size() const; + %rename("empty?") empty; + bool empty() const; + %rename("clear!") clear; + void clear(); + %rename("set!") set; + %rename("pop!") pop; + %rename("push!") push_back; + void push_back(const T& x); + %extend { + T pop() throw (std::out_of_range) { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T& ref(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + return (*self)[i]; + else + throw std::out_of_range("vector index out of range"); + } + void set(int i, const T& x) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + (*self)[i] = x; + else + throw std::out_of_range("vector index out of range"); + } + } + }; + + + // specializations for built-ins + %define specialize_stl_vector(T,CHECK,CONVERT_FROM,CONVERT_TO) + template<> class vector<T > { + %typemap(in) vector<T > { + if (gh_vector_p($input)) { + unsigned long size = gh_vector_length($input); + $1 = std::vector<T >(size); + for (unsigned long i=0; i<size; i++) { + SCM o = gh_vector_ref($input,gh_ulong2scm(i)); + if (CHECK(o)) + (($1_type &)$1)[i] = (T)(CONVERT_FROM(o)); + else + scm_wrong_type_arg(FUNC_NAME, $argnum, $input); + } + } else if (gh_null_p($input)) { + $1 = std::vector<T >(); + } else if (gh_pair_p($input)) { + SCM v = gh_list_to_vector($input); + unsigned long size = gh_vector_length(v); + $1 = std::vector<T >(size); + for (unsigned long i=0; i<size; i++) { + SCM o = gh_vector_ref(v,gh_ulong2scm(i)); + if (CHECK(o)) + (($1_type &)$1)[i] = (T)(CONVERT_FROM(o)); + else + scm_wrong_type_arg(FUNC_NAME, $argnum, $input); + } + } else { + $1 = *(($&1_type) + SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); + } + } + %typemap(in) const vector<T >& (std::vector<T > temp), + const vector<T >* (std::vector<T > temp) { + if (gh_vector_p($input)) { + unsigned long size = gh_vector_length($input); + temp = std::vector<T >(size); + $1 = &temp; + for (unsigned long i=0; i<size; i++) { + SCM o = gh_vector_ref($input,gh_ulong2scm(i)); + if (CHECK(o)) + temp[i] = (T)(CONVERT_FROM(o)); + else + scm_wrong_type_arg(FUNC_NAME, $argnum, $input); + } + } else if (gh_null_p($input)) { + temp = std::vector<T >(); + $1 = &temp; + } else if (gh_pair_p($input)) { + SCM v = gh_list_to_vector($input); + unsigned long size = gh_vector_length(v); + temp = std::vector<T >(size); + $1 = &temp; + for (unsigned long i=0; i<size; i++) { + SCM o = gh_vector_ref(v,gh_ulong2scm(i)); + if (CHECK(o)) + temp[i] = (T)(CONVERT_FROM(o)); + else + scm_wrong_type_arg(FUNC_NAME, $argnum, $input); + } + } else { + $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); + } + } + %typemap(out) vector<T > { + $result = gh_make_vector(gh_long2scm($1.size()),SCM_UNSPECIFIED); + for (unsigned int i=0; i<$1.size(); i++) { + SCM x = CONVERT_TO((($1_type &)$1)[i]); + gh_vector_set_x($result,gh_long2scm(i),x); + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) vector<T > { + /* native sequence? */ + if (gh_vector_p($input)) { + unsigned int size = gh_vector_length($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + SCM o = gh_vector_ref($input,gh_ulong2scm(0)); + $1 = CHECK(o) ? 1 : 0; + } + } else if (gh_null_p($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (gh_pair_p($input)) { + /* check the first element only */ + T* x; + SCM head = gh_car($input); + $1 = CHECK(head) ? 1 : 0; + } else { + /* wrapped vector? */ + std::vector<T >* v; + $1 = (SWIG_ConvertPtr($input,(void **) &v, + $&1_descriptor, 0) != -1) ? 1 : 0; + } + } + %typecheck(SWIG_TYPECHECK_VECTOR) const vector<T >&, + const vector<T >* { + /* native sequence? */ + if (gh_vector_p($input)) { + unsigned int size = gh_vector_length($input); + if (size == 0) { + /* an empty sequence can be of any type */ + $1 = 1; + } else { + /* check the first element only */ + T* x; + SCM o = gh_vector_ref($input,gh_ulong2scm(0)); + $1 = CHECK(o) ? 1 : 0; + } + } else if (gh_null_p($input)) { + /* again, an empty sequence can be of any type */ + $1 = 1; + } else if (gh_pair_p($input)) { + /* check the first element only */ + T* x; + SCM head = gh_car($input); + $1 = CHECK(head) ? 1 : 0; + } else { + /* wrapped vector? */ + std::vector<T >* v; + $1 = (SWIG_ConvertPtr($input,(void **) &v, + $1_descriptor, 0) != -1) ? 1 : 0; + } + } + public: + vector(unsigned int size = 0); + vector(unsigned int size, const T& value); + vector(const vector<T >&); + %rename(length) size; + unsigned int size() const; + %rename("empty?") empty; + bool empty() const; + %rename("clear!") clear; + void clear(); + %rename("set!") set; + %rename("pop!") pop; + %rename("push!") push_back; + void push_back(T x); + %extend { + T pop() throw (std::out_of_range) { + if (self->size() == 0) + throw std::out_of_range("pop from empty vector"); + T x = self->back(); + self->pop_back(); + return x; + } + T ref(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + return (*self)[i]; + else + throw std::out_of_range("vector index out of range"); + } + void set(int i, T x) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && i<size) + (*self)[i] = x; + else + throw std::out_of_range("vector index out of range"); + } + } + }; + %enddef + + specialize_stl_vector(bool,gh_boolean_p,gh_scm2bool,SWIG_bool2scm); + specialize_stl_vector(char,gh_number_p,gh_scm2long,gh_long2scm); + specialize_stl_vector(int,gh_number_p,gh_scm2long,gh_long2scm); + specialize_stl_vector(long,gh_number_p,gh_scm2long,gh_long2scm); + specialize_stl_vector(short,gh_number_p,gh_scm2long,gh_long2scm); + specialize_stl_vector(unsigned char,gh_number_p,gh_scm2ulong,gh_ulong2scm); + specialize_stl_vector(unsigned int,gh_number_p,gh_scm2ulong,gh_ulong2scm); + specialize_stl_vector(unsigned long,gh_number_p,gh_scm2ulong,gh_ulong2scm); + specialize_stl_vector(unsigned short,gh_number_p,gh_scm2ulong,gh_ulong2scm); + specialize_stl_vector(float,gh_number_p,gh_scm2double,gh_double2scm); + specialize_stl_vector(double,gh_number_p,gh_scm2double,gh_double2scm); + specialize_stl_vector(std::string,gh_string_p,SWIG_scm2string,SWIG_string2scm); + specialize_stl_vector(std::complex<float>, scm_is_complex, + SWIG_scm2cmplxfloat, SWIG_cmplxfloat2scm); + specialize_stl_vector(std::complex<double>, scm_is_complex, + SWIG_scm2cmplxdouble,SWIG_cmplxdouble2scm); + +} + diff --git a/gnuradio-core/src/python/Makefile.am b/gnuradio-core/src/python/Makefile.am index e50af8944..a90aaba5c 100644 --- a/gnuradio-core/src/python/Makefile.am +++ b/gnuradio-core/src/python/Makefile.am @@ -21,9 +21,10 @@ include $(top_srcdir)/Makefile.common +if PYTHON SUBDIRS = gnuradio bin noinst_PYTHON = \ build_utils.py \ build_utils_codes.py - +endif diff --git a/gnuradio-core/src/python/bin/Makefile.am b/gnuradio-core/src/python/bin/Makefile.am index 0afd32767..6f9f162f1 100644 --- a/gnuradio-core/src/python/bin/Makefile.am +++ b/gnuradio-core/src/python/bin/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2005,2009 Free Software Foundation, Inc. +# Copyright 2005,2009,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,7 +22,7 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST = microtune.py +EXTRA_DIST += microtune.py noinst_SCRIPTS = \ microtune.py diff --git a/gnuradio-core/src/python/gnuradio/Makefile.am b/gnuradio-core/src/python/gnuradio/Makefile.am index a3f3518de..30b5d02ab 100644 --- a/gnuradio-core/src/python/gnuradio/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2007,2008,2009,2010 Free Software Foundation, Inc. +# Copyright 2004-2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -26,13 +26,10 @@ SUBDIRS = gr gru gruimpl blks2 blks2impl vocoder grpython_PYTHON = \ __init__.py \ - audio.py \ eng_notation.py \ eng_option.py \ - modulation_utils.py \ modulation_utils2.py \ ofdm_packet_utils.py \ - packet_utils.py \ gr_unittest.py \ gr_xmlrunner.py \ optfir.py \ diff --git a/gnuradio-core/src/python/gnuradio/audio.py b/gnuradio-core/src/python/gnuradio/audio.py deleted file mode 100644 index f6e921f0e..000000000 --- a/gnuradio-core/src/python/gnuradio/audio.py +++ /dev/null @@ -1,88 +0,0 @@ -# -# Copyright 2004,2006 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. -# - -""" -This is the 'generic' audio or soundcard interface. - -The behavior of this module is controlled by the [audio] audio_module -configuration parameter. If it is 'auto' we attempt to import modules -from the known_modules list, using the first one imported successfully. - -If [audio] audio_module is not 'auto', we assume it's the name of -an audio module and attempt to import it. -""" - -__all__ = ['source', 'sink'] - -from gnuradio import gr -import sys - -source = None -sink = None - - -known_modules = ( - 'audio_alsa', 'audio_oss', 'audio_osx', 'audio_jack', 'audio_portaudio', 'audio_windows') - - -def try_import(name): - """ - Build a blob of code and try to execute it. - If it succeeds we will have set the globals source and sink - as side effects. - - returns True or False - """ - global source, sink - full_name = "gnuradio." + name - code = """ -import %s -source = %s.source -sink = %s.sink -""" % (full_name, full_name, full_name) - try: - exec code in globals() - return True - except ImportError: - return False - - -def __init__ (): - p = gr.prefs() # get preferences (config file) object - verbose = p.get_bool('audio', 'verbose', False) - module = p.get_string('audio', 'audio_module', 'auto') - - if module == 'auto': # search our list for the first one that we can import - for m in known_modules: - if try_import(m): - if verbose: sys.stderr.write('audio: using %s\n' % (m,)) - return - raise ImportError, 'Unable to locate an audio module.' - - else: # use the one the user specified - if try_import(module): - if verbose: sys.stderr.write('audio: using %s\n' % (module,)) - else: - msg = 'Failed to import user-specified audio module %s' % (module,) - if verbose: sys.stderr.write('audio: %s\n' % (msg,)) - raise ImportError, msg - -__init__() diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am b/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am index 7b24fb69d..9665dde0b 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/blks2impl/Makefile.am @@ -30,17 +30,10 @@ grblkspython_PYTHON = \ __init__.py \ am_demod.py \ channel_model.py \ - dbpsk.py \ - dbpsk2.py \ - dqpsk.py \ - dqpsk2.py \ - d8psk.py \ filterbank.py \ fm_demod.py \ fm_emph.py \ generic_usrp.py \ - gmsk.py \ - cpm.py \ logpwrfft.py \ nbfm_rx.py \ nbfm_tx.py \ @@ -54,13 +47,8 @@ grblkspython_PYTHON = \ pfb_channelizer.py \ pfb_decimator.py \ pfb_interpolator.py \ - pkt.py \ psk.py \ qam.py \ - qam8.py \ - qam16.py \ - qam64.py \ - qam256.py \ rational_resampler.py \ standard_squelch.py \ stream_to_vector_decimator.py \ diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/cpm.py b/gnuradio-core/src/python/gnuradio/blks2impl/cpm.py deleted file mode 100644 index 8f593cd51..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/cpm.py +++ /dev/null @@ -1,249 +0,0 @@ -# -# CPM modulation and demodulation. -# -# -# Copyright 2005,2006,2007 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. -# - -# See gnuradio-examples/python/digital for examples - -from gnuradio import gr -from gnuradio import modulation_utils -from math import pi -import numpy -from pprint import pprint -import inspect - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_bits_per_symbol = 1 -_def_h_numerator = 1 -_def_h_denominator = 2 -_def_cpm_type = 0 # 0=CPFSK, 1=GMSK, 2=RC, 3=GENERAL -_def_bt = 0.35 -_def_symbols_per_pulse = 1 -_def_generic_taps = numpy.empty(1) -_def_verbose = False -_def_log = False - - -# ///////////////////////////////////////////////////////////////////////////// -# CPM modulator -# ///////////////////////////////////////////////////////////////////////////// - -class cpm_mod(gr.hier_block2): - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - bits_per_symbol=_def_bits_per_symbol, - h_numerator=_def_h_numerator, - h_denominator=_def_h_denominator, - cpm_type=_def_cpm_type, - bt=_def_bt, - symbols_per_pulse=_def_symbols_per_pulse, - generic_taps=_def_generic_taps, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for Continuous Phase - modulation. - - The input is a byte stream (unsigned char) - representing packed bits and the - output is the complex modulated signal at baseband. - - See Proakis for definition of generic CPM signals: - s(t)=exp(j phi(t)) - phi(t)= 2 pi h int_0^t f(t') dt' - f(t)=sum_k a_k g(t-kT) - (normalizing assumption: int_0^infty g(t) dt = 1/2) - - @param samples_per_symbol: samples per baud >= 2 - @type samples_per_symbol: integer - @param bits_per_symbol: bits per symbol - @type bits_per_symbol: integer - @param h_numerator: numerator of modulation index - @type h_numerator: integer - @param h_denominator: denominator of modulation index (numerator and denominator must be relative primes) - @type h_denominator: integer - @param cpm_type: supported types are: 0=CPFSK, 1=GMSK, 2=RC, 3=GENERAL - @type cpm_type: integer - @param bt: bandwidth symbol time product for GMSK - @type bt: float - @param symbols_per_pulse: shaping pulse duration in symbols - @type symbols_per_pulse: integer - @param generic_taps: define a generic CPM pulse shape (sum = samples_per_symbol/2) - @type generic_taps: array of floats - - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modulation data to files? - @type debug: bool - """ - - gr.hier_block2.__init__("cpm_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._bits_per_symbol = bits_per_symbol - self._h_numerator = h_numerator - self._h_denominator = h_denominator - self._cpm_type = cpm_type - self._bt=bt - if cpm_type == 0 or cpm_type == 2 or cpm_type == 3: # CPFSK, RC, Generic - self._symbols_per_pulse = symbols_per_pulse - elif cpm_type == 1: # GMSK - self._symbols_per_pulse = 4 - else: - raise TypeError, ("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,)) - - self._generic_taps=numpy.array(generic_taps) - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("samples_per_symbol must be an integer >= 2, is %r" % (samples_per_symbol,)) - - self.nsymbols = 2**bits_per_symbol - self.sym_alphabet=numpy.arange(-(self.nsymbols-1),self.nsymbols,2) - - - self.ntaps = self._symbols_per_pulse * samples_per_symbol - sensitivity = 2 * pi * h_numerator / h_denominator / samples_per_symbol - - # Unpack Bytes into bits_per_symbol groups - self.B2s = gr.packed_to_unpacked_bb(bits_per_symbol,gr.GR_MSB_FIRST) - - - # Turn it into symmetric PAM data. - self.pam = gr.chunks_to_symbols_bf(self.sym_alphabet,1) - - # Generate pulse (sum of taps = samples_per_symbol/2) - if cpm_type == 0: # CPFSK - self.taps= (1.0/self._symbols_per_pulse/2,) * self.ntaps - elif cpm_type == 1: # GMSK - gaussian_taps = gr.firdes.gaussian( - 1.0/2, # gain - samples_per_symbol, # symbol_rate - bt, # bandwidth * symbol time - self.ntaps # number of taps - ) - sqwave = (1,) * samples_per_symbol # rectangular window - self.taps = numpy.convolve(numpy.array(gaussian_taps),numpy.array(sqwave)) - elif cpm_type == 2: # Raised Cosine - # generalize it for arbitrary roll-off factor - self.taps = (1-numpy.cos(2*pi*numpy.arange(0,self.ntaps)/samples_per_symbol/self._symbols_per_pulse))/(2*self._symbols_per_pulse) - elif cpm_type == 3: # Generic CPM - self.taps = generic_taps - else: - raise TypeError, ("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,)) - - self.filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) - - # FM modulation - self.fmmod = gr.frequency_modulator_fc(sensitivity) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.B2s, self.pam, self.filter, self.fmmod, self) - - #def samples_per_symbol(self): - #return self._samples_per_symbol - - #def bits_per_symbol(self): - #return self._bits_per_symbol - - #def h_numerator(self): - #return self._h_numerator - - #def h_denominator(self): - #return self._h_denominator - - #def cpm_type(self): - #return self._cpm_type - - #def bt(self): - #return self._bt - - #def symbols_per_pulse(self): - #return self._symbols_per_pulse - - - def _print_verbage(self): - print "Samples per symbol = %d" % self._samples_per_symbol - print "Bits per symbol = %d" % self._bits_per_symbol - print "h = " , self._h_numerator , " / " , self._h_denominator - print "Symbol alphabet = " , self.sym_alphabet - print "Symbols per pulse = %d" % self._symbols_per_pulse - print "taps = " , self.taps - - print "CPM type = %d" % self._cpm_type - if self._cpm_type == 1: - print "Gaussian filter BT = %.2f" % self._bt - - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.B2s, - gr.file_sink(gr.sizeof_float, "symbols.dat")) - self.connect(self.pam, - gr.file_sink(gr.sizeof_float, "pam.dat")) - self.connect(self.filter, - gr.file_sink(gr.sizeof_float, "filter.dat")) - self.connect(self.fmmod, - gr.file_sink(gr.sizeof_gr_complex, "fmmod.dat")) - - - def add_options(parser): - """ - Adds CPM modulation-specific options to the standard parser - """ - parser.add_option("", "--bt", type="float", default=_def_bt, - help="set bandwidth-time product [default=%default] (GMSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(cpm_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - - -# ///////////////////////////////////////////////////////////////////////////// -# CPM demodulator -# ///////////////////////////////////////////////////////////////////////////// -# -# Not yet implemented -# - - - -# -# Add these to the mod/demod registry -# -modulation_utils.add_type_1_mod('cpm', cpm_mod) -#modulation_utils.add_type_1_demod('cpm', cpm_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/d8psk.py b/gnuradio-core/src/python/gnuradio/blks2impl/d8psk.py deleted file mode 100644 index 67cf9f569..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/d8psk.py +++ /dev/null @@ -1,363 +0,0 @@ -# -# Copyright 2005,2006,2007 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential 8PSK modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 3 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = 0.175 -_def_gain_mu = 0.175 -_def_mu = 0.5 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# D8PSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class d8psk_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "d8psk_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 3 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RS roll-off factor = %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - def add_options(parser): - """ - Adds 8PSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(d8psk_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# D8PSK demodulator -# -# Differentially coherent detection of differentially encoded 8psk -# ///////////////////////////////////////////////////////////////////////////// - -class d8psk_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered DQPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param costas_alpha: loop filter gain - @type costas_alphas: float - @param gain_mu: for M&M block - @type gain_mu: float - @param mu: for M&M block - @type mu: float - @param omega_relative_limit: for M&M block - @type omega_relative_limit: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "d8psk_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(1, 1, gr.sizeof_char)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._costas_alpha = costas_alpha - self._mm_gain_mu = gain_mu - self._mm_mu = mu - self._mm_omega_relative_limit = omega_relative_limit - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "sbp must be >= 2, is %d" % samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - scale = (1.0/16384.0) - self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1 - #self.agc = gr.agc_cc(1e-2, 1, 1, 100) - self.agc = gr.agc2_cc(1e-1, 1e-2, 1, 1, 100) - #self.agc = gr.feedforward_agc_cc(16, 1.0) - - # RRC data filter - ntaps = 11 * samples_per_symbol - self.rrc_taps = gr.firdes.root_raised_cosine( - 1.0, # gain - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter=gr.interp_fir_filter_ccf(1, self.rrc_taps) - - # symbol clock recovery - self._mm_omega = self._samples_per_symbol - self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu - self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - fmin = -0.025 - fmax = 0.025 - - self.receiver=gr.mpsk_receiver_cc(arity, 0, - self._costas_alpha, self._costas_beta, - fmin, fmax, - self._mm_mu, self._mm_gain_mu, - self._mm_omega, self._mm_gain_omega, - self._mm_omega_relative_limit) - - # Perform Differential decoding on the constellation - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity)) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 3 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "Costas Loop alpha: %.2e" % self._costas_alpha - print "Costas Loop beta: %.2e" % self._costas_beta - print "M&M mu: %.2f" % self._mm_mu - print "M&M mu gain: %.2e" % self._mm_gain_mu - print "M&M omega: %.2f" % self._mm_omega - print "M&M omega gain: %.2e" % self._mm_gain_omega - print "M&M omega limit: %.2f" % self._mm_omega_relative_limit - - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.pre_scaler, - gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) - self.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) - self.connect(self.receiver, - gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) - self.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat")) - self.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--costas-alpha", type="float", default=_def_costas_alpha, - help="set Costas loop alpha value [default=%default] (PSK)") - parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, - help="set M&M symbol sync loop gain mu value [default=%default] (PSK)") - parser.add_option("", "--mu", type="float", default=_def_mu, - help="set M&M symbol sync loop mu value [default=%default] (PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options( - d8psk_demod.__init__, ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# -# Add these to the mod/demod registry -# -# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -modulation_utils.add_type_1_mod('d8psk', d8psk_mod) -modulation_utils.add_type_1_demod('d8psk', d8psk_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py deleted file mode 100644 index 55e4890f3..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk.py +++ /dev/null @@ -1,363 +0,0 @@ -# -# Copyright 2005,2006,2007,2009 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential BPSK modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = 0.1 -_def_gain_mu = None -_def_mu = 0.5 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# DBPSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class dbpsk_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered differential BPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per baud >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Log modulation data to files? - @type log: bool - """ - - gr.hier_block2.__init__(self, "dbpsk_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(self._samples_per_symbol, int) or self._samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol) - - ntaps = 11 * self._samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - self.chunks2symbols = gr.chunks_to_symbols_bc(psk.constellation[arity]) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (samples_per_symbol since we're - # interpolating by samples_per_symbol) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, - self.rrc_taps) - - # Connect - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # static method that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def add_options(parser): - """ - Adds DBPSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default]") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=True, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(dbpsk_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - - def _print_verbage(self): - print "\nModulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - -# ///////////////////////////////////////////////////////////////////////////// -# DBPSK demodulator -# -# Differentially coherent detection of differentially encoded BPSK -# ///////////////////////////////////////////////////////////////////////////// - -class dbpsk_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered differential BPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param costas_alpha: loop filter gain - @type costas_alphas: float - @param gain_mu: for M&M block - @type gain_mu: float - @param mu: for M&M block - @type mu: float - @param omega_relative_limit: for M&M block - @type omega_relative_limit: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "dbpsk_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(1, 1, gr.sizeof_char)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._costas_alpha = costas_alpha - self._mm_gain_mu = gain_mu - self._mm_mu = mu - self._mm_omega_relative_limit = omega_relative_limit - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "samples_per_symbol must be >= 2, is %r" % (samples_per_symbol,) - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - #scale = (1.0/16384.0) - #self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1 - self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - #self.agc = gr.feedforward_agc_cc(16, 2.0) - - # RRC data filter - ntaps = 11 * samples_per_symbol - self.rrc_taps = gr.firdes.root_raised_cosine( - 1.0, # gain - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter=gr.interp_fir_filter_ccf(1, self.rrc_taps) - - # symbol clock recovery - if not self._mm_gain_mu: - self._mm_gain_mu = 0.1 - - self._mm_omega = self._samples_per_symbol - self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu - self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - fmin = -0.25 - fmax = 0.25 - - self.receiver=gr.mpsk_receiver_cc(arity, 0, - self._costas_alpha, self._costas_beta, - fmin, fmax, - self._mm_mu, self._mm_gain_mu, - self._mm_omega, self._mm_gain_omega, - self._mm_omega_relative_limit) - - # Do differential decoding based on phase change of symbols - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity)) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect and Initialize base class - self.connect(self, self.agc, self.rrc_filter, self.receiver, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "Costas Loop alpha: %.2e" % self._costas_alpha - print "Costas Loop beta: %.2e" % self._costas_beta - print "M&M mu: %.2f" % self._mm_mu - print "M&M mu gain: %.2e" % self._mm_gain_mu - print "M&M omega: %.2f" % self._mm_omega - print "M&M omega gain: %.2e" % self._mm_gain_omega - print "M&M omega limit: %.2f" % self._mm_omega_relative_limit - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.pre_scaler, - gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) - self.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) - self.connect(self.receiver, - gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) - self.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat")) - self.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds DBPSK demodulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--costas-alpha", type="float", default=None, - help="set Costas loop alpha value [default=%default] (PSK)") - parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, - help="set M&M symbol sync loop gain mu value [default=%default] (GMSK/PSK)") - parser.add_option("", "--mu", type="float", default=_def_mu, - help="set M&M symbol sync loop mu value [default=%default] (GMSK/PSK)") - parser.add_option("", "--omega-relative-limit", type="float", default=_def_omega_relative_limit, - help="M&M clock recovery omega relative limit [default=%default] (GMSK/PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options( - dbpsk_demod.__init__, ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) -# -# Add these to the mod/demod registry -# -modulation_utils.add_type_1_mod('dbpsk', dbpsk_mod) -modulation_utils.add_type_1_demod('dbpsk', dbpsk_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py deleted file mode 100644 index d7bcf5390..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/dbpsk2.py +++ /dev/null @@ -1,369 +0,0 @@ -# -# Copyright 2009,2010 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential BPSK modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils2 -from math import pi, sqrt, ceil -import psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_freq_alpha = 0.010 -_def_phase_alpha = 0.1 -_def_timing_alpha = 0.100 -_def_timing_beta = 0.010 -_def_timing_max_dev = 1.5 - - -# ///////////////////////////////////////////////////////////////////////////// -# DBPSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class dbpsk2_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered differential BPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per baud >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Log modulation data to files? - @type log: bool - """ - - gr.hier_block2.__init__(self, "dbpsk_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if self._samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol) - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - self.chunks2symbols = gr.chunks_to_symbols_bc(psk.constellation[arity]) - - # pulse shaping filter - nfilts = 32 - ntaps = nfilts * 11 * int(self._samples_per_symbol) # make nfilts filters of ntaps each - self.rrc_taps = gr.firdes.root_raised_cosine( - nfilts, # gain - nfilts, # sampling rate based on 32 filters in resampler - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) - - # Connect - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # static method that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def add_options(parser): - """ - Adds DBPSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default]") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=True, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils2.extract_kwargs_from_options(dbpsk2_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - - def _print_verbage(self): - print "\nModulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - -# ///////////////////////////////////////////////////////////////////////////// -# DBPSK demodulator -# -# Differentially coherent detection of differentially encoded BPSK -# ///////////////////////////////////////////////////////////////////////////// - -class dbpsk2_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - freq_alpha=_def_freq_alpha, - phase_alpha=_def_phase_alpha, - timing_alpha=_def_timing_alpha, - timing_max_dev=_def_timing_max_dev, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log, - sync_out=False): - """ - Hierarchical block for RRC-filtered differential BPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param freq_alpha: loop filter gain for frequency recovery - @type freq_alpha: float - @param phase_alpha: loop filter gain for phase/fine frequency recovery - @type phase_alpha: float - @param timing_alpha: loop alpha gain for timing recovery - @type timing_alpha: float - @param timing_max: timing loop maximum rate deviations - @type timing_max: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Print modualtion data to files? - @type log: bool - @param sync_out: Output a sync signal on :1? - @type sync_out: bool - """ - if sync_out: io_sig_out = gr.io_signaturev(2, 2, (gr.sizeof_char, gr.sizeof_gr_complex)) - else: io_sig_out = gr.io_signature(1, 1, gr.sizeof_char) - - gr.hier_block2.__init__(self, "dqpsk2_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - io_sig_out) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._freq_alpha = freq_alpha - self._freq_beta = 0.10*self._freq_alpha - self._phase_alpha = phase_alpha - self._timing_alpha = timing_alpha - self._timing_beta = _def_timing_beta - self._timing_max_dev=timing_max_dev - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "samples_per_symbol must be >= 2, is %r" % (samples_per_symbol,) - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - #self.agc = gr.feedforward_agc_cc(16, 1.0) - - # Frequency correction - self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw, - 11*int(self._samples_per_symbol), - self._freq_alpha, self._freq_beta) - - # symbol timing recovery with RRC data filter - nfilts = 32 - ntaps = 11 * int(self._samples_per_symbol*nfilts) - taps = gr.firdes.root_raised_cosine(nfilts, nfilts, - 1.0/float(self._samples_per_symbol), - self._excess_bw, ntaps) - self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol, - self._timing_alpha, - taps, nfilts, nfilts/2, self._timing_max_dev) - self.time_recov.set_beta(self._timing_beta) - - # Perform phase / fine frequency correction - self._phase_beta = 0.25 * self._phase_alpha * self._phase_alpha - # Allow a frequency swing of +/- half of the sample rate - fmin = -0.5 - fmax = 0.5 - - self.phase_recov = gr.costas_loop_cc(self._phase_alpha, - self._phase_beta, - fmax, fmin, arity) - - # Do differential decoding based on phase change of symbols - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity)) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.agc, - self.freq_recov, self.time_recov, self.phase_recov, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) - if sync_out: self.connect(self.time_recov, (self, 1)) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "FLL gain: %.2e" % self._freq_alpha - print "Timing alpha gain: %.2e" % self._timing_alpha - print "Timing beta gain: %.2e" % self._timing_beta - print "Timing max dev: %.2f" % self._timing_max_dev - print "Phase track alpha: %.2e" % self._phase_alpha - print "Phase track beta: %.2e" % self._phase_beta - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.freq_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.dat")) - self.connect(self.time_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.dat")) - self.connect(self.phase_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_phase_recov.dat")) - self.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat")) - self.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds DBPSK demodulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha, - help="set frequency lock loop alpha gain value [default=%default] (PSK)") - parser.add_option("", "--phase-alpha", type="float", default=_def_phase_alpha, - help="set phase tracking loop alpha value [default=%default] (PSK)") - parser.add_option("", "--timing-alpha", type="float", default=_def_timing_alpha, - help="set timing symbol sync loop gain alpha value [default=%default] (GMSK/PSK)") - parser.add_option("", "--timing-beta", type="float", default=_def_timing_beta, - help="set timing symbol sync loop gain beta value [default=%default] (GMSK/PSK)") - parser.add_option("", "--timing-max-dev", type="float", default=_def_timing_max_dev, - help="set timing symbol sync loop maximum deviation [default=%default] (GMSK/PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils2.extract_kwargs_from_options( - dbpsk2_demod.__init__, ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) -# -# Add these to the mod/demod registry -# -modulation_utils2.add_type_1_mod('dbpsk2', dbpsk2_mod) -modulation_utils2.add_type_1_demod('dbpsk2', dbpsk2_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk.py b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk.py deleted file mode 100644 index 42d534168..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk.py +++ /dev/null @@ -1,363 +0,0 @@ -# -# Copyright 2005,2006,2007,2009 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential QPSK modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = 0.15 -_def_gain_mu = None -_def_mu = 0.5 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# DQPSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class dqpsk_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "dqpsk_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = .707 + .707j - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 2 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nModulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRS roll-off factor: %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - def add_options(parser): - """ - Adds QPSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(dqpsk_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# DQPSK demodulator -# -# Differentially coherent detection of differentially encoded qpsk -# ///////////////////////////////////////////////////////////////////////////// - -class dqpsk_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered DQPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param costas_alpha: loop filter gain - @type costas_alphas: float - @param gain_mu: for M&M block - @type gain_mu: float - @param mu: for M&M block - @type mu: float - @param omega_relative_limit: for M&M block - @type omega_relative_limit: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "dqpsk_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(1, 1, gr.sizeof_char)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._costas_alpha = costas_alpha - self._mm_gain_mu = gain_mu - self._mm_mu = mu - self._mm_omega_relative_limit = omega_relative_limit - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "sbp must be >= 2, is %d" % samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - scale = (1.0/16384.0) - self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1 - #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - self.agc = gr.feedforward_agc_cc(16, 2.0) - - # RRC data filter - ntaps = 11 * samples_per_symbol - self.rrc_taps = gr.firdes.root_raised_cosine( - 1.0, # gain - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter=gr.interp_fir_filter_ccf(1, self.rrc_taps) - - if not self._mm_gain_mu: - sbs_to_mm = {2: 0.050, 3: 0.075, 4: 0.11, 5: 0.125, 6: 0.15, 7: 0.15} - self._mm_gain_mu = sbs_to_mm[samples_per_symbol] - - self._mm_omega = self._samples_per_symbol - self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu - self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - fmin = -0.25 - fmax = 0.25 - - self.receiver=gr.mpsk_receiver_cc(arity, pi/4.0, - self._costas_alpha, self._costas_beta, - fmin, fmax, - self._mm_mu, self._mm_gain_mu, - self._mm_omega, self._mm_gain_omega, - self._mm_omega_relative_limit) - - # Perform Differential decoding on the constellation - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity)) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self.connect(self, self.pre_scaler, self.agc, self.rrc_filter, self.receiver, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 2 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "Costas Loop alpha: %.2e" % self._costas_alpha - print "Costas Loop beta: %.2e" % self._costas_beta - print "M&M mu: %.2f" % self._mm_mu - print "M&M mu gain: %.2e" % self._mm_gain_mu - print "M&M omega: %.2f" % self._mm_omega - print "M&M omega gain: %.2e" % self._mm_gain_omega - print "M&M omega limit: %.2f" % self._mm_omega_relative_limit - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.pre_scaler, - gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) - self.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) - self.connect(self.receiver, - gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) - self.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat")) - self.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--costas-alpha", type="float", default=_def_costas_alpha, - help="set Costas loop alpha value [default=%default] (PSK)") - parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, - help="set M&M symbol sync loop gain mu value [default=%default] (PSK)") - parser.add_option("", "--mu", type="float", default=_def_mu, - help="set M&M symbol sync loop mu value [default=%default] (PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options( - dqpsk_demod.__init__, ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# -# Add these to the mod/demod registry -# -modulation_utils.add_type_1_mod('dqpsk', dqpsk_mod) -modulation_utils.add_type_1_demod('dqpsk', dqpsk_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py b/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py deleted file mode 100644 index e1e627707..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/dqpsk2.py +++ /dev/null @@ -1,377 +0,0 @@ -# -# Copyright 2009,2010 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential QPSK modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils2 -from math import pi, sqrt -import psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_freq_alpha = 0.010 -_def_phase_alpha = 0.01 -_def_timing_alpha = 0.100 -_def_timing_beta = 0.010 -_def_timing_max_dev = 1.5 - - -# ///////////////////////////////////////////////////////////////////////////// -# DQPSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class dqpsk2_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "dqpsk2_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, ("sbp must be >= 2, is %f" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = .707 + .707j - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - nfilts = 32 - ntaps = 11 * int(nfilts * self._samples_per_symbol) # make nfilts filters of ntaps each - self.rrc_taps = gr.firdes.root_raised_cosine( - nfilts, # gain - nfilts, # sampling rate based on 32 filters in resampler - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter = gr.pfb_arb_resampler_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 2 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nModulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRS roll-off factor: %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - def add_options(parser): - """ - Adds QPSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils2.extract_kwargs_from_options(dqpsk2_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# DQPSK demodulator -# -# Differentially coherent detection of differentially encoded qpsk -# ///////////////////////////////////////////////////////////////////////////// - -class dqpsk2_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - freq_alpha=_def_freq_alpha, - phase_alpha=_def_phase_alpha, - timing_alpha=_def_timing_alpha, - timing_max_dev=_def_timing_max_dev, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log, - sync_out=False): - """ - Hierarchical block for RRC-filtered DQPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param freq_alpha: loop filter gain for frequency recovery - @type freq_alpha: float - @param phase_alpha: loop filter gain - @type phase_alphas: float - @param timing_alpha: timing loop alpha gain - @type timing_alpha: float - @param timing_max: timing loop maximum rate deviations - @type timing_max: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Print modualtion data to files? - @type log: bool - @param sync_out: Output a sync signal on :1? - @type sync_out: bool - """ - if sync_out: io_sig_out = gr.io_signaturev(2, 2, (gr.sizeof_char, gr.sizeof_gr_complex)) - else: io_sig_out = gr.io_signature(1, 1, gr.sizeof_char) - - gr.hier_block2.__init__(self, "dqpsk2_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - io_sig_out) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._freq_alpha = freq_alpha - self._freq_beta = 0.25*self._freq_alpha**2 - self._phase_alpha = phase_alpha - self._timing_alpha = timing_alpha - self._timing_beta = _def_timing_beta - self._timing_max_dev=timing_max_dev - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "sbp must be >= 2, is %d" % samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - #self.agc = gr.feedforward_agc_cc(16, 2.0) - - # Frequency correction - self.freq_recov = gr.fll_band_edge_cc(self._samples_per_symbol, self._excess_bw, - 11*int(self._samples_per_symbol), - self._freq_alpha, self._freq_beta) - - - # symbol timing recovery with RRC data filter - nfilts = 32 - ntaps = 11 * int(samples_per_symbol*nfilts) - taps = gr.firdes.root_raised_cosine(nfilts, nfilts, - 1.0/float(self._samples_per_symbol), - self._excess_bw, ntaps) - self.time_recov = gr.pfb_clock_sync_ccf(self._samples_per_symbol, - self._timing_alpha, - taps, nfilts, nfilts/2, self._timing_max_dev) - self.time_recov.set_beta(self._timing_beta) - - - # Perform phase / fine frequency correction - self._phase_beta = 0.25 * self._phase_alpha * self._phase_alpha - # Allow a frequency swing of +/- half of the sample rate - fmin = -0.5 - fmax = 0.5 - - self.phase_recov = gr.costas_loop_cc(self._phase_alpha, - self._phase_beta, - fmax, fmin, arity) - - - # Perform Differential decoding on the constellation - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity)) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.agc, - self.freq_recov, self.time_recov, self.phase_recov, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack, self) - if sync_out: self.connect(self.time_recov, (self, 1)) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 2 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "FLL gain: %.2f" % self._freq_alpha - print "Timing alpha gain: %.2f" % self._timing_alpha - print "Timing beta gain: %.2f" % self._timing_beta - print "Timing max dev: %.2f" % self._timing_max_dev - print "Phase track alpha: %.2e" % self._phase_alpha - print "Phase track beta: %.2e" % self._phase_beta - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self.connect(self.freq_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_freq_recov.dat")) - self.connect(self.time_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_time_recov.dat")) - self.connect(self.phase_recov, - gr.file_sink(gr.sizeof_gr_complex, "rx_phase_recov.dat")) - self.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat")) - self.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds DQPSK demodulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--freq-alpha", type="float", default=_def_freq_alpha, - help="set frequency lock loop alpha gain value [default=%default] (PSK)") - parser.add_option("", "--phase-alpha", type="float", default=_def_phase_alpha, - help="set phase tracking loop alpha value [default=%default] (PSK)") - parser.add_option("", "--timing-alpha", type="float", default=_def_timing_alpha, - help="set timing symbol sync loop gain alpha value [default=%default] (GMSK/PSK)") - parser.add_option("", "--timing-beta", type="float", default=_def_timing_beta, - help="set timing symbol sync loop gain beta value [default=%default] (GMSK/PSK)") - parser.add_option("", "--timing-max-dev", type="float", default=_def_timing_max_dev, - help="set timing symbol sync loop maximum deviation [default=%default] (GMSK/PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils2.extract_kwargs_from_options( - dqpsk2_demod.__init__, ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# -# Add these to the mod/demod registry -# -modulation_utils2.add_type_1_mod('dqpsk2', dqpsk2_mod) -modulation_utils2.add_type_1_demod('dqpsk2', dqpsk2_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/gmsk.py b/gnuradio-core/src/python/gnuradio/blks2impl/gmsk.py deleted file mode 100644 index 3b6c016a0..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/gmsk.py +++ /dev/null @@ -1,292 +0,0 @@ -# -# GMSK modulation and demodulation. -# -# -# Copyright 2005,2006,2007 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. -# - -# See gnuradio-examples/python/digital for examples - -from gnuradio import gr -from gnuradio import modulation_utils -from math import pi -import numpy -from pprint import pprint -import inspect - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_bt = 0.35 -_def_verbose = False -_def_log = False - -_def_gain_mu = None -_def_mu = 0.5 -_def_freq_error = 0.0 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# GMSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class gmsk_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - bt=_def_bt, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for Gaussian Minimum Shift Key (GMSK) - modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per baud >= 2 - @type samples_per_symbol: integer - @param bt: Gaussian filter bandwidth * symbol time - @type bt: float - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "gmsk_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._bt = bt - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("samples_per_symbol must be an integer >= 2, is %r" % (samples_per_symbol,)) - - ntaps = 4 * samples_per_symbol # up to 3 bits in filter at once - sensitivity = (pi / 2) / samples_per_symbol # phase change per bit = pi / 2 - - # Turn it into NRZ data. - self.nrz = gr.bytes_to_syms() - - # Form Gaussian filter - # Generate Gaussian response (Needs to be convolved with window below). - self.gaussian_taps = gr.firdes.gaussian( - 1, # gain - samples_per_symbol, # symbol_rate - bt, # bandwidth * symbol time - ntaps # number of taps - ) - - self.sqwave = (1,) * samples_per_symbol # rectangular window - self.taps = numpy.convolve(numpy.array(self.gaussian_taps),numpy.array(self.sqwave)) - self.gaussian_filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) - - # FM modulation - self.fmmod = gr.frequency_modulator_fc(sensitivity) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self.connect(self, self.nrz, self.gaussian_filter, self.fmmod, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. - - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gaussian filter bt = %.2f" % self._bt - - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.nrz, - gr.file_sink(gr.sizeof_float, "nrz.dat")) - self.connect(self.gaussian_filter, - gr.file_sink(gr.sizeof_float, "gaussian_filter.dat")) - self.connect(self.fmmod, - gr.file_sink(gr.sizeof_gr_complex, "fmmod.dat")) - - - def add_options(parser): - """ - Adds GMSK modulation-specific options to the standard parser - """ - parser.add_option("", "--bt", type="float", default=_def_bt, - help="set bandwidth-time product [default=%default] (GMSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(gmsk_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - - -# ///////////////////////////////////////////////////////////////////////////// -# GMSK demodulator -# ///////////////////////////////////////////////////////////////////////////// - -class gmsk_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - freq_error=_def_freq_error, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for Gaussian Minimum Shift Key (GMSK) - demodulation. - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (the LSB) - - @param samples_per_symbol: samples per baud - @type samples_per_symbol: integer - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Print modualtion data to files? - @type log: bool - - Clock recovery parameters. These all have reasonble defaults. - - @param gain_mu: controls rate of mu adjustment - @type gain_mu: float - @param mu: fractional delay [0.0, 1.0] - @type mu: float - @param omega_relative_limit: sets max variation in omega - @type omega_relative_limit: float, typically 0.000200 (200 ppm) - @param freq_error: bit rate error as a fraction - @param float - """ - - gr.hier_block2.__init__(self, "gmsk_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(1, 1, gr.sizeof_char)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._gain_mu = gain_mu - self._mu = mu - self._omega_relative_limit = omega_relative_limit - self._freq_error = freq_error - - if samples_per_symbol < 2: - raise TypeError, "samples_per_symbol >= 2, is %f" % samples_per_symbol - - self._omega = samples_per_symbol*(1+self._freq_error) - - if not self._gain_mu: - self._gain_mu = 0.175 - - self._gain_omega = .25 * self._gain_mu * self._gain_mu # critically damped - - # Demodulate FM - sensitivity = (pi / 2) / samples_per_symbol - self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) - - # the clock recovery block tracks the symbol clock and resamples as needed. - # the output of the block is a stream of soft symbols (float) - self.clock_recovery = gr.clock_recovery_mm_ff(self._omega, self._gain_omega, - self._mu, self._gain_mu, - self._omega_relative_limit) - - # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample - self.slicer = gr.binary_slicer_fb() - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self.connect(self, self.fmdemod, self.clock_recovery, self.slicer, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. - - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "M&M clock recovery omega = %f" % self._omega - print "M&M clock recovery gain mu = %f" % self._gain_mu - print "M&M clock recovery mu = %f" % self._mu - print "M&M clock recovery omega rel. limit = %f" % self._omega_relative_limit - print "frequency error = %f" % self._freq_error - - - def _setup_logging(self): - print "Demodulation logging turned on." - self.connect(self.fmdemod, - gr.file_sink(gr.sizeof_float, "fmdemod.dat")) - self.connect(self.clock_recovery, - gr.file_sink(gr.sizeof_float, "clock_recovery.dat")) - self.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "slicer.dat")) - - def add_options(parser): - """ - Adds GMSK demodulation-specific options to the standard parser - """ - parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, - help="M&M clock recovery gain mu [default=%default] (GMSK/PSK)") - parser.add_option("", "--mu", type="float", default=_def_mu, - help="M&M clock recovery mu [default=%default] (GMSK/PSK)") - parser.add_option("", "--omega-relative-limit", type="float", default=_def_omega_relative_limit, - help="M&M clock recovery omega relative limit [default=%default] (GMSK/PSK)") - parser.add_option("", "--freq-error", type="float", default=_def_freq_error, - help="M&M clock recovery frequency error [default=%default] (GMSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(gmsk_demod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# -# Add these to the mod/demod registry -# -modulation_utils.add_type_1_mod('gmsk', gmsk_mod) -modulation_utils.add_type_1_demod('gmsk', gmsk_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py index 2663f7cf8..3b1cd12ac 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py @@ -21,12 +21,26 @@ # import math -from gnuradio import gr, ofdm_packet_utils +from gnuradio import gr, ofdm_packet_utils, modulation_utils2 import gnuradio.gr.gr_threading as _threading import psk, qam from gnuradio.blks2impl.ofdm_receiver import ofdm_receiver +def _add_common_options(normal, expert): + """ + Adds OFDM-specific options to the Options Parser that are common + both to the modulator and demodulator. + """ + mods_list = ", ".join(modulation_utils2.type_1_constellations().keys()) + normal.add_option("-m", "--modulation", type="string", default="psk", + help="set modulation type (" + mods_list + ") [default=%default]") + expert.add_option("", "--fft-length", type="intx", default=512, + help="set the number of FFT bins [default=%default]") + expert.add_option("", "--occupied-tones", type="intx", default=200, + help="set the number of occupied FFT bins [default=%default]") + expert.add_option("", "--cp-length", type="intx", default=128, + help="set the number of bits in the cyclic prefix [default=%default]") # ///////////////////////////////////////////////////////////////////////////// # mod/demod with packets as i/o @@ -61,6 +75,8 @@ class ofdm_mod(gr.hier_block2): self._fft_length = options.fft_length self._occupied_tones = options.occupied_tones self._cp_length = options.cp_length + + arity = options.constellation_points win = [] #[1 for i in range(self._fft_length)] @@ -82,19 +98,9 @@ class ofdm_mod(gr.hier_block2): symbol_length = options.fft_length + options.cp_length - mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} - arity = mods[self._modulation] - - rot = 1 - if self._modulation == "qpsk": - rot = (0.707+0.707j) - - if(self._modulation.find("psk") >= 0): - rotated_const = map(lambda pt: pt * rot, psk.gray_constellation[arity]) - elif(self._modulation.find("qam") >= 0): - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) - #print rotated_const - self._pkt_input = gr.ofdm_mapper_bcv(rotated_const, msgq_limit, + const = modulation_utils2.type_1_constellations()[self._modulation](arity).points() + + self._pkt_input = gr.ofdm_mapper_bcv(const, msgq_limit, options.occupied_tones, options.fft_length) self.preambles = gr.ofdm_insert_preamble(self._fft_length, padded_preambles) @@ -140,14 +146,10 @@ class ofdm_mod(gr.hier_block2): """ Adds OFDM-specific options to the Options Parser """ - normal.add_option("-m", "--modulation", type="string", default="bpsk", - help="set modulation type (bpsk, qpsk, 8psk, qam{16,64}) [default=%default]") - expert.add_option("", "--fft-length", type="intx", default=512, - help="set the number of FFT bins [default=%default]") - expert.add_option("", "--occupied-tones", type="intx", default=200, - help="set the number of occupied FFT bins [default=%default]") - expert.add_option("", "--cp-length", type="intx", default=128, - help="set the number of bits in the cyclic prefix [default=%default]") + _add_common_options(normal, expert) + for mod in modulation_utils2.type_1_mods().values(): + mod.add_options(expert) + # Make a static method to call before instantiation add_options = staticmethod(add_options) @@ -196,6 +198,9 @@ class ofdm_demod(gr.hier_block2): self._cp_length = options.cp_length self._snr = options.snr + arity = options.constellation_points + print("con points is %s" % options.constellation_points) + # Use freq domain to get doubled-up known symbol for correlation in time domain zeros_on_left = int(math.ceil((self._fft_length - self._occupied_tones)/2.0)) ksfreq = known_symbols_4512_3[0:self._occupied_tones] @@ -211,22 +216,11 @@ class ofdm_demod(gr.hier_block2): self._occupied_tones, self._snr, preambles, options.log) - mods = {"bpsk": 2, "qpsk": 4, "8psk": 8, "qam8": 8, "qam16": 16, "qam64": 64, "qam256": 256} - arity = mods[self._modulation] - - rot = 1 - if self._modulation == "qpsk": - rot = (0.707+0.707j) - - if(self._modulation.find("psk") >= 0): - rotated_const = map(lambda pt: pt * rot, psk.gray_constellation[arity]) - elif(self._modulation.find("qam") >= 0): - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) - #print rotated_const + constell = modulation_utils2.type_1_constellations()[self._modulation](arity) phgain = 0.25 frgain = phgain*phgain / 4.0 - self.ofdm_demod = gr.ofdm_frame_sink(rotated_const, range(arity), + self.ofdm_demod = gr.ofdm_frame_sink2(constell.base(), self._rcvd_pktq, self._occupied_tones, phgain, frgain) @@ -253,14 +247,9 @@ class ofdm_demod(gr.hier_block2): """ Adds OFDM-specific options to the Options Parser """ - normal.add_option("-m", "--modulation", type="string", default="bpsk", - help="set modulation type (bpsk or qpsk) [default=%default]") - expert.add_option("", "--fft-length", type="intx", default=512, - help="set the number of FFT bins [default=%default]") - expert.add_option("", "--occupied-tones", type="intx", default=200, - help="set the number of occupied FFT bins [default=%default]") - expert.add_option("", "--cp-length", type="intx", default=128, - help="set the number of bits in the cyclic prefix [default=%default]") + _add_common_options(normal, expert) + for mod in modulation_utils2.type_1_mods().values(): + mod.add_options(expert) # Make a static method to call before instantiation add_options = staticmethod(add_options) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py index e40d9636a..62f40582e 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr +from gnuradio import gr, optfir class pfb_arb_resampler_ccf(gr.hier_block2): ''' @@ -31,19 +31,45 @@ class pfb_arb_resampler_ccf(gr.hier_block2): streams. This block is provided to be consistent with the interface to the other PFB block. ''' - def __init__(self, rate, taps, flt_size=32): + def __init__(self, rate, taps=None, flt_size=32, atten=100): gr.hier_block2.__init__(self, "pfb_arb_resampler_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._rate = rate - self._taps = taps self._size = flt_size - self.pfb = gr.pfb_arb_resampler_ccf(self._rate, self._taps, self._size) + if taps is not None: + self._taps = taps + else: + # Create a filter that covers the full bandwidth of the input signal + bw = 0.4 + tb = 0.2 + ripple = 0.1 + #self._taps = gr.firdes.low_pass_2(self._size, self._size, bw, tb, atten) + made = False + while not made: + try: + self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") + self.pfb = gr.pfb_arb_resampler_ccf(self._rate, self._taps, self._size) + #print "PFB has %d taps\n" % (len(self._taps),) + self.connect(self, self.pfb) self.connect(self.pfb, self) - + + # Note -- set_taps not implemented in base class yet def set_taps(self, taps): self.pfb.set_taps(taps) + + def set_rate(self, rate): + self.pfb.set_rate(rate) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py index a479ed48e..3ddc1749a 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr +from gnuradio import gr, optfir class pfb_channelizer_ccf(gr.hier_block2): ''' @@ -29,15 +29,35 @@ class pfb_channelizer_ccf(gr.hier_block2): This simplifies the interface by allowing a single input stream to connect to this block. It will then output a stream for each channel. ''' - def __init__(self, numchans, taps, oversample_rate=1): + def __init__(self, numchans, taps=None, oversample_rate=1, atten=100): gr.hier_block2.__init__(self, "pfb_channelizer_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(numchans, numchans, gr.sizeof_gr_complex)) # Output signature self._numchans = numchans - self._taps = taps self._oversample_rate = oversample_rate + if taps is not None: + self._taps = taps + else: + # Create a filter that covers the full bandwidth of the input signal + bw = 0.4 + tb = 0.2 + ripple = 0.1 + made = False + while not made: + try: + self._taps = optfir.low_pass(1, self._numchans, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") + self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._numchans) self.pfb = gr.pfb_channelizer_ccf(self._numchans, self._taps, self._oversample_rate) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py index 176d0473e..2e36e7bc1 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr +from gnuradio import gr, optfir class pfb_decimator_ccf(gr.hier_block2): ''' @@ -29,15 +29,35 @@ class pfb_decimator_ccf(gr.hier_block2): This simplifies the interface by allowing a single input stream to connect to this block. It will then output a stream that is the decimated output stream. ''' - def __init__(self, decim, taps, channel=0): + def __init__(self, decim, taps=None, channel=0, atten=100): gr.hier_block2.__init__(self, "pfb_decimator_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._decim = decim - self._taps = taps self._channel = channel + if taps is not None: + self._taps = taps + else: + # Create a filter that covers the full bandwidth of the input signal + bw = 0.4 + tb = 0.2 + ripple = 0.1 + made = False + while not made: + try: + self._taps = optfir.low_pass(1, self._decim, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") + self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._decim) self.pfb = gr.pfb_decimator_ccf(self._decim, self._taps, self._channel) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py index db2944042..a6094f7f4 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr +from gnuradio import gr, optfir class pfb_interpolator_ccf(gr.hier_block2): ''' @@ -31,7 +31,7 @@ class pfb_interpolator_ccf(gr.hier_block2): streams. This block is provided to be consistent with the interface to the other PFB block. ''' - def __init__(self, interp, taps): + def __init__(self, interp, taps=None, atten=100): gr.hier_block2.__init__(self, "pfb_interpolator_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature @@ -39,6 +39,27 @@ class pfb_interpolator_ccf(gr.hier_block2): self._interp = interp self._taps = taps + if taps is not None: + self._taps = taps + else: + # Create a filter that covers the full bandwidth of the input signal + bw = 0.4 + tb = 0.2 + ripple = 0.99 + made = False + while not made: + try: + self._taps = optfir.low_pass(self._interp, self._interp, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") + self.pfb = gr.pfb_interpolator_ccf(self._interp, self._taps) self.connect(self, self.pfb) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pkt.py b/gnuradio-core/src/python/gnuradio/blks2impl/pkt.py deleted file mode 100644 index 908437ef2..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/pkt.py +++ /dev/null @@ -1,164 +0,0 @@ -# -# Copyright 2005, 2006, 2007 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 math import pi -from gnuradio import gr, packet_utils -import gnuradio.gr.gr_threading as _threading - - -# ///////////////////////////////////////////////////////////////////////////// -# mod/demod with packets as i/o -# ///////////////////////////////////////////////////////////////////////////// - -class mod_pkts(gr.hier_block2): - """ - Wrap an arbitrary digital modulator in our packet handling framework. - - Send packets by calling send_pkt - """ - def __init__(self, modulator, access_code=None, msgq_limit=2, pad_for_usrp=True, use_whitener_offset=False): - """ - Hierarchical block for sending packets - - Packets to be sent are enqueued by calling send_pkt. - The output is the complex modulated signal at baseband. - - @param modulator: instance of modulator class (gr_block or hier_block2) - @type modulator: complex baseband out - @param access_code: AKA sync vector - @type access_code: string of 1's and 0's between 1 and 64 long - @param msgq_limit: maximum number of messages in message queue - @type msgq_limit: int - @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples - @param use_whitener_offset: If true, start of whitener XOR string is incremented each packet - - See gmsk_mod for remaining parameters - """ - - gr.hier_block2.__init__(self, "mod_pkts", - gr.io_signature(0, 0, 0), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._modulator = modulator - self._pad_for_usrp = pad_for_usrp - self._use_whitener_offset = use_whitener_offset - self._whitener_offset = 0 - - if access_code is None: - access_code = packet_utils.default_access_code - if not packet_utils.is_1_0_string(access_code): - raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,) - self._access_code = access_code - - # accepts messages from the outside world - self._pkt_input = gr.message_source(gr.sizeof_char, msgq_limit) - self.connect(self._pkt_input, self._modulator, self) - - def send_pkt(self, payload='', eof=False): - """ - Send the payload. - - @param payload: data to send - @type payload: string - """ - if eof: - msg = gr.message(1) # tell self._pkt_input we're not sending any more packets - else: - # print "original_payload =", string_to_hex_list(payload) - pkt = packet_utils.make_packet(payload, - self._modulator.samples_per_symbol(), - self._modulator.bits_per_symbol(), - self._access_code, - self._pad_for_usrp, - self._whitener_offset) - #print "pkt =", string_to_hex_list(pkt) - msg = gr.message_from_string(pkt) - if self._use_whitener_offset is True: - self._whitener_offset = (self._whitener_offset + 1) % 16 - - self._pkt_input.msgq().insert_tail(msg) - - - -class demod_pkts(gr.hier_block2): - """ - Wrap an arbitrary digital demodulator in our packet handling framework. - - The input is complex baseband. When packets are demodulated, they are passed to the - app via the callback. - """ - - def __init__(self, demodulator, access_code=None, callback=None, threshold=-1): - """ - Hierarchical block for demodulating and deframing packets. - - The input is the complex modulated signal at baseband. - Demodulated packets are sent to the handler. - - @param demodulator: instance of demodulator class (gr_block or hier_block2) - @type demodulator: complex baseband in - @param access_code: AKA sync vector - @type access_code: string of 1's and 0's - @param callback: function of two args: ok, payload - @type callback: ok: bool; payload: string - @param threshold: detect access_code with up to threshold bits wrong (-1 -> use default) - @type threshold: int - """ - - gr.hier_block2.__init__(self, "demod_pkts", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(0, 0, 0)) # Output signature - - self._demodulator = demodulator - if access_code is None: - access_code = packet_utils.default_access_code - if not packet_utils.is_1_0_string(access_code): - raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,) - self._access_code = access_code - - if threshold == -1: - threshold = 12 # FIXME raise exception - - self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY - self.correlator = gr.correlate_access_code_bb(access_code, threshold) - - self.framer_sink = gr.framer_sink_1(self._rcvd_pktq) - self.connect(self, self._demodulator, self.correlator, self.framer_sink) - - self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback) - - -class _queue_watcher_thread(_threading.Thread): - def __init__(self, rcvd_pktq, callback): - _threading.Thread.__init__(self) - self.setDaemon(1) - self.rcvd_pktq = rcvd_pktq - self.callback = callback - self.keep_running = True - self.start() - - - def run(self): - while self.keep_running: - msg = self.rcvd_pktq.delete_head() - ok, payload = packet_utils.unmake_packet(msg.to_string(), int(msg.arg1())) - if self.callback: - self.callback(ok, payload) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/qam16.py b/gnuradio-core/src/python/gnuradio/blks2impl/qam16.py deleted file mode 100644 index 0bdb9c6fb..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/qam16.py +++ /dev/null @@ -1,208 +0,0 @@ -# -# Copyright 2005,2006,2007 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -QAM16 modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import qam -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = None -_def_gain_mu = 0.03 -_def_mu = 0.05 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM16 modulator -# ///////////////////////////////////////////////////////////////////////////// - -class qam16_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "qam16_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2, self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1.0 - print "constellation with %d arity" % arity - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 4 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RRS roll-off factor = %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) - - def add_options(parser): - """ - Adds QAM modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(qam16_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM16 demodulator -# -# ///////////////////////////////////////////////////////////////////////////// - -class qam16_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - gr.hier_block2.__init__(self, "qam16_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(1, 1, gr.sizeof_char)) # Output signature - # do this - pass - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 4 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - -# -# Add these to the mod/demod registry -# -# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -#modulation_utils.add_type_1_mod('qam16', qam16_mod) -#modulation_utils.add_type_1_demod('qam16', qam16_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/qam256.py b/gnuradio-core/src/python/gnuradio/blks2impl/qam256.py deleted file mode 100644 index fc455f17c..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/qam256.py +++ /dev/null @@ -1,209 +0,0 @@ -# -# Copyright 2005,2006,2007 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -QAM256 modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import qam -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = None -_def_gain_mu = 0.03 -_def_mu = 0.05 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM256 modulator -# ///////////////////////////////////////////////////////////////////////////// - -class qam256_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "qam256_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2, self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1.0 - print "constellation with %d arity" % arity - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 8 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RRS roll-off factor = %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) - - def add_options(parser): - """ - Adds QAM modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(qam256_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM256 demodulator -# -# ///////////////////////////////////////////////////////////////////////////// - -class qam256_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - gr.hier_block2.__init__(self, "qam256_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(1, 1, gr.sizeof_char)) # Output signature - - # do this - pass - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 8 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - -# -# Add these to the mod/demod registry -# -# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -#modulation_utils.add_type_1_mod('qam256', qam256_mod) -#modulation_utils.add_type_1_demod('qam256', qam256_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/qam64.py b/gnuradio-core/src/python/gnuradio/blks2impl/qam64.py deleted file mode 100644 index 5509f3745..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/qam64.py +++ /dev/null @@ -1,208 +0,0 @@ -# -# Copyright 2005,2006,2007 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential QPSK modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import qam -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = None -_def_gain_mu = 0.03 -_def_mu = 0.05 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM64 modulator -# ///////////////////////////////////////////////////////////////////////////// - -class qam64_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "qam64_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2, self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1.0 - print "constellation with %d arity" % arity - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 6 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RRS roll-off factor = %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) - - def add_options(parser): - """ - Adds QAM modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(qam64_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM16 demodulator -# -# ///////////////////////////////////////////////////////////////////////////// - -class qam64_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - gr.hier_block2.__init__(self, "qam64_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(1, 1, gr.sizeof_char)) # Output signature - - # do this - pass - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 6 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - -# -# Add these to the mod/demod registry -# -# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -#modulation_utils.add_type_1_mod('qam64', qam64_mod) -#modulation_utils.add_type_1_demod('qam16', qam16_demod) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/qam8.py b/gnuradio-core/src/python/gnuradio/blks2impl/qam8.py deleted file mode 100644 index 6a7b35597..000000000 --- a/gnuradio-core/src/python/gnuradio/blks2impl/qam8.py +++ /dev/null @@ -1,209 +0,0 @@ -# -# Copyright 2005,2006,2007 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -QAM8 modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import qam -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = None -_def_gain_mu = 0.03 -_def_mu = 0.05 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM8 modulator -# ///////////////////////////////////////////////////////////////////////////// - -class qam8_mod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - gr.hier_block2.__init__(self, "qam8_mod", - gr.io_signature(1, 1, gr.sizeof_char), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2, self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1.0 - print "constellation with %d arity" % arity - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect - self.connect(self, self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter, self) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 3 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RRS roll-off factor = %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) - self.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "graycoder.dat")) - self.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "diffenc.dat")) - self.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) - self.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) - - def add_options(parser): - """ - Adds QAM modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(qam8_mod.__init__, - ('self',), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM8 demodulator -# -# ///////////////////////////////////////////////////////////////////////////// - -class qam8_demod(gr.hier_block2): - - def __init__(self, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - gr.hier_block2.__init__(self, "qam8_demod", - gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature - gr.io_signature(1, 1, gr.sizeof_char)) # Output signature - - # do this - pass - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 3 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - -# -# Add these to the mod/demod registry -# -# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -modulation_utils.add_type_1_mod('qam8', qam8_mod) -#modulation_utils.add_type_1_demod('qam8', qam8_demod) diff --git a/gnuradio-core/src/python/gnuradio/gr/Makefile.am b/gnuradio-core/src/python/gnuradio/gr/Makefile.am index 341f58812..7bf1c0827 100644 --- a/gnuradio-core/src/python/gnuradio/gr/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/gr/Makefile.am @@ -21,12 +21,11 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST = \ +EXTRA_DIST += \ run_tests.in \ test_16bit_1chunk.wav -TESTS = \ - run_tests +TESTS = run_tests grgrpythondir = $(grpythondir)/gr @@ -39,7 +38,6 @@ grgrpython_PYTHON = \ gr_threading_24.py \ hier_block2.py \ prefs.py \ - scheduler.py \ top_block.py \ pubsub.py @@ -51,12 +49,10 @@ noinst_PYTHON = \ qa_argmax.py \ qa_bin_statistics.py \ qa_classify.py \ - qa_cma_equalizer.py \ qa_complex_to_xxx.py \ - qa_constellation_decoder_cb.py \ qa_copy.py \ - qa_correlate_access_code.py \ qa_delay.py \ + qa_dc_blocker.py \ qa_diff_encoder.py \ qa_diff_phasor_cc.py \ qa_ecc_ccsds_27.py \ @@ -73,6 +69,7 @@ noinst_PYTHON = \ qa_hier_block2.py \ qa_hilbert.py \ qa_iir.py \ + qa_int_to_float.py \ qa_interleave.py \ qa_interp_fir_filter.py \ qa_kludge_copy.py \ diff --git a/gnuradio-core/src/python/gnuradio/gr/__init__.py b/gnuradio-core/src/python/gnuradio/gr/__init__.py index 6f939c470..73ca8e08f 100644 --- a/gnuradio-core/src/python/gnuradio/gr/__init__.py +++ b/gnuradio-core/src/python/gnuradio/gr/__init__.py @@ -1,5 +1,5 @@ # -# Copyright 2003,2004,2006,2008,2009 Free Software Foundation, Inc. +# Copyright 2003,2004,2006,2008,2009,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -40,7 +40,7 @@ if _RTLD_GLOBAL != 0: _dlopenflags = sys.getdlopenflags() sys.setdlopenflags(_dlopenflags|_RTLD_GLOBAL) -from gnuradio_swig_python import * +from gnuradio_core import * from exceptions import * from hier_block2 import * from top_block import * diff --git a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py index b43c5feda..debb65d91 100644 --- a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py +++ b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py @@ -19,7 +19,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio_swig_python import hier_block2_swig +from gnuradio_core import hier_block2_swig # # This hack forces a 'has-a' relationship to look like an 'is-a' one. @@ -66,7 +66,7 @@ class hier_block2(object): raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),)) else: if len(points) == 1: - self._hb.connect(points[0].basic_block()) + self._hb.primitive_connect(points[0].to_basic_block()) else: for i in range (1, len (points)): self._connect(points[i-1], points[i]) @@ -74,11 +74,11 @@ class hier_block2(object): def _connect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) (dst_block, dst_port) = self._coerce_endpoint(dst) - self._hb.connect(src_block.basic_block(), src_port, - dst_block.basic_block(), dst_port) + self._hb.primitive_connect(src_block.to_basic_block(), src_port, + dst_block.to_basic_block(), dst_port) def _coerce_endpoint(self, endp): - if hasattr(endp, 'basic_block'): + if hasattr(endp, 'to_basic_block'): return (endp, 0) else: if hasattr(endp, "__getitem__") and len(endp) == 2: @@ -97,10 +97,10 @@ class hier_block2(object): """ if len (points) < 1: - raise ValueError, ("disconnect requires at least two endpoints; %d provided." % (len (points),)) + raise ValueError, ("disconnect requires at least one endpoint; %d provided." % (len (points),)) else: if len (points) == 1: - self._hb.disconnect(points[0].basic_block()) + self._hb.primitive_disconnect(points[0].to_basic_block()) else: for i in range (1, len (points)): self._disconnect(points[i-1], points[i]) @@ -108,6 +108,6 @@ class hier_block2(object): def _disconnect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) (dst_block, dst_port) = self._coerce_endpoint(dst) - self._hb.disconnect(src_block.basic_block(), src_port, - dst_block.basic_block(), dst_port) + self._hb.primitive_disconnect(src_block.to_basic_block(), src_port, + dst_block.to_basic_block(), dst_port) diff --git a/gnuradio-core/src/python/gnuradio/gr/prefs.py b/gnuradio-core/src/python/gnuradio/gr/prefs.py index 9b31b772b..40347a2f4 100644 --- a/gnuradio-core/src/python/gnuradio/gr/prefs.py +++ b/gnuradio-core/src/python/gnuradio/gr/prefs.py @@ -19,7 +19,7 @@ # Boston, MA 02110-1301, USA. # -import gnuradio_swig_python as gsp +import gnuradio_core as gsp _prefs_base = gsp.gr_prefs diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_constellation_decoder_cb.py b/gnuradio-core/src/python/gnuradio/gr/qa_constellation_decoder_cb.py deleted file mode 100755 index 27e1802e0..000000000 --- a/gnuradio-core/src/python/gnuradio/gr/qa_constellation_decoder_cb.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2007,2010 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, gr_unittest -import math - -class test_constellation_decoder (gr_unittest.TestCase): - - def setUp (self): - self.tb = gr.top_block () - - def tearDown (self): - self.tb = None - - def test_constellation_decoder_cb (self): - symbol_positions = [1 + 0j, 0 + 1j , -1 + 0j, 0 - 1j] - symbol_values_out = [0, 1, 2, 3] - expected_result = ( 0, 3, 2, 1, 0, 0, 3) - src_data = (0.5 + 0j, 0.1 - 1.2j, -0.8 - 0.1j, -0.45 + 0.8j, 0.8 - 0j, 0.5 + 0j, 0.1 - 1.2j) - src = gr.vector_source_c (src_data) - op = gr.constellation_decoder_cb (symbol_positions, symbol_values_out) - dst = gr.vector_sink_b () - self.tb.connect (src, op) - self.tb.connect (op, dst) - self.tb.run () # run the graph and wait for it to finish - actual_result = dst.data () # fetch the contents of the sink - #print "actual result", actual_result - #print "expected result", expected_result - self.assertFloatTuplesAlmostEqual (expected_result, actual_result) - - -if __name__ == '__main__': - gr_unittest.run(test_constellation_decoder, "test_constellation_decoder.xml") - diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_correlate_access_code.py b/gnuradio-core/src/python/gnuradio/gr/qa_correlate_access_code.py deleted file mode 100755 index b3575f4e6..000000000 --- a/gnuradio-core/src/python/gnuradio/gr/qa_correlate_access_code.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2006,2007,2010 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, gr_unittest -import math - -default_access_code = '\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC' - -def string_to_1_0_list(s): - r = [] - for ch in s: - x = ord(ch) - for i in range(8): - t = (x >> i) & 0x1 - r.append(t) - - return r - -def to_1_0_string(L): - return ''.join(map(lambda x: chr(x + ord('0')), L)) - -class test_correlate_access_code(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def test_001(self): - pad = (0,) * 64 - # 0 0 0 1 0 0 0 1 - src_data = (1, 0, 1, 1, 1, 1, 0, 1, 1) + pad + (0,) * 7 - expected_result = pad + (1, 0, 1, 1, 3, 1, 0, 1, 1, 2) + (0,) * 6 - src = gr.vector_source_b (src_data) - op = gr.correlate_access_code_bb("1011", 0) - dst = gr.vector_sink_b () - self.tb.connect (src, op, dst) - self.tb.run () - result_data = dst.data () - self.assertEqual (expected_result, result_data) - - - def test_002(self): - code = tuple(string_to_1_0_list(default_access_code)) - access_code = to_1_0_string(code) - pad = (0,) * 64 - #print code - #print access_code - src_data = code + (1, 0, 1, 1) + pad - expected_result = pad + code + (3, 0, 1, 1) - src = gr.vector_source_b (src_data) - op = gr.correlate_access_code_bb(access_code, 0) - dst = gr.vector_sink_b () - self.tb.connect (src, op, dst) - self.tb.run () - result_data = dst.data () - self.assertEqual (expected_result, result_data) - - - -if __name__ == '__main__': - gr_unittest.run(test_correlate_access_code, "test_correlate_access_code.xml") - diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py b/gnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py new file mode 100755 index 000000000..8977b475a --- /dev/null +++ b/gnuradio-core/src/python/gnuradio/gr/qa_dc_blocker.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +# +# Copyright 2011 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, gr_unittest + +class test_dc_blocker(gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + ''' Test impulse response - long form, cc ''' + src_data = [1,] + 100*[0,] + expected_result = ((-0.02072429656982422+0j), (-0.02081298828125+0j), + (0.979156494140625+0j), (-0.02081298828125+0j), + (-0.02072429656982422+0j)) + + src = gr.vector_source_c(src_data) + op = gr.dc_blocker_cc(32, True) + dst = gr.vector_sink_c() + + self.tb.connect (src, op, dst) + self.tb.run() + + # only test samples around 2D-2 + result_data = dst.data()[60:65] + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + def test_002(self): + ''' Test impulse response - short form, cc ''' + src_data = [1,] + 100*[0,] + expected_result = ((-0.029296875+0j), (-0.0302734375+0j), + (0.96875+0j), (-0.0302734375+0j), + (-0.029296875+0j)) + + src = gr.vector_source_c(src_data) + op = gr.dc_blocker_cc(32, False) + dst = gr.vector_sink_c() + + self.tb.connect (src, op, dst) + self.tb.run() + + # only test samples around D-1 + result_data = dst.data()[29:34] + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + + def test_003(self): + ''' Test impulse response - long form, ff ''' + src_data = [1,] + 100*[0,] + expected_result = ((-0.02072429656982422), (-0.02081298828125), + (0.979156494140625), (-0.02081298828125), + (-0.02072429656982422)) + + src = gr.vector_source_f(src_data) + op = gr.dc_blocker_ff(32, True) + dst = gr.vector_sink_f() + + self.tb.connect (src, op, dst) + self.tb.run() + + # only test samples around 2D-2 + result_data = dst.data()[60:65] + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + def test_004(self): + ''' Test impulse response - short form, ff ''' + src_data = [1,] + 100*[0,] + expected_result = ((-0.029296875), (-0.0302734375), + (0.96875), (-0.0302734375), + (-0.029296875)) + + src = gr.vector_source_f(src_data) + op = gr.dc_blocker_ff(32, False) + dst = gr.vector_sink_f() + + self.tb.connect (src, op, dst) + self.tb.run() + + # only test samples around D-1 + result_data = dst.data()[29:34] + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_dc_blocker, "test_dc_blocker.xml") + diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_cma_equalizer.py b/gnuradio-core/src/python/gnuradio/gr/qa_int_to_float.py index 79e9cd092..edfc26409 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_cma_equalizer.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_int_to_float.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2006,2007,2010 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,28 +22,28 @@ from gnuradio import gr, gr_unittest -class test_cma_equalizer_fir(gr_unittest.TestCase): - - def setUp(self): - self.tb = gr.top_block() - - def tearDown(self): - self.tb = None - - def transform(self, src_data): - SRC = gr.vector_source_c(src_data, False) - EQU = gr.cma_equalizer_cc(4, 1.0, .001) - DST = gr.vector_sink_c() - self.tb.connect(SRC, EQU, DST) - self.tb.run() - return DST.data() - - def test_001_identity(self): - # Constant modulus signal so no adjustments - src_data = (1+0j, 0+1j, -1+0j, 0-1j)*1000 - expected_data = src_data - result = self.transform(src_data) - self.assertComplexTuplesAlmostEqual(expected_data, result) - -if __name__ == "__main__": - gr_unittest.run(test_cma_equalizer_fir, "test_cma_equalizer_fir.xml") +class test_int_to_float (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block () + + def tearDown (self): + self.tb = None + + def test_001(self): + + src_data = (0, 1, 2, 3, 4, 5, -1, -2, -3, -4, -5) + expected_result = [float(s) for s in src_data] + src = gr.vector_source_i(src_data) + op = gr.int_to_float() + dst = gr.vector_sink_f() + + self.tb.connect(src, op, dst) + self.tb.run() + result_data = dst.data() + + self.assertFloatTuplesAlmostEqual(expected_result, result_data) + +if __name__ == '__main__': + gr_unittest.run(test_int_to_float, "test_int_to_float.xml") + diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py b/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py index 8e4a0eefa..4c12924ec 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2007,2010 Free Software Foundation, Inc. +# Copyright 2004,2007,2010,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -32,117 +32,116 @@ class test_pll_carriertracking (gr_unittest.TestCase): self.tb = None def test_pll_carriertracking (self): - expected_result = ((1.00000238419+6.47922693275e-09j), - (0.998399555683+0.0565364062786j), - (0.994261980057+0.10695001483j), - (0.98843306303+0.151648163795j), - (0.981579363346+0.191063538194j), - (0.974212288857+0.225630432367j), - (0.966734290123+0.255773901939j), - (0.959442555904+0.281897842884j), - (0.952551782131+0.304379671812j), - (0.946205317974+0.323566257954j), - (0.940503358841+0.339778244495j), - (0.935505151749+0.353307723999j), - (0.931235432625+0.364419162273j), - (0.927616357803+0.373535633087j), - (0.924710214138+0.380666583776j), - (0.922494113445+0.386005342007j), - (0.92093116045+0.389725029469j), - (0.919974088669+0.391981720924j), - (0.919572234154+0.392916500568j), - (0.919680893421+0.392660915852j), - (0.920248389244+0.39133310318j), - (0.921222627163+0.389039844275j), - (0.922548472881+0.385877460241j), - (0.924184799194+0.381939411163j), - (0.926086127758+0.377309292555j), - (0.928135097027+0.37224984169j), - (0.930293083191+0.366814315319j), - (0.932614028454+0.360868781805j), - (0.935064375401+0.354473829269j), - (0.937613248825+0.347684770823j), - (0.940225422382+0.340550601482j), - (0.942881464958+0.33312189579j), - (0.945559620857+0.325443327427j), - (0.948240220547+0.31755694747j), - (0.950899422169+0.309499144554j), - (0.953524827957+0.301307469606j), - (0.956105649471+0.293015599251j), - (0.958630502224+0.284654557705j), - (0.96103054285+0.276443749666j), - (0.963361799717+0.26819768548j), - (0.965623259544+0.259936869144j), - (0.967810571194+0.251679092646j), - (0.969916880131+0.243440493941j), - (0.971936583519+0.235235646367j), - (0.97387367487+0.227080151439j), - (0.975726902485+0.218987599015j), - (0.977494239807+0.210969462991j), - (0.979169845581+0.203035995364j), - (0.980761289597+0.195199295878j), - (0.982269346714+0.187469303608j), - (0.983659446239+0.180052131414j), - (0.984931468964+0.1729388237j), - (0.986136198044+0.165923252702j), - (0.987275123596+0.159012272954j), - (0.988349795341+0.15221118927j), - (0.989354014397+0.145524248481j), - (0.990296065807+0.138957872987j), - (0.991178870201+0.132516458631j), - (0.992005050182+0.126204773784j), - (0.992770493031+0.120025672019j), - (0.993480443954+0.113984130323j), - (0.994139909744+0.108083210886j), - (0.994751393795+0.102326385677j), - (0.995293080807+0.0969148278236j), - (0.995791256428+0.091630294919j), - (0.996252119541+0.0864710733294j), - (0.996678769588+0.0814334899187j), - (0.997069239616+0.0765165910125j), - (0.997423350811+0.071716658771j), - (0.997748315334+0.0670333206654j), - (0.998046517372+0.0624645166099j), - (0.998317599297+0.058009263128j), - (0.998557567596+0.053665690124j), - (0.998775064945+0.0494344644248j), - (0.998971700668+0.0453144386411j), - (0.999140620232+0.0415064357221j), - (0.99927687645+0.0379924885929j), - (0.999400436878+0.0345549099147j), - (0.999511957169+0.0311931278557j), - (0.99961233139+0.0279070306569j), - (0.999694347382+0.0246965941042j), - (0.999765276909+0.0215622838587j), - (0.999826848507+0.0185046810657j), - (0.999880313873+0.0155246723443j), - (0.999920129776+0.0126227736473j), - (0.999949812889+0.00980060640723j), - (0.99997317791+0.00705910893157j), - (0.999990820885+0.00439921114594j), - (0.999998450279+0.00202245195396j), - (0.999998092651-0.00029227725463j), - (0.999994516373-0.00254815118387j), - (0.999988794327-0.00474932929501j), - (0.999977111816-0.00689708162099j), - (0.999957799911-0.00899503659457j), - (0.999936699867-0.0110441967845j), - (0.999914228916-0.0130464555696j), - (0.999889075756-0.0150024276227j), - (0.999855577946-0.0169130507857j), - (0.999821305275-0.0187777336687j), - (0.999786794186-0.0205969288945j)) + expected_result = ((1.00000238419+6.57831922268e-09j), + (0.998351693153+0.0573740489781j), + (0.994012773037+0.109242096543j), + (0.987789511681+0.155784770846j), + (0.980356454849+0.197242289782j), + (0.972262203693+0.233890414238j), + (0.963963091373+0.266027569771j), + (0.955816328526+0.293958544731j), + (0.948096513748+0.31798568368j), + (0.941002130508+0.338400006294j), + (0.934680581093+0.355482578278j), + (0.929229319096+0.369498342276j), + (0.924701035023+0.380694836378j), + (0.921043872833+0.389459967613j), + (0.918319702148+0.395834594965j), + (0.91650646925+0.400014132261j), + (0.915561556816+0.40217769146j), + (0.915425121784+0.402490824461j), + (0.916029334068+0.401106894016j), + (0.917308092117+0.39817237854j), + (0.919185698032+0.393822491169j), + (0.921583771706+0.388183712959j), + (0.924419641495+0.381372988224j), + (0.927624821663+0.373506993055j), + (0.93112629652+0.364693939686j), + (0.934793651104+0.355197936296j), + (0.938562095165+0.345107495785j), + (0.942447602749+0.33434677124j), + (0.946396291256+0.323003143072j), + (0.950359642506+0.311159342527j), + (0.954286515713+0.298890888691j), + (0.958144724369+0.286276459694j), + (0.961902141571+0.273387700319j), + (0.96553081274+0.260292351246j), + (0.969001471996+0.247053653002j), + (0.972298383713+0.233733415604j), + (0.975410103798+0.220389455557j), + (0.978325486183+0.207074314356j), + (0.981000483036+0.194007188082j), + (0.983471632004+0.181051760912j), + (0.985742926598+0.168245732784j), + (0.987816333771+0.155622571707j), + (0.989693164825+0.143212914467j), + (0.991374969482+0.131043404341j), + (0.992875099182+0.119139909744j), + (0.994201719761+0.107524067163j), + (0.995362222195+0.0962148010731j), + (0.996359944344+0.0852287560701j), + (0.997212648392+0.0745811164379j), + (0.997930467129+0.0642844736576j), + (0.998514950275+0.0545224510133j), + (0.998972594738+0.0452938191593j), + (0.999334216118+0.0364210158587j), + (0.99960911274+0.0279066264629j), + (0.999806642532+0.0197515785694j), + (0.99992787838+0.0119558870792j), + (0.999987542629+0.00451827049255j), + (0.999994814396-0.00256353616714j), + (0.999957740307-0.00929233431816j), + (0.999877095222-0.0156717002392j), + (0.999762177467-0.0217055380344j), + (0.999622702599-0.0273993015289j), + (0.999463677406-0.0327589809895j), + (0.999292552471-0.0376165211201j), + (0.999108791351-0.0421659946442j), + (0.998919844627-0.0464186370373j), + (0.998729586601-0.0503882467747j), + (0.998537421227-0.0540841519833j), + (0.998342692852-0.0575186908245j), + (0.9981533885-0.0607041418552j), + (0.997971534729-0.063651651144j), + (0.997796595097-0.0663715749979j), + (0.997623920441-0.0688742175698j), + (0.997461974621-0.0711689144373j), + (0.997311413288-0.0732654929161j), + (0.997185945511-0.0749996080995j), + (0.997077047825-0.0763883292675j), + (0.996980309486-0.0776248201728j), + (0.996895432472-0.0787187665701j), + (0.996822297573-0.0796797126532j), + (0.996752738953-0.0805156230927j), + (0.996692657471-0.0812350511551j), + (0.996642947197-0.0818456709385j), + (0.996603965759-0.0823540389538j), + (0.996568918228-0.0827651321888j), + (0.996540248394-0.0830852389336j), + (0.996520996094-0.0833202600479j), + (0.996510386467-0.0834743082523j), + (0.996518313885-0.0833787024021j), + (0.996529102325-0.083223849535j), + (0.996545791626-0.0830176770687j), + (0.99656867981-0.0827698707581j), + (0.996593296528-0.0824855566025j), + (0.99661642313-0.0821713805199j), + (0.996643543243-0.081834435463j), + (0.996674180031-0.0814796686172j), + (0.996706545353-0.0811114609241j), + (0.996734440327-0.0807323306799j), + (0.996764600277-0.0803465023637j), + (0.996797323227-0.0799564495683j)) sampling_freq = 10e3 freq = sampling_freq / 100 - alpha = 0.1 - beta = alpha * alpha / 4.0 + loop_bw = math.pi/100.0 maxf = 1 minf = -1 src = gr.sig_source_c (sampling_freq, gr.GR_COS_WAVE, freq, 1.0) - pll = gr.pll_carriertracking_cc(alpha, beta, maxf, minf) + pll = gr.pll_carriertracking_cc(loop_bw, maxf, minf) head = gr.head (gr.sizeof_gr_complex, int (freq)) dst = gr.vector_sink_c () diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py b/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py index 5225a9a3b..b84299a94 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2004,2007,2010 Free Software Foundation, Inc. +# Copyright 2004,2007,2010,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -32,117 +32,116 @@ class test_pll_freqdet (gr_unittest.TestCase): self.tb = None def test_pll_refout (self): - expected_result = (1.1489677586e-07, - 0.972821060568, - 2.74556447638, - 5.14063078448, - 8.00965819311, - 11.2291393027, - 14.6967068752, - 18.3279143967, - 22.0534772463, - 25.8170093072, - 29.5729107661, - 33.284774699, - 36.923857393, - 40.4367950308, - 43.8452195091, - 47.1363835133, - 50.3011949468, - 53.3336447847, - 56.2301489564, - 58.9891659262, - 61.6107668417, - 64.0962975824, - 66.4481356707, - 68.6694531128, - 70.7640326003, - 72.7048735417, - 74.5033180826, - 76.2012544926, - 77.8019199967, - 79.3088126954, - 80.7255907715, - 82.0560369166, - 83.3039516093, - 84.47312347, - 85.5673411194, - 86.5902864563, - 87.5456117346, - 88.4368565575, - 89.2363918613, - 89.9860999864, - 90.688880206, - 91.3474598523, - 91.9644654653, - 92.5423042123, - 93.0832706099, - 93.5894872344, - 94.0629225081, - 94.5054203452, - 94.9186882929, - 95.3043331057, - 95.6326268597, - 95.9117515522, - 96.1801447842, - 96.437391527, - 96.6831953314, - 96.9173605408, - 97.1397982206, - 97.3504727968, - 97.5493842694, - 97.7366275022, - 97.9123092169, - 98.0766013539, - 98.2297054988, - 98.3408087235, - 98.448722155, - 98.5534457933, - 98.6549322065, - 98.7531932527, - 98.8481459259, - 98.9397487233, - 99.0279067813, - 99.1125074491, - 99.193438076, - 99.2705800823, - 99.3438030304, - 99.3817663128, - 99.3911400359, - 99.4089388448, - 99.4334136894, - 99.4630408207, - 99.4964684305, - 99.5325166512, - 99.5701538394, - 99.6084432158, - 99.6466021546, - 99.6839073198, - 99.7197895289, - 99.7537270313, - 99.7542606398, - 99.7595848672, - 99.7691186729, - 99.7822928746, - 99.7986331535, - 99.8175940432, - 99.838713083, - 99.8614922382, - 99.8854571901, - 99.9101454781, - 99.9351302152, - 99.9599845147) + expected_result = (4.33888922882e-08, + 0.367369994515, + 1.08135249597, + 2.10983253908, + 3.42221529438, + 4.98940390402, + 6.78379190842, + 8.77923286024, + 10.9510106794, + 13.2758363182, + 15.7317829127, + 18.2982902299, + 20.9561068599, + 23.6755271122, + 26.452952094, + 29.2731265301, + 32.1219053479, + 34.9862418188, + 37.8540971414, + 40.7144315483, + 43.5571390869, + 46.3730179743, + 49.1537231663, + 51.8917218889, + 54.58026103, + 57.2015358514, + 59.7513664199, + 62.2380533124, + 64.657612252, + 67.006640002, + 69.2822432184, + 71.4820384499, + 73.6041047056, + 75.6469478817, + 77.6094829742, + 79.4909866472, + 81.2911031615, + 83.0097850853, + 84.6355598352, + 86.1820937186, + 87.6504420946, + 89.0418441206, + 90.3577286819, + 91.5996432431, + 92.7692775646, + 93.8684162704, + 94.8989269904, + 95.8627662892, + 96.7619381633, + 97.598505899, + 98.362769679, + 99.0579904444, + 99.6992633875, + 100.288805948, + 100.828805921, + 101.321421457, + 101.76878699, + 102.17300138, + 102.536116055, + 102.860158727, + 103.147085962, + 103.398830608, + 103.617254366, + 103.792467691, + 103.939387906, + 104.060030865, + 104.15631756, + 104.230085975, + 104.283067372, + 104.316933727, + 104.333238432, + 104.333440018, + 104.318914008, + 104.290941063, + 104.250742554, + 104.187634452, + 104.103822339, + 104.013227468, + 103.916810336, + 103.815448432, + 103.709936239, + 103.600997093, + 103.489283183, + 103.375351833, + 103.259712936, + 103.142828952, + 103.025091195, + 102.90686726, + 102.776726069, + 102.648078982, + 102.521459607, + 102.397294831, + 102.275999684, + 102.157882471, + 102.043215927, + 101.93218978, + 101.824958181, + 101.72159228, + 101.622151366, + 101.526623582) sampling_freq = 10e3 freq = sampling_freq / 100 - alpha = 0.2 - beta = alpha * alpha / 4.0 + loop_bw = math.pi/100.0 maxf = 1 minf = -1 src = gr.sig_source_c (sampling_freq, gr.GR_COS_WAVE, freq, 1.0) - pll = gr.pll_freqdet_cf(alpha, beta, maxf, minf) + pll = gr.pll_freqdet_cf(loop_bw, maxf, minf) head = gr.head (gr.sizeof_float, int (freq)) dst = gr.vector_sink_f () diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py b/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py index c40a885a8..14f9ab877 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py @@ -32,117 +32,116 @@ class test_pll_refout (gr_unittest.TestCase): self.tb = None def test_pll_refout (self): - expected_result = ((1+7.39965699825e-10j), - (0.999980390072+0.00626518437639j), - (0.999828696251+0.0185074284673j), - (0.999342679977+0.0362518876791j), - (0.998255133629+0.0590478181839j), - (0.996255218983+0.0864609107375j), - (0.993005692959+0.118066303432j), - (0.988157629967+0.153442293406j), - (0.981362581253+0.192165210843j), - (0.972283244133+0.233806177974j), - (0.960601866245+0.277928203344j), - (0.946027755737+0.324085712433j), - (0.928303182125+0.371824204922j), - (0.907292485237+0.420500129461j), - (0.882742881775+0.469856351614j), - (0.854515135288+0.519426465034j), - (0.822515428066+0.568742752075j), - (0.786696314812+0.617340147495j), - (0.747057616711+0.664759278297j), - (0.703645646572+0.710551083088j), - (0.656552672386+0.754280209541j), - (0.605915129185+0.795529305935j), - (0.551911592484+0.833902597427j), - (0.494760006666+0.869029641151j), - (0.43471455574+0.900568306446j), - (0.37224894762+0.928132891655j), - (0.30767711997+0.951490819454j), - (0.241136431694+0.970491230488j), - (0.172981828451+0.984925031662j), - (0.103586450219+0.99462044239j), - (0.0333373323083+0.999444127083j), - (-0.0373690575361+0.999301552773j), - (-0.108130030334+0.994136750698j), - (-0.178540825844+0.983932495117j), - (-0.248198583722+0.968709170818j), - (-0.316705673933+0.948523879051j), - (-0.383672952652+0.923469007015j), - (-0.448723316193+0.893670737743j), - (-0.51132196188+0.85938924551j), - (-0.571328520775+0.820721447468j), - (-0.628420114517+0.777874112129j), - (-0.682293117046+0.73107868433j), - (-0.732665538788+0.680588841438j), - (-0.779277384281+0.626679122448j), - (-0.821892917156+0.569642007351j), - (-0.860301196575+0.509786069393j), - (-0.894317150116+0.447433561087j), - (-0.923782229424+0.382918298244j), - (-0.948564887047+0.316582858562j), - (-0.968560874462+0.248776733875j), - (-0.983657121658+0.180051699281j), - (-0.993847966194+0.110753215849j), - (-0.999158322811+0.0410195216537j), - (-0.999585151672-0.0288011860102j), - (-0.995150566101-0.0983632653952j), - (-0.985901713371-0.16732545197j), - (-0.971909940243-0.235353127122j), - (-0.953270018101-0.302119642496j), - (-0.9300994277-0.367307811975j), - (-0.902537107468-0.430612027645j), - (-0.870742559433-0.49173912406j), - (-0.834894418716-0.550410091877j), - (-0.795189499855-0.606360971928j), - (-0.751972675323-0.659194231033j), - (-0.705345034599-0.708864152431j), - (-0.65554022789-0.755160272121j), - (-0.602804005146-0.79788929224j), - (-0.547393083572-0.836875617504j), - (-0.489574223757-0.871961653233j), - (-0.429622590542-0.903008520603j), - (-0.367820799351-0.929896712303j), - (-0.30445766449-0.952525854111j), - (-0.239826664329-0.970815718174j), - (-0.174224823713-0.984705924988j), - (-0.107951194048-0.994156181812j), - (-0.0415063276887-0.999138236046j), - (0.0248276274651-0.999691724777j), - (0.0909758731723-0.995853126049j), - (0.156649470329-0.987654268742j), - (0.221562758088-0.975146114826j), - (0.285434871912-0.958398103714j), - (0.347990810871-0.937497973442j), - (0.408962905407-0.912550985813j), - (0.468091338873-0.883680105209j), - (0.525126338005-0.851024270058j), - (0.57982814312-0.814738810062j), - (0.631968915462-0.77499371767j), - (0.681333422661-0.731973171234j), - (0.727582573891-0.68602013588j), - (0.770699381828-0.637198925018j), - (0.810512244701-0.585721731186j), - (0.846863090992-0.531810998917j), - (0.879608631134-0.475698113441j), - (0.908620357513-0.417623132467j), - (0.933785498142-0.357833325863j), - (0.955007195473-0.296582698822j), - (0.972205162048-0.234130680561j), - (0.985315918922-0.170741200447j), - (0.994293272495-0.106681488454j), - (0.999108314514-0.0422209985554j)) + expected_result = ((1+6.4087357643e-10j), + (0.999985277653+0.00542619498447j), + (0.999868750572+0.0162021834403j), + (0.99948567152+0.0320679470897j), + (0.99860727787+0.0527590736747j), + (0.996953129768+0.0780025869608j), + (0.994203746319+0.107512556016j), + (0.990011692047+0.140985429287j), + (0.984013140202+0.178095817566j), + (0.975838363171+0.218493551016j), + (0.965121984482+0.261800557375j), + (0.95151245594+0.307610183954j), + (0.934681296349+0.355486690998j), + (0.914401650429+0.404808044434j), + (0.890356600285+0.455263823271j), + (0.862329125404+0.506348133087j), + (0.830152392387+0.557536482811j), + (0.793714106083+0.608290970325j), + (0.752960026264+0.658066213131j), + (0.707896590233+0.706316053867j), + (0.658591926098+0.752500295639j), + (0.605175673962+0.796091973782j), + (0.547837555408+0.836584687233j), + (0.48682525754+0.873499393463j), + (0.42244040966+0.906390726566j), + (0.355197101831+0.934791445732j), + (0.285494059324+0.958380460739j), + (0.213591173291+0.976923108101j), + (0.139945343137+0.990159213543j), + (0.065038472414+0.997882783413j), + (-0.0106285437942+0.999943494797j), + (-0.0865436866879+0.996248066425j), + (-0.162189796567+0.986759603024j), + (-0.23705175519+0.971496999264j), + (-0.310622543097+0.950533330441j), + (-0.38240903616+0.923993110657j), + (-0.451937526464+0.89204955101j), + (-0.518758952618+0.854920566082j), + (-0.582311093807+0.812966048717j), + (-0.642372369766+0.76639264822j), + (-0.698591887951+0.715520322323j), + (-0.750654160976+0.660695314407j), + (-0.798280358315+0.602286040783j), + (-0.841228663921+0.540679454803j), + (-0.87929558754+0.476276367903j), + (-0.912315964699+0.409486919641j), + (-0.940161883831+0.340728074312j), + (-0.962742805481+0.270418733358j), + (-0.980004072189+0.198977485299j), + (-0.991925954819+0.126818284392j), + (-0.99851256609+0.0545223206282j), + (-0.999846458435-0.0175215266645j), + (-0.996021270752-0.0891158208251j), + (-0.987133920193-0.159895718098j), + (-0.973306238651-0.2295101583j), + (-0.954683184624-0.297624111176j), + (-0.931430280209-0.363919824362j), + (-0.903732538223-0.428097635508j), + (-0.871792256832-0.489875763655j), + (-0.835827112198-0.548992812634j), + (-0.796068251133-0.605206847191j), + (-0.752758979797-0.658296227455j), + (-0.706152498722-0.70805978775j), + (-0.656641483307-0.754202902317j), + (-0.604367733002-0.79670548439j), + (-0.549597978592-0.835429251194j), + (-0.492602348328-0.870254516602j), + (-0.433654457331-0.901079237461j), + (-0.373029649258-0.927819430828j), + (-0.31100410223-0.950408577919j), + (-0.247853919864-0.968797445297j), + (-0.183855071664-0.982953369617j), + (-0.119282215834-0.992860376835j), + (-0.0544078871608-0.998518764973j), + (0.0104992967099-0.999944865704j), + (0.0749994292855-0.997183561325j), + (0.138844624162-0.990314185619j), + (0.201967850327-0.979392170906j), + (0.264124274254-0.964488625526j), + (0.325075358152-0.945688128471j), + (0.3845885396-0.92308807373j), + (0.442438393831-0.89679890871j), + (0.498407125473-0.866943061352j), + (0.552284479141-0.833655714989j), + (0.603869199753-0.797083437443j), + (0.652970373631-0.757383465767j), + (0.69940674305-0.714723825455j), + (0.743007957935-0.66928255558j), + (0.78350687027-0.62138313055j), + (0.820889055729-0.571087777615j), + (0.855021059513-0.51859331131j), + (0.885780930519-0.46410369873j), + (0.913058102131-0.407829582691j), + (0.936754107475-0.349988251925j), + (0.956783294678-0.290801793337j), + (0.973072886467-0.230497643352j), + (0.985563337803-0.169307261705j), + (0.9942086339-0.1074674353j), + (0.9989772439-0.0452152714133j), + (0.999851942062+0.0172088555992j)) sampling_freq = 10e3 freq = sampling_freq / 100 - alpha = 0.1 - beta = alpha * alpha / 4.0 + loop_bw = math.pi/100.0 maxf = 1 minf = -1 src = gr.sig_source_c (sampling_freq, gr.GR_COS_WAVE, freq, 1.0) - pll = gr.pll_refout_cc(alpha, beta, maxf, minf) + pll = gr.pll_refout_cc(loop_bw, maxf, minf) head = gr.head (gr.sizeof_gr_complex, int (freq)) dst = gr.vector_sink_c () @@ -151,8 +150,7 @@ class test_pll_refout (gr_unittest.TestCase): self.tb.run () dst_data = dst.data () - - self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 5) + self.assertComplexTuplesAlmostEqual (expected_result, dst_data, 4) if __name__ == '__main__': gr_unittest.run(test_pll_refout, "test_pll_refout.xml") diff --git a/gnuradio-core/src/python/gnuradio/gr/scheduler.py b/gnuradio-core/src/python/gnuradio/gr/scheduler.py deleted file mode 100644 index 4694d48b2..000000000 --- a/gnuradio-core/src/python/gnuradio/gr/scheduler.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright 2004 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.gr.exceptions import * -from gnuradio_swig_python import single_threaded_scheduler, sts_pyrun -import gr_threading as _threading -#import threading as _threading - -class scheduler_thread(_threading.Thread): - def __init__(self, sts): - _threading.Thread.__init__(self) - self.sts = sts - def run(self): - # Invoke the single threaded scheduler's run method - # - # Note that we're in a new thread, and that sts_pyrun - # releases the global interpreter lock. This has the - # effect of evaluating the graph in parallel to the - # main line control code. - sts_pyrun(self.sts) - self.sts = None - -class scheduler(object): - def __init__(self, fg): - graphs = fg.partition_graph(fg.blocks) - # print "@@@ # graphs = %d" % (len(graphs)) - - self.state = [] - - for g in graphs: - list_of_blocks = [x.block() for x in g] - sts = single_threaded_scheduler(list_of_blocks) - thread = scheduler_thread(sts) - thread.setDaemon(1) - self.state.append((sts, thread)) - - def start(self): - for (sts, thread) in self.state: - thread.start() - - def stop(self): - for (sts, thread) in self.state: - sts.stop() - self.wait() - - def wait(self): - for (sts, thread) in self.state: - timeout = 0.100 - while True: - thread.join(timeout) - if not thread.isAlive(): - break diff --git a/gnuradio-core/src/python/gnuradio/gr/top_block.py b/gnuradio-core/src/python/gnuradio/gr/top_block.py index 71e401424..1e36d3b48 100644 --- a/gnuradio-core/src/python/gnuradio/gr/top_block.py +++ b/gnuradio-core/src/python/gnuradio/gr/top_block.py @@ -19,7 +19,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio_swig_python import top_block_swig, \ +from gnuradio_core import top_block_swig, \ top_block_wait_unlocked, top_block_run_unlocked #import gnuradio.gr.gr_threading as _threading @@ -118,7 +118,7 @@ class top_block(object): raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),)) else: if len(points) == 1: - self._tb.connect(points[0].basic_block()) + self._tb.primitive_connect(points[0].to_basic_block()) else: for i in range (1, len (points)): self._connect(points[i-1], points[i]) @@ -126,11 +126,11 @@ class top_block(object): def _connect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) (dst_block, dst_port) = self._coerce_endpoint(dst) - self._tb.connect(src_block.basic_block(), src_port, - dst_block.basic_block(), dst_port) + self._tb.primitive_connect(src_block.to_basic_block(), src_port, + dst_block.to_basic_block(), dst_port) def _coerce_endpoint(self, endp): - if hasattr(endp, 'basic_block'): + if hasattr(endp, 'to_basic_block'): return (endp, 0) else: if hasattr(endp, "__getitem__") and len(endp) == 2: @@ -139,14 +139,14 @@ class top_block(object): raise ValueError("unable to coerce endpoint") def disconnect(self, *points): - '''connect requires one or more arguments that can be coerced to endpoints. + '''disconnect requires one or more arguments that can be coerced to endpoints. If more than two arguments are provided, they are disconnected successively. ''' if len (points) < 1: - raise ValueError, ("disconnect requires at least two endpoints; %d provided." % (len (points),)) + raise ValueError, ("disconnect requires at least one endpoint; %d provided." % (len (points),)) else: if len(points) == 1: - self._tb.disconnect(points[0].basic_block()) + self._tb.primitive_disconnect(points[0].to_basic_block()) else: for i in range (1, len (points)): self._disconnect(points[i-1], points[i]) @@ -154,6 +154,6 @@ class top_block(object): def _disconnect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) (dst_block, dst_port) = self._coerce_endpoint(dst) - self._tb.disconnect(src_block.basic_block(), src_port, - dst_block.basic_block(), dst_port) + self._tb.primitive_disconnect(src_block.to_basic_block(), src_port, + dst_block.to_basic_block(), dst_port) diff --git a/gnuradio-core/src/python/gnuradio/gr_unittest.py b/gnuradio-core/src/python/gnuradio/gr_unittest.py index 50d484a76..c2c4df2ba 100755 --- a/gnuradio-core/src/python/gnuradio/gr_unittest.py +++ b/gnuradio-core/src/python/gnuradio/gr_unittest.py @@ -38,7 +38,7 @@ class TestCase(unittest.TestCase): Note that decimal places (from zero) is usually not the same as significant digits (measured from the most signficant digit). - """ + """ if round(second.real-first.real, places) != 0: raise self.failureException, \ (msg or '%s != %s within %s places' % (`first`, `second`, `places` )) @@ -112,30 +112,31 @@ def run(PUT, filename=None): Runs the unittest on a TestCase and produces an optional XML report PUT: the program under test and should be a gr_unittest.TestCase filename: an optional filename to save the XML report of the tests - this will live in $HOME/.gnuradio/unittests/python + this will live in ./.unittests/python ''' # Run this is given a file name if(filename is not None): - homepath = os.getenv("HOME") - basepath = homepath + "/.gnuradio" - path = homepath + "/.gnuradio/unittests/python" + basepath = "./.unittests" + path = basepath + "/python" + + if not os.path.exists(basepath): + os.makedirs(basepath, 0750) xmlrunner = None - if os.path.exists(basepath): - # only proceed if $HOME/.gnuradio is writable - st = os.stat(basepath)[stat.ST_MODE] + # only proceed if .unittests is writable + st = os.stat(basepath)[stat.ST_MODE] + if(st & stat.S_IWUSR > 0): + # Test if path exists; if not, build it + if not os.path.exists(path): + os.makedirs(path, 0750) + + # Just for safety: make sure we can write here, too + st = os.stat(path)[stat.ST_MODE] if(st & stat.S_IWUSR > 0): - # Test if path exists; if not, build it - if not os.path.exists(path): - os.makedirs(path, 0750) - - # Just for safety: make sure we can write here, too - st = os.stat(path)[stat.ST_MODE] - if(st & stat.S_IWUSR > 0): - # Create an XML runner to filename - fout = file(path+"/"+filename, "w") - xmlrunner = gr_xmlrunner.XMLTestRunner(fout) + # Create an XML runner to filename + fout = file(path+"/"+filename, "w") + xmlrunner = gr_xmlrunner.XMLTestRunner(fout) txtrunner = TextTestRunner(verbosity=1) diff --git a/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py b/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py index ded77f5f3..c3dc5cf13 100644 --- a/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py +++ b/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py @@ -6,8 +6,6 @@ XML Test Runner for PyUnit # the Public Domain. With contributions by Paolo Borelli and others. # Added to GNU Radio Oct. 3, 2010 -from __future__ import with_statement - __version__ = "0.1" import os.path @@ -185,7 +183,9 @@ class XMLTestRunner(object): result = _XMLTestResult(classname) start_time = time.time() - with _fake_std_streams(): + fss = _fake_std_streams() + fss.__enter__() + try: test(result) try: out_s = sys.stdout.getvalue() @@ -195,6 +195,8 @@ class XMLTestRunner(object): err_s = sys.stderr.getvalue() except AttributeError: err_s = "" + finally: + fss.__exit__(None, None, None) time_taken = time.time() - start_time result.print_report(stream, time_taken, out_s, err_s) @@ -218,8 +220,8 @@ class _fake_std_streams(object): def __enter__(self): self._orig_stdout = sys.stdout self._orig_stderr = sys.stderr - sys.stdout = StringIO() - sys.stderr = StringIO() + #sys.stdout = StringIO() + #sys.stderr = StringIO() def __exit__(self, exc_type, exc_val, exc_tb): sys.stdout = self._orig_stdout diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/Makefile.am b/gnuradio-core/src/python/gnuradio/gruimpl/Makefile.am index ffae4b809..903bc2695 100644 --- a/gnuradio-core/src/python/gnuradio/gruimpl/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/gruimpl/Makefile.am @@ -25,7 +25,6 @@ grupythondir = $(grpythondir)/gruimpl grupython_PYTHON = \ __init__.py \ - crc.py \ freqz.py \ gnuplot_freqz.py \ hexint.py \ diff --git a/gnuradio-core/src/python/gnuradio/gruimpl/crc.py b/gnuradio-core/src/python/gnuradio/gruimpl/crc.py deleted file mode 100644 index d31aca0ea..000000000 --- a/gnuradio-core/src/python/gnuradio/gruimpl/crc.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# Copyright 2005,2007 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 hexint import * -import struct - -def gen_and_append_crc32(s): - crc = gr.crc32(s) - return s + struct.pack(">I", hexint(crc) & 0xFFFFFFFF) - -def check_crc32(s): - if len(s) < 4: - return (False, '') - msg = s[:-4] - #print "msg = '%s'" % (msg,) - actual = gr.crc32(msg) - (expected,) = struct.unpack(">I", s[-4:]) - # print "actual =", hex(actual), "expected =", hex(expected) - return (actual == expected, msg) diff --git a/gnuradio-core/src/python/gnuradio/modulation_utils.py b/gnuradio-core/src/python/gnuradio/modulation_utils.py deleted file mode 100644 index 71ba77389..000000000 --- a/gnuradio-core/src/python/gnuradio/modulation_utils.py +++ /dev/null @@ -1,81 +0,0 @@ -# -# Copyright 2006 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 this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# - -""" -Miscellaneous utilities for managing mods and demods, as well as other items -useful in dealing with generalized handling of different modulations and demods. -""" - -import inspect - - -# Type 1 modulators accept a stream of bytes on their input and produce complex baseband output -_type_1_modulators = {} - -def type_1_mods(): - return _type_1_modulators - -def add_type_1_mod(name, mod_class): - _type_1_modulators[name] = mod_class - - -# Type 1 demodulators accept complex baseband input and produce a stream of bits, packed -# 1 bit / byte as their output. Their output is completely unambiguous. There is no need -# to resolve phase or polarity ambiguities. -_type_1_demodulators = {} - -def type_1_demods(): - return _type_1_demodulators - -def add_type_1_demod(name, demod_class): - _type_1_demodulators[name] = demod_class - - -def extract_kwargs_from_options(function, excluded_args, options): - """ - Given a function, a list of excluded arguments and the result of - parsing command line options, create a dictionary of key word - arguments suitable for passing to the function. The dictionary - will be populated with key/value pairs where the keys are those - that are common to the function's argument list (minus the - excluded_args) and the attributes in options. The values are the - corresponding values from options unless that value is None. - In that case, the corresponding dictionary entry is not populated. - - (This allows different modulations that have the same parameter - names, but different default values to coexist. The downside is - that --help in the option parser will list the default as None, - but in that case the default provided in the __init__ argument - list will be used since there is no kwargs entry.) - - @param function: the function whose parameter list will be examined - @param excluded_args: function arguments that are NOT to be added to the dictionary - @type excluded_args: sequence of strings - @param options: result of command argument parsing - @type options: optparse.Values - """ - # Try this in C++ ;) - args, varargs, varkw, defaults = inspect.getargspec(function) - d = {} - for kw in [a for a in args if a not in excluded_args]: - if hasattr(options, kw): - if getattr(options, kw) is not None: - d[kw] = getattr(options, kw) - return d diff --git a/gnuradio-core/src/python/gnuradio/modulation_utils2.py b/gnuradio-core/src/python/gnuradio/modulation_utils2.py index c5dba3e79..f30055f4a 100644 --- a/gnuradio-core/src/python/gnuradio/modulation_utils2.py +++ b/gnuradio-core/src/python/gnuradio/modulation_utils2.py @@ -47,6 +47,15 @@ def type_1_demods(): def add_type_1_demod(name, demod_class): _type_1_demodulators[name] = demod_class +# Also record the constellation making functions of the modulations +_type_1_constellations = {} + +def type_1_constellations(): + return _type_1_constellations + +def add_type_1_constellation(name, constellation): + _type_1_constellations[name] = constellation + def extract_kwargs_from_options(function, excluded_args, options): """ @@ -79,3 +88,14 @@ def extract_kwargs_from_options(function, excluded_args, options): if getattr(options, kw) is not None: d[kw] = getattr(options, kw) return d + +def extract_kwargs_from_options_for_class(cls, options): + """ + Given command line options, create dictionary suitable for passing to __init__ + """ + d = extract_kwargs_from_options( + cls.__init__, ('self',), options) + for base in cls.__bases__: + if hasattr(base, 'extract_kwargs_from_options'): + d.update(base.extract_kwargs_from_options(options)) + return d diff --git a/gnuradio-core/src/python/gnuradio/packet_utils.py b/gnuradio-core/src/python/gnuradio/packet_utils.py deleted file mode 100644 index e36b05413..000000000 --- a/gnuradio-core/src/python/gnuradio/packet_utils.py +++ /dev/null @@ -1,457 +0,0 @@ -# -# Copyright 2005,2006,2007 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 struct -import numpy -from gnuradio import gru - - -def conv_packed_binary_string_to_1_0_string(s): - """ - '\xAF' --> '10101111' - """ - r = [] - for ch in s: - x = ord(ch) - for i in range(7,-1,-1): - t = (x >> i) & 0x1 - r.append(t) - - return ''.join(map(lambda x: chr(x + ord('0')), r)) - -def conv_1_0_string_to_packed_binary_string(s): - """ - '10101111' -> ('\xAF', False) - - Basically the inverse of conv_packed_binary_string_to_1_0_string, - but also returns a flag indicating if we had to pad with leading zeros - to get to a multiple of 8. - """ - if not is_1_0_string(s): - raise ValueError, "Input must be a string containing only 0's and 1's" - - # pad to multiple of 8 - padded = False - rem = len(s) % 8 - if rem != 0: - npad = 8 - rem - s = '0' * npad + s - padded = True - - assert len(s) % 8 == 0 - - r = [] - i = 0 - while i < len(s): - t = 0 - for j in range(8): - t = (t << 1) | (ord(s[i + j]) - ord('0')) - r.append(chr(t)) - i += 8 - return (''.join(r), padded) - - -default_access_code = \ - conv_packed_binary_string_to_1_0_string('\xAC\xDD\xA4\xE2\xF2\x8C\x20\xFC') -preamble = \ - conv_packed_binary_string_to_1_0_string('\xA4\xF2') - -def is_1_0_string(s): - if not isinstance(s, str): - return False - for ch in s: - if not ch in ('0', '1'): - return False - return True - -def string_to_hex_list(s): - return map(lambda x: hex(ord(x)), s) - - -def whiten(s, o): - sa = numpy.fromstring(s, numpy.uint8) - z = sa ^ random_mask_vec8[o:len(sa)+o] - return z.tostring() - -def dewhiten(s, o): - return whiten(s, o) # self inverse - - -def make_header(payload_len, whitener_offset=0): - # Upper nibble is offset, lower 12 bits is len - val = ((whitener_offset & 0xf) << 12) | (payload_len & 0x0fff) - #print "offset =", whitener_offset, " len =", payload_len, " val=", val - return struct.pack('!HH', val, val) - -def make_packet(payload, samples_per_symbol, bits_per_symbol, - access_code=default_access_code, pad_for_usrp=True, - whitener_offset=0, whitening=True): - """ - Build a packet, given access code, payload, and whitener offset - - @param payload: packet payload, len [0, 4096] - @param samples_per_symbol: samples per symbol (needed for padding calculation) - @type samples_per_symbol: int - @param bits_per_symbol: (needed for padding calculation) - @type bits_per_symbol: int - @param access_code: string of ascii 0's and 1's - @param whitener_offset offset into whitener string to use [0-16) - - Packet will have access code at the beginning, followed by length, payload - and finally CRC-32. - """ - if not is_1_0_string(access_code): - raise ValueError, "access_code must be a string containing only 0's and 1's (%r)" % (access_code,) - - if not whitener_offset >=0 and whitener_offset < 16: - raise ValueError, "whitener_offset must be between 0 and 15, inclusive (%i)" % (whitener_offset,) - - (packed_access_code, padded) = conv_1_0_string_to_packed_binary_string(access_code) - (packed_preamble, ignore) = conv_1_0_string_to_packed_binary_string(preamble) - - payload_with_crc = gru.gen_and_append_crc32(payload) - #print "outbound crc =", string_to_hex_list(payload_with_crc[-4:]) - - L = len(payload_with_crc) - MAXLEN = len(random_mask_tuple) - if L > MAXLEN: - raise ValueError, "len(payload) must be in [0, %d]" % (MAXLEN,) - - if whitening: - pkt = ''.join((packed_preamble, packed_access_code, make_header(L, whitener_offset), - whiten(payload_with_crc, whitener_offset), '\x55')) - else: - pkt = ''.join((packed_preamble, packed_access_code, make_header(L, whitener_offset), - (payload_with_crc), '\x55')) - - if pad_for_usrp: - pkt = pkt + (_npadding_bytes(len(pkt), int(samples_per_symbol), bits_per_symbol) * '\x55') - - #print "make_packet: len(pkt) =", len(pkt) - return pkt - -def _npadding_bytes(pkt_byte_len, samples_per_symbol, bits_per_symbol): - """ - Generate sufficient padding such that each packet ultimately ends - up being a multiple of 512 bytes when sent across the USB. We - send 4-byte samples across the USB (16-bit I and 16-bit Q), thus - we want to pad so that after modulation the resulting packet - is a multiple of 128 samples. - - @param ptk_byte_len: len in bytes of packet, not including padding. - @param samples_per_symbol: samples per bit (1 bit / symbolwidth GMSK) - @type samples_per_symbol: int - @param bits_per_symbol: bits per symbol (log2(modulation order)) - @type bits_per_symbol: int - - @returns number of bytes of padding to append. - """ - modulus = 128 - byte_modulus = gru.lcm(modulus/8, samples_per_symbol) * bits_per_symbol / samples_per_symbol - r = pkt_byte_len % byte_modulus - if r == 0: - return 0 - return byte_modulus - r - - -def unmake_packet(whitened_payload_with_crc, whitener_offset=0, dewhitening=True): - """ - Return (ok, payload) - - @param whitened_payload_with_crc: string - """ - - if dewhitening: - payload_with_crc = dewhiten(whitened_payload_with_crc, whitener_offset) - else: - payload_with_crc = (whitened_payload_with_crc) - - ok, payload = gru.check_crc32(payload_with_crc) - - if 0: - print "payload_with_crc =", string_to_hex_list(payload_with_crc) - print "ok = %r, len(payload) = %d" % (ok, len(payload)) - print "payload =", string_to_hex_list(payload) - - return ok, payload - - -# FYI, this PN code is the output of a 15-bit LFSR -random_mask_tuple = ( - 255, 63, 0, 16, 0, 12, 0, 5, 192, 3, 16, 1, 204, 0, 85, 192, - 63, 16, 16, 12, 12, 5, 197, 195, 19, 17, 205, 204, 85, 149, 255, 47, - 0, 28, 0, 9, 192, 6, 208, 2, 220, 1, 153, 192, 106, 208, 47, 28, - 28, 9, 201, 198, 214, 210, 222, 221, 152, 89, 170, 186, 255, 51, 0, 21, - 192, 15, 16, 4, 12, 3, 69, 193, 243, 16, 69, 204, 51, 21, 213, 207, - 31, 20, 8, 15, 70, 132, 50, 227, 85, 137, 255, 38, 192, 26, 208, 11, - 28, 7, 73, 194, 182, 209, 182, 220, 118, 217, 230, 218, 202, 219, 23, 27, - 78, 139, 116, 103, 103, 106, 170, 175, 63, 60, 16, 17, 204, 12, 85, 197, - 255, 19, 0, 13, 192, 5, 144, 3, 44, 1, 221, 192, 89, 144, 58, 236, - 19, 13, 205, 197, 149, 147, 47, 45, 220, 29, 153, 201, 170, 214, 255, 30, - 192, 8, 80, 6, 188, 2, 241, 193, 132, 80, 99, 124, 41, 225, 222, 200, - 88, 86, 186, 190, 243, 48, 69, 212, 51, 31, 85, 200, 63, 22, 144, 14, - 236, 4, 77, 195, 117, 145, 231, 44, 74, 157, 247, 41, 134, 158, 226, 232, - 73, 142, 182, 228, 118, 203, 102, 215, 106, 222, 175, 24, 124, 10, 161, 199, - 56, 82, 146, 189, 173, 177, 189, 180, 113, 183, 100, 118, 171, 102, 255, 106, - 192, 47, 16, 28, 12, 9, 197, 198, 211, 18, 221, 205, 153, 149, 170, 239, - 63, 12, 16, 5, 204, 3, 21, 193, 207, 16, 84, 12, 63, 69, 208, 51, - 28, 21, 201, 207, 22, 212, 14, 223, 68, 88, 51, 122, 149, 227, 47, 9, - 220, 6, 217, 194, 218, 209, 155, 28, 107, 73, 239, 118, 204, 38, 213, 218, - 223, 27, 24, 11, 74, 135, 119, 34, 166, 153, 186, 234, 243, 15, 5, 196, - 3, 19, 65, 205, 240, 85, 132, 63, 35, 80, 25, 252, 10, 193, 199, 16, - 82, 140, 61, 165, 209, 187, 28, 115, 73, 229, 246, 203, 6, 215, 66, 222, - 177, 152, 116, 106, 167, 111, 58, 172, 19, 61, 205, 209, 149, 156, 111, 41, - 236, 30, 205, 200, 85, 150, 191, 46, 240, 28, 68, 9, 243, 70, 197, 242, - 211, 5, 157, 195, 41, 145, 222, 236, 88, 77, 250, 181, 131, 55, 33, 214, - 152, 94, 234, 184, 79, 50, 180, 21, 183, 79, 54, 180, 22, 247, 78, 198, - 180, 82, 247, 125, 134, 161, 162, 248, 121, 130, 162, 225, 185, 136, 114, 230, - 165, 138, 251, 39, 3, 90, 129, 251, 32, 67, 88, 49, 250, 148, 67, 47, - 113, 220, 36, 89, 219, 122, 219, 99, 27, 105, 203, 110, 215, 108, 94, 173, - 248, 125, 130, 161, 161, 184, 120, 114, 162, 165, 185, 187, 50, 243, 85, 133, - 255, 35, 0, 25, 192, 10, 208, 7, 28, 2, 137, 193, 166, 208, 122, 220, - 35, 25, 217, 202, 218, 215, 27, 30, 139, 72, 103, 118, 170, 166, 255, 58, - 192, 19, 16, 13, 204, 5, 149, 195, 47, 17, 220, 12, 89, 197, 250, 211, - 3, 29, 193, 201, 144, 86, 236, 62, 205, 208, 85, 156, 63, 41, 208, 30, - 220, 8, 89, 198, 186, 210, 243, 29, 133, 201, 163, 22, 249, 206, 194, 212, - 81, 159, 124, 104, 33, 238, 152, 76, 106, 181, 239, 55, 12, 22, 133, 206, - 227, 20, 73, 207, 118, 212, 38, 223, 90, 216, 59, 26, 147, 75, 45, 247, - 93, 134, 185, 162, 242, 249, 133, 130, 227, 33, 137, 216, 102, 218, 170, 219, - 63, 27, 80, 11, 124, 7, 97, 194, 168, 81, 190, 188, 112, 113, 228, 36, - 75, 91, 119, 123, 102, 163, 106, 249, 239, 2, 204, 1, 149, 192, 111, 16, - 44, 12, 29, 197, 201, 147, 22, 237, 206, 205, 148, 85, 175, 127, 60, 32, - 17, 216, 12, 90, 133, 251, 35, 3, 89, 193, 250, 208, 67, 28, 49, 201, - 212, 86, 223, 126, 216, 32, 90, 152, 59, 42, 147, 95, 45, 248, 29, 130, - 137, 161, 166, 248, 122, 194, 163, 17, 185, 204, 114, 213, 229, 159, 11, 40, - 7, 94, 130, 184, 97, 178, 168, 117, 190, 167, 48, 122, 148, 35, 47, 89, - 220, 58, 217, 211, 26, 221, 203, 25, 151, 74, 238, 183, 12, 118, 133, 230, - 227, 10, 201, 199, 22, 210, 142, 221, 164, 89, 187, 122, 243, 99, 5, 233, - 195, 14, 209, 196, 92, 83, 121, 253, 226, 193, 137, 144, 102, 236, 42, 205, - 223, 21, 152, 15, 42, 132, 31, 35, 72, 25, 246, 138, 198, 231, 18, 202, - 141, 151, 37, 174, 155, 60, 107, 81, 239, 124, 76, 33, 245, 216, 71, 26, - 178, 139, 53, 167, 87, 58, 190, 147, 48, 109, 212, 45, 159, 93, 168, 57, - 190, 146, 240, 109, 132, 45, 163, 93, 185, 249, 178, 194, 245, 145, 135, 44, - 98, 157, 233, 169, 142, 254, 228, 64, 75, 112, 55, 100, 22, 171, 78, 255, - 116, 64, 39, 112, 26, 164, 11, 59, 71, 83, 114, 189, 229, 177, 139, 52, - 103, 87, 106, 190, 175, 48, 124, 20, 33, 207, 88, 84, 58, 191, 83, 48, - 61, 212, 17, 159, 76, 104, 53, 238, 151, 12, 110, 133, 236, 99, 13, 233, - 197, 142, 211, 36, 93, 219, 121, 155, 98, 235, 105, 143, 110, 228, 44, 75, - 93, 247, 121, 134, 162, 226, 249, 137, 130, 230, 225, 138, 200, 103, 22, 170, - 142, 255, 36, 64, 27, 112, 11, 100, 7, 107, 66, 175, 113, 188, 36, 113, - 219, 100, 91, 107, 123, 111, 99, 108, 41, 237, 222, 205, 152, 85, 170, 191, - 63, 48, 16, 20, 12, 15, 69, 196, 51, 19, 85, 205, 255, 21, 128, 15, - 32, 4, 24, 3, 74, 129, 247, 32, 70, 152, 50, 234, 149, 143, 47, 36, - 28, 27, 73, 203, 118, 215, 102, 222, 170, 216, 127, 26, 160, 11, 56, 7, - 82, 130, 189, 161, 177, 184, 116, 114, 167, 101, 186, 171, 51, 63, 85, 208, - 63, 28, 16, 9, 204, 6, 213, 194, 223, 17, 152, 12, 106, 133, 239, 35, - 12, 25, 197, 202, 211, 23, 29, 206, 137, 148, 102, 239, 106, 204, 47, 21, - 220, 15, 25, 196, 10, 211, 71, 29, 242, 137, 133, 166, 227, 58, 201, 211, - 22, 221, 206, 217, 148, 90, 239, 123, 12, 35, 69, 217, 243, 26, 197, 203, - 19, 23, 77, 206, 181, 148, 119, 47, 102, 156, 42, 233, 223, 14, 216, 4, - 90, 131, 123, 33, 227, 88, 73, 250, 182, 195, 54, 209, 214, 220, 94, 217, - 248, 90, 194, 187, 17, 179, 76, 117, 245, 231, 7, 10, 130, 135, 33, 162, - 152, 121, 170, 162, 255, 57, 128, 18, 224, 13, 136, 5, 166, 131, 58, 225, - 211, 8, 93, 198, 185, 146, 242, 237, 133, 141, 163, 37, 185, 219, 50, 219, - 85, 155, 127, 43, 96, 31, 104, 8, 46, 134, 156, 98, 233, 233, 142, 206, - 228, 84, 75, 127, 119, 96, 38, 168, 26, 254, 139, 0, 103, 64, 42, 176, - 31, 52, 8, 23, 70, 142, 178, 228, 117, 139, 103, 39, 106, 154, 175, 43, - 60, 31, 81, 200, 60, 86, 145, 254, 236, 64, 77, 240, 53, 132, 23, 35, - 78, 153, 244, 106, 199, 111, 18, 172, 13, 189, 197, 177, 147, 52, 109, 215, - 109, 158, 173, 168, 125, 190, 161, 176, 120, 116, 34, 167, 89, 186, 186, 243, - 51, 5, 213, 195, 31, 17, 200, 12, 86, 133, 254, 227, 0, 73, 192, 54, - 208, 22, 220, 14, 217, 196, 90, 211, 123, 29, 227, 73, 137, 246, 230, 198, - 202, 210, 215, 29, 158, 137, 168, 102, 254, 170, 192, 127, 16, 32, 12, 24, - 5, 202, 131, 23, 33, 206, 152, 84, 106, 191, 111, 48, 44, 20, 29, 207, - 73, 148, 54, 239, 86, 204, 62, 213, 208, 95, 28, 56, 9, 210, 134, 221, - 162, 217, 185, 154, 242, 235, 5, 143, 67, 36, 49, 219, 84, 91, 127, 123, - 96, 35, 104, 25, 238, 138, 204, 103, 21, 234, 143, 15, 36, 4, 27, 67, - 75, 113, 247, 100, 70, 171, 114, 255, 101, 128, 43, 32, 31, 88, 8, 58, - 134, 147, 34, 237, 217, 141, 154, 229, 171, 11, 63, 71, 80, 50, 188, 21, - 177, 207, 52, 84, 23, 127, 78, 160, 52, 120, 23, 98, 142, 169, 164, 126, - 251, 96, 67, 104, 49, 238, 148, 76, 111, 117, 236, 39, 13, 218, 133, 155, - 35, 43, 89, 223, 122, 216, 35, 26, 153, 203, 42, 215, 95, 30, 184, 8, - 114, 134, 165, 162, 251, 57, 131, 82, 225, 253, 136, 65, 166, 176, 122, 244, - 35, 7, 89, 194, 186, 209, 179, 28, 117, 201, 231, 22, 202, 142, 215, 36, - 94, 155, 120, 107, 98, 175, 105, 188, 46, 241, 220, 68, 89, 243, 122, 197, - 227, 19, 9, 205, 198, 213, 146, 223, 45, 152, 29, 170, 137, 191, 38, 240, - 26, 196, 11, 19, 71, 77, 242, 181, 133, 183, 35, 54, 153, 214, 234, 222, - 207, 24, 84, 10, 191, 71, 48, 50, 148, 21, 175, 79, 60, 52, 17, 215, - 76, 94, 181, 248, 119, 2, 166, 129, 186, 224, 115, 8, 37, 198, 155, 18, - 235, 77, 143, 117, 164, 39, 59, 90, 147, 123, 45, 227, 93, 137, 249, 166, - 194, 250, 209, 131, 28, 97, 201, 232, 86, 206, 190, 212, 112, 95, 100, 56, - 43, 82, 159, 125, 168, 33, 190, 152, 112, 106, 164, 47, 59, 92, 19, 121, - 205, 226, 213, 137, 159, 38, 232, 26, 206, 139, 20, 103, 79, 106, 180, 47, - 55, 92, 22, 185, 206, 242, 212, 69, 159, 115, 40, 37, 222, 155, 24, 107, - 74, 175, 119, 60, 38, 145, 218, 236, 91, 13, 251, 69, 131, 115, 33, 229, - 216, 75, 26, 183, 75, 54, 183, 86, 246, 190, 198, 240, 82, 196, 61, 147, - 81, 173, 252, 125, 129, 225, 160, 72, 120, 54, 162, 150, 249, 174, 194, 252, - 81, 129, 252, 96, 65, 232, 48, 78, 148, 52, 111, 87, 108, 62, 173, 208, - 125, 156, 33, 169, 216, 126, 218, 160, 91, 56, 59, 82, 147, 125, 173, 225, - 189, 136, 113, 166, 164, 122, 251, 99, 3, 105, 193, 238, 208, 76, 92, 53, - 249, 215, 2, 222, 129, 152, 96, 106, 168, 47, 62, 156, 16, 105, 204, 46, - 213, 220, 95, 25, 248, 10, 194, 135, 17, 162, 140, 121, 165, 226, 251, 9, - 131, 70, 225, 242, 200, 69, 150, 179, 46, 245, 220, 71, 25, 242, 138, 197, - 167, 19, 58, 141, 211, 37, 157, 219, 41, 155, 94, 235, 120, 79, 98, 180, - 41, 183, 94, 246, 184, 70, 242, 178, 197, 181, 147, 55, 45, 214, 157, 158, - 233, 168, 78, 254, 180, 64, 119, 112, 38, 164, 26, 251, 75, 3, 119, 65, - 230, 176, 74, 244, 55, 7, 86, 130, 190, 225, 176, 72, 116, 54, 167, 86, - 250, 190, 195, 48, 81, 212, 60, 95, 81, 248, 60, 66, 145, 241, 172, 68, - 125, 243, 97, 133, 232, 99, 14, 169, 196, 126, 211, 96, 93, 232, 57, 142, - 146, 228, 109, 139, 109, 167, 109, 186, 173, 179, 61, 181, 209, 183, 28, 118, - 137, 230, 230, 202, 202, 215, 23, 30, 142, 136, 100, 102, 171, 106, 255, 111, - 0, 44, 0, 29, 192, 9, 144, 6, 236, 2, 205, 193, 149, 144, 111, 44, - 44, 29, 221, 201, 153, 150, 234, 238, 207, 12, 84, 5, 255, 67, 0, 49, - 192, 20, 80, 15, 124, 4, 33, 195, 88, 81, 250, 188, 67, 49, 241, 212, - 68, 95, 115, 120, 37, 226, 155, 9, 171, 70, 255, 114, 192, 37, 144, 27, - 44, 11, 93, 199, 121, 146, 162, 237, 185, 141, 178, 229, 181, 139, 55, 39, - 86, 154, 190, 235, 48, 79, 84, 52, 63, 87, 80, 62, 188, 16, 113, 204, - 36, 85, 219, 127, 27, 96, 11, 104, 7, 110, 130, 172, 97, 189, 232, 113, - 142, 164, 100, 123, 107, 99, 111, 105, 236, 46, 205, 220, 85, 153, 255, 42, - 192, 31, 16, 8, 12, 6, 133, 194, 227, 17, 137, 204, 102, 213, 234, 223, - 15, 24, 4, 10, 131, 71, 33, 242, 152, 69, 170, 179, 63, 53, 208, 23, - 28, 14, 137, 196, 102, 211, 106, 221, 239, 25, 140, 10, 229, 199, 11, 18, - 135, 77, 162, 181, 185, 183, 50, 246, 149, 134, 239, 34, 204, 25, 149, 202, - 239, 23, 12, 14, 133, 196, 99, 19, 105, 205, 238, 213, 140, 95, 37, 248, - 27, 2, 139, 65, 167, 112, 122, 164, 35, 59, 89, 211, 122, 221, 227, 25, - 137, 202, 230, 215, 10, 222, 135, 24, 98, 138, 169, 167, 62, 250, 144, 67, - 44, 49, 221, 212, 89, 159, 122, 232, 35, 14, 153, 196, 106, 211, 111, 29, - 236, 9, 141, 198, 229, 146, 203, 45, 151, 93, 174, 185, 188, 114, 241, 229, - 132, 75, 35, 119, 89, 230, 186, 202, 243, 23, 5, 206, 131, 20, 97, 207, - 104, 84, 46, 191, 92, 112, 57, 228, 18, 203, 77, 151, 117, 174, 167, 60, - 122, 145, 227, 44, 73, 221, 246, 217, 134, 218, 226, 219, 9, 155, 70, 235, - 114, 207, 101, 148, 43, 47, 95, 92, 56, 57, 210, 146, 221, 173, 153, 189, - 170, 241, 191, 4, 112, 3, 100, 1, 235, 64, 79, 112, 52, 36, 23, 91, - 78, 187, 116, 115, 103, 101, 234, 171, 15, 63, 68, 16, 51, 76, 21, 245, - 207, 7, 20, 2, 143, 65, 164, 48, 123, 84, 35, 127, 89, 224, 58, 200, - 19, 22, 141, 206, 229, 148, 75, 47, 119, 92, 38, 185, 218, 242, 219, 5, - 155, 67, 43, 113, 223, 100, 88, 43, 122, 159, 99, 40, 41, 222, 158, 216, - 104, 90, 174, 187, 60, 115, 81, 229, 252, 75, 1, 247, 64, 70, 176, 50, - 244, 21, 135, 79, 34, 180, 25, 183, 74, 246, 183, 6, 246, 130, 198, 225, - 146, 200, 109, 150, 173, 174, 253, 188, 65, 177, 240, 116, 68, 39, 115, 90, - 165, 251, 59, 3, 83, 65, 253, 240, 65, 132, 48, 99, 84, 41, 255, 94, - 192, 56, 80, 18, 188, 13, 177, 197, 180, 83, 55, 125, 214, 161, 158, 248, - 104, 66, 174, 177, 188, 116, 113, 231, 100, 74, 171, 119, 63, 102, 144, 42, - 236, 31, 13, 200, 5, 150, 131, 46, 225, 220, 72, 89, 246, 186, 198, 243, - 18, 197, 205, 147, 21, 173, 207, 61, 148, 17, 175, 76, 124, 53, 225, 215, - 8, 94, 134, 184, 98, 242, 169, 133, 190, 227, 48, 73, 212, 54, 223, 86, - 216, 62, 218, 144, 91, 44, 59, 93, 211, 121, 157, 226, 233, 137, 142, 230, - 228, 74, 203, 119, 23, 102, 142, 170, 228, 127, 11, 96, 7, 104, 2, 174, - 129, 188, 96, 113, 232, 36, 78, 155, 116, 107, 103, 111, 106, 172, 47, 61, - 220, 17, 153, 204, 106, 213, 239, 31, 12, 8, 5, 198, 131, 18, 225, 205, - 136, 85, 166, 191, 58, 240, 19, 4, 13, 195, 69, 145, 243, 44, 69, 221, - 243, 25, 133, 202, 227, 23, 9, 206, 134, 212, 98, 223, 105, 152, 46, 234, - 156, 79, 41, 244, 30, 199, 72, 82, 182, 189, 182, 241, 182, 196, 118, 211, - 102, 221, 234, 217, 143, 26, 228, 11, 11, 71, 71, 114, 178, 165, 181, 187, - 55, 51, 86, 149, 254, 239, 0, 76, 0, 53, 192, 23, 16, 14, 140, 4, - 101, 195, 107, 17, 239, 76, 76, 53, 245, 215, 7, 30, 130, 136, 97, 166, - 168, 122, 254, 163, 0, 121, 192, 34, 208, 25, 156, 10, 233, 199, 14, 210, - 132, 93, 163, 121, 185, 226, 242, 201, 133, 150, 227, 46, 201, 220, 86, 217, - 254, 218, 192, 91, 16, 59, 76, 19, 117, 205, 231, 21, 138, 143, 39, 36, - 26, 155, 75, 43, 119, 95, 102, 184, 42, 242, 159, 5, 168, 3, 62, 129, - 208, 96, 92, 40, 57, 222, 146, 216, 109, 154, 173, 171, 61, 191, 81, 176, - 60, 116, 17, 231, 76, 74, 181, 247, 55, 6, 150, 130, 238, 225, 140, 72, - 101, 246, 171, 6, 255, 66, 192, 49, 144, 20, 108, 15, 109, 196, 45, 147, - 93, 173, 249, 189, 130, 241, 161, 132, 120, 99, 98, 169, 233, 190, 206, 240, - 84, 68, 63, 115, 80, 37, 252, 27, 1, 203, 64, 87, 112, 62, 164, 16, - 123, 76, 35, 117, 217, 231, 26, 202, 139, 23, 39, 78, 154, 180, 107, 55, - 111, 86, 172, 62, 253, 208, 65, 156, 48, 105, 212, 46, 223, 92, 88, 57, - 250, 146, 195, 45, 145, 221, 172, 89, 189, 250, 241, 131, 4, 97, 195, 104, - 81, 238, 188, 76, 113, 245, 228, 71, 11, 114, 135, 101, 162, 171, 57, 191, - 82, 240, 61, 132, 17, 163, 76, 121, 245, 226, 199, 9, 146, 134, 237, 162, - 205, 185, 149, 178, 239, 53, 140, 23, 37, 206, 155, 20, 107, 79, 111, 116, - 44, 39, 93, 218, 185, 155, 50, 235, 85, 143, 127, 36, 32, 27, 88, 11, - 122, 135, 99, 34, 169, 217, 190, 218, 240, 91, 4, 59, 67, 83, 113, 253, - 228, 65, 139, 112, 103, 100, 42, 171, 95, 63, 120, 16, 34, 140, 25, 165, - 202, 251, 23, 3, 78, 129, 244, 96, 71, 104, 50, 174, 149, 188, 111, 49, - 236, 20, 77, 207, 117, 148, 39, 47, 90, 156, 59, 41, 211, 94, 221, 248, - 89, 130, 186, 225, 179, 8, 117, 198, 167, 18, 250, 141, 131, 37, 161, 219, - 56, 91, 82, 187, 125, 179, 97, 181, 232, 119, 14, 166, 132, 122, 227, 99, - 9, 233, 198, 206, 210, 212, 93, 159, 121, 168, 34, 254, 153, 128, 106, 224, - 47, 8, 28, 6, 137, 194, 230, 209, 138, 220, 103, 25, 234, 138, 207, 39, - 20, 26, 143, 75, 36, 55, 91, 86, 187, 126, 243, 96, 69, 232, 51, 14, - 149, 196, 111, 19, 108, 13, 237, 197, 141, 147, 37, 173, 219, 61, 155, 81, - 171, 124, 127, 97, 224, 40, 72, 30, 182, 136, 118, 230, 166, 202, 250, 215, - 3, 30, 129, 200, 96, 86, 168, 62, 254, 144, 64, 108, 48, 45, 212, 29, - 159, 73, 168, 54, 254, 150, 192, 110, 208, 44, 92, 29, 249, 201, 130, 214, - 225, 158, 200, 104, 86, 174, 190, 252, 112, 65, 228, 48, 75, 84, 55, 127, - 86, 160, 62, 248, 16, 66, 140, 49, 165, 212, 123, 31, 99, 72, 41, 246, - 158, 198, 232, 82, 206, 189, 148, 113, 175, 100, 124, 43, 97, 223, 104, 88, - 46, 186, 156, 115, 41, 229, 222, 203, 24, 87, 74, 190, 183, 48, 118, 148, - 38, 239, 90, 204, 59, 21, 211, 79, 29, 244, 9, 135, 70, 226, 178, 201, - 181, 150, 247, 46, 198, 156, 82, 233, 253, 142, 193, 164, 80, 123, 124, 35, - 97, 217, 232, 90, 206, 187, 20, 115, 79, 101, 244, 43, 7, 95, 66, 184, - 49, 178, 148, 117, 175, 103, 60, 42, 145, 223, 44, 88, 29, 250, 137, 131, - 38, 225, 218, 200, 91, 22, 187, 78, 243, 116, 69, 231, 115, 10, 165, 199, - 59, 18, 147, 77, 173, 245, 189, 135, 49, 162, 148, 121, 175, 98, 252, 41, - 129, 222, 224, 88, 72, 58, 182, 147, 54, 237, 214, 205, 158, 213, 168, 95, - 62, 184, 16, 114, 140, 37, 165, 219, 59, 27, 83, 75, 125, 247, 97, 134, - 168, 98, 254, 169, 128, 126, 224, 32, 72, 24, 54, 138, 150, 231, 46, 202, - 156, 87, 41, 254, 158, 192, 104, 80, 46, 188, 28, 113, 201, 228, 86, 203, - 126, 215, 96, 94, 168, 56, 126, 146, 160, 109, 184, 45, 178, 157, 181, 169, - 183, 62, 246, 144, 70, 236, 50, 205, 213, 149, 159, 47, 40, 28, 30, 137, - 200, 102, 214, 170, 222, 255, 24, 64, 10, 176, 7, 52, 2, 151, 65, 174, - 176, 124, 116, 33, 231, 88, 74, 186, 183, 51, 54, 149, 214, 239, 30, 204, - 8, 85, 198, 191, 18, 240, 13, 132, 5, 163, 67, 57, 241, 210, 196, 93, - 147, 121, 173, 226, 253, 137, 129, 166, 224, 122, 200, 35, 22, 153, 206, 234, - 212, 79, 31, 116, 8, 39, 70, 154, 178, 235, 53, 143, 87, 36, 62, 155, - 80, 107, 124, 47, 97, 220, 40, 89, 222, 186, 216, 115, 26, 165, 203, 59, - 23, 83, 78, 189, 244, 113, 135, 100, 98, 171, 105, 191, 110, 240, 44, 68, - 29, 243, 73, 133, 246, 227, 6, 201, 194, 214, 209, 158, 220, 104, 89, 238, - 186, 204, 115, 21, 229, 207, 11, 20, 7, 79, 66, 180, 49, 183, 84, 118, - 191, 102, 240, 42, 196, 31, 19, 72, 13, 246, 133, 134, 227, 34, 201, 217, - 150, 218, 238, 219, 12, 91, 69, 251, 115, 3, 101, 193, 235, 16, 79, 76, - 52, 53, 215, 87, 30, 190, 136, 112, 102, 164, 42, 251, 95, 3, 120, 1, - 226, 128, 73, 160, 54, 248, 22, 194, 142, 209, 164, 92, 123, 121, 227, 98, - 201, 233, 150, 206, 238, 212, 76, 95, 117, 248, 39, 2, 154, 129, 171, 32, - 127, 88, 32, 58, 152, 19, 42, 141, 223, 37, 152, 27, 42, 139, 95, 39, - 120, 26, 162, 139, 57, 167, 82, 250, 189, 131, 49, 161, 212, 120, 95, 98, - 184, 41, 178, 158, 245, 168, 71, 62, 178, 144, 117, 172, 39, 61, 218, 145, - 155, 44, 107, 93, 239, 121, 140, 34, 229, 217, 139, 26, 231, 75, 10, 183, - 71, 54, 178, 150, 245, 174, 199, 60, 82, 145, 253, 172, 65, 189, 240, 113, - 132, 36, 99, 91, 105, 251, 110, 195, 108, 81, 237, 252, 77, 129, 245, 160, - 71, 56, 50, 146, 149, 173, 175, 61, 188, 17, 177, 204, 116, 85, 231, 127, - 10, 160, 7, 56, 2, 146, 129, 173, 160, 125, 184, 33, 178, 152, 117, 170, - 167, 63, 58, 144, 19, 44, 13, 221, 197, 153, 147, 42, 237, 223, 13, 152, - 5, 170, 131, 63, 33, 208, 24, 92, 10, 185, 199, 50, 210, 149, 157, 175, - 41, 188, 30, 241, 200, 68, 86, 179, 126, 245, 224, 71, 8, 50, 134, 149, - 162, 239, 57, 140, 18, 229, 205, 139, 21, 167, 79, 58, 180, 19, 55, 77, - 214, 181, 158, 247, 40, 70, 158, 178, 232, 117, 142, 167, 36, 122, 155, 99, - 43, 105, 223, 110, 216, 44, 90, 157, 251, 41, 131, 94, 225, 248, 72, 66, - 182, 177, 182, 244, 118, 199, 102, 210, 170, 221, 191, 25, 176, 10, 244, 7, - 7, 66, 130, 177, 161, 180, 120, 119, 98, 166, 169, 186, 254, 243, 0, 69, - 192, 51, 16, 21, 204, 15, 21, 196, 15, 19, 68, 13, 243, 69, 133, 243, - 35, 5, 217, 195, 26, 209, 203, 28, 87, 73, 254, 182, 192, 118, 208, 38, - 220, 26, 217, 203, 26, 215, 75, 30, 183, 72, 118, 182, 166, 246, 250, 198, - 195, 18, 209, 205, 156, 85, 169, 255, 62, 192, 16, 80, 12, 60, 5, 209, - 195, 28, 81, 201, 252, 86, 193, 254, 208, 64, 92, 48, 57, 212, 18, 223, - 77, 152, 53, 170, 151, 63, 46, 144, 28, 108, 9, 237, 198, 205, 146, 213, - 173, 159, 61, 168, 17, 190, 140, 112, 101, 228, 43, 11, 95, 71, 120, 50, - 162, 149, 185, 175, 50, 252, 21, 129, 207, 32, 84, 24, 63, 74, 144, 55, - 44, 22, 157, 206, 233, 148, 78, 239, 116, 76, 39, 117, 218, 167, 27, 58, - 139, 83, 39, 125, 218, 161, 155, 56, 107, 82, 175, 125, 188, 33, 177, 216, - 116, 90, 167, 123, 58, 163, 83, 57, 253, 210, 193, 157, 144, 105, 172, 46, - 253, 220, 65, 153, 240, 106, 196, 47, 19, 92, 13, 249, 197, 130, 211, 33, - 157, 216, 105, 154, 174, 235, 60, 79, 81, 244, 60, 71, 81, 242, 188, 69, - 177, 243, 52, 69, 215, 115, 30, 165, 200, 123, 22, 163, 78, 249, 244, 66, - 199, 113, 146, 164, 109, 187, 109, 179, 109, 181, 237, 183, 13, 182, 133, 182, - 227, 54, 201, 214, 214, 222, 222, 216, 88, 90, 186, 187, 51, 51, 255, 63 ) - -random_mask_vec8 = numpy.array(random_mask_tuple, numpy.uint8) - diff --git a/gnuradio-core/src/tests/Makefile.am b/gnuradio-core/src/tests/Makefile.am index 2bf7cb4e5..5879a13d8 100644 --- a/gnuradio-core/src/tests/Makefile.am +++ b/gnuradio-core/src/tests/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2001,2008 Free Software Foundation, Inc. +# Copyright 2001,2008,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -31,7 +31,7 @@ TESTS = test_all # test_atsc #Test program to test setting up buffers using gr_test which can be run manually -EXTRA_DIST = \ +EXTRA_DIST += \ test_buffers.py \ benchmark_dotprod @@ -59,7 +59,7 @@ noinst_SCRIPTS = \ benchmark_dotprod -LIBGNURADIO = $(GNURADIO_CORE_LA) +LIBGNURADIO = $(GNURADIO_CORE_LA) $(BOOST_FILESYSTEM_LIB) LIBGNURADIOQA = $(top_builddir)/gnuradio-core/src/lib/libgnuradio-core-qa.la $(LIBGNURADIO) benchmark_dotprod_fff_SOURCES = benchmark_dotprod_fff.cc diff --git a/gnuradio-core/src/tests/benchmark_dotprod_ccc.cc b/gnuradio-core/src/tests/benchmark_dotprod_ccc.cc index 5d53a9f89..8ef26a40d 100644 --- a/gnuradio-core/src/tests/benchmark_dotprod_ccc.cc +++ b/gnuradio-core/src/tests/benchmark_dotprod_ccc.cc @@ -56,7 +56,8 @@ benchmark (fir_maker_t filter_maker, const char *implementation_name) { int i; gr_complex coeffs[NTAPS]; - gr_complex input[BLOCK_SIZE + NTAPS]; + //gr_complex input[BLOCK_SIZE + NTAPS]; // not always 16-bit aligned + gr_complex *input = new gr_complex[BLOCK_SIZE + NTAPS]; long n; gr_complex result; #ifdef HAVE_SYS_RESOURCE_H @@ -86,7 +87,7 @@ benchmark (fir_maker_t filter_maker, const char *implementation_name) exit (1); } #else - clock_start= (double) clock() * (1000000. / CLOCKS_PER_SEC); + clock_start= (double) clock() / CLOCKS_PER_SEC; #endif // do the actual work @@ -116,7 +117,7 @@ benchmark (fir_maker_t filter_maker, const char *implementation_name) double total = user + sys; #else - clock_end = (double) clock() * (1000000. / CLOCKS_PER_SEC); + clock_end = (double) clock() / CLOCKS_PER_SEC; double total = clock_end - clock_start; #endif @@ -126,6 +127,7 @@ benchmark (fir_maker_t filter_maker, const char *implementation_name) implementation_name, NTAPS, (double) TOTAL_TEST_SIZE, total, macs / total); delete f; + delete [] input; } static void diff --git a/gnuradio-core/src/tests/benchmark_dotprod_ccf.cc b/gnuradio-core/src/tests/benchmark_dotprod_ccf.cc index 60855ec94..ed3c49165 100644 --- a/gnuradio-core/src/tests/benchmark_dotprod_ccf.cc +++ b/gnuradio-core/src/tests/benchmark_dotprod_ccf.cc @@ -56,7 +56,8 @@ benchmark (fir_maker_t filter_maker, const char *implementation_name) { int i; float coeffs[NTAPS]; - gr_complex input[BLOCK_SIZE + NTAPS]; + //gr_complex input[BLOCK_SIZE + NTAPS]; // not always 16-bit aligned + gr_complex *input = new gr_complex[BLOCK_SIZE + NTAPS]; long n; gr_complex result; #ifdef HAVE_SYS_RESOURCE_H @@ -86,7 +87,7 @@ benchmark (fir_maker_t filter_maker, const char *implementation_name) exit (1); } #else - clock_start= (double) clock() * (1000000. / CLOCKS_PER_SEC); + clock_start= (double) clock() / CLOCKS_PER_SEC; #endif // do the actual work @@ -118,7 +119,7 @@ benchmark (fir_maker_t filter_maker, const char *implementation_name) double total = user + sys; #else - clock_end= (double) clock() * (1000000. / CLOCKS_PER_SEC); + clock_end= (double) clock() / CLOCKS_PER_SEC; double total = clock_end - clock_start; #endif @@ -128,6 +129,7 @@ benchmark (fir_maker_t filter_maker, const char *implementation_name) implementation_name, NTAPS, (double) TOTAL_TEST_SIZE, total, macs / total); delete f; + delete [] input; } static void diff --git a/gnuradio-core/src/tests/benchmark_vco.cc b/gnuradio-core/src/tests/benchmark_vco.cc index ed0ae3b67..3a6ade78c 100644 --- a/gnuradio-core/src/tests/benchmark_vco.cc +++ b/gnuradio-core/src/tests/benchmark_vco.cc @@ -63,7 +63,7 @@ benchmark (void test (float *x, const float *y), const char *implementation_name // touch memory memset(output, 0, BLOCK_SIZE*sizeof(float)); for (int i = 0; i<BLOCK_SIZE; i++) - input[i] = sin(i); + input[i] = sin(double(i)); // get starting CPU usage #ifdef HAVE_SYS_RESOURCE_H diff --git a/gnuradio-core/src/tests/test_all.cc b/gnuradio-core/src/tests/test_all.cc index 17ee32f34..6cec8ad0e 100644 --- a/gnuradio-core/src/tests/test_all.cc +++ b/gnuradio-core/src/tests/test_all.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002,2010 Free Software Foundation, Inc. + * Copyright 2002,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -34,11 +34,8 @@ int main (int argc, char **argv) { - char path[200]; - get_unittest_path ("gnuradio_core_all.xml", path, 200); - CppUnit::TextTestRunner runner; - std::ofstream xmlfile(path); + std::ofstream xmlfile(get_unittest_path("gnuradio_core_all.xml").c_str()); CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); runner.addTest (qa_runtime::suite ()); diff --git a/gnuradio-core/src/tests/test_atsc.cc b/gnuradio-core/src/tests/test_atsc.cc index 51642f81a..66cb2a312 100644 --- a/gnuradio-core/src/tests/test_atsc.cc +++ b/gnuradio-core/src/tests/test_atsc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002 Free Software Foundation, Inc. + * Copyright 2002,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -29,11 +29,8 @@ int main (int argc, char **argv) { - char path[200]; - get_unittest_path ("gnuradio_core_atsc.xml", path, 200); - CppUnit::TextTestRunner runner; - std::ofstream xmlfile(path); + std::ofstream xmlfile(get_unittest_path("gnuradio_core_atsc.xml").c_str()); CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); runner.addTest (qa_atsc::suite ()); diff --git a/gnuradio-core/src/tests/test_filter.cc b/gnuradio-core/src/tests/test_filter.cc index 90fe66c2f..3227a9ff2 100644 --- a/gnuradio-core/src/tests/test_filter.cc +++ b/gnuradio-core/src/tests/test_filter.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002,2010 Free Software Foundation, Inc. + * Copyright 2002,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -29,11 +29,8 @@ int main (int argc, char **argv) { - char path[200]; - get_unittest_path ("gnuradio_core_atsc.xml", path, 200); - CppUnit::TextTestRunner runner; - std::ofstream xmlfile(path); + std::ofstream xmlfile(get_unittest_path("gnuradio_core_filter.xml").c_str()); CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); runner.addTest (qa_filter::suite ()); diff --git a/gnuradio-core/src/tests/test_general.cc b/gnuradio-core/src/tests/test_general.cc index 16ee9c3ad..ca6dee40a 100644 --- a/gnuradio-core/src/tests/test_general.cc +++ b/gnuradio-core/src/tests/test_general.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002,2010 Free Software Foundation, Inc. + * Copyright 2002,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -29,11 +29,8 @@ int main (int argc, char **argv) { - char path[200]; - get_unittest_path ("gnuradio_core_general.xml", path, 200); - CppUnit::TextTestRunner runner; - std::ofstream xmlfile(path); + std::ofstream xmlfile(get_unittest_path("gnuradio_core_general.xml").c_str()); CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); runner.addTest (qa_general::suite ()); diff --git a/gnuradio-core/src/tests/test_runtime.cc b/gnuradio-core/src/tests/test_runtime.cc index c7983a23e..77af3001b 100644 --- a/gnuradio-core/src/tests/test_runtime.cc +++ b/gnuradio-core/src/tests/test_runtime.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2002,2010 Free Software Foundation, Inc. + * Copyright 2002,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -29,11 +29,8 @@ int main (int argc, char **argv) { - char path[200]; - get_unittest_path ("gnuradio_core_runtime.xml", path, 200); - CppUnit::TextTestRunner runner; - std::ofstream xmlfile(path); + std::ofstream xmlfile(get_unittest_path("gnuradio_core_runtime.xml").c_str()); CppUnit::XmlOutputter *xmlout = new CppUnit::XmlOutputter(&runner.result(), xmlfile); runner.addTest (qa_runtime::suite ()); diff --git a/gnuradio-core/src/utils/Makefile.am b/gnuradio-core/src/utils/Makefile.am index 07960a072..acf439140 100644 --- a/gnuradio-core/src/utils/Makefile.am +++ b/gnuradio-core/src/utils/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST = \ +EXTRA_DIST += \ cic_comp_taps.m \ db_width.m \ filter_tools.m \ @@ -42,4 +42,15 @@ EXTRA_DIST = \ read_cshort_binary.m \ single_pole_iir.m \ write_float_binary.m \ - write_short_binary.m + write_short_binary.m \ + is_complex.m \ + split_vect.m \ + rainbow.m \ + lp_to_bp.m \ + cool.m \ + read_xambi.m \ + runsum.m \ + plot_cic_decimator_response.m + +# partition-cascaded-decimating-filters.scm +# permute.scm |