diff options
author | Tom Rondeau | 2011-09-26 23:23:14 -0400 |
---|---|---|
committer | Tom Rondeau | 2011-09-26 23:23:14 -0400 |
commit | 4fec8eba2eb3d362319c8e09bf370edaa10cd1b9 (patch) | |
tree | e41ff025b20b5c4ad8928fa0651a06dca884dc6f | |
parent | 79e7183bda0e3850c79dee7f086a8676311607fa (diff) | |
parent | e3b56bfd879f16c2fa1f284f330ed3df6a211ec1 (diff) | |
download | gnuradio-4fec8eba2eb3d362319c8e09bf370edaa10cd1b9.tar.gz gnuradio-4fec8eba2eb3d362319c8e09bf370edaa10cd1b9.tar.bz2 gnuradio-4fec8eba2eb3d362319c8e09bf370edaa10cd1b9.zip |
Merge branch 'next' into digital
Conflicts:
gnuradio-core/src/lib/general/general.i
gnuradio-core/src/lib/general/gr_pll_carriertracking_cc.cc
gnuradio-core/src/lib/general/gr_pll_freqdet_cf.cc
gnuradio-core/src/lib/general/gr_pll_refout_cc.cc
gnuradio-core/src/python/gnuradio/gr/qa_pll_carriertracking.py
gnuradio-core/src/python/gnuradio/gr/qa_pll_freqdet.py
gnuradio-core/src/python/gnuradio/gr/qa_pll_refout.py
gr-digital/lib/digital_constellation_receiver_cb.cc
gr-digital/python/Makefile.am
gr-digital/python/__init__.py
gr-digital/python/generic_mod_demod.py
gr-digital/python/pkt.py
gr-digital/python/psk2.py
gr-digital/python/qam.py
344 files changed, 17899 insertions, 1917 deletions
diff --git a/config/Makefile.am b/config/Makefile.am index 473f88488..3eaa5e748 100644 --- a/config/Makefile.am +++ b/config/Makefile.am @@ -54,12 +54,12 @@ m4macros = \ grc_gr_audio.m4 \ grc_gr_comedi.m4 \ grc_gr_gcell.m4 \ - grc_gr_gsm_fr_vocoder.m4 \ grc_gr_noaa.m4 \ grc_gr_radio_astronomy.m4 \ grc_gr_trellis.m4 \ grc_gr_usrp.m4 \ grc_gr_video_sdl.m4 \ + grc_gr_vocoder.m4 \ grc_gr_wxgui.m4 \ grc_gruel.m4 \ gr_check_createfilemapping.m4 \ diff --git a/config/grc_gnuradio_core.m4 b/config/grc_gnuradio_core.m4 index c67696c7d..a35629e2e 100644 --- a/config/grc_gnuradio_core.m4 +++ b/config/grc_gnuradio_core.m4 @@ -86,7 +86,6 @@ AC_DEFUN([GRC_GNURADIO_CORE],[ gnuradio-core/src/guile/gr-run-waveform-script \ gnuradio-core/src/lib/Makefile \ gnuradio-core/src/lib/filter/Makefile \ - gnuradio-core/src/lib/g72x/Makefile \ gnuradio-core/src/lib/general/Makefile \ gnuradio-core/src/lib/general/gr_constants.cc \ gnuradio-core/src/lib/gengen/Makefile \ @@ -106,7 +105,6 @@ AC_DEFUN([GRC_GNURADIO_CORE],[ gnuradio-core/src/python/gnuradio/gr/run_tests \ gnuradio-core/src/python/gnuradio/gru/Makefile \ gnuradio-core/src/python/gnuradio/gruimpl/Makefile \ - gnuradio-core/src/python/gnuradio/vocoder/Makefile \ gnuradio-core/src/tests/Makefile \ gnuradio-core/src/utils/Makefile \ ]) diff --git a/config/grc_gnuradio_examples.m4 b/config/grc_gnuradio_examples.m4 index 6dff01943..f5d94318e 100644 --- a/config/grc_gnuradio_examples.m4 +++ b/config/grc_gnuradio_examples.m4 @@ -32,7 +32,6 @@ AC_DEFUN([GRC_GNURADIO_EXAMPLES],[ gnuradio-examples/python/apps/hf_radio/Makefile \ gnuradio-examples/python/apps/Makefile \ gnuradio-examples/python/digital/Makefile \ - gnuradio-examples/python/digital_voice/Makefile \ gnuradio-examples/python/digital-bert/Makefile \ gnuradio-examples/python/mp-sched/Makefile \ gnuradio-examples/python/multi-antenna/Makefile \ @@ -40,6 +39,7 @@ AC_DEFUN([GRC_GNURADIO_EXAMPLES],[ gnuradio-examples/python/network/Makefile \ gnuradio-examples/python/ofdm/Makefile \ gnuradio-examples/python/pfb/Makefile \ + gnuradio-examples/python/tags/Makefile \ gnuradio-examples/python/usrp/Makefile \ gnuradio-examples/python/usrp2/Makefile \ gnuradio-examples/waveforms/Makefile \ diff --git a/config/grc_gr_comedi.m4 b/config/grc_gr_comedi.m4 index 5e3089417..7e54b0f5a 100644 --- a/config/grc_gr_comedi.m4 +++ b/config/grc_gr_comedi.m4 @@ -29,7 +29,7 @@ AC_DEFUN([GRC_GR_COMEDI],[ dnl no : otherwise if test $passed = yes; then dnl Don't do gr-comedi if the 'comedi' library is unavailable. - PKG_CHECK_MODULES(COMEDI, comedilib < 0.8,[], + PKG_CHECK_MODULES(COMEDI, comedilib >= 0.8,[], [passed=no;AC_MSG_RESULT([gr-comedi requires comedilib, not found.])]) fi diff --git a/config/grc_gr_cvsd_vocoder.m4 b/config/grc_gr_cvsd_vocoder.m4 deleted file mode 100644 index ddf6f9b2f..000000000 --- a/config/grc_gr_cvsd_vocoder.m4 +++ /dev/null @@ -1,39 +0,0 @@ -dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. - -AC_DEFUN([GRC_GR_CVSD_VOCODER],[ - GRC_ENABLE(gr-cvsd-vocoder) - - dnl Don't do gr-cvsd-vocoder if gnuradio-core skipped - GRC_CHECK_DEPENDENCY(gr-cvsd-vocoder, gnuradio-core) - - AC_CONFIG_FILES([\ - gr-cvsd-vocoder/Makefile \ - gr-cvsd-vocoder/gnuradio-cvsd-vocoder.pc \ - gr-cvsd-vocoder/src/Makefile \ - gr-cvsd-vocoder/src/lib/Makefile \ - gr-cvsd-vocoder/src/python/Makefile \ - gr-cvsd-vocoder/src/python/run_tests \ - ]) - - GRC_BUILD_CONDITIONAL(gr-cvsd-vocoder,[ - dnl run_tests is created from run_tests.in. Make it executable. - AC_CONFIG_COMMANDS([run_tests_cvsd], [chmod +x gr-cvsd-vocoder/src/python/run_tests]) - ]) -]) diff --git a/config/grc_gr_gsm_fr_vocoder.m4 b/config/grc_gr_gsm_fr_vocoder.m4 deleted file mode 100644 index a93d4edb7..000000000 --- a/config/grc_gr_gsm_fr_vocoder.m4 +++ /dev/null @@ -1,40 +0,0 @@ -dnl Copyright 2001,2002,2003,2004,2005,2006,2008 Free Software Foundation, Inc. -dnl -dnl This file is part of GNU Radio -dnl -dnl GNU Radio is free software; you can redistribute it and/or modify -dnl it under the terms of the GNU General Public License as published by -dnl the Free Software Foundation; either version 3, or (at your option) -dnl any later version. -dnl -dnl GNU Radio is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -dnl GNU General Public License for more details. -dnl -dnl You should have received a copy of the GNU General Public License -dnl along with GNU Radio; see the file COPYING. If not, write to -dnl the Free Software Foundation, Inc., 51 Franklin Street, -dnl Boston, MA 02110-1301, USA. - -AC_DEFUN([GRC_GR_GSM_FR_VOCODER],[ - GRC_ENABLE(gr-gsm-fr-vocoder) - - dnl Don't do gr-gsm-fr-vocoder if gnuradio-core skipped - GRC_CHECK_DEPENDENCY(gr-gsm-fr-vocoder, gnuradio-core) - - AC_CONFIG_FILES([\ - gr-gsm-fr-vocoder/Makefile \ - gr-gsm-fr-vocoder/gnuradio-gsm-fr-vocoder.pc \ - gr-gsm-fr-vocoder/src/Makefile \ - gr-gsm-fr-vocoder/src/lib/Makefile \ - gr-gsm-fr-vocoder/src/lib/gsm/Makefile \ - gr-gsm-fr-vocoder/src/python/Makefile \ - gr-gsm-fr-vocoder/src/python/run_tests \ - ]) - - GRC_BUILD_CONDITIONAL(gr-gsm-fr-vocoder,[ - dnl run_tests is created from run_tests.in. Make it executable. - AC_CONFIG_COMMANDS([run_tests_gsm], [chmod +x gr-gsm-fr-vocoder/src/python/run_tests]) - ]) -]) diff --git a/config/grc_gr_qtgui.m4 b/config/grc_gr_qtgui.m4 index ddb7c7ca9..2204e49ae 100644 --- a/config/grc_gr_qtgui.m4 +++ b/config/grc_gr_qtgui.m4 @@ -83,6 +83,7 @@ AC_DEFUN([GRC_GR_QTGUI],[ gr-qtgui/Makefile \ gr-qtgui/gnuradio-qtgui.pc \ gr-qtgui/apps/Makefile \ + gr-qtgui/examples/Makefile \ gr-qtgui/grc/Makefile \ gr-qtgui/lib/Makefile \ gr-qtgui/python/Makefile \ diff --git a/config/grc_gr_trellis.m4 b/config/grc_gr_trellis.m4 index 963d5af79..57c75bf51 100644 --- a/config/grc_gr_trellis.m4 +++ b/config/grc_gr_trellis.m4 @@ -28,6 +28,7 @@ AC_DEFUN([GRC_GR_TRELLIS],[ gr-trellis/Makefile \ gr-trellis/gnuradio-trellis.pc \ gr-trellis/doc/Makefile \ + gr-trellis/grc/Makefile \ gr-trellis/src/Makefile \ gr-trellis/src/lib/Makefile \ gr-trellis/src/lib/run_guile_tests \ diff --git a/config/grc_gr_vocoder.m4 b/config/grc_gr_vocoder.m4 new file mode 100644 index 000000000..df75656fe --- /dev/null +++ b/config/grc_gr_vocoder.m4 @@ -0,0 +1,49 @@ +dnl Copyright 2011 Free Software Foundation, Inc. +dnl +dnl This file is part of GNU Radio +dnl +dnl GNU Radio is free software; you can redistribute it and/or modify +dnl it under the terms of the GNU General Public License as published by +dnl the Free Software Foundation; either version 3, or (at your option) +dnl any later version. +dnl +dnl GNU Radio is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +dnl GNU General Public License for more details. +dnl +dnl You should have received a copy of the GNU General Public License +dnl along with GNU Radio; see the file COPYING. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, +dnl Boston, MA 02110-1301, USA. + +AC_DEFUN([GRC_GR_VOCODER],[ + GRC_ENABLE(gr-vocoder) + + dnl Don't do gr-vocoder if gnuradio-core skipped + GRC_CHECK_DEPENDENCY(gr-fr-vocoder, gnuradio-core) + + AC_CONFIG_FILES([\ + gr-vocoder/Makefile \ + gr-vocoder/gnuradio-vocoder.pc \ + gr-vocoder/apps/Makefile \ + gr-vocoder/doc/Makefile \ + gr-vocoder/examples/Makefile \ + gr-vocoder/grc/Makefile \ + gr-vocoder/include/Makefile \ + gr-vocoder/lib/Makefile \ + gr-vocoder/lib/codec2/Makefile \ + gr-vocoder/lib/g7xx/Makefile \ + gr-vocoder/lib/gsm/Makefile \ + gr-vocoder/python/Makefile \ + gr-vocoder/python/run_tests \ + gr-vocoder/swig/Makefile \ + gr-vocoder/swig/run_guile_tests \ + ]) + + GRC_BUILD_CONDITIONAL(gr-vocoder,[ + dnl run_tests is created from run_tests.in. Make it executable. + AC_CONFIG_COMMANDS([run_tests_vocoder], [chmod +x gr-vocoder/python/run_tests]) + AC_CONFIG_COMMANDS([run_tests_vocoder_guile], [chmod +x gr-vocoder/swig/run_guile_tests]) + ]) +]) diff --git a/configure.ac b/configure.ac index 1ac5960c5..28fac41d4 100644 --- a/configure.ac +++ b/configure.ac @@ -360,10 +360,9 @@ GRC_GR_USRP dnl this must come after GRC_USRP GRC_GR_USRP2 GRC_GR_GCELL dnl this must come after GRC_GCELL and GRC_GNURADIO_CORE GRC_GR_AUDIO +GRC_GR_VOCODER GRC_GR_ATSC GRC_GR_COMEDI -GRC_GR_CVSD_VOCODER -GRC_GR_GSM_FR_VOCODER GRC_GR_NOAA GRC_GR_PAGER GRC_GR_RADIO_ASTRONOMY diff --git a/docs/doxygen/Doxyfile.in b/docs/doxygen/Doxyfile.in index f12dd61b7..1f544e5bd 100644 --- a/docs/doxygen/Doxyfile.in +++ b/docs/doxygen/Doxyfile.in @@ -552,7 +552,7 @@ WARN_LOGFILE = # directories like "/usr/src/myproject". Separate the files or directories # with spaces. -INPUT = @top_srcdir@ +INPUT = @top_srcdir@ @top_builddir@ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/gnuradio-core/src/lib/Makefile.am b/gnuradio-core/src/lib/Makefile.am index 4db2ff167..979ac7f91 100644 --- a/gnuradio-core/src/lib/Makefile.am +++ b/gnuradio-core/src/lib/Makefile.am @@ -24,7 +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 . swig +SUBDIRS = missing runtime filter viterbi general gengen reed-solomon io hier . swig AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(CPPUNIT_INCLUDES) $(WITH_INCLUDES) @@ -43,7 +43,6 @@ libgnuradio_core_qa_la_LDFLAGS = $(NO_UNDEFINED) -version-info 0:0:0 \ libgnuradio_core_la_LIBADD = \ filter/libfilter.la \ - g72x/libccitt.la \ viterbi/libviterbi.la \ general/libgeneral.la \ gengen/libgengen.la \ diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc index 884caf29c..3fed74641 100644 --- a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc +++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc @@ -33,7 +33,7 @@ gr_adaptive_fir_ccc::gr_adaptive_fir_ccc(const char *name, int decimation, 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) + d_updated(false), d_taps(taps) { set_history(d_taps.size()); } diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h index de9ccc0ea..d299cc7ef 100644 --- a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h @@ -79,7 +79,6 @@ class gr_dc_blocker_cc : public gr_sync_block * 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); diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h index b632d81da..8ffb6cf6f 100644 --- a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h @@ -79,7 +79,6 @@ class gr_dc_blocker_ff : public gr_sync_block * 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); 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 4718171a7..fbe803d42 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 @@ -123,6 +123,7 @@ class gr_pfb_clock_sync_ccf : public gr_block * \param init_phase (float) The initial phase to look at, or which filter to start * with (default = 0). * \param max_rate_deviation (float) Distance from 0 d_rate can get (default = 1.5). + * \param osps (int) The number of output samples per symbol (default=1). * */ friend gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float loop_bw, diff --git a/gnuradio-core/src/lib/filter/gri_goertzel.cc b/gnuradio-core/src/lib/filter/gri_goertzel.cc index 85e66c069..73b8366ab 100644 --- a/gnuradio-core/src/lib/filter/gri_goertzel.cc +++ b/gnuradio-core/src/lib/filter/gri_goertzel.cc @@ -20,6 +20,9 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif #include <cmath> #include <gri_goertzel.h> diff --git a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc index 63654a280..d158ff00d 100644 --- a/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc +++ b/gnuradio-core/src/lib/filter/qa_gri_mmse_fir_interpolator.cc @@ -20,6 +20,10 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <cppunit/TestAssert.h> #include <qa_gri_mmse_fir_interpolator.h> #include <gri_mmse_fir_interpolator.h> diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am index fe545f98c..e389e05e1 100644 --- a/gnuradio-core/src/lib/general/Makefile.am +++ b/gnuradio-core/src/lib/general/Makefile.am @@ -172,7 +172,8 @@ libgeneral_la_SOURCES = \ gr_probe_density_b.cc \ gr_annotator_alltoall.cc \ gr_annotator_1to1.cc \ - gr_burst_tagger.cc + gr_burst_tagger.cc \ + gr_correlate_access_code_tag_bb.cc libgeneral_qa_la_SOURCES = \ qa_general.cc \ @@ -338,7 +339,8 @@ grinclude_HEADERS = \ gr_probe_density_b.h \ gr_annotator_alltoall.h \ gr_annotator_1to1.h \ - gr_burst_tagger.h + gr_burst_tagger.h \ + gr_correlate_access_code_tag_bb.h noinst_HEADERS = \ qa_general.h \ @@ -474,4 +476,5 @@ swiginclude_HEADERS = \ gr_probe_density_b.i \ gr_annotator_alltoall.i \ gr_annotator_1to1.i \ - gr_burst_tagger.i + gr_burst_tagger.i \ + gr_correlate_access_code_tag_bb.i diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index e965eea64..107f5c9ea 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -138,6 +138,7 @@ #include <gr_annotator_1to1.h> #include <gr_burst_tagger.h> #include <gr_cpm.h> +#include <gr_correlate_access_code_tag_bb.h> %} %include "gri_control_loop.i" @@ -256,3 +257,4 @@ %include "gr_annotator_1to1.i" %include "gr_burst_tagger.i" %include "gr_cpm.i" +%include "gr_correlate_access_code_tag_bb.i" diff --git a/gnuradio-core/src/lib/general/gr_circular_file.cc b/gnuradio-core/src/lib/general/gr_circular_file.cc index c9222597a..4d88b9d99 100644 --- a/gnuradio-core/src/lib/general/gr_circular_file.cc +++ b/gnuradio-core/src/lib/general/gr_circular_file.cc @@ -42,6 +42,10 @@ #include <stdio.h> #include <string.h> +#ifdef HAVE_IO_H +#include <io.h> +#endif + static const int HEADER_SIZE = 4096; static const int HEADER_MAGIC = 0xEB021026; diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc new file mode 100644 index 000000000..23311f7a4 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.cc @@ -0,0 +1,129 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2006,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_correlate_access_code_tag_bb.h> +#include <gr_io_signature.h> +#include <stdexcept> +#include <gr_count_bits.h> +#include <cstdio> +#include <iostream> + +#define VERBOSE 0 + + +gr_correlate_access_code_tag_bb_sptr +gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, const std::string &tag_name) +{ + return gnuradio::get_initial_sptr(new gr_correlate_access_code_tag_bb (access_code, threshold, tag_name)); +} + + +gr_correlate_access_code_tag_bb::gr_correlate_access_code_tag_bb ( + const std::string &access_code, int threshold, const std::string &tag_name) + : gr_sync_block ("correlate_access_code_tag_bb", + gr_make_io_signature (1, 1, sizeof(char)), + gr_make_io_signature (1, 1, sizeof(char))), + d_data_reg(0), d_mask(0), d_len(0), + d_threshold(threshold) + +{ + if (!set_access_code(access_code)){ + fprintf(stderr, "gr_correlate_access_code_tag_bb: access_code is > 64 bits\n"); + throw std::out_of_range ("access_code is > 64 bits"); + } + + std::stringstream str; + str << name() << unique_id(); + d_me = pmt::pmt_string_to_symbol(str.str()); + d_key = pmt::pmt_string_to_symbol(tag_name); +} + +gr_correlate_access_code_tag_bb::~gr_correlate_access_code_tag_bb () +{ +} + +bool +gr_correlate_access_code_tag_bb::set_access_code( + const std::string &access_code) +{ + d_len = access_code.length(); // # of bytes in string + if (d_len > 64) + return false; + + // set len top bits to 1. + d_mask = ((~0ULL) >> (64 - d_len)) << (64 - d_len); + + d_access_code = 0; + for (unsigned i=0; i < 64; i++){ + d_access_code <<= 1; + if (i < d_len) + d_access_code |= access_code[i] & 1; // look at LSB only + } + + return true; +} + +int +gr_correlate_access_code_tag_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]; + + uint64_t abs_out_sample_cnt = nitems_written(0); + + for (int i = 0; i < noutput_items; i++){ + + out[i] = in[i]; + + // 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); + + // shift in new data and new flag + d_data_reg = (d_data_reg << 1) | (in[i] & 0x1); + if (new_flag) { + if(VERBOSE) std::cout << "writing tag at sample " << abs_out_sample_cnt + i << std::endl; + add_item_tag(0, //stream ID + abs_out_sample_cnt + i - 64 + d_len, //sample + d_key, //frame info + pmt::pmt_t(), //data (unused) + d_me //block src id + ); + } + } + + return noutput_items; +} + diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h new file mode 100644 index 000000000..1067bbc56 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.h @@ -0,0 +1,86 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,2006,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_correlate_access_code_tag_bb_H +#define INCLUDED_gr_correlate_access_code_tag_bb_H + +#include <gr_sync_block.h> +#include <string> + +class gr_correlate_access_code_tag_bb; +typedef boost::shared_ptr<gr_correlate_access_code_tag_bb> gr_correlate_access_code_tag_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 + * \param tag_name key of the tag inserted into the tag stream + */ +gr_correlate_access_code_tag_bb_sptr +gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, + const std::string &tag_name); + +/*! + * \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: unaltered stream of bits (plus tags) + * + * This block annotates the input stream with tags. The tags have key + * name [tag_name], specified in the constructor. Used for searching + * an input data stream for preambles, etc. + */ +class gr_correlate_access_code_tag_bb : public gr_sync_block +{ + friend gr_correlate_access_code_tag_bb_sptr + gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, + const std::string &tag_name); + 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_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 + unsigned int d_len; //the length of the access code + + pmt::pmt_t d_key, d_me; //d_key is the tag name, d_me is the block name + unique ID + + protected: + gr_correlate_access_code_tag_bb(const std::string &access_code, int threshold, + const std::string &tag_name); + + public: + ~gr_correlate_access_code_tag_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_tag_bb_H */ diff --git a/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i new file mode 100644 index 000000000..fb832194d --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_correlate_access_code_tag_bb.i @@ -0,0 +1,60 @@ +/* -*- 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_tag_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_tag_bb_sptr +gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, const std::string &tag_name) + 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_tag_bb : public gr_sync_block +{ + friend gr_correlate_access_code_tag_bb_sptr + gr_make_correlate_access_code_tag_bb (const std::string &access_code, int threshold, const std::string &tag_name); + protected: + gr_correlate_access_code_tag_bb(const std::string &access_code, int threshold, const std::string &tag_name); + + public: + ~gr_correlate_access_code_tag_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_firdes.cc b/gnuradio-core/src/lib/general/gr_firdes.cc index 5d192d67e..13110d57d 100644 --- a/gnuradio-core/src/lib/general/gr_firdes.cc +++ b/gnuradio-core/src/lib/general/gr_firdes.cc @@ -20,6 +20,10 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <gr_firdes.h> #include <stdexcept> 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 85495e277..8bccefa95 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 @@ -40,6 +40,12 @@ gr_keep_one_in_n::gr_keep_one_in_n (size_t item_size, int n) gr_make_io_signature (1, 1, item_size)), d_count(n) { + // To avoid bad behavior with using set_relative_rate in this block with + // VERY large values of n, we will keep track of things ourselves. Using + // this to turn off automatic tag propagation, which will be handled + // locally in general_work(). + set_tag_propagation_policy(TPP_DONT); + set_n(n); } @@ -52,7 +58,10 @@ gr_keep_one_in_n::set_n(int n) d_n = n; d_count = n; - set_relative_rate(1.0 / (float)n); + // keep our internal understanding of the relative rate of this block + // don't set the relative rate, though, and we will handle our own + // tag propagation. + d_decim_rate = 1.0/(float)d_n; } int @@ -80,6 +89,19 @@ gr_keep_one_in_n::general_work (int noutput_items, ni++; } + // Because we have set TPP_DONT, we have to propagate the tags here manually. + // Adjustment of the tag sample value is done using the float d_decim_rate. + std::vector<pmt::pmt_t> tags; + std::vector<pmt::pmt_t>::iterator t; + get_tags_in_range(tags, 0, nitems_read(0), nitems_read(0)+ni); + for(t = tags.begin(); t != tags.end(); t++) { + uint64_t newcount = pmt::pmt_to_uint64(pmt::pmt_tuple_ref(*t, 0)); + add_item_tag(0, newcount * d_decim_rate, + pmt::pmt_tuple_ref(*t, 1), + pmt::pmt_tuple_ref(*t, 2), + pmt::pmt_tuple_ref(*t, 3)); + } + consume_each (ni); return no; } diff --git a/gnuradio-core/src/lib/general/gr_keep_one_in_n.h b/gnuradio-core/src/lib/general/gr_keep_one_in_n.h index 337827446..ba573618e 100644 --- a/gnuradio-core/src/lib/general/gr_keep_one_in_n.h +++ b/gnuradio-core/src/lib/general/gr_keep_one_in_n.h @@ -43,6 +43,7 @@ class gr_keep_one_in_n : public gr_block int d_n; int d_count; + float d_decim_rate; protected: gr_keep_one_in_n (size_t item_size, int n); diff --git a/gnuradio-core/src/lib/general/gr_random.cc b/gnuradio-core/src/lib/general/gr_random.cc index 67f760006..52140acc2 100644 --- a/gnuradio-core/src/lib/general/gr_random.cc +++ b/gnuradio-core/src/lib/general/gr_random.cc @@ -35,6 +35,9 @@ * */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif #include <math.h> #include <gr_random.h> diff --git a/gnuradio-core/src/lib/general/gri_float_to_char.cc b/gnuradio-core/src/lib/general/gri_float_to_char.cc index a17b01f55..28f15a3b3 100644 --- a/gnuradio-core/src/lib/general/gri_float_to_char.cc +++ b/gnuradio-core/src/lib/general/gri_float_to_char.cc @@ -20,6 +20,10 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #define _ISOC9X_SOURCE #include <gri_float_to_char.h> #include <math.h> diff --git a/gnuradio-core/src/lib/general/gri_float_to_short.cc b/gnuradio-core/src/lib/general/gri_float_to_short.cc index 13afc51d9..93a2784f5 100644 --- a/gnuradio-core/src/lib/general/gri_float_to_short.cc +++ b/gnuradio-core/src/lib/general/gri_float_to_short.cc @@ -20,6 +20,10 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #define _ISOC9X_SOURCE #include <gri_float_to_short.h> #include <math.h> diff --git a/gnuradio-core/src/lib/general/gri_float_to_uchar.cc b/gnuradio-core/src/lib/general/gri_float_to_uchar.cc index 394cbc100..a022c95d8 100644 --- a/gnuradio-core/src/lib/general/gri_float_to_uchar.cc +++ b/gnuradio-core/src/lib/general/gri_float_to_uchar.cc @@ -20,6 +20,10 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #define _ISOC9X_SOURCE #include <gri_float_to_uchar.h> #include <math.h> diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc index 09fb6c826..11e0a8eb9 100644 --- a/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc +++ b/gnuradio-core/src/lib/io/gr_file_descriptor_sink.cc @@ -34,6 +34,9 @@ #include <stdexcept> #include <stdio.h> +#ifdef HAVE_IO_H +#include <io.h> +#endif gr_file_descriptor_sink::gr_file_descriptor_sink (size_t itemsize, int fd) : gr_sync_block ("file_descriptor_sink", diff --git a/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc b/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc index 700ad4aef..334a57848 100644 --- a/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc +++ b/gnuradio-core/src/lib/io/gr_file_descriptor_source.cc @@ -35,6 +35,9 @@ #include <stdio.h> #include <string.h> +#ifdef HAVE_IO_H +#include <io.h> +#endif gr_file_descriptor_source::gr_file_descriptor_source (size_t itemsize, int fd, diff --git a/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc b/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc index 154611c32..67184b9c5 100644 --- a/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc +++ b/gnuradio-core/src/lib/io/gr_tagged_file_sink.cc @@ -34,6 +34,10 @@ #include <iostream> #include <gr_tag_info.h> +#ifdef HAVE_IO_H +#include <io.h> +#endif + #ifdef O_BINARY #define OUR_O_BINARY O_BINARY #else @@ -179,7 +183,8 @@ gr_tagged_file_sink::work (int noutput_items, //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); + 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"); @@ -196,7 +201,8 @@ gr_tagged_file_sink::work (int noutput_items, } } if(d_state == IN_BURST) { - int count = fwrite (&inbuf[idx], d_itemsize, noutput_items-idx, d_handle); + int count = fwrite (&inbuf[d_itemsize*idx], d_itemsize, + noutput_items-idx, d_handle); if (count == 0) { if(ferror(d_handle)) { perror("gr_tagged_file_sink: error writing file"); diff --git a/gnuradio-core/src/lib/io/gri_wavfile.cc b/gnuradio-core/src/lib/io/gri_wavfile.cc index b8375edc2..8f1c6a2bb 100644 --- a/gnuradio-core/src/lib/io/gri_wavfile.cc +++ b/gnuradio-core/src/lib/io/gri_wavfile.cc @@ -160,25 +160,25 @@ gri_wavheader_parse(FILE *fp, return false; } - fread(&file_size, 1, 4, fp); + fresult = fread(&file_size, 1, 4, fp); fresult = fread(str_buf, 1, 8, fp); if (fresult != 8 || strncmp(str_buf, "WAVEfmt ", 8) || feof(fp)) { return false; } - fread(&fmt_hdr_skip, 1, 4, fp); + fresult = fread(&fmt_hdr_skip, 1, 4, fp); - fread(&compression_type, 1, 2, fp); + fresult = fread(&compression_type, 1, 2, fp); if (wav_to_host(compression_type) != VALID_COMPRESSION_TYPE) { return false; } - fread(&nchans, 1, 2, fp); - fread(&sample_rate, 1, 4, fp); - fread(&avg_bytes_per_sec, 1, 4, fp); - fread(&block_align, 1, 2, fp); - fread(&bits_per_sample, 1, 2, fp); + fresult = fread(&nchans, 1, 2, fp); + fresult = fread(&sample_rate, 1, 4, fp); + fresult = fread(&avg_bytes_per_sec, 1, 4, fp); + fresult = fread(&block_align, 1, 2, fp); + fresult = fread(&bits_per_sample, 1, 2, fp); if (ferror(fp)) { return false; @@ -204,7 +204,7 @@ gri_wavheader_parse(FILE *fp, return false; } - fread(&chunk_size, 1, 4, fp); + fresult = fread(&chunk_size, 1, 4, fp); if (ferror(fp)) { return false; } @@ -226,7 +226,9 @@ short int gri_wav_read_sample(FILE *fp, int bytes_per_sample) { int16_t buf = 0; - fread(&buf, bytes_per_sample, 1, fp); + size_t fresult; + + fresult = fread(&buf, bytes_per_sample, 1, fp); return (short) wav_to_host(buf); } diff --git a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc index 668f04cad..14f2b8589 100644 --- a/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc +++ b/gnuradio-core/src/lib/io/microtune_xxxx_eval_board.cc @@ -20,6 +20,10 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "microtune_xxxx_eval_board.h" #include "microtune_eval_board_defs.h" #include "microtune_xxxx.h" diff --git a/gnuradio-core/src/python/gnuradio/Makefile.am b/gnuradio-core/src/python/gnuradio/Makefile.am index 30b5d02ab..289e37662 100644 --- a/gnuradio-core/src/python/gnuradio/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/Makefile.am @@ -22,7 +22,7 @@ include $(top_srcdir)/Makefile.common if PYTHON -SUBDIRS = gr gru gruimpl blks2 blks2impl vocoder +SUBDIRS = gr gru gruimpl blks2 blks2impl grpython_PYTHON = \ __init__.py \ diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/logpwrfft.py b/gnuradio-core/src/python/gnuradio/blks2impl/logpwrfft.py index 200c4cfbe..6f7fc520f 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/logpwrfft.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/logpwrfft.py @@ -54,13 +54,13 @@ class _logpwrfft_base(gr.hier_block2): fft = self._fft_block[0](fft_size, True, fft_window) window_power = sum(map(lambda x: x*x, fft_window)) - c2mag = gr.complex_to_mag(fft_size) + c2magsq = gr.complex_to_mag_squared(fft_size) self._avg = gr.single_pole_iir_filter_ff(1.0, fft_size) - self._log = gr.nlog10_ff(20, fft_size, + self._log = gr.nlog10_ff(10, fft_size, -20*math.log10(fft_size) # Adjust for number of bins -10*math.log10(window_power/fft_size) # Adjust for windowing loss - -20*math.log10(ref_scale/2)+3.0) # Adjust for reference scale - self.connect(self, self._sd, fft, c2mag, self._avg, self._log, self) + -20*math.log10(ref_scale/2)) # Adjust for reference scale + self.connect(self, self._sd, fft, c2magsq, self._avg, self._log, self) self._average = average self._avg_alpha = avg_alpha diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py index 3b1cd12ac..2663f7cf8 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/ofdm.py @@ -21,26 +21,12 @@ # import math -from gnuradio import gr, ofdm_packet_utils, modulation_utils2 +from gnuradio import gr, ofdm_packet_utils 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 @@ -75,8 +61,6 @@ 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)] @@ -98,9 +82,19 @@ class ofdm_mod(gr.hier_block2): symbol_length = options.fft_length + options.cp_length - const = modulation_utils2.type_1_constellations()[self._modulation](arity).points() - - self._pkt_input = gr.ofdm_mapper_bcv(const, msgq_limit, + 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, options.occupied_tones, options.fft_length) self.preambles = gr.ofdm_insert_preamble(self._fft_length, padded_preambles) @@ -146,10 +140,14 @@ class ofdm_mod(gr.hier_block2): """ Adds OFDM-specific options to the Options Parser """ - _add_common_options(normal, expert) - for mod in modulation_utils2.type_1_mods().values(): - mod.add_options(expert) - + 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]") # Make a static method to call before instantiation add_options = staticmethod(add_options) @@ -198,9 +196,6 @@ 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] @@ -216,11 +211,22 @@ class ofdm_demod(gr.hier_block2): self._occupied_tones, self._snr, preambles, options.log) - constell = modulation_utils2.type_1_constellations()[self._modulation](arity) + 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 phgain = 0.25 frgain = phgain*phgain / 4.0 - self.ofdm_demod = gr.ofdm_frame_sink2(constell.base(), + self.ofdm_demod = gr.ofdm_frame_sink(rotated_const, range(arity), self._rcvd_pktq, self._occupied_tones, phgain, frgain) @@ -247,9 +253,14 @@ class ofdm_demod(gr.hier_block2): """ Adds OFDM-specific options to the Options Parser """ - _add_common_options(normal, expert) - for mod in modulation_utils2.type_1_mods().values(): - mod.add_options(expert) + 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]") # Make a static method to call before instantiation add_options = staticmethod(add_options) diff --git a/gnuradio-core/src/python/gnuradio/modulation_utils2.py b/gnuradio-core/src/python/gnuradio/modulation_utils2.py index f30055f4a..c5dba3e79 100644 --- a/gnuradio-core/src/python/gnuradio/modulation_utils2.py +++ b/gnuradio-core/src/python/gnuradio/modulation_utils2.py @@ -47,15 +47,6 @@ 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): """ @@ -88,14 +79,3 @@ 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/vocoder/__init__.py b/gnuradio-core/src/python/gnuradio/vocoder/__init__.py deleted file mode 100644 index a4917cf64..000000000 --- a/gnuradio-core/src/python/gnuradio/vocoder/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# make this a package diff --git a/gnuradio-examples/grc/trellis/interference_cancellation.grc b/gnuradio-examples/grc/trellis/interference_cancellation.grc index e93babd78..7674b4bf1 100644 --- a/gnuradio-examples/grc/trellis/interference_cancellation.grc +++ b/gnuradio-examples/grc/trellis/interference_cancellation.grc @@ -1,6 +1,6 @@ <?xml version='1.0' encoding='ASCII'?> <flow_graph> - <timestamp>Thu Mar 19 11:22:40 2009</timestamp> + <timestamp>Wed Aug 31 17:40:25 2011</timestamp> <block> <key>options</key> <param> @@ -36,6 +36,14 @@ <value>Custom</value> </param> <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> <key>realtime_scheduling</key> <value></value> </param> @@ -79,18 +87,22 @@ <value>100</value> </param> <param> - <key>slider_length</key> - <value>200</value> + <key>style</key> + <value>wx.SL_HORIZONTAL</value> </param> <param> - <key>slider_type</key> - <value>horizontal</value> + <key>converver</key> + <value>float_converter</value> </param> <param> <key>grid_pos</key> <value></value> </param> <param> + <key>notebook</key> + <value></value> + </param> + <param> <key>_coordinate</key> <value>(243, 11)</value> </param> @@ -130,18 +142,22 @@ <value>100</value> </param> <param> - <key>slider_length</key> - <value>200</value> + <key>style</key> + <value>wx.SL_HORIZONTAL</value> </param> <param> - <key>slider_type</key> - <value>horizontal</value> + <key>converver</key> + <value>float_converter</value> </param> <param> <key>grid_pos</key> <value></value> </param> <param> + <key>notebook</key> + <value></value> + </param> + <param> <key>_coordinate</key> <value>(447, 14)</value> </param> @@ -213,41 +229,6 @@ </param> </block> <block> - <key>gr_chunks_to_symbols_xx</key> - <param> - <key>id</key> - <value>gr_chunks_to_symbols_xx_0</value> - </param> - <param> - <key>_enabled</key> - <value>True</value> - </param> - <param> - <key>in_type</key> - <value>short</value> - </param> - <param> - <key>out_type</key> - <value>complex</value> - </param> - <param> - <key>symbol_table</key> - <value>1,1j,-1j,-1</value> - </param> - <param> - <key>dimension</key> - <value>1</value> - </param> - <param> - <key>_coordinate</key> - <value>(665, 187)</value> - </param> - <param> - <key>_rotation</key> - <value>0</value> - </param> - </block> - <block> <key>gr_multiply_const_vxx</key> <param> <key>id</key> @@ -344,6 +325,10 @@ <value>1</value> </param> <param> + <key>num_ports</key> + <value>1</value> + </param> + <param> <key>_coordinate</key> <value>(660, 311)</value> </param> @@ -638,6 +623,10 @@ <value>1</value> </param> <param> + <key>num_ports</key> + <value>1</value> + </param> + <param> <key>_coordinate</key> <value>(405, 998)</value> </param> @@ -816,6 +805,10 @@ <value>1</value> </param> <param> + <key>num_ports</key> + <value>1</value> + </param> + <param> <key>_coordinate</key> <value>(420, 1368)</value> </param> @@ -968,10 +961,10 @@ </param> </block> <block> - <key>wxgui_numbersink2</key> + <key>trellis_encoder_xx</key> <param> <key>id</key> - <value>wxgui_numbersink2_2</value> + <value>trellis_encoder_xx_1</value> </param> <param> <key>_enabled</key> @@ -979,71 +972,74 @@ </param> <param> <key>type</key> - <value>float</value> + <value>ss</value> </param> <param> - <key>title</key> - <value>BER 2 (raw)</value> + <key>fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> </param> <param> - <key>units</key> - <value>BER</value> + <key>init_state</key> + <value>0</value> </param> <param> - <key>samp_rate</key> - <value>R</value> + <key>_coordinate</key> + <value>(336, 311)</value> </param> <param> - <key>base_value</key> - <value>0.0</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>trellis_viterbi_combined_xx</key> <param> - <key>min_value</key> - <value>0</value> + <key>id</key> + <value>trellis_viterbi_combined_xx_1</value> </param> <param> - <key>max_value</key> - <value>1.0</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>factor</key> - <value>1.0</value> + <key>type</key> + <value>c</value> </param> <param> - <key>decimal_places</key> - <value>6</value> + <key>out_type</key> + <value>s</value> </param> <param> - <key>ref_level</key> - <value>0</value> + <key>fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> </param> <param> - <key>number_rate</key> - <value>15</value> + <key>block_size</key> + <value>1000</value> </param> <param> - <key>peak_hold</key> - <value>False</value> + <key>init_state</key> + <value>-1</value> </param> <param> - <key>average</key> - <value>False</value> + <key>final_state</key> + <value>-1</value> </param> <param> - <key>avg_alpha</key> - <value>0.001</value> + <key>dim</key> + <value>1</value> </param> <param> - <key>show_gauge</key> - <value>True</value> + <key>table</key> + <value>alpha**0.5*1,alpha**0.5*1j,alpha**0.5*(-1j),alpha**0.5*(-1)</value> </param> <param> - <key>grid_pos</key> - <value>0,1,1,1</value> + <key>metric_type</key> + <value>trellis.TRELLIS_EUCLIDEAN</value> </param> <param> <key>_coordinate</key> - <value>(1260, 659)</value> + <value>(79, 501)</value> </param> <param> <key>_rotation</key> @@ -1051,10 +1047,10 @@ </param> </block> <block> - <key>wxgui_numbersink2</key> + <key>trellis_viterbi_combined_xx</key> <param> <key>id</key> - <value>wxgui_numbersink2_3</value> + <value>trellis_viterbi_combined_xx_2</value> </param> <param> <key>_enabled</key> @@ -1062,71 +1058,74 @@ </param> <param> <key>type</key> - <value>float</value> + <value>c</value> </param> <param> - <key>title</key> - <value>BER 2 (after cancelling user 1)</value> + <key>out_type</key> + <value>s</value> </param> <param> - <key>units</key> - <value>BER</value> + <key>fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> </param> <param> - <key>samp_rate</key> - <value>R</value> + <key>block_size</key> + <value>1000</value> </param> <param> - <key>base_value</key> - <value>0.0</value> + <key>init_state</key> + <value>-1</value> </param> <param> - <key>min_value</key> - <value>0</value> + <key>final_state</key> + <value>-1</value> </param> <param> - <key>max_value</key> - <value>1.0</value> + <key>dim</key> + <value>1</value> </param> <param> - <key>factor</key> - <value>1.0</value> + <key>table</key> + <value>(1-alpha)**0.5*1,(1-alpha)**0.5*1j,(1-alpha)**0.5*(-1j),(1-alpha)**0.5*(-1)</value> </param> <param> - <key>decimal_places</key> - <value>6</value> + <key>metric_type</key> + <value>trellis.TRELLIS_EUCLIDEAN</value> </param> <param> - <key>ref_level</key> - <value>0</value> + <key>_coordinate</key> + <value>(82, 766)</value> </param> <param> - <key>number_rate</key> - <value>15</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>trellis_encoder_xx</key> <param> - <key>peak_hold</key> - <value>False</value> + <key>id</key> + <value>trellis_encoder_xx_2</value> </param> <param> - <key>average</key> - <value>False</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>avg_alpha</key> - <value>0.001</value> + <key>type</key> + <value>ss</value> </param> <param> - <key>show_gauge</key> - <value>True</value> + <key>fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> </param> <param> - <key>grid_pos</key> - <value>1,1,1,1</value> + <key>init_state</key> + <value>0</value> </param> <param> <key>_coordinate</key> - <value>(1262, 1020)</value> + <value>(89, 998)</value> </param> <param> <key>_rotation</key> @@ -1134,10 +1133,10 @@ </param> </block> <block> - <key>wxgui_numbersink2</key> + <key>trellis_viterbi_combined_xx</key> <param> <key>id</key> - <value>wxgui_numbersink2_3_0</value> + <value>trellis_viterbi_combined_xx_0</value> </param> <param> <key>_enabled</key> @@ -1145,71 +1144,74 @@ </param> <param> <key>type</key> - <value>float</value> + <value>c</value> </param> <param> - <key>title</key> - <value>BER 1 (after cancelling user 2)</value> + <key>out_type</key> + <value>s</value> </param> <param> - <key>units</key> - <value>BER</value> + <key>fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> </param> <param> - <key>samp_rate</key> - <value>R</value> + <key>block_size</key> + <value>1000</value> </param> <param> - <key>base_value</key> - <value>0.0</value> + <key>init_state</key> + <value>-1</value> </param> <param> - <key>min_value</key> - <value>0</value> + <key>final_state</key> + <value>-1</value> </param> <param> - <key>max_value</key> - <value>1.0</value> + <key>dim</key> + <value>1</value> </param> <param> - <key>factor</key> - <value>1.0</value> + <key>table</key> + <value>(1-alpha)**0.5*1,(1-alpha)**0.5*1j,(1-alpha)**0.5*(-1j),(1-alpha)**0.5*(-1)</value> </param> <param> - <key>decimal_places</key> - <value>6</value> + <key>metric_type</key> + <value>trellis.TRELLIS_EUCLIDEAN</value> </param> <param> - <key>ref_level</key> - <value>0</value> + <key>_coordinate</key> + <value>(83, 1111)</value> </param> <param> - <key>number_rate</key> - <value>15</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>trellis_encoder_xx</key> <param> - <key>peak_hold</key> - <value>False</value> + <key>id</key> + <value>trellis_encoder_xx_2_0</value> </param> <param> - <key>average</key> - <value>False</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>avg_alpha</key> - <value>0.001</value> + <key>type</key> + <value>ss</value> </param> <param> - <key>show_gauge</key> - <value>True</value> + <key>fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> </param> <param> - <key>grid_pos</key> - <value>1,0,1,1</value> + <key>init_state</key> + <value>0</value> </param> <param> <key>_coordinate</key> - <value>(1269, 1417)</value> + <value>(105, 1367)</value> </param> <param> <key>_rotation</key> @@ -1217,53 +1219,54 @@ </param> </block> <block> - <key>variable</key> + <key>trellis_viterbi_combined_xx</key> <param> <key>id</key> - <value>R</value> + <value>trellis_viterbi_combined_xx_0_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>10e3</value> + <key>type</key> + <value>c</value> </param> <param> - <key>_coordinate</key> - <value>(748, 12)</value> + <key>out_type</key> + <value>s</value> </param> <param> - <key>_rotation</key> - <value>0</value> + <key>fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> </param> - </block> - <block> - <key>trellis_encoder_xx</key> <param> - <key>id</key> - <value>trellis_encoder_xx_0</value> + <key>block_size</key> + <value>1000</value> </param> <param> - <key>_enabled</key> - <value>True</value> + <key>init_state</key> + <value>-1</value> </param> <param> - <key>type</key> - <value>ss</value> + <key>final_state</key> + <value>-1</value> </param> <param> - <key>fsm_args</key> - <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> + <key>dim</key> + <value>1</value> </param> <param> - <key>init_state</key> - <value>0</value> + <key>table</key> + <value>alpha**0.5*1,alpha**0.5*1j,alpha**0.5*(-1j),alpha**0.5*(-1)</value> + </param> + <param> + <key>metric_type</key> + <value>trellis.TRELLIS_EUCLIDEAN</value> </param> <param> <key>_coordinate</key> - <value>(334, 190)</value> + <value>(75, 1495)</value> </param> <param> <key>_rotation</key> @@ -1271,10 +1274,10 @@ </param> </block> <block> - <key>trellis_encoder_xx</key> + <key>gr_add_xx</key> <param> <key>id</key> - <value>trellis_encoder_xx_1</value> + <value>gr_add_xx_1</value> </param> <param> <key>_enabled</key> @@ -1282,19 +1285,19 @@ </param> <param> <key>type</key> - <value>ss</value> + <value>complex</value> </param> <param> - <key>fsm_args</key> - <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> + <key>num_inputs</key> + <value>2</value> </param> <param> - <key>init_state</key> - <value>0</value> + <key>vlen</key> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(336, 311)</value> + <value>(1400, 262)</value> </param> <param> <key>_rotation</key> @@ -1302,10 +1305,10 @@ </param> </block> <block> - <key>trellis_viterbi_combined_xx</key> + <key>wxgui_scopesink2</key> <param> <key>id</key> - <value>trellis_viterbi_combined_xx_1</value> + <value>wxgui_scopesink2_0</value> </param> <param> <key>_enabled</key> @@ -1313,43 +1316,63 @@ </param> <param> <key>type</key> - <value>c</value> + <value>complex</value> </param> <param> - <key>out_type</key> - <value>s</value> + <key>title</key> + <value>Scope Plot</value> </param> <param> - <key>fsm_args</key> - <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> + <key>samp_rate</key> + <value>R</value> </param> <param> - <key>block_size</key> - <value>1000</value> + <key>v_scale</key> + <value>0</value> </param> <param> - <key>init_state</key> - <value>-1</value> + <key>v_offset</key> + <value>0</value> </param> <param> - <key>final_state</key> - <value>-1</value> + <key>t_scale</key> + <value>0</value> </param> <param> - <key>dim</key> + <key>ac_couple</key> + <value>False</value> + </param> + <param> + <key>xy_mode</key> + <value>True</value> + </param> + <param> + <key>num_inputs</key> <value>1</value> </param> <param> - <key>table</key> - <value>alpha**0.5*1,alpha**0.5*1j,alpha**0.5*(-1j),alpha**0.5*(-1)</value> + <key>win_size</key> + <value></value> </param> <param> - <key>metric_type</key> - <value>trellis.TRELLIS_EUCLIDEAN</value> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>trig_mode</key> + <value>gr.gr_TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> </param> <param> <key>_coordinate</key> - <value>(79, 501)</value> + <value>(1533, 149)</value> </param> <param> <key>_rotation</key> @@ -1357,54 +1380,53 @@ </param> </block> <block> - <key>trellis_viterbi_combined_xx</key> + <key>variable</key> <param> <key>id</key> - <value>trellis_viterbi_combined_xx_2</value> + <value>prefix</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>c</value> - </param> - <param> - <key>out_type</key> - <value>s</value> + <key>value</key> + <value>"/n/harrisville/x/anastas/gnuradio_trunk/"</value> </param> <param> - <key>fsm_args</key> - <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> + <key>_coordinate</key> + <value>(871, 14)</value> </param> <param> - <key>block_size</key> - <value>1000</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>trellis_encoder_xx</key> <param> - <key>init_state</key> - <value>-1</value> + <key>id</key> + <value>trellis_encoder_xx_0</value> </param> <param> - <key>final_state</key> - <value>-1</value> + <key>_enabled</key> + <value>True</value> </param> <param> - <key>dim</key> - <value>1</value> + <key>type</key> + <value>ss</value> </param> <param> - <key>table</key> - <value>(1-alpha)**0.5*1,(1-alpha)**0.5*1j,(1-alpha)**0.5*(-1j),(1-alpha)**0.5*(-1)</value> + <key>fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> </param> <param> - <key>metric_type</key> - <value>trellis.TRELLIS_EUCLIDEAN</value> + <key>init_state</key> + <value>0</value> </param> <param> <key>_coordinate</key> - <value>(82, 766)</value> + <value>(340, 187)</value> </param> <param> <key>_rotation</key> @@ -1412,10 +1434,10 @@ </param> </block> <block> - <key>trellis_encoder_xx</key> + <key>gr_throttle</key> <param> <key>id</key> - <value>trellis_encoder_xx_2</value> + <value>gr_throttle_0</value> </param> <param> <key>_enabled</key> @@ -1423,19 +1445,19 @@ </param> <param> <key>type</key> - <value>ss</value> + <value>short</value> </param> <param> - <key>fsm_args</key> - <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> + <key>samples_per_second</key> + <value>R</value> </param> <param> - <key>init_state</key> - <value>0</value> + <key>vlen</key> + <value>1</value> </param> <param> <key>_coordinate</key> - <value>(89, 998)</value> + <value>(534, 149)</value> </param> <param> <key>_rotation</key> @@ -1443,54 +1465,61 @@ </param> </block> <block> - <key>trellis_viterbi_combined_xx</key> + <key>gr_chunks_to_symbols_xx</key> <param> <key>id</key> - <value>trellis_viterbi_combined_xx_0</value> + <value>gr_chunks_to_symbols_xx_0</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>type</key> - <value>c</value> + <key>in_type</key> + <value>short</value> </param> <param> <key>out_type</key> - <value>s</value> + <value>complex</value> </param> <param> - <key>fsm_args</key> - <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> + <key>symbol_table</key> + <value>1,1j,-1j,-1</value> </param> <param> - <key>block_size</key> - <value>1000</value> + <key>dimension</key> + <value>1</value> </param> <param> - <key>init_state</key> - <value>-1</value> + <key>num_ports</key> + <value>1</value> </param> <param> - <key>final_state</key> - <value>-1</value> + <key>_coordinate</key> + <value>(682, 186)</value> </param> <param> - <key>dim</key> - <value>1</value> + <key>_rotation</key> + <value>0</value> </param> + </block> + <block> + <key>variable</key> <param> - <key>table</key> - <value>(1-alpha)**0.5*1,(1-alpha)**0.5*1j,(1-alpha)**0.5*(-1j),(1-alpha)**0.5*(-1)</value> + <key>id</key> + <value>R</value> </param> <param> - <key>metric_type</key> - <value>trellis.TRELLIS_EUCLIDEAN</value> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>100e3</value> </param> <param> <key>_coordinate</key> - <value>(83, 1111)</value> + <value>(748, 12)</value> </param> <param> <key>_rotation</key> @@ -1498,10 +1527,10 @@ </param> </block> <block> - <key>trellis_encoder_xx</key> + <key>wxgui_numbersink2</key> <param> <key>id</key> - <value>trellis_encoder_xx_2_0</value> + <value>wxgui_numbersink2_0</value> </param> <param> <key>_enabled</key> @@ -1509,74 +1538,75 @@ </param> <param> <key>type</key> - <value>ss</value> + <value>float</value> </param> <param> - <key>fsm_args</key> - <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> + <key>title</key> + <value>BER 1 (raw)</value> </param> <param> - <key>init_state</key> - <value>0</value> + <key>units</key> + <value>BER</value> </param> <param> - <key>_coordinate</key> - <value>(105, 1367)</value> + <key>samp_rate</key> + <value>R</value> </param> <param> - <key>_rotation</key> + <key>min_value</key> <value>0</value> </param> - </block> - <block> - <key>trellis_viterbi_combined_xx</key> <param> - <key>id</key> - <value>trellis_viterbi_combined_xx_0_0</value> + <key>max_value</key> + <value>1</value> </param> <param> - <key>_enabled</key> - <value>True</value> + <key>factor</key> + <value>1.0</value> </param> <param> - <key>type</key> - <value>c</value> + <key>decimal_places</key> + <value>6</value> </param> <param> - <key>out_type</key> - <value>s</value> + <key>ref_level</key> + <value>0</value> </param> <param> - <key>fsm_args</key> - <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_16.fsm"</value> + <key>number_rate</key> + <value>15</value> </param> <param> - <key>block_size</key> - <value>1000</value> + <key>peak_hold</key> + <value>False</value> </param> <param> - <key>init_state</key> - <value>-1</value> + <key>average</key> + <value>True</value> </param> <param> - <key>final_state</key> - <value>-1</value> + <key>avg_alpha</key> + <value>0.001</value> </param> <param> - <key>dim</key> - <value>1</value> + <key>show_gauge</key> + <value>True</value> </param> <param> - <key>table</key> - <value>alpha**0.5*1,alpha**0.5*1j,alpha**0.5*(-1j),alpha**0.5*(-1)</value> + <key>win_size</key> + <value></value> </param> <param> - <key>metric_type</key> - <value>trellis.TRELLIS_EUCLIDEAN</value> + <key>grid_pos</key> + <value>0,0,1,1</value> + </param> + <param> + <key>notebook</key> + <value></value> </param> <param> <key>_coordinate</key> - <value>(75, 1495)</value> + <value>(1267, 410)</value> </param> <param> <key>_rotation</key> @@ -1584,53 +1614,86 @@ </param> </block> <block> - <key>variable</key> + <key>wxgui_numbersink2</key> <param> <key>id</key> - <value>prefix</value> + <value>wxgui_numbersink2_2</value> </param> <param> <key>_enabled</key> <value>True</value> </param> <param> - <key>value</key> - <value>"../../../"</value> + <key>type</key> + <value>float</value> </param> <param> - <key>_coordinate</key> - <value>(871, 14)</value> + <key>title</key> + <value>BER 2 (raw)</value> </param> <param> - <key>_rotation</key> + <key>units</key> + <value>BER</value> + </param> + <param> + <key>samp_rate</key> + <value>R</value> + </param> + <param> + <key>min_value</key> <value>0</value> </param> - </block> - <block> - <key>gr_add_xx</key> <param> - <key>id</key> - <value>gr_add_xx_1</value> + <key>max_value</key> + <value>1.0</value> </param> <param> - <key>_enabled</key> + <key>factor</key> + <value>1.0</value> + </param> + <param> + <key>decimal_places</key> + <value>6</value> + </param> + <param> + <key>ref_level</key> + <value>0</value> + </param> + <param> + <key>number_rate</key> + <value>15</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>average</key> <value>True</value> </param> <param> - <key>type</key> - <value>complex</value> + <key>avg_alpha</key> + <value>0.001</value> </param> <param> - <key>num_inputs</key> - <value>2</value> + <key>show_gauge</key> + <value>True</value> </param> <param> - <key>vlen</key> - <value>1</value> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value>0,1,1,1</value> + </param> + <param> + <key>notebook</key> + <value></value> </param> <param> <key>_coordinate</key> - <value>(1400, 262)</value> + <value>(1260, 659)</value> </param> <param> <key>_rotation</key> @@ -1641,7 +1704,7 @@ <key>wxgui_numbersink2</key> <param> <key>id</key> - <value>wxgui_numbersink2_0</value> + <value>wxgui_numbersink2_3</value> </param> <param> <key>_enabled</key> @@ -1653,7 +1716,7 @@ </param> <param> <key>title</key> - <value>BER 1 (raw)</value> + <value>BER 2 (after cancelling user 1)</value> </param> <param> <key>units</key> @@ -1664,16 +1727,12 @@ <value>R</value> </param> <param> - <key>base_value</key> - <value>0.0</value> - </param> - <param> <key>min_value</key> <value>0</value> </param> <param> <key>max_value</key> - <value>1</value> + <value>1.0</value> </param> <param> <key>factor</key> @@ -1697,7 +1756,7 @@ </param> <param> <key>average</key> - <value>False</value> + <value>True</value> </param> <param> <key>avg_alpha</key> @@ -1708,12 +1767,20 @@ <value>True</value> </param> <param> + <key>win_size</key> + <value></value> + </param> + <param> <key>grid_pos</key> - <value>0,0,1,1</value> + <value>1,1,1,1</value> + </param> + <param> + <key>notebook</key> + <value></value> </param> <param> <key>_coordinate</key> - <value>(1267, 410)</value> + <value>(1262, 1020)</value> </param> <param> <key>_rotation</key> @@ -1721,10 +1788,10 @@ </param> </block> <block> - <key>wxgui_scopesink2</key> + <key>wxgui_numbersink2</key> <param> <key>id</key> - <value>wxgui_scopesink2_0</value> + <value>wxgui_numbersink2_3_0</value> </param> <param> <key>_enabled</key> @@ -1732,43 +1799,75 @@ </param> <param> <key>type</key> - <value>complex</value> + <value>float</value> </param> <param> <key>title</key> - <value>Scope Plot</value> + <value>BER 1 (after cancelling user 2)</value> + </param> + <param> + <key>units</key> + <value>BER</value> </param> <param> <key>samp_rate</key> <value>R</value> </param> <param> - <key>v_scale</key> + <key>min_value</key> <value>0</value> </param> <param> - <key>t_scale</key> + <key>max_value</key> + <value>1.0</value> + </param> + <param> + <key>factor</key> + <value>1.0</value> + </param> + <param> + <key>decimal_places</key> + <value>6</value> + </param> + <param> + <key>ref_level</key> <value>0</value> </param> <param> - <key>ac_couple</key> + <key>number_rate</key> + <value>15</value> + </param> + <param> + <key>peak_hold</key> <value>False</value> </param> <param> - <key>xy_mode</key> + <key>average</key> <value>True</value> </param> <param> - <key>num_inputs</key> - <value>1</value> + <key>avg_alpha</key> + <value>0.001</value> + </param> + <param> + <key>show_gauge</key> + <value>True</value> + </param> + <param> + <key>win_size</key> + <value></value> </param> <param> <key>grid_pos</key> + <value>1,0,1,1</value> + </param> + <param> + <key>notebook</key> <value></value> </param> <param> <key>_coordinate</key> - <value>(1533, 149)</value> + <value>(1269, 1417)</value> </param> <param> <key>_rotation</key> @@ -1782,12 +1881,6 @@ <sink_key>0</sink_key> </connection> <connection> - <source_block_id>trellis_encoder_xx_0</source_block_id> - <sink_block_id>gr_chunks_to_symbols_xx_0</sink_block_id> - <source_key>0</source_key> - <sink_key>0</sink_key> - </connection> - <connection> <source_block_id>trellis_encoder_xx_1</source_block_id> <sink_block_id>gr_chunks_to_symbols_xx_1</sink_block_id> <source_key>0</source_key> @@ -2069,4 +2162,16 @@ <source_key>0</source_key> <sink_key>0</sink_key> </connection> + <connection> + <source_block_id>trellis_encoder_xx_0</source_block_id> + <sink_block_id>gr_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_chunks_to_symbols_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> </flow_graph> diff --git a/gnuradio-examples/grc/trellis/pccc.grc b/gnuradio-examples/grc/trellis/pccc.grc new file mode 100644 index 000000000..c3111c321 --- /dev/null +++ b/gnuradio-examples/grc/trellis/pccc.grc @@ -0,0 +1,832 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Thu Sep 1 12:53:13 2011</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>sccc1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>Serially Concatenated Convolutional Code</value> + </param> + <param> + <key>author</key> + <value>AA</value> + </param> + <param> + <key>description</key> + <value>gnuradio flow graph</value> + </param> + <param> + <key>window_size</key> + <value>2048, 2048</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>noisevar</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>10**(-snr_db/10)</value> + </param> + <param> + <key>_coordinate</key> + <value>(389, 15)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>prefix</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>"/n/harrisville/x/anastas/gnuradio_trunk/"</value> + </param> + <param> + <key>_coordinate</key> + <value>(590, 15)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>block</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>1000</value> + </param> + <param> + <key>_coordinate</key> + <value>(764, 16)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>snr_db</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>SNR (dB)</value> + </param> + <param> + <key>value</key> + <value>5</value> + </param> + <param> + <key>min</key> + <value>-10</value> + </param> + <param> + <key>max</key> + <value>10</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>style</key> + <value>wx.SL_HORIZONTAL</value> + </param> + <param> + <key>converver</key> + <value>float_converter</value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(229, 13)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_multiply_xx</key> + <param> + <key>id</key> + <value>gr_multiply_xx_2_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(392, 591)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_short_to_float</key> + <param> + <key>id</key> + <value>gr_short_to_float_1_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(535, 609)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_numbersink2</key> + <param> + <key>id</key> + <value>wxgui_numbersink2_3_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>BER</value> + </param> + <param> + <key>units</key> + <value>BER</value> + </param> + <param> + <key>samp_rate</key> + <value>R</value> + </param> + <param> + <key>min_value</key> + <value>0</value> + </param> + <param> + <key>max_value</key> + <value>1.0</value> + </param> + <param> + <key>factor</key> + <value>1.0</value> + </param> + <param> + <key>decimal_places</key> + <value>6</value> + </param> + <param> + <key>ref_level</key> + <value>0</value> + </param> + <param> + <key>number_rate</key> + <value>15</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>average</key> + <value>True</value> + </param> + <param> + <key>avg_alpha</key> + <value>0.001</value> + </param> + <param> + <key>show_gauge</key> + <value>True</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value>1,0,1,1</value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(713, 426)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_noise_source_x</key> + <param> + <key>id</key> + <value>gr_noise_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>noise_type</key> + <value>gr.GR_GAUSSIAN</value> + </param> + <param> + <key>amp</key> + <value>noisevar</value> + </param> + <param> + <key>seed</key> + <value>42</value> + </param> + <param> + <key>_coordinate</key> + <value>(672, 290)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_scopesink2</key> + <param> + <key>id</key> + <value>wxgui_scopesink2_0</value> + </param> + <param> + <key>_enabled</key> + <value>False</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>Scope Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>R</value> + </param> + <param> + <key>v_scale</key> + <value>0</value> + </param> + <param> + <key>v_offset</key> + <value>0</value> + </param> + <param> + <key>t_scale</key> + <value>0</value> + </param> + <param> + <key>ac_couple</key> + <value>False</value> + </param> + <param> + <key>xy_mode</key> + <value>False</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>trig_mode</key> + <value>gr.gr_TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> + </param> + <param> + <key>_coordinate</key> + <value>(952, 73)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>random_source_x</key> + <param> + <key>id</key> + <value>random_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>2</value> + </param> + <param> + <key>num_samps</key> + <value>1000</value> + </param> + <param> + <key>repeat</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(21, 170)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_throttle</key> + <param> + <key>id</key> + <value>gr_throttle_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>samples_per_second</key> + <value>R</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(517, 103)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_chunks_to_symbols_xx</key> + <param> + <key>id</key> + <value>gr_chunks_to_symbols_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>in_type</key> + <value>short</value> + </param> + <param> + <key>out_type</key> + <value>float</value> + </param> + <param> + <key>symbol_table</key> + <value>-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7,0, 0,-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7</value> + </param> + <param> + <key>dimension</key> + <value>2</value> + </param> + <param> + <key>num_ports</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(551, 184)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>trellis_pccc_encoder_xx</key> + <param> + <key>id</key> + <value>trellis_pccc_encoder_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>ss</value> + </param> + <param> + <key>o_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>o_init_state</key> + <value>0</value> + </param> + <param> + <key>i_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>i_init_state</key> + <value>0</value> + </param> + <param> + <key>interleaver_args</key> + <value>trellis.interleaver(block,666)</value> + </param> + <param> + <key>bl</key> + <value>block</value> + </param> + <param> + <key>_coordinate</key> + <value>(236, 147)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>R</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>100e3</value> + </param> + <param> + <key>_coordinate</key> + <value>(482, 17)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_add_xx</key> + <param> + <key>id</key> + <value>gr_add_xx_1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(951, 256)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>trellis_pccc_decoder_combined_xx</key> + <param> + <key>id</key> + <value>trellis_pccc_decoder_combined_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>f</value> + </param> + <param> + <key>out_type</key> + <value>s</value> + </param> + <param> + <key>o_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>o_init_state</key> + <value>0</value> + </param> + <param> + <key>o_final_state</key> + <value>-1</value> + </param> + <param> + <key>i_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>i_init_state</key> + <value>0</value> + </param> + <param> + <key>i_final_state</key> + <value>-1</value> + </param> + <param> + <key>interleaver</key> + <value>trellis.interleaver(block,666)</value> + </param> + <param> + <key>block_size</key> + <value>block</value> + </param> + <param> + <key>iterations</key> + <value>10</value> + </param> + <param> + <key>dim</key> + <value>2</value> + </param> + <param> + <key>table</key> + <value>-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7,0, 0,-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7</value> + </param> + <param> + <key>metric_type</key> + <value>trellis.TRELLIS_EUCLIDEAN</value> + </param> + <param> + <key>siso_type</key> + <value>trellis.TRELLIS_MIN_SUM</value> + </param> + <param> + <key>scaling</key> + <value>1.0</value> + </param> + <param> + <key>_coordinate</key> + <value>(196, 274)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sub_xx</key> + <param> + <key>id</key> + <value>gr_sub_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>_coordinate</key> + <value>(217, 597)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>random_source_x_0</source_block_id> + <sink_block_id>gr_sub_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_chunks_to_symbols_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_add_xx_1</source_block_id> + <sink_block_id>wxgui_scopesink2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_noise_source_x_0</source_block_id> + <sink_block_id>gr_add_xx_1</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_chunks_to_symbols_xx_0</source_block_id> + <sink_block_id>gr_add_xx_1</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_multiply_xx_2_0</source_block_id> + <sink_block_id>gr_short_to_float_1_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_short_to_float_1_0</source_block_id> + <sink_block_id>wxgui_numbersink2_3_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_sub_xx_0</source_block_id> + <sink_block_id>gr_multiply_xx_2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_sub_xx_0</source_block_id> + <sink_block_id>gr_multiply_xx_2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>random_source_x_0</source_block_id> + <sink_block_id>trellis_pccc_encoder_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>trellis_pccc_encoder_xx_0</source_block_id> + <sink_block_id>gr_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_add_xx_1</source_block_id> + <sink_block_id>trellis_pccc_decoder_combined_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>trellis_pccc_decoder_combined_xx_0</source_block_id> + <sink_block_id>gr_sub_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> +</flow_graph> diff --git a/gnuradio-examples/grc/trellis/pccc1.grc b/gnuradio-examples/grc/trellis/pccc1.grc new file mode 100644 index 000000000..15a63707e --- /dev/null +++ b/gnuradio-examples/grc/trellis/pccc1.grc @@ -0,0 +1,857 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Wed Aug 31 20:34:39 2011</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>sccc1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>Serially Concatenated Convolutional Code</value> + </param> + <param> + <key>author</key> + <value>AA</value> + </param> + <param> + <key>description</key> + <value>gnuradio flow graph</value> + </param> + <param> + <key>window_size</key> + <value>2048, 2048</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>noisevar</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>10**(-snr_db/10)</value> + </param> + <param> + <key>_coordinate</key> + <value>(389, 15)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>prefix</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>"/n/harrisville/x/anastas/gnuradio_trunk/"</value> + </param> + <param> + <key>_coordinate</key> + <value>(590, 15)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>block</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>1000</value> + </param> + <param> + <key>_coordinate</key> + <value>(764, 16)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>snr_db</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>SNR (dB)</value> + </param> + <param> + <key>value</key> + <value>5</value> + </param> + <param> + <key>min</key> + <value>-10</value> + </param> + <param> + <key>max</key> + <value>10</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>style</key> + <value>wx.SL_HORIZONTAL</value> + </param> + <param> + <key>converver</key> + <value>float_converter</value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(229, 13)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_multiply_xx</key> + <param> + <key>id</key> + <value>gr_multiply_xx_2_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(392, 591)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_short_to_float</key> + <param> + <key>id</key> + <value>gr_short_to_float_1_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(535, 609)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_numbersink2</key> + <param> + <key>id</key> + <value>wxgui_numbersink2_3_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>BER</value> + </param> + <param> + <key>units</key> + <value>BER</value> + </param> + <param> + <key>samp_rate</key> + <value>R</value> + </param> + <param> + <key>min_value</key> + <value>0</value> + </param> + <param> + <key>max_value</key> + <value>1.0</value> + </param> + <param> + <key>factor</key> + <value>1.0</value> + </param> + <param> + <key>decimal_places</key> + <value>6</value> + </param> + <param> + <key>ref_level</key> + <value>0</value> + </param> + <param> + <key>number_rate</key> + <value>15</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>average</key> + <value>True</value> + </param> + <param> + <key>avg_alpha</key> + <value>0.001</value> + </param> + <param> + <key>show_gauge</key> + <value>True</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value>1,0,1,1</value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(713, 426)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_noise_source_x</key> + <param> + <key>id</key> + <value>gr_noise_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>noise_type</key> + <value>gr.GR_GAUSSIAN</value> + </param> + <param> + <key>amp</key> + <value>noisevar</value> + </param> + <param> + <key>seed</key> + <value>42</value> + </param> + <param> + <key>_coordinate</key> + <value>(672, 290)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_add_xx</key> + <param> + <key>id</key> + <value>gr_add_xx_1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(951, 256)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_scopesink2</key> + <param> + <key>id</key> + <value>wxgui_scopesink2_0</value> + </param> + <param> + <key>_enabled</key> + <value>False</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>Scope Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>R</value> + </param> + <param> + <key>v_scale</key> + <value>0</value> + </param> + <param> + <key>v_offset</key> + <value>0</value> + </param> + <param> + <key>t_scale</key> + <value>0</value> + </param> + <param> + <key>ac_couple</key> + <value>False</value> + </param> + <param> + <key>xy_mode</key> + <value>False</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>trig_mode</key> + <value>gr.gr_TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> + </param> + <param> + <key>_coordinate</key> + <value>(952, 73)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>random_source_x</key> + <param> + <key>id</key> + <value>random_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>2</value> + </param> + <param> + <key>num_samps</key> + <value>1000</value> + </param> + <param> + <key>repeat</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(21, 170)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_throttle</key> + <param> + <key>id</key> + <value>gr_throttle_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>samples_per_second</key> + <value>R</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(517, 103)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sub_xx</key> + <param> + <key>id</key> + <value>gr_sub_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>_coordinate</key> + <value>(217, 597)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_chunks_to_symbols_xx</key> + <param> + <key>id</key> + <value>gr_chunks_to_symbols_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>in_type</key> + <value>short</value> + </param> + <param> + <key>out_type</key> + <value>float</value> + </param> + <param> + <key>symbol_table</key> + <value>-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7,0, 0,-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7</value> + </param> + <param> + <key>dimension</key> + <value>2</value> + </param> + <param> + <key>num_ports</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(551, 184)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>trellis_pccc_encoder_xx</key> + <param> + <key>id</key> + <value>trellis_pccc_encoder_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>ss</value> + </param> + <param> + <key>o_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>o_init_state</key> + <value>0</value> + </param> + <param> + <key>i_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>i_init_state</key> + <value>0</value> + </param> + <param> + <key>interleaver_args</key> + <value>trellis.interleaver(block,666)</value> + </param> + <param> + <key>bl</key> + <value>block</value> + </param> + <param> + <key>_coordinate</key> + <value>(236, 147)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>trellis_pccc_decoder_x</key> + <param> + <key>id</key> + <value>trellis_pccc_decoder_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>out_type</key> + <value>s</value> + </param> + <param> + <key>o_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>o_init_state</key> + <value>0</value> + </param> + <param> + <key>o_final_state</key> + <value>-1</value> + </param> + <param> + <key>i_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>i_init_state</key> + <value>0</value> + </param> + <param> + <key>i_final_state</key> + <value>-1</value> + </param> + <param> + <key>interleaver</key> + <value>trellis.interleaver(block,666)</value> + </param> + <param> + <key>block_size</key> + <value>block</value> + </param> + <param> + <key>iterations</key> + <value>10</value> + </param> + <param> + <key>siso_type</key> + <value>trellis.TRELLIS_MIN_SUM</value> + </param> + <param> + <key>_coordinate</key> + <value>(357, 304)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>trellis_metrics_x</key> + <param> + <key>id</key> + <value>trellis_metrics_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>f</value> + </param> + <param> + <key>card</key> + <value>16</value> + </param> + <param> + <key>dim</key> + <value>2</value> + </param> + <param> + <key>table</key> + <value>-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7,0, 0,-7,0, -5,0, -3,0, -1,0, 1,0, 3,0, 5,0, 7</value> + </param> + <param> + <key>metric_type</key> + <value>trellis.TRELLIS_EUCLIDEAN</value> + </param> + <param> + <key>_coordinate</key> + <value>(58, 354)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>R</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>100e3</value> + </param> + <param> + <key>_coordinate</key> + <value>(482, 17)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>random_source_x_0</source_block_id> + <sink_block_id>gr_sub_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_chunks_to_symbols_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_add_xx_1</source_block_id> + <sink_block_id>wxgui_scopesink2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_noise_source_x_0</source_block_id> + <sink_block_id>gr_add_xx_1</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_chunks_to_symbols_xx_0</source_block_id> + <sink_block_id>gr_add_xx_1</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_multiply_xx_2_0</source_block_id> + <sink_block_id>gr_short_to_float_1_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_short_to_float_1_0</source_block_id> + <sink_block_id>wxgui_numbersink2_3_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_sub_xx_0</source_block_id> + <sink_block_id>gr_multiply_xx_2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_sub_xx_0</source_block_id> + <sink_block_id>gr_multiply_xx_2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_add_xx_1</source_block_id> + <sink_block_id>trellis_metrics_x_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>random_source_x_0</source_block_id> + <sink_block_id>trellis_pccc_encoder_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>trellis_pccc_encoder_xx_0</source_block_id> + <sink_block_id>gr_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>trellis_metrics_x_0</source_block_id> + <sink_block_id>trellis_pccc_decoder_x_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>trellis_pccc_decoder_x_0</source_block_id> + <sink_block_id>gr_sub_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> +</flow_graph> diff --git a/gnuradio-examples/grc/trellis/readme.txt b/gnuradio-examples/grc/trellis/readme.txt index d620fd628..9c7363af8 100644 --- a/gnuradio-examples/grc/trellis/readme.txt +++ b/gnuradio-examples/grc/trellis/readme.txt @@ -1,5 +1,7 @@ -This is an example of using gr-trellis in grc. +These are examples of using gr-trellis in grc. +INTERFERENCE CANCELLATION +------------------------- Two users are transmitting simultaneously using convolutionally encoded QPSK, each with power P1=alpha*P and P2=(1-alpha)*P. The combined signal is observed in noise and four different receivers are considered: 1) A viterbi decoder decoding user 1 assuming user 2 is noise @@ -13,4 +15,18 @@ The combined signal is observed in noise and four different receivers are consid You can change the signal to noise ratio P/sigma^2 and the allocation of power to the two users, alpha. + +Serially Concatenated Convolutional Codes +----------------------------------------- +An SCCC can be defined by an outer and an inner FSM together with an interleaver +and a modulation type. You can change the SNR and observe the estimated BER. +In sccc.grc the decoding and metric calculation are combined; in sccc1.grc they are separate. + +Parallel Concatenated Convolutional Codes +----------------------------------------- +A PCCC can be defined by two FSMs together with an interleaver +and a modulation type. You can change the SNR and observe the estimated BER. +In pccc1.grc the decoding and metric calculation are separate. + + Enjoy. diff --git a/gnuradio-examples/grc/trellis/sccc.grc b/gnuradio-examples/grc/trellis/sccc.grc new file mode 100644 index 000000000..e8f656f63 --- /dev/null +++ b/gnuradio-examples/grc/trellis/sccc.grc @@ -0,0 +1,832 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Wed Aug 31 19:57:09 2011</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>sccc</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>Serially Concatenated Convolutional Code</value> + </param> + <param> + <key>author</key> + <value>AA</value> + </param> + <param> + <key>description</key> + <value>gnuradio flow graph</value> + </param> + <param> + <key>window_size</key> + <value>2048, 2048</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>noisevar</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>10**(-snr_db/10)</value> + </param> + <param> + <key>_coordinate</key> + <value>(389, 15)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>random_source_x</key> + <param> + <key>id</key> + <value>random_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>2</value> + </param> + <param> + <key>num_samps</key> + <value>1000</value> + </param> + <param> + <key>repeat</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(21, 170)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>prefix</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>"/n/harrisville/x/anastas/gnuradio_trunk/"</value> + </param> + <param> + <key>_coordinate</key> + <value>(590, 15)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>block</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>1000</value> + </param> + <param> + <key>_coordinate</key> + <value>(764, 16)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_add_xx</key> + <param> + <key>id</key> + <value>gr_add_xx_1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(951, 256)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sub_xx</key> + <param> + <key>id</key> + <value>gr_sub_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>_coordinate</key> + <value>(445, 517)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_multiply_xx</key> + <param> + <key>id</key> + <value>gr_multiply_xx_2_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(228.25, 798.39170361874085)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_short_to_float</key> + <param> + <key>id</key> + <value>gr_short_to_float_1_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(416, 815)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>snr_db</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>SNR (dB)</value> + </param> + <param> + <key>value</key> + <value>5</value> + </param> + <param> + <key>min</key> + <value>-10</value> + </param> + <param> + <key>max</key> + <value>10</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>style</key> + <value>wx.SL_HORIZONTAL</value> + </param> + <param> + <key>converver</key> + <value>float_converter</value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(229, 13)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>R</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>10e3</value> + </param> + <param> + <key>_coordinate</key> + <value>(482, 17)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_scopesink2</key> + <param> + <key>id</key> + <value>wxgui_scopesink2_0</value> + </param> + <param> + <key>_enabled</key> + <value>False</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>title</key> + <value>Scope Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>R</value> + </param> + <param> + <key>v_scale</key> + <value>0</value> + </param> + <param> + <key>v_offset</key> + <value>0</value> + </param> + <param> + <key>t_scale</key> + <value>0</value> + </param> + <param> + <key>ac_couple</key> + <value>False</value> + </param> + <param> + <key>xy_mode</key> + <value>True</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>trig_mode</key> + <value>gr.gr_TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> + </param> + <param> + <key>_coordinate</key> + <value>(952, 73)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_throttle</key> + <param> + <key>id</key> + <value>gr_throttle_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>samples_per_second</key> + <value>R</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(514, 105)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_chunks_to_symbols_xx</key> + <param> + <key>id</key> + <value>gr_chunks_to_symbols_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>in_type</key> + <value>short</value> + </param> + <param> + <key>out_type</key> + <value>complex</value> + </param> + <param> + <key>symbol_table</key> + <value>1,0,1j,0,-1j,0,-1,0, 0,1,0,1j,0,-1j,0,-1</value> + </param> + <param> + <key>dimension</key> + <value>2</value> + </param> + <param> + <key>num_ports</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(551, 184)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_noise_source_x</key> + <param> + <key>id</key> + <value>gr_noise_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>complex</value> + </param> + <param> + <key>noise_type</key> + <value>gr.GR_GAUSSIAN</value> + </param> + <param> + <key>amp</key> + <value>noisevar</value> + </param> + <param> + <key>seed</key> + <value>42</value> + </param> + <param> + <key>_coordinate</key> + <value>(672, 290)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>trellis_sccc_encoder_xx</key> + <param> + <key>id</key> + <value>trellis_sccc_encoder_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>ss</value> + </param> + <param> + <key>o_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>o_init_state</key> + <value>0</value> + </param> + <param> + <key>i_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn2o3_4.fsm"</value> + </param> + <param> + <key>i_init_state</key> + <value>0</value> + </param> + <param> + <key>interleaver_args</key> + <value>trellis.interleaver(block,666)</value> + </param> + <param> + <key>bl</key> + <value>block</value> + </param> + <param> + <key>_coordinate</key> + <value>(242, 154)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_numbersink2</key> + <param> + <key>id</key> + <value>wxgui_numbersink2_3_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>BER</value> + </param> + <param> + <key>units</key> + <value>BER</value> + </param> + <param> + <key>samp_rate</key> + <value>R</value> + </param> + <param> + <key>min_value</key> + <value>0</value> + </param> + <param> + <key>max_value</key> + <value>1.0</value> + </param> + <param> + <key>factor</key> + <value>1.0</value> + </param> + <param> + <key>decimal_places</key> + <value>6</value> + </param> + <param> + <key>ref_level</key> + <value>0</value> + </param> + <param> + <key>number_rate</key> + <value>15</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>average</key> + <value>True</value> + </param> + <param> + <key>avg_alpha</key> + <value>0.001</value> + </param> + <param> + <key>show_gauge</key> + <value>True</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value>1,0,1,1</value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(688, 572)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>trellis_sccc_decoder_combined_xx</key> + <param> + <key>id</key> + <value>trellis_sccc_decoder_combined_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>c</value> + </param> + <param> + <key>out_type</key> + <value>s</value> + </param> + <param> + <key>o_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>o_init_state</key> + <value>0</value> + </param> + <param> + <key>o_final_state</key> + <value>-1</value> + </param> + <param> + <key>i_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn2o3_4.fsm"</value> + </param> + <param> + <key>i_init_state</key> + <value>0</value> + </param> + <param> + <key>i_final_state</key> + <value>-1</value> + </param> + <param> + <key>interleaver</key> + <value>trellis.interleaver(block,666)</value> + </param> + <param> + <key>block_size</key> + <value>block</value> + </param> + <param> + <key>iterations</key> + <value>5</value> + </param> + <param> + <key>dim</key> + <value>2</value> + </param> + <param> + <key>table</key> + <value>1,0,1j,0,-1j,0,-1,0, 0,1,0,1j,0,-1j,0,-1</value> + </param> + <param> + <key>metric_type</key> + <value>trellis.TRELLIS_EUCLIDEAN</value> + </param> + <param> + <key>siso_type</key> + <value>trellis.TRELLIS_SUM_PRODUCT</value> + </param> + <param> + <key>scaling</key> + <value>1.0</value> + </param> + <param> + <key>_coordinate</key> + <value>(159, 335)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>random_source_x_0</source_block_id> + <sink_block_id>gr_sub_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_chunks_to_symbols_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_add_xx_1</source_block_id> + <sink_block_id>wxgui_scopesink2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_noise_source_x_0</source_block_id> + <sink_block_id>gr_add_xx_1</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_chunks_to_symbols_xx_0</source_block_id> + <sink_block_id>gr_add_xx_1</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>random_source_x_0</source_block_id> + <sink_block_id>trellis_sccc_encoder_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>trellis_sccc_encoder_xx_0</source_block_id> + <sink_block_id>gr_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_add_xx_1</source_block_id> + <sink_block_id>trellis_sccc_decoder_combined_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>trellis_sccc_decoder_combined_xx_0</source_block_id> + <sink_block_id>gr_sub_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_multiply_xx_2_0</source_block_id> + <sink_block_id>gr_short_to_float_1_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_short_to_float_1_0</source_block_id> + <sink_block_id>wxgui_numbersink2_3_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_sub_xx_0</source_block_id> + <sink_block_id>gr_multiply_xx_2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_sub_xx_0</source_block_id> + <sink_block_id>gr_multiply_xx_2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> +</flow_graph> diff --git a/gnuradio-examples/grc/trellis/sccc1.grc b/gnuradio-examples/grc/trellis/sccc1.grc new file mode 100644 index 000000000..0be59d0c4 --- /dev/null +++ b/gnuradio-examples/grc/trellis/sccc1.grc @@ -0,0 +1,857 @@ +<?xml version='1.0' encoding='ASCII'?> +<flow_graph> + <timestamp>Wed Aug 31 20:09:23 2011</timestamp> + <block> + <key>options</key> + <param> + <key>id</key> + <value>sccc1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>title</key> + <value>Serially Concatenated Convolutional Code</value> + </param> + <param> + <key>author</key> + <value>AA</value> + </param> + <param> + <key>description</key> + <value>gnuradio flow graph</value> + </param> + <param> + <key>window_size</key> + <value>2048, 2048</value> + </param> + <param> + <key>generate_options</key> + <value>wx_gui</value> + </param> + <param> + <key>category</key> + <value>Custom</value> + </param> + <param> + <key>run_options</key> + <value>prompt</value> + </param> + <param> + <key>run</key> + <value>True</value> + </param> + <param> + <key>realtime_scheduling</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(10, 10)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>noisevar</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>10**(-snr_db/10)</value> + </param> + <param> + <key>_coordinate</key> + <value>(389, 15)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>random_source_x</key> + <param> + <key>id</key> + <value>random_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>min</key> + <value>0</value> + </param> + <param> + <key>max</key> + <value>2</value> + </param> + <param> + <key>num_samps</key> + <value>1000</value> + </param> + <param> + <key>repeat</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(21, 170)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>prefix</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>"/n/harrisville/x/anastas/gnuradio_trunk/"</value> + </param> + <param> + <key>_coordinate</key> + <value>(590, 15)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>block</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>1000</value> + </param> + <param> + <key>_coordinate</key> + <value>(764, 16)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable_slider</key> + <param> + <key>id</key> + <value>snr_db</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>label</key> + <value>SNR (dB)</value> + </param> + <param> + <key>value</key> + <value>5</value> + </param> + <param> + <key>min</key> + <value>-10</value> + </param> + <param> + <key>max</key> + <value>10</value> + </param> + <param> + <key>num_steps</key> + <value>100</value> + </param> + <param> + <key>style</key> + <value>wx.SL_HORIZONTAL</value> + </param> + <param> + <key>converver</key> + <value>float_converter</value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(229, 13)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>variable</key> + <param> + <key>id</key> + <value>R</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>value</key> + <value>10e3</value> + </param> + <param> + <key>_coordinate</key> + <value>(482, 17)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>trellis_sccc_encoder_xx</key> + <param> + <key>id</key> + <value>trellis_sccc_encoder_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>ss</value> + </param> + <param> + <key>o_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>o_init_state</key> + <value>0</value> + </param> + <param> + <key>i_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn2o3_4.fsm"</value> + </param> + <param> + <key>i_init_state</key> + <value>0</value> + </param> + <param> + <key>interleaver_args</key> + <value>trellis.interleaver(block,666)</value> + </param> + <param> + <key>bl</key> + <value>block</value> + </param> + <param> + <key>_coordinate</key> + <value>(242, 154)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>trellis_sccc_decoder_x</key> + <param> + <key>id</key> + <value>trellis_sccc_decoder_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>out_type</key> + <value>s</value> + </param> + <param> + <key>o_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn1o2_4.fsm"</value> + </param> + <param> + <key>o_init_state</key> + <value>0</value> + </param> + <param> + <key>o_final_state</key> + <value>-1</value> + </param> + <param> + <key>i_fsm_args</key> + <value>prefix+"gr-trellis/src/examples/fsm_files/awgn2o3_4.fsm"</value> + </param> + <param> + <key>i_init_state</key> + <value>0</value> + </param> + <param> + <key>i_final_state</key> + <value>-1</value> + </param> + <param> + <key>interleaver</key> + <value>trellis.interleaver(block,666)</value> + </param> + <param> + <key>block_size</key> + <value>block</value> + </param> + <param> + <key>iterations</key> + <value>10</value> + </param> + <param> + <key>siso_type</key> + <value>trellis.TRELLIS_MIN_SUM</value> + </param> + <param> + <key>_coordinate</key> + <value>(333, 305)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_sub_xx</key> + <param> + <key>id</key> + <value>gr_sub_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>_coordinate</key> + <value>(217, 597)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_multiply_xx</key> + <param> + <key>id</key> + <value>gr_multiply_xx_2_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(392, 591)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_short_to_float</key> + <param> + <key>id</key> + <value>gr_short_to_float_1_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>_coordinate</key> + <value>(535, 609)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_numbersink2</key> + <param> + <key>id</key> + <value>wxgui_numbersink2_3_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>BER</value> + </param> + <param> + <key>units</key> + <value>BER</value> + </param> + <param> + <key>samp_rate</key> + <value>R</value> + </param> + <param> + <key>min_value</key> + <value>0</value> + </param> + <param> + <key>max_value</key> + <value>1.0</value> + </param> + <param> + <key>factor</key> + <value>1.0</value> + </param> + <param> + <key>decimal_places</key> + <value>6</value> + </param> + <param> + <key>ref_level</key> + <value>0</value> + </param> + <param> + <key>number_rate</key> + <value>15</value> + </param> + <param> + <key>peak_hold</key> + <value>False</value> + </param> + <param> + <key>average</key> + <value>True</value> + </param> + <param> + <key>avg_alpha</key> + <value>0.001</value> + </param> + <param> + <key>show_gauge</key> + <value>True</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value>1,0,1,1</value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>_coordinate</key> + <value>(713, 426)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_noise_source_x</key> + <param> + <key>id</key> + <value>gr_noise_source_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>noise_type</key> + <value>gr.GR_GAUSSIAN</value> + </param> + <param> + <key>amp</key> + <value>noisevar</value> + </param> + <param> + <key>seed</key> + <value>42</value> + </param> + <param> + <key>_coordinate</key> + <value>(672, 290)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_add_xx</key> + <param> + <key>id</key> + <value>gr_add_xx_1</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>num_inputs</key> + <value>2</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(951, 256)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>trellis_metrics_x</key> + <param> + <key>id</key> + <value>trellis_metrics_x_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>f</value> + </param> + <param> + <key>card</key> + <value>8</value> + </param> + <param> + <key>dim</key> + <value>1</value> + </param> + <param> + <key>table</key> + <value>-7, -5, -3, -1, 1, 3, 5, 7</value> + </param> + <param> + <key>metric_type</key> + <value>trellis.TRELLIS_EUCLIDEAN</value> + </param> + <param> + <key>_coordinate</key> + <value>(58, 354)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_throttle</key> + <param> + <key>id</key> + <value>gr_throttle_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>type</key> + <value>short</value> + </param> + <param> + <key>samples_per_second</key> + <value>R</value> + </param> + <param> + <key>vlen</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(517, 103)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>wxgui_scopesink2</key> + <param> + <key>id</key> + <value>wxgui_scopesink2_0</value> + </param> + <param> + <key>_enabled</key> + <value>False</value> + </param> + <param> + <key>type</key> + <value>float</value> + </param> + <param> + <key>title</key> + <value>Scope Plot</value> + </param> + <param> + <key>samp_rate</key> + <value>R</value> + </param> + <param> + <key>v_scale</key> + <value>0</value> + </param> + <param> + <key>v_offset</key> + <value>0</value> + </param> + <param> + <key>t_scale</key> + <value>0</value> + </param> + <param> + <key>ac_couple</key> + <value>False</value> + </param> + <param> + <key>xy_mode</key> + <value>False</value> + </param> + <param> + <key>num_inputs</key> + <value>1</value> + </param> + <param> + <key>win_size</key> + <value></value> + </param> + <param> + <key>grid_pos</key> + <value></value> + </param> + <param> + <key>notebook</key> + <value></value> + </param> + <param> + <key>trig_mode</key> + <value>gr.gr_TRIG_MODE_AUTO</value> + </param> + <param> + <key>y_axis_label</key> + <value>Counts</value> + </param> + <param> + <key>_coordinate</key> + <value>(952, 73)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <block> + <key>gr_chunks_to_symbols_xx</key> + <param> + <key>id</key> + <value>gr_chunks_to_symbols_xx_0</value> + </param> + <param> + <key>_enabled</key> + <value>True</value> + </param> + <param> + <key>in_type</key> + <value>short</value> + </param> + <param> + <key>out_type</key> + <value>float</value> + </param> + <param> + <key>symbol_table</key> + <value>-7, -5, -3, -1, 1, 3, 5, 7</value> + </param> + <param> + <key>dimension</key> + <value>1</value> + </param> + <param> + <key>num_ports</key> + <value>1</value> + </param> + <param> + <key>_coordinate</key> + <value>(551, 184)</value> + </param> + <param> + <key>_rotation</key> + <value>0</value> + </param> + </block> + <connection> + <source_block_id>random_source_x_0</source_block_id> + <sink_block_id>gr_sub_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_throttle_0</source_block_id> + <sink_block_id>gr_chunks_to_symbols_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_add_xx_1</source_block_id> + <sink_block_id>wxgui_scopesink2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_noise_source_x_0</source_block_id> + <sink_block_id>gr_add_xx_1</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_chunks_to_symbols_xx_0</source_block_id> + <sink_block_id>gr_add_xx_1</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>random_source_x_0</source_block_id> + <sink_block_id>trellis_sccc_encoder_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>trellis_sccc_encoder_xx_0</source_block_id> + <sink_block_id>gr_throttle_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_multiply_xx_2_0</source_block_id> + <sink_block_id>gr_short_to_float_1_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_short_to_float_1_0</source_block_id> + <sink_block_id>wxgui_numbersink2_3_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_sub_xx_0</source_block_id> + <sink_block_id>gr_multiply_xx_2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>gr_sub_xx_0</source_block_id> + <sink_block_id>gr_multiply_xx_2_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> + <connection> + <source_block_id>gr_add_xx_1</source_block_id> + <sink_block_id>trellis_metrics_x_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>trellis_metrics_x_0</source_block_id> + <sink_block_id>trellis_sccc_decoder_x_0</sink_block_id> + <source_key>0</source_key> + <sink_key>0</sink_key> + </connection> + <connection> + <source_block_id>trellis_sccc_decoder_x_0</source_block_id> + <sink_block_id>gr_sub_xx_0</sink_block_id> + <source_key>0</source_key> + <sink_key>1</sink_key> + </connection> +</flow_graph> diff --git a/gnuradio-examples/python/Makefile.am b/gnuradio-examples/python/Makefile.am index 30effdf9a..3f1977e74 100644 --- a/gnuradio-examples/python/Makefile.am +++ b/gnuradio-examples/python/Makefile.am @@ -25,12 +25,12 @@ SUBDIRS = \ apps \ digital \ digital-bert \ - digital_voice \ mp-sched \ multi-antenna \ multi_usrp \ network \ ofdm \ pfb \ + tags \ usrp \ usrp2 diff --git a/gnuradio-examples/python/digital_voice/cvsd_test.py b/gnuradio-examples/python/digital_voice/cvsd_test.py deleted file mode 100755 index f8f1b9cce..000000000 --- a/gnuradio-examples/python/digital_voice/cvsd_test.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 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, blks2 -from gnuradio import audio -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -def main(): - parser = OptionParser(option_class=eng_option) - parser.add_option("-I", "--audio-input", type="string", default="", - help="pcm input device name. E.g., hw:0,0 or /dev/dsp") - parser.add_option("-O", "--audio-output", type="string", default="", - help="pcm output device name. E.g., hw:0,0 or /dev/dsp") - parser.add_option("-r", "--sample-rate", type="eng_float", default="32000", - help="Audio sampling rate [defaul=%default]") - parser.add_option("-S", "--resample-rate", type="int", default="8", - help="Resampling rate in CVSD [default=%default]") - (options, args) = parser.parse_args () - - if len(args) != 0: - parser.print_help() - raise SystemExit, 1 - - tb = gr.top_block() - - src = audio.source(int(options.sample_rate), options.audio_input) - tx = blks2.cvsd_encode(options.resample_rate) - - # todo: add noise - - rx = blks2.cvsd_decode(options.resample_rate) - dst = audio.sink(int(options.sample_rate), options.audio_output) - - tb.connect(src, tx, rx, dst) - tb.run() - -if __name__ == '__main__': - print "Enter CTRL-C to exit" - try: - main() - except KeyboardInterrupt: - pass - diff --git a/gnuradio-examples/python/digital_voice/encdec.py b/gnuradio-examples/python/digital_voice/encdec.py deleted file mode 100755 index e87d57e2b..000000000 --- a/gnuradio-examples/python/digital_voice/encdec.py +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env python -# -# 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. -# - -from gnuradio import gr, blks2 -from gnuradio import audio -from gnuradio.eng_option import eng_option -from optparse import OptionParser - -class my_top_block(gr.top_block): - - def __init__(self): - gr.top_block.__init__(self) - - parser = OptionParser(option_class=eng_option) - parser.add_option("-I", "--audio-input", type="string", default="", - help="pcm input device name. E.g., hw:0,0 or /dev/dsp") - parser.add_option("-O", "--audio-output", type="string", default="", - help="pcm output device name. E.g., hw:0,0 or /dev/dsp") - (options, args) = parser.parse_args () - if len(args) != 0: - parser.print_help() - raise SystemExit, 1 - - sample_rate = 8000 - src = audio.source(sample_rate, options.audio_input) - tx = blks2.digital_voice_tx(self) - if_gain = gr.multiply_const_cc(10000) - # channel simulator here... - rx = blks2.digital_voice_rx(self) - dst = audio.sink(sample_rate, options.audio_output) - - self.connect(src, tx, if_gain, rx, dst) - - -if __name__ == '__main__': - try: - my_top_block().run() - except KeyboardInterrupt: - pass diff --git a/gnuradio-examples/python/ofdm/gr_plot_ofdm.py b/gnuradio-examples/python/ofdm/gr_plot_ofdm.py index e3b347189..b24855148 100755 --- a/gnuradio-examples/python/ofdm/gr_plot_ofdm.py +++ b/gnuradio-examples/python/ofdm/gr_plot_ofdm.py @@ -20,14 +20,24 @@ # Boston, MA 02110-1301, USA. # -import scipy, pylab, math -import struct, sys -from pylab import * -from matplotlib.font_manager import fontManager, FontProperties +import math, struct, sys from optparse import OptionParser -from scipy import fftpack from math import log10 +try: + import scipy + from scipy import fftpack +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + +try: + from pylab import * + from matplotlib.font_manager import fontManager, FontProperties +except ImportError: + print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)." + sys.exit(1) + matplotlib.interactive(True) matplotlib.use('TkAgg') diff --git a/gnuradio-examples/python/pfb/channelize.py b/gnuradio-examples/python/pfb/channelize.py index f845c05c6..999e5d20e 100755 --- a/gnuradio-examples/python/pfb/channelize.py +++ b/gnuradio-examples/python/pfb/channelize.py @@ -21,10 +21,21 @@ # from gnuradio import gr, blks2 -import os, time -import scipy, pylab -from scipy import fftpack -from pylab import mlab +import sys, time + +try: + import scipy + from scipy import fftpack +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + +try: + import pylab + from pylab import mlab +except ImportError: + print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)." + sys.exit(1) class pfb_top_block(gr.top_block): def __init__(self): diff --git a/gnuradio-examples/python/pfb/chirp_channelize.py b/gnuradio-examples/python/pfb/chirp_channelize.py index edebf5f59..951255d3b 100755 --- a/gnuradio-examples/python/pfb/chirp_channelize.py +++ b/gnuradio-examples/python/pfb/chirp_channelize.py @@ -21,10 +21,21 @@ # from gnuradio import gr, blks2 -import os, time -import scipy, pylab -from scipy import fftpack -from pylab import mlab +import sys, time + +try: + import scipy + from scipy import fftpack +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + +try: + import pylab + from pylab import mlab +except ImportError: + print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)." + sys.exit(1) class pfb_top_block(gr.top_block): def __init__(self): diff --git a/gnuradio-examples/python/pfb/decimate.py b/gnuradio-examples/python/pfb/decimate.py index cb5d61b72..643a2c241 100755 --- a/gnuradio-examples/python/pfb/decimate.py +++ b/gnuradio-examples/python/pfb/decimate.py @@ -21,14 +21,21 @@ # from gnuradio import gr, blks2 -import os -import scipy, pylab -from scipy import fftpack -from pylab import mlab -import time - -#print os.getpid() -#raw_input() +import sys, time + +try: + import scipy + from scipy import fftpack +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + +try: + import pylab + from pylab import mlab +except ImportError: + print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)." + sys.exit(1) class pfb_top_block(gr.top_block): def __init__(self): diff --git a/gnuradio-examples/python/pfb/fmtest.py b/gnuradio-examples/python/pfb/fmtest.py index 97df0e0f5..635ee4e9e 100755 --- a/gnuradio-examples/python/pfb/fmtest.py +++ b/gnuradio-examples/python/pfb/fmtest.py @@ -1,14 +1,42 @@ #!/usr/bin/env python # +# 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. +# + +from gnuradio import gr, blks2 +import sys, math, time + +try: + import scipy + from scipy import fftpack +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + +try: + import pylab +except ImportError: + print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)." + sys.exit(1) -from gnuradio import gr, eng_notation -from gnuradio import blks2 -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import math, time, sys, scipy, pylab -from scipy import fftpack - class fmtx(gr.hier_block2): def __init__(self, lo_freq, audio_rate, if_rate): diff --git a/gnuradio-examples/python/pfb/interpolate.py b/gnuradio-examples/python/pfb/interpolate.py index a7a2522f8..370cf26a7 100755 --- a/gnuradio-examples/python/pfb/interpolate.py +++ b/gnuradio-examples/python/pfb/interpolate.py @@ -21,14 +21,21 @@ # from gnuradio import gr, blks2 -import os -import scipy, pylab -from scipy import fftpack -from pylab import mlab -import time - -#print os.getpid() -#raw_input() +import sys, time + +try: + import scipy + from scipy import fftpack +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + +try: + import pylab + from pylab import mlab +except ImportError: + print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)." + sys.exit(1) class pfb_top_block(gr.top_block): def __init__(self): diff --git a/gnuradio-examples/python/pfb/resampler.py b/gnuradio-examples/python/pfb/resampler.py index 6be7cf14e..7b296ca71 100755 --- a/gnuradio-examples/python/pfb/resampler.py +++ b/gnuradio-examples/python/pfb/resampler.py @@ -1,7 +1,39 @@ #!/usr/bin/env python +# +# 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. +# from gnuradio import gr, blks2 -import scipy, pylab +import sys + +try: + import scipy +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + +try: + import pylab +except ImportError: + print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)." + sys.exit(1) class mytb(gr.top_block): def __init__(self, fs_in, fs_out, fc, N=10000): diff --git a/gnuradio-examples/python/pfb/synth_filter.py b/gnuradio-examples/python/pfb/synth_filter.py index a1562f9ea..074d9cb2c 100755 --- a/gnuradio-examples/python/pfb/synth_filter.py +++ b/gnuradio-examples/python/pfb/synth_filter.py @@ -21,7 +21,19 @@ # from gnuradio import gr, blks2 -import scipy, pylab +import sys + +try: + import scipy +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + +try: + import pylab +except ImportError: + print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)." + sys.exit(1) def main(): N = 1000000 diff --git a/gnuradio-examples/python/pfb/synth_to_chan.py b/gnuradio-examples/python/pfb/synth_to_chan.py index 1beda1a54..7e454d903 100755 --- a/gnuradio-examples/python/pfb/synth_to_chan.py +++ b/gnuradio-examples/python/pfb/synth_to_chan.py @@ -21,7 +21,19 @@ # from gnuradio import gr, blks2 -import scipy, pylab +import sys + +try: + import scipy +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + +try: + import pylab +except ImportError: + print "Error: Program requires matplotlib (see: matplotlib.sourceforge.net)." + sys.exit(1) def main(): N = 1000000 diff --git a/gr-cvsd-vocoder/src/.gitignore b/gnuradio-examples/python/tags/.gitignore index b336cc7ce..b336cc7ce 100644 --- a/gr-cvsd-vocoder/src/.gitignore +++ b/gnuradio-examples/python/tags/.gitignore diff --git a/gnuradio-examples/python/digital_voice/Makefile.am b/gnuradio-examples/python/tags/Makefile.am index 60f363b90..5d71bf9b0 100644 --- a/gnuradio-examples/python/digital_voice/Makefile.am +++ b/gnuradio-examples/python/tags/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2005,2009 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,8 +21,9 @@ include $(top_srcdir)/Makefile.common -ourdatadir = $(exampledir)/digital_voice +ourdatadir = $(exampledir)/tags + +dist_ourdata_SCRIPTS = \ + test_file_tags.py \ + uhd_burst_detector.py -dist_ourdata_SCRIPTS = \ - encdec.py \ - cvsd_test.py diff --git a/gnuradio-examples/python/tags/test_file_tags.py b/gnuradio-examples/python/tags/test_file_tags.py index 4ff4549ef..446986cd7 100755 --- a/gnuradio-examples/python/tags/test_file_tags.py +++ b/gnuradio-examples/python/tags/test_file_tags.py @@ -1,7 +1,33 @@ #!/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 -import scipy +import sys + +try: + import scipy +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) def main(): data = scipy.arange(0, 32000, 1).tolist() diff --git a/gnuradio-examples/python/tags/uhd_burst_detector.py b/gnuradio-examples/python/tags/uhd_burst_detector.py index f8ebbe66a..ffa419562 100755 --- a/gnuradio-examples/python/tags/uhd_burst_detector.py +++ b/gnuradio-examples/python/tags/uhd_burst_detector.py @@ -1,4 +1,24 @@ #!/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 eng_notation from gnuradio import gr @@ -9,16 +29,16 @@ from gnuradio.gr import firdes from optparse import OptionParser class uhd_burst_detector(gr.top_block): - def __init__(self, frequency, sample_rate, - uhd_address="192.168.10.2", trigger=False): + def __init__(self, uhd_address, options): gr.top_block.__init__(self) - self.freq = frequency - self.samp_rate = sample_rate self.uhd_addr = uhd_address - self.gain = 32 - self.trigger = trigger + self.freq = options.freq + self.samp_rate = options.samp_rate + self.gain = options.gain + self.threshold = options.threshold + self.trigger = options.trigger self.uhd_src = uhd.single_usrp_source( device_addr=self.uhd_addr, @@ -32,7 +52,6 @@ class uhd_burst_detector(gr.top_block): taps = firdes.low_pass_2(1, 1, 0.4, 0.1, 60) self.chanfilt = gr.fir_filter_ccc(10, taps) - self.ann0 = gr.annotator_alltoall(100000, gr.sizeof_gr_complex) self.tagger = gr.burst_tagger(gr.sizeof_gr_complex) # Dummy signaler to collect a burst on known periods @@ -40,11 +59,18 @@ class uhd_burst_detector(gr.top_block): self.signal = gr.vector_source_s(data, True) # Energy detector to get signal burst + ## use squelch to detect energy + self.det = gr.simple_squelch_cc(self.threshold, 0.01) + ## convert to mag squared (float) self.c2m = gr.complex_to_mag_squared() - self.iir = gr.single_pole_iir_filter_ff(0.0001) - self.sub = gr.sub_ff() - self.mult = gr.multiply_const_ff(32768) + ## average to debounce + self.avg = gr.single_pole_iir_filter_ff(0.01) + ## rescale signal for conversion to short + self.scale = gr.multiply_const_ff(2**16) + ## signal input uses shorts self.f2s = gr.float_to_short() + + # Use file sink burst tagger to capture bursts self.fsnk = gr.tagged_file_sink(gr.sizeof_gr_complex, self.samp_rate) @@ -60,17 +86,12 @@ class uhd_burst_detector(gr.top_block): else: # Connect an energy detector signaler to the burst tagger - self.connect((self.uhd_src, 0), (self.c2m, 0)) - self.connect((self.c2m, 0), (self.sub, 0)) - self.connect((self.c2m, 0), (self.iir, 0)) - self.connect((self.iir, 0), (self.sub, 1)) - self.connect((self.sub, 0), (self.mult,0)) - self.connect((self.mult, 0), (self.f2s, 0)) - self.connect((self.f2s, 0), (self.tagger, 1)) + self.connect(self.uhd_src, self.det) + self.connect(self.det, self.c2m, self.avg, self.scale, self.f2s) + self.connect(self.f2s, (self.tagger, 1)) def set_samp_rate(self, samp_rate): self.samp_rate = samp_rate - self.wxgui_fftsink2_0.set_sample_rate(self.samp_rate/10) self.uhd_src_0.set_samp_rate(self.samp_rate) if __name__ == '__main__': @@ -83,16 +104,15 @@ if __name__ == '__main__': help="set frequency to FREQ", metavar="FREQ") parser.add_option("-g", "--gain", type="eng_float", default=0, help="set gain in dB [default=%default]") - parser.add_option("-R", "--rate", type="eng_float", default=200000, + parser.add_option("-R", "--samp-rate", type="eng_float", default=200000, help="set USRP sample rate [default=%default]") + parser.add_option("-t", "--threshold", type="float", default=-60, + help="Set the detection power threshold (dBm) [default=%default") parser.add_option("-T", "--trigger", action="store_true", default=False, help="Use internal trigger instead of detector [default=%default]") (options, args) = parser.parse_args() - frequency = options.freq - samp_rate = samp_rate = options.rate uhd_addr = options.address - trigger = options.trigger - tb = uhd_burst_detector(frequency, samp_rate, uhd_addr, trigger) + tb = uhd_burst_detector(uhd_addr, options) tb.run() diff --git a/gr-audio/lib/alsa/audio_alsa_source.cc b/gr-audio/lib/alsa/audio_alsa_source.cc index 4f0042b22..2f4506f71 100644 --- a/gr-audio/lib/alsa/audio_alsa_source.cc +++ b/gr-audio/lib/alsa/audio_alsa_source.cc @@ -217,8 +217,14 @@ audio_alsa_source::check_topology (int ninputs, int noutputs) unsigned int nchan = noutputs; int err; - // FIXME check_topology may be called more than once. + // Check the state of the stream // Ensure that the pcm is in a state where we can still mess with the hw_params + snd_pcm_state_t state; + state=snd_pcm_state(d_pcm_handle); + if ( state== SND_PCM_STATE_RUNNING) + return true; // If stream is running, don't change any parameters + else if(state == SND_PCM_STATE_XRUN ) + snd_pcm_prepare ( d_pcm_handle ); // Prepare stream on underrun, and we can set parameters; bool special_case = nchan == 1 && d_special_case_stereo_to_mono; if (special_case) diff --git a/gr-comedi/src/comedi_sink_s.cc b/gr-comedi/src/comedi_sink_s.cc index d4a668758..fc5c14931 100644 --- a/gr-comedi/src/comedi_sink_s.cc +++ b/gr-comedi/src/comedi_sink_s.cc @@ -88,7 +88,7 @@ comedi_sink_s::comedi_sink_s (int sampling_freq, comedi_cmd cmd; int ret; - ret = comedi_get_cmd_generic_timed(d_dev,d_subdevice,&cmd,(unsigned int)(1e9/sampling_freq)); + ret = comedi_get_cmd_generic_timed(d_dev,d_subdevice,&cmd,d_n_chan,(unsigned int)(1e9/sampling_freq)); if(ret<0) bail ("comedi_get_cmd_generic_timed", comedi_errno()); diff --git a/gr-comedi/src/comedi_source_s.cc b/gr-comedi/src/comedi_source_s.cc index a52d04e2a..5d9f2f6b0 100644 --- a/gr-comedi/src/comedi_source_s.cc +++ b/gr-comedi/src/comedi_source_s.cc @@ -85,7 +85,7 @@ comedi_source_s::comedi_source_s (int sampling_freq, comedi_cmd cmd; int ret; - ret = comedi_get_cmd_generic_timed(d_dev,d_subdevice,&cmd,(unsigned int)(1e9/sampling_freq)); + ret = comedi_get_cmd_generic_timed(d_dev,d_subdevice,&cmd,d_n_chan,(unsigned int)(1e9/sampling_freq)); if(ret<0) bail ("comedi_get_cmd_generic_timed", comedi_errno()); diff --git a/gr-cvsd-vocoder/src/lib/Makefile.am b/gr-cvsd-vocoder/src/lib/Makefile.am deleted file mode 100644 index 9c8c96b96..000000000 --- a/gr-cvsd-vocoder/src/lib/Makefile.am +++ /dev/null @@ -1,58 +0,0 @@ -# -# Copyright 2004,2005,2008,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. -# - -include $(top_srcdir)/Makefile.common -include $(top_srcdir)/Makefile.swig - -AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES) - -# These headers get installed in ${prefix}/include/gnuradio -grinclude_HEADERS = \ - cvsd_decode_bs.h \ - cvsd_encode_sb.h - -lib_LTLIBRARIES = libgnuradio-cvsd-vocoder.la - -libgnuradio_cvsd_vocoder_la_SOURCES = \ - cvsd_decode_bs.cc \ - cvsd_encode_sb.cc - -libgnuradio_cvsd_vocoder_la_LIBADD = \ - $(GNURADIO_CORE_LA) - -libgnuradio_cvsd_vocoder_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS) - -################################### -# SWIG interface and library - -TOP_SWIG_IFILES = \ - cvsd_vocoder.i - -# Install so that they end up available as: -# import gnuradio.vocoder.cvsd_vocoder -# This ends up at: -# ${prefix}/lib/python${python_version}/site-packages/gnuradio/vocoder -cvsd_vocoder_pythondir_category = \ - gnuradio/vocoder - -# additional libraries for linking with the SWIG-generated library -cvsd_vocoder_la_swig_libadd = \ - libgnuradio-cvsd-vocoder.la diff --git a/gr-cvsd-vocoder/src/lib/cvsd_vocoder.i b/gr-cvsd-vocoder/src/lib/cvsd_vocoder.i deleted file mode 100644 index 82662e84e..000000000 --- a/gr-cvsd-vocoder/src/lib/cvsd_vocoder.i +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- c++ -*- */ -/* - * Copyright 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. - */ - -%include "gnuradio.i" - -%{ -#include "cvsd_encode_sb.h" -#include "cvsd_decode_bs.h" -%} - -GR_SWIG_BLOCK_MAGIC(cvsd,encode_sb); - -cvsd_encode_sb_sptr cvsd_make_encode_sb (short min_step=10, - short max_step=1280, - double step_decay=0.9990234375, - double accum_decay= 0.96875, - int K=32, - int J=4, - short pos_accum_max=32767, - short neg_accum_max=-32767); - -class cvsd_encode_sb : public gr_sync_decimator -{ -private: - cvsd_encode_sb (short min_step, short max_step, double step_decay, - double accum_decay, int K, int J, - short pos_accum_max, short neg_accum_max); - - - public: - short min_step() { return d_min_step; } - short max_step() { return d_max_step; } - double step_decay() { return d_step_decay; } - double accum_decay() { return d_accum_decay; } - int K() { return d_K; } - int J() { return d_J; } - short pos_accum_max() { return d_pos_accum_max; } - short neg_accum_max() { return d_neg_accum_max; } -}; - -// ---------------------------------------------------------------- - -GR_SWIG_BLOCK_MAGIC(cvsd,decode_bs); - -cvsd_decode_bs_sptr cvsd_make_decode_bs (short min_step=10, - short max_step=1280, - double step_decay=0.9990234375, - double accum_decay= 0.96875, - int K=32, - int J=4, - short pos_accum_max=32767, - short neg_accum_max=-32767); - -class cvsd_decode_bs : public gr_sync_interpolator -{ -private: - cvsd_decode_bs (short min_step, short max_step, double step_decay, - double accum_decay, int K, int J, - short pos_accum_max, short neg_accum_max); - - public: -}; - -#if SWIGGUILE -%scheme %{ -(load-extension-global "libguile-gnuradio-cvsd_vocoder" "scm_init_gnuradio_cvsd_vocoder_module") -%} - -%goops %{ -(use-modules (gnuradio gnuradio_core_runtime)) -%} -#endif diff --git a/gr-digital/include/digital_constellation.h b/gr-digital/include/digital_constellation.h index 3e54e7d96..84f4814df 100644 --- a/gr-digital/include/digital_constellation.h +++ b/gr-digital/include/digital_constellation.h @@ -85,7 +85,7 @@ public: unsigned int dimensionality() {return d_dimensionality;} unsigned int bits_per_symbol () { - return floor(log(d_constellation.size())/d_dimensionality/log(2)); + return floor(log(double(d_constellation.size()))/d_dimensionality/log(2.0)); } unsigned int arity () { diff --git a/gr-digital/lib/digital_constellation.cc b/gr-digital/lib/digital_constellation.cc index 3dfc70273..0c100f38e 100644 --- a/gr-digital/lib/digital_constellation.cc +++ b/gr-digital/lib/digital_constellation.cc @@ -20,6 +20,10 @@ * Boston, MA 02110-1301, USA. */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <gr_io_signature.h> #include <digital_constellation.h> #include <digital_metric_type.h> diff --git a/gr-digital/python/__init__.py b/gr-digital/python/__init__.py index 7173fa09d..b8060140e 100644 --- a/gr-digital/python/__init__.py +++ b/gr-digital/python/__init__.py @@ -26,7 +26,13 @@ from psk2 import * from bpsk import * from qpsk import * from qam import * +<<<<<<< HEAD from gmsk import * from pkt import * from packet_utils import * from crc import * +======= +from ofdm import * +from pkt import * +from modulation_utils2 import * +>>>>>>> next diff --git a/gr-digital/python/ofdm.py b/gr-digital/python/ofdm.py new file mode 100644 index 000000000..e05f074f4 --- /dev/null +++ b/gr-digital/python/ofdm.py @@ -0,0 +1,295 @@ +#!/usr/bin/env python +# +# Copyright 2006,2007,2008 Free Software Foundation, Inc. +# +# This file is part of GNU Radio +# +# GNU Radio is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3, or (at your option) +# any later version. +# +# GNU Radio is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Radio; see the file COPYING. If not, write to +# the Free Software Foundation, Inc., 51 Franklin Street, +# Boston, MA 02110-1301, USA. +# + +import math +from gnuradio import gr, 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()) + print dir(modulation_utils2) + print "MODS LIST: ", mods_list + print modulation_utils2.type_1_mods() + normal.add_option("-m", "--modulation", type="string", default="psk", + help="set modulation type (" + mods_list + ") [default=%default]") + normal.add_option("-c", "--constellation-points", type="int", default=2, + help="set number of constellation points [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 +# ///////////////////////////////////////////////////////////////////////////// + +class ofdm_mod(gr.hier_block2): + """ + Modulates an OFDM stream. Based on the options fft_length, occupied_tones, and + cp_length, this block creates OFDM symbols using a specified modulation option. + + Send packets by calling send_pkt + """ + def __init__(self, options, msgq_limit=2, pad_for_usrp=True): + """ + 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 options: pass modulation options from higher layers (fft length, occupied tones, etc.) + @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 + """ + + gr.hier_block2.__init__(self, "ofdm_mod", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + + self._pad_for_usrp = pad_for_usrp + self._modulation = options.modulation + self._fft_length = options.fft_length + self._occupied_tones = options.occupied_tones + self._cp_length = options.cp_length + + print (options) + arity = options.constellation_points + + win = [] #[1 for i in range(self._fft_length)] + + # 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] + for i in range(len(ksfreq)): + if((zeros_on_left + i) & 1): + ksfreq[i] = 0 + + # hard-coded known symbols + preambles = (ksfreq,) + + padded_preambles = list() + for pre in preambles: + padded = self._fft_length*[0,] + padded[zeros_on_left : zeros_on_left + self._occupied_tones] = pre + padded_preambles.append(padded) + + symbol_length = options.fft_length + options.cp_length + + print modulation_utils2.type_1_constellations + 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) + self.ifft = gr.fft_vcc(self._fft_length, False, win, True) + self.cp_adder = gr.ofdm_cyclic_prefixer(self._fft_length, symbol_length) + self.scale = gr.multiply_const_cc(1.0 / math.sqrt(self._fft_length)) + + self.connect((self._pkt_input, 0), (self.preambles, 0)) + self.connect((self._pkt_input, 1), (self.preambles, 1)) + self.connect(self.preambles, self.ifft, self.cp_adder, self.scale, self) + + if options.verbose: + self._print_verbage() + + if options.log: + self.connect(self._pkt_input, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, + "ofdm_mapper_c.dat")) + self.connect(self.preambles, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, + "ofdm_preambles.dat")) + self.connect(self.ifft, gr.file_sink(gr.sizeof_gr_complex*options.fft_length, + "ofdm_ifft_c.dat")) + self.connect(self.cp_adder, gr.file_sink(gr.sizeof_gr_complex, + "ofdm_cp_adder_c.dat")) + + 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 = ofdm_packet_utils.make_packet(payload, 1, 1, self._pad_for_usrp, whitening=True) + + #print "pkt =", string_to_hex_list(pkt) + msg = gr.message_from_string(pkt) + self._pkt_input.msgq().insert_tail(msg) + + def add_options(normal, expert): + """ + Adds OFDM-specific options to the Options Parser + """ + _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) + + def _print_verbage(self): + """ + Prints information about the OFDM modulator + """ + print "\nOFDM Modulator:" + print "Modulation Type: %s" % (self._modulation) + print "FFT length: %3d" % (self._fft_length) + print "Occupied Tones: %3d" % (self._occupied_tones) + print "CP length: %3d" % (self._cp_length) + + +class ofdm_demod(gr.hier_block2): + """ + Demodulates a received OFDM stream. Based on the options fft_length, occupied_tones, and + cp_length, this block performs synchronization, FFT, and demodulation of incoming OFDM + symbols and passes packets up the a higher layer. + + The input is complex baseband. When packets are demodulated, they are passed to the + app via the callback. + """ + + def __init__(self, options, callback=None): + """ + Hierarchical block for demodulating and deframing packets. + + The input is the complex modulated signal at baseband. + Demodulated packets are sent to the handler. + + @param options: pass modulation options from higher layers (fft length, occupied tones, etc.) + @param callback: function of two args: ok, payload + @type callback: ok: bool; payload: string + """ + gr.hier_block2.__init__(self, "ofdm_demod", + gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature + + + self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY + + self._modulation = options.modulation + self._fft_length = options.fft_length + self._occupied_tones = options.occupied_tones + 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] + for i in range(len(ksfreq)): + if((zeros_on_left + i) & 1): + ksfreq[i] = 0 + + # hard-coded known symbols + preambles = (ksfreq,) + + symbol_length = self._fft_length + self._cp_length + self.ofdm_recv = ofdm_receiver(self._fft_length, self._cp_length, + self._occupied_tones, self._snr, preambles, + options.log) + + constell = modulation_utils2.type_1_constellations()[self._modulation](arity) + + phgain = 0.25 + frgain = phgain*phgain / 4.0 + self.ofdm_demod = gr.ofdm_frame_sink2(constell.base(), + self._rcvd_pktq, + self._occupied_tones, + phgain, frgain) + + self.connect(self, self.ofdm_recv) + self.connect((self.ofdm_recv, 0), (self.ofdm_demod, 0)) + self.connect((self.ofdm_recv, 1), (self.ofdm_demod, 1)) + + # added output signature to work around bug, though it might not be a bad + # thing to export, anyway + self.connect(self.ofdm_recv.chan_filt, self) + + if options.log: + self.connect(self.ofdm_demod, gr.file_sink(gr.sizeof_gr_complex*self._occupied_tones, "ofdm_frame_sink_c.dat")) + else: + self.connect(self.ofdm_demod, gr.null_sink(gr.sizeof_gr_complex*self._occupied_tones)) + + if options.verbose: + self._print_verbage() + + self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback) + + def add_options(normal, expert): + """ + Adds OFDM-specific options to the Options Parser + """ + _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) + + def _print_verbage(self): + """ + Prints information about the OFDM demodulator + """ + print "\nOFDM Demodulator:" + print "Modulation Type: %s" % (self._modulation) + print "FFT length: %3d" % (self._fft_length) + print "Occupied Tones: %3d" % (self._occupied_tones) + print "CP length: %3d" % (self._cp_length) + + + +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 = ofdm_packet_utils.unmake_packet(msg.to_string()) + if self.callback: + self.callback(ok, payload) + +# Generating known symbols with: +# i = [2*random.randint(0,1)-1 for i in range(4512)] + +known_symbols_4512_3 = [-1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1] diff --git a/gr-digital/python/pkt.py b/gr-digital/python/pkt.py index c9b29bd51..8650bdbb0 100644 --- a/gr-digital/python/pkt.py +++ b/gr-digital/python/pkt.py @@ -52,18 +52,13 @@ class mod_pkts(gr.hier_block2): @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 - @param modulate: If false, no modulation will be performed. See gmsk_mod for remaining parameters """ - if modulate: - output_size = gr.sizeof_gr_complex - else: - output_size = gr.sizeof_char gr.hier_block2.__init__(self, "mod_pkts", gr.io_signature(0, 0, 0), # Input signature - gr.io_signature(1, 1, output_size)) # Output signature + gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._modulator = modulator self._pad_for_usrp = pad_for_usrp @@ -78,10 +73,7 @@ class mod_pkts(gr.hier_block2): # accepts messages from the outside world self._pkt_input = gr.message_source(gr.sizeof_char, msgq_limit) - if modulate: - self.connect(self._pkt_input, self._modulator, self) - else: - self.connect(self._pkt_input, self) + self.connect(self._pkt_input, self._modulator, self) def send_pkt(self, payload='', eof=False): """ @@ -117,15 +109,13 @@ class demod_pkts(gr.hier_block2): app via the callback. """ - def __init__(self, demodulator, access_code=None, callback=None, threshold=-1, demodulate=True): + 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. - If demodulator is None it is assumed the input is already demodulated. - @param demodulator: instance of demodulator class (gr_block or hier_block2) @type demodulator: complex baseband in @param access_code: AKA sync vector @@ -136,14 +126,9 @@ class demod_pkts(gr.hier_block2): @type threshold: int """ - if demodulator is not None: - input_size = gr.sizeof_gr_complex - else: - input_size = gr.sizeof_char - gr.hier_block2.__init__(self, "demod_pkts", - gr.io_signature(1, 1, input_size), # Input signature - gr.io_signature(0, 0, 0)) # Output signature + 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: @@ -159,13 +144,9 @@ class demod_pkts(gr.hier_block2): self.correlator = digital_swig.correlate_access_code_bb(access_code, threshold) self.framer_sink = gr.framer_sink_1(self._rcvd_pktq) - if self._demodulator is not None: - self.connect(self, self._demodulator, self.correlator, self.framer_sink) - else: - self.connect(self, self.correlator, self.framer_sink) + self.connect(self, self._demodulator, self.correlator, self.framer_sink) - if callback is not None: - self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback) + self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback) class _queue_watcher_thread(_threading.Thread): diff --git a/gr-gsm-fr-vocoder/gnuradio-gsm-fr-vocoder.pc.in b/gr-gsm-fr-vocoder/gnuradio-gsm-fr-vocoder.pc.in deleted file mode 100644 index a799fcd82..000000000 --- a/gr-gsm-fr-vocoder/gnuradio-gsm-fr-vocoder.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: gnuradio-comedi -Description: GNU Radio blocks implementing a GSM full rate vocoder -Requires: gnuradio-core -Version: @LIBVER@ -Libs: -L${libdir} -lgnuradio-gsm-fr-vocoder-$@LIBVER@ -Cflags: -I${includedir} diff --git a/gr-gsm-fr-vocoder/src/.gitignore b/gr-gsm-fr-vocoder/src/.gitignore deleted file mode 100644 index bb3f27777..000000000 --- a/gr-gsm-fr-vocoder/src/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/howto.cc -/howto.py diff --git a/gr-gsm-fr-vocoder/src/lib/.gitignore b/gr-gsm-fr-vocoder/src/lib/.gitignore deleted file mode 100644 index 5cf6fde83..000000000 --- a/gr-gsm-fr-vocoder/src/lib/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo -/gsm_full_rate.py -/gsm_full_rate.cc -/*.pyc -/gnuradio -/guile -/python diff --git a/gr-gsm-fr-vocoder/src/lib/Makefile.am b/gr-gsm-fr-vocoder/src/lib/Makefile.am deleted file mode 100644 index 4ce65bc31..000000000 --- a/gr-gsm-fr-vocoder/src/lib/Makefile.am +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright 2004,2005,2008,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. -# - -include $(top_srcdir)/Makefile.common -include $(top_srcdir)/Makefile.swig - -SUBDIRS = gsm . - -AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES) - -# C/C++ headers get installed in ${prefix}/include/gnuradio -grinclude_HEADERS = \ - gsm_fr_decode_ps.h \ - gsm_fr_encode_sp.h - -lib_LTLIBRARIES = libgnuradio-gsm-fr-vocoder.la - -libgnuradio_gsm_fr_vocoder_la_SOURCES = \ - gsm_fr_decode_ps.cc \ - gsm_fr_encode_sp.cc - -libgnuradio_gsm_fr_vocoder_la_LIBADD = \ - $(GNURADIO_CORE_LA) \ - gsm/libgsm.la - -libgnuradio_gsm_fr_vocoder_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS) - - -# SWIG interface and library -TOP_SWIG_IFILES = \ - gsm_full_rate.i - -# Install so that they end up available as: -# import gnuradio.vocoder.gsm_full_rate -# This ends up at: -# ${prefix}/lib/python${python_version}/site-packages/gnuradio/vocoder -gsm_full_rate_pythondir_category = \ - gnuradio/vocoder - -# additional libraries for linking with the SWIG-generated library -gsm_full_rate_la_swig_libadd = \ - libgnuradio-gsm-fr-vocoder.la - diff --git a/gr-gsm-fr-vocoder/src/lib/Makefile.swig.gen b/gr-gsm-fr-vocoder/src/lib/Makefile.swig.gen deleted file mode 100644 index 174ef046d..000000000 --- a/gr-gsm-fr-vocoder/src/lib/Makefile.swig.gen +++ /dev/null @@ -1,145 +0,0 @@ -# -*- Makefile -*- -# -# 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. -# - -# Makefile.swig.gen for gsm_full_rate.i - -## Default install locations for these files: -## -## Default location for the Python directory is: -## ${prefix}/lib/python${python_version}/site-packages/[category]/gsm_full_rate -## Default location for the Python exec directory is: -## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/gsm_full_rate -## -## 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. - -gsm_full_rate_pythondir_category ?= gnuradio/gsm_full_rate -gsm_full_rate_pylibdir_category ?= $(gsm_full_rate_pythondir_category) -gsm_full_rate_pythondir = $(pythondir)/$(gsm_full_rate_pythondir_category) -gsm_full_rate_pylibdir = $(pyexecdir)/$(gsm_full_rate_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. -gsm_full_rate_scmlibdir = $(libdir) - -# The scm files for the guile modules get installed where ever guile -# is installed, usually /usr/share/guile/site/gsm_full_rate -# FIXME: determince whether these should be installed with gnuradio. -gsm_full_rate_scmdir = $(guiledir) - -## SWIG headers are always installed into the same directory. - -gsm_full_rate_swigincludedir = $(swigincludedir) - -## This is a template file for a "generated" Makefile addition (in -## this case, "Makefile.swig.gen"). By including the top-level -## Makefile.swig, this file will be used to generate the SWIG -## dependencies. Assign the variable TOP_SWIG_FILES to be the list of -## SWIG .i files to generated wrappings for; there can be more than 1 -## so long as the names are unique (no sorting is done on the -## TOP_SWIG_FILES list). This file explicitly assumes that a SWIG .i -## file will generate .cc, .py, and possibly .h files -- meaning that -## all of these files will have the same base name (that provided for -## the SWIG .i file). -## -## This code is setup to ensure parallel MAKE ("-j" or "-jN") does the -## right thing. For more info, see < -## http://sources.redhat.com/automake/automake.html#Multiple-Outputs > - -## Other cleaned files: dependency files generated by SWIG or this Makefile - -MOSTLYCLEANFILES += $(DEPDIR)/*.S* - -## Various SWIG variables. These can be overloaded in the including -## Makefile.am by setting the variable value there, then including -## Makefile.swig . - -gsm_full_rate_swiginclude_HEADERS = \ - gsm_full_rate.i \ - $(gsm_full_rate_swiginclude_headers) - -if PYTHON -gsm_full_rate_pylib_LTLIBRARIES = \ - _gsm_full_rate.la - -_gsm_full_rate_la_SOURCES = \ - python/gsm_full_rate.cc \ - $(gsm_full_rate_la_swig_sources) - -gsm_full_rate_python_PYTHON = \ - gsm_full_rate.py \ - $(gsm_full_rate_python) - -_gsm_full_rate_la_LIBADD = \ - $(STD_SWIG_LA_LIB_ADD) \ - $(gsm_full_rate_la_swig_libadd) - -_gsm_full_rate_la_LDFLAGS = \ - $(STD_SWIG_LA_LD_FLAGS) \ - $(gsm_full_rate_la_swig_ldflags) - -_gsm_full_rate_la_CXXFLAGS = \ - $(STD_SWIG_CXX_FLAGS) \ - -I$(top_builddir) \ - $(gsm_full_rate_la_swig_cxxflags) - -python/gsm_full_rate.cc: gsm_full_rate.py -gsm_full_rate.py: gsm_full_rate.i - -# Include the python dependencies for this file --include python/gsm_full_rate.d - -endif # end of if python - -if GUILE - -gsm_full_rate_scmlib_LTLIBRARIES = \ - libguile-gnuradio-gsm_full_rate.la -libguile_gnuradio_gsm_full_rate_la_SOURCES = \ - guile/gsm_full_rate.cc \ - $(gsm_full_rate_la_swig_sources) -nobase_gsm_full_rate_scm_DATA = \ - gnuradio/gsm_full_rate.scm \ - gnuradio/gsm_full_rate-primitive.scm -libguile_gnuradio_gsm_full_rate_la_LIBADD = \ - $(STD_SWIG_LA_LIB_ADD) \ - $(gsm_full_rate_la_swig_libadd) -libguile_gnuradio_gsm_full_rate_la_LDFLAGS = \ - $(STD_SWIG_LA_LD_FLAGS) \ - $(gsm_full_rate_la_swig_ldflags) -libguile_gnuradio_gsm_full_rate_la_CXXFLAGS = \ - $(STD_SWIG_CXX_FLAGS) \ - -I$(top_builddir) \ - $(gsm_full_rate_la_swig_cxxflags) - -guile/gsm_full_rate.cc: gnuradio/gsm_full_rate.scm -gnuradio/gsm_full_rate.scm: gsm_full_rate.i -gnuradio/gsm_full_rate-primitive.scm: gnuradio/gsm_full_rate.scm - -# Include the guile dependencies for this file --include guile/gsm_full_rate.d - -endif # end of GUILE - - diff --git a/gr-gsm-fr-vocoder/src/python/run_tests.in b/gr-gsm-fr-vocoder/src/python/run_tests.in deleted file mode 100644 index 96eefc559..000000000 --- a/gr-gsm-fr-vocoder/src/python/run_tests.in +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# 1st parameter is absolute path to component source directory -# 2nd parameter is absolute path to component build directory -# 3rd parameter is path to Python QA directory - -@top_builddir@/run_tests.sh \ - @abs_top_srcdir@/gr-gsm-fr-vocoder \ - @abs_top_builddir@/gr-gsm-fr-vocoder \ - @srcdir@ diff --git a/gr-noaa/lib/noaa_hrpt_pll_cf.cc b/gr-noaa/lib/noaa_hrpt_pll_cf.cc index 08ab1d15f..ba2ce98d5 100644 --- a/gr-noaa/lib/noaa_hrpt_pll_cf.cc +++ b/gr-noaa/lib/noaa_hrpt_pll_cf.cc @@ -67,15 +67,16 @@ noaa_hrpt_pll_cf::work(int noutput_items, for (int i = 0; i < noutput_items; i++) { + // Generate and mix out carrier + float re, im; + gr_sincosf(d_phase, &im, &re); + out[i] = (in[i]*gr_complex(re, -im)).imag(); + // Adjust PLL phase/frequency float error = phase_wrap(gr_fast_atan2f(in[i].imag(), in[i].real()) - d_phase); d_freq = gr_branchless_clip(d_freq + error*d_beta, d_max_offset); d_phase = phase_wrap(d_phase + error*d_alpha + d_freq); - // Generate and mix out carrier - float re, im; - gr_sincosf(d_phase, &im, &re); - out[i] = (in[i]*gr_complex(re, -im)).imag(); } return noutput_items; diff --git a/gr-pager/lib/pager_flex_sync.cc b/gr-pager/lib/pager_flex_sync.cc index 61cf4ad38..30666298f 100644 --- a/gr-pager/lib/pager_flex_sync.cc +++ b/gr-pager/lib/pager_flex_sync.cc @@ -274,7 +274,7 @@ int pager_flex_sync::general_work(int noutput_items, while (i < ninputs && j < noutput_items) { unsigned char sym = *in++; i++; - d_index = ++d_index % d_spb; + d_index = (d_index+1) % d_spb; switch (d_state) { case ST_IDLE: diff --git a/gr-qtgui/Makefile.am b/gr-qtgui/Makefile.am index cc194e4c0..38033e1ac 100644 --- a/gr-qtgui/Makefile.am +++ b/gr-qtgui/Makefile.am @@ -24,7 +24,7 @@ include $(top_srcdir)/Makefile.common SUBDIRS = lib if PYTHON -SUBDIRS += swig python apps grc +SUBDIRS += swig python apps grc examples endif pkgconfigdir = $(libdir)/pkgconfig diff --git a/gr-qtgui/apps/Makefile.am b/gr-qtgui/apps/Makefile.am index 7b35d949e..4d0c550a1 100644 --- a/gr-qtgui/apps/Makefile.am +++ b/gr-qtgui/apps/Makefile.am @@ -28,13 +28,9 @@ nodist_bin_SCRIPTS = \ usrp_display_qtgui.ui noinst_PYTHON = \ - pyqt_example_f.py \ - pyqt_example_c.py \ - pyqt_time_c.py \ qt_digital.py \ qt_digital_window.py \ - usrp2_display.py \ - usrp_display.py \ + uhd_display.py \ qt_digital_window.py \ usrp_display_qtgui.py diff --git a/gr-qtgui/apps/qt_digital.py b/gr-qtgui/apps/qt_digital.py index 99c799f2a..2bc039a31 100755 --- a/gr-qtgui/apps/qt_digital.py +++ b/gr-qtgui/apps/qt_digital.py @@ -1,11 +1,42 @@ #!/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, blks2 -from gnuradio import qtgui from gnuradio import eng_notation -from PyQt4 import QtGui, QtCore -import sys, sip -import scipy +import sys + +try: + from gnuradio import qtgui + from PyQt4 import QtGui, QtCore + import sip +except ImportError: + print "Error: Program requires PyQt4 and gr-qtgui." + sys.exit(1) + +try: + import scipy +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) try: from qt_digital_window import Ui_DigitalWindow diff --git a/gr-qtgui/apps/usrp2_display.py b/gr-qtgui/apps/uhd_display.py index ab1a6f742..806914797 100755 --- a/gr-qtgui/apps/usrp2_display.py +++ b/gr-qtgui/apps/uhd_display.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2009 Free Software Foundation, Inc. +# Copyright 2009,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,7 +21,7 @@ # from gnuradio import gr -from gnuradio import usrp2 +from gnuradio import uhd from gnuradio import eng_notation from gnuradio.eng_option import eng_option from gnuradio.qtgui import qtgui @@ -33,7 +33,7 @@ try: from PyQt4 import QtGui, QtCore import sip except ImportError: - print "Please install gr-qtgui." + print "Error: Program requires PyQt4 and gr-qtgui." sys.exit(1) try: @@ -163,53 +163,40 @@ class main_window(QtGui.QMainWindow): class my_top_block(gr.top_block): - def __init__(self): + def __init__(self, options): gr.top_block.__init__(self) - parser = OptionParser(option_class=eng_option) - parser.add_option("-e", "--interface", type="string", default="eth0", - help="select Ethernet interface, default is eth0") - parser.add_option("-m", "--mac-addr", type="string", default="", - help="select USRP by MAC address, default is auto-select") - parser.add_option("-W", "--bw", type="eng_float", default=1e6, - help="set bandwidth of receiver [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=2412e6, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - parser.add_option("--fft-size", type="int", default=2048, - help="Set number of FFT bins [default=%default]") - (options, args) = parser.parse_args() - - if len(args) != 0: - parser.print_help() - sys.exit(1) - self.options = options + self.options = options self.show_debug_info = True self.qapp = QtGui.QApplication(sys.argv) - self.u = usrp2.source_32fc(options.interface, options.mac_addr) - self._adc_rate = self.u.adc_rate() - self.set_bandwidth(options.bw) + self.u = uhd.usrp_source(device_addr=options.address, + io_type=uhd.io_type.COMPLEX_FLOAT32, + num_channels=1) + self.set_bandwidth(options.samp_rate) if options.gain is None: # if no gain was specified, use the mid-point in dB - g = self.u.gain_range() - options.gain = float(g[0]+g[1])/2 + g = self.u.get_gain_range() + options.gain = float(g.start()+g.stop())/2 self.set_gain(options.gain) if options.freq is None: - # if no frequency was specified, use the mid-point of the subdev - f = self.u.freq_range() - options.freq = float(f[0]+f[1])/2 + # if no freq was specified, use the mid-point + r = self.u.get_freq_range() + options.freq = float(r.start()+r.stop())/2 self.set_frequency(options.freq) + if(options.antenna): + self.u.set_antenna(options.antenna, 0) + self._fftsize = options.fft_size - self.snk = qtgui.sink_c(options.fft_size, gr.firdes.WIN_BLACKMAN_hARRIS, + self.snk = qtgui.sink_c(options.fft_size, + gr.firdes.WIN_BLACKMAN_hARRIS, self._freq, self._bandwidth, - "USRP2 Display", + "UHD Display", True, True, True, False) # Set up internal amplifier @@ -225,9 +212,9 @@ class my_top_block(gr.top_block): self.connect(self.u, self.amp, self.snk) if self.show_debug_info: - print "Decimation rate: ", self._decim - print "Bandwidth: ", self._bandwidth - print "D'board: ", self.u.daughterboard_id() + print "Bandwidth: ", self.u.get_samp_rate() + print "Center Freq: ", self.u.get_center_freq() + print "Freq Range: ", self.u.get_freq_range() # Get the reference pointer to the SpectrumDisplayForm QWidget # Wrap the pointer as a PyQt SIP object @@ -268,8 +255,7 @@ class my_top_block(gr.top_block): def set_bandwidth(self, bw): self._bandwidth = bw - self._decim = int(self._adc_rate / self._bandwidth) - self.u.set_decim(self._decim) + self.u.set_samp_rate(self._bandwidth) try: self.snk.set_frequency_range(self._freq, self._bandwidth) @@ -301,7 +287,26 @@ class my_top_block(gr.top_block): self.unlock() def main (): - tb = my_top_block() + parser = OptionParser(option_class=eng_option) + parser.add_option("-a", "--address", type="string", default="addr=192.168.10.2", + help="Address of UHD device, [default=%default]") + parser.add_option("-A", "--antenna", type="string", default=None, + help="select Rx Antenna where appropriate") + parser.add_option("-s", "--samp-rate", type="eng_float", default=1e6, + help="set sample rate (bandwidth) [default=%default]") + parser.add_option("-f", "--freq", type="eng_float", default=2412e6, + help="set frequency to FREQ", metavar="FREQ") + parser.add_option("-g", "--gain", type="eng_float", default=None, + help="set gain in dB (default is midpoint)") + parser.add_option("--fft-size", type="int", default=2048, + help="Set number of FFT bins [default=%default]") + (options, args) = parser.parse_args() + + if len(args) != 0: + parser.print_help() + sys.exit(1) + + tb = my_top_block(options) tb.start() tb.snk.exec_(); diff --git a/gr-qtgui/apps/usrp_display.py b/gr-qtgui/apps/usrp_display.py deleted file mode 100755 index 131bc4a7e..000000000 --- a/gr-qtgui/apps/usrp_display.py +++ /dev/null @@ -1,299 +0,0 @@ -#!/usr/bin/env python -# -# 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. -# - -from gnuradio import gr -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.qtgui import qtgui -from optparse import OptionParser -import sys - -try: - from gnuradio.qtgui import qtgui - from PyQt4 import QtGui, QtCore - import sip -except ImportError: - print "Please install gr-qtgui." - sys.exit(1) - -try: - from usrp_display_qtgui import Ui_MainWindow -except ImportError: - print "Error: could not find usrp_display_qtgui.py:" - print "\t\"pyuic4 usrp_display_qtgui.ui -o usrp_display_qtgui.py\"" - sys.exit(1) - - - -# //////////////////////////////////////////////////////////////////// -# Define the QT Interface and Control Dialog -# //////////////////////////////////////////////////////////////////// - - -class main_window(QtGui.QMainWindow): - def __init__(self, snk, fg, parent=None): - - QtGui.QWidget.__init__(self, parent) - self.gui = Ui_MainWindow() - self.gui.setupUi(self) - - self.fg = fg - - # Add the qtsnk widgets to the layout box - self.gui.sinkLayout.addWidget(snk) - - # Connect up some signals - self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"), - self.pauseFg) - self.connect(self.gui.frequencyEdit, QtCore.SIGNAL("editingFinished()"), - self.frequencyEditText) - self.connect(self.gui.gainEdit, QtCore.SIGNAL("editingFinished()"), - self.gainEditText) - self.connect(self.gui.bandwidthEdit, QtCore.SIGNAL("editingFinished()"), - self.bandwidthEditText) - self.connect(self.gui.amplifierEdit, QtCore.SIGNAL("editingFinished()"), - self.amplifierEditText) - - self.connect(self.gui.actionSaveData, QtCore.SIGNAL("activated()"), - self.saveData) - self.gui.actionSaveData.setShortcut(QtGui.QKeySequence.Save) - - def pauseFg(self): - if(self.gui.pauseButton.text() == "Pause"): - self.fg.stop() - self.fg.wait() - self.gui.pauseButton.setText("Unpause") - else: - self.fg.start() - self.gui.pauseButton.setText("Pause") - - - # Functions to set the values in the GUI - def set_frequency(self, freq): - self.freq = freq - sfreq = eng_notation.num_to_str(self.freq) - self.gui.frequencyEdit.setText(QtCore.QString("%1").arg(sfreq)) - - def set_gain(self, gain): - self.gain = gain - self.gui.gainEdit.setText(QtCore.QString("%1").arg(self.gain)) - - def set_bandwidth(self, bw): - self.bw = bw - sbw = eng_notation.num_to_str(self.bw) - self.gui.bandwidthEdit.setText(QtCore.QString("%1").arg(sbw)) - - def set_amplifier(self, amp): - self.amp = amp - self.gui.amplifierEdit.setText(QtCore.QString("%1").arg(self.amp)) - - - # Functions called when signals are triggered in the GUI - def frequencyEditText(self): - try: - freq = eng_notation.str_to_num(self.gui.frequencyEdit.text().toAscii()) - self.fg.set_frequency(freq) - self.freq = freq - except RuntimeError: - pass - - def gainEditText(self): - try: - gain = float(self.gui.gainEdit.text()) - self.fg.set_gain(gain) - self.gain = gain - except ValueError: - pass - - def bandwidthEditText(self): - try: - bw = eng_notation.str_to_num(self.gui.bandwidthEdit.text().toAscii()) - self.fg.set_bandwidth(bw) - self.bw = bw - except ValueError: - pass - - def amplifierEditText(self): - try: - amp = float(self.gui.amplifierEdit.text()) - self.fg.set_amplifier_gain(amp) - self.amp = amp - except ValueError: - pass - - def saveData(self): - fileName = QtGui.QFileDialog.getSaveFileName(self, "Save data to file", "."); - if(len(fileName)): - self.fg.save_to_file(str(fileName)) - - -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - If there's a daughterboard on A, select A. - If there's a daughterboard on B, select B. - Otherwise, select A. - """ - if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem - return (0, 0) - if u.db(0, 0).dbid() >= 0: - return (1, 0) - return (0, 0) - -class my_top_block(gr.top_block): - def __init__(self): - gr.top_block.__init__(self) - - parser = OptionParser(option_class=eng_option) - parser.add_option("-w", "--which", type="int", default=0, - help="select which USRP (0, 1, ...) default is %default", - metavar="NUM") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=first one with a daughterboard)") - parser.add_option("-A", "--antenna", default=None, - help="select Rx Antenna (only on RFX-series boards)") - parser.add_option("-W", "--bw", type="float", default=1e6, - help="set bandwidth of receiver [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB [default is midpoint]") - parser.add_option("-8", "--width-8", action="store_true", default=False, - help="Enable 8-bit samples across USB") - parser.add_option( "--no-hb", action="store_true", default=False, - help="don't use halfband filter in usrp") - parser.add_option("-S", "--oscilloscope", action="store_true", default=False, - help="Enable oscilloscope display") - parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1, - help="Set fftsink averaging factor, [default=%default]") - parser.add_option("", "--ref-scale", type="eng_float", default=13490.0, - help="Set dBFS=0dB input value, [default=%default]") - parser.add_option("", "--fft-size", type="int", default=2048, - help="Set FFT frame size, [default=%default]"); - - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - self.options = options - self.show_debug_info = True - - # Call this before creating the Qt sink - self.qapp = QtGui.QApplication(sys.argv) - - self._fftsize = options.fft_size - - self.u = usrp.source_c(which=options.which) - self._adc_rate = self.u.converter_rate() - self.set_bandwidth(options.bw) - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - self._rx_subdev_spec = options.rx_subdev_spec - self.u.set_mux(usrp.determine_rx_mux_value(self.u, self._rx_subdev_spec)) - self.subdev = usrp.selected_subdev(self.u, self._rx_subdev_spec) - - self._gain_range = self.subdev.gain_range() - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self._gain_range - options.gain = float(g[0]+g[1])/2 - self.set_gain(options.gain) - - if options.freq is None: - # if no frequency was specified, use the mid-point of the subdev - f = self.subdev.freq_range() - options.freq = float(f[0]+f[1])/2 - self.set_frequency(options.freq) - - self.snk = qtgui.sink_c(self._fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, - self._freq, self._bandwidth, - "USRP Display", - True, True, True, False) - - # Set up internal amplifier - self.amp = gr.multiply_const_cc(0.0) - self.set_amplifier_gain(0.001) - - # Connect the flow graph - self.connect(self.u, self.amp, self.snk) - - - # Get the reference pointer to the SpectrumDisplayForm QWidget - # Wrap the pointer as a PyQt SIP object - # This can now be manipulated as a PyQt4.QtGui.QWidget - self.pysink = sip.wrapinstance(self.snk.pyqwidget(), QtGui.QWidget) - - self.main_win = main_window(self.pysink, self) - - self.main_win.set_frequency(self._freq) - self.main_win.set_gain(self._gain) - self.main_win.set_bandwidth(self._bandwidth) - self.main_win.set_amplifier(self._amp_value) - - self.main_win.show() - - def save_to_file(self, name): - # Pause the flow graph - self.stop() - self.wait() - - # Add file sink to save data - self.file_sink = gr.file_sink(gr.sizeof_gr_complex, name) - self.connect(self.amp, self.file_sink) - - # Restart flow graph - self.start() - - def set_gain(self, gain): - self._gain = gain - self.subdev.set_gain(self._gain) - - def set_frequency(self, freq): - self._freq = freq - self.u.tune(0, self.subdev, self._freq) - - try: - self.snk.set_frequency_range(self._freq, self._bandwidth) - except: - pass - - def set_bandwidth(self, bw): - self._bandwidth = bw - self._decim = int(self._adc_rate / self._bandwidth) - self.u.set_decim_rate(self._decim) - - try: - self.snk.set_frequency_range(self._freq, self._bandwidth) - except: - pass - - def set_amplifier_gain(self, amp): - self._amp_value = amp - self.amp.set_k(self._amp_value) - - -if __name__ == "__main__": - tb = my_top_block(); - tb.start() - tb.qapp.exec_() diff --git a/gr-cvsd-vocoder/src/python/.gitignore b/gr-qtgui/examples/.gitignore index 604b402c5..b336cc7ce 100644 --- a/gr-cvsd-vocoder/src/python/.gitignore +++ b/gr-qtgui/examples/.gitignore @@ -1,3 +1,2 @@ /Makefile /Makefile.in -/run_tests diff --git a/gr-gsm-fr-vocoder/src/python/Makefile.am b/gr-qtgui/examples/Makefile.am index 8a97395ee..a204d1fcc 100644 --- a/gr-gsm-fr-vocoder/src/python/Makefile.am +++ b/gr-qtgui/examples/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004 Free Software Foundation, Inc. +# Copyright 2008-2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,10 +21,14 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST += run_tests.in +if PYTHON +ourdatadir = $(exampledir)/qt-gui -TESTS = run_tests +dist_ourdata_SCRIPTS = \ + pyqt_example_c.py \ + pyqt_example_f.py \ + pyqt_time_c.py \ + pyqt_time_f.py +endif -noinst_PYTHON = \ - encdec.py \ - qa_gsm_full_rate.py +EXTRA_DIST += diff --git a/gr-qtgui/apps/pyqt_example_c.py b/gr-qtgui/examples/pyqt_example_c.py index 607ab12ee..553d346c9 100755 --- a/gr-qtgui/apps/pyqt_example_c.py +++ b/gr-qtgui/examples/pyqt_example_c.py @@ -1,9 +1,35 @@ #!/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 -from gnuradio import qtgui -from PyQt4 import QtGui, QtCore -import sys, sip +import sys + +try: + from gnuradio import qtgui + from PyQt4 import QtGui, QtCore + import sip +except ImportError: + print "Error: Program requires PyQt4 and gr-qtgui." + sys.exit(1) class dialog_box(QtGui.QWidget): def __init__(self, display, control): diff --git a/gr-qtgui/apps/pyqt_example_f.py b/gr-qtgui/examples/pyqt_example_f.py index 2d957c85a..5e432fe78 100755 --- a/gr-qtgui/apps/pyqt_example_f.py +++ b/gr-qtgui/examples/pyqt_example_f.py @@ -1,9 +1,35 @@ #!/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 -from gnuradio import qtgui -from PyQt4 import QtGui, QtCore -import sys, sip +import sys + +try: + from gnuradio import qtgui + from PyQt4 import QtGui, QtCore + import sip +except ImportError: + print "Error: Program requires PyQt4 and gr-qtgui." + sys.exit(1) class dialog_box(QtGui.QWidget): def __init__(self, display, control): diff --git a/gr-qtgui/apps/pyqt_time_c.py b/gr-qtgui/examples/pyqt_time_c.py index fa7d60e81..a47302d19 100755 --- a/gr-qtgui/apps/pyqt_time_c.py +++ b/gr-qtgui/examples/pyqt_time_c.py @@ -1,9 +1,35 @@ #!/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 -from gnuradio import qtgui -from PyQt4 import QtGui, QtCore -import sys, sip +import sys + +try: + from gnuradio import qtgui + from PyQt4 import QtGui, QtCore + import sip +except ImportError: + print "Error: Program requires PyQt4 and gr-qtgui." + sys.exit(1) class dialog_box(QtGui.QWidget): def __init__(self, display, control): diff --git a/gr-qtgui/apps/pyqt_time_f.py b/gr-qtgui/examples/pyqt_time_f.py index 1b9efa10d..835b42a75 100755 --- a/gr-qtgui/apps/pyqt_time_f.py +++ b/gr-qtgui/examples/pyqt_time_f.py @@ -1,9 +1,35 @@ #!/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 -from gnuradio import qtgui -from PyQt4 import QtGui, QtCore -import sys, sip +import sys + +try: + from gnuradio import qtgui + from PyQt4 import QtGui, QtCore + import sip +except ImportError: + print "Error: Program requires PyQt4 and gr-qtgui." + sys.exit(1) class dialog_box(QtGui.QWidget): def __init__(self, display, control): diff --git a/gr-qtgui/lib/spectrumUpdateEvents.h b/gr-qtgui/lib/spectrumUpdateEvents.h index 5a17657b7..760619f88 100644 --- a/gr-qtgui/lib/spectrumUpdateEvents.h +++ b/gr-qtgui/lib/spectrumUpdateEvents.h @@ -101,7 +101,6 @@ public: int which() const; const std::vector<double*> getTimeDomainPoints() const; uint64_t getNumTimeDomainDataPoints() const; - timespec getDataTimestamp() const; bool getRepeatDataFlag() const; protected: diff --git a/gr-qtgui/swig/qtgui_swig.i b/gr-qtgui/swig/qtgui_swig.i index 5a4ffd6fb..7cf8873e7 100644 --- a/gr-qtgui/swig/qtgui_swig.i +++ b/gr-qtgui/swig/qtgui_swig.i @@ -23,10 +23,10 @@ %include "gnuradio.i" %{ -#include <qtgui_sink_c.h> -#include <qtgui_sink_f.h> -#include <qtgui_time_sink_c.h> -#include <qtgui_time_sink_f.h> +#include "qtgui_sink_c.h" +#include "qtgui_sink_f.h" +#include "qtgui_time_sink_c.h" +#include "qtgui_time_sink_f.h" %} %include "qtgui_sink_c.i" diff --git a/gr-trellis/Makefile.am b/gr-trellis/Makefile.am index d68fb59c9..89d190ecf 100644 --- a/gr-trellis/Makefile.am +++ b/gr-trellis/Makefile.am @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -SUBDIRS = src doc +SUBDIRS = src grc doc pkgconfigdir = $(libdir)/pkgconfig dist_pkgconfig_DATA = gnuradio-trellis.pc diff --git a/gr-gsm-fr-vocoder/.gitignore b/gr-trellis/grc/.gitignore index f3462d009..f3462d009 100644 --- a/gr-gsm-fr-vocoder/.gitignore +++ b/gr-trellis/grc/.gitignore diff --git a/gr-trellis/grc/Makefile.am b/gr-trellis/grc/Makefile.am new file mode 100644 index 000000000..518c7f055 --- /dev/null +++ b/gr-trellis/grc/Makefile.am @@ -0,0 +1,39 @@ +# +# 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. +# + +include $(top_srcdir)/Makefile.common + +grcblocksdir = $(grc_blocksdir) + +dist_grcblocks_DATA = \ + trellis_encoder_xx.xml \ + trellis_siso_combined_f.xml \ + trellis_viterbi_x.xml \ + trellis_metrics_x.xml \ + trellis_siso_f.xml \ + trellis_permutation.xml \ + trellis_viterbi_combined_xx.xml \ + trellis_sccc_encoder_xx.xml \ + trellis_sccc_decoder_x.xml \ + trellis_sccc_decoder_combined_xx.xml \ + trellis_pccc_encoder_xx.xml \ + trellis_pccc_decoder_x.xml \ + trellis_pccc_decoder_combined_xx.xml diff --git a/grc/blocks/trellis_encoder_xx.xml b/gr-trellis/grc/trellis_encoder_xx.xml index 74a8cc346..639e948ec 100644 --- a/grc/blocks/trellis_encoder_xx.xml +++ b/gr-trellis/grc/trellis_encoder_xx.xml @@ -4,9 +4,11 @@ ##Trellis Encoder ################################################### --> + <block> <name>Trellis Encoder</name> <key>trellis_encoder_xx</key> + <category>Error Correction/Trellis</category> <import>from gnuradio import trellis</import> <make>trellis.encoder_$(type)(trellis.fsm($fsm_args), $init_state)</make> <param> @@ -58,6 +60,7 @@ <param> <name>Initial State</name> <key>init_state</key> + <value>0</value> <type>int</type> </param> <sink> diff --git a/grc/blocks/trellis_metrics_x.xml b/gr-trellis/grc/trellis_metrics_x.xml index 2016a34c2..ccb59a36e 100644 --- a/grc/blocks/trellis_metrics_x.xml +++ b/gr-trellis/grc/trellis_metrics_x.xml @@ -4,9 +4,12 @@ ##Trellis Metrics ################################################### --> + + <block> <name>Trellis Metrics</name> <key>trellis_metrics_x</key> + <category>Error Correction/Trellis</category> <import>from gnuradio import trellis</import> <make>trellis.metrics_$(type)($card, $dim, $table, $metric_type)</make> <callback>set_TABLE($table)</callback> diff --git a/gr-trellis/grc/trellis_pccc_decoder_combined_xx.xml b/gr-trellis/grc/trellis_pccc_decoder_combined_xx.xml new file mode 100644 index 000000000..ec58132f8 --- /dev/null +++ b/gr-trellis/grc/trellis_pccc_decoder_combined_xx.xml @@ -0,0 +1,170 @@ +<?xml version="1.0"?> +<!-- +################################################### +## PCCC Decoder Combined +################################################### + --> + + +<block> + <name>PCCC Decoder Combo</name> + <key>trellis_pccc_decoder_combined_xx</key> + <category>Error Correction/Trellis</category> + <import>from gnuradio import trellis</import> + <make>trellis.pccc_decoder_combined_$(type)$(out_type)( + trellis.fsm($o_fsm_args), $o_init_state, $o_final_state, + trellis.fsm($i_fsm_args), $i_init_state, $i_final_state, + trellis.interleaver($interleaver), + $block_size, + $iterations, + $siso_type, + $dim, $table, $metric_type, + $scaling) + </make> + <callback>set_TABLE($table)</callback> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>c</key> + <opt>io:complex</opt> + <opt>table:complex_vector</opt> + </option> + <option> + <name>Float</name> + <key>f</key> + <opt>io:float</opt> + <opt>table:real_vector</opt> + </option> + </param> + <param> + <name>Output Type</name> + <key>out_type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>i</key> + <opt>io:int</opt> + </option> + <option> + <name>Short</name> + <key>s</key> + <opt>io:short</opt> + </option> + <option> + <name>Byte</name> + <key>b</key> + <opt>io:byte</opt> + </option> + </param> + <param> + <name>FSM 1</name> + <key>o_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Initial State 1</name> + <key>o_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Final State 1</name> + <key>o_final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>FSM 2</name> + <key>i_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Initial State 2</name> + <key>i_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Final State 2</name> + <key>i_final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Interleaver</name> + <key>interleaver</key> + <type>raw</type> + </param> + <param> + <name>Block Size</name> + <key>block_size</key> + <type>int</type> + </param> + <param> + <name>Iterations</name> + <key>iterations</key> + <value>10</value> + <type>int</type> + </param> + <param> + <name>Dimensionality</name> + <key>dim</key> + <type>int</type> + </param> + <param> + <name>Constellation</name> + <key>table</key> + <type>$type.table</type> + </param> + <param> + <name>Metric Type</name> + <key>metric_type</key> + <type>enum</type> + <option> + <name>Euclidean</name> + <key>trellis.TRELLIS_EUCLIDEAN</key> + </option> + <option> + <name>Hard Symbol</name> + <key>trellis.TRELLIS_HARD_SYMBOL</key> + </option> + <option> + <name>Hard Bit</name> + <key>trellis.TRELLIS_HARD_BIT</key> + </option> + </param> + <param> + <name>SISO Type</name> + <key>siso_type</key> + <type>enum</type> + <option> + <name>Min Sum</name> + <key>trellis.TRELLIS_MIN_SUM</key> + </option> + <option> + <name>Sum Product</name> + <key>trellis.TRELLIS_SUM_PRODUCT</key> + </option> + </param> + <param> + <name>Scaling</name> + <key>scaling</key> + <value>1.0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type.io</type> + </sink> + <source> + <name>out</name> + <type>$out_type.io</type> + </source> + <doc> +PCCC turbo Decoder combined with metric calculation. +The fsm arguments are passed directly to the trellis.fsm() constructor. + </doc> +</block> diff --git a/gr-trellis/grc/trellis_pccc_decoder_x.xml b/gr-trellis/grc/trellis_pccc_decoder_x.xml new file mode 100644 index 000000000..e6eb03f11 --- /dev/null +++ b/gr-trellis/grc/trellis_pccc_decoder_x.xml @@ -0,0 +1,117 @@ +<?xml version="1.0"?> +<!-- +################################################### +## PCCC Decoder +################################################### + --> + + +<block> + <name>PCCC Decoder</name> + <key>trellis_pccc_decoder_x</key> + <category>Error Correction/Trellis</category> + <import>from gnuradio import trellis</import> + <make>trellis.pccc_decoder_$(out_type)( + trellis.fsm($o_fsm_args), $o_init_state, $o_final_state, + trellis.fsm($i_fsm_args), $i_init_state, $i_final_state, + trellis.interleaver($interleaver), + $block_size, + $iterations, + $siso_type) + </make> + <param> + <name>Output Type</name> + <key>out_type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>i</key> + <opt>io:int</opt> + </option> + <option> + <name>Short</name> + <key>s</key> + <opt>io:short</opt> + </option> + <option> + <name>Byte</name> + <key>b</key> + <opt>io:byte</opt> + </option> + </param> + <param> + <name>FSM 1</name> + <key>o_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Initial State 1</name> + <key>o_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Final State 1</name> + <key>o_final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>FSM 2</name> + <key>i_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Initial State 2</name> + <key>i_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Final State 2</name> + <key>i_final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Interleaver</name> + <key>interleaver</key> + <type>raw</type> + </param> + <param> + <name>Block Size</name> + <key>block_size</key> + <type>int</type> + </param> + <param> + <name>Iterations</name> + <key>iterations</key> + <value>10</value> + <type>int</type> + </param> + <param> + <name>SISO Type</name> + <key>siso_type</key> + <type>enum</type> + <option> + <name>Min Sum</name> + <key>trellis.TRELLIS_MIN_SUM</key> + </option> + <option> + <name>Sum Product</name> + <key>trellis.TRELLIS_SUM_PRODUCT</key> + </option> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>$out_type.io</type> + </source> + <doc> +PCCC turbo Decoder. +The fsm and interleaver arguments are passed directly to the trellis.fsm() and trellis.interleaver() constructors. + </doc> +</block> diff --git a/gr-trellis/grc/trellis_pccc_encoder_xx.xml b/gr-trellis/grc/trellis_pccc_encoder_xx.xml new file mode 100644 index 000000000..6774f18d2 --- /dev/null +++ b/gr-trellis/grc/trellis_pccc_encoder_xx.xml @@ -0,0 +1,98 @@ +<?xml version="1.0"?> +<!-- +################################################### +## PCCC Encoder +################################################### + --> + +<block> + <name>PCCC Encoder</name> + <key>trellis_pccc_encoder_xx</key> + <category>Error Correction/Trellis</category> + <import>from gnuradio import trellis</import> + <make>trellis.pccc_encoder_$(type)(trellis.fsm($o_fsm_args), $o_init_state, trellis.fsm($i_fsm_args), $i_init_state, trellis.interleaver($interleaver_args), $bl)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Byte->Byte</name> + <key>bb</key> + <opt>input:byte</opt> + <opt>output:byte</opt> + </option> + <option> + <name>Byte->Short</name> + <key>bs</key> + <opt>input:byte</opt> + <opt>output:short</opt> + </option> + <option> + <name>Byte->Int</name> + <key>bi</key> + <opt>input:byte</opt> + <opt>output:int</opt> + </option> + <option> + <name>Short->Short</name> + <key>ss</key> + <opt>input:short</opt> + <opt>output:short</opt> + </option> + <option> + <name>Short->Int</name> + <key>si</key> + <opt>input:short</opt> + <opt>output:int</opt> + </option> + <option> + <name>Int->Int</name> + <key>ii</key> + <opt>input:int</opt> + <opt>output:int</opt> + </option> + </param> + <param> + <name>FSM 1</name> + <key>o_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Initial State 1</name> + <key>o_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>FSM 2</name> + <key>i_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Initial State 2</name> + <key>i_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Interleaver</name> + <key>interleaver_args</key> + <type>raw</type> + </param> + <param> + <name>Blocklength</name> + <key>bl</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> + <doc> +The fsm and interleaver arguments are passed directly to the trellis.fsm() and trellis.interleaver() constructors. + </doc> +</block> diff --git a/grc/blocks/trellis_permutation.xml b/gr-trellis/grc/trellis_permutation.xml index 7721cc71d..125a78d4d 100644 --- a/grc/blocks/trellis_permutation.xml +++ b/gr-trellis/grc/trellis_permutation.xml @@ -4,11 +4,14 @@ ##Trellis Permutation ################################################### --> + + <block> <name>Trellis Permutation</name> <key>trellis_permutation</key> + <category>Error Correction/Trellis</category> <import>from gnuradio import trellis</import> - <make>trellis.permutation($block_size, $table, $syms_per_block, $type.size*$vlen)</make> + <make>trellis.permutation($interleaver_size, $table, $syms_per_block, $type.size*$vlen)</make> <param> <name>Type</name> <key>type</key> @@ -40,8 +43,8 @@ </option> </param> <param> - <name>Block Size</name> - <key>block_size</key> + <name>Interleaver Size</name> + <key>interleaver_size</key> <type>int</type> </param> <param> @@ -71,4 +74,8 @@ <type>$type</type> <vlen>$vlen</vlen> </source> + <doc> +Interleaver size is given in blocks. +One Symbol = (in/out type) * (vector length) + </doc> </block> diff --git a/gr-trellis/grc/trellis_sccc_decoder_combined_xx.xml b/gr-trellis/grc/trellis_sccc_decoder_combined_xx.xml new file mode 100644 index 000000000..81d800902 --- /dev/null +++ b/gr-trellis/grc/trellis_sccc_decoder_combined_xx.xml @@ -0,0 +1,170 @@ +<?xml version="1.0"?> +<!-- +################################################### +## SCCC Decoder Combined +################################################### + --> + + +<block> + <name>SCCC Decoder Combo</name> + <key>trellis_sccc_decoder_combined_xx</key> + <category>Error Correction/Trellis</category> + <import>from gnuradio import trellis</import> + <make>trellis.sccc_decoder_combined_$(type)$(out_type)( + trellis.fsm($o_fsm_args), $o_init_state, $o_final_state, + trellis.fsm($i_fsm_args), $i_init_state, $i_final_state, + trellis.interleaver($interleaver), + $block_size, + $iterations, + $siso_type, + $dim, $table, $metric_type, + $scaling) + </make> + <callback>set_TABLE($table)</callback> + <param> + <name>Input Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Complex</name> + <key>c</key> + <opt>io:complex</opt> + <opt>table:complex_vector</opt> + </option> + <option> + <name>Float</name> + <key>f</key> + <opt>io:float</opt> + <opt>table:real_vector</opt> + </option> + </param> + <param> + <name>Output Type</name> + <key>out_type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>i</key> + <opt>io:int</opt> + </option> + <option> + <name>Short</name> + <key>s</key> + <opt>io:short</opt> + </option> + <option> + <name>Byte</name> + <key>b</key> + <opt>io:byte</opt> + </option> + </param> + <param> + <name>Outer FSM</name> + <key>o_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Outer Initial State</name> + <key>o_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Outer Final State</name> + <key>o_final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Inner FSM</name> + <key>i_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Inner Initial State</name> + <key>i_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Inner Final State</name> + <key>i_final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Interleaver</name> + <key>interleaver</key> + <type>raw</type> + </param> + <param> + <name>Block Size</name> + <key>block_size</key> + <type>int</type> + </param> + <param> + <name>Iterations</name> + <key>iterations</key> + <value>10</value> + <type>int</type> + </param> + <param> + <name>Dimensionality</name> + <key>dim</key> + <type>int</type> + </param> + <param> + <name>Constellation</name> + <key>table</key> + <type>$type.table</type> + </param> + <param> + <name>Metric Type</name> + <key>metric_type</key> + <type>enum</type> + <option> + <name>Euclidean</name> + <key>trellis.TRELLIS_EUCLIDEAN</key> + </option> + <option> + <name>Hard Symbol</name> + <key>trellis.TRELLIS_HARD_SYMBOL</key> + </option> + <option> + <name>Hard Bit</name> + <key>trellis.TRELLIS_HARD_BIT</key> + </option> + </param> + <param> + <name>SISO Type</name> + <key>siso_type</key> + <type>enum</type> + <option> + <name>Min Sum</name> + <key>trellis.TRELLIS_MIN_SUM</key> + </option> + <option> + <name>Sum Product</name> + <key>trellis.TRELLIS_SUM_PRODUCT</key> + </option> + </param> + <param> + <name>Scaling</name> + <key>scaling</key> + <value>1.0</value> + <type>real</type> + </param> + <sink> + <name>in</name> + <type>$type.io</type> + </sink> + <source> + <name>out</name> + <type>$out_type.io</type> + </source> + <doc> +SCCC turbo Decoder combined with metric calculation. +The fsm arguments are passed directly to the trellis.fsm() constructor. + </doc> +</block> diff --git a/gr-trellis/grc/trellis_sccc_decoder_x.xml b/gr-trellis/grc/trellis_sccc_decoder_x.xml new file mode 100644 index 000000000..9fc24927b --- /dev/null +++ b/gr-trellis/grc/trellis_sccc_decoder_x.xml @@ -0,0 +1,117 @@ +<?xml version="1.0"?> +<!-- +################################################### +## SCCC Decoder +################################################### + --> + + +<block> + <name>SCCC Decoder</name> + <key>trellis_sccc_decoder_x</key> + <category>Error Correction/Trellis</category> + <import>from gnuradio import trellis</import> + <make>trellis.sccc_decoder_$(out_type)( + trellis.fsm($o_fsm_args), $o_init_state, $o_final_state, + trellis.fsm($i_fsm_args), $i_init_state, $i_final_state, + trellis.interleaver($interleaver), + $block_size, + $iterations, + $siso_type) + </make> + <param> + <name>Output Type</name> + <key>out_type</key> + <type>enum</type> + <option> + <name>Int</name> + <key>i</key> + <opt>io:int</opt> + </option> + <option> + <name>Short</name> + <key>s</key> + <opt>io:short</opt> + </option> + <option> + <name>Byte</name> + <key>b</key> + <opt>io:byte</opt> + </option> + </param> + <param> + <name>Outer FSM</name> + <key>o_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Outer Initial State</name> + <key>o_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Outer Final State</name> + <key>o_final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Inner FSM</name> + <key>i_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Inner Initial State</name> + <key>i_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Inner Final State</name> + <key>i_final_state</key> + <value>-1</value> + <type>int</type> + </param> + <param> + <name>Interleaver</name> + <key>interleaver</key> + <type>raw</type> + </param> + <param> + <name>Block Size</name> + <key>block_size</key> + <type>int</type> + </param> + <param> + <name>Iterations</name> + <key>iterations</key> + <value>10</value> + <type>int</type> + </param> + <param> + <name>SISO Type</name> + <key>siso_type</key> + <type>enum</type> + <option> + <name>Min Sum</name> + <key>trellis.TRELLIS_MIN_SUM</key> + </option> + <option> + <name>Sum Product</name> + <key>trellis.TRELLIS_SUM_PRODUCT</key> + </option> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>$out_type.io</type> + </source> + <doc> +SCCC turbo Decoder. +The fsm and interleaver arguments are passed directly to the trellis.fsm() and trellis.interleaver() constructors. + </doc> +</block> diff --git a/gr-trellis/grc/trellis_sccc_encoder_xx.xml b/gr-trellis/grc/trellis_sccc_encoder_xx.xml new file mode 100644 index 000000000..54d9c1e01 --- /dev/null +++ b/gr-trellis/grc/trellis_sccc_encoder_xx.xml @@ -0,0 +1,98 @@ +<?xml version="1.0"?> +<!-- +################################################### +##SCCC Encoder +################################################### + --> + +<block> + <name>SCCC Encoder</name> + <key>trellis_sccc_encoder_xx</key> + <category>Error Correction/Trellis</category> + <import>from gnuradio import trellis</import> + <make>trellis.sccc_encoder_$(type)(trellis.fsm($o_fsm_args), $o_init_state, trellis.fsm($i_fsm_args), $i_init_state, trellis.interleaver($interleaver_args), $bl)</make> + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Byte->Byte</name> + <key>bb</key> + <opt>input:byte</opt> + <opt>output:byte</opt> + </option> + <option> + <name>Byte->Short</name> + <key>bs</key> + <opt>input:byte</opt> + <opt>output:short</opt> + </option> + <option> + <name>Byte->Int</name> + <key>bi</key> + <opt>input:byte</opt> + <opt>output:int</opt> + </option> + <option> + <name>Short->Short</name> + <key>ss</key> + <opt>input:short</opt> + <opt>output:short</opt> + </option> + <option> + <name>Short->Int</name> + <key>si</key> + <opt>input:short</opt> + <opt>output:int</opt> + </option> + <option> + <name>Int->Int</name> + <key>ii</key> + <opt>input:int</opt> + <opt>output:int</opt> + </option> + </param> + <param> + <name>Outer FSM</name> + <key>o_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Outer Initial State</name> + <key>o_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Inner FSM</name> + <key>i_fsm_args</key> + <type>raw</type> + </param> + <param> + <name>Inner Initial State</name> + <key>i_init_state</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Interleaver</name> + <key>interleaver_args</key> + <type>raw</type> + </param> + <param> + <name>Blocklength</name> + <key>bl</key> + <type>int</type> + </param> + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + <source> + <name>out</name> + <type>$type.output</type> + </source> + <doc> +The fsm and interleaver arguments are passed directly to the trellis.fsm() and trellis.interleaver() constructors. + </doc> +</block> diff --git a/grc/blocks/trellis_siso_combined_f.xml b/gr-trellis/grc/trellis_siso_combined_f.xml index 98874d7f4..a39986a86 100644 --- a/grc/blocks/trellis_siso_combined_f.xml +++ b/gr-trellis/grc/trellis_siso_combined_f.xml @@ -4,9 +4,12 @@ ##Trellis SISO Combined ################################################### --> + + <block> - <name>Trellis SISO Combo</name> + <name>SISO Combo</name> <key>trellis_siso_combined_f</key> + <category>Error Correction/Trellis</category> <import>from gnuradio import trellis</import> <make>trellis.siso_combined_f(trellis.fsm($fsm_args), $block_size, $init_state, $final_state, $a_post_in, $a_post_out, $siso_type, $dim, $table, $metric_type)</make> <param> @@ -22,7 +25,7 @@ <param> <name>Initial State</name> <key>init_state</key> - <value>-1</value> + <value>0</value> <type>int</type> </param> <param> diff --git a/grc/blocks/trellis_siso_f.xml b/gr-trellis/grc/trellis_siso_f.xml index 2b9cfe5f7..e3fb502b3 100644 --- a/grc/blocks/trellis_siso_f.xml +++ b/gr-trellis/grc/trellis_siso_f.xml @@ -4,9 +4,12 @@ ##Trellis SISO ################################################### --> + + <block> - <name>Trellis SISO</name> + <name>SISO</name> <key>trellis_siso_f</key> + <category>Error Correction/Trellis</category> <import>from gnuradio import trellis</import> <make>trellis.siso_f(trellis.fsm($fsm_args), $block_size, $init_state, $final_state, $a_post_in, $a_post_out, $siso_type)</make> <param> @@ -22,7 +25,7 @@ <param> <name>Initial State</name> <key>init_state</key> - <value>-1</value> + <value>0</value> <type>int</type> </param> <param> diff --git a/grc/blocks/trellis_viterbi_combined_xx.xml b/gr-trellis/grc/trellis_viterbi_combined_xx.xml index 33dcaaf73..200f07859 100644 --- a/grc/blocks/trellis_viterbi_combined_xx.xml +++ b/gr-trellis/grc/trellis_viterbi_combined_xx.xml @@ -4,9 +4,12 @@ ##Trellis Viterbi Combined ################################################### --> + + <block> - <name>Trellis Viterbi Combo</name> + <name>Viterbi Combo</name> <key>trellis_viterbi_combined_xx</key> + <category>Error Correction/Trellis</category> <import>from gnuradio import trellis</import> <make>trellis.viterbi_combined_$(type)$(out_type)(trellis.fsm($fsm_args), $block_size, $init_state, $final_state, $dim, $table, $metric_type)</make> <callback>set_TABLE($table)</callback> @@ -72,7 +75,7 @@ <param> <name>Initial State</name> <key>init_state</key> - <value>-1</value> + <value>0</value> <type>int</type> </param> <param> diff --git a/grc/blocks/trellis_viterbi_x.xml b/gr-trellis/grc/trellis_viterbi_x.xml index 84b39677c..d97e6707a 100644 --- a/grc/blocks/trellis_viterbi_x.xml +++ b/gr-trellis/grc/trellis_viterbi_x.xml @@ -4,9 +4,12 @@ ##Trellis Viterbi ################################################### --> + + <block> - <name>Trellis Viterbi</name> + <name>Viterbi</name> <key>trellis_viterbi_x</key> + <category>Error Correction/Trellis</category> <import>from gnuradio import trellis</import> <make>trellis.viterbi_$(type)(trellis.fsm($fsm_args), $block_size, $init_state, $final_state)</make> <param> @@ -42,7 +45,7 @@ <param> <name>Initial State</name> <key>init_state</key> - <value>-1</value> + <value>0</value> <type>int</type> </param> <param> diff --git a/gr-trellis/src/examples/fsm_utils.py b/gr-trellis/src/examples/fsm_utils.py index e3426637c..e9243f899 100755 --- a/gr-trellis/src/examples/fsm_utils.py +++ b/gr-trellis/src/examples/fsm_utils.py @@ -26,10 +26,15 @@ import math import sys import operator import numpy -import scipy.linalg from gnuradio import trellis +try: + import scipy.linalg +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + ###################################################################### diff --git a/gr-trellis/src/examples/test_cpm.py b/gr-trellis/src/examples/test_cpm.py index ec432d4ff..b5bdaae44 100755 --- a/gr-trellis/src/examples/test_cpm.py +++ b/gr-trellis/src/examples/test_cpm.py @@ -13,10 +13,15 @@ from gnuradio.gr import firdes from grc_gnuradio import blks2 as grc_blks2 import math import numpy -import scipy.stats import fsm_utils from gnuradio import trellis +try: + import scipy.stats +except ImportError: + print "Error: Program requires scipy (see: www.scipy.org)." + sys.exit(1) + def run_test(seed,blocksize): tb = gr.top_block() @@ -83,7 +88,7 @@ def run_test(seed,blocksize): ################################################## # Blocks ################################################## - random_source_x_0 = gr.vector_source_b(data, False) + random_source_x_0 = gr.vector_source_b(data.tolist(), False) gr_chunks_to_symbols_xx_0 = gr.chunks_to_symbols_bf((-1, 1), 1) gr_interp_fir_filter_xxx_0 = gr.interp_fir_filter_fff(Q, p) gr_frequency_modulator_fc_0 = gr.frequency_modulator_fc(2*math.pi*h*(1.0/Q)) @@ -96,9 +101,9 @@ def run_test(seed,blocksize): # only works for N=2, do it manually for N>2... gr_fir_filter_xxx_0_0 = gr.fir_filter_ccc(Q, MF[0].conjugate()) gr_fir_filter_xxx_0_0_0 = gr.fir_filter_ccc(Q, MF[1].conjugate()) - gr_streams_to_stream_0 = gr.streams_to_stream(gr.sizeof_gr_complex*1, N) - gr_skiphead_0 = gr.skiphead(gr.sizeof_gr_complex*1, N*(1+0)) - viterbi = trellis.viterbi_combined_cb(f, head+blocksize+tail, 0, -1, N, constellation, trellis.TRELLIS_EUCLIDEAN) + gr_streams_to_stream_0 = gr.streams_to_stream(gr.sizeof_gr_complex*1, int(N)) + gr_skiphead_0 = gr.skiphead(gr.sizeof_gr_complex*1, int(N*(1+0))) + viterbi = trellis.viterbi_combined_cb(f, head+blocksize+tail, 0, -1, int(N), constellation, trellis.TRELLIS_EUCLIDEAN) gr_vector_sink_x_0 = gr.vector_sink_b() diff --git a/gr-trellis/src/lib/Makefile.am b/gr-trellis/src/lib/Makefile.am index f358cd523..e0b254756 100644 --- a/gr-trellis/src/lib/Makefile.am +++ b/gr-trellis/src/lib/Makefile.am @@ -42,12 +42,12 @@ core_generator = \ trellis_encoder_XX.cc.t \ trellis_encoder_XX.h.t \ trellis_encoder_XX.i.t \ - trellis_sccc_encoder_XX.cc.t \ - trellis_sccc_encoder_XX.h.t \ - trellis_sccc_encoder_XX.i.t \ - trellis_pccc_encoder_XX.cc.t \ - trellis_pccc_encoder_XX.h.t \ - trellis_pccc_encoder_XX.i.t \ + trellis_sccc_encoder_XX.cc.t \ + trellis_sccc_encoder_XX.h.t \ + trellis_sccc_encoder_XX.i.t \ + trellis_pccc_encoder_XX.cc.t \ + trellis_pccc_encoder_XX.h.t \ + trellis_pccc_encoder_XX.i.t \ trellis_metrics_X.cc.t \ trellis_metrics_X.h.t \ trellis_metrics_X.i.t \ @@ -55,14 +55,17 @@ core_generator = \ trellis_viterbi_combined_XX.h.t \ trellis_viterbi_combined_XX.i.t \ trellis_sccc_decoder_combined_XX.cc.t \ - trellis_sccc_decoder_combined_XX.h.t \ - trellis_sccc_decoder_combined_XX.i.t \ - trellis_sccc_decoder_X.cc.t \ + trellis_sccc_decoder_combined_XX.h.t \ + trellis_sccc_decoder_combined_XX.i.t \ + trellis_sccc_decoder_X.cc.t \ trellis_sccc_decoder_X.h.t \ trellis_sccc_decoder_X.i.t \ - trellis_pccc_decoder_X.cc.t \ + trellis_pccc_decoder_X.cc.t \ trellis_pccc_decoder_X.h.t \ trellis_pccc_decoder_X.i.t \ + trellis_pccc_decoder_combined_XX.cc.t \ + trellis_pccc_decoder_combined_XX.h.t \ + trellis_pccc_decoder_combined_XX.i.t \ trellis_viterbi_X.cc.t \ trellis_viterbi_X.h.t \ trellis_viterbi_X.i.t diff --git a/gr-trellis/src/lib/Makefile.gen b/gr-trellis/src/lib/Makefile.gen index 534a7466e..b9b9afb1f 100644 --- a/gr-trellis/src/lib/Makefile.gen +++ b/gr-trellis/src/lib/Makefile.gen @@ -13,6 +13,12 @@ GENERATED_H = \ trellis_metrics_i.h \ trellis_metrics_s.h \ trellis_pccc_decoder_b.h \ + trellis_pccc_decoder_combined_cb.h \ + trellis_pccc_decoder_combined_ci.h \ + trellis_pccc_decoder_combined_cs.h \ + trellis_pccc_decoder_combined_fb.h \ + trellis_pccc_decoder_combined_fi.h \ + trellis_pccc_decoder_combined_fs.h \ trellis_pccc_decoder_i.h \ trellis_pccc_decoder_s.h \ trellis_pccc_encoder_bb.h \ @@ -64,6 +70,12 @@ GENERATED_I = \ trellis_metrics_i.i \ trellis_metrics_s.i \ trellis_pccc_decoder_b.i \ + trellis_pccc_decoder_combined_cb.i \ + trellis_pccc_decoder_combined_ci.i \ + trellis_pccc_decoder_combined_cs.i \ + trellis_pccc_decoder_combined_fb.i \ + trellis_pccc_decoder_combined_fi.i \ + trellis_pccc_decoder_combined_fs.i \ trellis_pccc_decoder_i.i \ trellis_pccc_decoder_s.i \ trellis_pccc_encoder_bb.i \ @@ -115,6 +127,12 @@ GENERATED_CC = \ trellis_metrics_i.cc \ trellis_metrics_s.cc \ trellis_pccc_decoder_b.cc \ + trellis_pccc_decoder_combined_cb.cc \ + trellis_pccc_decoder_combined_ci.cc \ + trellis_pccc_decoder_combined_cs.cc \ + trellis_pccc_decoder_combined_fb.cc \ + trellis_pccc_decoder_combined_fi.cc \ + trellis_pccc_decoder_combined_fs.cc \ trellis_pccc_decoder_i.cc \ trellis_pccc_decoder_s.cc \ trellis_pccc_encoder_bb.cc \ diff --git a/gr-trellis/src/lib/core_algorithms.cc b/gr-trellis/src/lib/core_algorithms.cc index 91ac8fbdf..54193c818 100644 --- a/gr-trellis/src/lib/core_algorithms.cc +++ b/gr-trellis/src/lib/core_algorithms.cc @@ -784,7 +784,7 @@ template<class Ti, class To> void sccc_decoder_combined( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), int D, const std::vector<Ti> &TABLE, trellis_metric_type_t METRIC_TYPE, @@ -810,7 +810,7 @@ for(int k=0;k<blocklength;k++) { iprioro[k*FSMi.O()] *= scaling; } -for(int rep=0;rep<repetitions;rep++) { +for(int rep=0;rep<iterations;rep++) { // run inner SISO siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(), FSMi.NS(), FSMi.OS(), FSMi.PS(), FSMi.PI(), @@ -832,7 +832,7 @@ for(int rep=0;rep<repetitions;rep++) { // run outer SISO - if(rep<repetitions-1) { // do not produce posti + if(rep<iterations-1) { // do not produce posti siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), blocklength, @@ -897,7 +897,7 @@ template void sccc_decoder_combined<float,unsigned char>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), int D, const std::vector<float> &TABLE, trellis_metric_type_t METRIC_TYPE, @@ -909,7 +909,7 @@ template void sccc_decoder_combined<float,short>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), int D, const std::vector<float> &TABLE, trellis_metric_type_t METRIC_TYPE, @@ -921,7 +921,7 @@ template void sccc_decoder_combined<float,int>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), int D, const std::vector<float> &TABLE, trellis_metric_type_t METRIC_TYPE, @@ -933,7 +933,7 @@ template void sccc_decoder_combined<gr_complex,unsigned char>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), int D, const std::vector<gr_complex> &TABLE, trellis_metric_type_t METRIC_TYPE, @@ -945,7 +945,7 @@ template void sccc_decoder_combined<gr_complex,short>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), int D, const std::vector<gr_complex> &TABLE, trellis_metric_type_t METRIC_TYPE, @@ -957,7 +957,7 @@ template void sccc_decoder_combined<gr_complex,int>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), int D, const std::vector<gr_complex> &TABLE, trellis_metric_type_t METRIC_TYPE, @@ -973,7 +973,7 @@ template<class T> void sccc_decoder( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), const float *iprioro, T *data ) @@ -988,7 +988,7 @@ void sccc_decoder( std::vector<float> oposti(blocklength*FSMo.I()); std::vector<float> oposto(blocklength*FSMo.O()); - for(int rep=0;rep<repetitions;rep++) { + for(int rep=0;rep<iterations;rep++) { // run inner SISO siso_algorithm(FSMi.I(),FSMi.S(),FSMi.O(), FSMi.NS(), FSMi.OS(), FSMi.PS(), FSMi.PI(), @@ -1010,7 +1010,7 @@ void sccc_decoder( // run outer SISO - if(rep<repetitions-1) { // do not produce posti + if(rep<iterations-1) { // do not produce posti siso_algorithm(FSMo.I(),FSMo.S(),FSMo.O(), FSMo.NS(), FSMo.OS(), FSMo.PS(), FSMo.PI(), blocklength, @@ -1050,7 +1050,7 @@ void sccc_decoder( */ } - } // end repetitions + } // end iterations // generate hard decisions for(int k=0;k<blocklength;k++) { @@ -1075,7 +1075,7 @@ template void sccc_decoder<unsigned char>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), const float *iprioro, unsigned char *data ); @@ -1084,7 +1084,7 @@ template void sccc_decoder<short>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), const float *iprioro, short *data ); @@ -1093,7 +1093,7 @@ template void sccc_decoder<int>( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), const float *iprioro, int *data ); @@ -1105,7 +1105,7 @@ template<class T> void pccc_decoder( const fsm &FSM1, int ST10, int ST1K, const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), const float *cprioro, T *data ) @@ -1140,7 +1140,7 @@ void pccc_decoder( } } - for(int rep=0;rep<repetitions;rep++) { + for(int rep=0;rep<iterations;rep++) { // run SISO 1 siso_algorithm(FSM1.I(),FSM1.S(),FSM1.O(), FSM1.NS(), FSM1.OS(), FSM1.PS(), FSM1.PI(), @@ -1185,7 +1185,7 @@ void pccc_decoder( memcpy(&(priori1[ki*FSM1.I()]),&(posti2[k*FSM2.I()]),FSM1.I()*sizeof(float)); } - } // end repetitions + } // end iterations // generate hard decisions for(int k=0;k<blocklength;k++) { @@ -1204,8 +1204,6 @@ void pccc_decoder( } //std::cout << std::endl; - - } //---------------- @@ -1214,7 +1212,7 @@ template void pccc_decoder<unsigned char>( const fsm &FSM1, int ST10, int ST1K, const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), const float *cprioro, unsigned char *data ); @@ -1223,7 +1221,7 @@ template void pccc_decoder<short>( const fsm &FSM1, int ST10, int ST1K, const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), const float *cprioro, short *data ); @@ -1232,8 +1230,208 @@ template void pccc_decoder<int>( const fsm &FSM1, int ST10, int ST1K, const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), const float *cprioro, int *data ); + + +//---------------- + + +template<class Ti, class To> +void pccc_decoder_combined( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int iterations, + float (*p2mymin)(float,float), + int D, const std::vector<Ti> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling, + const Ti *observations, To *data +) +{ + + //allocate space for cprioro + std::vector<float> cprioro(blocklength*FSM1.O()*FSM2.O(),0.0); + + //allocate space for priori, prioro and posti of FSM1 + std::vector<float> priori1(blocklength*FSM1.I(),0.0); + std::vector<float> prioro1(blocklength*FSM1.O()); + std::vector<float> posti1(blocklength*FSM1.I()); + + //allocate space for priori, prioro and posti of FSM2 + std::vector<float> priori2(blocklength*FSM2.I(),0.0); + std::vector<float> prioro2(blocklength*FSM2.O()); + std::vector<float> posti2(blocklength*FSM2.I()); + + // turn observations to neg-log-priors for cprioiro + int O=FSM1.O()*FSM2.O(); + for(int k=0;k<blocklength;k++) { + calc_metric(O, D, TABLE, &(observations[k*D]), &(cprioro[k*O]),METRIC_TYPE); + cprioro[k*O] *= scaling; + } + + //generate prioro1,2 (metrics are not updated per iteration: this is not the best you can do...) + for (int k=0;k<blocklength;k++) { + //std::cout << k << std::endl; + for(int i=0;i<FSM1.O();i++) { + float x=cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+0]; + for(int j=1;j<FSM2.O();j++) + x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+i*FSM1.O()+j]); + prioro1[k*FSM1.O()+i]=x; + //std::cout << prioro1[k*FSM1.O()+i] << ", "; + } + //std::cout << std::endl; + for(int i=0;i<FSM2.O();i++) { + float x=cprioro[k*FSM1.O()*FSM2.O()+0*FSM1.O()+i]; + for(int j=1;j<FSM1.O();j++) + x = (*p2mymin)(x,cprioro[k*FSM1.O()*FSM2.O()+j*FSM1.O()+i]); + prioro2[k*FSM2.O()+i]=x; + } + } + + for(int rep=0;rep<iterations;rep++) { + // run SISO 1 + siso_algorithm(FSM1.I(),FSM1.S(),FSM1.O(), + FSM1.NS(), FSM1.OS(), FSM1.PS(), FSM1.PI(), + blocklength, + ST10,ST1K, + true, false, + p2mymin, + &(priori1[0]), &(prioro1[0]), &(posti1[0]) + ); + + //for(int k=0;k<blocklength;k++){ + //for(int i=0;i<FSM1.I();i++) + //std::cout << posti1[k*FSM1.I()+i] << ", "; + //std::cout << std::endl; + //} + + //interleave soft info 1 -> 2 + for(int k=0;k<blocklength;k++) { + int ki = INTERLEAVER.INTER()[k]; + //for(int i=0;i<FSMi.I();i++) { + //oprioro[k*FSMi.I()+i]=iposti[ki*FSMi.I()+i]; + //} + memcpy(&(priori2[k*FSM2.I()]),&(posti1[ki*FSM1.I()]),FSM1.I()*sizeof(float)); + } + + // run SISO 2 + siso_algorithm(FSM2.I(),FSM2.S(),FSM2.O(), + FSM2.NS(), FSM2.OS(), FSM2.PS(), FSM2.PI(), + blocklength, + ST20,ST2K, + true, false, + p2mymin, + &(priori2[0]), &(prioro2[0]), &(posti2[0]) + ); + + //interleave soft info 2 --> 1 + for(int k=0;k<blocklength;k++) { + int ki = INTERLEAVER.INTER()[k]; + //for(int i=0;i<FSMi.I();i++) { + //ipriori[ki*FSMi.I()+i]=oposto[k*FSMi.I()+i]; + //} + memcpy(&(priori1[ki*FSM1.I()]),&(posti2[k*FSM2.I()]),FSM1.I()*sizeof(float)); + } + + } // end iterations + + // generate hard decisions + for(int k=0;k<blocklength;k++) { + for(int i=0;i<FSM1.I();i++) + posti1[k*FSM1.I()+i] = (*p2mymin)(priori1[k*FSM1.I()+i],posti1[k*FSM1.I()+i]); + float min=INF; + int mini=0; + for(int i=0;i<FSM1.I();i++) { + if(posti1[k*FSM1.I()+i]<min) { + min=posti1[k*FSM1.I()+i]; + mini=i; + } + } + data[k]=(To)mini; + //std::cout << data[k] << ", "<< std::endl; + } + //std::cout << std::endl; + +} + + +template +void pccc_decoder_combined( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int iterations, + float (*p2mymin)(float,float), + int D, const std::vector<float> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling, + const float *observations, unsigned char *data +); + + +template +void pccc_decoder_combined( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int iterations, + float (*p2mymin)(float,float), + int D, const std::vector<float> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling, + const float *observations, short *data +); + + +template +void pccc_decoder_combined( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int iterations, + float (*p2mymin)(float,float), + int D, const std::vector<float> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling, + const float *observations, int *data +); + + +template +void pccc_decoder_combined( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int iterations, + float (*p2mymin)(float,float), + int D, const std::vector<gr_complex> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling, + const gr_complex *observations, unsigned char *data +); + + +template +void pccc_decoder_combined( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int iterations, + float (*p2mymin)(float,float), + int D, const std::vector<gr_complex> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling, + const gr_complex *observations, short *data +); + + +template +void pccc_decoder_combined( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int iterations, + float (*p2mymin)(float,float), + int D, const std::vector<gr_complex> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling, + const gr_complex *observations, int *data +); diff --git a/gr-trellis/src/lib/core_algorithms.h b/gr-trellis/src/lib/core_algorithms.h index fd45844c0..cab7086ba 100644 --- a/gr-trellis/src/lib/core_algorithms.h +++ b/gr-trellis/src/lib/core_algorithms.h @@ -91,11 +91,21 @@ void siso_algorithm_combined(int I, int S, int O, ); +template<class T> +void sccc_decoder( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, int blocklength, int iterations, + float (*p2mymin)(float,float), + const float *iprioro, T *data +); + + template<class Ti, class To> void sccc_decoder_combined( const fsm &FSMo, int STo0, int SToK, const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), int D, const std::vector<Ti> &TABLE, trellis_metric_type_t METRIC_TYPE, @@ -103,26 +113,28 @@ void sccc_decoder_combined( const Ti *observations, To *data ); - template<class T> -void sccc_decoder( - const fsm &FSMo, int STo0, int SToK, - const fsm &FSMi, int STi0, int STiK, - const interleaver &INTERLEAVER, int blocklength, int repetitions, +void pccc_decoder( + const fsm &FSM1, int ST10, int ST1K, + const fsm &FSM2, int ST20, int ST2K, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), - const float *iprioro, T *data + const float *cprioro, T *data ); - -template<class T> -void pccc_decoder( +template<class Ti, class To> +void pccc_decoder_combined( const fsm &FSM1, int ST10, int ST1K, const fsm &FSM2, int ST20, int ST2K, - const interleaver &INTERLEAVER, int blocklength, int repetitions, + const interleaver &INTERLEAVER, int blocklength, int iterations, float (*p2mymin)(float,float), - const float *cprioro, T *data + int D, const std::vector<Ti> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling, + const Ti *observations, To *data ); + #endif diff --git a/gr-trellis/src/lib/fsm.cc b/gr-trellis/src/lib/fsm.cc index 889a3918b..71e54b05a 100644 --- a/gr-trellis/src/lib/fsm.cc +++ b/gr-trellis/src/lib/fsm.cc @@ -132,7 +132,7 @@ fsm::fsm(int k, int n, const std::vector<int> &G) for(int j=0;j<n;j++) { int mem = -1; if(G[i*n+j]!=0) - mem=(int)(log(G[i*n+j])/log(2.0)); + mem=(int)(log(double(G[i*n+j]))/log(2.0)); if(mem>max_mem_x[i]) max_mem_x[i]=mem; if(mem>max_mem) @@ -417,7 +417,7 @@ void fsm::generate_TM() done = find_es(s); attempts ++; } - if (done == false and d_S > 1) { + if (done == false && d_S > 1) { //throw std::runtime_error ("fsm::generate_TM(): FSM appears to be disconnected\n"); printf("fsm::generate_TM(): FSM appears to be disconnected\n"); printf("state %d cannot be reached from all other states\n",s); diff --git a/gr-trellis/src/lib/fsm.h b/gr-trellis/src/lib/fsm.h index 8bae91754..134bbf26e 100644 --- a/gr-trellis/src/lib/fsm.h +++ b/gr-trellis/src/lib/fsm.h @@ -106,7 +106,7 @@ public: * \brief Creates an FSMS describing ISI. * * \param mod_size modulation size - * \param ch_lenth channel length + * \param ch_length channel length * */ fsm(int mod_size, int ch_length); @@ -125,14 +125,14 @@ public: /*! * \brief Creates an FSMS describing the joint trellis of two FSMs. * - * \param fsm1 first FSMS - * \param fsm2 second FSMS + * \param FSM1 first FSMS + * \param FSM2 second FSMS */ fsm(const fsm &FSM1, const fsm &FSM2); /*! * \brief Creates an FSMS representing n stages through the originial FSM (AKA radix-n FSM). * - * \param original FSMS + * \param FSM Original FSMs * \param n Number of stages. */ fsm(const fsm &FSM, int n); diff --git a/gr-trellis/src/lib/generate_trellis.py b/gr-trellis/src/lib/generate_trellis.py index 9f845f74a..31bc44aac 100644 --- a/gr-trellis/src/lib/generate_trellis.py +++ b/gr-trellis/src/lib/generate_trellis.py @@ -33,9 +33,10 @@ other_roots = [ 'trellis_metrics_X', 'trellis_viterbi_X', 'trellis_viterbi_combined_XX', - 'trellis_sccc_decoder_combined_XX', 'trellis_sccc_decoder_X', + 'trellis_sccc_decoder_combined_XX', 'trellis_pccc_decoder_X', + 'trellis_pccc_decoder_combined_XX', ] other_signatures = ( @@ -45,9 +46,10 @@ other_signatures = ( ['s','i','f','c'], ['b','s','i'], ['sb','ss','si','ib','is','ii','fb','fs','fi','cb','cs','ci'], - ['fb','fs','fi','cb','cs','ci'], ['b','s','i'], + ['fb','fs','fi','cb','cs','ci'], ['b','s','i'], + ['fb','fs','fi','cb','cs','ci'], ) diff --git a/gr-trellis/src/lib/trellis_constellation_metrics_cf.cc b/gr-trellis/src/lib/trellis_constellation_metrics_cf.cc index 1d03886f1..91520e4ce 100644 --- a/gr-trellis/src/lib/trellis_constellation_metrics_cf.cc +++ b/gr-trellis/src/lib/trellis_constellation_metrics_cf.cc @@ -20,9 +20,7 @@ * Boston, MA 02110-1301, USA. */ -// WARNING: this file is machine generated. Edits will be over written - -#ifndef HAVE_CONFIG_H +#ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/gr-trellis/src/lib/trellis_pccc_decoder_X.h.t b/gr-trellis/src/lib/trellis_pccc_decoder_X.h.t index ff4b7a1f8..2a5b43df6 100644 --- a/gr-trellis/src/lib/trellis_pccc_decoder_X.h.t +++ b/gr-trellis/src/lib/trellis_pccc_decoder_X.h.t @@ -50,9 +50,9 @@ typedef boost::shared_ptr<@NAME@> @SPTR_NAME@; class @NAME@ : public gr_block { fsm d_FSM1; - fsm d_FSM2; int d_ST10; int d_ST1K; + fsm d_FSM2; int d_ST20; int d_ST2K; interleaver d_INTERLEAVER; diff --git a/gr-trellis/src/lib/trellis_pccc_decoder_combined_XX.cc.t b/gr-trellis/src/lib/trellis_pccc_decoder_combined_XX.cc.t new file mode 100644 index 000000000..48f68f1fe --- /dev/null +++ b/gr-trellis/src/lib/trellis_pccc_decoder_combined_XX.cc.t @@ -0,0 +1,147 @@ +/* -*- 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. + */ + +// @WARNING@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <@NAME@.h> +#include <gr_io_signature.h> +#include <assert.h> +#include <iostream> +#include "core_algorithms.h" + + +static const float INF = 1.0e9; + +@SPTR_NAME@ +trellis_make_@BASE_NAME@ ( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE, + int D, + const std::vector<@I_TYPE@> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling +) +{ + return gnuradio::get_initial_sptr (new @NAME@ ( + FSMo, STo0, SToK, + FSMi, STi0, STiK, + INTERLEAVER, + blocklength, + repetitions, + SISO_TYPE, + D, + TABLE,METRIC_TYPE, + scaling + )); +} + +@NAME@::@NAME@ ( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE, + int D, + const std::vector<@I_TYPE@> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling +) + : gr_block ("@BASE_NAME@", + gr_make_io_signature (1, 1, sizeof (@I_TYPE@)), + gr_make_io_signature (1, 1, sizeof (@O_TYPE@))), + d_FSMo (FSMo), d_STo0 (STo0), d_SToK (SToK), + d_FSMi (FSMi), d_STi0 (STi0), d_STiK (STiK), + d_INTERLEAVER (INTERLEAVER), + d_blocklength (blocklength), + d_repetitions (repetitions), + d_SISO_TYPE (SISO_TYPE), + d_D (D), + d_TABLE (TABLE), + d_METRIC_TYPE (METRIC_TYPE), + d_scaling (scaling) +{ + assert(d_FSMo.I() == d_FSMi.I()); + set_relative_rate (1.0 / ((double) d_D)); + set_output_multiple (d_blocklength); +} + +void @NAME@::set_scaling(float scaling) +{ + d_scaling = scaling; +} + + +void +@NAME@::forecast (int noutput_items, gr_vector_int &ninput_items_required) +{ + assert (noutput_items % d_blocklength == 0); + int input_required = d_D * noutput_items ; + ninput_items_required[0] = input_required; +} + + + +//=========================================================== + +int +@NAME@::general_work (int noutput_items, + gr_vector_int &ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + assert (noutput_items % d_blocklength == 0); + int nblocks = noutput_items / d_blocklength; + + float (*p2min)(float, float) = NULL; + if(d_SISO_TYPE == TRELLIS_MIN_SUM) + p2min = &min; + else if(d_SISO_TYPE == TRELLIS_SUM_PRODUCT) + p2min = &min_star; + + + const @I_TYPE@ *in = (const @I_TYPE@ *) input_items[0]; + @O_TYPE@ *out = (@O_TYPE@ *) output_items[0]; + for (int n=0;n<nblocks;n++) { + pccc_decoder_combined( + d_FSMo, d_STo0, d_SToK, + d_FSMi, d_STi0, d_STiK, + d_INTERLEAVER, d_blocklength, d_repetitions, + p2min, + d_D,d_TABLE, + d_METRIC_TYPE, + d_scaling, + &(in[n*d_blocklength*d_D]),&(out[n*d_blocklength]) + ); + } + + consume_each (d_D * noutput_items ); + return noutput_items; +} diff --git a/gr-trellis/src/lib/trellis_pccc_decoder_combined_XX.h.t b/gr-trellis/src/lib/trellis_pccc_decoder_combined_XX.h.t new file mode 100644 index 000000000..dd9979af9 --- /dev/null +++ b/gr-trellis/src/lib/trellis_pccc_decoder_combined_XX.h.t @@ -0,0 +1,124 @@ +/* -*- 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. + */ + +// @WARNING@ + +#ifndef @GUARD_NAME@ +#define @GUARD_NAME@ + +#include "fsm.h" +#include "interleaver.h" +#include <gr_block.h> +#include <vector> +#include "calc_metric.h" +#include "siso_type.h" + +class @NAME@; +typedef boost::shared_ptr<@NAME@> @SPTR_NAME@; + +@SPTR_NAME@ trellis_make_@BASE_NAME@ ( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE, // perform "min-sum" or "sum-product" combining + int D, + const std::vector<@I_TYPE@> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling +); + + +/*! + * \ingroup coding_blk + */ +class @NAME@ : public gr_block +{ + fsm d_FSMo; + fsm d_FSMi; + int d_STo0; + int d_SToK; + int d_STi0; + int d_STiK; + interleaver d_INTERLEAVER; + int d_blocklength; + int d_repetitions; + trellis_siso_type_t d_SISO_TYPE; + int d_D; + std::vector<@I_TYPE@> d_TABLE; + trellis_metric_type_t d_METRIC_TYPE; + float d_scaling; + std::vector<float> d_buffer; + + friend @SPTR_NAME@ trellis_make_@BASE_NAME@ ( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE, + int D, + const std::vector<@I_TYPE@> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling + ); + + @NAME@ ( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE, + int D, + const std::vector<@I_TYPE@> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling + ); + +public: + fsm FSM1 () const { return d_FSMo; } + fsm FSM2 () const { return d_FSMi; } + int ST10 () const { return d_STo0; } + int ST1K () const { return d_SToK; } + int ST20 () const { return d_STi0; } + int ST2K () const { return d_STiK; } + interleaver INTERLEAVER () const { return d_INTERLEAVER; } + int blocklength () const { return d_blocklength; } + int repetitions () const { return d_repetitions; } + int D () const { return d_D; } + std::vector<@I_TYPE@> TABLE () const { return d_TABLE; } + trellis_metric_type_t METRIC_TYPE () const { return d_METRIC_TYPE; } + trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; } + float scaling () const { return d_scaling; } + void set_scaling (float scaling); + + 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); +}; + +#endif diff --git a/gr-trellis/src/lib/trellis_pccc_decoder_combined_XX.i.t b/gr-trellis/src/lib/trellis_pccc_decoder_combined_XX.i.t new file mode 100644 index 000000000..d841f67b4 --- /dev/null +++ b/gr-trellis/src/lib/trellis_pccc_decoder_combined_XX.i.t @@ -0,0 +1,73 @@ +/* -*- 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. + */ + +// @WARNING@ + +GR_SWIG_BLOCK_MAGIC(trellis,@BASE_NAME@); + +@SPTR_NAME@ trellis_make_@BASE_NAME@ ( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE, + int D, + const std::vector<@I_TYPE@> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling +); + + +class @NAME@ : public gr_block +{ +private: + @NAME@ ( + const fsm &FSMo, int STo0, int SToK, + const fsm &FSMi, int STi0, int STiK, + const interleaver &INTERLEAVER, + int blocklength, + int repetitions, + trellis_siso_type_t SISO_TYPE, + int D, + const std::vector<@I_TYPE@> &TABLE, + trellis_metric_type_t METRIC_TYPE, + float scaling + ); + +public: + fsm FSM1 () const { return d_FSMo; } + fsm FSM2 () const { return d_FSMi; } + int ST10 () const { return d_STo0; } + int ST1K () const { return d_SToK; } + int ST20 () const { return d_STi0; } + int ST2K () const { return d_STiK; } + interleaver INTERLEAVER () const { return d_INTERLEAVER; } + int blocklength () const { return d_blocklength; } + int repetitions () const { return d_repetitions; } + int D () const { return d_D; } + std::vector<@I_TYPE@> TABLE () const { return d_TABLE; } + trellis_metric_type_t METRIC_TYPE () const { return d_METRIC_TYPE; } + trellis_siso_type_t SISO_TYPE () const { return d_SISO_TYPE; } + float scaling() const { return d_scaling; } + void set_scaling (float scaling); +}; diff --git a/gr-trellis/src/lib/trellis_permutation.cc b/gr-trellis/src/lib/trellis_permutation.cc index a32390742..416fc58ec 100644 --- a/gr-trellis/src/lib/trellis_permutation.cc +++ b/gr-trellis/src/lib/trellis_permutation.cc @@ -30,19 +30,19 @@ #include <string.h> trellis_permutation_sptr -trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT) +trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t BYTES_PER_SYMBOL) { - return gnuradio::get_initial_sptr(new trellis_permutation (K,TABLE,SYMS_PER_BLOCK,NBYTES_INOUT)); + return gnuradio::get_initial_sptr(new trellis_permutation (K,TABLE,SYMS_PER_BLOCK,BYTES_PER_SYMBOL)); } -trellis_permutation::trellis_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT) +trellis_permutation::trellis_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t BYTES_PER_SYMBOL) : gr_sync_block ("permutation", - gr_make_io_signature (1, -1, NBYTES_INOUT), - gr_make_io_signature (1, -1, NBYTES_INOUT)), + gr_make_io_signature (1, -1, BYTES_PER_SYMBOL), + gr_make_io_signature (1, -1, BYTES_PER_SYMBOL)), d_K (K), d_TABLE (TABLE), d_SYMS_PER_BLOCK (SYMS_PER_BLOCK), - d_NBYTES_INOUT (NBYTES_INOUT) + d_BYTES_PER_SYMBOL (BYTES_PER_SYMBOL) { set_output_multiple (d_K*SYMS_PER_BLOCK); //std::cout << d_K << "\n"; @@ -72,9 +72,9 @@ trellis_permutation::work (int noutput_items, int j0 = i%d_K; // new position of block within packet (in blocks) int k0 = d_TABLE[j0]; - memcpy(&(out[i*d_SYMS_PER_BLOCK*d_NBYTES_INOUT]), - &(in[(i0+k0)*d_SYMS_PER_BLOCK*d_NBYTES_INOUT]), - d_NBYTES_INOUT*d_SYMS_PER_BLOCK); + memcpy(&(out[i*d_SYMS_PER_BLOCK*d_BYTES_PER_SYMBOL]), + &(in[(i0+k0)*d_SYMS_PER_BLOCK*d_BYTES_PER_SYMBOL]), + d_BYTES_PER_SYMBOL*d_SYMS_PER_BLOCK); } // end per stream processing } diff --git a/gr-trellis/src/lib/trellis_permutation.h b/gr-trellis/src/lib/trellis_permutation.h index 5505caf89..a5c858a8b 100644 --- a/gr-trellis/src/lib/trellis_permutation.h +++ b/gr-trellis/src/lib/trellis_permutation.h @@ -30,7 +30,7 @@ class trellis_permutation; typedef boost::shared_ptr<trellis_permutation> trellis_permutation_sptr; -trellis_permutation_sptr trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT); +trellis_permutation_sptr trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t BYTES_PER_SYMBOL); /*! * \brief Permutation. @@ -39,18 +39,18 @@ trellis_permutation_sptr trellis_make_permutation (int K, const std::vector<int> class trellis_permutation : public gr_sync_block { private: - friend trellis_permutation_sptr trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT); + friend trellis_permutation_sptr trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t BYTES_PER_SYMBOL); int d_K; std::vector<int> d_TABLE; int d_SYMS_PER_BLOCK; - size_t d_NBYTES_INOUT; + size_t d_BYTES_PER_SYMBOL; trellis_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES); public: int K () const { return d_K; } const std::vector<int> & TABLE () const { return d_TABLE; } int SYMS_PER_BLOCK () const { return d_SYMS_PER_BLOCK; } - size_t NBYTES_INOUT () const { return d_NBYTES_INOUT; } + size_t BYTES_PER_SYMBOL () const { return d_BYTES_PER_SYMBOL; } int work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gr-trellis/src/lib/trellis_permutation.i b/gr-trellis/src/lib/trellis_permutation.i index 834a36986..1433a6584 100644 --- a/gr-trellis/src/lib/trellis_permutation.i +++ b/gr-trellis/src/lib/trellis_permutation.i @@ -22,7 +22,7 @@ GR_SWIG_BLOCK_MAGIC(trellis,permutation); -trellis_permutation_sptr trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT); +trellis_permutation_sptr trellis_make_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t BYTES_PER_SYMBOL); class trellis_permutation : public gr_sync_block { @@ -30,12 +30,12 @@ private: int d_K; std::vector<int> d_TABLE; int d_SYMS_PER_BLOCK; - size_t d_NBYTES_INOUT; - trellis_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t NBYTES_INOUT); + size_t d_BYTES_PER_SYMBOL; + trellis_permutation (int K, const std::vector<int> &TABLE, int SYMS_PER_BLOCK, size_t BYTES_PER_SYMBOL); public: int K () const { return d_K; } const std::vector<int> & TABLE () const { return d_TABLE; } int SYMS_PER_BLOCK () const { return d_SYMS_PER_BLOCK; } - size_t NBYTES_INOUT () const { return d_NBYTES_INOUT; } + size_t BYTES_PER_SYMBOL () const { return d_BYTES_PER_SYMBOL; } }; diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_X.h.t b/gr-trellis/src/lib/trellis_sccc_decoder_X.h.t index 3adb8a5b7..93c9ac9b8 100644 --- a/gr-trellis/src/lib/trellis_sccc_decoder_X.h.t +++ b/gr-trellis/src/lib/trellis_sccc_decoder_X.h.t @@ -50,9 +50,9 @@ typedef boost::shared_ptr<@NAME@> @SPTR_NAME@; class @NAME@ : public gr_block { fsm d_FSMo; - fsm d_FSMi; int d_STo0; int d_SToK; + fsm d_FSMi; int d_STi0; int d_STiK; interleaver d_INTERLEAVER; diff --git a/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t index 146c26516..225a07ffe 100644 --- a/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t +++ b/gr-trellis/src/lib/trellis_sccc_decoder_combined_XX.h.t @@ -55,9 +55,9 @@ typedef boost::shared_ptr<@NAME@> @SPTR_NAME@; class @NAME@ : public gr_block { fsm d_FSMo; - fsm d_FSMi; int d_STo0; int d_SToK; + fsm d_FSMi; int d_STi0; int d_STiK; interleaver d_INTERLEAVER; diff --git a/gr-uhd/examples/tag_sink_demo.h b/gr-uhd/examples/tag_sink_demo.h new file mode 100644 index 000000000..84baf0a9c --- /dev/null +++ b/gr-uhd/examples/tag_sink_demo.h @@ -0,0 +1,66 @@ +/* + * 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_sync_block.h> +#include <gr_io_signature.h> +#include <gr_tag_info.h> +#include <boost/foreach.hpp> +#include <boost/format.hpp> +#include <iostream> +#include <complex> + +class tag_sink_demo : public gr_sync_block{ +public: + + tag_sink_demo(void): + gr_sync_block( + "uhd tag sink demo", + gr_make_io_signature(1, 1, sizeof(std::complex<float>)), + gr_make_io_signature(0, 0, 0) + ) + { + //NOP + } + + int work( + int ninput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ){ + //grab all "rx time" tags in this work call + const uint64_t samp0_count = this->nitems_read(0); + std::vector<pmt::pmt_t> rx_time_tags; + get_tags_in_range(rx_time_tags, 0, samp0_count, samp0_count + ninput_items, pmt::pmt_string_to_symbol("rx_time")); + + //print all tags + BOOST_FOREACH(const pmt::pmt_t &rx_time_tag, rx_time_tags){ + const uint64_t count = gr_tags::get_nitems(rx_time_tag); + const pmt::pmt_t &value = gr_tags::get_value(rx_time_tag); + + std::cout << boost::format("Full seconds %u, Frac seconds %f") + % pmt::pmt_to_uint64(pmt_tuple_ref(value, 0)) + % pmt::pmt_to_double(pmt_tuple_ref(value, 1)) + << std::endl; + } + + return ninput_items; + } +}; diff --git a/gr-uhd/examples/tag_source_demo.h b/gr-uhd/examples/tag_source_demo.h new file mode 100644 index 000000000..c7c0884d3 --- /dev/null +++ b/gr-uhd/examples/tag_source_demo.h @@ -0,0 +1,129 @@ +/* + * 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_sync_block.h> +#include <gr_io_signature.h> +#include <gr_tag_info.h> +#include <boost/foreach.hpp> +#include <boost/format.hpp> +#include <iostream> +#include <complex> + +class tag_source_demo : public gr_sync_block{ +public: + + tag_source_demo( + const uint64_t start_secs, + const double start_fracs, + const double samp_rate, + const double idle_duration, + const double burst_duration + ): + gr_sync_block( + "uhd tag source demo", + gr_make_io_signature(0, 0, 0), + gr_make_io_signature(1, 1, sizeof(std::complex<float>)) + ), + _time_secs(start_secs), + _time_fracs(start_fracs), + _samp_rate(samp_rate), + _samps_per_burst(samp_rate*burst_duration), + _cycle_duration(idle_duration + burst_duration), + _samps_left_in_burst(1), //immediate EOB + _do_new_burst(false) + { + //NOP + } + + void make_time_tag(const uint64_t tag_count){; + const pmt::pmt_t key = pmt::pmt_string_to_symbol("tx_time"); + const pmt::pmt_t value = pmt::pmt_make_tuple( + pmt::pmt_from_uint64(_time_secs), + pmt::pmt_from_double(_time_fracs) + ); + const pmt::pmt_t srcid = pmt::pmt_string_to_symbol(this->name()); + this->add_item_tag(0/*chan0*/, tag_count, key, value, srcid); + } + + void make_sob_tag(const uint64_t tag_count){ + const pmt::pmt_t key = pmt::pmt_string_to_symbol("tx_sob"); + const pmt::pmt_t value = pmt::PMT_T; + const pmt::pmt_t srcid = pmt::pmt_string_to_symbol(this->name()); + this->add_item_tag(0/*chan0*/, tag_count, key, value, srcid); + } + + void make_eob_tag(const uint64_t tag_count){; + const pmt::pmt_t key = pmt::pmt_string_to_symbol("tx_eob"); + const pmt::pmt_t value = pmt::PMT_T; + const pmt::pmt_t srcid = pmt::pmt_string_to_symbol(this->name()); + this->add_item_tag(0/*chan0*/, tag_count, key, value, srcid); + } + + int work( + int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items + ){ + //load the output with a constant + std::complex<float> *output = reinterpret_cast<std::complex<float> *>(output_items[0]); + for (size_t i = 0; i < size_t(noutput_items); i++){ + output[i] = std::complex<float>(0.7, 0.7); + } + + //Handle the start of burst condition. + //Tag a start of burst and timestamp. + //Increment the time for the next burst. + if (_do_new_burst){ + _do_new_burst = false; + _samps_left_in_burst = _samps_per_burst; + + this->make_sob_tag(this->nitems_written(0)); + this->make_time_tag(this->nitems_written(0)); + + _time_fracs += _cycle_duration; + double intpart; //normalize + _time_fracs = std::modf(_time_fracs, &intpart); + _time_secs += uint64_t(intpart); + } + + //Handle the end of burst condition. + //Tag an end of burst and return early. + //the next work call will be a start of burst. + if (_samps_left_in_burst < size_t(noutput_items)){ + this->make_eob_tag(this->nitems_written(0) + _samps_left_in_burst - 1); + _do_new_burst = true; + noutput_items = _samps_left_in_burst; + } + + _samps_left_in_burst -= noutput_items; + return noutput_items; + } + +private: + uint64_t _time_secs; + double _time_fracs; + const double _samp_rate; + const uint64_t _samps_per_burst; + const double _cycle_duration; + bool _do_new_burst; + uint64_t _samps_left_in_burst; + +}; diff --git a/gr-uhd/examples/tags_demo.cc b/gr-uhd/examples/tags_demo.cc new file mode 100644 index 000000000..b40518f34 --- /dev/null +++ b/gr-uhd/examples/tags_demo.cc @@ -0,0 +1,139 @@ +/* + * 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_top_block.h> +#include <gr_uhd_usrp_source.h> +#include <gr_uhd_usrp_sink.h> +#include <tag_source_demo.h> +#include <tag_sink_demo.h> +#include <boost/make_shared.hpp> +#include <boost/thread/thread.hpp> //sleep +#include <boost/program_options.hpp> +#include <csignal> +#include <iostream> + +namespace po = boost::program_options; + +/*********************************************************************** + * Signal handlers + **********************************************************************/ +static bool stop_signal_called = false; +void sig_int_handler(int){stop_signal_called = true;} + +/*********************************************************************** + * Main w/ program options + **********************************************************************/ +int main(int argc, char *argv[]){ + + std::string device_addr; + double center_freq, samp_rate, burst_dur, idle_dur; + + //setup the program options + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "help message") + ("addr", po::value<std::string>(&device_addr)->default_value(""), "the device address in string format") + ("rate", po::value<double>(&samp_rate)->default_value(1e6), "the sample rate in samples per second") + ("freq", po::value<double>(¢er_freq)->default_value(10e6), "the center frequency in Hz") + ("burst", po::value<double>(&burst_dur)->default_value(0.1), "the duration of each burst in seconds") + ("idle", po::value<double>(&idle_dur)->default_value(0.05), "idle time between bursts in seconds") + ; + po::variables_map vm; + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + //print the help message + if (vm.count("help")){ + std::cout + << boost::format("UHD Tags Demo %s") % desc << std::endl + << "The tags sink demo block will print USRP source time stamps." << std::endl + << "The tags source demo block will send bursts to the USRP sink." << std::endl + << "Look at the USRP output on a scope to see the timed bursts." << std::endl + << std::endl; + return ~0; + } + + //------------------------------------------------------------------ + //-- make a top block + //------------------------------------------------------------------ + gr_top_block_sptr tb = gr_make_top_block("tags_demo"); + + //------------------------------------------------------------------ + //-- make the usrp source test blocks + //------------------------------------------------------------------ + boost::shared_ptr<uhd_usrp_source> usrp_source = uhd_make_usrp_source( + device_addr, uhd::io_type_t::COMPLEX_FLOAT32, 1 + ); + usrp_source->set_samp_rate(samp_rate); + usrp_source->set_center_freq(center_freq); + + boost::shared_ptr<tag_sink_demo> tag_sink = boost::make_shared<tag_sink_demo>(); + + //------------------------------------------------------------------ + //-- connect the usrp source test blocks + //------------------------------------------------------------------ + tb->connect(usrp_source, 0, tag_sink, 0); + + //------------------------------------------------------------------ + //-- make the usrp sink test blocks + //------------------------------------------------------------------ + boost::shared_ptr<uhd_usrp_sink> usrp_sink = uhd_make_usrp_sink( + device_addr, uhd::io_type_t::COMPLEX_FLOAT32, 1 + ); + usrp_sink->set_samp_rate(samp_rate); + usrp_sink->set_center_freq(center_freq); + const uhd::time_spec_t time_now = usrp_sink->get_time_now(); + + boost::shared_ptr<tag_source_demo> tag_source = boost::make_shared<tag_source_demo>( + time_now.get_full_secs() + 1, time_now.get_frac_secs(), //time now + 1 second + samp_rate, idle_dur, burst_dur + ); + + //------------------------------------------------------------------ + //-- connect the usrp sink test blocks + //------------------------------------------------------------------ + tb->connect(tag_source, 0, usrp_sink, 0); + + //------------------------------------------------------------------ + //-- start flow graph execution + //------------------------------------------------------------------ + std::cout << "starting flow graph" << std::endl; + tb->start(); + + //------------------------------------------------------------------ + //-- poll the exit signal while running + //------------------------------------------------------------------ + std::signal(SIGINT, &sig_int_handler); + std::cout << "press ctrl + c to exit" << std::endl; + while (not stop_signal_called){ + boost::this_thread::sleep(boost::posix_time::milliseconds(100)); + } + + //------------------------------------------------------------------ + //-- stop flow graph execution + //------------------------------------------------------------------ + std::cout << "stopping flow graph" << std::endl; + tb->stop(); + tb->wait(); + + std::cout << "done!" << std::endl; + return 0; +} diff --git a/gr-uhd/grc/Makefile.am b/gr-uhd/grc/Makefile.am index 7e73a5b39..42a35b1c1 100644 --- a/gr-uhd/grc/Makefile.am +++ b/gr-uhd/grc/Makefile.am @@ -31,6 +31,7 @@ BUILT_SOURCES += $(generated_uhd_usrp_blocks) dist_grcblocks_DATA = \ uhd_block_tree.xml \ + uhd_amsg_source.xml \ $(BUILT_SOURCES) ######################################################################## diff --git a/gr-uhd/grc/gen_uhd_usrp_blocks.py b/gr-uhd/grc/gen_uhd_usrp_blocks.py index c77df6c97..b6bc5fb79 100644 --- a/gr-uhd/grc/gen_uhd_usrp_blocks.py +++ b/gr-uhd/grc/gen_uhd_usrp_blocks.py @@ -256,6 +256,8 @@ The center frequency is the overall frequency of the RF chain. \\ For greater control of how the UHD tunes elements in the RF chain, \\ pass a tune_request object rather than a simple target frequency. Tuning with an LO offset example: uhd.tune_request(freq, lo_off) +Tuning without DSP: uhd.tune_request(target_freq, dsp_freq=0, \\ +dsp_freq_policy=uhd.tune_request.POLICY_MANUAL) Antenna: For subdevices with only one antenna, this may be left blank. \\ @@ -266,6 +268,9 @@ Bandwidth: To use the default bandwidth filter setting, this should be zero. \\ Only certain subdevices have configurable bandwidth filters. \\ See the daughterboard application notes for possible configurations. + +See the UHD manual for more detailed documentation: +http://code.ettus.com/redmine/ettus/projects/uhd/wiki </doc> </block> """ diff --git a/gr-uhd/grc/uhd_amsg_source.xml b/gr-uhd/grc/uhd_amsg_source.xml new file mode 100644 index 000000000..78c9d7b58 --- /dev/null +++ b/gr-uhd/grc/uhd_amsg_source.xml @@ -0,0 +1,24 @@ +<?xml version="1.0"?> +<block> + <name>UHD: USRP Async Msg Source</name> + <key>uhd_amsg_source</key> + <import>from gnuradio import uhd</import> + <make>uhd.amsg_source(device_addr=$dev_addr, msgq=$(id)_msgq_out)</make> + <param> + <name>Device Addr</name> + <key>dev_addr</key> + <value></value> + <type>string</type> + <hide> + #if $dev_addr() + none + #else + part + #end if + </hide> + </param> + <source> + <name>out</name> + <type>msg</type> + </source> +</block> diff --git a/gr-uhd/grc/uhd_block_tree.xml b/gr-uhd/grc/uhd_block_tree.xml index 8a9f62f7c..5d3b49393 100644 --- a/gr-uhd/grc/uhd_block_tree.xml +++ b/gr-uhd/grc/uhd_block_tree.xml @@ -10,5 +10,6 @@ <name>UHD</name> <block>uhd_usrp_source</block> <block>uhd_usrp_sink</block> + <block>uhd_amsg_source</block> </cat> </cat> diff --git a/gr-uhd/include/Makefile.am b/gr-uhd/include/Makefile.am index 4a04c98c1..70b80681b 100644 --- a/gr-uhd/include/Makefile.am +++ b/gr-uhd/include/Makefile.am @@ -24,4 +24,5 @@ include $(top_srcdir)/Makefile.common grinclude_HEADERS = \ gr_uhd_api.h \ gr_uhd_usrp_source.h \ - gr_uhd_usrp_sink.h + gr_uhd_usrp_sink.h \ + gr_uhd_amsg_source.h diff --git a/gr-uhd/include/gr_uhd_amsg_source.h b/gr-uhd/include/gr_uhd_amsg_source.h new file mode 100644 index 000000000..bc0feb438 --- /dev/null +++ b/gr-uhd/include/gr_uhd_amsg_source.h @@ -0,0 +1,39 @@ +/* + * 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_UHD_AMSG_SOURCE_H +#define INCLUDED_GR_UHD_AMSG_SOURCE_H + +#include <gr_uhd_api.h> +#include <uhd/usrp/multi_usrp.hpp> +#include <gr_msg_queue.h> + +class uhd_amsg_source; + +GR_UHD_API boost::shared_ptr<uhd_amsg_source> uhd_make_amsg_source( + const uhd::device_addr_t &device_addr, + gr_msg_queue_sptr msgq +); + +class GR_UHD_API uhd_amsg_source{ +}; + +#endif /* INCLUDED_GR_UHD_AMSG_SOURCE_H */ diff --git a/gr-uhd/include/gr_uhd_usrp_sink.h b/gr-uhd/include/gr_uhd_usrp_sink.h index 320d07d41..c1fc3b09e 100644 --- a/gr-uhd/include/gr_uhd_usrp_sink.h +++ b/gr-uhd/include/gr_uhd_usrp_sink.h @@ -28,6 +28,33 @@ class uhd_usrp_sink; +/*! + * \brief Make a new USRP sink block. + * + * The USRP sink block reads a stream and transmits the samples. + * The sink block also provides API calls for transmitter settings. + * + * TX Stream tagging: + * + * The following tag keys will be consumed by the work function: + * - pmt::pmt_string_to_symbol("tx_sob") + * - pmt::pmt_string_to_symbol("tx_eob") + * - pmt::pmt_string_to_symbol("tx_time") + * + * The sob and eob (start and end of burst) tag values are pmt booleans. + * When present, burst tags should be set to true (pmt::PMT_T). + * + * The timstamp tag value is a pmt tuple of the following: + * (uint64 seconds, and double fractional seconds). + * + * See the UHD manual for more detailed documentation: + * http://code.ettus.com/redmine/ettus/projects/uhd/wiki + * + * \param device_addr the address to identify the hardware + * \param io_type the desired input data type + * \param num_channels number of stream from the device + * \return a new USRP sink block object + */ GR_UHD_API boost::shared_ptr<uhd_usrp_sink> uhd_make_usrp_sink( const uhd::device_addr_t &device_addr, const uhd::io_type_t &io_type, @@ -125,7 +152,6 @@ public: /*! * Get the actual dboard gain setting of named stage. - * \param name the name of the gain stage * \param chan the channel index 0 to N-1 * \return the actual gain in dB */ diff --git a/gr-uhd/include/gr_uhd_usrp_source.h b/gr-uhd/include/gr_uhd_usrp_source.h index 36331f782..f8ac9361e 100644 --- a/gr-uhd/include/gr_uhd_usrp_source.h +++ b/gr-uhd/include/gr_uhd_usrp_source.h @@ -28,6 +28,29 @@ class uhd_usrp_source; +/*! + * \brief Make a new USRP source block. + * + * The USRP source block receives samples and writes to a stream. + * The source block also provides API calls for receiver settings. + * + * RX Stream tagging: + * + * The following tag keys will be produced by the work function: + * - pmt::pmt_string_to_symbol("rx_time") + * + * The timstamp tag value is a pmt tuple of the following: + * (uint64 seconds, and double fractional seconds). + * A timestamp tag is produced at start() and after overflows. + * + * See the UHD manual for more detailed documentation: + * http://code.ettus.com/redmine/ettus/projects/uhd/wiki + * + * \param device_addr the address to identify the hardware + * \param io_type the desired output data type + * \param num_channels number of stream from the device + * \return a new USRP source block object + */ GR_UHD_API boost::shared_ptr<uhd_usrp_source> uhd_make_usrp_source( const uhd::device_addr_t &device_addr, const uhd::io_type_t &io_type, @@ -125,7 +148,6 @@ public: /*! * Get the actual dboard gain setting of named stage. - * \param name the name of the gain stage * \param chan the channel index 0 to N-1 * \return the actual gain in dB */ diff --git a/gr-uhd/lib/Makefile.am b/gr-uhd/lib/Makefile.am index c27682f7f..c322c6124 100644 --- a/gr-uhd/lib/Makefile.am +++ b/gr-uhd/lib/Makefile.am @@ -31,7 +31,8 @@ lib_LTLIBRARIES = libgnuradio-uhd.la libgnuradio_uhd_la_SOURCES = \ gr_uhd_usrp_source.cc \ - gr_uhd_usrp_sink.cc + gr_uhd_usrp_sink.cc \ + gr_uhd_amsg_source.cc libgnuradio_uhd_la_LIBADD = \ $(GNURADIO_CORE_LA) \ diff --git a/gr-uhd/lib/gr_uhd_amsg_source.cc b/gr-uhd/lib/gr_uhd_amsg_source.cc new file mode 100644 index 000000000..f2958f115 --- /dev/null +++ b/gr-uhd/lib/gr_uhd_amsg_source.cc @@ -0,0 +1,88 @@ +/* + * 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_uhd_amsg_source.h> +#include <boost/bind.hpp> +#include <gruel/thread.h> + +/*********************************************************************** + * UHD Asynchronous Message Source Impl + **********************************************************************/ +class uhd_amsg_source_impl : public uhd_amsg_source{ +public: + uhd_amsg_source_impl( + const uhd::device_addr_t &device_addr, + gr_msg_queue_sptr msgq + ): + _msgq(msgq), _running(true) + { + _dev = uhd::usrp::multi_usrp::make(device_addr); + _amsg_thread = + gruel::thread(boost::bind(&uhd_amsg_source_impl::recv_loop, this)); + } + + ~uhd_amsg_source_impl() + { + _running = false; + _amsg_thread.join(); + } + + void recv_loop() + { + gr_message_sptr msg; + uhd::async_metadata_t *md; + + while (_running) { + msg = gr_make_message(0, 0.0, 0.0, sizeof(uhd::async_metadata_t)); + md = (uhd::async_metadata_t *) msg->msg(); + + while (!_dev->get_device()->recv_async_msg(*md, 0.1)) { + if (!_running) + return; + } + + post(msg); + } + } + + void post(gr_message_sptr msg) + { + _msgq->insert_tail(msg); + } + +protected: + uhd::usrp::multi_usrp::sptr _dev; + gruel::thread _amsg_thread; + gr_msg_queue_sptr _msgq; + bool _running; +}; + +/*********************************************************************** + * Make UHD Asynchronous Message Source + **********************************************************************/ +boost::shared_ptr<uhd_amsg_source> uhd_make_amsg_source( + const uhd::device_addr_t &device_addr, + gr_msg_queue_sptr msgq +){ + return boost::shared_ptr<uhd_amsg_source>( + new uhd_amsg_source_impl(device_addr, msgq) + ); +} diff --git a/gr-uhd/lib/gr_uhd_usrp_sink.cc b/gr-uhd/lib/gr_uhd_usrp_sink.cc index ce9d89d8d..a780f0551 100644 --- a/gr-uhd/lib/gr_uhd_usrp_sink.cc +++ b/gr-uhd/lib/gr_uhd_usrp_sink.cc @@ -21,8 +21,13 @@ #include <gr_uhd_usrp_sink.h> #include <gr_io_signature.h> +#include <gr_tag_info.h> #include <stdexcept> +static const pmt::pmt_t SOB_KEY = pmt::pmt_string_to_symbol("tx_sob"); +static const pmt::pmt_t EOB_KEY = pmt::pmt_string_to_symbol("tx_eob"); +static const pmt::pmt_t TIME_KEY = pmt::pmt_string_to_symbol("tx_time"); + /*********************************************************************** * UHD Multi USRP Sink Impl **********************************************************************/ @@ -39,8 +44,7 @@ public: gr_make_io_signature(0, 0, 0) ), _type(io_type), - _nchan(num_channels), - _has_time_spec(_nchan > 1) + _nchan(num_channels) { _dev = uhd::usrp::multi_usrp::make(device_addr); } @@ -180,13 +184,20 @@ public: gr_vector_const_void_star &input_items, gr_vector_void_star &output_items ){ + int ninput_items = noutput_items; //cuz its a sync block + //send a mid-burst packet with time spec _metadata.start_of_burst = false; _metadata.end_of_burst = false; - _metadata.has_time_spec = _has_time_spec; - size_t num_sent = _dev->get_device()->send( - input_items, noutput_items, _metadata, + //collect tags in this work() + const uint64_t samp0_count = nitems_read(0); + get_tags_in_range(_tags, 0, samp0_count, samp0_count + ninput_items); + if (not _tags.empty()) this->tag_work(ninput_items); + + //send all ninput_items with metadata + const size_t num_sent = _dev->get_device()->send( + input_items, ninput_items, _metadata, _type, uhd::device::SEND_MODE_FULL_BUFF, 1.0 ); @@ -195,12 +206,70 @@ public: return num_sent; } +/*********************************************************************** + * Tag Work + **********************************************************************/ + inline void tag_work(int &ninput_items){ + //the for loop below assumes tags sorted by count low -> high + std::sort(_tags.begin(), _tags.end(), gr_tags::nitems_compare); + + //extract absolute sample counts + const pmt::pmt_t &tag0 = _tags.front(); + const uint64_t tag0_count = gr_tags::get_nitems(tag0); + const uint64_t samp0_count = this->nitems_read(0); + + //only transmit nsamples from 0 to the first tag + //this ensures that the next work starts on a tag + if (samp0_count != tag0_count){ + ninput_items = tag0_count - samp0_count; + return; + } + + //time will not be set unless a time tag is found + _metadata.has_time_spec = false; + + //process all of the tags found with the same count as tag0 + BOOST_FOREACH(const pmt::pmt_t &my_tag, _tags){ + const uint64_t my_tag_count = gr_tags::get_nitems(my_tag); + const pmt::pmt_t &key = gr_tags::get_key(my_tag); + const pmt::pmt_t &value = gr_tags::get_value(my_tag); + + //determine how many samples to send... + //from zero until the next tag or end of work + if (my_tag_count != tag0_count){ + ninput_items = my_tag_count - samp0_count; + break; + } + + //handle end of burst with a mini end of burst packet + else if (pmt::pmt_equal(key, EOB_KEY)){ + _metadata.end_of_burst = pmt::pmt_to_bool(value); + ninput_items = 1; + return; + } + + //set the start of burst flag in the metadata + else if (pmt::pmt_equal(key, SOB_KEY)){ + _metadata.start_of_burst = pmt::pmt_to_bool(value); + } + + //set the time specification in the metadata + else if (pmt::pmt_equal(key, TIME_KEY)){ + _metadata.has_time_spec = true; + _metadata.time_spec = uhd::time_spec_t( + pmt::pmt_to_uint64(pmt_tuple_ref(value, 0)), + pmt::pmt_to_double(pmt_tuple_ref(value, 1)) + ); + } + } + } + //Send an empty start-of-burst packet to begin streaming. //Set at a time in the near future to avoid late packets. bool start(void){ _metadata.start_of_burst = true; _metadata.end_of_burst = false; - _metadata.has_time_spec = _has_time_spec; + _metadata.has_time_spec = _nchan > 1; _metadata.time_spec = get_time_now() + uhd::time_spec_t(0.01); _dev->get_device()->send( @@ -224,13 +293,15 @@ public: return true; } -protected: +private: uhd::usrp::multi_usrp::sptr _dev; const uhd::io_type_t _type; size_t _nchan; - bool _has_time_spec; uhd::tx_metadata_t _metadata; double _sample_rate; + + //stream tags related stuff + std::vector<pmt::pmt_t> _tags; }; /*********************************************************************** diff --git a/gr-uhd/lib/gr_uhd_usrp_source.cc b/gr-uhd/lib/gr_uhd_usrp_source.cc index 669f890ea..62da83d96 100644 --- a/gr-uhd/lib/gr_uhd_usrp_source.cc +++ b/gr-uhd/lib/gr_uhd_usrp_source.cc @@ -25,6 +25,8 @@ #include <iostream> #include <boost/format.hpp> +static const pmt::pmt_t TIME_KEY = pmt::pmt_string_to_symbol("rx_time"); + /*********************************************************************** * UHD Multi USRP Source Impl **********************************************************************/ @@ -43,8 +45,11 @@ public: _type(io_type), _nchan(num_channels), _stream_now(_nchan == 1), - _tmp_buffs(_nchan) + _tag_now(false) { + std::stringstream str; + str << name() << unique_id(); + _id = pmt::pmt_string_to_symbol(str.str()); _dev = uhd::usrp::multi_usrp::make(device_addr); } @@ -202,7 +207,18 @@ public: //handle possible errors conditions switch(_metadata.error_code){ case uhd::rx_metadata_t::ERROR_CODE_NONE: - //TODO insert tag for time stamp + if (_tag_now){ + _tag_now = false; + //create a timestamp pmt for the first sample + const pmt::pmt_t val = pmt::pmt_make_tuple( + pmt::pmt_from_uint64(_metadata.time_spec.get_full_secs()), + pmt::pmt_from_double(_metadata.time_spec.get_frac_secs()) + ); + //create a timestamp tag for each channel + for (size_t i = 0; i < _nchan; i++){ + this->add_item_tag(i, nitems_written(0), TIME_KEY, val, _id); + } + } break; case uhd::rx_metadata_t::ERROR_CODE_TIMEOUT: @@ -211,8 +227,8 @@ public: return WORK_DONE; case uhd::rx_metadata_t::ERROR_CODE_OVERFLOW: + _tag_now = true; //ignore overflows and try work again - //TODO insert tag for overflow return work(noutput_items, input_items, output_items); default: @@ -232,6 +248,7 @@ public: stream_cmd.stream_now = _stream_now; stream_cmd.time_spec = get_time_now() + uhd::time_spec_t(reasonable_delay); _dev->issue_stream_cmd(stream_cmd); + _tag_now = true; return true; } @@ -244,9 +261,9 @@ private: uhd::usrp::multi_usrp::sptr _dev; const uhd::io_type_t _type; size_t _nchan; - bool _stream_now; - gr_vector_void_star _tmp_buffs; + bool _stream_now, _tag_now; uhd::rx_metadata_t _metadata; + pmt::pmt_t _id; }; diff --git a/gr-uhd/swig/__init__.py b/gr-uhd/swig/__init__.py index 7ed689ec0..1f82b4a26 100644 --- a/gr-uhd/swig/__init__.py +++ b/gr-uhd/swig/__init__.py @@ -32,9 +32,13 @@ def _prepare_uhd_swig(): #Make the python tune request object inherit from float #so that it can be passed in GRC as a frequency parameter. #The type checking in GRC will accept the tune request. + #Also use kwargs to construct individual struct elements. class tune_request_t(uhd_swig.tune_request_t, float): - def __new__(self, *args): return float.__new__(self) + def __new__(self, *args, **kwargs): return float.__new__(self) def __float__(self): return self.target_freq + def __init__(self, *args, **kwargs): + super(tune_request_t, self).__init__(*args) + for key, val in kwargs.iteritems(): setattr(self, key, val) setattr(uhd_swig, 'tune_request_t', tune_request_t) #Make the python tune request object inherit from string @@ -60,7 +64,7 @@ def _prepare_uhd_swig(): if attr.endswith('_t'): setattr(uhd_swig, attr[:-2], myobj) #Cast constructor args (FIXME swig handle overloads?) - for attr in ('usrp_source', 'usrp_sink'): + for attr in ('usrp_source', 'usrp_sink', 'amsg_source'): def constructor_factory(old_constructor): def constructor_interceptor(*args, **kwargs): args = list(args) diff --git a/gr-uhd/swig/uhd_swig.i b/gr-uhd/swig/uhd_swig.i index 9bdb962c9..b58fe9e18 100644 --- a/gr-uhd/swig/uhd_swig.i +++ b/gr-uhd/swig/uhd_swig.i @@ -55,6 +55,7 @@ %{ #include <gr_uhd_usrp_source.h> #include <gr_uhd_usrp_sink.h> +#include <gr_uhd_amsg_source.h> %} //////////////////////////////////////////////////////////////////////// @@ -114,6 +115,9 @@ GR_SWIG_BLOCK_MAGIC(uhd,usrp_source) GR_SWIG_BLOCK_MAGIC(uhd,usrp_sink) %include <gr_uhd_usrp_sink.h> +GR_SWIG_BLOCK_MAGIC(uhd,amsg_source) +%include <gr_uhd_amsg_source.h> + //////////////////////////////////////////////////////////////////////// // helpful constants //////////////////////////////////////////////////////////////////////// diff --git a/gr-cvsd-vocoder/.gitignore b/gr-vocoder/.gitignore index a37fc0c1a..a37fc0c1a 100644 --- a/gr-cvsd-vocoder/.gitignore +++ b/gr-vocoder/.gitignore diff --git a/gr-vocoder/Makefile.am b/gr-vocoder/Makefile.am new file mode 100644 index 000000000..c280358a8 --- /dev/null +++ b/gr-vocoder/Makefile.am @@ -0,0 +1,31 @@ +# +# 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 $(top_srcdir)/Makefile.common + +SUBDIRS = include lib python swig grc apps examples doc + +if PYTHON +SUBDIRS += python swig +endif + +pkgconfigdir = $(libdir)/pkgconfig +dist_pkgconfig_DATA = gnuradio-vocoder.pc diff --git a/gr-vocoder/apps/.gitignore b/gr-vocoder/apps/.gitignore new file mode 100644 index 000000000..b336cc7ce --- /dev/null +++ b/gr-vocoder/apps/.gitignore @@ -0,0 +1,2 @@ +/Makefile +/Makefile.in diff --git a/gr-cvsd-vocoder/src/Makefile.am b/gr-vocoder/apps/Makefile.am index be38b7c1a..b1c7b44d5 100644 --- a/gr-cvsd-vocoder/src/Makefile.am +++ b/gr-vocoder/apps/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -19,7 +19,6 @@ # Boston, MA 02110-1301, USA. # -SUBDIRS = lib -if PYTHON -SUBDIRS += python -endif +include $(top_srcdir)/Makefile.common + +SUBDIRS = diff --git a/gr-vocoder/doc/.gitignore b/gr-vocoder/doc/.gitignore new file mode 100644 index 000000000..b336cc7ce --- /dev/null +++ b/gr-vocoder/doc/.gitignore @@ -0,0 +1,2 @@ +/Makefile +/Makefile.in diff --git a/gnuradio-core/src/python/gnuradio/vocoder/Makefile.am b/gr-vocoder/doc/Makefile.am index 69c140c10..b1c7b44d5 100644 --- a/gnuradio-core/src/python/gnuradio/vocoder/Makefile.am +++ b/gr-vocoder/doc/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2007 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,6 +21,4 @@ include $(top_srcdir)/Makefile.common -grvocoderpythondir = $(grpythondir)/vocoder -grvocoderpython_PYTHON = \ - __init__.py +SUBDIRS = diff --git a/gr-vocoder/examples/.gitignore b/gr-vocoder/examples/.gitignore new file mode 100644 index 000000000..0a864cc38 --- /dev/null +++ b/gr-vocoder/examples/.gitignore @@ -0,0 +1,3 @@ +/Makefile +/Makefile.in + diff --git a/gr-vocoder/examples/Makefile.am b/gr-vocoder/examples/Makefile.am new file mode 100644 index 000000000..32176cf23 --- /dev/null +++ b/gr-vocoder/examples/Makefile.am @@ -0,0 +1,34 @@ +# +# 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 $(top_srcdir)/Makefile.common + +ourdatadir = $(exampledir)/vocoder + +dist_ourdata_SCRIPTS = \ + alaw_audio_loopback.py \ + codec2_audio_loopback.py \ + cvsd_audio_loopback.py \ + g721_audio_loopback.py \ + g723_24_audio_loopback.py \ + g723_40_audio_loopback.py \ + gsm_audio_loopback.py \ + ulaw_audio_loopback.py diff --git a/gr-gsm-fr-vocoder/src/python/encdec.py b/gr-vocoder/examples/alaw_audio_loopback.py index 94e4e5b82..8fdd64d44 100755 --- a/gr-gsm-fr-vocoder/src/python/encdec.py +++ b/gr-vocoder/examples/alaw_audio_loopback.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2007 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,15 +22,15 @@ from gnuradio import gr from gnuradio import audio -from gnuradio.vocoder import gsm_full_rate +from gnuradio import vocoder def build_graph(): tb = gr.top_block() src = audio.source(8000) src_scale = gr.multiply_const_ff(32767) f2s = gr.float_to_short () - enc = gsm_full_rate.encode_sp() - dec = gsm_full_rate.decode_ps() + enc = vocoder.alaw_encode_sb() + dec = vocoder.alaw_decode_bs() s2f = gr.short_to_float () sink_scale = gr.multiply_const_ff(1.0/32767.) sink = audio.sink(8000) @@ -42,3 +42,4 @@ if __name__ == '__main__': tb.start() raw_input ('Press Enter to exit: ') tb.stop() + tb.wait() diff --git a/gr-vocoder/examples/codec2_audio_loopback.py b/gr-vocoder/examples/codec2_audio_loopback.py new file mode 100755 index 000000000..54b453f8a --- /dev/null +++ b/gr-vocoder/examples/codec2_audio_loopback.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# +# Copyright 2005,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. +# + +from gnuradio import gr +from gnuradio import audio +from gnuradio import vocoder + +def build_graph(): + tb = gr.top_block() + src = audio.source(8000) + src_scale = gr.multiply_const_ff(32767) + f2s = gr.float_to_short () + enc = vocoder.codec2_encode_sp() + dec = vocoder.codec2_decode_ps() + s2f = gr.short_to_float () + sink_scale = gr.multiply_const_ff(1.0/32767.) + sink = audio.sink(8000) + tb.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) + return tb + +if __name__ == '__main__': + tb = build_graph() + tb.start() + raw_input ('Press Enter to exit: ') + tb.stop() + tb.wait() diff --git a/gr-cvsd-vocoder/src/python/encdec.py b/gr-vocoder/examples/cvsd_audio_loopback.py index 34c153b06..7f2a00dbf 100755 --- a/gr-cvsd-vocoder/src/python/encdec.py +++ b/gr-vocoder/examples/cvsd_audio_loopback.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2007 Free Software Foundation, Inc. +# Copyright 2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,7 +22,7 @@ from gnuradio import gr, blks2 from gnuradio import audio -from gnuradio.vocoder import cvsd_vocoder +from gnuradio import vocoder def build_graph(): sample_rate = 8000 @@ -35,8 +35,8 @@ def build_graph(): interp = blks2.rational_resampler_fff(8, 1) f2s = gr.float_to_short () - enc = cvsd_vocoder.encode_sb() - dec = cvsd_vocoder.decode_bs() + enc = vocoder.cvsd_encode_sb() + dec = vocoder.cvsd_decode_bs() s2f = gr.short_to_float () decim = blks2.rational_resampler_fff(1, 8) @@ -62,8 +62,7 @@ def build_graph(): if __name__ == '__main__': tb = build_graph() - print "Enter CTRL-C to stop" - try: - tb.run() - except KeyboardInterrupt: - pass + tb.start() + raw_input ('Press Enter to exit: ') + tb.stop() + tb.wait() diff --git a/gr-vocoder/examples/g721_audio_loopback.py b/gr-vocoder/examples/g721_audio_loopback.py new file mode 100755 index 000000000..8b5bc8f33 --- /dev/null +++ b/gr-vocoder/examples/g721_audio_loopback.py @@ -0,0 +1,45 @@ +#!/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 +from gnuradio import audio +from gnuradio import vocoder + +def build_graph(): + tb = gr.top_block() + src = audio.source(8000) + src_scale = gr.multiply_const_ff(32767) + f2s = gr.float_to_short () + enc = vocoder.g721_encode_sb() + dec = vocoder.g721_decode_bs() + s2f = gr.short_to_float () + sink_scale = gr.multiply_const_ff(1.0/32767.) + sink = audio.sink(8000) + tb.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) + return tb + +if __name__ == '__main__': + tb = build_graph() + tb.start() + raw_input ('Press Enter to exit: ') + tb.stop() + tb.wait() diff --git a/gr-vocoder/examples/g723_24_audio_loopback.py b/gr-vocoder/examples/g723_24_audio_loopback.py new file mode 100755 index 000000000..f125282dc --- /dev/null +++ b/gr-vocoder/examples/g723_24_audio_loopback.py @@ -0,0 +1,45 @@ +#!/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 +from gnuradio import audio +from gnuradio import vocoder + +def build_graph(): + tb = gr.top_block() + src = audio.source(8000) + src_scale = gr.multiply_const_ff(32767) + f2s = gr.float_to_short () + enc = vocoder.g723_24_encode_sb() + dec = vocoder.g723_24_decode_bs() + s2f = gr.short_to_float () + sink_scale = gr.multiply_const_ff(1.0/32767.) + sink = audio.sink(8000) + tb.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) + return tb + +if __name__ == '__main__': + tb = build_graph() + tb.start() + raw_input ('Press Enter to exit: ') + tb.stop() + tb.wait() diff --git a/gr-vocoder/examples/g723_40_audio_loopback.py b/gr-vocoder/examples/g723_40_audio_loopback.py new file mode 100755 index 000000000..cd2ea5ff1 --- /dev/null +++ b/gr-vocoder/examples/g723_40_audio_loopback.py @@ -0,0 +1,45 @@ +#!/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 +from gnuradio import audio +from gnuradio import vocoder + +def build_graph(): + tb = gr.top_block() + src = audio.source(8000) + src_scale = gr.multiply_const_ff(32767) + f2s = gr.float_to_short () + enc = vocoder.g723_40_encode_sb() + dec = vocoder.g723_40_decode_bs() + s2f = gr.short_to_float () + sink_scale = gr.multiply_const_ff(1.0/32767.) + sink = audio.sink(8000) + tb.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) + return tb + +if __name__ == '__main__': + tb = build_graph() + tb.start() + raw_input ('Press Enter to exit: ') + tb.stop() + tb.wait() diff --git a/gr-vocoder/examples/gsm_audio_loopback.py b/gr-vocoder/examples/gsm_audio_loopback.py new file mode 100755 index 000000000..f4e96f471 --- /dev/null +++ b/gr-vocoder/examples/gsm_audio_loopback.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +# +# Copyright 2005,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. +# + +from gnuradio import gr +from gnuradio import audio +from gnuradio import vocoder + +def build_graph(): + tb = gr.top_block() + src = audio.source(8000) + src_scale = gr.multiply_const_ff(32767) + f2s = gr.float_to_short () + enc = vocoder.gsm_fr_encode_sp() + dec = vocoder.gsm_fr_decode_ps() + s2f = gr.short_to_float () + sink_scale = gr.multiply_const_ff(1.0/32767.) + sink = audio.sink(8000) + tb.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) + return tb + +if __name__ == '__main__': + tb = build_graph() + tb.start() + raw_input ('Press Enter to exit: ') + tb.stop() + tb.wait() diff --git a/gr-vocoder/examples/ulaw_audio_loopback.py b/gr-vocoder/examples/ulaw_audio_loopback.py new file mode 100755 index 000000000..afe0921fa --- /dev/null +++ b/gr-vocoder/examples/ulaw_audio_loopback.py @@ -0,0 +1,45 @@ +#!/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 +from gnuradio import audio +from gnuradio import vocoder + +def build_graph(): + tb = gr.top_block() + src = audio.source(8000) + src_scale = gr.multiply_const_ff(32767) + f2s = gr.float_to_short () + enc = vocoder.ulaw_encode_sb() + dec = vocoder.ulaw_decode_bs() + s2f = gr.short_to_float () + sink_scale = gr.multiply_const_ff(1.0/32767.) + sink = audio.sink(8000) + tb.connect(src, src_scale, f2s, enc, dec, s2f, sink_scale, sink) + return tb + +if __name__ == '__main__': + tb = build_graph() + tb.start() + raw_input ('Press Enter to exit: ') + tb.stop() + tb.wait() diff --git a/gr-cvsd-vocoder/gnuradio-cvsd-vocoder.pc.in b/gr-vocoder/gnuradio-vocoder.pc.in index f5f0c2e64..7ff4420b6 100644 --- a/gr-cvsd-vocoder/gnuradio-cvsd-vocoder.pc.in +++ b/gr-vocoder/gnuradio-vocoder.pc.in @@ -3,9 +3,9 @@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ -Name: gnuradio-cvsd-vocoder -Description: GNU Radio blocks implementing a CVSD vocoder +Name: gnuradio-vocoder +Description: GNU Radio blocks implementing voice codecs Requires: gnuradio-core Version: @LIBVER@ -Libs: -L${libdir} -lgnuradio-cvsd-vocoder +Libs: -L${libdir} -lgnuradio-vocoder Cflags: -I${includedir} diff --git a/gr-cvsd-vocoder/src/lib/.gitignore b/gr-vocoder/grc/.gitignore index ea0a01678..d2e2e9ce8 100644 --- a/gr-cvsd-vocoder/src/lib/.gitignore +++ b/gr-vocoder/grc/.gitignore @@ -2,8 +2,6 @@ /Makefile.in /.libs /.deps -/cvsd_vocoder.cc -/cvsd_vocoder.py* /gnuradio /guile /python diff --git a/gr-cvsd-vocoder/Makefile.am b/gr-vocoder/grc/Makefile.am index 48807a34b..b1c7b44d5 100644 --- a/gr-cvsd-vocoder/Makefile.am +++ b/gr-vocoder/grc/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,7 +21,4 @@ include $(top_srcdir)/Makefile.common -SUBDIRS = src - -pkgconfigdir = $(libdir)/pkgconfig -dist_pkgconfig_DATA = gnuradio-cvsd-vocoder.pc +SUBDIRS = diff --git a/gr-vocoder/include/.gitignore b/gr-vocoder/include/.gitignore new file mode 100644 index 000000000..b336cc7ce --- /dev/null +++ b/gr-vocoder/include/.gitignore @@ -0,0 +1,2 @@ +/Makefile +/Makefile.in diff --git a/gr-vocoder/include/Makefile.am b/gr-vocoder/include/Makefile.am new file mode 100644 index 000000000..aab77e3f9 --- /dev/null +++ b/gr-vocoder/include/Makefile.am @@ -0,0 +1,41 @@ +# +# 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 $(top_srcdir)/Makefile.common + +# C/C++ headers get installed in ${prefix}/include/gnuradio +grinclude_HEADERS = \ + vocoder_alaw_decode_bs.h \ + vocoder_alaw_encode_sb.h \ + vocoder_codec2_decode_ps.h \ + vocoder_codec2_encode_sp.h \ + vocoder_cvsd_decode_bs.h \ + vocoder_cvsd_encode_sb.h \ + vocoder_g721_decode_bs.h \ + vocoder_g721_encode_sb.h \ + vocoder_g723_24_decode_bs.h \ + vocoder_g723_24_encode_sb.h \ + vocoder_g723_40_decode_bs.h \ + vocoder_g723_40_encode_sb.h \ + vocoder_gsm_fr_decode_ps.h \ + vocoder_gsm_fr_encode_sp.h \ + vocoder_ulaw_decode_bs.h \ + vocoder_ulaw_encode_sb.h diff --git a/gr-vocoder/include/vocoder_alaw_decode_bs.h b/gr-vocoder/include/vocoder_alaw_decode_bs.h new file mode 100644 index 000000000..b71569439 --- /dev/null +++ b/gr-vocoder/include/vocoder_alaw_decode_bs.h @@ -0,0 +1,55 @@ +/* -*- 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_VOCODER_ALAW_DECODE_BS_H +#define INCLUDED_VOCODER_ALAW_DECODE_BS_H + +#include <gr_sync_block.h> + +class vocoder_alaw_decode_bs; + +typedef boost::shared_ptr<vocoder_alaw_decode_bs> vocoder_alaw_decode_bs_sptr; + +vocoder_alaw_decode_bs_sptr vocoder_make_alaw_decode_bs(); + +/*! + * \brief This block performs alaw audio decoding. + * + * \ingroup vocoder_blk + */ + +class vocoder_alaw_decode_bs : public gr_sync_block +{ +private: + friend vocoder_alaw_decode_bs_sptr vocoder_make_alaw_decode_bs(); + + vocoder_alaw_decode_bs(); + + public: + ~vocoder_alaw_decode_bs(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_VOCODER_ALAW_DECODE_BS_H */ diff --git a/gr-vocoder/include/vocoder_alaw_encode_sb.h b/gr-vocoder/include/vocoder_alaw_encode_sb.h new file mode 100644 index 000000000..d1858d048 --- /dev/null +++ b/gr-vocoder/include/vocoder_alaw_encode_sb.h @@ -0,0 +1,54 @@ +/* -*- 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_VOCODER_ALAW_ENCODER_SB_H +#define INCLUDED_VOCODER_ALAW_ENCODER_SB_H + +#include <gr_sync_block.h> + +class vocoder_alaw_encode_sb; + +typedef boost::shared_ptr<vocoder_alaw_encode_sb> vocoder_alaw_encode_sb_sptr; + +vocoder_alaw_encode_sb_sptr vocoder_make_alaw_encode_sb(); + +/*! + * \brief This block performs g.711 alaw audio encoding. + * + * \ingroup vocoder_blk + */ +class vocoder_alaw_encode_sb : public gr_sync_block +{ +private: + friend vocoder_alaw_encode_sb_sptr vocoder_make_alaw_encode_sb(); + + vocoder_alaw_encode_sb(); + + public: + ~vocoder_alaw_encode_sb(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_VOCODER_ALAW_ENCODE_SB_H */ diff --git a/gr-vocoder/include/vocoder_codec2_decode_ps.h b/gr-vocoder/include/vocoder_codec2_decode_ps.h new file mode 100644 index 000000000..02b80a454 --- /dev/null +++ b/gr-vocoder/include/vocoder_codec2_decode_ps.h @@ -0,0 +1,50 @@ +/* -*- 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_VOCODER_CODEC2_DECODE_PS_H +#define INCLUDED_VOCODER_CODEC2_DECODE_PS_H + +#include <gr_sync_interpolator.h> + +class vocoder_codec2_decode_ps; +typedef boost::shared_ptr<vocoder_codec2_decode_ps> vocoder_codec2_decode_ps_sptr; + +vocoder_codec2_decode_ps_sptr vocoder_make_codec2_decode_ps (); + +/*! + * \brief CODEC2 Vocoder Decoder + * \ingroup vocoder_blk + */ +class vocoder_codec2_decode_ps : public gr_sync_interpolator { + void *d_codec2; + + friend vocoder_codec2_decode_ps_sptr vocoder_make_codec2_decode_ps (); + vocoder_codec2_decode_ps (); + +public: + ~vocoder_codec2_decode_ps (); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_VOCODER_CODEC2_DECODE_PS_H */ diff --git a/gr-vocoder/include/vocoder_codec2_encode_sp.h b/gr-vocoder/include/vocoder_codec2_encode_sp.h new file mode 100644 index 000000000..de4784f8d --- /dev/null +++ b/gr-vocoder/include/vocoder_codec2_encode_sp.h @@ -0,0 +1,50 @@ +/* -*- 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_VOCODER_CODEC2_ENCODE_SP_H +#define INCLUDED_VOCODER_CODEC2_ENCODE_SP_H + +#include <gr_sync_decimator.h> + +class vocoder_codec2_encode_sp; +typedef boost::shared_ptr<vocoder_codec2_encode_sp> vocoder_codec2_encode_sp_sptr; + +vocoder_codec2_encode_sp_sptr vocoder_make_codec2_encode_sp (); + +/*! + * \brief CODEC2 Vocoder Encoder + * \ingroup vocoder_blk + */ +class vocoder_codec2_encode_sp : public gr_sync_decimator { + void *d_codec2; + + friend vocoder_codec2_encode_sp_sptr vocoder_make_codec2_encode_sp (); + vocoder_codec2_encode_sp (); + +public: + ~vocoder_codec2_encode_sp (); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_VOCODER_CODEC2_ENCODE_SP_H */ diff --git a/gr-cvsd-vocoder/src/lib/cvsd_decode_bs.h b/gr-vocoder/include/vocoder_cvsd_decode_bs.h index f7b50909f..dd588c661 100644 --- a/gr-cvsd-vocoder/src/lib/cvsd_decode_bs.h +++ b/gr-vocoder/include/vocoder_cvsd_decode_bs.h @@ -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 * @@ -19,14 +19,15 @@ * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ -#ifndef INCLUDED_CVSD_DECODE_BS_H -#define INCLUDED_CVSD_DECODE_BS_H + +#ifndef INCLUDED_VOCODER_CVSD_DECODE_BS_H +#define INCLUDED_VOCODER_CVSD_DECODE_BS_H #include <gr_sync_interpolator.h> -class cvsd_decode_bs; +class vocoder_cvsd_decode_bs; -typedef boost::shared_ptr<cvsd_decode_bs> cvsd_decode_bs_sptr; +typedef boost::shared_ptr<vocoder_cvsd_decode_bs> vocoder_cvsd_decode_bs_sptr; /*! * \brief Constructor parameters to initialize the CVSD decoder. The default @@ -43,14 +44,14 @@ typedef boost::shared_ptr<cvsd_decode_bs> cvsd_decode_bs_sptr; * \param neg_accum_max Minimum integer value allowed for the internal reference. Default: "-32767" (-2^15 + 1 or MINSHORT+1) * */ -cvsd_decode_bs_sptr cvsd_make_decode_bs (short min_step=10, - short max_step=1280, - double step_decay=0.9990234375, - double accum_decay= 0.96875, - int K=32, - int J=4, - short pos_accum_max=32767, - short neg_accum_max=-32767); +vocoder_cvsd_decode_bs_sptr vocoder_make_cvsd_decode_bs (short min_step=10, + short max_step=1280, + double step_decay=0.9990234375, + double accum_decay= 0.96875, + int K=32, + int J=4, + short pos_accum_max=32767, + short neg_accum_max=-32767); /*! * \brief This block performs CVSD audio decoding. Its design and implementation @@ -104,21 +105,21 @@ cvsd_decode_bs_sptr cvsd_make_decode_bs (short min_step=10, * */ -class cvsd_decode_bs : public gr_sync_interpolator +class vocoder_cvsd_decode_bs : public gr_sync_interpolator { private: - friend cvsd_decode_bs_sptr cvsd_make_decode_bs (short min_step, - short max_step, - double step_decay, - double accum_decay, - int K, - int J, - short pos_accum_max, - short neg_accum_max); - - cvsd_decode_bs (short min_step, short max_step, double step_decay, - double accum_decay, int K, int J, - short pos_accum_max, short neg_accum_max); + friend vocoder_cvsd_decode_bs_sptr vocoder_make_cvsd_decode_bs (short min_step, + short max_step, + double step_decay, + double accum_decay, + int K, + int J, + short pos_accum_max, + short neg_accum_max); + + vocoder_cvsd_decode_bs (short min_step, short max_step, double step_decay, + double accum_decay, int K, int J, + short pos_accum_max, short neg_accum_max); //! Member functions required by the encoder/decoder //! \brief Rounding function specific to CVSD @@ -151,7 +152,7 @@ private: short d_stepsize; //!< \brief Current value of the step sizer public: - ~cvsd_decode_bs (); // public destructor + ~vocoder_cvsd_decode_bs (); // public destructor short min_step() { return d_min_step; } short max_step() { return d_max_step; } @@ -167,4 +168,4 @@ private: gr_vector_void_star &output_items); }; -#endif /* INCLUDED_CVSD_DECODE_BS_H */ +#endif /* INCLUDED_VOCODER_CVSD_DECODE_BS_H */ diff --git a/gr-cvsd-vocoder/src/lib/cvsd_encode_sb.h b/gr-vocoder/include/vocoder_cvsd_encode_sb.h index a7994d4ed..da09b3927 100644 --- a/gr-cvsd-vocoder/src/lib/cvsd_encode_sb.h +++ b/gr-vocoder/include/vocoder_cvsd_encode_sb.h @@ -19,14 +19,14 @@ * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ -#ifndef INCLUDED_CVSD_ENCODER_SB_H -#define INCLUDED_CVSD_ENCODER_SB_H +#ifndef INCLUDED_VOCODER_CVSD_ENCODER_SB_H +#define INCLUDED_VOCODER_CVSD_ENCODER_SB_H #include <gr_sync_decimator.h> -class cvsd_encode_sb; +class vocoder_cvsd_encode_sb; -typedef boost::shared_ptr<cvsd_encode_sb> cvsd_encode_sb_sptr; +typedef boost::shared_ptr<vocoder_cvsd_encode_sb> vocoder_cvsd_encode_sb_sptr; /*! * \brief Constructor parameters to initialize the CVSD encoder. The default @@ -44,14 +44,14 @@ typedef boost::shared_ptr<cvsd_encode_sb> cvsd_encode_sb_sptr; * */ -cvsd_encode_sb_sptr cvsd_make_encode_sb (short min_step=10, - short max_step=1280, - double step_decay=0.9990234375, - double accum_decay= 0.96875, - int K=32, - int J=4, - short pos_accum_max=32767, - short neg_accum_max=-32767); +vocoder_cvsd_encode_sb_sptr vocoder_make_cvsd_encode_sb(short min_step=10, + short max_step=1280, + double step_decay=0.9990234375, + double accum_decay= 0.96875, + int K=32, + int J=4, + short pos_accum_max=32767, + short neg_accum_max=-32767); /*! * \brief This block performs CVSD audio encoding. Its design and implementation @@ -107,21 +107,21 @@ cvsd_encode_sb_sptr cvsd_make_encode_sb (short min_step=10, * */ -class cvsd_encode_sb : public gr_sync_decimator +class vocoder_cvsd_encode_sb : public gr_sync_decimator { private: - friend cvsd_encode_sb_sptr cvsd_make_encode_sb (short min_step, - short max_step, - double step_decay, - double accum_decay, - int K, - int J, - short pos_accum_max, - short neg_accum_max); + friend vocoder_cvsd_encode_sb_sptr vocoder_make_cvsd_encode_sb(short min_step, + short max_step, + double step_decay, + double accum_decay, + int K, + int J, + short pos_accum_max, + short neg_accum_max); - cvsd_encode_sb (short min_step, short max_step, double step_decay, - double accum_decay, int K, int J, - short pos_accum_max, short neg_accum_max); + vocoder_cvsd_encode_sb(short min_step, short max_step, double step_decay, + double accum_decay, int K, int J, + short pos_accum_max, short neg_accum_max); //! Member functions required by the encoder/decoder //! \brief Rounding function specific to CVSD @@ -154,7 +154,7 @@ private: short d_stepsize; //!< \brief Current value of the step sizer public: - ~cvsd_encode_sb (); // public destructor + ~vocoder_cvsd_encode_sb (); // public destructor short min_step() { return d_min_step; } short max_step() { return d_max_step; } @@ -170,4 +170,4 @@ private: gr_vector_void_star &output_items); }; -#endif /* INCLUDED_CVSD_ENCODE_SB_H */ +#endif /* INCLUDED_VOCODER_CVSD_ENCODE_SB_H */ diff --git a/gr-vocoder/include/vocoder_g721_decode_bs.h b/gr-vocoder/include/vocoder_g721_decode_bs.h new file mode 100644 index 000000000..8ce3b12e5 --- /dev/null +++ b/gr-vocoder/include/vocoder_g721_decode_bs.h @@ -0,0 +1,44 @@ +/* -*- 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_VOCODER_G721_DECODE_BS_H +#define INCLUDED_VOCODER_G721_DECODE_BS_H + +#include <gr_sync_block.h> + +class vocoder_g721_decode_bs; + +typedef boost::shared_ptr<vocoder_g721_decode_bs> vocoder_g721_decode_bs_sptr; + +vocoder_g721_decode_bs_sptr vocoder_make_g721_decode_bs(); + +/*! + * \brief This block performs g721 audio decoding. + * + * \ingroup vocoder_blk + */ + +class vocoder_g721_decode_bs : virtual public gr_sync_block +{ +}; + +#endif /* INCLUDED_VOCODER_G721_DECODE_BS_H */ diff --git a/gr-vocoder/include/vocoder_g721_encode_sb.h b/gr-vocoder/include/vocoder_g721_encode_sb.h new file mode 100644 index 000000000..5af980640 --- /dev/null +++ b/gr-vocoder/include/vocoder_g721_encode_sb.h @@ -0,0 +1,44 @@ +/* -*- 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_VOCODER_G721_ENCODE_SB_H +#define INCLUDED_VOCODER_G721_ENCODE_SB_H + +#include <gr_sync_block.h> + +class vocoder_g721_encode_sb; + +typedef boost::shared_ptr<vocoder_g721_encode_sb> vocoder_g721_encode_sb_sptr; + +vocoder_g721_encode_sb_sptr vocoder_make_g721_encode_sb(); + +/*! + * \brief This block performs g721 audio encoding. + * + * \ingroup vocoder_blk + */ + +class vocoder_g721_encode_sb : virtual public gr_sync_block +{ +}; + +#endif /* INCLUDED_VOCODER_G721_ENCODE_SB_H */ diff --git a/gr-vocoder/include/vocoder_g723_24_decode_bs.h b/gr-vocoder/include/vocoder_g723_24_decode_bs.h new file mode 100644 index 000000000..8ca94f253 --- /dev/null +++ b/gr-vocoder/include/vocoder_g723_24_decode_bs.h @@ -0,0 +1,44 @@ +/* -*- 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_VOCODER_G723_24_DECODE_BS_H +#define INCLUDED_VOCODER_G723_24_DECODE_BS_H + +#include <gr_sync_block.h> + +class vocoder_g723_24_decode_bs; + +typedef boost::shared_ptr<vocoder_g723_24_decode_bs> vocoder_g723_24_decode_bs_sptr; + +vocoder_g723_24_decode_bs_sptr vocoder_make_g723_24_decode_bs(); + +/*! + * \brief This block performs g723_24 audio decoding. + * + * \ingroup vocoder_blk + */ + +class vocoder_g723_24_decode_bs : virtual public gr_sync_block +{ +}; + +#endif /* INCLUDED_VOCODER_G723_24_DECODE_BS_H */ diff --git a/gr-vocoder/include/vocoder_g723_24_encode_sb.h b/gr-vocoder/include/vocoder_g723_24_encode_sb.h new file mode 100644 index 000000000..b55229980 --- /dev/null +++ b/gr-vocoder/include/vocoder_g723_24_encode_sb.h @@ -0,0 +1,44 @@ +/* -*- 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_VOCODER_G723_24_ENCODE_SB_H +#define INCLUDED_VOCODER_G723_24_ENCODE_SB_H + +#include <gr_sync_block.h> + +class vocoder_g723_24_encode_sb; + +typedef boost::shared_ptr<vocoder_g723_24_encode_sb> vocoder_g723_24_encode_sb_sptr; + +vocoder_g723_24_encode_sb_sptr vocoder_make_g723_24_encode_sb(); + +/*! + * \brief This block performs g723_24 audio encoding. + * + * \ingroup vocoder_blk + */ + +class vocoder_g723_24_encode_sb : virtual public gr_sync_block +{ +}; + +#endif /* INCLUDED_VOCODER_G723_24_ENCODE_SB_H */ diff --git a/gr-vocoder/include/vocoder_g723_40_decode_bs.h b/gr-vocoder/include/vocoder_g723_40_decode_bs.h new file mode 100644 index 000000000..2299b8806 --- /dev/null +++ b/gr-vocoder/include/vocoder_g723_40_decode_bs.h @@ -0,0 +1,44 @@ +/* -*- 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_VOCODER_G723_40_DECODE_BS_H +#define INCLUDED_VOCODER_G723_40_DECODE_BS_H + +#include <gr_sync_block.h> + +class vocoder_g723_40_decode_bs; + +typedef boost::shared_ptr<vocoder_g723_40_decode_bs> vocoder_g723_40_decode_bs_sptr; + +vocoder_g723_40_decode_bs_sptr vocoder_make_g723_40_decode_bs(); + +/*! + * \brief This block performs g723_40 audio decoding. + * + * \ingroup vocoder_blk + */ + +class vocoder_g723_40_decode_bs : virtual public gr_sync_block +{ +}; + +#endif /* INCLUDED_VOCODER_G723_40_DECODE_BS_H */ diff --git a/gr-vocoder/include/vocoder_g723_40_encode_sb.h b/gr-vocoder/include/vocoder_g723_40_encode_sb.h new file mode 100644 index 000000000..f349cf425 --- /dev/null +++ b/gr-vocoder/include/vocoder_g723_40_encode_sb.h @@ -0,0 +1,44 @@ +/* -*- 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_VOCODER_G723_40_ENCODE_SB_H +#define INCLUDED_VOCODER_G723_40_ENCODE_SB_H + +#include <gr_sync_block.h> + +class vocoder_g723_40_encode_sb; + +typedef boost::shared_ptr<vocoder_g723_40_encode_sb> vocoder_g723_40_encode_sb_sptr; + +vocoder_g723_40_encode_sb_sptr vocoder_make_g723_40_encode_sb(); + +/*! + * \brief This block performs g723_40 audio encoding. + * + * \ingroup vocoder_blk + */ + +class vocoder_g723_40_encode_sb : virtual public gr_sync_block +{ +}; + +#endif /* INCLUDED_VOCODER_G723_40_ENCODE_SB_H */ diff --git a/gr-gsm-fr-vocoder/src/lib/gsm_fr_decode_ps.h b/gr-vocoder/include/vocoder_gsm_fr_decode_ps.h index 8002c2ce3..4c6248d39 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm_fr_decode_ps.h +++ b/gr-vocoder/include/vocoder_gsm_fr_decode_ps.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 * @@ -19,32 +19,33 @@ * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ -#ifndef INCLUDED_GSM_FR_DECODE_PS_H -#define INCLUDED_GSM_FR_DECODE_PS_H + +#ifndef INCLUDED_VOCODER_GSM_FR_DECODE_PS_H +#define INCLUDED_VOCODER_GSM_FR_DECODE_PS_H #include <gr_sync_interpolator.h> -class gsm_fr_decode_ps; -typedef boost::shared_ptr<gsm_fr_decode_ps> gsm_fr_decode_ps_sptr; +class vocoder_gsm_fr_decode_ps; +typedef boost::shared_ptr<vocoder_gsm_fr_decode_ps> vocoder_gsm_fr_decode_ps_sptr; -gsm_fr_decode_ps_sptr gsm_fr_make_decode_ps (); +vocoder_gsm_fr_decode_ps_sptr vocoder_make_gsm_fr_decode_ps (); /*! * \brief GSM 06.10 Full Rate Vocoder Decoder * \ingroup vocoder_blk */ -class gsm_fr_decode_ps : public gr_sync_interpolator { +class vocoder_gsm_fr_decode_ps : public gr_sync_interpolator { struct gsm_state *d_gsm; - friend gsm_fr_decode_ps_sptr gsm_fr_make_decode_ps (); - gsm_fr_decode_ps (); + friend vocoder_gsm_fr_decode_ps_sptr vocoder_make_gsm_fr_decode_ps (); + vocoder_gsm_fr_decode_ps (); public: - ~gsm_fr_decode_ps (); + ~vocoder_gsm_fr_decode_ps (); int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); }; -#endif /* INCLUDED_GSM_FR_DECODE_PS_H */ +#endif /* INCLUDED_VOCODER_GSM_FR_DECODE_PS_H */ diff --git a/gr-gsm-fr-vocoder/src/lib/gsm_fr_encode_sp.h b/gr-vocoder/include/vocoder_gsm_fr_encode_sp.h index f158a3d02..d1803c82e 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm_fr_encode_sp.h +++ b/gr-vocoder/include/vocoder_gsm_fr_encode_sp.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 * @@ -19,15 +19,16 @@ * the Free Software Foundation, Inc., 51 Franklin Street, * Boston, MA 02110-1301, USA. */ -#ifndef INCLUDED_GSM_FR_ENCODE_SP_H -#define INCLUDED_GSM_FR_ENCODE_SP_H + +#ifndef INCLUDED_VOCODER_GSM_FR_ENCODE_SP_H +#define INCLUDED_VOCODER_GSM_FR_ENCODE_SP_H #include <gr_sync_decimator.h> -class gsm_fr_encode_sp; -typedef boost::shared_ptr<gsm_fr_encode_sp> gsm_fr_encode_sp_sptr; +class vocoder_gsm_fr_encode_sp; +typedef boost::shared_ptr<vocoder_gsm_fr_encode_sp> vocoder_gsm_fr_encode_sp_sptr; -gsm_fr_encode_sp_sptr gsm_fr_make_encode_sp (); +vocoder_gsm_fr_encode_sp_sptr vocoder_make_gsm_fr_encode_sp (); /*! * \brief GSM 06.10 Full Rate Vocoder Encoder @@ -35,18 +36,18 @@ gsm_fr_encode_sp_sptr gsm_fr_make_encode_sp (); * * shorts in; 33 byte packets out */ -class gsm_fr_encode_sp : public gr_sync_decimator { +class vocoder_gsm_fr_encode_sp : public gr_sync_decimator { struct gsm_state *d_gsm; - friend gsm_fr_encode_sp_sptr gsm_fr_make_encode_sp (); - gsm_fr_encode_sp (); + friend vocoder_gsm_fr_encode_sp_sptr vocoder_make_gsm_fr_encode_sp (); + vocoder_gsm_fr_encode_sp (); public: - ~gsm_fr_encode_sp (); + ~vocoder_gsm_fr_encode_sp (); int work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items); }; -#endif /* INCLUDED_GSM_FR_ENCODE_SP_H */ +#endif /* INCLUDED_VOCODER_GSM_FR_ENCODE_SP_H */ diff --git a/gr-vocoder/include/vocoder_ulaw_decode_bs.h b/gr-vocoder/include/vocoder_ulaw_decode_bs.h new file mode 100644 index 000000000..1126c6cb3 --- /dev/null +++ b/gr-vocoder/include/vocoder_ulaw_decode_bs.h @@ -0,0 +1,55 @@ +/* -*- 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_VOCODER_ULAW_DECODE_BS_H +#define INCLUDED_VOCODER_ULAW_DECODE_BS_H + +#include <gr_sync_block.h> + +class vocoder_ulaw_decode_bs; + +typedef boost::shared_ptr<vocoder_ulaw_decode_bs> vocoder_ulaw_decode_bs_sptr; + +vocoder_ulaw_decode_bs_sptr vocoder_make_ulaw_decode_bs(); + +/*! + * \brief This block performs ulaw audio decoding. + * + * \ingroup vocoder_blk + */ + +class vocoder_ulaw_decode_bs : public gr_sync_block +{ +private: + friend vocoder_ulaw_decode_bs_sptr vocoder_make_ulaw_decode_bs(); + + vocoder_ulaw_decode_bs(); + + public: + ~vocoder_ulaw_decode_bs(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_VOCODER_ULAW_DECODE_BS_H */ diff --git a/gr-vocoder/include/vocoder_ulaw_encode_sb.h b/gr-vocoder/include/vocoder_ulaw_encode_sb.h new file mode 100644 index 000000000..eddc4f4e5 --- /dev/null +++ b/gr-vocoder/include/vocoder_ulaw_encode_sb.h @@ -0,0 +1,54 @@ +/* -*- 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_VOCODER_ULAW_ENCODER_SB_H +#define INCLUDED_VOCODER_ULAW_ENCODER_SB_H + +#include <gr_sync_block.h> + +class vocoder_ulaw_encode_sb; + +typedef boost::shared_ptr<vocoder_ulaw_encode_sb> vocoder_ulaw_encode_sb_sptr; + +vocoder_ulaw_encode_sb_sptr vocoder_make_ulaw_encode_sb(); + +/*! + * \brief This block performs g.711 ulaw audio encoding. + * + * \ingroup vocoder_blk + */ +class vocoder_ulaw_encode_sb : public gr_sync_block +{ +private: + friend vocoder_ulaw_encode_sb_sptr vocoder_make_ulaw_encode_sb(); + + vocoder_ulaw_encode_sb(); + + public: + ~vocoder_ulaw_encode_sb(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_VOCODER_ULAW_ENCODE_SB_H */ diff --git a/gnuradio-examples/python/digital_voice/.gitignore b/gr-vocoder/lib/.gitignore index c400497f5..d2e2e9ce8 100644 --- a/gnuradio-examples/python/digital_voice/.gitignore +++ b/gr-vocoder/lib/.gitignore @@ -1,10 +1,7 @@ /Makefile /Makefile.in -/.la -/.lo -/.deps /.libs -/*.la -/*.lo -/*.pyc -/*.pyo +/.deps +/gnuradio +/guile +/python diff --git a/gr-vocoder/lib/Makefile.am b/gr-vocoder/lib/Makefile.am new file mode 100644 index 000000000..158347ffe --- /dev/null +++ b/gr-vocoder/lib/Makefile.am @@ -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 $(top_srcdir)/Makefile.common + +SUBDIRS = codec2 g7xx gsm . + +AM_CPPFLAGS = $(STD_DEFINES_AND_INCLUDES) $(PYTHON_CPPFLAGS) $(WITH_INCLUDES) \ + -I$(top_srcdir)/gr-vocoder/include + +lib_LTLIBRARIES = libgnuradio-vocoder.la + +libgnuradio_vocoder_la_SOURCES = \ + vocoder_alaw_decode_bs.cc \ + vocoder_alaw_encode_sb.cc \ + vocoder_codec2_decode_ps.cc \ + vocoder_codec2_encode_sp.cc \ + vocoder_cvsd_decode_bs.cc \ + vocoder_cvsd_encode_sb.cc \ + vocoder_g721_decode_bs.cc \ + vocoder_g721_encode_sb.cc \ + vocoder_g723_24_decode_bs.cc \ + vocoder_g723_24_encode_sb.cc \ + vocoder_g723_40_decode_bs.cc \ + vocoder_g723_40_encode_sb.cc \ + vocoder_gsm_fr_decode_ps.cc \ + vocoder_gsm_fr_encode_sp.cc \ + vocoder_ulaw_decode_bs.cc \ + vocoder_ulaw_encode_sb.cc + +libgnuradio_vocoder_la_LIBADD = \ + $(GNURADIO_CORE_LA) \ + codec2/libcodec2.la \ + g7xx/libg7xx.la \ + gsm/libgsm.la + +libgnuradio_vocoder_la_LDFLAGS = $(NO_UNDEFINED) $(LTVERSIONFLAGS) diff --git a/gr-vocoder/lib/codec2/.gitignore b/gr-vocoder/lib/codec2/.gitignore new file mode 100644 index 000000000..b336cc7ce --- /dev/null +++ b/gr-vocoder/lib/codec2/.gitignore @@ -0,0 +1,2 @@ +/Makefile +/Makefile.in diff --git a/gr-vocoder/lib/codec2/Makefile.am b/gr-vocoder/lib/codec2/Makefile.am new file mode 100644 index 000000000..ae2094eff --- /dev/null +++ b/gr-vocoder/lib/codec2/Makefile.am @@ -0,0 +1,125 @@ +# +# 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 $(top_srcdir)/Makefile.common + +AM_CFLAGS = -fPIC -O3 + +# Helper program to create codebook source +noinst_PROGRAMS = generate_codebook +generate_codebook_LDFLAGS = -lm + +# lsp quantisers +CODEBOOKS= \ + $(srcdir)/codebook/lsp1.txt \ + $(srcdir)/codebook/lsp2.txt \ + $(srcdir)/codebook/lsp3.txt \ + $(srcdir)/codebook/lsp4.txt \ + $(srcdir)/codebook/lsp5.txt \ + $(srcdir)/codebook/lsp6.txt \ + $(srcdir)/codebook/lsp7.txt \ + $(srcdir)/codebook/lsp8.txt \ + $(srcdir)/codebook/lsp9.txt \ + $(srcdir)/codebook/lsp10.txt + +# lspd quantisers +CODEBOOKSD= \ + $(srcdir)/codebook/dlsp1.txt \ + $(srcdir)/codebook/dlsp2.txt \ + $(srcdir)/codebook/dlsp3.txt \ + $(srcdir)/codebook/dlsp4.txt \ + $(srcdir)/codebook/dlsp5.txt \ + $(srcdir)/codebook/dlsp6.txt \ + $(srcdir)/codebook/dlsp7.txt \ + $(srcdir)/codebook/dlsp8.txt \ + $(srcdir)/codebook/dlsp9.txt \ + $(srcdir)/codebook/dlsp10.txt + +# lspd VQ quantisers +CODEBOOKSDVQ= \ + $(srcdir)/codebook/dlsp1.txt \ + $(srcdir)/codebook/dlsp2.txt \ + $(srcdir)/codebook/dlsp3.txt \ + $(srcdir)/codebook/dlsp4.txt \ + $(srcdir)/codebook/dlsp5.txt + +# Generate codebook sources from text files +GENERATED_C = \ + codebook.c \ + codebookd.c \ + codebookdvq.c + +BUILT_SOURCES += $(GENERATED_C) + +codebook.c: $(builddir)/generate_codebook $(CODEBOOKS) + $(builddir)/generate_codebook lsp_cb $(CODEBOOKS) > codebook.c + +codebookd.c: $(builddir)/generate_codebook $(CODEBOOKSD) + $(builddir)/generate_codebook lsp_cbd $(CODEBOOKSD) > codebookd.c + +codebookdvq.c: $(builddir)/generate_codebook $(CODEBOOKSDVQ) + $(builddir)/generate_codebook lsp_cbdvq $(CODEBOOKSDVQ) > codebookdvq.c + +# Convenience library for linking into blocks +noinst_LTLIBRARIES = libcodec2.la + +libcodec2_la_CFLAGS = $(AM_CFLAGS) + +libcodec2_la_SOURCES = \ + dump.c \ + lpc.c \ + nlp.c \ + postfilter.c \ + sine.c \ + codec2.c \ + fft.c \ + kiss_fft.c \ + interp.c \ + lsp.c \ + phase.c \ + quantise.c \ + pack.c \ + $(GENERATED_C) + +# Evil inclusion of glottal.c by phase.c +EXTRA_DIST += glottal.c + +# Headers used locally but not installed in system +noinst_HEADERS = \ + codec2.h \ + codec2_internal.h \ + defines.h \ + kiss_fft.h\ + _kiss_fft_guts.h \ + fft.h \ + interp.h \ + lsp.h \ + phase.h \ + quantise.h \ + comp.h \ + dump.h \ + lpc.h \ + nlp.h \ + postfilter.h \ + sine.h + +EXTRA_DIST += $(CODEBOOKS) $(CODEBOOKSD) $(CODEBOOKSDVQ) + diff --git a/gr-vocoder/lib/codec2/_kiss_fft_guts.h b/gr-vocoder/lib/codec2/_kiss_fft_guts.h new file mode 100644 index 000000000..ba6614440 --- /dev/null +++ b/gr-vocoder/lib/codec2/_kiss_fft_guts.h @@ -0,0 +1,164 @@ +/* +Copyright (c) 2003-2010, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* kiss_fft.h + defines kiss_fft_scalar as either short or a float type + and defines + typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ +#include "kiss_fft.h" +#include <limits.h> + +#define MAXFACTORS 32 +/* e.g. an fft of length 128 has 4 factors + as far as kissfft is concerned + 4*4*4*2 + */ + +struct kiss_fft_state{ + int nfft; + int inverse; + int factors[2*MAXFACTORS]; + kiss_fft_cpx twiddles[1]; +}; + +/* + Explanation of macros dealing with complex math: + + C_MUL(m,a,b) : m = a*b + C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise + C_SUB( res, a,b) : res = a - b + C_SUBFROM( res , a) : res -= a + C_ADDTO( res , a) : res += a + * */ +#ifdef FIXED_POINT +#if (FIXED_POINT==32) +# define FRACBITS 31 +# define SAMPPROD int64_t +#define SAMP_MAX 2147483647 +#else +# define FRACBITS 15 +# define SAMPPROD int32_t +#define SAMP_MAX 32767 +#endif + +#define SAMP_MIN -SAMP_MAX + +#if defined(CHECK_OVERFLOW) +# define CHECK_OVERFLOW_OP(a,op,b) \ + if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \ + fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); } +#endif + + +# define smul(a,b) ( (SAMPPROD)(a)*(b) ) +# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS ) + +# define S_MUL(a,b) sround( smul(a,b) ) + +# define C_MUL(m,a,b) \ + do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \ + (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0) + +# define DIVSCALAR(x,k) \ + (x) = sround( smul( x, SAMP_MAX/k ) ) + +# define C_FIXDIV(c,div) \ + do { DIVSCALAR( (c).r , div); \ + DIVSCALAR( (c).i , div); }while (0) + +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r = sround( smul( (c).r , s ) ) ;\ + (c).i = sround( smul( (c).i , s ) ) ; }while(0) + +#else /* not FIXED_POINT*/ + +# define S_MUL(a,b) ( (a)*(b) ) +#define C_MUL(m,a,b) \ + do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ + (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) +# define C_FIXDIV(c,div) /* NOOP */ +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r *= (s);\ + (c).i *= (s); }while(0) +#endif + +#ifndef CHECK_OVERFLOW_OP +# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ +#endif + +#define C_ADD( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,+,(b).r)\ + CHECK_OVERFLOW_OP((a).i,+,(b).i)\ + (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ + }while(0) +#define C_SUB( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,-,(b).r)\ + CHECK_OVERFLOW_OP((a).i,-,(b).i)\ + (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ + }while(0) +#define C_ADDTO( res , a)\ + do { \ + CHECK_OVERFLOW_OP((res).r,+,(a).r)\ + CHECK_OVERFLOW_OP((res).i,+,(a).i)\ + (res).r += (a).r; (res).i += (a).i;\ + }while(0) + +#define C_SUBFROM( res , a)\ + do {\ + CHECK_OVERFLOW_OP((res).r,-,(a).r)\ + CHECK_OVERFLOW_OP((res).i,-,(a).i)\ + (res).r -= (a).r; (res).i -= (a).i; \ + }while(0) + + +#ifdef FIXED_POINT +# define KISS_FFT_COS(phase) floor(.5+SAMP_MAX * cos (phase)) +# define KISS_FFT_SIN(phase) floor(.5+SAMP_MAX * sin (phase)) +# define HALF_OF(x) ((x)>>1) +#elif defined(USE_SIMD) +# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) +# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) +# define HALF_OF(x) ((x)*_mm_set1_ps(.5)) +#else +# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) +# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) +# define HALF_OF(x) ((x)*.5) +#endif + +#define kf_cexp(x,phase) \ + do{ \ + (x)->r = KISS_FFT_COS(phase);\ + (x)->i = KISS_FFT_SIN(phase);\ + }while(0) + + +/* a debugging function */ +#define pcpx(c)\ + fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) ) + + +#ifdef KISS_FFT_USE_ALLOCA +// define this to allow use of alloca instead of malloc for temporary buffers +// Temporary buffers are used in two case: +// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5 +// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform. +#include <alloca.h> +#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes) +#define KISS_FFT_TMP_FREE(ptr) +#else +#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes) +#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr) +#endif diff --git a/gr-vocoder/lib/codec2/c2dec.c b/gr-vocoder/lib/codec2/c2dec.c new file mode 100644 index 000000000..b866d04d6 --- /dev/null +++ b/gr-vocoder/lib/codec2/c2dec.c @@ -0,0 +1,82 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: c2dec.c + AUTHOR......: David Rowe + DATE CREATED: 23/8/2010 + + Decodes a file of bits to a file of raw speech samples using codec2. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "codec2.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#define BITS_SIZE ((CODEC2_BITS_PER_FRAME + 7) / 8) + +int main(int argc, char *argv[]) +{ + void *codec2; + FILE *fin; + FILE *fout; + short buf[CODEC2_SAMPLES_PER_FRAME]; + unsigned char bits[BITS_SIZE]; + + if (argc != 3) { + printf("usage: %s InputBitFile OutputRawSpeechFile\n", argv[0]); + exit(1); + } + + if (strcmp(argv[1], "-") == 0) fin = stdin; + else if ( (fin = fopen(argv[1],"rb")) == NULL ) { + fprintf(stderr, "Error opening input bit file: %s: %s.\n", + argv[1], strerror(errno)); + exit(1); + } + + if (strcmp(argv[2], "-") == 0) fout = stdout; + else if ( (fout = fopen(argv[2],"wb")) == NULL ) { + fprintf(stderr, "Error opening output speech file: %s: %s.\n", + argv[2], strerror(errno)); + exit(1); + } + + codec2 = codec2_create(); + + while(fread(bits, sizeof(char), BITS_SIZE, fin) == BITS_SIZE) { + codec2_decode(codec2, buf, bits); + fwrite(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fout); + //if this is in a pipeline, we probably don't want the usual + //buffering to occur + if (fout == stdout) fflush(stdout); + if (fin == stdin) fflush(stdin); + + } + + codec2_destroy(codec2); + + fclose(fin); + fclose(fout); + + return 0; +} diff --git a/gr-vocoder/lib/codec2/c2demo.c b/gr-vocoder/lib/codec2/c2demo.c new file mode 100644 index 000000000..efa8d6449 --- /dev/null +++ b/gr-vocoder/lib/codec2/c2demo.c @@ -0,0 +1,86 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: c2demo.c + AUTHOR......: David Rowe + DATE CREATED: 15/11/2010 + + Encodes and decodes a file of raw speech samples using Codec 2. + Demonstrates use of Codec 2 function API. + + Note to convert a wave file to raw and vice-versa: + + $ sox file.wav -r 8000 -s -2 file.raw + $ sox -r 8000 -s -2 file.raw file.wav + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "codec2.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#define BITS_SIZE ((CODEC2_BITS_PER_FRAME + 7) / 8) + +int main(int argc, char *argv[]) +{ + void *codec2; + FILE *fin; + FILE *fout; + short buf[CODEC2_SAMPLES_PER_FRAME]; + unsigned char bits[BITS_SIZE]; + + if (argc != 3) { + printf("usage: %s InputRawSpeechFile OutputRawSpeechFile\n", argv[0]); + exit(1); + } + + if ( (fin = fopen(argv[1],"rb")) == NULL ) { + fprintf(stderr, "Error opening input speech file: %s: %s.\n", + argv[1], strerror(errno)); + exit(1); + } + + if ( (fout = fopen(argv[2],"wb")) == NULL ) { + fprintf(stderr, "Error opening output speech file: %s: %s.\n", + argv[2], strerror(errno)); + exit(1); + } + + /* Note only one set of Codec 2 states is required for an encoder + and decoder pair. */ + + codec2 = codec2_create(); + + while(fread(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fin) == + CODEC2_SAMPLES_PER_FRAME) { + codec2_encode(codec2, bits, buf); + codec2_decode(codec2, buf, bits); + fwrite(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fout); + } + + codec2_destroy(codec2); + + fclose(fin); + fclose(fout); + + return 0; +} diff --git a/gr-vocoder/lib/codec2/c2enc.c b/gr-vocoder/lib/codec2/c2enc.c new file mode 100644 index 000000000..4d1d019df --- /dev/null +++ b/gr-vocoder/lib/codec2/c2enc.c @@ -0,0 +1,83 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: c2enc.c + AUTHOR......: David Rowe + DATE CREATED: 23/8/2010 + + Encodes a file of raw speech samples using codec2 and outputs a file + of bits. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "codec2.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#define BITS_SIZE ((CODEC2_BITS_PER_FRAME + 7) / 8) + +int main(int argc, char *argv[]) +{ + void *codec2; + FILE *fin; + FILE *fout; + short buf[CODEC2_SAMPLES_PER_FRAME]; + unsigned char bits[BITS_SIZE]; + + if (argc != 3) { + printf("usage: %s InputRawspeechFile OutputBitFile\n", argv[0]); + exit(1); + } + + if (strcmp(argv[1], "-") == 0) fin = stdin; + else if ( (fin = fopen(argv[1],"rb")) == NULL ) { + fprintf(stderr, "Error opening input bit file: %s: %s.\n", + argv[1], strerror(errno)); + exit(1); + } + + if (strcmp(argv[2], "-") == 0) fout = stdout; + else if ( (fout = fopen(argv[2],"wb")) == NULL ) { + fprintf(stderr, "Error opening output speech file: %s: %s.\n", + argv[2], strerror(errno)); + exit(1); + } + + codec2 = codec2_create(); + + while(fread(buf, sizeof(short), CODEC2_SAMPLES_PER_FRAME, fin) == + CODEC2_SAMPLES_PER_FRAME) { + codec2_encode(codec2, bits, buf); + fwrite(bits, sizeof(char), BITS_SIZE, fout); + //if this is in a pipeline, we probably don't want the usual + //buffering to occur + if (fout == stdout) fflush(stdout); + if (fin == stdin) fflush(stdin); + } + + codec2_destroy(codec2); + + fclose(fin); + fclose(fout); + + return 0; +} diff --git a/gr-vocoder/lib/codec2/c2sim.c b/gr-vocoder/lib/codec2/c2sim.c new file mode 100644 index 000000000..bb49c7899 --- /dev/null +++ b/gr-vocoder/lib/codec2/c2sim.c @@ -0,0 +1,469 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: c2sim.c + AUTHOR......: David Rowe + DATE CREATED: 20/8/2010 + + Codec2 simulation. Combines encoder and decoder and allows switching in + out various algorithms and quantisation steps. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <math.h> + +#include "defines.h" +#include "sine.h" +#include "nlp.h" +#include "dump.h" +#include "lpc.h" +#include "lsp.h" +#include "quantise.h" +#include "phase.h" +#include "postfilter.h" +#include "interp.h" + +/*---------------------------------------------------------------------------*\ + + switch_present() + + Searches the command line arguments for a "switch". If the switch is + found, returns the command line argument where it ws found, else returns + NULL. + +\*---------------------------------------------------------------------------*/ + +int switch_present(sw,argc,argv) +register char sw[]; /* switch in string form */ +register int argc; /* number of command line arguments */ +register char *argv[]; /* array of command line arguments in string form */ +{ + register int i; /* loop variable */ + + for(i=1; i<argc; i++) + if (!strcmp(sw,argv[i])) + return(i); + + return 0; +} + +void synth_one_frame(short buf[], MODEL *model, float Sn_[], float Pn[]); + +/*---------------------------------------------------------------------------*\ + + MAIN + +\*---------------------------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + FILE *fout; /* output speech file */ + FILE *fin; /* input speech file */ + short buf[N]; /* input/output buffer */ + float Sn[M]; /* float input speech samples */ + COMP Sw[FFT_ENC]; /* DFT of Sn[] */ + float w[M]; /* time domain hamming window */ + COMP W[FFT_ENC]; /* DFT of w[] */ + MODEL model; + float Pn[2*N]; /* trapezoidal synthesis window */ + float Sn_[2*N]; /* synthesised speech */ + int i; /* loop variable */ + int frames; + float prev_Wo; + float pitch; + int voiced1 = 0; + + char out_file[MAX_STR]; + int arg; + float snr; + float sum_snr; + + int lpc_model, order = LPC_ORD; + int lsp, lspd, lspdvq, lsp_quantiser; + float ak[LPC_MAX]; + COMP Sw_[FFT_ENC]; + COMP Ew[FFT_ENC]; + + int dump; + + int phase0; + float ex_phase[MAX_AMP+1]; + + int postfilt; + float bg_est; + + int hand_voicing; + FILE *fvoicing = 0; + + MODEL prev_model, interp_model; + int decimate; + float lsps[LPC_ORD]; + float prev_lsps[LPC_ORD]; + float e, prev_e; + float ak_interp[LPC_MAX]; + + void *nlp_states; + float hpf_states[2]; + int resample; + float AresdB_prev[MAX_AMP]; + + for(i=0; i<MAX_AMP; i++) + AresdB_prev[i] = 0.0; + + for(i=0; i<M; i++) + Sn[i] = 1.0; + for(i=0; i<2*N; i++) + Sn_[i] = 0; + + prev_Wo = TWO_PI/P_MAX; + + prev_model.Wo = TWO_PI/P_MIN; + prev_model.L = floor(PI/prev_model.Wo); + for(i=1; i<=prev_model.L; i++) { + prev_model.A[i] = 0.0; + prev_model.phi[i] = 0.0; + } + for(i=1; i<=MAX_AMP; i++) { + ex_phase[i] = 0.0; + } + for(i=0; i<LPC_ORD; i++) { + prev_lsps[i] = i*PI/(LPC_ORD+1); + } + e = prev_e = 1; + hpf_states[0] = hpf_states[1] = 0.0; + + nlp_states = nlp_create(); + + if (argc < 2) { + fprintf(stderr, "\nCodec2 - 2400 bit/s speech codec - Simulation Program\n" + "\thttp://rowetel.com/codec2.html\n\n" + "usage: %s InputFile [-o OutputFile]\n" + "\t[--lpc Order]\n" + "\t[--lsp]\n" + "\t[--lspd]\n" + "\t[--lspdvq]\n" + "\t[--phase0]\n" + "\t[--postfilter]\n" + "\t[--hand_voicing]\n" + "\t[--dec]\n" + "\t[--dump DumpFilePrefix]\n", argv[0]); + exit(1); + } + + /* Interpret command line arguments -------------------------------------*/ + + /* Input file */ + + if ((fin = fopen(argv[1],"rb")) == NULL) { + fprintf(stderr, "Error opening input speech file: %s: %s.\n", + argv[1], strerror(errno)); + exit(1); + } + + /* Output file */ + + if ((arg = switch_present("-o",argc,argv))) { + if ((fout = fopen(argv[arg+1],"wb")) == NULL) { + fprintf(stderr, "Error opening output speech file: %s: %s.\n", + argv[arg+1], strerror(errno)); + exit(1); + } + strcpy(out_file,argv[arg+1]); + } + else + fout = NULL; + + lpc_model = 0; + if ((arg = switch_present("--lpc",argc,argv))) { + lpc_model = 1; + order = atoi(argv[arg+1]); + if ((order < 4) || (order > 20)) { + fprintf(stderr, "Error in lpc order: %d\n", order); + exit(1); + } + } + + dump = switch_present("--dump",argc,argv); +#ifdef DUMP + if (dump) + dump_on(argv[dump+1]); +#endif + + lsp = switch_present("--lsp",argc,argv); + lsp_quantiser = 0; + if (lsp) + assert(order == LPC_ORD); + + lspd = switch_present("--lspd",argc,argv); + if (lspd) + assert(order == LPC_ORD); + + lspdvq = switch_present("--lspdvq",argc,argv); + if (lspdvq) + assert(order == LPC_ORD); + + phase0 = switch_present("--phase0",argc,argv); + if (phase0) { + ex_phase[0] = 0; + } + + hand_voicing = switch_present("--hand_voicing",argc,argv); + if (hand_voicing) { + fvoicing = fopen(argv[hand_voicing+1],"rt"); + assert(fvoicing != NULL); + } + + bg_est = 0.0; + postfilt = switch_present("--postfilter",argc,argv); + + decimate = switch_present("--dec",argc,argv); + + arg = switch_present("--resample",argc,argv); + resample = atoi(argv[arg+1]); + + /* Initialise ------------------------------------------------------------*/ + + make_analysis_window(w,W); + make_synthesis_window(Pn); + quantise_init(); + + /* Main loop ------------------------------------------------------------*/ + + frames = 0; + sum_snr = 0; + while(fread(buf,sizeof(short),N,fin)) { + frames++; + //printf("frame: %d", frames); + + /* Read input speech */ + + for(i=0; i<M-N; i++) + Sn[i] = Sn[i+N]; + for(i=0; i<N; i++) { + //Sn[i+M-N] = hpf((float)buf[i], hpf_states); + Sn[i+M-N] = (float)buf[i]; + } + + /* Estimate pitch */ + + nlp(nlp_states,Sn,N,M,P_MIN,P_MAX,&pitch,Sw,&prev_Wo); + model.Wo = TWO_PI/pitch; + + /* estimate model parameters */ + + dft_speech(Sw, Sn, w); + two_stage_pitch_refinement(&model, Sw); + estimate_amplitudes(&model, Sw, W); +#ifdef DUMP + dump_Sn(Sn); dump_Sw(Sw); dump_model(&model); +#endif + + /* optional zero-phase modelling */ + + if (phase0) { + float Wn[M]; /* windowed speech samples */ + float Rk[LPC_MAX+1]; /* autocorrelation coeffs */ + +#ifdef DUMP + dump_phase(&model.phi[0], model.L); +#endif + + /* find aks here, these are overwritten if LPC modelling is enabled */ + + for(i=0; i<M; i++) + Wn[i] = Sn[i]*w[i]; + autocorrelate(Wn,Rk,M,order); + levinson_durbin(Rk,ak,order); + +#ifdef DUMP + dump_ak(ak, LPC_ORD); +#endif + + /* determine voicing */ + + snr = est_voicing_mbe(&model, Sw, W, Sw_, Ew, prev_Wo); +#ifdef DUMP + dump_Sw_(Sw_); + dump_Ew(Ew); + dump_snr(snr); +#endif + + /* just to make sure we are not cheating - kill all phases */ + + for(i=0; i<MAX_AMP; i++) + model.phi[i] = 0; + + if (hand_voicing) { + fscanf(fvoicing,"%d\n",&model.voiced); + } + } + + /* optional LPC model amplitudes */ + + if (lpc_model) { + int lsp_indexes[LPC_MAX]; + + e = speech_to_uq_lsps(lsps, ak, Sn, w, order); + + if (lsp) { + encode_lsps(lsp_indexes, lsps, LPC_ORD); + decode_lsps(lsps, lsp_indexes, LPC_ORD); + bw_expand_lsps(lsps, LPC_ORD); + lsp_to_lpc(lsps, ak, LPC_ORD); + } + + if (lspd) { + float lsps_[LPC_ORD]; + + lspd_quantise(lsps, lsps_, LPC_ORD); + lsp_to_lpc(lsps_, ak, LPC_ORD); + } + + if (lspdvq) { + float lsps_[LPC_ORD]; + + lspdvq_quantise(lsps, lsps_, LPC_ORD); + lsp_to_lpc(lsps_, ak, LPC_ORD); + } + + e = decode_energy(encode_energy(e)); + model.Wo = decode_Wo(encode_Wo(model.Wo)); + + aks_to_M2(ak, order, &model, e, &snr, 1); + apply_lpc_correction(&model); + sum_snr += snr; +#ifdef DUMP + dump_quantised_model(&model); +#endif + } + + /* optional resampling of model amplitudes */ + + printf("frames=%d\n", frames); + if (resample) { + snr = resample_amp_nl(&model, resample, AresdB_prev); + sum_snr += snr; +#ifdef DUMP + dump_quantised_model(&model); +#endif + } + + /* option decimation to 20ms rate, which enables interpolation + routine to synthesise in between frame */ + + if (decimate) { + if (!phase0) { + printf("needs --phase0 to resample phase for interpolated Wo\n"); + exit(0); + } + if (!lpc_model) { + printf("needs --lpc 10 to resample amplitudes\n"); + exit(0); + } + + /* odd frame - interpolate */ + + if (frames%2) { + + interp_model.voiced = voiced1; + + #ifdef LOG_LIN_INTERP + interpolate(&interp_model, &prev_model, &model); + #else + interpolate_lsp(&interp_model, &prev_model, &model, + prev_lsps, prev_e, lsps, e, ak_interp); + apply_lpc_correction(&interp_model); + #endif + + if (phase0) + phase_synth_zero_order(&interp_model, ak_interp, ex_phase, + order); + if (postfilt) + postfilter(&interp_model, &bg_est); + synth_one_frame(buf, &interp_model, Sn_, Pn); + if (fout != NULL) fwrite(buf,sizeof(short),N,fout); + + if (phase0) + phase_synth_zero_order(&model, ak, ex_phase, order); + if (postfilt) + postfilter(&model, &bg_est); + synth_one_frame(buf, &model, Sn_, Pn); + if (fout != NULL) fwrite(buf,sizeof(short),N,fout); + + prev_model = model; + for(i=0; i<LPC_ORD; i++) + prev_lsps[i] = lsps[i]; + prev_e = e; + } + else { + voiced1 = model.voiced; + } + } + else { + if (phase0) + phase_synth_zero_order(&model, ak, ex_phase, order); + if (postfilt) + postfilter(&model, &bg_est); + synth_one_frame(buf, &model, Sn_, Pn); + if (fout != NULL) fwrite(buf,sizeof(short),N,fout); + } + prev_Wo = TWO_PI/pitch; + } + fclose(fin); + + if (fout != NULL) + fclose(fout); + + if (lpc_model || resample) + printf("SNR av = %5.2f dB\n", sum_snr/frames); + +#ifdef DUMP + if (dump) + dump_off(); +#endif + + if (hand_voicing) + fclose(fvoicing); + + nlp_destroy(nlp_states); + + return 0; +} + +void synth_one_frame(short buf[], MODEL *model, float Sn_[], float Pn[]) +{ + int i; + + synthesise(Sn_, model, Pn, 1); + + for(i=0; i<N; i++) { + if (Sn_[i] > 32767.0) + buf[i] = 32767; + else if (Sn_[i] < -32767.0) + buf[i] = -32767; + else + buf[i] = Sn_[i]; + } + +} diff --git a/gr-vocoder/lib/codec2/codebook/dlsp1.txt b/gr-vocoder/lib/codec2/codebook/dlsp1.txt new file mode 100644 index 000000000..d126be771 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/dlsp1.txt @@ -0,0 +1,17 @@ +1 16 +225 +250 +275 +300 +325 +350 +375 +400 +425 +450 +475 +500 +525 +550 +575 +600 diff --git a/gr-vocoder/lib/codec2/codebook/dlsp10.txt b/gr-vocoder/lib/codec2/codebook/dlsp10.txt new file mode 100644 index 000000000..dea9dd9d8 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/dlsp10.txt @@ -0,0 +1,9 @@ +1 8 +50 +100 +200 +300 +425 +550 +675 +800 diff --git a/gr-vocoder/lib/codec2/codebook/dlsp2.txt b/gr-vocoder/lib/codec2/codebook/dlsp2.txt new file mode 100644 index 000000000..234bf2067 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/dlsp2.txt @@ -0,0 +1,17 @@ +1 16 +25 +50 +75 +100 +125 +150 +175 +200 +225 +250 +275 +300 +325 +350 +375 +400 diff --git a/gr-vocoder/lib/codec2/codebook/dlsp3.txt b/gr-vocoder/lib/codec2/codebook/dlsp3.txt new file mode 100644 index 000000000..b2ee06da4 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/dlsp3.txt @@ -0,0 +1,9 @@ +1 8 +50 +75 +100 +120 +150 +250 +350 +450 diff --git a/gr-vocoder/lib/codec2/codebook/dlsp4.txt b/gr-vocoder/lib/codec2/codebook/dlsp4.txt new file mode 100644 index 000000000..dea9dd9d8 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/dlsp4.txt @@ -0,0 +1,9 @@ +1 8 +50 +100 +200 +300 +425 +550 +675 +800 diff --git a/gr-vocoder/lib/codec2/codebook/dlsp5.txt b/gr-vocoder/lib/codec2/codebook/dlsp5.txt new file mode 100644 index 000000000..dea9dd9d8 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/dlsp5.txt @@ -0,0 +1,9 @@ +1 8 +50 +100 +200 +300 +425 +550 +675 +800 diff --git a/gr-vocoder/lib/codec2/codebook/dlsp6.txt b/gr-vocoder/lib/codec2/codebook/dlsp6.txt new file mode 100644 index 000000000..dea9dd9d8 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/dlsp6.txt @@ -0,0 +1,9 @@ +1 8 +50 +100 +200 +300 +425 +550 +675 +800 diff --git a/gr-vocoder/lib/codec2/codebook/dlsp7.txt b/gr-vocoder/lib/codec2/codebook/dlsp7.txt new file mode 100644 index 000000000..dea9dd9d8 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/dlsp7.txt @@ -0,0 +1,9 @@ +1 8 +50 +100 +200 +300 +425 +550 +675 +800 diff --git a/gr-vocoder/lib/codec2/codebook/dlsp8.txt b/gr-vocoder/lib/codec2/codebook/dlsp8.txt new file mode 100644 index 000000000..dea9dd9d8 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/dlsp8.txt @@ -0,0 +1,9 @@ +1 8 +50 +100 +200 +300 +425 +550 +675 +800 diff --git a/gr-vocoder/lib/codec2/codebook/dlsp9.txt b/gr-vocoder/lib/codec2/codebook/dlsp9.txt new file mode 100644 index 000000000..dea9dd9d8 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/dlsp9.txt @@ -0,0 +1,9 @@ +1 8 +50 +100 +200 +300 +425 +550 +675 +800 diff --git a/gr-vocoder/lib/codec2/codebook/lsp1.txt b/gr-vocoder/lib/codec2/codebook/lsp1.txt new file mode 100644 index 000000000..d126be771 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp1.txt @@ -0,0 +1,17 @@ +1 16 +225 +250 +275 +300 +325 +350 +375 +400 +425 +450 +475 +500 +525 +550 +575 +600 diff --git a/gr-vocoder/lib/codec2/codebook/lsp10.txt b/gr-vocoder/lib/codec2/codebook/lsp10.txt new file mode 100644 index 000000000..39aab7c56 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp10.txt @@ -0,0 +1,6 @@ +1 4 +2900 +3100 +3300 +3500 + diff --git a/gr-vocoder/lib/codec2/codebook/lsp2.txt b/gr-vocoder/lib/codec2/codebook/lsp2.txt new file mode 100644 index 000000000..597f14965 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp2.txt @@ -0,0 +1,17 @@ +1 16 +325 +350 +375 +400 +425 +450 +475 +500 +525 +550 +575 +600 +625 +650 +675 +700 diff --git a/gr-vocoder/lib/codec2/codebook/lsp3.txt b/gr-vocoder/lib/codec2/codebook/lsp3.txt new file mode 100644 index 000000000..36a64b158 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp3.txt @@ -0,0 +1,17 @@ +1 16 +500 +550 +600 +650 +700 +750 +800 +850 +900 +950 +1000 +1050 +1100 +1150 +1200 +1250 diff --git a/gr-vocoder/lib/codec2/codebook/lsp4.txt b/gr-vocoder/lib/codec2/codebook/lsp4.txt new file mode 100644 index 000000000..53a90bd8c --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp4.txt @@ -0,0 +1,17 @@ +1 16 +700 +800 +900 +1000 +1100 +1200 +1300 +1400 +1500 +1600 +1700 +1800 +1900 +2000 +2100 +2200 diff --git a/gr-vocoder/lib/codec2/codebook/lsp5.txt b/gr-vocoder/lib/codec2/codebook/lsp5.txt new file mode 100644 index 000000000..94739b56e --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp5.txt @@ -0,0 +1,19 @@ +1 16 + 950 +1050 +1150 +1250 +1350 +1450 +1550 +1650 +1750 +1850 +1950 +2050 +2150 +2250 +2350 +2450 + + diff --git a/gr-vocoder/lib/codec2/codebook/lsp6.txt b/gr-vocoder/lib/codec2/codebook/lsp6.txt new file mode 100644 index 000000000..992ea25c5 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp6.txt @@ -0,0 +1,19 @@ +1 16 +1100 +1200 +1300 +1400 +1500 +1600 +1700 +1800 +1900 +2000 +2100 +2200 +2300 +2400 +2500 +2600 + + diff --git a/gr-vocoder/lib/codec2/codebook/lsp7.txt b/gr-vocoder/lib/codec2/codebook/lsp7.txt new file mode 100644 index 000000000..839cbfdd5 --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp7.txt @@ -0,0 +1,19 @@ +1 16 +1500 +1600 +1700 +1800 +1900 +2000 +2100 +2200 +2300 +2400 +2500 +2600 +2700 +2800 +2900 +3000 + + diff --git a/gr-vocoder/lib/codec2/codebook/lsp8.txt b/gr-vocoder/lib/codec2/codebook/lsp8.txt new file mode 100644 index 000000000..d9880c94e --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp8.txt @@ -0,0 +1,11 @@ +1 8 +2300 +2400 +2500 +2600 +2700 +2800 +2900 +3000 + + diff --git a/gr-vocoder/lib/codec2/codebook/lsp8910.txt b/gr-vocoder/lib/codec2/codebook/lsp8910.txt new file mode 100644 index 000000000..93cfdd81d --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp8910.txt @@ -0,0 +1,65 @@ +3 64 +2.048073 2.534502 2.645915 +2.019670 2.269744 2.605462 +1.961101 2.329646 2.562857 +1.968573 2.532712 2.616918 +2.183480 2.514381 2.629582 +2.259379 2.516615 2.620410 +2.172791 2.462460 2.567064 +2.097666 2.303933 2.421685 +2.052990 2.353242 2.546992 +2.043642 2.232362 2.499262 +2.106151 2.393131 2.488401 +2.099167 2.437862 2.558655 +2.013877 2.422875 2.530071 +2.033848 2.483776 2.584598 +2.114474 2.516856 2.602372 +2.229214 2.584056 2.678855 +2.131151 2.584299 2.674845 +1.472721 2.477091 2.630241 +2.010907 2.598415 2.682989 +2.353653 2.524066 2.619773 +2.419897 2.623938 2.699605 +2.319080 2.602148 2.689044 +1.860342 2.503881 2.616576 +1.910517 2.386693 2.610126 +1.748689 2.371809 2.496542 +1.618495 2.403425 2.554956 +1.844073 2.437026 2.533443 +1.924810 2.388543 2.502698 +1.937227 2.258363 2.501697 +1.687554 2.209123 2.545239 +1.851950 2.278628 2.565632 +1.868154 2.330150 2.444883 +1.874180 2.213118 2.351940 +1.757311 2.030626 2.433836 +1.650306 2.152371 2.243421 +1.612794 1.884686 2.339313 +1.745431 2.278895 2.389449 +1.590923 2.304155 2.408510 +1.475982 2.275548 2.509897 +1.508695 2.045463 2.455520 +1.872054 2.061777 2.246202 +1.983947 2.159155 2.445535 +1.745180 2.483765 2.593698 +1.900116 2.079600 2.407479 +1.841672 2.167042 2.486827 +1.932912 2.148464 2.569850 +2.134174 2.363673 2.584252 +2.106094 2.450645 2.638417 +1.954135 2.460313 2.666512 +1.907634 2.573801 2.674025 +1.625579 2.539569 2.656363 +1.785866 2.572616 2.676082 +1.798447 2.376454 2.624298 +2.020033 2.397244 2.619868 +1.946581 2.468791 2.564185 +2.008920 2.342400 2.469132 +1.983846 2.271044 2.395408 +1.988039 2.154150 2.317920 +2.077197 2.216622 2.389101 +2.117255 2.283907 2.512242 +2.177233 2.334622 2.458268 +2.214655 2.425510 2.620013 +2.199931 2.390272 2.520731 +2.271755 2.448682 2.552649 diff --git a/gr-vocoder/lib/codec2/codebook/lsp9.txt b/gr-vocoder/lib/codec2/codebook/lsp9.txt new file mode 100644 index 000000000..7e159af2f --- /dev/null +++ b/gr-vocoder/lib/codec2/codebook/lsp9.txt @@ -0,0 +1,11 @@ +1 8 +2500 +2600 +2700 +2800 +2900 +3000 +3100 +3200 + + diff --git a/gr-vocoder/lib/codec2/codec2.c b/gr-vocoder/lib/codec2/codec2.c new file mode 100644 index 000000000..92708ee32 --- /dev/null +++ b/gr-vocoder/lib/codec2/codec2.c @@ -0,0 +1,342 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: codec2.c + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Codec2 fully quantised encoder and decoder functions. If you want use + codec2, the codec2_xxx functions are for you. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "defines.h" +#include "sine.h" +#include "nlp.h" +#include "dump.h" +#include "lpc.h" +#include "quantise.h" +#include "phase.h" +#include "interp.h" +#include "postfilter.h" +#include "codec2.h" +#include "codec2_internal.h" + +/*---------------------------------------------------------------------------*\ + + FUNCTIONS + +\*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_create + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Create and initialise an instance of the codec. Returns a pointer + to the codec states or NULL on failure. One set of states is + sufficient for a full duuplex codec (i.e. an encoder and decoder). + You don't need separate states for encoders and decoders. See + c2enc.c and c2dec.c for examples. + +\*---------------------------------------------------------------------------*/ + +void *codec2_create() +{ + CODEC2 *c2; + int i,l; + + c2 = (CODEC2*)malloc(sizeof(CODEC2)); + if (c2 == NULL) + return NULL; + + for(i=0; i<M; i++) + c2->Sn[i] = 1.0; + c2->hpf_states[0] = c2->hpf_states[1] = 0.0; + for(i=0; i<2*N; i++) + c2->Sn_[i] = 0; + make_analysis_window(c2->w,c2->W); + make_synthesis_window(c2->Pn); + quantise_init(); + c2->prev_Wo = 0.0; + c2->bg_est = 0.0; + c2->ex_phase = 0.0; + + for(l=1; l<MAX_AMP; l++) + c2->prev_model.A[l] = 0.0; + c2->prev_model.Wo = TWO_PI/P_MAX; + c2->prev_model.L = PI/c2->prev_model.Wo; + c2->prev_model.voiced = 0; + + for(i=0; i<LPC_ORD; i++) { + c2->prev_lsps[i] = i*PI/(LPC_ORD+1); + } + c2->prev_energy = 1; + + c2->nlp = nlp_create(); + if (c2->nlp == NULL) { + free (c2); + return NULL; + } + + return (void*)c2; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_create + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Destroy an instance of the codec. + +\*---------------------------------------------------------------------------*/ + +void codec2_destroy(void *codec2_state) +{ + CODEC2 *c2; + + assert(codec2_state != NULL); + c2 = (CODEC2*)codec2_state; + nlp_destroy(c2->nlp); + free(codec2_state); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_encode + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Encodes 160 speech samples (20ms of speech) into 51 bits. + + The codec2 algorithm actually operates internally on 10ms (80 + sample) frames, so we run the encoding algorithm twice. On the + first frame we just send the voicing bit. One the second frame we + send all model parameters. + + The bit allocation is: + + Parameter bits/frame + -------------------------------------- + Harmonic magnitudes (LSPs) 36 + Low frequency LPC correction 1 + Energy 5 + Wo (fundamental frequnecy) 7 + Voicing (10ms update) 2 + TOTAL 51 + +\*---------------------------------------------------------------------------*/ + +void codec2_encode(void *codec2_state, unsigned char * bits, short speech[]) +{ + CODEC2 *c2; + MODEL model; + int voiced1, voiced2; + int lsp_indexes[LPC_ORD]; + int energy_index; + int Wo_index; + int i; + unsigned int nbit = 0; + + assert(codec2_state != NULL); + c2 = (CODEC2*)codec2_state; + + /* first 10ms analysis frame - we just want voicing */ + + analyse_one_frame(c2, &model, speech); + voiced1 = model.voiced; + + /* second 10ms analysis frame */ + + analyse_one_frame(c2, &model, &speech[N]); + voiced2 = model.voiced; + + Wo_index = encode_Wo(model.Wo); + encode_amplitudes(lsp_indexes, + &energy_index, + &model, + c2->Sn, + c2->w); + memset(bits, '\0', ((CODEC2_BITS_PER_FRAME + 7) / 8)); + pack(bits, &nbit, Wo_index, WO_BITS); + for(i=0; i<LPC_ORD; i++) { + pack(bits, &nbit, lsp_indexes[i], lsp_bits(i)); + } + pack(bits, &nbit, energy_index, E_BITS); + pack(bits, &nbit, voiced1, 1); + pack(bits, &nbit, voiced2, 1); + + assert(nbit == CODEC2_BITS_PER_FRAME); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: codec2_decode + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Decodes frames of 51 bits into 160 samples (20ms) of speech. + +\*---------------------------------------------------------------------------*/ + +void codec2_decode(void *codec2_state, short speech[], + const unsigned char * bits) +{ + CODEC2 *c2; + MODEL model; + int voiced1, voiced2; + int lsp_indexes[LPC_ORD]; + float lsps[LPC_ORD]; + int energy_index; + float energy; + int Wo_index; + float ak[LPC_ORD+1]; + float ak_interp[LPC_ORD+1]; + int i; + unsigned int nbit = 0; + MODEL model_interp; + + assert(codec2_state != NULL); + c2 = (CODEC2*)codec2_state; + + /* unpack bit stream to integer codes */ + + Wo_index = unpack(bits, &nbit, WO_BITS); + for(i=0; i<LPC_ORD; i++) { + lsp_indexes[i] = unpack(bits, &nbit, lsp_bits(i)); + } + energy_index = unpack(bits, &nbit, E_BITS); + voiced1 = unpack(bits, &nbit, 1); + voiced2 = unpack(bits, &nbit, 1); + assert(nbit == CODEC2_BITS_PER_FRAME); + + /* decode integer codes to model parameters */ + + model.Wo = decode_Wo(Wo_index); + model.L = PI/model.Wo; + memset(&model.A, 0, (model.L+1)*sizeof(model.A[0])); + decode_amplitudes(&model, + ak, + lsp_indexes, + energy_index, + lsps, + &energy); + + model.voiced = voiced2; + model_interp.voiced = voiced1; + model_interp.Wo = P_MAX/2; + memset(&model_interp.A, 0, MAX_AMP*sizeof(model_interp.A[0])); + + /* interpolate middle frame's model parameters for adjacent frames */ + + interpolate_lsp(&model_interp, &c2->prev_model, &model, + c2->prev_lsps, c2->prev_energy, lsps, energy, ak_interp); + apply_lpc_correction(&model_interp); + + /* synthesis two 10ms frames */ + + synthesise_one_frame(c2, speech, &model_interp, ak_interp); + synthesise_one_frame(c2, &speech[N], &model, ak); + + /* update memories (decode states) for next time */ + + memcpy(&c2->prev_model, &model, sizeof(MODEL)); + memcpy(c2->prev_lsps, lsps, sizeof(lsps)); + c2->prev_energy = energy; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: synthesise_one_frame() + AUTHOR......: David Rowe + DATE CREATED: 23/8/2010 + + Synthesise 80 speech samples (10ms) from model parameters. + +\*---------------------------------------------------------------------------*/ + +void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model, float ak[]) +{ + int i; + + phase_synth_zero_order(model, ak, &c2->ex_phase, LPC_ORD); + postfilter(model, &c2->bg_est); + synthesise(c2->Sn_, model, c2->Pn, 1); + + for(i=0; i<N; i++) { + if (c2->Sn_[i] > 32767.0) + speech[i] = 32767; + else if (c2->Sn_[i] < -32767.0) + speech[i] = -32767; + else + speech[i] = c2->Sn_[i]; + } + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: analyse_one_frame() + AUTHOR......: David Rowe + DATE CREATED: 23/8/2010 + + Extract sinusoidal model parameters from 80 speech samples (10ms of + speech). + +\*---------------------------------------------------------------------------*/ + +void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]) +{ + COMP Sw[FFT_ENC]; + COMP Sw_[FFT_ENC]; + COMP Ew[FFT_ENC]; + float pitch; + int i; + + /* Read input speech */ + + for(i=0; i<M-N; i++) + c2->Sn[i] = c2->Sn[i+N]; + for(i=0; i<N; i++) + c2->Sn[i+M-N] = speech[i]; + + dft_speech(Sw, c2->Sn, c2->w); + + /* Estimate pitch */ + + nlp(c2->nlp,c2->Sn,N,M,P_MIN,P_MAX,&pitch,Sw,&c2->prev_Wo); + model->Wo = TWO_PI/pitch; + model->L = PI/model->Wo; + + /* estimate model parameters */ + + two_stage_pitch_refinement(model, Sw); + estimate_amplitudes(model, Sw, c2->W); + est_voicing_mbe(model, Sw, c2->W, Sw_, Ew, c2->prev_Wo); + + c2->prev_Wo = model->Wo; +} diff --git a/gr-vocoder/lib/codec2/codec2.h b/gr-vocoder/lib/codec2/codec2.h new file mode 100644 index 000000000..946dedca5 --- /dev/null +++ b/gr-vocoder/lib/codec2/codec2.h @@ -0,0 +1,41 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: codec2.h + AUTHOR......: David Rowe + DATE CREATED: 21/8/2010 + + Codec2 fully quantised encoder and decoder functions. If you want use + codec2, these are the functions you need to call. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __CODEC2__ +#define __CODEC2__ + +#define CODEC2_SAMPLES_PER_FRAME 160 +#define CODEC2_BITS_PER_FRAME 50 + +void *codec2_create(); +void codec2_destroy(void *codec2_state); +void codec2_encode(void *codec2_state, unsigned char * bits, short speech_in[]); +void codec2_decode(void *codec2_state, short speech_out[], + const unsigned char * bits); + +#endif diff --git a/gr-vocoder/lib/codec2/codec2_internal.h b/gr-vocoder/lib/codec2/codec2_internal.h new file mode 100644 index 000000000..3943ac29d --- /dev/null +++ b/gr-vocoder/lib/codec2/codec2_internal.h @@ -0,0 +1,63 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: codec2_internal.h + AUTHOR......: David Rowe + DATE CREATED: 22 March 2011 + + Some internal structures and states broken out here as they are useful for + testing and development. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2011 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __CODEC2_INTERNAL__ +#define __CODEC2_INTERNAL__ + +/*---------------------------------------------------------------------------*\ + + STATES + +\*---------------------------------------------------------------------------*/ + +typedef struct { + float w[M]; /* time domain hamming window */ + COMP W[FFT_ENC]; /* DFT of w[] */ + float Pn[2*N]; /* trapezoidal synthesis window */ + float Sn[M]; /* input speech */ + float hpf_states[2]; /* high pass filter states */ + void *nlp; /* pitch predictor states */ + float Sn_[2*N]; /* synthesised output speech */ + float ex_phase; /* excitation model phase track */ + float bg_est; /* background noise estimate for post filter */ + float prev_Wo; /* previous frame's pitch estimate */ + MODEL prev_model; /* previous frame's model parameters */ + float prev_lsps[LPC_ORD]; /* previous frame's LSPs */ + float prev_energy; /* previous frame's LPC energy */ +} CODEC2; + +/*---------------------------------------------------------------------------*\ + + FUNCTION HEADERS + +\*---------------------------------------------------------------------------*/ + +void analyse_one_frame(CODEC2 *c2, MODEL *model, short speech[]); +void synthesise_one_frame(CODEC2 *c2, short speech[], MODEL *model,float ak[]); + +#endif diff --git a/gr-vocoder/lib/codec2/comp.h b/gr-vocoder/lib/codec2/comp.h new file mode 100644 index 000000000..cedcab37f --- /dev/null +++ b/gr-vocoder/lib/codec2/comp.h @@ -0,0 +1,38 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: comp.h + AUTHOR......: David Rowe + DATE CREATED: 24/08/09 + + Complex number definition. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __COMP__ +#define __COMP__ + +/* Complex number */ + +typedef struct { + float real; + float imag; +} COMP; + +#endif diff --git a/gr-vocoder/lib/codec2/defines.h b/gr-vocoder/lib/codec2/defines.h new file mode 100644 index 000000000..2dcd527d3 --- /dev/null +++ b/gr-vocoder/lib/codec2/defines.h @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: defines.h + AUTHOR......: David Rowe + DATE CREATED: 23/4/93 + + Defines and structures used throughout the codec. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __DEFINES__ +#define __DEFINES__ + +/*---------------------------------------------------------------------------*\ + + DEFINES + +\*---------------------------------------------------------------------------*/ + +/* General defines */ + +#define N 80 /* number of samples per frame */ +#define MAX_AMP 80 /* maximum number of harmonics */ +#define PI 3.141592654 /* mathematical constant */ +#define TWO_PI 6.283185307 /* mathematical constant */ +#define FS 8000 /* sample rate in Hz */ +#define MAX_STR 256 /* maximum string size */ + +#define NW 279 /* analysis window size */ +#define FFT_ENC 512 /* size of FFT used for encoder */ +#define FFT_DEC 512 /* size of FFT used in decoder */ +#define TW 40 /* Trapezoidal synthesis window overlap */ +#define V_THRESH 6.0 /* voicing threshold in dB */ +#define LPC_MAX 20 /* maximum LPC order */ +#define LPC_ORD 10 /* phase modelling LPC order */ + +/* Pitch estimation defines */ + +#define M 320 /* pitch analysis frame size */ +#define P_MIN 20 /* minimum pitch */ +#define P_MAX 160 /* maximum pitch */ + +/*---------------------------------------------------------------------------*\ + + TYPEDEFS + +\*---------------------------------------------------------------------------*/ + +/* Structure to hold model parameters for one frame */ + +typedef struct { + float Wo; /* fundamental frequency estimate in radians */ + int L; /* number of harmonics */ + float A[MAX_AMP]; /* amplitiude of each harmonic */ + float phi[MAX_AMP]; /* phase of each harmonic */ + int voiced; /* non-zero if this frame is voiced */ +} MODEL; + +/* describes each codebook */ + +struct lsp_codebook { + int k; /* dimension of vector */ + int log2m; /* number of bits in m */ + int m; /* elements in codebook */ + const float * cb; /* The elements */ +}; +extern const struct lsp_codebook lsp_cb[]; +extern const struct lsp_codebook lsp_cbd[]; +extern const struct lsp_codebook lsp_cbdvq[]; + +#endif diff --git a/gr-vocoder/lib/codec2/dump.c b/gr-vocoder/lib/codec2/dump.c new file mode 100644 index 000000000..73a378e23 --- /dev/null +++ b/gr-vocoder/lib/codec2/dump.c @@ -0,0 +1,469 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: dump.c + AUTHOR......: David Rowe + DATE CREATED: 25/8/09 + + Routines to dump data to text files for Octave analysis. + +\*---------------------------------------------------------------------------*/ + +/* + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "defines.h" +#include "comp.h" +#include "dump.h" +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <math.h> + +#ifdef DUMP +static int dumpon = 0; + +static FILE *fsn = NULL; +static FILE *fsw = NULL; +static FILE *few = NULL; +static FILE *fsw_ = NULL; +static FILE *fmodel = NULL; +static FILE *fqmodel = NULL; +static FILE *fpw = NULL; +static FILE *flsp = NULL; +static FILE *fphase = NULL; +static FILE *fphase_ = NULL; +static FILE *ffw = NULL; +static FILE *fe = NULL; +static FILE *fsq = NULL; +static FILE *fdec = NULL; +static FILE *fsnr = NULL; +static FILE *fak = NULL; +static FILE *fbg = NULL; +static FILE *fE = NULL; +static FILE *frk = NULL; +static FILE *fres = NULL; + +static char prefix[MAX_STR]; + +void dump_on(char p[]) { + dumpon = 1; + strcpy(prefix, p); +} + +void dump_off(){ + if (fsn != NULL) + fclose(fsn); + if (fsw != NULL) + fclose(fsw); + if (fsw_ != NULL) + fclose(fsw_); + if (few != NULL) + fclose(few); + if (fmodel != NULL) + fclose(fmodel); + if (fqmodel != NULL) + fclose(fqmodel); + if (fpw != NULL) + fclose(fpw); + if (flsp != NULL) + fclose(flsp); + if (fphase != NULL) + fclose(fphase); + if (fphase_ != NULL) + fclose(fphase_); + if (ffw != NULL) + fclose(ffw); + if (fe != NULL) + fclose(fe); + if (fsq != NULL) + fclose(fsq); + if (fdec != NULL) + fclose(fdec); + if (fsnr != NULL) + fclose(fsnr); + if (fak != NULL) + fclose(fak); + if (fbg != NULL) + fclose(fbg); + if (fE != NULL) + fclose(fE); + if (frk != NULL) + fclose(frk); + if (fres != NULL) + fclose(fres); +} + +void dump_Sn(float Sn[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fsn == NULL) { + sprintf(s,"%s_sn.txt", prefix); + fsn = fopen(s, "wt"); + assert(fsn != NULL); + } + + /* split across two lines to avoid max line length problems */ + /* reconstruct in Octave */ + + for(i=0; i<M/2; i++) + fprintf(fsn,"%f\t",Sn[i]); + fprintf(fsn,"\n"); + for(i=M/2; i<M; i++) + fprintf(fsn,"%f\t",Sn[i]); + fprintf(fsn,"\n"); +} + +void dump_Sw(COMP Sw[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fsw == NULL) { + sprintf(s,"%s_sw.txt", prefix); + fsw = fopen(s, "wt"); + assert(fsw != NULL); + } + + for(i=0; i<FFT_ENC/2; i++) + fprintf(fsw,"%f\t", + 10.0*log10(Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag)); + fprintf(fsw,"\n"); +} + +void dump_Sw_(COMP Sw_[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fsw_ == NULL) { + sprintf(s,"%s_sw_.txt", prefix); + fsw_ = fopen(s, "wt"); + assert(fsw_ != NULL); + } + + for(i=0; i<FFT_ENC/2; i++) + fprintf(fsw_,"%f\t", + 10.0*log10(Sw_[i].real*Sw_[i].real + Sw_[i].imag*Sw_[i].imag)); + fprintf(fsw_,"\n"); +} + +void dump_Ew(COMP Ew[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (few == NULL) { + sprintf(s,"%s_ew.txt", prefix); + few = fopen(s, "wt"); + assert(few != NULL); + } + + for(i=0; i<FFT_ENC/2; i++) + fprintf(few,"%f\t", + 10.0*log10(Ew[i].real*Ew[i].real + Ew[i].imag*Ew[i].imag)); + fprintf(few,"\n"); +} + +void dump_model(MODEL *model) { + int l; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fmodel == NULL) { + sprintf(s,"%s_model.txt", prefix); + fmodel = fopen(s, "wt"); + assert(fmodel != NULL); + } + + fprintf(fmodel,"%f\t%d\t", model->Wo, model->L); + for(l=1; l<=model->L; l++) + fprintf(fmodel,"%f\t",model->A[l]); + for(l=model->L+1; l<MAX_AMP; l++) + fprintf(fmodel,"0.0\t"); + fprintf(fmodel,"%d\t",model->voiced); + fprintf(fmodel,"\n"); +} + +void dump_quantised_model(MODEL *model) { + int l; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fqmodel == NULL) { + sprintf(s,"%s_qmodel.txt", prefix); + fqmodel = fopen(s, "wt"); + assert(fqmodel != NULL); + } + + fprintf(fqmodel,"%f\t%d\t", model->Wo, model->L); + for(l=1; l<=model->L; l++) + fprintf(fqmodel,"%f\t",model->A[l]); + for(l=model->L+1; l<MAX_AMP; l++) + fprintf(fqmodel,"0.0\t"); + fprintf(fqmodel,"\n"); +} + +void dump_resample(float w[], float A[], int n) { + int l; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fres == NULL) { + sprintf(s,"%s_res.txt", prefix); + fres = fopen(s, "wt"); + assert(fres != NULL); + } + + fprintf(fres,"%d\t",n); + for(l=0; l<n; l++) + fprintf(fres,"%f\t",w[l]); + for(l=0; l<n; l++) + fprintf(fres,"%f\t",A[l]); + fprintf(fres,"\n"); +} + +void dump_phase(float phase[], int L) { + int l; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fphase == NULL) { + sprintf(s,"%s_phase.txt", prefix); + fphase = fopen(s, "wt"); + assert(fphase != NULL); + } + + for(l=1; l<=L; l++) + fprintf(fphase,"%f\t",phase[l]); + for(l=L+1; l<MAX_AMP; l++) + fprintf(fphase,"%f\t",0.0); + fprintf(fphase,"\n"); +} + +void dump_phase_(float phase_[], int L) { + int l; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fphase_ == NULL) { + sprintf(s,"%s_phase_.txt", prefix); + fphase_ = fopen(s, "wt"); + assert(fphase_ != NULL); + } + + for(l=1; l<=L; l++) + fprintf(fphase_,"%f\t",phase_[l]); + for(l=L+1; l<MAX_AMP; l++) + fprintf(fphase_,"%f\t",0.0); + fprintf(fphase_,"\n"); +} + +void dump_snr(float snr) { + char s[MAX_STR]; + + if (!dumpon) return; + + if (fsnr == NULL) { + sprintf(s,"%s_snr.txt", prefix); + fsnr = fopen(s, "wt"); + assert(fsnr != NULL); + } + + fprintf(fsnr,"%f\n",snr); +} + +void dump_Pw(COMP Pw[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fpw == NULL) { + sprintf(s,"%s_pw.txt", prefix); + fpw = fopen(s, "wt"); + assert(fpw != NULL); + } + + for(i=0; i<FFT_DEC/2; i++) + fprintf(fpw,"%f\t",Pw[i].real); + fprintf(fpw,"\n"); +} + +void dump_lsp(float lsp[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (flsp == NULL) { + sprintf(s,"%s_lsp.txt", prefix); + flsp = fopen(s, "wt"); + assert(flsp != NULL); + } + + for(i=0; i<10; i++) + fprintf(flsp,"%f\t",lsp[i]); + fprintf(flsp,"\n"); +} + +void dump_ak(float ak[], int order) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fak == NULL) { + sprintf(s,"%s_ak.txt", prefix); + fak = fopen(s, "wt"); + assert(fak != NULL); + } + + for(i=0; i<=order; i++) + fprintf(fak,"%f\t",ak[i]); + fprintf(fak,"\n"); +} + +void dump_Fw(COMP Fw[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (ffw == NULL) { + sprintf(s,"%s_fw.txt", prefix); + ffw = fopen(s, "wt"); + assert(ffw != NULL); + } + + for(i=0; i<256; i++) + fprintf(ffw,"%f\t",Fw[i].real); + fprintf(ffw,"\n"); +} + +void dump_e(float e_hz[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fe == NULL) { + sprintf(s,"%s_e.txt", prefix); + fe = fopen(s, "wt"); + assert(fe != NULL); + } + + for(i=0; i<500/2; i++) + fprintf(fe,"%f\t",e_hz[i]); + fprintf(fe,"\n"); + for(i=500/2; i<500; i++) + fprintf(fe,"%f\t",e_hz[i]); + fprintf(fe,"\n"); +} + +void dump_sq(float sq[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fsq == NULL) { + sprintf(s,"%s_sq.txt", prefix); + fsq = fopen(s, "wt"); + assert(fsq != NULL); + } + + for(i=0; i<M/2; i++) + fprintf(fsq,"%f\t",sq[i]); + fprintf(fsq,"\n"); + for(i=M/2; i<M; i++) + fprintf(fsq,"%f\t",sq[i]); + fprintf(fsq,"\n"); +} + +void dump_dec(COMP Fw[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (fdec == NULL) { + sprintf(s,"%s_dec.txt", prefix); + fdec = fopen(s, "wt"); + assert(fdec != NULL); + } + + for(i=0; i<320/5; i++) + fprintf(fdec,"%f\t",Fw[i].real); + fprintf(fdec,"\n"); +} + +void dump_bg(float e, float bg_est, float percent_uv) { + char s[MAX_STR]; + + if (!dumpon) return; + + if (fbg == NULL) { + sprintf(s,"%s_bg.txt", prefix); + fbg = fopen(s, "wt"); + assert(fbg != NULL); + } + + fprintf(fbg,"%f\t%f\t%f\n", e, bg_est, percent_uv); +} + +void dump_E(float E) { + char s[MAX_STR]; + + if (!dumpon) return; + + if (fE == NULL) { + sprintf(s,"%s_E.txt", prefix); + fE = fopen(s, "wt"); + assert(fE != NULL); + } + + fprintf(fE,"%f\n", 10.0*log10(E)); +} + +void dump_Rk(float Rk[]) { + int i; + char s[MAX_STR]; + + if (!dumpon) return; + + if (frk == NULL) { + sprintf(s,"%s_rk.txt", prefix); + frk = fopen(s, "wt"); + assert(frk != NULL); + } + + for(i=0; i<P_MAX; i++) + fprintf(frk,"%f\t",Rk[i]); + fprintf(frk,"\n"); +} + +#endif diff --git a/gr-vocoder/lib/codec2/dump.h b/gr-vocoder/lib/codec2/dump.h new file mode 100644 index 000000000..eeddd3406 --- /dev/null +++ b/gr-vocoder/lib/codec2/dump.h @@ -0,0 +1,67 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: dump.h + AUTHOR......: David Rowe + DATE CREATED: 25/8/09 + + Routines to dump data to text files for Octave analysis. + +\*---------------------------------------------------------------------------*/ + +/* + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __DUMP__ +#define __DUMP__ + +#include "comp.h" + +void dump_on(char filename_prefix[]); +void dump_off(); + +void dump_Sn(float Sn[]); +void dump_Sw(COMP Sw[]); +void dump_Sw_(COMP Sw_[]); +void dump_Ew(COMP Ew[]); + +/* amplitude modelling */ + +void dump_model(MODEL *m); +void dump_quantised_model(MODEL *m); +void dump_Pw(COMP Pw[]); +void dump_lsp(float lsp[]); +void dump_ak(float ak[], int order); +void dump_E(float E); +void dump_resample(float w[], float A[], int n); + +/* phase modelling */ + +void dump_snr(float snr); +void dump_phase(float phase[], int L); +void dump_phase_(float phase[], int L); + +/* NLP states */ + +void dump_sq(float sq[]); +void dump_dec(COMP Fw[]); +void dump_Fw(COMP Fw[]); +void dump_e(float e_hz[]); +void dump_Rk(float Rk[]); + +/* post filter */ + +void dump_bg(float e, float bg_est, float percent_uv); + +#endif diff --git a/gr-vocoder/lib/codec2/fft.c b/gr-vocoder/lib/codec2/fft.c new file mode 100644 index 000000000..a33e4d2c8 --- /dev/null +++ b/gr-vocoder/lib/codec2/fft.c @@ -0,0 +1,101 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: fft.c + AUTHOR......: Bruce Robertson + DATE CREATED: 20/11/2010 + + Bridging function to the kiss_fft package. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2010 Bruce Robertson + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <assert.h> +#include "kiss_fft.h" + +/*---------------------------------------------------------------------------*\ + + GLOBALS + +\*---------------------------------------------------------------------------*/ + +kiss_fft_cpx *fin; +kiss_fft_cpx *fout; +kiss_fft_cfg cfg_forward; +kiss_fft_cfg cfg_reverse; + +/*---------------------------------------------------------------------------*\ + + initialize_fft(int n) + + Initialisation function for kiss_fft. This assumes that all calls to fft() + use the same datatypes and are one arrays of the same size. + +\*---------------------------------------------------------------------------*/ + +void +initialize_fft (int n) +{ + fin = KISS_FFT_MALLOC (n * sizeof (kiss_fft_cpx)); + assert(fin != NULL); + fout = KISS_FFT_MALLOC (n * sizeof (kiss_fft_cpx)); + assert(fout != NULL); + cfg_forward = kiss_fft_alloc (n, 0, NULL, NULL); + assert(cfg_forward != NULL); + cfg_reverse = kiss_fft_alloc (n, 1, NULL, NULL); + assert(cfg_reverse != NULL); +} + +/*---------------------------------------------------------------------------*\ + + fft(float x[], int n, int isign) + Function that calls kiss_fft with the signature of four1 from NRC. + +\*---------------------------------------------------------------------------*/ + + +void +fft (float x[], int n, int isign) +{ + int isReverse = 0; + int c; + kiss_fft_cfg cfg; + if (cfg_forward == NULL) + { + initialize_fft (n); + } + for (c = 0; c < n * 2; c += 2) + { + fin[c / 2].r = x[c]; + fin[c / 2].i = -x[c + 1]; + } + if (isign == -1) + { + cfg = cfg_reverse; + } + else + { + cfg = cfg_forward; + } + kiss_fft (cfg, fin, fout); + for (c = 0; c < n * 2; c += 2) + { + x[c] = fout[(c) / 2].r; + x[c + 1] = -fout[(c) / 2].i; + } +} diff --git a/gr-vocoder/lib/codec2/fft.h b/gr-vocoder/lib/codec2/fft.h new file mode 100644 index 000000000..84c6737bd --- /dev/null +++ b/gr-vocoder/lib/codec2/fft.h @@ -0,0 +1,16 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: fft.h + AUTHOR......: Bruce Robertson + DATE CREATED: 29/11/2010 + + Bridge between existing code and kiss_fft. + +\*---------------------------------------------------------------------------*/ + +#ifndef __FFT__ +#define __FFT__ +void fft(float x[], int n, int isign); + +#endif /* __FFT__ */ + diff --git a/gr-vocoder/lib/codec2/fq20.sh b/gr-vocoder/lib/codec2/fq20.sh new file mode 100755 index 000000000..b83784b43 --- /dev/null +++ b/gr-vocoder/lib/codec2/fq20.sh @@ -0,0 +1,8 @@ +#!/bin/sh +# fq20.shsh +# David Rowe 27 July 2010 +# +# Decode a file with fully quantised codec at 20ms frame rate + +../src/sinedec ../raw/$1.raw $1.mdl -o $1_phase0_lsp_20_EWo2.raw --phase 0 --lpc 10 --lsp --postfilter --dec + diff --git a/gr-vocoder/lib/codec2/generate_codebook.c b/gr-vocoder/lib/codec2/generate_codebook.c new file mode 100644 index 000000000..0bea80d85 --- /dev/null +++ b/gr-vocoder/lib/codec2/generate_codebook.c @@ -0,0 +1,179 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: generate_codebook.c + AUTHOR......: Bruce Perens + DATE CREATED: 29 Sep 2010 + + Generate header files containing LSP quantisers, runs at compile time. + +\*---------------------------------------------------------------------------*/ + +/* + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <math.h> + +static const char usage[] = +"Usage: %s filename array_name [filename ...]\n" +"\tCreate C code for codebook tables.\n"; + +static const char format[] = +"The table format must be:\n" +"\tTwo integers describing the dimensions of the codebook.\n" +"\tThen, enough numbers to fill the specified dimensions.\n"; + +static const char header[] = +"/* THIS IS A GENERATED FILE. Edit generate_codebook.c and its input */\n\n" +"/*\n" +" * This intermediary file and the files that used to create it are under \n" +" * The LGPL. See the file COPYING.\n" +" */\n\n" +"#include \"defines.h\"\n\n"; + +struct codebook { + unsigned int k; + unsigned int log2m; + unsigned int m; + float * cb; +}; + +static void +dump_array(const struct codebook * b, int index) +{ + int limit = b->k * b->m; + int i; + + printf("static const float codes%d[] = {\n", index); + for ( i = 0; i < limit; i++ ) { + printf(" %g", b->cb[i]); + if ( i < limit - 1 ) + printf(","); + + /* organise VQs by rows, looks prettier */ + if ( ((i+1) % b->k) == 0 ) + printf("\n"); + } + printf("};\n"); +} + +static void +dump_structure(const struct codebook * b, int index) +{ + printf(" {\n"); + printf(" %d,\n", b->k); + printf(" %g,\n", log(b->m) / log(2)); + printf(" %d,\n", b->m); + printf(" codes%d\n", index); + printf(" }"); +} + +float +get_float(FILE * in, const char * name, char * * cursor, char * buffer, + int size) +{ + for ( ; ; ) { + char * s = *cursor; + char c; + + while ( (c = *s) != '\0' && !isdigit(c) && c != '-' && c != '.' ) + s++; + + /* Comments start with "#" and continue to the end of the line. */ + if ( c != '\0' && c != '#' ) { + char * end = 0; + float f = 0; + + f = strtod(s, &end); + + if ( end != s ) + *cursor = end; + return f; + } + + if ( fgets(buffer, size, in) == NULL ) { + fprintf(stderr, "%s: Format error. %s\n", name, format); + exit(1); + } + *cursor = buffer; + } +} + +static struct codebook * +load(FILE * file, const char * name) +{ + char line[1024]; + char * cursor = line; + struct codebook * b = malloc(sizeof(struct codebook)); + int i; + int size; + + *cursor = '\0'; + + b->k = (int)get_float(file, name, &cursor, line, sizeof(line)); + b->m = (int)get_float(file, name ,&cursor, line, sizeof(line)); + size = b->k * b->m; + + b->cb = (float *)malloc(size * sizeof(float)); + + for ( i = 0; i < size; i++ ) + b->cb[i] = get_float(file, name, &cursor, line, sizeof(line)); + + return b; +} + +int +main(int argc, char * * argv) +{ + struct codebook * * cb = malloc(argc * sizeof(struct codebook *)); + int i; + + if ( argc < 2 ) { + fprintf(stderr, usage, argv[0]); + fprintf(stderr, format); + exit(1); + } + + for ( i = 0; i < argc - 2; i++ ) { + FILE * in = fopen(argv[i + 2], "r"); + + if ( in == NULL ) { + perror(argv[i + 2]); + exit(1); + } + + cb[i] = load(in, argv[i + 2]); + + fclose(in); + } + + printf(header); + for ( i = 0; i < argc - 2; i++ ) { + printf(" /* %s */\n", argv[i + 2]); + dump_array(cb[i], i); + } + printf("\nconst struct lsp_codebook %s[] = {\n", argv[1]); + for ( i = 0; i < argc - 2; i++ ) { + printf(" /* %s */\n", argv[i + 2]); + dump_structure(cb[i], i); + printf(",\n"); + } + printf(" { 0, 0, 0, 0 }\n"); + printf("};\n"); + + return 0; +} diff --git a/gr-vocoder/lib/codec2/globals.c b/gr-vocoder/lib/codec2/globals.c new file mode 100644 index 000000000..f2182f79a --- /dev/null +++ b/gr-vocoder/lib/codec2/globals.c @@ -0,0 +1,49 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: globals.c + AUTHOR......: David Rowe + DATE CREATED: 11/5/94 + + Globals for sinusoidal speech coder. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "sine.h" /* global defines for coder */ + +/* Globals used in encoder and decoder */ + +int frames; /* number of frames processed so far */ +float Sn[M]; /* float input speech samples */ +MODEL model; /* model parameters for the current frame */ +int Nw; /* number of samples in analysis window */ +float sig; /* energy of current frame */ + +/* Globals used in encoder */ + +float w[M]; /* time domain hamming window */ +COMP W[FFT_ENC]; /* DFT of w[] */ +COMP Sw[FFT_ENC]; /* DFT of current frame */ + +/* Globals used in decoder */ + +COMP Sw_[FFT_ENC]; /* DFT of all voiced synthesised signal */ +float Sn_[AW_DEC]; /* synthesised speech */ +float Pn[AW_DEC]; /* time domain Parzen (trapezoidal) window */ + diff --git a/gr-vocoder/lib/codec2/globals.h b/gr-vocoder/lib/codec2/globals.h new file mode 100644 index 000000000..cef720344 --- /dev/null +++ b/gr-vocoder/lib/codec2/globals.h @@ -0,0 +1,47 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: globals.h + AUTHOR......: David Rowe + DATE CREATED: 1/11/94 + + Globals for sinusoidal speech coder. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +/* Globals used in encoder and decoder */ + +extern int frames; /* number of frames processed so far */ +extern float Sn[]; /* float input speech samples */ +extern MODEL model; /* model parameters for the current frame */ +extern int Nw; /* number of samples in analysis window */ +extern float sig; /* energy of current frame */ + +/* Globals used in encoder */ + +extern float w[]; /* time domain hamming window */ +extern COMP W[]; /* frequency domain hamming window */ +extern COMP Sw[]; /* DFT of current frame */ +extern COMP Sw_[]; /* DFT of all voiced synthesised signal */ + +/* Globals used in decoder */ + +extern float Sn_[]; /* output synthesised speech samples */ +extern float Pn[]; /* time domain Parzen (trapezoidal) window */ + diff --git a/gr-vocoder/lib/codec2/glottal.c b/gr-vocoder/lib/codec2/glottal.c new file mode 100644 index 000000000..8ac3ff4a9 --- /dev/null +++ b/gr-vocoder/lib/codec2/glottal.c @@ -0,0 +1,257 @@ +const float glottal[]={ + 0.000000, + -0.057687, + -0.115338, + -0.172917, + -0.230385, + -0.287707, + -0.344845, + -0.401762, + -0.458419, + -0.514781, + -0.570809, + -0.626467, + -0.681721, + -0.736537, + -0.790884, + -0.844733, + -0.898057, + -0.950834, + -1.003044, + -1.054670, + -1.105700, + -1.156124, + -1.205936, + -1.255132, + -1.303711, + -1.351675, + -1.399026, + -1.445769, + -1.491908, + -1.537448, + -1.582393, + -1.626747, + -1.670514, + -1.713693, + -1.756285, + -1.798288, + -1.839697, + -1.880507, + -1.920712, + -1.960302, + -1.999269, + -2.037603, + -2.075295, + -2.112335, + -2.148716, + -2.184430, + -2.219472, + -2.253839, + -2.287531, + -2.320550, + -2.352900, + -2.384588, + -2.415623, + -2.446019, + -2.475788, + -2.504946, + -2.533512, + -2.561501, + -2.588934, + -2.615827, + -2.642198, + -2.668064, + -2.693439, + -2.718337, + -2.742767, + -2.766738, + -2.790256, + -2.813322, + -2.835936, + -2.858094, + -2.879790, + -2.901016, + -2.921759, + -2.942008, + -2.961747, + -2.980961, + -2.999632, + -3.017745, + -3.035282, + -3.052228, + -3.068567, + -3.084285, + -3.099371, + -3.113813, + -3.127605, + -3.140738, + 3.129975, + 3.118167, + 3.107022, + 3.096537, + 3.086709, + 3.077531, + 3.068996, + 3.061096, + 3.053821, + 3.047159, + 3.041102, + 3.035636, + 3.030753, + 3.026441, + 3.022690, + 3.019491, + 3.016836, + 3.014718, + 3.013132, + 3.012072, + 3.011535, + 3.011521, + 3.012028, + 3.013057, + 3.014612, + 3.016695, + 3.019310, + 3.022463, + 3.026160, + 3.030407, + 3.035212, + 3.040580, + 3.046520, + 3.053038, + 3.060141, + 3.067836, + 3.076128, + 3.085023, + 3.094525, + 3.104639, + 3.115367, + 3.126712, + 3.138674, + -3.131930, + -3.118731, + -3.104915, + -3.090485, + -3.075444, + -3.059795, + -3.043543, + -3.026695, + -3.009254, + -2.991229, + -2.972625, + -2.953449, + -2.933710, + -2.913414, + -2.892567, + -2.871176, + -2.849248, + -2.826787, + -2.803798, + -2.780284, + -2.756247, + -2.731689, + -2.706609, + -2.681005, + -2.654875, + -2.628213, + -2.601015, + -2.573272, + -2.544977, + -2.516121, + -2.486694, + -2.456686, + -2.426084, + -2.394879, + -2.363060, + -2.330616, + -2.297538, + -2.263816, + -2.229444, + -2.194416, + -2.158727, + -2.122375, + -2.085359, + -2.047682, + -2.009347, + -1.970361, + -1.930732, + -1.890470, + -1.849587, + -1.808098, + -1.766017, + -1.723360, + -1.680145, + -1.636388, + -1.592105, + -1.547313, + -1.502025, + -1.456256, + -1.410016, + -1.363314, + -1.316157, + -1.268547, + -1.220486, + -1.171971, + -1.122997, + -1.073555, + -1.023636, + -0.973227, + -0.922312, + -0.870875, + -0.818899, + -0.766366, + -0.713257, + -0.659554, + -0.605242, + -0.550303, + -0.494723, + -0.438492, + -0.381598, + -0.324036, + -0.265800, + -0.206889, + -0.147303, + -0.087046, + -0.026121, + 0.035463, + 0.097698, + 0.160576, + 0.224087, + 0.288221, + 0.352969, + 0.418323, + 0.484276, + 0.550822, + 0.617958, + 0.685681, + 0.753991, + 0.822889, + 0.892378, + 0.962462, + 1.033144, + 1.104430, + 1.176325, + 1.248833, + 1.321956, + 1.395696, + 1.470051, + 1.545019, + 1.620593, + 1.696763, + 1.773516, + 1.850837, + 1.928705, + 2.007097, + 2.085987, + 2.165347, + 2.245145, + 2.325347, + 2.405919, + 2.486824, + 2.568025, + 2.649485, + 2.731167, + 2.813033, + 2.895045, + 2.977167, + 3.059362}; diff --git a/gr-vocoder/lib/codec2/interp.c b/gr-vocoder/lib/codec2/interp.c new file mode 100644 index 000000000..135d8c9e7 --- /dev/null +++ b/gr-vocoder/lib/codec2/interp.c @@ -0,0 +1,472 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: interp.c + AUTHOR......: David Rowe + DATE CREATED: 9/10/09 + + Interpolation of 20ms frames to 10ms frames. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <assert.h> +#include <math.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include "defines.h" +#include "interp.h" +#include "lsp.h" +#include "quantise.h" +#include "dump.h" + +float sample_log_amp(MODEL *model, float w); + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: interp() + AUTHOR......: David Rowe + DATE CREATED: 22/8/10 + + Given two frames decribed by model parameters 20ms apart, determines + the model parameters of the 10ms frame between them. Assumes + voicing is available for middle (interpolated) frame. Outputs are + amplitudes and Wo for the interpolated frame. + + This version can interpolate the amplitudes between two frames of + different Wo and L. + + This version works by log linear interpolation, but listening tests + showed it creates problems in background noise, e.g. hts2a and mmt1. + When this function is used (--dec mode) bg noise appears to be + amplitude modulated, and gets louder. The interp_lsp() function + below seems to do a better job. + +\*---------------------------------------------------------------------------*/ + +void interpolate( + MODEL *interp, /* interpolated model params */ + MODEL *prev, /* previous frames model params */ + MODEL *next /* next frames model params */ +) +{ + int l; + float w,log_amp; + + /* Wo depends on voicing of this and adjacent frames */ + + if (interp->voiced) { + if (prev->voiced && next->voiced) + interp->Wo = (prev->Wo + next->Wo)/2.0; + if (!prev->voiced && next->voiced) + interp->Wo = next->Wo; + if (prev->voiced && !next->voiced) + interp->Wo = prev->Wo; + } + else { + interp->Wo = TWO_PI/P_MAX; + } + interp->L = PI/interp->Wo; + + /* Interpolate amplitudes using linear interpolation in log domain */ + + for(l=1; l<=interp->L; l++) { + w = l*interp->Wo; + log_amp = (sample_log_amp(prev, w) + sample_log_amp(next, w))/2.0; + interp->A[l] = pow(10.0, log_amp); + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: sample_log_amp() + AUTHOR......: David Rowe + DATE CREATED: 22/8/10 + + Samples the amplitude envelope at an arbitrary frequency w. Uses + linear interpolation in the log domain to sample between harmonic + amplitudes. + +\*---------------------------------------------------------------------------*/ + +float sample_log_amp(MODEL *model, float w) +{ + int m; + float f, log_amp; + + assert(w > 0.0); assert (w <= PI); + + m = 0; + while ((m+1)*model->Wo < w) m++; + f = (w - m*model->Wo)/model->Wo; + assert(f <= 1.0); + + if (m < 1) { + log_amp = f*log10(model->A[1] + 1E-6); + } + else if ((m+1) > model->L) { + log_amp = (1.0-f)*log10(model->A[model->L] + 1E-6); + } + else { + log_amp = (1.0-f)*log10(model->A[m] + 1E-6) + + f*log10(model->A[m+1] + 1E-6); + //printf("m=%d A[m] %f A[m+1] %f x %f %f %f\n", m, model->A[m], + // model->A[m+1], pow(10.0, log_amp), + // (1-f), f); + } + + return log_amp; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: sample_log_amp_quad() + AUTHOR......: David Rowe + DATE CREATED: 9 March 2011 + + Samples the amplitude envelope at an arbitrary frequency w. Uses + quadratic interpolation in the log domain to sample between harmonic + amplitudes. + + y(x) = ax*x + bx + c + + We assume three points are x=-1, x=0, x=1, which we map to m-1,m,m+1 + + c = y(0) + b = (y(1) - y(-1))/2 + a = y(-1) + b - y(0) + +\*---------------------------------------------------------------------------*/ + +float sample_log_amp_quad(MODEL *model, float w) +{ + int m; + float a,b,c,x, log_amp; + + assert(w > 0.0); assert (w <= PI); + + m = floor(w/model->Wo + 0.5); + if (m < 2) m = 2; + if (m > (model->L-1)) m = model->L-1; + c = log10(model->A[m]+1E-6); + b = (log10(model->A[m+1]+1E-6) - log10(model->A[m-1]+1E-6))/2.0; + a = log10(model->A[m-1]+1E-6) + b - c; + x = (w - m*model->Wo)/model->Wo; + + log_amp = a*x*x + b*x + c; + //printf("m=%d A[m-1] %f A[m] %f A[m+1] %f w %f x %f log_amp %f\n", m, + // model->A[m-1], + // model->A[m], model->A[m+1], w, x, pow(10.0, log_amp)); + return log_amp; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: sample_log_amp_quad_nl() + AUTHOR......: David Rowe + DATE CREATED: 10 March 2011 + + Samples the amplitude envelope at an arbitrary frequency w. Uses + quadratic interpolation in the log domain to sample between harmonic + amplitudes. This version can handle non-linear steps along a freq + axis defined by arbitrary steps. + + y(x) = ax*x + bx + c + + We assume three points are (x_1,y_1), (0,y0) and (x1,y1). + +\*---------------------------------------------------------------------------*/ + +float sample_log_amp_quad_nl( + float w[], /* frequency points */ + float A[], /* for these amplitude samples */ + int np, /* number of frequency points */ + float w_sample /* frequency of new samples */ +) +{ + int m,i; + float a,b,c,x, log_amp, best_dist; + float x_1, x1; + float y_1, y0, y1; + + //printf("w_sample %f\n", w_sample); + assert(w_sample >= 0.0); assert (w_sample <= 1.1*PI); + + /* find closest point to centre quadratic interpolator */ + + best_dist = 1E32; + for (i=0; i<np; i++) + if (fabs(w[i] - w_sample) < best_dist) { + best_dist = fabs(w[i] - w_sample); + m = i; + } + + /* stay one point away from edge of array */ + + if (m < 1) m = 1; + if (m > (np-2)) m = np - 2; + + /* find polynomial coeffs */ + + x_1 = w[m-1]- w[m]; x1 = w[m+1] - w[m]; + y_1 = log10(A[m-1]+1E-6); + y0 = log10(A[m]+1E-6); + y1 = log10(A[m+1]+1E-6); + + c = y0; + a = (y_1*x1 - y1*x_1 + c*x_1 - c*x1)/(x_1*x_1*x1 - x1*x1*x_1); + b = (y1 -a*x1*x1 - c)/x1; + x = w_sample - w[m]; + + //printf("%f %f %f\n", w[0], w[1], w[2]); + //printf("%f %f %f %f %f %f\n", x_1, y_1, 0.0, y0, x1, y1); + log_amp = a*x*x + b*x + c; + //printf("a %f b %f c %f\n", a, b, c); + //printf("m=%d A[m-1] %f A[m] %f A[m+1] %f w_sample %f w[m] %f x %f log_amp %f\n", m, + // A[m-1], + // A[m], A[m+1], w_sample, w[m], x, log_amp); + //exit(0); + return log_amp; +} + +#define M_MAX 40 + +float fres[] = {100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, + 1200, 1400, 1600, 1850, 2100, 2350, 2600, 2900, 3400, 3800}; + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: resample_amp_nl() + AUTHOR......: David Rowe + DATE CREATED: 7 March 2011 + + Converts the current model with L {Am} samples spaced Wo apart to + RES_POINTS samples spaced Wo/RES_POINTS apart. Then subtracts + from the previous frames samples to get the delta. + +\*---------------------------------------------------------------------------*/ + +void resample_amp_fixed(MODEL *model, + float w[], float A[], + float wres[], float Ares[], + float AresdB_prev[], + float AresdB[], + float deltat[]) +{ + int i; + + for(i=1; i<=model->L; i++) { + w[i-1] = i*model->Wo; + A[i-1] = model->A[i]; + } + + for(i=0; i<RES_POINTS; i++) { + wres[i] = fres[i]*PI/4000.0; + } + + for(i=0; i<RES_POINTS; i++) { + Ares[i] = pow(10.0,sample_log_amp_quad_nl(w, A, model->L, wres[i])); + } + + /* work out delta T vector for this frame */ + + for(i=0; i<RES_POINTS; i++) { + AresdB[i] = 20.0*log10(Ares[i]); + deltat[i] = AresdB[i] - AresdB_prev[i]; + } + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: resample_amp_nl() + AUTHOR......: David Rowe + DATE CREATED: 7 March 2011 + + Converts the current model with L {Am} samples spaced Wo apart to M + samples spaced Wo/M apart. Then converts back to L {Am} samples. + used to prototype constant rate Amplitude encoding ideas. + + Returns the SNR in dB. + +\*---------------------------------------------------------------------------*/ + +float resample_amp_nl(MODEL *model, int m, float AresdB_prev[]) +{ + int i; + float w[MAX_AMP], A[MAX_AMP]; + float wres[MAX_AMP], Ares[MAX_AMP], AresdB[MAX_AMP]; + float signal, noise, snr; + float new_A; + float deltat[MAX_AMP], deltat_q[MAX_AMP], AresdB_q[MAX_AMP]; + + resample_amp_fixed(model, w, A, wres, Ares, AresdB_prev, AresdB, deltat); + + /* quantise delta T vector */ + + for(i=0; i<RES_POINTS; i++) { + noise = 3.0*(1.0 - 2.0*rand()/RAND_MAX); + //noise = 0.0; + deltat_q[i] = deltat[i] + noise; + } + + /* recover Ares vector */ + + for(i=0; i<RES_POINTS; i++) { + AresdB_q[i] = AresdB_prev[i] + deltat_q[i]; + Ares[i] = pow(10.0, AresdB_q[i]/20.0); + //printf("%d %f %f\n", i, AresdB[i], AresdB_q[i]); + } + + /* update memory based on version at decoder */ + + for(i=0; i<RES_POINTS; i++) { + AresdB_prev[i] = AresdB_q[i]; + } + +#ifdef DUMP + dump_resample(wres,Ares,M_MAX); +#endif + + signal = noise = 0.0; + + for(i=1; i<model->L; i++) { + new_A = pow(10.0,sample_log_amp_quad_nl(wres, Ares, RES_POINTS, model->Wo*i)); + signal += pow(model->A[i], 2.0); + noise += pow(model->A[i] - new_A, 2.0); + //printf("%f %f\n", model->A[i], new_A); + model->A[i] = new_A; + } + + snr = 10.0*log10(signal/noise); + printf("snr = %3.2f\n", snr); + //exit(0); + return snr; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: resample_amp() + AUTHOR......: David Rowe + DATE CREATED: 10 March 2011 + + Converts the current model with L {Am} samples spaced Wo apart to M + samples with a non-linear spacing. Then converts back to L {Am} + samples. used to prototype constant rate Amplitude encoding ideas. + + Returns the SNR in dB. + +\*---------------------------------------------------------------------------*/ + +float resample_amp(MODEL *model, int m) +{ + int i; + MODEL model_m; + float new_A, signal, noise, snr, log_amp_dB; + float n_db = 0.0; + + model_m.Wo = PI/(float)m; + model_m.L = PI/model_m.Wo; + + for(i=1; i<=model_m.L; i++) { + log_amp_dB = 20.0*sample_log_amp_quad(model, i*model_m.Wo); + log_amp_dB += n_db*(1.0 - 2.0*rand()/RAND_MAX); + model_m.A[i] = pow(10,log_amp_dB/20.0); + } + + //dump_resample(&model_m); + + signal = noise = 0.0; + + for(i=1; i<model->L/4; i++) { + new_A = pow(10,sample_log_amp_quad(&model_m, i*model->Wo)); + signal += pow(model->A[i], 2.0); + noise += pow(model->A[i] - new_A, 2.0); + //printf("%f %f\n", model->A[i], new_A); + model->A[i] = new_A; + } + + snr = 10.0*log10(signal/noise); + //printf("snr = %3.2f\n", snr); + //exit(0); + return snr; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: interp_lsp() + AUTHOR......: David Rowe + DATE CREATED: 10 Nov 2010 + + Given two frames decribed by model parameters 20ms apart, determines + the model parameters of the 10ms frame between them. Assumes + voicing is available for middle (interpolated) frame. Outputs are + amplitudes and Wo for the interpolated frame. + + This version uses interpolation of LSPs, seems to do a better job + with bg noise. + +\*---------------------------------------------------------------------------*/ + +void interpolate_lsp( + MODEL *interp, /* interpolated model params */ + MODEL *prev, /* previous frames model params */ + MODEL *next, /* next frames model params */ + float *prev_lsps, /* previous frames LSPs */ + float prev_e, /* previous frames LPC energy */ + float *next_lsps, /* next frames LSPs */ + float next_e, /* next frames LPC energy */ + float *ak_interp /* interpolated aks for this frame */ + ) +{ + int l,i; + float lsps[LPC_ORD],e; + float snr; + + /* Wo depends on voicing of this and adjacent frames */ + + if (interp->voiced) { + if (prev->voiced && next->voiced) + interp->Wo = (prev->Wo + next->Wo)/2.0; + if (!prev->voiced && next->voiced) + interp->Wo = next->Wo; + if (prev->voiced && !next->voiced) + interp->Wo = prev->Wo; + } + else { + interp->Wo = TWO_PI/P_MAX; + } + interp->L = PI/interp->Wo; + + /* interpolate LSPs */ + + for(i=0; i<LPC_ORD; i++) { + lsps[i] = (prev_lsps[i] + next_lsps[i])/2.0; + } + + /* Interpolate LPC energy in log domain */ + + e = pow(10.0, (log10(prev_e) + log10(next_e))/2.0); + + /* convert back to amplitudes */ + + lsp_to_lpc(lsps, ak_interp, LPC_ORD); + aks_to_M2(ak_interp, LPC_ORD, interp, e, &snr, 0); +} diff --git a/gr-vocoder/lib/codec2/interp.h b/gr-vocoder/lib/codec2/interp.h new file mode 100644 index 000000000..d41eac3f8 --- /dev/null +++ b/gr-vocoder/lib/codec2/interp.h @@ -0,0 +1,41 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: interp.h + AUTHOR......: David Rowe + DATE CREATED: 9/10/09 + + Interpolation of 20ms frames to 10ms frames. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __INTERP__ +#define __INTERP__ + +#define RES_POINTS 20 + +void interpolate(MODEL *interp, MODEL *prev, MODEL *next); +void interpolate_lsp(MODEL *interp, MODEL *prev, MODEL *next, + float *prev_lsps, float prev_e, + float *next_lsps, float next_e, + float *ak_interp); +float resample_amp(MODEL *model, int m); +float resample_amp_nl(MODEL *model, int m, float Ares_prev[]); + +#endif diff --git a/gr-vocoder/lib/codec2/kiss_fft.c b/gr-vocoder/lib/codec2/kiss_fft.c new file mode 100644 index 000000000..465d6c97a --- /dev/null +++ b/gr-vocoder/lib/codec2/kiss_fft.c @@ -0,0 +1,408 @@ +/* +Copyright (c) 2003-2010, Mark Borgerding + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "_kiss_fft_guts.h" +/* The guts header contains all the multiplication and addition macros that are defined for + fixed or floating point complex numbers. It also delares the kf_ internal functions. + */ + +static void kf_bfly2( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m + ) +{ + kiss_fft_cpx * Fout2; + kiss_fft_cpx * tw1 = st->twiddles; + kiss_fft_cpx t; + Fout2 = Fout + m; + do{ + C_FIXDIV(*Fout,2); C_FIXDIV(*Fout2,2); + + C_MUL (t, *Fout2 , *tw1); + tw1 += fstride; + C_SUB( *Fout2 , *Fout , t ); + C_ADDTO( *Fout , t ); + ++Fout2; + ++Fout; + }while (--m); +} + +static void kf_bfly4( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + const size_t m + ) +{ + kiss_fft_cpx *tw1,*tw2,*tw3; + kiss_fft_cpx scratch[6]; + size_t k=m; + const size_t m2=2*m; + const size_t m3=3*m; + + + tw3 = tw2 = tw1 = st->twiddles; + + do { + C_FIXDIV(*Fout,4); C_FIXDIV(Fout[m],4); C_FIXDIV(Fout[m2],4); C_FIXDIV(Fout[m3],4); + + C_MUL(scratch[0],Fout[m] , *tw1 ); + C_MUL(scratch[1],Fout[m2] , *tw2 ); + C_MUL(scratch[2],Fout[m3] , *tw3 ); + + C_SUB( scratch[5] , *Fout, scratch[1] ); + C_ADDTO(*Fout, scratch[1]); + C_ADD( scratch[3] , scratch[0] , scratch[2] ); + C_SUB( scratch[4] , scratch[0] , scratch[2] ); + C_SUB( Fout[m2], *Fout, scratch[3] ); + tw1 += fstride; + tw2 += fstride*2; + tw3 += fstride*3; + C_ADDTO( *Fout , scratch[3] ); + + if(st->inverse) { + Fout[m].r = scratch[5].r - scratch[4].i; + Fout[m].i = scratch[5].i + scratch[4].r; + Fout[m3].r = scratch[5].r + scratch[4].i; + Fout[m3].i = scratch[5].i - scratch[4].r; + }else{ + Fout[m].r = scratch[5].r + scratch[4].i; + Fout[m].i = scratch[5].i - scratch[4].r; + Fout[m3].r = scratch[5].r - scratch[4].i; + Fout[m3].i = scratch[5].i + scratch[4].r; + } + ++Fout; + }while(--k); +} + +static void kf_bfly3( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + size_t m + ) +{ + size_t k=m; + const size_t m2 = 2*m; + kiss_fft_cpx *tw1,*tw2; + kiss_fft_cpx scratch[5]; + kiss_fft_cpx epi3; + epi3 = st->twiddles[fstride*m]; + + tw1=tw2=st->twiddles; + + do{ + C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); + + C_MUL(scratch[1],Fout[m] , *tw1); + C_MUL(scratch[2],Fout[m2] , *tw2); + + C_ADD(scratch[3],scratch[1],scratch[2]); + C_SUB(scratch[0],scratch[1],scratch[2]); + tw1 += fstride; + tw2 += fstride*2; + + Fout[m].r = Fout->r - HALF_OF(scratch[3].r); + Fout[m].i = Fout->i - HALF_OF(scratch[3].i); + + C_MULBYSCALAR( scratch[0] , epi3.i ); + + C_ADDTO(*Fout,scratch[3]); + + Fout[m2].r = Fout[m].r + scratch[0].i; + Fout[m2].i = Fout[m].i - scratch[0].r; + + Fout[m].r -= scratch[0].i; + Fout[m].i += scratch[0].r; + + ++Fout; + }while(--k); +} + +static void kf_bfly5( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m + ) +{ + kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; + int u; + kiss_fft_cpx scratch[13]; + kiss_fft_cpx * twiddles = st->twiddles; + kiss_fft_cpx *tw; + kiss_fft_cpx ya,yb; + ya = twiddles[fstride*m]; + yb = twiddles[fstride*2*m]; + + Fout0=Fout; + Fout1=Fout0+m; + Fout2=Fout0+2*m; + Fout3=Fout0+3*m; + Fout4=Fout0+4*m; + + tw=st->twiddles; + for ( u=0; u<m; ++u ) { + C_FIXDIV( *Fout0,5); C_FIXDIV( *Fout1,5); C_FIXDIV( *Fout2,5); C_FIXDIV( *Fout3,5); C_FIXDIV( *Fout4,5); + scratch[0] = *Fout0; + + C_MUL(scratch[1] ,*Fout1, tw[u*fstride]); + C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]); + C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]); + C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]); + + C_ADD( scratch[7],scratch[1],scratch[4]); + C_SUB( scratch[10],scratch[1],scratch[4]); + C_ADD( scratch[8],scratch[2],scratch[3]); + C_SUB( scratch[9],scratch[2],scratch[3]); + + Fout0->r += scratch[7].r + scratch[8].r; + Fout0->i += scratch[7].i + scratch[8].i; + + scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); + scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); + + scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); + scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); + + C_SUB(*Fout1,scratch[5],scratch[6]); + C_ADD(*Fout4,scratch[5],scratch[6]); + + scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); + scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); + scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); + scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); + + C_ADD(*Fout2,scratch[11],scratch[12]); + C_SUB(*Fout3,scratch[11],scratch[12]); + + ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; + } +} + +/* perform the butterfly for one stage of a mixed radix FFT */ +static void kf_bfly_generic( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_cfg st, + int m, + int p + ) +{ + int u,k,q1,q; + kiss_fft_cpx * twiddles = st->twiddles; + kiss_fft_cpx t; + int Norig = st->nfft; + + kiss_fft_cpx * scratch = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC(sizeof(kiss_fft_cpx)*p); + + for ( u=0; u<m; ++u ) { + k=u; + for ( q1=0 ; q1<p ; ++q1 ) { + scratch[q1] = Fout[ k ]; + C_FIXDIV(scratch[q1],p); + k += m; + } + + k=u; + for ( q1=0 ; q1<p ; ++q1 ) { + int twidx=0; + Fout[ k ] = scratch[0]; + for (q=1;q<p;++q ) { + twidx += fstride * k; + if (twidx>=Norig) twidx-=Norig; + C_MUL(t,scratch[q] , twiddles[twidx] ); + C_ADDTO( Fout[ k ] ,t); + } + k += m; + } + } + KISS_FFT_TMP_FREE(scratch); +} + +static +void kf_work( + kiss_fft_cpx * Fout, + const kiss_fft_cpx * f, + const size_t fstride, + int in_stride, + int * factors, + const kiss_fft_cfg st + ) +{ + kiss_fft_cpx * Fout_beg=Fout; + const int p=*factors++; /* the radix */ + const int m=*factors++; /* stage's fft length/p */ + const kiss_fft_cpx * Fout_end = Fout + p*m; + +#ifdef _OPENMP + // use openmp extensions at the + // top-level (not recursive) + if (fstride==1 && p<=5) + { + int k; + + // execute the p different work units in different threads +# pragma omp parallel for + for (k=0;k<p;++k) + kf_work( Fout +k*m, f+ fstride*in_stride*k,fstride*p,in_stride,factors,st); + // all threads have joined by this point + + switch (p) { + case 2: kf_bfly2(Fout,fstride,st,m); break; + case 3: kf_bfly3(Fout,fstride,st,m); break; + case 4: kf_bfly4(Fout,fstride,st,m); break; + case 5: kf_bfly5(Fout,fstride,st,m); break; + default: kf_bfly_generic(Fout,fstride,st,m,p); break; + } + return; + } +#endif + + if (m==1) { + do{ + *Fout = *f; + f += fstride*in_stride; + }while(++Fout != Fout_end ); + }else{ + do{ + // recursive call: + // DFT of size m*p performed by doing + // p instances of smaller DFTs of size m, + // each one takes a decimated version of the input + kf_work( Fout , f, fstride*p, in_stride, factors,st); + f += fstride*in_stride; + }while( (Fout += m) != Fout_end ); + } + + Fout=Fout_beg; + + // recombine the p smaller DFTs + switch (p) { + case 2: kf_bfly2(Fout,fstride,st,m); break; + case 3: kf_bfly3(Fout,fstride,st,m); break; + case 4: kf_bfly4(Fout,fstride,st,m); break; + case 5: kf_bfly5(Fout,fstride,st,m); break; + default: kf_bfly_generic(Fout,fstride,st,m,p); break; + } +} + +/* facbuf is populated by p1,m1,p2,m2, ... + where + p[i] * m[i] = m[i-1] + m0 = n */ +static +void kf_factor(int n,int * facbuf) +{ + int p=4; + double floor_sqrt; + floor_sqrt = floor( sqrt((double)n) ); + + /*factor out powers of 4, powers of 2, then any remaining primes */ + do { + while (n % p) { + switch (p) { + case 4: p = 2; break; + case 2: p = 3; break; + default: p += 2; break; + } + if (p > floor_sqrt) + p = n; /* no more factors, skip to end */ + } + n /= p; + *facbuf++ = p; + *facbuf++ = n; + } while (n > 1); +} + +/* + * + * User-callable function to allocate all necessary storage space for the fft. + * + * The return value is a contiguous block of memory, allocated with malloc. As such, + * It can be freed with free(), rather than a kiss_fft-specific function. + * */ +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem ) +{ + kiss_fft_cfg st=NULL; + size_t memneeded = sizeof(struct kiss_fft_state) + + sizeof(kiss_fft_cpx)*(nfft-1); /* twiddle factors*/ + + if ( lenmem==NULL ) { + st = ( kiss_fft_cfg)KISS_FFT_MALLOC( memneeded ); + }else{ + if (mem != NULL && *lenmem >= memneeded) + st = (kiss_fft_cfg)mem; + *lenmem = memneeded; + } + if (st) { + int i; + st->nfft=nfft; + st->inverse = inverse_fft; + + for (i=0;i<nfft;++i) { + const double pi=3.141592653589793238462643383279502884197169399375105820974944; + double phase = -2*pi*i / nfft; + if (st->inverse) + phase *= -1; + kf_cexp(st->twiddles+i, phase ); + } + + kf_factor(nfft,st->factors); + } + return st; +} + + +void kiss_fft_stride(kiss_fft_cfg st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int in_stride) +{ + if (fin == fout) { + //NOTE: this is not really an in-place FFT algorithm. + //It just performs an out-of-place FFT into a temp buffer + kiss_fft_cpx * tmpbuf = (kiss_fft_cpx*)KISS_FFT_TMP_ALLOC( sizeof(kiss_fft_cpx)*st->nfft); + kf_work(tmpbuf,fin,1,in_stride, st->factors,st); + memcpy(fout,tmpbuf,sizeof(kiss_fft_cpx)*st->nfft); + KISS_FFT_TMP_FREE(tmpbuf); + }else{ + kf_work( fout, fin, 1,in_stride, st->factors,st ); + } +} + +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) +{ + kiss_fft_stride(cfg,fin,fout,1); +} + + +void kiss_fft_cleanup(void) +{ + // nothing needed any more +} + +int kiss_fft_next_fast_size(int n) +{ + while(1) { + int m=n; + while ( (m%2) == 0 ) m/=2; + while ( (m%3) == 0 ) m/=3; + while ( (m%5) == 0 ) m/=5; + if (m<=1) + break; /* n is completely factorable by twos, threes, and fives */ + n++; + } + return n; +} diff --git a/gr-vocoder/lib/codec2/kiss_fft.h b/gr-vocoder/lib/codec2/kiss_fft.h new file mode 100644 index 000000000..64c50f4aa --- /dev/null +++ b/gr-vocoder/lib/codec2/kiss_fft.h @@ -0,0 +1,124 @@ +#ifndef KISS_FFT_H +#define KISS_FFT_H + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> +#include <string.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + ATTENTION! + If you would like a : + -- a utility that will handle the caching of fft objects + -- real-only (no imaginary time component ) FFT + -- a multi-dimensional FFT + -- a command-line utility to perform ffts + -- a command-line utility to perform fast-convolution filtering + + Then see kfc.h kiss_fftr.h kiss_fftnd.h fftutil.c kiss_fastfir.c + in the tools/ directory. +*/ + +#ifdef USE_SIMD +# include <xmmintrin.h> +# define kiss_fft_scalar __m128 +#define KISS_FFT_MALLOC(nbytes) _mm_malloc(nbytes,16) +#define KISS_FFT_FREE _mm_free +#else +#define KISS_FFT_MALLOC malloc +#define KISS_FFT_FREE free +#endif + + +#ifdef FIXED_POINT +#include <sys/types.h> +# if (FIXED_POINT == 32) +# define kiss_fft_scalar int32_t +# else +# define kiss_fft_scalar int16_t +# endif +#else +# ifndef kiss_fft_scalar +/* default is float */ +# define kiss_fft_scalar float +# endif +#endif + +typedef struct { + kiss_fft_scalar r; + kiss_fft_scalar i; +}kiss_fft_cpx; + +typedef struct kiss_fft_state* kiss_fft_cfg; + +/* + * kiss_fft_alloc + * + * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. + * + * typical usage: kiss_fft_cfg mycfg=kiss_fft_alloc(1024,0,NULL,NULL); + * + * The return value from fft_alloc is a cfg buffer used internally + * by the fft routine or NULL. + * + * If lenmem is NULL, then kiss_fft_alloc will allocate a cfg buffer using malloc. + * The returned value should be free()d when done to avoid memory leaks. + * + * The state can be placed in a user supplied buffer 'mem': + * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, + * then the function places the cfg in mem and the size used in *lenmem + * and returns mem. + * + * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), + * then the function returns NULL and places the minimum cfg + * buffer size in *lenmem. + * */ + +kiss_fft_cfg kiss_fft_alloc(int nfft,int inverse_fft,void * mem,size_t * lenmem); + +/* + * kiss_fft(cfg,in_out_buf) + * + * Perform an FFT on a complex input buffer. + * for a forward FFT, + * fin should be f[0] , f[1] , ... ,f[nfft-1] + * fout will be F[0] , F[1] , ... ,F[nfft-1] + * Note that each element is complex and can be accessed like + f[k].r and f[k].i + * */ +void kiss_fft(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); + +/* + A more generic version of the above function. It reads its input from every Nth sample. + * */ +void kiss_fft_stride(kiss_fft_cfg cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout,int fin_stride); + +/* If kiss_fft_alloc allocated a buffer, it is one contiguous + buffer and can be simply free()d when no longer needed*/ +#define kiss_fft_free free + +/* + Cleans up some memory that gets managed internally. Not necessary to call, but it might clean up + your compiler output to call this before you exit. +*/ +void kiss_fft_cleanup(void); + + +/* + * Returns the smallest integer k, such that k>=n and k has only "fast" factors (2,3,5) + */ +int kiss_fft_next_fast_size(int n); + +/* for real ffts, we need an even size */ +#define kiss_fftr_next_fast_size_real(n) \ + (kiss_fft_next_fast_size( ((n)+1)>>1)<<1) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/gr-vocoder/lib/codec2/listensim.sh b/gr-vocoder/lib/codec2/listensim.sh new file mode 100755 index 000000000..0b27a1b0c --- /dev/null +++ b/gr-vocoder/lib/codec2/listensim.sh @@ -0,0 +1,9 @@ +#!/bin/sh +# listensim.sh +# David Rowe 10 Sep 2009 +# +# Listen to files processed with sim.sh + +../script/menu.sh ../raw/$1.raw $1_uq.raw $1_phase0.raw $1_lpc10.raw $1_phase0_lpc10.raw $1_phase0_lpc10_dec.raw $1_phase0_lsp_dec.raw $2 $3 + + diff --git a/gr-vocoder/lib/codec2/lpc.c b/gr-vocoder/lib/codec2/lpc.c new file mode 100644 index 000000000..ba8011377 --- /dev/null +++ b/gr-vocoder/lib/codec2/lpc.c @@ -0,0 +1,279 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: lpc.c + AUTHOR......: David Rowe + DATE CREATED: 30/9/90 + + Linear Prediction functions written in C. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#define LPC_MAX_N 512 /* maximum no. of samples in frame */ +#define PI 3.141592654 /* mathematical constant */ + +#include <assert.h> +#include <math.h> +#include "defines.h" +#include "lpc.h" + +/*---------------------------------------------------------------------------*\ + + hanning_window() + + Hanning windows a frame of speech samples. + +\*---------------------------------------------------------------------------*/ + +void hanning_window( + float Sn[], /* input frame of speech samples */ + float Wn[], /* output frame of windowed samples */ + int Nsam /* number of samples */ +) +{ + int i; /* loop variable */ + + for(i=0; i<Nsam; i++) + Wn[i] = Sn[i]*(0.5 - 0.5*cos(2*PI*(float)i/(Nsam-1))); +} + +/*---------------------------------------------------------------------------*\ + + autocorrelate() + + Finds the first P autocorrelation values of an array of windowed speech + samples Sn[]. + +\*---------------------------------------------------------------------------*/ + +void autocorrelate( + float Sn[], /* frame of Nsam windowed speech samples */ + float Rn[], /* array of P+1 autocorrelation coefficients */ + int Nsam, /* number of windowed samples to use */ + int order /* order of LPC analysis */ +) +{ + int i,j; /* loop variables */ + + for(j=0; j<order+1; j++) { + Rn[j] = 0.0; + for(i=0; i<Nsam-j; i++) + Rn[j] += Sn[i]*Sn[i+j]; + } +} + +/*---------------------------------------------------------------------------*\ + + autocorrelate_freq() + + Finds the first P autocorrelation values from an array of frequency domain + power samples. + +\*---------------------------------------------------------------------------*/ + +void autocorrelate_freq( + float Pw[], /* Nsam frequency domain power spectrum samples */ + float w[], /* frequency of each sample in Pw[] */ + float R[], /* array of order+1 autocorrelation coefficients */ + int Nsam, /* number of windowed samples to use */ + int order /* order of LPC analysis */ +) +{ + int i,j; /* loop variables */ + + for(j=0; j<order+1; j++) { + R[j] = 0.0; + for(i=0; i<Nsam; i++) + R[j] += Pw[i]*cos(j*w[i]); + } + R[j] /= Nsam; +} + +/*---------------------------------------------------------------------------*\ + + levinson_durbin() + + Given P+1 autocorrelation coefficients, finds P Linear Prediction Coeff. + (LPCs) where P is the order of the LPC all-pole model. The Levinson-Durbin + algorithm is used, and is described in: + + J. Makhoul + "Linear prediction, a tutorial review" + Proceedings of the IEEE + Vol-63, No. 4, April 1975 + +\*---------------------------------------------------------------------------*/ + +void levinson_durbin( + float R[], /* order+1 autocorrelation coeff */ + float lpcs[], /* order+1 LPC's */ + int order /* order of the LPC analysis */ +) +{ + float E[LPC_MAX+1]; + float k[LPC_MAX+1]; + float a[LPC_MAX+1][LPC_MAX+1]; + float sum; + int i,j; /* loop variables */ + + E[0] = R[0]; /* Equation 38a, Makhoul */ + + for(i=1; i<=order; i++) { + sum = 0.0; + for(j=1; j<=i-1; j++) + sum += a[i-1][j]*R[i-j]; + k[i] = -1.0*(R[i] + sum)/E[i-1]; /* Equation 38b, Makhoul */ + if (fabs(k[i]) > 1.0) + k[i] = 0.0; + + a[i][i] = k[i]; + + for(j=1; j<=i-1; j++) + a[i][j] = a[i-1][j] + k[i]*a[i-1][i-j]; /* Equation 38c, Makhoul */ + + E[i] = (1-k[i]*k[i])*E[i-1]; /* Equation 38d, Makhoul */ + } + + for(i=1; i<=order; i++) + lpcs[i] = a[order][i]; + lpcs[0] = 1.0; +} + +/*---------------------------------------------------------------------------*\ + + inverse_filter() + + Inverse Filter, A(z). Produces an array of residual samples from an array + of input samples and linear prediction coefficients. + + The filter memory is stored in the first order samples of the input array. + +\*---------------------------------------------------------------------------*/ + +void inverse_filter( + float Sn[], /* Nsam input samples */ + float a[], /* LPCs for this frame of samples */ + int Nsam, /* number of samples */ + float res[], /* Nsam residual samples */ + int order /* order of LPC */ +) +{ + int i,j; /* loop variables */ + + for(i=0; i<Nsam; i++) { + res[i] = 0.0; + for(j=0; j<=order; j++) + res[i] += Sn[i-j]*a[j]; + } +} + +/*---------------------------------------------------------------------------*\ + + synthesis_filter() + + C version of the Speech Synthesis Filter, 1/A(z). Given an array of + residual or excitation samples, and the the LP filter coefficients, this + function will produce an array of speech samples. This filter structure is + IIR. + + The synthesis filter has memory as well, this is treated in the same way + as the memory for the inverse filter (see inverse_filter() notes above). + The difference is that the memory for the synthesis filter is stored in + the output array, wheras the memory of the inverse filter is stored in the + input array. + + Note: the calling function must update the filter memory. + +\*---------------------------------------------------------------------------*/ + +void synthesis_filter( + float res[], /* Nsam input residual (excitation) samples */ + float a[], /* LPCs for this frame of speech samples */ + int Nsam, /* number of speech samples */ + int order, /* LPC order */ + float Sn_[] /* Nsam output synthesised speech samples */ +) +{ + int i,j; /* loop variables */ + + /* Filter Nsam samples */ + + for(i=0; i<Nsam; i++) { + Sn_[i] = res[i]*a[0]; + for(j=1; j<=order; j++) + Sn_[i] -= Sn_[i-j]*a[j]; + } +} + +/*---------------------------------------------------------------------------*\ + + find_aks() + + This function takes a frame of samples, and determines the linear + prediction coefficients for that frame of samples. + +\*---------------------------------------------------------------------------*/ + +void find_aks( + float Sn[], /* Nsam samples with order sample memory */ + float a[], /* order+1 LPCs with first coeff 1.0 */ + int Nsam, /* number of input speech samples */ + int order, /* order of the LPC analysis */ + float *E /* residual energy */ +) +{ + float Wn[LPC_MAX_N]; /* windowed frame of Nsam speech samples */ + float R[LPC_MAX+1]; /* order+1 autocorrelation values of Sn[] */ + int i; + + assert(order < LPC_MAX); + assert(Nsam < LPC_MAX_N); + + hanning_window(Sn,Wn,Nsam); + autocorrelate(Wn,R,Nsam,order); + levinson_durbin(R,a,order); + + *E = 0.0; + for(i=0; i<=order; i++) + *E += a[i]*R[i]; + if (*E < 0.0) + *E = 1E-12; +} + +/*---------------------------------------------------------------------------*\ + + weight() + + Weights a vector of LPCs. + +\*---------------------------------------------------------------------------*/ + +void weight( + float ak[], /* vector of order+1 LPCs */ + float gamma, /* weighting factor */ + int order, /* num LPCs (excluding leading 1.0) */ + float akw[] /* weighted vector of order+1 LPCs */ +) +{ + int i; + + for(i=1; i<=order; i++) + akw[i] = ak[i]*pow(gamma,(float)i); +} + diff --git a/gr-vocoder/lib/codec2/lpc.h b/gr-vocoder/lib/codec2/lpc.h new file mode 100644 index 000000000..ead05e1ba --- /dev/null +++ b/gr-vocoder/lib/codec2/lpc.h @@ -0,0 +1,42 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: lpc.h + AUTHOR......: David Rowe + DATE CREATED: 24/8/09 + + Linear Prediction functions written in C. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __LPC__ +#define __LPC__ + +#define LPC_MAX_ORDER 20 + +void hanning_window(float Sn[], float Wn[], int Nsam); +void autocorrelate(float Sn[], float Rn[], int Nsam, int order); +void autocorrelate_freq(float Pw[], float w[], float R[], int Nsam, int order); +void levinson_durbin(float R[], float lpcs[], int order); +void inverse_filter(float Sn[], float a[], int Nsam, float res[], int order); +void synthesis_filter(float res[], float a[], int Nsam, int order, float Sn_[]); +void find_aks(float Sn[], float a[], int Nsam, int order, float *E); +void weight(float ak[], float gamma, int order, float akw[]); + +#endif diff --git a/gr-vocoder/lib/codec2/lsp.c b/gr-vocoder/lib/codec2/lsp.c new file mode 100644 index 000000000..47001c1ef --- /dev/null +++ b/gr-vocoder/lib/codec2/lsp.c @@ -0,0 +1,325 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: lsp.c + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + + This file contains functions for LPC to LSP conversion and LSP to + LPC conversion. Note that the LSP coefficients are not in radians + format but in the x domain of the unit circle. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "defines.h" +#include "lsp.h" +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +/* Only 10 gets used, so far. */ +#define LSP_MAX_ORDER 20 + +/*---------------------------------------------------------------------------*\ + + Introduction to Line Spectrum Pairs (LSPs) + ------------------------------------------ + + LSPs are used to encode the LPC filter coefficients {ak} for + transmission over the channel. LSPs have several properties (like + less sensitivity to quantisation noise) that make them superior to + direct quantisation of {ak}. + + A(z) is a polynomial of order lpcrdr with {ak} as the coefficients. + + A(z) is transformed to P(z) and Q(z) (using a substitution and some + algebra), to obtain something like: + + A(z) = 0.5[P(z)(z+z^-1) + Q(z)(z-z^-1)] (1) + + As you can imagine A(z) has complex zeros all over the z-plane. P(z) + and Q(z) have the very neat property of only having zeros _on_ the + unit circle. So to find them we take a test point z=exp(jw) and + evaluate P (exp(jw)) and Q(exp(jw)) using a grid of points between 0 + and pi. + + The zeros (roots) of P(z) also happen to alternate, which is why we + swap coefficients as we find roots. So the process of finding the + LSP frequencies is basically finding the roots of 5th order + polynomials. + + The root so P(z) and Q(z) occur in symmetrical pairs at +/-w, hence + the name Line Spectrum Pairs (LSPs). + + To convert back to ak we just evaluate (1), "clocking" an impulse + thru it lpcrdr times gives us the impulse response of A(z) which is + {ak}. + +\*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: cheb_poly_eva() + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + This function evalutes a series of chebyshev polynomials + + FIXME: performing memory allocation at run time is very inefficient, + replace with stack variables of MAX_P size. + +\*---------------------------------------------------------------------------*/ + + +static float +cheb_poly_eva(float *coef,float x,int m) +/* float coef[] coefficients of the polynomial to be evaluated */ +/* float x the point where polynomial is to be evaluated */ +/* int m order of the polynomial */ +{ + int i; + float *t,*u,*v,sum; + float T[(LSP_MAX_ORDER / 2) + 1]; + + /* Initialise pointers */ + + t = T; /* T[i-2] */ + *t++ = 1.0; + u = t--; /* T[i-1] */ + *u++ = x; + v = u--; /* T[i] */ + + /* Evaluate chebyshev series formulation using iterative approach */ + + for(i=2;i<=m/2;i++) + *v++ = (2*x)*(*u++) - *t++; /* T[i] = 2*x*T[i-1] - T[i-2] */ + + sum=0.0; /* initialise sum to zero */ + t = T; /* reset pointer */ + + /* Evaluate polynomial and return value also free memory space */ + + for(i=0;i<=m/2;i++) + sum+=coef[(m/2)-i]**t++; + + return sum; +} + + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: lpc_to_lsp() + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + This function converts LPC coefficients to LSP coefficients. + +\*---------------------------------------------------------------------------*/ + +int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta) +/* float *a lpc coefficients */ +/* int lpcrdr order of LPC coefficients (10) */ +/* float *freq LSP frequencies in radians */ +/* int nb number of sub-intervals (4) */ +/* float delta grid spacing interval (0.02) */ +{ + float psuml,psumr,psumm,temp_xr,xl,xr,xm = 0; + float temp_psumr; + int i,j,m,flag,k; + float *px; /* ptrs of respective P'(z) & Q'(z) */ + float *qx; + float *p; + float *q; + float *pt; /* ptr used for cheb_poly_eval() + whether P' or Q' */ + int roots=0; /* number of roots found */ + float Q[LSP_MAX_ORDER + 1]; + float P[LSP_MAX_ORDER + 1]; + + flag = 1; + m = lpcrdr/2; /* order of P'(z) & Q'(z) polynimials */ + + /* Allocate memory space for polynomials */ + + /* determine P'(z)'s and Q'(z)'s coefficients where + P'(z) = P(z)/(1 + z^(-1)) and Q'(z) = Q(z)/(1-z^(-1)) */ + + px = P; /* initilaise ptrs */ + qx = Q; + p = px; + q = qx; + *px++ = 1.0; + *qx++ = 1.0; + for(i=1;i<=m;i++){ + *px++ = a[i]+a[lpcrdr+1-i]-*p++; + *qx++ = a[i]-a[lpcrdr+1-i]+*q++; + } + px = P; + qx = Q; + for(i=0;i<m;i++){ + *px = 2**px; + *qx = 2**qx; + px++; + qx++; + } + px = P; /* re-initialise ptrs */ + qx = Q; + + /* Search for a zero in P'(z) polynomial first and then alternate to Q'(z). + Keep alternating between the two polynomials as each zero is found */ + + xr = 0; /* initialise xr to zero */ + xl = 1.0; /* start at point xl = 1 */ + + + for(j=0;j<lpcrdr;j++){ + if(j%2) /* determines whether P' or Q' is eval. */ + pt = qx; + else + pt = px; + + psuml = cheb_poly_eva(pt,xl,lpcrdr); /* evals poly. at xl */ + flag = 1; + while(flag && (xr >= -1.0)){ + xr = xl - delta ; /* interval spacing */ + psumr = cheb_poly_eva(pt,xr,lpcrdr);/* poly(xl-delta_x) */ + temp_psumr = psumr; + temp_xr = xr; + + /* if no sign change increment xr and re-evaluate + poly(xr). Repeat til sign change. if a sign change has + occurred the interval is bisected and then checked again + for a sign change which determines in which interval the + zero lies in. If there is no sign change between poly(xm) + and poly(xl) set interval between xm and xr else set + interval between xl and xr and repeat till root is located + within the specified limits */ + + if((psumr*psuml)<0.0){ + roots++; + + psumm=psuml; + for(k=0;k<=nb;k++){ + xm = (xl+xr)/2; /* bisect the interval */ + psumm=cheb_poly_eva(pt,xm,lpcrdr); + if(psumm*psuml>0.){ + psuml=psumm; + xl=xm; + } + else{ + psumr=psumm; + xr=xm; + } + } + + /* once zero is found, reset initial interval to xr */ + freq[j] = (xm); + xl = xm; + flag = 0; /* reset flag for next search */ + } + else{ + psuml=temp_psumr; + xl=temp_xr; + } + } + } + + /* convert from x domain to radians */ + + for(i=0; i<lpcrdr; i++) { + freq[i] = acos(freq[i]); + } + + return(roots); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: lsp_to_lpc() + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + This function converts LSP coefficients to LPC coefficients. In the + Speex code we worked out a way to simplify this significantly. + +\*---------------------------------------------------------------------------*/ + +void lsp_to_lpc(float *lsp, float *ak, int lpcrdr) +/* float *freq array of LSP frequencies in radians */ +/* float *ak array of LPC coefficients */ +/* int lpcrdr order of LPC coefficients */ + + +{ + int i,j; + float xout1,xout2,xin1,xin2; + float *pw,*n1,*n2,*n3,*n4 = 0; + int m = lpcrdr/2; + float freq[LSP_MAX_ORDER]; + float Wp[(LSP_MAX_ORDER * 4) + 2]; + + /* convert from radians to the x=cos(w) domain */ + + for(i=0; i<lpcrdr; i++) + freq[i] = cos(lsp[i]); + + pw = Wp; + + /* initialise contents of array */ + + for(i=0;i<=4*m+1;i++){ /* set contents of buffer to 0 */ + *pw++ = 0.0; + } + + /* Set pointers up */ + + pw = Wp; + xin1 = 1.0; + xin2 = 1.0; + + /* reconstruct P(z) and Q(z) by cascading second order polynomials + in form 1 - 2xz(-1) +z(-2), where x is the LSP coefficient */ + + for(j=0;j<=lpcrdr;j++){ + for(i=0;i<m;i++){ + n1 = pw+(i*4); + n2 = n1 + 1; + n3 = n2 + 1; + n4 = n3 + 1; + xout1 = xin1 - 2*(freq[2*i]) * *n1 + *n2; + xout2 = xin2 - 2*(freq[2*i+1]) * *n3 + *n4; + *n2 = *n1; + *n4 = *n3; + *n1 = xin1; + *n3 = xin2; + xin1 = xout1; + xin2 = xout2; + } + xout1 = xin1 + *(n4+1); + xout2 = xin2 - *(n4+2); + ak[j] = (xout1 + xout2)*0.5; + *(n4+1) = xin1; + *(n4+2) = xin2; + + xin1 = 0.0; + xin2 = 0.0; + } +} + diff --git a/gr-vocoder/lib/codec2/lsp.h b/gr-vocoder/lib/codec2/lsp.h new file mode 100644 index 000000000..5acef0184 --- /dev/null +++ b/gr-vocoder/lib/codec2/lsp.h @@ -0,0 +1,37 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: lsp.c + AUTHOR......: David Rowe + DATE CREATED: 24/2/93 + + + This file contains functions for LPC to LSP conversion and LSP to + LPC conversion. Note that the LSP coefficients are not in radians + format but in the x domain of the unit circle. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __LSP__ +#define __LSP__ + +int lpc_to_lsp (float *a, int lpcrdr, float *freq, int nb, float delta); +void lsp_to_lpc(float *freq, float *ak, int lpcrdr); + +#endif diff --git a/gr-vocoder/lib/codec2/nlp.c b/gr-vocoder/lib/codec2/nlp.c new file mode 100644 index 000000000..42ae90919 --- /dev/null +++ b/gr-vocoder/lib/codec2/nlp.c @@ -0,0 +1,364 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: nlp.c + AUTHOR......: David Rowe + DATE CREATED: 23/3/93 + + Non Linear Pitch (NLP) estimation functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include "defines.h" +#include "nlp.h" +#include "dump.h" +#include "fft.h" + +#include <assert.h> +#include <math.h> +#include <stdlib.h> + +/*---------------------------------------------------------------------------*\ + + DEFINES + +\*---------------------------------------------------------------------------*/ + +#define PMAX_M 600 /* maximum NLP analysis window size */ +#define COEFF 0.95 /* notch filter parameter */ +#define PE_FFT_SIZE 512 /* DFT size for pitch estimation */ +#define DEC 5 /* decimation factor */ +#define SAMPLE_RATE 8000 +#define PI 3.141592654 /* mathematical constant */ +#define T 0.1 /* threshold for local minima candidate */ +#define F0_MAX 500 +#define CNLP 0.3 /* post processor constant */ +#define NLP_NTAP 48 /* Decimation LPF order */ + +/*---------------------------------------------------------------------------*\ + + GLOBALS + +\*---------------------------------------------------------------------------*/ + +/* 48 tap 600Hz low pass FIR filter coefficients */ + +const float nlp_fir[] = { + -1.0818124e-03, + -1.1008344e-03, + -9.2768838e-04, + -4.2289438e-04, + 5.5034190e-04, + 2.0029849e-03, + 3.7058509e-03, + 5.1449415e-03, + 5.5924666e-03, + 4.3036754e-03, + 8.0284511e-04, + -4.8204610e-03, + -1.1705810e-02, + -1.8199275e-02, + -2.2065282e-02, + -2.0920610e-02, + -1.2808831e-02, + 3.2204775e-03, + 2.6683811e-02, + 5.5520624e-02, + 8.6305944e-02, + 1.1480192e-01, + 1.3674206e-01, + 1.4867556e-01, + 1.4867556e-01, + 1.3674206e-01, + 1.1480192e-01, + 8.6305944e-02, + 5.5520624e-02, + 2.6683811e-02, + 3.2204775e-03, + -1.2808831e-02, + -2.0920610e-02, + -2.2065282e-02, + -1.8199275e-02, + -1.1705810e-02, + -4.8204610e-03, + 8.0284511e-04, + 4.3036754e-03, + 5.5924666e-03, + 5.1449415e-03, + 3.7058509e-03, + 2.0029849e-03, + 5.5034190e-04, + -4.2289438e-04, + -9.2768838e-04, + -1.1008344e-03, + -1.0818124e-03 +}; + +typedef struct { + float sq[PMAX_M]; /* squared speech samples */ + float mem_x,mem_y; /* memory for notch filter */ + float mem_fir[NLP_NTAP]; /* decimation FIR filter memory */ +} NLP; + +float post_process_mbe(COMP Fw[], int pmin, int pmax, float gmax); +float post_process_sub_multiples(COMP Fw[], + int pmin, int pmax, float gmax, int gmax_bin, + float *prev_Wo); + +/*---------------------------------------------------------------------------*\ + + nlp_create() + + Initialisation function for NLP pitch estimator. + +\*---------------------------------------------------------------------------*/ + +void *nlp_create() +{ + NLP *nlp; + int i; + + nlp = (NLP*)malloc(sizeof(NLP)); + if (nlp == NULL) + return NULL; + + for(i=0; i<PMAX_M; i++) + nlp->sq[i] = 0.0; + nlp->mem_x = 0.0; + nlp->mem_y = 0.0; + for(i=0; i<NLP_NTAP; i++) + nlp->mem_fir[i] = 0.0; + + return (void*)nlp; +} + +/*---------------------------------------------------------------------------*\ + + nlp_destory() + + Initialisation function for NLP pitch estimator. + +\*---------------------------------------------------------------------------*/ + +void nlp_destroy(void *nlp_state) +{ + assert(nlp_state != NULL); + free(nlp_state); +} + +/*---------------------------------------------------------------------------*\ + + nlp() + + Determines the pitch in samples using the Non Linear Pitch (NLP) + algorithm [1]. Returns the fundamental in Hz. Note that the actual + pitch estimate is for the centre of the M sample Sn[] vector, not + the current N sample input vector. This is (I think) a delay of 2.5 + frames with N=80 samples. You should align further analysis using + this pitch estimate to be centred on the middle of Sn[]. + + Two post processors have been tried, the MBE version (as discussed + in [1]), and a post processor that checks sub-multiples. Both + suffer occasional gross pitch errors (i.e. neither are perfect). In + the presence of background noise the sub-multiple algorithm tends + towards low F0 which leads to better sounding background noise than + the MBE post processor. + + A good way to test and develop the NLP pitch estimator is using the + tnlp (codec2/unittest) and the codec2/octave/plnlp.m Octave script. + + A pitch tracker searching a few frames forward and backward in time + would be a useful addition. + + References: + + [1] http://www.itr.unisa.edu.au/~steven/thesis/dgr.pdf Chapter 4 + +\*---------------------------------------------------------------------------*/ + +float nlp( + void *nlp_state, + float Sn[], /* input speech vector */ + int n, /* frames shift (no. new samples in Sn[]) */ + int m, /* analysis window size */ + int pmin, /* minimum pitch value */ + int pmax, /* maximum pitch value */ + float *pitch, /* estimated pitch period in samples */ + COMP Sw[], /* Freq domain version of Sn[] */ + float *prev_Wo +) +{ + NLP *nlp; + float notch; /* current notch filter output */ + COMP Fw[PE_FFT_SIZE]; /* DFT of squared signal */ + float gmax; + int gmax_bin; + int i,j; + float best_f0; + + assert(nlp_state != NULL); + nlp = (NLP*)nlp_state; + + /* Square, notch filter at DC, and LP filter vector */ + + for(i=m-n; i<M; i++) /* square latest speech samples */ + nlp->sq[i] = Sn[i]*Sn[i]; + + for(i=m-n; i<m; i++) { /* notch filter at DC */ + notch = nlp->sq[i] - nlp->mem_x; + notch += COEFF*nlp->mem_y; + nlp->mem_x = nlp->sq[i]; + nlp->mem_y = notch; + nlp->sq[i] = notch; + } + + for(i=m-n; i<m; i++) { /* FIR filter vector */ + + for(j=0; j<NLP_NTAP-1; j++) + nlp->mem_fir[j] = nlp->mem_fir[j+1]; + nlp->mem_fir[NLP_NTAP-1] = nlp->sq[i]; + + nlp->sq[i] = 0.0; + for(j=0; j<NLP_NTAP; j++) + nlp->sq[i] += nlp->mem_fir[j]*nlp_fir[j]; + } + + /* Decimate and DFT */ + + for(i=0; i<PE_FFT_SIZE; i++) { + Fw[i].real = 0.0; + Fw[i].imag = 0.0; + } + for(i=0; i<m/DEC; i++) { + Fw[i].real = nlp->sq[i*DEC]*(0.5 - 0.5*cos(2*PI*i/(m/DEC-1))); + } +#ifdef DUMP + dump_dec(Fw); +#endif + fft(&Fw[0].real,PE_FFT_SIZE,1); + for(i=0; i<PE_FFT_SIZE; i++) + Fw[i].real = Fw[i].real*Fw[i].real + Fw[i].imag*Fw[i].imag; + +#ifdef DUMP + dump_sq(nlp->sq); + dump_Fw(Fw); +#endif + + /* find global peak */ + + gmax = 0.0; + gmax_bin = PE_FFT_SIZE*DEC/pmax; + for(i=PE_FFT_SIZE*DEC/pmax; i<=PE_FFT_SIZE*DEC/pmin; i++) { + if (Fw[i].real > gmax) { + gmax = Fw[i].real; + gmax_bin = i; + } + } + + best_f0 = post_process_sub_multiples(Fw, pmin, pmax, gmax, gmax_bin, + prev_Wo); + + /* Shift samples in buffer to make room for new samples */ + + for(i=0; i<m-n; i++) + nlp->sq[i] = nlp->sq[i+n]; + + /* return pitch and F0 estimate */ + + *pitch = (float)SAMPLE_RATE/best_f0; + return(best_f0); +} + +/*---------------------------------------------------------------------------*\ + + post_process_sub_multiples() + + Given the global maximma of Fw[] we search interger submultiples for + local maxima. If local maxima exist and they are above an + experimentally derived threshold (OK a magic number I pulled out of + the air) we choose the submultiple as the F0 estimate. + + The rational for this is that the lowest frequency peak of Fw[] + should be F0, as Fw[] can be considered the autocorrelation function + of Sw[] (the speech spectrum). However sometimes due to phase + effects the lowest frequency maxima may not be the global maxima. + + This works OK in practice and favours low F0 values in the presence + of background noise which means the sinusoidal codec does an OK job + of synthesising the background noise. High F0 in background noise + tends to sound more periodic introducing annoying artifacts. + +\*---------------------------------------------------------------------------*/ + +float post_process_sub_multiples(COMP Fw[], + int pmin, int pmax, float gmax, int gmax_bin, + float *prev_Wo) +{ + int min_bin, cmax_bin; + int mult; + float thresh, best_f0; + int b, bmin, bmax, lmax_bin; + float lmax, cmax; + int prev_f0_bin; + + /* post process estimate by searching submultiples */ + + mult = 2; + min_bin = PE_FFT_SIZE*DEC/pmax; + cmax_bin = gmax_bin; + prev_f0_bin = *prev_Wo*(4000.0/PI)*(PE_FFT_SIZE*DEC)/SAMPLE_RATE; + + while(gmax_bin/mult >= min_bin) { + + b = gmax_bin/mult; /* determine search interval */ + bmin = 0.8*b; + bmax = 1.2*b; + if (bmin < min_bin) + bmin = min_bin; + + /* lower threshold to favour previous frames pitch estimate, + this is a form of pitch tracking */ + + if ((prev_f0_bin > bmin) && (prev_f0_bin < bmax)) + thresh = CNLP*0.5*gmax; + else + thresh = CNLP*gmax; + + lmax = 0; + lmax_bin = bmin; + for (b=bmin; b<=bmax; b++) /* look for maximum in interval */ + if (Fw[b].real > lmax) { + lmax = Fw[b].real; + lmax_bin = b; + } + + if (lmax > thresh) + if ((lmax > Fw[lmax_bin-1].real) && (lmax > Fw[lmax_bin+1].real)) { + cmax = lmax; + cmax_bin = lmax_bin; + } + + mult++; + } + + best_f0 = (float)cmax_bin*SAMPLE_RATE/(PE_FFT_SIZE*DEC); + + return best_f0; +} + diff --git a/gr-vocoder/lib/codec2/nlp.h b/gr-vocoder/lib/codec2/nlp.h new file mode 100644 index 000000000..88a3733dc --- /dev/null +++ b/gr-vocoder/lib/codec2/nlp.h @@ -0,0 +1,39 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: nlp.c + AUTHOR......: David Rowe + DATE CREATED: 23/3/93 + + Non Linear Pitch (NLP) estimation functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __NLP__ +#define __NLP__ + +#include "comp.h" + +void *nlp_create(); +void nlp_destroy(void *nlp_state); +float nlp(void *nlp_state, float Sn[], int n, int m, int pmin, int pmax, + float *pitch, COMP Sw[], float *prev_Wo); +float test_candidate_mbe(COMP Sw[], float f0, COMP Sw_[]); + +#endif diff --git a/gr-vocoder/lib/codec2/pack.c b/gr-vocoder/lib/codec2/pack.c new file mode 100644 index 000000000..31551dfc4 --- /dev/null +++ b/gr-vocoder/lib/codec2/pack.c @@ -0,0 +1,105 @@ +/* + Copyright (C) 2010 Perens LLC <bruce@perens.com> + + 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 3 of the License, 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 program. If not, see <http://www.gnu.org/licenses/>. + + */ +#include "defines.h" +#include "quantise.h" +#include <stdio.h> + +/* Compile-time constants */ +/* Size of unsigned char in bits. Assumes 8 bits-per-char. */ +static const unsigned int WordSize = 8; + +/* Mask to pick the bit component out of bitIndex. */ +static const unsigned int IndexMask = 0x7; + +/* Used to pick the word component out of bitIndex. */ +static const unsigned int ShiftRight = 3; + +/** Pack a bit field into a bit string, encoding the field in Gray code. + * + * The output is an array of unsigned char data. The fields are efficiently + * packed into the bit string. The Gray coding is a naive attempt to reduce + * the effect of single-bit errors, we expect to do a better job as the + * codec develops. + * + * This code would be simpler if it just set one bit at a time in the string, + * but would hit the same cache line more often. I'm not sure the complexity + * gains us anything here. + * + * Although field is currently of int type rather than unsigned for + * compatibility with the rest of the code, indices are always expected to + * be >= 0. + */ +void +pack( + unsigned char * bitArray, /* The output bit string. */ + unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ + int field, /* The bit field to be packed. */ + unsigned int fieldWidth/* Width of the field in BITS, not bytes. */ + ) +{ + /* Convert the field to Gray code */ + field = (field >> 1) ^ field; + + do { + unsigned int bI = *bitIndex; + unsigned int bitsLeft = WordSize - (bI & IndexMask); + unsigned int sliceWidth = + bitsLeft < fieldWidth ? bitsLeft : fieldWidth; + unsigned int wordIndex = bI >> ShiftRight; + + bitArray[wordIndex] |= + ((unsigned char)((field >> (fieldWidth - sliceWidth)) + << (bitsLeft - sliceWidth))); + + *bitIndex = bI + sliceWidth; + fieldWidth -= sliceWidth; + } while ( fieldWidth != 0 ); +} + +/** Unpack a field from a bit string, converting from Gray code to binary. + * + */ +int +unpack( + const unsigned char * bitArray, /* The input bit string. */ + unsigned int * bitIndex, /* Index into the string in BITS, not bytes.*/ + unsigned int fieldWidth/* Width of the field in BITS, not bytes. */ + ) +{ + unsigned int field = 0; + unsigned int t; + + do { + unsigned int bI = *bitIndex; + unsigned int bitsLeft = WordSize - (bI & IndexMask); + unsigned int sliceWidth = + bitsLeft < fieldWidth ? bitsLeft : fieldWidth; + + field |= (((bitArray[bI >> ShiftRight] >> (bitsLeft - sliceWidth)) & ((1 << sliceWidth) - 1)) << (fieldWidth - sliceWidth)); + + *bitIndex = bI + sliceWidth; + fieldWidth -= sliceWidth; + } while ( fieldWidth != 0 ); + + /* Convert from Gray code to binary. Works for maximum 8-bit fields. */ + t = field ^ (field >> 8); + t ^= (t >> 4); + t ^= (t >> 2); + t ^= (t >> 1); + return t; +} diff --git a/gr-vocoder/lib/codec2/phase.c b/gr-vocoder/lib/codec2/phase.c new file mode 100644 index 000000000..0e1a14a60 --- /dev/null +++ b/gr-vocoder/lib/codec2/phase.c @@ -0,0 +1,262 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: phase.c + AUTHOR......: David Rowe + DATE CREATED: 1/2/09 + + Functions for modelling and synthesising phase. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not,see <http://www.gnu.org/licenses/>. +*/ + +#include "defines.h" +#include "phase.h" +#include "fft.h" +#include "comp.h" +#include "glottal.c" + +#include <assert.h> +#include <math.h> +#include <string.h> +#include <stdlib.h> + +#define GLOTTAL_FFT_SIZE 512 + +/*---------------------------------------------------------------------------*\ + + aks_to_H() + + Samples the complex LPC synthesis filter spectrum at the harmonic + frequencies. + +\*---------------------------------------------------------------------------*/ + +void aks_to_H( + MODEL *model, /* model parameters */ + float aks[], /* LPC's */ + float G, /* energy term */ + COMP H[], /* complex LPC spectral samples */ + int order +) +{ + COMP Pw[FFT_DEC]; /* power spectrum */ + int i,m; /* loop variables */ + int am,bm; /* limits of current band */ + float r; /* no. rads/bin */ + float Em; /* energy in band */ + float Am; /* spectral amplitude sample */ + int b; /* centre bin of harmonic */ + float phi_; /* phase of LPC spectra */ + + r = TWO_PI/(FFT_DEC); + + /* Determine DFT of A(exp(jw)) ------------------------------------------*/ + + for(i=0; i<FFT_DEC; i++) { + Pw[i].real = 0.0; + Pw[i].imag = 0.0; + } + + for(i=0; i<=order; i++) + Pw[i].real = aks[i]; + + fft(&Pw[0].real,FFT_DEC,-1); + + /* Sample magnitude and phase at harmonics */ + + for(m=1; m<=model->L; m++) { + am = floor((m - 0.5)*model->Wo/r + 0.5); + bm = floor((m + 0.5)*model->Wo/r + 0.5); + b = floor(m*model->Wo/r + 0.5); + + Em = 0.0; + for(i=am; i<bm; i++) + Em += G/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag); + Am = sqrt(fabs(Em/(bm-am))); + + phi_ = -atan2(Pw[b].imag,Pw[b].real); + H[m].real = Am*cos(phi_); + H[m].imag = Am*sin(phi_); + } +} + + +/*---------------------------------------------------------------------------*\ + + phase_synth_zero_order() + + Synthesises phases based on SNR and a rule based approach. No phase + parameters are required apart from the SNR (which can be reduced to a + 1 bit V/UV decision per frame). + + The phase of each harmonic is modelled as the phase of a LPC + synthesis filter excited by an impulse. Unlike the first order + model the position of the impulse is not transmitted, so we create + an excitation pulse train using a rule based approach. + + Consider a pulse train with a pulse starting time n=0, with pulses + repeated at a rate of Wo, the fundamental frequency. A pulse train + in the time domain is equivalent to harmonics in the frequency + domain. We can make an excitation pulse train using a sum of + sinsusoids: + + for(m=1; m<=L; m++) + ex[n] = cos(m*Wo*n) + + Note: the Octave script ../octave/phase.m is an example of this if + you would like to try making a pulse train. + + The phase of each excitation harmonic is: + + arg(E[m]) = mWo + + where E[m] are the complex excitation (freq domain) samples, + arg(x), just returns the phase of a complex sample x. + + As we don't transmit the pulse position for this model, we need to + synthesise it. Now the excitation pulses occur at a rate of Wo. + This means the phase of the first harmonic advances by N samples + over a synthesis frame of N samples. For example if Wo is pi/20 + (200 Hz), then over a 10ms frame (N=80 samples), the phase of the + first harmonic would advance (pi/20)*80 = 4*pi or two complete + cycles. + + We generate the excitation phase of the fundamental (first + harmonic): + + arg[E[1]] = Wo*N; + + We then relate the phase of the m-th excitation harmonic to the + phase of the fundamental as: + + arg(E[m]) = m*arg(E[1]) + + This E[m] then gets passed through the LPC synthesis filter to + determine the final harmonic phase. + + Comparing to speech synthesised using original phases: + + - Through headphones speech synthesised with this model is not as + good. Through a loudspeaker it is very close to original phases. + + - If there are voicing errors, the speech can sound clicky or + staticy. If V speech is mistakenly declared UV, this model tends to + synthesise impulses or clicks, as there is usually very little shift or + dispersion through the LPC filter. + + - When combined with LPC amplitude modelling there is an additional + drop in quality. I am not sure why, theory is interformant energy + is raised making any phase errors more obvious. + + NOTES: + + 1/ This synthesis model is effectively the same as a simple LPC-10 + vocoders, and yet sounds much better. Why? Conventional wisdom + (AMBE, MELP) says mixed voicing is required for high quality + speech. + + 2/ I am pretty sure the Lincoln Lab sinusoidal coding guys (like xMBE + also from MIT) first described this zero phase model, I need to look + up the paper. + + 3/ Note that this approach could cause some discontinuities in + the phase at the edge of synthesis frames, as no attempt is made + to make sure that the phase tracks are continuous (the excitation + phases are continuous, but not the final phases after filtering + by the LPC spectra). Technically this is a bad thing. However + this may actually be a good thing, disturbing the phase tracks a + bit. More research needed, e.g. test a synthesis model that adds + a small delta-W to make phase tracks line up for voiced + harmonics. + +\*---------------------------------------------------------------------------*/ + +void phase_synth_zero_order( + MODEL *model, + float aks[], + float *ex_phase, /* excitation phase of fundamental */ + int order +) +{ + int m; + float new_phi; + COMP Ex[MAX_AMP]; /* excitation samples */ + COMP A_[MAX_AMP]; /* synthesised harmonic samples */ + COMP H[MAX_AMP]; /* LPC freq domain samples */ + float G; + float jitter = 0.0; + float r; + int b; + + G = 1.0; + aks_to_H(model, aks, G, H, order); + + /* + Update excitation fundamental phase track, this sets the position + of each pitch pulse during voiced speech. After much experiment + I found that using just this frame's Wo improved quality for UV + sounds compared to interpolating two frames Wo like this: + + ex_phase[0] += (*prev_Wo+mode->Wo)*N/2; + */ + + ex_phase[0] += (model->Wo)*N; + ex_phase[0] -= TWO_PI*floor(ex_phase[0]/TWO_PI + 0.5); + r = TWO_PI/GLOTTAL_FFT_SIZE; + + for(m=1; m<=model->L; m++) { + + /* generate excitation */ + + if (model->voiced) { + /* I think adding a little jitter helps improve low pitch + males like hts1a. This moves the onset of each harmonic + over at +/- 0.25 of a sample. + */ + jitter = 0.25*(1.0 - 2.0*rand()/RAND_MAX); + b = floor(m*model->Wo/r + 0.5); + if (b > ((GLOTTAL_FFT_SIZE/2)-1)) { + b = (GLOTTAL_FFT_SIZE/2)-1; + } + Ex[m].real = cos(ex_phase[0]*m - jitter*model->Wo*m + glottal[b]); + Ex[m].imag = sin(ex_phase[0]*m - jitter*model->Wo*m + glottal[b]); + } + else { + + /* When a few samples were tested I found that LPC filter + phase is not needed in the unvoiced case, but no harm in + keeping it. + */ + float phi = TWO_PI*(float)rand()/RAND_MAX; + Ex[m].real = cos(phi); + Ex[m].imag = sin(phi); + } + + /* filter using LPC filter */ + + A_[m].real = H[m].real*Ex[m].real - H[m].imag*Ex[m].imag; + A_[m].imag = H[m].imag*Ex[m].real + H[m].real*Ex[m].imag; + + /* modify sinusoidal phase */ + + new_phi = atan2(A_[m].imag, A_[m].real+1E-12); + model->phi[m] = new_phi; + } + +} diff --git a/gr-vocoder/lib/codec2/phase.h b/gr-vocoder/lib/codec2/phase.h new file mode 100644 index 000000000..833bc7cdc --- /dev/null +++ b/gr-vocoder/lib/codec2/phase.h @@ -0,0 +1,34 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: phase.h + AUTHOR......: David Rowe + DATE CREATED: 1/2/09 + + Functions for modelling phase. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __PHASE__ +#define __PHASE__ + +void phase_synth_zero_order(MODEL *model, float aks[], float *ex_phase, + int order); + +#endif diff --git a/gr-vocoder/lib/codec2/postfilter.c b/gr-vocoder/lib/codec2/postfilter.c new file mode 100644 index 000000000..6e17eeb87 --- /dev/null +++ b/gr-vocoder/lib/codec2/postfilter.c @@ -0,0 +1,133 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: postfilter.c + AUTHOR......: David Rowe + DATE CREATED: 13/09/09 + + Postfilter to improve sound quality for speech with high levels of + background noise. Unlike mixed-excitation models requires no bits + to be transmitted to handle background noise. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> + +#include "defines.h" +#include "comp.h" +#include "dump.h" +#include "postfilter.h" + +/*---------------------------------------------------------------------------*\ + + DEFINES + +\*---------------------------------------------------------------------------*/ + +#define BG_THRESH 40.0 /* only consider low levels signals for bg_est */ +#define BG_BETA 0.1 /* averaging filter constant */ + +/*---------------------------------------------------------------------------*\ + + postfilter() + + The post filter is designed to help with speech corrupted by + background noise. The zero phase model tends to make speech with + background noise sound "clicky". With high levels of background + noise the low level inter-formant parts of the spectrum will contain + noise rather than speech harmonics, so modelling them as voiced + (i.e. a continuous, non-random phase track) is inaccurate. + + Some codecs (like MBE) have a mixed voicing model that breaks the + spectrum into voiced and unvoiced regions. Several bits/frame + (5-12) are required to transmit the frequency selective voicing + information. Mixed excitation also requires accurate voicing + estimation (parameter estimators always break occasionally under + exceptional condition). + + In our case we use a post filter approach which requires no + additional bits to be transmitted. The decoder measures the average + level of the background noise during unvoiced frames. If a harmonic + is less than this level it is made unvoiced by randomising it's + phases. + + This idea is rather experimental. Some potential problems that may + happen: + + 1/ If someone says "aaaaaaaahhhhhhhhh" will background estimator track + up to speech level? This would be a bad thing. + + 2/ If background noise suddenly dissapears from the source speech does + estimate drop quickly? What is noise suddenly re-appears? + + 3/ Background noise with a non-flat sepctrum. Current algorithm just + comsiders scpetrum as a whole, but this could be broken up into + bands, each with their own estimator. + + 4/ Males and females with the same level of background noise. Check + performance the same. Changing Wo affects width of each band, may + affect bg energy estimates. + + 5/ Not sure what happens during long periods of voiced speech + e.g. "sshhhhhhh" + +\*---------------------------------------------------------------------------*/ + +void postfilter( + MODEL *model, + float *bg_est +) +{ + int m, uv; + float e; + + /* determine average energy across spectrum */ + + e = 0.0; + for(m=1; m<=model->L; m++) + e += model->A[m]*model->A[m]; + + e = 10.0*log10(e/model->L); + + /* If beneath threhold, update bg estimate. The idea + of the threshold is to prevent updating during high level + speech. */ + + if ((e < BG_THRESH) && !model->voiced) + *bg_est = *bg_est*(1.0 - BG_BETA) + e*BG_BETA; + + /* now mess with phases during voiced frames to make any harmonics + less then our background estimate unvoiced. + */ + + uv = 0; + if (model->voiced) + for(m=1; m<=model->L; m++) + if (20.0*log10(model->A[m]) < *bg_est) { + model->phi[m] = TWO_PI*(float)rand()/RAND_MAX; + uv++; + } + +#ifdef DUMP + dump_bg(e, *bg_est, 100.0*uv/model->L); +#endif + +} diff --git a/gr-vocoder/lib/codec2/postfilter.h b/gr-vocoder/lib/codec2/postfilter.h new file mode 100644 index 000000000..bf080b1b6 --- /dev/null +++ b/gr-vocoder/lib/codec2/postfilter.h @@ -0,0 +1,33 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: postfilter.h + AUTHOR......: David Rowe + DATE CREATED: 13/09/09 + + Postfilter header file. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __POSTFILTER__ +#define __POSTFILTER__ + +void postfilter(MODEL *model, float *bg_est); + +#endif diff --git a/gr-vocoder/lib/codec2/quantise.c b/gr-vocoder/lib/codec2/quantise.c new file mode 100644 index 000000000..ff8d156b5 --- /dev/null +++ b/gr-vocoder/lib/codec2/quantise.c @@ -0,0 +1,851 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: quantise.c + AUTHOR......: David Rowe + DATE CREATED: 31/5/92 + + Quantisation functions for the sinusoidal coder. + +\*---------------------------------------------------------------------------*/ + +/* + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. + +*/ + +#include <assert.h> +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include "defines.h" +#include "dump.h" +#include "quantise.h" +#include "lpc.h" +#include "lsp.h" +#include "fft.h" + +#define LSP_DELTA1 0.01 /* grid spacing for LSP root searches */ + +/*---------------------------------------------------------------------------*\ + + FUNCTION HEADERS + +\*---------------------------------------------------------------------------*/ + +float speech_to_uq_lsps(float lsp[], float ak[], float Sn[], float w[], + int order); + +/*---------------------------------------------------------------------------*\ + + FUNCTIONS + +\*---------------------------------------------------------------------------*/ + +int lsp_bits(int i) { + return lsp_cb[i].log2m; +} + +#if VECTOR_QUANTISATION +/*---------------------------------------------------------------------------*\ + + quantise_uniform + + Simulates uniform quantising of a float. + +\*---------------------------------------------------------------------------*/ + +void quantise_uniform(float *val, float min, float max, int bits) +{ + int levels = 1 << (bits-1); + float norm; + int index; + + /* hard limit to quantiser range */ + + printf("min: %f max: %f val: %f ", min, max, val[0]); + if (val[0] < min) val[0] = min; + if (val[0] > max) val[0] = max; + + norm = (*val - min)/(max-min); + printf("%f norm: %f ", val[0], norm); + index = fabs(levels*norm + 0.5); + + *val = min + index*(max-min)/levels; + + printf("index %d val_: %f\n", index, val[0]); +} + +#endif + +/*---------------------------------------------------------------------------*\ + + quantise_init + + Loads the entire LSP quantiser comprised of several vector quantisers + (codebooks). + +\*---------------------------------------------------------------------------*/ + +void quantise_init() +{ +} + +/*---------------------------------------------------------------------------*\ + + quantise + + Quantises vec by choosing the nearest vector in codebook cb, and + returns the vector index. The squared error of the quantised vector + is added to se. + +\*---------------------------------------------------------------------------*/ + +long quantise(const float * cb, float vec[], float w[], int k, int m, float *se) +/* float cb[][K]; current VQ codebook */ +/* float vec[]; vector to quantise */ +/* float w[]; weighting vector */ +/* int k; dimension of vectors */ +/* int m; size of codebook */ +/* float *se; accumulated squared error */ +{ + float e; /* current error */ + long besti; /* best index so far */ + float beste; /* best error so far */ + long j; + int i; + + besti = 0; + beste = 1E32; + for(j=0; j<m; j++) { + e = 0.0; + for(i=0; i<k; i++) + e += pow((cb[j*k+i]-vec[i])*w[i],2.0); + if (e < beste) { + beste = e; + besti = j; + } + } + + *se += beste; + + return(besti); +} + +/*---------------------------------------------------------------------------*\ + + lspd_quantise + + Scalar lsp difference quantiser. + +\*---------------------------------------------------------------------------*/ + +void lspd_quantise( + float lsp[], + float lsp_[], + int order +) +{ + int i,k,m; + float lsp_hz[LPC_MAX]; + float lsp__hz[LPC_MAX]; + float dlsp[LPC_MAX]; + float dlsp_[LPC_MAX]; + float wt[1]; + const float *cb; + float se; + int indexes[LPC_MAX]; + + /* convert from radians to Hz so we can use human readable + frequencies */ + + for(i=0; i<order; i++) + lsp_hz[i] = (4000.0/PI)*lsp[i]; + + dlsp[0] = lsp_hz[0]; + for(i=1; i<order; i++) + dlsp[i] = lsp_hz[i] - lsp_hz[i-1]; + + /* simple uniform scalar quantisers */ + + wt[0] = 1.0; + for(i=0; i<order; i++) { + if (i) + dlsp[i] = lsp_hz[i] - lsp__hz[i-1]; + else + dlsp[0] = lsp_hz[0]; + + k = lsp_cbd[i].k; + m = lsp_cbd[i].m; + cb = lsp_cbd[i].cb; + indexes[i] = quantise(cb, &dlsp[i], wt, k, m, &se); + dlsp_[i] = cb[indexes[i]*k]; + + if (i) + lsp__hz[i] = lsp__hz[i-1] + dlsp_[i]; + else + lsp__hz[0] = dlsp_[0]; + } + for(; i<order; i++) + lsp__hz[i] = lsp__hz[i-1] + dlsp[i]; + + /* convert back to radians */ + + for(i=0; i<order; i++) + lsp_[i] = (PI/4000.0)*lsp__hz[i]; +} + +/*---------------------------------------------------------------------------*\ + + lspd_vq_quantise + + Vector lsp difference quantiser. + +\*---------------------------------------------------------------------------*/ + +void lspdvq_quantise( + float lsp[], + float lsp_[], + int order +) +{ + int i,k,m,ncb, nlsp; + float dlsp[LPC_MAX]; + float dlsp_[LPC_MAX]; + float wt[LPC_ORD]; + const float *cb; + float se; + int index; + + dlsp[0] = lsp[0]; + for(i=1; i<order; i++) + dlsp[i] = lsp[i] - lsp[i-1]; + + for(i=0; i<order; i++) + dlsp_[i] = dlsp[i]; + + for(i=0; i<order; i++) + wt[i] = 1.0; + + /* scalar quantise dLSPs 1,2,3,4,5 */ + + for(i=0; i<5; i++) { + if (i) + dlsp[i] = (lsp[i] - lsp_[i-1])*4000.0/PI; + else + dlsp[0] = lsp[0]*4000.0/PI; + + k = lsp_cbdvq[i].k; + m = lsp_cbdvq[i].m; + cb = lsp_cbdvq[i].cb; + index = quantise(cb, &dlsp[i], wt, k, m, &se); + dlsp_[i] = cb[index*k]*PI/4000.0; + + if (i) + lsp_[i] = lsp_[i-1] + dlsp_[i]; + else + lsp_[0] = dlsp_[0]; + } + dlsp[i] = lsp[i] - lsp_[i-1]; + dlsp_[i] = dlsp[i]; + + //printf("lsp[0] %f lsp_[0] %f\n", lsp[0], lsp_[0]); + //printf("lsp[1] %f lsp_[1] %f\n", lsp[1], lsp_[1]); + +#ifdef TT + /* VQ dLSPs 3,4,5 */ + + ncb = 2; + nlsp = 2; + k = lsp_cbdvq[ncb].k; + m = lsp_cbdvq[ncb].m; + cb = lsp_cbdvq[ncb].cb; + index = quantise(cb, &dlsp[nlsp], wt, k, m, &se); + dlsp_[nlsp] = cb[index*k]; + dlsp_[nlsp+1] = cb[index*k+1]; + dlsp_[nlsp+2] = cb[index*k+2]; + + lsp_[0] = dlsp_[0]; + for(i=1; i<5; i++) + lsp_[i] = lsp_[i-1] + dlsp_[i]; + dlsp[i] = lsp[i] - lsp_[i-1]; + dlsp_[i] = dlsp[i]; +#endif + /* VQ dLSPs 6,7,8,9,10 */ + + ncb = 5; + nlsp = 5; + k = lsp_cbdvq[ncb].k; + m = lsp_cbdvq[ncb].m; + cb = lsp_cbdvq[ncb].cb; + index = quantise(cb, &dlsp[nlsp], wt, k, m, &se); + dlsp_[nlsp] = cb[index*k]; + dlsp_[nlsp+1] = cb[index*k+1]; + dlsp_[nlsp+2] = cb[index*k+2]; + dlsp_[nlsp+3] = cb[index*k+3]; + dlsp_[nlsp+4] = cb[index*k+4]; + + /* rebuild LSPs for dLSPs */ + + lsp_[0] = dlsp_[0]; + for(i=1; i<order; i++) + lsp_[i] = lsp_[i-1] + dlsp_[i]; +} + +void check_lsp_order(float lsp[], int lpc_order) +{ + int i; + float tmp; + + for(i=1; i<lpc_order; i++) + if (lsp[i] < lsp[i-1]) { + printf("swap %d\n",i); + tmp = lsp[i-1]; + lsp[i-1] = lsp[i]-0.05; + lsp[i] = tmp+0.05; + } +} + +void force_min_lsp_dist(float lsp[], int lpc_order) +{ + int i; + + for(i=1; i<lpc_order; i++) + if ((lsp[i]-lsp[i-1]) < 0.01) { + lsp[i] += 0.01; + } +} + +/*---------------------------------------------------------------------------*\ + + lpc_model_amplitudes + + Derive a LPC model for amplitude samples then estimate amplitude samples + from this model with optional LSP quantisation. + + Returns the spectral distortion for this frame. + +\*---------------------------------------------------------------------------*/ + +float lpc_model_amplitudes( + float Sn[], /* Input frame of speech samples */ + float w[], + MODEL *model, /* sinusoidal model parameters */ + int order, /* LPC model order */ + int lsp_quant, /* optional LSP quantisation if non-zero */ + float ak[] /* output aks */ +) +{ + float Wn[M]; + float R[LPC_MAX+1]; + float E; + int i,j; + float snr; + float lsp[LPC_MAX]; + float lsp_hz[LPC_MAX]; + float lsp_[LPC_MAX]; + int roots; /* number of LSP roots found */ + int index; + float se; + int k,m; + const float * cb; + float wt[LPC_MAX]; + + for(i=0; i<M; i++) + Wn[i] = Sn[i]*w[i]; + autocorrelate(Wn,R,M,order); + levinson_durbin(R,ak,order); + + E = 0.0; + for(i=0; i<=order; i++) + E += ak[i]*R[i]; + + for(i=0; i<order; i++) + wt[i] = 1.0; + + if (lsp_quant) { + roots = lpc_to_lsp(ak, order, lsp, 5, LSP_DELTA1); + if (roots != order) + printf("LSP roots not found\n"); + + /* convert from radians to Hz to make quantisers more + human readable */ + + for(i=0; i<order; i++) + lsp_hz[i] = (4000.0/PI)*lsp[i]; + + /* simple uniform scalar quantisers */ + + for(i=0; i<10; i++) { + k = lsp_cb[i].k; + m = lsp_cb[i].m; + cb = lsp_cb[i].cb; + index = quantise(cb, &lsp_hz[i], wt, k, m, &se); + lsp_hz[i] = cb[index*k]; + } + + /* experiment: simulating uniform quantisation error + for(i=0; i<order; i++) + lsp[i] += PI*(12.5/4000.0)*(1.0 - 2.0*(float)rand()/RAND_MAX); + */ + + for(i=0; i<order; i++) + lsp[i] = (PI/4000.0)*lsp_hz[i]; + + /* Bandwidth Expansion (BW). Prevents any two LSPs getting too + close together after quantisation. We know from experiment + that LSP quantisation errors < 12.5Hz (25Hz setp size) are + inaudible so we use that as the minimum LSP separation. + */ + + for(i=1; i<5; i++) { + if (lsp[i] - lsp[i-1] < PI*(12.5/4000.0)) + lsp[i] = lsp[i-1] + PI*(12.5/4000.0); + } + + /* as quantiser gaps increased, larger BW expansion was required + to prevent twinkly noises */ + + for(i=5; i<8; i++) { + if (lsp[i] - lsp[i-1] < PI*(25.0/4000.0)) + lsp[i] = lsp[i-1] + PI*(25.0/4000.0); + } + for(i=8; i<order; i++) { + if (lsp[i] - lsp[i-1] < PI*(75.0/4000.0)) + lsp[i] = lsp[i-1] + PI*(75.0/4000.0); + } + + for(j=0; j<order; j++) + lsp_[j] = lsp[j]; + + lsp_to_lpc(lsp_, ak, order); +#ifdef DUMP + dump_lsp(lsp); +#endif + } + +#ifdef DUMP + dump_E(E); +#endif + #ifdef SIM_QUANT + /* simulated LPC energy quantisation */ + { + float e = 10.0*log10(E); + e += 2.0*(1.0 - 2.0*(float)rand()/RAND_MAX); + E = pow(10.0,e/10.0); + } + #endif + + aks_to_M2(ak,order,model,E,&snr, 1); /* {ak} -> {Am} LPC decode */ + + return snr; +} + +/*---------------------------------------------------------------------------*\ + + aks_to_M2() + + Transforms the linear prediction coefficients to spectral amplitude + samples. This function determines A(m) from the average energy per + band using an FFT. + +\*---------------------------------------------------------------------------*/ + +void aks_to_M2( + float ak[], /* LPC's */ + int order, + MODEL *model, /* sinusoidal model parameters for this frame */ + float E, /* energy term */ + float *snr, /* signal to noise ratio for this frame in dB */ + int dump /* true to dump sample to dump file */ +) +{ + COMP Pw[FFT_DEC]; /* power spectrum */ + int i,m; /* loop variables */ + int am,bm; /* limits of current band */ + float r; /* no. rads/bin */ + float Em; /* energy in band */ + float Am; /* spectral amplitude sample */ + float signal, noise; + + r = TWO_PI/(FFT_DEC); + + /* Determine DFT of A(exp(jw)) --------------------------------------------*/ + + for(i=0; i<FFT_DEC; i++) { + Pw[i].real = 0.0; + Pw[i].imag = 0.0; + } + + for(i=0; i<=order; i++) + Pw[i].real = ak[i]; + fft(&Pw[0].real,FFT_DEC,1); + + /* Determine power spectrum P(w) = E/(A(exp(jw))^2 ------------------------*/ + + for(i=0; i<FFT_DEC/2; i++) + Pw[i].real = E/(Pw[i].real*Pw[i].real + Pw[i].imag*Pw[i].imag); +#ifdef DUMP + if (dump) + dump_Pw(Pw); +#endif + + /* Determine magnitudes by linear interpolation of P(w) -------------------*/ + + signal = noise = 0.0; + for(m=1; m<=model->L; m++) { + am = floor((m - 0.5)*model->Wo/r + 0.5); + bm = floor((m + 0.5)*model->Wo/r + 0.5); + Em = 0.0; + + for(i=am; i<bm; i++) + Em += Pw[i].real; + Am = sqrt(Em); + + signal += pow(model->A[m],2.0); + noise += pow(model->A[m] - Am,2.0); + model->A[m] = Am; + } + *snr = 10.0*log10(signal/noise); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_Wo() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Encodes Wo using a WO_LEVELS quantiser. + +\*---------------------------------------------------------------------------*/ + +int encode_Wo(float Wo) +{ + int index; + float Wo_min = TWO_PI/P_MAX; + float Wo_max = TWO_PI/P_MIN; + float norm; + + norm = (Wo - Wo_min)/(Wo_max - Wo_min); + index = floor(WO_LEVELS * norm + 0.5); + if (index < 0 ) index = 0; + if (index > (WO_LEVELS-1)) index = WO_LEVELS-1; + + return index; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_Wo() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Decodes Wo using a WO_LEVELS quantiser. + +\*---------------------------------------------------------------------------*/ + +float decode_Wo(int index) +{ + float Wo_min = TWO_PI/P_MAX; + float Wo_max = TWO_PI/P_MIN; + float step; + float Wo; + + step = (Wo_max - Wo_min)/WO_LEVELS; + Wo = Wo_min + step*(index); + + return Wo; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: speech_to_uq_lsps() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Analyse a windowed frame of time domain speech to determine LPCs + which are the converted to LSPs for quantisation and transmission + over the channel. + +\*---------------------------------------------------------------------------*/ + +float speech_to_uq_lsps(float lsp[], + float ak[], + float Sn[], + float w[], + int order +) +{ + int i, roots; + float Wn[M]; + float R[LPC_MAX+1]; + float E; + + for(i=0; i<M; i++) + Wn[i] = Sn[i]*w[i]; + autocorrelate(Wn, R, M, order); + levinson_durbin(R, ak, order); + + E = 0.0; + for(i=0; i<=order; i++) + E += ak[i]*R[i]; + + roots = lpc_to_lsp(ak, order, lsp, 5, LSP_DELTA1); + if (roots != order) { + /* for some reason LSP roots could not be found */ + /* some alpha testers are reporting this condition */ + fprintf(stderr, "LSP roots not found!\nroots = %d\n", roots); + for(i=0; i<=order; i++) + fprintf(stderr, "a[%d] = %f\n", i, ak[i]); + + /* some benign LSP values we can use instead */ + for(i=0; i<order; i++) + lsp[i] = (PI/order)*(float)i; + } + + return E; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_lsps() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + From a vector of unquantised (floating point) LSPs finds the quantised + LSP indexes. + +\*---------------------------------------------------------------------------*/ + +void encode_lsps(int indexes[], float lsp[], int order) +{ + int i,k,m; + float wt[1]; + float lsp_hz[LPC_MAX]; + const float * cb; + float se; + + /* convert from radians to Hz so we can use human readable + frequencies */ + + for(i=0; i<order; i++) + lsp_hz[i] = (4000.0/PI)*lsp[i]; + + /* simple uniform scalar quantisers */ + + wt[0] = 1.0; + for(i=0; i<order; i++) { + k = lsp_cb[i].k; + m = lsp_cb[i].m; + cb = lsp_cb[i].cb; + indexes[i] = quantise(cb, &lsp_hz[i], wt, k, m, &se); + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_lsps() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + From a vector of quantised LSP indexes, returns the quantised + (floating point) LSPs. + +\*---------------------------------------------------------------------------*/ + +void decode_lsps(float lsp[], int indexes[], int order) +{ + int i,k; + float lsp_hz[LPC_MAX]; + const float * cb; + + for(i=0; i<order; i++) { + k = lsp_cb[i].k; + cb = lsp_cb[i].cb; + lsp_hz[i] = cb[indexes[i]*k]; + } + + /* convert back to radians */ + + for(i=0; i<order; i++) + lsp[i] = (PI/4000.0)*lsp_hz[i]; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: bw_expand_lsps() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Applies Bandwidth Expansion (BW) to a vector of LSPs. Prevents any + two LSPs getting too close together after quantisation. We know + from experiment that LSP quantisation errors < 12.5Hz (25Hz setp + size) are inaudible so we use that as the minimum LSP separation. + +\*---------------------------------------------------------------------------*/ + +void bw_expand_lsps(float lsp[], + int order +) +{ + int i; + + for(i=1; i<5; i++) { + if (lsp[i] - lsp[i-1] < PI*(12.5/4000.0)) + lsp[i] = lsp[i-1] + PI*(12.5/4000.0); + } + + /* As quantiser gaps increased, larger BW expansion was required + to prevent twinkly noises. This may need more experiment for + different quanstisers. + */ + + for(i=5; i<8; i++) { + if (lsp[i] - lsp[i-1] < PI*(25.0/4000.0)) + lsp[i] = lsp[i-1] + PI*(25.0/4000.0); + } + for(i=8; i<order; i++) { + if (lsp[i] - lsp[i-1] < PI*(75.0/4000.0)) + lsp[i] = lsp[i-1] + PI*(75.0/4000.0); + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: apply_lpc_correction() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Apply first harmonic LPC correction at decoder. This helps improve + low pitch males after LPC modelling, like hts1a and morig. + +\*---------------------------------------------------------------------------*/ + +void apply_lpc_correction(MODEL *model) +{ + if (model->Wo < (PI*150.0/4000)) { + model->A[1] *= 0.032; + } +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_energy() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Encodes LPC energy using an E_LEVELS quantiser. + +\*---------------------------------------------------------------------------*/ + +int encode_energy(float e) +{ + int index; + float e_min = E_MIN_DB; + float e_max = E_MAX_DB; + float norm; + + e = 10.0*log10(e); + norm = (e - e_min)/(e_max - e_min); + index = floor(E_LEVELS * norm + 0.5); + if (index < 0 ) index = 0; + if (index > (E_LEVELS-1)) index = E_LEVELS-1; + + return index; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_energy() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Decodes energy using a WO_BITS quantiser. + +\*---------------------------------------------------------------------------*/ + +float decode_energy(int index) +{ + float e_min = E_MIN_DB; + float e_max = E_MAX_DB; + float step; + float e; + + step = (e_max - e_min)/E_LEVELS; + e = e_min + step*(index); + e = pow(10.0,e/10.0); + + return e; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: encode_amplitudes() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Time domain LPC is used model the amplitudes which are then + converted to LSPs and quantised. So we don't actually encode the + amplitudes directly, rather we derive an equivalent representation + from the time domain speech. + +\*---------------------------------------------------------------------------*/ + +void encode_amplitudes(int lsp_indexes[], + int *energy_index, + MODEL *model, + float Sn[], + float w[]) +{ + float lsps[LPC_ORD]; + float ak[LPC_ORD+1]; + float e; + + e = speech_to_uq_lsps(lsps, ak, Sn, w, LPC_ORD); + encode_lsps(lsp_indexes, lsps, LPC_ORD); + *energy_index = encode_energy(e); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: decode_amplitudes() + AUTHOR......: David Rowe + DATE CREATED: 22/8/2010 + + Given the amplitude quantiser indexes recovers the harmonic + amplitudes. + +\*---------------------------------------------------------------------------*/ + +float decode_amplitudes(MODEL *model, + float ak[], + int lsp_indexes[], + int energy_index, + float lsps[], + float *e +) +{ + float snr; + + decode_lsps(lsps, lsp_indexes, LPC_ORD); + bw_expand_lsps(lsps, LPC_ORD); + lsp_to_lpc(lsps, ak, LPC_ORD); + *e = decode_energy(energy_index); + aks_to_M2(ak, LPC_ORD, model, *e, &snr, 1); + apply_lpc_correction(model); + + return snr; +} diff --git a/gr-vocoder/lib/codec2/quantise.h b/gr-vocoder/lib/codec2/quantise.h new file mode 100644 index 000000000..90a3661ff --- /dev/null +++ b/gr-vocoder/lib/codec2/quantise.h @@ -0,0 +1,83 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: quantise.h + AUTHOR......: David Rowe + DATE CREATED: 31/5/92 + + Quantisation functions for the sinusoidal coder. + +\*---------------------------------------------------------------------------*/ + +/* + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __QUANTISE__ +#define __QUANTISE__ + +#define WO_BITS 7 +#define WO_LEVELS (1<<WO_BITS) +#define E_BITS 5 +#define E_LEVELS (1<<E_BITS) +#define E_MIN_DB -10.0 +#define E_MAX_DB 40.0 + +void quantise_init(); +float lpc_model_amplitudes(float Sn[], float w[], MODEL *model, int order, + int lsp,float ak[]); +void aks_to_M2(float ak[], int order, MODEL *model, float E, float *snr, + int dump); + +int encode_Wo(float Wo); +float decode_Wo(int index); + +void encode_lsps(int indexes[], float lsp[], int order); +void decode_lsps(float lsp[], int indexes[], int order); +void lspd_quantise(float lsp[], float lsp_[], int order); +void lspdvq_quantise(float lsp[], float lsp_[], int order); + +int encode_energy(float e); +float decode_energy(int index); + +void encode_amplitudes(int lsp_indexes[], + int *energy_index, + MODEL *model, + float Sn[], + float w[]); + +float decode_amplitudes(MODEL *model, + float ak[], + int lsp_indexes[], + int energy_index, + float lsps[], + float *e); + +void pack(unsigned char * bits, unsigned int *nbit, int index, unsigned int index_bits); +int unpack(const unsigned char * bits, unsigned int *nbit, unsigned int index_bits); + +int lsp_bits(int i); + +void apply_lpc_correction(MODEL *model); +float speech_to_uq_lsps(float lsp[], + float ak[], + float Sn[], + float w[], + int order + ); +void bw_expand_lsps(float lsp[], + int order + ); +void decode_lsps(float lsp[], int indexes[], int order); + +#endif diff --git a/gr-vocoder/lib/codec2/sim.sh b/gr-vocoder/lib/codec2/sim.sh new file mode 100755 index 000000000..10152d979 --- /dev/null +++ b/gr-vocoder/lib/codec2/sim.sh @@ -0,0 +1,22 @@ +#!/bin/sh +# sim.sh +# David Rowe 10 Sep 2009 + +# Process a source file using the codec 2 simulation. An output +# speech file is generated for each major processing step, from the +# unquantised siusoidal model to fully quantised. This way we can +# listen to the effect of each processing step. Use listensim.sh to +# test the output files. + +../src/c2sim ../raw/$1.raw -o $1_uq.raw +../src/c2sim ../raw/$1.raw --phase0 -o $1_phase0.raw --postfilter +../src/c2sim ../raw/$1.raw --lpc 10 -o $1_lpc10.raw --postfilter +../src/c2sim ../raw/$1.raw --phase0 --lpc 10 -o $1_phase0_lpc10.raw --postfilter +../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --dec -o $1_phase0_lpc10_dec.raw --postfilter +../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp --dec -o $1_phase0_lsp_dec.raw --postfilter + +#../src/c2sim ../raw/$1.raw --lpc 10 --lsp -o $1_lsp.raw +#../src/c2sim ../raw/$1.raw --phase0 --lpc 10 -o $1_phase0_lpc10.raw --postfilter +#../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp -o $1_phase0_lsp.raw --postfilter +#../src/c2sim ../raw/$1.raw --phase0 --lpc 10 --lsp -o $1_phase0_lsp_dec.raw --postfilter --dec + diff --git a/gr-vocoder/lib/codec2/sine.c b/gr-vocoder/lib/codec2/sine.c new file mode 100644 index 000000000..45cc9de71 --- /dev/null +++ b/gr-vocoder/lib/codec2/sine.c @@ -0,0 +1,638 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: sine.c + AUTHOR......: David Rowe + DATE CREATED: 19/8/2010 + + Sinusoidal analysis and synthesis functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 1990-2010 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +/*---------------------------------------------------------------------------*\ + + INCLUDES + +\*---------------------------------------------------------------------------*/ + +#include <stdlib.h> +#include <stdio.h> +#include <math.h> + +#include "defines.h" +#include "sine.h" +#include "fft.h" + +#define HPF_BETA 0.125 + +/*---------------------------------------------------------------------------*\ + + HEADERS + +\*---------------------------------------------------------------------------*/ + +void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, + float pstep); + +/*---------------------------------------------------------------------------*\ + + FUNCTIONS + +\*---------------------------------------------------------------------------*/ + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: make_analysis_window + AUTHOR......: David Rowe + DATE CREATED: 11/5/94 + + Init function that generates the time domain analysis window and it's DFT. + +\*---------------------------------------------------------------------------*/ + +void make_analysis_window(float w[],COMP W[]) +{ + float m; + COMP temp; + int i,j; + + /* + Generate Hamming window centered on M-sample pitch analysis window + + 0 M/2 M-1 + |-------------|-------------| + |-------|-------| + NW samples + + All our analysis/synthsis is centred on the M/2 sample. + */ + + m = 0.0; + for(i=0; i<M/2-NW/2; i++) + w[i] = 0.0; + for(i=M/2-NW/2,j=0; i<M/2+NW/2; i++,j++) { + w[i] = 0.5 - 0.5*cos(TWO_PI*j/(NW-1)); + m += w[i]*w[i]; + } + for(i=M/2+NW/2; i<M; i++) + w[i] = 0.0; + + /* Normalise - makes freq domain amplitude estimation straight + forward */ + + m = 1.0/sqrt(m*FFT_ENC); + for(i=0; i<M; i++) { + w[i] *= m; + } + + /* + Generate DFT of analysis window, used for later processing. Note + we modulo FFT_ENC shift the time domain window w[], this makes the + imaginary part of the DFT W[] equal to zero as the shifted w[] is + even about the n=0 time axis if NW is odd. Having the imag part + of the DFT W[] makes computation easier. + + 0 FFT_ENC-1 + |-------------------------| + + ----\ /---- + \ / + \ / <- shifted version of window w[n] + \ / + \ / + ------- + + |---------| |---------| + NW/2 NW/2 + */ + + for(i=0; i<FFT_ENC; i++) { + W[i].real = 0.0; + W[i].imag = 0.0; + } + for(i=0; i<NW/2; i++) + W[i].real = w[i+M/2]; + for(i=FFT_ENC-NW/2,j=M/2-NW/2; i<FFT_ENC; i++,j++) + W[i].real = w[j]; + + fft(&W[0].real,FFT_ENC,-1); /* "Numerical Recipes in C" FFT */ + + /* + Re-arrange W[] to be symmetrical about FFT_ENC/2. Makes later + analysis convenient. + + Before: + + + 0 FFT_ENC-1 + |----------|---------| + __ _ + \ / + \_______________/ + + After: + + 0 FFT_ENC-1 + |----------|---------| + ___ + / \ + ________/ \_______ + + */ + + + for(i=0; i<FFT_ENC/2; i++) { + temp.real = W[i].real; + temp.imag = W[i].imag; + W[i].real = W[i+FFT_ENC/2].real; + W[i].imag = W[i+FFT_ENC/2].imag; + W[i+FFT_ENC/2].real = temp.real; + W[i+FFT_ENC/2].imag = temp.imag; + } + +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: hpf + AUTHOR......: David Rowe + DATE CREATED: 16 Nov 2010 + + High pass filter with a -3dB point of about 160Hz. + + y(n) = -HPF_BETA*y(n-1) + x(n) - x(n-1) + +\*---------------------------------------------------------------------------*/ + +float hpf(float x, float states[]) +{ + states[0] += -HPF_BETA*states[0] + x - states[1]; + states[1] = x; + + return states[0]; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: dft_speech + AUTHOR......: David Rowe + DATE CREATED: 27/5/94 + + Finds the DFT of the current speech input speech frame. + +\*---------------------------------------------------------------------------*/ + +void dft_speech(COMP Sw[], float Sn[], float w[]) +{ + int i; + + for(i=0; i<FFT_ENC; i++) { + Sw[i].real = 0.0; + Sw[i].imag = 0.0; + } + + /* Centre analysis window on time axis, we need to arrange input + to FFT this way to make FFT phases correct */ + + /* move 2nd half to start of FFT input vector */ + + for(i=0; i<NW/2; i++) + Sw[i].real = Sn[i+M/2]*w[i+M/2]; + + /* move 1st half to end of FFT input vector */ + + for(i=0; i<NW/2; i++) + Sw[FFT_ENC-NW/2+i].real = Sn[i+M/2-NW/2]*w[i+M/2-NW/2]; + + fft(&Sw[0].real,FFT_ENC,-1); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: two_stage_pitch_refinement + AUTHOR......: David Rowe + DATE CREATED: 27/5/94 + + Refines the current pitch estimate using the harmonic sum pitch + estimation technique. + +\*---------------------------------------------------------------------------*/ + +void two_stage_pitch_refinement(MODEL *model, COMP Sw[]) +{ + float pmin,pmax,pstep; /* pitch refinment minimum, maximum and step */ + + /* Coarse refinement */ + + pmax = TWO_PI/model->Wo + 5; + pmin = TWO_PI/model->Wo - 5; + pstep = 1.0; + hs_pitch_refinement(model,Sw,pmin,pmax,pstep); + + /* Fine refinement */ + + pmax = TWO_PI/model->Wo + 1; + pmin = TWO_PI/model->Wo - 1; + pstep = 0.25; + hs_pitch_refinement(model,Sw,pmin,pmax,pstep); + + /* Limit range */ + + if (model->Wo < TWO_PI/P_MAX) + model->Wo = TWO_PI/P_MAX; + if (model->Wo > TWO_PI/P_MIN) + model->Wo = TWO_PI/P_MIN; + + model->L = floor(PI/model->Wo); +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: hs_pitch_refinement + AUTHOR......: David Rowe + DATE CREATED: 27/5/94 + + Harmonic sum pitch refinement function. + + pmin pitch search range minimum + pmax pitch search range maximum + step pitch search step size + model current pitch estimate in model.Wo + + model refined pitch estimate in model.Wo + +\*---------------------------------------------------------------------------*/ + +void hs_pitch_refinement(MODEL *model, COMP Sw[], float pmin, float pmax, float pstep) +{ + int m; /* loop variable */ + int b; /* bin for current harmonic centre */ + float E; /* energy for current pitch*/ + float Wo; /* current "test" fundamental freq. */ + float Wom; /* Wo that maximises E */ + float Em; /* mamimum energy */ + float r; /* number of rads/bin */ + float p; /* current pitch */ + + /* Initialisation */ + + model->L = PI/model->Wo; /* use initial pitch est. for L */ + Wom = model->Wo; + Em = 0.0; + r = TWO_PI/FFT_ENC; + + /* Determine harmonic sum for a range of Wo values */ + + for(p=pmin; p<=pmax; p+=pstep) { + E = 0.0; + Wo = TWO_PI/p; + + /* Sum harmonic magnitudes */ + + for(m=1; m<=model->L; m++) { + b = floor(m*Wo/r + 0.5); + E += Sw[b].real*Sw[b].real + Sw[b].imag*Sw[b].imag; + } + + /* Compare to see if this is a maximum */ + + if (E > Em) { + Em = E; + Wom = Wo; + } + } + + model->Wo = Wom; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: estimate_amplitudes + AUTHOR......: David Rowe + DATE CREATED: 27/5/94 + + Estimates the complex amplitudes of the harmonics. + +\*---------------------------------------------------------------------------*/ + +void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[]) +{ + int i,m; /* loop variables */ + int am,bm; /* bounds of current harmonic */ + int b; /* DFT bin of centre of current harmonic */ + float den; /* denominator of amplitude expression */ + float r; /* number of rads/bin */ + int offset; + COMP Am; + + r = TWO_PI/FFT_ENC; + + for(m=1; m<=model->L; m++) { + den = 0.0; + am = floor((m - 0.5)*model->Wo/r + 0.5); + bm = floor((m + 0.5)*model->Wo/r + 0.5); + b = floor(m*model->Wo/r + 0.5); + + /* Estimate ampltude of harmonic */ + + den = 0.0; + Am.real = Am.imag = 0.0; + for(i=am; i<bm; i++) { + den += Sw[i].real*Sw[i].real + Sw[i].imag*Sw[i].imag; + offset = i + FFT_ENC/2 - floor(m*model->Wo/r + 0.5); + Am.real += Sw[i].real*W[offset].real; + Am.imag += Sw[i].imag*W[offset].real; + } + + model->A[m] = sqrt(den); + + /* Estimate phase of harmonic */ + + model->phi[m] = atan2(Sw[b].imag,Sw[b].real); + } +} + +/*---------------------------------------------------------------------------*\ + + est_voicing_mbe() + + Returns the error of the MBE cost function for a fiven F0. + + Note: I think a lot of the operations below can be simplified as + W[].imag = 0 and has been normalised such that den always equals 1. + +\*---------------------------------------------------------------------------*/ + +float est_voicing_mbe( + MODEL *model, + COMP Sw[], + COMP W[], + COMP Sw_[], /* DFT of all voiced synthesised signal */ + /* useful for debugging/dump file */ + COMP Ew[], /* DFT of error */ + float prev_Wo) +{ + int i,l,al,bl,m; /* loop variables */ + COMP Am; /* amplitude sample for this band */ + int offset; /* centers Hw[] about current harmonic */ + float den; /* denominator of Am expression */ + float error; /* accumulated error between original and synthesised */ + float Wo; + float sig, snr; + float elow, ehigh, eratio; + float dF0, sixty; + + sig = 0.0; + for(l=1; l<=model->L/4; l++) { + sig += model->A[l]*model->A[l]; + } + for(i=0; i<FFT_ENC; i++) { + Sw_[i].real = 0.0; + Sw_[i].imag = 0.0; + Ew[i].real = 0.0; + Ew[i].imag = 0.0; + } + + Wo = model->Wo; + error = 0.0; + + /* Just test across the harmonics in the first 1000 Hz (L/4) */ + + for(l=1; l<=model->L/4; l++) { + Am.real = 0.0; + Am.imag = 0.0; + den = 0.0; + al = ceil((l - 0.5)*Wo*FFT_ENC/TWO_PI); + bl = ceil((l + 0.5)*Wo*FFT_ENC/TWO_PI); + + /* Estimate amplitude of harmonic assuming harmonic is totally voiced */ + + for(m=al; m<bl; m++) { + offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5; + Am.real += Sw[m].real*W[offset].real + Sw[m].imag*W[offset].imag; + Am.imag += Sw[m].imag*W[offset].real - Sw[m].real*W[offset].imag; + den += W[offset].real*W[offset].real + W[offset].imag*W[offset].imag; + } + + Am.real = Am.real/den; + Am.imag = Am.imag/den; + + /* Determine error between estimated harmonic and original */ + + for(m=al; m<bl; m++) { + offset = FFT_ENC/2 + m - l*Wo*FFT_ENC/TWO_PI + 0.5; + Sw_[m].real = Am.real*W[offset].real - Am.imag*W[offset].imag; + Sw_[m].imag = Am.real*W[offset].imag + Am.imag*W[offset].real; + Ew[m].real = Sw[m].real - Sw_[m].real; + Ew[m].imag = Sw[m].imag - Sw_[m].imag; + error += Ew[m].real*Ew[m].real; + error += Ew[m].imag*Ew[m].imag; + } + } + + snr = 10.0*log10(sig/error); + if (snr > V_THRESH) + model->voiced = 1; + else + model->voiced = 0; + + /* post processing, helps clean up some voicing errors ------------------*/ + + /* + Determine the ratio of low freancy to high frequency energy, + voiced speech tends to be dominated by low frequency energy, + unvoiced by high frequency. This measure can be used to + determine if we have made any gross errors. + */ + + elow = ehigh = 0.0; + for(l=1; l<=model->L/2; l++) { + elow += model->A[l]*model->A[l]; + } + for(l=model->L/2; l<=model->L; l++) { + ehigh += model->A[l]*model->A[l]; + } + eratio = 10.0*log10(elow/ehigh); + dF0 = 0.0; + + /* Look for Type 1 errors, strongly V speech that has been + accidentally declared UV */ + + if (model->voiced == 0) + if (eratio > 10.0) + model->voiced = 1; + + /* Look for Type 2 errors, strongly UV speech that has been + accidentally declared V */ + + if (model->voiced == 1) { + if (eratio < -10.0) + model->voiced = 0; + + /* If pitch is jumping about it's likely this is UV */ + + dF0 = (model->Wo - prev_Wo)*FS/TWO_PI; + if (fabs(dF0) > 15.0) + model->voiced = 0; + + /* A common source of Type 2 errors is the pitch estimator + gives a low (50Hz) estimate for UV speech, which gives a + good match with noise due to the close harmoonic spacing. + These errors are much more common than people with 50Hz + pitch, so we have just a small eratio threshold. */ + + sixty = 60.0*TWO_PI/FS; + if ((eratio < -4.0) && (model->Wo <= sixty)) + model->voiced = 0; + } + //printf(" v: %d snr: %f eratio: %3.2f %f\n",model->voiced,snr,eratio,dF0); + + return snr; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: make_synthesis_window + AUTHOR......: David Rowe + DATE CREATED: 11/5/94 + + Init function that generates the trapezoidal (Parzen) sythesis window. + +\*---------------------------------------------------------------------------*/ + +void make_synthesis_window(float Pn[]) +{ + int i; + float win; + + /* Generate Parzen window in time domain */ + + win = 0.0; + for(i=0; i<N/2-TW; i++) + Pn[i] = 0.0; + win = 0.0; + for(i=N/2-TW; i<N/2+TW; win+=1.0/(2*TW), i++ ) + Pn[i] = win; + for(i=N/2+TW; i<3*N/2-TW; i++) + Pn[i] = 1.0; + win = 1.0; + for(i=3*N/2-TW; i<3*N/2+TW; win-=1.0/(2*TW), i++) + Pn[i] = win; + for(i=3*N/2+TW; i<2*N; i++) + Pn[i] = 0.0; +} + +/*---------------------------------------------------------------------------*\ + + FUNCTION....: synthesise + AUTHOR......: David Rowe + DATE CREATED: 20/2/95 + + Synthesise a speech signal in the frequency domain from the + sinusodal model parameters. Uses overlap-add with a trapezoidal + window to smoothly interpolate betwen frames. + +\*---------------------------------------------------------------------------*/ + +void synthesise( + float Sn_[], /* time domain synthesised signal */ + MODEL *model, /* ptr to model parameters for this frame */ + float Pn[], /* time domain Parzen window */ + int shift /* flag used to handle transition frames */ +) +{ + int i,l,j,b; /* loop variables */ + COMP Sw_[FFT_DEC]; /* DFT of synthesised signal */ + + if (shift) { + /* Update memories */ + + for(i=0; i<N-1; i++) { + Sn_[i] = Sn_[i+N]; + } + Sn_[N-1] = 0.0; + } + + for(i=0; i<FFT_DEC; i++) { + Sw_[i].real = 0.0; + Sw_[i].imag = 0.0; + } + + /* + Nov 2010 - found that synthesis using time domain cos() functions + gives better results for synthesis frames greater than 10ms. Inverse + FFT synthesis using a 512 pt FFT works well for 10ms window. I think + (but am not sure) that the problem is realted to the quantisation of + the harmonic frequencies to the FFT bin size, e.g. there is a + 8000/512 Hz step between FFT bins. For some reason this makes + the speech from longer frame > 10ms sound poor. The effect can also + be seen when synthesising test signals like single sine waves, some + sort of amplitude modulation at the frame rate. + + Another possibility is using a larger FFT size (1024 or 2048). + */ + +#define FFT_SYNTHESIS +#ifdef FFT_SYNTHESIS + /* Now set up frequency domain synthesised speech */ + for(l=1; l<=model->L; l++) { + b = floor(l*model->Wo*FFT_DEC/TWO_PI + 0.5); + if (b > ((FFT_DEC/2)-1)) { + b = (FFT_DEC/2)-1; + } + Sw_[b].real = model->A[l]*cos(model->phi[l]); + Sw_[b].imag = model->A[l]*sin(model->phi[l]); + Sw_[FFT_DEC-b].real = Sw_[b].real; + Sw_[FFT_DEC-b].imag = -Sw_[b].imag; + } + + /* Perform inverse DFT */ + + fft(&Sw_[0].real,FFT_DEC,1); +#else + /* + Direct time domain synthesis using the cos() function. Works + well at 10ms and 20ms frames rates. Note synthesis window is + still used to handle overlap-add between adjacent frames. This + could be simplified as we don't need to synthesise where Pn[] + is zero. + */ + for(l=1; l<=model->L; l++) { + for(i=0,j=-N+1; i<N-1; i++,j++) { + Sw_[FFT_DEC-N+1+i].real += 2.0*model->A[l]*cos(j*model->Wo*l + model->phi[l]); + } + for(i=N-1,j=0; i<2*N; i++,j++) + Sw_[j].real += 2.0*model->A[l]*cos(j*model->Wo*l + model->phi[l]); + } +#endif + + /* Overlap add to previous samples */ + + for(i=0; i<N-1; i++) { + Sn_[i] += Sw_[FFT_DEC-N+1+i].real*Pn[i]; + } + + if (shift) + for(i=N-1,j=0; i<2*N; i++,j++) + Sn_[i] = Sw_[j].real*Pn[i]; + else + for(i=N-1,j=0; i<2*N; i++,j++) + Sn_[i] += Sw_[j].real*Pn[i]; +} + diff --git a/gr-vocoder/lib/codec2/sine.h b/gr-vocoder/lib/codec2/sine.h new file mode 100644 index 000000000..ae578bf70 --- /dev/null +++ b/gr-vocoder/lib/codec2/sine.h @@ -0,0 +1,44 @@ +/*---------------------------------------------------------------------------*\ + + FILE........: sine.h + AUTHOR......: David Rowe + DATE CREATED: 1/11/94 + + Header file for sinusoidal analysis and synthesis functions. + +\*---------------------------------------------------------------------------*/ + +/* + Copyright (C) 2009 David Rowe + + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License version 2.1, as + published by the Free Software Foundation. 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 Lesser General Public License + along with this program; if not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __SINE__ +#define __SINE__ + +#include "defines.h" +#include "comp.h" + +void make_analysis_window(float w[], COMP W[]); +float hpf(float x, float states[]); +void dft_speech(COMP Sw[], float Sn[], float w[]); +void two_stage_pitch_refinement(MODEL *model, COMP Sw[]); +void estimate_amplitudes(MODEL *model, COMP Sw[], COMP W[]); +float est_voicing_mbe(MODEL *model, COMP Sw[], COMP W[], COMP Sw_[],COMP Ew[], + float prev_Wo); +void make_synthesis_window(float Pn[]); +void synthesise(float Sn_[], MODEL *model, float Pn[], int shift); + +#endif diff --git a/gnuradio-core/src/lib/g72x/.gitignore b/gr-vocoder/lib/g7xx/.gitignore index a02b6ff73..a02b6ff73 100644 --- a/gnuradio-core/src/lib/g72x/.gitignore +++ b/gr-vocoder/lib/g7xx/.gitignore diff --git a/gnuradio-core/src/lib/g72x/Makefile.am b/gr-vocoder/lib/g7xx/Makefile.am index d2700376f..929fd23ba 100644 --- a/gnuradio-core/src/lib/g72x/Makefile.am +++ b/gr-vocoder/lib/g7xx/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2001 Free Software Foundation, Inc. +# Copyright 2001,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,7 +21,7 @@ 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 +noinst_LTLIBRARIES = libg7xx.la +libg7xx_la_SOURCES = g711.c g72x.c g721.c g723_24.c g723_40.c g72x.h EXTRA_DIST += encode.c decode.c diff --git a/gnuradio-core/src/lib/g72x/README b/gr-vocoder/lib/g7xx/README index 23b0e7dd5..23b0e7dd5 100644 --- a/gnuradio-core/src/lib/g72x/README +++ b/gr-vocoder/lib/g7xx/README diff --git a/gnuradio-core/src/lib/g72x/decode.c b/gr-vocoder/lib/g7xx/decode.c index cf8c739c5..cf8c739c5 100644 --- a/gnuradio-core/src/lib/g72x/decode.c +++ b/gr-vocoder/lib/g7xx/decode.c diff --git a/gnuradio-core/src/lib/g72x/encode.c b/gr-vocoder/lib/g7xx/encode.c index e74482869..e74482869 100644 --- a/gnuradio-core/src/lib/g72x/encode.c +++ b/gr-vocoder/lib/g7xx/encode.c diff --git a/gnuradio-core/src/lib/g72x/g711.c b/gr-vocoder/lib/g7xx/g711.c index d4d60a5c2..d4d60a5c2 100644 --- a/gnuradio-core/src/lib/g72x/g711.c +++ b/gr-vocoder/lib/g7xx/g711.c diff --git a/gnuradio-core/src/lib/g72x/g721.c b/gr-vocoder/lib/g7xx/g721.c index 445f177e8..445f177e8 100644 --- a/gnuradio-core/src/lib/g72x/g721.c +++ b/gr-vocoder/lib/g7xx/g721.c diff --git a/gnuradio-core/src/lib/g72x/g723_24.c b/gr-vocoder/lib/g7xx/g723_24.c index 452f4daeb..452f4daeb 100644 --- a/gnuradio-core/src/lib/g72x/g723_24.c +++ b/gr-vocoder/lib/g7xx/g723_24.c diff --git a/gnuradio-core/src/lib/g72x/g723_40.c b/gr-vocoder/lib/g7xx/g723_40.c index 4858baf40..4858baf40 100644 --- a/gnuradio-core/src/lib/g72x/g723_40.c +++ b/gr-vocoder/lib/g7xx/g723_40.c diff --git a/gnuradio-core/src/lib/g72x/g72x.c b/gr-vocoder/lib/g7xx/g72x.c index 9a823c755..9a823c755 100644 --- a/gnuradio-core/src/lib/g72x/g72x.c +++ b/gr-vocoder/lib/g7xx/g72x.c diff --git a/gnuradio-core/src/lib/g72x/g72x.h b/gr-vocoder/lib/g7xx/g72x.h index 33807171a..33807171a 100644 --- a/gnuradio-core/src/lib/g72x/g72x.h +++ b/gr-vocoder/lib/g7xx/g72x.h diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/.gitignore b/gr-vocoder/lib/gsm/.gitignore index a02b6ff73..a02b6ff73 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/.gitignore +++ b/gr-vocoder/lib/gsm/.gitignore diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/COPYRIGHT b/gr-vocoder/lib/gsm/COPYRIGHT index eba0e523b..eba0e523b 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/COPYRIGHT +++ b/gr-vocoder/lib/gsm/COPYRIGHT diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/Makefile.am b/gr-vocoder/lib/gsm/Makefile.am index d0872ff39..d0872ff39 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/Makefile.am +++ b/gr-vocoder/lib/gsm/Makefile.am diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/README b/gr-vocoder/lib/gsm/README index 1927d878a..1927d878a 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/README +++ b/gr-vocoder/lib/gsm/README diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/README.gsm b/gr-vocoder/lib/gsm/README.gsm index cb6af85cf..cb6af85cf 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/README.gsm +++ b/gr-vocoder/lib/gsm/README.gsm diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/add.c b/gr-vocoder/lib/gsm/add.c index 21ccfabe7..21ccfabe7 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/add.c +++ b/gr-vocoder/lib/gsm/add.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/code.c b/gr-vocoder/lib/gsm/code.c index 19af507b7..19af507b7 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/code.c +++ b/gr-vocoder/lib/gsm/code.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/config.h b/gr-vocoder/lib/gsm/config.h index 2a962ac7d..2a962ac7d 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/config.h +++ b/gr-vocoder/lib/gsm/config.h diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/debug.c b/gr-vocoder/lib/gsm/debug.c index e05210428..e05210428 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/debug.c +++ b/gr-vocoder/lib/gsm/debug.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/decode.c b/gr-vocoder/lib/gsm/decode.c index 34e558663..34e558663 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/decode.c +++ b/gr-vocoder/lib/gsm/decode.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm.h b/gr-vocoder/lib/gsm/gsm.h index 990e42af5..990e42af5 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/gsm.h +++ b/gr-vocoder/lib/gsm/gsm.h diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_create.c b/gr-vocoder/lib/gsm/gsm_create.c index de0b125b4..de0b125b4 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_create.c +++ b/gr-vocoder/lib/gsm/gsm_create.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_decode.c b/gr-vocoder/lib/gsm/gsm_decode.c index 7318ba2d4..7318ba2d4 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_decode.c +++ b/gr-vocoder/lib/gsm/gsm_decode.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_destroy.c b/gr-vocoder/lib/gsm/gsm_destroy.c index 4807c0acd..4807c0acd 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_destroy.c +++ b/gr-vocoder/lib/gsm/gsm_destroy.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_encode.c b/gr-vocoder/lib/gsm/gsm_encode.c index 62338300e..62338300e 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_encode.c +++ b/gr-vocoder/lib/gsm/gsm_encode.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_explode.c b/gr-vocoder/lib/gsm/gsm_explode.c index a906fc2ed..a906fc2ed 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_explode.c +++ b/gr-vocoder/lib/gsm/gsm_explode.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_implode.c b/gr-vocoder/lib/gsm/gsm_implode.c index 453b8cf39..453b8cf39 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_implode.c +++ b/gr-vocoder/lib/gsm/gsm_implode.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_option.c b/gr-vocoder/lib/gsm/gsm_option.c index 280780132..280780132 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_option.c +++ b/gr-vocoder/lib/gsm/gsm_option.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_print.c b/gr-vocoder/lib/gsm/gsm_print.c index af745bc48..af745bc48 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/gsm_print.c +++ b/gr-vocoder/lib/gsm/gsm_print.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/long_term.c b/gr-vocoder/lib/gsm/long_term.c index fd67bda19..fd67bda19 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/long_term.c +++ b/gr-vocoder/lib/gsm/long_term.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/lpc.c b/gr-vocoder/lib/gsm/lpc.c index ac2b8a9eb..ac2b8a9eb 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/lpc.c +++ b/gr-vocoder/lib/gsm/lpc.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/preprocess.c b/gr-vocoder/lib/gsm/preprocess.c index 99c0709dc..99c0709dc 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/preprocess.c +++ b/gr-vocoder/lib/gsm/preprocess.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/private.h b/gr-vocoder/lib/gsm/private.h index 6b538cc27..6b538cc27 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/private.h +++ b/gr-vocoder/lib/gsm/private.h diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/proto.h b/gr-vocoder/lib/gsm/proto.h index 87cf05e8a..87cf05e8a 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/proto.h +++ b/gr-vocoder/lib/gsm/proto.h diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/rpe.c b/gr-vocoder/lib/gsm/rpe.c index 8a6b81fae..8a6b81fae 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/rpe.c +++ b/gr-vocoder/lib/gsm/rpe.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/short_term.c b/gr-vocoder/lib/gsm/short_term.c index 4f5fd7be7..4f5fd7be7 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/short_term.c +++ b/gr-vocoder/lib/gsm/short_term.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/table.c b/gr-vocoder/lib/gsm/table.c index 16a04118c..16a04118c 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/table.c +++ b/gr-vocoder/lib/gsm/table.c diff --git a/gr-gsm-fr-vocoder/src/lib/gsm/unproto.h b/gr-vocoder/lib/gsm/unproto.h index ccd565109..ccd565109 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm/unproto.h +++ b/gr-vocoder/lib/gsm/unproto.h diff --git a/gr-vocoder/lib/vocoder_alaw_decode_bs.cc b/gr-vocoder/lib/vocoder_alaw_decode_bs.cc new file mode 100644 index 000000000..7ffdddd81 --- /dev/null +++ b/gr-vocoder/lib/vocoder_alaw_decode_bs.cc @@ -0,0 +1,65 @@ +/* -*- 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 <vocoder_alaw_decode_bs.h> +#include <gr_io_signature.h> +#include <limits.h> + +extern "C" { +#include "g7xx/g72x.h" +} + +vocoder_alaw_decode_bs_sptr vocoder_make_alaw_decode_bs() +{ + return gnuradio::get_initial_sptr(new vocoder_alaw_decode_bs()); +} + +vocoder_alaw_decode_bs::vocoder_alaw_decode_bs() + : gr_sync_block("vocoder_alaw_decode_bs", + gr_make_io_signature (1, 1, sizeof (unsigned char)), + gr_make_io_signature (1, 1, sizeof (short))) +{ +} + +vocoder_alaw_decode_bs::~vocoder_alaw_decode_bs() +{ +} + + + +int +vocoder_alaw_decode_bs::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]; + short *out = (short *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) + out[i] = alaw2linear(in[i]); + + return noutput_items; +} diff --git a/gr-vocoder/lib/vocoder_alaw_encode_sb.cc b/gr-vocoder/lib/vocoder_alaw_encode_sb.cc new file mode 100644 index 000000000..e4d975271 --- /dev/null +++ b/gr-vocoder/lib/vocoder_alaw_encode_sb.cc @@ -0,0 +1,63 @@ +/* -*- 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 <vocoder_alaw_encode_sb.h> +#include <gr_io_signature.h> +#include <limits.h> + +extern "C" { +#include "g7xx/g72x.h" +} + +vocoder_alaw_encode_sb_sptr vocoder_make_alaw_encode_sb() +{ + return gnuradio::get_initial_sptr(new vocoder_alaw_encode_sb()); +} + +vocoder_alaw_encode_sb::vocoder_alaw_encode_sb() + : gr_sync_block("vocoder_alaw_encode_sb", + gr_make_io_signature (1, 1, sizeof(short)), + gr_make_io_signature (1, 1, sizeof(unsigned char))) +{ +} + +vocoder_alaw_encode_sb::~vocoder_alaw_encode_sb() +{ +} + +int +vocoder_alaw_encode_sb::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const short *in = (const short *)input_items[0]; + unsigned char *out = (unsigned char *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) + out[i] = linear2alaw(in[i]); + + return noutput_items; +} diff --git a/gr-vocoder/lib/vocoder_codec2_decode_ps.cc b/gr-vocoder/lib/vocoder_codec2_decode_ps.cc new file mode 100644 index 000000000..b1feb1aaf --- /dev/null +++ b/gr-vocoder/lib/vocoder_codec2_decode_ps.cc @@ -0,0 +1,75 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,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 "vocoder_codec2_decode_ps.h" + +extern "C" { +#include "codec2/codec2.h" +} + +#include <gr_io_signature.h> +#include <stdexcept> +#include <assert.h> + +vocoder_codec2_decode_ps_sptr +vocoder_make_codec2_decode_ps () +{ + return gnuradio::get_initial_sptr(new vocoder_codec2_decode_ps ()); +} + +vocoder_codec2_decode_ps::vocoder_codec2_decode_ps () + : gr_sync_interpolator ("vocoder_codec2_decode_ps", + gr_make_io_signature (1, 1, CODEC2_BITS_PER_FRAME * sizeof (char)), + gr_make_io_signature (1, 1, sizeof (short)), + CODEC2_SAMPLES_PER_FRAME) +{ + if ((d_codec2 = codec2_create ()) == 0) + throw std::runtime_error ("vocoder_codec2_decode_ps: codec2_create failed"); +} + +vocoder_codec2_decode_ps::~vocoder_codec2_decode_ps () +{ + codec2_destroy(d_codec2); +} + +int +vocoder_codec2_decode_ps::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]; + short *out = (short *) output_items[0]; + + assert ((noutput_items % CODEC2_SAMPLES_PER_FRAME) == 0); + + for (int i = 0; i < noutput_items; i += CODEC2_SAMPLES_PER_FRAME){ + codec2_decode (d_codec2, out, const_cast<unsigned char*>(in)); + in += CODEC2_BITS_PER_FRAME * sizeof (char); + out += CODEC2_SAMPLES_PER_FRAME; + } + + return noutput_items; +} diff --git a/gr-vocoder/lib/vocoder_codec2_encode_sp.cc b/gr-vocoder/lib/vocoder_codec2_encode_sp.cc new file mode 100644 index 000000000..1f22e38b2 --- /dev/null +++ b/gr-vocoder/lib/vocoder_codec2_encode_sp.cc @@ -0,0 +1,72 @@ +/* -*- c++ -*- */ +/* + * Copyright 2005,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 "vocoder_codec2_encode_sp.h" + +extern "C" { +#include "codec2/codec2.h" +} + +#include <gr_io_signature.h> +#include <stdexcept> + +vocoder_codec2_encode_sp_sptr +vocoder_make_codec2_encode_sp () +{ + return gnuradio::get_initial_sptr(new vocoder_codec2_encode_sp ()); +} + +vocoder_codec2_encode_sp::vocoder_codec2_encode_sp () + : gr_sync_decimator ("vocoder_codec2_encode_sp", + gr_make_io_signature (1, 1, sizeof (short)), + gr_make_io_signature (1, 1, CODEC2_BITS_PER_FRAME * sizeof (char)), + CODEC2_SAMPLES_PER_FRAME) +{ + if ((d_codec2 = codec2_create ()) == 0) + throw std::runtime_error ("vocoder_codec2_encode_sp: codec2_create failed"); +} + +vocoder_codec2_encode_sp::~vocoder_codec2_encode_sp () +{ + codec2_destroy(d_codec2); +} + +int +vocoder_codec2_encode_sp::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const short *in = (const short *) input_items[0]; + unsigned char *out = (unsigned char *) output_items[0]; + + for (int i = 0; i < noutput_items; i++){ + codec2_encode (d_codec2, out, const_cast<short*>(in)); + in += CODEC2_SAMPLES_PER_FRAME; + out += CODEC2_BITS_PER_FRAME * sizeof (char); + } + + return noutput_items; +} diff --git a/gr-cvsd-vocoder/src/lib/cvsd_decode_bs.cc b/gr-vocoder/lib/vocoder_cvsd_decode_bs.cc index 26dcb29da..baf99f041 100644 --- a/gr-cvsd-vocoder/src/lib/cvsd_decode_bs.cc +++ b/gr-vocoder/lib/vocoder_cvsd_decode_bs.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007,2010 Free Software Foundation, Inc. + * Copyright 2007,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -29,28 +29,28 @@ #include "config.h" #endif -#include <cvsd_decode_bs.h> +#include <vocoder_cvsd_decode_bs.h> #include <gr_io_signature.h> #include <limits.h> /* - * Create a new instance of cvsd_decode_bs and return + * Create a new instance of vocoder_cvsd_decode_bs and return * a boost shared_ptr. This is effectively the public constructor. */ -cvsd_decode_bs_sptr -cvsd_make_decode_bs (short min_step, short max_step, double step_decay, - double accum_decay, int K, int J, - short pos_accum_max, short neg_accum_max) +vocoder_cvsd_decode_bs_sptr +vocoder_make_cvsd_decode_bs (short min_step, short max_step, double step_decay, + double accum_decay, int K, int J, + short pos_accum_max, short neg_accum_max) { - return gnuradio::get_initial_sptr(new cvsd_decode_bs (min_step, max_step, - step_decay, accum_decay, K, J, - pos_accum_max, neg_accum_max)); + return gnuradio::get_initial_sptr(new vocoder_cvsd_decode_bs (min_step, max_step, + step_decay, accum_decay, K, J, + pos_accum_max, neg_accum_max)); } -cvsd_decode_bs::cvsd_decode_bs (short min_step, short max_step, double step_decay, - double accum_decay, int K, int J, - short pos_accum_max, short neg_accum_max) - : gr_sync_interpolator ("cvsd_decode_bs", +vocoder_cvsd_decode_bs::vocoder_cvsd_decode_bs (short min_step, short max_step, double step_decay, + double accum_decay, int K, int J, + short pos_accum_max, short neg_accum_max) + : gr_sync_interpolator ("vocoder_cvsd_decode_bs", gr_make_io_signature (1, 1, sizeof (unsigned char)), gr_make_io_signature (1, 1, sizeof (short)), 8), @@ -69,12 +69,12 @@ cvsd_decode_bs::cvsd_decode_bs (short min_step, short max_step, double step_deca } -cvsd_decode_bs::~cvsd_decode_bs () +vocoder_cvsd_decode_bs::~vocoder_cvsd_decode_bs () { // nothing else required in this example } -unsigned char cvsd_decode_bs::cvsd_bitwise_sum (unsigned int input) +unsigned char vocoder_cvsd_decode_bs::cvsd_bitwise_sum (unsigned int input) { unsigned int temp=input; unsigned char bits=0; @@ -86,7 +86,7 @@ unsigned char cvsd_decode_bs::cvsd_bitwise_sum (unsigned int input) return bits; } -int cvsd_decode_bs::cvsd_round (double input) +int vocoder_cvsd_decode_bs::cvsd_round (double input) { double temp; temp=input+0.5; @@ -95,7 +95,7 @@ int cvsd_decode_bs::cvsd_round (double input) return (int)temp; } -unsigned int cvsd_decode_bs::cvsd_pow (short radix, short power) +unsigned int vocoder_cvsd_decode_bs::cvsd_pow (short radix, short power) { double d_radix = (double) radix; int i_power = (int) power; @@ -107,9 +107,9 @@ unsigned int cvsd_decode_bs::cvsd_pow (short radix, short power) int -cvsd_decode_bs::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) +vocoder_cvsd_decode_bs::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { diff --git a/gr-cvsd-vocoder/src/lib/cvsd_encode_sb.cc b/gr-vocoder/lib/vocoder_cvsd_encode_sb.cc index df867f3ba..71cf6df8c 100644 --- a/gr-cvsd-vocoder/src/lib/cvsd_encode_sb.cc +++ b/gr-vocoder/lib/vocoder_cvsd_encode_sb.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2007,2010 Free Software Foundation, Inc. + * Copyright 2007,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -29,28 +29,28 @@ #include "config.h" #endif -#include <cvsd_encode_sb.h> +#include <vocoder_cvsd_encode_sb.h> #include <gr_io_signature.h> #include <limits.h> /* - * Create a new instance of cvsd_encode_sb and return + * Create a new instance of vocoder_cvsd_encode_sb and return * a boost shared_ptr. This is effectively the public constructor. */ -cvsd_encode_sb_sptr -cvsd_make_encode_sb (short min_step, short max_step, double step_decay, - double accum_decay, int K, int J, - short pos_accum_max, short neg_accum_max) +vocoder_cvsd_encode_sb_sptr +vocoder_make_cvsd_encode_sb (short min_step, short max_step, double step_decay, + double accum_decay, int K, int J, + short pos_accum_max, short neg_accum_max) { - return gnuradio::get_initial_sptr(new cvsd_encode_sb (min_step, max_step, - step_decay, accum_decay, K, J, - pos_accum_max, neg_accum_max)); + return gnuradio::get_initial_sptr(new vocoder_cvsd_encode_sb (min_step, max_step, + step_decay, accum_decay, K, J, + pos_accum_max, neg_accum_max)); } -cvsd_encode_sb::cvsd_encode_sb (short min_step, short max_step, double step_decay, - double accum_decay, int K, int J, - short pos_accum_max, short neg_accum_max) - : gr_sync_decimator ("cvsd_encode_sb", +vocoder_cvsd_encode_sb::vocoder_cvsd_encode_sb (short min_step, short max_step, double step_decay, + double accum_decay, int K, int J, + short pos_accum_max, short neg_accum_max) + : gr_sync_decimator ("vocoder_cvsd_encode_sb", gr_make_io_signature (1, 1, sizeof (short)), gr_make_io_signature (1, 1, sizeof (unsigned char)), 8), @@ -68,12 +68,12 @@ cvsd_encode_sb::cvsd_encode_sb (short min_step, short max_step, double step_deca } -cvsd_encode_sb::~cvsd_encode_sb () +vocoder_cvsd_encode_sb::~vocoder_cvsd_encode_sb () { // nothing else required in this example } -unsigned char cvsd_encode_sb::cvsd_bitwise_sum (unsigned int input) +unsigned char vocoder_cvsd_encode_sb::cvsd_bitwise_sum (unsigned int input) { unsigned int temp=input; unsigned char bits=0; @@ -85,7 +85,7 @@ unsigned char cvsd_encode_sb::cvsd_bitwise_sum (unsigned int input) return bits; } -int cvsd_encode_sb::cvsd_round (double input) +int vocoder_cvsd_encode_sb::cvsd_round (double input) { double temp; temp=input+0.5; @@ -94,7 +94,7 @@ int cvsd_encode_sb::cvsd_round (double input) return (int)temp; } -unsigned int cvsd_encode_sb::cvsd_pow (short radix, short power) +unsigned int vocoder_cvsd_encode_sb::cvsd_pow (short radix, short power) { double d_radix = (double) radix; int i_power = (int) power; @@ -104,12 +104,10 @@ unsigned int cvsd_encode_sb::cvsd_pow (short radix, short power) return ( (unsigned int) cvsd_round(output)); } - - int -cvsd_encode_sb::work (int noutput_items, - gr_vector_const_void_star &input_items, - gr_vector_void_star &output_items) +vocoder_cvsd_encode_sb::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) { const short *in = (const short *) input_items[0]; unsigned char *out = (unsigned char *) output_items[0]; diff --git a/gr-vocoder/lib/vocoder_g721_decode_bs.cc b/gr-vocoder/lib/vocoder_g721_decode_bs.cc new file mode 100644 index 000000000..2abee8d14 --- /dev/null +++ b/gr-vocoder/lib/vocoder_g721_decode_bs.cc @@ -0,0 +1,81 @@ +/* -*- 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 <vocoder_g721_decode_bs.h> +#include <gr_io_signature.h> +#include <limits.h> + +extern "C" { +#include "g7xx/g72x.h" +} + +class vocoder_g721_decode_bs_impl : public vocoder_g721_decode_bs +{ +public: + + vocoder_g721_decode_bs_impl(); + ~vocoder_g721_decode_bs_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + +private: + + g72x_state d_state; + +}; + +vocoder_g721_decode_bs_sptr vocoder_make_g721_decode_bs() +{ + return gnuradio::get_initial_sptr(new vocoder_g721_decode_bs_impl()); +} + +vocoder_g721_decode_bs_impl::vocoder_g721_decode_bs_impl() + : gr_sync_block("vocoder_g721_decode_bs", + gr_make_io_signature (1, 1, sizeof (unsigned char)), + gr_make_io_signature (1, 1, sizeof (short))) +{ + g72x_init_state(&d_state); +} + +vocoder_g721_decode_bs_impl::~vocoder_g721_decode_bs_impl() +{ +} + +int +vocoder_g721_decode_bs_impl::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]; + short *out = (short *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) + out[i] = g721_decoder(in[i], AUDIO_ENCODING_LINEAR, &d_state); + + return noutput_items; +} diff --git a/gr-vocoder/lib/vocoder_g721_encode_sb.cc b/gr-vocoder/lib/vocoder_g721_encode_sb.cc new file mode 100644 index 000000000..667e983dc --- /dev/null +++ b/gr-vocoder/lib/vocoder_g721_encode_sb.cc @@ -0,0 +1,81 @@ +/* -*- 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 <vocoder_g721_encode_sb.h> +#include <gr_io_signature.h> +#include <limits.h> + +extern "C" { +#include "g7xx/g72x.h" +} + +class vocoder_g721_encode_sb_impl : public vocoder_g721_encode_sb +{ +public: + + vocoder_g721_encode_sb_impl(); + ~vocoder_g721_encode_sb_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + +private: + + g72x_state d_state; + +}; + +vocoder_g721_encode_sb_sptr vocoder_make_g721_encode_sb() +{ + return gnuradio::get_initial_sptr(new vocoder_g721_encode_sb_impl()); +} + +vocoder_g721_encode_sb_impl::vocoder_g721_encode_sb_impl() + : gr_sync_block("vocoder_g721_encode_sb", + gr_make_io_signature (1, 1, sizeof (short)), + gr_make_io_signature (1, 1, sizeof (unsigned char))) +{ + g72x_init_state(&d_state); +} + +vocoder_g721_encode_sb_impl::~vocoder_g721_encode_sb_impl() +{ +} + +int +vocoder_g721_encode_sb_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const short *in = (const short *)input_items[0]; + unsigned char *out = (unsigned char *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) + out[i] = g721_encoder(in[i], AUDIO_ENCODING_LINEAR, &d_state); + + return noutput_items; +} diff --git a/gr-vocoder/lib/vocoder_g723_24_decode_bs.cc b/gr-vocoder/lib/vocoder_g723_24_decode_bs.cc new file mode 100644 index 000000000..2ea036c58 --- /dev/null +++ b/gr-vocoder/lib/vocoder_g723_24_decode_bs.cc @@ -0,0 +1,81 @@ +/* -*- 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 <vocoder_g723_24_decode_bs.h> +#include <gr_io_signature.h> +#include <limits.h> + +extern "C" { +#include "g7xx/g72x.h" +} + +class vocoder_g723_24_decode_bs_impl : public vocoder_g723_24_decode_bs +{ +public: + + vocoder_g723_24_decode_bs_impl(); + ~vocoder_g723_24_decode_bs_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + +private: + + g72x_state d_state; + +}; + +vocoder_g723_24_decode_bs_sptr vocoder_make_g723_24_decode_bs() +{ + return gnuradio::get_initial_sptr(new vocoder_g723_24_decode_bs_impl()); +} + +vocoder_g723_24_decode_bs_impl::vocoder_g723_24_decode_bs_impl() + : gr_sync_block("vocoder_g723_24_decode_bs", + gr_make_io_signature (1, 1, sizeof (unsigned char)), + gr_make_io_signature (1, 1, sizeof (short))) +{ + g72x_init_state(&d_state); +} + +vocoder_g723_24_decode_bs_impl::~vocoder_g723_24_decode_bs_impl() +{ +} + +int +vocoder_g723_24_decode_bs_impl::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]; + short *out = (short *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) + out[i] = g723_24_decoder(in[i], AUDIO_ENCODING_LINEAR, &d_state); + + return noutput_items; +} diff --git a/gr-vocoder/lib/vocoder_g723_24_encode_sb.cc b/gr-vocoder/lib/vocoder_g723_24_encode_sb.cc new file mode 100644 index 000000000..7e6914223 --- /dev/null +++ b/gr-vocoder/lib/vocoder_g723_24_encode_sb.cc @@ -0,0 +1,81 @@ +/* -*- 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 <vocoder_g723_24_encode_sb.h> +#include <gr_io_signature.h> +#include <limits.h> + +extern "C" { +#include "g7xx/g72x.h" +} + +class vocoder_g723_24_encode_sb_impl : public vocoder_g723_24_encode_sb +{ +public: + + vocoder_g723_24_encode_sb_impl(); + ~vocoder_g723_24_encode_sb_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + +private: + + g72x_state d_state; + +}; + +vocoder_g723_24_encode_sb_sptr vocoder_make_g723_24_encode_sb() +{ + return gnuradio::get_initial_sptr(new vocoder_g723_24_encode_sb_impl()); +} + +vocoder_g723_24_encode_sb_impl::vocoder_g723_24_encode_sb_impl() + : gr_sync_block("vocoder_g723_24_encode_sb", + gr_make_io_signature (1, 1, sizeof (short)), + gr_make_io_signature (1, 1, sizeof (unsigned char))) +{ + g72x_init_state(&d_state); +} + +vocoder_g723_24_encode_sb_impl::~vocoder_g723_24_encode_sb_impl() +{ +} + +int +vocoder_g723_24_encode_sb_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const short *in = (const short *)input_items[0]; + unsigned char *out = (unsigned char *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) + out[i] = g723_24_encoder(in[i], AUDIO_ENCODING_LINEAR, &d_state); + + return noutput_items; +} diff --git a/gr-vocoder/lib/vocoder_g723_40_decode_bs.cc b/gr-vocoder/lib/vocoder_g723_40_decode_bs.cc new file mode 100644 index 000000000..38fd0fb5e --- /dev/null +++ b/gr-vocoder/lib/vocoder_g723_40_decode_bs.cc @@ -0,0 +1,81 @@ +/* -*- 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 <vocoder_g723_40_decode_bs.h> +#include <gr_io_signature.h> +#include <limits.h> + +extern "C" { +#include "g7xx/g72x.h" +} + +class vocoder_g723_40_decode_bs_impl : public vocoder_g723_40_decode_bs +{ +public: + + vocoder_g723_40_decode_bs_impl(); + ~vocoder_g723_40_decode_bs_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + +private: + + g72x_state d_state; + +}; + +vocoder_g723_40_decode_bs_sptr vocoder_make_g723_40_decode_bs() +{ + return gnuradio::get_initial_sptr(new vocoder_g723_40_decode_bs_impl()); +} + +vocoder_g723_40_decode_bs_impl::vocoder_g723_40_decode_bs_impl() + : gr_sync_block("vocoder_g723_40_decode_bs", + gr_make_io_signature (1, 1, sizeof (unsigned char)), + gr_make_io_signature (1, 1, sizeof (short))) +{ + g72x_init_state(&d_state); +} + +vocoder_g723_40_decode_bs_impl::~vocoder_g723_40_decode_bs_impl() +{ +} + +int +vocoder_g723_40_decode_bs_impl::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]; + short *out = (short *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) + out[i] = g723_40_decoder(in[i], AUDIO_ENCODING_LINEAR, &d_state); + + return noutput_items; +} diff --git a/gr-vocoder/lib/vocoder_g723_40_encode_sb.cc b/gr-vocoder/lib/vocoder_g723_40_encode_sb.cc new file mode 100644 index 000000000..1089306e7 --- /dev/null +++ b/gr-vocoder/lib/vocoder_g723_40_encode_sb.cc @@ -0,0 +1,81 @@ +/* -*- 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 <vocoder_g723_40_encode_sb.h> +#include <gr_io_signature.h> +#include <limits.h> + +extern "C" { +#include "g7xx/g72x.h" +} + +class vocoder_g723_40_encode_sb_impl : public vocoder_g723_40_encode_sb +{ +public: + + vocoder_g723_40_encode_sb_impl(); + ~vocoder_g723_40_encode_sb_impl(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + +private: + + g72x_state d_state; + +}; + +vocoder_g723_40_encode_sb_sptr vocoder_make_g723_40_encode_sb() +{ + return gnuradio::get_initial_sptr(new vocoder_g723_40_encode_sb_impl()); +} + +vocoder_g723_40_encode_sb_impl::vocoder_g723_40_encode_sb_impl() + : gr_sync_block("vocoder_g723_40_encode_sb", + gr_make_io_signature (1, 1, sizeof (short)), + gr_make_io_signature (1, 1, sizeof (unsigned char))) +{ + g72x_init_state(&d_state); +} + +vocoder_g723_40_encode_sb_impl::~vocoder_g723_40_encode_sb_impl() +{ +} + +int +vocoder_g723_40_encode_sb_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const short *in = (const short *)input_items[0]; + unsigned char *out = (unsigned char *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) + out[i] = g723_40_encoder(in[i], AUDIO_ENCODING_LINEAR, &d_state); + + return noutput_items; +} diff --git a/gr-gsm-fr-vocoder/src/lib/gsm_fr_decode_ps.cc b/gr-vocoder/lib/vocoder_gsm_fr_decode_ps.cc index 9b788dedf..986e0814e 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm_fr_decode_ps.cc +++ b/gr-vocoder/lib/vocoder_gsm_fr_decode_ps.cc @@ -23,7 +23,7 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "gsm_fr_decode_ps.h" +#include "vocoder_gsm_fr_decode_ps.h" extern "C"{ #include "gsm/gsm.h" } @@ -31,29 +31,29 @@ extern "C"{ #include <stdexcept> #include <assert.h> -gsm_fr_decode_ps_sptr -gsm_fr_make_decode_ps () +vocoder_gsm_fr_decode_ps_sptr +vocoder_make_gsm_fr_decode_ps () { - return gnuradio::get_initial_sptr(new gsm_fr_decode_ps ()); + return gnuradio::get_initial_sptr(new vocoder_gsm_fr_decode_ps ()); } -gsm_fr_decode_ps::gsm_fr_decode_ps () - : gr_sync_interpolator ("gsm_fr_decode_ps", +vocoder_gsm_fr_decode_ps::vocoder_gsm_fr_decode_ps () + : gr_sync_interpolator ("vocoder_gsm_fr_decode_ps", gr_make_io_signature (1, 1, sizeof (gsm_frame)), gr_make_io_signature (1, 1, sizeof (short)), GSM_SAMPLES_PER_FRAME) { if ((d_gsm = gsm_create ()) == 0) - throw std::runtime_error ("gsm_fr_decode_ps: gsm_create failed"); + throw std::runtime_error ("vocoder_gsm_fr_decode_ps: gsm_create failed"); } -gsm_fr_decode_ps::~gsm_fr_decode_ps () +vocoder_gsm_fr_decode_ps::~vocoder_gsm_fr_decode_ps () { gsm_destroy (d_gsm); } int -gsm_fr_decode_ps::work (int noutput_items, +vocoder_gsm_fr_decode_ps::work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { diff --git a/gr-gsm-fr-vocoder/src/lib/gsm_fr_encode_sp.cc b/gr-vocoder/lib/vocoder_gsm_fr_encode_sp.cc index 10bd1fef8..7a69b856d 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm_fr_encode_sp.cc +++ b/gr-vocoder/lib/vocoder_gsm_fr_encode_sp.cc @@ -23,36 +23,36 @@ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "gsm_fr_encode_sp.h" +#include "vocoder_gsm_fr_encode_sp.h" extern "C"{ #include "gsm/gsm.h" } #include <gr_io_signature.h> #include <stdexcept> -gsm_fr_encode_sp_sptr -gsm_fr_make_encode_sp () +vocoder_gsm_fr_encode_sp_sptr +vocoder_make_gsm_fr_encode_sp () { - return gnuradio::get_initial_sptr(new gsm_fr_encode_sp ()); + return gnuradio::get_initial_sptr(new vocoder_gsm_fr_encode_sp ()); } -gsm_fr_encode_sp::gsm_fr_encode_sp () - : gr_sync_decimator ("gsm_fr_encode_sp", +vocoder_gsm_fr_encode_sp::vocoder_gsm_fr_encode_sp () + : gr_sync_decimator ("vocoder_gsm_fr_encode_sp", gr_make_io_signature (1, 1, sizeof (short)), gr_make_io_signature (1, 1, sizeof (gsm_frame)), GSM_SAMPLES_PER_FRAME) { if ((d_gsm = gsm_create ()) == 0) - throw std::runtime_error ("gsm_fr_encode_sp: gsm_create failed"); + throw std::runtime_error ("vocoder_gsm_fr_encode_sp: gsm_create failed"); } -gsm_fr_encode_sp::~gsm_fr_encode_sp () +vocoder_gsm_fr_encode_sp::~vocoder_gsm_fr_encode_sp () { gsm_destroy (d_gsm); } int -gsm_fr_encode_sp::work (int noutput_items, +vocoder_gsm_fr_encode_sp::work (int noutput_items, gr_vector_const_void_star &input_items, gr_vector_void_star &output_items) { diff --git a/gr-vocoder/lib/vocoder_ulaw_decode_bs.cc b/gr-vocoder/lib/vocoder_ulaw_decode_bs.cc new file mode 100644 index 000000000..3ade9d3f0 --- /dev/null +++ b/gr-vocoder/lib/vocoder_ulaw_decode_bs.cc @@ -0,0 +1,65 @@ +/* -*- 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 <vocoder_ulaw_decode_bs.h> +#include <gr_io_signature.h> +#include <limits.h> + +extern "C" { +#include "g7xx/g72x.h" +} + +vocoder_ulaw_decode_bs_sptr vocoder_make_ulaw_decode_bs() +{ + return gnuradio::get_initial_sptr(new vocoder_ulaw_decode_bs()); +} + +vocoder_ulaw_decode_bs::vocoder_ulaw_decode_bs() + : gr_sync_block("vocoder_ulaw_decode_bs", + gr_make_io_signature (1, 1, sizeof (unsigned char)), + gr_make_io_signature (1, 1, sizeof (short))) +{ +} + +vocoder_ulaw_decode_bs::~vocoder_ulaw_decode_bs() +{ +} + + + +int +vocoder_ulaw_decode_bs::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]; + short *out = (short *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) + out[i] = ulaw2linear(in[i]); + + return noutput_items; +} diff --git a/gr-vocoder/lib/vocoder_ulaw_encode_sb.cc b/gr-vocoder/lib/vocoder_ulaw_encode_sb.cc new file mode 100644 index 000000000..19c53d72c --- /dev/null +++ b/gr-vocoder/lib/vocoder_ulaw_encode_sb.cc @@ -0,0 +1,63 @@ +/* -*- 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 <vocoder_ulaw_encode_sb.h> +#include <gr_io_signature.h> +#include <limits.h> + +extern "C" { +#include "g7xx/g72x.h" +} + +vocoder_ulaw_encode_sb_sptr vocoder_make_ulaw_encode_sb() +{ + return gnuradio::get_initial_sptr(new vocoder_ulaw_encode_sb()); +} + +vocoder_ulaw_encode_sb::vocoder_ulaw_encode_sb() + : gr_sync_block("vocoder_ulaw_encode_sb", + gr_make_io_signature (1, 1, sizeof(short)), + gr_make_io_signature (1, 1, sizeof(unsigned char))) +{ +} + +vocoder_ulaw_encode_sb::~vocoder_ulaw_encode_sb() +{ +} + +int +vocoder_ulaw_encode_sb::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const short *in = (const short *)input_items[0]; + unsigned char *out = (unsigned char *)output_items[0]; + + for(int i = 0; i < noutput_items; i++) + out[i] = linear2ulaw(in[i]); + + return noutput_items; +} diff --git a/gr-gsm-fr-vocoder/src/python/.gitignore b/gr-vocoder/python/.gitignore index bf03975bb..bf03975bb 100644 --- a/gr-gsm-fr-vocoder/src/python/.gitignore +++ b/gr-vocoder/python/.gitignore diff --git a/gr-cvsd-vocoder/src/python/Makefile.am b/gr-vocoder/python/Makefile.am index e6fd74828..4b6146ca7 100644 --- a/gr-cvsd-vocoder/src/python/Makefile.am +++ b/gr-vocoder/python/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2009,2010 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,16 +21,22 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST += run_tests.in -DISTCLEANFILES += run_tests -TESTS = run_tests +vocoderdir = $(grpythondir)/vocoder +TESTS = run_tests -grblkspythondir = $(grpythondir)/blks2impl +noinst_PYTHON = \ + qa_alaw_vocoder.py \ + qa_codec2_vocoder.py \ + qa_cvsd_vocoder.py \ + qa_g721_vocoder.py \ + qa_g723_24_vocoder.py \ + qa_g723_40_vocoder.py \ + qa_gsm_full_rate.py \ + qa_ulaw_vocoder.py -grblkspython_PYTHON = \ +vocoder_PYTHON = \ + __init__.py \ cvsd.py -noinst_PYTHON = \ - encdec.py \ - qa_cvsd_vocoder.py +EXTRA_DIST += run_tests.in diff --git a/gr-gsm-fr-vocoder/src/Makefile.am b/gr-vocoder/python/__init__.py index be38b7c1a..eb5fa6fc1 100644 --- a/gr-gsm-fr-vocoder/src/Makefile.am +++ b/gr-vocoder/python/__init__.py @@ -1,5 +1,5 @@ # -# Copyright 2004 Free Software Foundation, Inc. +# Copyright 2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -19,7 +19,5 @@ # Boston, MA 02110-1301, USA. # -SUBDIRS = lib -if PYTHON -SUBDIRS += python -endif +from vocoder_swig import * +from cvsd import * diff --git a/gr-cvsd-vocoder/src/python/cvsd.py b/gr-vocoder/python/cvsd.py index 4defbf9a2..27b06ddeb 100644 --- a/gr-cvsd-vocoder/src/python/cvsd.py +++ b/gr-vocoder/python/cvsd.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2007 Free Software Foundation, Inc. +# Copyright 2007,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,9 +21,9 @@ # from gnuradio import gr -from gnuradio.vocoder import cvsd_vocoder +import vocoder_swig -class cvsd_encode(gr.hier_block2): +class cvsd_encode_fb(gr.hier_block2): ''' This is a wrapper for the CVSD encoder that performs interpolation and filtering necessary to work with the vocoding. It converts an incoming float (+-1) to a short, scales @@ -50,12 +50,12 @@ class cvsd_encode(gr.hier_block2): taps = gr.firdes.low_pass(self.interp, self.interp, bw, 2*bw) interp = gr.interp_fir_filter_fff(self.interp, taps) f2s = gr.float_to_short() - enc = cvsd_vocoder.encode_sb() + enc = vocoder_swig.cvsd_encode_sb() self.connect(self, src_scale, interp, f2s, enc, self) -class cvsd_decode(gr.hier_block2): +class cvsd_decode_bf(gr.hier_block2): ''' This is a wrapper for the CVSD decoder that performs decimation and filtering necessary to work with the vocoding. It converts an incoming CVSD-encoded short to a float, decodes it @@ -77,11 +77,10 @@ class cvsd_decode(gr.hier_block2): scale_factor = 32000.0 self.decim = resample - dec = cvsd_vocoder.decode_bs() + dec = vocoder_swig.cvsd_decode_bs() s2f = gr.short_to_float() taps = gr.firdes.low_pass(1, 1, bw, 2*bw) decim = gr.fir_filter_fff(self.decim, taps) sink_scale = gr.multiply_const_ff(1.0/scale_factor) self.connect(self, dec, s2f, decim, sink_scale, self) - diff --git a/gr-vocoder/python/qa_alaw_vocoder.py b/gr-vocoder/python/qa_alaw_vocoder.py new file mode 100755 index 000000000..b7b937138 --- /dev/null +++ b/gr-vocoder/python/qa_alaw_vocoder.py @@ -0,0 +1,39 @@ +#!/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 +from vocoder_swig import * + +class test_alaw_vocoder (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test001_module_load (self): + enc = alaw_encode_sb(); + dec = alaw_decode_bs(); + +if __name__ == '__main__': + gr_unittest.run(test_alaw_vocoder, "test_alaw_vocoder.xml") diff --git a/gr-vocoder/python/qa_codec2_vocoder.py b/gr-vocoder/python/qa_codec2_vocoder.py new file mode 100755 index 000000000..699bb7dda --- /dev/null +++ b/gr-vocoder/python/qa_codec2_vocoder.py @@ -0,0 +1,39 @@ +#!/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 +from vocoder_swig import * + +class test_codec2_vocoder (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test001_module_load (self): + raw_enc = codec2_encode_sp(); + raw_dec = codec2_decode_ps(); + +if __name__ == '__main__': + gr_unittest.run(test_codec2_vocoder, "test_codec2_vocoder.xml") diff --git a/gr-cvsd-vocoder/src/python/qa_cvsd_vocoder.py b/gr-vocoder/python/qa_cvsd_vocoder.py index 99a38d946..53045e4a9 100755 --- a/gr-cvsd-vocoder/src/python/qa_cvsd_vocoder.py +++ b/gr-vocoder/python/qa_cvsd_vocoder.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2007,2010 Free Software Foundation, Inc. +# Copyright 2007,2010,2011 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,17 +20,25 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gr_unittest, blks2 -import cvsd_vocoder +from gnuradio import gr, gr_unittest +from vocoder_swig import * +from cvsd import * class test_cvsd_vocoder (gr_unittest.TestCase): def setUp (self): self.tb = gr.top_block() - + def tearDown (self): self.tb = None + def test001_module_load (self): + raw_enc = cvsd_encode_sb(); + raw_dec = cvsd_decode_bs(); + hb_enc = cvsd_encode_fb(); + hb_dec = cvsd_decode_bf(); + + """ Disable for now def test01(self): sample_rate = 8000 diff --git a/gr-vocoder/python/qa_g721_vocoder.py b/gr-vocoder/python/qa_g721_vocoder.py new file mode 100755 index 000000000..79cc944f3 --- /dev/null +++ b/gr-vocoder/python/qa_g721_vocoder.py @@ -0,0 +1,39 @@ +#!/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 +from vocoder_swig import * + +class test_g721_vocoder (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test001_module_load (self): + enc = g721_encode_sb(); + dec = g721_decode_bs(); + +if __name__ == '__main__': + gr_unittest.run(test_g721_vocoder, "test_g721_vocoder.xml") diff --git a/gr-vocoder/python/qa_g723_24_vocoder.py b/gr-vocoder/python/qa_g723_24_vocoder.py new file mode 100755 index 000000000..ccf215f46 --- /dev/null +++ b/gr-vocoder/python/qa_g723_24_vocoder.py @@ -0,0 +1,39 @@ +#!/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 +from vocoder_swig import * + +class test_g723_24_vocoder (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test001_module_load (self): + enc = g723_24_encode_sb(); + dec = g723_24_decode_bs(); + +if __name__ == '__main__': + gr_unittest.run(test_g723_24_vocoder, "test_g723_24_vocoder.xml") diff --git a/gr-vocoder/python/qa_g723_40_vocoder.py b/gr-vocoder/python/qa_g723_40_vocoder.py new file mode 100755 index 000000000..9e6a52339 --- /dev/null +++ b/gr-vocoder/python/qa_g723_40_vocoder.py @@ -0,0 +1,39 @@ +#!/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 +from vocoder_swig import * + +class test_g723_40_vocoder (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test001_module_load (self): + enc = g723_40_encode_sb(); + dec = g723_40_decode_bs(); + +if __name__ == '__main__': + gr_unittest.run(test_g723_40_vocoder, "test_g723_40_vocoder.xml") diff --git a/gr-gsm-fr-vocoder/src/python/qa_gsm_full_rate.py b/gr-vocoder/python/qa_gsm_full_rate.py index 4164a1965..f9125905c 100755 --- a/gr-gsm-fr-vocoder/src/python/qa_gsm_full_rate.py +++ b/gr-vocoder/python/qa_gsm_full_rate.py @@ -21,7 +21,7 @@ # from gnuradio import gr, gr_unittest -import gsm_full_rate +import vocoder_swig class test_gsm_vocoder (gr_unittest.TestCase): @@ -31,5 +31,9 @@ class test_gsm_vocoder (gr_unittest.TestCase): def tearDown (self): self.tb = None + def test001_module_load (self): + enc = vocoder_swig.gsm_fr_encode_sp(); + dec = vocoder_swig.gsm_fr_decode_ps(); + if __name__ == '__main__': gr_unittest.run(test_gsm_vocoder, "test_gsm_vocoder.xml") diff --git a/gr-vocoder/python/qa_ulaw_vocoder.py b/gr-vocoder/python/qa_ulaw_vocoder.py new file mode 100755 index 000000000..0e201638c --- /dev/null +++ b/gr-vocoder/python/qa_ulaw_vocoder.py @@ -0,0 +1,39 @@ +#!/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 +from vocoder_swig import * + +class test_ulaw_vocoder (gr_unittest.TestCase): + + def setUp (self): + self.tb = gr.top_block() + + def tearDown (self): + self.tb = None + + def test001_module_load (self): + enc = ulaw_encode_sb(); + dec = ulaw_decode_bs(); + +if __name__ == '__main__': + gr_unittest.run(test_ulaw_vocoder, "test_ulaw_vocoder.xml") diff --git a/gr-cvsd-vocoder/src/python/run_tests.in b/gr-vocoder/python/run_tests.in index be969e287..e0c61a6b4 100644 --- a/gr-cvsd-vocoder/src/python/run_tests.in +++ b/gr-vocoder/python/run_tests.in @@ -5,6 +5,6 @@ # 3rd parameter is path to Python QA directory @top_builddir@/run_tests.sh \ - @abs_top_srcdir@/gr-cvsd-vocoder \ - @abs_top_builddir@/gr-cvsd-vocoder \ + @abs_top_srcdir@/gr-vocoder \ + @abs_top_builddir@/gr-vocoder \ @srcdir@ diff --git a/gr-vocoder/swig/.gitignore b/gr-vocoder/swig/.gitignore new file mode 100644 index 000000000..b336cc7ce --- /dev/null +++ b/gr-vocoder/swig/.gitignore @@ -0,0 +1,2 @@ +/Makefile +/Makefile.in diff --git a/gr-vocoder/swig/Makefile.am b/gr-vocoder/swig/Makefile.am new file mode 100644 index 000000000..500d72ec7 --- /dev/null +++ b/gr-vocoder/swig/Makefile.am @@ -0,0 +1,82 @@ +# +# 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 $(top_srcdir)/Makefile.common +include $(top_srcdir)/Makefile.swig + +TESTS = +EXTRA_DIST += $(nobase_guile_DATA) + +AM_CPPFLAGS = \ + -I$(abs_top_srcdir)/gr-vocoder/include \ + $(STD_DEFINES_AND_INCLUDES) \ + $(PYTHON_CPPFLAGS) \ + $(WITH_INCLUDES) + +if GUILE +nobase_guile_DATA = \ + gnuradio/vocoder_swig.scm +endif + +noinst_GUILE = vocoder.test + + +############################## +# SWIG interface and library +TOP_SWIG_IFILES = \ + vocoder_swig.i + +# Install so that they end up available as: +# import gnuradio.vocoder +# This ends up at: +# ${prefix}/lib/python${python_version}/site-packages/gnuradio/vocoder +vocoder_swig_pythondir_category = \ + gnuradio/vocoder + +# additional libraries for linking with the SWIG-generated library +vocoder_swig_la_swig_libadd = \ + $(abs_top_builddir)/gr-vocoder/lib/libgnuradio-vocoder.la + +# additional SWIG files to be installed +vocoder_swig_swiginclude_headers = \ + vocoder_alaw_decode_bs.i \ + vocoder_alaw_encode_sb.i \ + vocoder_codec2_decode_ps.i \ + vocoder_codec2_encode_sp.i \ + vocoder_cvsd_decode_bs.i \ + vocoder_cvsd_encode_sb.i \ + vocoder_g721_decode_bs.i \ + vocoder_g721_encode_sb.i \ + vocoder_g723_24_decode_bs.i \ + vocoder_g723_24_encode_sb.i \ + vocoder_g723_40_decode_bs.i \ + vocoder_g723_40_encode_sb.i \ + vocoder_gsm_fr_encode_sp.i \ + vocoder_gsm_fr_decode_ps.i \ + vocoder_ulaw_decode_bs.i \ + vocoder_ulaw_encode_sb.i + +vocoder_swig_swig_args = \ + -I$(abs_top_builddir)/gr-vocoder/lib + +if GUILE +TESTS += run_guile_tests +endif diff --git a/gr-cvsd-vocoder/src/lib/Makefile.swig.gen b/gr-vocoder/swig/Makefile.swig.gen index 8e22f0a98..b0d0504a8 100644 --- a/gr-cvsd-vocoder/src/lib/Makefile.swig.gen +++ b/gr-vocoder/swig/Makefile.swig.gen @@ -20,37 +20,37 @@ # Boston, MA 02110-1301, USA. # -# Makefile.swig.gen for cvsd_vocoder.i +# Makefile.swig.gen for vocoder_swig.i ## Default install locations for these files: ## ## Default location for the Python directory is: -## ${prefix}/lib/python${python_version}/site-packages/[category]/cvsd_vocoder +## ${prefix}/lib/python${python_version}/site-packages/[category]/vocoder_swig ## Default location for the Python exec directory is: -## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/cvsd_vocoder +## ${exec_prefix}/lib/python${python_version}/site-packages/[category]/vocoder_swig ## ## 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. -cvsd_vocoder_pythondir_category ?= gnuradio/cvsd_vocoder -cvsd_vocoder_pylibdir_category ?= $(cvsd_vocoder_pythondir_category) -cvsd_vocoder_pythondir = $(pythondir)/$(cvsd_vocoder_pythondir_category) -cvsd_vocoder_pylibdir = $(pyexecdir)/$(cvsd_vocoder_pylibdir_category) +vocoder_swig_pythondir_category ?= gnuradio/vocoder_swig +vocoder_swig_pylibdir_category ?= $(vocoder_swig_pythondir_category) +vocoder_swig_pythondir = $(pythondir)/$(vocoder_swig_pythondir_category) +vocoder_swig_pylibdir = $(pyexecdir)/$(vocoder_swig_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. -cvsd_vocoder_scmlibdir = $(libdir) +vocoder_swig_scmlibdir = $(libdir) # The scm files for the guile modules get installed where ever guile -# is installed, usually /usr/share/guile/site/cvsd_vocoder +# is installed, usually /usr/share/guile/site/vocoder_swig # FIXME: determince whether these should be installed with gnuradio. -cvsd_vocoder_scmdir = $(guiledir) +vocoder_swig_scmdir = $(guiledir) ## SWIG headers are always installed into the same directory. -cvsd_vocoder_swigincludedir = $(swigincludedir) +vocoder_swig_swigincludedir = $(swigincludedir) ## This is a template file for a "generated" Makefile addition (in ## this case, "Makefile.swig.gen"). By including the top-level @@ -75,70 +75,70 @@ MOSTLYCLEANFILES += $(DEPDIR)/*.S* ## Makefile.am by setting the variable value there, then including ## Makefile.swig . -cvsd_vocoder_swiginclude_HEADERS = \ - cvsd_vocoder.i \ - $(cvsd_vocoder_swiginclude_headers) +vocoder_swig_swiginclude_HEADERS = \ + vocoder_swig.i \ + $(vocoder_swig_swiginclude_headers) if PYTHON -cvsd_vocoder_pylib_LTLIBRARIES = \ - _cvsd_vocoder.la +vocoder_swig_pylib_LTLIBRARIES = \ + _vocoder_swig.la -_cvsd_vocoder_la_SOURCES = \ - python/cvsd_vocoder.cc \ - $(cvsd_vocoder_la_swig_sources) +_vocoder_swig_la_SOURCES = \ + python/vocoder_swig.cc \ + $(vocoder_swig_la_swig_sources) -cvsd_vocoder_python_PYTHON = \ - cvsd_vocoder.py \ - $(cvsd_vocoder_python) +vocoder_swig_python_PYTHON = \ + vocoder_swig.py \ + $(vocoder_swig_python) -_cvsd_vocoder_la_LIBADD = \ +_vocoder_swig_la_LIBADD = \ $(STD_SWIG_LA_LIB_ADD) \ - $(cvsd_vocoder_la_swig_libadd) + $(vocoder_swig_la_swig_libadd) -_cvsd_vocoder_la_LDFLAGS = \ +_vocoder_swig_la_LDFLAGS = \ $(STD_SWIG_LA_LD_FLAGS) \ - $(cvsd_vocoder_la_swig_ldflags) + $(vocoder_swig_la_swig_ldflags) -_cvsd_vocoder_la_CXXFLAGS = \ +_vocoder_swig_la_CXXFLAGS = \ $(STD_SWIG_CXX_FLAGS) \ -I$(top_builddir) \ - $(cvsd_vocoder_la_swig_cxxflags) + $(vocoder_swig_la_swig_cxxflags) -python/cvsd_vocoder.cc: cvsd_vocoder.py -cvsd_vocoder.py: cvsd_vocoder.i +python/vocoder_swig.cc: vocoder_swig.py +vocoder_swig.py: vocoder_swig.i # Include the python dependencies for this file --include python/cvsd_vocoder.d +-include python/vocoder_swig.d endif # end of if python if GUILE -cvsd_vocoder_scmlib_LTLIBRARIES = \ - libguile-gnuradio-cvsd_vocoder.la -libguile_gnuradio_cvsd_vocoder_la_SOURCES = \ - guile/cvsd_vocoder.cc \ - $(cvsd_vocoder_la_swig_sources) -nobase_cvsd_vocoder_scm_DATA = \ - gnuradio/cvsd_vocoder.scm \ - gnuradio/cvsd_vocoder-primitive.scm -libguile_gnuradio_cvsd_vocoder_la_LIBADD = \ +vocoder_swig_scmlib_LTLIBRARIES = \ + libguile-gnuradio-vocoder_swig.la +libguile_gnuradio_vocoder_swig_la_SOURCES = \ + guile/vocoder_swig.cc \ + $(vocoder_swig_la_swig_sources) +nobase_vocoder_swig_scm_DATA = \ + gnuradio/vocoder_swig.scm \ + gnuradio/vocoder_swig-primitive.scm +libguile_gnuradio_vocoder_swig_la_LIBADD = \ $(STD_SWIG_LA_LIB_ADD) \ - $(cvsd_vocoder_la_swig_libadd) -libguile_gnuradio_cvsd_vocoder_la_LDFLAGS = \ + $(vocoder_swig_la_swig_libadd) +libguile_gnuradio_vocoder_swig_la_LDFLAGS = \ $(STD_SWIG_LA_LD_FLAGS) \ - $(cvsd_vocoder_la_swig_ldflags) -libguile_gnuradio_cvsd_vocoder_la_CXXFLAGS = \ + $(vocoder_swig_la_swig_ldflags) +libguile_gnuradio_vocoder_swig_la_CXXFLAGS = \ $(STD_SWIG_CXX_FLAGS) \ -I$(top_builddir) \ - $(cvsd_vocoder_la_swig_cxxflags) + $(vocoder_swig_la_swig_cxxflags) -guile/cvsd_vocoder.cc: gnuradio/cvsd_vocoder.scm -gnuradio/cvsd_vocoder.scm: cvsd_vocoder.i -gnuradio/cvsd_vocoder-primitive.scm: gnuradio/cvsd_vocoder.scm +guile/vocoder_swig.cc: gnuradio/vocoder_swig.scm +gnuradio/vocoder_swig.scm: vocoder_swig.i +gnuradio/vocoder_swig-primitive.scm: gnuradio/vocoder_swig.scm # Include the guile dependencies for this file --include guile/cvsd_vocoder.d +-include guile/vocoder_swig.d endif # end of GUILE diff --git a/gr-vocoder/swig/run_guile_tests.in b/gr-vocoder/swig/run_guile_tests.in new file mode 100644 index 000000000..5d08b0dd5 --- /dev/null +++ b/gr-vocoder/swig/run_guile_tests.in @@ -0,0 +1,14 @@ +#!/bin/sh + +. @top_builddir@/setup_guile_test_env + +# 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 \ + @srcdir@ \ + @abs_builddir@ \ + @abs_builddir@ + +@GUILE@ -e main -c '(use-modules (gnuradio test-suite guile-test))' -t @srcdir@ diff --git a/gr-vocoder/swig/vocoder_alaw_decode_bs.i b/gr-vocoder/swig/vocoder_alaw_decode_bs.i new file mode 100644 index 000000000..f789c454f --- /dev/null +++ b/gr-vocoder/swig/vocoder_alaw_decode_bs.i @@ -0,0 +1,35 @@ +/* -*- 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 "vocoder_alaw_decode_bs.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,alaw_decode_bs); + +vocoder_alaw_decode_bs_sptr vocoder_make_alaw_decode_bs(); + +class vocoder_alaw_decode_bs : public gr_sync_block +{ +private: + vocoder_alaw_decode_bs(); +}; diff --git a/gr-vocoder/swig/vocoder_alaw_encode_sb.i b/gr-vocoder/swig/vocoder_alaw_encode_sb.i new file mode 100644 index 000000000..9fe537d55 --- /dev/null +++ b/gr-vocoder/swig/vocoder_alaw_encode_sb.i @@ -0,0 +1,35 @@ +/* -*- 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 "vocoder_alaw_encode_sb.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,alaw_encode_sb); + +vocoder_alaw_encode_sb_sptr vocoder_make_alaw_encode_sb(); + +class vocoder_alaw_encode_sb : public gr_sync_block +{ +private: + vocoder_alaw_encode_sb(); +}; diff --git a/gr-vocoder/swig/vocoder_codec2_decode_ps.i b/gr-vocoder/swig/vocoder_codec2_decode_ps.i new file mode 100644 index 000000000..e53cb078a --- /dev/null +++ b/gr-vocoder/swig/vocoder_codec2_decode_ps.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. + */ + +%{ +#include "vocoder_codec2_decode_ps.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,codec2_decode_ps); + +vocoder_codec2_decode_ps_sptr vocoder_make_codec2_decode_ps (); + +class vocoder_codec2_decode_ps : public gr_sync_interpolator { +public: + ~vocoder_codec2_decode_ps (); +}; diff --git a/gr-vocoder/swig/vocoder_codec2_encode_sp.i b/gr-vocoder/swig/vocoder_codec2_encode_sp.i new file mode 100644 index 000000000..84f26954d --- /dev/null +++ b/gr-vocoder/swig/vocoder_codec2_encode_sp.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. + */ + +%{ +#include "vocoder_codec2_encode_sp.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,codec2_encode_sp); + +vocoder_codec2_encode_sp_sptr vocoder_make_codec2_encode_sp (); + +class vocoder_codec2_encode_sp : public gr_sync_decimator { +public: + ~vocoder_codec2_encode_sp (); +}; diff --git a/gr-vocoder/swig/vocoder_cvsd_decode_bs.i b/gr-vocoder/swig/vocoder_cvsd_decode_bs.i new file mode 100644 index 000000000..e990f5440 --- /dev/null +++ b/gr-vocoder/swig/vocoder_cvsd_decode_bs.i @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +%{ +#include "vocoder_cvsd_decode_bs.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,cvsd_decode_bs); + +vocoder_cvsd_decode_bs_sptr vocoder_make_cvsd_decode_bs (short min_step=10, + short max_step=1280, + double step_decay=0.9990234375, + double accum_decay= 0.96875, + int K=32, + int J=4, + short pos_accum_max=32767, + short neg_accum_max=-32767); + +class vocoder_cvsd_decode_bs : public gr_sync_interpolator +{ +private: + vocoder_cvsd_decode_bs (short min_step, short max_step, double step_decay, + double accum_decay, int K, int J, + short pos_accum_max, short neg_accum_max); +}; diff --git a/gr-vocoder/swig/vocoder_cvsd_encode_sb.i b/gr-vocoder/swig/vocoder_cvsd_encode_sb.i new file mode 100644 index 000000000..5db7b3a48 --- /dev/null +++ b/gr-vocoder/swig/vocoder_cvsd_encode_sb.i @@ -0,0 +1,44 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,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 GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +%{ +#include "vocoder_cvsd_encode_sb.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,cvsd_encode_sb); + +vocoder_cvsd_encode_sb_sptr vocoder_make_cvsd_encode_sb (short min_step=10, + short max_step=1280, + double step_decay=0.9990234375, + double accum_decay= 0.96875, + int K=32, + int J=4, + short pos_accum_max=32767, + short neg_accum_max=-32767); + +class vocoder_cvsd_encode_sb : public gr_sync_decimator +{ +private: + vocoder_cvsd_encode_sb (short min_step, short max_step, double step_decay, + double accum_decay, int K, int J, + short pos_accum_max, short neg_accum_max); +}; diff --git a/gr-vocoder/swig/vocoder_g721_decode_bs.i b/gr-vocoder/swig/vocoder_g721_decode_bs.i new file mode 100644 index 000000000..47e7d2861 --- /dev/null +++ b/gr-vocoder/swig/vocoder_g721_decode_bs.i @@ -0,0 +1,33 @@ +/* -*- 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 "vocoder_g721_decode_bs.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,g721_decode_bs); + +vocoder_g721_decode_bs_sptr vocoder_make_g721_decode_bs(); + +class vocoder_g721_decode_bs : public gr_sync_block +{ +}; diff --git a/gr-vocoder/swig/vocoder_g721_encode_sb.i b/gr-vocoder/swig/vocoder_g721_encode_sb.i new file mode 100644 index 000000000..0675087a0 --- /dev/null +++ b/gr-vocoder/swig/vocoder_g721_encode_sb.i @@ -0,0 +1,33 @@ +/* -*- 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 "vocoder_g721_encode_sb.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,g721_encode_sb); + +vocoder_g721_encode_sb_sptr vocoder_make_g721_encode_sb(); + +class vocoder_g721_encode_sb : public gr_sync_block +{ +}; diff --git a/gr-vocoder/swig/vocoder_g723_24_decode_bs.i b/gr-vocoder/swig/vocoder_g723_24_decode_bs.i new file mode 100644 index 000000000..41548059f --- /dev/null +++ b/gr-vocoder/swig/vocoder_g723_24_decode_bs.i @@ -0,0 +1,33 @@ +/* -*- 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 "vocoder_g723_24_decode_bs.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,g723_24_decode_bs); + +vocoder_g723_24_decode_bs_sptr vocoder_make_g723_24_decode_bs(); + +class vocoder_g723_24_decode_bs : public gr_sync_block +{ +}; diff --git a/gr-vocoder/swig/vocoder_g723_24_encode_sb.i b/gr-vocoder/swig/vocoder_g723_24_encode_sb.i new file mode 100644 index 000000000..7165a8a82 --- /dev/null +++ b/gr-vocoder/swig/vocoder_g723_24_encode_sb.i @@ -0,0 +1,33 @@ +/* -*- 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 "vocoder_g723_24_encode_sb.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,g723_24_encode_sb); + +vocoder_g723_24_encode_sb_sptr vocoder_make_g723_24_encode_sb(); + +class vocoder_g723_24_encode_sb : public gr_sync_block +{ +}; diff --git a/gr-vocoder/swig/vocoder_g723_40_decode_bs.i b/gr-vocoder/swig/vocoder_g723_40_decode_bs.i new file mode 100644 index 000000000..d9ec9d6c9 --- /dev/null +++ b/gr-vocoder/swig/vocoder_g723_40_decode_bs.i @@ -0,0 +1,33 @@ +/* -*- 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 "vocoder_g723_40_decode_bs.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,g723_40_decode_bs); + +vocoder_g723_40_decode_bs_sptr vocoder_make_g723_40_decode_bs(); + +class vocoder_g723_40_decode_bs : public gr_sync_block +{ +}; diff --git a/gr-vocoder/swig/vocoder_g723_40_encode_sb.i b/gr-vocoder/swig/vocoder_g723_40_encode_sb.i new file mode 100644 index 000000000..839ae46cf --- /dev/null +++ b/gr-vocoder/swig/vocoder_g723_40_encode_sb.i @@ -0,0 +1,33 @@ +/* -*- 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 "vocoder_g723_40_encode_sb.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,g723_40_encode_sb); + +vocoder_g723_40_encode_sb_sptr vocoder_make_g723_40_encode_sb(); + +class vocoder_g723_40_encode_sb : public gr_sync_block +{ +}; diff --git a/gr-vocoder/swig/vocoder_gsm_fr_decode_ps.i b/gr-vocoder/swig/vocoder_gsm_fr_decode_ps.i new file mode 100644 index 000000000..8e96689f6 --- /dev/null +++ b/gr-vocoder/swig/vocoder_gsm_fr_decode_ps.i @@ -0,0 +1,35 @@ +/* -*- 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 "vocoder_gsm_fr_decode_ps.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,gsm_fr_decode_ps); + +vocoder_gsm_fr_decode_ps_sptr vocoder_make_gsm_fr_decode_ps(); + +class vocoder_gsm_fr_decode_ps : public gr_sync_interpolator +{ +public: + ~vocoder_gsm_fr_decode_ps(); +}; diff --git a/gr-vocoder/swig/vocoder_gsm_fr_encode_sp.i b/gr-vocoder/swig/vocoder_gsm_fr_encode_sp.i new file mode 100644 index 000000000..8216336a9 --- /dev/null +++ b/gr-vocoder/swig/vocoder_gsm_fr_encode_sp.i @@ -0,0 +1,35 @@ +/* -*- 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 "vocoder_gsm_fr_encode_sp.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,gsm_fr_encode_sp); + +vocoder_gsm_fr_encode_sp_sptr vocoder_make_gsm_fr_encode_sp(); + +class vocoder_gsm_fr_encode_sp : public gr_sync_decimator +{ +public: + ~vocoder_gsm_fr_encode_sp(); +}; diff --git a/gr-gsm-fr-vocoder/src/lib/gsm_full_rate.i b/gr-vocoder/swig/vocoder_swig.i index 20bf8fdea..71a2952dd 100644 --- a/gr-gsm-fr-vocoder/src/lib/gsm_full_rate.i +++ b/gr-vocoder/swig/vocoder_swig.i @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2005,2009 Free Software Foundation, Inc. + * Copyright 2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -22,34 +22,26 @@ %include "gnuradio.i" -%{ -#include "gsm_fr_encode_sp.h" -#include "gsm_fr_decode_ps.h" -%} - -GR_SWIG_BLOCK_MAGIC(gsm_fr,encode_sp); - -gsm_fr_encode_sp_sptr gsm_fr_make_encode_sp (); - -class gsm_fr_encode_sp : public gr_sync_decimator { -public: - ~gsm_fr_encode_sp (); -}; - -// ---------------------------------------------------------------- - -GR_SWIG_BLOCK_MAGIC(gsm_fr,decode_ps); - -gsm_fr_decode_ps_sptr gsm_fr_make_decode_ps (); - -class gsm_fr_decode_ps : public gr_sync_interpolator { -public: - ~gsm_fr_decode_ps (); -}; +%include "vocoder_alaw_decode_bs.i" +%include "vocoder_alaw_encode_sb.i" +%include "vocoder_codec2_decode_ps.i" +%include "vocoder_codec2_encode_sp.i" +%include "vocoder_cvsd_decode_bs.i" +%include "vocoder_cvsd_encode_sb.i" +%include "vocoder_g721_decode_bs.i" +%include "vocoder_g721_encode_sb.i" +%include "vocoder_g723_24_decode_bs.i" +%include "vocoder_g723_24_encode_sb.i" +%include "vocoder_g723_40_decode_bs.i" +%include "vocoder_g723_40_encode_sb.i" +%include "vocoder_gsm_fr_decode_ps.i" +%include "vocoder_gsm_fr_encode_sp.i" +%include "vocoder_ulaw_decode_bs.i" +%include "vocoder_ulaw_encode_sb.i" #if SWIGGUILE %scheme %{ -(load-extension-global "libguile-gnuradio-gsm_full_rate" "scm_init_gnuradio_gsm_full_rate_module") +(load-extension-global "libguile-gnuradio-vocoder" "scm_init_gnuradio_gsm_vocoder_module") %} %goops %{ diff --git a/gr-vocoder/swig/vocoder_ulaw_decode_bs.i b/gr-vocoder/swig/vocoder_ulaw_decode_bs.i new file mode 100644 index 000000000..5e8e8c9ae --- /dev/null +++ b/gr-vocoder/swig/vocoder_ulaw_decode_bs.i @@ -0,0 +1,35 @@ +/* -*- 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 "vocoder_ulaw_decode_bs.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,ulaw_decode_bs); + +vocoder_ulaw_decode_bs_sptr vocoder_make_ulaw_decode_bs(); + +class vocoder_ulaw_decode_bs : public gr_sync_block +{ +private: + vocoder_ulaw_decode_bs(); +}; diff --git a/gr-vocoder/swig/vocoder_ulaw_encode_sb.i b/gr-vocoder/swig/vocoder_ulaw_encode_sb.i new file mode 100644 index 000000000..1665df480 --- /dev/null +++ b/gr-vocoder/swig/vocoder_ulaw_encode_sb.i @@ -0,0 +1,35 @@ +/* -*- 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 "vocoder_ulaw_encode_sb.h" +%} + +GR_SWIG_BLOCK_MAGIC(vocoder,ulaw_encode_sb); + +vocoder_ulaw_encode_sb_sptr vocoder_make_ulaw_encode_sb(); + +class vocoder_ulaw_encode_sb : public gr_sync_block +{ +private: + vocoder_ulaw_encode_sb(); +}; diff --git a/grc/blocks/Makefile.am b/grc/blocks/Makefile.am index bed84adc8..9813154bd 100644 --- a/grc/blocks/Makefile.am +++ b/grc/blocks/Makefile.am @@ -80,6 +80,7 @@ dist_ourdata_DATA = \ gr_conjugate_cc.xml \ gr_copy.xml \ gr_cpfsk_bc.xml \ + gr_ctcss_squelch_ff.xml \ gr_dc_blocker.xml \ gr_cpmmod_bc.xml \ gr_decode_ccsds_27_fb.xml \ @@ -195,13 +196,6 @@ dist_ourdata_DATA = \ parameter.xml \ random_source_x.xml \ root_raised_cosine_filter.xml \ - trellis_encoder_xx.xml \ - trellis_metrics_x.xml \ - trellis_permutation.xml \ - trellis_siso_combined_f.xml \ - trellis_siso_f.xml \ - trellis_viterbi_combined_xx.xml \ - trellis_viterbi_x.xml \ variable.xml \ variable_config.xml \ variable_function_probe.xml \ diff --git a/grc/blocks/block_tree.xml b/grc/blocks/block_tree.xml index c729d4903..ea7d744d4 100644 --- a/grc/blocks/block_tree.xml +++ b/grc/blocks/block_tree.xml @@ -145,6 +145,7 @@ <block>gr_simple_squelch_cc</block> <block>blks2_standard_squelch</block> <block>gr_pwr_squelch_xx</block> + <block>gr_ctcss_squelch_ff</block> <block>gr_threshold_ff</block> </cat> <cat> @@ -222,13 +223,6 @@ <name>Error Correction</name> <cat> <name>Trellis</name> - <block>trellis_encoder_xx</block> - <block>trellis_metrics_x</block> - <block>trellis_permutation</block> - <block>trellis_siso_combined_f</block> - <block>trellis_siso_f</block> - <block>trellis_viterbi_combined_xx</block> - <block>trellis_viterbi_x</block> </cat> <block>gr_encode_ccsds_27_bb</block> diff --git a/grc/blocks/gr_ctcss_squelch_ff.xml b/grc/blocks/gr_ctcss_squelch_ff.xml new file mode 100644 index 000000000..a34c75374 --- /dev/null +++ b/grc/blocks/gr_ctcss_squelch_ff.xml @@ -0,0 +1,79 @@ +<?xml version="1.0"?> +<!-- +# +# 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. +--> + +<!-- +################################################### +##CTCSS Squelch +################################################### + --> +<block> + <name>CTCSS Squelch</name> + <key>gr_ctcss_squelch_ff</key> + <import>from gnuradio import gr</import> + <make>gr.ctcss_squelch_ff($rate, $freq, $level, $len, $ramp, $gate)</make> + <callback>set_level($level)</callback> + <param> + <name>Sampling Rate (Hz)</name> + <key>rate</key> + <value>samp_rate</value> + <type>real</type> + </param> + <param> + <name>Tone Frequency</name> + <key>freq</key> + <value>100.0</value> + <type>real</type> + </param> + <param> + <name>Level</name> + <key>level</key> + <value>0.01</value> + <type>real</type> + </param> + <param> + <name>Length</name> + <key>len</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Ramp</name> + <key>ramp</key> + <value>0</value> + <type>int</type> + </param> + <param> + <name>Gate</name> + <key>gate</key> + <value>False</value> + <type>bool</type> + </param> + <sink> + <name>in</name> + <type>float</type> + </sink> + <source> + <name>out</name> + <type>float</type> + </source> +</block> diff --git a/grc/python/Block.py b/grc/python/Block.py index 14a5859e4..424706d68 100644 --- a/grc/python/Block.py +++ b/grc/python/Block.py @@ -108,7 +108,7 @@ class Block(_Block, _GUIBlock): if nports == num_ports: continue #remove excess ports and connections if nports < num_ports: - for key in map(str, range(index_first+nports, index_first+num_ports)): + for key in reversed(map(str, range(index_first+nports, index_first+num_ports))): remove_port(get_ports, get_port, key) continue #add more ports diff --git a/usrp/firmware/include/usrp_ids.h b/usrp/firmware/include/usrp_ids.h index 46a069434..159151ea9 100644 --- a/usrp/firmware/include/usrp_ids.h +++ b/usrp/firmware/include/usrp_ids.h @@ -44,21 +44,31 @@ #define USB_PID_FSF_HPSDR_HA 0x0007 // High Performance Software Defined Radio (Host Assisted Boot) #define USB_PID_FSF_QS1R 0x0008 // QS1R HF receiver #define USB_PID_FSF_EZDOP 0x0009 // ezdop <jcorgan@aeinet.com> -#define USB_PID_FSF_BDALE_0 0x000a // Bdale Garbee <bdale@gag.com> -#define USB_PID_FSF_BDALE_1 0x000b // Bdale Garbee <bdale@gag.com> -#define USB_PID_FSF_BDALE_2 0x000c // Bdale Garbee <bdale@gag.com> -#define USB_PID_FSF_BDALE_3 0x000d // Bdale Garbee <bdale@gag.com> -#define USB_PID_FSF_BDALE_4 0x000e // Bdale Garbee <bdale@gag.com> -#define USB_PID_FSF_BDALE_5 0x000f // Bdale Garbee <bdale@gag.com> -#define USB_PID_FSF_BDALE_6 0x0010 // Bdale Garbee <bdale@gag.com> -#define USB_PID_FSF_BDALE_7 0x0011 // Bdale Garbee <bdale@gag.com> -#define USB_PID_FSF_BDALE_8 0x0012 // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_Development 0x000a // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_TeleMetrum 0x000b // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_TeleDongle 0x000c // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_TeleTerra 0x000d // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_TeleBT 0x000e // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_TeleLaunch 0x000f // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_TeleLCO 0x0010 // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_TeleScience 0x0011 // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_TelePyro 0x0012 // Bdale Garbee <bdale@gag.com> #define USB_PID_FSF_BDALE_9 0x0013 // Bdale Garbee <bdale@gag.com> #define USB_PID_FSF_HPSDR_HERMES 0x0014 // HPSDR Hermes #define USB_PID_FSF_THINKRF 0x0015 // Catalin Patulea <catalin.patulea@thinkrf.com> #define USB_PID_FSF_MSA 0x0016 // Hans de Bok <hdbok@dionaea.demon.nl> Scotty's Modular Spectrum Analyzer #define USB_PID_FSF_LBNL_UXO 0x0018 // http://recycle.lbl.gov/~ldoolitt/uxo/ +#define USB_PID_FSF_BDALE_10 0x0019 // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_11 0x001a // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_12 0x001b // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_13 0x001c // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_14 0x001d // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_15 0x001e // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_16 0x001f // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_17 0x0020 // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_18 0x0021 // Bdale Garbee <bdale@gag.com> +#define USB_PID_FSF_BDALE_19 0x0022 // Bdale Garbee <bdale@gag.com> #define USB_DID_USRP_0 0x0000 // unconfigured rev 0 USRP diff --git a/volk/bootstrap b/volk/bootstrap index a7fb78ac5..838f03aa2 100755 --- a/volk/bootstrap +++ b/volk/bootstrap @@ -20,7 +20,11 @@ # Boston, MA 02110-1301, USA. rm -fr config.cache autom4te*.cache -python -B gen/volk_register.py +#alternative to -B that wont break on python 2.5 +PYTHONDONTWRITEBYTECODE=1 +export PYTHONDONTWRITEBYTECODE +python gen/volk_register.py + mv gen/lib/Makefile.am lib/ aclocal -I config -I gen/config diff --git a/volk/gen/make_makefile_am.py b/volk/gen/make_makefile_am.py index d700626bb..f843b4413 100644 --- a/volk/gen/make_makefile_am.py +++ b/volk/gen/make_makefile_am.py @@ -77,9 +77,9 @@ noinst_LTLIBRARIES = if archflags_dict[arch] != "none": tempstring += "-" + archflags_dict[arch] + " " - tempstring += "\nnoinst_LTLIBRARIES += libvolk_" + machine_name + ".la " + tempstring += "\nnoinst_LTLIBRARIES += libvolk_" + machine_name + ".la " tempstring += "\nlibvolk_la_LIBADD += libvolk_" + machine_name + ".la\n" - tempstring += "libvolk_la_CPPFLAGS += -DLV_MACHINE_" + machine_name.swapcase() + " \n" + tempstring += "libvolk_la_CPPFLAGS += -DLV_MACHINE_" + machine_name.swapcase() + " \n" tempstring += "endif\n" |