comparison examples/iAudioDB/AppController.m @ 687:e2f4924130ef

* Query parameters added (multi, length, etc) * Tweaks to status bar for more detailed info
author mas01mj
date Thu, 11 Mar 2010 17:19:15 +0000
parents e78e5a80b73d
children 8bc10774e56b
comparison
equal deleted inserted replaced
686:d9bb0dba8e7a 687:e2f4924130ef
3 // iAudioDB 3 // iAudioDB
4 // 4 //
5 // Created by Mike Jewell on 27/01/2010. 5 // Created by Mike Jewell on 27/01/2010.
6 // Copyright 2010 __MyCompanyName__. All rights reserved. 6 // Copyright 2010 __MyCompanyName__. All rights reserved.
7 // 7 //
8
9 #import "AppController.h" 8 #import "AppController.h"
9
10 10
11 11
12 @implementation AppController 12 @implementation AppController
13 13
14 -(id)init 14 -(id)init
93 // Calculate the max DB size 93 // Calculate the max DB size
94 int vectors = ceil(([maxLengthField doubleValue] * 60) / ([hopSizeField doubleValue] / 44100)); 94 int vectors = ceil(([maxLengthField doubleValue] * 60) / ([hopSizeField doubleValue] / 44100));
95 int numtracks = [maxTracksField intValue]; 95 int numtracks = [maxTracksField intValue];
96 int datasize = ceil((numtracks * vectors * dim * 8) / 1024 / 1024); // In MB 96 int datasize = ceil((numtracks * vectors * dim * 8) / 1024 / 1024); // In MB
97 97
98 // TODO: Refactor this into a 'tidy' method. 98 [self reset];
99 // Tidy any existing references up.
100 if(db)
101 {
102 audiodb_close(db);
103 }
104
105 if(dbFilename)
106 {
107 [dbFilename release];
108 [dbName release];
109 [plistFilename release];
110 }
111 99
112 // Create new db, and set flags. 100 // Create new db, and set flags.
113 db = audiodb_create([[panel filename] cStringUsingEncoding:NSUTF8StringEncoding], datasize, numtracks, dim); 101 db = audiodb_create([[panel filename] cStringUsingEncoding:NSUTF8StringEncoding], datasize, numtracks, dim);
114 audiodb_l2norm(db); 102 audiodb_l2norm(db);
115 103
130 [queryKey setStringValue:@"None Selected"]; 118 [queryKey setStringValue:@"None Selected"];
131 [self updateStatus]; 119 [self updateStatus];
132 } 120 }
133 } 121 }
134 122
123 -(void)reset
124 {
125 // Tidy any existing references up.
126 if(db)
127 {
128 NSLog(@"Close db");
129 audiodb_close(db);
130 }
131
132 if(dbFilename)
133 {
134 NSLog(@"Tidy up filenames");
135 [dbFilename release];
136 [dbName release];
137 [plistFilename release];
138 [trackMap release];
139 [dbState release];
140 }
141
142 // Reset query flags
143 [queryPath setStringValue: @"No file selected"];
144 [queryLengthSeconds setDoubleValue:0];
145 [queryLengthVectors setDoubleValue:0];
146 [multipleCheckBox setState:NSOnState];
147 }
148
135 /** 149 /**
136 * Open an existing adb (which must have a plist) 150 * Open an existing adb (which must have a plist)
137 */ 151 */
138 -(IBAction)openDatabase:(id)sender 152 -(IBAction)openDatabase:(id)sender
139 { 153 {
140 NSArray *fileTypes = [NSArray arrayWithObject:@"adb"]; 154 NSArray *fileTypes = [NSArray arrayWithObject:@"adb"];
141 NSOpenPanel* panel = [NSOpenPanel openPanel]; 155 NSOpenPanel* panel = [NSOpenPanel openPanel];
142 NSInteger response = [panel runModalForDirectory:NSHomeDirectory() file:@"" types:fileTypes]; 156 NSInteger response = [panel runModalForDirectory:NSHomeDirectory() file:@"" types:fileTypes];
143 if(response == NSFileHandlingPanelOKButton) 157 if(response == NSFileHandlingPanelOKButton)
144 { 158 {
145 // Tidy any existing references up. 159 [self reset];
146 if(db)
147 {
148 NSLog(@"Close db");
149 audiodb_close(db);
150 }
151
152 if(dbFilename)
153 {
154 NSLog(@"Tidy up filenames");
155 [dbFilename release];
156 [dbName release];
157 [plistFilename release];
158 [trackMap release];
159 [dbState release];
160 }
161 160
162 // Store useful paths. 161 // Store useful paths.
163 NSLog(@"Open"); 162 NSLog(@"Open");
164 db = audiodb_open([[panel filename] cStringUsingEncoding:NSUTF8StringEncoding], O_RDONLY); 163 db = audiodb_open([[panel filename] cStringUsingEncoding:NSUTF8StringEncoding], O_RDONLY);
165 dbName = [[[panel URL] relativePath] retain]; 164 dbName = [[[panel URL] relativePath] retain];
171 // Clear out any old results. 170 // Clear out any old results.
172 [results removeAllObjects]; 171 [results removeAllObjects];
173 [tracksView reloadData]; 172 [tracksView reloadData];
174 173
175 [queryKey setStringValue:@"None Selected"]; 174 [queryKey setStringValue:@"None Selected"];
176 [self updateStatus];
177 175
178 adb_liszt_results_t* liszt_results = audiodb_liszt(db); 176 adb_liszt_results_t* liszt_results = audiodb_liszt(db);
179 177
180 for(int k=0; k<liszt_results->nresults; k++) 178 for(int k=0; k<liszt_results->nresults; k++)
181 { 179 {
185 183
186 audiodb_liszt_free_results(db, liszt_results); 184 audiodb_liszt_free_results(db, liszt_results);
187 dbState = [[[NSMutableDictionary alloc] initWithContentsOfFile:plistFilename] retain]; 185 dbState = [[[NSMutableDictionary alloc] initWithContentsOfFile:plistFilename] retain];
188 trackMap = [[dbState objectForKey:@"tracks"] retain]; 186 trackMap = [[dbState objectForKey:@"tracks"] retain];
189 187
188 [self updateStatus];
189
190 NSLog(@"Size: %d", [trackMap count]); 190 NSLog(@"Size: %d", [trackMap count]);
191 } 191 }
192 }
193
194 -(IBAction)pathAction:(id)sender
195 {
196 NSLog(@"Path action");
192 } 197 }
193 198
194 /** 199 /**
195 * Update button states and status field based on current state. 200 * Update button states and status field based on current state.
196 */ 201 */
201 { 206 {
202 NSLog(@"Got a db"); 207 NSLog(@"Got a db");
203 adb_status_t *status = (adb_status_t *)malloc(sizeof(adb_status_t)); 208 adb_status_t *status = (adb_status_t *)malloc(sizeof(adb_status_t));
204 int flags; 209 int flags;
205 flags = audiodb_status(db, status); 210 flags = audiodb_status(db, status);
206 [statusField setStringValue: [NSString stringWithFormat:@"Database: %@ Dimensions: %d Files: %d", dbName, status->dim, status->numFiles]]; 211 [statusField setStringValue: [NSString stringWithFormat:@"%@ Dim: %d Files: %d Hop: %@ Win: %@ Ext: %@",
207 [chooseButton setEnabled:YES]; 212 dbName,
213 status->dim,
214 status->numFiles,
215 [dbState objectForKey:@"hopsize"],
216 [dbState objectForKey:@"windowsize"],
217 [dbState objectForKey:@"extractor"]]];
218 [performQueryButton setEnabled:YES];
208 } 219 }
209 else 220 else
210 { 221 {
211 NSLog(@"No db"); 222 NSLog(@"No db");
212 [chooseButton setEnabled:NO]; 223 [performQueryButton setEnabled:NO];
213 [playBothButton setEnabled:FALSE]; 224 [playBothButton setEnabled:FALSE];
214 [playResultButton setEnabled:FALSE]; 225 [playResultButton setEnabled:FALSE];
215 } 226 }
216 } 227 }
217 228
238 NSArray *filesToOpen = [panel filenames]; 249 NSArray *filesToOpen = [panel filenames];
239 250
240 NSString* extractor = [dbState objectForKey:@"extractor"]; 251 NSString* extractor = [dbState objectForKey:@"extractor"];
241 NSString* extractorPath = [NSString stringWithFormat:@"/Users/mikej/Development/audioDB/examples/iAudioDB/rdf/%@.n3", extractor]; 252 NSString* extractorPath = [NSString stringWithFormat:@"/Users/mikej/Development/audioDB/examples/iAudioDB/rdf/%@.n3", extractor];
242 253
254 // TODO Shift this process into a separate function.
243 // Create the customized extractor config 255 // Create the customized extractor config
244 NSString* extractorContent = [NSString stringWithContentsOfFile:extractorPath]; 256 NSString* extractorContent = [NSString stringWithContentsOfFile:extractorPath];
245 NSString* hopStr = [dbState objectForKey:@"hopsize"]; 257 NSString* hopStr = [dbState objectForKey:@"hopsize"];
246 NSString* winStr = [dbState objectForKey:@"windowsize"]; 258 NSString* winStr = [dbState objectForKey:@"windowsize"];
247 NSString* newContent = [[extractorContent stringByReplacingOccurrencesOfString:@"HOP_SIZE" withString:hopStr] 259 NSString* newContent = [[extractorContent stringByReplacingOccurrencesOfString:@"HOP_SIZE" withString:hopStr]
497 /** 509 /**
498 * Select an audio file, determine the key, and fire off a query. 510 * Select an audio file, determine the key, and fire off a query.
499 */ 511 */
500 -(IBAction)chooseQuery:(id)sender 512 -(IBAction)chooseQuery:(id)sender
501 { 513 {
514 [NSApp beginSheet:querySheet modalForWindow:mainWindow modalDelegate:self didEndSelector:NULL contextInfo:nil];
515 session = [NSApp beginModalSessionForWindow:querySheet];
516 [NSApp runModalSession:session];
517 }
518
519
520 -(IBAction)selectQueryFile:(id)sender
521 {
502 NSArray* fileTypes = [NSArray arrayWithObject:@"wav"]; 522 NSArray* fileTypes = [NSArray arrayWithObject:@"wav"];
503 NSOpenPanel* panel = [NSOpenPanel openPanel]; 523 NSOpenPanel* panel = [NSOpenPanel openPanel];
504 NSInteger response = [panel runModalForDirectory:NSHomeDirectory() file:@"" types:fileTypes]; 524 NSInteger response = [panel runModalForDirectory:NSHomeDirectory() file:@"" types:fileTypes];
505 if(response == NSFileHandlingPanelOKButton) 525 if(response == NSFileHandlingPanelOKButton)
506 { 526 {
507 NSLog(@"%@", [panel filename]);
508 // Grab key
509 NSArray* opts = [trackMap allKeysForObject:[panel filename]]; 527 NSArray* opts = [trackMap allKeysForObject:[panel filename]];
510 if([opts count] != 1) 528 if([opts count] != 1)
511 { 529 {
530 // TODO : Needs fixing!
531
512 NSAlert *alert = [[[NSAlert alloc] init] autorelease]; 532 NSAlert *alert = [[[NSAlert alloc] init] autorelease];
513 [alert addButtonWithTitle:@"OK"]; 533 [alert addButtonWithTitle:@"OK"];
514 [alert setMessageText:@"Track not found"]; 534 [alert setMessageText:@"Track not found"];
515 [alert setInformativeText:@"Make sure you have specified a valid track identifier."]; 535 [alert setInformativeText:@"Make sure you have specified a valid track identifier."];
516 [alert setAlertStyle:NSWarningAlertStyle]; 536 [alert setAlertStyle:NSWarningAlertStyle];
518 } 538 }
519 else 539 else
520 { 540 {
521 selectedKey = [opts objectAtIndex:0]; 541 selectedKey = [opts objectAtIndex:0];
522 [queryKey setStringValue:selectedKey]; 542 [queryKey setStringValue:selectedKey];
543 [queryPath setStringValue:selectedKey];
523 selectedFilename = [[panel filename] retain]; 544 selectedFilename = [[panel filename] retain];
524 [self performQuery]; 545
525 } 546 [self resetLengths:self];
526 } 547 }
548 }
549 }
550
551 -(IBAction)resetLengths:(id)sender
552 {
553 queryTrack = [[NSSound alloc] initWithContentsOfFile:selectedFilename byReference:YES];
554 NSLog(@"%f", [queryTrack duration]);
555 double samples = ([queryTrack duration]*44100);
556 double hopSize = [[dbState objectForKey:@"hopsize"] doubleValue];
557 double winSize = [[dbState objectForKey:@"windowsize"] doubleValue];
558
559 [queryLengthSeconds setDoubleValue:ceil([queryTrack duration])];
560 [queryLengthVectors setDoubleValue:ceil((samples-winSize)/hopSize)];
561
562 }
563
564 - (void)controlTextDidChange:(NSNotification *)nd
565 {
566 NSTextField *ed = [nd object];
567
568 double hopSize = [[dbState objectForKey:@"hopsize"] doubleValue];
569 double winSize = [[dbState objectForKey:@"windowsize"] doubleValue];
570
571 if (ed == queryLengthSeconds)
572 {
573 double secs = [queryLengthSeconds doubleValue];
574 if(secs > 0)
575 {
576 [queryLengthVectors setDoubleValue:ceil(((secs*44100)-winSize)/hopSize)];
577 }
578 }
579 if (ed == queryLengthVectors)
580 {
581 double vectors = [queryLengthVectors doubleValue];
582 if(vectors > 0)
583 {
584 [queryLengthSeconds setDoubleValue:ceil(((hopSize*vectors)+winSize)/44100)];
585 }
586 }
587 };
588
589 -(IBAction)cancelQuery:(id)sender
590 {
591 [NSApp endModalSession:session];
592 [querySheet orderOut:nil];
593 [NSApp endSheet:querySheet];
527 } 594 }
528 595
529 /** 596 /**
530 * Actually perform the query. TODO: Monolithic. 597 * Actually perform the query. TODO: Monolithic.
531 */ 598 */
532 -(void)performQuery 599 -(IBAction)performQuery:(id)sender
533 { 600 {
601 [NSApp endModalSession:session];
602 [querySheet orderOut:nil];
603 [NSApp endSheet:querySheet];
604
534 NSLog(@"Perform query! %@, %@", selectedKey, selectedFilename); 605 NSLog(@"Perform query! %@, %@", selectedKey, selectedFilename);
535 606
536 adb_query_spec_t *spec = (adb_query_spec_t *)malloc(sizeof(adb_query_spec_t)); 607 adb_query_spec_t *spec = (adb_query_spec_t *)malloc(sizeof(adb_query_spec_t));
537 spec->qid.datum = (adb_datum_t *)malloc(sizeof(adb_datum_t)); 608 spec->qid.datum = (adb_datum_t *)malloc(sizeof(adb_datum_t));
538 609
539 spec->qid.sequence_length = 20; 610 spec->qid.sequence_length = [queryLengthVectors doubleValue];
540 spec->qid.sequence_start = 0; 611 spec->qid.sequence_start = 0;
541 spec->qid.flags = 0; 612 spec->qid.flags = 0;
542
543 // spec->qid.flags = spec->qid.flags | ADB_QID_FLAG_EXHAUSTIVE; 613 // spec->qid.flags = spec->qid.flags | ADB_QID_FLAG_EXHAUSTIVE;
614
544 spec->params.accumulation = ADB_ACCUMULATION_PER_TRACK; 615 spec->params.accumulation = ADB_ACCUMULATION_PER_TRACK;
616
617 if([multipleCheckBox state] == NSOnState)
618 {
619 spec->params.npoints = 10;
620 }
621 else
622 {
623 spec->params.npoints = 1;
624 }
625
545 spec->params.distance = ADB_DISTANCE_EUCLIDEAN_NORMED; 626 spec->params.distance = ADB_DISTANCE_EUCLIDEAN_NORMED;
546 627
547 spec->params.npoints = 1;
548 spec->params.ntracks = 100; 628 spec->params.ntracks = 100;
549 //spec->refine.radius = 5.0; 629 //spec->refine.radius = 5.0;
550 // spec->refine.absolute_threshold = -6; 630 // spec->refine.absolute_threshold = -6;
551 // spec->refine.relative_threshold = 10; 631 // spec->refine.relative_threshold = 10;
552 // spec->refine.duration_ratio = 0; 632 // spec->refine.duration_ratio = 0;