Mercurial > hg > audiodb
comparison examples/iAudioDB/AppController.m @ 685:e78e5a80b73d
* Extraction params supplied at db creation time
* n3 configs are customized at extraction time
* Changes to import UI
* Extraction params stored in db plist
author | mas01mj |
---|---|
date | Thu, 11 Mar 2010 11:50:39 +0000 |
parents | fed70cb84a92 |
children | e2f4924130ef |
comparison
equal
deleted
inserted
replaced
684:fed70cb84a92 | 685:e78e5a80b73d |
---|---|
36 /** | 36 /** |
37 * Create a new database, given the selected filename. | 37 * Create a new database, given the selected filename. |
38 */ | 38 */ |
39 -(IBAction)newDatabase:(id)sender | 39 -(IBAction)newDatabase:(id)sender |
40 { | 40 { |
41 | |
42 [NSApp beginSheet:createSheet modalForWindow:mainWindow modalDelegate:self didEndSelector:NULL contextInfo:nil]; | |
43 session = [NSApp beginModalSessionForWindow:createSheet]; | |
44 [NSApp runModalSession:session]; | |
45 } | |
46 | |
47 /** | |
48 * Cancel the db creation (at configuration time). | |
49 */ | |
50 -(IBAction)cancelCreate:(id)sender | |
51 { | |
52 [NSApp endModalSession:session]; | |
53 [createSheet orderOut:nil]; | |
54 [NSApp endSheet:createSheet]; | |
55 } | |
56 | |
57 -(IBAction)createDatabase:(id)sender | |
58 { | |
59 [self cancelCreate:self]; | |
60 | |
41 NSSavePanel* panel = [NSSavePanel savePanel]; | 61 NSSavePanel* panel = [NSSavePanel savePanel]; |
42 NSInteger response = [panel runModalForDirectory:NSHomeDirectory() file:@""]; | 62 NSInteger response = [panel runModalForDirectory:NSHomeDirectory() file:@""]; |
43 | 63 |
44 [results removeAllObjects]; | 64 [results removeAllObjects]; |
45 [tracksView reloadData]; | 65 [tracksView reloadData]; |
46 | 66 |
47 if(response == NSFileHandlingPanelOKButton) | 67 if(response == NSFileHandlingPanelOKButton) |
48 { | 68 { |
69 // Work out which extractor to use | |
70 NSString* extractor = @"adb_chroma"; | |
71 // TODO: This should be stored with the n3. | |
72 int dim; | |
73 switch([extractorOptions selectedTag]) | |
74 { | |
75 case 0: | |
76 extractor = @"adb_chroma"; | |
77 dim = 12; | |
78 break; | |
79 case 1: | |
80 extractor = @"adb_cq"; | |
81 dim = 48; | |
82 break; | |
83 case 2: | |
84 extractor = @"qm_chroma"; | |
85 dim = 12; | |
86 break; | |
87 case 3: | |
88 extractor = @"qm_mfcc"; | |
89 dim = 12; | |
90 break; | |
91 } | |
92 | |
93 // Calculate the max DB size | |
94 int vectors = ceil(([maxLengthField doubleValue] * 60) / ([hopSizeField doubleValue] / 44100)); | |
95 int numtracks = [maxTracksField intValue]; | |
96 int datasize = ceil((numtracks * vectors * dim * 8) / 1024 / 1024); // In MB | |
97 | |
49 // TODO: Refactor this into a 'tidy' method. | 98 // TODO: Refactor this into a 'tidy' method. |
50 // Tidy any existing references up. | 99 // Tidy any existing references up. |
51 if(db) | 100 if(db) |
52 { | 101 { |
53 audiodb_close(db); | 102 audiodb_close(db); |
54 } | 103 } |
55 | 104 |
56 if(dbFilename) | 105 if(dbFilename) |
57 { | 106 { |
58 [dbFilename release]; | 107 [dbFilename release]; |
59 [dbName release]; | 108 [dbName release]; |
60 [plistFilename release]; | 109 [plistFilename release]; |
61 } | 110 } |
62 | 111 |
63 // Create new db, and set flags. | 112 // Create new db, and set flags. |
64 db = audiodb_create([[panel filename] cStringUsingEncoding:NSUTF8StringEncoding], 0, 0, 0); | 113 db = audiodb_create([[panel filename] cStringUsingEncoding:NSUTF8StringEncoding], datasize, numtracks, dim); |
65 audiodb_l2norm(db); | 114 audiodb_l2norm(db); |
66 // audiodb_power(db); | 115 |
67 | |
68 // Store useful paths. | 116 // Store useful paths. |
69 dbName = [[[panel URL] relativePath] retain]; | 117 dbName = [[[panel URL] relativePath] retain]; |
70 dbFilename = [[panel filename] retain]; | 118 dbFilename = [[panel filename] retain]; |
71 plistFilename = [[NSString stringWithFormat:@"%@.plist", [dbFilename stringByDeletingPathExtension]] retain]; | 119 plistFilename = [[NSString stringWithFormat:@"%@.plist", [dbFilename stringByDeletingPathExtension]] retain]; |
72 | 120 |
73 // Create the plist file (contains mapping from filename to key). | 121 // Create the plist file (contains mapping from filename to key). |
122 dbState = [[NSMutableDictionary alloc] init]; | |
74 trackMap = [[NSMutableDictionary alloc] init]; | 123 trackMap = [[NSMutableDictionary alloc] init]; |
75 [trackMap writeToFile:plistFilename atomically:YES]; | 124 [dbState setValue:trackMap forKey:@"tracks"]; |
76 | 125 [dbState setValue:extractor forKey:@"extractor"]; |
126 [dbState setValue:[hopSizeField stringValue] forKey:@"hopsize"]; | |
127 [dbState setValue:[windowSizeField stringValue] forKey:@"windowsize"]; | |
128 [dbState writeToFile:plistFilename atomically:YES]; | |
129 | |
77 [queryKey setStringValue:@"None Selected"]; | 130 [queryKey setStringValue:@"None Selected"]; |
78 [self updateStatus]; | 131 [self updateStatus]; |
79 } | 132 } |
80 } | 133 } |
81 | 134 |
100 { | 153 { |
101 NSLog(@"Tidy up filenames"); | 154 NSLog(@"Tidy up filenames"); |
102 [dbFilename release]; | 155 [dbFilename release]; |
103 [dbName release]; | 156 [dbName release]; |
104 [plistFilename release]; | 157 [plistFilename release]; |
158 [trackMap release]; | |
159 [dbState release]; | |
105 } | 160 } |
106 | 161 |
107 // Store useful paths. | 162 // Store useful paths. |
108 NSLog(@"Open"); | 163 NSLog(@"Open"); |
109 db = audiodb_open([[panel filename] cStringUsingEncoding:NSUTF8StringEncoding], O_RDONLY); | 164 db = audiodb_open([[panel filename] cStringUsingEncoding:NSUTF8StringEncoding], O_RDONLY); |
127 NSMutableString *trackVal = [[NSMutableString alloc] init]; | 182 NSMutableString *trackVal = [[NSMutableString alloc] init]; |
128 [trackVal appendFormat:@"%s", liszt_results->entries[k].key]; | 183 [trackVal appendFormat:@"%s", liszt_results->entries[k].key]; |
129 } | 184 } |
130 | 185 |
131 audiodb_liszt_free_results(db, liszt_results); | 186 audiodb_liszt_free_results(db, liszt_results); |
132 trackMap = [[[NSMutableDictionary alloc] initWithContentsOfFile:plistFilename] retain]; | 187 dbState = [[[NSMutableDictionary alloc] initWithContentsOfFile:plistFilename] retain]; |
188 trackMap = [[dbState objectForKey:@"tracks"] retain]; | |
189 | |
133 NSLog(@"Size: %d", [trackMap count]); | 190 NSLog(@"Size: %d", [trackMap count]); |
134 } | 191 } |
135 } | 192 } |
136 | 193 |
137 /** | 194 /** |
157 [playResultButton setEnabled:FALSE]; | 214 [playResultButton setEnabled:FALSE]; |
158 } | 215 } |
159 } | 216 } |
160 | 217 |
161 /** | 218 /** |
162 * Get user's import choices. | |
163 */ | |
164 -(IBAction)importAudio:(id)sender | |
165 { | |
166 [NSApp beginSheet:importSheet modalForWindow:mainWindow modalDelegate:self didEndSelector:NULL contextInfo:nil]; | |
167 session = [NSApp beginModalSessionForWindow: importSheet]; | |
168 [NSApp runModalSession:session]; | |
169 } | |
170 | |
171 /** | |
172 * Cancel the import (at configuration time). | |
173 */ | |
174 -(IBAction)cancelImport:(id)sender; | |
175 { | |
176 [NSApp endModalSession:session]; | |
177 [importSheet orderOut:nil]; | |
178 [NSApp endSheet:importSheet]; | |
179 } | |
180 | |
181 /** | |
182 * Choose the file(s) to be imported. | 219 * Choose the file(s) to be imported. |
183 * TODO: Currently handles the import process too - split this off. | 220 * TODO: Currently handles the import process too - split this off. |
184 */ | 221 */ |
185 -(IBAction)selectFiles:(id)sender | 222 -(IBAction)importAudio:(id)sender |
186 { | 223 { |
187 [tracksView reloadData]; | 224 [tracksView reloadData]; |
188 | 225 |
189 NSArray *fileTypes = [NSArray arrayWithObject:@"wav"]; | 226 NSArray *fileTypes = [NSArray arrayWithObject:@"wav"]; |
190 NSOpenPanel* panel = [NSOpenPanel openPanel]; | 227 NSOpenPanel* panel = [NSOpenPanel openPanel]; |
191 [panel setAllowsMultipleSelection:TRUE]; | 228 [panel setAllowsMultipleSelection:TRUE]; |
192 NSInteger response = [panel runModalForDirectory:NSHomeDirectory() file:@"" types:fileTypes]; | 229 NSInteger response = [panel runModalForDirectory:NSHomeDirectory() file:@"" types:fileTypes]; |
193 if(response == NSFileHandlingPanelOKButton) | 230 if(response == NSFileHandlingPanelOKButton) |
194 { | 231 { |
195 NSRect newFrame; | |
196 | |
197 [extractingBox setHidden:FALSE]; | |
198 newFrame.origin.x = [importSheet frame].origin.x; | |
199 newFrame.origin.y = [importSheet frame].origin.y - [extractingBox frame].size.height; | |
200 newFrame.size.width = [importSheet frame].size.width; | |
201 newFrame.size.height = [importSheet frame].size.height + [extractingBox frame].size.height; | |
202 | |
203 [indicator startAnimation:self]; | 232 [indicator startAnimation:self]; |
204 [importSheet setFrame:newFrame display:YES animate:YES]; | 233 |
234 [NSApp beginSheet:importSheet modalForWindow:mainWindow modalDelegate:self didEndSelector:NULL contextInfo:nil]; | |
235 session = [NSApp beginModalSessionForWindow: importSheet]; | |
236 [NSApp runModalSession:session]; | |
205 | 237 |
206 NSArray *filesToOpen = [panel filenames]; | 238 NSArray *filesToOpen = [panel filenames]; |
207 | 239 |
208 NSLog(@"Begin import"); | 240 NSString* extractor = [dbState objectForKey:@"extractor"]; |
209 | 241 NSString* extractorPath = [NSString stringWithFormat:@"/Users/mikej/Development/audioDB/examples/iAudioDB/rdf/%@.n3", extractor]; |
210 /* | 242 |
211 vamp:vamp-audiodb-plugins:cq:cq | 243 // Create the customized extractor config |
212 vamp:vamp-audiodb-plugins:chromagram:chroma | 244 NSString* extractorContent = [NSString stringWithContentsOfFile:extractorPath]; |
213 vamp:qm-vamp-plugins:qm-mfcc:coefficients | 245 NSString* hopStr = [dbState objectForKey:@"hopsize"]; |
214 vamp:qm-vamp-plugins:qm-chromagram:chromagram | 246 NSString* winStr = [dbState objectForKey:@"windowsize"]; |
215 */ | 247 NSString* newContent = [[extractorContent stringByReplacingOccurrencesOfString:@"HOP_SIZE" withString:hopStr] |
216 | 248 stringByReplacingOccurrencesOfString:@"WINDOW_SIZE" withString:winStr]; |
217 | 249 NSString* n3FileName = [NSTemporaryDirectory() stringByAppendingPathComponent:@"extractor_config.n3"]; |
218 // adb_chroma | 250 |
219 // adb_cq | 251 NSError* error; |
220 // qm_chroma | 252 [newContent writeToFile:n3FileName atomically:YES encoding:NSASCIIStringEncoding error:&error]; |
221 // qm_mfcc | |
222 | |
223 // Work out which extractor to use | |
224 NSString* extractor = @"chromagram"; | |
225 switch([extractorOptions selectedTag]) | |
226 { | |
227 case 0: | |
228 extractor = @"adb_chroma"; | |
229 break; | |
230 case 1: | |
231 extractor = @"adb_cq"; | |
232 break; | |
233 case 2: | |
234 extractor = @"qm_chroma"; | |
235 break; | |
236 case 3: | |
237 extractor = @"qm_mfcc"; | |
238 break; | |
239 } | |
240 | |
241 | 253 |
242 for(int i=0; i<[filesToOpen count]; i++) | 254 for(int i=0; i<[filesToOpen count]; i++) |
243 { | 255 { |
244 audiodb_close(db); | 256 audiodb_close(db); |
245 NSString* tempFileTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent:@"features.XXXXXX"]; | 257 NSString* tempFileTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent:@"features.XXXXXX"]; |
252 free(tempFileNameCString); | 264 free(tempFileNameCString); |
253 | 265 |
254 NSTask* task = [[NSTask alloc] init]; | 266 NSTask* task = [[NSTask alloc] init]; |
255 | 267 |
256 [task setLaunchPath:@"/usr/local/bin/sonic-annotator"]; | 268 [task setLaunchPath:@"/usr/local/bin/sonic-annotator"]; |
257 | |
258 NSString* extractorPath = [NSString stringWithFormat:@"/Users/mikej/Development/audioDB/examples/iAudioDB/rdf/%@.n3", extractor]; | |
259 NSLog(@"Extractor path: %@", extractorPath); | |
260 NSArray* args; | 269 NSArray* args; |
261 args = [NSArray arrayWithObjects:@"-t", extractorPath, @"-w", @"rdf", @"-r", @"--rdf-network", @"--rdf-one-file", featuresFileName, @"--rdf-force", [filesToOpen objectAtIndex:i], nil]; | 270 args = [NSArray arrayWithObjects:@"-t", n3FileName, @"-w", @"rdf", @"-r", @"--rdf-network", @"--rdf-one-file", featuresFileName, @"--rdf-force", [filesToOpen objectAtIndex:i], nil]; |
262 [task setArguments:args]; | 271 [task setArguments:args]; |
263 [task launch]; | 272 [task launch]; |
264 [task waitUntilExit]; | 273 [task waitUntilExit]; |
265 [task release]; | 274 [task release]; |
266 | 275 |
272 [importTask waitUntilExit]; | 281 [importTask waitUntilExit]; |
273 [importTask release]; | 282 [importTask release]; |
274 | 283 |
275 NSString* val = [[filesToOpen objectAtIndex:i] retain]; | 284 NSString* val = [[filesToOpen objectAtIndex:i] retain]; |
276 NSString* key = [[[filesToOpen objectAtIndex:i] lastPathComponent] retain]; | 285 NSString* key = [[[filesToOpen objectAtIndex:i] lastPathComponent] retain]; |
277 /* | 286 |
278 adb_insert_t insert; | |
279 insert.features = [featuresFileName cStringUsingEncoding:NSUTF8StringEncoding]; | |
280 // insert.power = [powersFileName cStringUsingEncoding:NSUTF8StringEncoding]; | |
281 insert.times = NULL; | |
282 insert.key = [key cStringUsingEncoding:NSUTF8StringEncoding]; | |
283 | |
284 // Insert into db. | |
285 if(audiodb_insert(db, &insert)) | |
286 { | |
287 // TODO: Show an error message. | |
288 NSLog(@"Weep: %@ %@", featuresFileName, key); | |
289 continue; | |
290 }*/ | |
291 | |
292 // Update the plist store. | 287 // Update the plist store. |
293 [trackMap setValue:val forKey:key]; | 288 [trackMap setValue:val forKey:key]; |
294 [trackMap writeToFile:plistFilename atomically: YES]; | 289 [dbState writeToFile:plistFilename atomically: YES]; |
295 | 290 |
296 | 291 |
297 db = audiodb_open([dbFilename cStringUsingEncoding:NSUTF8StringEncoding], O_RDONLY); | 292 db = audiodb_open([dbFilename cStringUsingEncoding:NSUTF8StringEncoding], O_RDONLY); |
298 [self updateStatus]; | 293 [self updateStatus]; |
299 } | 294 } |
300 | |
301 newFrame.origin.x = [importSheet frame].origin.x; | |
302 newFrame.origin.y = [importSheet frame].origin.y + [extractingBox frame].size.height; | |
303 newFrame.size.width = [importSheet frame].size.width; | |
304 newFrame.size.height = [importSheet frame].size.height - [extractingBox frame].size.height; | |
305 | |
306 [importSheet setFrame:newFrame display:YES animate:YES]; | |
307 | 295 |
308 [NSApp endModalSession:session]; | 296 [NSApp endModalSession:session]; |
309 [importSheet orderOut:nil]; | 297 [importSheet orderOut:nil]; |
310 [NSApp endSheet:importSheet]; | 298 [NSApp endSheet:importSheet]; |
311 [indicator stopAnimation:self]; | 299 [indicator stopAnimation:self]; |
312 [extractingBox setHidden:TRUE]; | |
313 } | 300 } |
314 } | 301 } |
315 | 302 |
316 /** | 303 /** |
317 * Required table methods begin here. | 304 * Required table methods begin here. |