Main Page       Index


env4.lsp


 env4.lsp
 Version 1.00   05 April 2005
 Author Steven Jones

 Contact jones57@swbell.net include the word "nyquist" in subject line

 The contents of this file are released under the terms of the GNU General
 Public License. See the file LICENSE.txt

 Implements DX7 style envelope; 4 levels, 4 rates.


class

env4:class

 A 4-level, 4-rates envelope


method

env4:class :new

 (send env4:class :new gate lev1 lev2 lev3 lev4 time1 time2 time3 time4)
 Construct new env4:class object.
 See function env4 for arguments.


function

env4

 (env4   gate lev1 lev2 lev3 lev4 time1 time2 time3 time4)
 A DX7 style envelope.

 The envelope has 4-levels and 4-rates. Initially the output is at lev4 and
 immediately moves to lev1 over time1 seconds. After time1 the output moves
 to lev2 in time2 seconds. Similarly the output moves from lev2 to lev3 over
 the next time3 seconds. The output is static at lev3 for as long as the key
 is held down (key depression time is represented by the gate argument)
 After the key is released the output moves from lev3 to lev4 over time4
 seconds. If the key is released prior to the sustain stage the output
 immediately starts to move towards lev4.

 gate   - Flonum. The "key down" time in seconds.
 lev1   - Flonum. Output level after time1 seconds.
 lev2   - Flonum. Output level after time1+time2 seconds
 lev3   - Flonum. Output level after time1+time2+time3 seconds
 lev4   - Flonum. Initial and final output level
 time1  - Flonum. Interval in seconds between lev0 and lev1. 
          Note lev0 is the same as lev4
 time2  - Flonum. Interval in seconds between lev1 and lev2. 
 time3  - Flonum. Interval in seconds between lev2 and lev3. 
 time4  - Flonum. Decay time in seconds. There is always a decay stage. 
          The other stages may be terminated by the gate time.
 return - Sound. The total duration of the resault is gate+time4.


View the Sourcecode :



;; env4.lsp
;; Version 1.00   05 April 2005
;; Author Steven Jones
;;
;; Contact jones57@swbell.net include the word "nyquist" in subject line
;;
;; The contents of this file are released under the terms of the GNU General
;; Public License. See the file LICENSE.txt
;;
;; Implements DX7 style envelope; 4 levels, 4 rates.
;;

(provide 'env4)
(current-file "env4")


;; @doc class env4:class
;; A 4-level, 4-rates envelope
;;

(setf env4:class (send class :new 
			 '(.out		;Current output level.
			   .delta-1	;Increment stage 1-4.
			   .delta-2	
			   .delta-3
			   .delta-4
			   .lev-4	;Amplitude of level 4.
			   .events-1	;Number of samples/stage 1-4.
			   .events-2
			   .events-3
			   .events-4
			   .events-g	;Number of samples while key-down.
			   .temp	;Temporary variable.
			   )))


;; @doc method env4:class :new
;; (send env4:class :new gate lev1 lev2 lev3 lev4 time1 time2 time3 time4)
;; Construct new env4:class object.
;; See function env4 for arguments.
;;

(send env4:class :answer :isnew '(gate lev1 lev2 lev3 lev4 time1 time2 time3 time4)
      '(
	(setf .out lev4)
	
	(setf .events-1 (truncate (* time1 *control-srate*)))
	
	(setf .events-2 (truncate (* time2 *control-srate*)))
	
	(setf .events-3 (truncate (* time3 *control-srate*)))
	
	(setf .events-4 (truncate (* time4 *control-srate*)))

	(setf .events-g (truncate (* gate *control-srate*)))

	(setf .delta-1 (if (zerop .events-1) 0 
			 (/ (float (- lev1 lev4)) .events-1)))

	(setf .delta-2 (if (zerop .events-2) 0
			 (/ (float (- lev2 lev1)) .events-2)))

	(setf .delta-3 (if (zerop .events-3) 0
			 (/ (float (- lev3 lev2)) .events-3)))

	;; We don't know initial amplitude of stage 4 yet,
	;; defer calculation of delta-4.
	(setf .delta-4 nil)
	(setf .lev-4 lev4)
	))


