Forum: GNU Radio Simple block with constant rate

4759c0b9477f73dcf5aa12d5b901571a?d=identicon&s=25 caruiz.ext (Guest)
on 2014-06-25 11:16
(Received via mailing list)
Hello,

I'm doing a block with two inputs (signal and noise) and one output.

Signal input block generates samples sometimes. For example:
2,3,-,-,4,-,-,-,5,1,1,-,4,55...
Noise block generates samples always. For example:
1,1,0,2,2,1,2,3,4,2...

I want to create a block that adds noise to the signal and generate
samples always:

Signal 2,3,-,-,4,-,-,-,5,1,1,-,4,55...
Noise  1,1,0,2,2,1,2,3,4,2,3,4,1,12...

Output 3,4,0,2,6,1,2,3,9,3,4,4,5,67...



I have written this code, what is the fail?

Thank you ;)





#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <gnuradio/io_signature.h>
#include "add_noise_fff_impl.h"

namespace gr {
   namespace howto {

     add_noise_fff::sptr
     add_noise_fff::make()
     {
       return gnuradio::get_initial_sptr
         (new add_noise_fff_impl());
     }

     /*
      * The private constructor
      */
     add_noise_fff_impl::add_noise_fff_impl()
       : gr::block("add_noise_fff",
               gr::io_signature::make(2,2, sizeof(float)),
               gr::io_signature::make(1,1, sizeof(float)))
     {}

     /*
      * Our virtual destructor.
      */
     add_noise_fff_impl::~add_noise_fff_impl()
     {
     }

     void
     add_noise_fff_impl::forecast (int noutput_items, gr_vector_int
&ninput_items_required)
     {
         ninput_items_required[1] = noutput_items;
         //ninput_items_required[0] = 0;
     }

     int
     add_noise_fff_impl::general_work (int noutput_items,
                        gr_vector_int &ninput_items,
                        gr_vector_const_void_star &input_items,
                        gr_vector_void_star &output_items)
     {
         const float *in = (const float *) input_items[0];
         const float *in_noise = (const float *) input_items[1];

         float *out = (float *) output_items[0];


         int j=0;
         int i=0;
         for(;i<noutput_items;++i){
             if(i<ninput_items[0]){
                 ++j;
                 out[i]=in[i]+in_noise[i];
             }
             else
                 out[i]=in_noise[i];
         }

         //consume the inputs
         this->consume(0, j); //consume port 0 input
         this->consume(1, i); //consume port 1 input


         // Tell runtime system how many output items we produced.
         return noutput_items;
     }

   } /* namespace howto */
} /* namespace gr */




***********************************************************************************************




#ifndef INCLUDED_HOWTO_ADD_NOISE_FFF_IMPL_H
#define INCLUDED_HOWTO_ADD_NOISE_FFF_IMPL_H

#include <howto/add_noise_fff.h>

namespace gr {
   namespace howto {

     class add_noise_fff_impl : public add_noise_fff
     {
      private:
       // Nothing to declare in this block.

      public:
       add_noise_fff_impl();
       ~add_noise_fff_impl();

       // Where all the action really happens
       void forecast (int noutput_items, gr_vector_int
&ninput_items_required);

       int general_work(int noutput_items,
           gr_vector_int &ninput_items,
           gr_vector_const_void_star &input_items,
           gr_vector_void_star &output_items);
     };

   } // namespace howto
} // namespace gr

#endif /* INCLUDED_HOWTO_ADD_NOISE_FFF_IMPL_H */
D17685d174fee4ca258c75cce7bc2202?d=identicon&s=25 Marcus Müller (Guest)
on 2014-06-25 11:54
(Received via mailing list)
Hi Caruiz,

you don't even tell us what goes wrong, so it might be hard to answer
your question ;)

