00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00039 #include <unistd.h>
00040 #endif
00041
00042
00043 #ifdef _DEBUG
00044
00045 #endif
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
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
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
00076
00077
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
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
00189
00190
00191
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
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
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
00237 buf[0] = (nValue >> 8) & 0xff;
00238 buf[1] = (nValue) & 0xff;
00239 }
00240
00241
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
00258
00259
00260 int
00261 CheckVbrTag(unsigned char *buf)
00262 {
00263 int h_id, h_mode, h_sr_index;
00264
00265
00266 h_id = (buf[1] >> 3) & 1;
00267 h_sr_index = (buf[2] >> 2) & 3;
00268 h_mode = (buf[3] >> 6) & 3;
00269
00270
00271 if (h_id) {
00272
00273 if (h_mode != 3)
00274 buf += (32 + 4);
00275 else
00276 buf += (17 + 4);
00277 }
00278 else {
00279
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
00297 pTagData->flags = 0;
00298
00299
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
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
00312
00313
00314
00315
00316
00317 if (h_id) {
00318
00319 if (h_mode != 3)
00320 buf += (32 + 4);
00321 else
00322 buf += (17 + 4);
00323 }
00324 else {
00325
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;
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
00375
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;
00404 }
00405
00406
00407
00408
00409
00410
00411
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
00421
00422 nMode = gfp->mode;
00423 SampIndex = gfc->samplerate_index;
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
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
00469 gfp->bWriteVbrTag = 0;
00470 return 0;
00471 }
00472 }
00473
00474
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
00497 return 0;
00498 }
00499
00500
00501
00502
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
00526
00527
00528
00529
00530
00531
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;
00543 int i;
00544
00545 int enc_delay = lame_get_encoder_delay(gfp);
00546 int enc_padding = lame_get_encoder_padding(gfp);
00547
00548
00549
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 };
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
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;
00590
00591 uint8_t nFlags = 0;
00592
00593
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:{
00605 nABRBitrate = gfp->VBR_min_bitrate_kbps;
00606 }
00607 }
00608
00609
00610
00611 if (gfp->VBR < sizeof(vbr_type_translator))
00612 nVBR = vbr_type_translator[gfp->VBR];
00613 else
00614 nVBR = 0x00;
00615
00616 nRevMethod = 0x10 * nRevision + nVBR;
00617
00618
00619
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;
00627 nRadioReplayGain |= 0xC00;
00628
00629 if (gfc->RadioGain >= 0)
00630 nRadioReplayGain |= gfc->RadioGain;
00631 else {
00632 nRadioReplayGain |= 0x200;
00633 nRadioReplayGain |= -gfc->RadioGain;
00634 }
00635 }
00636
00637
00638 if (gfc->findPeakSample)
00639 nPeakSignalAmplitude = abs((int) ((((FLOAT) gfc->PeakSample) / 32767.0) * pow(2, 23) + .5));
00640
00641
00642 if (nNoGapCount != -1) {
00643 if (nNoGapCurr > 0)
00644 bNoGapPrevious = 1;
00645
00646 if (nNoGapCurr < nNoGapCount - 1)
00647 bNoGapMore = 1;
00648 }
00649
00650
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
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
00681 default:
00682 nStereoMode = 7;
00683 break;
00684 }
00685
00686
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;
00696
00697
00698
00699
00700 if (gfp->short_blocks == short_block_forced || gfp->short_blocks == short_block_dispensed || ((gfp->lowpassfreq == -1) && (gfp->highpassfreq == -1)) ||
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
00714 fseek(fpStream, 0, SEEK_END);
00715 nFilesize = ftell(fpStream);
00716
00717
00718 nMusicLength = nFilesize - id3v2size;
00719 if (bId3v1Present)
00720 nMusicLength -= 128;
00721 nMusicCRC = gfc->nMusicCRC;
00722
00723
00724
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;
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;
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
00777
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
00791
00792
00793
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
00816 memset(pbtStreamBuffer, 0x00, sizeof(pbtStreamBuffer));
00817
00818
00819 fseek(fpStream, 0, SEEK_END);
00820
00821
00822 lFileSize = ftell(fpStream);
00823
00824
00825 if (lFileSize == 0)
00826 return -1;
00827
00828
00829
00830
00831
00832
00833
00834
00835 if (fseek(fpStream, 0, SEEK_SET) != 0) {
00836 return -2;
00837 }
00838
00839 nbytes = fread(id3v2Header, 1, sizeof(id3v2Header), fpStream);
00840 if (nbytes != sizeof(id3v2Header)) {
00841 return -3;
00842 }
00843
00844 if (!strncmp((char *) id3v2Header, "ID3", 3)) {
00845
00846
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
00855 id3v2TagSize = 0;
00856 }
00857
00858
00859 fseek(fpStream, (long)(id3v2TagSize + gfc->VBR_seek_table.TotalFrameSize), SEEK_SET);
00860
00861
00862 nbytes = fread(pbtStreamBuffer, 1, 4, fpStream);
00863 if (nbytes != 4) {
00864 return -3;
00865 }
00866
00867
00868
00869
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
00894
00895
00896 if (gfp->version == 1) {
00897
00898 pbtStreamBuffer[1] = abyte | (char) 0x0a;
00899 abyte = pbtStreamBuffer[2] & (char) 0x0d;
00900 pbtStreamBuffer[2] = (char) bbyte | abyte;
00901 }
00902 else {
00903
00904 pbtStreamBuffer[1] = abyte | (char) 0x02;
00905 abyte = pbtStreamBuffer[2] & (char) 0x0d;
00906 pbtStreamBuffer[2] = (char) bbyte | abyte;
00907 }
00908
00909
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
00925 nStreamIndex = gfc->sideinfo_len;
00926
00927
00928
00929
00930
00931 if (gfp->error_protection)
00932 nStreamIndex -= 2;
00933
00934
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
00950 CreateI4(&pbtStreamBuffer[nStreamIndex], FRAMES_FLAG + BYTES_FLAG + TOC_FLAG + VBR_SCALE_FLAG);
00951 nStreamIndex += 4;
00952
00953
00954 CreateI4(&pbtStreamBuffer[nStreamIndex], gfc->VBR_seek_table.nVbrNumFrames);
00955 nStreamIndex += 4;
00956
00957
00958 stream_size = gfc->VBR_seek_table.nBytesWritten + gfc->VBR_seek_table.TotalFrameSize;
00959 CreateI4(&pbtStreamBuffer[nStreamIndex], stream_size);
00960 nStreamIndex += 4;
00961
00962
00963 memcpy(&pbtStreamBuffer[nStreamIndex], btToc, sizeof(btToc));
00964 nStreamIndex += sizeof(btToc);
00965
00966
00967 if (gfp->error_protection) {
00968
00969 CRC_writeheader(gfc, (char *) pbtStreamBuffer);
00970 }
00971
00972
00973 {
00974
00975 uint16_t crc = 0x00;
00976 int i;
00977 for (i = 0; i < nStreamIndex; i++)
00978 crc = CRC_update_lookup(pbtStreamBuffer[i], crc);
00979
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
00991 fseek(fpStream, (long)id3v2TagSize, SEEK_SET);
00992
00993
00994 if (fwrite(pbtStreamBuffer, gfc->VBR_seek_table.TotalFrameSize, 1, fpStream) != 1) {
00995 return -1;
00996 }
00997
00998
00999 return 0;
01000 }