# Change spectrum and normalization

I have a question about magnitude of a spectrum. My task is to build the spectrum and make IFFT - the result waveform should have unity amplitude.

For example:

1. Create 2 arrays with Magnitudes and Phases;
2. Fill the magnitudes array with noise (for example Perlin noise or white uniform noise);
3. Fill the phases with noise too;
4. Build the symmetrical-rectangular spectrum based on the above arrays (the first and FFTSize / 2 elements of imaginary arrays are zeroed too);
5. Perform IFFT;
6. The output waveform should contains the noise with unity amplitude.

I have troubles because on the output i have single impulse with unity amplitude and silent noise.

The code:

' Main code

. . .

InitSoundFromFile "C:\temp\test_spin.wav"

DrawSpectrum picSpectrumOrigin, m_fSpectrum, m_cWavFile.SampleRate

Randomize 1, 1  ' // Replace data with noise

IFFT

DrawSpectrum picSpectrumModified, m_fSpectrum, m_cWavFile.SampleRate
DrawWaveform picWaveForm, m_fSamples, m_cWavFile.SampleRate

End Sub

' Noise/Signal ratio

Private Sub Randomize( _
ByVal fMagnitude As Single, _
ByVal fPhase As Single)
Dim lIndex  As Long
Dim fMag    As Single
Dim fPh     As Single

For lIndex = 0 To m_cFFT.FFTSize \ 2

fMag = Rnd / (m_cFFT.FFTSize / 2)
fPh = Rnd / (m_cFFT.FFTSize / 2)

m_fSpectrum(0, lIndex) = fMag * fMagnitude + (1 - fMagnitude) * m_fSpectrum(0, lIndex)
m_fSpectrum(1, lIndex) = fPh * fPhase + (1 - fPhase) * m_fSpectrum(1, lIndex)

Next

End Sub

Private Sub IFFT()
Dim fRectSpectrum() As Single
Dim lIndex          As Long
Dim lFFTSize        As Long

lFFTSize = UBound(m_fSpectrum, 2) * 2

ReDim fRectSpectrum(1, lFFTSize - 1)

For lIndex = 0 To UBound(m_fSpectrum, 2)

fRectSpectrum(0, lIndex) = Cos(m_fSpectrum(1, lIndex)) * m_fSpectrum(0, lIndex)
fRectSpectrum(1, lIndex) = Sin(m_fSpectrum(1, lIndex)) * m_fSpectrum(0, lIndex)

Next

For lIndex = 1 To lFFTSize - 1

fRectSpectrum(0, lFFTSize - lIndex) = fRectSpectrum(0, lIndex)
fRectSpectrum(1, lFFTSize - lIndex) = -fRectSpectrum(1, lIndex)

Next

fRectSpectrum(1, 0) = 0
fRectSpectrum(1, lFFTSize \ 2) = 0

m_cFFT.IFFTR fRectSpectrum(), m_fSamples

Debug.Print m_fSamples(0)

End Sub


InitSoundFromFile - just creates a waveform from a file (just container) and calculates the spectrum to m_fSpectrum array; Randomize - adds the noise to m_fSpectrum array (with arguments equal to 1 it just replace signal with noise);

The output i have: I've fixed the single impulse time-domain result by change range of phase-randomization from -PI to PI. I still can't calculate magnitude bins values to get the unity noise amplitude in time domain. What's the value of noise should i add in frequency domain to get unity noise value in time domain?

Now i add the random values from (0..1) / (FFTSize / 2) range to bins but then i get the time domain noise with 1.968998E-02 maximum amplitude after IFFT.

• Can you add a plot of your result? Jul 14 at 12:23
• I've fixed problem with single pulse (just i've changed random-range for phases from -pi to pi), but i still can't calculate bins values to get unity time domain noise.
– John
Jul 14 at 15:36