Anyway, that's not how GNU Radio really works. For the sample streams,
real time just happens to pass by and has no meaning. So the concept
"generates samples sometimes" doesn't exist in GNU Radio -- it just may
take longer.
There are various factors that determine when your block's general_work
is called. You were right to have the forecast with the
nitems_required[0] = 0; so why did you comment that out?
I guess it was because your block started to run free and basically
never consumed on input stream 1; and that's exactly the problem here:
GNU Radio will always try to call your blocks as often as possible, i.e.
whenever there is space free to put output into and when there is enough
input. Assuming the noise source is fast, and your signal source takes
relatively long times, especially when your CPU is busy generating noise
and passing it through your block, then you will always never consume
signal samples. Even with throttle between the noise source and your
block (beware: NEVER use throttle -- UNLESS you really just need to
reduce the *average* sample rate of a stream), there is absolutely no
reliable correlation between the duration of no-signal samples and real
time passing with signal present.
Just an example: Assume your source produces 100 samples with a sample
rate (that only you know about and GNU Radio doesn't even care about) of
1kS/s, and the next work call of the source takes 0.9s, to produce 100
samples again:
s - - - - - - - - - s - - - - - - - - - s - - - - - - - - - ... [REAL
TIME axis]
There will never ever be 100 samples signal + noise, 900 samples noise
only etc... but
s+n[100] n[121200] s+n[100] n[80000] s+n[100] ....

Because the noise source will produce as fast as possible, and that
means it's only bound by CPU time available and the speed of samples
going through your flow graph.

Please note: real world sampling rate is a concept utterly meaningless
in GNU Radio and is only occasionally used to calculate relative
frequencies.

Greetings,
Marcus
739a038d5a03d5448114b3615e2caedc?d=identicon&s=25 Activecat K. (activecat_k)
on 2014-06-25 12:36
(Received via mailing list)
On Wed, Jun 25, 2014 at 5:15 PM, caruiz.ext <caruiz.ext@catec.aero>
wrote:

> Signal 2,3,-,-,4,-,-,-,5,1,1,-,4,55...
> Noise  1,1,0,2,2,1,2,3,4,2,3,4,1,12...
>
> Output 3,4,0,2,6,1,2,3,9,3,4,4,5,67...
>


I believe your problem could be easily solved.
Let's show us the code that generates the Signal (2,3,-,-,4,....), or
does
it come from a UHD source?
Meanwhile your code above is not correct.
4759c0b9477f73dcf5aa12d5b901571a?d=identicon&s=25 caruiz.ext (Guest)
on 2014-06-25 12:55
(Received via mailing list)
Really clear your explanation Marcus :)

Activecat, my input block
is a variable delay.

- I have a signal recorded in a file.

- Signal
enters in a variable delay (delay is controlled by another block).
-
Signal enters in Add noise block.

File --> Variable delay --> Add
noise --> out

My problem is that if variable delay is, for example, 5
samples: a sample enters, the block "waits" 5 samples, the sample
leaves. Then my output is: sample_3,- , - , - , - , - ,sample_2 , - , -
, - , - , - , sample_1

Greetings
4759c0b9477f73dcf5aa12d5b901571a?d=identicon&s=25 caruiz.ext (Guest)
on 2014-06-25 13:33
(Received via mailing list)
Ahh, the problem! :S

When I run the flow graph, it dies...

**I
use GRC and my final block is a GUI Scope Sink.
739a038d5a03d5448114b3615e2caedc?d=identicon&s=25 Activecat K. (activecat_k)
on 2014-06-25 17:31
(Received via mailing list)
On Wed, Jun 25, 2014 at 6:53 PM, caruiz.ext <caruiz.ext@catec.aero>
wrote:

> sample_3,- , - , - , - , - ,sample_2 , - , - , - , - , - , sample_1
>
>

Could you please explain how did you build the "variable delay", do you
use
the built-in "delay" block?
If this is a custom delay block, please show your code.

Meanwhile your understanding about the delay block is wrong.
Says, the input is:  s1, s2, s3, s4, s5.
After going through the delay block (with delay=5), the output becomes:
0,
0, 0, 0, 0, s1, s2, s3, s4, s5.
The output of delay block will never be "-" but it could be "0" (zero).

Probably you just need the standard "Add" block instead of your custom
block above.
Could you try this first..?
4759c0b9477f73dcf5aa12d5b901571a?d=identicon&s=25 caruiz.ext (Guest)
on 2014-06-25 18:05
(Received via mailing list)
Monday I will post the code (I have it in the lab).

Thank you ;)


El 25-06-2014 17:29, Activecat escribió:

