From cd7d55a2c4a2ac1e65269bdbeff53dd393dc8a73 Mon Sep 17 00:00:00 2001 From: Ahmet Inan Date: Wed, 3 Apr 2019 20:53:17 +0200 Subject: [PATCH] added Fs/4 complex down conversion --- README.md | 4 ++++ cdc.hh | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 cdc.hh diff --git a/README.md b/README.md index 907af11..ac3cfe6 100644 --- a/README.md +++ b/README.md @@ -56,6 +56,10 @@ Normalizers for [periodic](https://en.wikipedia.org/wiki/Periodic_function) sign [Numerically controlled oscillator](https://en.wikipedia.org/wiki/Numerically_controlled_oscillator) implemented using a [phasor](https://en.wikipedia.org/wiki/Phasor) and [complex multiplication](https://en.wikipedia.org/wiki/Complex_number#Multiplication) instead of a [lookup table](https://en.wikipedia.org/wiki/Lookup_table). +### [cdc.hh](cdc.hh) + +Fs/4 [Complex down conversion](https://en.wikipedia.org/wiki/Digital_down_converter) + ### [fmd.hh](fmd.hh) [Frequency modulation](https://en.wikipedia.org/wiki/Frequency_modulation) [demodulation](https://en.wikipedia.org/wiki/Demodulation) with and without [atan2](https://en.wikipedia.org/wiki/Atan2). diff --git a/cdc.hh b/cdc.hh new file mode 100644 index 0000000..1d56553 --- /dev/null +++ b/cdc.hh @@ -0,0 +1,51 @@ +/* +Fs/4 Complex down conversion + +Copyright 2019 Ahmet Inan +*/ + +#pragma once + +#include "filter.hh" +#include "window.hh" + +namespace DSP { + +template +class CDC +{ + typedef TYPE complex_type; + typedef typename TYPE::value_type value_type; + value_type real[(TAPS-1)/4]; + value_type imag[(TAPS-1)/2]; + value_type imco[(TAPS-1)/4]; + value_type reco; + bool sign; +public: + CDC(value_type a = value_type(2)) : sign(false) + { + Kaiser win(a); + LowPass2 hbf(1, 4); + reco = win((TAPS-1)/2, TAPS) * hbf((TAPS-1)/2, TAPS); + for (int i = 0; i < (TAPS-1)/4; ++i) + imco[i] = win(2*i+(TAPS-1)/2+1, TAPS) * hbf(2*i+(TAPS-1)/2+1, TAPS); + } + complex_type operator()(value_type in0, value_type in1) + { + sign = !sign; + value_type re = reco * real[0]; + for (int i = 0; i < (TAPS-1)/4-1; ++i) + real[i] = real[i+1]; + real[(TAPS-1)/4-1] = sign ? in1 : -in1; + for (int i = 0; i < (TAPS-1)/2-1; ++i) + imag[i] = imag[i+1]; + imag[(TAPS-1)/2-1] = sign ? in0 : -in0; + value_type im = imco[0] * (imag[(TAPS-1)/4-1] + imag[(TAPS-1)/4]); + for (int i = 1; i < (TAPS-1)/4; ++i) + im += imco[i] * (imag[(TAPS-1)/4-1-i] + imag[(TAPS-1)/4+i]); + return complex_type(re, im); + } +}; + +} +