天天看點

gnuradio子產品分類

sync_XXX

很簡單,輸入輸出比固定,不需要做consume和produce。可以調用set_history(TAPS_LEN);  來輸入曆史資料,類似fir。

source:1 2 3 4 5 6 7 8 9 10

noutput=5

則第一次輸入:12345

set_history(2)

則得二次輸入為

56789

第三次輸入為

678910

若set_history(1)//預設值

則第二次輸入為

6 7 8 9 10

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

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

namespace gr {
    namespace dab {

        bin2dec_bb::sptr
        bin2dec_bb::make(uint32_t k)
        {
            return gnuradio::get_initial_sptr
                (new bin2dec_bb_impl(k));
        }

        /*
         * The private constructor
         */
        bin2dec_bb_impl::bin2dec_bb_impl(uint32_t k)
            : gr::sync_decimator("bin2dec_bb",
                    gr::io_signature::make(1, 1, sizeof(uint8_t)),
                    gr::io_signature::make(1, 1, sizeof(uint8_t)), k),
            d_k(k)
        {
            if (d_k == 0) {
                throw std::out_of_range("interpolation must be > 0");
            }
        }

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

        int
        bin2dec_bb_impl::work(int noutput_items,
                gr_vector_const_void_star &input_items,
                gr_vector_void_star &output_items)
        {
            const uint8_t *in = (const uint8_t *) input_items[0];
            uint8_t *out = (uint8_t *) output_items[0];

            // Do <+signal processing+>

            for(uint32_t i = 0; i < noutput_items; i++) {
                out[i] = 0x00;
                for(uint32_t j = 0; j < d_k; j++) {
                    out[i] |= (0x01 & in[i*d_k+j])<<(d_k-j-1);
                }
            }

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

    } /* namespace dab */
} /* namespace gr */
           

這裡輸入輸出比k:1

這裡輸入比輸出k:1 保證有k × noutput 個ninput,in[i*d_k+j]不會越界

以for(uint32_t i = 0; i < noutput_items; i++)來驅動資料

一個例子qpsk map:輸入1 2 3 4 5 6 輸出1+4j 2+5j 3+6j

<pre name="code" class="cpp">
<pre name="code" class="cpp">

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

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

namespace gr {
    namespace dab {

        qpsk_map::sptr
        qpsk_map::make(uint32_t data_size)
        {
            return gnuradio::get_initial_sptr
                (new qpsk_map_impl(data_size));
        }

        /*
         * The private constructor
         */
        qpsk_map_impl::qpsk_map_impl(uint32_t data_size)
            : gr::sync_block("qpsk_map",
                gr::io_signature::make(1, 1, data_size * sizeof(float)),
                gr::io_signature::make(1, 1, data_size * sizeof(gr_complex) / 2)),
            d_data_size(data_size)
        {}

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

        int
        qpsk_map_impl::work(int noutput_items,
                gr_vector_const_void_star &input_items,
                gr_vector_void_star &output_items)
        {
            const float *in = (const float *) input_items[0];
            gr_complex *out = (gr_complex *) output_items[0];

            // Do <+signal processing+>
            for (size_t i = 0; i < noutput_items; i++) {
                for (size_t j = 0; j < d_data_size/2; j++) {
                    out[j].real() = in[j];
                    out[j].imag() = in[j+d_data_size/2];
                }
                out += d_data_size / 2;
                in += d_data_size;
            }
            // Tell runtime system how many output items we produced.
            return noutput_items;
        }

    } /* namespace dab */
} /* namespace gr */
           

//注意輸入輸出size的大小,将輸入輸出都定義為vector。   

gr::io_signature::make(1, 1, data_size * sizeof(float)),

gr::io_signature::make(1, 1, data_size * sizeof(gr_complex) / 2))

//看起來輸入輸出是2:1,但其實是1:1,因為輸入輸出都是vector,輸入<strong>1 2 3 4 5 6 是一個vector,不是6個數,同理輸出 輸出1+4j 2+5j 3+6j是一個複數vector不是3個複數

//注意不要忘記out += d_data_size / 2;in += d_data_size;,當data_size很大的時候,noutput_iterms經常為1,不加以上兩句結果也對,但是noutput_iterms>1時就有問題,會導緻結果一下對一下錯,很難debug

general

輸入輸出比任意。主要是通過consume(消耗了多少個input)和produce(産生了多少個output),預設return值就是produce的值,當然也可以顯示調用,此時傳回值為 return WORK_CALLED_PRODUCE。使用forecast來保證在給定noutput情況下需要有多少個input輸入。

source:1 2 3 4 5 6 7 8 9 10

forecase:2

noutput=2

則第一次輸入:1234

若consume(2)

若produce(1)

則第一次輸出1個output

則第二次輸入:3456

若consume(4)

則第二次輸入5678

peak_detector_XXX_impl.cc是好例子

sync和general類型子產品都是以noutput驅動的,如下所示,forecast中也是以noutput去指派ninput

for (size_t i = 0; i < noutput_items; i++)

但是tag類型子產品是以ninput驅動的,如下所示

 {            

         const float *in = (const float *) input_items[0];           

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

         uint32_t packet_length = ninput_items[0];            

         // Do <+signal processing+>            

        for (uint32_t i = 0; i < packet_length; i++) {                

                 if (d_pnctrg_vec[i] == 1) {                   

  *out++ = *in++;                

                     } 

         else {                    

           *out++ = d_fill_val;              

           }            

}            

             // Tell runtime system how many output items we produced.            

            return d_return_len;

在tag類型的子產品中使用calculate_output_stream_length函數,ninput決定noutput,如下所示

             unpuncture_impl::calculate_output_stream_length(const gr_vector_int &ninput_items)        {          

                     int noutput_items = d_return_len;           

                     return noutput_items ;