discuss-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Discuss-gnuradio] 4-to-32 bit symbol mapper block


From: Marcus Müller
Subject: Re: [Discuss-gnuradio] 4-to-32 bit symbol mapper block
Date: Sat, 03 Jan 2015 19:38:16 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0

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]http://gnuradio.org/doc/doxygen/classgr_1_1sync__interpolator.html#details
[2]http://gnuradio.org/doc/doxygen/classgr_1_1block.html#a63d67fd758b70c6f2d7b7d4edcec53b3

On 01/03/2015 06:40 PM, Christopher Friedt wrote:
> 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;
>
> _______________________________________________
> Discuss-gnuradio mailing list
> address@hidden
> https://lists.gnu.org/mailman/listinfo/discuss-gnuradio




reply via email to

[Prev in Thread] Current Thread [Next in Thread]