Main Page       Index


accordion.lsp


 accordion.lsp 
 Version 1.01   28 December 2004
 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

 An accordion simulation.


wrapper

accordion

 (accordion  plist dur [:vel][:pos][:arpeg][:hp][:mix][:detune][:a][:d][:r])

 An accordion instrument created by summing two detuned
 oscillators. Oscillator 1 is tuned to the fundamental and is approximately
 a 25% pulse. Oscillator 2 produces an approximately 33% pulse and is (by
 default) an octave above osc 1. The envelope of osc 2 is slower then osc
 1. The envelopes for both oscillators contain noise components. There is
 also a global high pass filter (static) and low pass filter (dynamic).


 plist    - list of flonum. The MIDI note(s) to be played.
 dur      - flonum. Duration in seconds
 :vel     - flonum. MIDI velocity controls low pass filter modulation depth, 
            overall amplitude and attack times. Higher velocity values 
            produce quicker attack times and a brighter tone.
 :pos     - flonum or sound. Pan position, default 0.5
 :arpeg   - flonum. Arpeggio time, default 0
 :hp      - flonum. Static high-pass filter cutoff, default 300 Hz
 :mix     - flonum. Relative mix between oscillators. 0 <= mix <= 1 
            Default 0.75
 :detune  - flonum. Relative frequency of osc2, default 2.01
 :a       - flonum. ADSR Attack time
 :d       - flonum. ADSR Decay time
 :r       - flonum. ADSR Release time

 return   - sound vector.


View the Sourcecode :



;; accordion.lsp 
;; Version 1.01   28 December 2004
;; 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
;;
;; An accordion simulation.
;;


(require 'xenvelope)
(require 'map)
(require 'map-vel3)
(require 'definst)

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


(setq accordion:*vel-lp-map* (map:linear 100 5000)
      accordion:*vel-db-map* map:*vel3*
      accordion:*vel-attack-map* (map:quad 0.01 0)
)


(defun accordion:make-wavtab (n skip)
  (wtab:make (wtab:make-plist n 
			      :ampfn #'(lambda (n)(* (/ 1.0 n)(min 1 (rem n skip)))))))


(setq accordion:*tab-1-060* (accordion:make-wavtab 64 4)
      accordion:*tab-1-080* (accordion:make-wavtab 32 4)
      accordion:*tab-1-100* (accordion:make-wavtab 12 4)

      accordion:*tab-2-060* (accordion:make-wavtab 64 3)
      accordion:*tab-2-080* (accordion:make-wavtab 32 3)
      accordion:*tab-2-100* (accordion:make-wavtab 12 3))


(defun accordion:osc (hz dur tab mix)
  (scale mix (osc (hz-to-step hz) dur tab)))


(defun accordion:env (a d s r dur)
  (let* ((sl           0.90)
	 (nse-cf      50.00)
	 (nse-bw      30.00)
	 (nse-floor   00.25)
	 (nse-amp     02.00)
	 (nse-attack  (* 0.50 a))
	 (nse-decay   (* 2.00 d))
	 (nse-release r)
	 (nse-hold    (max 0 (- dur nse-attack nse-decay nse-release))))
    (sum (xadsr a d s r sl dur)
	 (mult 
	  (mult (lfo nse-cf dur)
		(lowpass2 (noise dur) nse-bw))
	  (scale nse-amp 
		 (pwlr nse-attack 1 nse-decay nse-floor nse-hold nse-floor nse-release 1))))))


(defun accordion:rack (hz dur tab amp detune a d r)
  (mult (accordion:osc (* detune hz) dur tab amp)
	(accordion:env a d 0 r dur)))


(defun accordion:voice (pitch dur &key mix detune a d r)
  (let* ((mix (max 0 (min 1 (or mix 0.6))))
	 (detune (or detune 2.01))
	 (a1  (or a 0.05))
	 (d1  (or d 0.05))
	 (r1  (or r 0.25))
	 (a2  (* 1.1 a1))
	 (d2  (* 1.20 d2))
	 (r2  (* 0.90 r1))
	 (hz (step-to-hz pitch))
	 (tab1 nil)
	 (tab2 nil))
    (cond ((> pitch 80)
	   (setq tab1 accordion:*tab-1-100*
		 tab2 accordion:*tab-2-100*))
	  ((> pitch 64)
	   (setq tab1 accordion:*tab-1-080*
		 tab2 accordion:*tab-2-080*))
	  (t
	   (setq tab1 accordion:*tab-1-060*
		 tab2 accordion:*tab-2-060*)))
    (sum (accordion:rack hz dur tab1 mix 1.00 a1 d1 r1)
	 (accordion:rack hz dur tab2 (- mix 1) detune a2 d2 r2))))


;; @doc wrapper accordion
;; (accordion  plist dur [:vel][:pos][:arpeg][:hp][:mix][:detune][:a][:d][:r])
;;
;; An accordion instrument created by summing two detuned
;; oscillators. Oscillator 1 is tuned to the fundamental and is approximately
;; a 25% pulse. Oscillator 2 produces an approximately 33% pulse and is (by
;; default) an octave above osc 1. The envelope of osc 2 is slower then osc
;; 1. The envelopes for both oscillators contain noise components. There is
;; also a global high pass filter (static) and low pass filter (dynamic).
;;
;;
;; plist    - list of flonum. The MIDI note(s) to be played.
;; dur      - flonum. Duration in seconds
;; :vel     - flonum. MIDI velocity controls low pass filter modulation depth, 
;;            overall amplitude and attack times. Higher velocity values 
;;            produce quicker attack times and a brighter tone.
;; :pos     - flonum or sound. Pan position, default 0.5
;; :arpeg   - flonum. Arpeggio time, default 0
;; :hp      - flonum. Static high-pass filter cutoff, default 300 Hz
;; :mix     - flonum. Relative mix between oscillators. 0 <= mix <= 1 
;;            Default 0.75
;; :detune  - flonum. Relative frequency of osc2, default 2.01
;; :a       - flonum. ADSR Attack time
;; :d       - flonum. ADSR Decay time
;; :r       - flonum. ADSR Release time
;;
;; return   - sound vector.
;;

(defwrapper accordion
  #'accordion:voice
  #'(lambda (sig args)
      (let* ((vel (get-keyword-value ':vel args 64))
	     (lpcf  50)
	     (lpmod (send accordion:*vel-lp-map* :get vel))
	     (lpa 0.20)
	     (lpr 0.20)
	     (hpcf (get-keyword-value ':hp args  300.0))
	     )
	(scale-db (send accordion:*vel-db-map* :get vel)
		  (mult
		   (hp
		    (lp sig (sum lpcf (scale lpmod (xasd lpa (max 0 (- dur lpa lpr) lpr)))))
		    hpcf)
		   (xasd (send accordion:*vel-attack-map* :get vel) dur 0))))))


Main Page       Index