GNU Radio Manual and C++ API Reference  3.7.14.0
The Free & Open Software Radio Ecosystem
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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/gr_complex.h>
27 #include <gnuradio/sincos.h>
28 #include <cmath>
29 #include <vector>
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) { phase = angle; }
47 
48  void adjust_phase(double delta_phase) { phase += delta_phase; }
49 
50  // angle_rate is in radians / step
51  void set_freq(double angle_rate) { phase_inc = angle_rate; }
52 
53  // angle_rate is a delta in radians / step
54  void adjust_freq(double delta_angle_rate) { phase_inc += delta_angle_rate; }
55 
56  // increment current phase angle
57  void step()
58  {
59  phase += phase_inc;
60  if (fabs(phase) > M_PI) {
61  while (phase > M_PI)
62  phase -= 2 * M_PI;
63 
64  while (phase < -M_PI)
65  phase += 2 * M_PI;
66  }
67  }
68 
69  void step(int n)
70  {
71  phase += phase_inc * n;
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  // units are radians / step
82  double get_phase() const { return phase; }
83  double get_freq() const { return phase_inc; }
84 
85  // compute sin and cos for current phase angle
86  void sincos(float* sinx, float* cosx) const;
87 
88  // compute cos or sin for current phase angle
89  float cos() const { return std::cos(phase); }
90  float sin() const { return std::sin(phase); }
91 
92  // compute a block at a time
93  void sin(float* output, int noutput_items, double ampl = 1.0);
94  void cos(float* output, int noutput_items, double ampl = 1.0);
95  void sincos(gr_complex* output, int noutput_items, double ampl = 1.0);
96  void sin(short* output, int noutput_items, double ampl = 1.0);
97  void cos(short* output, int noutput_items, double ampl = 1.0);
98  void sin(int* output, int noutput_items, double ampl = 1.0);
99  void cos(int* output, int noutput_items, double ampl = 1.0);
100 
101 protected:
102  double phase;
103  double phase_inc;
104 };
105 
106 template <class o_type, class i_type>
107 void nco<o_type, i_type>::sincos(float* sinx, float* cosx) const
108 {
109  gr::sincosf(phase, sinx, cosx);
110 }
111 
112 template <class o_type, class i_type>
113 void nco<o_type, i_type>::sin(float* output, int noutput_items, double ampl)
114 {
115  for (int i = 0; i < noutput_items; i++) {
116  output[i] = (float)(sin() * ampl);
117  step();
118  }
119 }
120 
121 template <class o_type, class i_type>
122 void nco<o_type, i_type>::cos(float* output, int noutput_items, double ampl)
123 {
124  for (int i = 0; i < noutput_items; i++) {
125  output[i] = (float)(cos() * ampl);
126  step();
127  }
128 }
129 
130 template <class o_type, class i_type>
131 void nco<o_type, i_type>::sin(short* output, int noutput_items, double ampl)
132 {
133  for (int i = 0; i < noutput_items; i++) {
134  output[i] = (short)(sin() * ampl);
135  step();
136  }
137 }
138 
139 template <class o_type, class i_type>
140 void nco<o_type, i_type>::cos(short* output, int noutput_items, double ampl)
141 {
142  for (int i = 0; i < noutput_items; i++) {
143  output[i] = (short)(cos() * ampl);
144  step();
145  }
146 }
147 
148 template <class o_type, class i_type>
149 void nco<o_type, i_type>::sin(int* output, int noutput_items, double ampl)
150 {
151  for (int i = 0; i < noutput_items; i++) {
152  output[i] = (int)(sin() * ampl);
153  step();
154  }
155 }
156 
157 template <class o_type, class i_type>
158 void nco<o_type, i_type>::cos(int* output, int noutput_items, double ampl)
159 {
160  for (int i = 0; i < noutput_items; i++) {
161  output[i] = (int)(cos() * ampl);
162  step();
163  }
164 }
165 
166 template <class o_type, class i_type>
167 void nco<o_type, i_type>::sincos(gr_complex* output, int noutput_items, double ampl)
168 {
169  for (int i = 0; i < noutput_items; i++) {
170  float cosx, sinx;
171  nco::sincos(&sinx, &cosx);
172  output[i] = gr_complex(cosx * ampl, sinx * ampl);
173  step();
174  }
175 }
176 
177 } /* namespace gr */
178 
179 #endif /* _NCO_H_ */
float sin() const
Definition: nco.h:90
void adjust_phase(double delta_phase)
Definition: nco.h:48
void sincos(float *sinx, float *cosx) const
Definition: nco.h:107
void step(int n)
Definition: nco.h:69
void step()
Definition: nco.h:57
void adjust_freq(double delta_angle_rate)
Definition: nco.h:54
GR_RUNTIME_API void sincosf(float x, float *sin, float *cos)
nco()
Definition: nco.h:41
double phase
Definition: nco.h:102
std::complex< float > gr_complex
Definition: gr_complex.h:27
double get_freq() const
Definition: nco.h:83
double get_phase() const
Definition: nco.h:82
virtual ~nco()
Definition: nco.h:43
void set_freq(double angle_rate)
Definition: nco.h:51
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:89
double phase_inc
Definition: nco.h:103