How to rotate the phase of an audio signal?

Hello. I want to rotate the phase of an audio signal by an arbitrary number (not necessarily 90° or 180° but any number in the range 0 -> 2Pi). I know that I need to decompose the signal into real and imaginary numbers and work in that domain but…how?
I don’t have experience with FFT, I’ve read about it, watched some video tutorials… and I get the theoretical idea but I got lost trying to convert this understanding into c++ code !
Please can someone point me toward a solution?
I have read that Hilbert transform can be used too, but I don’t quite get how.

And lastly… if I go FFT would juce’s FFT be fine for what I need to do? I have looked at other libraries as well like ffts and kissfft but really… before venturing into external libraries I need to get the process straight.

Thank you.

1 Like

May I ask what’s your use-case to rotate the phase of a complete signal by an arbitrary phase angle? I ask because I personally never needed such functionality in the audio context, however I implemented a hilbert filter for RF signal processing applications. Took me a few hours to understand it, but once you got the idea, it’s quite straightforward to implement if you have a solid dsp math background.

So if you really need such a feature I would take some time if I find it trying to explain the hilbert filter. But maybe we can find an even easier solution to your underlying problem before diving into this topic :wink:

Most FFT libraries out there work more or less the same when it comes to how to interface with them in terms of data structures. Some are superior in performance, some have an easier api and some have better cross platform compatibility. The JUCE implementation tries to combine all those three aspects, so I’d recommend to use the JUCE one before adding third party libraries.

@PluginPenguin thanks for taking the time to answer.
I was just reading something you posted on this same topic here
https://forum.juce.com/t/phase-rotating-math-question/27476/10
I start by saying why I think I need the phase-shift…
I’m developing a plugin which generates simple soundwaves (sine,saw,etc…) and shows the lissajous patterns of the final output. So basically it generates graphics controlled by sound. I have an x-y oscilloscope that shows the left and right channels of the output on the two axis. I know what I want to achieve because I have made a beta test using max msp and it works as I expect.
The phase rotation is not very needed usually but in this case it changes remarkably the outcome (the sound and consequentially the graphics on the oscilloscope). Just to give a visual example, it allows to do this:


… if then I want to use this plugin as a filter that processes (and phase-shifts) incoming sound rather than process sound waves generated internally, I can compose tracks based on what shapes I like to generate. Like this:

In max msp the fft is pretty much behind the scene, I had only to know what object to call: i decomposed the signal from polar to cartesian coordinates, changed the imaginary component and then reassembled. I don’t know if I was just lucky but it worked.

2 Likes

Cool, like Jerobeam Fenderson’s Oscilloscope music. I guess you know about this already, but if not, there’s lots of information on his page.

I know… I stumbled upon his work just while I was developing this kind of plugin and it blew me away… amazing.

1 Like

I might be naive, but as long as you have a pure sine wave, a phase rotation can be achieved simply by delaying the signal. The problem only exists for spectral content, since the delay time depends on the wavelength (and therefore the frequency of the component).

@daniel yes I guess that delaying the flow of samples on a simple waveform could work, but I would like to also be able to shift the phase of the mixed oscillators’ output, and eventually convert this generator/visualizer plugin into a filter-type plugin that shifts the phase of incoming audio. I will start by trying the delay trick while I gather further information on the FFT. :upside_down_face: !

Maybe I’m not fully understanding but: an all pass filter applies phase shifts across the spectrum while keeping amplitude constant. That’s basically how phasers work right?

And a band pass filter selects parts of the spectrum.

So wouldn’t a smallish network of band pass filters feeding all pass filters in parallel with correct tuning be another approach? You could then also choose to phase shift different spectrum buckets differently.

There would be some slop and overlap but also seems like 10 biquads (so a 5 band network) would be both less latent and potentially less computationally taxing than ffts.

But again I’m not 100% sure I understood your use case. Hope it helps anyway!

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 will in the end equal a time shift in discrete time steps, depending on your sample rate, so this should just be listed under time shift in the following part) or as a phase shift. All three are explanations of the same effect. While the time shift is an absolute value in seconds, the phase shift is a relative value , in detail a fraction of the wave-length multiplied by 2pi or 360° (lets stick to radians here).

Now if we take two sine waves with different frequency, played at the same time and apply a constant time shift to it, this will result in a different phase shift for both, as both waves differ in their wavelength. On the other hand, if we apply the same phase shift to both, it will result in a different time shift for both. I tried to quickly draw that to explain what I mean :sweat_smile::

