1 /* Time-stamp: <2009-01-31 18:21:09 jcs>
2 |
3 |  Copyright (C) 2002-2005 Jorg Schuler <jcsjcs at users sourceforge net>
4 |  Part of the gtkpod project.
5 |
6 |  URL: http://www.gtkpod.org/
7 |  URL: http://gtkpod.sourceforge.net/
8 |
9 |  This program is free software; you can redistribute it and/or modify
10 |  it under the terms of the GNU General Public License as published by
11 |  the Free Software Foundation; either version 2 of the License, or
12 |  (at your option) any later version.
13 |
14 |  This program is distributed in the hope that it will be useful,
15 |  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 |  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 |  GNU General Public License for more details.
18 |
19 |  You should have received a copy of the GNU General Public License
20 |  along with this program; if not, write to the Free Software
21 |  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 |
23 |  iTunes and iPod are trademarks of Apple
24 |
25 |  This product is not supported/written/published by Apple!
26 |
27 |  $Id$
28 */
29 
30 #define LOCALDEBUG 0
31 
32 #if LOCALDEBUG
33 #  define DEBUG(args...) printf(args)
34 #else
35 #  define DEBUG(args...)
36 #endif
37 
38 
39 /* The code in the first section of this file is taken from the
40  * mp3info (http://www.ibiblio.org/mp3info/) project. Only the code
41  * needed for the playlength calculation has been extracted. */
42 
43 /* The code in the second section of this file is taken from the
44  * mpg123 code used in xmms-1.2.7 (Input/mpg123). Only the code needed
45  * for the playlength calculation has been extracted. */
46 
47 /* The code in the third section of this file is taken from the
48  * crc code used in libmad (crc.h). */
49 
50 /* The code in the last section of this file is original gtkpod
51  * code. */
52 
53 /****************
54  * Declarations *
55  ****************/
56 
57 #include <glib.h>
58 #include <math.h>
59 /*
60  * Description of each item of the TagList list
61  */
62 typedef struct _File_Tag File_Tag;
63 typedef struct _GainData GainData;
64 typedef struct _GaplessData GaplessData;
65 typedef struct _LameTag LameTag;
66 
67 struct _File_Tag
68 {
69     gchar *title;          /* Title of track */
70     gchar *artist;         /* Artist name */
71     gchar *album;          /* Album name */
72     gchar *year;           /* Year of track */
73     gchar *trackstring;    /* Position of track in the album */
74     gchar *track_total;    /* The number of tracks for the album (ex: 12/20) */
75     gchar *genre;          /* Genre of song */
76     gchar *comment;        /* Comment */
77     gchar *composer;	   /* Composer */
78     guint32 songlen;       /* Length of file in ms */
79     gchar *cdnostring;    /* Position of disc in the album */
80     gchar *cdno_total;    /* The number of discs in the album (ex: 1/2) */
81     gchar *compilation;   /* The track is a member of a compilation */
82     gchar *podcasturl;    /* The following are mainly used for podcasts */
83     gchar *sort_artist;
84     gchar *sort_title;
85     gchar *sort_album;
86     gchar *sort_albumartist;
87     gchar *sort_composer;
88     gchar *description;
89     gchar *podcastrss;
90     gchar *time_released;
91     gchar *subtitle;
92     gchar *BPM;           /* beats per minute */
93     gchar *lyrics;        /* does not appear to be the full lyrics --
94 			     only used to set the flag 'lyrics_flag'
95 			     of the Track structure */
96     gchar *albumartist;         /* Album artist  */
97 };
98 
99 
100 struct _GainData
101 {
102   guint32 peak_signal;	  /* LAME Peak Signal * 0x800000             */
103   gdouble radio_gain;	  /* RadioGain in dB
104 			     (as defined by www.replaygain.org)      */
105   gdouble audiophile_gain;/* AudiophileGain in dB
106 			     (as defined by www.replaygain.org)      */
107   gboolean peak_signal_set;    /* has the peak signal been set?      */
108   gboolean radio_gain_set;     /* has the radio gain been set?       */
109   gboolean audiophile_gain_set;/* has the audiophile gain been set?  */
110 };
111 
112 struct _GaplessData
113 {
114     guint32 pregap;       /* number of pregap samples */
115     guint64 samplecount;  /* number of actual music samples */
116     guint32 postgap;      /* number of postgap samples */
117     guint32 gapless_data; /* number of bytes from the first sync frame to the 8th to last frame */
118 };
119 
120 #define LAME_TAG_SIZE 0x24
121 #define INFO_TAG_CRC_SIZE 0xBE	/* number of bytes to pass to crc_compute */
122 
123 /* A structure to hold the various data found in a LAME info tag.
124  * Please see http://gabriel.mp3-tech.org/mp3infotag.html for full
125  * documentation.
126  */
127 struct _LameTag
128 {
129     gchar encoder[4];
130     gchar version_string[5];
131     guint8 info_tag_revision;
132     guint8 vbr_method;
133     guint8 lowpass;
134     float peak_signal_amplitude;
135     guchar radio_replay_gain[2];
136     guchar audiophile_replay_gain[2];
137     guint8 encoding_flags;
138     guint8 ath_type;
139     guint8 bitrate;
140     guint16 delay;
141     guint16 padding;
142     guint8 noise_shaping;
143     guint8 stereo_mode;
144     gboolean unwise_settings;
145     guint8 source_sample_frequency;
146     guint8 mp3_gain;
147     guint8 surround_info;
148     guint16 preset;
149     guint32 music_length;
150     guint16 music_crc;
151     guint16 info_tag_crc;
152     guint16 calculated_info_tag_crc;
153 };
154 
155 /* This code is taken from the mp3info code. Only the code needed for
156  * the playlength calculation has been extracted */
157 
158 /*
159     mp3tech.c - Functions for handling MP3 files and most MP3 data
160 		structure manipulation.
161 
162     Copyright (C) 2000-2001  Cedric Tefft <cedric@earthling.net>
163 
164     This program is free software; you can redistribute it and/or modify
165     it under the terms of the GNU General Public License as published by
166     the Free Software Foundation; either version 2 of the License, or
167     (at your option) any later version.
168 
169     This program is distributed in the hope that it will be useful,
170     but WITHOUT ANY WARRANTY; without even the implied warranty of
171     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
172     GNU General Public License for more details.
173 
174     You should have received a copy of the GNU General Public License
175     along with this program; if not, write to the Free Software
176     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
177 
178   ***************************************************************************
179 
180   This file is based in part on:
181 
182 	* MP3Info 0.5 by Ricardo Cerqueira <rmc@rccn.net>
183 	* MP3Stat 0.9 by Ed Sweetman <safemode@voicenet.com> and
184 			 Johannes Overmann <overmann@iname.com>
185 
186 */
187 
188 #include <ctype.h>
189 #include <errno.h>
190 #include <stdio.h>
191 #include <stdlib.h>
192 #include <string.h>
193 #include <sys/stat.h>
194 #include <sys/types.h>
195 #include <unistd.h>
196 
197 #include "mp3file.h"
198 #include "charset.h"
199 #include "itdb.h"
200 #include "file.h"
201 #include "misc.h"
202 #include "prefs.h"
203 
204 
205 /* MIN_CONSEC_GOOD_FRAMES defines how many consecutive valid MP3 frames
206    we need to see before we decide we are looking at a real MP3 file */
207 #define MIN_CONSEC_GOOD_FRAMES 4
208 #define FRAME_HEADER_SIZE 4
209 #define MIN_FRAME_SIZE 21
210 
211 enum VBR_REPORT { VBR_VARIABLE, VBR_AVERAGE, VBR_MEDIAN };
212 
213 typedef struct {
214     gulong sync;
215     guint  version;
216     guint  layer;
217     guint  crc;
218     guint  bitrate;
219     guint  freq;
220     guint  padding;
221     guint  extension;
222     guint  mode;
223     guint  mode_extension;
224     guint  copyright;
225     guint  original;
226     guint  emphasis;
227 } MP3Header;
228 
229 typedef struct {
230     const gchar *filename;
231     FILE *file;
232     off_t datasize;
233     gint header_isvalid;
234     MP3Header header;
235     gint id3_isvalid;
236     gint vbr;
237     float vbr_average;
238     gint milliseconds;
239     gint frames;
240     gint badframes;
241 } MP3Info;
242 
243 /* This is for xmms code */
244 static guint get_track_time(const gchar *path);
245 
246 
247 /* This is for soundcheck code */
248 gboolean mp3_read_lame_tag (const gchar *path, LameTag *lt);
249 
250 /* ------------------------------------------------------------
251 
252    start of first section
253 
254    ------------------------------------------------------------ */
255 void get_mp3_info(MP3Info *mp3);
256 
257 gint frequencies[3][4] = {
258    {22050,24000,16000,50000},  /* MPEG 2.0 */
259    {44100,48000,32000,50000},  /* MPEG 1.0 */
260    {11025,12000,8000,50000}    /* MPEG 2.5 */
261 };
262 
263 /* "0" added by JCS */
264 gint bitrate[2][3][16] = {
265   { /* MPEG 2.0 */
266     {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0},/* layer 1 */
267     {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},     /* layer 2 */
268     {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0}      /* layer 3 */
269   },
270 
271   { /* MPEG 1.0 */
272     {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0},/* layer 1 */
273     {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0},   /* layer 2 */
274     {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0}     /* layer 3 */
275   }
276 };
277 
278 gint frame_size_index[] = {24000, 72000, 72000};
279 
280 
281 gchar *mode_text[] = {
282    "stereo", "joint stereo", "dual channel", "mono"
283 };
284 
285 gchar *emphasis_text[] = {
286   "none", "50/15 microsecs", "reserved", "CCITT J 17"
287 };
288 
289 
mp3file_header_bitrate(MP3Header * h)290 static gint mp3file_header_bitrate(MP3Header *h) {
291     return bitrate[h->version & 1][3-h->layer][h->bitrate];
292 }
293 
294 
mp3file_header_frequency(MP3Header * h)295 static gint mp3file_header_frequency(MP3Header *h) {
296     return frequencies[h->version][h->freq];
297 }
298 
299 
frame_length(MP3Header * header)300 gint frame_length(MP3Header *header) {
301 	return header->sync == 0xFFE ?
302 		    (frame_size_index[3-header->layer]*((header->version&1)+1)*
303 		    mp3file_header_bitrate(header)/(float)mp3file_header_frequency(header))+
304 		    header->padding : 1;
305 }
306 
307 /* Get next MP3 frame header.
308    Return codes:
309    positive value = Frame Length of this header
310    0 = No, we did not retrieve a valid frame header
311 */
get_header(FILE * file,MP3Header * header)312 gint get_header(FILE *file,MP3Header *header)
313 {
314     guchar buffer[FRAME_HEADER_SIZE];
315     gint fl;
316 
317     if(fread(&buffer,FRAME_HEADER_SIZE,1,file)<1) {
318 	header->sync=0;
319 	return 0;
320     }
321     header->sync=(((gint)buffer[0]<<4) | ((gint)(buffer[1]&0xE0)>>4));
322     if(buffer[1] & 0x10) header->version=(buffer[1] >> 3) & 1;
323 		    else header->version=2;
324     header->layer=(buffer[1] >> 1) & 3;
325     if (header->layer == 0)
326     {
327 	header->layer = 1; /* sanity added by JCS */
328     }
329     if((header->sync != 0xFFE) || (header->layer != 1)) {
330 	header->sync=0;
331 	return 0;
332     }
333     header->crc=buffer[1] & 1;
334     header->bitrate=(buffer[2] >> 4) & 0x0F;
335     header->freq=(buffer[2] >> 2) & 0x3;
336     header->padding=(buffer[2] >>1) & 0x1;
337     header->extension=(buffer[2]) & 0x1;
338     header->mode=(buffer[3] >> 6) & 0x3;
339     header->mode_extension=(buffer[3] >> 4) & 0x3;
340     header->copyright=(buffer[3] >> 3) & 0x1;
341     header->original=(buffer[3] >> 2) & 0x1;
342     header->emphasis=(buffer[3]) & 0x3;
343 
344     return ((fl=frame_length(header)) >= MIN_FRAME_SIZE ? fl : 0);
345 }
346 
sameConstant(MP3Header * h1,MP3Header * h2)347 gint sameConstant(MP3Header *h1, MP3Header *h2) {
348     if((*(guint*)h1) == (*(guint*)h2)) return 1;
349 
350     if((h1->version       == h2->version         ) &&
351        (h1->layer         == h2->layer           ) &&
352        (h1->crc           == h2->crc             ) &&
353        (h1->freq          == h2->freq            ) &&
354        (h1->mode          == h2->mode            ) &&
355        (h1->copyright     == h2->copyright       ) &&
356        (h1->original      == h2->original        ) &&
357        (h1->emphasis      == h2->emphasis        ))
358 		return 1;
359     else return 0;
360 }
361 
362 
get_first_header(MP3Info * mp3,long startpos)363 gint get_first_header(MP3Info *mp3, long startpos)
364 {
365   gint k, l=0,c;
366   MP3Header h, h2;
367   long valid_start=0;
368 
369   fseek(mp3->file,startpos,SEEK_SET);
370   while (1) {
371      while((c=fgetc(mp3->file)) != 255 && (c != EOF));
372      if(c == 255) {
373 	ungetc(c,mp3->file);
374 	valid_start=ftell(mp3->file);
375 	if((l=get_header(mp3->file,&h))) {
376 	  fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR);
377 	  for(k=1; (k < MIN_CONSEC_GOOD_FRAMES) && (mp3->datasize-ftell(mp3->file) >= FRAME_HEADER_SIZE); k++) {
378 	    if(!(l=get_header(mp3->file,&h2))) break;
379 	    if(!sameConstant(&h,&h2)) break;
380 	    fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR);
381 	  }
382 	  if(k == MIN_CONSEC_GOOD_FRAMES) {
383 		fseek(mp3->file,valid_start,SEEK_SET);
384 		memcpy(&(mp3->header),&h2,sizeof(MP3Header));
385 		mp3->header_isvalid=1;
386 		return 1;
387 	  }
388 	}
389      } else {
390 	return 0;
391      }
392    }
393 
394   return 0;
395 }
396 
397 
398 /* get_next_header() - read header at current position or look for
399    the next valid header if there isn't one at the current position
400 */
get_next_header(MP3Info * mp3)401 gint get_next_header(MP3Info *mp3)
402 {
403   gint l=0,c,skip_bytes=0;
404   MP3Header h;
405 
406    while(1) {
407      while((c=fgetc(mp3->file)) != 255 && (ftell(mp3->file) < mp3->datasize)) skip_bytes++;
408      if(c == 255) {
409 	ungetc(c,mp3->file);
410 	if((l=get_header(mp3->file,&h))) {
411 	  if(skip_bytes) mp3->badframes++;
412 	  fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR);
413 	  return 15-h.bitrate;
414 	} else {
415 		skip_bytes += FRAME_HEADER_SIZE;
416 	}
417      } else {
418 	  if(skip_bytes) mp3->badframes++;
419 	  return 0;
420      }
421   }
422 }
423 
424 
get_mp3_info(MP3Info * mp3)425 void get_mp3_info(MP3Info *mp3)
426 {
427   gint frame_type[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
428   double milliseconds=0,total_rate=0;
429   gint frames=0,frame_types=0,frames_so_far=0;
430   gint vbr_median=-1;
431   guint bitrate;
432   gint counter=0;
433   MP3Header header;
434   struct stat filestat;
435   off_t data_start=0;
436 
437 
438   stat(mp3->filename,&filestat);
439   mp3->datasize=filestat.st_size;
440 
441   if(get_first_header(mp3,0L)) {
442       data_start=ftell(mp3->file);
443       while((bitrate=get_next_header(mp3))) {
444 	  if (bitrate < 15)  /* sanity added by JCS */
445 	      frame_type[15-bitrate]++;
446 	  frames++;
447       }
448       memcpy(&header,&(mp3->header),sizeof(MP3Header));
449       for(counter=0;counter<15;counter++) {
450 	  if(frame_type[counter]) {
451 	      float header_bitrate; /* introduced by JCS to speed up */
452 	      frame_types++;
453 	      header.bitrate=counter;
454 	      frames_so_far += frame_type[counter];
455 	      header_bitrate = mp3file_header_bitrate(&header);
456 	      if (header_bitrate != 0)
457                  milliseconds += 8*(double)frame_length(&header)*(double)frame_type[counter]/header_bitrate;
458 	      total_rate += header_bitrate*frame_type[counter];
459 	      if((vbr_median == -1) && (frames_so_far >= frames/2))
460 		  vbr_median=counter;
461 	  }
462       }
463       mp3->milliseconds=(gint)(milliseconds+0.5);
464       mp3->header.bitrate=vbr_median;
465       mp3->vbr_average=total_rate/(float)frames;
466       mp3->frames=frames;
467       if(frame_types > 1) {
468 	  mp3->vbr=1;
469       }
470   }
471 }
472 
473 
474 
475 
476 /* ------------------------------------------------------------
477 
478 	 xmms code
479 
480 
481    ------------------------------------------------------------ */
482 
483 /*
484 |  Changed by Jorg Schuler <jcsjcs at users.sourceforge.net> to
485 |  compile with the gtkpod project. 2003/04/01
486 */
487 
488 /* This code is taken from the mpg123 code used in xmms-1.2.7
489  * (Input/mpg123). Only the code needed for the playlength calculation
490  * has been extracted */
491 
492 #include "mp3file.h"
493 #include <stdio.h>
494 #include <string.h>
495 
496 #define FRAMES_FLAG     0x0001
497 #define BYTES_FLAG      0x0002
498 #define TOC_FLAG        0x0004
499 #define VBR_SCALE_FLAG  0x0008
500 
501 #define         SBLIMIT                 32
502 #define         SCALE_BLOCK             12
503 #define         SSLIMIT                 18
504 
505 #define         MPG_MD_STEREO           0
506 #define         MPG_MD_JOINT_STEREO     1
507 #define         MPG_MD_DUAL_CHANNEL     2
508 #define         MPG_MD_MONO             3
509 #define MAXFRAMESIZE 1792
510 #define real float
511 
512 struct bitstream_info
513 {
514 	int bitindex;
515 	unsigned char *wordpointer;
516 };
517 
518 struct bitstream_info bsi;
519 
520 real mpg123_muls[27][64];	/* also used by layer 1 */
521 
522 int tabsel_123[2][3][16] =
523 {
524 	{
525     {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,},
526        {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,},
527        {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,}},
528 
529 	{
530        {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,},
531 	    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,},
532 	    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}}
533 };
534 
535 long mpg123_freqs[9] =
536 {44100, 48000, 32000, 22050, 24000, 16000, 11025, 12000, 8000};
537 
538 /*
539  * structure to receive extracted header
540  */
541 typedef struct
542 {
543 	int frames;		/* total bit stream frames from Xing header data */
544 	int bytes;		/* total bit stream bytes from Xing header data */
545 	unsigned char toc[100];	/* "table of contents" */
546 } xing_header_t;
547 
548 struct al_table
549 {
550 	short bits;
551 	short d;
552 };
553 
554 struct frame
555 {
556 	struct al_table *alloc;
557 	int (*synth) (real *, int, unsigned char *, int *);
558 	int (*synth_mono) (real *, unsigned char *, int *);
559 #ifdef USE_3DNOW
560 	void (*dct36)(real *,real *,real *,real *,real *);
561 #endif
562 	int stereo;
563 	int jsbound;
564 	int single;
565 	int II_sblimit;
566 	int down_sample_sblimit;
567 	int lsf;
568 	int mpeg25;
569 	int down_sample;
570 	int header_change;
571 	int lay;
572 	int (*do_layer) (struct frame * fr);
573 	int error_protection;
574 	int bitrate_index;
575 	int sampling_frequency;
576 	int padding;
577 	int extension;
578 	int mode;
579 	int mode_ext;
580 	int copyright;
581 	int original;
582 	int emphasis;
583 	int framesize;		/* computed framesize */
584 };
585 
convert_to_header(guint8 * buf)586 static guint32 convert_to_header(guint8 * buf)
587 {
588 
589 	return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
590 }
591 
mpg123_head_check(unsigned long head)592 static int mpg123_head_check(unsigned long head)
593 {
594 	if ((head & 0xffe00000) != 0xffe00000)
595 		return FALSE;
596 	if (!((head >> 17) & 3))
597 		return FALSE;
598 	if (((head >> 12) & 0xf) == 0xf)
599 		return FALSE;
600 	if (!((head >> 12) & 0xf))
601 		return FALSE;
602 	if (((head >> 10) & 0x3) == 0x3)
603 		return FALSE;
604 	if (((head >> 19) & 1) == 1 && ((head >> 17) & 3) == 3 && ((head >> 16) & 1) == 1)
605 		return FALSE;
606 	if ((head & 0xffff0000) == 0xfffe0000)
607 		return FALSE;
608 
609 	return TRUE;
610 }
611 
612 
613 /*
614  * the code a header and write the information
615  * into the frame structure
616  */
mpg123_decode_header(struct frame * fr,unsigned long newhead)617 static int mpg123_decode_header(struct frame *fr, unsigned long newhead)
618 {
619     int ssize;
620 
621 	if (newhead & (1 << 20))
622 	{
623 		fr->lsf = (newhead & (1 << 19)) ? 0x0 : 0x1;
624 		fr->mpeg25 = 0;
625 	}
626 	else
627 	{
628 		fr->lsf = 1;
629 		fr->mpeg25 = 1;
630 	}
631 	fr->lay = 4 - ((newhead >> 17) & 3);
632 	if (fr->mpeg25)
633 	{
634 		fr->sampling_frequency = 6 + ((newhead >> 10) & 0x3);
635 	}
636 	else
637 		fr->sampling_frequency = ((newhead >> 10) & 0x3) + (fr->lsf * 3);
638 	fr->error_protection = ((newhead >> 16) & 0x1) ^ 0x1;
639 
640 	fr->bitrate_index = ((newhead >> 12) & 0xf);
641 	fr->padding = ((newhead >> 9) & 0x1);
642 	fr->extension = ((newhead >> 8) & 0x1);
643 	fr->mode = ((newhead >> 6) & 0x3);
644 	fr->mode_ext = ((newhead >> 4) & 0x3);
645 	fr->copyright = ((newhead >> 3) & 0x1);
646 	fr->original = ((newhead >> 2) & 0x1);
647 	fr->emphasis = newhead & 0x3;
648 
649 	fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2;
650 
651 	ssize = 0;
652 
653 	if (!fr->bitrate_index)
654 		return (0);
655 
656 	switch (fr->lay)
657 	{
658 		case 1:
659 /*			fr->do_layer = mpg123_do_layer1; */
660 /*			mpg123_init_layer2();	/\* inits also shared tables with layer1 *\/ */
661 			fr->framesize = (long) tabsel_123[fr->lsf][0][fr->bitrate_index] * 12000;
662 			fr->framesize /= mpg123_freqs[fr->sampling_frequency];
663 			fr->framesize = ((fr->framesize + fr->padding) << 2) - 4;
664 			break;
665 		case 2:
666 /*			fr->do_layer = mpg123_do_layer2; */
667 /*			mpg123_init_layer2();	/\* inits also shared tables with layer1 *\/ */
668 			fr->framesize = (long) tabsel_123[fr->lsf][1][fr->bitrate_index] * 144000;
669 			fr->framesize /= mpg123_freqs[fr->sampling_frequency];
670 			fr->framesize += fr->padding - 4;
671 			break;
672 		case 3:
673 /*			fr->do_layer = mpg123_do_layer3; */
674 			if (fr->lsf)
675 				ssize = (fr->stereo == 1) ? 9 : 17;
676 			else
677 				ssize = (fr->stereo == 1) ? 17 : 32;
678 			if (fr->error_protection)
679 				ssize += 2;
680 			fr->framesize = (long) tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000;
681 			fr->framesize /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
682 			fr->framesize = fr->framesize + fr->padding - 4;
683 			break;
684 		default:
685 			return (0);
686 	}
687 	if(fr->framesize > MAXFRAMESIZE)
688 		return 0;
689 	return 1;
690 }
691 
692 #define GET_INT32BE(b) \
693 (i = (b[0] << 24) | (b[1] << 16) | b[2] << 8 | b[3], b += 4, i)
694 
mpg123_get_xing_header(xing_header_t * xing,unsigned char * buf)695 static int mpg123_get_xing_header(xing_header_t * xing, unsigned char *buf)
696 {
697 	int i, head_flags;
698 	int id, mode;
699 
700 	memset(xing, 0, sizeof(xing_header_t));
701 
702 	/* get selected MPEG header data */
703 	id = (buf[1] >> 3) & 1;
704 	mode = (buf[3] >> 6) & 3;
705 	buf += 4;
706 
707 	/* Skip the sub band data */
708 	if (id)
709 	{
710 		/* mpeg1 */
711 		if (mode != 3)
712 			buf += 32;
713 		else
714 			buf += 17;
715 	}
716 	else
717 	{
718 		/* mpeg2 */
719 		if (mode != 3)
720 			buf += 17;
721 		else
722 			buf += 9;
723 	}
724 
725 	if (strncmp(buf, "Xing", 4))
726 		return 0;
727 	buf += 4;
728 
729 	head_flags = GET_INT32BE(buf);
730 
731 	if (head_flags & FRAMES_FLAG)
732 		xing->frames = GET_INT32BE(buf);
733 	if (xing->frames < 1)
734 		xing->frames = 1;
735 	if (head_flags & BYTES_FLAG)
736 		xing->bytes = GET_INT32BE(buf);
737 
738 	if (head_flags & TOC_FLAG)
739 	{
740 		for (i = 0; i < 100; i++)
741 			xing->toc[i] = buf[i];
742 		buf += 100;
743 	}
744 
745 #ifdef XING_DEBUG
746 	for (i = 0; i < 100; i++)
747 	{
748 		if ((i % 10) == 0)
749 			fprintf(stderr, "\n");
750 		fprintf(stderr, " %3d", xing->toc[i]);
751 	}
752 #endif
753 
754 	return 1;
755 }
756 
mpg123_compute_tpf(struct frame * fr)757 static double mpg123_compute_tpf(struct frame *fr)
758 {
759 	const int bs[4] = {0, 384, 1152, 1152};
760 	double tpf;
761 
762 	tpf = bs[fr->lay];
763 	tpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
764 	return tpf;
765 }
766 
mpg123_compute_bpf(struct frame * fr)767 static double mpg123_compute_bpf(struct frame *fr)
768 {
769 	double bpf;
770 
771 	switch (fr->lay)
772 	{
773 		case 1:
774 			bpf = tabsel_123[fr->lsf][0][fr->bitrate_index];
775 			bpf *= 12000.0 * 4.0;
776 			bpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
777 			break;
778 		case 2:
779 		case 3:
780 			bpf = tabsel_123[fr->lsf][fr->lay - 1][fr->bitrate_index];
781 			bpf *= 144000;
782 			bpf /= mpg123_freqs[fr->sampling_frequency] << (fr->lsf);
783 			break;
784 		default:
785 			bpf = 1.0;
786 	}
787 
788 	return bpf;
789 }
790 
791 
mpg123_getbits(int number_of_bits)792 unsigned int mpg123_getbits(int number_of_bits)
793 {
794 	unsigned long rval;
795 
796 #ifdef DEBUG_GETBITS
797 	fprintf(stderr, "g%d", number_of_bits);
798 #endif
799 
800 	if(!number_of_bits)
801 		return 0;
802 
803 #if 0
804 	check_buffer_range(number_of_bits + bsi.bitindex);
805 #endif
806 
807 	{
808 		rval = bsi.wordpointer[0];
809 		rval <<= 8;
810 		rval |= bsi.wordpointer[1];
811 		rval <<= 8;
812 		rval |= bsi.wordpointer[2];
813 
814 		rval <<= bsi.bitindex;
815 		rval &= 0xffffff;
816 
817 		bsi.bitindex += number_of_bits;
818 
819 		rval >>= (24-number_of_bits);
820 
821 		bsi.wordpointer += (bsi.bitindex >> 3);
822 		bsi.bitindex &= 7;
823 	}
824 
825 #ifdef DEBUG_GETBITS
826 	fprintf(stderr,":%x ",rval);
827 #endif
828 
829 	return rval;
830 }
831 
832 
I_step_one(unsigned int balloc[],unsigned int scale_index[2][SBLIMIT],struct frame * fr)833 void I_step_one(unsigned int balloc[], unsigned int scale_index[2][SBLIMIT], struct frame *fr)
834 {
835 	unsigned int *ba = balloc;
836 	unsigned int *sca = (unsigned int *) scale_index;
837 
838 	if (fr->stereo)
839 	{
840 		int i;
841 		int jsbound = fr->jsbound;
842 
843 		for (i = 0; i < jsbound; i++)
844 		{
845 			*ba++ = mpg123_getbits(4);
846 			*ba++ = mpg123_getbits(4);
847 		}
848 		for (i = jsbound; i < SBLIMIT; i++)
849 			*ba++ = mpg123_getbits(4);
850 
851 		ba = balloc;
852 
853 		for (i = 0; i < jsbound; i++)
854 		{
855 			if ((*ba++))
856 				*sca++ = mpg123_getbits(6);
857 			if ((*ba++))
858 				*sca++ = mpg123_getbits(6);
859 		}
860 		for (i = jsbound; i < SBLIMIT; i++)
861 			if ((*ba++))
862 			{
863 				*sca++ = mpg123_getbits(6);
864 				*sca++ = mpg123_getbits(6);
865 			}
866 	}
867 	else
868 	{
869 		int i;
870 
871 		for (i = 0; i < SBLIMIT; i++)
872 			*ba++ = mpg123_getbits(4);
873 		ba = balloc;
874 		for (i = 0; i < SBLIMIT; i++)
875 			if ((*ba++))
876 				*sca++ = mpg123_getbits(6);
877 	}
878 }
879 
I_step_two(real fraction[2][SBLIMIT],unsigned int balloc[2* SBLIMIT],unsigned int scale_index[2][SBLIMIT],struct frame * fr)880 void I_step_two(real fraction[2][SBLIMIT], unsigned int balloc[2 * SBLIMIT],
881 		unsigned int scale_index[2][SBLIMIT], struct frame *fr)
882 {
883 	int i, n;
884 	int smpb[2 * SBLIMIT];	/* values: 0-65535 */
885 	int *sample;
886 	register unsigned int *ba;
887 	register unsigned int *sca = (unsigned int *) scale_index;
888 
889 	if (fr->stereo)
890 	{
891 		int jsbound = fr->jsbound;
892 		register real *f0 = fraction[0];
893 		register real *f1 = fraction[1];
894 
895 		ba = balloc;
896 		for (sample = smpb, i = 0; i < jsbound; i++)
897 		{
898 			if ((n = *ba++))
899 				*sample++ = mpg123_getbits(n + 1);
900 			if ((n = *ba++))
901 				*sample++ = mpg123_getbits(n + 1);
902 		}
903 		for (i = jsbound; i < SBLIMIT; i++)
904 			if ((n = *ba++))
905 				*sample++ = mpg123_getbits(n + 1);
906 
907 		ba = balloc;
908 		for (sample = smpb, i = 0; i < jsbound; i++)
909 		{
910 			if ((n = *ba++))
911 				*f0++ = (real) (((-1) << n) + (*sample++) + 1) * mpg123_muls[n + 1][*sca++];
912 			else
913 				*f0++ = 0.0;
914 			if ((n = *ba++))
915 				*f1++ = (real) (((-1) << n) + (*sample++) + 1) * mpg123_muls[n + 1][*sca++];
916 			else
917 				*f1++ = 0.0;
918 		}
919 		for (i = jsbound; i < SBLIMIT; i++)
920 		{
921 			if ((n = *ba++))
922 			{
923 				real samp = (((-1) << n) + (*sample++) + 1);
924 
925 				*f0++ = samp * mpg123_muls[n + 1][*sca++];
926 				*f1++ = samp * mpg123_muls[n + 1][*sca++];
927 			}
928 			else
929 				*f0++ = *f1++ = 0.0;
930 		}
931 		for (i = fr->down_sample_sblimit; i < 32; i++)
932 			fraction[0][i] = fraction[1][i] = 0.0;
933 	}
934 	else
935 	{
936 		register real *f0 = fraction[0];
937 
938 		ba = balloc;
939 		for (sample = smpb, i = 0; i < SBLIMIT; i++)
940 			if ((n = *ba++))
941 				*sample++ = mpg123_getbits(n + 1);
942 		ba = balloc;
943 		for (sample = smpb, i = 0; i < SBLIMIT; i++)
944 		{
945 			if ((n = *ba++))
946 				*f0++ = (real) (((-1) << n) + (*sample++) + 1) * mpg123_muls[n + 1][*sca++];
947 			else
948 				*f0++ = 0.0;
949 		}
950 		for (i = fr->down_sample_sblimit; i < 32; i++)
951 			fraction[0][i] = 0.0;
952 	}
953 }
954 
get_track_time_file(FILE * file)955 static guint get_track_time_file(FILE * file)
956 {
957 	guint32 head;
958 	guchar tmp[4], *buf;
959 	struct frame frm;
960 	xing_header_t xing_header;
961 	double tpf, bpf;
962 	guint32 len;
963 
964 	if (!file)
965 		return -1;
966 
967 	fseek(file, 0, SEEK_SET);
968 	if (fread(tmp, 1, 4, file) != 4)
969 		return 0;
970 	head = convert_to_header(tmp);
971 	while (!mpg123_head_check(head))
972 	{
973 		head <<= 8;
974 		if (fread(tmp, 1, 1, file) != 1)
975 			return 0;
976 		head |= tmp[0];
977 	}
978 	if (mpg123_decode_header(&frm, head))
979 	{
980 		buf = g_malloc(frm.framesize + 4);
981 		fseek(file, -4, SEEK_CUR);
982 		fread(buf, 1, frm.framesize + 4, file);
983 		tpf = mpg123_compute_tpf(&frm);
984 		if (mpg123_get_xing_header(&xing_header, buf))
985 		{
986 			g_free(buf);
987 			return ((guint) (tpf * xing_header.frames * 1000));
988 		}
989 		g_free(buf);
990 		bpf = mpg123_compute_bpf(&frm);
991 		fseek(file, 0, SEEK_END);
992 		len = ftell(file);
993 		fseek(file, -128, SEEK_END);
994 		fread(tmp, 1, 3, file);
995 		if (!strncmp(tmp, "TAG", 3))
996 			len -= 128;
997 		return ((guint) ((guint)(len / bpf) * tpf * 1000));
998 	}
999 	return 0;
1000 }
1001 
get_track_time(const gchar * path)1002 static guint get_track_time (const gchar *path)
1003 {
1004     guint result = 0;
1005 
1006     if (path)
1007     {
1008 	FILE *file = fopen (path, "r");
1009 	result = get_track_time_file (file);
1010 	if (file) fclose (file);
1011     }
1012     return result;
1013 }
1014 
1015 
1016 /* libid3tag stuff */
1017 
1018 #include <id3tag.h>
1019 #include "prefs.h"
1020 
1021 #ifndef ID3_FRAME_GROUP
1022 #define ID3_FRAME_GROUP "TPE2"
1023 #endif
1024 
1025 
1026 
id3_get_binary(struct id3_tag * tag,char * frame_name,id3_length_t * len,int index)1027 static const gchar* id3_get_binary (struct id3_tag *tag,
1028 				    char *frame_name,
1029 				    id3_length_t *len,
1030 				    int index)
1031 {
1032     const id3_byte_t *binary = NULL;
1033     struct id3_frame *frame;
1034     union id3_field *field;
1035 
1036     g_return_val_if_fail (len, NULL);
1037 
1038     *len = 0;
1039 
1040     frame = id3_tag_findframe (tag, frame_name, index);
1041     DEBUG ("frame: %p\n", frame);
1042 
1043     if (!frame) return NULL;
1044 
1045 #if LOCALDEBUG
1046     printf (" nfields: %d\n", frame->nfields);
1047     if (strncmp (frame_name, "APIC",  4) == 0)
1048     {
1049 	field = id3_frame_field (frame, 2);
1050 	printf (" picture type: %ld\n", field->number.value);
1051     }
1052 #endif
1053 
1054 
1055 #if 0
1056 /*-----------------*/
1057 /* just to show that this field (before last) contains the d8 ff e0 ff
1058    part of the start of a jpeg file when the coverart war embedded by iTunes */
1059 
1060     const id3_ucs4_t *string = NULL;
1061     gchar *raw = NULL;
1062 
1063     /* The last field contains the data */
1064     field = id3_frame_field (frame, frame->nfields-2);
1065 
1066 #if LOCALDEBUG
1067      printf (" field: %p\n", field);
1068 #endif
1069 
1070     if (!field) return NULL;
1071 
1072 #if LOCALDEBUG
1073      printf (" type: %d\n", field->type);
1074 #endif
1075 
1076     switch (field->type)
1077     {
1078     case ID3_FIELD_TYPE_STRING:
1079 	string = id3_field_getstring (field);
1080 	break;
1081     default:
1082 	break;
1083     }
1084 
1085     /* ISO_8859_1 is just a "marker" -- most people just drop
1086        whatever coding system they are using into it, so we use
1087        charset_to_utf8() to convert to utf8 */
1088 
1089     if (string)
1090     {
1091 	raw = id3_ucs4_latin1duplicate (string);
1092     }
1093 
1094 
1095 #if LOCALDEBUG
1096     {
1097 	FILE *file;
1098 	printf (" string len: %d\n", raw?strlen(raw):0);
1099 	file = fopen ("/tmp/folder1.jpg", "w");
1100 	fwrite (raw, 1, raw?strlen(raw):0, file);
1101 	fclose (file);
1102     }
1103 #endif
1104     g_free (raw);
1105 
1106 /*-----------------*/
1107 #endif
1108 
1109     /* The last field contains the data */
1110     field = id3_frame_field (frame, frame->nfields-1);
1111 
1112     DEBUG (" field: %p\n", field);
1113 
1114     if (!field) return NULL;
1115 
1116     DEBUG (" type: %d\n", field->type);
1117 
1118     switch (field->type)
1119     {
1120     case ID3_FIELD_TYPE_BINARYDATA:
1121 	binary = id3_field_getbinarydata(field, len);
1122 	break;
1123     default:
1124 	break;
1125     }
1126 
1127 #if LOCALDEBUG
1128     {
1129 	FILE *file;
1130 	printf (" binary len: %ld\n", *len);
1131 	file = fopen ("/tmp/folder2.jpg", "w");
1132 	fwrite (binary, 1, *len, file);
1133 	fclose (file);
1134     }
1135 #endif
1136 
1137 
1138 
1139     return binary;
1140 }
1141 
1142 
1143 
id3_get_string(struct id3_tag * tag,char * frame_name)1144 static gchar* id3_get_string (struct id3_tag *tag, char *frame_name)
1145 {
1146     const id3_ucs4_t *string = NULL;
1147     const id3_byte_t *binary = NULL;
1148     id3_length_t len = 0;
1149     struct id3_frame *frame;
1150     union id3_field *field;
1151     gchar *utf8 = NULL;
1152     enum id3_field_textencoding encoding = ID3_FIELD_TEXTENCODING_ISO_8859_1;
1153 
1154     frame = id3_tag_findframe (tag, frame_name, 0);
1155     DEBUG ("frame: %p\n", frame);
1156 
1157     if (!frame) return NULL;
1158 
1159     /* Find the encoding used for the field */
1160     field = id3_frame_field (frame, 0);
1161     DEBUG ("field: %p\n", field);
1162     DEBUG ("type: %d\n", id3_field_type (field));
1163 
1164     if (field && (id3_field_type (field) == ID3_FIELD_TYPE_TEXTENCODING))
1165     {
1166 	encoding = field->number.value;
1167 	DEBUG ("encoding: %d\n", encoding);
1168     }
1169 
1170     /* The last field contains the data */
1171     field = id3_frame_field (frame, frame->nfields-1);
1172 
1173     DEBUG ("field: %p\n", field);
1174 
1175     if (!field) return NULL;
1176 
1177     DEBUG ("type: %d\n", field->type);
1178 
1179     switch (field->type)
1180     {
1181     case ID3_FIELD_TYPE_STRINGLIST:
1182 	string = id3_field_getstrings (field, 0);
1183 	break;
1184     case ID3_FIELD_TYPE_STRINGFULL:
1185 	string = id3_field_getfullstring (field);
1186 	break;
1187     case ID3_FIELD_TYPE_BINARYDATA:
1188 	binary = id3_field_getbinarydata(field, &len);
1189 	DEBUG ("len: %ld\nbinary: %s\n", len, binary+1);
1190 	if (len > 0)
1191 	    return charset_to_utf8 (binary+1);
1192 	break;
1193     default:
1194 	break;
1195     }
1196 
1197 /*     printf ("string: %p\n", string); */
1198 
1199     if (!string) return NULL;
1200 
1201     if (strcmp (frame_name, ID3_FRAME_GENRE) == 0)
1202        string = id3_genre_name (string);
1203 
1204     if (encoding == ID3_FIELD_TEXTENCODING_ISO_8859_1)
1205     {
1206 	/* ISO_8859_1 is just a "marker" -- most people just drop
1207 	   whatever coding system they are using into it, so we use
1208 	   charset_to_utf8() to convert to utf8 */
1209 	id3_latin1_t *raw = id3_ucs4_latin1duplicate (string);
1210 	utf8 = charset_to_utf8 (raw);
1211 	g_free (raw);
1212     }
1213     else
1214     {
1215 	/* Standard unicode is being used -- we won't have to worry
1216 	   about charsets then. */
1217 	utf8 = id3_ucs4_utf8duplicate (string);
1218     }
1219     return utf8;
1220 }
1221 
id3_set_string(struct id3_tag * tag,const char * frame_name,const char * data,enum id3_field_textencoding encoding)1222 static void id3_set_string (struct id3_tag *tag,
1223 			    const char *frame_name,
1224 			    const char *data,
1225 			    enum id3_field_textencoding encoding)
1226 {
1227     int res;
1228     struct id3_frame *frame;
1229     union id3_field *field;
1230     id3_ucs4_t *ucs4;
1231 
1232     /* clear the frame, because of bug in libid3tag see
1233        http://www.mars.org/mailman/public/mad-dev/2004-October/001113.html
1234     */
1235     while ((frame = id3_tag_findframe (tag, frame_name, 0)))
1236     {
1237 	id3_tag_detachframe (tag, frame);
1238         id3_frame_delete (frame);
1239     }
1240 
1241     if ((data == NULL) || (strlen(data) == 0))
1242 	return;
1243 
1244     frame = id3_frame_new (frame_name);
1245     id3_tag_attachframe (tag, frame);
1246 
1247     /* Use the specified text encoding */
1248     field = id3_frame_field (frame, 0);
1249     id3_field_settextencoding(field, encoding);
1250 
1251     if ((strcmp (frame_name, ID3_FRAME_COMMENT) == 0) ||
1252         (strcmp (frame_name, "USLT") == 0))
1253     {
1254 	field = id3_frame_field (frame, 3);
1255 	field->type = ID3_FIELD_TYPE_STRINGFULL;
1256     }
1257     else
1258     {
1259 	field = id3_frame_field (frame, 1);
1260 	field->type = ID3_FIELD_TYPE_STRINGLIST;
1261     }
1262 
1263 
1264     /* maybe could be optimized see
1265        http://www.mars.org/mailman/public/mad-dev/2002-October/000739.html
1266     */
1267 /* don't handle the genre frame differently any more */
1268 #define USE_GENRE_IDS 0
1269 #if USE_GENRE_IDS
1270     if (strcmp (frame_name, ID3_FRAME_GENRE) == 0)
1271     {
1272 	id3_ucs4_t *tmp_ucs4 = id3_utf8_ucs4duplicate ((id3_utf8_t *)data);
1273 	int index = id3_genre_number (tmp_ucs4);
1274 	if (index != -1)
1275 	{
1276 	    /* valid genre -- simply store the genre number */
1277 	    gchar *tmp = g_strdup_printf("(%d)", index);
1278 	    ucs4 = id3_latin1_ucs4duplicate (tmp);
1279 	    g_free (tmp);
1280 	}
1281 	else
1282 	{
1283 	    /* oups -- not a valid genre -- save the entire genre string */
1284 	    if (encoding == ID3_FIELD_TEXTENCODING_ISO_8859_1)
1285 	    {
1286 		/* we read 'ISO_8859_1' to stand for 'any locale
1287 		   charset' -- most programs seem to work that way */
1288 		id3_latin1_t *raw = charset_from_utf8 (data);
1289 		ucs4 = id3_latin1_ucs4duplicate (raw);
1290 		g_free (raw);
1291 	    }
1292 	    else
1293 	    {
1294 		/* Yeah! We use unicode encoding and won't have to
1295 		   worry about charsets */
1296 		ucs4 = tmp_ucs4;
1297 		tmp_ucs4 = NULL;
1298 	    }
1299 	}
1300 	g_free (tmp_ucs4);
1301     }
1302     else
1303     {
1304 #endif
1305 	if (encoding == ID3_FIELD_TEXTENCODING_ISO_8859_1)
1306 	{
1307 	    /* we read 'ISO_8859_1' to stand for 'any locale charset'
1308 	       -- most programs seem to work that way */
1309 	    id3_latin1_t *raw = charset_from_utf8 (data);
1310 	    ucs4 = id3_latin1_ucs4duplicate (raw);
1311 	    g_free (raw);
1312 	}
1313 	else
1314 	{
1315 	    /* Yeah! We use unicode encoding and won't have to
1316 	       worry about charsets */
1317 	    ucs4 = id3_utf8_ucs4duplicate ((id3_utf8_t *)data);
1318 	}
1319 #if USE_GENRE_IDS
1320     }
1321 #endif
1322 
1323     if ((strcmp (frame_name, ID3_FRAME_COMMENT) == 0) || (strcmp (frame_name, "USLT") == 0))
1324 	res = id3_field_setfullstring (field, ucs4);
1325     else
1326 	res = id3_field_setstrings (field, 1, &ucs4);
1327 
1328     g_free (ucs4);
1329 
1330     if (res != 0)
1331 	g_print(_("Error setting ID3 field: %s\n"), frame_name);
1332 }
1333 
1334 
1335 /***
1336  * Reads id3v1.x / id3v2 apic data
1337  * @returns: TRUE on success, else FALSE.
1338  */
id3_apic_read(const gchar * filename,guchar ** image_data,gsize * image_data_len)1339 static gboolean id3_apic_read (const gchar *filename,
1340 			       guchar **image_data, gsize *image_data_len)
1341 {
1342     struct id3_file *id3file;
1343     struct id3_tag *id3tag;
1344 
1345     g_return_val_if_fail (filename, FALSE);
1346     g_return_val_if_fail (image_data, FALSE);
1347     g_return_val_if_fail (image_data_len, FALSE);
1348 
1349     *image_data = NULL;
1350     *image_data_len = 0;
1351 
1352     if (!(id3file = id3_file_open (filename, ID3_FILE_MODE_READONLY)))
1353     {
1354 	gchar *fbuf = charset_to_utf8 (filename);
1355 	g_print(_("ERROR while opening file: '%s' (%s).\n"),
1356 		fbuf, g_strerror(errno));
1357 	g_free (fbuf);
1358 	return FALSE;
1359     }
1360 
1361     if ((id3tag = id3_file_tag(id3file)))
1362     {
1363 	id3_length_t len;
1364 	const guchar *coverart = NULL;
1365 	int i;
1366 	struct id3_frame *frame;
1367 
1368 	/* Loop through APIC tags and set coverart.  The picture type should be
1369 	 * 3 -- Cover (front), but iTunes has been known to use 0 -- Other. */
1370 	for (i = 0; (frame = id3_tag_findframe(id3tag, "APIC", i)) != NULL; i++)
1371 	{
1372 	    union id3_field *field = id3_frame_field (frame, 2);
1373 	    int pictype = field->number.value;
1374 /*	    printf ("%s: found apic type %d\n", filename, pictype);*/
1375 
1376 	    /* We'll prefer type 3 (cover) over type 0 (other) */
1377 	    if (pictype == 3)
1378 	    {
1379 		coverart = id3_get_binary (id3tag, "APIC", &len, i);
1380 		break;
1381 	    }
1382 	    if ((pictype == 0) && !coverart)
1383 	    {
1384 		coverart = id3_get_binary (id3tag, "APIC", &len, i);
1385 	    }
1386 	}
1387 
1388 	if (coverart)
1389 	{   /* I guess iTunes is doing something wrong -- the
1390 	     * beginning of the coverart data ends up in a different
1391 	       field... We'll just add the missing data manually. */
1392 	    const guchar itunes_broken_jfif_marker[] =
1393 		{ 0x10, 'J', 'F', 'I', 'F'};
1394 	    if (len >= 5)
1395 	    {
1396 		if (strncmp (itunes_broken_jfif_marker, coverart,  5) == 0)
1397 		{
1398 		    const guchar itunes_missing_header[] =
1399 			{ 0xff, 0xd8, 0xff, 0xe0, 0x00 };
1400 		    *image_data = g_malloc (len+5);
1401 		    memcpy (*image_data, itunes_missing_header, 5);
1402 		    memcpy ((*image_data)+5, coverart, len);
1403 		    *image_data_len = len+5;
1404 		}
1405 	    }
1406 	    if (!*image_data)
1407 	    {
1408 		*image_data = g_malloc (len);
1409 		memcpy (*image_data, coverart, len);
1410 		*image_data_len = len;
1411 	    }
1412 #if LOCALDEBUG
1413 	    if (*image_data)
1414 	    {
1415 		FILE *file;
1416 		file = fopen ("/tmp/folder.jpg", "w");
1417 		fwrite (*image_data, 1, *image_data_len, file);
1418 		fclose (file);
1419 	    }
1420 #endif
1421 	}
1422     }
1423     id3_file_close (id3file);
1424     return TRUE;
1425 }
1426 
1427 
1428 /* Do some checks on the genre string -- ideally this should
1429  * be done within the id3tag library, I think */
handle_genre_variations(gchar ** genrep)1430 static void handle_genre_variations (gchar **genrep)
1431 {
1432 /* http://www.id3.org/id3v2.3.0#head-42b02d20fb8bf48e38ec5415e34909945dd849dc */
1433 
1434 /* The 'Content type', which previously was stored as a one byte
1435  * numeric value only, is now a numeric string. You may use one or
1436  * several of the types as ID3v1.1 did or, since the category list
1437  * would be impossible to maintain with accurate and up to date
1438  * categories, define your own.
1439 
1440  * References to the ID3v1 genres can be made by, as first byte, enter
1441  * "(" followed by a number from the genres list (appendix A) and
1442  * ended with a ")" character. This is optionally followed by a
1443  * refinement, e.g. "(21)" or "(4)Eurodisco". Several references can
1444  * be made in the same frame, e.g. "(51)(39)". If the refinement
1445  * should begin with a "(" character it should be replaced with "((",
1446  * e.g. "((I can figure out any genre)" or "(55)((I think...)". The
1447  * following new content types is defined in ID3v2 and is implemented
1448  * in the same way as the numeric content types, e.g. "(RX)".
1449  */
1450 
1451     /* If a "refinement" exists, we will forget about the ID's. */
1452     /* If only an ID is given, we will translate that ID into a string */
1453     gchar *genre, *oldgenre, *utf8_genre=NULL;
1454     const gchar *newgenre = NULL;
1455     g_return_if_fail (genrep);
1456 
1457     genre = *genrep;
1458     oldgenre = *genrep;
1459     if (genre == NULL) return;
1460 
1461     while (*genre)
1462     {
1463 	if (genre[0] == '(')
1464 	{
1465 	    if (genre[1] == '(')
1466 	    {
1467 		/* starting with "((" */
1468 		newgenre = &genre[1];
1469 		break;
1470 	    }
1471 	    if (isdigit (genre[1]))
1472 	    {   /* possibly a genre ID */
1473 		int num, genreid;
1474 		num = sscanf (genre, "(%d)", &genreid);
1475 		if (num != 1)
1476 		{   /* invalid ID -> give up */
1477 		    newgenre = &genre[0];
1478 		    break;
1479 		}
1480 		genre = strchr (&genre[1], ')');
1481 		g_return_if_fail (genre);
1482 		++genre;
1483 		if (!newgenre)
1484 		{   /* retrieve genre string from ID -- we only
1485 		     * convert the first ID */
1486 		    id3_ucs4_t const *ucs4_genre = id3_genre_index (genreid);
1487 		    if (ucs4_genre == NULL)
1488 		    {
1489 			break;
1490 		    }
1491 		    utf8_genre = id3_ucs4_utf8duplicate (ucs4_genre);
1492 		    newgenre = utf8_genre;
1493 		}
1494 	    }
1495 	    else
1496 	    {
1497 		newgenre = &genre[0];
1498 		break;
1499 	    }
1500 	}
1501 	else
1502 	{
1503 	    newgenre = &genre[0];
1504 	    break;
1505 	}
1506     }
1507     if (newgenre && (newgenre != oldgenre))
1508     {
1509 	*genrep = g_strdup (newgenre);
1510 	g_free (oldgenre);
1511     }
1512     g_free (utf8_genre);
1513 }
1514 
1515 
1516 
1517 
1518 /***
1519  * Reads id3v1.x / id3v2 tag and load data into the Id3tag structure.
1520  * If a tag entry exists (ex: title), we allocate memory, else value
1521  * stays to NULL
1522  * @returns: TRUE on success, else FALSE.
1523  */
id3_tag_read(const gchar * filename,File_Tag * tag)1524 gboolean id3_tag_read (const gchar *filename, File_Tag *tag)
1525 {
1526     struct id3_file *id3file;
1527     struct id3_tag *id3tag;
1528     gchar* string;
1529     gchar* string2;
1530 
1531     g_return_val_if_fail (filename, FALSE);
1532     g_return_val_if_fail (tag, FALSE);
1533 
1534     memset (tag, 0, sizeof (File_Tag));
1535 
1536     if (!(id3file = id3_file_open (filename, ID3_FILE_MODE_READONLY)))
1537     {
1538 	gchar *fbuf = charset_to_utf8 (filename);
1539 	g_print(_("ERROR while opening file: '%s' (%s).\n"),
1540 		fbuf, g_strerror(errno));
1541 	g_free (fbuf);
1542 	return FALSE;
1543     }
1544 
1545     if ((id3tag = id3_file_tag(id3file)))
1546     {
1547 	tag->title = id3_get_string (id3tag, ID3_FRAME_TITLE);
1548 	tag->artist = id3_get_string (id3tag, ID3_FRAME_ARTIST);
1549 	if (!tag->artist || !*tag->artist)
1550 	{
1551 	    g_free (tag->artist);
1552 	    tag->artist = id3_get_string (id3tag, ID3_FRAME_GROUP);
1553 	} else {
1554 	    tag->albumartist = id3_get_string (id3tag, ID3_FRAME_GROUP);
1555 	}
1556 	tag->album = id3_get_string (id3tag, ID3_FRAME_ALBUM);
1557 	tag->year = id3_get_string (id3tag, ID3_FRAME_YEAR);
1558 	tag->composer = id3_get_string (id3tag, "TCOM");
1559 	tag->comment = id3_get_string (id3tag, ID3_FRAME_COMMENT);
1560 	tag->genre = id3_get_string (id3tag, ID3_FRAME_GENRE);
1561 	tag->compilation = id3_get_string (id3tag, "TCMP");
1562 	tag->subtitle = id3_get_string (id3tag, "TIT3");
1563 	tag->lyrics = id3_get_string (id3tag, "USLT");
1564 	tag->podcasturl = id3_get_string (id3tag, "YTID");
1565 	tag->podcastrss = id3_get_string (id3tag, "YWFD");
1566 	tag->description = id3_get_string (id3tag, "YTDS");
1567 	tag->time_released = id3_get_string (id3tag, "YTDR");
1568 	tag->BPM = id3_get_string (id3tag, "TBPM");
1569 	tag->sort_artist = id3_get_string (id3tag, "TSOP");
1570 	tag->sort_album = id3_get_string (id3tag, "TSOA");
1571 	tag->sort_title = id3_get_string (id3tag, "TSOT");
1572 	tag->sort_albumartist = id3_get_string (id3tag, "TSO2");
1573 	tag->sort_composer = id3_get_string (id3tag, "TSOC");
1574 
1575 	string = id3_get_string (id3tag, "TLEN");
1576 	if (string)
1577 	{
1578 	    tag->songlen = (guint32) strtoul (string, 0, 10);
1579 	    g_free (string);
1580 	}
1581 
1582 	string = id3_get_string (id3tag, ID3_FRAME_TRACK);
1583 	if (string)
1584 	{
1585 	    string2 = strchr(string,'/');
1586 	    if (string2)
1587 	    {
1588 		tag->track_total = g_strdup_printf ("%.2d", atoi (string2+1));
1589 		*string2 = '\0';
1590 	    }
1591 	    tag->trackstring = g_strdup_printf ("%.2d", atoi (string));
1592 	    g_free(string);
1593 	}
1594 
1595 	/* CD/disc number tag handling */
1596 	string = id3_get_string (id3tag, "TPOS");
1597 	if (string)
1598 	{
1599 	    string2 = strchr(string,'/');
1600 	    if (string2)
1601 	    {
1602 		tag->cdno_total = g_strdup_printf ("%.2d", atoi (string2+1));
1603 		*string2 = '\0';
1604 	    }
1605 	    tag->cdnostring = g_strdup_printf ("%.2d", atoi (string));
1606 	    g_free(string);
1607 	}
1608 
1609 	/* Do some checks on the genre string -- ideally this should
1610 	 * be done within the id3tag library, I think */
1611 	handle_genre_variations (&tag->genre);
1612     }
1613 
1614     id3_file_close (id3file);
1615     return TRUE;
1616 }
1617 
1618 
1619 
get_encoding_of(struct id3_tag * tag,const char * frame_name)1620 static enum id3_field_textencoding get_encoding_of (struct id3_tag *tag, const char *frame_name)
1621 {
1622     struct id3_frame *frame;
1623     enum id3_field_textencoding encoding = -1;
1624 
1625     frame = id3_tag_findframe (tag, frame_name, 0);
1626     if (frame)
1627     {
1628 	union id3_field *field = id3_frame_field (frame, 0);
1629 	if (field && (id3_field_type (field) == ID3_FIELD_TYPE_TEXTENCODING))
1630 	    encoding = field->number.value;
1631     }
1632     return encoding;
1633 }
1634 
1635 /* Find out which encoding is being used. If in doubt, return
1636  * latin1. This code assumes that the same encoding is used in all
1637  * fields.  */
get_encoding(struct id3_tag * tag)1638 static enum id3_field_textencoding get_encoding (struct id3_tag *tag)
1639 {
1640     enum id3_field_textencoding enc;
1641 
1642     enc = get_encoding_of (tag, ID3_FRAME_TITLE);
1643     if (enc != -1) return enc;
1644     enc = get_encoding_of (tag, ID3_FRAME_ARTIST);
1645     if (enc != -1) return enc;
1646     enc = get_encoding_of (tag, ID3_FRAME_ALBUM);
1647     if (enc != -1) return enc;
1648     enc = get_encoding_of (tag, "TCOM");
1649     if (enc != -1) return enc;
1650     enc = get_encoding_of (tag, ID3_FRAME_COMMENT);
1651     if (enc != -1) return enc;
1652     enc = get_encoding_of (tag, ID3_FRAME_YEAR);
1653     if (enc != -1) return enc;
1654     return ID3_FIELD_TEXTENCODING_ISO_8859_1;
1655 }
1656 
1657 
1658 /* I'm not really sure about this: The original TAG identifier was
1659    "TID", but no matter what I do I end up writing "YTID" */
set_uncommon_tag(struct id3_tag * id3tag,const gchar * id,const gchar * text,enum id3_field_textencoding encoding)1660 void set_uncommon_tag (struct id3_tag *id3tag,
1661 		       const gchar *id,
1662 		       const gchar *text,
1663 		       enum id3_field_textencoding encoding)
1664 {
1665 #if 0
1666     struct id3_frame *frame;
1667     union id3_field *field;
1668 
1669     frame = id3_tag_findframe (id3tag, id, 0);
1670 	frame->flags = 0;
1671 	field = id3_frame_field (frame, 0);
1672 	    if (field)
1673 	    {
1674 		string1 = g_strdup_printf ("%c%s", '\0',
1675 					   track->podcasturl);
1676 		id3_field_setbinarydata (field, string1,
1677 					 strlen(track->podcasturl)+1);
1678 		g_free (string1);
1679 	    }
1680 
1681 #endif
1682 }
1683 
1684 
1685 
1686 /**
1687  * Write the ID3 tags to the file.
1688  * @returns: TRUE on success, else FALSE.
1689  */
mp3_write_file_info(const gchar * filename,Track * track)1690 gboolean mp3_write_file_info (const gchar *filename, Track *track)
1691 {
1692     struct id3_tag* id3tag;
1693     struct id3_file* id3file;
1694     gint error = 0;
1695 
1696     id3file = id3_file_open (filename, ID3_FILE_MODE_READWRITE);
1697     if (!id3file)
1698     {
1699 	gchar *fbuf = charset_to_utf8 (filename);
1700 	g_print(_("ERROR while opening file: '%s' (%s).\n"),
1701 		fbuf, g_strerror(errno));
1702 	g_free (fbuf);
1703 	return FALSE;
1704     }
1705 
1706     if ((id3tag = id3_file_tag(id3file)))
1707     {
1708 	char *string1;
1709 	enum id3_field_textencoding encoding;
1710 
1711 	/* use the same coding as before... */
1712 	encoding = get_encoding (id3tag);
1713 	/* ...unless it's ISO_8859_1 and prefs say we should use
1714 	   unicode (i.e. ID3v2.4) */
1715 	if (prefs_get_int("id3_write_id3v24") &&
1716 	    (encoding == ID3_FIELD_TEXTENCODING_ISO_8859_1))
1717 	    encoding = ID3_FIELD_TEXTENCODING_UTF_8;
1718 
1719 	/* always render id3v1 to prevent dj studio from crashing */
1720 	id3_tag_options(id3tag, ID3_TAG_OPTION_ID3V1, ~0);
1721 
1722         /* turn off frame compression and crc information to let
1723 	   itunes read tags see
1724 	   http://www.mars.org/mailman/public/mad-dev/2002-October/000742.html
1725 	*/
1726 	id3_tag_options(id3tag, ID3_TAG_OPTION_COMPRESSION, 0);
1727 	id3_tag_options(id3tag, ID3_TAG_OPTION_CRC, 0);
1728 
1729 	id3_set_string (id3tag, ID3_FRAME_TITLE, track->title, encoding);
1730 	id3_set_string (id3tag, ID3_FRAME_ARTIST, track->artist, encoding);
1731 	id3_set_string (id3tag, ID3_FRAME_GROUP, track->albumartist, encoding);
1732 	id3_set_string (id3tag, ID3_FRAME_ALBUM, track->album, encoding);
1733 	id3_set_string (id3tag, ID3_FRAME_GENRE, track->genre, encoding);
1734 	id3_set_string (id3tag, ID3_FRAME_COMMENT, track->comment, encoding);
1735 	id3_set_string (id3tag, "TIT3", track->subtitle, encoding);
1736 	id3_set_string (id3tag, "TSOP", track->sort_artist, encoding);
1737 	id3_set_string (id3tag, "TSOA", track->sort_album, encoding);
1738 	id3_set_string (id3tag, "TSOT", track->sort_title, encoding);
1739 	id3_set_string (id3tag, "TSO2", track->sort_albumartist, encoding);
1740 	id3_set_string (id3tag, "TSOC", track->sort_composer, encoding);
1741 
1742 	set_uncommon_tag (id3tag, "YTID", track->podcasturl, encoding);
1743 	set_uncommon_tag (id3tag, "YTDS", track->description, encoding);
1744 	set_uncommon_tag (id3tag, "YWFD", track->podcastrss, encoding);
1745 
1746 	id3_set_string (id3tag, "TCOM", track->composer, encoding);
1747 
1748 	string1 = g_strdup_printf("%d", track->year);
1749 	id3_set_string(id3tag, ID3_FRAME_YEAR, string1, encoding);
1750 	g_free(string1);
1751 
1752 	string1 = g_strdup_printf("%d", track->BPM);
1753 	id3_set_string(id3tag, "TBPM", string1, encoding);
1754 	g_free(string1);
1755 
1756 	if (track->tracks)
1757 	    string1 = g_strdup_printf ("%d/%d",
1758 				       track->track_nr, track->tracks);
1759 	else
1760 	    string1 = g_strdup_printf ("%d", track->track_nr);
1761 	id3_set_string (id3tag, ID3_FRAME_TRACK, string1, encoding);
1762 	g_free(string1);
1763 
1764 	if (track->cds)
1765 	    string1 = g_strdup_printf ("%d/%d",
1766 				       track->cd_nr, track->cds);
1767 	else
1768 	    string1 = g_strdup_printf ("%d", track->cd_nr);
1769 	id3_set_string (id3tag, "TPOS", string1, encoding);
1770 	g_free(string1);
1771 
1772        string1 = g_strdup_printf ("%d", track->compilation);
1773        id3_set_string (id3tag, "TCMP", string1, encoding);
1774        g_free(string1);
1775     }
1776 
1777     if (id3_file_update(id3file) != 0)
1778     {
1779 	gchar *fbuf = charset_to_utf8 (filename);
1780 	g_print(_("ERROR while writing tag to file: '%s' (%s).\n"),
1781 		fbuf, g_strerror(errno));
1782 	g_free (fbuf);
1783 	return FALSE;
1784     }
1785 
1786     id3_file_close (id3file);
1787 
1788     if (error) return FALSE;
1789     else       return TRUE;
1790 }
1791 
1792 
1793 /*
1794  * Code used to calculate the CRC-16 of the info tag.  Used to check the
1795  * validity of the data read from the lame tag.
1796  * Code taken from the libmad project, licensed under GPL
1797  */
1798 
1799 static
1800 unsigned short const crc_table[256] = {
1801   0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241,
1802   0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440,
1803   0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40,
1804   0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841,
1805   0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40,
1806   0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41,
1807   0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641,
1808   0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040,
1809 
1810   0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240,
1811   0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441,
1812   0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41,
1813   0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840,
1814   0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41,
1815   0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40,
1816   0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640,
1817   0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041,
1818 
1819   0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240,
1820   0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441,
1821   0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41,
1822   0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840,
1823   0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41,
1824   0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40,
1825   0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640,
1826   0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041,
1827 
1828   0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241,
1829   0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440,
1830   0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40,
1831   0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841,
1832   0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40,
1833   0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41,
1834   0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641,
1835   0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040
1836 };
1837 
crc_compute(char const * data,unsigned int length,unsigned short init)1838 unsigned short crc_compute(char const *data, unsigned int length,
1839 			   unsigned short init)
1840 {
1841   register unsigned int crc;
1842 
1843   for (crc = init; length >= 8; length -= 8) {
1844     crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1845     crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1846     crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1847     crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1848     crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1849     crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1850     crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1851     crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1852   }
1853 
1854   switch (length) {
1855   case 7: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1856   case 6: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1857   case 5: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1858   case 4: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1859   case 3: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1860   case 2: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1861   case 1: crc = crc_table[(crc ^ *data++) & 0xff] ^ (crc >> 8);
1862   case 0: break;
1863   }
1864 
1865   return crc;
1866 }
1867 
1868 
1869 /*
1870  * Code to read the ReplayGain Values stored by LAME in its own tag.
1871  *
1872  * Most of the relevant information has been extracted from them LAME sources
1873  * (http://lame.sourceforge.net/).
1874  * The "Mp3 info Tag rev 1 specifications - draft 0"
1875  * (http://gabriel.mp3-tech.org/mp3infotag.html) by Gabriel Bouvigne describes
1876  * the actual Tag (except for small changes).
1877  * Details on the actual ReplayGain fields have been obtained from
1878  * http://www.replaygain.org .
1879  *
1880  * Apart from that, some information has been derived from phwip's LameTag
1881  * (http://www.silisoftware.com/applets/?scriptname=LameTag)
1882  *
1883  *
1884  * Code to read the ReplayGain Values stored in an Ape tag.
1885  *
1886  * Info on Lyrics3 V2.00 can be found at:
1887  * http://www.id3.org/lyrics3200.html
1888  * On the actual Ape Tag V2.0:
1889  * http://www.personal.uni-jena.de/~pfk/mpp/sv8/apetag.html
1890  *
1891  * Copyright (C) 2004 Jens Taprogge <jens.taprogge at post.rwth-aachen.de>
1892  *
1893  * Provided under GPL according to Jens Taprogge. (JCS -- 12 March 2004)
1894  */
1895 
1896 #define TAG_FOOTER		0x10
1897 #define LAME_OFFSET		0x74
1898 #define SIDEINFO_MPEG1_MONO	17
1899 #define SIDEINFO_MPEG1_MULTI	32
1900 #define SIDEINFO_MPEG2_MONO	9
1901 #define SIDEINFO_MPEG2_MULTI	17
1902 #define ID3V1_SIZE		0x80
1903 #define APE_FOOTER_SIZE 	0x20
1904 #define LYRICS_FOOTER_SIZE 	0x0f
1905 
1906 
lame_vcmp(gchar a[5],gchar b[5])1907 static gint lame_vcmp(gchar a[5], gchar b[5]) {
1908 	int r;
1909 
1910 	r = strncmp(a, b, 4);
1911 	if (r) return r;
1912 
1913 	if (a[4] == b[4]) return 0;
1914 
1915 	/* check for '.': indicates subminor version */
1916 	if (a[4] == '.') return 1;
1917 	if (b[4] == '.') return -1;
1918 
1919 	/* check for alpha or beta versions */
1920 	if (a[4] == ' ') return 1;
1921 	if (b[4] == ' ') return -1;
1922 
1923 	/* check for alpha, beta etc. indicated by a, b... */
1924 	return strncmp(&a[4], &b[4], 1);
1925 }
1926 
1927 
1928 /* buf[] must be declared unsigned -- otherwise the casts, shifts and
1929    additions below produce funny results */
read_lame_replaygain(unsigned char buf[],GainData * gd,int gain_adjust)1930 static void read_lame_replaygain(unsigned char buf[],
1931 				 GainData *gd, int gain_adjust) {
1932 	char oc, nc;
1933 	gint gain;
1934 
1935 	g_return_if_fail (gd);
1936 
1937 	/* buf[0] and buf[1] are a bit field:
1938 	   3 bits: name  (mask: 0xe0 = 11100000)
1939 	   3 bits: originator (mask: 0x1c = 00011100)
1940 	   1 bit: negative if set (mask: 0x02 = 00000010)
1941 	   9 bits: value
1942 	*/
1943 
1944 	/* check originator */
1945 	oc = (buf[0] & 0x1c) >> 2;
1946 	if ((oc <= 0) || (oc > 3)) return;
1947 
1948 	/* check name code */
1949 	nc = buf[0] & 0xe0;
1950 	if (!((nc == 0x20) || (nc == 0x40))) return;
1951 
1952 	gain = ((((guint)buf[0]) & 0x1) << 8) + buf[1];
1953 
1954 	/* This would be a value of -0.
1955 	 * That value however is illegal by current standards and reserved for
1956 	 * future use. */
1957 	if ((!gain) && (buf[0] & 0x02)) return;
1958 
1959 	if (buf[0] & 2) gain = -gain;
1960 
1961 	gain += gain_adjust;
1962 
1963 	switch (nc) {
1964 		case 0x20:
1965 			if (gd->radio_gain_set) return;
1966 			gd->radio_gain = (gdouble)gain / 10;
1967 			gd->radio_gain_set = TRUE;
1968 			DEBUG ("radio gain (lame): %f\n", gd->radio_gain);
1969 			break;
1970 		case 0x40:
1971 			if (gd->audiophile_gain_set) return;
1972 			gd->audiophile_gain = (gdouble)gain / 10;
1973 			gd->audiophile_gain_set = TRUE;
1974 			DEBUG ("album gain (lame): %f\n", gd->audiophile_gain);
1975 			break;
1976 	}
1977 }
1978 
1979 
parse_ape_uint32(char * buf)1980 static inline guint32 parse_ape_uint32(char *buf) {
1981 	return (buf[0] & 0xff) | (buf[1] & 0xff) << 8
1982 		| (buf[2] & 0xff) << 16 | (buf[3] & 0xff) << 24;
1983 }
1984 
parse_lame_uint32(char * buf)1985 static inline guint32 parse_lame_uint32(char *buf) {
1986 	return (buf[0] & 0xff) << 24 | (buf[1] & 0xff) << 16
1987 		| (buf[2] & 0xff) << 8 | (buf[3] & 0xff);
1988 }
1989 
parse_lame_uint16(char * buf)1990 static inline guint16 parse_lame_uint16(char *buf) {
1991 	return (buf[0] & 0xff) << 8 | (buf[1] & 0xff);
1992 }
1993 
1994 /*
1995  * mp3_get_track_lame_replaygain:
1996  *
1997  * @path: location of the file
1998  * @gd: #GainData structure
1999  *
2000  * Parse ReplayGain data for a given path from the LAME Tag.
2001  *
2002  * FIXME: Are there other encoders writing a LAME Tag using a different magic
2003  * string?
2004  */
mp3_get_track_lame_replaygain(const gchar * path,GainData * gd)2005 gboolean mp3_get_track_lame_replaygain (const gchar *path, GainData *gd)
2006 {
2007 	unsigned char ubuf[2];
2008 	int gain_adjust = 0;
2009 	LameTag lt;
2010 
2011 	g_return_val_if_fail (path, FALSE);
2012 
2013 	if (!mp3_read_lame_tag (path, &lt))
2014 	    goto rg_fail;
2015 
2016 	g_return_val_if_fail (gd, FALSE);
2017 
2018 	gd->radio_gain = 0;
2019 	gd->audiophile_gain = 0;
2020 	gd->peak_signal = 0;
2021 	gd->radio_gain_set = FALSE;
2022 	gd->audiophile_gain_set = FALSE;
2023 	gd->peak_signal_set = FALSE;
2024 
2025 	/* Replay Gain data is only available since Lame version 3.94b */
2026 	if (lame_vcmp(lt.version_string, "3.94b") < 0) {
2027 		DEBUG ("Old lame version (%s). Not used.\n", lt.version_string);
2028 		goto rg_fail;
2029 	}
2030 
2031 	if ((!gd->peak_signal_set) && lt.peak_signal_amplitude) {
2032 		gd->peak_signal = lt.peak_signal_amplitude;
2033 		gd->peak_signal_set = TRUE;
2034 		DEBUG ("peak signal (lame): %f\n",
2035 			(double)gd->peak_signal / 0x800000);
2036 	}
2037 
2038 	/*
2039 	 * Versions prior to 3.95.1 used a reference volume of 83dB.
2040 	 * (As compared to the currently used 89dB.)
2041 	 */
2042 	if ((lame_vcmp(lt.version_string, "3.95.") < 0)) {
2043 		gain_adjust = 60;
2044 		DEBUG ("Old lame version (%s). Adjusting gain.\n",
2045 			lt.version_string);
2046 	}
2047 
2048 	/* radio gain */
2049 	memcpy(ubuf,&lt.radio_replay_gain,2);
2050 	read_lame_replaygain (ubuf, gd, gain_adjust);
2051 
2052 	/* audiophile gain */
2053 	memcpy(ubuf,&lt.audiophile_replay_gain,2);
2054 	read_lame_replaygain (ubuf, gd, gain_adjust);
2055 
2056 	return TRUE;
2057 
2058 rg_fail:
2059 	return FALSE;
2060 }
2061 
2062 /*
2063  * mp3_get_track_id3_replaygain:
2064  *
2065  * @path: location of the file
2066  * @gd: #GainData structure
2067  *
2068  * Read the specified file and scan for ReplayGain information in
2069  * common ID3v2 tags.
2070  *
2071  */
mp3_get_track_id3_replaygain(const gchar * path,GainData * gd)2072 gboolean mp3_get_track_id3_replaygain (const gchar *path, GainData *gd)
2073 {
2074     int i;
2075     double d;
2076     char *ep, *key, *val;
2077     struct id3_file *id3file;
2078     struct id3_tag *id3tag;
2079     struct id3_frame *frame;
2080 
2081     g_return_val_if_fail (path, FALSE);
2082     g_return_val_if_fail (gd, FALSE);
2083 
2084     gd->radio_gain = 0;
2085     gd->audiophile_gain = 0;
2086     gd->peak_signal = 0;
2087     gd->radio_gain_set = FALSE;
2088     gd->audiophile_gain_set = FALSE;
2089     gd->peak_signal_set = FALSE;
2090 
2091     if (!(id3file = id3_file_open (path, ID3_FILE_MODE_READONLY)))
2092     {
2093 	gchar *fbuf = charset_to_utf8 (path);
2094 	g_print(_("ERROR while opening file: '%s' (%s).\n"),
2095 		fbuf, g_strerror(errno));
2096 	g_free (fbuf);
2097 	return FALSE;
2098     }
2099 
2100     if (!(id3tag = id3_file_tag (id3file)))
2101     {
2102 	id3_file_close (id3file);
2103 	return FALSE;
2104     }
2105 
2106     for (i = 0; (frame = id3_tag_findframe (id3tag, "TXXX", i)); i++)
2107     {
2108 	if (gd->radio_gain_set && gd->audiophile_gain_set
2109 	    && gd->peak_signal_set)
2110 	    break;
2111 
2112 	if (frame->nfields < 3)
2113 	    continue;
2114 
2115 	key = (char *)id3_ucs4_utf8duplicate (id3_field_getstring
2116 					      (&frame->fields[1]));
2117 
2118 	val = (char *)id3_ucs4_utf8duplicate (id3_field_getstring
2119 					      (&frame->fields[2]));
2120 
2121 	if (g_ascii_strcasecmp (key, "replaygain_album_gain") == 0)
2122 	{
2123 	    d = g_ascii_strtod (val, &ep);
2124 	    if (!g_ascii_strncasecmp (ep, " dB", 3))
2125 	    {
2126 		gd->audiophile_gain = d;
2127 		gd->audiophile_gain_set = TRUE;
2128 		DEBUG ("album gain (id3): %f\n", gd->audiophile_gain);
2129 	    }
2130 	}
2131 	else if (g_ascii_strcasecmp (key, "replaygain_album_peak") == 0)
2132 	{
2133 	    d = g_ascii_strtod (val, NULL);
2134 	    d *= 0x800000;
2135 	    gd->peak_signal = (guint32) floor (d + 0.5);
2136 	    gd->peak_signal_set = TRUE;
2137 	    DEBUG ("album peak signal (id3): %f\n",
2138 		    (double)gd->peak_signal / 0x800000);
2139 	}
2140 	else if (g_ascii_strcasecmp (key, "replaygain_track_gain") == 0)
2141 	{
2142 	    d = g_ascii_strtod (val, &ep);
2143 	    if (!g_ascii_strncasecmp (ep, " dB", 3))
2144 	    {
2145 		gd->radio_gain = d;
2146 		gd->radio_gain_set = TRUE;
2147 		DEBUG ("radio gain (id3): %f\n", gd->radio_gain);
2148 	    }
2149 	}
2150 	else if (g_ascii_strcasecmp (key, "replaygain_track_peak") == 0)
2151 	{
2152 	    d = g_ascii_strtod (val, NULL);
2153 	    d *= 0x800000;
2154 	    gd->peak_signal = (guint32) floor (d + 0.5);
2155 	    gd->peak_signal_set = TRUE;
2156 	    DEBUG ("radio peak signal (id3): %f\n",
2157 		    (double)gd->peak_signal / 0x800000);
2158 	}
2159 
2160 	g_free (key);
2161 	g_free (val);
2162     }
2163 
2164     id3_file_close (id3file);
2165 
2166     if (!gd->radio_gain_set && !gd->audiophile_gain_set
2167 	&& !gd->peak_signal_set)
2168 	return FALSE;
2169     return TRUE;
2170 }
2171 
2172 /*
2173  * mp3_get_track_ape_replaygain:
2174  *
2175  * @path: location of the file
2176  * @gd: #GainData structure
2177  *
2178  * Read the specified file and scan for Ape Tag ReplayGain information.
2179  *
2180  */
mp3_get_track_ape_replaygain(const gchar * path,GainData * gd)2181 gboolean mp3_get_track_ape_replaygain(const gchar *path, GainData *gd)
2182 {
2183 	/* The Ape Tag is located at the end of the file. Or at least that seems
2184 	 * where it can most likely be found. Either it is at the very end or
2185 	 * before a trailing ID3v1 Tag. Sometimes a Lyrics3 Tag is placed
2186 	 * between the ID3v1 and the Ape Tag.  If you find files that have the
2187 	 * Tags located in different positions please report it to
2188 	 * gtkpod-devel@sourceforge.net.
2189 	 */
2190 
2191 	FILE *file = NULL;
2192 	char buf[16];
2193 	char *dbuf = NULL, *ep;
2194 
2195 	int offset = 0;
2196 	int i;
2197 	int pos = 0, pos2 = 0;
2198 	guint32 version;
2199 	guint32 data_length;
2200 	guint32 entry_length = 0;
2201 	guint32 entries;
2202 	double d;
2203 
2204 	g_return_val_if_fail (gd, FALSE);
2205 	g_return_val_if_fail (path, FALSE);
2206 
2207 	gd->radio_gain = 0;
2208 	gd->audiophile_gain = 0;
2209 	gd->peak_signal = 0;
2210 	gd->radio_gain_set = FALSE;
2211 	gd->audiophile_gain_set = FALSE;
2212 	gd->peak_signal_set = FALSE;
2213 
2214 	file = fopen (path, "r");
2215 
2216 	if (!file)
2217 	    goto rg_fail;
2218 
2219 	/* check for ID3v1 Tag */
2220 	if (fseek(file, -ID3V1_SIZE, SEEK_END) ||
2221 			fread(&buf, 1, 3, file) != 3)
2222 		goto rg_fail;
2223 	if (!strncmp(buf, "TAG", 3)) offset -= ID3V1_SIZE;
2224 
2225 	/* check for Lyrics3 Tag */
2226 	if (fseek(file, -9 + offset, SEEK_END) ||
2227 			fread(&buf, 1, 9, file) != 9)
2228 		goto rg_fail;
2229 	if (!strncmp(buf, "LYRICS200", 9)) {
2230 		if (fseek(file, -LYRICS_FOOTER_SIZE + offset, SEEK_END) ||
2231 				fread(&buf, 1, 9, file) != 9)
2232 			goto rg_fail;
2233 		data_length = buf[0] - '0';
2234 		for (i = 1; i < 6; i++) {
2235 			data_length *= 10;
2236 			data_length += buf[i] - '0';
2237 		}
2238 		if (fseek(file, -LYRICS_FOOTER_SIZE - data_length + offset,
2239 					SEEK_END) ||
2240 				fread(&buf, 1, 11, file) != 11)
2241 			goto rg_fail;
2242 		if (!strncmp(buf, "LYRICSBEGIN", 11))
2243 			offset -= LYRICS_FOOTER_SIZE + data_length;
2244 	}
2245 
2246 	/* check for APE Tag */
2247 	if (fseek(file, -APE_FOOTER_SIZE + offset, SEEK_END) ||
2248 			fread(&buf, 1, 8, file) != 8)
2249 		goto rg_fail;
2250 	if (strncmp(buf, "APETAGEX", 8)) goto rg_fail;
2251 
2252 	/* Check the version of the tag. 1000 and 2000 (v1.0 and 2.0) are the
2253 	 * only ones I know about. Make suer things do not break in the future.
2254 	 */
2255 	if (fread(&buf, 1, 4, file) != 4)
2256 		goto rg_fail;
2257 	version = parse_ape_uint32(buf);
2258 	if (version != 1000 && version != 2000)
2259 		goto rg_fail;
2260 
2261 	/* determine data length */
2262 	if (fread(&buf, 1, 4, file) != 4)
2263 		goto rg_fail;
2264 	data_length = parse_ape_uint32(buf) - APE_FOOTER_SIZE;
2265 
2266 	/* determine number of entries */
2267 	if (fread(&buf, 1, 4, file) != 4)
2268 		goto rg_fail;
2269 	entries = parse_ape_uint32(buf);
2270 
2271 	/* seek to first entry and read the whole buffer */
2272 	if (fseek(file, -APE_FOOTER_SIZE + offset - data_length, SEEK_END))
2273 		goto rg_fail;
2274 	if (!(dbuf = malloc(data_length)))
2275 		goto rg_fail;
2276 	if (fread(dbuf, 1, data_length, file) != data_length)
2277 		goto rg_fail;
2278 
2279 	for (i = 0; i < entries; i++) {
2280 		if (gd->radio_gain_set && gd->peak_signal_set && gd->audiophile_gain_set) break;
2281 		pos = pos2 + entry_length;
2282 		if (pos > data_length - 10) break;
2283 
2284 		entry_length = parse_ape_uint32(&dbuf[pos]); pos += 4;
2285 		pos += 4;
2286 
2287 		pos2 = pos;
2288 		while (dbuf[pos2] && pos2 < data_length) pos2++;
2289 		if (pos2 == data_length) break;
2290 		pos2++;
2291 
2292 		if (entry_length + 1 > sizeof(buf))
2293 			continue;
2294 
2295 		/* album gain */
2296 		if (!gd->audiophile_gain_set && !strcasecmp(&dbuf[pos],
2297 					"REPLAYGAIN_ALBUM_GAIN")) {
2298 			memcpy(buf, &dbuf[pos2], entry_length);
2299 			buf[entry_length] = '\0';
2300 
2301 			d = g_ascii_strtod(buf, &ep);
2302 			if ((ep == buf + entry_length - 3)
2303 					&& (!strncasecmp(ep, " dB", 3))) {
2304 			    gd->audiophile_gain = d;
2305 				gd->audiophile_gain_set = TRUE;
2306 				DEBUG ("album gain (ape): %f\n", gd->audiophile_gain);
2307 			}
2308 
2309 			continue;
2310 		}
2311 		if (!gd->peak_signal_set && !strcasecmp(&dbuf[pos],
2312 					"REPLAYGAIN_ALBUM_PEAK")) {
2313 			memcpy(buf, &dbuf[pos2], entry_length);
2314 			buf[entry_length] = '\0';
2315 
2316 			d = g_ascii_strtod(buf, &ep);
2317 			if (ep == buf + entry_length) {
2318 				d *= 0x800000;
2319 				gd->peak_signal = (guint32) floor(d + 0.5);
2320 				gd->peak_signal_set = TRUE;
2321 				DEBUG ("album peak signal (ape): %f\n",
2322 					(double)gd->peak_signal / 0x800000);
2323 			}
2324 
2325 			continue;
2326 		}
2327 
2328 		/* track gain */
2329 		if (!gd->radio_gain_set && !strcasecmp(&dbuf[pos],
2330 					"REPLAYGAIN_TRACK_GAIN")) {
2331 			memcpy(buf, &dbuf[pos2], entry_length);
2332 			buf[entry_length] = '\0';
2333 
2334 			d = g_ascii_strtod(buf, &ep);
2335 			if ((ep == buf + entry_length - 3)
2336 					&& (!strncasecmp(ep, " dB", 3))) {
2337 			    gd->radio_gain = d;
2338 				gd->radio_gain_set = TRUE;
2339 				DEBUG ("radio gain (ape): %f\n", gd->radio_gain);
2340 			}
2341 
2342 			continue;
2343 		}
2344 		if (!gd->peak_signal_set && !strcasecmp(&dbuf[pos],
2345 					"REPLAYGAIN_TRACK_PEAK")) {
2346 			memcpy(buf, &dbuf[pos2], entry_length);
2347 			buf[entry_length] = '\0';
2348 
2349 			d = g_ascii_strtod(buf, &ep);
2350 			if (ep == buf + entry_length) {
2351 				d *= 0x800000;
2352 				gd->peak_signal = (guint32) floor(d + 0.5);
2353 				gd->peak_signal_set = TRUE;
2354 				DEBUG ("radio peak signal (ape): %f\n",
2355 					(double)gd->peak_signal / 0x800000);
2356 			}
2357 
2358 			continue;
2359 		}
2360 	}
2361 
2362 	free(dbuf);
2363 	fclose(file);
2364 	return TRUE;
2365 
2366 rg_fail:
2367 	if (dbuf)
2368 		free(dbuf);
2369 	if (file)
2370 		fclose(file);
2371 	return FALSE;
2372 }
2373 
2374 
2375 /* ----------------------------------------------------------------------
2376 
2377 	      mp3gain code
2378 
2379 ---------------------------------------------------------------------- */
2380 
2381 #include <sys/wait.h>
2382 #include <fcntl.h>
2383 
2384 
2385 /*
2386  * mp3_read_soundcheck:
2387  *
2388  * @path: localtion of the file
2389  * @track: structure holding track information
2390  *
2391  * Try to read ReplayGain values and set the track's soundcheck field
2392  * accordingly.  If an ID3 tag is present and contains replaygain
2393  * fields (in the format used by Foobar2k and others), the values are
2394  * read from that tag.  If no ID3 tag is present, an APE tag is
2395  * checked and used if possible.  Lastly, the LAME tag is checked.  In
2396  * all cases, audiophile (aka album) gain is preferred over radio (aka
2397  * track) gain if both gain types are set.
2398  *
2399  * The function always rereads the gain from the file.
2400  *
2401  * Returns TRUE if the soundcheck field could be set.
2402  */
mp3_read_soundcheck(const gchar * path,Track * track)2403 gboolean mp3_read_soundcheck (const gchar *path, Track *track)
2404 {
2405     GainData gd;
2406     gint replaygain_offset;
2407     gint replaygain_mode_album_priority;
2408 
2409     replaygain_offset = prefs_get_int ("replaygain_offset");
2410     replaygain_mode_album_priority = prefs_get_int ("replaygain_mode_album_priority");
2411 
2412     g_return_val_if_fail (track, FALSE);
2413 
2414     memset (&gd, 0, sizeof (GainData));
2415 
2416     gd.radio_gain_set = FALSE;
2417     gd.audiophile_gain_set = FALSE;
2418     gd.peak_signal_set = FALSE;
2419 
2420     if (mp3_get_track_id3_replaygain (path, &gd))
2421 	DEBUG ("Using ID3 ReplayGain data\n");
2422     else if (mp3_get_track_ape_replaygain (path, &gd))
2423 	DEBUG ("Using APE ReplayGain data\n");
2424     else if (mp3_get_track_lame_replaygain (path, &gd))
2425 	DEBUG ("Using LAME ReplayGain data\n");
2426     else
2427 	return FALSE;
2428 
2429     if (gd.audiophile_gain_set && replaygain_mode_album_priority)
2430     {
2431 	DEBUG ("Setting Soundcheck value from album ReplayGain\n");
2432 	track->soundcheck = replaygain_to_soundcheck (gd.audiophile_gain + replaygain_offset);
2433 	return TRUE;
2434     }
2435     if (gd.radio_gain_set)
2436     {
2437 	DEBUG ("Setting Soundcheck value from radio ReplayGain\n");
2438 	track->soundcheck = replaygain_to_soundcheck (gd.radio_gain + replaygain_offset);
2439 	return TRUE;
2440     }
2441 
2442     return FALSE;
2443 }
2444 
2445 
2446 
2447 
2448 
2449 /* ----------------------------------------------------------------------
2450 
2451 	      From here starts original gtkpod code
2452 
2453 ---------------------------------------------------------------------- */
2454 
2455 /* mpeg audio slot size in bytes */
2456 int slotsize[3] = {4,1,1}; /* layer 1, layer 2, layer 3 */
2457 
2458 int samplesperframe[2][3] = {
2459   { /* MPEG 2.0 */
2460     384,1152,576 /* layer 1, layer 2, layer 3 */
2461   },
2462 
2463   { /* MPEG 1.0 */
2464     384,1152,1152 /* layer 1, layer 2, layer 3 */
2465   }
2466 };
2467 
2468 
2469 /*
2470  * mp3_read_lame_tag - read the data from the lame tag (if it exists)
2471  *
2472  * @path: location of the file
2473  * @lt: pointer to structure to be filled
2474  */
mp3_read_lame_tag(const gchar * path,LameTag * lt)2475 gboolean mp3_read_lame_tag (const gchar *path, LameTag *lt)
2476 {
2477     MP3Info *mp3i = NULL;
2478     MP3Header h;
2479     guint32 flags, peak_amplitude;
2480     gint toskip = 0;
2481     FILE *file;
2482     guchar ubuf[LAME_TAG_SIZE];
2483     gint sideinfo;
2484     guchar full_info_tag[INFO_TAG_CRC_SIZE];
2485 
2486     g_return_val_if_fail (path, FALSE);
2487 
2488     /* Attempt to open the file */
2489     file = fopen (path, "r");
2490     if (!file)
2491 	goto lt_fail;
2492 
2493     mp3i = g_malloc0 (sizeof (MP3Info));
2494     mp3i->filename = path;
2495     mp3i->file = file;
2496     get_mp3_info (mp3i);
2497 
2498     /* use get_first_header() to seek to the first mp3 header */
2499     get_first_header (mp3i, 0);
2500 
2501     if (fread (full_info_tag, 1, INFO_TAG_CRC_SIZE, mp3i->file) != INFO_TAG_CRC_SIZE)
2502 	goto lt_fail;
2503     fseek(mp3i->file, -INFO_TAG_CRC_SIZE, SEEK_CUR);
2504 
2505     if (!get_header (mp3i->file, &h))
2506 	goto lt_fail;
2507 
2508     /* Determine offset of Xing header based on sideinfo size */
2509     if (h.version & 0x1)
2510     {
2511 	sideinfo = (h.mode & 0x2) ?
2512 	    SIDEINFO_MPEG1_MONO : SIDEINFO_MPEG1_MULTI;
2513     }
2514     else
2515     {
2516 	sideinfo = (h.mode & 0x2) ?
2517 	    SIDEINFO_MPEG2_MONO : SIDEINFO_MPEG2_MULTI;
2518     }
2519 
2520     if (fseek (mp3i->file, sideinfo, SEEK_CUR) ||
2521 	(fread (&ubuf[0], 1, 4, mp3i->file) != 4))
2522 	goto lt_fail;
2523 
2524     /* Is this really a Xing or Info Header?
2525      * FIXME: Apparently (according to madplay sources) there is a different
2526      * possible location for the Xing header ("due to an unfortunate
2527      * historical event"). I do not thing we need to care though since
2528      * ReplayGain information is only contained in recent files.  */
2529     if (strncmp (ubuf, "Xing", 4) && strncmp (ubuf, "Info", 4))
2530 	goto lt_fail;
2531 
2532     /* Determine the offset of the LAME tag based on contents of the Xing header */
2533     fread (ubuf, 4, 1, mp3i->file);
2534     flags = (ubuf[0] << 24) | (ubuf[1] << 16) | (ubuf[2] << 8) | ubuf[3];
2535 
2536     if (flags & FRAMES_FLAG)
2537     {				/* frames field is set */
2538 	toskip += 4;
2539     }
2540     if (flags & BYTES_FLAG)
2541     {				/* bytes field is set */
2542 	toskip += 4;
2543     }
2544     if (flags & TOC_FLAG)
2545     {				/* TOC field is set */
2546 	toskip += 100;
2547     }
2548     if (flags & VBR_SCALE_FLAG)
2549     {				/* quality field is set */
2550 	toskip += 4;
2551     }
2552 
2553     /* Check for LAME Tag */
2554     if (fseek (mp3i->file, toskip, SEEK_CUR) || (fread (ubuf, 1, LAME_TAG_SIZE, mp3i->file) != LAME_TAG_SIZE))
2555 	goto lt_fail;
2556     if (strncmp (ubuf, "LAME", 4))
2557     {
2558 	goto lt_fail;
2559     }
2560 
2561     strncpy(lt->encoder, &ubuf[0x0], 4);
2562 
2563     strncpy(lt->version_string, &ubuf[0x4], 5);
2564 
2565     lt->info_tag_revision = (ubuf[0x9] >> 4);
2566     lt->vbr_method = (ubuf[0x9] & 0xf);
2567     lt->lowpass = ubuf[0xa];
2568 
2569 
2570     /* convert BE float */
2571     peak_amplitude = (ubuf[0xb] << 24) | (ubuf[0xc] << 16) | (ubuf[0xd] << 8) | ubuf[0xe];
2572     memcpy(&lt->peak_signal_amplitude, &peak_amplitude, 4);
2573     memcpy(&lt->radio_replay_gain, &ubuf[0xf], 2);
2574     memcpy(&lt->audiophile_replay_gain, &ubuf[0x11], 2);
2575 
2576     lt->encoding_flags = ubuf[0x13] >> 4;
2577     lt->ath_type = ubuf[0x13] & 0xf;
2578 
2579     lt->bitrate = ubuf[0x14];
2580 
2581     lt->delay = (ubuf[0x15] << 4) + (ubuf[0x16] >> 4);
2582     lt->padding = ((ubuf[0x16] & 0xf) << 8) + ubuf[0x17];
2583 
2584     lt->noise_shaping = ubuf[0x18] & 0x3;
2585     lt->stereo_mode = (ubuf[0x18] >> 2) & 0x7;
2586     lt->unwise_settings = (ubuf[0x18] >> 5) & 0x1;
2587     lt->source_sample_frequency = (ubuf[0x18] >> 6) & 0x3;
2588 
2589     lt->mp3_gain = ubuf[0x19];
2590 
2591     lt->surround_info = (ubuf[0x1a] >> 3) & 0x7;
2592     lt->preset = ((ubuf[0x1a] & 0x7) << 8) + ubuf[0x1b];
2593 
2594     lt->music_length = parse_lame_uint32(&ubuf[0x1c]);
2595 
2596     lt->music_crc = parse_lame_uint16(&ubuf[0x20]);
2597     lt->info_tag_crc = parse_lame_uint16(&ubuf[0x22]);
2598 
2599     lt->calculated_info_tag_crc = crc_compute(full_info_tag, INFO_TAG_CRC_SIZE, 0x0000);
2600 
2601     fclose(file);
2602     g_free (mp3i);
2603     return (lt->calculated_info_tag_crc == lt->info_tag_crc);
2604 
2605   lt_fail:
2606     if (file)
2607 	fclose(file);
2608     g_free (mp3i);
2609     return FALSE;
2610 
2611 }
2612 
2613 
2614 /*
2615  * mp3_get_track_gapless - read the specified file and calculate gapless
2616  * information: totalsamples and gapless_data
2617  *
2618  * @mp3i: MP3Info of the file; should already have run get_mp3_info() on it
2619  * @gd: structure holding gapless information; should have pregap and
2620  * 	postgap already filled
2621  */
2622 
mp3_get_track_gapless(MP3Info * mp3i,GaplessData * gd)2623 gboolean mp3_get_track_gapless (MP3Info *mp3i, GaplessData *gd)
2624 {
2625     int i;
2626     int xing_header_offset;
2627     int mysamplesperframe;
2628     int totaldatasize;
2629     int lastframes[8];
2630     int totalframes;
2631     int finaleight;
2632     int l;
2633 
2634     g_return_val_if_fail (mp3i, FALSE);
2635     g_return_val_if_fail (gd, FALSE);
2636 
2637     /* use get_first_header() to seek to the first mp3 header */
2638     get_first_header (mp3i, 0);
2639 
2640     xing_header_offset = ftell (mp3i->file);
2641 
2642     get_header(mp3i->file, &(mp3i->header));
2643 
2644     mysamplesperframe = samplesperframe[mp3i->header.version & 1][3 - mp3i->header.layer];
2645 
2646     /* jump to the end of the frame with the xing header */
2647     if (fseek (mp3i->file, xing_header_offset + frame_length (&(mp3i->header)), SEEK_SET))
2648 	goto gp_fail;
2649 
2650     /* counts bytes from the start of the 1st sync frame */
2651     totaldatasize = frame_length (&(mp3i->header));
2652 
2653     /* lastframes keeps track of the last 8 frame sizes */
2654 
2655     /* counts number of music frames */
2656     totalframes = 0;
2657 
2658     /* quickly parse the file, reading only frame headers */
2659     l = 0;
2660     while ((l = get_header (mp3i->file, &(mp3i->header))) != 0)
2661     {
2662 	lastframes[totalframes%8] = l;
2663 	totaldatasize += l;
2664 	totalframes++;
2665 
2666 	if (fseek (mp3i->file, l - FRAME_HEADER_SIZE, SEEK_CUR))
2667 	    goto gp_fail;
2668     }
2669 
2670     finaleight = 0;
2671     for (i = 0; i < 8; i++)
2672     {
2673 	finaleight += lastframes[i];
2674     }
2675 
2676     /* For some reason, iTunes appears to add an extra frames worth of
2677      * samples to the samplecount for CBR files.  CBR files don't currently
2678      * (2 Jul 07) play gaplessly whether uploaded from iTunes or gtkpod,
2679      * even with apparently correct values, but we will attempt to emulate
2680      * iTunes' behavior */
2681     if (mp3i->vbr == 0) // CBR
2682 	totalframes++;
2683 
2684     /* all but last eight frames */
2685     gd->gapless_data = totaldatasize - finaleight;
2686     /* total samples minus pre/postgap */
2687     gd->samplecount = totalframes * mysamplesperframe - gd->pregap - gd->postgap;
2688 
2689     return TRUE;
2690 
2691 
2692   gp_fail:
2693     return FALSE;
2694 
2695 }
2696 
2697 
2698 /**
2699  * mp3_read_gapless:
2700  *
2701  * try to read the gapless values from the LAME Tag and set
2702  * the track's pregap, postgap, samplecount, and gapless_data fields
2703  * accordingly.
2704  *
2705  * @path: location of the file
2706  * @track: structure holding track information
2707  *
2708  * The function always rereads the data from the file.
2709  *
2710  * Returns TRUE if all four gapless fields could be
2711  * set. etrack->tchanged is set to TRUE if data has been changed,
2712  * FALSE otherwise.
2713  */
2714 
mp3_read_gapless(const gchar * path,Track * track)2715 gboolean mp3_read_gapless (const gchar *path, Track *track) {
2716     MP3Info *mp3i=NULL;
2717     FILE *file;
2718 
2719     GaplessData gd;
2720     ExtraTrackData *etr;
2721 
2722     g_return_val_if_fail (track, FALSE);
2723 
2724     etr = track->userdata;
2725 
2726     g_return_val_if_fail (etr, FALSE);
2727 
2728     memset (&gd, 0, sizeof (GaplessData));
2729 
2730 
2731     g_return_val_if_fail (path, FALSE);
2732 
2733     /* Attempt to open the file */
2734     file = fopen (path, "r");
2735     if (file)
2736     {
2737 	mp3i = g_malloc0 (sizeof (MP3Info));
2738 	mp3i->filename = path;
2739 	mp3i->file = file;
2740 	get_mp3_info (mp3i);
2741 
2742 	/* Try the LAME tag for pregap and postgap */
2743 	LameTag lt;
2744 	if (mp3_read_lame_tag (path, &lt)) {
2745 	    gd.pregap = lt.delay;
2746 	    gd.postgap = lt.padding;
2747 	} else {
2748 	    /* insert non-LAME methods of finding pregap and postgap */
2749 	    fclose(file);
2750 	    g_free (mp3i);
2751 	    return FALSE;
2752 	}
2753 
2754 	mp3_get_track_gapless (mp3i, &gd);
2755 
2756 	etr->tchanged = FALSE;
2757 
2758 	if ((gd.pregap) && (gd.samplecount) && (gd.postgap) && (gd.gapless_data))
2759 	{
2760 	    if ((track->pregap != gd.pregap) ||
2761 		(track->samplecount != gd.samplecount) ||
2762 		(track->postgap != gd.postgap) ||
2763 		(track->gapless_data != gd.gapless_data) ||
2764 		(track->gapless_track_flag == FALSE))
2765 	    {
2766 		etr->tchanged = TRUE;
2767 		track->pregap = gd.pregap;
2768 		track->samplecount = gd.samplecount;
2769 		track->postgap = gd.postgap;
2770 		track->gapless_data = gd.gapless_data;
2771 		track->gapless_track_flag = TRUE;
2772 	    }
2773 	}
2774 	else
2775 	{   /* remove gapless data which doesn't seem to be valid any
2776 	     * more */
2777 	    if (track->gapless_track_flag == TRUE)
2778 	    {
2779 		etr->tchanged = TRUE;
2780 	    }
2781 	    track->pregap = 0;
2782 	    track->samplecount = 0;
2783 	    track->postgap = 0;
2784 	    track->gapless_data = 0;
2785 	    track->gapless_track_flag = FALSE;
2786 	}
2787 
2788 	fclose(file);
2789 	g_free (mp3i);
2790 	return TRUE;
2791     }
2792     return FALSE;
2793 }
2794 
2795 
2796 /* Read ID3 tags of filename @name into track structure @track */
2797 /* Return value: TRUE if tags could be read, FALSE if an error
2798    occured */
id3_read_tags(const gchar * name,Track * track)2799 gboolean id3_read_tags (const gchar *name, Track *track)
2800 {
2801     File_Tag filetag;
2802 
2803     g_return_val_if_fail (name && track, FALSE);
2804 
2805     if (id3_tag_read (name, &filetag))
2806     {
2807 	guchar *image_data = NULL;
2808 	gsize image_data_len = 0;
2809 
2810 	if (filetag.album)
2811 	{
2812 	    track->album = filetag.album;
2813 	}
2814 
2815 	if (filetag.artist)
2816 	{
2817 	    track->artist = filetag.artist;
2818 	}
2819 
2820 	if (filetag.albumartist)
2821 	{
2822 	    track->albumartist = filetag.albumartist;
2823 	}
2824 
2825 	if (filetag.title)
2826 	{
2827 	    track->title = filetag.title;
2828 	}
2829 
2830 	if (filetag.genre)
2831 	{
2832 	    track->genre = filetag.genre;
2833 	}
2834 
2835 	if (filetag.composer)
2836 	{
2837 	    track->composer = filetag.composer;
2838 	}
2839 
2840 	if (filetag.comment)
2841 	{
2842 	    track->comment = filetag.comment;
2843 	}
2844 
2845 	if (filetag.podcasturl)
2846 	{
2847 	    track->podcasturl = filetag.podcasturl;
2848 	}
2849 
2850 	if (filetag.podcastrss)
2851 	{
2852 	    track->podcastrss = filetag.podcastrss;
2853 	}
2854 
2855 	if (filetag.subtitle)
2856 	{
2857 	    track->subtitle = filetag.subtitle;
2858 	}
2859 
2860 	if (filetag.description)
2861 	{
2862 	    track->description = filetag.description;
2863 	}
2864 
2865 	if (filetag.sort_artist)
2866 	{
2867 	    track->sort_artist = filetag.sort_artist;
2868 	}
2869 
2870 	if (filetag.sort_title)
2871 	{
2872 	    track->sort_title = filetag.sort_title;
2873 	}
2874 
2875 	if (filetag.sort_album)
2876 	{
2877 	    track->sort_album = filetag.sort_album;
2878 	}
2879 
2880 	if (filetag.sort_albumartist)
2881 	{
2882 	    track->sort_albumartist = filetag.sort_albumartist;
2883 	}
2884 
2885 	if (filetag.sort_composer)
2886 	{
2887 	    track->sort_composer = filetag.sort_composer;
2888 	}
2889 
2890 	if (filetag.year == NULL)
2891 	{
2892 	    track->year = 0;
2893 	}
2894 	else
2895 	{
2896 	    track->year = atoi(filetag.year);
2897 	    g_free (filetag.year);
2898 	}
2899 
2900 	if (filetag.trackstring == NULL)
2901 	{
2902 	    track->track_nr = 0;
2903 	}
2904 	else
2905 	{
2906 	    track->track_nr = atoi(filetag.trackstring);
2907 	    g_free (filetag.trackstring);
2908 	}
2909 
2910 	if (filetag.track_total == NULL)
2911 	{
2912 	    track->tracks = 0;
2913 	}
2914 	else
2915 	{
2916 	    track->tracks = atoi(filetag.track_total);
2917 	    g_free (filetag.track_total);
2918 	}
2919 	/* CD/disc number handling */
2920 	if (filetag.cdnostring == NULL)
2921 	{
2922 	    track->cd_nr = 0;
2923 	}
2924 	else
2925 	{
2926 	    track->cd_nr = atoi(filetag.cdnostring);
2927 	    g_free (filetag.cdnostring);
2928 	}
2929 
2930 	if (filetag.cdno_total == NULL)
2931 	{
2932 	    track->cds = 0;
2933 	}
2934 	else
2935 	{
2936 	    track->cds = atoi(filetag.cdno_total);
2937 	    g_free (filetag.cdno_total);
2938 	}
2939 
2940 	if (filetag.compilation == NULL)
2941 	{
2942 	    track->compilation = 0;
2943 	}
2944 	else
2945 	{
2946 	    track->compilation = atoi(filetag.compilation);
2947 	    g_free (filetag.compilation);
2948 	}
2949 
2950 	if (filetag.BPM == NULL)
2951 	{
2952 	    track->BPM = 0;
2953 	}
2954 	else
2955 	{
2956 	    track->BPM = atoi(filetag.BPM);
2957 	    g_free (filetag.BPM);
2958 	}
2959 
2960 	if (filetag.lyrics)
2961 	{
2962 	    track->lyrics_flag = 0x01;
2963 	    g_free (filetag.lyrics);
2964 	}
2965 	else
2966 	{
2967 	    track->lyrics_flag = 0x00;
2968 	}
2969 
2970 	if (prefs_get_int("coverart_apic") &&
2971 	    (id3_apic_read (name, &image_data, &image_data_len) == TRUE))
2972 	{
2973 	    if (image_data)
2974 	    {
2975 		gp_track_set_thumbnails_from_data (track,
2976 						   image_data,
2977 						   image_data_len);
2978 		g_free (image_data);
2979 	    }
2980 	}
2981 	return TRUE;
2982     }
2983     return FALSE;
2984 }
2985 
2986 
2987 /* ----------------------------------------------------------------------
2988 
2989 	      From here starts original gtkpod code
2990 
2991 ---------------------------------------------------------------------- */
2992 
2993 /* Return a Track structure with all information read from the mp3
2994    file filled in */
mp3_get_file_info(const gchar * name)2995 Track *mp3_get_file_info (const gchar *name)
2996 {
2997     Track *track = NULL;
2998     MP3Info *mp3i=NULL;
2999     FILE *file;
3000 
3001     g_return_val_if_fail (name, NULL);
3002 
3003     /* Attempt to open the file */
3004     file = fopen (name, "r");
3005     if (file)
3006     {
3007 	mp3i = g_malloc0 (sizeof (MP3Info));
3008 	mp3i->filename = name;
3009 	mp3i->file = file;
3010 	get_mp3_info (mp3i);
3011 	mp3i->file = NULL;
3012 	fclose (file);
3013     }
3014     else
3015     {
3016 	gchar *fbuf = charset_to_utf8 (name);
3017     	gtkpod_warning(_("ERROR while opening file: '%s' (%s).\n"),
3018 		       fbuf, g_strerror(errno));
3019 	g_free (fbuf);
3020 	return NULL;
3021     }
3022 
3023     track = gp_track_new ();
3024     track->filetype = g_strdup ("MPEG audio file");
3025 
3026     if (prefs_get_int("readtags"))
3027     {
3028 	id3_read_tags (name, track);
3029     }
3030 
3031     mp3_read_soundcheck (name, track);
3032 
3033     mp3_read_gapless (name, track);
3034 
3035     /* Get additional info (play time and bitrate */
3036     if (mp3i)
3037     {
3038 	track->tracklen = mp3i->milliseconds;
3039 	track->bitrate = (gint)(mp3i->vbr_average);
3040  	track->samplerate = mp3file_header_frequency (&mp3i->header);
3041 	g_free (mp3i);
3042     }
3043     /* Fall back to xmms code if tracklen is 0 */
3044     if (track->tracklen == 0)
3045     {
3046 	track->tracklen = get_track_time (name);
3047 	if (track->tracklen)
3048 	    track->bitrate = (float)track->size*8/track->tracklen;
3049     }
3050 
3051     if (track->tracklen == 0)
3052     {
3053 	/* Tracks with zero play length are ignored by iPod... */
3054 	gtkpod_warning (_("File \"%s\" has zero play length. Ignoring.\n"),
3055 			name);
3056 	gp_track_free (track);
3057 	track = NULL;
3058     }
3059     return track;
3060 }
3061 /*
3062  *
3063  * @returns: TRUE on success, else FALSE.
3064  */
id3_lyrics_read(const gchar * filename,gchar ** lyrics)3065 gboolean id3_lyrics_read (const gchar *filename,gchar **lyrics)
3066 {
3067     struct id3_file *id3file;
3068     struct id3_tag *id3tag;
3069 
3070     g_return_val_if_fail (filename, FALSE);
3071     g_return_val_if_fail (lyrics, FALSE);
3072 
3073     if (!(id3file = id3_file_open (filename, ID3_FILE_MODE_READONLY)))
3074     {
3075 	gchar *fbuf = charset_to_utf8 (filename);
3076 	g_print(_("ERROR while opening file: '%s' (%s).\n"),
3077 		fbuf, g_strerror(errno));
3078 	g_free (fbuf);
3079 	return FALSE;
3080     }
3081 
3082     if ((id3tag = id3_file_tag(id3file)))
3083     {
3084 	*lyrics = id3_get_string (id3tag, "USLT");
3085     }
3086 
3087     id3_file_close (id3file);
3088     return TRUE;
3089 }
3090 
id3_lyrics_save(const gchar * filename,const gchar * lyrics)3091 gboolean id3_lyrics_save (const gchar *filename,const gchar *lyrics)
3092 {
3093     struct id3_file *id3file;
3094     struct id3_tag *id3tag;
3095 
3096     g_return_val_if_fail (filename, FALSE);
3097 
3098 
3099     id3file = id3_file_open (filename, ID3_FILE_MODE_READWRITE);
3100     if (!id3file)
3101     {
3102 	gchar *fbuf = charset_to_utf8 (filename);
3103 	g_print(_("ERROR while opening file: '%s' (%s).\n"),
3104 		fbuf, g_strerror(errno));
3105 	g_free (fbuf);
3106 	return FALSE;
3107     }
3108 
3109     if ((id3tag = id3_file_tag(id3file)))
3110     {
3111 	enum id3_field_textencoding encoding;
3112 
3113 	/* actually the iPod only understands UTF8 lyrics, but for
3114 	   consistency's sake we'll do the same as for the other tags
3115 	*/
3116 	/* use the same coding as before... */
3117 	encoding = get_encoding (id3tag);
3118 	/* ...unless it's ISO_8859_1 and prefs say we should use
3119 	   unicode (i.e. ID3v2.4) */
3120 	if (prefs_get_int("id3_write_id3v24") &&
3121 	    (encoding == ID3_FIELD_TEXTENCODING_ISO_8859_1))
3122 	    encoding = ID3_FIELD_TEXTENCODING_UTF_8;
3123 
3124 	/* always render id3v1 to prevent dj studio from crashing */
3125 	id3_tag_options(id3tag, ID3_TAG_OPTION_ID3V1, ~0);
3126 
3127         /* turn off frame compression and crc information to let
3128 	   itunes read tags see
3129 	   http://www.mars.org/mailman/public/mad-dev/2002-October/000742.html
3130 	*/
3131 	id3_tag_options(id3tag, ID3_TAG_OPTION_COMPRESSION, 0);
3132 	id3_tag_options(id3tag, ID3_TAG_OPTION_CRC, 0);
3133 
3134 	id3_set_string (id3tag, "USLT", lyrics, encoding);
3135     }
3136 
3137     if (id3_file_update(id3file) != 0)
3138     {
3139 	gchar *fbuf = charset_to_utf8 (filename);
3140 	g_print(_("ERROR while writing tag to file: '%s' (%s).\n"),
3141 		fbuf, g_strerror(errno));
3142 	g_free (fbuf);
3143 	return FALSE;
3144     }
3145 
3146     id3_file_close (id3file);
3147 
3148     return TRUE;
3149 }
3150