Exponential Amplifier (Exponentiator)

This Plug-in is a distortion effect. It computes the exponent (e^x) of the signal, converting (sample) to e^(sample).

I came up with this idea after finding about logarithmic and exponential amplifiers, which use the exponential voltage/current relationship in a diode to generate a non-linear output. Logarithmic amps are often used to measure intensity, while exponential amplifiers are used in applications like generating the control voltage for an analog synthesiser’s VCO.

Because the exponential amplifier is inherently non-linear, I decided it would be interesting to experiment with using it as a distortion effect.

During testing I found that this plugin has a problem with stereo tracks, where the right channel doesn’t get normalised while the left channel does. On mono tracks it shouldn’t be a problem. Let me know what you think.

The “Multiplier” could best be described as the peak voltage that 1.0 Amplitude (0 dBFS) is referred to. For example, a multiplier of 2.0 would refer 1.0 Amplitude to 2.0 Volts.

“Centered” allows you to select between converting (sample) to e^(m * sample) or (e^(m * sample) - 1), where m is the multiplier mentioned above.

“Normalise” reduces the peak amplitude of the resulting (exponentiated) signal to the Amplitude entered.
Exponentiator.ny (944 Bytes)

Have you posted the correct version of this plug-in?
On running it (with the Debug button, default settings and a mono track), I’m getting the error:

error: unexpected EOF

Also, I notice that “flr” is defined but not used.

Also, you only appear to use the “multiplier” (“a”) if track is mono.

I’d also suggest a different approach to normalizing.
The problem with using PEAK is that it retains a reference to the sound in memory, which makes the effect heavy on RAM use, and limits the length of the selection that can be processed.

Because you know that the signal should have a peak level no greater than 1.0 (which, you could enforce using CLIP), you can calculate the maximum peak level as (for mono tracks) as e^a (where “a” is the multiplier.
You can also calculate the minimum output a e^-a.

From that you can calculate the necessary “make-up gain” and the correct offset for centering (assuming that the original waveform was symmetrical).

The problem here is due to incorrect use of DIFF.

To demonstrate the problem, I’ll use an array of two numbers instead of an array of two sounds:

(setf test #(20 20))  ;an array containing the numbers 20 and 20
(print (diff test 2))	;returns #(18 20)

There’s two ways you can fix this:

(setf test #(20 20))
(print (diff test #(2 2)))  ;returns #(18 18)

or

(setf test #(20 20))  ;an array containing the numbers 20 and 20
(print (multichan-expand #'diff test 2))	;returns #(18 18)

The way that the second solution works, is that MULTICHAN-EXPAND is a macro that “expands” the array and applies the function DIFF to each element of the array in turn. This is a common way to apply functions that require mono sounds, to stereo tracks. See also: Missing features - Audacity Support

Here’s the updated version of this plugin.
Exponentiator.ny (950 Bytes)

Congratulations on creating a fully working plug-in.

It’s an interesting form of distortion, producing similar overtones (harmonics) to clipping, but with a gradual onset of the distortion as the level increases.
Inevitably it creates a large amount of DC offset (the average level is always above zero), which could be problematic in practical use situations, though that could be mitigated by applying a low cut filter.

I note that you still set “flr” to zero, which does nothing. That could be removed entirely.

Also, you don’t need “(if (not (boundp 'norm))”.
The variable “NORM” is already bound to a value by the “;control” header:

;control norm "Normalise" choice "Yes,No" 0

Re. Normalizing: This isn’t necessary, but as a point of interest. If we assume that the input is symmetrical (maximum positive peak is about the same as the maximum negative peak), then we can avoid the memory restrictions of the “PEAK” command like this (slightly simplified interface):

;control multiplier "Multiplier" float "" 1 -10 10
;control level "Normalize to" float "" 0.8 0 1

(defun process (sig normgain)
  (let* ((sig (mult sig normgain multiplier))
         (sig (s-exp sig))
         (maxpeak (exp (abs multiplier))))
    (setf makeupgain (/ 1.0 (- maxpeak 1)))
    (setf sig (mult (sum sig -1) makeupgain level))))


(setf normalizegain (/ (get '*selection* 'peak)))
(multichan-expand #'process *track* normalizegain)