# Using general\_work when output rate is not fixed

**URL:** <https://www.ruby-forum.com/t/using-general-work-when-output-rate-is-not-fixed/222763>\
**Category:** GNU Radio\
**Created:** [September 10, 2012, 1:01am UTC](https://www.ruby-forum.com/t/using-general-work-when-output-rate-is-not-fixed/222763 "2012-09-10T01:01:57Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![aris](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/258eb7/32.png) [@aris](https://www.ruby-forum.com/u/aris)\
**Post date:** [September 10, 2012, 1:01am UTC](https://www.ruby-forum.com/t/using-general-work-when-output-rate-is-not-fixed/222763/1 "2012-09-10T01:01:57Z")

</div>

All,

I have made a simple custom block (derived from gr\_block class) whose  
general\_work() function is given below:

int howto\_my\_custom\_blk::general\_work (int noutput\_items, gr\_vector\_int  
&ninput\_items, gr\_vector\_const\_void\_star &input\_items,  
gr\_vector\_void\_star &output\_items){  
const gr\_complex \*in = (const gr\_complex \*) input\_items[0];  
const short \*trigger = (const short \*) input\_items[1];  
gr\_complex \*out = (gr\_complex \*) output\_items[0];

int ninput\_items\_used\_in\_this\_work\_call;  
ninput\_items\_used\_in\_this\_work\_call = 0;

for (int i = 0; i \< noutput\_items; i++){  
if (trigger[i] \> 0) {  
out[i] = in[i];  
ninput\_items\_used\_in\_this\_work\_call++;  
if (!tx\_sob\_sent) { this-\>make\_sob\_tag(this-\>nitems\_written(0)

- i); tx\_sob\_sent = true; tx\_eob\_sent = false;}

Some comments about the block ports:  
In above custom block code,

- in is an input which comes from uhd\_usrp\_source and consists of set of  
packets sent by some packet transmitter.
- trigger is an input which goes high (\>0) every time a packet is  
detected and remains high thereafter for the duration of packet. It is  
essentially Tom’s energy detection mechanism borrowed from  
uhd\_burst\_detector.py.
- out is the block output which goes to uhd\_usrp\_sink.  
In short, my custom block receives a set of packets and forwards it to  
the tx side of the usrp.

Now, I have some questions which are as follows:

- When trigger goes high, the input samples at in (which correspond to  
the received packet) should be copied to the output and then sent to the  
uhd\_usrp sink. But this is not the case, as I see using the external  
oscilloscope (and by recording the output out of the block into a file)  
that instead the noise samples are copied to output. Why it is so?
- As can be seen, general\_work() returns  
ninput\_items\_used\_in\_this\_work\_call every time it is called by  
scheduler. Since trigger remains low most of the time, it means  
general\_work() will produce no output samples most of the times it is  
called. But the output port out is connected to uhd\_usrp\_source which  
will produce underruns every time my custom block does not produce an  
output. I have put sob and eob tags to eliminate this problem but did  
not succeed. Any ideas, what might be wrong?
- Since my custom block is not a fixed ratio block, how should I  
override the forecast function, or, is it optional and meant for  
efficiency purposes?

Thanks,  
Mahboob

---

<div class="post-metadata">

**Author:** ![RahmanS\_Muhammad\_Ma](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/df788c/32.png) [@RahmanS\_Muhammad\_Ma](https://www.ruby-forum.com/u/RahmanS_Muhammad_Ma)\
**Post date:** [September 15, 2012, 4:29pm UTC](https://www.ruby-forum.com/t/using-general-work-when-output-rate-is-not-fixed/222763/2 "2012-09-15T16:29:20Z")

</div>

On Sun, Sep 9, 2012 at 6:39 PM, Rahman, Muhammad Mahboob Ur  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> gr\_complex \*out = (gr\_complex \*) output\_items[0];
> 
> ```
> }
> else {
> if (!tx_eob_sent) { this->make_eob_tag(this->nitems_written(0) +
> 
> ```
> 
> i-1); tx\_eob\_sent = true; tx\_sob\_sent = false; }  
> }  
> }  
> consume\_each (ninput\_items[0]);
> 
> return ninput\_items\_used\_in\_this\_work\_call;  
> }

Hi Mahboob,

I would consume\_each(noutput\_items) since ninput\_items[0] \>=  
noutput\_items (I’m guessing you are using the standard forecast  
function), but you are only looking over noutput\_items in your for  
loop. So you might have more inputs available that you are looking at  
and by consuming all of the inputs, you might be dropping data. So  
look at that and see if it solves your main problem.

The other thing is that the way we handled it in the burst detector  
was that we send a tag once when the burst signal goes high and then  
another when it goes low. It looks like you are sending a tag every  
time trigger \> 0, which could mean you will be sending a lot of tags  
through the system, which can be expensive. This is an optimization  
for the scheduler, but a pretty big one since moving  
hundreds/thousands of tags a second through the scheduler will  
significantly impact the performance.

Hope this helps,  
Tom

---

<div class="post-metadata">

**Author:** ![RahmanS\_Muhammad\_Ma](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/df788c/32.png) [@RahmanS\_Muhammad\_Ma](https://www.ruby-forum.com/u/RahmanS_Muhammad_Ma)\
**Post date:** [September 25, 2012, 6:03pm UTC](https://www.ruby-forum.com/t/using-general-work-when-output-rate-is-not-fixed/222763/3 "2012-09-25T18:03:27Z")

</div>

Hi Tom & All,

I am now doing consume\_each(noutput\_items) but my problem is not solved  
yet. I have also made sure that my code effectively sends one sob tag  
and one eob tag per burst of samples.

Questions about new experiment:  
Now, I have created yet another simple experiment whose flow-graph is as  
follows:

uhd usrp source --\> my custom block --\> uhd usrp sink  
|  
–\> file sink

The relevant code of my custom block is below:  
int  
howto\_send\_discont::general\_work (…) {

int ninput\_items\_used\_in\_this\_work\_call;  
ninput\_items\_used\_in\_this\_work\_call = 0;

for (int i = 0; i \< noutput\_items; i++){

```
samp_count++;
if (samp_count == 1) { out[i] = gr_complex(0.7,0); 

```

this-\>make\_sob\_tag(this-\>nitems\_written(0)+i);}  
else if (samp\_count == 2) { out[i] = gr\_complex(0.7,0);  
this-\>make\_eob\_tag(this-\>nitems\_written(0)+i);}  
else if (samp\_count == 25000) {  
samp\_count = 0; send\_tx\_pkt = true; pkt\_no++; }  
if (send\_tx\_pkt) {  
pkt\_samp\_no++;  
ninput\_items\_used\_in\_this\_work\_call++;  
/_if (total\_samps\_outputted\_so\_far == 7761) {  
pkt\_samp\_no = 1; samp\_count = 1;  
total\_samps\_outputted\_so\_far = 10000; pkt\_no = 0; }  
else if (total\_samps\_outputted\_so\_far \< 7761){  
total\_samps\_outputted\_so\_far++; }_/  
out[i] = gmsk\_pkt\_samples\_2[pkt\_samp\_no-1];  
if (pkt\_samp\_no == 1) {  
this-\>make\_sob\_tag(this-\>nitems\_written(0)+i);  
}  
else if (pkt\_samp\_no == 1536) {  
this-\>make\_eob\_tag(this-\>nitems\_written(0)+i);  
pkt\_samp\_no = 0;  
send\_tx\_pkt = false;  
}  
}

}

consume\_each (noutput\_items);

// Tell runtime system how many output items we produced.  
return ninput\_items\_used\_in\_this\_work\_call;  
}

You can see from the above code that my custom block maintains an  
internal counter samp\_count which causes the custom block to output N  
samples whenever internal counter’s count equals M (N=1536, M=25000 in  
my case). I use the same counter to initially send a burst of 2 samples  
to uhd usrp sink after attaching sob and eob tags so as to avoid  
underflow problem at the transmit side. But my problems are persistent  
which are:

- I see many zero-valued samples among the first 7761 output samples of  
my custom block, even when the samples my custom block should output are  
either constant valued samples or pre-recorded GMSK samples (depending  
upon which line is uncommented in my above code). Why it is so?

- Even though I have avoided the above mentioned problem by noticing  
that in my case, after first 7761 samples, all the subsequent samples  
are correct. So, I use another counter to start all over again (to reset  
the functionality of my block) once my custom block has sent 7761  
samples to uhd usrp sink. Now, the other issue is, when I send  
pre-recorded GMSK samples to the uhd usrp sink, I still see lot of  
underruns occuring indefinitely at tx side. Why are the sob and eob tags  
being ineffective? Moreover, when those GMSK packets are received at  
another node, the packet decode rate is too low over there (I guess not  
all of the samples corresponding to many GMSK packets are being  
transmitted from node1, fix me).

Thanks in anticipation for your help,  
Mahboob
