Access a buffer as an array, inside a SynthDef?


I want to use the Cepstrum UGen and then continue some PV_ chaining on its output - but Cepstrum leaves the output data buffer in (magnitude, phase) form rather than (real, imaginary).

So far as I can tell, the PV_ChainUGens want input and output to be (real, imag). I can see that the .pvcalc method lets me access the data in the FFT chain buffer, but only after first unpacking from (real, imag), applying a func {mags, phases} that I supply, and then packing them back to (real, imag). Here, the Cepstrum output buffer data is already (mag, phase) so .pvcalc would convert it one time too many. Using only PackFFT seems attractive, but I need first to have the data in an Array, not a Buffer. And this is all on the server, so the loadBuffertoArray functions are not relevant.

So this leaves me wishing for a way of converting a (mag, phase) buffer back into a (real, imag) buffer from inside a SynthDef, or more generally, accessing the data in a buffer as an Array, inside a SynthDef. Any ideas?


As far as I can see, for this specific requirement (FFT data format), the units already do the required conversion internally, so you don’t need to worry about any of this.

include/plugin_interface_SC_SndBuf.h line 147:

    int coord; // used by fft ugens

This is a flag indicating whether the buffer is in complex or polar format.

Then, if you take a look into, for instance, IFFT_next() (server/plugins/FFT_UGens.cpp line 287) – this does expect the data in complex format. Right near the top, there’s:


… which function is defined in:

if (buf->coord == coord_Polar) means it will convert only if it needs to – if the last PV unit left the buffer in complex format, then, no conversion; if it left the buffer in polar format, then it will convert. There’s also ToPolarApx() for PV units that work on mag-phase data.

EDIT: Also checked UnpackFFTUGens.cpp – it does convert for you.

The time domain buffer units can operate on one buffer location per audio sample. Currently we don’t have a way to apply an arbitrary processing chain to multiple samples, or every sample, in a buffer simultaneously, per output audio sample. This would, for obvious reasons, be expensive.

pvcalc etc. get away with it because FFT/PV processing is done once per FFT frame, not per sample, so the pvcalc model doesn’t translate easily into the time domain.


Many thanks for your reply. I could not see the buf->coord flag in the documentation, but suspected it was there. pvcalc was far too slow. In the end, I wrote a new UGen PeakProminence to do what I needed (cvt to dB, linear regression on fromBin…toBin, and peak’s height over the regression line). It’s for CPP, a metric of vocal status. Works fine now.