;nyquist plug-in
;version 1
;type process
;name "Nonlinear Compressor/Limiter/Expander"
;action "Nonlinear Compressor/Limiter/Expander"
;info "by Igor Chernenko\nReleased under terms of GNU Public License.\nNonlinear compression can produce natural loudness, simply because it is more natural than linear compression.\nIf you do not like any loudness, try to decompress sound with expander (compression degree < 0).\nFor compressing speech, try these presets: Threshold = 0.66; compression degree = 1; compression power = 3.\nIf it is too strong, take compression power = 1 and/or a higher threshold.\nHOW TO USE:\n1. switch to 32-bit resolution;\n2. normalize the sound to 0dB;\n3. apply the compressor.\ncompression degree = 1 means \ncompression degree = 0.5 means \ncompression degree = 0 means \ncompression degree < 0 means \ncompression power = 1 means \ncompression power = 3 means **\ncompression power = 5 means "
;control comp-limit "Threshold" real "" 1 0.66 1
;control compression-degree "compression degree" real "" 1 -5 1
;control power-comp "compression power" int "" 1 1 5
; Nonlinear Compressor/Limiter/Expander by Igor Chernenko
; updated November 23, 2008
; Released under terms of the GNU Public License
; http://www.opensource.org/licenses/gpl-license.php
;
; HOW IT WORKS
;
; Nonlinear Compressor performs smooth non-linear transformation of the sound rather than classic compression.
; Afterwards, the sound is amplified to the previous level. If compression degree < 0, it works as expander.
; Although compression curves look similar to those of classic compressor, the non-linear curves are smooth,
; and this makes the difference.
;
; The magic formula of compression is this one:
;
; Y = X - beta*(((1-alpha)/3)*X^3 + (alpha/11)*X^11)
;
; alpha >= 0
;
; beta <= 1
;
; X = sound
;
; Y = compressed sound
;
; Threshold = (2/33)(4*alpha+11)
;
; alpha = (1/8)*(33*Threshold-22)
;
; This "esoteric formula", of course, is a Taylor polynomial of the 11th order. Do not worry!
; The 11th order is not a problem anymore, for we have a magic computer algebra system
; called Maxima. It is easy to use, and it is free, open source and cross-platform. You can
; train sophisticated math, solve equations, and build graphics on Linux and Windows for free.
; Maxima homepage:
; http://maxima.sourceforge.net
; http://maxima.sourceforge.net/documentation.html
;
; To understand how the Nonlinear Compressor works, you may need to see compression curves.
; Such curves can be easily produced with Maxima.
; I use "wxMaxima" together with "gnuplot" on Ubuntu Linux. This "wxMaxima" is so designed
; that you do not need to read any documentation (or help-file) on Maxima. I have not read yet.
;
; It would be much more convenient, of course, if the Nonlinear Compressor would also display
; graphics of compression curves. But Nyquist does not support such things. One may need
; Python, and the source code of Audacity, and this might be a long story...
(if (> comp-limit 1.0) (setq comp-limit 1.0))
; muu=(33*comp-limit - 22)/8
; (/ (- (* 33 comp-limit) 22) 8)
(setq muu (/ (- (* 33 comp-limit) 22) 8.0))
(if (< muu 0.0) (setq muu 0.0))
(if (> compression-degree 1.0) (setq compression-degree 1.0))
; betaa1 = (compression_degree/3)*(muu-1)
; betaa2 = -(compression_degree/11)*muu
(setq betaa1 (* (/ compression-degree 3.0) (- muu 1)))
(setq betaa2 (* (/ compression-degree -11.0) muu ))
; max_amp = 1 + betaa1 + betaa2
(setq max-amplitude (+ (+ 1.0 betaa1) betaa2))
(setq amplify-it (/ 1.0 max-amplitude))
; (setq max-amplitude 1.0)
(display "Threshold" comp-limit)
(display "muu" muu)
(display "compression degree" compression-degree)
(display "betaa1" betaa1)
(display "betaa2" betaa2)
(display "max-amplitude" max-amplitude)
(display "amplify-it" amplify-it)
; (mult a [b c ...]) Returns the product of a, b, c, ..., allowing mixed multiplication
; of sounds, multichannel sounds and numbers.
; x + betaa1*x^3 + betaa2*x^11
(defun compress-it (mysound)
(scale amplify-it
(sum mysound
(scale betaa1
(mult mysound (mult mysound mysound))
)
(scale betaa2
(mult mysound (mult mysound (mult mysound (mult mysound (mult mysound (mult mysound (mult mysound (mult mysound (mult mysound (mult mysound mysound))))))))))
)
)
)
)
(defun compress-it-2-times (mysound) (compress-it (compress-it mysound)))
(defun compress-it-3-times (mysound) (compress-it (compress-it-2-times mysound)))
(defun compress-it-4-times (mysound) (compress-it (compress-it-3-times mysound)))
(defun compress-it-5-times (mysound) (compress-it (compress-it-4-times mysound)))
(cond
((= power-comp 1)
(setf compressed-sound (compress-it s))
)
((= power-comp 2)
(setf compressed-sound (compress-it-2-times s))
)
((= power-comp 3)
(setf compressed-sound (compress-it-3-times s))
)
((= power-comp 4)
(setf compressed-sound (compress-it-4-times s))
)
((= power-comp 5)
(setf compressed-sound (compress-it-5-times s))
)
)**