# HG changeset patch # User m.pearce # Date 1166199377 0 # Node ID 8d2b1662f65852fcaca074cbcaae946d21dc9b7a # Parent e2e19baba730120873da8fccbc626a1ad540f852 base/*.lisp: move files in amuse-base to subdirectory. darcs-hash:20061215161617-aa3d6-1b63bd555b02ec02aa2db12d335e8b726e2108cd.gz diff -r e2e19baba730 -r 8d2b1662f658 base/classes.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/classes.lisp Fri Dec 15 16:16:17 2006 +0000 @@ -0,0 +1,78 @@ +(cl:in-package #:amuse) + +;; collections of more than one event + +(defclass constituent () ()) +(defclass composition (constituent) ()) +(defclass monody (constituent) ()) + +;; types of information-specifiers + +(defclass moment-designator () ()) +(defclass period-designator () ()) +(defclass anchored-period-designator (moment-designator period-designator) ()) +(defclass pitch-designator () ()) +(defclass pitch-interval-designator () ()) + +;; time-related classes + +(defclass moment (moment-designator) + ((time :accessor %moment-time :initarg :time))) + +(defclass period (period-designator) + ((interval :accessor %period-interval :initarg :interval))) + +(defclass floating-period (period) ()) +(defclass anchored-period (period moment anchored-period-designator) ()) + +;; pitch-related classes + +(defclass frequency () ()) + +(defclass pitch (pitch-designator) ()) +(defclass chromatic-pitch (pitch) + ((number :accessor %chromatic-pitch-number :initarg :number))) +(defclass diatonic-pitch (pitch) + ((name :accessor %diatonic-pitch-name :initarg :name) + (accidental :accessor %diatonic-pitch-accidental :initarg :accidental) + (octave :accessor %diatonic-pitch-octave :initarg :octave))) + +(defclass pitch-interval (pitch-interval-designator) + ((span :accessor %pitch-interval-span :initarg :span))) + +;; events + +(defclass event (anchored-period) ()) +(defclass pitched-event (event pitch-designator) ()) +(defclass chromatic-pitched-event (pitched-event chromatic-pitch) ()) +(defclass percussive-event (event) ()) + +;;; Range-based `constituents' +;; Whilst these are all constituents in the CHARM sense, their +;; properties apply to a timed range rather than to a set of +;; events. As such, they can be regarded as anchored-periods with +;; properties. + +(defclass time-signature (anchored-period) ()) + +(defclass basic-time-signature (anchored-period) + ;; N.B. Can only deal with numeric signatures + ((numerator :accessor %basic-time-signature-numerator + :initarg :numerator) + (denominator :accessor %basic-time-signature-denominator + :initarg :denominator))) + +(defclass key-signature (anchored-period) ()) + +(defclass basic-key-signature (key-signature) + ;; Only has line-of-fifths distance from c, so custom signatures + ;; won't work + ((sharp-count :accessor %basic-key-signature-sharp-count + :initarg sharp-count))) + +(defclass tempo (anchored-period) + ;; accel and rit in symbolic encoding will need other structures, as + ;; will textual tempo markings. + ((bpm :accessor %tempo-bpm + :initarg :bpm))) + \ No newline at end of file diff -r e2e19baba730 -r 8d2b1662f658 base/conditions.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/conditions.lisp Fri Dec 15 16:16:17 2006 +0000 @@ -0,0 +1,34 @@ +(cl:in-package #:amuse) + +;; Some conditions we might want to be able to signal + +(define-condition undefined-action (condition) + ;; This condition would apply to an attempt to perform a meaningless + ;; operation on an object. This may, initially, include things that + ;; are a pain to implement but should really be used when it's + ;; genuinely unclear what an operation means in the given + ;; context. In such cases, a condition handler might be the best + ;; approach anyway. + ((operation :initarg :operation + :reader undefined-action-operation) + (datatype :initarg :datatype + :reader undefined-action-datatype)) + (:report (lambda (condition stream) + (format stream "The consequence of performing ~A on and object of type ~A is undefined" + (undefined-action-operation condition) + (undefined-action-datatype condition))))) + +(define-condition insufficient-information (condition) + ;; It should be possible to construct genuinely minimal musical + ;; structures. When the information in these is insufficient to + ;; answer a query, this condition should be raised. + ((operation :initarg :operation + :reader insufficient-information-operation) + (datatype :initarg :datatype + :reader insufficient-information-datatype)) + (:report (lambda (condition stream) + (format stream "The ~A object does not contain enough information to perform ~A" + (insufficient-information-datatype condition) + (insufficient-information-operation condition))))) + + diff -r e2e19baba730 -r 8d2b1662f658 base/constructors.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/constructors.lisp Fri Dec 15 16:16:17 2006 +0000 @@ -0,0 +1,58 @@ +(cl:in-package #:amuse) + +;; Time classes + +(defun make-moment (time) + (make-instance 'moment :time time)) + +;; N.B. period should never be constructed directly - it's either +;; floating or anchored or some other subclass. + +(defun make-floating-period (interval) + (make-instance 'floating-period :interval interval)) + +(defun make-anchored-period (onset interval) + (make-instance 'anchored-period + :time onset + :interval interval)) + +;; Pitch classes (no, not that sort of pitch class) + +(defun make-chromatic-pitch (pitch-number) + (make-instance 'chromatic-pitch :number pitch-number)) + +(defun make-diatonic-pitch (name accidental octave) + (make-instance 'diatonic-pitch + :name name + :accidental accidental + :octave octave)) + +(defun make-pitch-interval (span) + (make-instance 'pitch-interval :span span)) + +;; Events + +(defun make-chromatic-pitched-event (pitch-number onset duration) + (make-instance 'chromatic-pitched-event + :number pitch-number + :time onset + :interval duration)) + +(defun make-basic-time-signature (numerator denominator onset duration) + (make-instance 'basic-time-signature + :numerator numerator + :denominator denominator + :time onset + :interval duration)) + +(defun make-basic-key-signature (sharp-count onset duration) + (make-instance 'basic-key-signature + :sharp-count sharp-count + :time onset + :interval duration)) + +(defun make-tempo (bpm onset duration) + (make-instance 'tempo + :bpm bpm + :time onset + :interval duration)) diff -r e2e19baba730 -r 8d2b1662f658 base/generics.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/generics.lisp Fri Dec 15 16:16:17 2006 +0000 @@ -0,0 +1,205 @@ +(cl:in-package #:amuse) + +;;; Pulling compositions from the database + +(defgeneric get-composition (identifier)) + +;;; Simple Accessors + +;; pitch-based + +(defgeneric pitch (object &key kind)) ; ? Maybe this returns the pitch + ; in its ur form? +(defgeneric chromatic-pitch (pitch-designator)) ; How simple are these +(defgeneric diatonic-pitch (pitch-designator)) ; if has to be computed? +(defgeneric frequency (object)) ;? +(defgeneric midi-pitch-number (pitch-designator)) +(defgeneric meredith-chromatic-pitch-number (pitch-designator) + ;; David Meredith's PhD and ps13 code + (:method (p) (- (midi-pitch-number p) 21))) +(defgeneric pitch-class (pitch-designator) + (:method (p) (mod (midi-pitch-number p) 12))) +(defgeneric span (pitch-interval-designator)) + +;; time + +(defgeneric duration (period-designator)) +(defgeneric (setf duration) (value period-designator)) +(defgeneric timepoint (moment-designator)) +(defgeneric (setf timepoint) (value moment-designator)) +(defgeneric cut-off (anchored-period-designator) ; name? + (:method (apd) (time+ (moment apd) (floating-period apd)))) + +;; 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 +;; it's meaning is clear. beat-units-per-bar is clearer, though, I +;; think. + +(defgeneric beat-units-per-bar (time-signature)) +(defgeneric time-signature-numerator (time-signature) + (:method (ts) (beat-units-per-bar ts))) +(defgeneric beat-units (time-signature)) +(defgeneric time-signature-denominator (time-signature) + (:method (ts) (beat-units ts))) + +(defgeneric key-signature-sharps (key-signature)) + +(defgeneric bpm (tempo)) ;; in bpm +(defgeneric microseconds-per-crotchet (tempo) + ;; As used (when rounded) in MIDI + (:method (tp) (/ 60000000 (bpm tp)))) + +;;; 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-designator) + (:method (apd) (make-anchored-period (onset apd) (duration apd)))) + +(defgeneric floating-period (period-designator) + (:method (pd) (make-floating-period (duration pd)))) + +(defgeneric moment (moment-designator) + (:method (md) (make-moment (timepoint md)))) + +(defgeneric onset (anchored-period-designator) + (:method (apd) (moment apd))) +(defgeneric (setf onset) (value anchored-period-designator)) + +;;; Time Protocol (or moments?) + +;; negative times/durations -> ERROR? + +;; time+: