# Hilbert Transforms

**URL:** <https://forum.juce.com/t/hilbert-transforms/40531>\
**Category:** Audio Plugins\
**Created:** [July 4, 2020, 12:57am UTC](https://forum.juce.com/t/hilbert-transforms/40531 "2020-07-04T00:57:12Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![jakemumu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jakemumu/32/13038_2.png) [@jakemumu](https://forum.juce.com/u/jakemumu)\
**Post date:** [July 4, 2020, 12:57am UTC](https://forum.juce.com/t/hilbert-transforms/40531/1 "2020-07-04T00:57:12Z")

</div>

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](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

---

<div class="post-metadata">

**Author:** ![matt](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/matt/32/18340_2.png) [@matt](https://forum.juce.com/u/matt)\
**Post date:** [July 4, 2020, 1:15am UTC](https://forum.juce.com/t/hilbert-transforms/40531/2 "2020-07-04T01:15:50Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![jakemumu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jakemumu/32/13038_2.png) [@jakemumu](https://forum.juce.com/u/jakemumu)\
**Post date:** [July 4, 2020, 1:17am UTC](https://forum.juce.com/t/hilbert-transforms/40531/3 "2020-07-04T01:17:55Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![matt](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/matt/32/18340_2.png) [@matt](https://forum.juce.com/u/matt)\
**Post date:** [July 4, 2020, 1:59am UTC](https://forum.juce.com/t/hilbert-transforms/40531/4 "2020-07-04T01:59:19Z")

</div>

> is the IPP library cross platform and free to use?

Yes and yes.

[https://software.intel.com/intel-ipp](https://software.intel.com/intel-ipp)

---

<div class="post-metadata">

**Author:** ![ttg](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/ttg/32/14456_2.png) [@ttg](https://forum.juce.com/u/ttg)\
**Post date:** [July 4, 2020, 6:08am UTC](https://forum.juce.com/t/hilbert-transforms/40531/5 "2020-07-04T06:08:19Z")

</div>

Just worth noting, IPP is cross-platform but not multi-arch 🙂 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…)

---

<div class="post-metadata">

**Author:** ![matt](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/matt/32/18340_2.png) [@matt](https://forum.juce.com/u/matt)\
**Post date:** [July 4, 2020, 4:13pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/6 "2020-07-04T16:13:08Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![PluginPenguin](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/pluginpenguin/32/10203_2.png) [@PluginPenguin](https://forum.juce.com/u/PluginPenguin)\
**Post date:** [July 4, 2020, 4:56pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/7 "2020-07-04T16:56:38Z")

</div>

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

> [@How to rotate the phase of an audio signal?](https://forum.juce.com/t/how-to-rotate-the-phase-of-an-audio-signal/39072/10):
>
> First of all: The videos you posted above look really interesting! I’m not really deeply into the theory behind what you are doing there, but just a few points that might be worth thinking about and which may help you understanding the whole topic Phase shift vs. time shift If you take a pure single frequency sine wave and create a time shifted version of that wave you can express the shift amount either in e.g. seconds if it is a time based signal, in samples if it is a sampled signal (which w…

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 😃

---

<div class="post-metadata">

**Author:** ![modosc](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/modosc/32/2308_2.png) [@modosc](https://forum.juce.com/u/modosc)\
**Post date:** [July 4, 2020, 7:07pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/8 "2020-07-04T19:07:31Z")

</div>

i built one based on [this blog entry](http://yehar.com/blog/?p=368) and it was fairly straightforward. not sure about performance though, i ended up using a different technique for obtaining quadrature outputs.

---

<div class="post-metadata">

**Author:** ![modosc](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/modosc/32/2308_2.png) [@modosc](https://forum.juce.com/u/modosc)\
**Post date:** [July 4, 2020, 7:12pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/9 "2020-07-04T19:12:17Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![jakemumu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jakemumu/32/13038_2.png) [@jakemumu](https://forum.juce.com/u/jakemumu)\
**Post date:** [July 4, 2020, 8:49pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/10 "2020-07-04T20:49:02Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![jakemumu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jakemumu/32/13038_2.png) [@jakemumu](https://forum.juce.com/u/jakemumu)\
**Post date:** [July 4, 2020, 8:49pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/11 "2020-07-04T20:49:44Z")

</div>

What’s Chamberlain?

---

<div class="post-metadata">

**Author:** ![modosc](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/modosc/32/2308_2.png) [@modosc](https://forum.juce.com/u/modosc)\
**Post date:** [July 5, 2020, 1:53am UTC](https://forum.juce.com/t/hilbert-transforms/40531/12 "2020-07-05T01:53:04Z")

</div>

hah , spelling. i meant [chamberlin](https://www.goodreads.com/book/show/8273563-musical-applications-of-microprocessors)`

---

<div class="post-metadata">

**Author:** ![jakemumu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jakemumu/32/13038_2.png) [@jakemumu](https://forum.juce.com/u/jakemumu)\
**Post date:** [July 6, 2020, 10:18pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/13 "2020-07-06T22:18:11Z")

</div>

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.

> **[Downloads: DSP Library | ZHdK.ch](https://www.zhdk.ch/en/research/icst/software-downloads-5379/downloads-dsp-library-5384)**
>
> ZHdK is the Zurich University of the Arts

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.

---

<div class="post-metadata">

**Author:** ![waddafunk](https://avatars.discourse-cdn.com/v4/letter/w/b38774/32.png) [@waddafunk](https://forum.juce.com/u/waddafunk)\
**Post date:** [October 14, 2020, 9:55am UTC](https://forum.juce.com/t/hilbert-transforms/40531/14 "2020-10-14T09:55:35Z")

</div>

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](https://www.cfa.harvard.edu/~spaine/am/) 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](https://github.com/waddafunk/Smithsonians_Discrete_Hilbert_Fourier_Hartley_Transforms) 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.

---

<div class="post-metadata">

**Author:** ![gustav-scholda](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/gustav-scholda/32/4172_2.png) [@gustav-scholda](https://forum.juce.com/u/gustav-scholda)\
**Post date:** [October 15, 2020, 7:01am UTC](https://forum.juce.com/t/hilbert-transforms/40531/15 "2020-10-15T07:01:47Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![waddafunk](https://avatars.discourse-cdn.com/v4/letter/w/b38774/32.png) [@waddafunk](https://forum.juce.com/u/waddafunk)\
**Post date:** [October 15, 2020, 10:57am UTC](https://forum.juce.com/t/hilbert-transforms/40531/16 "2020-10-15T10:57:33Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![gustav-scholda](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/gustav-scholda/32/4172_2.png) [@gustav-scholda](https://forum.juce.com/u/gustav-scholda)\
**Post date:** [October 15, 2020, 1:42pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/17 "2020-10-15T13:42:26Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![waddafunk](https://avatars.discourse-cdn.com/v4/letter/w/b38774/32.png) [@waddafunk](https://forum.juce.com/u/waddafunk)\
**Post date:** [October 15, 2020, 2:00pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/18 "2020-10-15T14:00:52Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![jakemumu](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.juce.com/jakemumu/32/13038_2.png) [@jakemumu](https://forum.juce.com/u/jakemumu)\
**Post date:** [October 15, 2020, 3:39pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/19 "2020-10-15T15:39:42Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![waddafunk](https://avatars.discourse-cdn.com/v4/letter/w/b38774/32.png) [@waddafunk](https://forum.juce.com/u/waddafunk)\
**Post date:** [October 15, 2020, 4:37pm UTC](https://forum.juce.com/t/hilbert-transforms/40531/20 "2020-10-15T16:37:19Z")

</div>

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 😅

[Next page](https://forum.juce.com/t/hilbert-transforms/40531.md?page=2)
