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.