Mercurial > hg > amuse
changeset 175:7e8d95d00267
Bars independant of time sigs
darcs-hash:20080313112352-40ec0-0805528027499f30d3812fa6c4e65596d1ff40fe.gz
author | d.lewis <d.lewis@gold.ac.uk> |
---|---|
date | Thu, 13 Mar 2008 11:23:52 +0000 |
parents | 9b152d515275 |
children | cddf83554c08 |
files | base/generics.lisp base/methods.lisp |
diffstat | 2 files changed, 99 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/base/generics.lisp Thu Mar 13 11:22:29 2008 +0000 +++ b/base/generics.lisp Thu Mar 13 11:23:52 2008 +0000 @@ -409,3 +409,49 @@ ;;; Dynamics ;;; Voice ;;; Boundary Strength (phrasing) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Experimental: +;; + +;;; Proposed new metre functions +;; These should provide sufficient functionality that the users need +;; not refer to get-applicable-time-signatures unless they really mean +;; it. In turn, this means that barline based representations have a +;; better chance at guessing. + +;; Notes: +;; * iteration is possible with +;; (do ((beat (current-beat (make-moment 0) composition)) +;; (current-beat (cut-off beat) composition))) ... +;; [That's probably not very efficient. there must be better ways] +;; * gsharp and tabcode can answer bar questions, but not beat +;; questions. Appropriate conditions and restarts will be needed. +;; * a good test of this functionality will prob be amuse-harmony. + +(defgeneric bar-period (time-signature implementation-object) + (:documentation "Returns a <period> with a duration equal to the + duration of a bar in the given time signature for the given + implementation. FIXME: this isn't guaranteed to be + meaningful (double time signatures break this")) +(defgeneric current-bar (moment composition) + (:documentation "Returns an <anchored-period> representing the + bar which contains moment")) + +(defgeneric beat-period (moment time-signature implementation-object) + (:documentation "Takes a moment, time signature object and crotchet and returns + an <anchored-period> for the containing beat containing moment. This + is more useful when there's a complex time signature (not currently + possible) in which tactus is different in different parts of the + bar (e.g. 3+3+2/8)")) +(defgeneric current-beat (moment composition) + (:documentation "Returns an <anchored-period> representing the + tactus unit which contains moment")) + + +;;;;;;;;;;;;;; +;; +;; + +(defgeneric get-applicable-clefs (anchored-period constituent))
--- a/base/methods.lisp Thu Mar 13 11:22:29 2008 +0000 +++ b/base/methods.lisp Thu Mar 13 11:23:52 2008 +0000 @@ -508,4 +508,56 @@ &key initial-element (initial-contents nil icp)) (declare (ignore length o initial-element initial-contents icp)) - (%recompute-standard-composition-period (call-next-method))) \ No newline at end of file + (%recompute-standard-composition-period (call-next-method))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Experimental: +;; + +;; Some not obviously correct implementations of the new metre +;; functions. These are no worse than we're already using (they should +;; be more or less equivalent) + +(defmethod bar-period ((time-signature standard-time-signature) + object) + (make-standard-period (* (duration (crotchet object)) + (time-signature-numerator time-signature) + (/ 4 (time-signature-denominator time-signature))))) + +(defmethod current-bar ((moment standard-moment) (composition composition)) + (let* ((time-sig (car (get-applicable-time-signatures + (make-standard-anchored-period (timepoint moment) + (duration (crotchet composition))) + composition))) + (bar-duration (bar-period time-sig composition))) + (do* ((start (onset time-sig) next-start) + (next-start (time+ start bar-duration) (time+ start bar-duration))) + ((time> next-start moment) + (make-standard-anchored-period (timepoint start) + (duration bar-duration)))))) + +(defmethod beat-period ((moment standard-moment) + (time-signature standard-time-signature) + (composition composition)) + ;; Simple example - standard-time-signature has constant tactus + (let* ((containing-bar (current-bar moment composition)) + (beat-duration (* (duration (crotchet composition)) + (tactus-duration time-signature))) + (beat-period (make-standard-anchored-period (timepoint containing-bar) + beat-duration))) + (do () + ((time> (cut-off beat-period) moment) beat-period) + (setf (timepoint beat-period) (timepoint (cut-off beat-period)))))) + +(defmethod current-beat ((moment standard-moment) (composition composition)) + ;; Assume at most one time signature per bar (otherwise, this is hell) + (let* ((time-sig (car (get-applicable-time-signatures (current-bar moment composition) composition)))) + (if time-sig + (beat-period moment time-sig composition) + ;; If no time-sig, there's no way of answering this + ;; directly. There may be sensible defaults, but it's the job + ;; of an implementation's author to solve that. + (error 'insufficient-information :operation 'beat-period :datatype (class-of composition))))) +