VbrTag.c

Go to the documentation of this file.
00001 /*
00002  *      Xing VBR tagging for LAME.
00003  *
00004  *      Copyright (c) 1999 A.L. Faber
00005  *      Copyright (c) 2001 Jonathan Dee
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2 of the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the
00019  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020  * Boston, MA 02111-1307, USA.
00021  */
00022 
00023 /* $Id: VbrTag.c,v 1.90 2007/07/24 17:46:10 bouvigne Exp $ */
00024 
00025 #ifdef HAVE_CONFIG_H
00026 # include <config.h>
00027 #endif
00028 
00029 #include "lame.h"
00030 #include "machine.h"
00031 #include "encoder.h"
00032 #include "util.h"
00033 #include "bitstream.h"
00034 #include "VbrTag.h"
00035 #include "lame_global_flags.h"
00036 
00037 #ifdef __sun__
00038 /* woraround for SunOS 4.x, it has SEEK_* defined here */
00039 #include <unistd.h>
00040 #endif
00041 
00042 
00043 #ifdef _DEBUG
00044 /*  #define DEBUG_VBRTAG */
00045 #endif
00046 
00047 /*
00048  *    4 bytes for Header Tag
00049  *    4 bytes for Header Flags
00050  *  100 bytes for entry (NUMTOCENTRIES)
00051  *    4 bytes for FRAME SIZE
00052  *    4 bytes for STREAM_SIZE
00053  *    4 bytes for VBR SCALE. a VBR quality indicator: 0=best 100=worst
00054  *   20 bytes for LAME tag.  for example, "LAME3.12 (beta 6)"
00055  * ___________
00056  *  140 bytes
00057 */
00058 #define VBRHEADERSIZE (NUMTOCENTRIES+4+4+4+4+4)
00059 
00060 #define LAMEHEADERSIZE (VBRHEADERSIZE + 9 + 1 + 1 + 8 + 1 + 1 + 3 + 1 + 1 + 2 + 4 + 2 + 2)
00061 
00062 /* the size of the Xing header (MPEG1 and MPEG2) in kbps */
00063 #define XING_BITRATE1 128
00064 #define XING_BITRATE2  64
00065 #define XING_BITRATE25 32
00066 
00067 
00068 
00069 static const char VBRTag0[] = { "Xing" };
00070 static const char VBRTag1[] = { "Info" };
00071 
00072 
00073 
00074 
00075 /* Lookup table for fast CRC computation
00076  * See 'CRC_update_lookup'
00077  * Uses the polynomial x^16+x^15+x^2+1 */
00078 
00079 static const unsigned int crc16_lookup[256] = {
00080     0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
00081     0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
00082     0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
00083     0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
00084     0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
00085     0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
00086     0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
00087     0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
00088     0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
00089     0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
00090     0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
00091     0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
00092     0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
00093     0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
00094     0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
00095     0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
00096     0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
00097     0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
00098     0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
00099     0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
00100     0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
00101     0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
00102     0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
00103     0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
00104     0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
00105     0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
00106     0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
00107     0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
00108     0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
00109     0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
00110     0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
00111     0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
00112 };
00113 
00114 
00115 
00116 
00117 
00118 /***********************************************************************
00119  *  Robert Hegemann 2001-01-17
00120  ***********************************************************************/
00121 
00122 static void
00123 addVbr(VBR_seek_info_t * v, int bitrate)
00124 {
00125     int     i;
00126 
00127     v->nVbrNumFrames++;
00128     v->sum += bitrate;
00129     v->seen++;
00130 
00131     if (v->seen < v->want) {
00132         return;
00133     }
00134 
00135     if (v->pos < v->size) {
00136         v->bag[v->pos] = v->sum;
00137         v->pos++;
00138         v->seen = 0;
00139     }
00140     if (v->pos == v->size) {
00141         for (i = 1; i < v->size; i += 2) {
00142             v->bag[i / 2] = v->bag[i];
00143         }
00144         v->want *= 2;
00145         v->pos /= 2;
00146     }
00147 }
00148 
00149 static void
00150 Xing_seek_table(VBR_seek_info_t * v, unsigned char *t)
00151 {
00152     int     i, indx;
00153     int     seek_point;
00154 
00155     if (v->pos <= 0)
00156         return;
00157 
00158     for (i = 1; i < NUMTOCENTRIES; ++i) {
00159         float   j = i / (float) NUMTOCENTRIES, act, sum;
00160         indx = (int) (floor(j * v->pos));
00161         if (indx > v->pos - 1)
00162             indx = v->pos - 1;
00163         act = v->bag[indx];
00164         sum = v->sum;
00165         seek_point = (int) (256. * act / sum);
00166         if (seek_point > 255)
00167             seek_point = 255;
00168         t[i] = seek_point;
00169     }
00170 }
00171 
00172 #ifdef DEBUG_VBR_SEEKING_TABLE
00173 static void
00174 print_seeking(unsigned char *t)
00175 {
00176     int     i;
00177 
00178     printf("seeking table ");
00179     for (i = 0; i < NUMTOCENTRIES; ++i) {
00180         printf(" %d ", t[i]);
00181     }
00182     printf("\n");
00183 }
00184 #endif
00185 
00186 
00187 /****************************************************************************
00188  * AddVbrFrame: Add VBR entry, used to fill the VBR the TOC entries
00189  * Paramters:
00190  *      nStreamPos: how many bytes did we write to the bitstream so far
00191  *                              (in Bytes NOT Bits)
00192  ****************************************************************************
00193 */
00194 void
00195 AddVbrFrame(lame_global_flags * gfp)
00196 {
00197     lame_internal_flags *gfc = gfp->internal_flags;
00198 
00199     int     kbps = bitrate_table[gfp->version][gfc->bitrate_index];
00200     assert(gfc->VBR_seek_table.bag);
00201     addVbr(&gfc->VBR_seek_table, kbps);
00202 }
00203 
00204 
00205 /*-------------------------------------------------------------*/
00206 static int
00207 ExtractI4(unsigned char *buf)
00208 {
00209     int     x;
00210     /* big endian extract */
00211     x = buf[0];
00212     x <<= 8;
00213     x |= buf[1];
00214     x <<= 8;
00215     x |= buf[2];
00216     x <<= 8;
00217     x |= buf[3];
00218     return x;
00219 }
00220 
00221 static void
00222 CreateI4(unsigned char *buf, int nValue)
00223 {
00224     /* big endian create */
00225     buf[0] = (nValue >> 24) & 0xff;
00226     buf[1] = (nValue >> 16) & 0xff;
00227     buf[2] = (nValue >> 8) & 0xff;
00228     buf[3] = (nValue) & 0xff;
00229 }
00230 
00231 
00232 
00233 static void
00234 CreateI2(unsigned char *buf, int nValue)
00235 {
00236     /* big endian create */
00237     buf[0] = (nValue >> 8) & 0xff;
00238     buf[1] = (nValue) & 0xff;
00239 }
00240 
00241 /* check for magic strings*/
00242 static int
00243 IsVbrTag(const unsigned char *buf)
00244 {
00245     int     isTag0, isTag1;
00246 
00247     isTag0 = ((buf[0] == VBRTag0[0]) && (buf[1] == VBRTag0[1]) && (buf[2] == VBRTag0[2])
00248               && (buf[3] == VBRTag0[3]));
00249     isTag1 = ((buf[0] == VBRTag1[0]) && (buf[1] == VBRTag1[1]) && (buf[2] == VBRTag1[2])
00250               && (buf[3] == VBRTag1[3]));
00251 
00252     return (isTag0 || isTag1);
00253 }
00254 
00255 
00256 /*-------------------------------------------------------------*/
00257 /* Same as GetVbrTag below, but only checks for the Xing tag.
00258    requires buf to contain only 40 bytes */
00259 /*-------------------------------------------------------------*/
00260 int
00261 CheckVbrTag(unsigned char *buf)
00262 {
00263     int     h_id, h_mode, h_sr_index;
00264 
00265     /* get selected MPEG header data */
00266     h_id = (buf[1] >> 3) & 1;
00267     h_sr_index = (buf[2] >> 2) & 3;
00268     h_mode = (buf[3] >> 6) & 3;
00269 
00270     /*  determine offset of header */
00271     if (h_id) {
00272         /* mpeg1 */
00273         if (h_mode != 3)
00274             buf += (32 + 4);
00275         else
00276             buf += (17 + 4);
00277     }
00278     else {
00279         /* mpeg2 */
00280         if (h_mode != 3)
00281             buf += (17 + 4);
00282         else
00283             buf += (9 + 4);
00284     }
00285 
00286     return IsVbrTag(buf);
00287 }
00288 
00289 int
00290 GetVbrTag(VBRTAGDATA * pTagData, unsigned char *buf)
00291 {
00292     int     i, head_flags;
00293     int     h_bitrate, h_id, h_mode, h_sr_index;
00294     int     enc_delay, enc_padding;
00295 
00296     /* get Vbr header data */
00297     pTagData->flags = 0;
00298 
00299     /* get selected MPEG header data */
00300     h_id = (buf[1] >> 3) & 1;
00301     h_sr_index = (buf[2] >> 2) & 3;
00302     h_mode = (buf[3] >> 6) & 3;
00303     h_bitrate = ((buf[2] >> 4) & 0xf);
00304     h_bitrate = bitrate_table[h_id][h_bitrate];
00305 
00306     /* check for FFE syncword */
00307     if ((buf[1] >> 4) == 0xE)
00308         pTagData->samprate = samplerate_table[2][h_sr_index];
00309     else
00310         pTagData->samprate = samplerate_table[h_id][h_sr_index];
00311     /* if( h_id == 0 ) */
00312     /*  pTagData->samprate >>= 1; */
00313 
00314 
00315 
00316     /*  determine offset of header */
00317     if (h_id) {
00318         /* mpeg1 */
00319         if (h_mode != 3)
00320             buf += (32 + 4);
00321         else
00322             buf += (17 + 4);
00323     }
00324     else {
00325         /* mpeg2 */
00326         if (h_mode != 3)
00327             buf += (17 + 4);
00328         else
00329             buf += (9 + 4);
00330     }
00331 
00332     if (!IsVbrTag(buf))
00333         return 0;
00334 
00335     buf += 4;
00336 
00337     pTagData->h_id = h_id;
00338 
00339     head_flags = pTagData->flags = ExtractI4(buf);
00340     buf += 4;           /* get flags */
00341 
00342     if (head_flags & FRAMES_FLAG) {
00343         pTagData->frames = ExtractI4(buf);
00344         buf += 4;
00345     }
00346 
00347     if (head_flags & BYTES_FLAG) {
00348         pTagData->bytes = ExtractI4(buf);
00349         buf += 4;
00350     }
00351 
00352     if (head_flags & TOC_FLAG) {
00353         if (pTagData->toc != NULL) {
00354             for (i = 0; i < NUMTOCENTRIES; i++)
00355                 pTagData->toc[i] = buf[i];
00356         }
00357         buf += NUMTOCENTRIES;
00358     }
00359 
00360     pTagData->vbr_scale = -1;
00361 
00362     if (head_flags & VBR_SCALE_FLAG) {
00363         pTagData->vbr_scale = ExtractI4(buf);
00364         buf += 4;
00365     }
00366 
00367     pTagData->headersize = ((h_id + 1) * 72000 * h_bitrate) / pTagData->samprate;
00368 
00369     buf += 21;
00370     enc_delay = buf[0] << 4;
00371     enc_delay += buf[1] >> 4;
00372     enc_padding = (buf[1] & 0x0F) << 8;
00373     enc_padding += buf[2];
00374     /* check for reasonable values (this may be an old Xing header, */
00375     /* not a INFO tag) */
00376     if (enc_delay < 0 || enc_delay > 3000)
00377         enc_delay = -1;
00378     if (enc_padding < 0 || enc_padding > 3000)
00379         enc_padding = -1;
00380 
00381     pTagData->enc_delay = enc_delay;
00382     pTagData->enc_padding = enc_padding;
00383 
00384 #ifdef DEBUG_VBRTAG
00385     fprintf(stderr, "\n\n********************* VBR TAG INFO *****************\n");
00386     fprintf(stderr, "tag         :%s\n", VBRTag);
00387     fprintf(stderr, "head_flags  :%d\n", head_flags);
00388     fprintf(stderr, "bytes       :%d\n", pTagData->bytes);
00389     fprintf(stderr, "frames      :%d\n", pTagData->frames);
00390     fprintf(stderr, "VBR Scale   :%d\n", pTagData->vbr_scale);
00391     fprintf(stderr, "enc_delay  = %i \n", enc_delay);
00392     fprintf(stderr, "enc_padding= %i \n", enc_padding);
00393     fprintf(stderr, "toc:\n");
00394     if (pTagData->toc != NULL) {
00395         for (i = 0; i < NUMTOCENTRIES; i++) {
00396             if ((i % 10) == 0)
00397                 fprintf(stderr, "\n");
00398             fprintf(stderr, " %3d", (int) (pTagData->toc[i]));
00399         }
00400     }
00401     fprintf(stderr, "\n***************** END OF VBR TAG INFO ***************\n");
00402 #endif
00403     return 1;           /* success */
00404 }
00405 
00406 
00407 /****************************************************************************
00408  * InitVbrTag: Initializes the header, and write empty frame to stream
00409  * Paramters:
00410  *                              fpStream: pointer to output file stream
00411  *                              nMode   : Channel Mode: 0=STEREO 1=JS 2=DS 3=MONO
00412  ****************************************************************************
00413 */
00414 int
00415 InitVbrTag(lame_global_flags * gfp)
00416 {
00417     int     nMode, SampIndex;
00418     int     kbps_header;
00419     lame_internal_flags *gfc = gfp->internal_flags;
00420 #define MAXFRAMESIZE 2880 /* or 0xB40, the max freeformat 640 32kHz framesize */
00421     /* uint8_t pbtStreamBuffer[MAXFRAMESIZE]; */
00422     nMode = gfp->mode;
00423     SampIndex = gfc->samplerate_index;
00424 
00425 
00426 
00427     /* Clear stream buffer */
00428     /* memset(pbtStreamBuffer,0x00,sizeof(pbtStreamBuffer)); */
00429 
00430 
00431 
00432     /*
00433      * Xing VBR pretends to be a 48kbs layer III frame.  (at 44.1kHz).
00434      * (at 48kHz they use 56kbs since 48kbs frame not big enough for
00435      * table of contents)
00436      * let's always embed Xing header inside a 64kbs layer III frame.
00437      * this gives us enough room for a LAME version string too.
00438      * size determined by sampling frequency (MPEG1)
00439      * 32kHz:    216 bytes@48kbs    288bytes@ 64kbs
00440      * 44.1kHz:  156 bytes          208bytes@64kbs     (+1 if padding = 1)
00441      * 48kHz:    144 bytes          192
00442      *
00443      * MPEG 2 values are the same since the framesize and samplerate
00444      * are each reduced by a factor of 2.
00445      */
00446 
00447 
00448     if (1 == gfp->version) {
00449         kbps_header = XING_BITRATE1;
00450     }
00451     else {
00452         if (gfp->out_samplerate < 16000)
00453             kbps_header = XING_BITRATE25;
00454         else
00455             kbps_header = XING_BITRATE2;
00456     }
00457 
00458     if (gfp->VBR == vbr_off)
00459         kbps_header = gfp->brate;
00460 
00463     {
00464         int total_frame_size = ((gfp->version + 1) * 72000 * kbps_header) / gfp->out_samplerate;
00465         int header_size = (gfc->sideinfo_len + LAMEHEADERSIZE);
00466         gfc->VBR_seek_table.TotalFrameSize = total_frame_size;
00467         if (total_frame_size < header_size || total_frame_size > MAXFRAMESIZE) {
00468             /* disable tag, it wont fit */
00469             gfp->bWriteVbrTag = 0;
00470             return 0;
00471         }
00472     }
00473 
00474     /* write dummy VBR tag of all 0's into bitstream */
00475     add_dummy_byte(gfp, 0, gfc->VBR_seek_table.TotalFrameSize);
00476 
00477     gfc->VBR_seek_table.nVbrNumFrames = 0;
00478     gfc->VBR_seek_table.nBytesWritten = 0;
00479     gfc->VBR_seek_table.sum = 0;
00480 
00481     gfc->VBR_seek_table.seen = 0;
00482     gfc->VBR_seek_table.want = 1;
00483     gfc->VBR_seek_table.pos = 0;
00484 
00485     if (gfc->VBR_seek_table.bag == NULL) {
00486         gfc->VBR_seek_table.bag = malloc(400 * sizeof(int));
00487         if (gfc->VBR_seek_table.bag != NULL) {
00488             gfc->VBR_seek_table.size = 400;
00489         }
00490         else {
00491             gfc->VBR_seek_table.size = 0;
00492             ERRORF(gfc, "Error: can't allocate VbrFrames buffer\n");
00493             return -1;
00494         }
00495     }
00496     /* Success */
00497     return 0;
00498 }
00499 
00500 
00501 
00502 /* fast CRC-16 computation - uses table crc16_lookup 8*/
00503 static int
00504 CRC_update_lookup(int value, int crc)
00505 {
00506     int     tmp;
00507     tmp = crc ^ value;
00508     crc = (crc >> 8) ^ crc16_lookup[tmp & 0xff];
00509     return crc;
00510 }
00511 
00512 void
00513 UpdateMusicCRC(uint16_t * crc, unsigned char *buffer, int size)
00514 {
00515     int     i;
00516     for (i = 0; i < size; ++i)
00517         *crc = CRC_update_lookup(buffer[i], *crc);
00518 }
00519 
00520 
00521 
00522 
00523 
00524 /****************************************************************************
00525  * Jonathan Dee 2001/08/31
00526  *
00527  * PutLameVBR: Write LAME info: mini version + info on various switches used
00528  * Paramters:
00529  *                              pbtStreamBuffer : pointer to output buffer
00530  *                              id3v2size               : size of id3v2 tag in bytes
00531  *                              crc                             : computation of crc-16 of Lame Tag so far (starting at frame sync)
00532  *
00533  ****************************************************************************
00534 */
00535 int
00536 PutLameVBR(lame_global_flags const* gfp, FILE * fpStream, uint8_t * pbtStreamBuffer, uint32_t id3v2size,
00537            uint16_t crc)
00538 {
00539     lame_internal_flags *gfc = gfp->internal_flags;
00540 
00541     int     nBytesWritten = 0;
00542     int     nFilesize = 0;   /*size of fpStream. Will be equal to size after process finishes. */
00543     int     i;
00544 
00545     int     enc_delay = lame_get_encoder_delay(gfp); /* encoder delay */
00546     int     enc_padding = lame_get_encoder_padding(gfp); /* encoder padding  */
00547 
00548     /*recall: gfp->VBR_q is for example set by the switch -V  */
00549     /*   gfp->quality by -q, -h, -f, etc */
00550 
00551     int     nQuality = (100 - 10 * gfp->VBR_q - gfp->quality);
00552 
00553 
00554     const char *szVersion = get_lame_very_short_version();
00555     uint8_t nVBR;
00556     uint8_t nRevision = 0x00;
00557     uint8_t nRevMethod;
00558     uint8_t vbr_type_translator[] = { 1, 5, 3, 2, 4, 0, 3 }; /*numbering different in vbr_mode vs. Lame tag */
00559 
00560     uint8_t nLowpass =
00561         (((gfp->lowpassfreq / 100.0) + .5) > 255 ? 255 : (gfp->lowpassfreq / 100.0) + .5);
00562 
00563     uint32_t nPeakSignalAmplitude = 0;
00564 
00565     uint16_t nRadioReplayGain = 0;
00566     uint16_t nAudiophileReplayGain = 0;
00567 
00568     uint8_t nNoiseShaping = gfp->internal_flags->noise_shaping;
00569     uint8_t nStereoMode = 0;
00570     int     bNonOptimal = 0;
00571     uint8_t nSourceFreq = 0;
00572     uint8_t nMisc = 0;
00573     uint32_t nMusicLength = 0;
00574     int     bId3v1Present = ((gfp->internal_flags->tag_spec.flags & CHANGED_FLAG)
00575                              && !(gfp->internal_flags->tag_spec.flags & V2_ONLY_FLAG));
00576     uint16_t nMusicCRC = 0;
00577 
00578     /*psy model type: Gpsycho or NsPsytune */
00579     unsigned char bExpNPsyTune = gfp->exp_nspsytune & 1;
00580     unsigned char bSafeJoint = (gfp->exp_nspsytune & 2) != 0;
00581 
00582     unsigned char bNoGapMore = 0;
00583     unsigned char bNoGapPrevious = 0;
00584 
00585     int     nNoGapCount = gfp->internal_flags->nogap_total;
00586     int     nNoGapCurr = gfp->internal_flags->nogap_current;
00587 
00588 
00589     uint8_t nAthType = gfp->ATHtype; /*4 bits. */
00590 
00591     uint8_t nFlags = 0;
00592 
00593     /* if ABR, {store bitrate <=255} else { store "-b"} */
00594     int     nABRBitrate;
00595     switch (gfp->VBR) {
00596     case vbr_abr:{
00597             nABRBitrate = gfp->VBR_mean_bitrate_kbps;
00598             break;
00599         }
00600     case vbr_off:{
00601             nABRBitrate = gfp->brate;
00602             break;
00603         }
00604     default:{          /*vbr modes */
00605             nABRBitrate = gfp->VBR_min_bitrate_kbps;
00606         }
00607     }
00608 
00609 
00610     /*revision and vbr method */
00611     if (gfp->VBR < sizeof(vbr_type_translator))
00612         nVBR = vbr_type_translator[gfp->VBR];
00613     else
00614         nVBR = 0x00;    /*unknown. */
00615 
00616     nRevMethod = 0x10 * nRevision + nVBR;
00617 
00618 
00619     /* ReplayGain */
00620     if (gfc->findReplayGain) {
00621         if (gfc->RadioGain > 0x1FE)
00622             gfc->RadioGain = 0x1FE;
00623         if (gfc->RadioGain < -0x1FE)
00624             gfc->RadioGain = -0x1FE;
00625 
00626         nRadioReplayGain = 0x2000; /* set name code */
00627         nRadioReplayGain |= 0xC00; /* set originator code to `determined automatically' */
00628 
00629         if (gfc->RadioGain >= 0)
00630             nRadioReplayGain |= gfc->RadioGain; /* set gain adjustment */
00631         else {
00632             nRadioReplayGain |= 0x200; /* set the sign bit */
00633             nRadioReplayGain |= -gfc->RadioGain; /* set gain adjustment */
00634         }
00635     }
00636 
00637     /* peak sample */
00638     if (gfc->findPeakSample)
00639         nPeakSignalAmplitude = abs((int) ((((FLOAT) gfc->PeakSample) / 32767.0) * pow(2, 23) + .5));
00640 
00641     /*nogap */
00642     if (nNoGapCount != -1) {
00643         if (nNoGapCurr > 0)
00644             bNoGapPrevious = 1;
00645 
00646         if (nNoGapCurr < nNoGapCount - 1)
00647             bNoGapMore = 1;
00648     }
00649 
00650     /*flags */
00651 
00652     nFlags = nAthType + (bExpNPsyTune << 4)
00653         + (bSafeJoint << 5)
00654         + (bNoGapMore << 6)
00655         + (bNoGapPrevious << 7);
00656 
00657 
00658     if (nQuality < 0)
00659         nQuality = 0;
00660 
00661     /*stereo mode field... a bit ugly. */
00662 
00663     switch (gfp->mode) {
00664     case MONO:
00665         nStereoMode = 0;
00666         break;
00667     case STEREO:
00668         nStereoMode = 1;
00669         break;
00670     case DUAL_CHANNEL:
00671         nStereoMode = 2;
00672         break;
00673     case JOINT_STEREO:
00674         if (gfp->force_ms)
00675             nStereoMode = 4;
00676         else
00677             nStereoMode = 3;
00678         break;
00679     case NOT_SET:
00680         /* FALLTHROUGH */
00681     default:
00682         nStereoMode = 7;
00683         break;
00684     }
00685 
00686     /*Intensity stereo : nStereoMode = 6. IS is not implemented */
00687 
00688     if (gfp->in_samplerate <= 32000)
00689         nSourceFreq = 0x00;
00690     else if (gfp->in_samplerate == 48000)
00691         nSourceFreq = 0x02;
00692     else if (gfp->in_samplerate > 48000)
00693         nSourceFreq = 0x03;
00694     else
00695         nSourceFreq = 0x01; /*default is 44100Hz. */
00696 
00697 
00698     /*Check if the user overrided the default LAME behaviour with some nasty options */
00699 
00700     if (gfp->short_blocks == short_block_forced || gfp->short_blocks == short_block_dispensed || ((gfp->lowpassfreq == -1) && (gfp->highpassfreq == -1)) || /* "-k" */
00701         (gfp->scale_left < gfp->scale_right) ||
00702         (gfp->scale_left > gfp->scale_right) ||
00703         (gfp->disable_reservoir && gfp->brate < 320) ||
00704         gfp->noATH || gfp->ATHonly || (nAthType == 0) || gfp->in_samplerate <= 32000)
00705         bNonOptimal = 1;
00706 
00707     nMisc = nNoiseShaping + (nStereoMode << 2)
00708         + (bNonOptimal << 5)
00709         + (nSourceFreq << 6);
00710 
00711 
00712 
00713     /*get filesize */
00714     fseek(fpStream, 0, SEEK_END);
00715     nFilesize = ftell(fpStream);
00716 
00717 
00718     nMusicLength = nFilesize - id3v2size; /*omit current frame */
00719     if (bId3v1Present)
00720         nMusicLength -= 128; /*id3v1 present. */
00721     nMusicCRC = gfc->nMusicCRC;
00722 
00723 
00724     /*Write all this information into the stream */
00725     CreateI4(&pbtStreamBuffer[nBytesWritten], nQuality);
00726     nBytesWritten += 4;
00727 
00728     strncpy((char*)&pbtStreamBuffer[nBytesWritten], szVersion, 9);
00729     nBytesWritten += 9;
00730 
00731     pbtStreamBuffer[nBytesWritten] = nRevMethod;
00732     nBytesWritten++;
00733 
00734     pbtStreamBuffer[nBytesWritten] = nLowpass;
00735     nBytesWritten++;
00736 
00737     CreateI4(&pbtStreamBuffer[nBytesWritten], nPeakSignalAmplitude);
00738     nBytesWritten += 4;
00739 
00740     CreateI2(&pbtStreamBuffer[nBytesWritten], nRadioReplayGain);
00741     nBytesWritten += 2;
00742 
00743     CreateI2(&pbtStreamBuffer[nBytesWritten], nAudiophileReplayGain);
00744     nBytesWritten += 2;
00745 
00746     pbtStreamBuffer[nBytesWritten] = nFlags;
00747     nBytesWritten++;
00748 
00749     if (nABRBitrate >= 255)
00750         pbtStreamBuffer[nBytesWritten] = 0xFF;
00751     else
00752         pbtStreamBuffer[nBytesWritten] = nABRBitrate;
00753     nBytesWritten++;
00754 
00755     pbtStreamBuffer[nBytesWritten] = enc_delay >> 4; /* works for win32, does it for unix? */
00756     pbtStreamBuffer[nBytesWritten + 1] = (enc_delay << 4) + (enc_padding >> 8);
00757     pbtStreamBuffer[nBytesWritten + 2] = enc_padding;
00758 
00759     nBytesWritten += 3;
00760 
00761     pbtStreamBuffer[nBytesWritten] = nMisc;
00762     nBytesWritten++;
00763 
00764 
00765     pbtStreamBuffer[nBytesWritten++] = 0; /*unused in rev0 */
00766 
00767     CreateI2(&pbtStreamBuffer[nBytesWritten], gfp->preset);
00768     nBytesWritten += 2;
00769 
00770     CreateI4(&pbtStreamBuffer[nBytesWritten], nMusicLength);
00771     nBytesWritten += 4;
00772 
00773     CreateI2(&pbtStreamBuffer[nBytesWritten], nMusicCRC);
00774     nBytesWritten += 2;
00775 
00776     /*Calculate tag CRC.... must be done here, since it includes
00777      *previous information*/
00778 
00779     for (i = 0; i < nBytesWritten; i++)
00780         crc = CRC_update_lookup(pbtStreamBuffer[i], crc);
00781 
00782     CreateI2(&pbtStreamBuffer[nBytesWritten], crc);
00783     nBytesWritten += 2;
00784 
00785     return nBytesWritten;
00786 }
00787 
00788 /***********************************************************************
00789  *
00790  * PutVbrTag: Write final VBR tag to the file
00791  * Paramters:
00792  *                              lpszFileName: filename of MP3 bit stream
00793  *                              nVbrScale       : encoder quality indicator (0..100)
00794  ****************************************************************************
00795 */
00796 int
00797 PutVbrTag(lame_global_flags const* gfp, FILE * fpStream)
00798 {
00799     lame_internal_flags *gfc = gfp->internal_flags;
00800 
00801     long    lFileSize;
00802     int     stream_size;
00803     int     nStreamIndex;
00804     char    abyte, bbyte;
00805     uint8_t btToc[NUMTOCENTRIES];
00806     uint8_t pbtStreamBuffer[MAXFRAMESIZE];
00807     size_t  nbytes;
00808     unsigned char id3v2Header[10];
00809     size_t  id3v2TagSize;
00810 
00811     if (gfc->VBR_seek_table.pos <= 0)
00812         return -1;
00813 
00814 
00815     /* Clear stream buffer */
00816     memset(pbtStreamBuffer, 0x00, sizeof(pbtStreamBuffer));
00817 
00818     /* Seek to end of file */
00819     fseek(fpStream, 0, SEEK_END);
00820 
00821     /* Get file size */
00822     lFileSize = ftell(fpStream);
00823 
00824     /* Abort if file has zero length. Yes, it can happen :) */
00825     if (lFileSize == 0)
00826         return -1;
00827 
00828     /*
00829      * The VBR tag may NOT be located at the beginning of the stream.
00830      * If an ID3 version 2 tag was added, then it must be skipped to write
00831      * the VBR tag data.
00832      */
00833 
00834     /* seek to the beginning of the stream */
00835     if (fseek(fpStream, 0, SEEK_SET) != 0) {
00836         return -2;  /* not seekable, abort */
00837     }
00838     /* read 10 bytes in case there's an ID3 version 2 header here */
00839     nbytes = fread(id3v2Header, 1, sizeof(id3v2Header), fpStream);
00840     if (nbytes != sizeof(id3v2Header)) {
00841         return -3;  /* not readable, maybe opened Write-Only */
00842     }
00843     /* does the stream begin with the ID3 version 2 file identifier? */
00844     if (!strncmp((char *) id3v2Header, "ID3", 3)) {
00845         /* the tag size (minus the 10-byte header) is encoded into four
00846          * bytes where the most significant bit is clear in each byte */
00847         id3v2TagSize = (((id3v2Header[6] & 0x7f) << 21)
00848                         | ((id3v2Header[7] & 0x7f) << 14)
00849                         | ((id3v2Header[8] & 0x7f) << 7)
00850                         | (id3v2Header[9] & 0x7f))
00851             + sizeof id3v2Header;
00852     }
00853     else {
00854         /* no ID3 version 2 tag in this stream */
00855         id3v2TagSize = 0;
00856     }
00857 
00858     /* Seek to first real frame */
00859     fseek(fpStream, (long)(id3v2TagSize + gfc->VBR_seek_table.TotalFrameSize), SEEK_SET);
00860 
00861     /* Read the header (first valid frame) */
00862     nbytes = fread(pbtStreamBuffer, 1, 4, fpStream);
00863     if (nbytes != 4) {
00864         return -3;  /* Read failed */
00865     }
00866 
00867     /* the default VBR header. 48 kbps layer III, no padding, no crc */
00868     /* but sampling freq, mode andy copyright/copy protection taken */
00869     /* from first valid frame */
00870     pbtStreamBuffer[0] = (uint8_t) 0xff;
00871     abyte = (pbtStreamBuffer[1] & (char) 0xf1);
00872     {
00873         int     bitrate;
00874         if (1 == gfp->version) {
00875             bitrate = XING_BITRATE1;
00876         }
00877         else {
00878             if (gfp->out_samplerate < 16000)
00879                 bitrate = XING_BITRATE25;
00880             else
00881                 bitrate = XING_BITRATE2;
00882         }
00883 
00884         if (gfp->VBR == vbr_off)
00885             bitrate = gfp->brate;
00886 
00887         if (gfp->free_format)
00888             bbyte = 0x00;
00889         else
00890             bbyte = 16 * BitrateIndex(bitrate, gfp->version, gfp->out_samplerate);
00891     }
00892 
00893     /* Use as much of the info from the real frames in the
00894      * Xing header:  samplerate, channels, crc, etc...
00895      */
00896     if (gfp->version == 1) {
00897         /* MPEG1 */
00898         pbtStreamBuffer[1] = abyte | (char) 0x0a; /* was 0x0b; */
00899         abyte = pbtStreamBuffer[2] & (char) 0x0d; /* AF keep also private bit */
00900         pbtStreamBuffer[2] = (char) bbyte | abyte; /* 64kbs MPEG1 frame */
00901     }
00902     else {
00903         /* MPEG2 */
00904         pbtStreamBuffer[1] = abyte | (char) 0x02; /* was 0x03; */
00905         abyte = pbtStreamBuffer[2] & (char) 0x0d; /* AF keep also private bit */
00906         pbtStreamBuffer[2] = (char) bbyte | abyte; /* 64kbs MPEG2 frame */
00907     }
00908 
00909     /* Clear all TOC entries */
00910     memset(btToc, 0, sizeof(btToc));
00911 
00912     if (gfp->free_format) {
00913         int     i;
00914         for (i = 1; i < NUMTOCENTRIES; ++i)
00915             btToc[i] = 255 * i / 100;
00916     }
00917     else {
00918         Xing_seek_table(&gfc->VBR_seek_table, btToc);
00919     }
00920 #ifdef DEBUG_VBR_SEEKING_TABLE
00921     print_seeking (btToc);
00922 #endif
00923 
00924     /* Start writing the tag after the zero frame */
00925     nStreamIndex = gfc->sideinfo_len;
00926     /* note! Xing header specifies that Xing data goes in the
00927      * ancillary data with NO ERROR PROTECTION.  If error protecton
00928      * in enabled, the Xing data still starts at the same offset,
00929      * and now it is in sideinfo data block, and thus will not
00930      * decode correctly by non-Xing tag aware players */
00931     if (gfp->error_protection)
00932         nStreamIndex -= 2;
00933 
00934     /* Put Vbr tag */
00935     if (gfp->VBR == vbr_off) {
00936         pbtStreamBuffer[nStreamIndex++] = VBRTag1[0];
00937         pbtStreamBuffer[nStreamIndex++] = VBRTag1[1];
00938         pbtStreamBuffer[nStreamIndex++] = VBRTag1[2];
00939         pbtStreamBuffer[nStreamIndex++] = VBRTag1[3];
00940 
00941     }
00942     else {
00943         pbtStreamBuffer[nStreamIndex++] = VBRTag0[0];
00944         pbtStreamBuffer[nStreamIndex++] = VBRTag0[1];
00945         pbtStreamBuffer[nStreamIndex++] = VBRTag0[2];
00946         pbtStreamBuffer[nStreamIndex++] = VBRTag0[3];
00947     }
00948 
00949     /* Put header flags */
00950     CreateI4(&pbtStreamBuffer[nStreamIndex], FRAMES_FLAG + BYTES_FLAG + TOC_FLAG + VBR_SCALE_FLAG);
00951     nStreamIndex += 4;
00952 
00953     /* Put Total Number of frames */
00954     CreateI4(&pbtStreamBuffer[nStreamIndex], gfc->VBR_seek_table.nVbrNumFrames);
00955     nStreamIndex += 4;
00956 
00957     /* Put total audio stream size, including Xing/LAME Header */
00958     stream_size = gfc->VBR_seek_table.nBytesWritten + gfc->VBR_seek_table.TotalFrameSize;
00959     CreateI4(&pbtStreamBuffer[nStreamIndex], stream_size);
00960     nStreamIndex += 4;
00961 
00962     /* Put TOC */
00963     memcpy(&pbtStreamBuffer[nStreamIndex], btToc, sizeof(btToc));
00964     nStreamIndex += sizeof(btToc);
00965 
00966 
00967     if (gfp->error_protection) {
00968         /* (jo) error_protection: add crc16 information to header */
00969         CRC_writeheader(gfc, (char *) pbtStreamBuffer);
00970     }
00971 
00972 
00973     {
00974         /*work out CRC so far: initially crc = 0 */
00975         uint16_t crc = 0x00;
00976         int i;
00977         for (i = 0; i < nStreamIndex; i++)
00978             crc = CRC_update_lookup(pbtStreamBuffer[i], crc);
00979         /*Put LAME VBR info */
00980         nStreamIndex += PutLameVBR(gfp, fpStream, pbtStreamBuffer + nStreamIndex, (uint32_t)id3v2TagSize, crc);
00981     }
00982 
00983 #ifdef DEBUG_VBRTAG
00984     {
00985         VBRTAGDATA TestHeader;
00986         GetVbrTag(&TestHeader, pbtStreamBuffer);
00987     }
00988 #endif
00989 
00990     /*Seek to the beginning of the stream */
00991     fseek(fpStream, (long)id3v2TagSize, SEEK_SET);
00992 
00993     /* Put it all to disk again */
00994     if (fwrite(pbtStreamBuffer, gfc->VBR_seek_table.TotalFrameSize, 1, fpStream) != 1) {
00995         return -1;
00996     }
00997 
00998 
00999     return 0;           /* success */
01000 }

Generated on Sun Dec 2 11:34:21 2007 for LAME by  doxygen 1.5.2