1 /*
2 * Xing VBR tagging for LAME.
3 *
4 * Copyright (c) 1999 A.L. Faber
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22 /* $Id: VbrTag.c,v 1.20 2001/02/27 09:59:16 robert Exp $ */
23
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
27
28 #include "machine.h"
29 #if defined(__riscos__) && defined(FPA10)
30 #include "ymath.h"
31 #else
32 #include <math.h>
33 #endif
34 #include "VbrTag.h"
35 #include "version.h"
36 #include "bitstream.h"
37 #include "VbrTag.h"
38 #include <assert.h>
39
40 #ifdef WITH_DMALLOC
41 #include <dmalloc.h>
42 #endif
43
44
45 #ifdef _DEBUG
46 /* #define DEBUG_VBRTAG */
47 #endif
48
49 /*
50 // 4 bytes for Header Tag
51 // 4 bytes for Header Flags
52 // 100 bytes for entry (NUMTOCENTRIES)
53 // 4 bytes for FRAME SIZE
54 // 4 bytes for STREAM_SIZE
55 // 4 bytes for VBR SCALE. a VBR quality indicator: 0=best 100=worst
56 // 20 bytes for LAME tag. for example, "LAME3.12 (beta 6)"
57 // ___________
58 // 140 bytes
59 */
60 #define VBRHEADERSIZE (NUMTOCENTRIES+4+4+4+4+4)
61
62 /* the size of the Xing header (MPEG1 and MPEG2) in kbps */
63 #define XING_BITRATE1 128
64 #define XING_BITRATE2 64
65 #define XING_BITRATE25 32
66
67
68
69 const static char VBRTag[]={"Xing"};
70 const int SizeOfEmptyFrame[2][2]=
71 {
72 {17,9},
73 {32,17},
74 };
75
76
77 /***********************************************************************
78 * Robert Hegemann 2001-01-17
79 ***********************************************************************/
80
addVbr(VBR_seek_info_t * v,int bitrate)81 void addVbr(VBR_seek_info_t * v, int bitrate)
82 {
83 int i;
84
85 v->sum += bitrate;
86 v->seen ++;
87
88 if (v->seen < v->want) {
89 return;
90 }
91
92 if (v->pos < v->size) {
93 v->bag[v->pos] = v->sum;
94 v->pos ++;
95 v->seen = 0;
96 }
97 if (v->pos == v->size) {
98 for (i = 1; i < v->size; i += 2) {
99 v->bag[i/2] = v->bag[i];
100 }
101 v->want *= 2;
102 v->pos /= 2;
103 }
104 }
105
Xing_seek_table(VBR_seek_info_t * v,unsigned char * t)106 void Xing_seek_table(VBR_seek_info_t * v, unsigned char *t)
107 {
108 int i, index;
109 int seek_point;
110
111 if (v->pos <= 0)
112 return;
113
114 for (i = 1; i < NUMTOCENTRIES; ++i) {
115 float j = i/(float)NUMTOCENTRIES, act, sum;
116 index = (int)(floor(j * v->pos));
117 if (index > v->pos-1)
118 index = v->pos-1;
119 act = v->bag[index];
120 sum = v->sum;
121 seek_point = (int)(256. * act / sum);
122 if (seek_point > 255)
123 seek_point = 255;
124 t[i] = seek_point;
125 }
126 }
127
128 #if 0
129 void print_seeking(unsigned char *t)
130 {
131 int i;
132
133 printf("seeking table ");
134 for (i = 0; i < NUMTOCENTRIES; ++i) {
135 printf(" %d ", t[i]);
136 }
137 printf("\n");
138 }
139 #endif
140
141
142
143 /****************************************************************************
144 * AddVbrFrame: Add VBR entry, used to fill the VBR the TOC entries
145 * Paramters:
146 * nStreamPos: how many bytes did we write to the bitstream so far
147 * (in Bytes NOT Bits)
148 ****************************************************************************
149 */
AddVbrFrame(lame_global_flags * gfp)150 void AddVbrFrame(lame_global_flags *gfp)
151 {
152 lame_internal_flags *gfc = gfp->internal_flags;
153
154 int kbps = bitrate_table[gfp->version][gfc->bitrate_index];
155
156 if (gfc->VBR_seek_table.bag == NULL) {
157 gfc->VBR_seek_table.sum = 0;
158 gfc->VBR_seek_table.seen = 0;
159 gfc->VBR_seek_table.want = 1;
160 gfc->VBR_seek_table.pos = 0;
161 gfc->VBR_seek_table.bag = malloc (400*sizeof(int));
162 if (gfc->VBR_seek_table.bag != NULL) {
163 gfc->VBR_seek_table.size = 400;
164 }
165 else {
166 gfc->VBR_seek_table.size = 0;
167 ERRORF (gfc,"Error: can't allocate VbrFrames buffer\n");
168 return;
169 }
170 }
171 addVbr(&gfc->VBR_seek_table, kbps);
172 gfp->nVbrNumFrames++;
173 }
174
175
176 /*-------------------------------------------------------------*/
ExtractI4(unsigned char * buf)177 static int ExtractI4(unsigned char *buf)
178 {
179 int x;
180 /* big endian extract */
181 x = buf[0];
182 x <<= 8;
183 x |= buf[1];
184 x <<= 8;
185 x |= buf[2];
186 x <<= 8;
187 x |= buf[3];
188 return x;
189 }
190
CreateI4(unsigned char * buf,int nValue)191 void CreateI4(unsigned char *buf, int nValue)
192 {
193 /* big endian create */
194 buf[0]=(nValue>>24)&0xff;
195 buf[1]=(nValue>>16)&0xff;
196 buf[2]=(nValue>> 8)&0xff;
197 buf[3]=(nValue )&0xff;
198 }
199
200
201 /*-------------------------------------------------------------*/
202 /* Same as GetVbrTag below, but only checks for the Xing tag.
203 requires buf to contain only 40 bytes */
204 /*-------------------------------------------------------------*/
CheckVbrTag(unsigned char * buf)205 int CheckVbrTag(unsigned char *buf)
206 {
207 int h_id, h_mode, h_sr_index;
208
209 /* get selected MPEG header data */
210 h_id = (buf[1] >> 3) & 1;
211 h_sr_index = (buf[2] >> 2) & 3;
212 h_mode = (buf[3] >> 6) & 3;
213
214 /* determine offset of header */
215 if( h_id )
216 {
217 /* mpeg1 */
218 if( h_mode != 3 ) buf+=(32+4);
219 else buf+=(17+4);
220 }
221 else
222 {
223 /* mpeg2 */
224 if( h_mode != 3 ) buf+=(17+4);
225 else buf+=(9+4);
226 }
227
228 if( buf[0] != VBRTag[0] ) return 0; /* fail */
229 if( buf[1] != VBRTag[1] ) return 0; /* header not found*/
230 if( buf[2] != VBRTag[2] ) return 0;
231 if( buf[3] != VBRTag[3] ) return 0;
232 return 1;
233 }
234
GetVbrTag(VBRTAGDATA * pTagData,unsigned char * buf)235 int GetVbrTag(VBRTAGDATA *pTagData, unsigned char *buf)
236 {
237 int i, head_flags;
238 int h_bitrate,h_id, h_mode, h_sr_index;
239
240 /* get Vbr header data */
241 pTagData->flags = 0;
242
243 /* get selected MPEG header data */
244 h_id = (buf[1] >> 3) & 1;
245 h_sr_index = (buf[2] >> 2) & 3;
246 h_mode = (buf[3] >> 6) & 3;
247 h_bitrate = ((buf[2]>>4)&0xf);
248 h_bitrate = bitrate_table[h_id][h_bitrate];
249
250
251 /* determine offset of header */
252 if( h_id )
253 {
254 /* mpeg1 */
255 if( h_mode != 3 ) buf+=(32+4);
256 else buf+=(17+4);
257 }
258 else
259 {
260 /* mpeg2 */
261 if( h_mode != 3 ) buf+=(17+4);
262 else buf+=(9+4);
263 }
264
265 if( buf[0] != VBRTag[0] ) return 0; /* fail */
266 if( buf[1] != VBRTag[1] ) return 0; /* header not found*/
267 if( buf[2] != VBRTag[2] ) return 0;
268 if( buf[3] != VBRTag[3] ) return 0;
269
270 buf+=4;
271
272 pTagData->h_id = h_id;
273 pTagData->samprate = samplerate_table[h_id][h_sr_index];
274
275 if( h_id == 0 )
276 pTagData->samprate >>= 1;
277
278 head_flags = pTagData->flags = ExtractI4(buf); buf+=4; /* get flags */
279
280 if( head_flags & FRAMES_FLAG )
281 {
282 pTagData->frames = ExtractI4(buf); buf+=4;
283 }
284
285 if( head_flags & BYTES_FLAG )
286 {
287 pTagData->bytes = ExtractI4(buf); buf+=4;
288 }
289
290 if( head_flags & TOC_FLAG )
291 {
292 if( pTagData->toc != NULL )
293 {
294 for(i=0;i<NUMTOCENTRIES;i++)
295 pTagData->toc[i] = buf[i];
296 }
297 buf+=NUMTOCENTRIES;
298 }
299
300 pTagData->vbr_scale = -1;
301
302 if( head_flags & VBR_SCALE_FLAG )
303 {
304 pTagData->vbr_scale = ExtractI4(buf); buf+=4;
305 }
306
307 pTagData->headersize =
308 ((h_id+1)*72000*h_bitrate) / pTagData->samprate;
309
310
311 #ifdef DEBUG_VBRTAG
312 DEBUGF("\n\n********************* VBR TAG INFO *****************\n");
313 DEBUGF("tag :%s\n",VBRTag);
314 DEBUGF("head_flags :%d\n",head_flags);
315 DEBUGF("bytes :%d\n",pTagData->bytes);
316 DEBUGF("frames :%d\n",pTagData->frames);
317 DEBUGF("VBR Scale :%d\n",pTagData->vbr_scale);
318 DEBUGF("toc:\n");
319 if( pTagData->toc != NULL )
320 {
321 for(i=0;i<NUMTOCENTRIES;i++)
322 {
323 if( (i%10) == 0 ) DEBUGF("\n");
324 DEBUGF(" %3d", (int)(pTagData->toc[i]));
325 }
326 }
327 DEBUGF("\n***************** END OF VBR TAG INFO ***************\n");
328 #endif
329 return 1; /* success */
330 }
331
332
333 /****************************************************************************
334 * InitVbrTag: Initializes the header, and write empty frame to stream
335 * Paramters:
336 * fpStream: pointer to output file stream
337 * nMode : Channel Mode: 0=STEREO 1=JS 2=DS 3=MONO
338 ****************************************************************************
339 */
InitVbrTag(lame_global_flags * gfp)340 int InitVbrTag(lame_global_flags *gfp)
341 {
342 int nMode,SampIndex;
343 lame_internal_flags *gfc = gfp->internal_flags;
344 #define MAXFRAMESIZE 576
345 // u_char pbtStreamBuffer[MAXFRAMESIZE];
346 nMode = gfp->mode;
347 SampIndex = gfc->samplerate_index;
348
349
350 /* Clear Frame position array variables */
351 gfp->pVbrFrames=NULL;
352 gfp->nVbrNumFrames=0;
353 gfp->nVbrFrameBufferSize=0;
354
355
356 /* Clear stream buffer */
357 // memset(pbtStreamBuffer,0x00,sizeof(pbtStreamBuffer));
358
359
360
361 /* Reserve the proper amount of bytes */
362 if (nMode==3)
363 {
364 gfp->nZeroStreamSize=SizeOfEmptyFrame[gfp->version][1]+4;
365 }
366 else
367 {
368 gfp->nZeroStreamSize=SizeOfEmptyFrame[gfp->version][0]+4;
369 }
370
371 /*
372 // Xing VBR pretends to be a 48kbs layer III frame. (at 44.1kHz).
373 // (at 48kHz they use 56kbs since 48kbs frame not big enough for
374 // table of contents)
375 // let's always embed Xing header inside a 64kbs layer III frame.
376 // this gives us enough room for a LAME version string too.
377 // size determined by sampling frequency (MPEG1)
378 // 32kHz: 216 bytes@48kbs 288bytes@ 64kbs
379 // 44.1kHz: 156 bytes 208bytes@64kbs (+1 if padding = 1)
380 // 48kHz: 144 bytes 192
381 //
382 // MPEG 2 values are the same since the framesize and samplerate
383 // are each reduced by a factor of 2.
384 */
385 {
386 int i,bitrate,tot;
387 if (1==gfp->version) {
388 bitrate = XING_BITRATE1;
389 } else {
390 if (gfp->out_samplerate < 16000 )
391 bitrate = XING_BITRATE25;
392 else
393 bitrate = XING_BITRATE2;
394 }
395 gfp->TotalFrameSize=
396 ((gfp->version+1)*72000*bitrate) / gfp->out_samplerate;
397 tot = (gfp->nZeroStreamSize+VBRHEADERSIZE);
398 tot += 20; /* extra 20 bytes for LAME & version string */
399
400 assert(gfp->TotalFrameSize >= tot );
401 assert(gfp->TotalFrameSize <= MAXFRAMESIZE );
402
403 for (i=0; i<gfp->TotalFrameSize; ++i)
404 add_dummy_byte(gfp,0);
405 }
406
407 /* Success */
408 return 0;
409 }
410
411
412
413 /****************************************************************************
414 * PutVbrTag: Write final VBR tag to the file
415 * Paramters:
416 * lpszFileName: filename of MP3 bit stream
417 * nVbrScale : encoder quality indicator (0..100)
418 ****************************************************************************
419 */
PutVbrTag(lame_global_flags * gfp,FILE * fpStream,int nVbrScale)420 int PutVbrTag(lame_global_flags *gfp,FILE *fpStream,int nVbrScale)
421 {
422 lame_internal_flags * gfc = gfp->internal_flags;
423
424 long lFileSize;
425 int nStreamIndex;
426 char abyte,bbyte;
427 u_char btToc[NUMTOCENTRIES];
428 u_char pbtStreamBuffer[MAXFRAMESIZE];
429 char str1[80];
430 unsigned char id3v2Header[10];
431 size_t id3v2TagSize;
432
433 if (gfc->VBR_seek_table.pos <= 0)
434 return -1;
435
436
437 /* Clear stream buffer */
438 memset(pbtStreamBuffer,0x00,sizeof(pbtStreamBuffer));
439
440 /* Seek to end of file*/
441 fseek(fpStream,0,SEEK_END);
442
443 /* Get file size */
444 lFileSize=ftell(fpStream);
445
446 /* Abort if file has zero length. Yes, it can happen :) */
447 if (lFileSize==0)
448 return -1;
449
450 /*
451 * The VBR tag may NOT be located at the beginning of the stream.
452 * If an ID3 version 2 tag was added, then it must be skipped to write
453 * the VBR tag data.
454 */
455
456 /* seek to the beginning of the stream */
457 fseek(fpStream,0,SEEK_SET);
458 /* read 10 bytes in case there's an ID3 version 2 header here */
459 fread(id3v2Header,1,sizeof id3v2Header,fpStream);
460 /* does the stream begin with the ID3 version 2 file identifier? */
461 if (!strncmp((char *)id3v2Header,"ID3",3)) {
462 /* the tag size (minus the 10-byte header) is encoded into four
463 * bytes where the most significant bit is clear in each byte */
464 id3v2TagSize=(((id3v2Header[6] & 0x7f)<<21)
465 | ((id3v2Header[7] & 0x7f)<<14)
466 | ((id3v2Header[8] & 0x7f)<<7)
467 | (id3v2Header[9] & 0x7f))
468 + sizeof id3v2Header;
469 } else {
470 /* no ID3 version 2 tag in this stream */
471 id3v2TagSize=0;
472 }
473
474 /* Seek to first real frame */
475 fseek(fpStream,id3v2TagSize+gfp->TotalFrameSize,SEEK_SET);
476
477 /* Read the header (first valid frame) */
478 fread(pbtStreamBuffer,4,1,fpStream);
479
480 /* the default VBR header. 48 kbps layer III, no padding, no crc */
481 /* but sampling freq, mode andy copyright/copy protection taken */
482 /* from first valid frame */
483 pbtStreamBuffer[0]=(u_char) 0xff;
484 abyte = (pbtStreamBuffer[1] & (char) 0xf1);
485 { int bitrate;
486 if (1==gfp->version) {
487 bitrate = XING_BITRATE1;
488 } else {
489 if (gfp->out_samplerate < 16000 )
490 bitrate = XING_BITRATE25;
491 else
492 bitrate = XING_BITRATE2;
493 }
494 bbyte = 16*BitrateIndex(bitrate,gfp->version,gfp->out_samplerate);
495 }
496
497 /* Use as much of the info from the real frames in the
498 * Xing header: samplerate, channels, crc, etc...
499 */
500 if (gfp->version==1) {
501 /* MPEG1 */
502 pbtStreamBuffer[1]=abyte | (char) 0x0a; /* was 0x0b; */
503 abyte = pbtStreamBuffer[2] & (char) 0x0d; /* AF keep also private bit */
504 pbtStreamBuffer[2]=(char) bbyte | abyte; /* 64kbs MPEG1 frame */
505 }else{
506 /* MPEG2 */
507 pbtStreamBuffer[1]=abyte | (char) 0x02; /* was 0x03; */
508 abyte = pbtStreamBuffer[2] & (char) 0x0d; /* AF keep also private bit */
509 pbtStreamBuffer[2]=(char) bbyte | abyte; /* 64kbs MPEG2 frame */
510 }
511
512
513 /*Seek to the beginning of the stream */
514 fseek(fpStream,id3v2TagSize,SEEK_SET);
515
516 /* Clear all TOC entries */
517 memset(btToc,0,sizeof(btToc));
518
519 Xing_seek_table (&gfc->VBR_seek_table, btToc);
520 /* print_seeking (btToc); */
521
522 /* Start writing the tag after the zero frame */
523 nStreamIndex=gfp->nZeroStreamSize;
524
525 /* Put Vbr tag */
526 pbtStreamBuffer[nStreamIndex++]=VBRTag[0];
527 pbtStreamBuffer[nStreamIndex++]=VBRTag[1];
528 pbtStreamBuffer[nStreamIndex++]=VBRTag[2];
529 pbtStreamBuffer[nStreamIndex++]=VBRTag[3];
530
531 /* Put header flags */
532 CreateI4(&pbtStreamBuffer[nStreamIndex],FRAMES_FLAG+BYTES_FLAG+TOC_FLAG+VBR_SCALE_FLAG);
533 nStreamIndex+=4;
534
535 /* Put Total Number of frames */
536 CreateI4(&pbtStreamBuffer[nStreamIndex],gfp->nVbrNumFrames);
537 nStreamIndex+=4;
538
539 /* Put Total file size */
540 CreateI4(&pbtStreamBuffer[nStreamIndex],(int)lFileSize);
541 nStreamIndex+=4;
542
543 /* Put TOC */
544 memcpy(&pbtStreamBuffer[nStreamIndex],btToc,sizeof(btToc));
545 nStreamIndex+=sizeof(btToc);
546
547 /* Put VBR SCALE */
548 CreateI4(&pbtStreamBuffer[nStreamIndex],nVbrScale);
549 nStreamIndex+=4;
550
551 /* Put LAME ID */
552 sprintf ( str1, "LAME%s", get_lame_short_version () );
553 strncpy ( (char*)pbtStreamBuffer + nStreamIndex, str1, 20 );
554 nStreamIndex += 20;
555
556
557 #ifdef DEBUG_VBRTAG
558 {
559 VBRTAGDATA TestHeader;
560 GetVbrTag(&TestHeader,pbtStreamBuffer);
561 }
562 #endif
563
564 /* Put it all to disk again */
565 if (fwrite(pbtStreamBuffer,(unsigned int)gfp->TotalFrameSize,1,fpStream)!=1)
566 {
567 return -1;
568 }
569 /* Save to delete the frame buffer */
570 free(gfp->pVbrFrames);
571 gfp->pVbrFrames=NULL;
572
573 return 0; /* success */
574 }
575
576