diff options
Diffstat (limited to 'gnuradio-core')
34 files changed, 802 insertions, 1954 deletions
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/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am index 0314079a2..d8f634c38 100644 --- a/gnuradio-core/src/lib/filter/Makefile.am +++ b/gnuradio-core/src/lib/filter/Makefile.am @@ -188,6 +188,7 @@ EXTRA_DIST += \ # work around automake deficiency libfilter_la_common_SOURCES = \ $(GENERATED_CC) \ + gr_adaptive_fir_ccc.cc \ gr_adaptive_fir_ccf.cc \ gr_cma_equalizer_cc.cc \ gri_fft_filter_fff_generic.cc \ @@ -272,6 +273,7 @@ grinclude_HEADERS = \ ccomplex_dotprod_x86.h \ float_dotprod_generic.h \ float_dotprod_x86.h \ + gr_adaptive_fir_ccc.h \ gr_adaptive_fir_ccf.h \ gr_altivec.h \ gr_cma_equalizer_cc.h \ @@ -357,6 +359,7 @@ noinst_HEADERS = \ swiginclude_HEADERS = \ filter.i \ filter_generated.i \ + gr_adaptive_fir_ccc.i \ gr_adaptive_fir_ccf.i \ gr_cma_equalizer_cc.i \ gr_fft_filter_ccc.i \ diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc new file mode 100644 index 000000000..3fed74641 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.cc @@ -0,0 +1,88 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_adaptive_fir_ccc.h> +#include <gr_io_signature.h> + +gr_adaptive_fir_ccc::gr_adaptive_fir_ccc(const char *name, int decimation, + const std::vector<gr_complex> &taps) + : gr_sync_decimator (name, + gr_make_io_signature (1, 1, sizeof(gr_complex)), + gr_make_io_signature (1, 1, sizeof(gr_complex)), + decimation), + d_updated(false), d_taps(taps) +{ + set_history(d_taps.size()); +} + +void +gr_adaptive_fir_ccc::set_taps(const std::vector<gr_complex> &taps) +{ + d_new_taps = taps; + d_updated = true; +} + +gr_complex +gr_adaptive_fir_ccc::filter(gr_complex *x) +{ + // Generic dot product of d_taps[] and in[] + gr_complex acc(0.0, 0.0); + int l = d_taps.size(); + for (int k = 0; k < l; k++) + acc += d_taps[l-k-1] * x[k]; + return acc; +} + +int +gr_adaptive_fir_ccc::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + gr_complex *in = (gr_complex *)input_items[0]; + gr_complex *out = (gr_complex *)output_items[0]; + + if (d_updated) { + d_taps = d_new_taps; + set_history(d_taps.size()); + d_updated = false; + return 0; // history requirements may have changed. + } + + int j = 0, k, l = d_taps.size(); + for (int i = 0; i < noutput_items; i++) { + out[i] = filter(&in[j]); + + // Adjust taps + d_error = error(out[i]); + for (k = 0; k < l; k++) { + update_tap(d_taps[l-k-1], in[j+k]); + } + + j += decimation(); + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.h b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.h new file mode 100644 index 000000000..8678255b7 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.h @@ -0,0 +1,61 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_ADAPTIVE_FIR_CCC_H +#define INCLUDED_GR_ADAPTIVE_FIR_CCC_H + +#include <gr_sync_decimator.h> + +/*! + * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps + * \ingroup filter_blk + */ +class gr_adaptive_fir_ccc : public gr_sync_decimator +{ +private: + std::vector<gr_complex> d_new_taps; + bool d_updated; + +protected: + gr_complex d_error; + std::vector<gr_complex> d_taps; + + // Override to calculate error signal per output + virtual gr_complex error(const gr_complex &out) = 0; + + // Override to calculate new weight from old, corresponding input + virtual void update_tap(gr_complex &tap, const gr_complex &in) = 0; + + gr_complex filter(gr_complex *x); + + gr_adaptive_fir_ccc(const char *name, int decimation, + const std::vector<gr_complex> &taps); + +public: + void set_taps(const std::vector<gr_complex> &taps); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.i b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.i new file mode 100644 index 000000000..7e9a3fac3 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_adaptive_fir_ccc.i @@ -0,0 +1,31 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +class gr_adaptive_fir_ccc : public gr_sync_decimator +{ +protected: + gr_adaptive_fir_ccc(char *name, int decimation, + const std::vector<gr_complex> &taps); + +public: + void set_taps(const std::vector<gr_complex> &taps); +}; diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc index 937899c0d..a52d1d901 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.cc @@ -37,12 +37,14 @@ gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain, const std::vector<float> &taps, unsigned int filter_size, float init_phase, - float max_rate_deviation) + float max_rate_deviation, + int osps) { return gnuradio::get_initial_sptr(new gr_pfb_clock_sync_ccf (sps, gain, taps, - filter_size, - init_phase, - max_rate_deviation)); + filter_size, + init_phase, + max_rate_deviation, + osps)); } static int ios[] = {sizeof(gr_complex), sizeof(float), sizeof(float), sizeof(float)}; @@ -51,12 +53,14 @@ gr_pfb_clock_sync_ccf::gr_pfb_clock_sync_ccf (double sps, float gain, const std::vector<float> &taps, unsigned int filter_size, float init_phase, - float max_rate_deviation) + float max_rate_deviation, + int osps) : gr_block ("pfb_clock_sync_ccf", gr_make_io_signature (1, 1, sizeof(gr_complex)), gr_make_io_signaturev (1, 4, iosig)), d_updated (false), d_nfilters(filter_size), - d_max_dev(max_rate_deviation) + d_max_dev(max_rate_deviation), + d_osps(osps) { d_nfilters = filter_size; d_sps = floor(sps); @@ -239,13 +243,13 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, } // We need this many to process one output - int nrequired = ninput_items[0] - d_taps_per_filter; + int nrequired = ninput_items[0] - d_taps_per_filter - d_osps; int i = 0, count = 0; float error, error_r, error_i; // produce output as long as we can and there are enough input samples - while((i < noutput_items) && (count < nrequired)) { + while((i < noutput_items-d_osps) && (count < nrequired)) { d_filtnum = (int)floor(d_k); // Keep the current filter number in [0, d_nfilters] @@ -262,7 +266,10 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, count -= 1; } - out[i] = d_filters[d_filtnum]->filter(&in[count]); + for(int k = 0; k < d_osps; k++) { + out[i+k] = d_filters[d_filtnum]->filter(&in[count+k]); + } + gr_complex diff = d_diff_filters[d_filtnum]->filter(&in[count]); error_r = out[i].real() * diff.real(); error_i = out[i].imag() * diff.imag(); @@ -275,14 +282,17 @@ gr_pfb_clock_sync_ccf::general_work (int noutput_items, // Keep our rate within a good range d_rate_f = gr_branchless_clip(d_rate_f, d_max_dev); - i++; - count += (int)floor(d_sps); - if(output_items.size() == 4) { - err[i] = error; - outrate[i] = d_rate_f; - outk[i] = d_k; + // FIXME: don't really know what to do about d_osps>1 + for(int k = 0; k < d_osps; k++) { + err[i] = error; + outrate[i] = d_rate_f; + outk[i] = d_k; + } } + + i+=d_osps; + count += (int)floor(d_sps); } consume_each(count); diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.h index 684ac85ce..f4f24fec6 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 @@ -32,7 +32,8 @@ gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain, const std::vector<float> &taps, unsigned int filter_size=32, float init_phase=0, - float max_rate_deviation=1.5); + float max_rate_deviation=1.5, + int osps=1); class gr_fir_ccf; @@ -47,7 +48,7 @@ class gr_fir_ccf; * derivative of the filtered signal, which in turn maximizes the SNR and * minimizes ISI. * - * This approach works by setting up two filterbanks; one filterbanke contains the + * This approach works by setting up two filterbanks; one filterbank contains the * signal's pulse shaping matched filter (such as a root raised cosine filter), * where each branch of the filterbank contains a different phase of the filter. * The second filterbank contains the derivatives of the filters in the first @@ -85,7 +86,7 @@ class gr_fir_ccf; * equal to (gain^2)/4. * * The clock sync block needs to know the number of samples per symbol (sps), because it - * only returns a single point representing the sample. The sps can be any positive real + * only returns a single point representing the symbol. The sps can be any positive real * number and does not need to be an integer. The filter taps must also be specified. The * taps are generated by first conceiving of the prototype filter that would be the signal's * matched filter. Then interpolate this by the number of filters in the filterbank. These @@ -122,13 +123,15 @@ 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 gain, const std::vector<float> &taps, unsigned int filter_size, float init_phase, - float max_rate_deviation); + float max_rate_deviation, + int osps); bool d_updated; double d_sps; @@ -147,6 +150,7 @@ class gr_pfb_clock_sync_ccf : public gr_block float d_max_dev; int d_filtnum; int d_taps_per_filter; + int d_osps; /*! * Build the polyphase filterbank timing synchronizer. @@ -155,7 +159,8 @@ class gr_pfb_clock_sync_ccf : public gr_block const std::vector<float> &taps, unsigned int filter_size, float init_phase, - float max_rate_deviation); + float max_rate_deviation, + int osps); void create_diff_taps(const std::vector<float> &newtaps, std::vector<float> &difftaps); diff --git a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i index 197984287..343ed0912 100644 --- a/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i +++ b/gnuradio-core/src/lib/filter/gr_pfb_clock_sync_ccf.i @@ -26,7 +26,8 @@ gr_pfb_clock_sync_ccf_sptr gr_make_pfb_clock_sync_ccf (double sps, float gain, const std::vector<float> &taps, unsigned int filter_size=32, float init_phase=0, - float max_rate_deviation=1.5); + float max_rate_deviation=1.5, + int osps=1); class gr_pfb_clock_sync_ccf : public gr_block { @@ -35,7 +36,8 @@ class gr_pfb_clock_sync_ccf : public gr_block const std::vector<float> &taps, unsigned int filter_size, float init_phase, - float max_rate_deviation); + float max_rate_deviation, + int osps); public: ~gr_pfb_clock_sync_ccf (); diff --git a/gnuradio-core/src/lib/g72x/.gitignore b/gnuradio-core/src/lib/g72x/.gitignore deleted file mode 100644 index a02b6ff73..000000000 --- a/gnuradio-core/src/lib/g72x/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -/Makefile -/Makefile.in -/.la -/.lo -/.deps -/.libs -/*.la -/*.lo diff --git a/gnuradio-core/src/lib/g72x/Makefile.am b/gnuradio-core/src/lib/g72x/Makefile.am deleted file mode 100644 index d2700376f..000000000 --- a/gnuradio-core/src/lib/g72x/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -# -# Copyright 2001 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 - -noinst_LTLIBRARIES = libccitt.la -libccitt_la_SOURCES = g711.c g72x.c g721.c g723_24.c g723_40.c g72x.h - -EXTRA_DIST += encode.c decode.c diff --git a/gnuradio-core/src/lib/g72x/README b/gnuradio-core/src/lib/g72x/README deleted file mode 100644 index 23b0e7dd5..000000000 --- a/gnuradio-core/src/lib/g72x/README +++ /dev/null @@ -1,94 +0,0 @@ -The files in this directory comprise ANSI-C language reference implementations -of the CCITT (International Telegraph and Telephone Consultative Committee) -G.711, G.721 and G.723 voice compressions. They have been tested on Sun -SPARCstations and passed 82 out of 84 test vectors published by CCITT -(Dec. 20, 1988) for G.721 and G.723. [The two remaining test vectors, -which the G.721 decoder implementation for u-law samples did not pass, -may be in error because they are identical to two other vectors for G.723_40.] - -This source code is released by Sun Microsystems, Inc. to the public domain. -Please give your acknowledgement in product literature if this code is used -in your product implementation. - -Sun Microsystems supports some CCITT audio formats in Solaris 2.0 system -software. However, Sun's implementations have been optimized for higher -performance on SPARCstations. - - -The source files for CCITT conversion routines in this directory are: - - g72x.h header file for g721.c, g723_24.c and g723_40.c - g711.c CCITT G.711 u-law and A-law compression - g72x.c common denominator of G.721 and G.723 ADPCM codes - g721.c CCITT G.721 32Kbps ADPCM coder (with g72x.c) - g723_24.c CCITT G.723 24Kbps ADPCM coder (with g72x.c) - g723_40.c CCITT G.723 40Kbps ADPCM coder (with g72x.c) - - -Simple conversions between u-law, A-law, and 16-bit linear PCM are invoked -as follows: - - unsigned char ucode, acode; - short pcm_val; - - ucode = linear2ulaw(pcm_val); - ucode = alaw2ulaw(acode); - - acode = linear2alaw(pcm_val); - acode = ulaw2alaw(ucode); - - pcm_val = ulaw2linear(ucode); - pcm_val = alaw2linear(acode); - - -The other CCITT compression routines are invoked as follows: - - #include "g72x.h" - - struct g72x_state state; - int sample, code; - - g72x_init_state(&state); - code = {g721,g723_24,g723_40}_encoder(sample, coding, &state); - sample = {g721,g723_24,g723_40}_decoder(code, coding, &state); - -where - coding = AUDIO_ENCODING_ULAW for 8-bit u-law samples - AUDIO_ENCODING_ALAW for 8-bit A-law samples - AUDIO_ENCODING_LINEAR for 16-bit linear PCM samples - - - -This directory also includes the following sample programs: - - encode.c CCITT ADPCM encoder - decode.c CCITT ADPCM decoder - Makefile makefile for the sample programs - - -The sample programs contain examples of how to call the various compression -routines and pack/unpack the bits. The sample programs read byte streams from -stdin and write to stdout. The input/output data is raw data (no file header -or other identifying information is embedded). The sample programs are -invoked as follows: - - encode [-3|4|5] [-a|u|l] <infile >outfile - decode [-3|4|5] [-a|u|l] <infile >outfile -where: - -3 encode to (decode from) G.723 24kbps (3-bit) data - -4 encode to (decode from) G.721 32kbps (4-bit) data [the default] - -5 encode to (decode from) G.723 40kbps (5-bit) data - -a encode from (decode to) A-law data - -u encode from (decode to) u-law data [the default] - -l encode from (decode to) 16-bit linear data - -Examples: - # Read 16-bit linear and output G.721 - encode -4 -l <pcmfile >g721file - - # Read 40Kbps G.723 and output A-law - decode -5 -a <g723file >alawfile - - # Compress and then decompress u-law data using 24Kbps G.723 - encode -3 <ulawin | deoced -3 >ulawout - diff --git a/gnuradio-core/src/lib/g72x/decode.c b/gnuradio-core/src/lib/g72x/decode.c deleted file mode 100644 index cf8c739c5..000000000 --- a/gnuradio-core/src/lib/g72x/decode.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * decode.c - * - * CCITT ADPCM decoder - * - * Usage : decode [-3|4|5] [-a|u|l] < infile > outfile - */ -#include <stdio.h> -#include "g72x.h" - - -/* - * Unpack input codes and pass them back as bytes. - * Returns 1 if there is residual input, returns -1 if eof, else returns 0. - */ -int -unpack_input( - unsigned char *code, - int bits) -{ - static unsigned int in_buffer = 0; - static int in_bits = 0; - unsigned char in_byte; - - if (in_bits < bits) { - if (fread(&in_byte, sizeof (char), 1, stdin) != 1) { - *code = 0; - return (-1); - } - in_buffer |= (in_byte << in_bits); - in_bits += 8; - } - *code = in_buffer & ((1 << bits) - 1); - in_buffer >>= bits; - in_bits -= bits; - return (in_bits > 0); -} - - -main( - int argc, - char **argv) -{ - short sample; - unsigned char code; - int n; - struct g72x_state state; - int out_coding; - int out_size; - int (*dec_routine)(); - int dec_bits; - - g72x_init_state(&state); - out_coding = AUDIO_ENCODING_ULAW; - out_size = sizeof (char); - dec_routine = g721_decoder; - dec_bits = 4; - - /* Process encoding argument, if any */ - while ((argc > 1) && (argv[1][0] == '-')) { - switch (argv[1][1]) { - case '3': - dec_routine = g723_24_decoder; - dec_bits = 3; - break; - case '4': - dec_routine = g721_decoder; - dec_bits = 4; - break; - case '5': - dec_routine = g723_40_decoder; - dec_bits = 5; - break; - case 'u': - out_coding = AUDIO_ENCODING_ULAW; - out_size = sizeof (char); - break; - case 'a': - out_coding = AUDIO_ENCODING_ALAW; - out_size = sizeof (char); - break; - case 'l': - out_coding = AUDIO_ENCODING_LINEAR; - out_size = sizeof (short); - break; - default: -fprintf(stderr, "CCITT ADPCM Decoder -- usage:\n"); -fprintf(stderr, "\tdecode [-3|4|5] [-a|u|l] < infile > outfile\n"); -fprintf(stderr, "where:\n"); -fprintf(stderr, "\t-3\tProcess G.723 24kbps (3-bit) input data\n"); -fprintf(stderr, "\t-4\tProcess G.721 32kbps (4-bit) input data [default]\n"); -fprintf(stderr, "\t-5\tProcess G.723 40kbps (5-bit) input data\n"); -fprintf(stderr, "\t-a\tGenerate 8-bit A-law data\n"); -fprintf(stderr, "\t-u\tGenerate 8-bit u-law data [default]\n"); -fprintf(stderr, "\t-l\tGenerate 16-bit linear PCM data\n"); - exit(1); - } - argc--; - argv++; - } - - /* Read and unpack input codes and process them */ - while (unpack_input(&code, dec_bits) >= 0) { - sample = (*dec_routine)(code, out_coding, &state); - if (out_size == 2) { - fwrite(&sample, out_size, 1, stdout); - } else { - code = (unsigned char)sample; - fwrite(&code, out_size, 1, stdout); - } - } - fclose(stdout); -} diff --git a/gnuradio-core/src/lib/g72x/encode.c b/gnuradio-core/src/lib/g72x/encode.c deleted file mode 100644 index e74482869..000000000 --- a/gnuradio-core/src/lib/g72x/encode.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * encode.c - * - * CCITT ADPCM encoder - * - * Usage : encode [-3|4|5] [-a|u|l] < infile > outfile - */ -#include <stdio.h> -#include "g72x.h" - - -/* - * Pack output codes into bytes and write them to stdout. - * Returns 1 if there is residual output, else returns 0. - */ -int -pack_output( - unsigned code, - int bits) -{ - static unsigned int out_buffer = 0; - static int out_bits = 0; - unsigned char out_byte; - - out_buffer |= (code << out_bits); - out_bits += bits; - if (out_bits >= 8) { - out_byte = out_buffer & 0xff; - out_bits -= 8; - out_buffer >>= 8; - fwrite(&out_byte, sizeof (char), 1, stdout); - } - return (out_bits > 0); -} - - -main( - int argc, - char **argv) -{ - struct g72x_state state; - unsigned char sample_char; - short sample_short; - unsigned char code; - int resid; - int in_coding; - int in_size; - unsigned *in_buf; - int (*enc_routine)(); - int enc_bits; - - g72x_init_state(&state); - - /* Set defaults to u-law input, G.721 output */ - in_coding = AUDIO_ENCODING_ULAW; - in_size = sizeof (char); - in_buf = (unsigned *)&sample_char; - enc_routine = g721_encoder; - enc_bits = 4; - - /* Process encoding argument, if any */ - while ((argc > 1) && (argv[1][0] == '-')) { - switch (argv[1][1]) { - case '3': - enc_routine = g723_24_encoder; - enc_bits = 3; - break; - case '4': - enc_routine = g721_encoder; - enc_bits = 4; - break; - case '5': - enc_routine = g723_40_encoder; - enc_bits = 5; - break; - case 'u': - in_coding = AUDIO_ENCODING_ULAW; - in_size = sizeof (char); - in_buf = (unsigned *)&sample_char; - break; - case 'a': - in_coding = AUDIO_ENCODING_ALAW; - in_size = sizeof (char); - in_buf = (unsigned *)&sample_char; - break; - case 'l': - in_coding = AUDIO_ENCODING_LINEAR; - in_size = sizeof (short); - in_buf = (unsigned *)&sample_short; - break; - default: -fprintf(stderr, "CCITT ADPCM Encoder -- usage:\n"); -fprintf(stderr, "\tencode [-3|4|5] [-a|u|l] < infile > outfile\n"); -fprintf(stderr, "where:\n"); -fprintf(stderr, "\t-3\tGenerate G.723 24kbps (3-bit) data\n"); -fprintf(stderr, "\t-4\tGenerate G.721 32kbps (4-bit) data [default]\n"); -fprintf(stderr, "\t-5\tGenerate G.723 40kbps (5-bit) data\n"); -fprintf(stderr, "\t-a\tProcess 8-bit A-law input data\n"); -fprintf(stderr, "\t-u\tProcess 8-bit u-law input data [default]\n"); -fprintf(stderr, "\t-l\tProcess 16-bit linear PCM input data\n"); - exit(1); - } - argc--; - argv++; - } - - /* Read input file and process */ - while (fread(in_buf, in_size, 1, stdin) == 1) { - code = (*enc_routine)(in_size == 2 ? sample_short : sample_char, - in_coding, &state); - resid = pack_output(code, enc_bits); - } - - /* Write zero codes until all residual codes are written out */ - while (resid) { - resid = pack_output(0, enc_bits); - } - fclose(stdout); -} diff --git a/gnuradio-core/src/lib/g72x/g711.c b/gnuradio-core/src/lib/g72x/g711.c deleted file mode 100644 index d4d60a5c2..000000000 --- a/gnuradio-core/src/lib/g72x/g711.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * This source code is a product of Sun Microsystems, Inc. and is provided - * for unrestricted use. Users may copy or modify this source code without - * charge. - * - * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING - * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun source code is provided with no support and without any obligation on - * the part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -/* - * g711.c - * - * u-law, A-law and linear PCM conversions. - */ -#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */ -#define QUANT_MASK (0xf) /* Quantization field mask. */ -#define NSEGS (8) /* Number of A-law segments. */ -#define SEG_SHIFT (4) /* Left shift for segment number. */ -#define SEG_MASK (0x70) /* Segment field mask. */ - -static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF, - 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF}; - -/* copy from CCITT G.711 specifications */ -unsigned char _u2a[128] = { /* u- to A-law conversions */ - 1, 1, 2, 2, 3, 3, 4, 4, - 5, 5, 6, 6, 7, 7, 8, 8, - 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, - 25, 27, 29, 31, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, - 46, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, - 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, - 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128}; - -unsigned char _a2u[128] = { /* A- to u-law conversions */ - 1, 3, 5, 7, 9, 11, 13, 15, - 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, - 32, 32, 33, 33, 34, 34, 35, 35, - 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 48, 49, 49, - 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, 64, 64, - 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 79, - 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127}; - -static int -search( - int val, - short *table, - int size) -{ - int i; - - for (i = 0; i < size; i++) { - if (val <= *table++) - return (i); - } - return (size); -} - -/* - * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law - * - * linear2alaw() accepts an 16-bit integer and encodes it as A-law data. - * - * Linear Input Code Compressed Code - * ------------------------ --------------- - * 0000000wxyza 000wxyz - * 0000001wxyza 001wxyz - * 000001wxyzab 010wxyz - * 00001wxyzabc 011wxyz - * 0001wxyzabcd 100wxyz - * 001wxyzabcde 101wxyz - * 01wxyzabcdef 110wxyz - * 1wxyzabcdefg 111wxyz - * - * For further information see John C. Bellamy's Digital Telephony, 1982, - * John Wiley & Sons, pps 98-111 and 472-476. - */ -unsigned char -linear2alaw( - int pcm_val) /* 2's complement (16-bit range) */ -{ - int mask; - int seg; - unsigned char aval; - - if (pcm_val >= 0) { - mask = 0xD5; /* sign (7th) bit = 1 */ - } else { - mask = 0x55; /* sign bit = 0 */ - pcm_val = -pcm_val - 8; - } - - /* Convert the scaled magnitude to segment number. */ - seg = search(pcm_val, seg_end, 8); - - /* Combine the sign, segment, and quantization bits. */ - - if (seg >= 8) /* out of range, return maximum value. */ - return (0x7F ^ mask); - else { - aval = seg << SEG_SHIFT; - if (seg < 2) - aval |= (pcm_val >> 4) & QUANT_MASK; - else - aval |= (pcm_val >> (seg + 3)) & QUANT_MASK; - return (aval ^ mask); - } -} - -/* - * alaw2linear() - Convert an A-law value to 16-bit linear PCM - * - */ -int -alaw2linear( - unsigned char a_val) -{ - int t; - int seg; - - a_val ^= 0x55; - - t = (a_val & QUANT_MASK) << 4; - seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT; - switch (seg) { - case 0: - t += 8; - break; - case 1: - t += 0x108; - break; - default: - t += 0x108; - t <<= seg - 1; - } - return ((a_val & SIGN_BIT) ? t : -t); -} - -#define BIAS (0x84) /* Bias for linear code. */ - -/* - * linear2ulaw() - Convert a linear PCM value to u-law - * - * In order to simplify the encoding process, the original linear magnitude - * is biased by adding 33 which shifts the encoding range from (0 - 8158) to - * (33 - 8191). The result can be seen in the following encoding table: - * - * Biased Linear Input Code Compressed Code - * ------------------------ --------------- - * 00000001wxyza 000wxyz - * 0000001wxyzab 001wxyz - * 000001wxyzabc 010wxyz - * 00001wxyzabcd 011wxyz - * 0001wxyzabcde 100wxyz - * 001wxyzabcdef 101wxyz - * 01wxyzabcdefg 110wxyz - * 1wxyzabcdefgh 111wxyz - * - * Each biased linear code has a leading 1 which identifies the segment - * number. The value of the segment number is equal to 7 minus the number - * of leading 0's. The quantization interval is directly available as the - * four bits wxyz. * The trailing bits (a - h) are ignored. - * - * Ordinarily the complement of the resulting code word is used for - * transmission, and so the code word is complemented before it is returned. - * - * For further information see John C. Bellamy's Digital Telephony, 1982, - * John Wiley & Sons, pps 98-111 and 472-476. - */ -unsigned char -linear2ulaw( - int pcm_val) /* 2's complement (16-bit range) */ -{ - int mask; - int seg; - unsigned char uval; - - /* Get the sign and the magnitude of the value. */ - if (pcm_val < 0) { - pcm_val = BIAS - pcm_val; - mask = 0x7F; - } else { - pcm_val += BIAS; - mask = 0xFF; - } - - /* Convert the scaled magnitude to segment number. */ - seg = search(pcm_val, seg_end, 8); - - /* - * Combine the sign, segment, quantization bits; - * and complement the code word. - */ - if (seg >= 8) /* out of range, return maximum value. */ - return (0x7F ^ mask); - else { - uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF); - return (uval ^ mask); - } - -} - -/* - * ulaw2linear() - Convert a u-law value to 16-bit linear PCM - * - * First, a biased linear code is derived from the code word. An unbiased - * output can then be obtained by subtracting 33 from the biased code. - * - * Note that this function expects to be passed the complement of the - * original code word. This is in keeping with ISDN conventions. - */ -int -ulaw2linear( - unsigned char u_val) -{ - int t; - - /* Complement to obtain normal u-law value. */ - u_val = ~u_val; - - /* - * Extract and bias the quantization bits. Then - * shift up by the segment number and subtract out the bias. - */ - t = ((u_val & QUANT_MASK) << 3) + BIAS; - t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT; - - return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS)); -} - -/* A-law to u-law conversion */ -unsigned char -alaw2ulaw( - unsigned char aval) -{ - aval &= 0xff; - return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) : - (0x7F ^ _a2u[aval ^ 0x55])); -} - -/* u-law to A-law conversion */ -unsigned char -ulaw2alaw( - unsigned char uval) -{ - uval &= 0xff; - return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) : - (0x55 ^ (_u2a[0x7F ^ uval] - 1))); -} diff --git a/gnuradio-core/src/lib/g72x/g721.c b/gnuradio-core/src/lib/g72x/g721.c deleted file mode 100644 index 445f177e8..000000000 --- a/gnuradio-core/src/lib/g72x/g721.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * This source code is a product of Sun Microsystems, Inc. and is provided - * for unrestricted use. Users may copy or modify this source code without - * charge. - * - * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING - * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun source code is provided with no support and without any obligation on - * the part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -/* - * g721.c - * - * Description: - * - * g721_encoder(), g721_decoder() - * - * These routines comprise an implementation of the CCITT G.721 ADPCM - * coding algorithm. Essentially, this implementation is identical to - * the bit level description except for a few deviations which - * take advantage of work station attributes, such as hardware 2's - * complement arithmetic and large memory. Specifically, certain time - * consuming operations such as multiplications are replaced - * with lookup tables and software 2's complement operations are - * replaced with hardware 2's complement. - * - * The deviation from the bit level specification (lookup tables) - * preserves the bit level performance specifications. - * - * As outlined in the G.721 Recommendation, the algorithm is broken - * down into modules. Each section of code below is preceded by - * the name of the module which it is implementing. - * - */ -#include "g72x.h" - -static short qtab_721[7] = {-124, 80, 178, 246, 300, 349, 400}; -/* - * Maps G.721 code word to reconstructed scale factor normalized log - * magnitude values. - */ -static short _dqlntab[16] = {-2048, 4, 135, 213, 273, 323, 373, 425, - 425, 373, 323, 273, 213, 135, 4, -2048}; - -/* Maps G.721 code word to log of scale factor multiplier. */ -static short _witab[16] = {-12, 18, 41, 64, 112, 198, 355, 1122, - 1122, 355, 198, 112, 64, 41, 18, -12}; -/* - * Maps G.721 code words to a set of values whose long and short - * term averages are computed and then compared to give an indication - * how stationary (steady state) the signal is. - */ -static short _fitab[16] = {0, 0, 0, 0x200, 0x200, 0x200, 0x600, 0xE00, - 0xE00, 0x600, 0x200, 0x200, 0x200, 0, 0, 0}; - -/* - * g721_encoder() - * - * Encodes the input vale of linear PCM, A-law or u-law data sl and returns - * the resulting code. -1 is returned for unknown input coding value. - */ -int -g721_encoder( - int sl, - int in_coding, - struct g72x_state *state_ptr) -{ - short sezi, se, sez; /* ACCUM */ - short d; /* SUBTA */ - short sr; /* ADDB */ - short y; /* MIX */ - short dqsez; /* ADDC */ - short dq, i; - - switch (in_coding) { /* linearize input sample to 14-bit PCM */ - case AUDIO_ENCODING_ALAW: - sl = alaw2linear(sl) >> 2; - break; - case AUDIO_ENCODING_ULAW: - sl = ulaw2linear(sl) >> 2; - break; - case AUDIO_ENCODING_LINEAR: - sl >>= 2; /* 14-bit dynamic range */ - break; - default: - return (-1); - } - - sezi = predictor_zero(state_ptr); - sez = sezi >> 1; - se = (sezi + predictor_pole(state_ptr)) >> 1; /* estimated signal */ - - d = sl - se; /* estimation difference */ - - /* quantize the prediction difference */ - y = step_size(state_ptr); /* quantizer step size */ - i = quantize(d, y, qtab_721, 7); /* i = ADPCM code */ - - dq = reconstruct(i & 8, _dqlntab[i], y); /* quantized est diff */ - - sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconst. signal */ - - dqsez = sr + sez - se; /* pole prediction diff. */ - - update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr); - - return (i); -} - -/* - * g721_decoder() - * - * Description: - * - * Decodes a 4-bit code of G.721 encoded data of i and - * returns the resulting linear PCM, A-law or u-law value. - * return -1 for unknown out_coding value. - */ -int -g721_decoder( - int i, - int out_coding, - struct g72x_state *state_ptr) -{ - short sezi, sei, sez, se; /* ACCUM */ - short y; /* MIX */ - short sr; /* ADDB */ - short dq; - short dqsez; - - i &= 0x0f; /* mask to get proper bits */ - sezi = predictor_zero(state_ptr); - sez = sezi >> 1; - sei = sezi + predictor_pole(state_ptr); - se = sei >> 1; /* se = estimated signal */ - - y = step_size(state_ptr); /* dynamic quantizer step size */ - - dq = reconstruct(i & 0x08, _dqlntab[i], y); /* quantized diff. */ - - sr = (dq < 0) ? (se - (dq & 0x3FFF)) : se + dq; /* reconst. signal */ - - dqsez = sr - se + sez; /* pole prediction diff. */ - - update(4, y, _witab[i] << 5, _fitab[i], dq, sr, dqsez, state_ptr); - - switch (out_coding) { - case AUDIO_ENCODING_ALAW: - return (tandem_adjust_alaw(sr, se, y, i, 8, qtab_721)); - case AUDIO_ENCODING_ULAW: - return (tandem_adjust_ulaw(sr, se, y, i, 8, qtab_721)); - case AUDIO_ENCODING_LINEAR: - return (sr << 2); /* sr was 14-bit dynamic range */ - default: - return (-1); - } -} diff --git a/gnuradio-core/src/lib/g72x/g723_24.c b/gnuradio-core/src/lib/g72x/g723_24.c deleted file mode 100644 index 452f4daeb..000000000 --- a/gnuradio-core/src/lib/g72x/g723_24.c +++ /dev/null @@ -1,158 +0,0 @@ -/* - * This source code is a product of Sun Microsystems, Inc. and is provided - * for unrestricted use. Users may copy or modify this source code without - * charge. - * - * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING - * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun source code is provided with no support and without any obligation on - * the part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -/* - * g723_24.c - * - * Description: - * - * g723_24_encoder(), g723_24_decoder() - * - * These routines comprise an implementation of the CCITT G.723 24 Kbps - * ADPCM coding algorithm. Essentially, this implementation is identical to - * the bit level description except for a few deviations which take advantage - * of workstation attributes, such as hardware 2's complement arithmetic. - * - */ -#include "g72x.h" - -/* - * Maps G.723_24 code word to reconstructed scale factor normalized log - * magnitude values. - */ -static short _dqlntab[8] = {-2048, 135, 273, 373, 373, 273, 135, -2048}; - -/* Maps G.723_24 code word to log of scale factor multiplier. */ -static short _witab[8] = {-128, 960, 4384, 18624, 18624, 4384, 960, -128}; - -/* - * Maps G.723_24 code words to a set of values whose long and short - * term averages are computed and then compared to give an indication - * how stationary (steady state) the signal is. - */ -static short _fitab[8] = {0, 0x200, 0x400, 0xE00, 0xE00, 0x400, 0x200, 0}; - -static short qtab_723_24[3] = {8, 218, 331}; - -/* - * g723_24_encoder() - * - * Encodes a linear PCM, A-law or u-law input sample and returns its 3-bit code. - * Returns -1 if invalid input coding value. - */ -int -g723_24_encoder( - int sl, - int in_coding, - struct g72x_state *state_ptr) -{ - short sei, sezi, se, sez; /* ACCUM */ - short d; /* SUBTA */ - short y; /* MIX */ - short sr; /* ADDB */ - short dqsez; /* ADDC */ - short dq, i; - - switch (in_coding) { /* linearize input sample to 14-bit PCM */ - case AUDIO_ENCODING_ALAW: - sl = alaw2linear(sl) >> 2; - break; - case AUDIO_ENCODING_ULAW: - sl = ulaw2linear(sl) >> 2; - break; - case AUDIO_ENCODING_LINEAR: - sl >>= 2; /* sl of 14-bit dynamic range */ - break; - default: - return (-1); - } - - sezi = predictor_zero(state_ptr); - sez = sezi >> 1; - sei = sezi + predictor_pole(state_ptr); - se = sei >> 1; /* se = estimated signal */ - - d = sl - se; /* d = estimation diff. */ - - /* quantize prediction difference d */ - y = step_size(state_ptr); /* quantizer step size */ - i = quantize(d, y, qtab_723_24, 3); /* i = ADPCM code */ - dq = reconstruct(i & 4, _dqlntab[i], y); /* quantized diff. */ - - sr = (dq < 0) ? se - (dq & 0x3FFF) : se + dq; /* reconstructed signal */ - - dqsez = sr + sez - se; /* pole prediction diff. */ - - update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); - - return (i); -} - -/* - * g723_24_decoder() - * - * Decodes a 3-bit CCITT G.723_24 ADPCM code and returns - * the resulting 16-bit linear PCM, A-law or u-law sample value. - * -1 is returned if the output coding is unknown. - */ -int -g723_24_decoder( - int i, - int out_coding, - struct g72x_state *state_ptr) -{ - short sezi, sei, sez, se; /* ACCUM */ - short y; /* MIX */ - short sr; /* ADDB */ - short dq; - short dqsez; - - i &= 0x07; /* mask to get proper bits */ - sezi = predictor_zero(state_ptr); - sez = sezi >> 1; - sei = sezi + predictor_pole(state_ptr); - se = sei >> 1; /* se = estimated signal */ - - y = step_size(state_ptr); /* adaptive quantizer step size */ - dq = reconstruct(i & 0x04, _dqlntab[i], y); /* unquantize pred diff */ - - sr = (dq < 0) ? (se - (dq & 0x3FFF)) : (se + dq); /* reconst. signal */ - - dqsez = sr - se + sez; /* pole prediction diff. */ - - update(3, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); - - switch (out_coding) { - case AUDIO_ENCODING_ALAW: - return (tandem_adjust_alaw(sr, se, y, i, 4, qtab_723_24)); - case AUDIO_ENCODING_ULAW: - return (tandem_adjust_ulaw(sr, se, y, i, 4, qtab_723_24)); - case AUDIO_ENCODING_LINEAR: - return (sr << 2); /* sr was of 14-bit dynamic range */ - default: - return (-1); - } -} diff --git a/gnuradio-core/src/lib/g72x/g723_40.c b/gnuradio-core/src/lib/g72x/g723_40.c deleted file mode 100644 index 4858baf40..000000000 --- a/gnuradio-core/src/lib/g72x/g723_40.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * This source code is a product of Sun Microsystems, Inc. and is provided - * for unrestricted use. Users may copy or modify this source code without - * charge. - * - * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING - * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun source code is provided with no support and without any obligation on - * the part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -/* - * g723_40.c - * - * Description: - * - * g723_40_encoder(), g723_40_decoder() - * - * These routines comprise an implementation of the CCITT G.723 40Kbps - * ADPCM coding algorithm. Essentially, this implementation is identical to - * the bit level description except for a few deviations which - * take advantage of workstation attributes, such as hardware 2's - * complement arithmetic. - * - * The deviation from the bit level specification (lookup tables), - * preserves the bit level performance specifications. - * - * As outlined in the G.723 Recommendation, the algorithm is broken - * down into modules. Each section of code below is preceded by - * the name of the module which it is implementing. - * - */ -#include "g72x.h" - -/* - * Maps G.723_40 code word to ructeconstructed scale factor normalized log - * magnitude values. - */ -static short _dqlntab[32] = {-2048, -66, 28, 104, 169, 224, 274, 318, - 358, 395, 429, 459, 488, 514, 539, 566, - 566, 539, 514, 488, 459, 429, 395, 358, - 318, 274, 224, 169, 104, 28, -66, -2048}; - -/* Maps G.723_40 code word to log of scale factor multiplier. */ -static short _witab[32] = {448, 448, 768, 1248, 1280, 1312, 1856, 3200, - 4512, 5728, 7008, 8960, 11456, 14080, 16928, 22272, - 22272, 16928, 14080, 11456, 8960, 7008, 5728, 4512, - 3200, 1856, 1312, 1280, 1248, 768, 448, 448}; - -/* - * Maps G.723_40 code words to a set of values whose long and short - * term averages are computed and then compared to give an indication - * how stationary (steady state) the signal is. - */ -static short _fitab[32] = {0, 0, 0, 0, 0, 0x200, 0x200, 0x200, - 0x200, 0x200, 0x400, 0x600, 0x800, 0xA00, 0xC00, 0xC00, - 0xC00, 0xC00, 0xA00, 0x800, 0x600, 0x400, 0x200, 0x200, - 0x200, 0x200, 0x200, 0, 0, 0, 0, 0}; - -static short qtab_723_40[15] = {-122, -16, 68, 139, 198, 250, 298, 339, - 378, 413, 445, 475, 502, 528, 553}; - -/* - * g723_40_encoder() - * - * Encodes a 16-bit linear PCM, A-law or u-law input sample and retuens - * the resulting 5-bit CCITT G.723 40Kbps code. - * Returns -1 if the input coding value is invalid. - */ -int -g723_40_encoder( - int sl, - int in_coding, - struct g72x_state *state_ptr) -{ - short sei, sezi, se, sez; /* ACCUM */ - short d; /* SUBTA */ - short y; /* MIX */ - short sr; /* ADDB */ - short dqsez; /* ADDC */ - short dq, i; - - switch (in_coding) { /* linearize input sample to 14-bit PCM */ - case AUDIO_ENCODING_ALAW: - sl = alaw2linear(sl) >> 2; - break; - case AUDIO_ENCODING_ULAW: - sl = ulaw2linear(sl) >> 2; - break; - case AUDIO_ENCODING_LINEAR: - sl >>= 2; /* sl of 14-bit dynamic range */ - break; - default: - return (-1); - } - - sezi = predictor_zero(state_ptr); - sez = sezi >> 1; - sei = sezi + predictor_pole(state_ptr); - se = sei >> 1; /* se = estimated signal */ - - d = sl - se; /* d = estimation difference */ - - /* quantize prediction difference */ - y = step_size(state_ptr); /* adaptive quantizer step size */ - i = quantize(d, y, qtab_723_40, 15); /* i = ADPCM code */ - - dq = reconstruct(i & 0x10, _dqlntab[i], y); /* quantized diff */ - - sr = (dq < 0) ? se - (dq & 0x7FFF) : se + dq; /* reconstructed signal */ - - dqsez = sr + sez - se; /* dqsez = pole prediction diff. */ - - update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); - - return (i); -} - -/* - * g723_40_decoder() - * - * Decodes a 5-bit CCITT G.723 40Kbps code and returns - * the resulting 16-bit linear PCM, A-law or u-law sample value. - * -1 is returned if the output coding is unknown. - */ -int -g723_40_decoder( - int i, - int out_coding, - struct g72x_state *state_ptr) -{ - short sezi, sei, sez, se; /* ACCUM */ - short y; /* MIX */ - short sr; /* ADDB */ - short dq; - short dqsez; - - i &= 0x1f; /* mask to get proper bits */ - sezi = predictor_zero(state_ptr); - sez = sezi >> 1; - sei = sezi + predictor_pole(state_ptr); - se = sei >> 1; /* se = estimated signal */ - - y = step_size(state_ptr); /* adaptive quantizer step size */ - dq = reconstruct(i & 0x10, _dqlntab[i], y); /* estimation diff. */ - - sr = (dq < 0) ? (se - (dq & 0x7FFF)) : (se + dq); /* reconst. signal */ - - dqsez = sr - se + sez; /* pole prediction diff. */ - - update(5, y, _witab[i], _fitab[i], dq, sr, dqsez, state_ptr); - - switch (out_coding) { - case AUDIO_ENCODING_ALAW: - return (tandem_adjust_alaw(sr, se, y, i, 0x10, qtab_723_40)); - case AUDIO_ENCODING_ULAW: - return (tandem_adjust_ulaw(sr, se, y, i, 0x10, qtab_723_40)); - case AUDIO_ENCODING_LINEAR: - return (sr << 2); /* sr was of 14-bit dynamic range */ - default: - return (-1); - } -} diff --git a/gnuradio-core/src/lib/g72x/g72x.c b/gnuradio-core/src/lib/g72x/g72x.c deleted file mode 100644 index 9a823c755..000000000 --- a/gnuradio-core/src/lib/g72x/g72x.c +++ /dev/null @@ -1,576 +0,0 @@ -/* - * This source code is a product of Sun Microsystems, Inc. and is provided - * for unrestricted use. Users may copy or modify this source code without - * charge. - * - * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING - * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun source code is provided with no support and without any obligation on - * the part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ -#include <stdlib.h> -/* - * g72x.c - * - * Common routines for G.721 and G.723 conversions. - */ - -#include "g72x.h" - -static short power2[15] = {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, - 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000}; - -/* - * quan() - * - * quantizes the input val against the table of size short integers. - * It returns i if table[i - 1] <= val < table[i]. - * - * Using linear search for simple coding. - */ -static int -quan( - int val, - short *table, - int size) -{ - int i; - - for (i = 0; i < size; i++) - if (val < *table++) - break; - return (i); -} - -/* - * fmult() - * - * returns the integer product of the 14-bit integer "an" and - * "floating point" representation (4-bit exponent, 6-bit mantessa) "srn". - */ -static int -fmult( - int an, - int srn) -{ - short anmag, anexp, anmant; - short wanexp, wanmant; - short retval; - - anmag = (an > 0) ? an : ((-an) & 0x1FFF); - anexp = quan(anmag, power2, 15) - 6; - anmant = (anmag == 0) ? 32 : - (anexp >= 0) ? anmag >> anexp : anmag << -anexp; - wanexp = anexp + ((srn >> 6) & 0xF) - 13; - - wanmant = (anmant * (srn & 077) + 0x30) >> 4; - retval = (wanexp >= 0) ? ((wanmant << wanexp) & 0x7FFF) : - (wanmant >> -wanexp); - - return (((an ^ srn) < 0) ? -retval : retval); -} - -/* - * g72x_init_state() - * - * This routine initializes and/or resets the g72x_state structure - * pointed to by 'state_ptr'. - * All the initial state values are specified in the CCITT G.721 document. - */ -void -g72x_init_state( - struct g72x_state *state_ptr) -{ - int cnta; - - state_ptr->yl = 34816; - state_ptr->yu = 544; - state_ptr->dms = 0; - state_ptr->dml = 0; - state_ptr->ap = 0; - for (cnta = 0; cnta < 2; cnta++) { - state_ptr->a[cnta] = 0; - state_ptr->pk[cnta] = 0; - state_ptr->sr[cnta] = 32; - } - for (cnta = 0; cnta < 6; cnta++) { - state_ptr->b[cnta] = 0; - state_ptr->dq[cnta] = 32; - } - state_ptr->td = 0; -} - -/* - * predictor_zero() - * - * computes the estimated signal from 6-zero predictor. - * - */ -int -predictor_zero( - struct g72x_state *state_ptr) -{ - int i; - int sezi; - - sezi = fmult(state_ptr->b[0] >> 2, state_ptr->dq[0]); - for (i = 1; i < 6; i++) /* ACCUM */ - sezi += fmult(state_ptr->b[i] >> 2, state_ptr->dq[i]); - return (sezi); -} -/* - * predictor_pole() - * - * computes the estimated signal from 2-pole predictor. - * - */ -int -predictor_pole( - struct g72x_state *state_ptr) -{ - return (fmult(state_ptr->a[1] >> 2, state_ptr->sr[1]) + - fmult(state_ptr->a[0] >> 2, state_ptr->sr[0])); -} -/* - * step_size() - * - * computes the quantization step size of the adaptive quantizer. - * - */ -int -step_size( - struct g72x_state *state_ptr) -{ - int y; - int dif; - int al; - - if (state_ptr->ap >= 256) - return (state_ptr->yu); - else { - y = state_ptr->yl >> 6; - dif = state_ptr->yu - y; - al = state_ptr->ap >> 2; - if (dif > 0) - y += (dif * al) >> 6; - else if (dif < 0) - y += (dif * al + 0x3F) >> 6; - return (y); - } -} - -/* - * quantize() - * - * Given a raw sample, 'd', of the difference signal and a - * quantization step size scale factor, 'y', this routine returns the - * ADPCM codeword to which that sample gets quantized. The step - * size scale factor division operation is done in the log base 2 domain - * as a subtraction. - */ -int -quantize( - int d, /* Raw difference signal sample */ - int y, /* Step size multiplier */ - short *table, /* quantization table */ - int size) /* table size of short integers */ -{ - short dqm; /* Magnitude of 'd' */ - short exp; /* Integer part of base 2 log of 'd' */ - short mant; /* Fractional part of base 2 log */ - short dl; /* Log of magnitude of 'd' */ - short dln; /* Step size scale factor normalized log */ - int i; - - /* - * LOG - * - * Compute base 2 log of 'd', and store in 'dl'. - */ - dqm = abs(d); - exp = quan(dqm >> 1, power2, 15); - mant = ((dqm << 7) >> exp) & 0x7F; /* Fractional portion. */ - dl = (exp << 7) + mant; - - /* - * SUBTB - * - * "Divide" by step size multiplier. - */ - dln = dl - (y >> 2); - - /* - * QUAN - * - * Obtain codword i for 'd'. - */ - i = quan(dln, table, size); - if (d < 0) /* take 1's complement of i */ - return ((size << 1) + 1 - i); - else if (i == 0) /* take 1's complement of 0 */ - return ((size << 1) + 1); /* new in 1988 */ - else - return (i); -} -/* - * reconstruct() - * - * Returns reconstructed difference signal 'dq' obtained from - * codeword 'i' and quantization step size scale factor 'y'. - * Multiplication is performed in log base 2 domain as addition. - */ -int -reconstruct( - int sign, /* 0 for non-negative value */ - int dqln, /* G.72x codeword */ - int y) /* Step size multiplier */ -{ - short dql; /* Log of 'dq' magnitude */ - short dex; /* Integer part of log */ - short dqt; - short dq; /* Reconstructed difference signal sample */ - - dql = dqln + (y >> 2); /* ADDA */ - - if (dql < 0) { - return ((sign) ? -0x8000 : 0); - } else { /* ANTILOG */ - dex = (dql >> 7) & 15; - dqt = 128 + (dql & 127); - dq = (dqt << 7) >> (14 - dex); - return ((sign) ? (dq - 0x8000) : dq); - } -} - - -/* - * update() - * - * updates the state variables for each output code - */ -void -update( - int code_size, /* distinguish 723_40 with others */ - int y, /* quantizer step size */ - int wi, /* scale factor multiplier */ - int fi, /* for long/short term energies */ - int dq, /* quantized prediction difference */ - int sr, /* reconstructed signal */ - int dqsez, /* difference from 2-pole predictor */ - struct g72x_state *state_ptr) /* coder state pointer */ -{ - int cnt; - short mag, exp; /* Adaptive predictor, FLOAT A */ - short a2p = 0; /* LIMC */ - short a1ul; /* UPA1 */ - short pks1; /* UPA2 */ - short fa1; - char tr; /* tone/transition detector */ - short ylint, thr2, dqthr; - short ylfrac, thr1; - short pk0; - - pk0 = (dqsez < 0) ? 1 : 0; /* needed in updating predictor poles */ - - mag = dq & 0x7FFF; /* prediction difference magnitude */ - /* TRANS */ - ylint = state_ptr->yl >> 15; /* exponent part of yl */ - ylfrac = (state_ptr->yl >> 10) & 0x1F; /* fractional part of yl */ - thr1 = (32 + ylfrac) << ylint; /* threshold */ - thr2 = (ylint > 9) ? 31 << 10 : thr1; /* limit thr2 to 31 << 10 */ - dqthr = (thr2 + (thr2 >> 1)) >> 1; /* dqthr = 0.75 * thr2 */ - if (state_ptr->td == 0) /* signal supposed voice */ - tr = 0; - else if (mag <= dqthr) /* supposed data, but small mag */ - tr = 0; /* treated as voice */ - else /* signal is data (modem) */ - tr = 1; - - /* - * Quantizer scale factor adaptation. - */ - - /* FUNCTW & FILTD & DELAY */ - /* update non-steady state step size multiplier */ - state_ptr->yu = y + ((wi - y) >> 5); - - /* LIMB */ - if (state_ptr->yu < 544) /* 544 <= yu <= 5120 */ - state_ptr->yu = 544; - else if (state_ptr->yu > 5120) - state_ptr->yu = 5120; - - /* FILTE & DELAY */ - /* update steady state step size multiplier */ - state_ptr->yl += state_ptr->yu + ((-state_ptr->yl) >> 6); - - /* - * Adaptive predictor coefficients. - */ - if (tr == 1) { /* reset a's and b's for modem signal */ - state_ptr->a[0] = 0; - state_ptr->a[1] = 0; - state_ptr->b[0] = 0; - state_ptr->b[1] = 0; - state_ptr->b[2] = 0; - state_ptr->b[3] = 0; - state_ptr->b[4] = 0; - state_ptr->b[5] = 0; - } else { /* update a's and b's */ - pks1 = pk0 ^ state_ptr->pk[0]; /* UPA2 */ - - /* update predictor pole a[1] */ - a2p = state_ptr->a[1] - (state_ptr->a[1] >> 7); - if (dqsez != 0) { - fa1 = (pks1) ? state_ptr->a[0] : -state_ptr->a[0]; - if (fa1 < -8191) /* a2p = function of fa1 */ - a2p -= 0x100; - else if (fa1 > 8191) - a2p += 0xFF; - else - a2p += fa1 >> 5; - - if (pk0 ^ state_ptr->pk[1]) - /* LIMC */ - if (a2p <= -12160) - a2p = -12288; - else if (a2p >= 12416) - a2p = 12288; - else - a2p -= 0x80; - else if (a2p <= -12416) - a2p = -12288; - else if (a2p >= 12160) - a2p = 12288; - else - a2p += 0x80; - } - - /* TRIGB & DELAY */ - state_ptr->a[1] = a2p; - - /* UPA1 */ - /* update predictor pole a[0] */ - state_ptr->a[0] -= state_ptr->a[0] >> 8; - if (dqsez != 0){ - if (pks1 == 0) - state_ptr->a[0] += 192; - else - state_ptr->a[0] -= 192; - } - - /* LIMD */ - a1ul = 15360 - a2p; - if (state_ptr->a[0] < -a1ul) - state_ptr->a[0] = -a1ul; - else if (state_ptr->a[0] > a1ul) - state_ptr->a[0] = a1ul; - - /* UPB : update predictor zeros b[6] */ - for (cnt = 0; cnt < 6; cnt++) { - if (code_size == 5) /* for 40Kbps G.723 */ - state_ptr->b[cnt] -= state_ptr->b[cnt] >> 9; - else /* for G.721 and 24Kbps G.723 */ - state_ptr->b[cnt] -= state_ptr->b[cnt] >> 8; - if (dq & 0x7FFF) { /* XOR */ - if ((dq ^ state_ptr->dq[cnt]) >= 0) - state_ptr->b[cnt] += 128; - else - state_ptr->b[cnt] -= 128; - } - } - } - - for (cnt = 5; cnt > 0; cnt--) - state_ptr->dq[cnt] = state_ptr->dq[cnt-1]; - /* FLOAT A : convert dq[0] to 4-bit exp, 6-bit mantissa f.p. */ - if (mag == 0) { - state_ptr->dq[0] = (dq >= 0) ? 0x20 : 0xFC20; - } else { - exp = quan(mag, power2, 15); - state_ptr->dq[0] = (dq >= 0) ? - (exp << 6) + ((mag << 6) >> exp) : - (exp << 6) + ((mag << 6) >> exp) - 0x400; - } - - state_ptr->sr[1] = state_ptr->sr[0]; - /* FLOAT B : convert sr to 4-bit exp., 6-bit mantissa f.p. */ - if (sr == 0) { - state_ptr->sr[0] = 0x20; - } else if (sr > 0) { - exp = quan(sr, power2, 15); - state_ptr->sr[0] = (exp << 6) + ((sr << 6) >> exp); - } else if (sr > -32768) { - mag = -sr; - exp = quan(mag, power2, 15); - state_ptr->sr[0] = (exp << 6) + ((mag << 6) >> exp) - 0x400; - } else - state_ptr->sr[0] = 0xFC20; - - /* DELAY A */ - state_ptr->pk[1] = state_ptr->pk[0]; - state_ptr->pk[0] = pk0; - - /* TONE */ - if (tr == 1) /* this sample has been treated as data */ - state_ptr->td = 0; /* next one will be treated as voice */ - else if (a2p < -11776) /* small sample-to-sample correlation */ - state_ptr->td = 1; /* signal may be data */ - else /* signal is voice */ - state_ptr->td = 0; - - /* - * Adaptation speed control. - */ - state_ptr->dms += (fi - state_ptr->dms) >> 5; /* FILTA */ - state_ptr->dml += (((fi << 2) - state_ptr->dml) >> 7); /* FILTB */ - - if (tr == 1) - state_ptr->ap = 256; - else if (y < 1536) /* SUBTC */ - state_ptr->ap += (0x200 - state_ptr->ap) >> 4; - else if (state_ptr->td == 1) - state_ptr->ap += (0x200 - state_ptr->ap) >> 4; - else if (abs((state_ptr->dms << 2) - state_ptr->dml) >= - (state_ptr->dml >> 3)) - state_ptr->ap += (0x200 - state_ptr->ap) >> 4; - else - state_ptr->ap += (-state_ptr->ap) >> 4; -} - -/* - * tandem_adjust(sr, se, y, i, sign) - * - * At the end of ADPCM decoding, it simulates an encoder which may be receiving - * the output of this decoder as a tandem process. If the output of the - * simulated encoder differs from the input to this decoder, the decoder output - * is adjusted by one level of A-law or u-law codes. - * - * Input: - * sr decoder output linear PCM sample, - * se predictor estimate sample, - * y quantizer step size, - * i decoder input code, - * sign sign bit of code i - * - * Return: - * adjusted A-law or u-law compressed sample. - */ -int -tandem_adjust_alaw( - int sr, /* decoder output linear PCM sample */ - int se, /* predictor estimate sample */ - int y, /* quantizer step size */ - int i, /* decoder input code */ - int sign, - short *qtab) -{ - unsigned char sp; /* A-law compressed 8-bit code */ - short dx; /* prediction error */ - char id; /* quantized prediction error */ - int sd; /* adjusted A-law decoded sample value */ - int im; /* biased magnitude of i */ - int imx; /* biased magnitude of id */ - - if (sr <= -32768) - sr = -1; - sp = linear2alaw((sr >> 1) << 3); /* short to A-law compression */ - dx = (alaw2linear(sp) >> 2) - se; /* 16-bit prediction error */ - id = quantize(dx, y, qtab, sign - 1); - - if (id == i) { /* no adjustment on sp */ - return (sp); - } else { /* sp adjustment needed */ - /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */ - im = i ^ sign; /* 2's complement to biased unsigned */ - imx = id ^ sign; - - if (imx > im) { /* sp adjusted to next lower value */ - if (sp & 0x80) { - sd = (sp == 0xD5) ? 0x55 : - ((sp ^ 0x55) - 1) ^ 0x55; - } else { - sd = (sp == 0x2A) ? 0x2A : - ((sp ^ 0x55) + 1) ^ 0x55; - } - } else { /* sp adjusted to next higher value */ - if (sp & 0x80) - sd = (sp == 0xAA) ? 0xAA : - ((sp ^ 0x55) + 1) ^ 0x55; - else - sd = (sp == 0x55) ? 0xD5 : - ((sp ^ 0x55) - 1) ^ 0x55; - } - return (sd); - } -} - -int -tandem_adjust_ulaw( - int sr, /* decoder output linear PCM sample */ - int se, /* predictor estimate sample */ - int y, /* quantizer step size */ - int i, /* decoder input code */ - int sign, - short *qtab) -{ - unsigned char sp; /* u-law compressed 8-bit code */ - short dx; /* prediction error */ - char id; /* quantized prediction error */ - int sd; /* adjusted u-law decoded sample value */ - int im; /* biased magnitude of i */ - int imx; /* biased magnitude of id */ - - if (sr <= -32768) - sr = 0; - sp = linear2ulaw(sr << 2); /* short to u-law compression */ - dx = (ulaw2linear(sp) >> 2) - se; /* 16-bit prediction error */ - id = quantize(dx, y, qtab, sign - 1); - if (id == i) { - return (sp); - } else { - /* ADPCM codes : 8, 9, ... F, 0, 1, ... , 6, 7 */ - im = i ^ sign; /* 2's complement to biased unsigned */ - imx = id ^ sign; - if (imx > im) { /* sp adjusted to next lower value */ - if (sp & 0x80) - sd = (sp == 0xFF) ? 0x7E : sp + 1; - else - sd = (sp == 0) ? 0 : sp - 1; - - } else { /* sp adjusted to next higher value */ - if (sp & 0x80) - sd = (sp == 0x80) ? 0x80 : sp - 1; - else - sd = (sp == 0x7F) ? 0xFE : sp + 1; - } - return (sd); - } -} - - - - - - - - - - - - diff --git a/gnuradio-core/src/lib/g72x/g72x.h b/gnuradio-core/src/lib/g72x/g72x.h deleted file mode 100644 index 33807171a..000000000 --- a/gnuradio-core/src/lib/g72x/g72x.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * This source code is a product of Sun Microsystems, Inc. and is provided - * for unrestricted use. Users may copy or modify this source code without - * charge. - * - * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING - * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR - * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * - * Sun source code is provided with no support and without any obligation on - * the part of Sun Microsystems, Inc. to assist in its use, correction, - * modification or enhancement. - * - * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE - * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE - * OR ANY PART THEREOF. - * - * In no event will Sun Microsystems, Inc. be liable for any lost revenue - * or profits or other special, indirect and consequential damages, even if - * Sun has been advised of the possibility of such damages. - * - * Sun Microsystems, Inc. - * 2550 Garcia Avenue - * Mountain View, California 94043 - */ - -/* - * g72x.h - * - * Header file for CCITT conversion routines. - * - */ -#ifndef _G72X_H -#define _G72X_H - -#define AUDIO_ENCODING_ULAW (1) /* ISDN u-law */ -#define AUDIO_ENCODING_ALAW (2) /* ISDN A-law */ -#define AUDIO_ENCODING_LINEAR (3) /* PCM 2's-complement (0-center) */ - -/* - * The following is the definition of the state structure - * used by the G.721/G.723 encoder and decoder to preserve their internal - * state between successive calls. The meanings of the majority - * of the state structure fields are explained in detail in the - * CCITT Recommendation G.721. The field names are essentially indentical - * to variable names in the bit level description of the coding algorithm - * included in this Recommendation. - */ -struct g72x_state { - long yl; /* Locked or steady state step size multiplier. */ - short yu; /* Unlocked or non-steady state step size multiplier. */ - short dms; /* Short term energy estimate. */ - short dml; /* Long term energy estimate. */ - short ap; /* Linear weighting coefficient of 'yl' and 'yu'. */ - - short a[2]; /* Coefficients of pole portion of prediction filter. */ - short b[6]; /* Coefficients of zero portion of prediction filter. */ - short pk[2]; /* - * Signs of previous two samples of a partially - * reconstructed signal. - */ - short dq[6]; /* - * Previous 6 samples of the quantized difference - * signal represented in an internal floating point - * format. - */ - short sr[2]; /* - * Previous 2 samples of the quantized difference - * signal represented in an internal floating point - * format. - */ - char td; /* delayed tone detect, new in 1988 version */ -}; - -/* External function definitions. */ - -extern void g72x_init_state(struct g72x_state *); -extern int g721_encoder( - int sample, - int in_coding, - struct g72x_state *state_ptr); -extern int g721_decoder( - int code, - int out_coding, - struct g72x_state *state_ptr); -extern int g723_24_encoder( - int sample, - int in_coding, - struct g72x_state *state_ptr); -extern int g723_24_decoder( - int code, - int out_coding, - struct g72x_state *state_ptr); -extern int g723_40_encoder( - int sample, - int in_coding, - struct g72x_state *state_ptr); -extern int g723_40_decoder( - int code, - int out_coding, - struct g72x_state *state_ptr); - - -extern int -quantize( - int d, - int y, - short *table, - int size); -extern int reconstruct(int,int,int);void - -extern update( - int code_size, - int y, - int wi, - int fi, - int dq, - int sr, - int dqsez, - struct g72x_state *state_ptr); -extern int -tandem_adjust_alaw( - int sr, - int se, - int y, - int i, - int sign, - short *qtab); - -extern int -tandem_adjust_ulaw( - int sr, - int se, - int y, - int i, - int sign, - short *qtab); - -extern unsigned char -linear2alaw( - int pcm_val); - -extern int -alaw2linear( - unsigned char a_val); - -extern unsigned char -linear2ulaw(int pcm_val); - -extern int ulaw2linear( unsigned char u_val); - -extern int predictor_zero(struct g72x_state *state_ptr); - -extern int predictor_pole( struct g72x_state *state_ptr); -extern int step_size( struct g72x_state *state_ptr); -#endif /* !_G72X_H */ diff --git a/gnuradio-core/src/lib/general/Makefile.am b/gnuradio-core/src/lib/general/Makefile.am index 15272dd5c..7a7e6f496 100644 --- a/gnuradio-core/src/lib/general/Makefile.am +++ b/gnuradio-core/src/lib/general/Makefile.am @@ -264,8 +264,8 @@ grinclude_HEADERS = \ gr_map_bb.h \ gr_math.h \ gr_misc.h \ - gr_mpsk_receiver_cc.h \ gr_nco.h \ + gr_mpsk_receiver_cc.h \ gr_nlog10_ff.h \ gr_nop.h \ gr_null_sink.h \ diff --git a/gnuradio-core/src/lib/general/general.i b/gnuradio-core/src/lib/general/general.i index fd158cd1f..bef55a252 100644 --- a/gnuradio-core/src/lib/general/general.i +++ b/gnuradio-core/src/lib/general/general.i @@ -98,6 +98,7 @@ #include <gr_ofdm_cyclic_prefixer.h> #include <gr_ofdm_mapper_bcv.h> #include <gr_ofdm_frame_sink.h> + //#include <gr_ofdm_frame_sink2.h> #include <gr_ofdm_insert_preamble.h> #include <gr_ofdm_sampler.h> #include <gr_regenerate_bb.h> @@ -225,6 +226,7 @@ %include "gr_ofdm_cyclic_prefixer.i" %include "gr_ofdm_mapper_bcv.i" %include "gr_ofdm_frame_sink.i" + //%include "gr_ofdm_frame_sink2.i" %include "gr_ofdm_insert_preamble.i" %include "gr_ofdm_sampler.i" %include "gr_regenerate_bb.i" diff --git a/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc b/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc index f3bfd0951..b77b19745 100644 --- a/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc +++ b/gnuradio-core/src/lib/general/gr_costas_loop_cc.cc @@ -1,6 +1,6 @@ /* -*- c++ -*- */ /* - * Copyright 2006,2010 Free Software Foundation, Inc. + * Copyright 2006,2010,2011 Free Software Foundation, Inc. * * This file is part of GNU Radio * @@ -64,12 +64,30 @@ gr_costas_loop_cc::gr_costas_loop_cc (float alpha, float beta, d_phase_detector = &gr_costas_loop_cc::phase_detector_4; break; + case 8: + d_phase_detector = &gr_costas_loop_cc::phase_detector_8; + break; + default: - throw std::invalid_argument("order must be 2 or 4"); + throw std::invalid_argument("order must be 2, 4, or 8"); break; } } +float +gr_costas_loop_cc::phase_detector_8(gr_complex sample) const +{ + float K = sqrt(2.0) - 1; + + if(abs(sample.real()) >= abs(sample.imag())) { + return ((sample.real()>0 ? 1.0 : -1.0) * sample.imag() - + (sample.imag()>0 ? 1.0 : -1.0) * sample.real() * K); + } + else { + return ((sample.real()>0 ? 1.0 : -1.0) * sample.imag() * K - + (sample.imag()>0 ? 1.0 : -1.0) * sample.real()); + } +} float gr_costas_loop_cc::phase_detector_4(gr_complex sample) const diff --git a/gnuradio-core/src/lib/general/gr_costas_loop_cc.h b/gnuradio-core/src/lib/general/gr_costas_loop_cc.h index 3b4aab86c..181880f1c 100644 --- a/gnuradio-core/src/lib/general/gr_costas_loop_cc.h +++ b/gnuradio-core/src/lib/general/gr_costas_loop_cc.h @@ -89,6 +89,12 @@ class gr_costas_loop_cc : public gr_sync_block int order ) throw (std::invalid_argument); + /*! \brief the phase detector circuit for 8th-order PSK loops + * \param sample complex sample + * \return the phase error + */ + float phase_detector_8(gr_complex sample) const; // for 8PSK + /*! \brief the phase detector circuit for fourth-order loops * \param sample complex sample * \return the phase error diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h index 55f8412ce..385f447b7 100644 --- a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h +++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.h @@ -48,7 +48,7 @@ class gr_frequency_modulator_fc : public gr_sync_block public: void set_sensitivity(float sens) { d_sensitivity = sens; } - float get_sensitivity() { return d_sensitivity; } + float sensitivity() const { return d_sensitivity; } int work (int noutput_items, gr_vector_const_void_star &input_items, diff --git a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i index 04d9a41ba..7dfb82f1f 100644 --- a/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i +++ b/gnuradio-core/src/lib/general/gr_frequency_modulator_fc.i @@ -30,5 +30,5 @@ class gr_frequency_modulator_fc : public gr_sync_block gr_frequency_modulator_fc (double sensitivity); public: void set_sensitivity(float sens) { d_sensitivity = sens; } - float get_sensitivity() { return d_sensitivity; } + float sensitivity() const { return d_sensitivity; } }; diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.cc b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.cc new file mode 100644 index 000000000..40574b4e9 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.cc @@ -0,0 +1,374 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2008,2010,2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <gr_ofdm_frame_sink2.h> +#include <gr_io_signature.h> +#include <gr_expj.h> +#include <gr_math.h> +#include <math.h> +#include <cstdio> +#include <stdexcept> +#include <iostream> +#include <string.h> +#include <gr_constellation.h> + +#define VERBOSE 0 + +inline void +gr_ofdm_frame_sink2::enter_search() +{ + if (VERBOSE) + fprintf(stderr, "@ enter_search\n"); + + d_state = STATE_SYNC_SEARCH; + +} + +inline void +gr_ofdm_frame_sink2::enter_have_sync() +{ + if (VERBOSE) + fprintf(stderr, "@ enter_have_sync\n"); + + d_state = STATE_HAVE_SYNC; + + // clear state of demapper + d_byte_offset = 0; + d_partial_byte = 0; + + d_header = 0; + d_headerbytelen_cnt = 0; + + // Resetting PLL + d_freq = 0.0; + d_phase = 0.0; + fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0)); +} + +inline void +gr_ofdm_frame_sink2::enter_have_header() +{ + d_state = STATE_HAVE_HEADER; + + // header consists of two 16-bit shorts in network byte order + // payload length is lower 12 bits + // whitener offset is upper 4 bits + d_packetlen = (d_header >> 16) & 0x0fff; + d_packet_whitener_offset = (d_header >> 28) & 0x000f; + d_packetlen_cnt = 0; + + if (VERBOSE) + fprintf(stderr, "@ enter_have_header (payload_len = %d) (offset = %d)\n", + d_packetlen, d_packet_whitener_offset); +} + + +unsigned int gr_ofdm_frame_sink2::demapper(const gr_complex *in, + unsigned char *out) +{ + unsigned int i=0, bytes_produced=0; + gr_complex carrier; + + carrier=gr_expj(d_phase); + + gr_complex accum_error = 0.0; + //while(i < d_occupied_carriers) { + while(i < d_subcarrier_map.size()) { + if(d_nresid > 0) { + d_partial_byte |= d_resid; + d_byte_offset += d_nresid; + d_nresid = 0; + d_resid = 0; + } + + //while((d_byte_offset < 8) && (i < d_occupied_carriers)) { + while((d_byte_offset < 8) && (i < d_subcarrier_map.size())) { + //gr_complex sigrot = in[i]*carrier*d_dfe[i]; + gr_complex sigrot = in[d_subcarrier_map[i]]*carrier*d_dfe[i]; + + if(d_derotated_output != NULL){ + d_derotated_output[i] = sigrot; + } + + unsigned char bits = d_constell->decision_maker(&sigrot); + + gr_complex closest_sym = d_constell->points()[bits]; + + accum_error += sigrot * conj(closest_sym); + + // FIX THE FOLLOWING STATEMENT + if (norm(sigrot)> 0.001) d_dfe[i] += d_eq_gain*(closest_sym/sigrot-d_dfe[i]); + + i++; + + if((8 - d_byte_offset) >= d_nbits) { + d_partial_byte |= bits << (d_byte_offset); + d_byte_offset += d_nbits; + } + else { + d_nresid = d_nbits-(8-d_byte_offset); + int mask = ((1<<(8-d_byte_offset))-1); + d_partial_byte |= (bits & mask) << d_byte_offset; + d_resid = bits >> (8-d_byte_offset); + d_byte_offset += (d_nbits - d_nresid); + } + //printf("demod symbol: %.4f + j%.4f bits: %x partial_byte: %x byte_offset: %d resid: %x nresid: %d\n", + // in[i-1].real(), in[i-1].imag(), bits, d_partial_byte, d_byte_offset, d_resid, d_nresid); + } + + if(d_byte_offset == 8) { + //printf("demod byte: %x \n\n", d_partial_byte); + out[bytes_produced++] = d_partial_byte; + d_byte_offset = 0; + d_partial_byte = 0; + } + } + //std::cerr << "accum_error " << accum_error << std::endl; + + float angle = arg(accum_error); + + d_freq = d_freq - d_freq_gain*angle; + d_phase = d_phase + d_freq - d_phase_gain*angle; + if (d_phase >= 2*M_PI) d_phase -= 2*M_PI; + if (d_phase <0) d_phase += 2*M_PI; + + //if(VERBOSE) + // std::cerr << angle << "\t" << d_freq << "\t" << d_phase << "\t" << std::endl; + + return bytes_produced; +} + + +gr_ofdm_frame_sink2_sptr +gr_make_ofdm_frame_sink2(gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_carriers, + float phase_gain, float freq_gain) +{ + return gnuradio::get_initial_sptr(new gr_ofdm_frame_sink2(constell, + target_queue, occupied_carriers, + phase_gain, freq_gain)); +} + + +gr_ofdm_frame_sink2::gr_ofdm_frame_sink2(gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_carriers, + float phase_gain, float freq_gain) + : gr_sync_block ("ofdm_frame_sink2", + gr_make_io_signature2 (2, 2, sizeof(gr_complex)*occupied_carriers, sizeof(char)), + gr_make_io_signature (1, 1, sizeof(gr_complex)*occupied_carriers)), + d_constell(constell), + d_target_queue(target_queue), d_occupied_carriers(occupied_carriers), + d_byte_offset(0), d_partial_byte(0), + d_resid(0), d_nresid(0),d_phase(0),d_freq(0),d_phase_gain(phase_gain),d_freq_gain(freq_gain), + d_eq_gain(0.05) +{ + if (d_constell->dimensionality() != 1) + throw std::runtime_error ("This receiver only works with constellations of dimension 1."); + + std::string carriers = "FE7F"; + + // A bit hacky to fill out carriers to occupied_carriers length + int diff = (d_occupied_carriers - 4*carriers.length()); + while(diff > 7) { + carriers.insert(0, "f"); + carriers.insert(carriers.length(), "f"); + diff -= 8; + } + + // if there's extras left to be processed + // divide remaining to put on either side of current map + // all of this is done to stick with the concept of a carrier map string that + // can be later passed by the user, even though it'd be cleaner to just do this + // on the carrier map itself + int diff_left=0; + int diff_right=0; + + // dictionary to convert from integers to ascii hex representation + char abc[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + if(diff > 0) { + char c[2] = {0,0}; + + diff_left = (int)ceil((float)diff/2.0f); // number of carriers to put on the left side + c[0] = abc[(1 << diff_left) - 1]; // convert to bits and move to ASCI integer + carriers.insert(0, c); + + diff_right = diff - diff_left; // number of carriers to put on the right side + c[0] = abc[0xF^((1 << diff_right) - 1)]; // convert to bits and move to ASCI integer + carriers.insert(carriers.length(), c); + } + + // It seemed like such a good idea at the time... + // because we are only dealing with the occupied_carriers + // at this point, the diff_left in the following compensates + // for any offset from the 0th carrier introduced + unsigned int i,j,k; + for(i = 0; i < (d_occupied_carriers/4)+diff_left; i++) { + char c = carriers[i]; + for(j = 0; j < 4; j++) { + k = (strtol(&c, NULL, 16) >> (3-j)) & 0x1; + if(k) { + d_subcarrier_map.push_back(4*i + j - diff_left); + } + } + } + + // make sure we stay in the limit currently imposed by the occupied_carriers + if(d_subcarrier_map.size() > d_occupied_carriers) { + throw std::invalid_argument("gr_ofdm_mapper_bcv: subcarriers allocated exceeds size of occupied carriers"); + } + + d_bytes_out = new unsigned char[d_occupied_carriers]; + d_dfe.resize(occupied_carriers); + fill(d_dfe.begin(), d_dfe.end(), gr_complex(1.0,0.0)); + + d_nbits = d_constell->bits_per_symbol(); + + enter_search(); +} + +gr_ofdm_frame_sink2::~gr_ofdm_frame_sink2 () +{ + delete [] d_bytes_out; +} + + +int +gr_ofdm_frame_sink2::work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const gr_complex *in = (const gr_complex *) input_items[0]; + const char *sig = (const char *) input_items[1]; + unsigned int j = 0; + unsigned int bytes=0; + + // If the output is connected, send it the derotated symbols + if(output_items.size() >= 1) + d_derotated_output = (gr_complex *)output_items[0]; + else + d_derotated_output = NULL; + + if (VERBOSE) + fprintf(stderr,">>> Entering state machine\n"); + + switch(d_state) { + + case STATE_SYNC_SEARCH: // Look for flag indicating beginning of pkt + if (VERBOSE) + fprintf(stderr,"SYNC Search, noutput=%d\n", noutput_items); + + if (sig[0]) { // Found it, set up for header decode + enter_have_sync(); + } + break; + + case STATE_HAVE_SYNC: + // only demod after getting the preamble signal; otherwise, the + // equalizer taps will screw with the PLL performance + bytes = demapper(&in[0], d_bytes_out); + + if (VERBOSE) { + if(sig[0]) + printf("ERROR -- Found SYNC in HAVE_SYNC\n"); + fprintf(stderr,"Header Search bitcnt=%d, header=0x%08x\n", + d_headerbytelen_cnt, d_header); + } + + j = 0; + while(j < bytes) { + d_header = (d_header << 8) | (d_bytes_out[j] & 0xFF); + j++; + + if (++d_headerbytelen_cnt == HEADERBYTELEN) { + + if (VERBOSE) + fprintf(stderr, "got header: 0x%08x\n", d_header); + + // we have a full header, check to see if it has been received properly + if (header_ok()){ + enter_have_header(); + + if (VERBOSE) + printf("\nPacket Length: %d\n", d_packetlen); + + while((j < bytes) && (d_packetlen_cnt < d_packetlen)) { + d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; + } + + if(d_packetlen_cnt == d_packetlen) { + gr_message_sptr msg = + gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen); + memcpy(msg->msg(), d_packet, d_packetlen_cnt); + d_target_queue->insert_tail(msg); // send it + msg.reset(); // free it up + + enter_search(); + } + } + else { + enter_search(); // bad header + } + } + } + break; + + case STATE_HAVE_HEADER: + bytes = demapper(&in[0], d_bytes_out); + + if (VERBOSE) { + if(sig[0]) + printf("ERROR -- Found SYNC in HAVE_HEADER at %d, length of %d\n", d_packetlen_cnt, d_packetlen); + fprintf(stderr,"Packet Build\n"); + } + + j = 0; + while(j < bytes) { + d_packet[d_packetlen_cnt++] = d_bytes_out[j++]; + + if (d_packetlen_cnt == d_packetlen){ // packet is filled + // build a message + // NOTE: passing header field as arg1 is not scalable + gr_message_sptr msg = + gr_make_message(0, d_packet_whitener_offset, 0, d_packetlen_cnt); + memcpy(msg->msg(), d_packet, d_packetlen_cnt); + + d_target_queue->insert_tail(msg); // send it + msg.reset(); // free it up + + enter_search(); + break; + } + } + break; + + default: + assert(0); + + } // switch + + return 1; +} diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.h b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.h new file mode 100644 index 000000000..de8c6a37e --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.h @@ -0,0 +1,120 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_GR_OFDM_FRAME_SINK2_H +#define INCLUDED_GR_OFDM_FRAME_SINK2_H + +#include <gr_sync_block.h> +#include <gr_msg_queue.h> +#include <gr_constellation.h> + +class gr_ofdm_frame_sink2; +typedef boost::shared_ptr<gr_ofdm_frame_sink2> gr_ofdm_frame_sink2_sptr; + +gr_ofdm_frame_sink2_sptr +gr_make_ofdm_frame_sink2 (gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + float phase_gain=0.25, float freq_gain=0.25*0.25/4.0); + +/*! + * \brief Takes an OFDM symbol in, demaps it into bits of 0's and 1's, packs + * them into packets, and sends to to a message queue sink. + * \ingroup sink_blk + * \ingroup ofdm_blk + * + * NOTE: The mod input parameter simply chooses a pre-defined demapper/slicer. Eventually, + * we want to be able to pass in a reference to an object to do the demapping and slicing + * for a given modulation type. + */ +class gr_ofdm_frame_sink2 : public gr_sync_block +{ + friend gr_ofdm_frame_sink2_sptr + gr_make_ofdm_frame_sink2 (gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + float phase_gain, float freq_gain); + + private: + enum state_t {STATE_SYNC_SEARCH, STATE_HAVE_SYNC, STATE_HAVE_HEADER}; + + static const int MAX_PKT_LEN = 4096; + static const int HEADERBYTELEN = 4; + + gr_msg_queue_sptr d_target_queue; // where to send the packet when received + state_t d_state; + unsigned int d_header; // header bits + int d_headerbytelen_cnt; // how many so far + + unsigned char *d_bytes_out; // hold the current bytes produced by the demapper + + unsigned int d_occupied_carriers; + unsigned int d_byte_offset; + unsigned int d_partial_byte; + + unsigned char d_packet[MAX_PKT_LEN]; // assembled payload + int d_packetlen; // length of packet + int d_packet_whitener_offset; // offset into whitener string to use + int d_packetlen_cnt; // how many so far + + gr_complex * d_derotated_output; // Pointer to output stream to send deroated symbols out + + gr_constellation_sptr d_constell; + std::vector<gr_complex> d_dfe; + unsigned int d_nbits; + + unsigned char d_resid; + unsigned int d_nresid; + float d_phase; + float d_freq; + float d_phase_gain; + float d_freq_gain; + float d_eq_gain; + + std::vector<int> d_subcarrier_map; + + protected: + gr_ofdm_frame_sink2(gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + float phase_gain, float freq_gain); + + void enter_search(); + void enter_have_sync(); + void enter_have_header(); + + bool header_ok() + { + // confirm that two copies of header info are identical + return ((d_header >> 16) ^ (d_header & 0xffff)) == 0; + } + + unsigned char slicer(const gr_complex x); + unsigned int demapper(const gr_complex *in, + unsigned char *out); + + public: + ~gr_ofdm_frame_sink2(); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif /* INCLUDED_GR_OFDM_FRAME_SINK2_H */ diff --git a/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.i b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.i new file mode 100644 index 000000000..8fa320089 --- /dev/null +++ b/gnuradio-core/src/lib/general/gr_ofdm_frame_sink2.i @@ -0,0 +1,39 @@ +/* -*- c++ -*- */ +/* + * Copyright 2007,2011 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +GR_SWIG_BLOCK_MAGIC(gr,ofdm_frame_sink2); + +gr_ofdm_frame_sink2_sptr +gr_make_ofdm_frame_sink2(gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + float phase_gain=0.25, float freq_gain=0.25*0.25/4); + +class gr_ofdm_frame_sink2 : public gr_sync_block +{ + protected: + gr_ofdm_frame_sink2(gr_constellation_sptr constell, + gr_msg_queue_sptr target_queue, unsigned int occupied_tones, + float phase_gain, float freq_gain); + + public: + ~gr_ofdm_frame_sink2(); +}; diff --git a/gnuradio-core/src/lib/swig/Makefile.am b/gnuradio-core/src/lib/swig/Makefile.am index f8e7640ae..d304a2123 100644 --- a/gnuradio-core/src/lib/swig/Makefile.am +++ b/gnuradio-core/src/lib/swig/Makefile.am @@ -45,7 +45,7 @@ TOP_SWIG_IFILES = \ swiginclude_HEADERS = \ gnuradio.i \ gr_swig_block_magic.i \ - gr_shared_ptr.i + gr_shared_ptr.i # SWIG headers that get installed in ${prefix}/include/gnuradio/swig/... nobase_swiginclude_HEADERS = \ diff --git a/gnuradio-core/src/lib/swig/Makefile.swig.gen b/gnuradio-core/src/lib/swig/Makefile.swig.gen index 0c3247565..cede68817 100644 --- a/gnuradio-core/src/lib/swig/Makefile.swig.gen +++ b/gnuradio-core/src/lib/swig/Makefile.swig.gen @@ -105,7 +105,7 @@ _gnuradio_core_runtime_la_CXXFLAGS = \ $(gnuradio_core_runtime_la_swig_cxxflags) python/gnuradio_core_runtime.cc: gnuradio_core_runtime.py -gnuradio_core_runtime.py: gnuradio_core_runtime.i +gnuradio_core_runtime.py: gnuradio_core_runtime.i # Include the python dependencies for this file -include python/gnuradio_core_runtime.d @@ -250,7 +250,7 @@ _gnuradio_core_general_la_CXXFLAGS = \ $(gnuradio_core_general_la_swig_cxxflags) python/gnuradio_core_general.cc: gnuradio_core_general.py -gnuradio_core_general.py: gnuradio_core_general.i +gnuradio_core_general.py: gnuradio_core_general.i # Include the python dependencies for this file -include python/gnuradio_core_general.d @@ -395,7 +395,7 @@ _gnuradio_core_gengen_la_CXXFLAGS = \ $(gnuradio_core_gengen_la_swig_cxxflags) python/gnuradio_core_gengen.cc: gnuradio_core_gengen.py -gnuradio_core_gengen.py: gnuradio_core_gengen.i +gnuradio_core_gengen.py: gnuradio_core_gengen.i # Include the python dependencies for this file -include python/gnuradio_core_gengen.d @@ -540,7 +540,7 @@ _gnuradio_core_filter_la_CXXFLAGS = \ $(gnuradio_core_filter_la_swig_cxxflags) python/gnuradio_core_filter.cc: gnuradio_core_filter.py -gnuradio_core_filter.py: gnuradio_core_filter.i +gnuradio_core_filter.py: gnuradio_core_filter.i # Include the python dependencies for this file -include python/gnuradio_core_filter.d @@ -685,7 +685,7 @@ _gnuradio_core_io_la_CXXFLAGS = \ $(gnuradio_core_io_la_swig_cxxflags) python/gnuradio_core_io.cc: gnuradio_core_io.py -gnuradio_core_io.py: gnuradio_core_io.i +gnuradio_core_io.py: gnuradio_core_io.i # Include the python dependencies for this file -include python/gnuradio_core_io.d @@ -830,7 +830,7 @@ _gnuradio_core_hier_la_CXXFLAGS = \ $(gnuradio_core_hier_la_swig_cxxflags) python/gnuradio_core_hier.cc: gnuradio_core_hier.py -gnuradio_core_hier.py: gnuradio_core_hier.i +gnuradio_core_hier.py: gnuradio_core_hier.i # Include the python dependencies for this file -include python/gnuradio_core_hier.d diff --git a/gnuradio-core/src/python/gnuradio/Makefile.am b/gnuradio-core/src/python/gnuradio/Makefile.am index eff35e95c..7d27386a4 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/gr_xmlrunner.py b/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py index ded77f5f3..c3dc5cf13 100644 --- a/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py +++ b/gnuradio-core/src/python/gnuradio/gr_xmlrunner.py @@ -6,8 +6,6 @@ XML Test Runner for PyUnit # the Public Domain. With contributions by Paolo Borelli and others. # Added to GNU Radio Oct. 3, 2010 -from __future__ import with_statement - __version__ = "0.1" import os.path @@ -185,7 +183,9 @@ class XMLTestRunner(object): result = _XMLTestResult(classname) start_time = time.time() - with _fake_std_streams(): + fss = _fake_std_streams() + fss.__enter__() + try: test(result) try: out_s = sys.stdout.getvalue() @@ -195,6 +195,8 @@ class XMLTestRunner(object): err_s = sys.stderr.getvalue() except AttributeError: err_s = "" + finally: + fss.__exit__(None, None, None) time_taken = time.time() - start_time result.print_report(stream, time_taken, out_s, err_s) @@ -218,8 +220,8 @@ class _fake_std_streams(object): def __enter__(self): self._orig_stdout = sys.stdout self._orig_stderr = sys.stderr - sys.stdout = StringIO() - sys.stderr = StringIO() + #sys.stdout = StringIO() + #sys.stderr = StringIO() def __exit__(self, exc_type, exc_val, exc_tb): sys.stdout = self._orig_stdout diff --git a/gnuradio-core/src/python/gnuradio/vocoder/Makefile.am b/gnuradio-core/src/python/gnuradio/vocoder/Makefile.am deleted file mode 100644 index 69c140c10..000000000 --- a/gnuradio-core/src/python/gnuradio/vocoder/Makefile.am +++ /dev/null @@ -1,26 +0,0 @@ -# -# Copyright 2004,2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -include $(top_srcdir)/Makefile.common - -grvocoderpythondir = $(grpythondir)/vocoder -grvocoderpython_PYTHON = \ - __init__.py 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 |