diff --git a/contrib/mt-daapd-ssc.pl b/contrib/mt-daapd-ssc.pl index 6e9fb1e6..8ac0f72c 100644 --- a/contrib/mt-daapd-ssc.pl +++ b/contrib/mt-daapd-ssc.pl @@ -27,13 +27,11 @@ # # -# This is quite rudimentary. Obvious TODO list is as follows: +# This is quite rudimentary but handles most cases quite well. # -# - Speedup the streaming start. -# - Make the guessing of the wav length reliable. -# - Implement Apple Lossless, somehow, someone, PLEASE! It could be done -# by integrating QuickTime 6.5 codecs to MPlayer (currently 6.3) -# - Possibly implement some kind of caching. +# TODO-list: +# - Make the guessing of the wav length reliable. +# - Possibly implement some kind of caching. # # I'll probably never have time for above things, but now it should # be easy for someone to take this over, since basically all you have @@ -71,23 +69,33 @@ $SIG{PIPE} = 'IGNORE'; if ($off < 0) { usage(); } - if ($fn =~ m/^..*\.wav/i) { + if ($fn =~ m/^..*\.wav$/i) { passthru_proc($fn, $off, $forgelen); - } elsif ($fn =~ m/^..*\.wave/i) { + } elsif ($fn =~ m/^..*\.wave$/i) { passthru_proc($fn, $off, $forgelen); - } elsif ($fn =~ m/^..*\.flac/i) { + } elsif ($fn =~ m/^..*\.flac$/i) { flac_proc($fn, $off, $forgelen); - } elsif ($fn =~ m/^..*\.fla/i) { + } elsif ($fn =~ m/^..*\.fla$/i) { flac_proc($fn, $off, $forgelen); - } elsif ($fn =~ m/^..*\.mp3/i) { + } elsif ($fn =~ m/^..*\.mp4$/i) { + mpeg4_proc($fn, $off, $forgelen); + } elsif ($fn =~ m/^..*\.m4a$/i) { + mpeg4_proc($fn, $off, $forgelen); + } elsif ($fn =~ m/^..*\.m4p$/i) { + mpeg4_proc($fn, $off, $forgelen); + } elsif ($fn =~ m/^..*\.aac$/i) { + mpeg4_proc($fn, $off, $forgelen); + } elsif ($fn =~ m/^..*\.shn$/i) { ffmpeg_proc($fn, $off, $forgelen); - } elsif ($fn =~ m/^..*\.mpg/i) { + } elsif ($fn =~ m/^..*\.mp3$/i) { ffmpeg_proc($fn, $off, $forgelen); - } elsif ($fn =~ m/^..*\.ogg/i) { + } elsif ($fn =~ m/^..*\.mpg$/i) { ffmpeg_proc($fn, $off, $forgelen); - } elsif ($fn =~ m/^..*\.avi/i) { + } elsif ($fn =~ m/^..*\.ogg$/i) { ffmpeg_proc($fn, $off, $forgelen); - } elsif ($fn =~ m/^..*\.au/i) { + } elsif ($fn =~ m/^..*\.avi$/i) { + ffmpeg_proc($fn, $off, $forgelen); + } elsif ($fn =~ m/^..*\.au$/i) { ffmpeg_proc($fn, $off, $forgelen); } else { mplayer_proc($fn, $off, $forgelen); @@ -513,3 +521,54 @@ sub mplayer_proc close($w); unlink($tf); } + +sub mpeg4_proc +{ + my ($fn) = shift; + my ($off) = shift; + my ($forgelen) = shift; + my ($f) = undef; + my ($hdr) = undef; + my ($r) = undef; + + if (open($f, "< $fn")) { + my ($rl) = sysread($f, $hdr, 512); + close($f); + if ($rl != 512) { + return undef; + } + } else { + return undef; + } + + # + # This detection is really rudimentary, but seems to + # do the job for now. + # + if (index($hdr, "Halac") >= 0) { + $r = alac_proc($fn, $off, $forgelen); + } else { + $r = ffmpeg_proc($fn, $off, $forgelen); + } + + return $r; +} + +sub alac_proc +{ + my ($fn) = shift; + my ($off) = shift; + my ($forgelen) = shift; + my ($r) = undef; + my ($w) = undef; + my ($pid); + + $pid = open2($r, $w, 'alac', "$fn"); + wav_loop($r, $off, undef); # Ignore $forgelen + close($r); + close($w); + if (waitpid($pid, WNOHANG) <= 0) { + kill(SIGKILL, $pid); + waitpid($pid, 0); + } +} diff --git a/src/db-generic.c b/src/db-generic.c index e992d7d7..5450d590 100644 --- a/src/db-generic.c +++ b/src/db-generic.c @@ -732,6 +732,29 @@ int db_dmap_add_string(char *where, char *tag, char *value) { return 8 + strlen(value); } +/** + * add a literal chunk of data to a dmap block + * + * \param where where to serialize the dmap info + * \param tag what four byte tag + * \param value what to put there + * \param size how much data to cram in there + */ +int db_dmap_add_literal(char *where, char *tag, char *value, int size) { + /* tag */ + memcpy(where,tag,4); + + /* length */ + where[4]=(size >> 24) & 0xFF; + where[5]=(size >> 16) & 0xFF; + where[6]=(size >> 8) & 0xFF; + where[7]=size & 0xFF; + + memcpy(where+8,value,size); + return 8+size; +} + + /** * add a container type to a dmap block (type 0x0C) * diff --git a/src/db-generic.h b/src/db-generic.h index a7a8e0a4..e7b02953 100644 --- a/src/db-generic.h +++ b/src/db-generic.h @@ -171,6 +171,7 @@ extern int db_dmap_add_char(char *where, char *tag, char value); extern int db_dmap_add_short(char *where, char *tag, short value); extern int db_dmap_add_int(char *where, char *tag, int value); extern int db_dmap_add_string(char *where, char *tag, char *value); +extern int db_dmap_add_literal(char *where, char *tag, char *value, int size); extern int db_dmap_add_container(char *where, char *tag, int size); /* Holdover functions from old db interface... diff --git a/src/dbs-sqlite.c b/src/dbs-sqlite.c index 46ded559..68c72f6a 100644 --- a/src/dbs-sqlite.c +++ b/src/dbs-sqlite.c @@ -244,6 +244,8 @@ int db_sqlite_init(int reload) { db_sqlite_reload=1; db_sqlite_exec(E_DBG,"DROP INDEX idx_path"); db_sqlite_exec(E_FATAL,"DELETE FROM songs"); + } else { + db_sqlite_exec(E_FATAL,"VACUUM"); } return 0; } @@ -435,7 +437,8 @@ int db_sqlite_add(MP3FILE *pmp3) { "%d," // db_timestamp "%d," // disabled "%d," // sample_count - "0)", // force_update + "0," // force_update + "'%q')", // codectype STR(pmp3->path), STR(pmp3->fname), STR(pmp3->title), @@ -468,7 +471,9 @@ int db_sqlite_add(MP3FILE *pmp3) { pmp3->time_modified, pmp3->time_played, pmp3->db_timestamp, - pmp3->disabled); + pmp3->disabled, + pmp3->sample_count, + STR(pmp3->codectype)); if(err == SQLITE_CONSTRAINT) { /* probably because the path already exists... */ @@ -529,7 +534,8 @@ int db_sqlite_update(MP3FILE *pmp3) { "bpm=%d," // bpm "compilation=%d," // compilation "rating=%d," // rating - "sample_count=%d" // sample_count + "sample_count=%d," // sample_count + "codectype='%q'" // codec " WHERE path='%q'", STR(pmp3->title), STR(pmp3->artist), @@ -557,6 +563,7 @@ int db_sqlite_update(MP3FILE *pmp3) { pmp3->compilation, pmp3->rating, pmp3->sample_count, + STR(pmp3->codectype), pmp3->path); if((db_sqlite_in_scan) && (!db_sqlite_reload)) { @@ -1021,7 +1028,9 @@ int db_sqlite_get_size(DBQUERYINFO *pinfo, char **valarray) { if(db_wantsmeta(pinfo->meta, metaContainerItemId)) /* mcti */ size += 12; - + if(ISSTR(valarray[37]) && db_wantsmeta(pinfo->meta, metaSongCodecType)) + /* ascd */ + size += 12; return size; break; @@ -1146,6 +1155,8 @@ int db_sqlite_build_dmap(DBQUERYINFO *pinfo, char **valarray, char *presult, int current += db_dmap_add_char(current,"asur",(char)atoi(valarray[25])); if(valarray[18] && atoi(valarray[18]) && db_wantsmeta(pinfo->meta, metaSongYear)) current += db_dmap_add_short(current,"asyr",(short)atoi(valarray[18])); + if(ISSTR(valarray[37]) && db_wantsmeta(pinfo->meta, metaSongCodecType)) + current += db_dmap_add_literal(current,"ascd",valarray[37],4); if(db_wantsmeta(pinfo->meta, metaContainerItemId)) current += db_dmap_add_int(current,"mcti",atoi(valarray[0])); return 0; @@ -1205,6 +1216,7 @@ void db_sqlite_build_mp3file(char **valarray, MP3FILE *pmp3) { pmp3->disabled=db_sqlite_atoi(valarray[34]); pmp3->sample_count=db_sqlite_atoi(valarray[35]); pmp3->force_update=db_sqlite_atoi(valarray[36]); + pmp3->codectype=db_sqlite_strdup(valarray[37]); } /** @@ -1289,6 +1301,7 @@ void db_sqlite_dispose_item(MP3FILE *pmp3) { MAYBEFREE(pmp3->grouping); MAYBEFREE(pmp3->description); MAYBEFREE(pmp3->url); + MAYBEFREE(pmp3->codectype); free(pmp3); } @@ -1411,6 +1424,71 @@ char *db_sqlite_upgrade_scripts[] = { "REPLACE INTO config VALUES('rescan',NULL,1);\n" "UPDATE config SET value=2 WHERE term='version';\n", + /* version 2 -> version 3 */ + /* add daap.songcodectype, normalize daap.songformat and daap.songdescription */ + "drop index idx_path;\n" + "create temp table tempsongs as select * from songs;\n" + "drop table songs;\n" + "CREATE TABLE songs (\n" + " id INTEGER PRIMARY KEY NOT NULL,\n" + " path VARCHAR(4096) UNIQUE NOT NULL,\n" + " fname VARCHAR(255) NOT NULL,\n" + " title VARCHAR(1024) DEFAULT NULL,\n" + " artist VARCHAR(1024) DEFAULT NULL,\n" + " album VARCHAR(1024) DEFAULT NULL,\n" + " genre VARCHAR(255) DEFAULT NULL,\n" + " comment VARCHAR(4096) DEFAULT NULL,\n" + " type VARCHAR(255) DEFAULT NULL,\n" + " composer VARCHAR(1024) DEFAULT NULL,\n" + " orchestra VARCHAR(1024) DEFAULT NULL,\n" + " conductor VARCHAR(1024) DEFAULT NULL,\n" + " grouping VARCHAR(1024) DEFAULT NULL,\n" + " url VARCHAR(1024) DEFAULT NULL,\n" + " bitrate INTEGER DEFAULT 0,\n" + " samplerate INTEGER DEFAULT 0,\n" + " song_length INTEGER DEFAULT 0,\n" + " file_size INTEGER DEFAULT 0,\n" + " year INTEGER DEFAULT 0,\n" + " track INTEGER DEFAULT 0,\n" + " total_tracks INTEGER DEFAULT 0,\n" + " disc INTEGER DEFAULT 0,\n" + " total_discs INTEGER DEFAULT 0,\n" + " bpm INTEGER DEFAULT 0,\n" + " compilation INTEGER DEFAULT 0,\n" + " rating INTEGER DEFAULT 0,\n" + " play_count INTEGER DEFAULT 0,\n" + " data_kind INTEGER DEFAULT 0,\n" + " item_kind INTEGER DEFAULT 0,\n" + " description INTEGER DEFAULT 0,\n" + " time_added INTEGER DEFAULT 0,\n" + " time_modified INTEGER DEFAULT 0,\n" + " time_played INTEGER DEFAULT 0,\n" + " db_timestamp INTEGER DEFAULT 0,\n" + " disabled INTEGER DEFAULT 0,\n" + " sample_count INTEGER DEFAULT 0,\n" + " force_update INTEGER DEFAULT 0,\n" + " codectype VARCHAR(5) DEFAULT NULL\n" + ");\n" + "begin transaction;\n" + "insert into songs select *,NULL from tempsongs;\n" + "commit transaction;\n" + "update songs set type=lower(type);\n" + "update songs set type='m4a' where type='aac' or type='mp4';\n" + "update songs set type='flac' where type='fla';\n" + "update songs set description='AAC audio file' where type='m4a';\n" + "update songs set description='MPEG audio file' where type='mp3';\n" + "update songs set description='WAV audio file' where type='wav';\n" + "update songs set description='Playlist URL' where type='pls';\n" + "update songs set description='Ogg Vorbis audio file' where type='ogg';\n" + "update songs set description='FLAC audio file' where type='flac';\n" + "update songs set codectype='mp4a' where type='m4a' or type='m4p';\n" + "update songs set codectype='mpeg' where type='mp3';\n" + "update songs set codectype='ogg' where type='ogg';\n" + "update songs set codectype='flac' where type='flac';\n" + "update songs set force_update=1 where type='m4a';\n" /* look for alac */ + "create index idx_path on songs(path);\n" + "drop table tempsongs;\n" + "update config set value=3 where term='version';\n", NULL /* No more versions! */ }; diff --git a/src/mp3-scanner.c b/src/mp3-scanner.c index 79e9b8ca..2bae8987 100644 --- a/src/mp3-scanner.c +++ b/src/mp3-scanner.c @@ -264,6 +264,20 @@ char *scan_winamp_genre[] = { #define WINAMP_GENRE_UNKNOWN 148 +/* + * Typedefs + */ + +typedef struct { + char *suffix; + int (*tags)(char* file, MP3FILE* pmp3); + int (*files)(char* file, MP3FILE* pmp3); + char *type; /* daap.songformat */ + char *codectype; /* song.codectype */ + char *description; /* daap.songdescription */ +} TAGHANDLER; + + /* * Forwards @@ -287,6 +301,8 @@ static void scan_music_file(char *path, struct dirent *pde, struct stat *psb); static int scan_decode_mp3_frame(unsigned char *frame, SCAN_FRAMEINFO *pfi); static time_t mac_to_unix_time(int t); +static TAGHANDLER *scan_gethandler(char *type); + #ifdef OGGVORBIS extern int scan_get_oggfileinfo(char *filename, MP3FILE *pmp3); #endif @@ -296,35 +312,46 @@ extern int scan_get_flacfileinfo(char *filename, MP3FILE *pmp3); extern int scan_get_flactags(char *filename, MP3FILE *pmp3); #endif -/* - * Typedefs + +/* For known types, I'm gong to use the "official" apple + * daap.songformat, daap.songdescription, and daap.songcodecsubtype. + * If I we don't have "official" ones, we can make them up the + * way we currently are: using extension or whatver. + * + * This means that you can test to see if something is, say, an un-drmed + * aac file by just testing for ->type "m4a", rather than checking every different + * flavor of file extension. + * + * NOTE: Although they are represented here as strings, the codectype is *really* + * an unsigned short. So when it gets serialized, it gets serialized as a short int. + * If you put something other than 3 or 4 characters as your codectype, you'll see + * strange results. + * + * FIXME: url != pls -- this method of dispatching handlers based on file type + * is completely wrong. There needs to be a separate type that gets carried around + * with it, at least outside the database that says where the info CAME FROM. + * + * This system is broken, and won't work with something like a .cue file */ - -typedef struct { - char* suffix; - int (*tags)(char* file, MP3FILE* pmp3); - int (*files)(char* file, MP3FILE* pmp3); -} taghandler; - -static taghandler taghandlers[] = { - { "aac", scan_get_aactags, scan_get_aacfileinfo }, - { "mp4", scan_get_aactags, scan_get_aacfileinfo }, - { "m4a", scan_get_aactags, scan_get_aacfileinfo }, - { "m4p", scan_get_aactags, scan_get_aacfileinfo }, - { "mp3", scan_get_mp3tags, scan_get_mp3fileinfo }, - { "wav", scan_get_nultags, scan_get_wavfileinfo }, - { "url", scan_get_nultags, scan_get_urlfileinfo }, +static TAGHANDLER taghandlers[] = { + { "aac", scan_get_aactags, scan_get_aacfileinfo, "m4a", "mp4a", "AAC audio file" }, + { "mp4", scan_get_aactags, scan_get_aacfileinfo, "m4a", "mp4a", "AAC audio file" }, + { "m4a", scan_get_aactags, scan_get_aacfileinfo, "m4a", "mp4a", "AAC audio file" }, + { "m4p", scan_get_aactags, scan_get_aacfileinfo, "m4p", "mp4a", "AAC audio file" }, + { "mp3", scan_get_mp3tags, scan_get_mp3fileinfo, "mp3", "mpeg", "MPEG audio file" }, + { "wav", scan_get_nultags, scan_get_wavfileinfo, "wav", "wav", "WAV audio file" }, + { "url", scan_get_nultags, scan_get_urlfileinfo, "pls", NULL, "Playlist URL" }, + { "pls", scan_get_nultags, scan_get_urlfileinfo, "pls", NULL, "Playlist URL" }, #ifdef OGGVORBIS - { "ogg", scan_get_nultags, scan_get_oggfileinfo }, + { "ogg", scan_get_nultags, scan_get_oggfileinfo, "ogg", "ogg", "Ogg Vorbis audio file" }, #endif #ifdef FLAC - { "flac", scan_get_flactags, scan_get_flacfileinfo }, - { "fla", scan_get_flactags, scan_get_flacfileinfo }, + { "flac", scan_get_flactags, scan_get_flacfileinfo, "flac","flac", "FLAC audio file" }, + { "fla", scan_get_flactags, scan_get_flacfileinfo, "flac","flac", "FLAC audio file" }, #endif - { NULL, 0 } + { NULL, NULL, NULL, NULL, NULL, NULL } }; - /** * Convert mac time to unix time (different epochs) * @@ -520,6 +547,7 @@ void scan_static_playlist(char *path, struct dirent *pde, struct stat *psb) { DPRINTF(E_WARN,L_SCAN|L_PL,"Done processing playlist\n"); } */ + /* * scan_music_file * @@ -528,6 +556,10 @@ void scan_static_playlist(char *path, struct dirent *pde, struct stat *psb) { void scan_music_file(char *path, struct dirent *pde, struct stat *psb) { MP3FILE mp3file; char mp3_path[PATH_MAX]; + char *current=NULL; + char *type; + TAGHANDLER *ptaghandler; + char fdescr[50]; snprintf(mp3_path,sizeof(mp3_path),"%s/%s",path,pde->d_name); @@ -537,14 +569,38 @@ void scan_music_file(char *path, struct dirent *pde, struct stat *psb) { memset((void*)&mp3file,0,sizeof(mp3file)); mp3file.path=strdup(mp3_path); mp3file.fname=strdup(pde->d_name); - if(strlen(pde->d_name) > 4) - mp3file.type=strdup(strrchr(pde->d_name, '.') + 1); - - /* FIXME: assumes that st_ino is a u_int_32 - DWB: also assumes that the library is contained entirely within - one file system - */ - mp3file.id=psb->st_ino; + if(strlen(pde->d_name) > 4) { + type = strrchr(pde->d_name, '.') + 1; + if(type) { + /* see if there is "official" format and info for it */ + ptaghandler=scan_gethandler(type); + if(ptaghandler) { + /* yup, use the official format */ + mp3file.type=strdup(ptaghandler->type); + if(ptaghandler->description) + mp3file.description=strdup(ptaghandler->description); + + if(ptaghandler->codectype) + mp3file.codectype=strdup(ptaghandler->codectype); + + DPRINTF(E_DBG,L_SCAN,"Codec type: %s\n",mp3file.codectype); + } else { + /* just dummy up songformat, codectype and description */ + mp3file.type=strdup(type); + + /* upper-case types cause some problems */ + current=mp3file.type; + while(*current) { + *current=tolower(*current); + current++; + } + + sprintf(fdescr,"%s audio file",mp3file.type); + mp3file.description = strdup(fdescr); + /* we'll just dodge the codectype */ + } + } + } /* Do the tag lookup here */ if(!scan_gettags(mp3file.path,&mp3file) && @@ -559,12 +615,11 @@ void scan_music_file(char *path, struct dirent *pde, struct stat *psb) { mp3file.time_added=psb->st_ctime; mp3file.time_modified=psb->st_mtime; - // server_side_convert_set(&mp3file); - DPRINTF(E_DBG,L_SCAN," Date Added: %d\n",mp3file.time_added); + DPRINTF(E_DBG,L_SCAN," Codec: %s\n",mp3file.codectype); + db_add(&mp3file); - // pl_eval(&mp3file); /* FIXME: move to db_add? */ } else { DPRINTF(E_WARN,L_SCAN,"Skipping %s - scan_gettags failed\n",pde->d_name); } @@ -720,27 +775,37 @@ int scan_get_aactags(char *file, MP3FILE *pmp3) { } -/* - * scan_gettags +/** + * fetch the taghandler for this file type + */ +TAGHANDLER *scan_gethandler(char *type) { + TAGHANDLER *phdl = taghandlers; + + while((phdl->suffix) && (strcasecmp(phdl->suffix,type))) + phdl++; + + if(phdl->suffix) + return phdl; + + return NULL; +} + + +/** + * Dispatch the appropriate handler to get specific tag metainfomation * - * Scan an mp3 file for id3 tags using libid3tag + * \param file file to get tag info for + * \param pmp3 mp3 file struct to fill info into */ int scan_gettags(char *file, MP3FILE *pmp3) { - taghandler *hdl; + TAGHANDLER *hdl; /* dispatch to appropriate tag handler */ - for(hdl = taghandlers ; hdl->suffix ; ++hdl) - if(!strcasecmp(hdl->suffix, pmp3->type)) - break; - - if(hdl->tags) - return hdl->tags(file, pmp3); - - /* maybe this is an extension that we've manually - * specified in the config file, but don't know how - * to extract tags from. Ogg, maybe. - */ + hdl = scan_gethandler(pmp3->type); + if(hdl && hdl->tags) + return hdl->tags(file,pmp3); + /* otherwise, it's a file type we don't understand yet */ return 0; } @@ -760,9 +825,6 @@ int scan_get_mp3tags(char *file, MP3FILE *pmp3) { char *tmp; int got_numeric_genre; - if(strcasecmp(pmp3->type,"mp3")) /* can't get tags for non-mp3 */ - return 0; - pid3file=id3_file_open(file,ID3_FILE_MODE_READONLY); if(!pid3file) { DPRINTF(E_WARN,L_SCAN,"Cannot open %s\n",file); @@ -963,29 +1025,28 @@ int scan_freetags(MP3FILE *pmp3) { MAYBEFREE(pmp3->conductor); MAYBEFREE(pmp3->grouping); MAYBEFREE(pmp3->description); + MAYBEFREE(pmp3->codectype); return 0; } -/* - * scan_get_fileinfo - * +/** * Dispatch to actual file info handlers + * + * \param file file to read file metainfo for + * \param pmp3 struct to stuff with info gleaned */ int scan_get_fileinfo(char *file, MP3FILE *pmp3) { FILE *infile; off_t file_size; - taghandler *hdl; + TAGHANDLER *hdl; /* dispatch to appropriate tag handler */ - for(hdl = taghandlers ; hdl->suffix ; ++hdl) - if(!strcasecmp(hdl->suffix, pmp3->type)) - break; - - if(hdl->files) - return hdl->files(file, pmp3); + hdl = scan_gethandler(pmp3->type); + if(hdl && hdl->files) + return hdl->files(file,pmp3); /* a file we don't know anything about... ogg or aiff maybe */ if(!(infile=fopen(file,"rb"))) { @@ -1148,6 +1209,7 @@ int scan_get_aacfileinfo(char *file, MP3FILE *pmp3) { pmp3->file_size=file_size; + /* now, hunt for the mvhd atom */ atom_offset = aac_drilltoatom(infile, "moov:mvhd", &atom_length); if(atom_offset != -1) { @@ -1180,6 +1242,17 @@ int scan_get_aacfileinfo(char *file, MP3FILE *pmp3) { pmp3->bitrate = 0; + + /* see if it is aac or alac */ + atom_offset = aac_drilltoatom(infile, "moov:trak:mdia:minf:stbl:stsd:alac", &atom_length); + if(atom_offset != -1) { + /* should we still pull samplerate, etc from the this atom? */ + if(pmp3->codectype) { + free(pmp3->codectype); + } + pmp3->codectype=strdup("alac"); + } + /* Get the sample rate from the 'mp4a' atom (timescale). This is also found in the 'mdhd' atom which is a bit closer but we need to navigate to the 'mp4a' atom anyways to get to the 'esds' atom. */ @@ -1207,6 +1280,14 @@ int scan_get_aacfileinfo(char *file, MP3FILE *pmp3) { fread((void *)&bit_rate, sizeof(unsigned int), 1, infile); pmp3->bitrate = ntohl(bit_rate) / 1000; + + DPRINTF(E_DBG,L_SCAN,"esds bitrate: %d\n",pmp3->bitrate); + + if(pmp3->bitrate > 320) { + DPRINTF(E_LOG,L_SCAN,"Capping AAC bitrate. Please report this " + "message to the forums on www.mt-daapd.org. Thx.\n"); + pmp3->bitrate = 320; + } } else { DPRINTF(E_DBG,L_SCAN, "Could not find 'esds' atom to determine bit rate.\n"); } @@ -1225,7 +1306,6 @@ int scan_get_aacfileinfo(char *file, MP3FILE *pmp3) { if ((atom_offset != -1) && (pmp3->song_length)) { pmp3->bitrate = atom_length / ((pmp3->song_length / 1000) * 128); } - } fclose(infile); @@ -1809,10 +1889,8 @@ int scan_get_mp3fileinfo(char *file, MP3FILE *pmp3) { * * @param song MP3FILE of the file to build composite tags for */ -void make_composite_tags(MP3FILE *song) -{ +void make_composite_tags(MP3FILE *song) { int len; - char fdescr[50]; len=0; @@ -1837,16 +1915,8 @@ void make_composite_tags(MP3FILE *song) } } - sprintf(fdescr,"%s audio file",song->type); - song->description = strdup(fdescr); - if(song->url) { - song->description = strdup("Playlist URL"); song->data_kind=1; - /* bit of a hack for the roku soundbridge - type *has* to be pls */ - if(song->type) - free(song->type); - song->type = strdup("pls"); } else { song->data_kind=0; } @@ -1854,7 +1924,6 @@ void make_composite_tags(MP3FILE *song) if(!song->title) song->title = strdup(song->fname); - /* Ogg used to be set as an item_kind of 4. Dunno why */ - song->item_kind = 2; + song->item_kind = 2; /* music, I think. */ } diff --git a/src/mp3-scanner.h b/src/mp3-scanner.h index cdbd8dbc..e93277f0 100644 --- a/src/mp3-scanner.h +++ b/src/mp3-scanner.h @@ -63,7 +63,8 @@ typedef struct tag_mp3file { int got_id3; unsigned int id; - char* description; /* long file type */ + char *description; /* long file type */ + char *codectype; /* song.codectype */ int item_kind; /* song or movie */ int data_kind; /* dmap.datakind (asdk) */ int force_update;