Skip to content

pows

Calculates a power spectrum from a packed real FFT array.

Use pows after rfft to compare the power at different frequencies. It returns the squared magnitude of each bin, including DC and Nyquist. It runs at control rate and does not perform an FFT itself.

Syntax

kpower[] = pows(kspectrum[])
kpower[] pows kspectrum[]

Performance

kspectrum[] is an initialized, one-dimensional k-rate array in the packed format returned by the k-array form of rfft. Its length N must be even and at least 2. pows does not require a power-of-two length.

kpower[] is a one-dimensional k-rate array with N/2 + 1 elements. The opcode allocates its storage at initialization and calculates its values on each control cycle. Keep the input length fixed unless the output already has enough storage for the new length.

Input layout

The first two input elements hold the real-only DC and Nyquist coefficients. The remaining elements hold real and imaginary pairs for the bins between them.

Input index Value
0 DC coefficient, at 0 Hz
1 Nyquist coefficient, at half the sample rate
2*j Real part of bin j, for 1 <= j < N/2
2*j + 1 Imaginary part of bin j, for 1 <= j < N/2

The output places the bins in frequency order. For an FFT of samples at rate sr, output bin j represents j*sr/N Hz.

Output index Calculation
0 kspectrum[0] * kspectrum[0]
j, for 1 <= j < N/2 kspectrum[2*j]^2 + kspectrum[2*j + 1]^2
N/2 kspectrum[1] * kspectrum[1]

For example, the packed input [2, -3, 3, 4, 0, -2, -5, 0] produces [4, 25, 4, 25, 9]. The Nyquist value moves from the second input element to the last output element.

Pass the packed k-array output of rfft, not a Complex[] array, the full complex output of fft, or magnitude and phase pairs.

Scaling

The results are squared magnitudes, as if each value from mags had been squared. They are not in decibels. pows does not divide by the FFT size, adjust for a window or double the interior bins of the one-sided spectrum. Apply the scaling your analysis needs if you want mean-square values or power per Hz.

For a fixed FFT size and window, doubling a tone's amplitude gives four times the power in its bin.

Examples

The example compares two tones in a 64-sample block. At 48000 Hz, the first tone is 750 Hz with amplitude 0.5 and the second is 1500 Hz with amplitude 0.25. Both fit whole cycles in the block, so no window is needed for this comparison.

The printed bin powers are 256 and 64. Their ratio is 4, matching the square of the amplitude ratio. The example prints the result and makes no sound.

It uses pows.csd.

Compare the power of two tones
<CsoundSynthesizer>
<CsOptions>
-n -d -m0
</CsOptions>
<CsInstruments>
sr = 48000
ksmps = 32
nchnls = 1
0dbfs = 1

instr CompareTones
  iSize = 64
  kSamples[] init iSize

  // One cycle of the lower tone and two of the higher tone.
  // The lower tone has twice the amplitude.
  kIndex = 0
  while kIndex < iSize do
    kPhase = 2 * $M_PI * kIndex / iSize
    kSamples[kIndex] = 0.5 * cos(kPhase) + 0.25 * cos(2 * kPhase)
    kIndex += 1
  od

  // rfft returns packed real and imaginary coefficients.
  kSpectrum[] = rfft(kSamples)
  kPower[] = pows(kSpectrum)

  // Power bins are in frequency order, from DC to Nyquist.
  printks "750 Hz power = %.0f, 1500 Hz power = %.0f\n", 0, kPower[1], kPower[2]
  printks "Power ratio = %.0f\n", 0, kPower[1] / kPower[2]
  turnoff
endin
</CsInstruments>
<CsScore>
i "CompareTones" 0 0.1
e
</CsScore>
</CsoundSynthesizer>

See also

rfft, mags, phs, window, Array-based spectral opcodes

Credits

Author Victor Lazzarini, 2016.

New in Csound 6.08.