Phase rotating - math question

Hello,
I would like to ask how to perform phase rotating in the wave form.
I know that I need to multiply by j - imaginary number to rotate for 90 degree, and j^2 to rotate 180 degree, and j^3 for 270 degree and so on.
But it takes me to 3 questions:

  1. what should I multiply by to get some between 90 degree angles, for example 45 degree or 60 degree?

  2. what exactly should I multiply by j? Each sample of the wave? I am not sure, because each sample of wave is real component but for multiplying by j I need complex form, need I? If yes, how to get complex form from each sample of real wave? Do I need perform DFT and then inverse DFT? It seems to be too processor consuming for such thing, but maybe it’s necassery?

  3. How exactly multiply by j in C++. I know there is std::complex variables, but I see only access to real number, like someComplex.real() and imaginary number by calling someComplex.imag() But it gives me just value that stand next to j. But how to get just j? That I can use in multiplication, like j*sameWave[sample] ? I tried to derclare int i = pow(sqrt(-1)); but obviously it doesn’t work.

Please help. Thanks in advance

Multiplying your signal by a complex number only makes sense if your signal is in the complex domain in the first place:

04formula

This can be seen if you substitute y(t) with a sum of exponentials:

01formula

I think, in general, the only way to add the same arbitrary phase to your signal over the whole frequency spectrum, is to get your real signal into the above format, i.e. you need to do a Fourier-Transform.
Having said that, that’s only for arbitrary phases. Certain phases can be achieved more easily with simpler FIR and IIR filters. The most simplest being the 180 degree phase shift which is simply a multiplication of -1. I’m not sure about a constant π/2-shift though. Maybe there is an easy FIR/IIR filter for this. @IvanC?

Edit: My ‘i’ above is an imaginary i. A bit confusing as I am also using i as the index over which I sum. Sorry.

1 Like

Hello guys !

Arbitrary phase rotation is done using Hilbert filters, which provide two FIR or IIR filters, returning a signal more or less equivalent to your input signal (with some phase shift), and the same result with a more or less perfect 90 degrees fixed offset everywhere. That gives you something equivalent to a real + imaginary representation of your signal, allowing you to do the rotation.

Of course, some things can be done directly in the frequency domain, where you get complex numbers by design that you can process, but it’s more complicated to do properly some processing there (think about SFT and phase vocoders)

OK, thought about this a bit more. If your original signal is yn, then your signal with of φ phase-shift is:

01formula

where Y(w) is the DTFT of your original signal. The above gives

12formula

So to get your phase shifted signal, you need to convolute your original signal with

03formula

in the time-domain. If φ is 90 degrees:

07formula

then the above becomes:

15formula

So for a 90 degree phase shift you need to convolute your signal with

16formula

in the time-domain. The problem is that the function is unbounded for negative n. Therefore, it is better to use the phase shift-factor

08formula

which leads to the Hilbert filter that @IvanC was talking about:

17formula

Note, however, that if you are processing the audio in real-time then you will likely need to buffer the signal to apply the convolution which will also cause a phase shift.

Also look at the wiki page for Hilbert filters for some nice graphs as they will not be perfect.

2 Likes

Hello great thanks for help. Today I made some math experiments. And I am pretty sure you are right. I need make DFT on oryginal signal then the result complex number multiply by i^r where 0 <= r <= 4 (0 gives angle 0 degree, and 4 gives 360 degree so other values have no sense). And after that multiplication I need to make inverse DFT. Great. But it’s really lot of calculations for sample rate 44100 Hz, even if I perform FFT it’s still a lot of math operations. So it’s not ideal solution to make real time rotation. I need to check your advice about filters to solve that problem. If you have more rethinkink please share it with me. Great thanks again.

Oh doesn’t that forum recognize LatEx?

