-
Notifications
You must be signed in to change notification settings - Fork 3
how can i change pitches algorithmically?
Michael Edwards edited this page Jun 1, 2024
·
1 revision
I've made quite a few pieces with make-slippery-chicken
where I'm not actually
interested in the pitches generated, but I am very much interested in the
rhythmic and related structures offered by the function and resultant object. In
those cases it's necessary to change instruments' pitches post hoc,
using post-generation
editing
techniques.
Below is an interesting example, prompted by Diana Ortiz, where a piece is first
of all generated with make-slippery-chicken
, then, according to a
chance-curve which is automagically extrapolated over the whole piece,
instruments' notes are changed to those of another player. In this way we can
very easily control the amount of unison playing over all notes of a piece.
(in-package :sc)
;;; First let's generate an existing piece that we can clone and then act
;;; upon. Comment out and load tempus-perfectum.lsp by hand if working in
;;; another directory.
(load-from-same-dir "tempus-perfectum.lsp")
;;; To avoid warnings about globals in the code below.
(proclaim '(special +tempus-perfectum+))
(defmethod tendency-unison ((sc slippery-chicken)
&optional
(main-player 'ob)
;; x values can range over whatever you like but y
;; values are expressed as a percentage where 0 = no
;; pitch change and 100 = definite pitch
;; change. Change 'em all by default, just to prove
;; it works.
(change-chance-env '(0 100 100 100)))
(let ((all-events (get-events-sorted-by-time sc))
(chance 0.0)
(do-it nil)
(main-player-note nil)
(event-count 0)
(changed-count 0))
;; we've used an x-axis from 0-100 (or whatever), but need to stretch this
;; over all the notes in the whole piece (including, for simplicity's sake
;; the main-player)
(setq change-chance-env (new-lastx change-chance-env (1- (num-notes sc))))
(loop for event in all-events do
(when (needs-new-note event) ; only process attacked notes
(if (eq main-player (player event))
;; for simplicity's sake we'll just grab the last main-player
;; note and use that to change subsequent non-main-player
;; notes, accepting or even enjoying that, depending on
;; rhythmic structure, we might be a little behind.
(setq main-player-note (pitch-or-chord event))
;; don't change main-player's notes, and only change other
;; player's notes if we've seen a main-player note already
(when main-player-note
;; get the chance of changing
(setq chance (interpolate event-count change-chance-env)
;; determine whether to change the note to the
;; main-player's note using fixed-seed
;; randomness. Note that we reset the random
;; generator when event-count is 0, i.e. on the first
;; time through the loop. Note also the less-than
;; test assumes that the Y values of the
;; change-chance-env range from 0 to 100
do-it (< (random-rep 100.0 (zerop event-count))
chance))
(when do-it
;; bear in mind that no checks are made here that the
;; instrument we're dealing with can actually play the
;; main player's note! If we wanted to be more
;; sophisticated, then we could use the in-range method
;; and octavise where necessary.
(setf (pitch-or-chord event) main-player-note)
(incf changed-count))))
(incf event-count)))
;; we've only changed attacked notes' pitches, so any tied-to notes will
;; be wrong! Helpfully the check-ties method takes care of fixing these :-)
(check-ties sc t)
;; these two for statistics' sake really
(update-slots sc)
(update-instrument-slots sc)
(format t "~&Changed ~a notes." changed-count)
sc))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; now actually do it, cloning the original so as not to have to reload, and/or
;;; to enable easier comparisons.
(let ((sc (tendency-unison (clone +tempus-perfectum+))))
(cmn-display sc :size 10
:in-c t))
- which instruments are available in the standard instrument-palette?
- how can I change the default directory for output?
- how can I change the range of instruments in the standard instrument-palette?
- how can I stop (or start) slippery chicken from opening score files automatically?
- how do I make a one-note rthm-seq with a chord?
- set-limits by section
- empty bars
- combining bars
- combining chopped and unchopped rthm-seq palettes
- how can I 'roll-my-own' slippery-chicken
- graphics files as marks
- three-quarter tone accidentals
- what to do when lilypond fails?
- tuplets with colons e.g 7:6