dulcimer.lsp Version 1.00 01 February 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 Defines dulcimer instrument with "Aeolian harp reverb". By default the instrument uses a 12 note just scale in C. The sound is composed of three components; FM pluck sound, Karplus-Strong pluck sound and Aeolian reverb.
function
(dulcimer:pluck pindex dur [:vel][:rc][:rm][:i][:mix]) The primary sound is composed of two "pluck" components; FM and Karplus-Strong. pindex - integer. MIDI key number. dur - flonum. Pluck decay time :vel - integer. MIDI velocity controls modulation index and relative mix of FM and Karplus-Strong components. At velocities above 63 the two components have approximately equal amplitude. With lower velocities the Karplus-Strong component drops out and the FM component becomes less bright. Default 64 :rc - flonum. Relative FM carrier frequency, default 1.000 :rm - flonum. Relative FM modulation frequency, default 1.001 :i - flonum. FM modulation index. The actual index is modified by velocity, default 4.00. :mix - flonum. Relative mix between FM and Karplus-Strong components. 0 <= mix <= 1. If specified mix overrides the velocity derived mix, default nil. return - sound.
function
(dulcimer:aeolian pindex dur [:vel][:rc][:rm][:i][:attack][:decay]) The Aeolian reverb component of Dulcimer. See aeolus.lsp pindex - integer. dur - flonum. :vel - integer. :rc - flonum. :rm - flonum. :i - flonum. :attack - flonum. :decay - flonum. return - sound.
function
(dulcimer:voice pindex dur [keywords...]) pindex - integer. dur - flonum. :vel - integer. :mix - flonum. Relative mix of FM and Karplus-Strong components. :rc - flonum. :rm - flonum. :i - flonum. :attack - flonum. :decay - flonum. :aeo - integer. MIDI Amplitude of Aeolian reverb 0<= aeo < 128 return - sound
wrapper
(dulcimer plist dur [keywords...]) A dulcimer instrument with just intonation and Aeolian Harp reverb. The intonation is a 12 note just scale in C. The sound is composed of three components; FM pluck, Karplus-Strong pluck and Aeolian reverb plist - list or integer. MIDI key-number(s) to be played. Be aware the dulcimer is demanding computation wise, long list of notes require long rendering times. dur - flonum. Duration in seconds. The harp continues for decay seconds after dur. :vel - integer. MIDI velocity controls amplitude, brightness and relative mix of FM and Karplus-Strong components, default 64. :pos - flonum or sound. Pan position, default 0.5 :arpeg - flonum. Arpeggio time, default 0 :rc - flonum. Relative FM carrier frequency. The rc argument applies to both the FM pluck and Aeolian components. Default 1.000 :rm - flonum. Relative FM modulator frequency. The rm argument applies to both the FM pluck and Aeolian components. Default 1.001 :i - flonum. FM modulation index applies to both FM pluck and Aeolian components. Default ? :mix - flonum. Relative mix of FM and Karplus-Strong components. 0 <= mix <= 1. If specified mix overrides velocity derived mix. :attack - flonum. Base line attack time of Aeolian reverb, default 0.050 :decay - flonum. Base line decay time of Aeolian reverb, default 1.50 :aeo - integer. MIDI controller of Aeolian reverb. Default 64 :fc - flonum. Filter resonance in Hertz, default 750. :q - flonum. Filter q, 0<= q <= 1, default 0.75. return - sound vector.
wrapper
(pdulcimer plist dur [keywords...]) Version of duclimer without Aeolian reverb.
;; dulcimer.lsp ;; Version 1.00 01 February 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 ;; ;; Defines dulcimer instrument with "Aeolian harp reverb". By default the ;; instrument uses a 12 note just scale in C. The sound is composed of three ;; components; FM pluck sound, Karplus-Strong pluck sound and Aeolian reverb. (require 'aeolus) (require 'map) (require 'map-vel6) (require 'definst) (provide 'dulcimer) (current-file "dulcimer") ;; Maps pluck FM index as function of velocity ;; (setf dulcimer:*vel-fmindex-map* (map:linear 0.75 4.00)) ;; Maps pluck component mix (FM vs Karplus-Strong) as function of velocity ;; For velocities above 63 the relative mix is constant ;; For velocities less then 63 Karplus-Strong component is reduced ;; (setf dulcimer:*vel-mix-map* (send map:discrete :new 128 :fillfn #'(lambda (n) 0.5))) (do ((i 0 (+ i 1))(val 0 (+ val (/ 1.0 128)))) ((>= i 64)) (send dulcimer:*vel-mix-map* :set i val)) ;; Instrument amplitude in db as function of velocity ;; (setf dulcimer:*vel-db-map* map:*vel6*) ;; Amplitude of aeolian component in db as function of MIDI controller. ;; (setf dulcimer:*aeolian-db-map* (map:quad -48 +6)) ;; Defines the primary scale ;; (setf dulcimer:*scale* (vector 1.000 ;unison 1.067 ;min 2nd 1.125 ;2nd 1.200 ;min 3rd 1.250 ;maj 3rd 1.333 ;4th 1.400 ;aug 4th/dim 5th 1.500 ;5th 1.600 ;aug 5th 1.667 ;6th 1.800 ;min 7th 1.875 ;7th )) ;; Defines the Aeolian scale. ;; (setf dulcimer:*aeolian-scale* (vector 1.000 ;unison 1.067 ;min 2nd 1.125 ;2nd 1.200 ;min 3rd 1.250 ;maj 3rd 1.333 ;4th 1.400 ;aug 4th/dim 5th 1.500 ;5th 1.600 ;aug 5th 1.667 ;6th 1.800 ;min 7th 1.875 ;7th )) ;; Aeolian harmonics list ;; (setf dulcimer:*aeolian-plist* '((0.500 0.800) (0.750 0.600) (1.000 1.000) (1.200 0.300) (1.250 0.400) (1.333 0.700) (1.500 0.800) (1.667 0.400) (1.875 0.100) (2.000 0.500) (3.000 0.500))) ;; Build the primary pitch map ;; (setf dulcimer:*pitch-map* (send map:discrete :new 128)) (setf dulcimer:*ref-frq* (/ (step-to-hz C0) 2.0)) (let ((rindex 0) (frq dulcimer:*ref-frq*)) (do ((pindex 0 (+ pindex 1))) ((> pindex 127)) (send dulcimer:*pitch-map* :set pindex (hz-to-step (* frq (aref dulcimer:*scale* rindex)))) (if (< rindex (- (length dulcimer:*scale*) 1)) (setq rindex (+ 1 rindex)) (setq rindex 0 frq (* 2 frq))))) ;; Build the Aeolian harp ;; (setf dulcimer:*aeolian-ref-pitch* C4) (setf dulcimer:*aeolian-octaves* 2) (setf dulcimer:*aeolian* (send aeolus:class :new)) (let (frq) (dotimes (oindex dulcimer:*aeolian-octaves*) (setf frq (* (step-to-hz dulcimer:*aeolian-ref-pitch*)(expt 2.0 oindex))) (dotimes (rindex (length dulcimer:*aeolian-scale*)) (send dulcimer:*aeolian* :string (* frq (aref dulcimer:*aeolian-scale* rindex)) :plist dulcimer:*aeolian-plist*)))) (send dulcimer:*aeolian* :key ':i 3.000 (map:linear 0.10 1.00 0 1)) (send dulcimer:*aeolian* :key ':attack 0.050 (map:linear 25.0 1.00 0 1)) (send dulcimer:*aeolian* :key ':decay 1.500 (map:linear 0.25 1.00 0 1)) (send dulcimer:*aeolian* :key ':rc 1.000 (map:constant 1)) (send dulcimer:*aeolian* :key ':rm 1.010 (map:constant 1)) ;; @doc function dulcimer:pluck ;; (dulcimer:pluck pindex dur [:vel][:rc][:rm][:i][:mix]) ;; The primary sound is composed of two "pluck" components; FM and ;; Karplus-Strong. ;; ;; pindex - integer. MIDI key number. ;; ;; dur - flonum. Pluck decay time ;; ;; :vel - integer. MIDI velocity controls modulation index and relative mix ;; of FM and Karplus-Strong components. At velocities above 63 the ;; two components have approximately equal amplitude. With lower ;; velocities the Karplus-Strong component drops out and the FM ;; component becomes less bright. Default 64 ;; ;; :rc - flonum. Relative FM carrier frequency, default 1.000 ;; ;; :rm - flonum. Relative FM modulation frequency, default 1.001 ;; ;; :i - flonum. FM modulation index. The actual index is modified by ;; velocity, default 4.00. ;; ;; :mix - flonum. Relative mix between FM and Karplus-Strong components. ;; 0 <= mix <= 1. If specified mix overrides the velocity derived ;; mix, default nil. ;; ;; return - sound. ;; (defun dulcimer:pluck (pindex dur &key vel rc rm i mix) (let* ((hz (step-to-hz (send dulcimer:*pitch-map* :get (truncate pindex)))) (vel (or vel 74)) (chz (* hz (or rc 1.000))) (mhz (* hz (or rm 1.010))) (mamp (* chz (send dulcimer:*vel-fmindex-map* :get vel)(or i 4.00))) (mix (min (max (or mix (send dulcimer:*vel-mix-map* :get vel)) 0.00) 1.00)) (envsig (percussion dur)) ) (sum (scale mix (pluck (hz-to-step hz) dur)) (scale (- 1 mix) (mult (fmosc (hz-to-step chz) (mult (osc (hz-to-step mhz) dur) (scale mamp envsig))) envsig))))) ;; @doc function dulcimer:aeolian ;; (dulcimer:aeolian pindex dur [:vel][:rc][:rm][:i][:attack][:decay]) ;; The Aeolian reverb component of Dulcimer. See aeolus.lsp ;; ;; pindex - integer. ;; dur - flonum. ;; :vel - integer. ;; :rc - flonum. ;; :rm - flonum. ;; :i - flonum. ;; :attack - flonum. ;; :decay - flonum. ;; return - sound. ;; (defun dulcimer:aeolian (pindex dur &rest args) (send dulcimer:*aeolian* :render (step-to-hz (send dulcimer:*pitch-map* :get pindex)) dur (append (->list args)(list ':rc 2)))) ;; @doc function dulcimer:voice ;; (dulcimer:voice pindex dur [keywords...]) ;; ;; pindex - integer. ;; dur - flonum. ;; :vel - integer. ;; :mix - flonum. Relative mix of FM and Karplus-Strong components. ;; :rc - flonum. ;; :rm - flonum. ;; :i - flonum. ;; :attack - flonum. ;; :decay - flonum. ;; :aeo - integer. MIDI Amplitude of Aeolian reverb 0<= aeo < 128 ;; return - sound ;; (defun dulcimer:voice (pindex dur &rest args) (let ((amix (send dulcimer:*aeolian-db-map* :get (get-keyword-value ':aeo args 64))) (arglist (append (list pindex dur) args))) (sum (apply #'dulcimer:pluck arglist) (scale-db amix (apply #'dulcimer:aeolian arglist)) ))) ;; Provides global filter for dulcimer. ;; (defun dulcimer:eq (sig frq q) (multichan-expand #'bandpass2 sig frq q)) ;; @doc wrapper dulcimer ;; (dulcimer plist dur [keywords...]) ;; A dulcimer instrument with just intonation and Aeolian Harp reverb. The ;; intonation is a 12 note just scale in C. The sound is composed of three ;; components; FM pluck, Karplus-Strong pluck and Aeolian reverb ;; ;; plist - list or integer. MIDI key-number(s) to be played. Be aware the ;; dulcimer is demanding computation wise, long list of notes ;; require long rendering times. ;; ;; dur - flonum. Duration in seconds. The harp continues for decay ;; seconds after dur. ;; ;; :vel - integer. MIDI velocity controls amplitude, brightness and relative ;; mix of FM and Karplus-Strong components, default 64. ;; ;; :pos - flonum or sound. Pan position, default 0.5 ;; ;; :arpeg - flonum. Arpeggio time, default 0 ;; ;; :rc - flonum. Relative FM carrier frequency. The rc argument applies to ;; both the FM pluck and Aeolian components. Default 1.000 ;; ;; :rm - flonum. Relative FM modulator frequency. The rm argument applies ;; to both the FM pluck and Aeolian components. Default 1.001 ;; ;; :i - flonum. FM modulation index applies to both FM pluck and Aeolian ;; components. Default ? ;; ;; :mix - flonum. Relative mix of FM and Karplus-Strong components. ;; 0 <= mix <= 1. If specified mix overrides velocity derived mix. ;; ;; :attack - flonum. Base line attack time of Aeolian reverb, default 0.050 ;; ;; :decay - flonum. Base line decay time of Aeolian reverb, default 1.50 ;; ;; :aeo - integer. MIDI controller of Aeolian reverb. Default 64 ;; ;; :fc - flonum. Filter resonance in Hertz, default 750. ;; ;; :q - flonum. Filter q, 0<= q <= 1, default 0.75. ;; ;; return - sound vector. ;; (defwrapper dulcimer #'dulcimer:voice #'(lambda (sig args) (scale-db (send dulcimer:*vel-db-map* :get (get-keyword-value ':vel args 64)) (dulcimer:eq sig (get-keyword-value ':fc args 750) (get-keyword-value ':q args 0.75) )))) ;; @doc wrapper pdulcimer ;; (pdulcimer plist dur [keywords...]) ;; Version of duclimer without Aeolian reverb. ;; (defwrapper pdulcimer #'dulcimer:pluck #'(lambda (sig args) (scale-db (send dulcimer:*vel-db-map* :get (get-keyword-value ':vel args 64)) sig)))