Hilbert Transforms

Hey All,

Wondering if there are some DSP gurus out there that would feel kind enough to point me in the correct direction on an issue.

I’ve attempting for a while to build a single sideband frequency shifter.

My current understanding of the processing is something like:

  1. Generate a Hilbert Transform of an input signal
  2. Multiply the Q piece of the transform via a sin() function
  3. Multiply the I piece of the transform via a cos() function
  4. Subtract Q from I to create the output sample

My rough understanding is somehow this phase shifted version cancels out the lower sideband of what you commonly see doing ring modulation.

I attempted doing this by copying the coefficients from this article into a JUCE FIR filter structure:

https://www.dsprelated.com/showarticle/1147.php

But I’m still seeing / hearing the lower sideband.

It also seems there’s many ways to generate a hilbert transforms:

FFT Based, All Pass IIR Based, & FIR Kernel based.

Am I headed in the right direction here? does it make sense to copy to coefficients from this article into a FIR structure?

Thanks so much for any assistance!

Best,

J

Are you trying to roll your own Hilbert transform, or just use the output of the Hilbert transform?

For what it’s worth, we’ve had excellent results using the Hilbert transform from the Intel Performance Primitives library.

Matt

Hey Matt,

Thanks for the pointer, I’m not attached at all to rolling my own transform but I wasn’t sure where to source one, is the IPP library cross platform and free to use?

I’ll take a look at it!

is the IPP library cross platform and free to use?

Yes and yes.

https://software.intel.com/intel-ipp

Just worth noting, IPP is cross-platform but not multi-arch :slight_smile: as it’s Intel’s.

  • It’s optimized for Intel’s processors (so AMD might get a performance hit due to Intel qualifying higher vector instruction set to ‘Genuine Intel’.

  • Since you link to a compiled code. your only target x86/x64 (and x64 only on macOS).
    So if you plan of doing any iOS/Android/Windows on ARM this would require a different implementation. (and of course post-2021 Macs…)

2 Likes

Yeah, I’ve been trying to figure out how to handle ARM. There’s the Arm Compute library, but I don’t know if that has everything we need (especially the Hilbert transform).

Matt

Just in case it’s interesting for you, some weeks ago I created a rather detailed explanation on what a Hilbert Transform is and how it could be implemented

I personally only built one in Matlab and implemented a VHDL based FPGA version, but after having understood the idea, I found it quite straightforward to implement :smiley:

1 Like

i built one based on this blog entry and it was fairly straightforward. not sure about performance though, i ended up using a different technique for obtaining quadrature outputs.

also iirc the “chorus effect” section of chamberlain has a good model of one.

Hmm… My math skills here are killing me. I think the most ideal is to somehow determine the coefficients / filters needed to build this with an FIR or an All Pass network, If I fail there I’ll try to get the IPP lib running, although a quick glance at the library it doesn’t look too trivial.

I’ll post results back here and see how it goes. Maybe if we’re able to get something working with the built in FIR or IIR it will be helpful to others.

J

What’s Chamberlain?

hah , spelling. i meant chamberlin`

Alright, soooo, this took me so much longer to figure out so I’m happy to share here so no one else must ever struggle like this again for one of the “basic” audio effects we should all have in our toolkits as audio devs.

After scouring for Hilbert transform code all over the internet, I actually found a really nice drop & play implementation here on the forum in an old post. This appears to be one of the “All Pass” Implementations of the Hilbert Transform. Where these coefficients came from – is really beyond my understanding of DSP as I can barely read any maths, but the good news is it works.

BSD License it appears

The Hilbert Transform will generate two signals often referred to as Q & I, the “In Phase” & “Quadrature”

Once you have the Hilbert Transform magic running creating the frequency shifting effect is very simple:

outShifted = I*cos(2 * juce::float_Pi * mPhase) - Q*sin(2 * juce::float_Pi * mPhase);

Simply iterate the phase at the frequency which you’d like to transpose the signal and voila, a nice frequency shifted signal without the nasty lower sideband created by ring modulation.