diff --git a/README.md b/README.md index 7cdd61e..5980ba4 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,10 @@ Normalizers for [periodic](https://en.wikipedia.org/wiki/Periodic_function) sign Fs/4 [Complex down conversion](https://en.wikipedia.org/wiki/Digital_down_converter) +### [hilbert.hh](hilbert.hh) + +[Discrete Hilbert transform](https://en.wikipedia.org/wiki/Hilbert_transform#Discrete_Hilbert_transform) + ### [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/hilbert.hh b/hilbert.hh new file mode 100644 index 0000000..5463c4a --- /dev/null +++ b/hilbert.hh @@ -0,0 +1,44 @@ +/* +Discrete Hilbert transformation + +Copyright 2020 Ahmet Inan +*/ + +#pragma once + +#include "window.hh" + +namespace DSP { + +template +class Hilbert +{ + static_assert((TAPS-1) % 4 == 0, "TAPS-1 not divisible by four"); + typedef TYPE complex_type; + typedef typename TYPE::value_type value_type; + value_type real[TAPS]; + value_type imco[(TAPS-1)/4]; + value_type reco; +public: + Hilbert(value_type a = value_type(2)) + { + Kaiser win(a); + reco = win((TAPS-1)/2, TAPS); + for (int i = 0; i < (TAPS-1)/4; ++i) + imco[i] = win((2*i+1)+(TAPS-1)/2, TAPS) * 2 / ((2*i+1) * Const::Pi()); + } + complex_type operator()(value_type input) + { + value_type re = reco * real[(TAPS-1)/2]; + value_type im = imco[0] * (real[(TAPS-1)/2-1] - real[(TAPS-1)/2+1]); + for (int i = 1; i < (TAPS-1)/4; ++i) + im += imco[i] * (real[(TAPS-1)/2-(2*i+1)] - real[(TAPS-1)/2+(2*i+1)]); + for (int i = 0; i < TAPS-1; ++i) + real[i] = real[i+1]; + real[TAPS-1] = input; + return complex_type(re, im); + } +}; + +} +