What does phase shifting a whole signal mean?

So with this knowledge, what does phase shifting a complete signal mean? As Mr. Fourier found out nearly 200 years ago (an amazing fact, by the way), all time signals can be decomposed into and fully described by a number of sine waves that represent each frequency occurring in the signal, the complete signal equals the sum of all those sines. A fourier transform computes the magnitude and phase of all the sine waves needed to create the signal you put into it.

Now if we try to think of our signal as a big number of sine waves with different frequencies and look at the drawing above, this would mean an individual time shift of each of this frequencies in order to obtain a constant phase shift for all frequencies. A simple time shift of the overall signal wouldn’t do.

So which kind of tool is needed to perform that operation?

Short answer: An allpass filter with a constant phase shift.

A short introduction to filters

As you might know, a filter is some abstract kind of processing block that alters the magnitude of the incoming signal over the frequency and introduces a phase shift over the frequency. In case of an EQ, the phase shift is not so important in many cases, as it is not directly audible if you listen to the output signal alone. If this is the case, we normally use super efficient IIR filter structures, they alter the magnitude and you have to deal with the phase shift. We can also create linear phase equalizers with FIR filters, they are computationally more heavy but can achieve an arbitrary magnitude combined with a linear phase. And we can create all pass filters. They have a linear magnitude and only introduce a phase shift.

How to build that allpass?

If you want a true linear magnitude combined with a phase shift equal for all frequencies, you need an FIR filter. An IIR biquad-based allpass is not suitable for this case of constant phase shift over all frequencies. While a true constant phase shift is not so hard to achieve with an FIR filter, a true linear magnitude is only achieved by a longer filter, which will be computationally more expensive.

The FFT-based solution

A straightforward solution is what you have done in max: Computing the FFT, shifting the frequencies of the resulting spectrum and don’t touch the magnitude. In fact, mathematically this can be seen as a way to implement an FIR based allpass, you basically perform a convolution here. However, if you want to go that route, you should have a look at how convolution is done right, because you will need to compute some kind of overlap and add it to the next block – otherwise you will introduce (subtle) artifacts to your output signal.

The FIR-based solution

All this can done with an FIR filter as well, completely without an FFT. With filter design tools as found in Matlab etc. you can compute the corresponding filter coefficient to create any FIR filter that does anything to your phase. However if you want to change the phase shift at runtime, re-computing can or cannot be a computationally heavy task.

Now what’s with the Hilbert filter

Ah right. The Hilbert filter. This thing is a bit difficult to understand, as it basically creates a complex-valued version of your real-valued input signal. While the spectrum of a real-valued signal is symmetric for negative frequencies (and therefore is not computed and displayed at all most of the time when working with real valued audio signals), the spectrum of a Hilbert filtered signal is zero for negative frequencies :scream: You can even reduce the sample rate after hilbert filtering down to 1/2 without any aliasing effects, but this is another topic…
The hilbert filter basically creates a signal with +1/2 pi phase shift for positive frequencies and -1/2pi phase shift for negative frequencies, a so-called IQ signal (In phase and Quadrature). By applying gain to the I or Q part of the signal, you can now create an arbitrary phase shift to the signal. To get back a real valued signal, just sum both parts up. If you want to compute an FFT on such a signal, just chose a complex to complex FFT.

That being said, I only did a hilbert filter for non-audio applications so far. Here is a figure from my master thesis where I described the filter structure that I implemented

image
I chosed to implement it with only 15 coefficients and you see that the resulting magnitude is far from being constant – however it was sufficient for my use case back then. Another interesting thing is the repeating coefficient pattern – this can be exploited to reduce the computational complexity of such a structure quite a bit:
image

But those are implementation details :wink:

I hope this could at least shed some light at some of the aspects and give you an idea what to google for

Edit: Why do my uploaded pictures look so bad here?

20 Likes

Many thanks for such an amazing answer!

this is an awesome answer!

@PluginPenguin Thanks so much for such a detailed answer !
It covers all that I came across while researching on this topic:
the FIR filter approach, clear insights on the usefulness of FFT for my user case and also the Hilbert filter which I read about but haven’t researched yet. I will surely go back to this post as I conceive a suitable approach. Coming from a not-mathematical background there is lots to take in (and trigonometry at school didn’t sound as fascinating as it seems now :sweat_smile:), and this kind of help makes the learning curve less steep ! Much appreciated.

1 Like