2
$\begingroup$

suppose I have a sum of cosine waves. Their frequencies are 500 Hz, 501 Hz, 502 Hz and so on, all the way up to 900 Hz. The important thing here is that the amplitude of the slowest one and of the fastest one is equal to some quantity a/2 while the amplitude of all the others is equal to a. Because the GCD of all the frequencies is equal to 1, the waveform repeats itself every 1 second. Now if all the components are indeed cosine waves, then the highest absolute value within each 1-second period is a×400 (because 1/2 + 1×399 + 1/2 = 400). However, if each individual sinusoid had a different phase offset, then the highest absolute value found within each 1-second period would be less than a×400. My question is: Which specific phase offsets should I choose for the individual sinusoids if the highest absolute value (within one 1-second period) should be the lowest possible? Thanks.

$\endgroup$

1 Answer 1

1
$\begingroup$

What you are describing is called a "low crest factor" signal. The crest factor is the ratio of the absolute maximum to it's RMS value. The crest factor is a metric how "peaky" a signal is. The lowest possible crest factor is 1 (constant, or rectangular wave). A sine wave has a crest factor of $\sqrt{2}$.

Choosing the same phase for all frequencies will result in the highest crest factor which would in your example be around 28 (assuming a sample rate of 48kHz and a DFT length of 48000, i.e. one second of signal).

The quickest way to reduce the crest factor is to simply choose a random phase for each spectral component. If the number of non-zero frequencies is reasonable large (which in your case it is), this will result in a Gaussian distribution and a crest factor somewhere between 3.5 and (depending on the length of the signal).

A better choice is to generate a "sweep like" signal. Sweeps are frequency modulated sine wave and hence they have a Crest factor of only $\sqrt{2}$ (1.414). However a simple linear sweep will not exactly match your amplitude requirements, but we can correct for this (at the expense of a slightly higher crest factor).

  1. Create a sweep from 500Hz to 900Hz
  2. Do an FFT
  3. Adjust the amplitudes to your target spectrum but keep the phase of the sweep spectrum
  4. Inverse FFT

If we do this for your specific signal, we get a crest factor of about 1.86 and the signal looks like this:

enter image description here

if the highest absolute value (within one 1-second period) should be the lowest possible?

The lowest possible is very difficult to achieve since it requires solving a highly non-linear optimization problem. Typically this is done by using iterative search algorithms. In your case the optimum is limited by the "degrees of freedom". Let's assume a sample rate of 48kHz and a signal that's one second long. You have 48000 samples but the only things you can control are 401 phases. In other words you only have 400 knobs to turn to constrain 48000 numbers simultaneously.

I took a swing at this and got the crest factor down to slightly below 1.5, but I think this is about the best you can do with reasonable (for my personal definition of "reasonable" that is). Looks like this

enter image description here

Appendix: Matlab code to generate the sweep-like version

%% sweep from 500Hz to 900Hz in 1 Hz steps
 fs = 48000;% sample rate
 nx = fs; % signal length: one second
 t0 = (0:nx-1)'/fs;  % time vector
 x0 = chirp(t0,500,1,900); % create a sweep from 500Hz to 900Hz;
 fx0 = fft(x0);
 %% create the spectral mask
 fx1 = zeros(nx/2+1,1);
 dF = fs/nx; % frequency resolution. Simply one in this case
 i500 = round(500/dF) + 1; % index of 500 Hz
 i900 = round(900/dF) + 1; % index of 900 Hz
 
 % copy phase
 fx1(ifr) = fx0(ifr)./abs(fx0(ifr));
 % adjust amplitude at the edges
 fx1(i500) =  fx1(i500)/2;
 fx1(i900) =  fx1(i900)/2;
 fx2 = [fx1; conj(fx1(end-1:-1:2))];  % make conjugate symmetric
 x2 = ifft(fx2); % back to time domain
 x2 = x2/rms(x2); % normalize RMS to 1
 
 %% plot it
 figure(1);
 clf;
 plot(t0,x2);
 xlabel('time in seconds');
 grid('on');
 crestFactor = max(abs(x2))./rms(x2);
 title(sprintf('Amplitude adjusted sweep, Crest = %6.3f',(crestFactor)));
$\endgroup$
3
  • $\begingroup$ If you have computer time, like even with MATLAB you can run something like this overnight, then use different collections of random phases, measure the crest factor and choose the collection of random phases that has the lowest crest factor. You can also make small deviations to one phase at a time and see if that deviation slightly reduces or increases the crest factor. Just keep making wild-ass guesses and tweeks until you get a result that is better than all other wild guesses. $\endgroup$ Commented Apr 12 at 15:40
  • $\begingroup$ I know. But in practice I find little value going below 1.5. Most downstream equipment is designed with sine waves in mind and you run the risk of clipping/over-powering something. I also found that very low crest factors are extremely fragile: even a simple R/C filter downstream will increase it again. $\endgroup$
    – Hilmar
    Commented Apr 12 at 16:35
  • $\begingroup$ That's true. If you tweek it to get the lowest possible crest factor, all an APF can do with it is to increase the crest factor. $\endgroup$ Commented Apr 12 at 18:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.