1/*
2 * $Id: mp3-scanner.c,v 1.1 2009-06-30 02:31:08 steven Exp $
3 * Implementation file for mp3 scanner and monitor
4 *
5 * Ironically, this now scans file types other than mp3 files,
6 * but the name is the same for historical purposes, not to mention
7 * the fact that sf.net makes it virtually impossible to manage a cvs
8 * root reasonably.  Perhaps one day soon they will move to subversion.
9 *
10 * /me crosses his fingers
11 *
12 * Copyright (C) 2003 Ron Pedde (ron@pedde.com)
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27 */
28
29#ifdef HAVE_CONFIG_H
30#  include "config.h"
31#endif
32
33#define _POSIX_PTHREAD_SEMANTICS
34#include <ctype.h>
35#include <errno.h>
36#include <fcntl.h>
37#include <id3tag.h>
38#include <limits.h>
39#include <restart.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43
44#include <netinet/in.h>  /* htons and friends */
45#include <sys/stat.h>
46#include <dirent.h>      /* why here?  For osx 10.2, of course! */
47
48#include "daapd.h"
49#include "db-memory.h"
50#include "err.h"
51#include "mp3-scanner.h"
52#include "playlist.h"
53
54#ifndef HAVE_STRCASESTR
55# include "strcasestr.h"
56#endif
57
58/*
59 * Typedefs
60 */
61
62/**
63 * Struct to keep info about the information gleaned from
64 * the mp3 frame header.
65 */
66typedef struct tag_scan_frameinfo {
67    int layer;               /**< 1, 2, or 3, representing Layer I, II, and III */
68    int bitrate;             /**< Bitrate in kbps (128, 64, etc) */
69    int samplerate;          /**< Samplerate (e.g. 44100) */
70    int stereo;              /**< Any kind of stereo.. joint, dual mono, etc */
71
72    int frame_length;        /**< Frame length in bytes - calculated */
73    int crc_protected;       /**< Is the frame crc protected? */
74    int samples_per_frame;   /**< Samples per frame - calculated field */
75    int padding;             /**< Whether or not there is a padding sample */
76    int xing_offset;         /**< Where the xing header should be relative to end of hdr */
77    int number_of_frames;    /**< Number of frames in the song */
78
79    int frame_offset;        /**< Where this frame was found */
80
81    double version;          /**< MPEG version (e.g. 2.0, 2.5, 1.0) */
82
83    int is_valid;
84} SCAN_FRAMEINFO;
85
86
87typedef struct tag_scan_id3header {
88    unsigned char id[3];
89    unsigned char version[2];
90    unsigned char flags;
91    unsigned char size[4];
92} __attribute((packed)) SCAN_ID3HEADER;
93
94#define MAYBEFREE(a) { if((a)) free((a)); };
95
96/*
97 * Globals
98 */
99int scan_br_table[5][16] = {
100    { 0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0 }, /* MPEG1, Layer 1 */
101    { 0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0 },    /* MPEG1, Layer 2 */
102    { 0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0 },     /* MPEG1, Layer 3 */
103    { 0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0 },    /* MPEG2/2.5, Layer 1 */
104    { 0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0 }          /* MPEG2/2.5, Layer 2/3 */
105};
106
107int scan_sample_table[3][4] = {
108    { 44100, 48000, 32000, 0 },  /* MPEG 1 */
109    { 22050, 24000, 16000, 0 },  /* MPEG 2 */
110    { 11025, 12000, 8000, 0 }    /* MPEG 2.5 */
111};
112
113
114
115int scan_mode_foreground=1;
116
117char *scan_winamp_genre[] = {
118    "Blues",              // 0
119    "Classic Rock",
120    "Country",
121    "Dance",
122    "Disco",
123    "Funk",               // 5
124    "Grunge",
125    "Hip-Hop",
126    "Jazz",
127    "Metal",
128    "New Age",            // 10
129    "Oldies",
130    "Other",
131    "Pop",
132    "R&B",
133    "Rap",                // 15
134    "Reggae",
135    "Rock",
136    "Techno",
137    "Industrial",
138    "Alternative",        // 20
139    "Ska",
140    "Death Metal",
141    "Pranks",
142    "Soundtrack",
143    "Euro-Techno",        // 25
144    "Ambient",
145    "Trip-Hop",
146    "Vocal",
147    "Jazz+Funk",
148    "Fusion",             // 30
149    "Trance",
150    "Classical",
151    "Instrumental",
152    "Acid",
153    "House",              // 35
154    "Game",
155    "Sound Clip",
156    "Gospel",
157    "Noise",
158    "AlternRock",         // 40
159    "Bass",
160    "Soul",
161    "Punk",
162    "Space",
163    "Meditative",         // 45
164    "Instrumental Pop",
165    "Instrumental Rock",
166    "Ethnic",
167    "Gothic",
168    "Darkwave",           // 50
169    "Techno-Industrial",
170    "Electronic",
171    "Pop-Folk",
172    "Eurodance",
173    "Dream",              // 55
174    "Southern Rock",
175    "Comedy",
176    "Cult",
177    "Gangsta",
178    "Top 40",             // 60
179    "Christian Rap",
180    "Pop/Funk",
181    "Jungle",
182    "Native American",
183    "Cabaret",            // 65
184    "New Wave",
185    "Psychadelic",
186    "Rave",
187    "Showtunes",
188    "Trailer",            // 70
189    "Lo-Fi",
190    "Tribal",
191    "Acid Punk",
192    "Acid Jazz",
193    "Polka",              // 75
194    "Retro",
195    "Musical",
196    "Rock & Roll",
197    "Hard Rock",
198    "Folk",               // 80
199    "Folk/Rock",
200    "National folk",
201    "Swing",
202    "Fast-fusion",
203    "Bebob",              // 85
204    "Latin",
205    "Revival",
206    "Celtic",
207    "Bluegrass",
208    "Avantgarde",         // 90
209    "Gothic Rock",
210    "Progressive Rock",
211    "Psychedelic Rock",
212    "Symphonic Rock",
213    "Slow Rock",          // 95
214    "Big Band",
215    "Chorus",
216    "Easy Listening",
217    "Acoustic",
218    "Humour",             // 100
219    "Speech",
220    "Chanson",
221    "Opera",
222    "Chamber Music",
223    "Sonata",             // 105
224    "Symphony",
225    "Booty Bass",
226    "Primus",
227    "Porn Groove",
228    "Satire",             // 110
229    "Slow Jam",
230    "Club",
231    "Tango",
232    "Samba",
233    "Folklore",           // 115
234    "Ballad",
235    "Powder Ballad",
236    "Rhythmic Soul",
237    "Freestyle",
238    "Duet",               // 120
239    "Punk Rock",
240    "Drum Solo",
241    "A Capella",
242    "Euro-House",
243    "Dance Hall",         // 125
244    "Goa",
245    "Drum & Bass",
246    "Club House",
247    "Hardcore",
248    "Terror",             // 130
249    "Indie",
250    "BritPop",
251    "NegerPunk",
252    "Polsk Punk",
253    "Beat",               // 135
254    "Christian Gangsta",
255    "Heavy Metal",
256    "Black Metal",
257    "Crossover",
258    "Contemporary C",     // 140
259    "Christian Rock",
260    "Merengue",
261    "Salsa",
262    "Thrash Metal",
263    "Anime",              // 145
264    "JPop",
265    "SynthPop",
266    "Unknown"
267};
268
269#define WINAMP_GENRE_UNKNOWN 148
270
271
272/*
273 * Forwards
274 */
275static int scan_path(char *path);
276static int scan_gettags(char *file, MP3FILE *pmp3);
277static int scan_get_mp3tags(char *file, MP3FILE *pmp3);
278static int scan_get_aactags(char *file, MP3FILE *pmp3);
279static int scan_get_nultags(char *file, MP3FILE *pmp3) { return 0; };
280static int scan_get_fileinfo(char *file, MP3FILE *pmp3);
281static int scan_get_mp3fileinfo(char *file, MP3FILE *pmp3);
282static int scan_get_aacfileinfo(char *file, MP3FILE *pmp3);
283static int scan_get_nulfileinfo(char *file, MP3FILE *pmp3) { return 0; };
284static int scan_get_urlfileinfo(char *file, MP3FILE *pmp3);
285
286static int scan_freetags(MP3FILE *pmp3);
287static void scan_static_playlist(char *path, struct dirent *pde, struct stat *psb);
288static void scan_music_file(char *path, struct dirent *pde, struct stat *psb);
289
290static int scan_decode_mp3_frame(unsigned char *frame, SCAN_FRAMEINFO *pfi);
291static time_t mac_to_unix_time(int t);
292
293#ifdef OGGVORBIS
294extern int scan_get_oggfileinfo(char *filename, MP3FILE *pmp3);
295#endif
296
297/*
298 * Typedefs
299 */
300
301typedef struct {
302    char*	suffix;
303    int		(*tags)(char* file, MP3FILE* pmp3);
304    int		(*files)(char* file, MP3FILE* pmp3);
305} taghandler;
306
307static taghandler taghandlers[] = {
308    { "aac", scan_get_aactags, scan_get_aacfileinfo },
309    { "mp4", scan_get_aactags, scan_get_aacfileinfo },
310    { "m4a", scan_get_aactags, scan_get_aacfileinfo },
311    { "m4p", scan_get_aactags, scan_get_aacfileinfo },
312    { "mp3", scan_get_mp3tags, scan_get_mp3fileinfo },
313    { "url", scan_get_nultags, scan_get_urlfileinfo },
314#ifdef OGGVORBIS
315    { "ogg", scan_get_nultags, scan_get_oggfileinfo },
316#endif
317    { NULL, 0 }
318};
319
320
321/**
322 * Convert mac time to unix time (different epochs)
323 *
324 * param t time since mac epoch
325 */
326time_t mac_to_unix_time(int t) {
327  struct timeval        tv;
328  struct timezone       tz;
329
330  gettimeofday(&tv, &tz);
331
332  return (t - (365L * 66L * 24L * 60L * 60L + 17L * 60L * 60L * 24L) +
333          (tz.tz_minuteswest * 60));
334}
335
336/*
337 * scan_init
338 *
339 * This assumes the database is already initialized.
340 *
341 * Ideally, this would check to see if the database is empty.
342 * If it is, it sets the database into bulk-import mode, and scans
343 * the MP3 directory.
344 *
345 * If not empty, it would start a background monitor thread
346 * and update files on a file-by-file basis
347 */
348
349int scan_init(char *path) {
350    int err;
351
352    scan_mode_foreground=0;
353    if(db_is_empty()) {
354	scan_mode_foreground=1;
355    }
356
357    if(db_start_initial_update())
358	return -1;
359
360    DPRINTF(E_DBG,L_SCAN,"%s scanning for MP3s in %s\n",
361	    scan_mode_foreground ? "Foreground" : "Background",
362	    path);
363
364    err=scan_path(path);
365
366    if(db_end_initial_update())
367	return -1;
368
369    scan_mode_foreground=0;
370
371    return err;
372}
373
374int
375is_dir(const char *path)
376{
377	struct stat stat_buf;
378
379	if (!stat(path, &stat_buf))
380		return S_ISDIR(stat_buf.st_mode);
381	else
382		return 0;
383}
384
385int
386is_sys_dir(const char *dirname)
387{
388	char *MS_System_folder[] = {"SYSTEM VOLUME INFORMATION", "RECYCLER", "RECYCLED", "$RECYCLE.BIN", "asusware", NULL};
389	char *Linux_System_folder[] = {"lost+found", NULL};
390	int i;
391
392	for (i = 0; MS_System_folder[i] != NULL; ++i) {
393		if (!strcasecmp(dirname, MS_System_folder[i]))
394			return 1;
395	}
396
397	for (i = 0; Linux_System_folder[i] != NULL; ++i) {
398		if (!strcasecmp(dirname, Linux_System_folder[i]))
399		return 1;
400	}
401
402	return 0;
403}
404
405/*
406 * scan_path
407 *
408 * Do a brute force scan of a path, finding all the MP3 files there
409 */
410int scan_path(char *path) {
411    DIR *current_dir;
412    char de[sizeof(struct dirent) + MAXNAMLEN + 1]; /* overcommit for solaris */
413    struct dirent *pde;
414    int err;
415    char mp3_path[PATH_MAX];
416    struct stat sb;
417    int modified_time;
418
419    if((current_dir=opendir(path)) == NULL) {
420	return -1;
421    }
422
423    while(1) {
424	if(config.stop) {
425	    DPRINTF(E_WARN,L_SCAN,"Stop detected.  Aborting scan of %s.\n",path);
426	    closedir(current_dir);
427	    return 0;
428	}
429
430	pde=(struct dirent *)&de;
431
432	err=readdir_r(current_dir,(struct dirent *)de,&pde);
433	if(err == -1) {
434	    DPRINTF(E_DBG,L_SCAN,"Error on readdir_r: %s\n",strerror(errno));
435	    err=errno;
436	    closedir(current_dir);
437	    errno=err;
438	    return -1;
439	}
440
441	if(!pde)
442	    break;
443
444	if(pde->d_name[0] == '.') /* skip hidden and directories */
445	    continue;
446
447	snprintf(mp3_path,PATH_MAX,"%s/%s",path,pde->d_name);
448
449	if (is_dir(mp3_path) && is_sys_dir(pde->d_name))
450	    continue;
451
452	DPRINTF(E_DBG,L_SCAN,"Found %s\n",mp3_path);
453	if(stat(mp3_path,&sb)) {
454	    DPRINTF(E_WARN,L_SCAN,"Error statting: %s\n",strerror(errno));
455	} else {
456	    if(sb.st_mode & S_IFDIR) { /* dir -- recurse */
457		DPRINTF(E_DBG,L_SCAN,"Found dir %s... recursing\n",pde->d_name);
458		scan_path(mp3_path);
459	    } else {
460		/* process the file */
461		if(strlen(pde->d_name) > 4) {
462		    if((strcasecmp(".m3u",(char*)&pde->d_name[strlen(pde->d_name) - 4]) == 0) &&
463		       config.process_m3u){
464			/* we found an m3u file */
465			scan_static_playlist(path, pde, &sb);
466		    } else if (strcasestr(config.extensions,
467					  (char*)&pde->d_name[strlen(pde->d_name) - 4])) {
468
469			/* only scan if it's been changed, or empty db */
470			modified_time=sb.st_mtime;
471			DPRINTF(E_DBG,L_SCAN,"FS Mod time: %d\n",modified_time);
472			DPRINTF(E_DBG,L_SCAN,"DB Mod time: %d\n",db_last_modified(sb.st_ino));
473			if((scan_mode_foreground) ||
474			   !db_exists(sb.st_ino) ||
475			   db_last_modified(sb.st_ino) < modified_time) {
476			    scan_music_file(path,pde,&sb);
477			} else {
478			    DPRINTF(E_DBG,L_SCAN,"Skipping file... not modified\n");
479			}
480		    }
481		}
482	    }
483	}
484    }
485
486    closedir(current_dir);
487    return 0;
488}
489
490/*
491 * scan_static_playlist
492 *
493 * Scan a file as a static playlist
494 */
495void scan_static_playlist(char *path, struct dirent *pde, struct stat *psb) {
496    char playlist_path[PATH_MAX];
497    char m3u_path[PATH_MAX];
498    char linebuffer[PATH_MAX];
499    int fd;
500    int playlistid;
501    struct stat sb;
502
503    DPRINTF(E_WARN,L_SCAN|L_PL,"Processing static playlist: %s\n",pde->d_name);
504
505    /* see if we should update it */
506    if(db_playlist_last_modified(psb->st_ino) == psb->st_mtime)
507	return;
508
509    db_delete_playlist(psb->st_ino);
510
511    strcpy(m3u_path,pde->d_name);
512    snprintf(playlist_path,sizeof(playlist_path),"%s/%s",path,pde->d_name);
513    m3u_path[strlen(pde->d_name) - 4] = '\0';
514    playlistid=psb->st_ino;
515    fd=open(playlist_path,O_RDONLY);
516    if(fd != -1) {
517	db_add_playlist(playlistid,m3u_path,psb->st_mtime,0);
518	DPRINTF(E_INF,L_SCAN|L_PL,"Added playlist as id %d\n",playlistid);
519
520	memset(linebuffer,0x00,sizeof(linebuffer));
521	while(readline(fd,linebuffer,sizeof(linebuffer)) > 0) {
522	    while((linebuffer[strlen(linebuffer)-1] == '\n') ||
523		  (linebuffer[strlen(linebuffer)-1] == '\r'))   /* windows? */
524		linebuffer[strlen(linebuffer)-1] = '\0';
525
526	    if((linebuffer[0] == ';') || (linebuffer[0] == '#'))
527		continue;
528
529	    /* FIXME - should chomp trailing comments */
530
531	    /* otherwise, assume it is a path */
532	    if(linebuffer[0] == '/') {
533		strcpy(m3u_path,linebuffer);
534	    } else {
535		snprintf(m3u_path,sizeof(m3u_path),"%s/%s",path,linebuffer);
536	    }
537
538	    DPRINTF(E_DBG,L_SCAN|L_PL,"Checking %s\n",m3u_path);
539
540	    /* might be valid, might not... */
541	    if(!stat(m3u_path,&sb)) {
542		/* FIXME: check to see if valid inode! */
543		db_add_playlist_song(playlistid,sb.st_ino);
544	    } else {
545		DPRINTF(E_WARN,L_SCAN|L_PL,"Playlist entry %s bad: %s\n",
546			m3u_path,strerror(errno));
547	    }
548	}
549	close(fd);
550    }
551
552    DPRINTF(E_WARN,L_SCAN|L_PL,"Done processing playlist\n");
553}
554
555/*
556 * scan_music_file
557 *
558 * scan a particular file as a music file
559 */
560void scan_music_file(char *path, struct dirent *pde, struct stat *psb) {
561    MP3FILE mp3file;
562    char mp3_path[PATH_MAX];
563
564    snprintf(mp3_path,sizeof(mp3_path),"%s/%s",path,pde->d_name);
565
566    /* we found an mp3 file */
567    DPRINTF(E_INF,L_SCAN,"Found music file: %s\n",pde->d_name);
568
569    memset((void*)&mp3file,0,sizeof(mp3file));
570    mp3file.path=mp3_path;
571    mp3file.fname=pde->d_name;
572    if(strlen(pde->d_name) > 4)
573	mp3file.type=strdup(strrchr(pde->d_name, '.') + 1);
574
575    /* FIXME: assumes that st_ino is a u_int_32
576       DWB: also assumes that the library is contained entirely within
577       one file system
578    */
579    mp3file.id=psb->st_ino;
580
581    /* Do the tag lookup here */
582    if(!scan_gettags(mp3file.path,&mp3file) &&
583       !scan_get_fileinfo(mp3file.path,&mp3file)) {
584	make_composite_tags(&mp3file);
585	/* fill in the time_added.  I'm not sure of the logic in this.
586	   My thinking is to use time created, but what is that?  Best
587	   guess would be earliest of st_mtime and st_ctime...
588	*/
589	mp3file.time_added=psb->st_mtime;
590	if(psb->st_ctime < mp3file.time_added)
591	    mp3file.time_added=psb->st_ctime;
592        mp3file.time_modified=psb->st_mtime;
593
594	DPRINTF(E_DBG,L_SCAN," Date Added: %d\n",mp3file.time_added);
595
596	db_add(&mp3file);
597	pl_eval(&mp3file); /* FIXME: move to db_add? */
598    } else {
599	DPRINTF(E_WARN,L_SCAN,"Skipping %s - scan_gettags failed\n",pde->d_name);
600    }
601
602    scan_freetags(&mp3file);
603}
604
605/*
606 * scan_aac_findatom
607 *
608 * Find an AAC atom
609 */
610long scan_aac_findatom(FILE *fin, long max_offset, char *which_atom, int *atom_size) {
611    long current_offset=0;
612    int size;
613    char atom[4];
614
615    while(current_offset < max_offset) {
616	if(fread((void*)&size,1,sizeof(int),fin) != sizeof(int))
617	    return -1;
618
619	size=ntohl(size);
620
621	if(size <= 7) /* something not right */
622	    return -1;
623
624	if(fread(atom,1,4,fin) != 4)
625	    return -1;
626
627	if(strncasecmp(atom,which_atom,4) == 0) {
628	    *atom_size=size;
629	    return current_offset;
630	}
631
632	fseek(fin,size-8,SEEK_CUR);
633	current_offset+=size;
634    }
635
636    return -1;
637}
638
639/*
640 * scan_get_aactags
641 *
642 * Get tags from an AAC (m4a) file
643 */
644int scan_get_aactags(char *file, MP3FILE *pmp3) {
645    FILE *fin;
646    long atom_offset;
647    int atom_length;
648
649    long current_offset=0;
650    int current_size;
651    char current_atom[4];
652    char *current_data;
653    unsigned short us_data;
654    int genre;
655    int len;
656
657    if(!(fin=fopen(file,"rb"))) {
658	DPRINTF(E_INF,L_SCAN,"Cannot open file %s for reading\n",file);
659	return -1;
660    }
661
662    fseek(fin,0,SEEK_SET);
663
664    atom_offset = aac_drilltoatom(fin, "moov:udta:meta:ilst", &atom_length);
665    if(atom_offset != -1) {
666	/* found the tag section - need to walk through now */
667
668	while(current_offset < atom_length) {
669	    if(fread((void*)&current_size,1,sizeof(int),fin) != sizeof(int))
670		break;
671
672	    current_size=ntohl(current_size);
673
674	    if(current_size <= 7) /* something not right */
675		break;
676
677	    if(fread(current_atom,1,4,fin) != 4)
678		break;
679
680	    len=current_size-7;  /* for ill-formed too-short tags */
681	    if(len < 22)
682		len=22;
683
684	    current_data=(char*)malloc(len);  /* extra byte */
685	    memset(current_data,0x00,len);
686
687	    if(fread(current_data,1,current_size-8,fin) != current_size-8)
688		break;
689
690	    if(!memcmp(current_atom,"\xA9" "nam",4)) { /* Song name */
691		pmp3->title=strdup((char*)&current_data[16]);
692	    } else if(!memcmp(current_atom,"\xA9" "ART",4)) {
693		pmp3->artist=strdup((char*)&current_data[16]);
694	    } else if(!memcmp(current_atom,"\xA9" "alb",4)) {
695		pmp3->album=strdup((char*)&current_data[16]);
696	    } else if(!memcmp(current_atom,"\xA9" "cmt",4)) {
697		pmp3->comment=strdup((char*)&current_data[16]);
698	    } else if(!memcmp(current_atom,"\xA9" "wrt",4)) {
699		pmp3->composer=strdup((char*)&current_data[16]);
700	    } else if(!memcmp(current_atom,"\xA9" "grp",4)) {
701		pmp3->grouping=strdup((char*)&current_data[16]);
702	    } else if(!memcmp(current_atom,"\xA9" "gen",4)) {
703		/* can this be a winamp genre??? */
704		pmp3->genre=strdup((char*)&current_data[16]);
705	    } else if(!memcmp(current_atom,"tmpo",4)) {
706		us_data=*((unsigned short *)&current_data[16]);
707		us_data=ntohs(us_data);
708		pmp3->bpm=us_data;
709	    } else if(!memcmp(current_atom,"trkn",4)) {
710		us_data=*((unsigned short *)&current_data[18]);
711		us_data=ntohs(us_data);
712
713		pmp3->track=us_data;
714
715		us_data=*((unsigned short *)&current_data[20]);
716		us_data=ntohs(us_data);
717
718		pmp3->total_tracks=us_data;
719	    } else if(!memcmp(current_atom,"disk",4)) {
720		us_data=*((unsigned short *)&current_data[18]);
721		us_data=ntohs(us_data);
722
723		pmp3->disc=us_data;
724
725		us_data=*((unsigned short *)&current_data[20]);
726		us_data=ntohs(us_data);
727
728		pmp3->total_discs=us_data;
729	    } else if(!memcmp(current_atom,"\xA9" "day",4)) {
730		pmp3->year=atoi((char*)&current_data[16]);
731	    } else if(!memcmp(current_atom,"gnre",4)) {
732		genre=(int)(*((char*)&current_data[17]));
733		genre--;
734
735		if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
736		    genre=WINAMP_GENRE_UNKNOWN;
737
738		pmp3->genre=strdup(scan_winamp_genre[genre]);
739	    } else if (!memcmp(current_atom, "cpil", 4)) {
740		pmp3->compilation = current_data[16];
741	    }
742
743	    free(current_data);
744	    current_offset+=current_size;
745	}
746    }
747
748    fclose(fin);
749    return 0;  /* we'll return as much as we got. */
750}
751
752
753/*
754 * scan_gettags
755 *
756 * Scan an mp3 file for id3 tags using libid3tag
757 */
758int scan_gettags(char *file, MP3FILE *pmp3) {
759    taghandler *hdl;
760
761    /* dispatch to appropriate tag handler */
762    for(hdl = taghandlers ; hdl->suffix ; ++hdl)
763	if(!strcasecmp(hdl->suffix, pmp3->type))
764	    break;
765
766    if(hdl->tags)
767	return hdl->tags(file, pmp3);
768
769    /* maybe this is an extension that we've manually
770     * specified in the config file, but don't know how
771     * to extract tags from.  Ogg, maybe.
772     */
773
774    return 0;
775}
776
777
778int scan_get_mp3tags(char *file, MP3FILE *pmp3) {
779    struct id3_file *pid3file;
780    struct id3_tag *pid3tag;
781    struct id3_frame *pid3frame;
782    int err;
783    int index;
784    int used;
785    unsigned char *utf8_text;
786    int genre=WINAMP_GENRE_UNKNOWN;
787    int have_utf8;
788    int have_text;
789    id3_ucs4_t const *native_text;
790    char *tmp;
791    int got_numeric_genre;
792
793    if(strcasecmp(pmp3->type,"mp3"))  /* can't get tags for non-mp3 */
794	return 0;
795
796    pid3file=id3_file_open(file,ID3_FILE_MODE_READONLY);
797    if(!pid3file) {
798	DPRINTF(E_WARN,L_SCAN,"Cannot open %s\n",file);
799	return -1;
800    }
801
802    pid3tag=id3_file_tag(pid3file);
803
804    if(!pid3tag) {
805	err=errno;
806	id3_file_close(pid3file);
807	errno=err;
808	DPRINTF(E_WARN,L_SCAN,"Cannot get ID3 tag for %s\n",file);
809	return -1;
810    }
811
812    index=0;
813    while((pid3frame=id3_tag_findframe(pid3tag,"",index))) {
814	used=0;
815	utf8_text=NULL;
816	native_text=NULL;
817	have_utf8=0;
818	have_text=0;
819
820	if(!strcmp(pid3frame->id,"YTCP")) { /* for id3v2.2 */
821	    pmp3->compilation = 1;
822	    DPRINTF(E_DBG,L_SCAN,"Compilation: %d\n", pmp3->compilation);
823	}
824
825	if(((pid3frame->id[0] == 'T')||(strcmp(pid3frame->id,"COMM")==0)) &&
826	   (id3_field_getnstrings(&pid3frame->fields[1])))
827	    have_text=1;
828
829	if(have_text) {
830	    native_text=id3_field_getstrings(&pid3frame->fields[1],0);
831
832	    if(native_text) {
833		have_utf8=1;
834		utf8_text=id3_ucs4_utf8duplicate(native_text);
835		MEMNOTIFY(utf8_text);
836
837		if(!strcmp(pid3frame->id,"TIT2")) { /* Title */
838		    used=1;
839		    pmp3->title = utf8_text;
840		    DPRINTF(E_DBG,L_SCAN," Title: %s\n",utf8_text);
841		} else if(!strcmp(pid3frame->id,"TPE1")) {
842		    used=1;
843		    pmp3->artist = utf8_text;
844		    DPRINTF(E_DBG,L_SCAN," Artist: %s\n",utf8_text);
845		} else if(!strcmp(pid3frame->id,"TALB")) {
846		    used=1;
847		    pmp3->album = utf8_text;
848		    DPRINTF(E_DBG,L_SCAN," Album: %s\n",utf8_text);
849		} else if(!strcmp(pid3frame->id,"TCOM")) {
850		    used=1;
851		    pmp3->composer = utf8_text;
852		    DPRINTF(E_DBG,L_SCAN," Composer: %s\n",utf8_text);
853		} else if(!strcmp(pid3frame->id,"TIT1")) {
854		    used=1;
855		    pmp3->grouping = utf8_text;
856		    DPRINTF(E_DBG,L_SCAN," Grouping: %s\n",utf8_text);
857		} else if(!strcmp(pid3frame->id,"TPE2")) {
858		    used=1;
859		    pmp3->orchestra = utf8_text;
860		    DPRINTF(E_DBG,L_SCAN," Orchestra: %s\n",utf8_text);
861		} else if(!strcmp(pid3frame->id,"TPE3")) {
862		    used=1;
863		    pmp3->conductor = utf8_text;
864		    DPRINTF(E_DBG,L_SCAN," Conductor: %s\n",utf8_text);
865		} else if(!strcmp(pid3frame->id,"TCON")) {
866		    used=1;
867		    pmp3->genre = utf8_text;
868		    got_numeric_genre=0;
869		    DPRINTF(E_DBG,L_SCAN," Genre: %s\n",utf8_text);
870		    if(pmp3->genre) {
871			if(!strlen(pmp3->genre)) {
872			    genre=WINAMP_GENRE_UNKNOWN;
873			    got_numeric_genre=1;
874			} else if (isdigit(pmp3->genre[0])) {
875			    genre=atoi(pmp3->genre);
876			    got_numeric_genre=1;
877			} else if ((pmp3->genre[0] == '(') && (isdigit(pmp3->genre[1]))) {
878			    genre=atoi((char*)&pmp3->genre[1]);
879			    got_numeric_genre=1;
880			}
881
882			if(got_numeric_genre) {
883			    if((genre < 0) || (genre > WINAMP_GENRE_UNKNOWN))
884				genre=WINAMP_GENRE_UNKNOWN;
885			    free(pmp3->genre);
886			    pmp3->genre=strdup(scan_winamp_genre[genre]);
887			}
888		    }
889		} else if(!strcmp(pid3frame->id,"COMM")) {
890		    used=1;
891		    pmp3->comment = utf8_text;
892		    DPRINTF(E_DBG,L_SCAN," Comment: %s\n",pmp3->comment);
893		} else if(!strcmp(pid3frame->id,"TPOS")) {
894		    tmp=(char*)utf8_text;
895		    strsep(&tmp,"/");
896		    if(tmp) {
897			pmp3->total_discs=atoi(tmp);
898		    }
899		    pmp3->disc=atoi((char*)utf8_text);
900		    DPRINTF(E_DBG,L_SCAN," Disc %d of %d\n",pmp3->disc,pmp3->total_discs);
901		} else if(!strcmp(pid3frame->id,"TRCK")) {
902		    tmp=(char*)utf8_text;
903		    strsep(&tmp,"/");
904		    if(tmp) {
905			pmp3->total_tracks=atoi(tmp);
906		    }
907		    pmp3->track=atoi((char*)utf8_text);
908		    DPRINTF(E_DBG,L_SCAN," Track %d of %d\n",pmp3->track,pmp3->total_tracks);
909		} else if(!strcmp(pid3frame->id,"TDRC")) {
910		    pmp3->year = atoi(utf8_text);
911		    DPRINTF(E_DBG,L_SCAN," Year: %d\n",pmp3->year);
912		} else if(!strcmp(pid3frame->id,"TLEN")) {
913		    pmp3->song_length = atoi(utf8_text); /* now in ms */
914		    DPRINTF(E_DBG,L_SCAN," Length: %d\n", pmp3->song_length);
915		} else if(!strcmp(pid3frame->id,"TBPM")) {
916		    pmp3->bpm = atoi(utf8_text);
917		    DPRINTF(E_DBG,L_SCAN,"BPM: %d\n", pmp3->bpm);
918		} else if(!strcmp(pid3frame->id,"TCMP")) { /* for id3v2.3 */
919                    pmp3->compilation = (char)atoi(utf8_text);
920                    DPRINTF(E_DBG,L_SCAN,"Compilation: %d\n", pmp3->compilation);
921                }
922	    }
923	}
924
925	/* can check for non-text tags here */
926	if((!used) && (have_utf8) && (utf8_text))
927	    free(utf8_text);
928
929	/* v2 COMM tags are a bit different than v1 */
930	if((!strcmp(pid3frame->id,"COMM")) && (pid3frame->nfields == 4)) {
931	    /* Make sure it isn't a application-specific comment...
932	     * This currently includes the following:
933	     *
934	     * iTunes_CDDB_IDs
935	     * iTunNORM
936	     *
937	     * If other apps stuff crap into comment fields, then we'll ignore them
938	     * here.
939	     */
940	    native_text=id3_field_getstring(&pid3frame->fields[2]);
941	    if(native_text) {
942		utf8_text=id3_ucs4_utf8duplicate(native_text);
943		if((utf8_text) && (strncasecmp(utf8_text,"iTun",4) != 0)) {
944		    /* it's a real comment */
945		    if(utf8_text)
946			free(utf8_text);
947
948		    native_text=id3_field_getfullstring(&pid3frame->fields[3]);
949		    if(native_text) {
950			if(pmp3->comment)
951			    free(pmp3->comment);
952			utf8_text=id3_ucs4_utf8duplicate(native_text);
953			if(utf8_text) {
954			    pmp3->comment=utf8_text;
955			    MEMNOTIFY(pmp3->comment);
956			}
957		    }
958		} else {
959		    if(utf8_text)
960			free(utf8_text);
961		}
962	    }
963	}
964
965	index++;
966    }
967
968    id3_file_close(pid3file);
969    DPRINTF(E_DBG,L_SCAN,"Got id3 tag successfully\n");
970    return 0;
971}
972
973/*
974 * scan_freetags
975 *
976 * Free up the tags that were dynamically allocated
977 */
978int scan_freetags(MP3FILE *pmp3) {
979    MAYBEFREE(pmp3->title);
980    MAYBEFREE(pmp3->artist);
981    MAYBEFREE(pmp3->album);
982    MAYBEFREE(pmp3->genre);
983    MAYBEFREE(pmp3->comment);
984    MAYBEFREE(pmp3->type);
985    MAYBEFREE(pmp3->composer);
986    MAYBEFREE(pmp3->orchestra);
987    MAYBEFREE(pmp3->conductor);
988    MAYBEFREE(pmp3->grouping);
989    MAYBEFREE(pmp3->description);
990
991    return 0;
992}
993
994
995/*
996 * scan_get_fileinfo
997 *
998 * Dispatch to actual file info handlers
999 */
1000int scan_get_fileinfo(char *file, MP3FILE *pmp3) {
1001    FILE *infile;
1002    off_t file_size;
1003
1004    taghandler *hdl;
1005
1006    /* dispatch to appropriate tag handler */
1007    for(hdl = taghandlers ; hdl->suffix ; ++hdl)
1008	if(!strcmp(hdl->suffix, pmp3->type))
1009	    break;
1010
1011    if(hdl->files)
1012	return hdl->files(file, pmp3);
1013
1014    /* a file we don't know anything about... ogg or aiff maybe */
1015    if(!(infile=fopen(file,"rb"))) {
1016	DPRINTF(E_WARN,L_SCAN,"Could not open %s for reading\n",file);
1017	return -1;
1018    }
1019
1020    /* we can at least get this */
1021    fseek(infile,0,SEEK_END);
1022    file_size=ftell(infile);
1023    fseek(infile,0,SEEK_SET);
1024
1025    pmp3->file_size=file_size;
1026
1027    fclose(infile);
1028    return 0;
1029}
1030
1031/*
1032 * aac_drilltoatom
1033 *
1034 * Returns the offset of the atom specified by the given path or -1 if
1035 * not found. atom_path is a colon separated list of atoms specifying
1036 * a path from parent node to the target node. All paths must be specified
1037 * from the root.
1038 */
1039off_t aac_drilltoatom(FILE *aac_fp, char *atom_path, unsigned int *atom_length)
1040{
1041    long          atom_offset;
1042    off_t         file_size;
1043    char          *cur_p, *end_p;
1044    char          atom_name[5];
1045
1046    fseek(aac_fp, 0, SEEK_END);
1047    file_size = ftell(aac_fp);
1048    rewind(aac_fp);
1049
1050    end_p = atom_path;
1051    while (*end_p != '\0')
1052	{
1053	    end_p++;
1054	}
1055    atom_name[4] = '\0';
1056    cur_p = atom_path;
1057
1058    while (cur_p != NULL)
1059	{
1060	    if ((end_p - cur_p) < 4)
1061		{
1062		    return -1;
1063		}
1064	    strncpy(atom_name, cur_p, 4);
1065	    atom_offset = scan_aac_findatom(aac_fp, file_size, atom_name, atom_length);
1066	    if (atom_offset == -1)
1067		{
1068		    return -1;
1069		}
1070	    DPRINTF(E_DBG,L_SCAN,"Found %s atom at off %ld.\n", atom_name, ftell(aac_fp) - 8);
1071	    cur_p = strchr(cur_p, ':');
1072	    if (cur_p != NULL)
1073		{
1074		    cur_p++;
1075
1076		    /* PENDING: Hack to deal with atoms that have extra data in addition
1077		       to having child atoms. This should be dealt in a better fashion
1078		       than this (table with skip offsets or an actual real mp4 parser.) */
1079		    if (!strcmp(atom_name, "meta")) {
1080			fseek(aac_fp, 4, SEEK_CUR);
1081		    } else if (!strcmp(atom_name, "stsd")) {
1082			fseek(aac_fp, 8, SEEK_CUR);
1083		    } else if (!strcmp(atom_name, "mp4a")) {
1084			fseek(aac_fp, 28, SEEK_CUR);
1085		    }
1086		}
1087	}
1088
1089    return ftell(aac_fp) - 8;
1090}
1091
1092/*
1093 * scan_get_urlfileinfo
1094 *
1095 * Get info from a "url" file -- a media stream file
1096 */
1097int scan_get_urlfileinfo(char *file, MP3FILE *pmp3) {
1098    FILE *infile;
1099    char *head, *tail;
1100    char linebuffer[256];
1101
1102    DPRINTF(E_DBG,L_SCAN,"Getting URL file info\n");
1103
1104    if(!(infile=fopen(file,"rb"))) {
1105	DPRINTF(E_WARN,L_SCAN,"Could not open %s for reading\n",file);
1106	return -1;
1107    }
1108
1109    fgets(linebuffer,sizeof(linebuffer),infile);
1110    while((linebuffer[strlen(linebuffer)-1] == '\n') ||
1111	  (linebuffer[strlen(linebuffer)-1] == '\r')) {
1112	linebuffer[strlen(linebuffer)-1] = '\0';
1113    }
1114
1115    head=linebuffer;
1116    tail=strchr(head,',');
1117    if(!tail) {
1118	DPRINTF(E_LOG,L_SCAN,"Badly formatted .url file - must be bitrate,descr,url\n");
1119	fclose(infile);
1120	return -1;
1121    }
1122
1123    pmp3->bitrate=atoi(head);
1124    head=++tail;
1125    tail=strchr(head,',');
1126    if(!tail) {
1127	DPRINTF(E_LOG,L_SCAN,"Badly formatted .url file - must be bitrate,descr,url\n");
1128	fclose(infile);
1129	return -1;
1130    }
1131
1132    *tail++='\0';
1133
1134    pmp3->title=strdup(head);
1135    pmp3->url=strdup(tail);
1136    fclose(infile);
1137
1138    DPRINTF(E_DBG,L_SCAN,"  Title:    %s\n",pmp3->title);
1139    DPRINTF(E_DBG,L_SCAN,"  Bitrate:  %d\n",pmp3->bitrate);
1140    DPRINTF(E_DBG,L_SCAN,"  URL:      %s\n",pmp3->url);
1141
1142    return 0;
1143}
1144
1145/*
1146 * scan_get_aacfileinfo
1147 *
1148 * Get info from the actual aac headers
1149 */
1150int scan_get_aacfileinfo(char *file, MP3FILE *pmp3) {
1151    FILE *infile;
1152    long atom_offset;
1153    int atom_length;
1154    int sample_size;
1155    int samples;
1156    unsigned int bit_rate;
1157    off_t file_size;
1158    int ms;
1159    unsigned char buffer[2];
1160    int time = 0;
1161
1162    DPRINTF(E_DBG,L_SCAN,"Getting AAC file info\n");
1163
1164    if(!(infile=fopen(file,"rb"))) {
1165	DPRINTF(E_WARN,L_SCAN,"Could not open %s for reading\n",file);
1166	return -1;
1167    }
1168
1169    fseek(infile,0,SEEK_END);
1170    file_size=ftell(infile);
1171    fseek(infile,0,SEEK_SET);
1172
1173    pmp3->file_size=file_size;
1174
1175    /* now, hunt for the mvhd atom */
1176    atom_offset = aac_drilltoatom(infile, "moov:mvhd", &atom_length);
1177    if(atom_offset != -1) {
1178        fseek(infile, 4, SEEK_CUR);
1179        fread((void *)&time, sizeof(int), 1, infile);
1180        time = ntohl(time);
1181        pmp3->time_added = mac_to_unix_time(time);
1182
1183        fread((void *)&time, sizeof(int), 1, infile);
1184        time = ntohl(time);
1185        pmp3->time_modified = mac_to_unix_time(time);
1186	fread((void*)&sample_size,1,sizeof(int),infile);
1187	fread((void*)&samples,1,sizeof(int),infile);
1188
1189	sample_size=ntohl(sample_size);
1190	samples=ntohl(samples);
1191
1192	/* avoid overflowing on large sample_sizes (90000) */
1193	ms=1000;
1194	while((ms > 9) && (!(sample_size % 10))) {
1195	    sample_size /= 10;
1196	    ms /= 10;
1197	}
1198
1199	/* DWB: use ms time instead of sec */
1200	pmp3->song_length=(int)((samples * ms) / sample_size);
1201
1202	DPRINTF(E_DBG,L_SCAN,"Song length: %d seconds\n", pmp3->song_length / 1000);
1203    }
1204
1205    pmp3->bitrate = 0;
1206
1207    /* Get the sample rate from the 'mp4a' atom (timescale). This is also
1208       found in the 'mdhd' atom which is a bit closer but we need to
1209       navigate to the 'mp4a' atom anyways to get to the 'esds' atom. */
1210    atom_offset = aac_drilltoatom(infile, "moov:trak:mdia:minf:stbl:stsd:mp4a", &atom_length);
1211    if (atom_offset != -1) {
1212	fseek(infile, atom_offset + 32, SEEK_SET);
1213
1214	/* Timescale here seems to be 2 bytes here (the 2 bytes before it are
1215	   "reserved") though the timescale in the 'mdhd' atom is 4. Not sure how
1216	   this is dealt with when sample rate goes higher than 64K. */
1217	fread(buffer, sizeof(unsigned char), 2, infile);
1218
1219	pmp3->samplerate = (buffer[0] << 8) | (buffer[1]);
1220
1221	/* Seek to end of atom. */
1222	fseek(infile, 2, SEEK_CUR);
1223
1224	/* Get the bit rate from the 'esds' atom. We are already positioned
1225	   in the parent atom so just scan ahead. */
1226	atom_offset = scan_aac_findatom(infile, atom_length - (ftell(infile) - atom_offset), "esds", &atom_length);
1227
1228	if (atom_offset != -1) {
1229	    fseek(infile, atom_offset + 22, SEEK_CUR);
1230
1231	    fread((void *)&bit_rate, sizeof(unsigned int), 1, infile);
1232
1233	    pmp3->bitrate = ntohl(bit_rate) / 1000;
1234	} else {
1235	    DPRINTF(E_DBG,L_SCAN, "Could not find 'esds' atom to determine bit rate.\n");
1236	}
1237
1238    } else {
1239	DPRINTF(E_DBG,L_SCAN, "Could not find 'mp4a' atom to determine sample rate.\n");
1240    }
1241
1242    /* Fallback if we can't find the info in the atoms. */
1243    if (pmp3->bitrate == 0) {
1244	/* calculate bitrate from song length... Kinda cheesy */
1245	DPRINTF(E_DBG,L_SCAN, "Could not find 'esds' atom. Calculating bit rate.\n");
1246
1247	atom_offset=aac_drilltoatom(infile,"mdat",&atom_length);
1248
1249	if ((atom_offset != -1) && (pmp3->song_length)) {
1250	    pmp3->bitrate = atom_length / ((pmp3->song_length / 1000) * 128);
1251	}
1252
1253    }
1254
1255    fclose(infile);
1256    return 0;
1257}
1258
1259
1260/**
1261 * Decode an mp3 frame header.  Determine layer, bitrate,
1262 * samplerate, etc, and fill in the passed structure.
1263 *
1264 * @param frame 4 byte mp3 frame header
1265 * @param pfi pointer to an allocated SCAN_FRAMEINFO struct
1266 * @return 0 on success (valid frame), -1 otherwise
1267 */
1268int scan_decode_mp3_frame(unsigned char *frame, SCAN_FRAMEINFO *pfi) {
1269    int ver;
1270    int layer_index;
1271    int sample_index;
1272    int bitrate_index;
1273    int samplerate_index;
1274
1275    if((frame[0] != 0xFF) || (frame[1] < 224)) {
1276	pfi->is_valid=0;
1277	return -1;
1278    }
1279
1280    ver=(frame[1] & 0x18) >> 3;
1281    pfi->layer = 4 - ((frame[1] & 0x6) >> 1);
1282
1283    layer_index=-1;
1284    sample_index=-1;
1285
1286    switch(ver) {
1287    case 0:
1288	pfi->version = 2.5;
1289	sample_index=2;
1290	if(pfi->layer == 1)
1291	    layer_index = 3;
1292	if((pfi->layer == 2) || (pfi->layer == 3))
1293	    layer_index = 4;
1294	break;
1295    case 2:
1296	pfi->version = 2.0;
1297	sample_index=1;
1298	if(pfi->layer == 1)
1299	    layer_index=3;
1300	if((pfi->layer == 2) || (pfi->layer == 3))
1301	    layer_index=4;
1302	break;
1303    case 3:
1304	pfi->version = 1.0;
1305	sample_index=0;
1306	if(pfi->layer == 1)
1307	    layer_index = 0;
1308	if(pfi->layer == 2)
1309	    layer_index = 1;
1310	if(pfi->layer == 3)
1311	    layer_index = 2;
1312	break;
1313    }
1314
1315    if((layer_index < 0) || (layer_index > 4)) {
1316	pfi->is_valid=0;
1317	return -1;
1318    }
1319
1320    if((sample_index < 0) || (sample_index > 2)) {
1321	pfi->is_valid=0;
1322	return -1;
1323    }
1324
1325    if(pfi->layer==1) pfi->samples_per_frame=384;
1326    if(pfi->layer==2) pfi->samples_per_frame=1152;
1327    if(pfi->layer==3) {
1328	if(pfi->version == 1.0) {
1329	    pfi->samples_per_frame=1152;
1330	} else {
1331	    pfi->samples_per_frame=576;
1332	}
1333    }
1334
1335    bitrate_index=(frame[2] & 0xF0) >> 4;
1336    samplerate_index=(frame[2] & 0x0C) >> 2;
1337
1338    if((bitrate_index == 0xF) || (bitrate_index==0x0)) {
1339	pfi->is_valid=0;
1340	return -1;
1341    }
1342
1343    if(samplerate_index == 3) {
1344	pfi->is_valid=0;
1345	return -1;
1346    }
1347
1348    pfi->bitrate = scan_br_table[layer_index][bitrate_index];
1349    pfi->samplerate = scan_sample_table[sample_index][samplerate_index];
1350
1351    if((frame[3] & 0xC0 >> 6) == 3)
1352	pfi->stereo = 0;
1353    else
1354	pfi->stereo = 1;
1355
1356    if(frame[2] & 0x02) { /* Padding bit set */
1357	pfi->padding=1;
1358    } else {
1359	pfi->padding=0;
1360    }
1361
1362    if(pfi->version == 1.0) {
1363	if(pfi->stereo) {
1364	    pfi->xing_offset=32;
1365	} else {
1366	    pfi->xing_offset=17;
1367	}
1368    } else {
1369	if(pfi->stereo) {
1370	    pfi->xing_offset=17;
1371	} else {
1372	    pfi->xing_offset=9;
1373	}
1374    }
1375
1376    pfi->crc_protected=(frame[1] & 0xFE);
1377
1378    if(pfi->layer == 1) {
1379	pfi->frame_length = (12 * pfi->bitrate * 1000 / pfi->samplerate + pfi->padding) * 4;
1380    } else {
1381	pfi->frame_length = 144 * pfi->bitrate * 1000 / pfi->samplerate + pfi->padding;
1382    }
1383
1384    if((pfi->frame_length > 2880) || (pfi->frame_length <= 0)) {
1385	pfi->is_valid=0;
1386	return -1;
1387    }
1388
1389    pfi->is_valid=1;
1390    return 0;
1391}
1392
1393/**
1394 * Scan 10 frames from the middle of the file and determine an
1395 * average bitrate from that.  It might not be as accurate as a full
1396 * frame count, but it's probably Close Enough (tm)
1397 *
1398 * @param infile file to scan for average bitrate
1399 * @param pfi pointer to frame info struct to put the bitrate into
1400 */
1401void scan_get_average_bitrate(FILE *infile, SCAN_FRAMEINFO *pfi) {
1402    off_t file_size;
1403    unsigned char frame_buffer[2900];
1404    unsigned char header[4];
1405    int index=0;
1406    int found=0;
1407    off_t pos;
1408    SCAN_FRAMEINFO fi;
1409    int frame_count=0;
1410    int bitrate_total=0;
1411
1412    DPRINTF(E_DBG,L_SCAN,"Starting averaging bitrate\n");
1413
1414    fseek(infile,0,SEEK_END);
1415    file_size=ftell(infile);
1416
1417    pos=file_size/2;
1418
1419    /* now, find the first frame */
1420    fseek(infile,pos,SEEK_SET);
1421    if(fread(frame_buffer,1,sizeof(frame_buffer),infile) != sizeof(frame_buffer))
1422	return;
1423
1424    while(!found) {
1425	while((frame_buffer[index] != 0xFF) && (index < (sizeof(frame_buffer)-4)))
1426	    index++;
1427
1428	if(index >= (sizeof(frame_buffer)-4)) { /* largest mp3 frame is 2880 bytes */
1429	    DPRINTF(E_DBG,L_SCAN,"Could not find frame... quitting\n");
1430	    return;
1431	}
1432
1433	if(!scan_decode_mp3_frame(&frame_buffer[index],&fi)) {
1434	    /* see if next frame is valid */
1435	    fseek(infile,pos + index + fi.frame_length,SEEK_SET);
1436	    if(fread(header,1,sizeof(header),infile) != sizeof(header)) {
1437		DPRINTF(E_DBG,L_SCAN,"Could not read frame header\n");
1438		return;
1439	    }
1440
1441	    if(!scan_decode_mp3_frame(header,&fi))
1442		found=1;
1443	}
1444
1445	if(!found)
1446	    index++;
1447    }
1448
1449    pos += index;
1450
1451    /* found first frame.  Let's move */
1452    while(frame_count < 10) {
1453	fseek(infile,pos,SEEK_SET);
1454	if(fread(header,1,sizeof(header),infile) != sizeof(header)) {
1455	    DPRINTF(E_DBG,L_SCAN,"Could not read frame header\n");
1456	    return;
1457	}
1458	if(scan_decode_mp3_frame(header,&fi)) {
1459	    DPRINTF(E_DBG,L_SCAN,"Invalid frame header while averaging\n");
1460	    return;
1461	}
1462
1463	bitrate_total += fi.bitrate;
1464	frame_count++;
1465	pos += fi.frame_length;
1466    }
1467
1468    DPRINTF(E_DBG,L_SCAN,"Old bitrate: %d\n",pfi->bitrate);
1469    pfi->bitrate = bitrate_total/frame_count;
1470    DPRINTF(E_DBG,L_SCAN,"New bitrate: %d\n",pfi->bitrate);
1471
1472    return;
1473}
1474
1475/**
1476 * do a full frame-by-frame scan of the file, counting frames
1477 * as we go to try and get a more accurate song length estimate.
1478 * If the song turns out to be CBR, then we'll not set the frame
1479 * length.  Instead we'll use the file size estimate, since it is
1480 * more consistent with iTunes.
1481 *
1482 * @param infile file to scan for frame count
1483 * @param pfi pointer to frame info struct to put framecount into
1484 */
1485void scan_get_frame_count(FILE *infile, SCAN_FRAMEINFO *pfi) {
1486    int pos;
1487    int frames=0;
1488    unsigned char frame_buffer[4];
1489    SCAN_FRAMEINFO fi;
1490    off_t file_size;
1491    int err=0;
1492    int cbr=1;
1493    int last_bitrate=0;
1494
1495    DPRINTF(E_DBG,L_SCAN,"Starting frame count\n");
1496
1497    fseek(infile,0,SEEK_END);
1498    file_size=ftell(infile);
1499
1500    pos=pfi->frame_offset;
1501
1502    while(1) {
1503	err=1;
1504	DPRINTF(E_SPAM,L_SCAN,"Seeking to %d\n",pos);
1505
1506	fseek(infile,pos,SEEK_SET);
1507	if(fread(frame_buffer,1,sizeof(frame_buffer),infile) == sizeof(frame_buffer)) {
1508	    /* check for valid frame */
1509	    if(!scan_decode_mp3_frame(frame_buffer,&fi)) {
1510		frames++;
1511		pos += fi.frame_length;
1512		err=0;
1513
1514		if((last_bitrate) && (fi.bitrate != last_bitrate))
1515		    cbr=0;
1516		last_bitrate=fi.bitrate;
1517
1518		/* no point in brute scan of a cbr file... */
1519		if(cbr && (frames > 100)) {
1520		    DPRINTF(E_DBG,L_SCAN,"File appears to be CBR... quitting frame count\n");
1521		    return;
1522		}
1523	    }
1524	}
1525
1526	if(err) {
1527	    if(pos > (file_size - 4096)) {  /* probably good enough */
1528		pfi->number_of_frames=frames;
1529		DPRINTF(E_DBG,L_SCAN,"Estimated frame count: %d\n",frames);
1530		return;
1531	    } else {
1532		DPRINTF(E_DBG,L_SCAN,"Frame count aborted on error.  Pos=%d, Count=%d\n",
1533			pos, frames);
1534		return;
1535	    }
1536	}
1537    }
1538}
1539
1540
1541/**
1542 * Get information from the file headers itself -- like
1543 * song length, bit rate, etc.
1544 *
1545 * @param file File to get info for
1546 * @param pmp3 where to put the found information
1547 */
1548int scan_get_mp3fileinfo(char *file, MP3FILE *pmp3) {
1549    FILE *infile;
1550    SCAN_ID3HEADER *pid3;
1551    SCAN_FRAMEINFO fi;
1552    unsigned int size=0;
1553    off_t fp_size=0;
1554    off_t file_size;
1555    unsigned char buffer[1024];
1556    int index;
1557
1558    int xing_flags;
1559    int found;
1560
1561    int first_check;
1562    char frame_buffer[4];
1563
1564    if(!(infile=fopen(file,"rb"))) {
1565	DPRINTF(E_WARN,L_SCAN,"Could not open %s for reading\n",file);
1566	return -1;
1567    }
1568
1569    memset((void*)&fi,0x00,sizeof(fi));
1570
1571    fseek(infile,0,SEEK_END);
1572    file_size=ftell(infile);
1573    fseek(infile,0,SEEK_SET);
1574
1575    pmp3->file_size=file_size;
1576
1577    if(fread(buffer,1,sizeof(buffer),infile) != sizeof(buffer)) {
1578	if(ferror(infile)) {
1579	    DPRINTF(E_LOG,L_SCAN,"Error reading: %s\n",strerror(errno));
1580	} else {
1581	    DPRINTF(E_LOG,L_SCAN,"Short file: %s\n",file);
1582	}
1583	fclose(infile);
1584	return -1;
1585    }
1586
1587    pid3=(SCAN_ID3HEADER*)buffer;
1588
1589    found=0;
1590    fp_size=0;
1591
1592    if(strncmp(pid3->id,"ID3",3)==0) {
1593	/* found an ID3 header... */
1594	DPRINTF(E_DBG,L_SCAN,"Found ID3 header\n");
1595	size = (pid3->size[0] << 21 | pid3->size[1] << 14 |
1596		pid3->size[2] << 7 | pid3->size[3]);
1597	fp_size=size + sizeof(SCAN_ID3HEADER);
1598	first_check=1;
1599	DPRINTF(E_DBG,L_SCAN,"Header length: %d\n",size);
1600    }
1601
1602    index = 0;
1603
1604    /* Here we start the brute-force header seeking.  Sure wish there
1605     * weren't so many crappy mp3 files out there
1606     */
1607
1608    while(!found) {
1609	fseek(infile,fp_size,SEEK_SET);
1610	DPRINTF(E_DBG,L_SCAN,"Reading in new block at %d\n",(int)fp_size);
1611	if(fread(buffer,1,sizeof(buffer),infile) < sizeof(buffer)) {
1612	    DPRINTF(E_LOG,L_SCAN,"Short read: %s\n",file);
1613	    fclose(infile);
1614	    return 0;
1615	}
1616
1617	index=0;
1618	while(!found) {
1619	    while((buffer[index] != 0xFF) && (index < (sizeof(buffer)-50)))
1620		index++;
1621
1622	    if((first_check) && (index)) {
1623		fp_size=0;
1624		DPRINTF(E_DBG,L_SCAN,"Bad header... dropping back for full frame search\n");
1625		first_check=0;
1626		break;
1627	    }
1628
1629	    if(index > sizeof(buffer) - 50) {
1630		fp_size += index;
1631		DPRINTF(E_DBG,L_SCAN,"Block exhausted\n");
1632		break;
1633	    }
1634
1635	    if(!scan_decode_mp3_frame(&buffer[index],&fi)) {
1636		DPRINTF(E_DBG,L_SCAN,"valid header at %d\n",index);
1637		if(strncasecmp((char*)&buffer[index+fi.xing_offset+4],"XING",4) == 0) {
1638		    /* no need to check further... if there is a xing header there,
1639		     * this is definately a valid frame */
1640		    found=1;
1641		    fp_size += index;
1642		} else {
1643		    /* No Xing... check for next frame */
1644		    DPRINTF(E_DBG,L_SCAN,"Found valid frame at %04x\n",(int)fp_size+index);
1645		    DPRINTF(E_DBG,L_SCAN,"Checking at %04x\n",(int)fp_size+index+fi.frame_length);
1646		    fseek(infile,fp_size + index + fi.frame_length,SEEK_SET);
1647		    if(fread(frame_buffer,1,sizeof(frame_buffer),infile) == sizeof(frame_buffer)) {
1648			if(!scan_decode_mp3_frame(frame_buffer,&fi)) {
1649			    found=1;
1650			    fp_size += index;
1651			}
1652		    } else {
1653			DPRINTF(E_LOG,L_SCAN,"Could not read frame header: %s\n",file);
1654			fclose(infile);
1655			return 0;
1656		    }
1657
1658		    if(!found) {
1659			DPRINTF(E_DBG,L_SCAN,"Didn't pan out.\n");
1660		    }
1661		}
1662	    }
1663
1664	    if(!found) {
1665		index++;
1666		if (first_check) {
1667		    /* if the header info was wrong about where the data started,
1668		     * then start a brute-force scan from the beginning of the file.
1669		     * don't want to just scan forward, because we might have already
1670		     * missed the xing header
1671		     */
1672		    DPRINTF(E_DBG,L_SCAN,"Bad header... dropping back for full frame search\n");
1673		    first_check=0;
1674		    fp_size=0;
1675		    break;
1676		}
1677	    }
1678	}
1679    }
1680
1681    file_size -= fp_size;
1682    fi.frame_offset=fp_size;
1683
1684    if(scan_decode_mp3_frame(&buffer[index],&fi)) {
1685	fclose(infile);
1686	DPRINTF(E_LOG,L_SCAN,"Could not find sync frame: %s\n",file);
1687	DPRINTF(E_LOG,L_SCAN,"If this is a valid mp3 file that plays in "
1688		"other applications, please email me at rpedde@users.sourceforge.net "
1689		"and tell me you got this error.  Thanks");
1690	return 0;
1691    }
1692
1693    DPRINTF(E_DBG,L_SCAN," MPEG Version: %0.1g\n",fi.version);
1694    DPRINTF(E_DBG,L_SCAN," Layer: %d\n",fi.layer);
1695    DPRINTF(E_DBG,L_SCAN," Sample Rate: %d\n",fi.samplerate);
1696    DPRINTF(E_DBG,L_SCAN," Bit Rate: %d\n",fi.bitrate);
1697
1698    /* now check for an XING header */
1699    if(strncasecmp((char*)&buffer[index+fi.xing_offset+4],"XING",4) == 0) {
1700	DPRINTF(E_DBG,L_SCAN,"Found Xing header\n");
1701	xing_flags=*((int*)&buffer[index+fi.xing_offset+4+4]);
1702	xing_flags=ntohs(xing_flags);
1703
1704	DPRINTF(E_DBG,L_SCAN,"Xing Flags: %02X\n",xing_flags);
1705
1706	if(xing_flags & 0x1) {
1707	    /* Frames field is valid... */
1708	    fi.number_of_frames=*((int*)&buffer[index+fi.xing_offset+4+8]);
1709	    fi.number_of_frames=ntohs(fi.number_of_frames);
1710	}
1711    }
1712
1713    if((config.scan_type != 0) &&
1714       (fi.number_of_frames == 0) &&
1715       (!pmp3->song_length)) {
1716	/* We have no good estimate of song time, and we want more
1717	 * aggressive scanning */
1718	DPRINTF(E_DBG,L_SCAN,"Starting aggressive file length scan\n");
1719	if(config.scan_type == 1) {
1720	    /* get average bitrate */
1721	    scan_get_average_bitrate(infile, &fi);
1722	} else {
1723	    /* get full frame count */
1724	    scan_get_frame_count(infile, &fi);
1725	}
1726    }
1727
1728    pmp3->bitrate=fi.bitrate;
1729    pmp3->samplerate=fi.samplerate;
1730
1731    /* guesstimate the file length */
1732    if(!pmp3->song_length) { /* could have gotten it from the tag */
1733	/* DWB: use ms time instead of seconds, use doubles to
1734	   avoid overflow */
1735	if(!fi.number_of_frames) { /* not vbr */
1736	    pmp3->song_length = (int) ((double) file_size * 8. /
1737				       (double) fi.bitrate);
1738
1739	} else {
1740	    pmp3->song_length = (int) ((double)(fi.number_of_frames*fi.samples_per_frame*1000.)/
1741				       (double) fi.samplerate);
1742	}
1743
1744    }
1745    DPRINTF(E_DBG,L_SCAN," Song Length: %d\n",pmp3->song_length);
1746
1747    fclose(infile);
1748    return 0;
1749}
1750
1751/**
1752 * Manually build tags.  Set artist to computer/orchestra
1753 * if there is already no artist.  Perhaps this could be
1754 * done better, but I'm not sure what else to do here.
1755 *
1756 * @param song MP3FILE of the file to build composite tags for
1757 */
1758void make_composite_tags(MP3FILE *song)
1759{
1760    int len;
1761    char fdescr[50];
1762
1763    len=0;
1764
1765    if(!song->artist && (song->orchestra || song->conductor)) {
1766	if(song->orchestra)
1767	    len += strlen(song->orchestra);
1768	if(song->conductor)
1769	    len += strlen(song->conductor);
1770
1771	len += 3;
1772
1773	song->artist=(char*)calloc(len, 1);
1774	if(song->artist) {
1775	    if(song->orchestra)
1776		strcat(song->artist,song->orchestra);
1777
1778	    if(song->orchestra && song->conductor)
1779		strcat(song->artist," - ");
1780
1781	    if(song->conductor)
1782		strcat(song->artist,song->conductor);
1783	}
1784    }
1785
1786    sprintf(fdescr,"%s audio file",song->type);
1787    song->description = strdup(fdescr);
1788
1789    if(song->url) {
1790	song->description = strdup("Playlist URL");
1791	song->data_kind=1;
1792	/* bit of a hack for the roku soundbridge - type *has* to be pls */
1793	if(song->type)
1794	    free(song->type);
1795	song->type = strdup("pls");
1796    } else {
1797	song->data_kind=0;
1798    }
1799
1800    if(!song->title)
1801	song->title = strdup(song->fname);
1802
1803    /* Ogg used to be set as an item_kind of 4.  Dunno why */
1804    song->item_kind = 2;
1805}
1806