function y = whitenoise_perfect(T, Fs, N)
   // White noise generator with perfectly flat spectrum
   //
   // Usage:
   //       y = whitenoise_perfect(T, Fs, N)
   //
   // where T:  duration in s
   //       Fs: sample rate in Hz
   //       N:  length of frame over which the FFT
   //           spectrum is flat
   //       y:  white noise output row vector with
   //           RMS value equal to 1
   //
   // NOTE: The signal generated by this function
   //       has perfectly flat spectrum over any 
   //       window of length N, but for any other 
   //       window length the spectrum is not flat.
   //       The DC component of any block of length
   //       N has been removed and the RMS value 
   //       has been adjusted to 1
   //
   // TECHNICAL DESCRIPTION
   // The signal is generated from a perfectly flat 
   // spectrum with random phase
   //
   // Y = exp(%i*phi),
   // 
   // where phi is a vector of phases whose first
   // half is random and whose second half complies 
   // with conjugate phase (opposite phase), as
   // required to correspond to a real signal in
   // the time domain. Both the DC component and
   // the amplitude of the Nyquist frequency    
   // component are set to 0. The time-domain signal
   // is obtained applying the IFFT.
   // 
   // --------------------------------  
   // Federico Miyara
   // 2022-04-28
   // 2024-11-03

   // Signal length
   L = floor(T*Fs) + 1;

   // Number of complete frames
   n = floor(L/N);

   // Tail length
   Ltail = L - n*N; 

   // Phase of spectral components of noise
   phi = 2*%pi*rand(1,N/2-1,"normal");
   phi = [0, phi, 0, -(phi($:-1:1))];

   // FFT of noise frame
   Y = exp(%i*phi);

   // Signal obtained by applying IFFT, removing
   // DC component and normalizing to get effective
   // value = 1
   yy = ifft(Y) - 1/N;
   yy = yy / sqrt(mean(yy.^2));

   // Replication n times
   yy = repmat(yy, 1, n);
   
   // Extension by an incomplete frame to reach 
   // the desired signal length
   y = [yy, yy(1:Ltail)];

endfunction