;; @method env4:class :next
;; (send /env4:class/ :next)
;; Sequentially return envelope values. After returning final envelope sample
;; the next call to :next returns nil.
;;

(send env4:class :answer :next '()
      '(
	;(display "" .out .events-g .events-1 .events-2 .events-3)
	(if (plusp .events-g)
	    ;; Stages 1 - 3
	    (cond ((plusp .events-1)
		   ;(display "attack" .out .events-g .events-1 .events-2 .events-3)
		   (setf .temp .out)
		   (setf .out (+ .out .delta-1))
		   (setf .events-1 (1- .events-1))
		   (setf .events-g (1- .events-g))
		   .out)

		  ((plusp .events-2)
		   (setf .temp .out)
		   (setf .out (+ .out .delta-2))
		   (setf .events-2 (1- .events-2))
		   (setf .events-g (1- .events-g))
		   .out)

		  ((plusp .events-3)
		   (setf .temp .out)
		   (setf .out (+ .out .delta-3))
		   (setf .events-3 (1- .events-3))
		   (setf .events-g (1- .events-g))
		   .out)
		  ;; sustain stage
		  (t 
		   (setf .events-g (1- .events-g))
		   .out))
	  ;; Decay stage 4
	  (progn 
	    (if (null .delta-4)
		(setf .delta-4 (if (zerop .events-4) 0
				 (/ (float (- .lev-4 .out)) .events-4))))
	    (if (plusp .events-4)
		(progn 
		  ;(display "decay" .out .delta-4 .events-4 .events-g)
		  (setf .temp .out)
		  (setf .out (+ .out .delta-4))
		  (setf .events-4 (1- .events-4))
		  .out)
	      nil))
	  )))


;; @doc function env4
;; (env4   gate lev1 lev2 lev3 lev4 time1 time2 time3 time4)
;; A DX7 style envelope.
;;
;; The envelope has 4-levels and 4-rates. Initially the output is at lev4 and
;; immediately moves to lev1 over time1 seconds. After time1 the output moves
;; to lev2 in time2 seconds. Similarly the output moves from lev2 to lev3 over
;; the next time3 seconds. The output is static at lev3 for as long as the key
;; is held down (key depression time is represented by the gate argument)
;; After the key is released the output moves from lev3 to lev4 over time4
;; seconds. If the key is released prior to the sustain stage the output
;; immediately starts to move towards lev4.
;;
;; gate   - Flonum. The "key down" time in seconds.
;; lev1   - Flonum. Output level after time1 seconds.
;; lev2   - Flonum. Output level after time1+time2 seconds
;; lev3   - Flonum. Output level after time1+time2+time3 seconds
;; lev4   - Flonum. Initial and final output level
;; time1  - Flonum. Interval in seconds between lev0 and lev1. 
;;          Note lev0 is the same as lev4
;; time2  - Flonum. Interval in seconds between lev1 and lev2. 
;; time3  - Flonum. Interval in seconds between lev2 and lev3. 
;; time4  - Flonum. Decay time in seconds. There is always a decay stage. 
;;          The other stages may be terminated by the gate time.
;; return - Sound. The total duration of the resault is gate+time4.
;;

(defun env4 (gate lev1 lev2 lev3 lev4 time1 time2 time3 time4)
  ;(display "env4" gate lev1 lev2 lev3 lev4 time1 time2 time3 time4)
  (let (obj)
    (setf gate (max gate (min-control-time)))
    (setf obj (send env4:class :new gate 
		    lev1 lev2 lev3 lev4 
		    (max (min-control-time) time1) time2 time3 time4))
    (snd-fromobject (local-to-global 0) *control-srate* obj)))


Main Page       Index