# 4-to-32 bit symbol mapper block

**URL:** <https://www.ruby-forum.com/t/4-to-32-bit-symbol-mapper-block/233682>\
**Category:** GNU Radio\
**Created:** [January 3, 2015, 6:41pm UTC](https://www.ruby-forum.com/t/4-to-32-bit-symbol-mapper-block/233682 "2015-01-03T18:41:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![addis\_a](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/c4cdca/32.png) [@addis\_a](https://www.ruby-forum.com/u/addis_a)\
**Post date:** [January 3, 2015, 6:41pm UTC](https://www.ruby-forum.com/t/4-to-32-bit-symbol-mapper-block/233682/1 "2015-01-03T18:41:58Z")

</div>

Hi list,

I’d like to write a custom block that takes 1, 4-bit symbol and remaps  
it to 1, 32-bit symbol. Some code for a general\_work() method is below  
[1], but it doesn’t quite work yet.

It isn’t convolutional - i.e. the 4-bits of symbol k, do not overlap  
with the 4-bits of symbol k-1 - so it doesn’t really fall into the  
concept of a filter. It also must operate on multiples of 4-bits in  
one operation (at least 4).

In a sense, it’s an interpolating block that operates on 4 bits at a  
time.

I originally thought that I should be operating on vectors, but  
haven’t really found many examples of the stream\_to\_vector\_ii block or  
the vector\_to\_stream\_ii block.

Does anyone on the list have any thoughts or suggestions?

Thanks,

C

[1]

#define N 4  
#define M 32  
#define K (M/N)

forecast():

// input items requires for nout \< 4 = 0  
ninput\_items\_required[0] = ( noutput\_items / N ) \* N \* K;

general\_work():

// input is a binary stream encoded as integers  
// output is a binary stream encoded as integers

int \*in = (int \*) input\_items[0];  
int \*out = (int \*) output\_items[0];

int j, nchips = 0;

for( j=0; j \< noutput\_items; j += M, nchips++, in += j/K, out += j ) {  
// FIXME: throw some sort of exception if j / K \>= ninput\_items  
// Do symbol-to-chip mapping  
// pack the first four input items and form a nibble  
unsigned symbol = 0;  
for( int i=0; i \< N; i++ ) {  
int bit = !! in[i];  
symbol |= bit \<\< i;  
}  
// form a word via the LUT  
unsigned chip = LUT[symbol];  
// unpack the word into output items  
for( int i=0; i \< M; i++ ) {  
int bit = ( chip \>\> i ) & 0x1;  
out[i] = bit;  
}  
}  
// Tell runtime system how many input items we consumed on each input  
stream.  
consume\_each ( nchips \* N );  
// Tell runtime system how many output items we produced.  
return nchips \* M;

---

<div class="post-metadata">

**Author:** ![christophrost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a3d4f5/32.png) [@christophrost](https://www.ruby-forum.com/u/christophrost)\
**Post date:** [January 3, 2015, 7:27pm UTC](https://www.ruby-forum.com/t/4-to-32-bit-symbol-mapper-block/233682/2 "2015-01-03T19:27:49Z")

</div>

I’ll definitely try the Pack K Bits block - that might just do it!

---

<div class="post-metadata">

**Author:** ![christophrost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a3d4f5/32.png) [@christophrost](https://www.ruby-forum.com/u/christophrost)\
**Post date:** [January 3, 2015, 7:48pm UTC](https://www.ruby-forum.com/t/4-to-32-bit-symbol-mapper-block/233682/3 "2015-01-03T19:48:54Z")

</div>

On Sat, Jan 3, 2015 at 1:38 PM, Marcus Müller [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> as you noted, this block has a fixed relation between in- and output;  
> thus, you can use the sync\_interpolator [1] to get rid of the need to  
> write your own forecast and calling consume; you’ll need to override  
> work instead of general\_work, which is more comfortable. With the  
> set\_output\_multiple[2] you can restrict the possible values of  
> n\_output\_items, which are directly proportional to your input items.

Perfect - thanks!

---

<div class="post-metadata">

**Author:** ![christophrost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a3d4f5/32.png) [@christophrost](https://www.ruby-forum.com/u/christophrost)\
**Post date:** [January 3, 2015, 9:58pm UTC](https://www.ruby-forum.com/t/4-to-32-bit-symbol-mapper-block/233682/4 "2015-01-03T21:58:10Z")

</div>

On Sat, Jan 3, 2015 at 1:38 PM, Marcus Müller [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Then: If I understand you correctly, what you have is an input stream of  
> unsigned (32 bit)ints, each int containing exactly one bit of information:  
> 0x00000000, 0x00000001, 0x00000001, 0x00000000, and so forth.  
> This format is especially wasteful on memory, and wherever GNU Radio  
> uses unpacked bits, they are usually transported as unsigned char items  
> (giving you a memory overhead of only 8x instead of 32x), so there’s  
> blocks for that particular job (packed\_to\_unpacked and the reverse).

For sure it’s wasteful on memory. I usually just try getting something  
working before optimizing it. Unit tests pass now, thankfully 🙂

So, assuming that I may do this basing my class on the  
sync\_interpolator class, I’d like to pack my input and output -  
ideally as 32 or 64-bit ints (whatever the wordsize is - 64 bits in my  
case). From what I’ve read, I can only expect to pack up to 32-bits  
into each integer-type output item [1], and therefore will  
unfortunately only be able to pack up to 4-bits into each integer-type  
input. Is that correct, or is there also a 64-bit output type?

I guess if I’m packing 4 bits into one byte on the output and 32-bits  
into an int on the output, I would probably just use a sync block with  
a ratio of 1-1, and e.g. add an example to remind the user to use the  
Pack 4 Bits block on the input.

It was an interesting exercise to learn a bit about some of gr’s  
various blocks 🙂

> Since I really _want_ to understand what is happening here, I’ll go

I wrote most of my code snippet when I was 1/2 asleep at 2 am last  
night! Sorry for subjecting you to it!

[1]  
[http://gnuradio.org/redmine/projects/gnuradio/wiki/FAQ#What-are-items-in-a-flowgraph](http://gnuradio.org/redmine/projects/gnuradio/wiki/FAQ#What-are-items-in-a-flowgraph)

---

<div class="post-metadata">

**Author:** ![christophrost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a3d4f5/32.png) [@christophrost](https://www.ruby-forum.com/u/christophrost)\
**Post date:** [January 3, 2015, 10:52pm UTC](https://www.ruby-forum.com/t/4-to-32-bit-symbol-mapper-block/233682/5 "2015-01-03T22:52:00Z")

</div>

Hi Christopher,

On 01/03/2015 09:56 PM, Christopher F. wrote:

> On Sat, Jan 3, 2015 at 1:38 PM, Marcus Müller [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > Then: If I understand you correctly, what you have is an input stream of  
> > unsigned (32 bit)ints, each int containing exactly one bit of information:  
> > 0x00000000, 0x00000001, 0x00000001, 0x00000000, and so forth.  
> > This format is especially wasteful on memory, and wherever GNU Radio  
> > uses unpacked bits, they are usually transported as unsigned char items  
> > (giving you a memory overhead of only 8x instead of 32x), so there’s  
> > blocks for that particular job (packed\_to\_unpacked and the reverse).  
> > For sure it’s wasteful on memory. I usually just try getting something  
> > working before optimizing it. Unit tests pass now, thankfully 🙂  
> > Good approach; I often do premature optimization and end up with  
> > nothing…  
> > So, assuming that I may do this basing my class on the  
> > sync\_interpolator class, I’d like to pack my input and output -  
> > ideally as 32 or 64-bit ints (whatever the wordsize is - 64 bits in my  
> > case).  
> > As you mentioned in IRC, your symbols/chips might contain a maximum of  
> > 32 bit, which would make uint32\_t sufficient. x86\_64 CPUs still deal  
> > with 32 bit ints as efficiently as it does in 32 bit mode, so use  
> > whatever makes sense for your application (or use 64 bit if you might  
> > want to expand).  
> > From what I’ve read, I can only expect to pack up to 32-bits  
> > into each integer-type output item [1], and therefore will  
> > unfortunately only be able to pack up to 4-bits into each integer-type  
> > input. Is that correct, or is there also a 64-bit output type?  
> > Well, the FAQ entry is half-true, only. Basically, GNU Radio knows  
> > nothing of types. We don’t have a convention on how to suffix blocks  
> > that take 64 bit integers, and I guess GRC doesn’t have a color for  
> > them, but other than that, there’s nothing stopping you from using items  
> > of an arbitrary length of bytes (there’s memory reservation issues if  
> > you use things that are hard to page-align, but unless you use items of  
> > say 1023 byte length, this shouldn’t be a problem). This has some  
> > dangerous effects: for example, you can connect a block that produces  
> > float items to a block that consumes 32 bit integers – because these  
> > items have the same size, GNU Radio won’t notice the mixup. Therefore,  
> > the suffix convention explained in that FAQ entry was born.

There’s a lot of blocks that really don’t care about what’s inside an  
item – file\_sink for example just takes the items as memory, and puts  
them into a file. You just have to tell it “hey, expect items of length  
N bytes”; the same goes for many network sinks etc.

On the other hand, you might want to use existing arithmetic blocks on  
these items – in that case, you might be better off using a type that  
they actually know.

> I guess if I’m packing 4 bits into one byte on the output and 32-bits  
> into an int on the output, I would probably just use a sync block with  
> a ratio of 1-1, and e.g. add an example to remind the user to use the  
> Pack 4 Bits block on the input.  
> Well, I agree that memory is most probably not the problem – so it  
> might be easiest to modify your block to take completely unpacked bits  
> in bytes, and using  
> a) a matching output multiple or  
> b) vectors of 4.  
> By the way, b) would be a 4 byte input signature, exactly like you have  
> with your int block, but with different packing scheme (eg. 0x01010101  
> instead of 0x0000000F for the 1111-symbol)
> 
> It was an interesting exercise to learn a bit about some of gr’s  
> various blocks 🙂  
> 🙂 !
> 
> > Since I really _want_ to understand what is happening here, I’ll go  
> > I wrote most of my code snippet when I was 1/2 asleep at 2 am last  
> > night! Sorry for subjecting you to it!  
> > Oh no problem at all, keep it coming! So nice to read something like  
> > that; I’ve written code that used a bit more variables than it needed to  
> > a hundred times, and the fact that I put my own rewrite in the mail was  
> > that I had it at hand, anyway (it’s how I often try to understand  
> > someone else’s code, by slightly rewriting it), it just had to be  
> > formatted a bit nicer. In fact, I think it’s commonly agreed that  
> > although GR has gotten some nice features for digital data (as in hard  
> > symbols) processing over the last two years (PDUs, tagged stream blocks,  
> > the whole messaging/PMT thing), there’s still a lot of room and need for  
> > best practices when it comes to processing bitstreams – so your program  
> > excerpt is, as I assume, useful for the community and development  
> > process.

Greetings,  
Marcus

---

<div class="post-metadata">

**Author:** ![christophrost](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/a3d4f5/32.png) [@christophrost](https://www.ruby-forum.com/u/christophrost)\
**Post date:** [January 3, 2015, 7:39pm UTC](https://www.ruby-forum.com/t/4-to-32-bit-symbol-mapper-block/233682/6 "2015-01-03T19:39:36Z")

</div>

Hi Christopher,

as you noted, this block has a fixed relation between in- and output;  
thus, you can use the sync\_interpolator [1] to get rid of the need to  
write your own forecast and calling consume; you’ll need to override  
work instead of general\_work, which is more comfortable. With the  
set\_output\_multiple[2] you can restrict the possible values of  
n\_output\_items, which are directly proportional to your input items.

Then: If I understand you correctly, what you have is an input stream of  
unsigned (32 bit)ints, each int containing exactly one bit of  
information:  
0x00000000, 0x00000001, 0x00000001, 0x00000000, and so forth.  
This format is especially wasteful on memory, and wherever GNU Radio  
uses unpacked bits, they are usually transported as unsigned char items  
(giving you a memory overhead of only 8x instead of 32x), so there’s  
blocks for that particular job (packed\_to\_unpacked and the reverse).  
However, I’m not completely sure you’re actually doing that, because  
your nested loop with N,k,j,M and i confused me a lot, and I personally  
would avoid doing #defines whenever possible, because compilers are  
smart. (also, I had to look up if it’s well defined to do “j += M, …,  
out += j” in the for loop advancement statement)

Since I really _want_ to understand what is happening here, I’ll go  
ahead and rewrite your outer for loop to increment only one variable,  
and substitute the others in place when used. Please don’t take my usage  
of uint32\_t too serious, I just wanted to make sure I got the data types  
right myself.

work (int noutput\_items, gr\_vector\_const\_void\_star &input\_items,  
gr\_vector\_void\_star &output\_items)

{  
uint32\_t _in = …;  
uint32\_t out = …;  
for(unsigned int nchips = 0; nchips \* M \< noutput\_items; nchips++)  
/ aha, so we’re actually doing one chip per iteration! /  
{  
/ from for loop advancement statement: /  
in += N;  
/ was j/K == j / (M/N) == nchips \* M / M \* N == nchips \* N,  
simplified this._/  
uint32\_t symbol = 0x0;  
for(unsigned int bitcounter=0; bitcounter \< N; i++ )  
{  
int bit = !(!in[bitcounter]); /_this indicates that an input  
item is 0 iff none of the bits are set, else 1_/  
symbol |= bit \<\< bitcounter;  
}  
uint32\_t chip = LUT [symbol];

```
    for(unsigned int i=0; i < M; i++ )

```

{  
uint32\_t bit = ( chip \>\> i ) & 0x1;  
\*(out++) = bit;  
}  
}  
return noutput\_items;  
}

If I’ve (sense-)correctly reproduced your loop, then what you’re doing  
is a sync\_interpolator with an interpolation rate of M/N, and an  
output\_multiple of M, which automatically implies that GNU Radio will  
only call you with N-multiples of input items, if, in your constructor,  
you set the correct io signature (sizeof(uint32\_t)), and call  
set\_output\_multiple(M/N).

I hope this was a little helpful,

Greetings,  
Marcus

[1][GNU Radio Manual and C++ API Reference: gr::sync\_interpolator Class Reference](http://gnuradio.org/doc/doxygen/classgr_1_1sync__interpolator.html#details)  
[2][http://gnuradio.org/doc/doxygen/classgr\_1\_1block.html#a63d67fd758b70c6f2d7b7d4edcec53b3](http://gnuradio.org/doc/doxygen/classgr_1_1block.html#a63d67fd758b70c6f2d7b7d4edcec53b3)
