Mercurial > hg > audiodb
comparison examples/iAudioDB/AppController.m @ 702:6d8539709d9c
Switching over to use sample rate where possible - poss bug in query start specification.
author | mas01mj |
---|---|
date | Fri, 30 Apr 2010 14:57:30 +0000 |
parents | e21abbac820e |
children | 14b48e1b9ca4 |
comparison
equal
deleted
inserted
replaced
701:e21abbac820e | 702:6d8539709d9c |
---|---|
91 dim = 12; | 91 dim = 12; |
92 break; | 92 break; |
93 } | 93 } |
94 | 94 |
95 // Calculate the max DB size | 95 // Calculate the max DB size |
96 int vectors = ceil(([maxLengthField doubleValue] * 60.0f) / ([hopSizeField doubleValue] / 44100.0f)); | 96 int vectors = ceil(([maxLengthField doubleValue] * 60.0f) / (([hopSizeField doubleValue] / 1000) * 44100.0f)); |
97 NSLog(@"Vectors: %d", vectors); | |
97 int numtracks = [maxTracksField intValue]; | 98 int numtracks = [maxTracksField intValue]; |
98 int datasize = ceil((numtracks * vectors * dim * 8.0f) / 1024.0f / 1024.0f); // In MB | 99 int datasize = ceil((numtracks * vectors * dim * 8.0f) / 1024.0f / 1024.0f); // In MB |
99 | 100 |
100 [self reset]; | 101 [self reset]; |
101 | 102 |
259 AudioFileClose(audioFile); | 260 AudioFileClose(audioFile); |
260 | 261 |
261 return sampleRate; | 262 return sampleRate; |
262 } | 263 } |
263 | 264 |
265 -(UInt64)getHopSizeInSamples:(NSString *)filename | |
266 { | |
267 NSString* hopStr = [dbState objectForKey:@"hopsize"]; | |
268 return round([self getSampleRate:filename] * ([hopStr doubleValue] / 1000)); | |
269 } | |
270 | |
271 -(int)nearestPow2:(int)x | |
272 { | |
273 if (x < 0) | |
274 return 0; | |
275 --x; | |
276 x |= x >> 1; | |
277 x |= x >> 2; | |
278 x |= x >> 4; | |
279 x |= x >> 8; | |
280 x |= x >> 16; | |
281 return x+1; | |
282 } | |
283 | |
264 -(void)importFile:(NSString *)filename withExtractorConfig:(NSString *)extractorPath | 284 -(void)importFile:(NSString *)filename withExtractorConfig:(NSString *)extractorPath |
265 { | 285 { |
266 // Create the extractor configuration | 286 // Create the extractor configuration |
267 UInt64 sampleRate = [self getSampleRate:filename]; | 287 int hopSizeSamples = [self getHopSizeInSamples:filename]; |
288 int windowSizeSamples = [self nearestPow2:(hopSizeSamples*8)]; | |
268 | 289 |
269 NSString* extractorContent = [NSString stringWithContentsOfFile:extractorPath]; | 290 NSString* extractorContent = [NSString stringWithContentsOfFile:extractorPath]; |
270 NSString* hopStr = [dbState objectForKey:@"hopsize"]; | 291 NSString* newContent = [[extractorContent stringByReplacingOccurrencesOfString:@"HOP_SIZE" withString:[NSString stringWithFormat:@"%d", hopSizeSamples]] |
271 NSString* newContent = [[extractorContent stringByReplacingOccurrencesOfString:@"HOP_SIZE" withString:hopStr] | 292 stringByReplacingOccurrencesOfString:@"WINDOW_SIZE" withString:[NSString stringWithFormat:@"%d", windowSizeSamples]]; |
272 stringByReplacingOccurrencesOfString:@"WINDOW_SIZE" withString:[NSString stringWithFormat:@"%d", [hopStr intValue] * 8]]; | |
273 NSString* n3FileName = [NSTemporaryDirectory() stringByAppendingPathComponent:@"extractor_config.n3"]; | 293 NSString* n3FileName = [NSTemporaryDirectory() stringByAppendingPathComponent:@"extractor_config.n3"]; |
274 | 294 NSLog(newContent); |
275 NSError* error; | 295 NSError* error; |
276 [newContent writeToFile:n3FileName atomically:YES encoding:NSASCIIStringEncoding error:&error]; | 296 [newContent writeToFile:n3FileName atomically:YES encoding:NSASCIIStringEncoding error:&error]; |
277 | 297 |
278 // Create the temp file for the extracted features | 298 // Create the temp file for the extracted features |
279 NSString* tempFileTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent:@"features.XXXXXX"]; | 299 NSString* tempFileTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent:@"features.XXXXXX"]; |
313 | 333 |
314 } | 334 } |
315 | 335 |
316 /** | 336 /** |
317 * Choose the file(s) to be imported. | 337 * Choose the file(s) to be imported. |
318 * TODO: Currently handles the import process too - split this off. | |
319 */ | 338 */ |
320 -(IBAction)importAudio:(id)sender | 339 -(IBAction)importAudio:(id)sender |
321 { | 340 { |
322 [tracksView reloadData]; | 341 [tracksView reloadData]; |
323 | 342 |
336 NSArray *filesToOpen = [panel filenames]; | 355 NSArray *filesToOpen = [panel filenames]; |
337 | 356 |
338 NSString* extractor = [dbState objectForKey:@"extractor"]; | 357 NSString* extractor = [dbState objectForKey:@"extractor"]; |
339 NSString* extractorPath = [NSString stringWithFormat:@"/Applications/iAudioDB.app/rdf/%@.n3", extractor]; | 358 NSString* extractorPath = [NSString stringWithFormat:@"/Applications/iAudioDB.app/rdf/%@.n3", extractor]; |
340 | 359 |
341 // TODO Shift this process into a separate function. | |
342 // Create the customized extractor config | |
343 /* NSString* extractorContent = [NSString stringWithContentsOfFile:extractorPath]; | |
344 NSString* hopStr = [dbState objectForKey:@"hopsize"]; | |
345 NSString* winStr = [dbState objectForKey:@"windowsize"]; | |
346 NSString* newContent = [[extractorContent stringByReplacingOccurrencesOfString:@"HOP_SIZE" withString:hopStr] | |
347 stringByReplacingOccurrencesOfString:@"WINDOW_SIZE" withString:winStr]; | |
348 NSString* n3FileName = [NSTemporaryDirectory() stringByAppendingPathComponent:@"extractor_config.n3"]; | |
349 | |
350 NSError* error; | |
351 [newContent writeToFile:n3FileName atomically:YES encoding:NSASCIIStringEncoding error:&error]; | |
352 */ | |
353 for(int i=0; i<[filesToOpen count]; i++) | 360 for(int i=0; i<[filesToOpen count]; i++) |
354 { | 361 { |
355 audiodb_close(db); | 362 audiodb_close(db); |
356 | 363 |
357 // Get the sample rate for the audio file | 364 // Get the sample rate for the audio file |
358 | 365 |
359 [self importFile:[filesToOpen objectAtIndex:i] withExtractorConfig:extractorPath]; | 366 [self importFile:[filesToOpen objectAtIndex:i] withExtractorConfig:extractorPath]; |
360 | |
361 /* NSString* tempFileTemplate = [NSTemporaryDirectory() stringByAppendingPathComponent:@"features.XXXXXX"]; | |
362 const char* tempFileTemplateCString = [tempFileTemplate fileSystemRepresentation]; | |
363 char* tempFileNameCString = (char *)malloc(strlen(tempFileTemplateCString) + 1); | |
364 strcpy(tempFileNameCString, tempFileTemplateCString); | |
365 mktemp(tempFileNameCString); | |
366 | |
367 NSString* featuresFileName = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:tempFileNameCString length:strlen(tempFileNameCString)]; | |
368 free(tempFileNameCString); | |
369 | |
370 NSTask* task = [[NSTask alloc] init]; | |
371 | |
372 [task setLaunchPath:@"/usr/local/bin/sonic-annotator"]; | |
373 NSArray* args; | |
374 args = [NSArray arrayWithObjects:@"-t", n3FileName, @"-w", @"rdf", @"-r", @"--rdf-network", @"--rdf-one-file", featuresFileName, @"--rdf-force", [filesToOpen objectAtIndex:i], nil]; | |
375 [task setArguments:args]; | |
376 [task launch]; | |
377 [task waitUntilExit]; | |
378 [task release]; | |
379 | |
380 NSTask* importTask = [[NSTask alloc] init]; | |
381 [importTask setLaunchPath:@"/usr/local/bin/populate"]; | |
382 args = [NSArray arrayWithObjects:featuresFileName, dbFilename, nil]; | |
383 [importTask setArguments:args]; | |
384 [importTask launch]; | |
385 [importTask waitUntilExit]; | |
386 [importTask release]; | |
387 | |
388 NSString* val = [[filesToOpen objectAtIndex:i] retain]; | |
389 NSString* key = [[[filesToOpen objectAtIndex:i] lastPathComponent] retain]; | |
390 | |
391 // Update the plist store. | |
392 [trackMap setValue:val forKey:key]; | |
393 [dbState writeToFile:plistFilename atomically: YES]; | |
394 */ | |
395 | |
396 db = audiodb_open([dbFilename cStringUsingEncoding:NSUTF8StringEncoding], O_RDONLY); | 367 db = audiodb_open([dbFilename cStringUsingEncoding:NSUTF8StringEncoding], O_RDONLY); |
397 [self updateStatus]; | 368 [self updateStatus]; |
398 } | 369 } |
399 | 370 |
400 [NSApp endModalSession:session]; | 371 [NSApp endModalSession:session]; |
646 | 617 |
647 -(IBAction)resetLengths:(id)sender | 618 -(IBAction)resetLengths:(id)sender |
648 { | 619 { |
649 queryTrack = [[NSSound alloc] initWithContentsOfFile:selectedFilename byReference:YES]; | 620 queryTrack = [[NSSound alloc] initWithContentsOfFile:selectedFilename byReference:YES]; |
650 | 621 |
651 double samples = ([queryTrack duration]*44100.0f); | 622 int sampleRate = [self getSampleRate:selectedFilename]; |
652 double hopSize = [[dbState objectForKey:@"hopsize"] doubleValue]; | 623 int hopSize = [self getHopSizeInSamples:selectedFilename]; |
653 double winSize = [[dbState objectForKey:@"windowsize"] doubleValue]; | 624 int winSize = [self nearestPow2:(hopSize*8)]; |
625 | |
626 double samples = ([queryTrack duration]*sampleRate); | |
654 | 627 |
655 [queryLengthSeconds setDoubleValue:[queryTrack duration]]; | 628 [queryLengthSeconds setDoubleValue:[queryTrack duration]]; |
656 [queryLengthVectors setDoubleValue:ceil((samples-winSize)/hopSize)]; | 629 [queryLengthVectors setDoubleValue:ceil((samples-winSize)/hopSize)]; |
657 | 630 |
658 // For now, go with 0 | 631 // For now, go with 0 |
663 [queryLengthVectors setEnabled:YES]; | 636 [queryLengthVectors setEnabled:YES]; |
664 [queryStartSeconds setEnabled:YES]; | 637 [queryStartSeconds setEnabled:YES]; |
665 [queryStartVectors setEnabled:YES]; | 638 [queryStartVectors setEnabled:YES]; |
666 [resetButton setEnabled:YES]; | 639 [resetButton setEnabled:YES]; |
667 [multipleCheckBox setEnabled:YES]; | 640 [multipleCheckBox setEnabled:YES]; |
641 [queryButton setEnabled:YES]; | |
668 | 642 |
669 } | 643 } |
670 | 644 |
671 - (void)controlTextDidChange:(NSNotification *)nd | 645 - (void)controlTextDidChange:(NSNotification *)nd |
672 { | 646 { |
673 NSTextField *ed = [nd object]; | 647 NSTextField *ed = [nd object]; |
674 | 648 |
675 double hopSize = [[dbState objectForKey:@"hopsize"] doubleValue]; | 649 int sampleRate = [self getSampleRate:selectedFilename]; |
676 double winSize = [[dbState objectForKey:@"windowsize"] doubleValue]; | 650 int hopSize = [self getHopSizeInSamples:selectedFilename]; |
651 int winSize = [self nearestPow2:(hopSize*8)]; | |
677 | 652 |
678 if(!queryTrack) | 653 if(!queryTrack) |
679 { | 654 { |
680 queryTrack = [[NSSound alloc] initWithContentsOfFile:selectedFilename byReference:YES]; | 655 queryTrack = [[NSSound alloc] initWithContentsOfFile:selectedFilename byReference:YES]; |
681 } | 656 } |
682 | 657 |
683 double totalDuration = [queryTrack duration]; | 658 double totalDuration = [queryTrack duration]; |
684 double samples = totalDuration * 44100.0f; | 659 double samples = totalDuration * sampleRate; |
685 double totalVectors = ceil((samples-winSize)/hopSize); | 660 double totalVectors = ceil((samples-winSize)/hopSize); |
686 | 661 |
662 | |
687 double lengthSecs = [queryLengthSeconds doubleValue]; | 663 double lengthSecs = [queryLengthSeconds doubleValue]; |
688 double startSecs = [queryStartSeconds doubleValue]; | 664 double startSecs = [queryStartSeconds doubleValue]; |
689 double lengthVectors = [queryLengthVectors doubleValue]; | 665 double lengthVectors = [queryLengthVectors doubleValue]; |
690 double startVectors = [queryStartVectors doubleValue]; | 666 double startVectors = [queryStartVectors doubleValue]; |
691 | 667 |
692 // Query Length | 668 // Query Length |
693 if (ed == queryLengthSeconds) | 669 if (ed == queryLengthSeconds) |
694 { | 670 { |
695 if(lengthSecs >= 0) | 671 if(lengthSecs >= 0) |
696 { | 672 { |
697 lengthVectors = ceil(((lengthSecs*44100.0f)-winSize)/hopSize); | 673 lengthVectors = ceil(((lengthSecs*sampleRate)-winSize)/hopSize); |
698 if(lengthVectors < 0) {lengthVectors = 0; } | 674 if(lengthVectors < 0) {lengthVectors = 0; } |
699 [queryLengthVectors setDoubleValue:lengthVectors]; | 675 [queryLengthVectors setDoubleValue:lengthVectors]; |
700 | |
701 } | 676 } |
702 } | 677 } |
703 | 678 |
704 if (ed == queryLengthVectors) | 679 if (ed == queryLengthVectors) |
705 { | 680 { |
706 if(lengthVectors >= 0) | 681 if(lengthVectors >= 0) |
707 { | 682 { |
708 lengthSecs = ((hopSize*lengthVectors)+winSize)/44100.0f; | 683 lengthSecs = ((hopSize*lengthVectors)+winSize)/sampleRate; |
709 if(lengthSecs < 0) { lengthSecs = 0; } | 684 if(lengthSecs < 0) { lengthSecs = 0; } |
710 [queryLengthSeconds setDoubleValue:lengthSecs]; | 685 [queryLengthSeconds setDoubleValue:lengthSecs]; |
711 } | 686 } |
712 } | 687 } |
713 | 688 |
714 // Query start | 689 // Query start |
715 if (ed == queryStartSeconds) | 690 if (ed == queryStartSeconds) |
716 { | 691 { |
717 if(startSecs >= 0) | 692 if(startSecs >= 0) |
718 { | 693 { |
719 startVectors = ceil(((startSecs*44100.0f)-winSize)/hopSize); | 694 startVectors = ceil(((startSecs*sampleRate)-winSize)/hopSize); |
720 if(startVectors < 0) { startVectors = 0; } | 695 if(startVectors < 0) { startVectors = 0; } |
721 [queryStartVectors setDoubleValue:startVectors]; | 696 [queryStartVectors setDoubleValue:startVectors]; |
722 } | 697 } |
723 } | 698 } |
724 if (ed == queryStartVectors) | 699 if (ed == queryStartVectors) |
725 { | 700 { |
726 if(startVectors >= 0) | 701 if(startVectors >= 0) |
727 { | 702 { |
728 startSecs = ((hopSize*startVectors)+winSize)/44100.0f; | 703 startSecs = ((hopSize*startVectors)+winSize)/sampleRate; |
729 if(startSecs < 0) { startSecs = 0; } | 704 if(startSecs < 0) { startSecs = 0; } |
730 [queryStartSeconds setDoubleValue:startSecs]; | 705 [queryStartSeconds setDoubleValue:startSecs]; |
731 } | 706 } |
732 } | 707 } |
733 | 708 |
811 | 786 |
812 NSLog(@"No results"); | 787 NSLog(@"No results"); |
813 } | 788 } |
814 else | 789 else |
815 { | 790 { |
791 | |
816 NSLog(@"Populate table: %d", result->nresults); | 792 NSLog(@"Populate table: %d", result->nresults); |
817 float divisor = (44100.0f/hopSize); | |
818 for(int i=0; i<result->nresults; i++) | 793 for(int i=0; i<result->nresults; i++) |
819 { | 794 { |
795 | |
796 NSString* filename = [trackMap objectForKey:[NSString stringWithFormat:@"%s", result->results[i].ikey]]; | |
797 int sampleRate = [self getSampleRate:filename]; | |
798 int hopSize = [self getHopSizeInSamples:filename]; | |
799 float divisor = (sampleRate/hopSize); | |
820 | 800 |
821 NSMutableDictionary* dict = [[NSMutableDictionary alloc] initWithCapacity:4]; | 801 NSMutableDictionary* dict = [[NSMutableDictionary alloc] initWithCapacity:4]; |
822 [dict setValue:[NSString stringWithFormat:@"%s", result->results[i].ikey] forKey:@"key"]; | 802 [dict setValue:[NSString stringWithFormat:@"%s", result->results[i].ikey] forKey:@"key"]; |
823 [dict setValue:[NSNumber numberWithFloat:result->results[i].dist] forKey:@"distance"]; | 803 [dict setValue:[NSNumber numberWithFloat:result->results[i].dist] forKey:@"distance"]; |
824 [dict setValue:[NSNumber numberWithFloat:result->results[i].dist] forKey:@"meter"]; | 804 [dict setValue:[NSNumber numberWithFloat:result->results[i].dist] forKey:@"meter"]; |