Blocks handling vectors

Hi, I have been struggling a bit trying to code a block that accept for
example vectors of sync_len*sizeof(float) as input signature and outputs
vectors of (sync_len+pkt_len)*sizeof(float) as output signature.

To understand how blocks handling vectors work, I tried to make the same
block I did using single element items, which consists of a block that
adds a preamble of sync_len at the beginning of the sequence. It worked
using single element items, instead of vectors but in the receiving
part, should be a block that basically removes that preamble. In this
case, it was so difficult the coding and did not get it, that is why I
decided to try with vectors.

Now some doubts came to my mind. In the tutorials there is a gap
concerning vectors or I haven’t found any processing block in the
tutorial examples that explains a bit how vectors are processed.

  • The io signatures would be defined like this:
    gr::io_signature::make(1, 1, pkt_len*sizeof(float)),
    gr::io_signature::make(1, 1, sizeof(float) * (sync_word_len +
    pkt_len)))
    To clarify a bit what I want is to add a predefined preamble of length
    sync_word, which I define in the constructor and cannot be accessible.
    Now, one of my questions was, is the most suitable block that I have to
    use a general one? or is it possible to use a decimator?

  • In my first implementation I used a general block:

void
add_sync_impl::forecast (int noutput_items, gr_vector_int
&ninput_items_required)
{
ninput_items_required[0] = noutput_items * d_pkt_len;
}

int
add_sync_impl::general_work (int noutput_items,
gr_vector_int &ninput_items,
gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
const float *in = (const float *) input_items[0];
float *out = (float *) output_items[0];

    // Do <+signal processing+>
    for (int i = 0; i < noutput_items; i++) {
        std::memcpy(&out[0], &d_sync_word[0], sizeof(float) * 

d_sync_word_len);
std::memcpy(&out[d_sync_word_len], &in[0], sizeof(float) *
d_pkt_len);
}
// Tell runtime system how many input items we consumed on
// each input stream.
consume_each (d_pkt_len);

    // Tell runtime system how many output items we produced.
    return noutput_items;
}

But when I try to connect the blocks to test them with python it gives
me error:
File “”, line 1, in
File
“/usr/local/lib/python2.7/dist-packages/gnuradio/gr/hier_block2.py”,
line 48, in wrapped
raise ValueError(“Unable to coerce endpoint”)
ValueError: Unable to coerce endpoint

I am doing something wrong, like copying the info into output wrongly,
or I coded forecast wrongly or I am indicating wrongly the consumed
items. I would thanks any kind of help or explanation about how block
handles vectors.

As example: d_sync_word_len = 3
d_sync_word = {0, 0, 0}
d_pkt_len = 5

Result(passed from vector to stream with a vector to stream block):
input = (1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
output = (0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1)

I know that there are some blocks that already do this, but I was mostly
interested in knowing how blocks handle vectors. Or also I would be
interested to know the inverse block of vector_insert (in python).
Thanks before hand.

Gabriele Galiero

On 03.08.2015 00:18, Galiero Casay Gabriele wrote:

  • The io signatures would be defined like this:
    gr::io_signature::make(1, 1, pkt_len*sizeof(float)),
    gr::io_signature::make(1, 1, sizeof(float) * (sync_word_len +
    pkt_len)))
    To clarify a bit what I want is to add a predefined preamble of length
    sync_word, which I define in the constructor and cannot be accessible.
    Now, one of my questions was, is the most suitable block that I have to
    use a general one? or is it possible to use a decimator?\

In this case, you can use a sync block, because you have 1 output items
per 1 input item. However, you’re packaging entire packets as vectors –
not sure if that’s your intention.

If you want to handle this on an item-by-item basis, you need a general
block, because the relative rate is (sync_len+pkt_len)/pkt_len, and
that’s (most likely) non-integer. This approach can be convenient if
your packets are very large, or if your packet length (with or without
sync word) is an annoying size and doesn’t fit into page boundaries.

    for (int i = 0; i < noutput_items; i++) {
        std::memcpy(&out[0], &d_sync_word[0], sizeof(float) *

d_sync_word_len);
std::memcpy(&out[d_sync_word_len], &in[0], sizeof(float) *
d_pkt_len);
}
// Tell runtime system how many input items we consumed on
// each input stream.
consume_each (d_pkt_len);

Nope, you’ve consumed noutput_items.

raise ValueError("Unable to coerce endpoint")

ValueError: Unable to coerce endpoint

Well, we can’t see what you’re connecting this too, but it probably
doesn’t have pkt_len or pkt_len+sync_word vector lengths.

M