GNU Radio Manual and C++ API Reference  3.7.13.4
The Free & Open Software Radio Ecosystem
nco.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2002,2013 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * 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.
11  *
12  * GNU Radio is distributed in the hope that it will be useful,
13  * 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.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING. If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifndef _GR_NCO_H_
24 #define _GR_NCO_H_
25 
26 #include <gnuradio/sincos.h>
27 #include <gnuradio/gr_complex.h>
28 #include <vector>
29 #include <cmath>
30 
31 namespace gr {
32 
33  /*!
34  * \brief base class template for Numerically Controlled Oscillator (NCO)
35  * \ingroup misc
36  */
37  template<class o_type, class i_type>
38  class nco
39  {
40  public:
41  nco() : phase(0), phase_inc(0) {}
42 
43  virtual ~nco() {}
44 
45  // radians
46  void set_phase(double angle)
47  {
48  phase = angle;
49  }
50 
51  void adjust_phase(double delta_phase)
52  {
53  phase += delta_phase;
54  }
55 
56  // angle_rate is in radians / step
57  void set_freq(double angle_rate)
58  {
59  phase_inc = angle_rate;
60  }
61 
62  // angle_rate is a delta in radians / step
63  void adjust_freq(double delta_angle_rate)
64  {
65  phase_inc += delta_angle_rate;
66  }
67 
68  // increment current phase angle
69  void step()
70  {
71  phase += phase_inc;
72  if(fabs(phase) > M_PI) {
73  while(phase > M_PI)
74  phase -= 2*M_PI;
75 
76  while(phase < -M_PI)
77  phase += 2*M_PI;
78  }
79  }
80 
81  void step(int n)
82  {
83  phase += phase_inc * n;
84  if(fabs(phase) > M_PI){
85  while(phase > M_PI)
86  phase -= 2*M_PI;
87 
88  while(phase < -M_PI)
89  phase += 2*M_PI;
90  }
91  }
92 
93  // units are radians / step
94  double get_phase() const { return phase; }
95  double get_freq() const { return phase_inc; }
96 
97  // compute sin and cos for current phase angle
98  void sincos(float *sinx, float *cosx) const;
99 
100  // compute cos or sin for current phase angle
101  float cos() const { return std::cos(phase); }
102  float sin() const { return std::sin(phase); }
103 
104  // compute a block at a time
105  void sin(float *output, int noutput_items, double ampl = 1.0);
106  void cos(float *output, int noutput_items, double ampl = 1.0);
107  void sincos(gr_complex *output, int noutput_items, double ampl = 1.0);
108  void sin(short *output, int noutput_items, double ampl = 1.0);
109  void cos(short *output, int noutput_items, double ampl = 1.0);
110  void sin(int *output, int noutput_items, double ampl = 1.0);
111  void cos(int *output, int noutput_items, double ampl = 1.0);
112 
113  protected:
114  double phase;
115  double phase_inc;
116  };
117 
118  template<class o_type, class i_type>
119  void
120  nco<o_type,i_type>::sincos(float *sinx, float *cosx) const
121  {
122  gr::sincosf(phase, sinx, cosx);
123  }
124 
125  template<class o_type, class i_type>
126  void
127  nco<o_type,i_type>::sin(float *output, int noutput_items, double ampl)
128  {
129  for(int i = 0; i < noutput_items; i++) {
130  output[i] = (float)(sin () * ampl);
131  step();
132  }
133  }
134 
135  template<class o_type, class i_type>
136  void
137  nco<o_type,i_type>::cos(float *output, int noutput_items, double ampl)
138  {
139  for(int i = 0; i < noutput_items; i++) {
140  output[i] = (float)(cos() * ampl);
141  step();
142  }
143  }
144 
145  template<class o_type, class i_type>
146  void
147  nco<o_type,i_type>::sin(short *output, int noutput_items, double ampl)
148  {
149  for(int i = 0; i < noutput_items; i++) {
150  output[i] = (short)(sin() * ampl);
151  step();
152  }
153  }
154 
155  template<class o_type, class i_type>
156  void
157  nco<o_type,i_type>::cos(short *output, int noutput_items, double ampl)
158  {
159  for(int i = 0; i < noutput_items; i++) {
160  output[i] = (short)(cos() * ampl);
161  step();
162  }
163  }
164 
165  template<class o_type, class i_type>
166  void
167  nco<o_type,i_type>::sin(int *output, int noutput_items, double ampl)
168  {
169  for(int i = 0; i < noutput_items; i++) {
170  output[i] = (int)(sin() * ampl);
171  step();
172  }
173  }
174 
175  template<class o_type, class i_type>
176  void
177  nco<o_type,i_type>::cos(int *output, int noutput_items, double ampl)
178  {
179  for(int i = 0; i < noutput_items; i++) {
180  output[i] = (int)(cos() * ampl);
181  step();
182  }
183  }
184 
185  template<class o_type, class i_type>
186  void
187  nco<o_type,i_type>::sincos(gr_complex *output, int noutput_items, double ampl)
188  {
189  for(int i = 0; i < noutput_items; i++) {
190  float cosx, sinx;
191  nco::sincos(&sinx, &cosx);
192  output[i] = gr_complex(cosx * ampl, sinx * ampl);
193  step();
194  }
195  }
196 
197 } /* namespace gr */
198 
199 #endif /* _NCO_H_ */
float sin() const
Definition: nco.h:102
void adjust_phase(double delta_phase)
Definition: nco.h:51
void sincos(float *sinx, float *cosx) const
Definition: nco.h:120
void step(int n)
Definition: nco.h:81
void step()
Definition: nco.h:69
void adjust_freq(double delta_angle_rate)
Definition: nco.h:63
GR_RUNTIME_API void sincosf(float x, float *sin, float *cos)
nco()
Definition: nco.h:41
double phase
Definition: nco.h:114
std::complex< float > gr_complex
Definition: gr_complex.h:27
Include this header to use the message passing features.
Definition: logger.h:695
double get_freq() const
Definition: nco.h:95
double get_phase() const
Definition: nco.h:94
virtual ~nco()
Definition: nco.h:43
void set_freq(double angle_rate)
Definition: nco.h:57
void set_phase(double angle)
Definition: nco.h:46
base class template for Numerically Controlled Oscillator (NCO)
Definition: nco.h:38
float cos() const
Definition: nco.h:101
double phase_inc
Definition: nco.h:115