## 5 Streaming Spectral Processing  
Csound has a very useful mechanism for _streaming_ (as opposed to _batch_) spectral processing, which is based on its fsig data type [26]. This is a self-describing type, which holds a frame of spectral data in one of several formats, defined by the C data structure PVSDAT (This C structure is provided here for reference only, it is opaque to CPOF):
``` typedefstructpvsdat{ int32N; int32 sliding; int32 NB;int32 overlap;  int32 winsize;  int32 wintype;  int32 format;  uint32 framework;  AUXCHframe; } PVSDAT; This structure contains information on the DFT size used in the analysis, the window and hop sizes, the window type, the data format, and the current frame count. It also sets the analysis mode (normal or sample-by-sample sliding, where the actual hopsize is 1). The actual frame data is stored in an AUXCH memory structure, which is managed by Csound. An opcode implementing fsig processing will operate nominally at the control rate, but will actually compute new frames at a rate determined by the analysis hopsize. This is implemented by checking the fsig framecount and only proceeding to consume and produce new frames if this is greater than the opcode internal frame counter. For streaming spectral processing opcodes, CPOF provides a separate base class, FPlugin, derived from Plugin, with an extra member variable, framecount, used for this purpose. To facilitate fsig manipulation, the toolkit provides the Fsig class, derived from PVSDAT, with the following methods:

* init(): initialises an fsig. There are two overloads: it is possible to initialise it from individual parameters (DFT size, hop size, etc.) or directly from another fsig. Initialisation is only needed for output variables. * dft_size(): DFT size. * hop_size(): hopsize. * win_size(): window size. * win_type(): returns the window type (Hamming = 0, von Hann =1, Kaiser = 2, custom = 3, Blackman = 4 and 5, Nutall = 6, Blackman-Harris = 7 and 8, rectangular = 9). * nbins(): number of bins. * count(): current frame count. * isSliding(): checks for sliding mode. * fsig_format(): returns the data format. This will vary depending on the source. To facilitate identification, CPOF defines the following constants:
* fsig_format::pvs: standard phase vocoder frame, composed of bins containing amplitude and frequency pairs.There are \(N/2+1\) bins (N is the DFT frame size), equally spaced between between 0 Hz and the Nyquist frequency (inclusive). * fsig_format::polar: similar to the pvs type, except that bins contain pairs of magnitude and phase data. * fsig_format::complex: as above, but with bins holding complex-format data (real, imaginary). * fsig_format::tracks: this format holds tracks of amplitude, frequency, phase, and track ID (used in partial tracking opcodes). ### Phase Vocoder Data

The most common format used in Csound opcodes is phase vocoder amplitude-frequency [25; 27]. To provide a convinient access access to bins, a container interface is provided by pv_frame (spv_frame for the sliding mode (pv_frame is a convenience typedef for Pvframe<pv_bin>), whereas spv_frame is Pvframe<spv_bin>). This is a class derived from Fsig that can hold a series of pv_bin (spv_bin for sliding (pv_bin is Pvbin<float> and spv_bin is Pvbin<MYFLT>)) objects, which have the following methods (Figure 3):

* amp(): returns the bin amplitude. * freq(): returns the bin frequency. * amp(float a): sets the bin amplitude to a. * freq({float f): sets the bin frequency to f.
* operator*(pv_bin f): multiply the amp of a pvs bin by f.amp. * operator*(MYFLT f): multiply the bin amp by f
* operator*=(): unary versions of the above. The pv_bin class can also be translated into a std::complex<float>, object if needed. This class is also fully compatible with the C complex type and an object obj can be cast into a float array consisting of two items (or a float pointer), using reinterpret_cast<float(&)[2]>(obj) or reinterpret_cast<float*>(&obj).