Analyze plug-in: Peak Amplitude

The peak amplitude of a selection can be found quite easily and quickly as a side-effect of the “Amplify” effect, but here is a plug-in that is designed specifically for the job.
Using the Amplify effect has the advantage that it is extremely fast, but some users may not be comfortable with using the Amplify effect this way.

This plug-in works well for short selections and provides output in both dB and linear scales.
It is rather slow on very long selections, but it does not require lots of RAM so it can be used on very long selections (up to about 6 hours of audio at 44.1 kHz if you don’t mind waiting for it :wink:)
peak-amplitude.ny (1.44 KB)

Apropos side effect:
The Plug-in evaluates the peak with the equally named function.
There can situations arise where you also want to know the length of a sound, its sample rate or the number of channels.
One could now easily use the functions “peak” “snd-extent” and so on. The bad thing is that the length calculation takes nearly the same amount of time as the peak function does.
Here comes the trick with the side effect into play. “Peak” is based on “s-save”. By using this function directly we will obtain 4 values instead of only one and in the same time. Here’s the snippet to illustrate this:

(mapcar #'(lambda (arg1 arg2) 
    (format t "~a: ~a ~%" arg1 arg2))
  '("Peak" "Sample rate" "Channels" "Duration")
  (cons
    (progv 
      '(*standard-output*) '(nil)
        (s-save  s ny:all ""))
    *rslt*))

Neat trick Robert, though not very easy to follow for people that are starting out with Nyquist.

It may also be worth noting that sample rate, number of channels and duration are also available (almost instantly) without needing to calculate them:

(format nil
  "Sample Rate: ~a~%Channels: ~a~%Duration: ~a"
  *sound-srate*
  (if (arrayp s) "2 (stereo)" "1 (mono)")
  (get-duration 1))

The main point of the plug-in was to look ways to avoid loading the audio into RAM, thus allowing processing of long selections, so for completeness here’s a quick example of your snippet used to print the output but still releasing memory as it processes the audio:

;;; make a local copy of 's' and release 's' immediately
(defun get-s ()
  (let ((temp s))
    (setf s nil)
    temp))

;;; construct output string
(defun make-text (a b)
  (setq output
    (format nil "~a: ~a ~%~a" a b output)))

(setq output "") ; global variable

(mapcar #'(lambda (arg1 arg2)
            (make-text arg1 arg2))
            '("Peak" "Sample rate" "Channels" "Duration")
            (cons
              (progv
                '(*standard-output*) '(nil)
                  (s-save  (get-s) ny:all ""))
              *rslt*))

(print output)