discuss-gnuradio
[Top][All Lists]
Advanced

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

forecast() function usage with static addition of bits


From: John Moon
Subject: forecast() function usage with static addition of bits
Date: Thu, 25 Jan 2024 18:30:16 +0000

Hi,

I'm trying to write an OOT Python block which takes an input "packet" of bytes 
and outputs a longer "packet" of bytes. This is an implementation of an 
error-correcting code which adds a static 64 bytes to the input.

The input is able to operate on 1 byte up to 63 bytes. When it gets 1 byte in, 
I'd expect 65 bytes to come out. When it gets 63 bytes in, I'd expect 127 bytes 
to come out, so n_output_items should always be n_input_items + 64.

I'm having trouble expressing this kind of block in GR. Here's a minimal 
version of what I have:

============

class encoder(gr.basic_block):
    def __init__(self):
        gr.basic_block.__init__(self, name="encoder", in_sig=[np.uint8], 
out_sig=[np.uint8])

        self.logger = gr.logger(self.alias())

        self.msg_len = 63
        self.block_len = 127
        self.set_min_noutput_items(self.msg_len + 2)
        self.set_max_noutput_items(self.block_len)

    def fixed_rate(self):
        return True

    def fixed_rate_noutput_to_ninput(self, noutput_items):
        return noutput_items - self.msg_len - 1

    def fixed_rate_ninput_to_noutput(self, ninput_items):
        return ninput_items + self.msg_len + 1

    def forecast(self, noutput_items, ninputs):
        # This block will take in N bytes and output N + msg_len + 1 bytes, so 
the minimum
        # input we need is 1 + msg_len + 1 and the max is 1 + RS_BLOCK_LEN + 1. 
So, say
        # GR wants us to produce y output items. y = x + msg_len + 1, where x 
is the
        # number of input items. So, generally, x = y - msg_len - 1.
        ninput_items_required = self.fixed_rate_noutput_to_ninput(noutput_items)
        print(f"FORECAST: for {noutput_items} outputs, {ninput_items_required} 
inputs are required")
        return [ninput_items_required] * ninputs

    def general_work(self, input_items, output_items):
        in0 = input_items[0]
        out = output_items[0]
        self.logger.info(f"Input is {len(in0)} symbols")
        self.logger.info(f"Output buffer is {len(out)} symbols")

        out.fill(0)
        self.consume(0, len(in0))
        return len(out)

============

I believe the forecast() function is doing what it's supposed to be doing, but 
I'm puzzled by the inputs it's getting. From the debug prints, I can see that 
the "noutput_items" being passed to forecast() goes: 127, 63, 31, 15, 7, 3, 1. 
So, halving the number of outputs requested each time. I have three questions 
about this:

1. Why would the GR scheduler try to forecast for outputs smaller than the 
"min_noutput_items()" I set in the constructor?
2. Is there a way (from the forecast function) to tell the scheduler a 
particular noutput_items is invalid?
3. What happens to the buffer sizes for inputs that aren't forecasted for? E.g, 
if I pass in 1 byte to my block, I'd expect 65 outputs, but I don't see that 
output being forecasted.

I'm relatively new to GR, so apologies for any blatant misunderstandings and 
thank you so much for your time!

- John



reply via email to

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