Here is my new formula / method for an exponential test chirp.
sin((((pi/2^p)*L)/ln(2^p)) * e^((n/N)*ln(2^p)))
condition: ((pi/2^p)*L/ln(2^p)) = M*2*pi
M = a positive integer
L = a decimal number (floating point number) expressing chirpsize in unity samples
N = ceil(L), that is L rounded up to an integer, the real arraysize
p = the integer number of octaves in the chirp (user argument)
With this method, you get a chirp with evenly-spaced octaves. The chirp starts in sine-phase and also ends in (approximate) sine-phase, thus minimizing the ripple height. It is even the case that each octave starts and ends in approximate sine-phase, whatever use that may have.
The crucial element in the method is the exponential curve at index 0 and N.
e^((0/N)*ln(2^p)) = e^0 = 1
e^((N/N)*ln(2^p)) = e^ln(2^p) = 2^p
Notice that ((pi/2^p)*L/ln(2^p)) is a constant. If this constant is an integer multiple of 2*pi, the exponential curve will start with 2*pi and end with an integer multiple of 2*pi, since 2^p is also an integer.
Using this method, the start frequency depends on the sampling rate and number of octaves. The start frequency is (sr/2)/2^p. For example: (44100/2)/(2^10) = 21.53 Hz. The stop frequency is always near Nyquist, with a small deviance resulting from the rounding of L to N. For large N, the deviance is negligible for all practical purposes.
If y[n] is the chirp, the inverse chirp is formulated:
y[N-n] * -ln(1/2^p) * (2^(p/N))^-n
This calculates an inverse chirp with average power equal to the forward chirp. That means, more than unity peak level in the high frequencies, and less than unity in the low frequencies.
The user supplies a maximum length argument in nr of samples, and the required number of octaves. From this, a new object [expochirp~] calculates the first ideal length L below the maximum length. It returns the integer chirp size N as a message (so you can resize arrays), and starts feeding chirp and inverse chirp to the signal outputs.
Chirp and inverse chirp can be stored in a 32 bit float stereo .wav file, but the risk is that someone will play the stereo file in a regular soundfile player, which for the inverse chirp could lead to severe clipping. The reason for normalising to amplitude instead of unity peak level is that no further information is now needed about the chirp for normalisation after deconvolution. That normalisation will be simply N/2, like it would be the case for a linear chirp. For safety, chirp&inverse could be stored as .txt files instead of .wav. I don't know yet what is wise.
Although my expochirp method so far guarantuees a straightforward chirp with minimized ripple, the ripple is still considerable, and at the low frequency side quite problematic in my view. Some speaker systems may already have their own resonance frequencies in the region of the start frequency. Therefore this is exactly the region where a flat chirp spectrum is most important, to not push eventual resonances to further height. I have experimented with correction filters on the IR, but it would be better to relieve the problem at it's origin again, the shape of the chirp itself. I am now trying to find a fade-in window for that purpose. Windowing means amplitude modulation, causing sum- and difference frequencies. A proper window may cancel ripples, but a bad window could easily amplify them, or not? For me this is a new research topic. Only when results are acceptable I will finish [expochirp~] and share it.
Katja