Sample wise execution of blocks in grc flow graph?

Hi,

I have made a custom block derived from gr_block which has two inputs.
First input comes at a sampling rate of 20 samples/sec while the other
input comes from the gr_noise_source block. Now, my question is: what
will be the sampling rate at my custom block output? Is it also 20
samples/sec? If not then how can I make it 20 samples/sec. Also, my
custom block needs to operate on sample by sample basis not on chunks of
noutput_items. In other words, the custom block should produce an output
sample after every 50mS (and not before) when both inputs arrive and
that output value then should stay there for another 50mS until next
input samples for two inputs arrive and new output is computed.

Thanks in anticipation,
H.

Hi Henry,

GNU Radio, as far as I understand, does not have a concept of time. It
will
try to process samples as quickly as they are available. If your input
sample is arriving every 50mS then a sample should be produced by your
block
shortly after the 50mS arrival mark.

What do you mean, the output value should stay there? The output value
is
shipped off to some other block that connects to yours.

–Colby

Hi Colby,

So it means that it if one input comes at 20 samples/sec then it limits
the output rate of my custom block to exactly 20 samples/sec? That is,
the other input, gr_noise_source can provide samples at a rate faster
than 20 samples/sec to the custom block input but the custom block
produces output only when both inputs are available. Am I right?

I am sorry for not being clear about the other part of question. The
question is that if I further multiply the output of the custom block
(which has a sample rate of 20 samples/sec) with another signal of
sampling rate 2M samples/sec then what will be the sampling rate of the
product signal? If it will be 2M samples/sec then will the custom block
output sampled at 2M samples/sec have 1 non-zero sample followed by
100,000-1 zeros or will the custom block hold its output value to repeat
it 100,000 times until the next sample arrives after 50mS?

Thanks a lot,
H.

Hi Henry,

GNU Radio, as far as I understand, does not have a concept of time. It
will try to process samples as quickly as they are available. If your
input sample is arriving every 50mS then a sample should be produced by
your block shortly after the 50mS arrival mark.

What do you mean, the output value should stay there? The output value
is shipped off to some other block that connects to yours.

–Colby

On Tue, Jun 14, 2011 at 10:35 PM, Henry M. [email protected]
wrote:

Hi,

On Tue, Jun 14, 2011 at 11:31 PM, Henry M. [email protected]
wrote:

has a sample rate of 20 samples/sec) with another signal of sampling rate 2M
Hi Henry,

words, the custom block should produce an output sample after every 50mS
Discuss-gnuradio Info Page

If in your custom block you require a sample each from your 20
sample/sec
and other source (in this case noise) to produce one output sample, then
the
block will output samples at about ~20 sample/sec. I believe this is
default
behaviour for the gr_sync blocks?

In the case of the multiplication block, it will be done on a sample by
sample basis. If a 20 sample/sec and a 2MSample/sec block are put into a
multiplication block, then the output will be 20 sample/sec. HOWEVER,
this
is a very bad idea because the 2Msamp source will backup and over flow
because the samples arrive at 2 orders faster than the other source. You
need to rate match the two sources in this situation or things will
probably
crash.

Remember in the world of digital samples, the absolute rate of a signal
does
not mean anything. Only the relative rates between different signal
streams
mater, i.e. stream A produces samples twice as fast as stream B, etc.
The
absolute rate only matters when you want to relate a digital signal to
the
analog world.

–Colby

On Wed, Jun 15, 2011 at 1:31 AM, Henry M. [email protected]
wrote:

Hi Colby,

So it means that it if one input comes at 20 samples/sec then it limits the
output rate of my custom block to exactly 20 samples/sec? That is, the other
input, gr_noise_source can provide samples at a rate faster than 20
samples/sec to the custom block input but the custom block produces output
only when both inputs are available. Am I right?

Yes, the custom block will execute its general_work() function only when
the
right number of input items are available on all the input streams.

I am sorry for not being clear about the other part of question. The
question is that if I further multiply the output of the custom block (which
has a sample rate of 20 samples/sec) with another signal of sampling rate 2M
samples/sec then what will be the sampling rate of the product signal?

Look at the general_work() function for the simplest of blocks such as
gr_add_cc etc to understand the behaviour. Look at the following
example. In
this I am producing 1/4th the number of input items I am using. I am
sending
out every 4th input sample to the output, and effectively reducing the
sampling rate by 4. So as long as the input is available I keep sending
every 4th item to the output. If the input doesn’t arrive then the
executing
thread waits until it has something to work with.

