class sdr.NCO

Implements a numerically controlled oscillator (NCO).

Notes

Numerically Controlled Oscillator Block Diagram
               constant           constant
              increment            offset    p[n]
                  |                  |         |
         +----+   v   +------+       v         v   +-----------+
 f[n] -->| K0 |-->@-->| z^-1 |---+-->@-------->@-->| output(.) |--> y[n]
         +----+   ^   +------+   |                 +-----------+
                  |              |
                  +--------------+

 f[n] = Input frequency signal (radians/sample)
 p[n] = Input phase signal (radians)
 y[n] = Output complex signal
 K0 = NCO gain
 increment = Constant phase accumulation (radians/sample)
 offset = Absolute phase offset (radians)
 output(.) = Phase-to-output mapping function, either: ., sin(.), cos(.), exp(j .)
 z^-1 = Unit delay
 @ = Adder

Examples

Create an NCO with a constant phase increment of \(2 \pi / 20\) radians/sample and a constant phase offset of \(\pi\) radians.

In [1]: nco = sdr.NCO(increment=2 * np.pi / 20, offset=np.pi); \
   ...: y = nco.step(100)
   ...: 

In [2]: plt.figure(); \
   ...: sdr.plot.time_domain(y, marker="."); \
   ...: plt.title("Constant frequency NCO");
   ...: 
../../_images/sdr_NCO_1.png

Create an NCO with a constant phase increment of 0 radians/sample and a constant phase offset of 0 radians. Then step the NCO with a FSK frequency signal.

In [3]: nco = sdr.NCO(); \
   ...: freq = np.array([1, 2, -3, 0, 2, -1]) * 2 * np.pi / 60; \
   ...: freq = np.repeat(freq, 20); \
   ...: y = nco(freq=freq)
   ...: 

In [4]: plt.figure(); \
   ...: sdr.plot.time_domain(y, marker="."); \
   ...: plt.title("NCO implementing CP-FSK modulation");
   ...: 
../../_images/sdr_NCO_2.png

Create an NCO with a constant phase increment of \(2 \pi / 57\) radians/sample and a constant phase offset of 0 radians. Then step the NCO with a BPSK phase signal.

In [5]: nco = sdr.NCO(increment=2 * np.pi / 57); \
   ...: phase = np.array([0, 1, 0, 1, 0, 1]) * np.pi; \
   ...: phase = np.repeat(phase, 20); \
   ...: y = nco(phase=phase)
   ...: 

In [6]: plt.figure(); \
   ...: sdr.plot.time_domain(y, marker="."); \
   ...: plt.title("NCO implementing BPSK modulation");
   ...: 
../../_images/sdr_NCO_3.png

See the Phase-locked loops example.

Constructors

NCO(gain: float = 1.0, increment: float = 0.0, offset: float = 0.0)

Creates a numerically controlled oscillator (NCO).

Special methods

__call__(...) ndarray[Any, dtype[float64]]
__call__(...) ndarray[Any, dtype[complex128]]

Steps the NCO with variable frequency and/or phase signals.

Methods

reset()

Resets the NCO.

step(N: int) NDArray[complex128]

Steps the NCO forward by \(N\) samples.

Properties

property gain : float

(Settable) The NCO gain \(K_0\).

property increment : float

(Settable) The constant phase accumulation \(\omega\) of the NCO in radians/sample.

property offset : float

(Settable) The absolute phase offset \(\theta\) of the NCO in radians.