Re: [Audacity-nyquist] Text entry envelope plug-in
A free multi-track audio editor and recorder
Brought to you by:
aosiniao
From: Steve t. F. <ste...@gm...> - 2010-05-28 10:38:44
|
;nyquist plug-in ;version 3 ;type process ;categories "http://lv2plug.in/ns/lv2core/#DynamicsPlugin" ;name "Text Envelope 0.83" ;action "Applying Envelope..." ;info "Text Input Envelope by Steve Daulton. Released under GPL v2.\nhttp://audacity.easyspacepro.com\n\nIntermediate Control Points have time values from 0% to +/-100%, or as the\nabsolute time between the start and end of the selection.\nPositive values for distance from the start, negative values for distance from the end.\n\nWhen Amplification Units are dB, silence is achieved by entering '-inf' (without quotes)\nor use a large negative value. Other than '-inf', all entered text must be numerical.\n\nIntermediate points must be entered in pairs separated by a space or comma.\nEach pair of values must be separated from other pairs by spaces or commas.\nSee help file for examples." ;control extra "Show Help Menu" choice "No,Quick Help,Examples,More Tips" 0 ;control t-units "Time Units" choice "milliseconds,seconds,minutes,%" 1 ;control amp-units "Amplification Units" choice "dB,%" 0 ;control Linit "Initial Amplification" string "" "0" ;control Lfin "Final Amplification" string "" "0" ;control text "Intermediate Control Points as pairs of\ntime and amplification e.g. '1,0 2,2.5'" string "" ;; version 0.83 beta ;; HELP FILES (setq help (format nil "HELP (overview):\n 'Initial Amplification' = how much to amplify the start of the selection. 'Final Amplification' = how much to amplify the end of the selection (relative to the original sound level).\n When Amplification Units are dB, silence is achieved by entering '-inf' (without quotes) or a large negative value. Other than '-inf', all values must be numbers.\n Intermediate points must be a 'time' 'amplification' pair, separated by spaces or commas. Each pair of values must be separated from other pairs by one or more spaces or commas.\n Time values for intermediate control points: When time units are set to '%' the Intermediate Control Points have time values in the range 0% to +/-100%. Positive values = time after the start of the selection Negative values = time before the end of the selection. Decimals are allowed but must use a dot as the decimal separator.\n All fades between control points are linear.\n Remember to deselect Help before using the effect.")) (setq examples (format nil "EXAMPLES: Fade out from full volume to silence:\n For % settings: Initial Amplification = 100 Final Amplification = 0\n For dB settings: Initial Amplification = 0 Final Amplification = -inf\n Fade from silence at 0 seconds, to full volume after 2 seconds, then back to silence at the end:\n For % Amplification settings / Time settings in seconds: Initial Amplification = 0 Final Amplification = 0 Intermediate Control Points = 2 100\n For dB Amplification settings / Time settings in seconds: Initial Amplification = -inf Final Amplification = -inf Intermediate Control Points = 2 , 0\n Remember to deselect Help before using the effect")) (setq tips (format nil "TIPS:\n Commas or spaces may be used to separate values. Intermediate Conrol Point times may be written relative to the beginning or end of the track selection. A 10 second track with -6dB points at 2 and 8 seconds can be written as either: 2,-6 8,-6 or as 2 -6 , -2 -6\n Intermediate Control Points are automatically sorted into the correct time order. If you wish to add an additional control point 'time/amplification' pair to the current list, you can just add it to the end of the list. For example: 1,2 3,-12 8,-12 9,2 5,-15 gives exactly the same result as 1,2 3,-12 5,-15 8,-12 9,2\n Remember to deselect Help before using the effect")) (case extra (1 (print help)) (2 (print examples)) (3 (print tips)) (T ;; Initialise variables (setq err-msg "") (if (equal Linit "")(setf Linit "0")) (if (equal Lfin "")(setq Lfin "0")) ;;FUNCTIONS ; function to convert a string into a list (defun string-to-list (string) (read (make-string-input-stream (format nil "(~a)" string)))) (defun check-time-numbers (var) (if(not(numberp var)) (setq err-msg (strcat err-msg (format nil "'~A' is not valid.~%Time values must be numbers~%" var))))) (defun substitute (new old text) (do ((i 0 (setq i (1+ i)))(newtext "")(new (string new))) ((= i (length text)) newtext) (setf newtext (if (char= (char text i) old) (strcat newtext new) (strcat newtext (string (char text i))))))) ; Time conversion functions (defun ms-to-lin (var) (if (< var 0) (+ 1.0(/ var(get-duration 1000.0))) (/ var(get-duration 1000.0)))) (defun s-to-lin (var) (if (< var 0) (+ 1.0(/ var (get-duration 1))) (/ var (get-duration 1)))) (defun m-to-lin (var) (if (< var 0) (+ 1.0(/ var (get-duration (/ 60.0)))) (/ var (get-duration (/ 60.0))))) (defun pc-to-lin (var) (if (< var 0) (+ 1.0(/ var 100.0)) (/ var 100.0))) ;;;;;;;;;;; START OF MAIN FUNCTION ;;;;;;;;;;;;; ;; Main function to convert and check string list (defun convert (inlist t-u amp-u) ;print input data (format T "inlist: ~a~%time: ~a~%amplify: ~a~%" inlist t-u amp-u) ; Split time and level (setf newlists (let (time amp) (do ((i (1- (length inlist)))) ((<= i 0)(vector time amp)) (setf amp (cons (nth i inlist) amp)) (setf time (cons (nth (1- i) inlist) time)) (setq i (- i 2))))) (setf times (aref newlists 0)) (setf amps (aref newlists 1)) ;test (format T "times: ~a~%" times) (format T "amps: ~a~%" amps) ; Amplify conversion function (convert amplify values to linear) (defun make-linear (var) ; var=input to check, unit is dB or % ; Nested function to handle '-inf (defun convert-symbol (val) (if (not(eql val '-inf)) ; check for invalid value (setq err-msg (strcat err-msg (format nil "'~A' is not a valid Amplification value~%" val)))) 0) ; returns 0 as linear value ; End of nested function (setq var (if (= amp-u 0) ; dB (case (type-of var) (symbol (convert-symbol var)) ; if symbol, sets to 0 ((or fixnum flonum) (print var)(db-to-linear var)) ; if number, convert to linear (T (setq err-msg (strcat err-msg (format nil "'~a' is not a valid Amplification value~%" val))) 0)) ; Returns dB value or 0 and error message ; If not dB, then convert % (case (type-of var) ((or fixnum flonum) (if (< var 0)(setq err-msg (strcat err-msg (format nil "'~A' is not valid.~%Amplification must be greater than 0% (silence).~%" var)))) ; check for negative % value (/ var 100.0)) ; if number, convert to linear (T (setq err-msg (strcat err-msg (format nil "~A is not a valid 'Amplification %' value~%" var))) 0)))) (abs var)) ; return var ; End of make-linear function ; Convert times to linear (mapcar 'check-time-numbers times) ; test that all numbers (if (= (length err-msg) 0) (setf times (case t-u (0 (mapcar 'ms-to-lin times)) ; milliseconds (1 (mapcar 's-to-lin times)) ; seconds (2 (mapcar 'm-to-lin times)) ; minutes (3 (mapcar 'pc-to-lin times))))) ; percent ; Convert amplification to linear (setf amps (mapcar 'make-linear amps)) (format T "times after conversion: ~a~%" times) (format T "amps after conversion: ~a~%" amps) ;; sort lists (setq n (1- (length times))) ; initialise counter for length of list (setq loopnum 0) ; initialise loop counter (setq inputmsg (format nil "List of times before sort: ~a~%List of amplifications before sort: ~a~%" times amps)) ;; perform a selection sort (dotimes (i n) (do ((i loopnum (setq i (1+ i)))) ; initialise couner i to the loop number and incriment on each pass ((>= i n) amps times) ; repeat do loop till i=n (if (< (nth(1+ i)times)(nth loopnum times)) ; if nth+1 value is less than the nth-loopnum (progn (setq temp (nth loopnum times)) ; set temp to nth (setf (nth loopnum times)(nth(1+ i)times)) ; set nth to value of nth+1 (setf (nth(1+ i)times) temp) ; set nth+1 to temp ;same for amps (setq temp (nth loopnum amps)) (setf (nth loopnum amps)(nth(1+ i)amps)) (setf (nth(1+ i)amps) temp) ))) ; end of inner loop (setq loopnum (1+ loopnum))) ; end of sort routine (setq outputmsg (format nil "List of sorted times: ~a~%List of sorted amplifications: ~a~%" times amps)) (format T "~a~%~a~%" inputmsg outputmsg) ; Combine back into one list (setf newlist ()) ; initialise newlist (setf newlist (do ((i (1- (length times)))) ((< i 0) newlist) (setf newlist (cons (nth i amps) newlist)) ; add amp (setf newlist (cons (nth i times) newlist)) ; add time (setq i (1- i))))) ;; End of function ;;;;;;;;;;; END OF MAIN FUNCTION ;;;;;;;;;;;;; ;; ------------- END OF FUNCTIONS ------------- ;; Initialise input values (setf initial (car (string-to-list Linit))) ; initial amplification (setf final (car (string-to-list Lfin))) ; final amplification (setf text (substitute #\space #\, text)) ; substitute spaces for commas (setf cp-list (string-to-list text)) ; intermediate values ;;check for pairs (if (oddp (length cp-list))(setq err-msg (strcat err-msg (format nil "Intermediate Control Points:~%~a~%Text must be pairs of values (time amplify) separated by spaces.~%" cp-list))) (progn ; get end time (setf end-time (case t-units (0 (* (get-duration 1) 1000.0)) ; milliseconds (1 (get-duration 1)) ; seconds (2 (/ (get-duration 1) 60.0)) ; minutes (3 100))) ; percent ; Create list (setf cp-list (append cp-list(list end-time final))) ;adds list from text input to final point (setf cp-list (append (list 0 initial) cp-list)) ; adds initial point to list (print (convert cp-list t-units amp-units)) ; Convert value range to linear (if (= (length err-msg) 0) ;; Convert string list values (setf cp-list (convert cp-list t-units amp-units))) )) ; end of check for pairs ; test (format T "Error Messages: ~a~%Output list: ~a~%~%" err-msg cp-list) (if (> (length err-msg) 0) (format nil "The following errors occured: ~%~a~%" err-msg) (control-srate-abs *sound-srate* (mult s (pwl-list cp-list)))) )) ; End of 'help' case |