int
custom_block_b::general_work(int noutput_items,gr_vector_int
&ninput_items,gr_vector_const_void_star &input_items,gr_vector_void_star
&output_items)
{
const unsigned char *in = (const unsigned char *)input_items[0];
unsigned char *out = (unsigned char *)output_items[0];
int j=0;
for(int i=0;i<noutput_items;i++) {
if(i%4==0){
out[j] = in[i];
j++;
}

The output rate is determined by your work function. In the following
code I
am producing more output than what I am using at the input.

int
custom_block_b::general_work(int noutput_items,gr_vector_int
&ninput_items,gr_vector_const_void_star &input_items,gr_vector_void_star
&output_items)
{
const unsigned char *in = (const unsigned char *)input_items[0];
unsigned char *out = (unsigned char *)output_items[0];
int j=0;
int k=0;
for(int i=0;i<noutput_items;i++) {
if(in[i]==0x00){
for (int j=0;j<4;j++){
out[k]=in[i] ;
k++;
}
else{
for(int j=0;j<4;j++){
out[k]=~in[i];
k++;
}
}

consume(noutput_items);
return k;
}

As Colby has already mentioned, you must be careful about having
mismatched
rates.

I hope this helps.

Hi John and Colby,

Thanks for the detailed and helpful replies about the sampling rates.
Now, I have another issue which is unclear to me. I am printing out
“noutput_items” for my custom block which come out to be either 1 or 2.
As I mentioned before, the custom block is intended to do sample by
sample calculation, i.e., for an input sample it calculates the output
sample which is then transmitted by the a usrp to another usrp which
sends a feedback to first usrp; that feedback, after some processing
goes into the input of the custom block. So, you can imagine that I am
kind of running my algorithm iteratively. Now, question is that how can
I force noutput_items=1? Apparently it seems to me if noutput_items is
set to 2 then scheduler will wait for the arrival of second input sample
to compute two output samples at the same time but what I want from
scheduler is to compute a single output sample, no less and no more. So,
if the input to the custom block is coming at a
rate of 20 samples/sec, how frequent will work() or general_work be
called? Also, if during a call to work(), noutput_items comes out to be
“n” (more than 1) then it computes “n” output samples at the same time
which I do not want. I want to generate 1 sample, send it, wait for the
feedback, and then after arrival of feedback compute the new output
sample from custom block and so on. How to do it? Any ideas?

Thanks a lot,

H.


From: John A. [email protected]

On Wed, Jun 15, 2011 at 1:31 AM, Henry M. [email protected]
wrote:

Hi Colby,

So it means that it if one input comes at 20 samples/sec then it limits the
output rate of my custom block to exactly 20 samples/sec? That is, the other
input, gr_noise_source can provide samples at a rate faster than 20 samples/sec to
the custom block input but the custom block produces output only when both inputs
are available. Am I right?

Yes, the custom block will execute its general_work() function only when
the right number of input items are available on all the input streams.

I am sorry for not being clear about the other part of question. The question is
that if I further multiply the output of the custom block (which has a sample rate
of 20 samples/sec) with another signal of sampling rate 2M samples/sec then what
will be the sampling rate of the product signal?

Look at the general_work() function for the simplest of blocks such as
gr_add_cc etc to understand the behaviour. Look at the following
example. In this I am producing 1/4th the number of input items I am
using. I am sending out every 4th input sample to the output, and
effectively reducing the sampling rate by 4. So as long as the input is
available I keep sending every 4th item to the output. If the input
doesn’t arrive then the executing thread waits until it has something to
work with.

int
custom_block_b::general_work(int noutput_items,gr_vector_int
&ninput_items,gr_vector_const_void_star
&input_items,gr_vector_void_star &output_items)
{
const unsigned char *in = (const unsigned char *)input_items[0];
unsigned char *out = (unsigned char *)output_items[0];
int j=0;
for(int i=0;i<noutput_items;i++) {
if(i%4==0){
out[j] = in[i];
j++;
}

The output rate is determined by your work function. In the following
code I am producing more output than what I am using at the input.

int
custom_block_b::general_work(int noutput_items,gr_vector_int
&ninput_items,gr_vector_const_void_star
&input_items,gr_vector_void_star &output_items)
{
const unsigned char *in = (const unsigned char *)input_items[0];
unsigned char *out = (unsigned char *)output_items[0];
int j=0;
int k=0;
for(int i=0;i<noutput_items;i++) {
if(in[i]==0x00){
for (int j=0;j<4;j++){
out[k]=in[i] ;
k++;
}
else{
for(int j=0;j<4;j++){
out[k]=~in[i];
k++;
}
}

consume(noutput_items);
return k;
}

As Colby has already mentioned, you must be careful about having
mismatched rates.

I hope this helps.

Hello all,

Lately, I am experimenting with an implementation of a point-to-point
On-off Keying communication system. I mostly prefer to use the USRP as
the receiver, in which I can capture samples and later process them
through Matlab. However, because of the algorithms I try to apply at the
receiver (packet/symbol synchronization, channel estimation,
carrier-frequency offset cancellation, detection) I have to deal with a
lot of delay at the receiver processing part. As a result, my
transmitter keeps sending packets which will either get lost or stored
at the fifo.

Therefore, I would like to know, if it is possible to construct a second
buffer (softwarely in Matlab) in order not to lose so many data packets.
Does anyone have an intuition about the way the fifo is used?

Thanks,
GS


Sklivanitis Georgios
M.Sc. Student
Telecommunications Division,
Department of Electronics and Computer Engineering
Technical University of Crete,
Kounoupidiana Campus, Office 145.A10
Chania, Crete, 73100, Greece
Tel. : 28210 59257
www.telecom.tuc.gr/~gsklivanitis

On Wed, Jun 15, 2011 at 03:27:18PM -0700, Henry M. wrote:

two output samples at the same time but what I want from scheduler is to
compute a single output sample, no less and no more. So, if the input to the
custom block is coming at a rate of 20 samples/sec, how frequent will work() or
general_work be called? Also, if during a call to work(), noutput_items comes
out to be “n” (more than 1) then it computes “n” output samples at the same
time which I do not want. I want to generate 1 sample, send it, wait for the
feedback, and then after arrival of feedback compute the new output sample from
custom block and so on. How to do it? Any ideas?

Hi Henry,

some thoughts:

noutput_items is the number of items your block is expected to
produce. You can always choose to translate 1 input sample into 1
output sample and then exit the work() function. Simply end your
work() function with ‘return 1;’.
(You should be using a gr_sync_block, not a gr_block, for this!)
Something like:
int block::work(…)
{
const unsigned char *in = &input_items[0];
unsigned char *out = &output_items[0];

*in = f(*out); // Where f(x) is what you do
return 1;
}

Still, I don’t think this will help you and actually, I’m not sure you
understood what Colby and John have been trying to say.
GNU Radio does not have a concept of time and sampling frequencies.

You make it sound like precisely clocked elements in digital circuitry,
but GNU Radio kind of randomly assigns processor time to each block, you
have no real way to influence when it is actually run!
So, to say your block has a sampling rate of x is completely
meaningless for its guts. This is what you need for most kind of signal
processing, anyway.
So, to answer your question: work() or general_work() are called at
random times, whenever the GNU Radio scheduler decides there’s enough
stuff in the input buffer of your block. You won’t know when. Neither in
sample time, nor in real time.

For this reason, feedback loops are very difficult to implement. A
feedback loop inside a flow graph is not even possible.
Via air, it might be doable–but I don’t recommend actually using GNU
Radio for this, at least not at this state of the code.

If you’re familiar with real-time programming (i.e. writing code where
instructions get executed at a guaranteed timing) you might even write a
custom application that uses UHD.
If you’re not used to doing this, the only other option I can think of
is a pact with the devil: Matlab/Simulink has realtime capabilities and
supports feedback loops.

Good luck,
MB

From: John A. [email protected]
output rate of my custom block to exactly 20 samples/sec? That is, the

out every 4th input sample to the output, and effectively reducing the sampling
unsigned char *out = (unsigned char *)output_items[0];
int
for (int j=0;j<4;j++){
consume(noutput_items);


Discuss-gnuradio mailing list
[email protected]
Discuss-gnuradio Info Page


Karlsruhe Institute of Technology (KIT)
Communications Engineering Lab (CEL)

Dipl.-Ing. Martin B.
Research Associate

Kaiserstraße 12
Building 05.01
76131 Karlsruhe

Phone: +49 721 608-43790
Fax: +49 721 608-46071
www.cel.kit.edu

KIT – University of the State of Baden-Württemberg and
National Laboratory of the Helmholtz Association