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.
- Create 2 arrays with Magnitudes and Phases;
- Fill the magnitudes array with noise (for example Perlin noise or white uniform noise);
- Fill the phases with noise too;
- Build the symmetrical-rectangular spectrum based on the above arrays (the first and FFTSize / 2 elements of imaginary arrays are zeroed too);
- Perform IFFT;
- 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.
' Main code Private Sub Form_Load() . . . 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.