I have a complex signal and would like to zero out the phases. However, I seem to be unable to do this simply by setting .theta to 0 for all indexes. What is the proper way to do this (slightly modified example from the Signal help file)?

```
(
var size = 512;
var real, imag, cosTable, frqAmpPhs, complex;
// Create a signal of sine partials:
// partial freqs, amps, and phases
frqAmpPhs = [
// 0 Hz (DC), amp: 1, phase pi/2 (cosine)
[0, 1, 0.5pi],
// other partials, various amp and phase
[8], [13, 0.25], [21, 0.25], [55, 0.5, 0.5pi],
// nyquist, amp: 1, phase pi/2 (cosine)
[size/2, 1, 0.5pi]
];
real = Signal.newClear(size);
real.sineFill2(frqAmpPhs);
imag = Signal.newClear(size); // zeros
cosTable = Signal.fftCosTable(size);
// Perform fft
~complex = fft(real, imag, cosTable));
```

The following causes SuperCollider to freeze

```
~complex.theta.size.do{|i|
~complex.theta[0] = 0};
```

1 Like

Try making a new Polar and converting it back to Complex:

```
~polar = Polar(~complex.rho, (0!~complex.theta.size));
~polar.theta;
~complex2 = ~polar.asComplex
```

Sam

I don’t see it freezing – but it will leave ~complex unchanged.

~complex is made of `.real`

and `.imag`

*only*.

`.theta`

is calculated from real and imag. So every `.theta`

makes a new array (this is why it’s slow-running for you – you’re doing 512x `atan(imag, real)`

512 times). You can modify that array, but it has zero effect on the original Complex data.

Sam’s approach is right: convert to an object that contains `rho`

and `theta`

arrays, then modify the arrays, then convert back to Cartesian Complex. EDIT: But the quick way for general cases is `~polar = ~complex.asPolar`

– then, after manipulation, `~complex = ~polar.asComplex`

.

hjh

Thanks a lot for the help @Sam_Pluta and @jamshark70, this makes sense to me now. To convert back to a complex Signal, I made this function, heavily inspired by some code @Gerhard_Eckel sent me:

```
~zeroPhase = {|item|
var polar, newComplex, size;
size = item.real.size;
polar = item.asPolar;
size.do{|i|
polar.theta[i] = 0.0};
newComplex = polar.real.as(Signal).complex(polar.imag.as(Signal));
s.sync; // Not sure this is needed
newComplex;
};
```

Best, Adam

Side note: your function operates entirely in the language, so there is no need for any kind of Server synchronization. `s.sync`

is only ever needed if you want to synchronize with *asynchronous* Server commands. Here’s a typical example:

```
fork {
SynthDef({ ... }, \foo).add;
s.sync; // make sure SynthDef has been sent
Synth(\foo);
}
```

Ah yes, of course, thank you!

@Adam_Pultz, you may want to try playing with the SignalBox quark.

SignalBox includes a number of extension methods for `Signal`

along with the `FreqSpectrum`

class, which provides a number of useful frequency domain methods.

Zeroing out the phase is as easy as calling `-phase`

, and setting to zeros.

See also:

Help for `FreqSpectrum`

can be found here.

… and simple example:

```
~size = 128;
~cosTable = Signal.fftCosTable(~size);
// real signal
~realSignal = Array.fill(~size, { 1.0.bilinrand }).as(Signal);
~imagSignal = Signal.zeroFill(~size);
~realSignal.plot("time domain - rando!");
// complex spectrum - cartesian
~complex = ~realSignal.fft(~imagSignal, ~cosTable);
// spectrum
~spectrum = FreqSpectrum.newComplex(~complex);
~spectrum.magnitude.plot("magnitude - rando!");
~spectrum.phase.plot("phase - rando!");
// reset the phase to zeros!
~newZeroSpectrum = ~spectrum.deepCopy;
~newZeroSpectrum.phase; // check... all rando!
~newZeroSpectrum.phase = Signal.zeroFill(~size);
~newZeroSpectrum.phase; // check... all zeros!
// now, resynthesize zeroed phase FreqSpectrum as Signal
~newRealZeroSignal = ~newZeroSpectrum.real.ifft(~newZeroSpectrum.imag, ~cosTable).real; // we just want the real part
~newRealZeroSignal.plot("time domain - zero-ed!");
/*
NOTE:
Zero-ing the phase "just" returns a sum of cosines, hence the spike @ index = 0
We can also make it linear phase using -linearPhase OR minimum phase using -minimumPhase
Linear phase will look like zero-ed phase, but the spike will be centered.
*/
~newLinearSpectrum = ~spectrum.deepCopy.linearPhase;
~newMinimumSpectrum = ~spectrum.deepCopy.minimumPhase;
// and, resynthesize & plot
~newRealLinearSignal = ~newLinearSpectrum.real.ifft(~newLinearSpectrum.imag, ~cosTable).real; // we just want the real part
~newRealMinimumSignal = ~newMinimumSpectrum.real.ifft(~newMinimumSpectrum.imag, ~cosTable).real; // we just want the real part
~newRealLinearSignal.plot("time domain - linear!");
~newRealMinimumSignal.plot("time domain - minimum!");
```

1 Like

@joslloand,Thanks so much, I should definitely give this as look!