mas01cr@239
|
1 #include "audioDB.h"
|
mas01cr@399
|
2 extern "C" {
|
mas01cr@399
|
3 #include "audioDB_API.h"
|
mas01cr@399
|
4 }
|
mas01cr@239
|
5
|
mas01cr@399
|
6 /* We could go gcc-specific here and use typeof() instead of passing
|
mas01cr@399
|
7 * in an explicit type. Answers on a postcard as to whether that's a
|
mas01cr@399
|
8 * good plan or not. */
|
mas01cr@399
|
9 #define mmap_or_goto_error(type, var, start, length) \
|
mas01cr@399
|
10 { void *tmp = mmap(0, length, PROT_READ, MAP_SHARED, adb->fd, (start)); \
|
mas01cr@399
|
11 if(tmp == (void *) -1) { \
|
mas01cr@399
|
12 goto error; \
|
mas01cr@399
|
13 } \
|
mas01cr@399
|
14 var = (type) tmp; \
|
mas01cr@399
|
15 }
|
mas01cr@399
|
16
|
mas01cr@399
|
17 #define maybe_munmap(table, length) \
|
mas01cr@399
|
18 { if(table) { \
|
mas01cr@399
|
19 munmap(table, length); \
|
mas01cr@399
|
20 } \
|
mas01cr@399
|
21 }
|
mas01cr@399
|
22
|
mas01cr@399
|
23 int audiodb_dump(adb_t *adb, const char *output) {
|
mas01cr@399
|
24 char *fileTable = 0; /* key_table */
|
mas01cr@399
|
25 unsigned *trackTable = 0; /* track_size_table */
|
mas01cr@399
|
26 double *timesTable = 0; /* timestamps_table */
|
mas01cr@399
|
27 double *powerTable = 0; /* power_table */
|
mas01cr@399
|
28
|
mas01cr@399
|
29 size_t fileTableLength = 0;
|
mas01cr@399
|
30 size_t trackTableLength = 0;
|
mas01cr@399
|
31 size_t timesTableLength = 0;
|
mas01cr@399
|
32 size_t powerTableLength = 0;
|
mas01cr@399
|
33
|
mas01cr@399
|
34 char *featureFileNameTable = 0;
|
mas01cr@399
|
35 char *powerFileNameTable = 0;
|
mas01cr@399
|
36 char *timesFileNameTable = 0;
|
mas01cr@399
|
37
|
mas01cr@399
|
38 char cwd[PATH_MAX];
|
mas01cr@399
|
39 int directory_changed = 0;
|
mas01cr@399
|
40
|
mas01cr@399
|
41 int fLfd = 0, tLfd = 0, pLfd = 0, kLfd = 0;
|
mas01cr@399
|
42 FILE *fLFile = 0, *tLFile = 0, *pLFile = 0, *kLFile = 0;
|
mas01cr@399
|
43
|
mas01cr@399
|
44 int times, power;
|
mas01cr@399
|
45
|
mas01cr@399
|
46 char fName[256];
|
mas01cr@399
|
47 int ffd, pfd;
|
mas01cr@399
|
48 FILE *tFile;
|
mas01cr@399
|
49 unsigned pos = 0;
|
mas01cr@399
|
50 double *data_buffer;
|
mas01cr@399
|
51 size_t data_buffer_size;
|
mas01cr@399
|
52 FILE *scriptFile = 0;
|
mas01cr@399
|
53
|
mas01cr@399
|
54 unsigned nfiles = adb->header->numFiles;
|
mas01cr@399
|
55
|
mas01cr@399
|
56 if(adb->header->length > 0) {
|
mas01cr@399
|
57 fileTableLength = ALIGN_PAGE_UP(nfiles * O2_FILETABLE_ENTRY_SIZE);
|
mas01cr@399
|
58 trackTableLength = ALIGN_PAGE_UP(nfiles * O2_TRACKTABLE_ENTRY_SIZE);
|
mas01cr@399
|
59 if(!(adb->header->flags & O2_FLAG_LARGE_ADB)) {
|
mas01cr@399
|
60 off_t length = adb->header->length;
|
mas01cr@399
|
61 unsigned dim = adb->header->dim;
|
mas01cr@399
|
62 timesTableLength = ALIGN_PAGE_UP(2*length/dim);
|
mas01cr@399
|
63 powerTableLength = ALIGN_PAGE_UP(length/dim);
|
mas01cr@399
|
64 }
|
mas01cr@399
|
65
|
mas01cr@399
|
66 mmap_or_goto_error(char *, fileTable, adb->header->fileTableOffset, fileTableLength);
|
mas01cr@399
|
67 mmap_or_goto_error(unsigned *, trackTable, adb->header->trackTableOffset, trackTableLength);
|
mas01cr@399
|
68 if (adb->header->flags & O2_FLAG_LARGE_ADB) {
|
mas01cr@399
|
69 mmap_or_goto_error(char *, featureFileNameTable, adb->header->dataOffset, fileTableLength);
|
mas01cr@399
|
70 mmap_or_goto_error(char *, powerFileNameTable, adb->header->powerTableOffset, fileTableLength);
|
mas01cr@399
|
71 mmap_or_goto_error(char *, timesFileNameTable, adb->header->timesTableOffset, fileTableLength);
|
mas01cr@399
|
72 } else {
|
mas01cr@399
|
73 mmap_or_goto_error(double *, powerTable, adb->header->powerTableOffset, powerTableLength);
|
mas01cr@399
|
74 mmap_or_goto_error(double *, timesTable, adb->header->timesTableOffset, timesTableLength);
|
mas01cr@399
|
75 }
|
mas01cr@239
|
76 }
|
mas01cr@239
|
77
|
mas01cr@239
|
78 if((mkdir(output, S_IRWXU|S_IRWXG|S_IRWXO)) < 0) {
|
mas01cr@399
|
79 goto error;
|
mas01cr@239
|
80 }
|
mas01cr@239
|
81
|
mas01cr@239
|
82 if ((getcwd(cwd, PATH_MAX)) == 0) {
|
mas01cr@399
|
83 goto error;
|
mas01cr@239
|
84 }
|
mas01cr@239
|
85
|
mas01cr@399
|
86 /* FIXME: Hrm. How does chdir(2) interact with threads? Does each
|
mas01cr@399
|
87 * thread have its own working directory? */
|
mas01cr@239
|
88 if((chdir(output)) < 0) {
|
mas01cr@399
|
89 goto error;
|
mas01cr@399
|
90 }
|
mas01cr@399
|
91 directory_changed = 1;
|
mas01cr@399
|
92
|
mas01cr@399
|
93 if ((fLfd = open("featureList.txt", O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
|
mas01cr@399
|
94 goto error;
|
mas01cr@239
|
95 }
|
mas01cr@239
|
96
|
mas01cr@399
|
97 times = adb->header->flags & O2_FLAG_TIMES;
|
mas01cr@239
|
98 if (times) {
|
mas01cr@239
|
99 if ((tLfd = open("timesList.txt", O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
|
mas01cr@399
|
100 goto error;
|
mas01cr@239
|
101 }
|
mas01cr@239
|
102 }
|
mas01cr@239
|
103
|
mas01cr@399
|
104 power = adb->header->flags & O2_FLAG_POWER;
|
mas01cr@239
|
105 if (power) {
|
mas01cr@239
|
106 if ((pLfd = open("powerList.txt", O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
|
mas01cr@399
|
107 goto error;
|
mas01cr@239
|
108 }
|
mas01cr@239
|
109 }
|
mas01cr@239
|
110
|
mas01cr@239
|
111 if ((kLfd = open("keyList.txt", O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
|
mas01cr@399
|
112 goto error;
|
mas01cr@239
|
113 }
|
mas01cr@239
|
114
|
mas01cr@239
|
115 /* can these fail? I sincerely hope not. */
|
mas01cr@239
|
116 fLFile = fdopen(fLfd, "w");
|
mas01cr@239
|
117 if (times) {
|
mas01cr@239
|
118 tLFile = fdopen(tLfd, "w");
|
mas01cr@239
|
119 }
|
mas01cr@239
|
120 if (power) {
|
mas01cr@239
|
121 pLFile = fdopen(pLfd, "w");
|
mas01cr@239
|
122 }
|
mas01cr@239
|
123 kLFile = fdopen(kLfd, "w");
|
mas01cr@239
|
124
|
mas01cr@399
|
125 lseek(adb->fd, adb->header->dataOffset, SEEK_SET);
|
mas01cr@399
|
126
|
mas01cr@399
|
127 for(unsigned k = 0; k < nfiles; k++) {
|
mas01cr@256
|
128 fprintf(kLFile, "%s\n", fileTable + k*O2_FILETABLE_ENTRY_SIZE);
|
mas01cr@399
|
129 if(adb->header->flags & O2_FLAG_LARGE_ADB) {
|
mas01cr@380
|
130 char *featureFileName = featureFileNameTable+k*O2_FILETABLE_ENTRY_SIZE;
|
mas01cr@399
|
131 if(*featureFileName != '/') {
|
mas01cr@399
|
132 goto error;
|
mas01cr@399
|
133 }
|
mas01cr@380
|
134 fprintf(fLFile, "%s\n", featureFileName);
|
mas01cr@380
|
135 if(times) {
|
mas01cr@380
|
136 char *timesFileName = timesFileNameTable + k*O2_FILETABLE_ENTRY_SIZE;
|
mas01cr@399
|
137 if(*timesFileName != '/') {
|
mas01cr@399
|
138 goto error;
|
mas01cr@399
|
139 }
|
mas01cr@380
|
140 fprintf(tLFile, "%s\n", timesFileName);
|
mas01cr@239
|
141 }
|
mas01cr@380
|
142 if(power) {
|
mas01cr@380
|
143 char *powerFileName = powerFileNameTable + k*O2_FILETABLE_ENTRY_SIZE;
|
mas01cr@399
|
144 if(*powerFileName != '/') {
|
mas01cr@399
|
145 goto error;
|
mas01cr@399
|
146 }
|
mas01cr@380
|
147 fprintf(pLFile, "%s\n", powerFileName);
|
mas01cr@239
|
148 }
|
mas01cr@380
|
149 } else {
|
mas01cr@380
|
150 snprintf(fName, 256, "%05d.features", k);
|
mas01cr@380
|
151 if ((ffd = open(fName, O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
|
mas01cr@399
|
152 goto error;
|
mas01cr@239
|
153 }
|
mas01cr@399
|
154 if ((write(ffd, &(adb->header->dim), sizeof(uint32_t))) < 0) {
|
mas01cr@399
|
155 goto error;
|
mas01cr@380
|
156 }
|
mas01cr@380
|
157
|
mas01cr@380
|
158 /* FIXME: this repeated malloc()/free() of data buffers is
|
mas01cr@380
|
159 inefficient. */
|
mas01cr@399
|
160 data_buffer_size = trackTable[k] * adb->header->dim * sizeof(double);
|
mas01cr@380
|
161
|
mas01cr@380
|
162 {
|
mas01cr@380
|
163 void *tmp = malloc(data_buffer_size);
|
mas01cr@380
|
164 if (tmp == NULL) {
|
mas01cr@399
|
165 goto error;
|
mas01cr@380
|
166 }
|
mas01cr@380
|
167 data_buffer = (double *) tmp;
|
mas01cr@380
|
168 }
|
mas01cr@380
|
169
|
mas01cr@399
|
170 if ((read(adb->fd, data_buffer, data_buffer_size)) != (ssize_t) data_buffer_size) {
|
mas01cr@399
|
171 goto error;
|
mas01cr@380
|
172 }
|
mas01cr@380
|
173
|
mas01cr@380
|
174 if ((write(ffd, data_buffer, data_buffer_size)) < 0) {
|
mas01cr@399
|
175 goto error;
|
mas01cr@239
|
176 }
|
mas01cr@380
|
177
|
mas01cr@380
|
178 free(data_buffer);
|
mas01cr@380
|
179
|
mas01cr@380
|
180 fprintf(fLFile, "%s\n", fName);
|
mas01cr@380
|
181 close(ffd);
|
mas01cr@399
|
182 ffd = 0;
|
mas01cr@399
|
183
|
mas01cr@380
|
184 if (times) {
|
mas01cr@380
|
185 snprintf(fName, 256, "%05d.times", k);
|
mas01cr@380
|
186 tFile = fopen(fName, "w");
|
mas01cr@380
|
187 for(unsigned i = 0; i < trackTable[k]; i++) {
|
mas01cr@380
|
188 // KLUDGE: specifying 16 digits of precision after the decimal
|
mas01cr@380
|
189 // point is (but check this!) sufficient to uniquely identify
|
mas01cr@380
|
190 // doubles; however, that will cause ugliness, as that's
|
mas01cr@380
|
191 // vastly too many for most values of interest. Moving to %a
|
mas01cr@380
|
192 // here and scanf() in the timesFile reading might fix this.
|
mas01cr@380
|
193 // -- CSR, 2007-10-19
|
mas01cr@380
|
194 fprintf(tFile, "%.16e\n", *(timesTable + 2*pos + 2*i));
|
mas01cr@380
|
195 }
|
mas01cr@380
|
196 fprintf(tFile, "%.16e\n", *(timesTable + 2*pos + 2*trackTable[k]-1));
|
mas01cr@399
|
197 fclose(tFile);
|
mas01cr@380
|
198
|
mas01cr@380
|
199 fprintf(tLFile, "%s\n", fName);
|
mas01cr@380
|
200 }
|
mas01cr@380
|
201
|
mas01cr@380
|
202 if (power) {
|
mas01cr@380
|
203 uint32_t one = 1;
|
mas01cr@380
|
204 snprintf(fName, 256, "%05d.power", k);
|
mas01cr@380
|
205 if ((pfd = open(fName, O_CREAT|O_RDWR|O_EXCL, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) < 0) {
|
mas01cr@399
|
206 goto error;
|
mas01cr@380
|
207 }
|
mas01cr@380
|
208 if ((write(pfd, &one, sizeof(uint32_t))) < 0) {
|
mas01cr@399
|
209 goto error;
|
mas01cr@380
|
210 }
|
mas01cr@380
|
211 if ((write(pfd, powerTable + pos, trackTable[k] * sizeof(double))) < 0) {
|
mas01cr@399
|
212 goto error;
|
mas01cr@380
|
213 }
|
mas01cr@380
|
214 fprintf(pLFile, "%s\n", fName);
|
mas01cr@380
|
215 close(pfd);
|
mas01cr@399
|
216 pfd = 0;
|
mas01cr@380
|
217 }
|
mas01cr@380
|
218
|
mas01cr@380
|
219 pos += trackTable[k];
|
mas01cr@380
|
220 std::cout << fileTable+k*O2_FILETABLE_ENTRY_SIZE << " " << trackTable[k] << std::endl;
|
mas01cr@380
|
221 }
|
mas01cr@239
|
222 }
|
mas01cr@239
|
223
|
mas01cr@239
|
224 scriptFile = fopen("restore.sh", "w");
|
mas01cr@239
|
225 fprintf(scriptFile, "\
|
mas01cr@239
|
226 #! /bin/sh\n\
|
mas01cr@239
|
227 #\n\
|
mas01cr@239
|
228 # usage: AUDIODB=/path/to/audioDB sh ./restore.sh <newdb>\n\
|
mas01cr@239
|
229 \n\
|
mas01cr@239
|
230 if [ -z \"${AUDIODB}\" ]; then echo set AUDIODB variable; exit 1; fi\n\
|
mas01cr@239
|
231 if [ -z \"$1\" ]; then echo usage: $0 newdb; exit 1; fi\n\n\
|
mas01cr@256
|
232 \"${AUDIODB}\" -d \"$1\" -N --datasize=%d --ntracks=%d --datadim=%d\n",
|
mas01cr@399
|
233 (int) ((adb->header->timesTableOffset - adb->header->dataOffset) / (1024*1024)),
|
mas01cr@256
|
234 // fileTable entries (char[256]) are bigger than trackTable
|
mas01cr@256
|
235 // (int), so the granularity of page aligning is finer.
|
mas01cr@399
|
236 (int) ((adb->header->trackTableOffset - adb->header->fileTableOffset) / O2_FILETABLE_ENTRY_SIZE),
|
mas01cr@399
|
237 (int) ceil(((double) (adb->header->timesTableOffset - adb->header->dataOffset)) / ((double) (adb->header->dbSize - adb->header->l2normTableOffset))));
|
mas01cr@399
|
238 if(adb->header->flags & O2_FLAG_L2NORM) {
|
mas01cr@239
|
239 fprintf(scriptFile, "\"${AUDIODB}\" -d \"$1\" -L\n");
|
mas01cr@239
|
240 }
|
mas01cr@239
|
241 if(power) {
|
mas01cr@239
|
242 fprintf(scriptFile, "\"${AUDIODB}\" -d \"$1\" -P\n");
|
mas01cr@239
|
243 }
|
mas01cr@239
|
244 fprintf(scriptFile, "\"${AUDIODB}\" -d \"$1\" -B -F featureList.txt -K keyList.txt");
|
mas01cr@239
|
245 if(times) {
|
mas01cr@239
|
246 fprintf(scriptFile, " -T timesList.txt");
|
mas01cr@239
|
247 }
|
mas01cr@239
|
248 if(power) {
|
mas01cr@239
|
249 fprintf(scriptFile, " -W powerList.txt");
|
mas01cr@239
|
250 }
|
mas01cr@239
|
251 fprintf(scriptFile, "\n");
|
mas01cr@239
|
252 fclose(scriptFile);
|
mas01cr@239
|
253
|
mas01cr@239
|
254 fclose(fLFile);
|
mas01cr@239
|
255 if(times) {
|
mas01cr@239
|
256 fclose(tLFile);
|
mas01cr@239
|
257 }
|
mas01cr@239
|
258 if(power) {
|
mas01cr@239
|
259 fclose(pLFile);
|
mas01cr@239
|
260 }
|
mas01cr@239
|
261 fclose(kLFile);
|
mas01cr@239
|
262
|
mas01cr@399
|
263 maybe_munmap(fileTable, fileTableLength);
|
mas01cr@399
|
264 maybe_munmap(trackTable, trackTableLength);
|
mas01cr@399
|
265 maybe_munmap(timesTable, timesTableLength);
|
mas01cr@399
|
266 maybe_munmap(powerTable, powerTableLength);
|
mas01cr@399
|
267 maybe_munmap(featureFileNameTable, fileTableLength);
|
mas01cr@399
|
268 maybe_munmap(timesFileNameTable, fileTableLength);
|
mas01cr@399
|
269 maybe_munmap(powerFileNameTable, fileTableLength);
|
mas01cr@399
|
270
|
mas01cr@399
|
271 if((chdir(cwd)) < 0) {
|
mas01cr@399
|
272 /* don't goto error because the error handling will try to
|
mas01cr@399
|
273 * chdir() */
|
mas01cr@399
|
274 return 1;
|
mas01cr@399
|
275 }
|
mas01cr@399
|
276
|
mas01cr@399
|
277 return 0;
|
mas01cr@399
|
278
|
mas01cr@399
|
279 error:
|
mas01cr@399
|
280 if(fLFile) {
|
mas01cr@399
|
281 fclose(fLFile);
|
mas01cr@399
|
282 } else if(fLfd) {
|
mas01cr@399
|
283 close(fLfd);
|
mas01cr@399
|
284 }
|
mas01cr@399
|
285 if(tLFile) {
|
mas01cr@399
|
286 fclose(tLFile);
|
mas01cr@399
|
287 } else if(tLfd) {
|
mas01cr@399
|
288 close(fLfd);
|
mas01cr@399
|
289 }
|
mas01cr@399
|
290 if(pLFile) {
|
mas01cr@399
|
291 fclose(pLFile);
|
mas01cr@399
|
292 } else if(pLfd) {
|
mas01cr@399
|
293 close(pLfd);
|
mas01cr@399
|
294 }
|
mas01cr@399
|
295 if(kLFile) {
|
mas01cr@399
|
296 fclose(kLFile);
|
mas01cr@399
|
297 } else if(kLfd) {
|
mas01cr@399
|
298 close(kLfd);
|
mas01cr@399
|
299 }
|
mas01cr@399
|
300 if(scriptFile) {
|
mas01cr@399
|
301 fclose(scriptFile);
|
mas01cr@399
|
302 }
|
mas01cr@399
|
303
|
mas01cr@399
|
304 maybe_munmap(fileTable, fileTableLength);
|
mas01cr@399
|
305 maybe_munmap(trackTable, trackTableLength);
|
mas01cr@399
|
306 maybe_munmap(timesTable, timesTableLength);
|
mas01cr@399
|
307 maybe_munmap(powerTable, powerTableLength);
|
mas01cr@399
|
308 maybe_munmap(featureFileNameTable, fileTableLength);
|
mas01cr@399
|
309 maybe_munmap(timesFileNameTable, fileTableLength);
|
mas01cr@399
|
310 maybe_munmap(powerFileNameTable, fileTableLength);
|
mas01cr@399
|
311
|
mas01cr@399
|
312 if(directory_changed) {
|
mas01cr@399
|
313 chdir(cwd);
|
mas01cr@399
|
314 }
|
mas01cr@399
|
315 return 1;
|
mas01cr@239
|
316 }
|