Daqarta
Data AcQuisition And Real-Time Analysis
Scope - Spectrum - Spectrogram - Signal Generator
Software for Windows
The following is from the Daqarta Help system:

# Macro Array Spectrum (FFT) Operations

## Introduction:

Macro array operations can perform Fast Fourier Transform (FFT) operations on raw waveform data and store the results in any Buf0-Buf7 array. Data may come from instantaneous or averaged main waveform buffers, or from the same or another BufN.

The FFT takes 1024 waveform samples and converts them into 512 pairs of values called "Real" and "Imaginary" (Re and Im), each pair representing one of 512 spectral lines designated 0-511. The Re components have even indices (starting from 0) and the Im indices are odd, so to access the Kth spectral line in Buf0, read the Re value at Buf0[2 * K] and the Im value at Buf0[2 * K + 1].

There are also operations to perform an inverse FFT (IFFT), which converts the Re,Im spectrum data to waveform data. One use for this is simple digital filtering: Take an FFT of the raw waveform, remove the unwanted spectral lines (Re,Im pairs) by setting them to 0, and then perform an IFFT to get a filtered waveform.

In addition, there are operations to convert the raw Re,Im data to a magnitude spectrum or a phase spectrum.

## FFT Operations:

Buf0="<fW1" takes the FFT of waveform channel 1 and sends the raw Re,Im data to Buf0. The 16-bit waveform data is automatically scaled up to 32-bit for maximum FFT resolution, by multiplying each sample by 2^16 = 65536.

Valid waveform channels are 0 to 3:

```    0 = Left In
1 = Right In
2 = Left Out
3 = Right Out
```

In this and any buffer command that requires a channel number you can use an expression for the channel by enclosing it in parentheses, as in Buf0="<=fW(A+B)".

Buf0="<fA1" takes the FFT of the waveform average of channel 1, if present (active or done), and sends the raw Re,Im data to Buf0. Data values are scaled as above. If this is invoked during Spectrum mode and a waveform average is present (typically from starting an average in waveform mode, then switching to Spectrum mode), it is the same as Buf0="<=A1" discussed under Copy/Swap Operations.

Buf0="<fB0" takes the FFT of assumed 32-bit data in Buf0 and sends raw Re,Im data back. Note that if Buf0 is a simple copy of 16-bit waveform data, such as from Buf0="<=W1", you should first use Buf0="<*(65536)" to scale it up to 32 bits for best FFT resolution. See Macro Array Math Operations.

In this and any buffer command that requires a source (right side) buffer number you can use an expression for the buffer by enclosing it in parentheses, as in Buf0="<=fB(X+Y)".

Note: The above <fW, <fA, and fB operations do not apply any spectrum window functions. To apply windowing, use an uppercase FW, <FA, or FB. The selected window will be applied, even if Window is toggled off for display of main channels.

## Inverse FFT Operations:

Buf0="<iS1" takes the inverse FFT (IFFT) of Re,Im data in Spectrum channel 1 and sends wave data to Buf0. Afterward, the result should be scaled by Buf0="<*(512)" to restore the original waveform.

Buf0="<iB0" takes the IFFT of assumed raw Re,Im data in Buf0 and sends waveform data back. If the raw data is from an FFT using Buf0="<*(65536)" pre-scaling as above, then after the IFFT the resulting wave data must be downscaled by Buf0="</(32)" to restore the original data range.

In other words, the FFT/IFFT pair results in a 1/2048 reduction in amplitude, so a further reduction of 1/32 removes the original 65536 scaling.

However, if the purpose of the FFT/IFFT is to provide filtering (by operating on the FFT output before taking the IFFT), please be aware that the fundamental sine wave component of a square wave is 1.27 times the amplitude of the square wave itself. That means that with the above scaling the filtered waveform could be too large for any subsequent FFT (such as to verify the filtered spectrum).

To avoid such problems, the _Filt_Task macro used by the FFT_Filter mini-app only prescales by 32768 before the initial FFT. After the FFT/IFFT (which caused a reduction of 1/2048), it scales the filtered waveform down by 1/16 for waveform display. This removes the initial 32768 scaling to restore the original signal range.

For Spectrum display of the filter output, _Filt_Task scales the wavform up by 2048 after the IFFT, removing the 1/2048 reduction of the FFT/IFFT pair to restore the original 32768 scaling. Then it takes the display FFT with this "safe" scaling, and scales up by 2 afterward to restore the original signal range before finding the magnitude for display.

## Magnitude and Phase Operations:

The magnitude of an FFT spectral line is equal to the square root of the sum of the squares of Re and Im for that line.

Buf0="<mS1" computes 512 spectral magnitudes from 1024 raw Re,Im FFT values of Spectrum channel 1, and sends them to Buf0[0]-Buf0[511]. Buf0[512]-Buf0[1023] are untouched.

To scale magnitude values down to the 16-bit range such that a full-scale (+/-32767) input sine wave (whose frequency falls exactly on a spectral line) yields a +32767 magnitude, divide by 2^15 or shift down by 15 bits.

Buf0="<mB1" is similar to the above but assumes raw Re,Im data in Buf1 (such as after prior array copy via Buf1="<=Sn", where n = 0-3) and computes 512 magnitudes which are stored in the lower 512 values of Buf0. The upper 512 buffer values are untouched. Note that Buf0="<mB0" is a valid command.

The phase at an FFT spectral line is the angle whose tangent is Im/Re.

Buf0="<pS1" computes 512 phase values from 1024 raw Re,Im FFT values of Spectrum channel 1, and sends them to Buf0[0]-Buf0[511]. Buf0[512]-Buf0[1023] are untouched.

Buf0="<pB1" is similar to the above but assumes raw Re,Im data in Buf1 and computes 512 phase values which are stored in the lower 512 values of Buf0. The upper 512 buffer values are untouched. Note that Buf0="<pB0" is a valid command.

Note that since the phase is the arctangent of Im/Re, even very tiny values of Re and Im can result in a very large range of computed phase values. Low-level noise at otherwise empty FFT frequency lines can thus cause a wildly incorrect phase response.

Buf0#p=K sets the threshold for phase detection. When either the Re or Im value of a pair is below K, the phase for that frequency is reported as 0. K may be a constant, variable, or expression. The default value is 262144 (hex 00040000), which is about 0.024% (-72 dB) relative to full scale (1073741824 or hex 40000000). Attempting to set a negative threshold will automatically reset the threshold to this default.

Note that use of Spectrum Window Functions has a big effect on the phase spectrum.