|
|
#1 |
|
Find matching Song Titles in iPod library
Hi Guys,
This is a giveaway, but credit where it's due please, particularly if you use it in any paid app. iTunes appears to be doing this itself when you restore downloads, but what if you provided the mp3's yourself? This routine searches an iPod library (over 1500 items) in approx 0.5 seconds on iPhone 5. Code:
int musicsearched = 0; // status flag set once the searchmusic function has run
int totalrecords = 0;
int matchcount = 0;
int cyclerecords = 0;
int nomatch = 0;
int musicsearched = 0;
int nonuniquetitles = 0;
int checked[10000]; // used for searchmusic function
char record[10000][200]; // 10,000 records of 200 bytes iPod library ends up here
char artist[10000][100]; // artists records
char matches[10000][200]; // parallel array - track matches
char amatches[10000][100]; // artist matches
char temprecord[200];
char resultrecord[200];
void searchmusic() {
NSTimeInterval start = [NSDate timeIntervalSinceReferenceDate];
//do time-consuming stuff like calculating pi to 50000 places.
MPMediaQuery *everything = [[MPMediaQuery alloc] init];
oitemcount = 0;
NSArray *itemsFromGenericQuery = [everything items];
for (MPMediaItem *song in itemsFromGenericQuery) {
songTitle = [song valueForProperty: MPMediaItemPropertyTitle];
artistTitle = [song valueForProperty: MPMediaItemPropertyArtist];
slength=[songTitle length];
if (slength > 199) {slength = 199;} // limit string length to buffer size
alength=[artistTitle length];
if (alength > 99) {alength = 99;} // limit string length to buffer size
const char *c = [songTitle UTF8String];
strncpy(record[oitemcount], c, slength);
const char *a = [artistTitle UTF8String];
strncpy(artist[oitemcount], a, alength);
oitemcount++;
}
totalrecords = oitemcount;
matchcount = 26;
cyclerecords = 0;
oitemcount = 0;
firstmatch = 0;
while (oitemcount < totalrecords) {
for(int j = 0; j < 199; j++) { // read in temp record at index to compare against all others
temprecord[j] = record[oitemcount][j];
}
for(cyclerecords = oitemcount+1; cyclerecords < totalrecords; cyclerecords++) {
nomatch = 0;
for(int k = 0; k < 199; k++) { // compare a single record
if (temprecord[k] != record[cyclerecords][k]) {nomatch = 1;}
}
if (nomatch == 1) {cyclerecords = totalrecords;}
if (nomatch == 0) {
if (checked[oitemcount] != 1) {
for(int k = 0; k < 99; k++) { // draw line in text
amatches[matchcount][k] = 0x5F;
matches[matchcount][k] = 0x5F;
}
if (matchcount < 9999) {matchcount++;} // line seperator
for(int k = 0; k < 99; k++) { // copy artist match
amatches[matchcount][k] = artist[oitemcount][k];
}
for(int k = 0; k < 199; k++) { // copy song match
matches[matchcount][k] = record[oitemcount][k];
}
if (matchcount < 9999) {matchcount++;}
checked[oitemcount] = 1;
nonuniquetitles++;
} // checked
if (checked[cyclerecords] != 1) {
for(int k = 0; k < 99; k++) { // copy artist match
amatches[matchcount][k] = artist[cyclerecords][k];
}
if (matchcount < 9999) {matchcount++;}
checked[cyclerecords] = 1;
} // checked
}
}
oitemcount++;
}
NSTimeInterval end = [NSDate timeIntervalSinceReferenceDate];
NSTimeInterval elapsed = end - start;
xelapsed = elapsed;
//NSLog(@"The search took %.2f seconds", xelapsed);
for(int k = 0; k < 99; k++) { // draw last line in text
amatches[matchcount][k] = 0x5F;
matches[matchcount][k] = 0x5F;
}
if (matchcount < 9999) {matchcount++;} // last line seperator
if (matchcount < 9999) {matchcount++;} // seperator
sprintf(resultrecord, "Searched %i titles",totalrecords);
for(int k = 0; k < 99; k++) { // write result line
matches[matchcount][k] = resultrecord[k];
if (matches[matchcount][k] == 0x00) {matches[matchcount][k] = 0x20;}
}
sprintf(resultrecord, "in %.2f seconds. ",xelapsed);
for(int k = 0; k < 99; k++) { // write message line
matches[matchcount+1][k] = resultrecord[k];
if (matches[matchcount+1][k] == 0x00) {matches[matchcount+1][k] = 0x20;}
}
sprintf(resultrecord, "Found %i titles! ",nonuniquetitles);
for(int k = 0; k < 99; k++) { // write result line
matches[matchcount+2][k] = resultrecord[k];
if (matches[matchcount+2][k] == 0x00) {matches[matchcount+2][k] = 0x20;}
}
sprintf(resultrecord, "xPod By Art 2013 ");
for(int k = 0; k < 99; k++) { // write message line
matches[matchcount+4][k] = resultrecord[k];
if (matches[matchcount+4][k] == 0x00) {matches[matchcount+4][k] = 0x20;}
}
for(int k = 0; k < 99; k++) { // draw last line after footer
amatches[matchcount+6][k] = 0x5F;
matches[matchcount+6][k] = 0x5F;
}
matchcount--;
matchcount--;
musicsearched = 1;
}
can look like this: ![]() ![]() enjoy! & points to whomever sees why it's so fast! Last edited by xArtx; Jan 2, 2013 at 05:16 AM. |
|
|
|
0
|
|
|
#2 |
|
Sounds great! Thanks for sharing.
But I think there's a flaw: "I Think We're Alone Now" is not displaying Tommy James & The Shondells. I guess it could be a problem with your iTunes library. ![]() Impressive search time none-the-less! ![]() As to why it's so fast, my guess is this: You're using plain C and no Objective-C objects (except for NSDate, NSArray, and a custom class, MPMediaQuery.) C is a small language with very little overhead. So you are not spending processing time allocating memory for and then destroying Cocoa objects. That's my conclusion from things I've read in various places. I'm no expert.
__________________
13" MacBook Pro, 2.26 GHz, 4 GB RAM, 500 GB HD iPhone 4 32GB 2nd gen iPod nano 4GB
|
|
|
|
0
|
|
|
#3 | ||
|
Quote:
![]() Quote:
![]() Um, no! Arrays are already allocated. By default the Mediaquery is already in order of track title. Rather than comparing every title to every other title, you only need compare every title with those beneath it, until the next title does not match, then resume the search from there ![]() BTW a few well placed NSLOG lines would alleviate the need to work with the output arrays of this routine in order to test it out. |
|||
|
|
0
|
![]() |
|
«
Previous Thread
|
Next Thread
»
| Thread Tools | Search this Thread |
| Display Modes | |
|
|
All times are GMT -5. The time now is 05:52 AM.










13" MacBook Pro, 2.26 GHz, 4 GB RAM, 500 GB HD 
Linear Mode
