Mercurial > hg > amuse
view base/generics.lisp @ 330:2fbff655ba47 tip
Removed cpitch-adj and cents SQL columns
author | Jeremy Gow <jeremy.gow@gmail.com> |
---|---|
date | Mon, 21 Jan 2013 11:08:11 +0000 |
parents | 6c57b16a7829 |
children |
line wrap: on
line source
(cl:in-package #:amuse) ;;; Identifiers (defgeneric identifier (object)) (defgeneric event-id (object)) (defgeneric composition-id (object)) ;;; Pulling compositions from the database (defgeneric get-composition (identifier) (:documentation "Returns a composition of type dependant on identifier")) (defgeneric get-constituents (constituent-identifier) (:documentation "Returns a list of constituents matching the criteria in identifier")) (defgeneric monody (object) (:documentation "Returns a monody.")) (defgeneric ensure-monody (object) (:documentation "Returns a generalised boolean.")) ;;; Getting constituents from compositions ;; IS this the mechanism we want to use (defgeneric time-signatures (composition) (:documentation "Returns all time-signatures in a composition Probably shouldn't be exported - can be replaced by (get-applicable-time-signature commposition composition)")) (defgeneric (setf time-signatures) (sequence composition) (:documentation "Sets all time-signatures in a composition. Is this wanted here?")) (defgeneric tempi (composition) (:documentation "Returns all tempi in a composition Probably shouldn't be exported - can be replaced by (get-applicable-tempi commposition composition)")) (defgeneric (setf tempi) (sequence composition) (:documentation "Sets all tempi in a composition. Is this wanted here?")) (defgeneric key-signatures (composition) (:documentation "Returns all key-signatures in a composition Probably shouldn't be exported - can be replaced by (get-applicable-key-signature commposition composition)")) (defgeneric (setf key-signatures) (sequence composition) (:documentation "Sets all key sigs in a composition. Is this wanted here?")) ;;; Simple Accessors ;; pitch-based (defgeneric pitch (object &key kind)) ; ? Maybe this returns the pitch ; in its ur form? (defgeneric chromatic-pitch (pitch)) (defgeneric diatonic-pitch (pitch)) (defgeneric frequency (object)) ;? (defgeneric octave (pitch) (:documentation "Return an integer representing the octave of pitch where middle c is defined to be the lowest pitch in octave 4.")) (defgeneric diatonic-pitch-octave (pitch) (:documentation "Return an integer representing the diatonic octave of pitch.")) (defgeneric diatonic-pitch-accidental (pitch) (:documentation "Return an integer representing the inflection of a diatonic pitch where where negative values indicate numbers of flats, 0 indicates natural and positive values indicate numbers of sharps.")) (defgeneric diatonic-pitch-mp (pitch) (:documentation "Return an integer representing the morphetic pitch \(in MIPS terms) of a diatonic pitch.")) (defgeneric diatonic-pitch-cp (pitch) (:documentation "Return an integer representing the chromatic pitch \(in MIPS terms) of a diatonic pitch.")) (defgeneric middle-c (pitch) (:documentation "Returns the value of middle C in the particular representation of pitch used by PITCH.")) (defgeneric midi-pitch-number (pitch) (:documentation "Takes a pitch (usually a pitched event) and returns an integer between 0 and 127 representing the chromatic pitch represented (60=middle C, 48 the C below that, etc.)")) (defgeneric asa-pitch-string (pitch) (:documentation "Returns a string representing the designated ASA pitch name which has three parts: a letter name in the set {A,B,C,D,E,F,G}, an inflection in the set {n,f,s,ff,ss,fff,sss,...} and an octave number. E.g., Cn4 = Middle C.")) (defgeneric asa-interval-string (pitch) (:documentation "Returns a string representing the designated ASA interval name which has two or three parts: a direction in the set {r,f} (absent for unisons/primes), a type in the set {p,ma,mi,a,d,aa,dd,aaa,ddd,...}, and a size number. E.g. rma2 = rising major second.")) (defgeneric diatonic-pitch-name (pitch) (:documentation "Returns a char in the set {#\A,#\B,#\C,#\D,#\E,#\F,#\G}, representing the pitch name of PITCH.")) (defgeneric pitch-class (pitch) (:documentation "Takes a pitch (usually a pitched event) and returns an integer between 0 and 12 representing the octave-independant pitch, with c=0, c#=1, etc.") (:method (p) (mod (midi-pitch-number p) 12))) (defgeneric span (pitch-interval)) ;; time (defgeneric duration (period) (:documentation "Returns a real. Probably should only apply do standard-periods (rather than periods? or should it return something other than a value in other cases)")) (defgeneric (setf duration) (value period) (:documentation "As with duration, perhaps this should work only with standard-periods")) (defgeneric timepoint (moment) (:documentation "Returns a number for a moment. Does this make any sense on an abstrace class? Should it just apply to standard-moment?")) (defgeneric (setf timepoint) (value moment) (:documentation "Sets timepoint. What does this mean for an abstract class? Should it just apply to standard-moment")) (defgeneric cut-off (anchored-period) ; name? (:documentation "Returns a <moment> representing the point at which the anchored period has ended. By default, is calculated as the result of running time+ on the onset and period of the object.") (:method (apd) (time+ (moment apd) (period apd)))) (defgeneric crotchet (object) (:documentation "Returns a period, the duration of which represents a crotchet in the time representation used by object.")) ;; others ;; I've given the time-sig accessors general names because it allows ;; for symbols in time-signatures as well as numbers - numerator is an ;; odd accessor if the time sig is C (even in common practice) but ;; its meaning is clear. beat-units-per-bar is clearer, though, I ;; think. (defgeneric beat-units-per-bar (time-signature) (:documentation "In a standard, fraction-like time-signature or a symbolic equivalent, this is the numerator.")) (defgeneric time-signature-numerator (time-signature) (:method (ts) (beat-units-per-bar ts)) (:documentation "Not obviously meaningful for non fraction-like time signatures")) (defgeneric beat-units (time-signature) (:documentation "In a standard, fraction-like time-signature or a symbolic equivalent, this is the denominator (n.b. the difference between this and @code{tactus-duration} is only visible for compound time, where this returns the lower portion of the time signature, but @code{tactus-duration} returns the higher-level unit).")) (defgeneric time-signature-denominator (time-signature) (:method (ts) (beat-units ts)) (:documentation "Not obviously meaningful for non fraction-like time signatures")) (defgeneric tactus-duration (time-signature) ;; basic, but should do? NO! This defines 6/4 as compound. We need ;; proper simplep and compoundp predicates. (:method (ts) (warn "FIXME: tactus-duration is broken") (cond ;; ((and (not (= (beat-units-per-bar ts) 3)) ;; (= (rem (beat-units-per-bar ts) 3) 0)) ((and (= (beat-units ts) 8) (= (rem (beat-units-per-bar ts) 3) 0)) ;; compound time (* (/ 4 (beat-units ts)) 3)) (t (/ 4 (beat-units ts))))) (:documentation "Returns a number of crotchets to represent the tactus, based on some idea of time signature patterns. Should, in future, return a duration rather than a number.")) (defgeneric key-signature-sharps (key-signature) (:documentation "Simple query for normal key-signatures.")) (defgeneric key-signature-mode (ks) (:documentation "Query that only makes sense for midi-like key signatures")) (defgeneric bpm (tempo) (:documentation "Basic tempo query")) ;; in bpm (defgeneric microseconds-per-crotchet (tempo) ;; As used (when rounded) in MIDI (:method (tp) (/ 60000000 (bpm tp))) (:documentation "Basic tempo query for MIDI. N.B. This will be a fraction and must be rounded before being used for output.")) ;;; Coerce-type accessors ;; Should I be including these default methods? Should the accessors ;; be direct slot accessors or the generics I'm using? Should we ;; return the object itself if it already is in the target class? (defgeneric anchored-period (anchored-period) (:method (apd) (make-anchored-period (onset apd) (duration apd))) (:documentation "Coerce any anchored period to a plain anchored period")) (defgeneric period (period) (:method (pd) (make-period (duration pd))) (:documentation "Coerce any period to a floating period")) (defgeneric moment (moment) (:method (md) (make-moment (timepoint md))) (:documentation "Coerce any moment, including an anchored-period to a moment")) (defgeneric onset (anchored-period) (:method (ap) (moment ap)) (:documentation "Return a moment for the start of an anchored period")) (defgeneric (setf onset) (value anchored-period)) ;;; Time Protocol (or moments?) ;; negative times/durations -> ERROR? ;; time+: <time> <duration> -> <time> ;; <duration> <time> -> <time> (same as previous?) ;; <duration> <duration> -> <duration> (or a distinct duration+?) ;; <time> <time> -> ERROR? ;; ;; time-: <time> <time> -> <duration> ;; <time> <duration> -> <time> ;; <duration> <duration> -> <duration> (or a distinct duration-?) ;; <duration> <time> -> ERROR? ;; <anchored> <anchored> -> (time- (moment o1) (moment o2)) ? or error? (defgeneric time+ (object1 object2) (:documentation "Addition for time objects")) (defgeneric time- (object1 object2) (:documentation "Subtraction for time objects")) (defgeneric time> (object1 object2) (:documentation "> operator for moments")) (defgeneric time< (object1 object2) (:documentation "< operator for moments") (:method (o1 o2) (time> o2 o1))) (defgeneric time= (object1 object2) (:documentation "= operator for moments")) (defgeneric time>= (object1 object2) (:documentation ">= operator for moments") (:method (o1 o2) (or (time> o1 o2) (time= o1 o2)))) (defgeneric time<= (object1 object2) (:documentation "<= operator for moments") (:method (o1 o2) (or (time< o1 o2) (time= o1 o2)))) (defgeneric time/= (object1 object2) (:documentation "not = operator for moments") (:method (o1 o2) (not (time= o1 o2)))) ;;; Duration protocol (defgeneric duration> (object1 object2) (:documentation "> operator for periods")) (defgeneric duration< (object1 object2) (:documentation "< operator for periods") (:method (o1 o2) (duration> o2 o1))) (defgeneric duration= (object1 object2) (:documentation "= operator for periods")) (defgeneric duration>= (object1 object2) (:documentation ">= operator for periods") (:method (o1 o2) (or (duration> o1 o2) (duration= o1 o2)))) (defgeneric duration<= (object1 object2) (:documentation "<= operator for periods") (:method (o1 o2) (or (duration< o1 o2) (duration= o1 o2)))) (defgeneric duration/= (object1 object2) (:documentation "not = operator for periods") (:method (o1 o2) (not (duration= o1 o2)))) ;; for linear scaling: (defgeneric duration* (object1 object2) (:documentation "Multiplication operator for periods. Intuitively, this makes sense, but it may cause us trouble with some implementations in the future.")) (defgeneric duration/ (object1 number) (:documentation "Division operator for periods. This may turn out not to mean much. Division is probably useful, but we may need to define what we mean with care.")) ;;; Pitch protocol ;; pitch+: <pitch> <pitch> -> ERROR ;; <pitch> <interval> -> <pitch> ;; <interval> <pitch> -> <pitch> (same as previous?) ;; <interval> <interval> -> <interval> (or a distinct interval+?) ;; ;; pitch-: <pitch> <pitch> -> <interval> ;; <pitch> <interval> -> <pitch> ;; <interval> <interval> -> <interval> ;; <interval> <pitch> -> ERROR (defgeneric pitch+ (object1 object2)) (defgeneric pitch- (object1 object2)) (defgeneric pitch> (object1 object2)) (defgeneric pitch< (object1 object2) (:method (o1 o2) (pitch> o2 o1))) (defgeneric pitch= (object1 object2)) (defgeneric pitch>= (object1 object2) (:method (o1 o2) (or (pitch> o1 o2) (pitch= o1 o2)))) (defgeneric pitch<= (object1 object2) (:method (o1 o2) (or (pitch< o1 o2) (pitch= o1 o2)))) (defgeneric pitch/= (object1 object2) (:method (o1 o2) (not (pitch= o1 o2)))) ;;; Interval protocol (emphasise _pitch_ not _time_ interval?) (defgeneric interval> (object1 object2)) (defgeneric interval< (object1 object2) (:method (o1 o2) (interval> o2 o1))) (defgeneric interval= (object1 object2)) (defgeneric interval>= (object1 object2) (:method (o1 o2) (or (interval> o1 o2) (interval= o1 o2)))) (defgeneric interval<= (object1 object2) (:method (o1 o2) (or (interval< o1 o2) (interval= o1 o2)))) (defgeneric interval/= (object1 object2) (:method (o1 o2) (not (interval= o1 o2)))) ;;; Allen's (1984) interval relations ;;; . equals already defined as INTERVAL= above ;;; . inverses ommitted for now (just use CL:NOT) ;;; . can all be defined in terms of MEETS (apparently) (defgeneric meets (object1 object2)) (defgeneric before (object1 object2)) (defgeneric overlaps (object1 object2)) (defgeneric during (object1 object2)) (defgeneric starts (object1 object2)) (defgeneric ends (object1 object2)) ;;; and extensions thereof ... (defgeneric subinterval (object1 object2) (:method (o1 o2) (or (starts o1 o2) (during o1 o2) (ends o1 o2)))) (defgeneric disjoint (object1 object2) (:method (o1 o2) (or (before o1 o2) (meets o1 o2) (meets o2 o1) (before o2 o1)))) ;;; More time-based functions (defgeneric period= (object1 object2) (:method (x y) nil)) (defgeneric find-overlapping (anchored-period sequence) ;; Returns all members of a sequence of period signifiers that overlap ;; with the supplied period (:method (ap s) (remove-if #'(lambda (x) (amuse:disjoint ap x)) s))) ;; Return the anchored-period representing the intersection of two ;; anchored-period. (defgeneric period-intersection (anchored-period1 anchored-period2)) (defgeneric inter-onset-interval (moment1 moment2) (:method (moment1 moment2) (time- (moment moment2) (moment moment1)))) ;;; Time Signature (defgeneric get-applicable-time-signatures (anchored-period composition) (:method (ap c) (find-overlapping ap (time-signatures c))) (:documentation "Return a list of TIME-SIGNATURE-PERIODs that are relevant to <anchored-period>. The period may contain information such as staff position and voicing, and the method may use this to filter its response")) (defgeneric time-signature-equal (ts1 ts2) (:documentation "Comparison operator. The definition of equality is left open for implementers")) ;;; Tempo (defgeneric get-applicable-tempi (anchored-period composition) (:method (ap c) (find-overlapping ap (tempi c))) (:documentation "Return a list of TEMPO-PERIODs that are relevant to <anchored-period>. The period may contain information such as staff position and voicing, and the method may use this to filter its response")) (defgeneric tempo-equal (t1 t2) (:documentation "Comparison operator. The definition of equality is left open for implementers")) ;;; Tonality (Key Signature / Mode) (defgeneric get-applicable-key-signatures (object1 object2) (:documentation "Return a list of KEY-SIGNATURE-PERIODs that are relevant to <anchored-period>. The period may contain information such as staff position and voicing, and the method may use this to filter its response")) (defgeneric key-signature-equal (ks1 ks2) (:documentation "Comparison operator. The definition of equality is left open to implementers")) ;;; Some generic constructors - are these useful? (DL 31/8/07) (defgeneric make-moment (value) (:documentation "Returns MOMENT of subclass appropriate to the class of value. Probably guessed.")) (defgeneric make-period (value) (:documentation "Returns PERIOD of subclass appropriate to the class of value. Probably guessed.")) (defgeneric make-anchored-period (start-value duration-value) (:documentation "Returns ANCHORED-PERIOD of subclass appropriate to the class of value. Probably guessed.")) (defgeneric trim-enclosing-silence (composition) (:documentation "Returns a composition of the same type as composition provided, with leading and following silences/rests removed, but preserving all relevant information. Where relevant, any silence in a bar containing musical material may be preserved.")) ;;; 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 ioi-from-bar (moment) (:documentation "Returns the IOI of moment (i.e. an event) from the bar line.")) (defgeneric onset-in-bar (moment) (:documentation "The position of moment in the bar, measured in beats.")) ;;;;;;;;;;;;;; ;; ;; (defgeneric get-applicable-clefs (anchored-period constituent)) ;;;===================================================================== ;;; Copying events in time ;;;===================================================================== (defgeneric move-to-first-bar (composition)) (defgeneric copy-event (event)) (defgeneric voice (event)) ;;;===================================================================== ;;; Searching for events ;;;===================================================================== (defgeneric find-next-event (source-event &key predicate test break-test search-list)) ;;;===================================================================== ;;; Sorting Compositions ;;;===================================================================== (defgeneric event< (event1 event2 attribute-list)) (defgeneric sort-composition (composition attribute-list))