linked-named-object/player [ Classes ]
[ Top ] [ linked-named-object ] [ Classes ]
NAME
player File: player.lsp Class Hierarchy: named-object -> linked-named-object -> player Version: 1.1.0 Project: slippery chicken (algorithmic composition) Purpose: Implementation of the player class which holds an instrument or a assoc-list of instruments in it's data slot. Author: Michael Edwards: m@michael-edwards.org Creation date: 7th September 2001 $$ Last modified: 15:13:59 Fri Aug 23 2024 CEST SVN ID: $Id$
player/make-player [ Functions ]
[ Top ] [ player ] [ Functions ]
DESCRIPTION
Create a player object from a specified instrument-palette object and a specified instrument or list of instruments which that player plays. The player object is separate from the instrument object as on player in an ensemble may perform more than one instrument ("double"), such as flute and piccolo, clarinet and bass clarinet, or sax, flute and clarinet.
ARGUMENTS
- A symbol which will be the ID of the resulting player object. - An instrument-palette object. If NIL then +slippery-chicken-standard-instrument-palette+ will be used - A symbol or a list of symbols that are the instruments from the specified instrument-palette object that the given player will play, as spelled and defined within the instrument-palette object. NB: If only one instrument is to be assigned to the given player, it should be stated as symbol rather than a list, to avoid errors in the DOUBLES slot.
OPTIONAL ARGUMENTS
keyword arguments: - :midi-channel. An integer that indicates the MIDI channel on which any non-microtonal pitch material for this player is to be played back. Default = 1. - :microtones-midi-channel. An integer that indicates the MIDI channel on which any microtonal pitch material for this player is to be played back. slippery chicken uses this channel to add MIDI pitch-bends via CM so that microtonal chords are possible, but due to a current glitch these tracks contain no pitch-bend data. A work-around for this is to simply open the MIDI file in a sequencer and shift the entire channel by the desired pitch-bend value. Default = -1. - :cmn-staff-args. A list of pairs that indicate any additional arguments to the call to cmn::staff for this player, such as staff size, number of lines etc. Instead of being real cmn function calls, as they would be in normal cmn, this is a simple list of pairs; e.g. '(staff-size .8 staff-lines 3). Defaults = NIL. - :staff-names. A symbol, string or list of staff names, generally strings, for each instrument the player will play. E.g. '("violin II"). If not given, then the instrument's name as defined in the instrument palette will be used. Default = NIL. - :staff-short-names. A symbol, string or list of short staff names. E.g. '("vln2"). Default = NIL
RETURN VALUE
Returns a player object.
EXAMPLE
;; Create a player object with just one instrument object (let ((ip (make-instrument-palette 'inst-pal '((picc (:transposition-semitones 12 :lowest-written d4 :highest-written c6)) (flute (:lowest-written c4 :highest-written d7)) (clar (:transposition-semitones -2 :lowest-written e3 :highest-written c6)) (horn (:transposition f :transposition-semitones -7 :lowest-written f2 :highest-written c5)) (vln (:lowest-written g3 :highest-written c7 :chords t)) (vla (:lowest-written c3 :highest-written f6 :chords t)))))) (make-player 'player-one ip 'flute)) => PLAYER: (id instrument-palette): INST-PAL doubles: NIL, cmn-staff-args: NIL LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL NAMED-OBJECT: id: PLAYER-ONE, tag: NIL, data: INSTRUMENT: lowest-written: [...] NAMED-OBJECT: id: FLUTE, tag: NIL, data: NIL ;; Create a player object with two instruments, setting the midi channels using ;; the keyword arguments, then print the corresponding slots to see the changes (let* ((ip (make-instrument-palette 'inst-pal '((picc (:transposition-semitones 12 :lowest-written d4 :highest-written c6)) (flute (:lowest-written c4 :highest-written d7)) (clar (:transposition-semitones -2 :lowest-written e3 :highest-written c6)) (horn (:transposition f :transposition-semitones -7 :lowest-written f2 :highest-written c5)) (vln (:lowest-written g3 :highest-written c7 :chords t)) (vla (:lowest-written c3 :highest-written f6 :chords t))))) (plr (make-player 'player-one ip '(flute picc) :midi-channel 1 :microtones-midi-channel 2))) (print (loop for i in (data (data plr)) collect (id i))) (print (midi-channel plr)) (print (microtones-midi-channel plr))) => (FLUTE PICC) 1 2 ;;; With specified cmn-staff-args (let ((ip (make-instrument-palette 'inst-pal '((picc (:transposition-semitones 12 :lowest-written d4 :highest-written c6)) (flute (:lowest-written c4 :highest-written d7)) (clar (:transposition-semitones -2 :lowest-written e3 :highest-written c6)) (horn (:transposition f :transposition-semitones -7 :lowest-written f2 :highest-written c5)) (vln (:lowest-written g3 :highest-written c7 :chords t)) (vla (:lowest-written c3 :highest-written f6 :chords t)))))) (make-player 'player-one ip '(flute picc) :midi-channel 1 :microtones-midi-channel 2 :cmn-staff-args '(staff-size .8 staff-lines 3))) => PLAYER: (id instrument-palette): INST-PAL doubles: T, cmn-staff-args: (#<SELF-ACTING {10097B6E73}> #<SELF-ACTING {10097B6EE3}>), total-notes: 0, total-degrees: 0, total-duration: 0.000, total-bars: 0, tessitura: NIL LINKED-NAMED-OBJECT: previous: NIL, this: NIL, next: NIL NAMED-OBJECT: id: PLAYER-ONE, tag: NIL, data: [...]
SYNOPSIS
(defun make-player (id instrument-palette instruments &key (cmn-staff-args nil) staff-names staff-short-names (microtones-midi-channel -1) (midi-channel 1))
player/microtonal-chords-p [ Methods ]
[ Top ] [ player ] [ Methods ]
DESCRIPTION
Determines whether the MICROTONES-MIDI-CHANNEL slot of the given player object is set to a value greater than 0 and is different to the midi-channel slot, indicating that the player and its instrument are capable of performing microtonal chords.
ARGUMENTS
- A player object.
RETURN VALUE
Returns T if the value stored in the MICROTONES-MIDI-CHANNEL slot of the given player object is greater than 0, otherwise returns NIL.
EXAMPLE
;; Returns T (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'vln ip 'violin :microtones-midi-channel 2))) (microtonal-chords-p plr)) => T ;; Returns NIL (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'pno ip 'piano))) (microtonal-chords-p plr)) => NIL
SYNOPSIS
(defmethod microtonal-chords-p ((p player)) ;; MDE Thu Dec 28 17:49:36 2017 -- updated as now make-player sets microtones ;; channel to midi-channel if it's not explicitly set (and (integer>0 (microtones-midi-channel p)) (/= (microtones-midi-channel p) (midi-channel p)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defmethod score-write-bar-line ((p player)) (let* ((data (data p)) (ins (if (typep data 'assoc-list) (first (data data)) data))) (score-write-bar-line ins)))
player/player-get-instrument [ Methods ]
[ Top ] [ player ] [ Methods ]
DESCRIPTION
Get the instrument object assigned to a single-instrument player object or get the specified instrument object assigned to a multiple-instrument player object. NB: This method will drop into the debugger with an error if no optional argument is supplied when applying the method to a multiple-instrument player object. It will also print a warning when supplying an optional argument to a player object that contains only one instrument object.
ARGUMENTS
- A player object.
OPTIONAL ARGUMENTS
- Actually a required object for multiple-instrument player objects: The symbol that is the ID of the sought-after instrument object, as it appears in the instrument-palette with which the player object which made. If the given player object consists of only one instrument object, this argument is disregarded and a warning is printed. If this argument is simply T then the first instrument is returned (in the assoc-list, not the piece, of which we have no knowledge).
RETURN VALUE
Returns an instrument object.
EXAMPLE
;; Returns an instrument object. Needs no optional argument when applied to a ;; player object that contains only one instrument object (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'pno ip 'piano))) (player-get-instrument plr)) => INSTRUMENT: [...] NAMED-OBJECT: id: PIANO, tag: NIL, data: NIL ;; Returns the only existing instrument object and prints a warning if using ;; the optional argument when applying to a single-instrument player object (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'pno ip 'piano))) (id (player-get-instrument plr 'piano))) => PIANO WARNING: player::player-get-instrument: player PNO has only 1 instrument so optional argument PIANO is being ignored ;; Asking for a non-existent instrument obect from a single-instrument player ;; object returns the only existing instrument object instead (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'pno ip 'piano))) (id (player-get-instrument plr 'marimba))) => PIANO WARNING: player::player-get-instrument: player PNO has only 1 instrument so optional argument PIANO is being ignored ;; The ID desired instrument object must be specified when applying the method ;; to a multiple-instrument player object (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'percussion ip '(marimba vibraphone)))) (id (player-get-instrument plr 'marimba))) => MARIMBA ;; Interrupts and drops into the debugger when the optional argument is omitted ;; in applying the method to a multiple-instrument player object (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'percussion ip '(marimba vibraphone)))) (player-get-instrument plr)) => player::player-get-instrument: PERCUSSION doubles so you need to pass the ID of the instrument you want. [Condition of type SIMPLE-ERROR]
SYNOPSIS
(defmethod player-get-instrument ((p player) &optional ins (warn t))
player/plays-transposing-instrument [ Methods ]
[ Top ] [ player ] [ Methods ]
DESCRIPTION
Determine whether a given player object has one or more transposing instrument objects assigned to it.
ARGUMENTS
- A player object.
OPTIONAL ARGUMENTS
- T or NIL to indicate whether instruments that transpose at the octave are to be considered transposing instruments. T = instruments that transpose at the octave are not considered transposing instruments. Default = T.
RETURN VALUE
Returns T if one or more of the instrument objects assigned to the given player object has a transposition value other than C or a transposition-semitones value other than 0.
EXAMPLE
;; Create a player object using the 'b-flat-clarinet instrument object ;; definition from the default +slippery-chicken-standard-instrument-palette+, ;; then apply the method. (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'cl ip 'b-flat-clarinet))) (plays-transposing-instrument plr)) => T ;; Create a player object using the 'flute instrument object definition from ;; the default +slippery-chicken-standard-instrument-palette+, then apply the ;; method. (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'fl ip 'flute))) (plays-transposing-instrument plr)) => NIL ;; Although the intended procedure is to list single instruments as once-off ;; symbols (as in the previous example), single instruments can also be added ;; as a one-item list (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'fl ip '(flute)))) (doubles plr)) => NIL ;; Create a player object using a list that consists of the 'flute and ;; 'alto-sax instrument object definitions from the default ;; +slippery-chicken-standard-instrument-palette+, then apply the method to see ;; that it returns T even when only one of the instruments is transposing. (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'fl ip '(flute alto-sax)))) (plays-transposing-instrument plr)) => T ;; Setting the optional argument to NIL causes instruments that transpose at ;; the octave to return T. (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'db ip 'double-bass))) (plays-transposing-instrument plr)) => NIL (let* ((ip +slippery-chicken-standard-instrument-palette+) (plr (make-player 'db ip 'double-bass))) (plays-transposing-instrument plr nil)) => T
SYNOPSIS
(defmethod plays-transposing-instrument ((p player) &optional (ignore-octaves t) ignore)
player/reset-instrument-stats [ Methods ]
[ Top ] [ player ] [ Methods ]
DATE
23rd August 2013
DESCRIPTION
Reset the statistics slots for each instrument the player plays.
ARGUMENTS
- The player object
OPTIONAL ARGUMENTS
- just-total-duration. If NIL update all statistics slots, otherwise just the total-duration slot of each instrument
RETURN VALUE
T if the player has instruments, NIL if not.
SYNOPSIS
(defmethod reset-instrument-stats ((p player) &optional just-total-duration)
player/tessitura-degree [ Methods ]
[ Top ] [ player ] [ Methods ]
DESCRIPTION
Return a number that represents the average pitch for a specified instrument over the course of a piece. The number returned will be degrees in the current scale.
ARGUMENTS
- A player object.
RETURN VALUE
A number that is the tessitura-degree; i.e., average pitch of the given instrument for the entirety of the given musical data.
EXAMPLE
(let ((mini (make-slippery-chicken '+mini+ :ensemble '(((vn (violin :midi-channel 1)) (va (violin :midi-channel 2)) (vc (cello :midi-channel 3)))) :set-palette '((1 ((gs3 as3 b3 cs4 ds4 e4 fs4 gs4 as4 b4 cs5)))) :set-map '((1 (1 1 1 1 1))) :rthm-seq-palette '((1 ((((2 4) q (e) s (32) 32)) :pitch-seq-palette ((1 2 3))))) :rthm-seq-map '((1 ((vn (1 1 1 1 1)) (va (1 1 1 1 1)) (vc (1 1 1 1 1)))))))) (tessitura-degree (get-data 'vc (ensemble mini)))) => 136
SYNOPSIS
(defmethod tessitura-degree ((p player))
player/tessitura-note [ Methods ]
[ Top ] [ player ] [ Methods ]
DESCRIPTION
Return the value of the TESSITURA-DEGREE slot of a specified player object as a note-name symbol.
ARGUMENTS
- A player object.
RETURN VALUE
- A note-name symbol.
EXAMPLE
(in-scale :chromatic) (let ((mini (make-slippery-chicken '+mini+ :ensemble '(((vn (violin :midi-channel 1)) (va (violin :midi-channel 2)) (vc (cello :midi-channel 3)))) :set-palette '((1 ((gs3 as3 b3 cs4 ds4 e4 fs4 gs4 as4 b4 cs5)))) :set-map '((1 (1 1 1 1 1))) :rthm-seq-palette '((1 ((((2 4) q (e) s (32) 32)) :pitch-seq-palette ((1 2 3))))) :rthm-seq-map '((1 ((vn (1 1 1 1 1)) (va (1 1 1 1 1)) (vc (1 1 1 1 1)))))))) (tessitura-note (first (data (ensemble mini))))) => BF3
SYNOPSIS
(defmethod tessitura-note ((p player))
player/total-bars [ Methods ]
[ Top ] [ player ] [ Methods ]
DESCRIPTION
Return the number of bars in a specified player object.
ARGUMENTS
- A player object.
RETURN VALUE
- An integer.
EXAMPLE
(let ((mini (make-slippery-chicken '+mini+ :ensemble '(((vn (violin :midi-channel 1)) (va (violin :midi-channel 2)) (vc (cello :midi-channel 3)))) :set-palette '((1 ((gs3 as3 b3 cs4 ds4 e4 fs4 gs4 as4 b4 cs5)))) :set-map '((1 (1 1 1 1 1))) :rthm-seq-palette '((1 ((((2 4) q (e) s (32) 32)) :pitch-seq-palette ((1 2 3))))) :rthm-seq-map '((1 ((vn (1 1 1 1 1)) (va (1 1 1 1 1)) (vc (1 1 1 1 1)))))))) (total-bars (first (data (ensemble mini))))) => 5
SYNOPSIS
(defmethod total-bars ((p player))
player/total-degrees [ Methods ]
[ Top ] [ player ] [ Methods ]
DESCRIPTION
Return a number that reflects the mean note (tessitura) of a player's part. This is calculated by incrementing the TOTAL-DEGREES slot of the corresponding instrument object for each attacked note in the player's part by the degree of that note (in the scale of the piece), and then dividing the sum by the total number of notes in the player's part.
ARGUMENTS
- A player object.
RETURN VALUE
- An integer.
EXAMPLE
(in-scale :chromatic) (let ((mini (make-slippery-chicken '+mini+ :ensemble '(((vn (violin :midi-channel 1)) (va (violin :midi-channel 2)) (vc (cello :midi-channel 3)))) :set-palette '((1 ((gs3 as3 b3 cs4 ds4 e4 fs4 gs4 as4 b4 cs5)))) :set-map '((1 (1 1 1 1 1))) :rthm-seq-palette '((1 ((((2 4) q (e) s (32) 32)) :pitch-seq-palette ((1 2 3))))) :rthm-seq-map '((1 ((vn (1 1 1 1 1)) (va (1 1 1 1 1)) (vc (1 1 1 1 1)))))))) (total-degrees (first (data (ensemble mini))))) => 865
SYNOPSIS
(defmethod total-degrees ((p player))
player/total-duration [ Methods ]
[ Top ] [ player ] [ Methods ]
DESCRIPTION
Get the total duration of played notes for a given player over the span of a piece.
ARGUMENTS
- A player object.
RETURN VALUE
A number that is the total duration in seconds of played notes.
EXAMPLE
(let ((mini (make-slippery-chicken '+mini+ :ensemble '(((vn (violin :midi-channel 1)) (va (violin :midi-channel 2)) (vc (cello :midi-channel 3)))) :set-palette '((1 ((gs3 as3 b3 cs4 ds4 e4 fs4 gs4 as4 b4 cs5)))) :set-map '((1 (1 1 1 1 1))) :rthm-seq-palette '((1 ((((2 4) q (e) s (32) 32)) :pitch-seq-palette ((1 2 3)))) (2 ((((2 4) (q) e (s) 32 32)) :pitch-seq-palette ((1 2 3))))) :rthm-seq-map '((1 ((vn (1 1 1 1 1)) (va (2 2 2 2 2)) (vc (1 2 1 2 1)))))))) (print (total-duration (get-data 'vn (ensemble mini)))) (print (total-duration (get-data 'va (ensemble mini)))) (print (total-duration (get-data 'vc (ensemble mini))))) => 6.875 3.75 5.625
SYNOPSIS
(defmethod total-duration ((p player))
player/total-notes [ Methods ]
[ Top ] [ player ] [ Methods ]
DESCRIPTION
Get the total number of notes (actually events) played by a specified player (not rests or tied notes, but midi-notes) in the piece which this instrument plays. A chord counts as 1 note/event.
ARGUMENTS
- A player object.
RETURN VALUE
- An integer that is the number of notes for that player.
EXAMPLE
(let ((mini (make-slippery-chicken '+mini+ :ensemble '(((vn (violin :midi-channel 1)) (va (violin :midi-channel 2)) (vc (cello :midi-channel 3)))) :set-palette '((1 ((gs3 as3 b3 cs4 ds4 e4 fs4 gs4 as4 b4 cs5)))) :set-map '((1 (1 1 1 1 1))) :rthm-seq-palette '((1 ((((2 4) q (e) s (32) 32)) :pitch-seq-palette ((1 2 3))))) :rthm-seq-map '((1 ((vn (1 1 1 1 1)) (va (1 1 1 1 1)) (vc (1 1 1 1 1)))))))) (print (total-notes (get-data 'vc (ensemble mini))))) => 15
SYNOPSIS
(defmethod total-notes ((p player))