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