fix parsing extended_content_description, better song duration by using preroll

This commit is contained in:
Ron Pedde 2005-04-17 21:18:59 +00:00
parent b21d1340c9
commit 1ffd741e50
3 changed files with 121 additions and 29 deletions

View File

@ -230,6 +230,8 @@ int db_sqlite_init(int reload) {
int items; int items;
int rescan=0; 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_update_version(db_sqlite_get_version());
db_sqlite_get_int(E_DBG,&rescan,"SELECT value FROM config WHERE term='rescan'"); 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)) if(db_wantsmeta(pinfo->meta, metaItunesSmartPlaylist))
size += 9; /* aeSP */ size += 9; /* aeSP */
if(db_wantsmeta(pinfo->meta, metaItemName)) if(db_wantsmeta(pinfo->meta, metaItemName))
size += (8 + strlen(valarray[1])); /* minm */ size += (8 + strlen(valarray[plTitle])); /* minm */
if(valarray[2] && atoi(valarray[2]) && db_wantsmeta(pinfo->meta, metaMPlaylistSpec)) if(valarray[plType] && (atoi(valarray[plType])==1) &&
size += (8 + strlen(valarray[4])); /* MSPS */ db_wantsmeta(pinfo->meta, metaMPlaylistSpec))
size += (8 + strlen(valarray[plQuery])); /* MSPS */
if(db_wantsmeta(pinfo->meta, metaMPlaylistType)) if(db_wantsmeta(pinfo->meta, metaMPlaylistType))
size += 9; /* MPTY */ size += 9; /* MPTY */
return size; return size;
@ -1045,6 +1048,7 @@ int db_sqlite_build_dmap(DBQUERYINFO *pinfo, char **valarray, char *presult, int
unsigned char *current = presult; unsigned char *current = presult;
int transcode; int transcode;
int samplerate=0; int samplerate=0;
int smart;
switch(pinfo->query_type) { switch(pinfo->query_type) {
case queryTypeBrowseArtists: /* simple 'mlit' entry */ 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? */ /* do I want to include the mlit? */
current += db_dmap_add_container(current,"mlit",len - 8); current += db_dmap_add_container(current,"mlit",len - 8);
if(db_wantsmeta(pinfo->meta,metaItemId)) if(db_wantsmeta(pinfo->meta,metaItemId))
current += db_dmap_add_int(current,"miid",atoi(valarray[0])); current += db_dmap_add_int(current,"miid",atoi(valarray[plID]));
current += db_dmap_add_int(current,"mimc",atoi(valarray[3])); current += db_dmap_add_int(current,"mimc",atoi(valarray[plItems]));
if(db_wantsmeta(pinfo->meta,metaItunesSmartPlaylist)) if(db_wantsmeta(pinfo->meta,metaItunesSmartPlaylist)) {
current += db_dmap_add_char(current,"aeSP",atoi(valarray[2])); smart=0;
if(atoi(valarray[plType]) == 1)
smart=1;
current += db_dmap_add_char(current,"aeSP",smart);
}
if(db_wantsmeta(pinfo->meta,metaItemName)) if(db_wantsmeta(pinfo->meta,metaItemName))
current += db_dmap_add_string(current,"minm",valarray[1]); current += db_dmap_add_string(current,"minm",valarray[plTitle]);
if((valarray[2]) && atoi(valarray[2]) && db_wantsmeta(pinfo->meta, metaMPlaylistSpec)) if((valarray[plType]) && (atoi(valarray[plType])==1) &&
current += db_dmap_add_string(current,"MSPS",valarray[4]); db_wantsmeta(pinfo->meta, metaMPlaylistSpec))
current += db_dmap_add_string(current,"MSPS",valarray[plQuery]);
if(db_wantsmeta(pinfo->meta, metaMPlaylistType)) 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; break;
case queryTypeItems: case queryTypeItems:
case queryTypePlaylistItems: /* essentially the same query */ case queryTypePlaylistItems: /* essentially the same query */
@ -1489,6 +1498,23 @@ char *db_sqlite_upgrade_scripts[] = {
"create index idx_path on songs(path);\n" "create index idx_path on songs(path);\n"
"drop table tempsongs;\n" "drop table tempsongs;\n"
"update config set value=3 where term='version';\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! */ NULL /* No more versions! */
}; };
@ -1498,6 +1524,10 @@ char *db_sqlite_upgrade_scripts[] = {
* \param from_version the current version of the database * \param from_version the current version of the database
*/ */
int db_sqlite_update_version(int from_version) { 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]) { while(db_sqlite_upgrade_scripts[from_version]) {
DPRINTF(E_LOG,L_DB,"Upgrading database from version %d to version %d\n",from_version, DPRINTF(E_LOG,L_DB,"Upgrading database from version %d to version %d\n",from_version,
from_version+1); from_version+1);
@ -1508,5 +1538,3 @@ int db_sqlite_update_version(int from_version) {
return 0; return 0;
} }

View File

@ -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(char *name, int type, char *clause, int *playlistid);
extern int db_sqlite_add_playlist_item(int playlistid, int songid); 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_ */ #endif /* _DBS_SQLITE_H_ */

View File

@ -364,7 +364,7 @@ int wma_parse_extended_content_description(int fd,int size, MP3FILE *pmp3) {
switch(descriptor_value_type) { switch(descriptor_value_type) {
case 0x0000: /* string */ case 0x0000: /* string */
if(!wma_file_read_utf16(fd,descriptor_value_len,&descriptor_byte_value)) fail=1; 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; break;
case 0x0001: /* byte array */ case 0x0001: /* byte array */
if(!wma_file_read_bytes(fd,descriptor_value_len,&descriptor_byte_value)) fail=1; 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 */ /* do stuff with what we found */
if(!strcasecmp(descriptor_name,"wm/genre")==0) { if(strcasecmp(descriptor_name,"wm/genre")==0) {
MAYBEFREE(pmp3->genre); MAYBEFREE(pmp3->genre);
pmp3->genre = descriptor_byte_value; pmp3->genre = descriptor_byte_value;
descriptor_byte_value = NULL; /* don't free it! */ 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); MAYBEFREE(pmp3->album);
pmp3->album = descriptor_byte_value; pmp3->album = descriptor_byte_value;
descriptor_byte_value = NULL; 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; 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; pmp3->track = descriptor_int_value;
} else if(!strcasecmp(descriptor_name,"wm/year")==0) { } else if(strcasecmp(descriptor_name,"wm/year")==0) {
pmp3->track = atoi(descriptor_byte_value); pmp3->year = atoi(descriptor_byte_value);
} else if(!strcasecmp(descriptor_name,"wm/composer")==0) { } else if(strcasecmp(descriptor_name,"wm/composer")==0) {
MAYBEFREE(pmp3->composer); MAYBEFREE(pmp3->composer);
pmp3->composer = descriptor_byte_value; pmp3->composer = descriptor_byte_value;
descriptor_byte_value = NULL; descriptor_byte_value = NULL;
} else if(!strcasecmp(descriptor_name,"wm/albumartist")==0) { } else if(strcasecmp(descriptor_name,"wm/albumartist")==0) {
MAYBEFREE(pmp3->artist); MAYBEFREE(pmp3->artist);
pmp3->artist = descriptor_byte_value; pmp3->artist = descriptor_byte_value;
descriptor_byte_value = NULL; descriptor_byte_value = NULL;
} else if(!strcasecmp(descriptor_name,"wm/contengroupdescription")==0) { } else if(strcasecmp(descriptor_name,"wm/contengroupdescription")==0) {
MAYBEFREE(pmp3->grouping); MAYBEFREE(pmp3->grouping);
pmp3->grouping = descriptor_byte_value; pmp3->grouping = descriptor_byte_value;
descriptor_byte_value = NULL; descriptor_byte_value = NULL;
} else if(!strcasecmp(descriptor_name,"comment")==0) { } else if(strcasecmp(descriptor_name,"comment")==0) {
MAYBEFREE(pmp3->comment); MAYBEFREE(pmp3->comment);
pmp3->comment = descriptor_byte_value; pmp3->comment = descriptor_byte_value;
descriptor_byte_value = NULL; 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) { int wma_parse_file_properties(int fd,int size, MP3FILE *pmp3) {
long long play_duration; long long play_duration;
long long send_duration;
long long preroll;
int max_bitrate; int max_bitrate;
/* skip guid (16 bytes), filesize (8), creation time (8), /* 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); lseek(fd,40,SEEK_CUR);
/* we'll ignore the preroll */
if(!wma_file_read_ll(fd, &play_duration)) if(!wma_file_read_ll(fd, &play_duration))
return -1; 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) * 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)) if(!wma_file_read_int(fd,&max_bitrate))
return -1; 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) { unsigned char *wma_utf16toutf8(char *utf16, int len) {
char *utf8; char *utf8;
char *src=utf16;; char *src=utf16;
char *dst; char *dst;
unsigned int w1, w2; unsigned int w1, w2;
int bytes; int bytes;