State Machine that drops samples (Problems with return and consume_each in general_work)

Dear all,

I’m trying to implement a simple state machine to receive bursty data
and
write it in a file.

To accomplish this I have created a general block that accepts complex
samples and has two states:

0 - Just drops data. If one of the samples is 0, go to state 1.

1 - Copy inputs to outputs. If one of the samples is 1, go to state 0.

I will use this block in the future to wrap another more complex signal
processing block that will generate a proper parameter for state
transition.

However I’m failing to make even this simple one work. Here’s my
general_work:


    for (int i = 0; i < noutput_items; i++) {

      currentState = nextState;

      if(in[i] == std::complex<float> (0,0)){

        if(currentState == 0){
          nextState = 1;
          consume_each(i);
          return 0;

        }

        if(currentState == 1){
          for (int j = 0; j < i; j++) {
            out[j] = in[j];
          }
          nextState = 0;
          consume_each(i);
          return i;
        }

      }

    }

    if (currentState == 0){
      consume_each (noutput_items);
      return 0;
    }

    if (currentState == 1){
      for (int j = 0; j < noutput_items; j++) {
        out[j] = in[j];
      }
      consume_each (noutput_items);
      return noutput_items;
    }

Here’s what it does:

  1. Receive new state

  2. Checks for state transition condition. If true:

2A) If it’s in state 0: Change state to 1, consume all inputs processed
so
far (which makes non-processed inputs to go back to the queue in the
next
call of general_work, correct?) and returns 0 (which is equivalent to
not
generating outputs, right?)

2B) If it’s in state 1: Same as 2A, but copy ( i ) inputs to the output
(number of samples before state transition happens) and returns i
samples.

  1. If the loop ends without any state transition, the same thing that
    happened in 2A) and 2B) is executed, however noutput_items are
    processed/consumed/returned instead.

I’m testing this block in the attached flow graph, however the generated
file is blank. Both nextState and currentState are private attributes of
the block and are initialized in the constructor with 0.

My questions are:

  1. Am I misunderstanding the way consume_each and return works?

  2. What should I do with the forecast() function? I cannot guarantee
    that
    any numbers of inputs will actually produce an output.

  3. Is this really the best way to accomplish what I want?

Thank you all for your assistance,

Dear all,

I was able to fix the problem.

Fist I had forecast set to a big number and vector sink was unable to
provide such amount of inputs. I changed that to
ninput_items_required[0]=
noutput_items, not sure if it’s the correct relation thought. But the
block
still didn’t work.

Apparently I was not consuming the item responsible for the state
transition, so general_work was in an infinite loop. Changing
consume_each(i) to consume_each(i+1) did the trick.

Finally, for some reason I had to delete the blank file generated by
past
iterations of the program manually and a correct one was created. Now I
don’t need to do that any more, but watch out if you are using Ubuntu
14.04.

Here is the (apparently) working code:

    for (int i = 0; i < noutput_items; i++) {

      currentState = nextState;
      std::cout << noutput_items << std::endl;
      std::cout << "\nin[i]: " << in[i] << std::endl;


      if(in[i] == std::complex<float> (0,0)){

        if(currentState == 0){
          std::cout << "\nstatezero" << std::endl;
          nextState = 1;
          consume_each(i+1);
          return 0;

        }

        if(currentState == 1){
          std::cout << "\nstateone" << std::endl;
          for (int j = 0; j < i; j++) {
            out[j] = in[j];
          }
          nextState = 0;
          consume_each(i+1);
          return i;
        }

      }

    }

    if (currentState == 0){
      std::cout << "\nFinishing loop in state zero" << std::endl;
      consume_each (noutput_items);
      return 0;
    }

    if (currentState == 1){

      for (int j = 0; j < noutput_items; j++) {
        out[j] = in[j];
      }
      consume_each (noutput_items);
      std::cout << "\nnFinishing loop in state one" << std::endl;
      return noutput_items;
    }

BTW there was a typo in my original email, both state transitions use
the
same condition.

Thank you very much for your attention,