blob: 9cb5316e023c3e77db0bc73b202787366233b2f6 [file] [log] [blame]
piotr4089c1a2014-08-06 14:10:56 +02001/* -*- c++ -*- */
ptrkrysik529895b2014-12-02 18:07:38 +01002/*
3 * @file
Piotr Krysika6268a52017-08-23 16:02:19 +02004 * @author (C) 2014 by Piotr Krysik <ptrkrysik@gmail.com>
ptrkrysik529895b2014-12-02 18:07:38 +01005 * @section LICENSE
6 *
7 * Gr-gsm is free software; you can redistribute it and/or modify
piotr4089c1a2014-08-06 14:10:56 +02008 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
ptrkrysik529895b2014-12-02 18:07:38 +010011 *
12 * Gr-gsm is distributed in the hope that it will be useful,
piotr4089c1a2014-08-06 14:10:56 +020013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
ptrkrysik529895b2014-12-02 18:07:38 +010016 *
piotr4089c1a2014-08-06 14:10:56 +020017 * You should have received a copy of the GNU General Public License
ptrkrysik529895b2014-12-02 18:07:38 +010018 * along with gr-gsm; see the file COPYING. If not, write to
piotr4089c1a2014-08-06 14:10:56 +020019 * the Free Software Foundation, Inc., 51 Franklin Street,
20 * Boston, MA 02110-1301, USA.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include <gnuradio/io_signature.h>
28#include "controlled_rotator_cc_impl.h"
piotr4089c1a2014-08-06 14:10:56 +020029
30namespace gr {
31 namespace gsm {
32
33 controlled_rotator_cc::sptr
Piotr Krysik83afe732016-07-17 22:48:35 +020034 controlled_rotator_cc::make(double phase_inc)
piotr4089c1a2014-08-06 14:10:56 +020035 {
36 return gnuradio::get_initial_sptr
Piotr Krysik83afe732016-07-17 22:48:35 +020037 (new controlled_rotator_cc_impl(phase_inc));
piotr4089c1a2014-08-06 14:10:56 +020038 }
39
40 /*
41 * The private constructor
42 */
Piotr Krysik83afe732016-07-17 22:48:35 +020043 controlled_rotator_cc_impl::controlled_rotator_cc_impl(double phase_inc)
piotr4089c1a2014-08-06 14:10:56 +020044 : gr::sync_block("controlled_rotator_cc",
45 gr::io_signature::make2(1, 2, sizeof(gr_complex), sizeof(float)),
46 gr::io_signature::make(1, 1, sizeof(gr_complex)))
47 {
48 set_phase_inc(phase_inc);
piotr4089c1a2014-08-06 14:10:56 +020049 }
50
51 /*
52 * Our virtual destructor.
53 */
54 controlled_rotator_cc_impl::~controlled_rotator_cc_impl()
55 {
56 }
57
58 void
59 controlled_rotator_cc_impl::set_phase_inc(double phase_inc)
60 {
61 d_phase_inc = phase_inc;
62 d_r.set_phase_incr( exp(gr_complex(0, (double)phase_inc)) );
63 }
64
Piotr Krysik83afe732016-07-17 22:48:35 +020065// void
66// controlled_rotator_cc_impl::set_samp_rate(double samp_rate)
67// {
68// d_samp_rate = samp_rate;
69// }
piotr4089c1a2014-08-06 14:10:56 +020070
71 int
72 controlled_rotator_cc_impl::work(int noutput_items,
73 gr_vector_const_void_star &input_items,
74 gr_vector_void_star &output_items)
Piotr Krysik74c4f2c2016-07-15 13:12:46 +020075 {
76 //process phase_inc input
Piotr Krysik83afe732016-07-17 22:48:35 +020077 /*if(input_items.size() == 2) {
piotr4089c1a2014-08-06 14:10:56 +020078 int ii=0;
79 const float *pp = (const float *)input_items[1];
80
81 while(ii < noutput_items){
82 //look for different values on phase increment control input
83 if(d_phase_inc != (*pp)){
Piotr K66bb3cd2014-08-13 19:04:57 +020084
piotr4089c1a2014-08-06 14:10:56 +020085 set_phase_inc(*(pp)); //set new value of phase increment
86
87 float freq_offset_setting = (*(pp) / (2*M_PI)) * d_samp_rate; //send stream tag with a new value of the frequency offset
Piotr K66bb3cd2014-08-13 19:04:57 +020088
89 uint64_t offset = nitems_written(0);
piotr4089c1a2014-08-06 14:10:56 +020090 pmt::pmt_t key = pmt::string_to_symbol("setting_freq_offset");
91 pmt::pmt_t value = pmt::from_double(freq_offset_setting);
92 add_item_tag(0,offset, key, value);
Piotr K66bb3cd2014-08-13 19:04:57 +020093
piotr4089c1a2014-08-06 14:10:56 +020094 break;
95 }
96 pp++;
97 ii++;
98 }
99 }
Piotr Krysik83afe732016-07-17 22:48:35 +0200100 */
101
Piotr Krysik74c4f2c2016-07-15 13:12:46 +0200102 //get complex input and output
103 const gr_complex *in = (const gr_complex *)input_items[0];
104 gr_complex *out = (gr_complex *)output_items[0];
105 //get tags
piotr4089c1a2014-08-06 14:10:56 +0200106
Piotr Krysik74c4f2c2016-07-15 13:12:46 +0200107 uint64_t processed_in = 0;
108 uint64_t produced_out = 0;
109
110 std::vector<tag_t> set_phase_inc_tags;
111
112 pmt::pmt_t key = pmt::string_to_symbol("set_phase_inc");
113 get_tags_in_window(set_phase_inc_tags, 0, 0, noutput_items, key);
114
115 for(std::vector<tag_t>::iterator i_tag = set_phase_inc_tags.begin(); i_tag < set_phase_inc_tags.end(); i_tag++){
116 uint64_t tag_offset_rel = i_tag->offset-nitems_read(0);
117 set_phase_inc(pmt::to_double(i_tag->value));
118 uint64_t samples_to_process = tag_offset_rel-processed_in;
119 d_r.rotateN((out+produced_out), const_cast<gr_complex *>(in+processed_in), samples_to_process);
120 processed_in = processed_in + samples_to_process;
121 produced_out = produced_out + samples_to_process;
122// std::cout << "Rotator, phase inc: " << pmt::to_double(i_tag->value) << std::endl;
Piotr Krysik83afe732016-07-17 22:48:35 +0200123//
124// float freq_offset_setting = (pmt::to_double(i_tag->value) / (2*M_PI)) * d_samp_rate; //send stream tag with a new value of the frequency offset
125// pmt::pmt_t key = pmt::string_to_symbol("setting_freq_offset");
126// pmt::pmt_t value = pmt::from_double(freq_offset_setting);
127// add_item_tag(0,i_tag->offset, key, value);
Piotr Krysik74c4f2c2016-07-15 13:12:46 +0200128 }
129
130 d_r.rotateN((out+produced_out), const_cast<gr_complex *>(in+processed_in), (noutput_items-produced_out)); //const_cast<gr_complex *> is workaround old implementation of rotateN that is still present in ubuntu 14.04 packages
131 return noutput_items;
132 }
piotr4089c1a2014-08-06 14:10:56 +0200133 } /* namespace gsm */
134} /* namespace gr */
135