> On Wed, Jun 25, 2014 at
6:53 PM, caruiz.ext <caruiz.ext@catec.aero> wrote:
>
>> Activecat, my
input block is a variable delay.
>>
>> - I have a signal recorded in a
file.
>>
>> - Signal enters in a variable delay (delay is controlled
by another block).
>> - Signal enters in Add noise block. File -->
Variable delay --> Add noise --> out
>>
>> My problem is that if
variable delay is, for example, 5 samples: a sample enters, the block
"waits" 5 samples, the sample leaves. Then my output is: sample_3,- , -
, - , - , - ,sample_2 , - , - , - , - , - , sample_1
>
> Could you
please explain how did you build the "variable delay", do you use the
built-in "delay" block?
> If this is a custom delay block, please show
your code.
>
> Meanwhile your understanding about the delay block is
wrong.
> Says, the input is: s1, s2, s3, s4, s5.
> After going through
the delay block (with delay=5), the output becomes: 0, 0, 0, 0, 0, s1,
s2, s3, s4, s5.
> The output of delay block will never be "-" but it
could be "0" (zero).
>
> Probably you just need the standard "Add"
block instead of your custom block above.
> Could you try this
first..?
4759c0b9477f73dcf5aa12d5b901571a?d=identicon&s=25 caruiz.ext (Guest)
on 2014-07-01 12:19
(Received via mailing list)
Attachment: delay_cola_fff_impl.cc (6 KB)
Attachment: delay_cola_fff_impl.h (2 KB)
Hi there,

I have modified my block. Now it works well for 10-15
seconds and then dies.

My block have two inputs:

- Signal

- Control
delay: number of samples to delay

And one output:

- New signal

In the
image example:

** Current delay = 0

---> Delay = 1

current_delay <
delay ->delay of 1 sample

I insert a virtual sample (linear
interpolation)

I sent the next sample (2)

current_delay = 1

--->
Delay = 1

current_delay = delay -> nothing

I send the next sample
(3)
 current_delay = 1

---> Delay = 1

current_delay = delay ->
nothing

I send the next sample (4)
 current_delay = 1

---> Delay =
2

current_delay < delay -> delay of 1 sample (delay-current_delay)

I
insert a virtual sample
I send the next sample (5)
 current_delay =
2

---> Delay = 1

current_delay > delay ->ADVANCE 1 sample

I delete a
sample (6)

I send the next sample (7)
 current_delay = 1

Attach the
code.

*** The value of control block is about 400000

Thank you ;)
739a038d5a03d5448114b3615e2caedc?d=identicon&s=25 Activecat K. (activecat_k)
on 2014-07-01 15:31
(Received via mailing list)
On Tue, Jul 1, 2014 at 6:17 PM, caruiz.ext <caruiz.ext@catec.aero>
wrote:
>
>   ---> Delay = 1
> current_delay < delay ->delay of 1 sample
> I insert a virtual sample (linear interpolation)
> I sent the next sample (2)
> current_delay = 1
>

I don't understand what this means.


>   ---> Delay = 1
>  current_delay = delay -> nothing
> I send the next sample (3)
> current_delay = 1
>



My comments:

1).  I see no reason that "q", "inicio", "sample_rate" and "delay"
should
be defined as public class variables, rather than private.

2).  You make this a general block that always consumes and returns the
same value.  This is similar to a sync block.
      But a delay block is not a sync block.

3).  Basically what a delay block does is just to copy "input[i]" to
"output[ i + delay ]", this creates an effect of delaying the signal.
      You don't need to create a std::queue to perform delay.

4).  The definition of "Sample" class, if it is really needed, should be
placed in separate file.

5).  Your always forecast 1 input item, but in general_work() you always
consumes and access the input buffer as if its length is always not
smaller
than noutput_items.
      (you forget the memory boundary) This is fatal.

6).  I don't understand your attached picture.
      I also don't understand your requirement.


You have written a code (delay_cola_fff) that is wrong from the ground
up.
The only way to help you is to understand your requirement and suggest
something else from scratch.
Unfortunately I fail to understand your requirement.

I suggest you to look into the source code of the existing "Delay"
block,
and start from there.
739a038d5a03d5448114b3615e2caedc?d=identicon&s=25 Activecat K. (activecat_k)
on 2014-07-01 16:15
(Received via mailing list)
On Tue, Jul 1, 2014 at 9:30 PM, Activecat <activecat@gmail.com> wrote:

> I don't understand what this means.
> My comments:
>       You don't need to create a std::queue to perform delay.
>       I also don't understand your requirement.
>
Meanwhile, you shouldn't have skipped the unittest from the very
beginning.
The unittest will show you that this block (delay_cola_fff) doesn't work
accordingly.
There is no point to go further unless this block has passed its
unittest.
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.