Skip to content

Instantly share code, notes, and snippets.

@CircuV
Created June 4, 2015 14:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CircuV/a579e265c65911e62eef to your computer and use it in GitHub Desktop.
Save CircuV/a579e265c65911e62eef to your computer and use it in GitHub Desktop.
;; cv_part_fratres_midi.xtm --
;;
;; Author: cv
;; Keywords: extempore
;;; Commentary: Live-coding Arvo Pärt's Fratres (strings and percussion version)
;; Midi Version controlling NI Kontakt Sampler (Factory Library)
;; Channels:
;; Upper voice (1 : Violin Ensemble)
;; Bottom voice (2 : Cello Ensemble)
;; Middle voice (3 : Viola Ensemble)
;; Bass voice (4 : Double Bass Ensemble)
;; Percussion (5 : Bass Drum)
;;
;;
;;
;;; Code:
;; First, load the library where the sampler infrastructure is
;; located. Have a look at this file in your editor to see how the
;; sampler works.
;; load Midi library
(sys:load "libs/external/rtmidi.xtm")
;; Now define the sampler instrument and DSP callback function (in
;; this case, it just calls the sampler closure)
;; midi stuff
(define *midi-out* (midi_new_outdevice))
;; query for valid midi output devices
(midi_query_outports *midi-out*)
;; now open output port (assuming port 0)
(midi_open_outport *midi-out* 0)
;; play midi test note
(play-midi-note (now) *midi-out* 72 100 10000 0)
;; requires pc_ivl-lib
(sys:load "libs/core/pc_ivl.xtm")
;; performance starts here
;; fratres pärt
;; midi channel 3
;; CC volume device type channel nr val
(midi_send *midi-out* *midi-control-change* 3 7 60)
;; play drones A2 and E3
(play-midi-note (now) *midi-out* 33 100 (* 12.0 *minute*) 3)
(play-midi-note (now) *midi-out* 40 100 (* 12.0 *minute*) 3)
;; percussion part beat pattern
(*metro* 'set-tempo 60)
;; looped percussion
(define perc
(let ((ns '(40)) ;; add or remove as much as you like (but leave 1!)
(ds '(2 1 3))) ;; add or remove as much as you like (but leave 1!)
(lambda (beat notes durations)
(play-midi-note (*metro* beat) *midi-out* (car notes) 90 (*metro* 'dur (car durations)) 4)
(if #t (callback (*metro* (+ beat (* 0.95 (car durations)))) 'perc (+ beat (car durations))
(if (null? (cdr notes)) ns (cdr notes))
(if (null? (cdr durations)) ds (cdr durations)))))))
(perc (*metro* 'get-beat 4) '(60) '(2 1 3 2 1 3))
;; stop percussion #t -> #f in callback
;; single perussion run
(define perc
(lambda (beat ps ds)
(play-midi-note (*metro* beat) *midi-out* (car ps) 90 (*metro* 'dur (car ds)) 4 )
(if (not(null? (cdr ds)))(callback (*metro* (+ beat (* 0.5 (car ds)))) 'perc (+ beat (car ds))
ps
(cdr ds)))))
;; run percussion
(define chorale)
(perc (*metro* 'get-beat 4) '(60) '(2 1 3 2 1 3))
;; chorale part
;; add hamonic scale to scales (for version <= 0.57)
(define *pc:scales* (append *pc:scales* (list (cons 'harmonic '(2 1 2 2 1 3)))))
;;
(println *pc:scales*)
;;(define scale '(52 50 49 46 45 43 41 40 38 37 34 33 31 29))
(define scale (pc:scale 2 'harmonic))
(println scale)
(define root 76)
;; test
(println (pc:relative root -2 scale))
;; note function cycle through scale starting on different notes
(define fnote
(lambda (cycle index)
(pc:relative (pc:relative root (- (* 2 cycle)) scale) (- index) scale)
))
;; test
(println (fnote 0 1))
;; define chord list of notes A C E as PC
(define mid '(9 4 4 0 0 0 0 9 9 4 4 0 0 9))
(println (rotate mid -2))
;; untility functions
;; octave shift in the middle
(define seam
(lambda (i)
(if (< i 4) 0 12)))
;;test seam
(println (seam 5))
;;
;; note lengths function
(define nlnF
(lambda (i)
(case i
((= 0) 2)
((= 7) 3)
(else 1))))
;; test nlnF
(println (nlnF 0))
;; function for middle note combined version with dir
(define mnote
(lambda (cycle index dir)
(let* ((i index )
(ind (if (> dir 0) index (modulo (+ index 7) 14)))
(high (+ 12 (seam i) (fnote cycle i)))
(low (+ (seam i) (fnote (+ 1 cycle) i))))
(let ((nota (+ (list-ref (rotate mid (* -2 cycle)) ind) (* 12 (quotient low 12)))))
(if (> nota low) nota (+ nota 12))
))))
(println (> -1 0))
(println (mnote 0 7 1))
;;
;; single run versions
;; segment F falling chords cyc 1
;; segment G rising chords cyc -1 (retrograde upper lowere voice, different middle voice)
;;
(define chorale
(lambda (beat notes vol cyc dir)
;;
(let* ((ii (car notes))
(i (if (> dir 0) ii (- 7 ii)))
(len (nlnF (car notes))))
;; top note
;; (midi_send *midi-out* *midi-control-change* 0 7 vol)
(play-midi-note (*metro* beat) *midi-out* (+ 12 (seam i) (fnote cyc i)) vol (*metro* 'dur len) 0)
;; bottom note
;; (midi_send *midi-out* *midi-control-change* 1 7 vol)
(play-midi-note (*metro* beat) *midi-out* (+ (seam i) (fnote (+ 1 cyc) i)) vol (*metro* 'dur len) 1)
;; middle note
;; (midi_send *midi-out* *midi-control-change* 2 7 vol)
(play-midi-note (*metro* beat) *midi-out* (mnote cyc i dir) vol (*metro* 'dur len) 2)
;;
(if (not(null? (cdr notes))) (callback (*metro* (+ beat (* 0.95 len))) 'chorale (+ beat len)
(cdr notes) vol cyc dir)))))
;; run chorale
;; change dir 1 -1
;; change cycle nr from 1 to 7
;; change volume according to cycle
(chorale (*metro* 'get-beat 4) '(0 1 6 7 0 1 2 5 6 7 0 1 2 3 4 5 6 7) 65 0 1)
;; play percussion part at beginning and end and between every cyc change
(perc (*metro* 'get-beat 4) '(60) '(2 1 3 2 1 3))
;; stop
;; for fade out bordun
;; CC volume device type channel nr val
(midi_send *midi-out* *midi-control-change* 3 7 60)
;; the end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment