Massi1987
Massi1987

Reputation: 91

How do I read byte output data of GRC block "Random Source" into own OOT-block in c++ correctly?

I'm doing my first steps in gnuradio-companion and want to code my own out-of-three blocks in c++ for signal processing. I worked through the gnuradio tutorial and have some knowledge of c++ but I'm not an expert.

Sytem setup: Ubuntu 18.04.2 LTS GNU Radio-Companion 3.7.13.4

I want to use the grc-block "Random Source" to generate bytes and pass them to an interpolator out-of-three block that will create a pulse position symbol.

The "Random Source" block is configured as followed: Min: 0 Max: 4 (which is 2^M = count of pulse positions in a ppm symbol) Num Samples: 16 or 32 Repeat: Yes

My out-of-three block is an interpolation block in c++ and has one input and one output. The interpolation value in the constructor is 6000 which mean the relation ship for input:output is 1:6000. A function get the input in[0] as parameter and generate a vector of type gr_complex with the pulse at the position of the value of in[0] which can be [0, 1, 2, 3]. The vector with the ppm symbol will be returned to the work()-function.

Observed problems: First problem: if the "Random Source" generate a byte with the value 0x00 and I use std::cout to print the value of in[0] the following error is displayed in the terminal window that is running gnuradio-companion:

/home/xyz/software/gnuradio/lib/python2.7/dist-packages/gnuradio/grc/gui/Dialogs.py:65: GtkWarning: gtk_text_buffer_emit_insert: assertion 'g_utf8_validate (text, len, NULL)' failed self.get_buffer().insert(self.get_buffer().get_end_iter(), line)

Solution: my solution is to copy the value of in[0] into an integer variable. The std::cout print the value as expected.

Second problem: If I set Num Samples of "Random Source" from 16 to 32 or higher and look watch the values of in[0] (that are copied into a int variable) in the terminal with std::cout the values are not matching the values that are generated by "Random Source" and displayed in a "QT GUI Time Sink". I really don't know what is causing the problem.

Solution: no solution so far...


This is the code of my out-of-three block

namespace gr {
  namespace newmodulator {

    pre_mod_v2::sptr
    pre_mod_v2::make(int M, float duty_cycle, int samples_per_symbol)
    {
      return gnuradio::get_initial_sptr
        (new pre_mod_v2_impl(M, duty_cycle, samples_per_symbol));
    }

    /*
     * The private constructor
     */
    pre_mod_v2_impl::pre_mod_v2_impl(int M, float duty_cycle, int samples_per_symbol)
      : gr::sync_interpolator("pre_mod_v2",
              gr::io_signature::make(1, 1, sizeof(char)),
              gr::io_signature::make(1, 1, sizeof(gr_complex)), samples_per_symbol + 94) /*, d_M(M), d_duty_cycle(duty_cycle), d_samples_per_symbol(samples_per_symbol)*/
    {
        d_M = M;
        d_duty_cycle = duty_cycle;
        d_samples_per_symbol = samples_per_symbol;

        //Variablen die in der Funktion set_vppm_symbol benötigt werden.
        count_slots_per_symbol = 0;
        vppm_slots = pow(2, M);
        samples_per_slot = samples_per_symbol / vppm_slots;
        pulse_length = (samples_per_symbol / 100 * duty_cycle);
        symbol_value = 0;

        //preamble = {{0, 5}, {0, 0}, {0, 0}, {0, 0}, {0, 5}};
        preamble = {{0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 1}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 1}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0},
        {0, 0}, {0, 0}, {0, 0}, {0, 1}};
    }

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

    /* noutput_items = zahl (interpolation factor)
     */
    int
    pre_mod_v2_impl::work(int noutput_items,
        gr_vector_const_void_star &input_items,
        gr_vector_void_star &output_items)
    {
        /* es werden Zeiger deklariert, die auf die Startadresse von input_items und output_items zeigen.
         * Die Größe eines Zeigers wird durch typ* festgelegt
         * ninput_items hat nur ein Element,
         * während output_items so viele Elemente hat, wie oben durch den Interpolation-Faktor samples_per_symbol angegeben ist */
      const unsigned char *in = (const unsigned char *) input_items[0];
      gr_complex *out = (gr_complex *) output_items[0];

      //std::cout << "symbol_value: " << in[0] << std::endl;
      std::vector<gr_complex> vppm_symbols(d_samples_per_symbol + 94);

      vppm_symbols = set_vppm_symbol(in, d_M, d_duty_cycle, d_samples_per_symbol);


      //std::cout << "noutput_items: " << noutput_items << std::endl;

      for (int i = 0; i < noutput_items; i++)
      {
          out[i] = vppm_symbols[i];
      }

      // es werden insgesamt noutput_items verarbeitet
      consume_each(noutput_items);
      // Tell runtime system how many output items we produced.
      return noutput_items;
    }

    std::vector<gr_complex> pre_mod_v2_impl::set_vppm_symbol(const unsigned char* in, int &M, float &duty_cycle, int &samples_per_symbol)
    {
        symbol_value = in[0];

//        if (!symbol_value){
//            symbol_value = 0;
//        }

        std::cout << "symbol_value: " << static_cast<int>(in[0]) << std::endl;

        std::vector<gr_complex> vppm_symbol(samples_per_symbol);
        for (int i = (symbol_value * samples_per_slot); i < (symbol_value * samples_per_slot + pulse_length); i++)
        {
            vppm_symbol[i] = {static_cast<float>(1.0), 0};
        }

        vppm_symbol.insert(vppm_symbol.begin(), preamble.begin(), preamble.end());


        return vppm_symbol;
    }

  } /* namespace newmodulator */
} /* namespace gr */

Upvotes: 1

Views: 1319

Answers (1)

Massi1987
Massi1987

Reputation: 91

OK I solved my problem. I just add the code of my function set_vppm_symbol into my work function and deleted the line "consume_each(noutput_items)" although in the manual it is described to use the function what's irritating me. Now I'm getting the expected output.

Upvotes: 0

Related Questions