From 1ffd741e508732992045bd3d9832d2c1c71770a0 Mon Sep 17 00:00:00 2001 From: Ron Pedde Date: Sun, 17 Apr 2005 21:18:59 +0000 Subject: [PATCH] fix parsing extended_content_description, better song duration by using preroll --- src/dbs-sqlite.c | 54 ++++++++++++++++++++++++++++++++++++------------ src/dbs-sqlite.h | 52 ++++++++++++++++++++++++++++++++++++++++++++++ src/wma.c | 44 +++++++++++++++++++++++++-------------- 3 files changed, 121 insertions(+), 29 deletions(-) diff --git a/src/dbs-sqlite.c b/src/dbs-sqlite.c index 68c72f6a..3d4390d5 100644 --- a/src/dbs-sqlite.c +++ b/src/dbs-sqlite.c @@ -230,6 +230,8 @@ int db_sqlite_init(int reload) { int items; int rescan=0; + /* make sure we have an index... might not if aborted during scan */ + db_sqlite_exec(E_DBG,"CREATE INDEX idx_path ON songs(path)"); db_sqlite_update_version(db_sqlite_get_version()); db_sqlite_get_int(E_DBG,&rescan,"SELECT value FROM config WHERE term='rescan'"); @@ -899,9 +901,10 @@ int db_sqlite_get_size(DBQUERYINFO *pinfo, char **valarray) { if(db_wantsmeta(pinfo->meta, metaItunesSmartPlaylist)) size += 9; /* aeSP */ if(db_wantsmeta(pinfo->meta, metaItemName)) - size += (8 + strlen(valarray[1])); /* minm */ - if(valarray[2] && atoi(valarray[2]) && db_wantsmeta(pinfo->meta, metaMPlaylistSpec)) - size += (8 + strlen(valarray[4])); /* MSPS */ + size += (8 + strlen(valarray[plTitle])); /* minm */ + if(valarray[plType] && (atoi(valarray[plType])==1) && + db_wantsmeta(pinfo->meta, metaMPlaylistSpec)) + size += (8 + strlen(valarray[plQuery])); /* MSPS */ if(db_wantsmeta(pinfo->meta, metaMPlaylistType)) size += 9; /* MPTY */ return size; @@ -1045,6 +1048,7 @@ int db_sqlite_build_dmap(DBQUERYINFO *pinfo, char **valarray, char *presult, int unsigned char *current = presult; int transcode; int samplerate=0; + int smart; switch(pinfo->query_type) { case queryTypeBrowseArtists: /* simple 'mlit' entry */ @@ -1056,16 +1060,21 @@ int db_sqlite_build_dmap(DBQUERYINFO *pinfo, char **valarray, char *presult, int /* do I want to include the mlit? */ current += db_dmap_add_container(current,"mlit",len - 8); if(db_wantsmeta(pinfo->meta,metaItemId)) - current += db_dmap_add_int(current,"miid",atoi(valarray[0])); - current += db_dmap_add_int(current,"mimc",atoi(valarray[3])); - if(db_wantsmeta(pinfo->meta,metaItunesSmartPlaylist)) - current += db_dmap_add_char(current,"aeSP",atoi(valarray[2])); + current += db_dmap_add_int(current,"miid",atoi(valarray[plID])); + current += db_dmap_add_int(current,"mimc",atoi(valarray[plItems])); + if(db_wantsmeta(pinfo->meta,metaItunesSmartPlaylist)) { + smart=0; + if(atoi(valarray[plType]) == 1) + smart=1; + current += db_dmap_add_char(current,"aeSP",smart); + } if(db_wantsmeta(pinfo->meta,metaItemName)) - current += db_dmap_add_string(current,"minm",valarray[1]); - if((valarray[2]) && atoi(valarray[2]) && db_wantsmeta(pinfo->meta, metaMPlaylistSpec)) - current += db_dmap_add_string(current,"MSPS",valarray[4]); + current += db_dmap_add_string(current,"minm",valarray[plTitle]); + if((valarray[plType]) && (atoi(valarray[plType])==1) && + db_wantsmeta(pinfo->meta, metaMPlaylistSpec)) + current += db_dmap_add_string(current,"MSPS",valarray[plQuery]); if(db_wantsmeta(pinfo->meta, metaMPlaylistType)) - current += db_dmap_add_char(current,"MPTY",atoi(valarray[2])); + current += db_dmap_add_char(current,"MPTY",atoi(valarray[plType])); break; case queryTypeItems: case queryTypePlaylistItems: /* essentially the same query */ @@ -1489,6 +1498,23 @@ char *db_sqlite_upgrade_scripts[] = { "create index idx_path on songs(path);\n" "drop table tempsongs;\n" "update config set value=3 where term='version';\n", + + /* version 3 -> version 4 */ + /* add db_timestamp and path to playlist table */ + "create temp table tempplaylists as select * from playlists;\n" + "drop table playlists;\n" + "CREATE TABLE playlists (\n" + " id INTEGER PRIMARY KEY NOT NULL,\n" + " title VARCHAR(255) NOT NULL,\n" + " smart INTEGER NOT NULL,\n" + " items INTEGER NOT NULL,\n" + " query VARCHAR(1024)\n" + " db_timestamp INTEGER NOT NULL,\n" + " path VARCHAR(4096)\n" + ");\n" + "insert into playlists select *,0,NULL from tempplaylists;\n" + "drop table tempplaylists;\n" + "update config set value=4 where term='version';\n", NULL /* No more versions! */ }; @@ -1498,6 +1524,10 @@ char *db_sqlite_upgrade_scripts[] = { * \param from_version the current version of the database */ int db_sqlite_update_version(int from_version) { + if(from_version > (sizeof(db_sqlite_upgrade_scripts)/sizeof(char*))) { + DPRINTF(E_FATAL,L_DB,"Database version too new (time machine, maybe?)\n"); + } + while(db_sqlite_upgrade_scripts[from_version]) { DPRINTF(E_LOG,L_DB,"Upgrading database from version %d to version %d\n",from_version, from_version+1); @@ -1508,5 +1538,3 @@ int db_sqlite_update_version(int from_version) { return 0; } - - diff --git a/src/dbs-sqlite.h b/src/dbs-sqlite.h index a4732bb6..78579458 100644 --- a/src/dbs-sqlite.h +++ b/src/dbs-sqlite.h @@ -40,4 +40,56 @@ extern void db_sqlite_dispose_item(MP3FILE *pmp3); extern int db_sqlite_add_playlist(char *name, int type, char *clause, int *playlistid); extern int db_sqlite_add_playlist_item(int playlistid, int songid); + +typedef enum { + songID, + songPath, + songFname, + songTitle, + songArtist, + songAlbum, + songGenre, + songComment, + songType, + songComposer, + songOrchestra, + songGrouping, + songURL, + songBitrate, + songSampleRate, + songLength, + songFilesize, + songYear, + songTrack, + songTotalTracks, + songDisc, + songTotalDiscs, + songBPM, + songCompilation, + songRating, + songPlayCount, + songDataKind, + songItemKind, + songDescription, + songTimeAdded, + songTimeModified, + songTimePlayed, + songDBTimestamp, + songDisabled, + songSampleCount, + songForceUpdate, + songCodecType +} SongField_t; + +typedef enum { + plID, + plTitle, + plType, + plItems, + plQuery, + plDBTimestamp, + plPath +} PlaylistField_t; + + #endif /* _DBS_SQLITE_H_ */ diff --git a/src/wma.c b/src/wma.c index 4875a33a..50281f4c 100644 --- a/src/wma.c +++ b/src/wma.c @@ -364,7 +364,7 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) { switch(descriptor_value_type) { case 0x0000: /* string */ if(!wma_file_read_utf16(fd,descriptor_value_len,&descriptor_byte_value)) fail=1; - DPRINTF(E_DBG,L_SCAN,"Type: string, value (%s)\n",descriptor_byte_value); + DPRINTF(E_DBG,L_SCAN,"Type: string, value: %s\n",descriptor_byte_value); break; case 0x0001: /* byte array */ if(!wma_file_read_bytes(fd,descriptor_value_len,&descriptor_byte_value)) fail=1; @@ -391,33 +391,33 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) { } /* do stuff with what we found */ - if(!strcasecmp(descriptor_name,"wm/genre")==0) { + if(strcasecmp(descriptor_name,"wm/genre")==0) { MAYBEFREE(pmp3->genre); pmp3->genre = descriptor_byte_value; descriptor_byte_value = NULL; /* don't free it! */ - } else if(!strcasecmp(descriptor_name,"wm/albumtitle")==0) { + } else if(strcasecmp(descriptor_name,"wm/albumtitle")==0) { MAYBEFREE(pmp3->album); pmp3->album = descriptor_byte_value; descriptor_byte_value = NULL; - } else if(!strcasecmp(descriptor_name,"wm/track")==0) { + } else if(strcasecmp(descriptor_name,"wm/track")==0) { pmp3->track = descriptor_int_value + 1; - } else if(!strcasecmp(descriptor_name,"wm/tracknumber")==0) { + } else if(strcasecmp(descriptor_name,"wm/tracknumber")==0) { pmp3->track = descriptor_int_value; - } else if(!strcasecmp(descriptor_name,"wm/year")==0) { - pmp3->track = atoi(descriptor_byte_value); - } else if(!strcasecmp(descriptor_name,"wm/composer")==0) { + } else if(strcasecmp(descriptor_name,"wm/year")==0) { + pmp3->year = atoi(descriptor_byte_value); + } else if(strcasecmp(descriptor_name,"wm/composer")==0) { MAYBEFREE(pmp3->composer); pmp3->composer = descriptor_byte_value; descriptor_byte_value = NULL; - } else if(!strcasecmp(descriptor_name,"wm/albumartist")==0) { + } else if(strcasecmp(descriptor_name,"wm/albumartist")==0) { MAYBEFREE(pmp3->artist); pmp3->artist = descriptor_byte_value; descriptor_byte_value = NULL; - } else if(!strcasecmp(descriptor_name,"wm/contengroupdescription")==0) { + } else if(strcasecmp(descriptor_name,"wm/contengroupdescription")==0) { MAYBEFREE(pmp3->grouping); pmp3->grouping = descriptor_byte_value; descriptor_byte_value = NULL; - } else if(!strcasecmp(descriptor_name,"comment")==0) { + } else if(strcasecmp(descriptor_name,"comment")==0) { MAYBEFREE(pmp3->comment); pmp3->comment = descriptor_byte_value; descriptor_byte_value = NULL; @@ -506,6 +506,9 @@ int wma_parse_content_description(int fd,int size, MP3FILE *pmp3) { */ int wma_parse_file_properties(int fd,int size, MP3FILE *pmp3) { long long play_duration; + long long send_duration; + long long preroll; + int max_bitrate; /* skip guid (16 bytes), filesize (8), creation time (8), @@ -513,17 +516,26 @@ int wma_parse_file_properties(int fd,int size, MP3FILE *pmp3) { */ lseek(fd,40,SEEK_CUR); - /* we'll ignore the preroll */ if(!wma_file_read_ll(fd, &play_duration)) return -1; - pmp3->song_length = (int) (play_duration / 10000); + if(!wma_file_read_ll(fd, &send_duration)) + return -1; + + if(!wma_file_read_ll(fd, &preroll)) + return -1; + + /* I'm not entirely certain what preroll is, but it seems + * to make it match up with what windows thinks is the song + * length. + */ + pmp3->song_length = ((int) (play_duration / 10000)) - preroll; - /* skip send_duration (8), preroll (8), flags(4), + /* skip flags(4), * min_packet_size (4), max_packet_size(4) */ - lseek(fd,28,SEEK_CUR); + lseek(fd,12,SEEK_CUR); if(!wma_file_read_int(fd,&max_bitrate)) return -1; @@ -549,7 +561,7 @@ int wma_parse_file_properties(int fd,int size, MP3FILE *pmp3) { */ unsigned char *wma_utf16toutf8(char *utf16, int len) { char *utf8; - char *src=utf16;; + char *src=utf16; char *dst; unsigned int w1, w2; int bytes;