What made you think it would not involve a lot of calculations? If it was a trivial thing to do, surely DAWs would have included this as a standard processing available on every track. (Free phase transformation can be a useful technique for layering sounds. But for obvious reasons the DAWs only offer the very simple polarity inversion.)

1 Like

I am not sure if I can agree with that. Of course performing FFT forward and backward one by one in real time is a lot of calculations, but only for computer. For programmer it’s just implementation of some math which is known very well for every one who is interesting in maths. Actually programmer even don’t need to understend it in the depth due to fact there are a lot of free FFT libraries, like FFTw. But maybe you are right. I am not sure.

It’s just not that simple as doing FFT, changing stuff, and doing the inverse FFT.
That strategy might produce decent results if you apply a single FFT for the whole audio file (which could be hours of audio in some cases) but that would be very computationally heavy to do and not support any form of real-time.
Then you’d start wanting to do these on smaller windows which you’ll have to stitch together and you will start to get artifacts, which are the audible equivalent to how JPEG artifacts look…

3 Likes

Hello Fabian. I tried to perform FFT on my wave, then the output multiply by for example
i^0.4. And then perform inverse FFT. But it’s just doesn’t change the phase. Probably it’s because source wave (audio) is expressed only by real numbers, and imaginary numbers are always zero. So I still need help :slight_smile:
How to convert waves real numbers to complex? And vice versa, if I have complex expressed wave, how to convert it to only real numbers but including imaginary properties? I see you tried to explain that. But I am really too stupid for understand it. Could you help me by presenting some more detailed solution? :slight_smile:

I get the feeling you’re misunderstanding some things here. First of all you won’t multiply your complex number by i^r, instead you multiply by e^(i * r) (with e = eulers number, others prefer to express this as exp(i * r)).
Second your r value is an angle expressed in radians. This means 360 degree equals an r of 2 * pi, 180 degree equals r=pi, 90 degree equals r=0.5 * pi and so on, I think you get it. So r=0.4 equals 22.9 degrees.

Now first of all, why do you think that other shift values than 0 or 360 don’t make any sense?

So what kind of result are you expecting? What do you want to achieve? How do you measure/observe your phaseshift. And what fft length are you using? Do you do block-based processing as in a plug-in or do you operate on your whole recorded data?

Phaseshifting definitively works, by the way you could do it with an allpass-filter for a fixed shift value, but I‘m not sure if you really have an idea what phaseshifting means. Maybe we should talk about this before talking about how to compute it

1 Like

As @PluginPenguin points out, it doesn’t matter if the source audio is expressed only by real numbers. The Fourier Transform will be complex, so multiplying it by a complex number is fine. When you do the inverse Fourier Transform, your signal will be real again (as long as you don’t break the symmetry between positive/negative coefficients - which you don’t) but shifted.

As @PluginPenguin points out, it might not be so easy to see that the phase is shifted on a complicated signal. Try your algorithm on a simple sine wave and then check if the positions of the extrema are now where the zeros used to be (as you are shifting by 90 degrees). Also, this will only work if you are processing a whole file and then compare the input file and the output file. If you are doing block based processing then you must compare a single (and the same!) input and output block, as buffering your audio into blocks will also always cause a shift in the signal (a phase shift which is linear in frequency)!

If you are simply shifting by whole multiples of 90 degrees then it’s ok that you are multiplying your Fourier Coefficients by i^r - as

r * 90 deg = r * pi/2 rad

and

exp (irpi/2)=i^r

as long as r is an integer.

1 Like

Wait, what exactly does your r value express? Too sad this forum doesn’t support equations. Is r an integer multiplier, so r=0 equals 0° phase shift, r=1 equals 90° phase shift, r=2 equals 180° and so on…? If you meant that, yes that’s true. I interpreted r as an arbitrarily shift value expressed in radians. I don’t quite get where the author requests only 90° phase shift steps, but maybe I’m misinterpreting his posts?

Hello,
I can’t agree with that:

…as long as r is an integer.

