LISP code for the mixer
(setf piano-notes-directory "/bark/chris/PNONOTES.new/")
(setf concrete-sounds-directory "/bark/chris/allsoundsfinal/")
(setf section-number '0)
;
;
; note also:
; re-write-flag = (first (last (nth note-number note-list))
; duration = (nth (- (length note-number note-list) 2) (nth note-number note-list))
; filename of
; output sound = (nth (- (length note-number note-list) 3) (nth note-number note-list))
;
;
;
; PARAMETER LOCATIONS in NOTES
; for everyone
(setf instrument-name-par '0)
(setf start-msr-par '1)
(setf start-beat-par '2)
(setf start-div-par '3)
; for pitches
(setf pitch-dur-msr-par '4)
(setf pitch-dur-beat-par '5)
(setf pitch-dur-div-par '6)
(setf pitch-octave-par '7)
(setf pitch-pc-par '8)
(setf pitch-register-lyne-par '9)
(setf pitch-dyn-par '10)
(setf pitch-spatq-par '11)
(setf pitch-stereo-par '12)
(setf pitch-artic-par '13)
(setf pitch-droneq-par '14)
; for wwave only
(setf wwave-waveform-par '15)
(setf wwave-filename-par '16)
(setf wwave-dur-par '17)
(setf wwave-rewrite-par '18)
; for piano only
(setf piano-attq-par '15)
(setf piano-filename-par '16)
(setf piano-dur-par '17)
(setf piano-rewrite-par '18)
; for filter only
(setf filt-noisiness-par '15)
(setf filt-filename-par '16)
(setf filt-dur-par '17)
(setf filt-rewrite-par '18)
; for concrete only
(setf conc-list-par '4)
(setf conc-amp-par '5)
(setf conc-spatq-par '6)
(setf conc-stereo-par '7)
(setf conc-attq-par '8)
(setf conc-makegen-curve-par '9)
(setf conc-loud-hard-amp-par '10)
(setf conc-soundnumber-par '11)
(setf conc-file-par '12)
(setf conc-dur-par '13)
(setf conc-rewrite-par '14)
; for arb only
(setf arb-inst-type-par '4)
(setf arb-pitch-register-lyne-par '5)
(setf arb-pitch-pc-par '6)
(setf arb-pitch-dyn-par '7)
(setf arb-pitch-spatq-par '8)
(setf arb-pitch-droneq-par '9)
(setf arb-pitch-file-par '10)
(setf arb-pitch-dur-par '11)
(setf arb-conc-stereo-par '5)
(setf arb-conc-loud-hard-par '6)
(setf arb-conc-file-par '7)
(setf arb-conc-dur-par '8)
;**************************************************************
;**************************************************************
;**************************************************************
;**************************************************************
;**************************************************************
; BASIC CLASS DEFINITIONS
;**************************************************************
;**************************************************************
;**************************************************************
;**************************************************************
;**************************************************************
;**************************************************************
(defclass articulation ()
((desired-dur :accessor desired-dur :initarg :desired-dur)
(frequency :accessor frequency :initarg :frequency)
(dynamic :accessor dynamic :initarg :dynamic)
(extra-params :accessor extra-params :initarg :extra-params)
(note-number :accessor note-number :initarg :note-number)
(this-source :accessor this-source :initarg :this-source)))
(defclass inst () ())
;****************************************************************
;****************************************************************
;****************************************************************
;****************************************************************
; LOAD STUFF RELEVANT TO EACH INSTRUMENT
;****************************************************************
;****************************************************************
;****************************************************************
;****************************************************************
(load "init.lsp")
(load "sdata.lisp")
(load "wwavestuff.lisp")
(load "filtstuff.lisp")
(load "pianostuff.lisp")
(load "concretestuff.lisp")
;
;
; note-list is a global special variable with the "score" for the whole piece
;
(defun process-notes ()
(let ((elle ()))
(dotimes (ctr (length note-list))
(setf elle (nth ctr note-list))
(if (or (eq (nth instrument-name-par elle) 'bang)
(eq (nth instrument-name-par elle) 'arb)
(if (numberp (first (last elle))) (= (first (last elle)) 0) ()))
()
(make-note ctr)))))
(defun make-note (note-number)
(let ((type 'hi))
(setf type (nth instrument-name-par (nth note-number note-list)))
(case type
('wave (make-wave note-number))
('filt (make-filt note-number))
('piano (make-piano note-number))
('conc (make-conc note-number))
(otherwise (format t "A note around # ~a, it's type is muffed up." note-number) (bye)))))
;*************************************************************
;*************************************************************
;*************************************************************
;*************************************************************
;*************************************************************
;*************************************************************
;*************************************************************
;*************************************************************
;*************************************************************
;
; MISCELLAENEOUS USEFUL FUNCTIONS
;
;*************************************************************
;*************************************************************
;*************************************************************
;*************************************************************
;*************************************************************
; for octave, pitch, calculates frequency in 19 TET
(defun pitch-to-freq (octave pitch)
; 1.037155 is the ratio for 19-TET
; octave 8 is middle C, pitch 0 = 261.6256
; octave 0 is pitch 0 = 1.021974864
; octave 4 is pitch 0 = 16.351601
; how many chromatic steps up from 0 0?
; 1.021975 * (1.037155 ^ X)
(setf stepsup (+ (* octave 19) pitch))
(* 1.021974864 (expt 1.037155044 stepsup)))
; slightly adjusts a list of floats, random-deviates them
(defun piddle (list-of-numbers deviance)
(dotimes (ctr (length list-of-numbers))
(setf (nth ctr list-of-numbers)
(* (nth ctr list-of-numbers)
(const-frandom (- 1.0 deviance) (+ 1.0 deviance)))))
list-of-numbers)
(defun convert-dur-from-mbd-sec (list-of-three)
(/
(* 18
(+ (third list-of-three)
(* (second list-of-three) 6)
(* (first list-of-three) 114)))
1000.0))
(defun get-smallest-largest (lipst)
(let ((largest (first lipst))
(smallest (first lipst)))
(append
(list
(setf smallest
(dolist (elle lipst smallest)
(if (< elle smallest)
(setf smallest elle)))))
(list
(setf largest
(dolist (elle lipst largest)
(if (> elle largest)
(setf largest elle))))))))
(defun put-notes-in-order ()
; takes the notes in note-list, and puts them in chronological order.
; make another list of pairs of (note-number in original, time in total divs)
; sort that list by div-pairs
; construct a 3rd list by
; moving each note of note-list into it, in the new order.
;
(let ((index-div-list ())
(new-note-list)
)
(dotimes (counter (length note-list))
(setf index-div-list
(append index-div-list
(list
(append
(list counter)
(list (+
(* (* 6 19) (nth start-msr-par (nth counter note-list)))
(* 6 (nth start-beat-par (nth counter note-list)))
(nth start-div-par (nth counter note-list))))
)))))
;
(setf index-div-list (sort index-div-list #'< :key #'second))
;
(dolist (elle index-div-list)
(setf new-note-list
(append new-note-list
(list
(nth (first elle) note-list)))))
;
;
(setf note-list new-note-list)))
;
;
;
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
; MIXER
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
(defun mix-em ()
(let (
(cmix-score-filename ())
(cmix-sound-filename ())
(start '0.0)
(last-element-index '0)
(filename ())
(dur '0.0)
(type-for-interface '0)
(spatq-for-interface '0)
(droneq-for-interface '0)
(pinst-for-interface '0)
(prcs-lyne-number '0)
(pdcl-lyne-number '0)
(prcs-lyne-coll-file ())
(pdcl-lyne-coll-file ())
(prcs (make-array '(6) :initial-element '0))
(pdcl (make-array '(6) :initial-element '0))
)
; clear all old versions of colls and score-file
(setf cmix-score-filename (concatenate 'string "sec."
(princ-to-string section-number)
".buff.sco"))
(setf cmix-sound-filename (concatenate 'string "sec."
(princ-to-string section-number)
".buff.aiff"))
(shell (concatenate 'string "rm " cmix-score-filename))
(shell (concatenate 'string "rm " cmix-sound-filename))
(dotimes (lyne-number '6)
(shell (concatenate 'string "rm sec"
(princ-to-string section-number)
"reglyne"
(princ-to-string lyne-number)))
(shell (concatenate 'string "rm sec"
(princ-to-string section-number)
"dynlyne"
(princ-to-string lyne-number))))
; set up the CMIX buffer-creation score
; clears it automatically
(with-open-file (cmix-score cmix-score-filename :direction :output)
(format cmix-score "rtsetparams(44100, 2)~%
rtoutput(\"~a\")~%
makegen(1, 24, 200, 0,1,1,1)~%"
cmix-sound-filename))
;
;******************************
; main loop for the notes
;******************************
;
(dolist (elle note-list)
;
;
;a test to make sure the notes are in temporal order
;
(setf last-element-index (- (length elle) 1))
; write to the CMIX buffer-creation score
(setf filename (nth (- last-element-index 2) elle))
(setf dur (nth (- last-element-index 1) elle))
(with-open-file (cmix-score cmix-score-filename
:direction :output :if-exists :append)
(format cmix-score "rtinput(\"~a\")~%
MIX(~a, 0.0, ~a, 1.0, 0, 1)~%~%"
filename
start
dur))
;
;***************************************************************************************
; write to the pitch-register/concrete-stereopos coll
;***************************************************************************************
;
(setf prcs-lyne-number
(case (first elle)
((wave piano filt) (setf type-for-interface '0)
(setf spatq-for-interface (nth pitch-spatq-par elle))
(setf droneq-for-interface (nth pitch-droneq-par elle))
(setf pinst-for-interface (case (first elle)
(wave '0) (piano '1) (filt '2)))
(nth pitch-register-lyne-par elle))
(conc (setf type-for-interface '1)
(setf spatq-for-interface (nth conc-spatq-par elle))
(setf droneq-for-interface '0)
(setf pinst-for-interface '0)
; map extreme channels of concrete to extremes of register
(nth (nth conc-stereo-par elle) '(0 5 2 3 4 1)))
(arb (case
(nth arb-inst-type-par elle)
((wave piano filt) (setf type-for-interface '0)
(setf spatq-for-interface (nth arb-pitch-spatq-par elle))
(setf droneq-for-interface (nth arb-pitch-droneq-par elle))
(setf pinst-for-interface (case (first elle)
(wave '0) (piano '1) (filt '2)))
(nth arb-pitch-register-lyne-par elle))
(conc (setf type-for-interface '1)
(setf spatq-for-interface (nth arb-conc-spatq-par elle))
(setf droneq-for-interface '0)
(setf pinst-for-interface '0)
; map extreme channels of concrete to extremes of register
(nth (nth arb-conc-stereo-par elle) '(0 5 2 3 4 1)))))))
;
;
(setf prcs-lyne-coll-file (concatenate 'string "sec"
(princ-to-string section-number)
"reglyne"
(princ-to-string prcs-lyne-number)))
; write to it
(with-open-file (prcs-lyne-coll-stream prcs-lyne-coll-file
:direction :output :if-exists :append
:if-does-not-exist :create)
(format prcs-lyne-coll-stream
"~a, ~a ~a ~a ~a ~a ~a ~a ~a ~a ~a;~%"
(aref prcs prcs-lyne-number)
(nth start-msr-par elle)
(nth start-beat-par elle)
(nth start-div-par elle)
(* start 1000.0)
(+ (* start 1000.0) (* dur 1000.0))
(* dur 1000.0)
spatq-for-interface
type-for-interface
droneq-for-interface
pinst-for-interface))
;
;***************************************************************************************
; write to pitch-dynamic concrete-loudness/hardness coll
;***************************************************************************************
;
(setf pdcl-lyne-number
(case (first elle)
((wave piano filt) (nth pitch-dyn-par elle))
(conc (nth conc-loud-hard-amp-par elle))
(arb (case
(nth arb-inst-type-par elle)
((wave piano filt) (nth arb-pitch-dyn-par elle))
(conc (nth arb-conc-loud-hard-par elle))))))
(setf pdcl-lyne-coll-file (concatenate 'string "sec"
(princ-to-string section-number)
"dynlyne"
(princ-to-string pdcl-lyne-number)))
; write to it
(with-open-file (pdcl-lyne-coll-stream pdcl-lyne-coll-file
:direction :output :if-exists :append
:if-does-not-exist :create)
(format pdcl-lyne-coll-stream
"~a, ~a ~a ~a ~a ~a ~a ~a ~a ~a ~a;~%"
(aref pdcl pdcl-lyne-number)
(nth start-msr-par elle)
(nth start-beat-par elle)
(nth start-div-par elle)
(* start 1000.0)
(+ (* start 1000.0) (* dur 1000.0))
(* dur 1000.0)
spatq-for-interface
type-for-interface
droneq-for-interface
pinst-for-interface))
;
;*************************************************************************************************
;
;*************************************************************************************************
;
; update start time for next note
(setf start (+ start (nth (- last-element-index 1) elle) '.01))
(setf (aref prcs prcs-lyne-number) (+ (aref prcs prcs-lyne-number) 1))
(setf (aref pdcl pdcl-lyne-number) (+ (aref pdcl pdcl-lyne-number) 1))
)
;
; synthesize the buffer
;
(shell (concatenate 'string "CMIX < " cmix-score-filename))
;
; write empty colls to any non-existant ones
;
;
))
(defun resolve-bang-trees ()
(format t "write the bang-tree procedure some day, eh?~%~%"))
(defun print-used-and-unused-concrete-sounds ()
(format t "write the print unused conrete sounds function some day, ok?~%~%"))
(defun undo-bang-trees ()
(format t "write the undo bang-trees function some day, ok?~%~%"))
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
; MAIN PROCEDURE
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
;*****************************************************************
(format t "~%~%~% should we start at the VERY VERY beginning, with an
~% initial score file, or ~%
are you coming back, after having
modified a few notes, or you're just ready to mix? ~%
Type 1 or 2: ")
(case (read)
('1
(load "note-list")
(put-notes-in-order)
(process-notes)
; print updated working version of note-list to a working-version file
(with-open-file (score-file "working.note.list" :direction :output)
(format score-file "(setf note-list ~%'")
(prin1 note-list score-file)
(format score-file "~% ) ~%"))
(format t "~% To mix, run this again, and type 2. ~%")
(bye)
)
('2
(load "working.note.list")
(process-notes)
(with-open-file (score-file "working.note.list" :direction :output)
(format score-file "(setf note-list ~%'")
(prin1 note-list score-file)
(format score-file " ) ~%"))
(format t "I have re-written the notes you requested, if any. ~% Do you want to go on and mix? 1/0 ~%")
(if (= (read) 1)
(progn
(format t "What section-number of the piece am I about to mix down?")
(setf section-number (read))
(if (null (numberp section-number))
(progn (format t "Enter a fraokine number, you bosturd!!") (bye)))
(resolve-bang-trees)
(mix-em)
(print-used-and-unused-concrete-sounds)
(undo-bang-trees)
(format t "All done. Yay! ~%~%~% Bye. ")
(bye))
(progn (format t "OK. See ya later.") (bye)))
)
(otherwise (format t "~%~% Don't try to get wise with me!! ~%
Answer my question correctly next time! ~%") (bye)))
;
; mixing methods:
;
; pitch-register and concrete-stereo OR
;
; pitch-dynamics and concrete-loudness/hardness
;
; BASIC METRO SPEED === 18 milliseconds/div
;
;
; all time is measured in measures of 19/16, the BEAT of the measure, and the DIVision of the beat
;
;
;******************************************************************************************
;******************************************************************************************
;******************************************************************************************
;******************************************************************************************
;******************************************************************************************
;******************************************************************************************
;******************************************************************************************
;******************************************************************************************
;******************************************************************************************
;
; User writes an Initial Score File
;
; run it: <-------------------------------ENTER HERE
;
;
;************************************
;
;FOR ALL NOTES IN SCORE:
; {
; skip any bang-attach-block commands
; skip any arbitrary soundfiles
; skip any 0-flagged notes : 0-flag means we've written the note,
; and don't want to write it again.
; write a given note ---write its soundfile
; AND add parameters to it's list:
; note its filename ---test if already exists
; note its duration
; note its concrete soundnumber, if applic.
; possibly other stuff depending on instrument
; 0-flag it--it won't be written again, unless we
; explicitly change the flag to 1, to get a new
; version.
; }
;
;
; write Working-Version of Score-file to disk--
;
;
;******************************************************
; the program continues below, but we can also
; start using it at this point, essentially asking
; to find/make new versions of given 1-flagged notes
;
; In the Working Score File, we flag the notes
; we want re-written or changed.
; we can also insert a note into the Working Score File
;
;******************************************************
;
;
; MIXING -------- we can enter here. <--------------------------- POSS. ENTER HERE
;
;
; This time we work with the Working Version of the Score-file
; {
; skip any bang-attach-block commands
; skip any arbitrary soundfiles
; skip any 0-flagged notes : 0-flag means we've written the note,
; and don't want to write it again.
; 1-flag, or lack of flag, means write the note.
; write a given note ---write its soundfile
; AND add parameters to it's list:
; note its filename ---test if already exists
; note its duration
; note its concrete soundnumber, if applic.
; possibly other stuff depending on instrument
; 0-flag it--it won't be written again, unless we
; explicitly change the flag to 1, to get a new
; version.
; }
;
;
; stop, ask if you want to go on? ------------------------> EXIT HERE TO TEST REWRITTEN SOUND FILES
;
;
;
;
;*********************************************************
;
;
; BANG ATTACH-PROCESSOR
; This reads a bang-tree.
; It then takes the following listed sounds,
; that are involved in the tree, and
; adds necessary "padding" to the beginning
; of those soundfiles, so the bangs will line up;
; (OR OR OR OR: change start times to approximate
; bang line-up).
; changing their durations (start-times should
; already be ALL THE SAME for all sounds in a
; given tree)
; note: pitches have only one bang each---you can't attach stuff to them,
; (except on the 0'th bang?)
; Keep track of what we do, so we can un-do it later (see bottom).
; maybe remove bangs-list from note-list before is goes into the mixer.
;
;
; FINAL-MIXER
;
; uses "working.note.list"
;
; Mix all notes into one buffer-soundfile
; create colls---12 colls,
; building several files: 12 colls, a CMIX-score to make the buffer,
;
; counters: which note in each coll, a "pointer" into the buffer
;
;
;
;
;
; LOOP:
; MIX IN A NOTE:
; {
; make coll entries, add to appropriate colls (2, for each type of mix)
; add to CMIX STEREO score that will create buffer
; keep track of which concrete sounds used
; }
;
;
;
; RUN CMIX score to produce buffer.
;
; print list of used concrete sounds to a file
; (we can combine this with other files later
; to figure out sounds are left).
;
; IMPORTANT: now UN-PAD the bang-attached sounds, so that if we mix down
; again, they will not be "double-padded".
;
;
;**************************************************************************************
;**********************************************************************************
;*****************************************************************************
;*********************************************************************************
;*************************************************************************************
;**************************************************************************************
;**********************************************************************************
;*****************************************************************************
;*********************************************************************************
;*************************************************************************************
;
;
;
;
;
;Articulation/agitation. might be a list:
;------------------------------------------
; (staccatto: short duration)
; accent/ten
; Fp
; TRemolo --- internal rate changes determined by random row form
;"Bartok Pizz"
; random adsr
; vibrato (on wave & filt) --- internal rate changes determined by random row form
; random Gliss (on wave & filt) (you could include end pitch)
; changing trem. , from more to less
; cresc. (list includes start and end dynamic)
; decresc. (list includes start and end dynamic)
; cresc./decresc (list of low dynamic, hi dynamic, temporal proportion like 0 1 9 or 0 5 11
; soft-attack (uses a cresc./decresc preset)
;-------------------------------------------
;***************************************
; FOR WWAVE INSTRUMENT:
;
;
; 0 1 2 3 4 5 6 7 8 9 10 11 12 13
; Inst start: msr beat div dur: msr beat div Octve PC registral-lyne# Dyn-lvl Spatlztn stereo Artic
; name 0 0 0 1 0 0 5 17 0-5 0-5 0-1 0-5 word
;
;
; 14 15 16 17 18
; filter wave
; is-it-drone? (noisiness or wave-form) (soundfile-name) (final duration) (rewrite-flag)
; 0-1 word (oboe, clar) in seconds 0-1
;
;******************************************************
;
; FOR PIANO INSTRUMENT:
; 0 1 2 3 4 5 6 7 8 9 10 11 12 13
; Inst start: msr beat div dur: msr beat div Octve PC registral-lyne# Dyn-lvl Spatlztn stereo Artic
; name 0 0 0 1 0 0 5 17 0-5 0-5 0-1 0-5 word
;
;
;
; 14 15 16 17 18
; is-it-drone? cut to start (soundfile-name) (final duration) (rewrite-flag)
; 0-1 or full attack ? in seconds 0-1
;
;*********************************************************
; CONCRETE INSTRUMENT
;
; instr msr beat div par-list amp-fac spat? stereo cut/full makegen-curve loud/hard/amp ||| conc-sound# filename dur re-write?
; 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
;
;*****************************************************************************************************
;
; FOR ARBITRARY SOUNDFILES:
;
; start: msr beat div type:
; conc
; wave or piano or filt
;
; if pitch, we need to know register, pitch, dynamic, spat, part-o-drone?
; if concrete, we need to know stereo-pos, loud/hardness
;
;
; other data needed? soundfile-name duration
; in seconds
;
; (arb 0 0 0 wave 0-5 14 0-5 0-1 0-1 "2.3.4.5.aiff" 1.234)
; (arb 0 0 0 piano 0-5 14 0-5 0-1 0-1 "2.3.4.5.aiff" 1.234)
; (arb 0 1 2 conc 0-5 0-5 "2.3.4.7.aiff" 2.345)
;
;
;
;****************************************************************************8
;
;
;
; FOR BANG-ATTACH COMMAND-BLOCKS
;
;
; (bang 5
; (bang-tree here))
;
; (note . . . .) first should be defined regularly
; (note . . . . . .) the next ones should have the keyword "bang" in place of all start parameters
; OR, maybe, all notes have the same start time----so only the "padding" changes when
; they happen.
;
;
; (shell "ls")
;
; abort
; backtrace (?)
;