Mercurial > hg > amuse
diff implementations/midi-db/db-select-functions.lisp @ 236:a5d065905f6d
Add midi-db.
Ignore-this: c6f4fc32efa4453ddbdc478793eedd52
A basic implementation for working with MIDI files stored in the database.
It is a test case for `versioned' data, but only partially implemented at the moment.
darcs-hash:20100223152703-16a00-4388d2720907d777a1c6c6b3a010885ce0fe06a7.gz
committer: Jamie Forth <j.forth@gold.ac.uk>
author | j.forth <j.forth@gold.ac.uk> |
---|---|
date | Thu, 24 Feb 2011 11:23:18 +0000 |
parents | |
children | 2138ea478adb |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/implementations/midi-db/db-select-functions.lisp Thu Feb 24 11:23:18 2011 +0000 @@ -0,0 +1,220 @@ +(cl:in-package #:amuse-midi-db) + +(defmethod get-composition ((identifier midi-db-composition-identifier)) + (let ((database *amuse-database*)) ; Shaddow this to use a different + ; database (for debugging). + (destructuring-bind (collection-id filename timebase start + duration owner version + creation-timestamp + deletion-timestamp) + (%get-midi-db-composition-header identifier database) + (let* ((collection-identifier (make-midi-db-collection-identifier + collection-id)) + (events (%get-midi-db-events identifier + collection-identifier + version timebase database)) + (tempi (%get-midi-db-tempi identifier + collection-identifier version + timebase database)) + (timesigs (%get-midi-db-timesigs identifier + collection-identifier + version timebase database)) + (keysigs (%get-midi-db-keysigs identifier + collection-identifier + version timebase database))) + (make-midi-db-composition events + (/ start timebase) + (/ duration timebase) + tempi + timesigs + keysigs + identifier + collection-identifier + timebase + filename + owner + version + creation-timestamp + deletion-timestamp))))) + + +(defun %get-all-collection-headers () + #.(clsql:locally-enable-sql-reader-syntax) + (let ((collection-rows (clsql:select [collection-id] + [collection-name] [description] + :from "midi_db_collections" + :flatp t + :database *amuse-database*))) + #.(clsql:locally-disable-sql-reader-syntax) collection-rows)) + +(defun %get-midi-db-composition-header (identifier database) + "Basic low-level retrieval of constituents. Just takes an identifier +and returns a header without any checking of version or deletion +fields." + #.(clsql:locally-enable-sql-reader-syntax) + (let ((header-row (car (clsql:select + [collection-id] + [filename] + [timebase] + [start] + [duration] + [owner] + [version] + [creation-timestamp] + [deletion-timestamp] + :from "midi_db_compositions" + :where [= [composition-id] + (composition-id identifier)] + :flatp t + :database database)))) + #.(clsql:locally-disable-sql-reader-syntax) + header-row)) + +(defun %get-all-collection-composition-headers (collection-identifier) + #.(clsql:locally-enable-sql-reader-syntax) + (let ((header-rows (clsql:select + [collection-id] + [filename] + [timebase] + [start] + [duration] + [owner] + [version] + [creation-timestamp] + [deletion-timestamp] + :from "midi_db_compositions" + :where [= [collection-id] (collection-id + collection-identifier)] + :flatp t + :database *amuse-database*))) + #.(clsql:locally-disable-sql-reader-syntax) + header-rows)) + +(defun %get-all-composition-headers () + #.(clsql:locally-enable-sql-reader-syntax) + (let ((header-rows (clsql:select + [collection-id] + [filename] + [timebase] + [start] + [duration] + [owner] + [version] + [creation-timestamp] + [deletion-timestamp] + :from "midi_db_compositions" + :flatp t + :database *amuse-database*))) + #.(clsql:locally-disable-sql-reader-syntax) + header-rows)) + +(defun %get-midi-db-events (identifier collection-identifier version + timebase database) + (let ((event-rows (clsql:query (concatenate 'string " +SELECT event_id, track, channel, patch, pitch, velocity, start, duration, +version +FROM midi_db_events +WHERE collection_id = " (princ-to-string (collection-id collection-identifier)) " +AND composition_id= " (princ-to-string (composition-id identifier)) " +AND version = " (princ-to-string version)) + :flatp t + :database database))) + (%init-events identifier collection-identifier event-rows timebase))) + +(defun %init-events (identifier collection-identifier event-rows timebase) + (loop for event-row in event-rows + collecting (init-midi-db-event identifier collection-identifier event-row timebase) + into events + finally (return events))) + +(defun init-midi-db-event (identifier collection-identifier event-row timebase) + (destructuring-bind (event-id track channel patch pitch velocity + start duration version) + event-row + (if (= channel 10) + (make-midi-db-percussive-event (collection-id collection-identifier) + (composition-id identifier) + event-id track channel patch + pitch velocity + (/ start timebase) + (/ duration timebase) version) + (make-midi-db-pitched-event (collection-id collection-identifier) + (composition-id identifier) + event-id track channel patch pitch + velocity (/ start timebase) + (/ duration timebase) version)))) + +(defun %get-midi-db-tempi (identifier collection-identifier version + timebase database) + (declare (ignore version)) + (let ((tempo-rows (clsql:query (concatenate 'string " +SELECT start, duration, microsecs_per_crotchet, version +FROM midi_db_tempi +WHERE collection_id = " (princ-to-string (collection-id collection-identifier)) " +AND composition_id = " (princ-to-string (composition-id identifier))) +;AND version = " (princ-to-string version)) + :flatp t + :database database))) + (%init-midi-db-tempi tempo-rows timebase))) + +(defun %init-midi-db-tempi (tempo-rows timebase) + (loop for tempo-row in tempo-rows + collecting (init-midi-db-tempo tempo-row timebase) + into tempi + finally (return tempi))) + +(defun init-midi-db-tempo (tempo-row timebase) + (destructuring-bind (start duration microsecs-per-crotchet version) + tempo-row + (make-midi-db-tempo (/ start timebase) (/ duration timebase) + microsecs-per-crotchet version))) + +(defun %get-midi-db-timesigs (identifier collection-identifier version + timebase database) + (declare (ignore version)) + (let ((timesig-rows (clsql:query (concatenate 'string " +SELECT start, duration, numerator, denominator, version +FROM midi_db_timesigs +WHERE collection_id = " (princ-to-string (collection-id collection-identifier)) " +AND composition_id = " (princ-to-string (composition-id identifier))) +;AND version = " (princ-to-string version)) + :flatp t + :database database))) + (%init-midi-db-timesigs timesig-rows timebase))) + +(defun %init-midi-db-timesigs (timesig-rows timebase) + (loop for timesig-row in timesig-rows + collecting (init-midi-db-timesig timesig-row timebase) + into timesigs + finally (return timesigs))) + +(defun init-midi-db-timesig (timesig-row timebase) + (destructuring-bind (start duration numerator denominator version) + timesig-row + (make-midi-db-timesig (/ start timebase) (/ duration timebase) + numerator denominator version))) + +(defun %get-midi-db-keysigs (identifier collection-identifier version + timebase database) + (declare (ignore version)) + (let ((keysig-rows (clsql:query (concatenate 'string " +SELECT start, duration, mode, sharp_count, version +FROM midi_db_keysigs +WHERE collection_id = " (princ-to-string (collection-id collection-identifier)) " +AND composition_id = " (princ-to-string (composition-id identifier))) +;AND version = " (princ-to-string version)) + :flatp t + :database database))) + (%init-midi-db-keysigs keysig-rows timebase))) + +(defun %init-midi-db-keysigs (keysig-rows timebase) + (loop for keysig-row in keysig-rows + collecting (init-midi-db-keysig keysig-row timebase) + into keysigs + finally (return keysigs))) + +(defun init-midi-db-keysig (keysig-row timebase) + (destructuring-bind (start duration mode sharp-count version) + keysig-row + (make-midi-db-keysig (/ start timebase) (/ duration timebase) + mode sharp-count version)))