1 /* Rewritten for Ardour by Paul Davis <paul@linuxaudiosystems.com>, Feb 2010
6 Copyright (C) 2009 Hannes Breul
10 Based on the m3u example included in the Reaper SDK,
11 Copyright (C) 2005-2008 Cockos Incorporated
13 Original source available at:
14 http://www.reaper.fm/sdk/plugin/plugin.php#ext_dl
16 This software is provided 'as-is', without any express or implied
17 warranty. In no event will the authors be held liable for any damages
18 arising from the use of this software.
20 Permission is granted to anyone to use this software for any purpose,
21 including commercial applications, and to alter it and redistribute it
22 freely, subject to the following restrictions:
24 1. The origin of this software must not be misrepresented; you must not
25 claim that you wrote the original software. If you use this software
26 in a product, an acknowledgment in the product documentation would be
27 appreciated but is not required.
28 2. Altered source versions must be plainly marked as such, and must not be
29 misrepresented as being the original software.
30 3. This notice may not be removed or altered from any source distribution.
33 #ifndef __STDC_FORMAT_MACROS
34 #define __STDC_FORMAT_MACROS /* PRI<foo>; C++ requires explicit requesting of these */
47 #include <sys/errno.h>
51 #include "pbd/xml++.h"
52 #include "pbd/basename.h"
58 //#define DEBUG(fmt,...) fprintf (stderr, fmt, ## __VA_ARGS__)
59 #define DEBUG(fmt,...)
60 #define INFO(fmt,...) fprintf (stdout, fmt, ## __VA_ARGS__)
64 MessageBox (FILE* /*ignored*/, const char* msg
, const char* title
, int status
)
66 fprintf (stderr
, msg
);
72 /* Add built-in types */
73 sqlite3_exec(db
, "INSERT INTO lookup VALUES (1, 'TOC property 1')", 0, 0, 0);
74 sqlite3_exec(db
, "INSERT INTO lookup VALUES (2, 'TOC property 2')", 0, 0, 0);
75 sqlite3_exec(db
, "INSERT INTO lookup VALUES (3, 'TOC property 3')", 0, 0, 0);
76 sqlite3_exec(db
, "INSERT INTO lookup VALUES (4, 'TOC property 4')", 0, 0, 0);
77 sqlite3_exec(db
, "INSERT INTO lookup VALUES (5, 'TOC property 5')", 0, 0, 0);
78 sqlite3_exec(db
, "INSERT INTO lookup VALUES (6, 'TOC property 6')", 0, 0, 0);
79 sqlite3_exec(db
, "INSERT INTO lookup VALUES (7, '(Type 7)')", 0, 0, 0);
80 sqlite3_exec(db
, "INSERT INTO lookup VALUES (8, '(Type 8)')", 0, 0, 0);
81 sqlite3_exec(db
, "INSERT INTO lookup VALUES (9, '(Type 9)')", 0, 0, 0);
82 sqlite3_exec(db
, "INSERT INTO lookup VALUES (10, '(Type 10)')", 0, 0, 0);
83 sqlite3_exec(db
, "INSERT INTO lookup VALUES (11, '(Type 11)')", 0, 0, 0);
84 sqlite3_exec(db
, "INSERT INTO lookup VALUES (12, '(Type 12)')", 0, 0, 0);
85 sqlite3_exec(db
, "INSERT INTO lookup VALUES (13, '(Type 13)')", 0, 0, 0);
86 sqlite3_exec(db
, "INSERT INTO lookup VALUES (14, '(Type 14)')", 0, 0, 0);
87 sqlite3_exec(db
, "INSERT INTO lookup VALUES (15, '(Type 15)')", 0, 0, 0);
88 sqlite3_exec(db
, "INSERT INTO lookup VALUES (16, '(Type 16)')", 0, 0, 0);
89 sqlite3_exec(db
, "INSERT INTO lookup VALUES (17, '(Type 17)')", 0, 0, 0);
90 sqlite3_exec(db
, "INSERT INTO lookup VALUES (18, '(Type 18)')", 0, 0, 0);
91 sqlite3_exec(db
, "INSERT INTO lookup VALUES (19, 'TOC Value')", 0, 0, 0);
92 sqlite3_exec(db
, "INSERT INTO lookup VALUES (20, '(Type 20)')", 0, 0, 0);
93 sqlite3_exec(db
, "INSERT INTO lookup VALUES (21, 'String')", 0, 0, 0);
94 sqlite3_exec(db
, "INSERT INTO lookup VALUES (22, '(Type 22)')", 0, 0, 0);
95 sqlite3_exec(db
, "INSERT INTO lookup VALUES (23, 'Type Name')", 0, 0, 0);
96 sqlite3_exec(db
, "INSERT INTO lookup VALUES (24, 'Property Name')", 0, 0, 0);
97 sqlite3_exec(db
, "INSERT INTO lookup VALUES (25, '(Type 25)')", 0, 0, 0);
98 sqlite3_exec(db
, "INSERT INTO lookup VALUES (26, '(Type 26)')", 0, 0, 0);
99 sqlite3_exec(db
, "INSERT INTO lookup VALUES (27, '(Type 27)')", 0, 0, 0);
100 sqlite3_exec(db
, "INSERT INTO lookup VALUES (28, '(Type 28)')", 0, 0, 0);
101 sqlite3_exec(db
, "INSERT INTO lookup VALUES (29, '(Type 29)')", 0, 0, 0);
102 sqlite3_exec(db
, "INSERT INTO lookup VALUES (30, '(Type 30)')", 0, 0, 0);
103 sqlite3_exec(db
, "INSERT INTO lookup VALUES (31, 'Referenced Object')", 0, 0, 0);
104 sqlite3_exec(db
, "INSERT INTO lookup VALUES (32, 'Object')", 0, 0, 0);
105 sqlite3_exec(db
, "INSERT INTO lookup VALUES (33, '(Type 33)')", 0, 0, 0);
106 sqlite3_exec(db
, "INSERT INTO lookup VALUES (34, '(Type 34)')", 0, 0, 0);
107 sqlite3_exec(db
, "INSERT INTO lookup VALUES (35, '(Type 35)')", 0, 0, 0);
108 sqlite3_exec(db
, "INSERT INTO lookup VALUES (36, '(Type 36)')", 0, 0, 0);
109 sqlite3_exec(db
, "INSERT INTO lookup VALUES (37, '(Type 37)')", 0, 0, 0);
110 sqlite3_exec(db
, "INSERT INTO lookup VALUES (38, '(Type 38)')", 0, 0, 0);
111 sqlite3_exec(db
, "INSERT INTO lookup VALUES (39, '(Type 39)')", 0, 0, 0);
112 sqlite3_exec(db
, "INSERT INTO lookup VALUES (40, '(Type 40)')", 0, 0, 0);
113 sqlite3_exec(db
, "INSERT INTO lookup VALUES (41, '(Type 41)')", 0, 0, 0);
114 sqlite3_exec(db
, "INSERT INTO lookup VALUES (42, '(Type 42)')", 0, 0, 0);
116 /* Assign type and property values to names */
117 sqlite3_exec(db
, "UPDATE data SET property = (SELECT name FROM lookup WHERE property = key), type = (SELECT name FROM lookup WHERE type = key)", 0, 0, 0);
118 sqlite3_exec(db
, "DROP TABLE lookup", 0, 0, 0);
122 OMF::load (const string
& path
)
124 if ((file
= fopen(path
.c_str(), "rb")) == 0) {
125 MessageBox(NULL
, "Cannot open file","OMF Error", MB_OK
);
129 /* --------------- */
130 char *fname
= (char*) malloc (path
.size()+5);
132 strcpy(fname
, path
.c_str());
133 strcat(fname
, ".db3");
135 if(sqlite3_open(":memory:", &db
)) {
137 sprintf(error
, "Can't open database: %s", sqlite3_errmsg(db
));
138 MessageBox(NULL
, error
,"OMF Error", MB_OK
);
142 sqlite3_exec(db
, "BEGIN", 0, 0, 0);
143 sqlite3_exec(db
, "CREATE TABLE data (object, property, type, value, offset, length)", 0, 0, 0);
144 sqlite3_exec(db
, "CREATE TABLE lookup (key, name)", 0, 0, 0);
147 fseek(file
, -24, SEEK_END
);
148 fread(magic
, 8, 1, file
);
149 if ((magic
[0] != 0xa4) | (magic
[1] != 0x43) | (magic
[2] != 0x4d) | (magic
[3] != 0xa5) | (magic
[4] != 0x48) | (magic
[5] != 0x64) | (magic
[6] != 0x72) | (magic
[7] != 0xd7)) {
150 MessageBox(NULL
, "No valid OMF file.","OMF Error", MB_OK
);
154 uint16_t bSize
, version
;
155 fseek(file
, -12, SEEK_END
);
156 fread(&version
, 2, 1, file
);
158 if ((version
== 1) | (version
== 256)) {
159 MessageBox(NULL
, "You tried to open an OMF1 file.\nOMF1 is not supported.","OMF Error", MB_OK
);
161 } else if (version
== 512) {
163 } else if (version
!= 2) {
164 MessageBox(NULL
, "You tried to open a corrupted file.","OMF Error", MB_OK
);
168 uint32_t tocStart
, tocSize
;
169 fseek(file
, -14, SEEK_END
);
170 fread(&bSize
, 2, 1, file
);
173 fseek(file
, -8, SEEK_END
);
174 fread(&tocStart
, 4, 1, file
);
175 tocStart
= e32(tocStart
);
177 fseek(file
, -4, SEEK_END
);
178 fread(&tocSize
, 4, 1, file
);
179 tocSize
= e32(tocSize
);
180 DEBUG ("block size: %d\n toc start: %d\n toc size: %d\n", bSize
, tocStart
, tocSize
);
183 /* Calculate number of TOC blocks */
184 uint32_t tocBlocks
= tocSize
/ (bSize
* 1024) + 1;
185 DEBUG ("toc blocks: %d\n", tocBlocks
);
186 /* ------------------------------ */
188 time_t globalstart
, starttime
, endtime
;
190 starttime
= globalstart
;
191 INFO ("Parsing TOC... ");
193 /* Go through TOC blocks */
195 uint32_t currentObj
= 0;
196 uint32_t currentProp
= 0;
197 uint32_t currentType
= 0;
200 for (j
= 0; j
< tocBlocks
; j
++) {
201 uint32_t currentBlock
= tocStart
+ j
* 1024 * bSize
; // Start at beginning of current block
203 for (currentPos
= currentBlock
; currentPos
< currentBlock
+ 1024 * bSize
; currentPos
++) {
204 if (currentPos
> tocStart
+ tocSize
) break; // Exit at end of TOC
205 char cByte
; // TOC control byte
206 fseek(file
, currentPos
, SEEK_SET
);
207 fread(&cByte
, 1, 1, file
);
211 fseek(file
, currentPos
+ 1, SEEK_SET
);
212 fread(¤tObj
, 4, 1, file
);
213 currentObj
= e32(currentObj
);
214 fseek(file
, currentPos
+ 5, SEEK_SET
);
215 fread(¤tProp
, 4, 1, file
);
216 currentProp
= e32(currentProp
);
217 fseek(file
, currentPos
+ 9, SEEK_SET
);
218 fread(¤tType
, 4, 1, file
);
219 currentType
= e32(currentType
);
220 DEBUG("---------------------\n");
221 DEBUG(" object: 0x%x\n", currentObj
);
222 DEBUG(" property: 0x%x\n", currentProp
);
223 DEBUG(" type: 0x%x\n", currentType
);
225 currentPos
+= 12; // Skip the bytes that were just read
231 else if (cByte
== 2) {
232 fseek(file
, currentPos
+ 1, SEEK_SET
);
233 fread(¤tProp
, 4, 1, file
);
234 currentProp
= e32(currentProp
);
235 fseek(file
, currentPos
+ 5, SEEK_SET
);
236 fread(¤tType
, 4, 1, file
);
237 currentType
= e32(currentType
);
238 DEBUG(" property: 0x%x\n", currentProp
);
239 DEBUG(" type: 0x%x\n", currentType
);
247 else if (cByte
== 3) {
248 fseek(file
, currentPos
+ 1, SEEK_SET
);
249 fread(¤tType
, 4, 1, file
);
250 currentType
= e32(currentType
);
251 DEBUG(" type: 0x%x\n", currentType
);
259 else if (cByte
== 4) {
265 /* Reference to a value - 4/8 byte offset, 4/8 byte size */
266 else if ((cByte
== 5) | (cByte
== 6) | (cByte
== 7) | (cByte
== 8)) {
268 uint32_t offset32
= 0;
269 uint32_t length32
= 0;
270 uint64_t dataOffset
= 0;
271 uint64_t dataLength
= 0;
272 if ((cByte
== 5) | (cByte
== 6)) {
273 fseek(file
, currentPos
+ 1, SEEK_SET
);
274 fread(&offset32
, 4, 1, file
);
275 fseek(file
, currentPos
+ 5, SEEK_SET
);
276 fread(&length32
, 4, 1, file
);
277 dataOffset
= e32(offset32
);
278 dataLength
= e32(length32
);
280 fseek(file
, currentPos
+ 1, SEEK_SET
);
281 fread(&dataOffset
, 8, 1, file
);
282 dataOffset
= e64(dataOffset
);
283 fseek(file
, currentPos
+ 9, SEEK_SET
);
284 fread(&dataLength
, 8, 1, file
);
285 dataLength
= e64(dataLength
);
287 DEBUG(" offset: %d\n", dataOffset
);
288 DEBUG(" length: %d\n", dataLength
);
290 if (currentType
== 21) {
291 char* string
= (char*) malloc((uint32_t) dataLength
);
292 fseek(file
, dataOffset
, SEEK_SET
);
293 fread(string
, dataLength
, 1, file
);
294 char* query
= sqlite3_mprintf("INSERT INTO lookup VALUES(%d, '%s')",currentObj
, string
);
295 sqlite3_exec(db
, query
, 0, 0, 0);
297 } else if (currentType
== 32){
299 fseek(file
, dataOffset
, SEEK_SET
);
300 fread(&object
, 4, 1, file
);
301 object
= e32(object
);
302 char* query
= sqlite3_mprintf("INSERT INTO data VALUES(%d, %d, %d, %d, -1, -1)",currentObj
, currentProp
, currentType
, object
);
303 sqlite3_exec(db
, query
, 0, 0, 0);
305 if (dataLength
== 16) {
306 DEBUG(" offset: %lld\n", dataOffset
+ 8);
307 DEBUG(" length: %lld\n", dataLength
);
308 fseek(file
, dataOffset
+ 8, SEEK_SET
);
309 fread(&object
, 4, 1, file
);
310 object
= e32(object
);
311 char* query2
= sqlite3_mprintf("INSERT INTO data VALUES(%d, %d, %d, %d, -1, -1)",currentObj
, currentProp
, currentType
, object
);
312 sqlite3_exec(db
, query2
, 0, 0, 0);
313 sqlite3_free(query2
);
316 char* query
= sqlite3_mprintf("INSERT INTO data VALUES(%d, %d, %d, '', %lld, %lld)",currentObj
, currentProp
, currentType
, dataOffset
, dataLength
);
317 sqlite3_exec(db
, query
, 0, 0, 0);
321 if ((cByte
== 5) | (cByte
== 6)) {
327 /* ----------------------------------------------------- */
330 /* Zero byte value */
331 else if (cByte
== 9) {
333 char* query
= sqlite3_mprintf("INSERT INTO data VALUES(%d, %d, %d, 'true', -1, -1)",currentObj
, currentProp
, currentType
);
334 sqlite3_exec(db
, query
, 0, 0, 0);
336 DEBUG(" value: true\n");
339 /* --------------- */
342 /* Immediate value */
343 else if ((cByte
== 10) | (cByte
== 11) | (cByte
== 12) | (cByte
== 13) | (cByte
== 14)) {
346 fseek(file
, currentPos
+ 1, SEEK_SET
);
347 fread(&data
, 4, 1, file
);
349 char* query
= sqlite3_mprintf("INSERT INTO data VALUES(%d, %d, %d, %d, -1, -1)",currentObj
, currentProp
, currentType
, data
);
350 sqlite3_exec(db
, query
, 0, 0, 0);
352 DEBUG(" value: %d\n", data
);
357 /* --------------- */
361 else if (cByte
== 15) {
363 fseek(file
, currentPos
+ 1, SEEK_SET
);
364 fread(&data
, 4, 1, file
);
366 char* query
= sqlite3_mprintf("INSERT INTO data VALUES(%d, %d, %d, %d, -1, -1)",currentObj
, currentProp
, currentType
, data
);
367 sqlite3_exec(db
, query
, 0, 0, 0);
369 DEBUG("reference: 0x%x\n", data
);
380 /* --------------------- */
382 INFO("done. (%ld seconds)\n", endtime
- starttime
);
385 INFO("Assigning type and property names... ");
388 INFO("done. (%ld seconds)\n", endtime
- starttime
);
393 /* resolve ObjRefArrays */
397 INFO("Resolving ObjRefArrays ");
398 sqlite3_get_table(db
, "SELECT * FROM data WHERE type LIKE 'omfi:ObjRefArray' AND value = ''", &arrays
, &arrayCount
, 0, 0);
399 INFO("(%d to be processed)... ", arrayCount
);
400 sqlite3_exec(db
,"DELETE FROM data WHERE type LIKE 'omfi:ObjRefArray' AND value = ''",0,0,0);
401 for (l
= 6; l
<= arrayCount
* 6; l
+=6) {
403 uint32_t arrOffs
= atoi(arrays
[l
+4]);
404 uint32_t arrLen
= atoi(arrays
[l
+5]);
405 fseek(file
, arrOffs
, SEEK_SET
);
406 fread(&counter
, 2, 1, file
);
407 counter
= e16(counter
);
408 if (arrLen
= 4 * counter
+ 2) {
411 DEBUG("currentObj: %d - references:", currentObj
);
412 for (counter
= 2; counter
< arrLen
; counter
+= 4) {
414 fseek(file
, arrOffs
+ counter
, SEEK_SET
);
415 fread(&temp
, 4, 1, file
);
418 sqlite3_exec(db
, sqlite3_mprintf("INSERT INTO data VALUES (%d, 'Referenced Object', 'Object', %d, -1, -1)", currentObj
, temp
), 0, 0, 0);
420 DEBUG("\nData: %s | %s | %s | %d | -1 | -1\n", arrays
[l
], arrays
[l
+1], arrays
[l
+2], currentObj
);
421 sqlite3_exec(db
, sqlite3_mprintf("INSERT INTO data VALUES (%s, '%s', '%s', %d, -1, -1)", arrays
[l
], arrays
[l
+1], arrays
[l
+2], currentObj
), 0, 0, 0);
424 sqlite3_free_table(arrays
);
426 INFO("done. (%ld seconds)\n", endtime
- starttime
);
428 /* -------------------- */
435 printf("Resolving ObjRefs...\n");
436 sqlite3_get_table(db,"SELECT object, property, value FROM data WHERE type = 'omfi:ObjRef'", &refs, &refCount, 0, 0);
437 printf("temporary table created\n");
438 for (currentRef = 3; currentRef <= refCount * 3; currentRef += 3) {
439 DEBUG("%d / %d\n", currentRef/3, refCount);
442 sqlite3_get_table(db, sqlite3_mprintf("SELECT value FROM data WHERE object = %s AND type = 'Object' LIMIT 1", refs[currentRef+2]), &target, &targetCount, 0, 0);
443 DEBUG("temporary table filled\n");
444 if (targetCount > 0) {
445 //sqlite3_exec(db,sqlite3_mprintf("DELETE FROM data WHERE object = %s", refs[currentRef+2]),0,0,0);
446 DEBUG("unused reference deleted\n");
447 sqlite3_exec(db,sqlite3_mprintf("UPDATE data SET value = %s WHERE object LIKE '%s' AND property LIKE '%s' LIMIT 1", target[1], refs[currentRef], refs[currentRef+1]),0,0,0);
448 printf("temporary data inserted\n");
450 sqlite3_free_table(target);
452 sqlite3_free_table(refs);
453 printf("temporary table deleted\n"); */
456 INFO("Resolving ObjRefs ");
457 sqlite3_exec(db
,"CREATE TABLE reference (object1, property1, value1)",0,0,0);
458 sqlite3_exec(db
,"INSERT INTO reference SELECT object, property, value FROM data WHERE type LIKE 'omfi:ObjRef'",0,0,0);
459 sqlite3_exec(db
,"CREATE TABLE objects (object2, value2)",0,0,0);
460 sqlite3_exec(db
,"INSERT INTO objects SELECT object, value FROM data WHERE type LIKE 'Object'",0,0,0);
461 sqlite3_exec(db
,"UPDATE reference SET value1 = (SELECT value2 FROM objects WHERE object2 = value1)",0,0,0);
462 //sqlite3_exec(db,"UPDATE data SET value = (SELECT value1 FROM references WHERE object1 = object) WHERE ",0,0,0);
467 sqlite3_get_table(db
,"SELECT * FROM reference", &refs
, &refCount
, 0, 0);
468 INFO ("(%d to be processed)... ", refCount
);
469 for (currentRef
= 3; currentRef
<= refCount
* 3; currentRef
+= 3) {
470 DEBUG("%d / %d: object %s, property %s, value %s\n", currentRef
/3, refCount
, refs
[currentRef
], refs
[currentRef
+1], refs
[currentRef
+2]);
471 sqlite3_exec(db
,sqlite3_mprintf("DELETE FROM data WHERE object = %s AND property = '%s'", refs
[currentRef
], refs
[currentRef
+1]),0,0,0);
472 sqlite3_exec(db
,sqlite3_mprintf("INSERT INTO data VALUES (%s, '%s', 'omfi:ObjRef', %s, -1, -1)", refs
[currentRef
], refs
[currentRef
+1], refs
[currentRef
+2]),0,0,0);
474 sqlite3_free_table(refs
);
476 DEBUG("temporary table deleted\n");
478 /*sqlite3_get_table(db,"SELECT object, property, value FROM data WHERE type LIKE 'omfi:ObjRef'", &refs, &refCount, 0, 0);
479 printf("%d\n", refCount);
480 for (currentRef = 3; currentRef <= refCount * 3; currentRef += 3) {
481 printf("%d / %d: object %s, property %s, value %s\n", currentRef/3, refCount, refs[currentRef], refs[currentRef+1], refs[currentRef+2]);
483 sqlite3_free_table(refs);
488 printf("Resolving ObjRefs...\n");
489 sqlite3_exec(db,"CREATE TABLE temp (object, property, type, value, offset, length)",0,0,0);
490 printf("temporary table created\n");
491 sqlite3_exec(db,"INSERT INTO temp SELECT d1.object, d1.property, d1.type, d2.value, d1.offset, d1.length FROM data d1, data d2 WHERE d1.type = 'omfi:ObjRef' AND d1.value = d2.object AND d2.type = 'Object'",0,0,0);
492 printf("temporary table filled\n");
493 //sqlite3_exec(db,"DELETE FROM data WHERE object IN (SELECT value FROM data WHERE type LIKE 'omfi:ObjRef')",0,0,0);
494 sqlite3_exec(db,"DELETE FROM data WHERE object IN (SELECT object FROM temp) AND type = 'omfi:ObjRef'",0,0,0);
495 printf("unused referenced deleted\n");
496 sqlite3_exec(db,"INSERT INTO data SELECT * FROM temp",0,0,0);
497 printf("temporary data inserted\n");
498 sqlite3_exec(db,"DROP TABLE temp",0,0,0);
499 printf("temporary table deleted\n");
503 INFO("done. (%ld seconds)\n", endtime
- starttime
);
508 INFO("Resolving UIDs... ");
512 sqlite3_get_table(db
,"SELECT object, property, offset FROM data WHERE type LIKE 'omfi:UID'", &mobID
, &mobIDCount
, 0, 0);
513 sqlite3_exec(db
,"DELETE FROM data WHERE type LIKE 'omfi:UID'",0,0,0);
514 for (currentID
= 3; currentID
<= mobIDCount
* 3; currentID
+= 3) {
515 uint32_t mobIDoffs
= atoi(mobID
[currentID
+2]);
516 //sscanf(mobID[currentID+2], "%d", &mobIDoffs);
518 fseek(file
, mobIDoffs
, SEEK_SET
);
519 fread(mobBuffer
, 12, 1, file
);
520 sqlite3_exec(db
,sqlite3_mprintf("INSERT INTO data VALUES (%s, '%s', 'omfi:UID', '%d %d %d', -1, -1)", mobID
[currentID
], mobID
[currentID
+ 1], mobBuffer
[0], mobBuffer
[1], mobBuffer
[2]),0,0,0);
522 sqlite3_free_table(mobID
);
526 INFO("done. (%ld seconds)\n", endtime
- starttime
);
531 /* extract media data */
532 printf("Extracting media data...\n");
535 //sqlite3_exec(db,"CREATE TABLE names (UID, value)",0,0,0);
536 sqlite3_get_table(db
, "SELECT object, offset, length FROM data WHERE object IN (SELECT value FROM data WHERE object IN (SELECT value FROM data WHERE property = 'OMFI:HEAD:MediaData' LIMIT 1)) AND type = 'omfi:DataValue'", &objects
, &objectsCount
, 0, 0);
537 for (k
= 3; k
<= objectsCount
* 3; k
+= 3) {
541 std::string full_path
;
542 sqlite3_get_table(db
, sqlite3_mprintf("SELECT offset, length FROM data WHERE object IN (SELECT object FROM data WHERE value IN (SELECT value FROM data WHERE object = %s AND property = 'OMFI:MDAT:MobID' LIMIT 1) AND property = 'OMFI:MOBJ:MobID' LIMIT 1) AND property = 'OMFI:MOBJ:Name' LIMIT 1", objects
[k
]), &fileName
, &fileNameCount
, 0, 0);
543 if (fileNameCount
> 0) {
544 uint32_t fnOffs
= atoi(fileName
[2]);
545 uint32_t fnLen
= atoi(fileName
[3]);
546 if (get_offset_and_length (fileName
[2], fileName
[3], fnOffs
, fnLen
)) {
547 char *fnBuf
= (char*) malloc(fnLen
+1);
548 fseek(file
, fnOffs
, SEEK_SET
);
549 fread(fnBuf
, fnLen
, 1, file
);
552 audiofile_path_vector
.push_back (fnBuf
);
553 full_path
= Glib::build_filename (audiofile_path_vector
);
554 audiofile_path_vector
.pop_back ();
556 fd
= fopen(full_path
.c_str(), "wb");
559 INFO ("Skip unnamed media file\n");
563 audiofile_path_vector
.push_back (objects
[k
]);
564 full_path
= Glib::build_filename (audiofile_path_vector
);
565 audiofile_path_vector
.pop_back ();
566 fd
= fopen(full_path
.c_str(), "wb");
567 INFO ("Direct file name used (%s)\n", full_path
.c_str());
572 sprintf(error
, "Can't create file [%s] (object %s)", full_path
.c_str(), objects
[k
]);
573 MessageBox(NULL
,error
,"OMF Error", MB_OK
);
574 sqlite3_exec(db
, "COMMIT", 0, 0, 0);
578 INFO("Writing file %s (object %s): ", full_path
.c_str(), objects
[k
]);
583 if (get_offset_and_length (objects
[k
+1], objects
[k
+2], foffset
, flength
)) {
584 int blockSize
= 1024;
585 uint32_t currentBlock
;
586 uint32_t written
= 0;
587 char* buffer
= (char*) malloc(blockSize
);
588 fseek(file
, foffset
, SEEK_SET
);
589 for (currentBlock
= 0; currentBlock
< flength
/ blockSize
; currentBlock
++) {
590 fread(buffer
, blockSize
, 1, file
);
591 written
+= fwrite(buffer
, 1, blockSize
, fd
);
593 fread(buffer
, flength
% blockSize
, 1, file
);
594 written
+= fwrite(buffer
, 1, flength
% blockSize
, fd
);
595 INFO("%d of %d bytes\n", written
, flength
);
598 get_audio_info (full_path
);
600 sqlite3_free_table(fileName
);
602 sqlite3_free_table(objects
);
603 /* ------------------ */
606 INFO("done. (%ld seconds)\n", endtime
- starttime
);
609 /* resolve ClassIDs */
610 printf("Resolving ClassIDs ");
614 sqlite3_get_table(db
,"SELECT object, property, value FROM data WHERE type = 'omfi:ClassID'", &classID
, &classIDCount
, 0, 0);
615 sqlite3_exec(db
,"DELETE FROM data WHERE type = 'omfi:ClassID'",0,0,0);
616 INFO("(%d to be processed)... ", classIDCount
);
617 for (currentClsID
= 3; currentClsID
<= classIDCount
* 3; currentClsID
+= 3) {
618 //int clsID = (int) malloc(5);
619 int clsID
= atoi(classID
[currentClsID
+2]);
621 //sscanf(classID[currentClsID+2], "%d", &clsID);
623 strncpy(clsString
, (char *) &clsID
, 4);
625 DEBUG("%d -> %s\n", clsID
, clsString
);
627 sqlite3_exec(db
,sqlite3_mprintf("INSERT INTO data VALUES (%s, '%s', 'omfi:ClassID', '%s', -1, -1)", classID
[currentClsID
], classID
[currentClsID
+ 1], clsString
),0,0,0);
629 sqlite3_free_table(classID
);
630 /* ---------------- */
632 sqlite3_exec(db
, "COMMIT", 0, 0, 0);
635 INFO("done. (%ld seconds)\n", endtime
- starttime
);
639 printf("Took %ld seconds\n", endtime - starttime);
640 starttime = endtime;*/
644 INFO("done. (%ld seconds)\n", endtime
- starttime
);
645 INFO("Overall time: %ld seconds\n", endtime
- globalstart
);