comparison implementations/midi-db/db-insert-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
comparison
equal deleted inserted replaced
235:ea45a3d0730c 236:a5d065905f6d
1 (cl:in-package #:amuse-midi-db)
2
3 (defun register-new-collection (collection-name description database)
4 (clsql:with-transaction (:database database)
5 "Error checking needed for duplicates."
6 #.(clsql:locally-enable-sql-reader-syntax)
7 (clsql:insert-records
8 :into "midi_db_collections"
9 :attributes '([collection-name]
10 [description])
11 :values (list collection-name description)
12 :database database)
13 #.(clsql:locally-disable-sql-reader-syntax)
14 (make-midi-db-collection-identifier ;return new collection identifier
15 (clsql-mysql::mysql-insert-id
16 (clsql-mysql::database-mysql-ptr
17 database)))))
18
19 (defvar *import-file* (pathname "/tmp/midi-db.txt"))
20
21 (defun import-composition (composition collection-identifier database)
22 #.(clsql:locally-enable-sql-reader-syntax)
23 (let* ((collection-id (collection-id collection-identifier))
24 (filename (file-namestring (midifile-identifier-pathname
25 (identifier composition))))
26 (timebase (midi-timebase composition))
27 (start (* (timepoint composition) timebase))
28 (duration (* (duration composition) timebase))
29 (composition-id))
30 ;; add composition header
31 (clsql:with-transaction (:database database)
32 (clsql:insert-records :into "midi_db_compositions"
33 :attributes '([collection-id] [filename]
34 [timebase] [start] [duration])
35 :values (list collection-id
36 filename
37 timebase
38 start
39 duration)
40 :database database)
41 (setf composition-id (clsql-mysql::mysql-insert-id
42 (clsql-mysql::database-mysql-ptr
43 database)))
44 #.(clsql:locally-disable-sql-reader-syntax)
45 ;; add tempo, timesig and keysig constituents
46 (%add-tempo-constituents collection-id composition-id
47 (tempi composition) timebase database)
48 (%add-timesig-constituents collection-id composition-id
49 (time-signatures composition)
50 timebase database)
51 (%add-keysig-constituents collection-id composition-id
52 (key-signatures composition) timebase
53 database)
54 (write-to-db-file collection-id composition-id composition)
55 (clsql:execute-command
56 (concatenate 'string
57 "LOAD DATA LOCAL INFILE '"
58 (namestring *import-file*)
59 "' INTO TABLE "
60 "midi_db_events")
61 :database database)
62 (delete-file *import-file*)
63 (format t "Composition added to db, id: ~A~%" composition-id))))
64
65
66 ;;;=====================================================================
67 ;;; All the below are just helper functions.
68 ;;;=====================================================================
69
70 (defun write-to-db-file (collection-id composition-id composition)
71 (let ((timebase (midi-timebase composition)))
72 (with-open-file (stream *import-file*
73 :direction :output
74 :if-exists :supersede
75 :external-format :latin1)
76 (sequence:dosequence (event composition)
77 (format stream
78 "~S ~S \\N ~{~S ~}1~%" ; 1 is the
79 ; version number
80 collection-id composition-id
81 (if (amuse-utils:pitchedp event)
82 (list (midi-track event)
83 (midi-channel event)
84 (midi-patch event)
85 (midi-pitch-number event)
86 (midi-velocity event)
87 (* (timepoint event) timebase)
88 (* (duration event) timebase))
89 (list (midi-track event)
90 (midi-channel event)
91 0 ;FIXME no patch for perc?
92 (midi-drum-sound event)
93 (midi-velocity event)
94 (* (timepoint event) timebase)
95 (* (duration event) timebase)))))))
96 t)
97
98 ;;; FIXME: use macros here.
99
100 (defun %add-tempo-constituents (collection-id composition-id tempi timebase
101 database)
102 #.(clsql:locally-enable-sql-reader-syntax)
103 (loop ;with constituent-id
104 for tempo in tempi
105 do (clsql:insert-records :into "midi_db_tempi"
106 :attributes '([collection-id]
107 [composition-id]
108 [start]
109 [duration]
110 [microsecs-per-crotchet])
111 :values (list collection-id
112 composition-id
113 (* (timepoint tempo) timebase)
114 (* (duration tempo) timebase)
115 (microseconds-per-crotchet
116 tempo))
117 :database database))
118 #.(clsql:locally-disable-sql-reader-syntax))
119
120 (defun %add-timesig-constituents (collection-id composition-id timesigs
121 timebase database)
122 #.(clsql:locally-enable-sql-reader-syntax)
123 (loop for timesig in timesigs
124 do (clsql:insert-records :into "midi_db_timesigs"
125 :attributes '([collection-id]
126 [composition-id]
127 [start]
128 [duration]
129 [numerator]
130 [denominator])
131 :values (list collection-id
132 composition-id
133 (* (timepoint timesig) timebase)
134 (* (duration timesig) timebase)
135 (time-signature-numerator
136 timesig)
137 (time-signature-denominator
138 timesig))
139 :database database))
140 #.(clsql:locally-disable-sql-reader-syntax))
141
142 (defun %add-keysig-constituents (collection-id composition-id keysigs
143 timebase database)
144 #.(clsql:locally-enable-sql-reader-syntax)
145 (loop for keysig in keysigs
146 do (clsql:insert-records :into "midi_db_keysigs"
147 :attributes '([collection-id]
148 [composition-id]
149 [start]
150 [duration]
151 [mode]
152 [sharp-count])
153 :values (list collection-id
154 composition-id
155 (* (timepoint keysig) timebase)
156 (* (duration keysig) timebase)
157 (key-signature-mode
158 keysig)
159 (key-signature-sharps
160 keysig))
161 :database database))
162 #.(clsql:locally-disable-sql-reader-syntax))