Ok, never mind, my error was based on a fundamental misunderstanding of what "io_signature" defines: I found the answer in the mailing list.
It would be great to see just a few words about this in the "how-to-write-a-block" tutorial. Have a nice week-end, Jens On Thu, Jul 20, 2006 at 12:54:25PM +0200, Jens Elsner wrote: > Good morning! > > I started writing a small signal processing block (OFDM transmitter) and ran > into some problems. > > My starting point was the well written gr-how-to-write-a-block tutorial. > > I have, let's say, 1536 input samples and want to produce 1800 output > samples with my block. When I run my code with small values > (say fft size of 32) I get valid OFDM symbols but a lot of zeros in > between. When I uses higher values either the scheduler quits > > ( > sched: <gr_block ofdm_tx_vcc (0)> is > requesting more input data > than we can provide. > ) > > or even the buffer can't be allocated. This makes me sure that there is > a programming mistake on my part, but I can't seem to find it. > I would be thankful if somebody could point out my mistake? The main > files are attached, a modified gr-how-to-build-a-block can be found here: > http://www.1c3.de/gr-dab.tar.bz2 . > > Yet another question: Can blocks somehow interchange values? I would > like to write two blocks, one that estimates a frequency offset and > another one that compensates it (simple modulation). Or do I have to > do that in one block? > > Jens > > /* -*- c++ -*- */ > > %feature("autodoc", "1"); // generate python docstrings > > %include "exception.i" > %import "gnuradio.i" // the common stuff > > %{ > #include "gnuradio_swig_bug_workaround.h" // mandatory bug fix > #include "ofdm_tx_cc.h" > #include <stdexcept> > %} > > // ---------------------------------------------------------------- > > /* > * First arg is the package prefix. > * Second arg is the name of the class minus the prefix. > * > * This does some behind-the-scenes magic so we can > * access howto_square_ff from python as howto.square_ff > */ > GR_SWIG_BLOCK_MAGIC(ofdm,tx_cc); > > ofdm_tx_cc_sptr ofdm_do_tx_cc (int ofdm_sym_len, int gi_len, int fft_len); > > class ofdm_tx_cc : public gr_sync_block > { > private: > ofdm_tx_cc (int ofdm_sym_len, int gi_len, int fft_len); > }; > > /* -*- c++ -*- */ > /* > * Copyright 2004 Free Software Foundation, Inc. > * > * This file is part of GNU Radio > * > * GNU Radio is free software; you can redistribute it and/or modify > * it under the terms of the GNU General Public License as published by > * the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, > * Boston, MA 02111-1307, USA. > */ > > /* > * config.h is generated by configure. It contains the results > * of probing for features, options etc. It should be the first > * file included in your .cc file. > */ > #ifdef HAVE_CONFIG_H > #include "config.h" > #endif > > #include <ofdm_tx_cc.h> > #include <gr_io_signature.h> > > #include <gri_fft.h> > #include <math.h> > > /* > * Create a new instance of gr_ofdm_tx_cc and return > * a boost shared_ptr. This is effectively the public constructor. > */ > ofdm_tx_cc_sptr > ofdm_do_tx_cc (int ofdm_sym_len, int gi_len, int fft_len) > { > return ofdm_tx_cc_sptr (new ofdm_tx_cc (ofdm_sym_len, gi_len, fft_len)); > } > > /* > * Specify constraints on number of input and output streams. > * This info is used to construct the input and output signatures > * (2nd & 3rd args to gr_block's constructor). The input and > * output signatures are used by the runtime system to > * check that a valid number and type of inputs and outputs > * are connected to this block. In this case, we accept > * only 1 input and 1 output. > */ > static const int MIN_IN = 1; // mininum number of input streams > static const int MAX_IN = 1; // maximum number of input streams > static const int MIN_OUT = 1; // minimum number of output streams > static const int MAX_OUT = 1; // maximum number of output streams > > /* > * The private constructor > * Takes length of OFDM symbol (including guard interval) and guard interval > length as > * arguments. Variable FFT length and subcarrier selection mask is > implemented later. > */ > ofdm_tx_cc::ofdm_tx_cc (int ofdm_sym_len, int gi_len, int fft_len) > : gr_block ("ofdm_tx_vcc", > gr_make_io_signature (MIN_IN, MAX_IN, > (ofdm_sym_len-gi_len)*sizeof(gr_complex)), > gr_make_io_signature (MIN_OUT, MAX_OUT, ofdm_sym_len * > sizeof(gr_complex))) > { > d_ofdm_sym_len = ofdm_sym_len; > d_gi_len = gi_len; > d_fft_len = ofdm_sym_len-gi_len; // FIXME: not yet implemented > > // OFDM symbols can't be split, contrain request size > set_output_multiple(d_ofdm_sym_len); > > // set approximate out rate > set_relative_rate((double)(d_ofdm_sym_len) / > (double)(d_ofdm_sym_len-d_gi_len)); > > d_fft = new gri_fft_complex(d_fft_len, true); > } > > /* > * Our virtual destructor. > */ > ofdm_tx_cc::~ofdm_tx_cc () > { > delete d_fft; > } > > /* > * Implementation of gr_block::forecast() - estimate the number of input > samples, if we are asked to > * output noutput_items samples. > */ > void > ofdm_tx_cc::forecast (int noutput_items, gr_vector_int > &ninput_items_required) > { > // noutput_items should be a multiple of d_ofdm_sym_len (see > constructor) > assert ((noutput_items % d_ofdm_sym_len) == 0); > > int nblocks = noutput_items / d_ofdm_sym_len; > int input_required = nblocks * (d_ofdm_sym_len-d_gi_len); > > unsigned ninputs = ninput_items_required.size(); > for (unsigned int i = 0; i < ninputs; i++) > ninput_items_required[i] = input_required; > } > > > /* > * Here the actual work is done - "d_ofdm_sym_len-d_gi_len" complex samples > are consumed and > * "d_ofdm_sym_len" samples are written. > */ > > int > ofdm_tx_cc::general_work (int noutput_items, > gr_vector_int &ninput_items, > gr_vector_const_void_star &input_items, > gr_vector_void_star &output_items) > { > // pointers to data > const gr_complex *in = (const gr_complex *) input_items[0]; > gr_complex *out = (gr_complex *) output_items[0]; > > int out_count=0; // counts the number of written complex samples > int in_count=0; // counts number of samples consumed > > printf("available in (samples): %i\n", ninput_items[0]); > printf("requested out (samples): %i\n", noutput_items); > > while(out_count<noutput_items) > { > memcpy(d_fft->get_inbuf(), in, d_fft_len*sizeof(gr_complex)); // copy > to input buffer > d_fft->execute(); // compute fft > // cyclic prefix is repetition of the end in the beginning > memcpy(out, d_fft->get_outbuf()+(d_fft_len-d_gi_len), > d_gi_len*sizeof(gr_complex)); // guard interval; last argument of memcpy is > length in bytes > memcpy(out+d_gi_len, d_fft->get_outbuf(), > d_fft_len*sizeof(gr_complex)); // copy data > > // increase pointers, counters > in += d_ofdm_sym_len-d_gi_len; > out += d_ofdm_sym_len; > out_count += d_ofdm_sym_len; > in_count += d_ofdm_sym_len-d_gi_len; > } > > // noutput_items should always be a multiple of d_ofdm_sym_len, so the > assert shouldn't fail now > assert (out_count == noutput_items); > > // Tell runtime system how many input items we consumed. > consume_each(in_count); > > // Tell runtime system how many output items we produced. > return out_count; > } > > /* -*- c++ -*- */ > /* > * Copyright 2004 Free Software Foundation, Inc. > * > * This file is part of GNU Radio > * > * GNU Radio is free software; you can redistribute it and/or modify > * it under the terms of the GNU General Public License as published by > * the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, > * Boston, MA 02111-1307, USA. > */ > #ifndef INCLUDED_OFDM_TX_CC_H > #define INCLUDED_OFDM_TX_CC_H > > #include <gr_block.h> > > class gri_fft_complex; > > class ofdm_tx_cc; > > /* > * We use boost::shared_ptr's instead of raw pointers for all access > * to gr_blocks (and many other data structures). The shared_ptr gets > * us transparent reference counting, which greatly simplifies storage > * management issues. This is especially helpful in our hybrid > * C++ / Python system. > * > * See http://www.boost.org/libs/smart_ptr/smart_ptr.htm > * > * As a convention, the _sptr suffix indicates a boost::shared_ptr > */ > typedef boost::shared_ptr<ofdm_tx_cc> ofdm_tx_cc_sptr; > > /*! > * \brief Return a shared_ptr to a new instance of howto_square2_ff. > * > * To avoid accidental use of raw pointers, howto_square2_ff's > * constructor is private. howto_make_square2_ff is the public > * interface for creating new instances. > */ > ofdm_tx_cc_sptr ofdm_do_tx_cc (); > > /*! > * \brief OFDM transmitter. > * \ingroup block > * > * A simple OFDM transmitter block. > */ > class ofdm_tx_cc : public gr_block > { > private: > // The friend declaration allows ofdm_do_tx_cc to > // access the private constructor. > > friend ofdm_tx_cc_sptr ofdm_do_tx_cc (int ofdm_sym_len, int gi_len, int > fft_len); > > ofdm_tx_cc (int ofdm_sym_len, int gi_len, int fft_len); // private > constructor > > unsigned int d_ofdm_sym_len; > unsigned int d_gi_len; > unsigned int d_fft_len; > gri_fft_complex *d_fft; > > public: > ~ofdm_tx_cc (); // public destructor > > // Where all the action really happens > > int general_work (int noutput_items, > gr_vector_int &ninput_items, > gr_vector_const_void_star &input_items, > gr_vector_void_star &output_items); > > void forecast(int noutput_items, gr_vector_int &ninput_items_required); > > }; > > #endif /* INCLUDED_OFDM_TX_H */ > #!/usr/bin/env python > # > # Copyright 2004 Free Software Foundation, Inc. > # > # This file is part of GNU Radio > # > # GNU Radio is free software; you can redistribute it and/or modify > # it under the terms of the GNU General Public License as published by > # the Free Software Foundation; either version 2, 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., 59 Temple Place - Suite 330, > # Boston, MA 02111-1307, USA. > # > > from gnuradio import gr, gr_unittest > import ofdm, inspect > > class qa_ofdm (gr_unittest.TestCase): > > def setUp (self): > self.fg = gr.flow_graph () > > def tearDown (self): > self.fg = None > > def test_001_square_ff (self): > > fft_len = 32 # fails for higher values (eg. 512) > gi_len = 4 > ofdm_sym_len = fft_len+gi_len; > ofdm_tx = ofdm.ofdm_do_tx_cc (ofdm_sym_len, gi_len, 0) > print ofdm_tx.output_multiple() > print ofdm_tx.relative_rate() > > s2p = gr.serial_to_parallel (gr.sizeof_gr_complex, fft_len) > p2s = gr.parallel_to_serial (gr.sizeof_gr_complex, ofdm_sym_len) > > dst = gr.file_sink(gr.sizeof_gr_complex, "ofdm_sym_out") > > SNR=10 > src = gr.noise_source_c(gr.GR_GAUSSIAN, pow(10.0,-SNR/20.0)) > > self.fg.connect(src, s2p) > self.fg.connect(s2p, ofdm_tx) > self.fg.connect(ofdm_tx, p2s) > self.fg.connect(p2s, dst) > > self.fg.run() > > if __name__ == '__main__': > gr_unittest.main () > _______________________________________________ > Discuss-gnuradio mailing list > Discuss-gnuradio@gnu.org > http://lists.gnu.org/mailman/listinfo/discuss-gnuradio _______________________________________________ Discuss-gnuradio mailing list Discuss-gnuradio@gnu.org http://lists.gnu.org/mailman/listinfo/discuss-gnuradio