Rego Sen - Final Project for Music 220b - March 15, 2004

 

"Blasphemous Bosphorous" is based on rhythmic and tonal modes of traditional Middle Eastern origin. The tonal elements of the piece use the Rast scale, which can be derived from the major scale with the 3rd and 7th notes flattened by a quarter step. To sound the tonal elements, I used the pluck instrument to imitate a saz by doubling the melody at an octave. (Strings on a saz are grouped so that plucking one cluster sounds a note at two octaves.) I then used darbuka samples to play rhythms from the eight traditional modes outlined by Safi-ad-Din in the 13th century:

Section A (0:00) Each rhythmic motive is played through for one cycle by one of the eight instruments (the seven Darbuka samples and the pluck instrument).

Section B (0:17) The saz plays variations on a melodic motive as additional sazes harmonize along. In addition, the drums take turns interlacing the rhythmic motives.

Section C (1:02) Now the saz takes a solo in this Sierpinski-based interlude. More and more drums join in as the tension rises.

Section D (2:39) The saz theme reverts back to its rhythmic motive but up a third and with the harmonics in the foreground.

Section E (3:09) Soon a new saz layer arrives, harshly low and accelerating in tempo.

Section F/Outro (3:37) This short, flaky ending is provided by an until-recently-obscured light layer in the upper register.

 

Here is the code that generated the music:
NOTE: pluckLR.ins incorporates the following changes to pluck.ins: pluckL is the same as the instrument from pluck.ins, while pluckR replaces 'outa' with 'outb', and the new pluck utilizes both.

;;; :cl pluckLR.ins
;;; :cl scales.lisp

(new tuning :name 'rast
     :ratios '((1 C)
	       (7/6 D)
	       (21/16  Eq)
	       (17/12 F)
	       (19/12 G)
	       (7/4 A)
	       (91/48 Bq)
	       2/1))

(defun d01 (time)
  (mix "/user/r/regosen/220b/sounds/b1.wav" :amplitude 0.4
       :output-frame (floor (* time *srate*))))
(defun d02 (time)
  (mix "/user/r/regosen/220b/sounds/b2.wav" :amplitude 0.55
       :output-frame (floor (* time *srate*))))
(defun d03 (time)
  (mix "/user/r/regosen/220b/sounds/b3.wav" :amplitude 0.55
       :output-frame (floor (* time *srate*))))
(defun d04 (time)
  (mix "/user/r/regosen/220b/sounds/b4.wav" :amplitude 0.55
       :output-frame (floor (* time *srate*))))

(defun d1 (time)
  (mix "/user/r/regosen/220b/samples/darbuka/darbuka1-s.wav" :amplitude 0.4
       :output-frame (floor (* time *srate*))))
(defun d2 (time)
  (mix "/user/r/regosen/220b/samples/darbuka/darbuka2-s.wav" :amplitude 0.55
       :output-frame (floor (* time *srate*))))
(defun d3 (time)
  (mix "/user/r/regosen/220b/samples/darbuka/darbuka3-s.wav" :amplitude 0.55
       :output-frame (floor (* time *srate*))))
(defun d4 (time)
  (mix "/user/r/regosen/220b/samples/darbuka/darbuka4-s.wav" :amplitude 0.55
       :output-frame (floor (* time *srate*))))
(defun d5 (time)
  (mix "/user/r/regosen/220b/samples/darbuka/darbuka5-s.wav" :amplitude 0.4
       :output-frame (floor (* time *srate*))))
(defun d6 (time)
  (mix "/user/r/regosen/220b/samples/darbuka/darbuka6-s.wav" :amplitude 0.55
       :output-frame (floor (* time *srate*))))
(defun d7 (time)
  (mix "/user/r/regosen/220b/samples/darbuka/darbuka7-s.wav" :amplitude 0.55
       :output-frame (floor (* time *srate*))))

;;; Replacing the following definition of 'human' will make each note vary by 5 ms.
;;; to sound more natural.  Unfortunately, in the faster sections (incl. sierpinski)
;;; the notes start to sound a bit sloppy.  An optimal solution would be to make the
;;; variation itself a function of the tempo.

;;; (defun human (time) (+ time (/ (- (random 10) 5) 1000)))
(defun human (time) time)