I’ve just created some simply graph representation (very popular in all Fourier concern viedos on youtube):
X_j_powTo_0

And as you probably know that is the sum Sn of real cosinusoids and imaginary sinusoids (which is the same as cosinusoids but shifted phase to 90 degree). Knob is representing Sn * i^(knob value). So see what happens when I set knob to 0.25:
X_j_powTo_025
And I can assure you that if I set knob to 4.25 I get exactly the same graph. That’s why I told that multiplying by i to the power of >4 has no sense, because it starts repeating.

But let’s back to main question. I have my wave (let’s say square like on first gif) with just real values. I can make Fourier transform on that wave and it will give me amplitudes for all frequencies from which my square wave is built. So I could shift in phase 90 dergree each one of those frequencies (not sure how to do that), and those phase shifted frequencies copy in some way (also not sure how) to my imaginary numbers. Than I could multiply it by i^r to make phase rotation, and then perform inverse FFT. Now on the output I will get authentic complex domain wave. Get I?
But even I have that, now I need to send my wave to the speaker. But my speaker accept only real numbers :slight_smile: So I am at the beginning. Where I am wrong?

An FFT of any signal (real or complex) with length N will give you N complex FFT values of positive and negative frequencies. Trying to understand negative frequencies is a little bit tricky, but there is a sliver lining when using a real signal (like audio is, yay!): When transforming real signals, the FFT values of a positive frequency and that of the corresponding negative frequency will be complex conjugated! E.g. 0.5+0.3i and 0.5-0.3i. That’s the reason why there is a real-only-fourier transform which produces only values for the positive frequencies (as the negatives will just be complex conjugated ones). With these values you can do you complex operation (multiplying your phase offset).

So now the other way around: If you transform complex conjugated FFT values back to the time-domain, you will get a real-only signal (which you can send to your loudspeakers, whose mechanic elements also do some kind of complex processing btw :wink: ). So as long as the values stay complex conjugated you are just fine.

So basically you have to rotate the complex values of negative frequencies the other way, but as you don’t have access to the negative values with real-only transform, you can’t do anything wrong here, which would result in a complex audio signal.

2 Likes

The input signal is real, when you do the FFT you don’t only get amplitudes, you get complex numbers (real and imaginary). As long as you symmetrically apply your phase-factor to both the negative and positive frequencies (as @danielrudrich mentions - you need to apply the phase negatively for negative frequencies) , you will get real numbers again when transforming back. Obviously, you can send that directly to the speaker (as it is real).

The difference between the input and output signal is that your phases are now shifted in the output signal. For example, if you look at your waveform in a DAW, your extrema of a sinusoid in the input signal will now have moved to where the zeroes used to be (when shifting by 90 degrees). The amplitude will remain the same. But all values are still non-complex.


Red = real-valued input audio signal
Green = real-valued output signal shifted by 90 degrees

Great thanks for comment, but in all those theories still I can’t find the answer for how to rotate phase in my audio signal which is expressed only by real numbers :blush:

What part do you not understand: Your audio signal is expressed only by real numbers. You now do a Fourier Transform. The transformed signal is now in complex numbers (because any real-valued audio signal will be complex-valued after a Fourier Transform). You apply the phase, transform back and you receive a real-valued signal again.

I don’t believe you :slight_smile: I need to check it. I don’t believe because: of course after FFT on real values wave I will get complex, but those complex would have all imaginary numbers equal zero. wouldn’t it? I am almost sure I am right but I will check it again.
But which part I do not understand: Let’s say I have square wave (like on my first gif) expressed only by real numbers. How to make my wave to look exactly like on my second gif? How to do that? That’s what I still can’t understand.

No of course not! You will definitely get non-zero imaginary components. Those (together with the real values) represent the amplitudes and the phases. I think this is where your misunderstanding is coming from.

Well just follow the steps that we have repeatedly posted in this thread.

1 Like