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.

1 Like

Hello everyone,

I’ve just been through the struggle of finding a nice implementation of a Hilbert transform to drop in my Juce project. Not finding one i ended up on this project from the Smithsonian Astrophysical Observatory in which they did implement it in c as sharply as an astrophysical observatory could do. So I isolated the references for the transforms from the project, provided an example of usage on a real signal in c++ and compared the result with the MATLAB result.
Find everything here ready to be dropped in your project.
Note that for now the transforms take as input only (complex) signals with length equal to a power of 2, but I’ll work on relaxing that condition to a signal of any length, that should be quite straightforward.

Just one thing to add here: if you want to use the resulting frequency shifter in a feedbackloop you need to use an allpass based implementation. FIR and FFT based implementations introduce latency. I ended up rolling my own for Tonsturm’s FRQ SHIFT.

Of course, I am using the code i shared in a not real-time analisys, to calculate average time and frequency of grains of a sound that i granulated and only after resynthetising it via scattering in the time-freq plane obtained.
For real-time applications an allpass implementation is much more well-suited, totally agree. Is your allpass implementation open-source, if I can ask? I’ll totally be in need of an implementation of that type sooner or later.

Sorry, as I stated above it’s used in a commercial plugin…

Thanks, lost the part about the commercial plugin my bad. I’ll follow up with an opensource implementation if I’ll implement/find one.

I’m confused – there’s an open source all pass implementation with a BSD license right in this thread I posted up before. No latency – just kinda crumby code you make need to rewrite a bit.

Oh, yes, i tried that library but i got so many deprecation errors and bad stuff that I abandoned it, maybe I did something wrong and in that case shame on me…
On the other hand also ideas are coming up to my mind to generate the filter from the transform implementation i posted with a pair of mathemathical tricks… Sorry for the confusion, just wanted to say that I’ll dig deeper into this when I’ll have the time (I’m a math/physics enthusiast and this Hilbert transform is triggering me so hard for so many reasons) and post my results if I’ll have any :sweat_smile: