VbrTag.c 15 KB

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