GNU Radio Manual and C++ API Reference  3.10.9.1
The Free & Open Software Radio Ecosystem
nco.h
Go to the documentation of this file.
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2002,2013,2018 Free Software Foundation, Inc.
4  *
5  * This file is part of GNU Radio
6  *
7  * SPDX-License-Identifier: GPL-3.0-or-later
8  *
9  */
10 
11 #ifndef _GR_NCO_H_
12 #define _GR_NCO_H_
13 
14 #include <gnuradio/gr_complex.h>
15 #include <gnuradio/math.h>
16 #include <gnuradio/sincos.h>
17 
18 #include <cmath>
19 #include <vector>
20 
21 namespace gr {
22 
23 /*!
24  * \brief base class template for Numerically Controlled Oscillator (NCO)
25  * \ingroup misc
26  */
27 template <class o_type, class i_type>
28 class nco
29 {
30 public:
31  nco() : phase(0), phase_inc(0) {}
32 
33  virtual ~nco() {}
34 
35  // radians
36  void set_phase(double angle) { phase = angle; }
37 
38  void adjust_phase(double delta_phase) { phase += delta_phase; }
39 
40  // angle_rate is in radians / step
41  void set_freq(double angle_rate) { phase_inc = angle_rate; }
42 
43  // angle_rate is a delta in radians / step
44  void adjust_freq(double delta_angle_rate) { phase_inc += delta_angle_rate; }
45 
46  // increment current phase angle
47  void step(int n = 1)
48  {
49  phase += phase_inc * n;
50  if (fabs(phase) > GR_M_PI) {
51  while (phase > GR_M_PI)
52  phase -= 2 * GR_M_PI;
53 
54  while (phase < -GR_M_PI)
55  phase += 2 * GR_M_PI;
56  }
57  }
58 
59  // units are radians / step
60  double get_phase() const { return phase; }
61  double get_freq() const { return phase_inc; }
62 
63  // compute sin and cos for current phase angle
64  void sincos(float* sinx, float* cosx) const { gr::sincosf(phase, sinx, cosx); }
65 
66  // compute cos or sin for current phase angle
67  float cos() const { return std::cos(phase); }
68  float sin() const { return std::sin(phase); }
69 
70  // compute a block at a time
71  void sin(float* output, int noutput_items, double ampl = 1.0);
72  void cos(float* output, int noutput_items, double ampl = 1.0);
73  void sincos(gr_complex* output, int noutput_items, double ampl = 1.0);
74  void sin(short* output, int noutput_items, double ampl = 1.0);
75  void cos(short* output, int noutput_items, double ampl = 1.0);
76  void sin(int* output, int noutput_items, double ampl = 1.0);
77  void cos(int* output, int noutput_items, double ampl = 1.0);
78 
79 protected:
80  double phase;
81  double phase_inc;
82 };
83 
84 template <class o_type, class i_type>
85 void nco<o_type, i_type>::sin(float* output, int noutput_items, double ampl)
86 {
87  for (int i = 0; i < noutput_items; i++) {
88  output[i] = (float)(sin() * ampl);
89  step();
90  }
91 }
92 
93 template <class o_type, class i_type>
94 void nco<o_type, i_type>::cos(float* output, int noutput_items, double ampl)
95 {
96  for (int i = 0; i < noutput_items; i++) {
97  output[i] = (float)(cos() * ampl);
98  step();
99  }
100 }
101 
102 template <class o_type, class i_type>
103 void nco<o_type, i_type>::sin(short* output, int noutput_items, double ampl)
104 {
105  for (int i = 0; i < noutput_items; i++) {
106  output[i] = (short)(sin() * ampl);
107  step();
108  }
109 }
110 
111 template <class o_type, class i_type>
112 void nco<o_type, i_type>::cos(short* output, int noutput_items, double ampl)
113 {
114  for (int i = 0; i < noutput_items; i++) {
115  output[i] = (short)(cos() * ampl);
116  step();
117  }
118 }
119 
120 template <class o_type, class i_type>
121 void nco<o_type, i_type>::sin(int* output, int noutput_items, double ampl)
122 {
123  for (int i = 0; i < noutput_items; i++) {
124  output[i] = (int)(sin() * ampl);
125  step();
126  }
127 }
128 
129 template <class o_type, class i_type>
130 void nco<o_type, i_type>::cos(int* output, int noutput_items, double ampl)
131 {
132  for (int i = 0; i < noutput_items; i++) {
133  output[i] = (int)(cos() * ampl);
134  step();
135  }
136 }
137 
138 template <class o_type, class i_type>
139 void nco<o_type, i_type>::sincos(gr_complex* output, int noutput_items, double ampl)
140 {
141  for (int i = 0; i < noutput_items; i++) {
142  float cosx, sinx;
143  nco::sincos(&sinx, &cosx);
144  output[i] = gr_complex(cosx * ampl, sinx * ampl);
145  step();
146  }
147 }
148 
149 } /* namespace gr */
150 
151 #endif /* _NCO_H_ */
base class template for Numerically Controlled Oscillator (NCO)
Definition: nco.h:29
double phase_inc
Definition: nco.h:81
void sincos(float *sinx, float *cosx) const
Definition: nco.h:64
float sin() const
Definition: nco.h:68
void set_freq(double angle_rate)
Definition: nco.h:41
void adjust_phase(double delta_phase)
Definition: nco.h:38
virtual ~nco()
Definition: nco.h:33
double phase
Definition: nco.h:80
void adjust_freq(double delta_angle_rate)
Definition: nco.h:44
void step(int n=1)
Definition: nco.h:47
void set_phase(double angle)
Definition: nco.h:36
float cos() const
Definition: nco.h:67
double get_phase() const
Definition: nco.h:60
double get_freq() const
Definition: nco.h:61
nco()
Definition: nco.h:31
std::complex< float > gr_complex
Definition: gr_complex.h:15
#define GR_M_PI
Definition: math.h:32
GNU Radio logging wrapper.
Definition: basic_block.h:29
void sincosf(float x, float *sinx, float *cosx)
Definition: sincos.h:49