libcfe  0.12.1
some useful C-functions
mp3tech.c
Go to the documentation of this file.
1 /*
2  mp3tech.c - Functions for handling MP3 files and most MP3 data
3  structure manipulation.
4 
5  Copyright (C) 2000-2006 Cedric Tefft <cedric@phreaker.net>
6 
7  This program is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21  ***************************************************************************
22 
23  This file is based in part on:
24 
25  * MP3Info 0.5 by Ricardo Cerqueira <rmc@rccn.net>
26  * MP3Stat 0.9 by Ed Sweetman <safemode@voicenet.com> and
27  Johannes Overmann <overmann@iname.com>
28 
29 */
30 #include "config.h"
31 #include "cfe/mp3info/mp3info.h"
32 
33 
34 int layer_tab[4]= {0, 3, 2, 1};
35 
36 int frequencies[3][4] = {
37  {22050,24000,16000,50000}, /* MPEG 2.0 */
38  {44100,48000,32000,50000}, /* MPEG 1.0 */
39  {11025,12000,8000,50000} /* MPEG 2.5 */
40 };
41 
42 int bitrate[2][3][15] = {
43  { /* MPEG 2.0 */
44  {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256}, /* layer 1 */
45  {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160}, /* layer 2 */
46  {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160} /* layer 3 */
47 
48  },
49 
50  { /* MPEG 1.0 */
51  {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448}, /* layer 1 */
52  {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384}, /* layer 2 */
53  {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320} /* layer 3 */
54  }
55 };
56 
57 int frame_size_index[] = {24000, 72000, 72000};
58 
59 
60 char *mode_text[] = {
61  "stereo", "joint stereo", "dual channel", "mono"
62 };
63 
64 char *emphasis_text[] = {
65  "none", "50/15 microsecs", "reserved", "CCITT J 17"
66 };
67 
68 
69 int get_mp3_info(mp3info *mp3,int scantype, int fullscan_vbr)
70 {
71  int had_error = 0;
72  int frame_type[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
73  float seconds=0,total_rate=0;
74  int frames=0,frame_types=0,frames_so_far=0;
75  int l,vbr_median=-1;
76  int bitrate_val,lastrate;
77  int counter=0;
78  mp3header header;
79  struct stat filestat;
80  off_t sample_pos,data_start=0;
81 
82 
83  stat(mp3->filename,&filestat);
84  mp3->datasize=filestat.st_size;
85  get_id3(mp3);
86 
87  if(scantype == SCAN_QUICK) {
88  if(get_first_header(mp3,0L)) {
89  data_start=ftell(mp3->file);
90  lastrate=15-mp3->header.bitrate;
91  while(counter < NUM_SAMPLES) {
92  if(!lastrate) break;
93  sample_pos=(counter*(mp3->datasize/NUM_SAMPLES+1))+data_start;
94  if(get_first_header(mp3,sample_pos)) {
95  bitrate_val=15-mp3->header.bitrate;
96  } else {
97  bitrate_val=-1;
98  }
99 
100  if(bitrate_val != lastrate) {
101  mp3->vbr=1;
102  if(fullscan_vbr) {
103  counter=NUM_SAMPLES;
104  scantype=SCAN_FULL;
105  }
106  }
107  lastrate=bitrate_val;
108  counter++;
109 
110  }
111  if(!(scantype == SCAN_FULL)) {
112  int bitrate_tmp = header_bitrate(&mp3->header);
113  mp3->frames=(mp3->datasize-data_start)/(l=frame_length(&mp3->header));
114  mp3->seconds = (int)((float)(frame_length(&mp3->header)*mp3->frames)/
115  (float)(bitrate_tmp*125)+0.5);
116  mp3->vbr_average = (float)bitrate_tmp;
117  }
118  }
119 
120  }
121 
122  if(scantype == SCAN_FULL) {
123  if(get_first_header(mp3,0L)) {
124  data_start=ftell(mp3->file);
125  while((bitrate_val=get_next_header(mp3))) {
126  frame_type[15-bitrate_val]++;
127  frames++;
128  }
129  memcpy(&header,&(mp3->header),sizeof(mp3header));
130  for(counter=0;counter<15;counter++) {
131  if(frame_type[counter]) {
132  frame_types++;
133  header.bitrate=counter;
134  frames_so_far += frame_type[counter];
135  seconds += (float)(frame_length(&header)*frame_type[counter])/
136  (float)(header_bitrate(&header)*125);
137  total_rate += (float)((header_bitrate(&header))*frame_type[counter]);
138  if((vbr_median == -1) && (frames_so_far >= frames/2))
139  vbr_median=counter;
140  }
141  }
142  mp3->seconds=(int)(seconds+0.5);
143  mp3->header.bitrate=vbr_median;
144  mp3->vbr_average=total_rate/(float)frames;
145  mp3->frames=frames;
146  if(frame_types > 1) {
147  mp3->vbr=1;
148  }
149  }
150  }
151  return had_error;
152 }
153 
154 
155 int get_first_header(mp3info *mp3, long startpos)
156 {
157  int k, l=0,c;
158  mp3header h, h2;
159  long valid_start=0;
160 
161  fseek(mp3->file,startpos,SEEK_SET);
162  while (1) {
163  while((c=fgetc(mp3->file)) != 255 && (c != EOF));
164  if(c == 255) {
165  ungetc(c,mp3->file);
166  valid_start=ftell(mp3->file);
167  if((l=get_header(mp3->file,&h))) {
168  fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR);
169  for(k=1; (k < MIN_CONSEC_GOOD_FRAMES) && (mp3->datasize-ftell(mp3->file) >= FRAME_HEADER_SIZE); k++) {
170  if(!(l=get_header(mp3->file,&h2))) break;
171  if(!sameConstant(&h,&h2)) break;
172  fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR);
173  }
174  if(k == MIN_CONSEC_GOOD_FRAMES) {
175  fseek(mp3->file,valid_start,SEEK_SET);
176  memcpy(&(mp3->header),&h2,sizeof(mp3header));
177  mp3->header_isvalid=1;
178  return 1;
179  }
180  }
181  } else {
182  return 0;
183  }
184  }
185 
186  return 0;
187 }
188 
189 /* get_next_header() - read header at current position or look for
190  the next valid header if there isn't one at the current position
191 */
193 {
194  int l=0,c,skip_bytes=0;
195  mp3header h;
196 
197  while(1) {
198  while((c=fgetc(mp3->file)) != 255 && (ftell(mp3->file) < mp3->datasize)) skip_bytes++;
199  if(c == 255) {
200  ungetc(c,mp3->file);
201  if((l=get_header(mp3->file,&h))) {
202  if(skip_bytes) mp3->badframes++;
203  fseek(mp3->file,l-FRAME_HEADER_SIZE,SEEK_CUR);
204  return 15-h.bitrate;
205  } else {
206  skip_bytes += FRAME_HEADER_SIZE;
207  }
208  } else {
209  if(skip_bytes) mp3->badframes++;
210  return 0;
211  }
212  }
213  return 0;
214 }
215 
216 
217 /* Get next MP3 frame header.
218  Return codes:
219  positive value = Frame Length of this header
220  0 = No, we did not retrieve a valid frame header
221 */
222 
223 int get_header(FILE *file,mp3header *header)
224 {
225  unsigned char buffer[FRAME_HEADER_SIZE];
226  int fl;
227 
228  if(fread(&buffer,FRAME_HEADER_SIZE,1,file)<1) {
229  header->sync=0;
230  return 0;
231  }
232  header->sync=(((int)buffer[0]<<4) | ((int)(buffer[1]&0xE0)>>4));
233  if(buffer[1] & 0x10) header->version=(buffer[1] >> 3) & 1;
234  else header->version=2;
235  header->layer=(buffer[1] >> 1) & 3;
236  header->bitrate=(buffer[2] >> 4) & 0x0F;
237  if((header->sync != 0xFFE) || (header->layer != 1) || (header->bitrate == 0xF)) {
238  header->sync=0;
239  return 0;
240  }
241  header->crc=buffer[1] & 1;
242  header->freq=(buffer[2] >> 2) & 0x3;
243  header->padding=(buffer[2] >>1) & 0x1;
244  header->extension=(buffer[2]) & 0x1;
245  header->mode=(buffer[3] >> 6) & 0x3;
246  header->mode_extension=(buffer[3] >> 4) & 0x3;
247  header->copyright=(buffer[3] >> 3) & 0x1;
248  header->original=(buffer[3] >> 2) & 0x1;
249  header->emphasis=(buffer[3]) & 0x3;
250 
251  /* Final sanity checks: bitrate 1111b and frequency 11b are reserved (invalid) */
252  if (header->bitrate == 0x0F || header->freq == 0x3) {
253  return 0;
254  }
255 
256  return ((fl=frame_length(header)) >= MIN_FRAME_SIZE ? fl : 0);
257 }
258 
259 int frame_length(mp3header *header) {
260  return header->sync == 0xFFE ?
261  (frame_size_index[3-header->layer]*((header->version&1)+1)*
262  header_bitrate(header)/header_frequency(header))+
263  header->padding : 1;
264 }
265 
266 int header_layer(mp3header *h) {return layer_tab[h->layer];}
267 
269  return bitrate[h->version & 1][3-h->layer][h->bitrate];
270 }
271 
273  return frequencies[h->version][h->freq];
274 }
275 
277  return emphasis_text[h->emphasis];
278 }
279 
281  return mode_text[h->mode];
282 }
283 
285  if((*(uint*)h1) == (*(uint*)h2)) return 1;
286 
287  if((h1->version == h2->version ) &&
288  (h1->layer == h2->layer ) &&
289  (h1->crc == h2->crc ) &&
290  (h1->freq == h2->freq ) &&
291  (h1->mode == h2->mode ) &&
292  (h1->copyright == h2->copyright ) &&
293  (h1->original == h2->original ) &&
294  (h1->emphasis == h2->emphasis ))
295  return 1;
296  else return 0;
297 }
298 
299 
300 int get_id3(mp3info *mp3) {
301  int retcode=0;
302  char fbuf[4];
303 
304  if(mp3->datasize >= 128) {
305  if(fseek(mp3->file, -128, SEEK_END )) {
306  fprintf(stderr,"ERROR: Couldn't read last 128 bytes of %s!!\n",mp3->filename);
307  retcode |= 4;
308  } else {
309  fread(fbuf,1,3,mp3->file); fbuf[3] = '\0';
310  mp3->id3.genre[0]=255;
311 
312 
313  if (!strcmp((const char *)"TAG",(const char *)fbuf)) {
314 
315 
316  mp3->id3_isvalid=1;
317  mp3->datasize -= 128;
318  fseek(mp3->file, -125, SEEK_END);
319  fread(mp3->id3.title,1,30,mp3->file); mp3->id3.title[30] = '\0';
320  fread(mp3->id3.artist,1,30,mp3->file); mp3->id3.artist[30] = '\0';
321  fread(mp3->id3.album,1,30,mp3->file); mp3->id3.album[30] = '\0';
322  fread(mp3->id3.year,1,4,mp3->file); mp3->id3.year[4] = '\0';
323  fread(mp3->id3.comment,1,30,mp3->file); mp3->id3.comment[30] = '\0';
324  if(mp3->id3.comment[28] == '\0') {
325  mp3->id3.track[0] = mp3->id3.comment[29];
326  }
327  fread(mp3->id3.genre,1,1,mp3->file);
328  unpad(mp3->id3.title);
329  unpad(mp3->id3.artist);
330  unpad(mp3->id3.album);
331  unpad(mp3->id3.year);
332  unpad(mp3->id3.comment);
333  }
334  }
335  }
336  return retcode;
337 
338 }
339 
340 char *pad(char *string, int length) {
341  int l;
342 
343  l=strlen(string);
344  while(l<length) {
345  string[l] = ' ';
346  l++;
347  }
348 
349  string[l]='\0';
350  return string;
351 }
352 
353 /* Remove trailing whitespace from the end of a string */
354 
355 char *unpad(char *string) {
356  char *pos=string+strlen(string)-1;
357  while(isspace(pos[0])) (pos--)[0]=0;
358  return string;
359 }
360 
361 /*
362  * Build an ID3 tag and write it to the file
363  * Returns positive int on success, 0 on failure
364  */
365 
366 int write_tag(mp3info *mp3) {
367 
368  char buf[129];
369 
370  strcpy(buf,"TAG");
371  pad(mp3->id3.title,TEXT_FIELD_LEN);
372  strncat(buf,mp3->id3.title,TEXT_FIELD_LEN);
374  strncat(buf,mp3->id3.artist,TEXT_FIELD_LEN);
375  pad(mp3->id3.album,TEXT_FIELD_LEN);
376  strncat(buf,mp3->id3.album,TEXT_FIELD_LEN);
377  pad(mp3->id3.year,INT_FIELD_LEN);
378  strncat(buf,mp3->id3.year,INT_FIELD_LEN);
380  strncat(buf,mp3->id3.comment,TEXT_FIELD_LEN);
381  strncat(buf,(char *)&(mp3->id3.genre),1);
382  if (mp3->id3.track[0] != '\0') {
383  buf[125]='\0';
384  buf[126]=mp3->id3.track[0];
385  }
386  fseek(mp3->file,-128*mp3->id3_isvalid,SEEK_END);
387  return (int)fwrite(buf,1,128,mp3->file);
388 }
unsigned int copyright
Definition: mp3tech.h:51
off_t datasize
Definition: mp3tech.h:69
int get_id3(mp3info *mp3)
Definition: mp3tech.c:300
unsigned int padding
Definition: mp3tech.h:47
char * emphasis_text[]
Definition: mp3tech.c:64
char year[5]
Definition: mp3tech.h:60
unsigned int mode
Definition: mp3tech.h:49
unsigned int original
Definition: mp3tech.h:52
#define NUM_SAMPLES
Definition: mp3tech.h:35
unsigned int freq
Definition: mp3tech.h:46
unsigned int mode_extension
Definition: mp3tech.h:50
unsigned char genre[1]
Definition: mp3tech.h:63
char comment[31]
Definition: mp3tech.h:61
char * pad(char *string, int length)
Definition: mp3tech.c:340
char album[31]
Definition: mp3tech.h:59
unsigned int extension
Definition: mp3tech.h:48
int get_header(FILE *file, mp3header *header)
Definition: mp3tech.c:223
int bitrate[2][3][15]
Definition: mp3tech.c:42
id3tag id3
Definition: mp3tech.h:73
char * header_emphasis(mp3header *h)
Definition: mp3tech.c:276
int seconds
Definition: mp3tech.h:76
unsigned int bitrate
Definition: mp3tech.h:45
int layer_tab[4]
Definition: mp3tech.c:34
int write_tag(mp3info *mp3)
Definition: mp3tech.c:366
int frequencies[3][4]
Definition: mp3tech.c:36
unsigned long sync
Definition: mp3tech.h:41
int header_bitrate(mp3header *h)
Definition: mp3tech.c:268
#define MIN_CONSEC_GOOD_FRAMES
Definition: mp3tech.h:32
unsigned int version
Definition: mp3tech.h:42
#define INT_FIELD_LEN
Definition: textfunc.h:28
char * filename
Definition: mp3tech.h:67
unsigned int crc
Definition: mp3tech.h:44
int badframes
Definition: mp3tech.h:78
int id3_isvalid
Definition: mp3tech.h:72
int header_isvalid
Definition: mp3tech.h:70
char artist[31]
Definition: mp3tech.h:58
int frames
Definition: mp3tech.h:77
mp3header header
Definition: mp3tech.h:71
unsigned char track[1]
Definition: mp3tech.h:62
char * mode_text[]
Definition: mp3tech.c:60
int header_layer(mp3header *h)
Definition: mp3tech.c:266
FILE * file
Definition: mp3tech.h:68
int get_first_header(mp3info *mp3, long startpos)
Definition: mp3tech.c:155
char title[31]
Definition: mp3tech.h:57
#define MIN_FRAME_SIZE
Definition: mp3tech.h:34
char * header_mode(mp3header *h)
Definition: mp3tech.c:280
unsigned int emphasis
Definition: mp3tech.h:53
int get_mp3_info(mp3info *mp3, int scantype, int fullscan_vbr)
Definition: mp3tech.c:69
int get_next_header(mp3info *mp3)
Definition: mp3tech.c:192
char * unpad(char *string)
Definition: mp3tech.c:355
#define TEXT_FIELD_LEN
Definition: textfunc.h:27
unsigned int layer
Definition: mp3tech.h:43
int frame_length(mp3header *header)
Definition: mp3tech.c:259
float vbr_average
Definition: mp3tech.h:75
int header_frequency(mp3header *h)
Definition: mp3tech.c:272
int sameConstant(mp3header *h1, mp3header *h2)
Definition: mp3tech.c:284
int frame_size_index[]
Definition: mp3tech.c:57
int vbr
Definition: mp3tech.h:74
#define FRAME_HEADER_SIZE
Definition: mp3tech.h:33