(define (sierpinski knum ints dur amp depth)
  (let ((len (length ints)))
    (process for i in ints
             for k = (transpose knum i)
	     ;; MODIFIED SIERPINSKI HERE TO USE RAST SCALE
             output (new pluck :start (now) :dur dur :freq (hertz k :in #!rast) :amp amp :weighting 0.9 :lossfact 0.99 :decaytime 3 :attacktime 0.01)
             when (> depth 1)
	     ;; sprout a process on output note
	     sprout
             (sierpinski (transpose k 12) ints
                         (/ dur len) amp (- depth 1))
             wait dur)))

(events (list (sierpinski 30 '(1 0 0 -1 1) 10 0.2 1)
              (sierpinski 37 '(1 0 0 -1 1) 10 0.2 1)) "phase1.snd" :channels 2)
(events (list (sierpinski 30 '(1 0 0 -1 1) 10 0.2 2)
(sierpinski 35 '(1 0 0 -1 1) 10 0.2 2)) "phase2.snd" :channels 2)

(events (list (sierpinski 30 '(1 0 0 -1 1) 10 0.2 3)
(sierpinski 25 '(1 0 0 -1 1) 10 0.2 3)) "phase3.snd" :channels 2)
(events (list (sierpinski 23 '(1 0 0 -1 1) 10 0.2 4)
(sierpinski 30 '(1 0 0 -1 1) 10 0.2 4)) "phase4.snd" :channels 2)
(events (sierpinski 10 '(1 0 0 -1 1) 10 0.1 4) "phase4a.snd" :channels 2)

(defun phase2 (time) (mix "/zap/phase2.snd" :amplitude 1 :output-frame (floor (* time *srate*))))
(defun phase3 (time) (mix "/zap/phase3.snd" :amplitude 1 :output-frame (floor (* time *srate*))))
(defun phase4 (time) (mix "/zap/phase4.snd" :amplitude 1 :output-frame (floor (* time *srate*))))
(defun phase4a (time) (mix "/zap/phase4a.snd" :amplitude 1 :output-frame (floor (* time *srate*))))



(with-sound (:srate 44100 :channels 2 :header-type mus-riff :output "/usr/ccrma/snd/220a-2003/regosen/220b/east1.wav")


;;; the following 8 rhythmic modes date back to the 13th century Middle East and are still used today.


(setf m1 (new cycle :of '(e. e. q e q)))
(setf m2 (new cycle :of '(e. e. e e. e. e)))
(setf m3 (new cycle :of '(e e e e e e e e)))
(setf m4 (new cycle :of '(q q e e e e e e q q)))
(setf m5 (new cycle :of '(e e e e e e)))
(setf m6 (new cycle :of '(e e. e e.)))
(setf m7 (new cycle :of '(q e. e. e)))
(setf m8 (new cycle :of '(q e q q e q)))

(setf rmotive1 (new cycle :of '(e s s e e)))
(setf nmotive1 (new cycle :of '(1 0 0 -1 1)))
(setf nmotive2 (new cycle :of '(-1 0 0 1 -1)))
(setf nmotive3 (new cycle :of '(-1 0 0 -1 1)))
(setf nmotive4 (new cycle :of '(1 0 0 1 -1)))
(setf nup (new cycle :of '(2 0 0 -5)))
(setf ndown (new cycle :of '(5 0 0 -2)))

(setf dur 1)
(setf nstep 1)
(setf amp 0.1)
(setf ampo 0.1)
(setf time 0)


(with-mix '(:channels 2) "intro" 0
  (loop repeat 6 do
    (setf time (+ time (rhythm (next m8) 120)))
    (d1 (human time)))

  (loop repeat 6 do
    (setf time (+ time (rhythm (next m2) 120)))
    (d2 (human time)))

  (loop repeat 8 do
    (setf time (+ time (rhythm (next m3) 120)))
    (d3 (human time)))

  (loop repeat 10 do
    (setf time (+ time (rhythm (next m4) 120)))
    (d4 (human time)))

  (loop repeat 6 do
    (setf time (+ time (rhythm (next m5) 120)))
    (d5 (human time)))

  (loop repeat 4 do
    (setf time (+ time (rhythm (next m6) 120)))
    (d6 (human time)))

  (loop repeat 4 do
    (setf time (+ time (rhythm (next m7) 120)))
   (d7 (human time)))
  (setf note 30)
  (loop repeat 5 do
    (setf time (+ time (rhythm (next m1) 120)))
    (setf note (+ note (next nmotive1)))
    (pluck (human time) dur (hertz note :in #!rast) amp 0.9 0.99 6 0.01)
    (pluck (human time) dur (hertz (+ note 7) :in #!rast) amp 0.9 0.99 6 0.01)
 )
)

(setf time 0)
(with-mix '(:channels 2) "saz1" 17.7
(setf overt (new heap :of `(,(new cycle :of '(8 8 8 8 8 8 8)) ,(new cycle :of '(5 5 5 5 5 5)) ,(new cycle :of '(8 8 8 8 8 8 8)) ,(new cycle :of '(4 4)))))
      (setf nmotives (new random :of `(,nmotive1 ,nmotive2 ,nmotive3 ,nmotive4)))
(loop for note = 30 then (+ note (next nmotives)) repeat 140 do

      (setf rnext (rhythm (next rmotive1) 90))
      (pluck (human time) dur (hertz note :in #!rast) amp 0.9 0.99 6 0.01)
      (pluck (human time) dur (hertz (+ note 7) :in #!rast) amp 0.9 0.99 6 0.01)
      (pluckL (human time) dur (hertz (+ note (next overt)) :in #!rast) ampo 0.5 0.99 1 0.05)
      (pluckR (human time) dur (hertz (+ note (next overt)):in #!rast) ampo 0.9 0.99 6 0.05)
      (setf time (+ time rnext))
))
(with-mix '(:channels 2) "drums1" 16.7
(setf overm (new rotation :of `(,m1 ,m2 ,m3 ,m4 ,m5 ,m6 ,m7 ,m8)))

  (loop repeat 30
    for time = 0 then (+ time (rhythm (next overm) 30)) do
    (d1 (human time)))

  (loop repeat 30
    for time = 0 then (+ time (rhythm (next overm) 30)) do
    (d2 (human time)))

  (loop repeat 60
    for time = 0 then (+ time (rhythm (next overm) 60)) do
    (d3 (human time)))

  (loop repeat 45
    for time = 0 then (+ time (rhythm (next overm) 45)) do
    (d4 (human time)))

  (loop repeat 45
    for time = 0 then (+ time (rhythm (next overm) 45)) do
    (d5 (human time)))

  (loop repeat 90
    for time = 0 then (+ time (rhythm (next overm) 90)) do
    (d6 (human time)))

  (loop repeat 90
    for time = 0 then (+ time (rhythm (next overm) 90)) do
    (d7 (human time)))
)

(with-mix '(:channels 2) "sierpinskis" 40
    (phase2 0)
    (phase3 22)
    (phase4 44)
    (phase4 69)
    (phase4a 94)
)

(with-mix '(:channels 2) "drums2" 95
  (loop repeat 60
    for time = 16 then (+ time (rhythm (next overm) 90)) do
    (d7 (human time)))

  (loop repeat 64
    for time = 0 then (+ time (rhythm (next overm) 45)) do
    (d5 (human time)))

  (loop repeat 64
    for time = 0 then (+ time (rhythm (next overm) 45)) do
    (d4 (human time)))

  (loop repeat 80
    for time = 30 then (+ time (rhythm (next overm) 120)) do
    (d1 (human time)))

  (loop repeat 44
    for time = 40 then (+ time (rhythm (next overm) 120)) do
    (d2 (human time)))

  (loop repeat 120
    for time = 50 then (+ time (rhythm (next overm) 120)) do
    (d1 (human time))
    (d2 (human time))
    (d3 (human time)))

  (loop repeat 60
    for time = 60 then (+ time (rhythm (next overm) 60)) do
    (d4 (human time))
    (d5 (human time))
    (d6 (human time)))

  (loop repeat 200
    for time = 60 then (+ time (rhythm (next overm) 240)) do
    (d7 (human time)))
 )

(with-mix '(:channels 2) "saz2" 159
(setf time 0)
(loop for note = 25 then (+ note (next nmotives)) repeat 240 do

      (setf rnext (rhythm (next rmotive1) 120))
      (pluckL (human time) dur (hertz note :in #!rast) ampo 0.9 0.99 6 0.01)
      (pluckR (human time) dur (hertz (+ note 7) :in #!rast) ampo 0.9 0.99 6 0.01)
      (pluck (human time) dur (hertz (+ note (next overt)) :in #!rast) amp 0.5 0.99 1 0.05)
      (pluck (human time) dur (hertz (+ note (next overt)):in #!rast) amp 0.9 0.99 6 0.05)
      (setf time (+ time rnext))
)
(setf time 30)
(loop for note = 15 then (+ note (next nmotives)) repeat 200
      for tempo = 90 then (+ tempo 1) do

      (setf rnext (rhythm (next rmotive1) tempo))
      (pluckL (human time) dur (hertz note :in #!rast) ampo 0.9 0.99 6 0.01)
      (pluckR (human time) dur (hertz (+ note 7) :in #!rast) ampo 0.9 0.99 6 0.01)
      (pluck (human time) dur (hertz (+ note (next overt)) :in #!rast) amp 0.5 0.99 1 0.05)
      (pluck (human time) dur (hertz (+ note (next overt)):in #!rast) amp 0.9 0.99 6 0.05)
      (setf time (+ time rnext))
)
(setf time 40)
(loop for note = 45 then (+ note (next nmotives)) repeat 90 do

      (setf rnext (rhythm (next rmotive1) 90))
      (pluckL (human time) dur (hertz note :in #!rast) ampo 0.9 0.99 6 0.01)
      (pluckR (human time) dur (hertz (+ note 7) :in #!rast) ampo 0.9 0.99 6 0.01)
      (pluck (human time) dur (hertz (+ note (next overt)) :in #!rast) amp 0.5 0.99 1 0.05)
      (pluck (human time) dur (hertz (+ note (next overt)):in #!rast) amp 0.9 0.99 6 0.05)
      (setf time (+ time rnext))
)

)
)


The data used to derive the Middle Eastern modes came from a dissertation by Nigel Horne, which can be found here.