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
00026
00032 #include "splt.h"
00033
00034 #include "mp3.h"
00035 #include "mp3_silence.h"
00036 #include "mp3_utils.h"
00037
00038
00039
00040
00045 static const char *splt_mp3_chan[] =
00046 {
00047 "Mono",
00048 "Dual Mono",
00049 "Joint Stereo",
00050 "Stereo",
00051 "?"
00052 };
00053
00057 static const unsigned long splt_mp3_crctab[256] = {
00058 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
00059 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
00060 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
00061 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
00062 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
00063 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
00064 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
00065 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
00066 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
00067 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
00068 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
00069 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
00070 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
00071 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
00072 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
00073 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
00074 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
00075 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
00076 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
00077 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
00078 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
00079 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
00080 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
00081 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
00082 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
00083 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
00084 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
00085 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
00086 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
00087 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
00088 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
00089 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
00090 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
00091 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
00092 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
00093 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
00094 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
00095 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
00096 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
00097 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
00098 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
00099 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
00100 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
00101 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
00102 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
00103 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
00104 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
00105 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
00106 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
00107 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
00108 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
00109 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
00110 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
00111 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
00112 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
00113 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
00114 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
00115 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
00116 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
00117 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
00118 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
00119 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
00120 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
00121 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
00122 };
00123
00124 static void splt_mp3_save_end_point(splt_state *state, splt_mp3_state *mp3state,
00125 int save_end_point, off_t end)
00126 {
00127 mp3state->end_non_zero = end;
00128
00129 if (save_end_point)
00130 {
00131 mp3state->end = end;
00132 }
00133 else
00134 {
00135 mp3state->end = 0;
00136 }
00137 }
00138
00146 static FILE *splt_mp3_open_file_read(splt_state *state, const char *filename, int *error)
00147 {
00148 FILE *file_input = NULL;
00149
00150 if (filename != NULL && ((strcmp(filename,"-") == 0) ||
00151 (strcmp(filename,"m-") == 0)))
00152 {
00153 file_input = stdin;
00154 #ifdef __WIN32__
00155 _setmode(fileno(file_input), _O_BINARY);
00156 #endif
00157 }
00158 else
00159 {
00160 file_input = splt_io_fopen(filename, "rb");
00161 if (file_input == NULL)
00162 {
00163 splt_e_set_strerror_msg_with_data(state, filename);
00164 *error = SPLT_ERROR_CANNOT_OPEN_FILE;
00165 }
00166 }
00167
00168 return file_input;
00169 }
00170
00174 static FILE *splt_mp3_open_file_write(splt_state *state, const char *output_fname, int *error)
00175 {
00176 FILE *file_output = NULL;
00177
00178
00179 if (strcmp(output_fname, "-")==0)
00180 {
00181 file_output = stdout;
00182 #ifdef __WIN32__
00183 _setmode(fileno(file_output), _O_BINARY);
00184 #endif
00185 }
00186 else
00187 {
00188 if (!(file_output = splt_io_fopen(output_fname, "wb+")))
00189 {
00190 splt_e_set_strerror_msg_with_data(state, output_fname);
00191 *error = SPLT_ERROR_CANNOT_OPEN_DEST_FILE;
00192 }
00193 }
00194
00195 return file_output;
00196 }
00197
00198
00199
00200
00202 static unsigned long splt_mp3_c_crc(splt_state *state,
00203 FILE *in, off_t begin, off_t end, int *error)
00204 {
00205 register unsigned long crc;
00206 int c;
00207
00208 crc = 0xFFFFFFFF;
00209
00210 if (fseeko(in, begin, SEEK_SET) == -1)
00211 {
00212 splt_e_set_strerror_msg_with_data(state, splt_t_get_filename_to_split(state));
00213 *error = SPLT_ERROR_SEEKING_FILE;
00214 return 0;
00215 }
00216
00217 while(begin++ < end)
00218 {
00219 c = fgetc(in);
00220 crc = ((crc >> 8) & 0x00FFFFFF) ^ splt_mp3_crctab[(crc ^ c) & 0xFF];
00221 }
00222
00223 return (crc ^ 0xFFFFFFFF);
00224 }
00225
00230 static void splt_mp3_state_free(splt_state *state)
00231 {
00232 splt_mp3_state *mp3state = state->codec;
00233
00234 if (mp3state)
00235 {
00236 if (mp3state->mp3file.xingbuffer)
00237 {
00238 free(mp3state->mp3file.xingbuffer);
00239 mp3state->mp3file.xingbuffer = NULL;
00240 }
00241
00242
00243 free(mp3state);
00244 state->codec = NULL;
00245 }
00246 }
00247
00248
00249
00250
00259 static int splt_mp3_getid3v1_offset(FILE *file_input)
00260 {
00261 if (fseeko(file_input, (off_t) -128, SEEK_END)==-1)
00262 {
00263 return 0;
00264 }
00265
00266 if (fgetc(file_input)=='T')
00267 if (fgetc(file_input)=='A')
00268 if (fgetc(file_input)=='G')
00269 return -128;
00270
00271 return 0;
00272 }
00273
00282 static off_t splt_mp3_getid3v2_end_offset(FILE *in, off_t start)
00283 {
00284 unsigned long oword = 0;
00285 if (fseeko(in, start, SEEK_SET)==-1)
00286 {
00287 return 0;
00288 }
00289
00290 if (fgetc(in)=='I')
00291 if (fgetc(in)=='D')
00292 if (fgetc(in)=='3')
00293 {
00294 int i;
00295 if (fseeko(in, (off_t) 3, SEEK_CUR)==-1)
00296 {
00297 return 0;
00298 }
00299
00300 for (i=0; i<4; i++)
00301 {
00302 oword = (oword << 7) | fgetc(in);
00303 }
00304
00305 return (off_t) (oword);
00306 }
00307
00308 return 0;
00309 }
00310
00311
00312 #ifndef NO_ID3TAG
00313
00315 static id3_byte_t *splt_mp3_get_id3v2_tag_bytes(FILE *file, id3_length_t *length)
00316 {
00317 id3_byte_t *bytes = NULL;
00318 *length = 0;
00319
00320 off_t id3v2_end_offset = splt_mp3_getid3v2_end_offset(file, 0);
00321
00322 if (id3v2_end_offset != 0)
00323 {
00324 size_t id3v2_size = (size_t) (id3v2_end_offset + 10);
00325
00326 rewind(file);
00327 bytes = splt_io_fread(file, 1, id3v2_size);
00328
00329 if (! bytes)
00330 {
00331 return NULL;
00332 }
00333
00334 *length = (unsigned long) id3v2_size;
00335 }
00336
00337 return bytes;
00338 }
00339
00340 static id3_byte_t *splt_mp3_get_id3v1_tag_bytes(FILE *file, id3_length_t *length)
00341 {
00342 id3_byte_t *bytes = NULL;
00343 *length = 0;
00344
00345 off_t id3v1_offset = splt_mp3_getid3v1_offset(file);
00346
00347 if (id3v1_offset != 0)
00348 {
00349 if (fseeko(file, id3v1_offset, SEEK_END) !=-1)
00350 {
00351 bytes = malloc(sizeof(unsigned char) * 128);
00352
00353 if (! bytes)
00354 {
00355 return NULL;
00356 }
00357
00358 if (fread(bytes, 1 , 128, file) != 128)
00359 {
00360 if (bytes)
00361 {
00362 free(bytes);
00363 bytes = NULL;
00364 return NULL;
00365 }
00366 }
00367 else
00368 {
00369 *length = (unsigned long) 128;
00370 }
00371 }
00372 }
00373
00374 return bytes;
00375 }
00376
00386 static id3_byte_t *splt_mp3_get_id3_tag_bytes(splt_state *state, const char *filename,
00387 id3_length_t *length, int *error, int *tags_version)
00388 {
00389 *length = 0;
00390 id3_byte_t *bytes = NULL;
00391
00392 FILE *file = splt_io_fopen(filename, "rb");
00393
00394 if (! file)
00395 {
00396 splt_e_set_strerror_msg_with_data(state, filename);
00397 *error = SPLT_ERROR_CANNOT_OPEN_FILE;
00398 goto end;
00399 }
00400 else
00401 {
00402 id3_length_t id3v1_length = 0;
00403 id3_byte_t *id3v1_bytes = splt_mp3_get_id3v1_tag_bytes(file, &id3v1_length);
00404
00405 id3_length_t id3v2_length = 0;
00406 id3_byte_t *id3v2_bytes = splt_mp3_get_id3v2_tag_bytes(file, &id3v2_length);
00407
00408 if (id3v2_bytes)
00409 {
00410 *tags_version = 2;
00411 bytes = id3v2_bytes;
00412 *length = id3v2_length;
00413
00414 if (id3v1_bytes)
00415 {
00416 *tags_version = 12;
00417 free(id3v1_bytes);
00418 id3v1_bytes = NULL;
00419 }
00420 }
00421 else if (id3v1_bytes)
00422 {
00423 *tags_version = 1;
00424 bytes = id3v1_bytes;
00425 *length = id3v1_length;
00426 }
00427 }
00428
00429 end:
00430 if (file)
00431 {
00432 if (fclose(file) != 0)
00433 {
00434 if (bytes)
00435 {
00436 free(bytes);
00437 bytes = NULL;
00438 }
00439 return NULL;
00440 }
00441 }
00442
00443 return bytes;
00444 }
00445
00447 static int splt_mp3_put_original_libid3_frame(splt_state *state,
00448 const struct id3_tag *id3tag, const char *frame_type, int id_type)
00449 {
00450 struct id3_frame *frame = NULL;
00451 union id3_field *field = NULL;
00452 id3_ucs4_t *ucs4 = NULL;
00453 id3_utf8_t *tag_value = NULL;
00454
00455 int err = SPLT_OK;
00456
00457 frame = id3_tag_findframe(id3tag, frame_type,0);
00458 if (frame != NULL)
00459 {
00460 if (id_type == SPLT_MP3_ID3_COMMENT)
00461 {
00462 field = id3_frame_field(frame, 3);
00463 ucs4 = (id3_ucs4_t *) id3_field_getfullstring(field);
00464 }
00465 else
00466 {
00467 field = id3_frame_field(frame, 1);
00468 ucs4 = (id3_ucs4_t *) id3_field_getstrings(field,0);
00469 }
00470 if (ucs4 != NULL)
00471 {
00472 tag_value = id3_ucs4_utf8duplicate(ucs4);
00473
00474 if (tag_value != NULL)
00475 {
00476 switch (id_type)
00477 {
00478 case SPLT_MP3_ID3_ALBUM:
00479 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_ALBUM, tag_value);
00480 break;
00481 case SPLT_MP3_ID3_ARTIST:
00482 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_ARTIST, tag_value);
00483 break;
00484 case SPLT_MP3_ID3_TITLE:
00485 if (strcmp(frame_type,ID3_FRAME_TITLE) == 0)
00486 {
00487 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_TITLE, tag_value);
00488 }
00489 break;
00490 case SPLT_MP3_ID3_YEAR:
00491 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_YEAR, tag_value);
00492 break;
00493 case SPLT_MP3_ID3_TRACK:
00494 ;
00495 int track = atoi((char *)tag_value);
00496 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_TRACK, &track);
00497 break;
00498 case SPLT_MP3_ID3_COMMENT:
00499 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_COMMENT, tag_value);
00500 break;
00501 case SPLT_MP3_ID3_GENRE:
00502 ;
00503 char *genre = (char *)tag_value;
00504
00505 int id3v1 = atoi(genre);
00506 if ((id3v1 > 0) &&
00507 (id3v1 < SPLT_ID3V1_NUMBER_OF_GENRES) &&
00508 (state->original_tags.tags.genre == NULL))
00509 {
00510 err = splt_tu_set_original_tags_field(state, SPLT_TAGS_GENRE, splt_id3v1_genres[id3v1]);
00511 }
00512 else if (strlen(genre) == 0)
00513 {
00514 err = splt_tu_set_original_tags_field(state, SPLT_TAGS_GENRE, SPLT_UNDEFINED_GENRE);
00515 }
00516 else
00517 {
00518 err = splt_tu_set_original_tags_field(state, SPLT_TAGS_GENRE, genre);
00519 }
00520 break;
00521 default:
00522 break;
00523 }
00524 free(tag_value);
00525 tag_value = NULL;
00526 }
00527 else
00528 {
00529 err = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00530 }
00531 }
00532 }
00533
00534 return err;
00535 }
00536
00538 #define MP3_VERIFY_ERROR() \
00539 if (err != SPLT_OK) \
00540 { \
00541 *tag_error = err; \
00542 goto end; \
00543 };
00544
00550 static void splt_mp3_get_original_tags(const char *filename,
00551 splt_state *state, int *tag_error)
00552 {
00553 int err = SPLT_OK;
00554
00555
00556 struct id3_tag *id3tag = NULL;
00557
00558
00559 id3_length_t id3_tag_length = 0;
00560 int tags_version = 0;
00561 id3_byte_t *id3_tag_bytes =
00562 splt_mp3_get_id3_tag_bytes(state, filename, &id3_tag_length, tag_error,
00563 &tags_version);
00564
00565 if (*tag_error >= 0)
00566 {
00567 if (id3_tag_bytes)
00568 {
00569 id3tag = id3_tag_parse(id3_tag_bytes, id3_tag_length);
00570
00571 if (id3tag)
00572 {
00573 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_VERSION, &tags_version);
00574 MP3_VERIFY_ERROR();
00575 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_ARTIST,
00576 SPLT_MP3_ID3_ARTIST);
00577 MP3_VERIFY_ERROR();
00578 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_ALBUM,
00579 SPLT_MP3_ID3_ALBUM);
00580 MP3_VERIFY_ERROR();
00581 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_TITLE,
00582 SPLT_MP3_ID3_TITLE);
00583 MP3_VERIFY_ERROR();
00584 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_YEAR,
00585 SPLT_MP3_ID3_YEAR);
00586 MP3_VERIFY_ERROR();
00587 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_GENRE,
00588 SPLT_MP3_ID3_GENRE);
00589 MP3_VERIFY_ERROR();
00590 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_COMMENT,
00591 SPLT_MP3_ID3_COMMENT);
00592 MP3_VERIFY_ERROR();
00593 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_TRACK,
00594 SPLT_MP3_ID3_TRACK);
00595 MP3_VERIFY_ERROR();
00596
00597 id3_tag_delete(id3tag);
00598 }
00599
00600 tag_bytes_and_size *bytes_and_size = malloc(sizeof(tag_bytes_and_size));
00601 if (bytes_and_size == NULL)
00602 {
00603 err = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00604 MP3_VERIFY_ERROR();
00605 }
00606
00607 bytes_and_size->tag_bytes = id3_tag_bytes;
00608 bytes_and_size->tag_length = id3_tag_length;
00609
00610 splt_tu_set_original_tags_data(state, bytes_and_size);
00611 }
00612
00613 end:
00614 ;
00615 }
00616 else if (id3_tag_bytes)
00617 {
00618 free(id3_tag_bytes);
00619 id3_tag_bytes = NULL;
00620 }
00621 }
00622
00625 static void splt_mp3_delete_existing_frames(struct id3_tag *id, const char *frame_type)
00626 {
00627 struct id3_frame *frame = NULL;
00628 while ((frame = id3_tag_findframe(id, frame_type, 0)))
00629 {
00630 id3_tag_detachframe(id, frame);
00631 id3_frame_delete(frame);
00632 }
00633 }
00634
00635 static void splt_mp3_put_libid3_frame_in_tag_with_content(struct id3_tag *id,
00636 const char *frame_type, int field_number, const char *content, int *error)
00637 {
00638 struct id3_frame *id_frame = NULL;
00639 id3_ucs4_t *field_content = NULL;
00640 union id3_field *id_field = NULL;
00641
00642 if (content)
00643 {
00644 splt_mp3_delete_existing_frames(id, frame_type);
00645
00646 id_frame = id3_frame_new(frame_type);
00647 if (!id_frame)
00648 {
00649 goto error;
00650 }
00651
00652 id_field = id3_frame_field(id_frame, field_number);
00653
00654 id3_field_settextencoding(id3_frame_field(id_frame, 0),
00655 ID3_FIELD_TEXTENCODING_UTF_16);
00656
00657 field_content = id3_utf8_ucs4duplicate((signed char *)content);
00658 if (! field_content)
00659 {
00660 goto error;
00661 }
00662
00663
00664 if (field_number == 1)
00665 {
00666 if (id3_field_addstring(id_field, field_content) == -1)
00667 {
00668 goto error;
00669 }
00670 }
00671
00672 else if (field_number == 3)
00673 {
00674 if (id3_field_setfullstring(id_field, field_content) == -1)
00675 {
00676 goto error;
00677 }
00678 }
00679
00680 free(field_content);
00681 field_content = NULL;
00682
00683 if (id3_tag_attachframe(id, id_frame) == -1)
00684 {
00685 goto error;
00686 }
00687
00688 id3_frame_delete(id_frame);
00689 }
00690
00691 return;
00692
00693 error:
00694 *error = SPLT_ERROR_LIBID3;
00695 if (id_frame)
00696 {
00697 id3_frame_delete(id_frame);
00698 }
00699 if (field_content)
00700 {
00701 free(field_content);
00702 field_content = NULL;
00703 }
00704
00705 return;
00706 }
00707
00708 static char *splt_mp3_build_libid3tag(const char *title, const char *artist,
00709 const char *album, const char *year, const char *genre,
00710 const char *comment, int track, int set_original_tags,
00711 int *error, unsigned long *number_of_bytes, int tags_version,
00712 splt_state *state)
00713 {
00714 struct id3_tag *id = NULL;
00715
00716 tag_bytes_and_size *bytes_and_size =
00717 (tag_bytes_and_size *) splt_tu_get_original_tags_data(state);
00718
00719 if (set_original_tags && bytes_and_size)
00720 {
00721 id = id3_tag_parse(bytes_and_size->tag_bytes, bytes_and_size->tag_length);
00722 }
00723 else
00724 {
00725 id = id3_tag_new();
00726 }
00727
00728 id3_byte_t *bytes = NULL;
00729 id3_length_t bytes_length = 0;
00730
00731 if (tags_version == 1)
00732 {
00733 id3_tag_options(id, ID3_TAG_OPTION_ID3V1, ID3_TAG_OPTION_ID3V1);
00734 }
00735 else
00736 {
00737
00738
00739 id3_tag_options(id, ID3_TAG_OPTION_CRC, 0);
00740 id3_tag_options(id, ID3_TAG_OPTION_COMPRESSION, 0);
00741 }
00742
00743 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_TITLE, 1, title, error);
00744 if (*error < 0) { goto error; }
00745 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_ARTIST, 1, artist, error);
00746 if (*error < 0) { goto error; }
00747 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_ALBUM, 1, album, error);
00748 if (*error < 0) { goto error; }
00749 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_YEAR, 1, year, error);
00750 if (*error < 0) { goto error; }
00751 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_COMMENT, 3, comment, error);
00752 if (*error < 0) { goto error; }
00753 if (track != -1)
00754 {
00755 char track_str[255] = { '\0' };
00756 snprintf(track_str,254,"%d",track);
00757 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_TRACK, 1,
00758 track_str, error);
00759 if (*error < 0) { goto error; }
00760 }
00761
00762 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_GENRE, 1, genre, error);
00763 if (*error < 0) { goto error; }
00764
00765
00766 bytes_length = id3_tag_render(id, NULL);
00767
00768 if (bytes_length > 0)
00769 {
00770
00771 bytes = malloc(sizeof(id3_byte_t) * bytes_length);
00772 if (!bytes)
00773 {
00774 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00775 goto error;
00776 }
00777 memset(bytes, '\0', sizeof(id3_byte_t) * bytes_length);
00778
00779 bytes_length = id3_tag_render(id, bytes);
00780
00781 *number_of_bytes = (unsigned long) bytes_length;
00782 }
00783
00784 id3_tag_delete(id);
00785
00786 return (char *) bytes;
00787
00788 error:
00789 id3_tag_delete(id);
00790 *number_of_bytes = 0;
00791 if (bytes)
00792 {
00793 free(bytes);
00794 bytes = NULL;
00795 }
00796
00797 return NULL;
00798 }
00799
00800 #else
00801
00803 static const char unsigned splt_mp3_id3v1_genre_mapping[SPLT_ID3V1_NUMBER_OF_GENRES] =
00804 { 0x00,
00805
00806 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A,
00807 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14,
00808 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E,
00809 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
00810 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32,
00811 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C,
00812 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46,
00813 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
00814
00815 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
00816 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63,
00817 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D,
00818 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
00819 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D,
00820
00821 0xFF };
00822
00824 static unsigned char splt_mp3_get_id3v1_mapping(const char *genre_string)
00825 {
00826 if (genre_string == NULL)
00827 {
00828 return 0xFF;
00829 }
00830
00831 int i = 0;
00832 for (i = 0; i < SPLT_ID3V1_NUMBER_OF_GENRES; i++)
00833 {
00834 if (strncmp(genre_string, splt_id3v1_genres[i], strlen(genre_string)) == 0)
00835 {
00836 return splt_mp3_id3v1_genre_mapping[i];
00837 }
00838 }
00839
00840 return 0xFF;
00841 }
00842
00849 static char *splt_mp3_build_simple_id3v1(const char *title, const char *artist,
00850 const char *album, const char *year, const char *genre,
00851 const char *comment, int track, int *error, unsigned long *number_of_bytes)
00852 {
00853 char *id = NULL;
00854 char buffer[30] = { '\0' };
00855 int j = 3,i = 0;
00856
00857 if ((id = malloc(sizeof(char) * 128)) != NULL)
00858 {
00859 memset(id,'\0',128);
00860
00861 strncpy(id, SPLT_MP3_TAG, 4);
00862
00863 memset(buffer, '\0', 30);
00864 if (title!=NULL) strncpy(buffer, title, 30);
00865 for (i=0; i<30; i++) id[j++]=buffer[i];
00866
00867 memset(buffer, '\0', 30);
00868 if (artist!=NULL) strncpy(buffer, artist, 30);
00869 for (i=0; i<30; i++) id[j++]=buffer[i];
00870
00871 memset(buffer, '\0', 30);
00872 if (album!=NULL) strncpy(buffer, album, 30);
00873 for (i=0; i<30; i++) id[j++]=buffer[i];
00874
00875 memset(buffer, '\0', 30);
00876 if (year!=NULL) strncpy(buffer, year, 4);
00877 for (i=0; i<4; i++) id[j++]=buffer[i];
00878
00879 memset(buffer, '\0', 30);
00880 if (comment!=NULL) strncpy(buffer, comment, 30);
00881 for (i=0; i<30; i++)
00882 {
00883 id[j++]=buffer[i];
00884 }
00885
00886 if (track != -1)
00887 {
00888 if (track != 0x00)
00889 {
00890 id[j-1] = (char) track;
00891 }
00892 }
00893 id[j] = (char) splt_mp3_get_id3v1_mapping(genre);
00894 }
00895 else
00896 {
00897 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
00898 return NULL;
00899 }
00900
00901 *number_of_bytes = 128;
00902
00903 return id;
00904 }
00905 #endif
00906
00913 static char *splt_mp3_build_id3_tags(splt_state *state,
00914 const char *title, const char *artist,
00915 const char *album, const char *year, const char *genre,
00916 const char *comment, int track, int set_original_tags,
00917 int *error, unsigned long *number_of_bytes, int version)
00918 {
00919 char *id = NULL;
00920
00921 #ifdef NO_ID3TAG
00922 if (version == 1)
00923 {
00924 splt_d_print_debug(state,"Setting ID3v1 tags without libid3tag\n");
00925 id = splt_mp3_build_simple_id3v1(title, artist, album, year, genre, comment, track,
00926 error, number_of_bytes);
00927 }
00928 #else
00929 if (version == 1)
00930 {
00931 splt_d_print_debug(state,"Setting ID3v1 tags with libid3tag\n");
00932 id = splt_mp3_build_libid3tag(title, artist, album, year, genre, comment, track,
00933 set_original_tags, error, number_of_bytes, 1, state);
00934 }
00935 else
00936 {
00937 splt_d_print_debug(state,"Setting ID3v2 tags with libid3tag\n");
00938 id = splt_mp3_build_libid3tag(title, artist, album, year, genre, comment, track,
00939 set_original_tags, error, number_of_bytes, 2, state);
00940 }
00941 #endif
00942
00943 return id;
00944 }
00945
00952 static char *splt_mp3_build_tags(const char *filename, splt_state *state, int *error,
00953 unsigned long *number_of_bytes, int id3_version)
00954 {
00955 char *id3_data = NULL;
00956
00957 if (splt_o_get_int_option(state,SPLT_OPT_TAGS) != SPLT_NO_TAGS)
00958 {
00959 splt_tags *tags = splt_tu_get_current_tags(state);
00960
00961 if (tags)
00962 {
00963 char *artist_or_performer = splt_tu_get_artist_or_performer_ptr(tags);
00964 id3_data = splt_mp3_build_id3_tags(state,
00965 tags->title, artist_or_performer, tags->album,
00966 tags->year, tags->genre, tags->comment,
00967 tags->track, tags->set_original_tags ,error, number_of_bytes, id3_version);
00968 }
00969 }
00970
00971 return id3_data;
00972 }
00973
00975 int splt_mp3_write_id3v1_tags(splt_state *state, FILE *file_output,
00976 const char *output_fname)
00977 {
00978 const char *filename = splt_t_get_filename_to_split(state);
00979 unsigned long number_of_bytes = 0;
00980 int error = SPLT_OK;
00981
00982 char *id3_tags = splt_mp3_build_tags(filename, state, &error, &number_of_bytes, 1);
00983
00984 if ((error >= 0) && (id3_tags) && (number_of_bytes > 0))
00985 {
00986 if (file_output)
00987 {
00988 if (fseeko(file_output, splt_mp3_getid3v1_offset(file_output), SEEK_END)!=-1)
00989 {
00990 if (splt_io_fwrite(state, id3_tags, 1, number_of_bytes, file_output) < number_of_bytes)
00991 {
00992 splt_e_set_error_data(state, output_fname);
00993 error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
00994 }
00995 }
00996 else
00997 {
00998 splt_e_set_strerror_msg_with_data(state, output_fname);
00999 error = SPLT_ERROR_SEEKING_FILE;
01000 }
01001 }
01002 }
01003
01004 if (id3_tags)
01005 {
01006 free(id3_tags);
01007 id3_tags = NULL;
01008 }
01009
01010 return error;
01011 }
01012
01013 #ifndef NO_ID3TAG
01014 int splt_mp3_write_id3v2_tags(splt_state *state, FILE *file_output,
01015 const char *output_fname, off_t *end_offset)
01016 {
01017 const char *filename = splt_t_get_filename_to_split(state);
01018 unsigned long number_of_bytes = 0;
01019 int error = SPLT_OK;
01020
01021 char *id3_tags = splt_mp3_build_tags(filename, state, &error, &number_of_bytes, 2);
01022
01023 if ((error >= 0) && (id3_tags) && (number_of_bytes > 0))
01024 {
01025 if (splt_io_fwrite(state, id3_tags, 1, number_of_bytes, file_output) < number_of_bytes)
01026 {
01027 splt_e_set_error_data(state, output_fname);
01028 error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
01029 }
01030 else
01031 {
01032 if (end_offset != NULL)
01033 {
01034 *end_offset = number_of_bytes;
01035 }
01036 }
01037 }
01038
01039 if (id3_tags)
01040 {
01041 free(id3_tags);
01042 id3_tags = NULL;
01043 }
01044
01045 return error;
01046 }
01047 #endif
01048
01050 int splt_mp3_get_output_tags_version(splt_state *state)
01051 {
01052 #ifdef NO_ID3TAG
01053 splt_d_print_debug(state,"Output tags version is ID3v1 without libid3tag\n");
01054 return 1;
01055 #else
01056 int original_tags_version = state->original_tags.tags.tags_version;
01057 int force_tags_version = splt_o_get_int_option(state, SPLT_OPT_FORCE_TAGS_VERSION);
01058
01059 int output_tags_version = original_tags_version;
01060 if (force_tags_version != 0)
01061 {
01062 output_tags_version = force_tags_version;
01063 }
01064
01065 if ((output_tags_version == 0) &&
01066 (splt_o_get_int_option(state, SPLT_OPT_TAGS) == SPLT_CURRENT_TAGS))
01067 {
01068 char *filename = splt_t_get_filename_to_split(state);
01069 if (strcmp(filename, "-") != 0)
01070 {
01071 output_tags_version = 12;
01072 }
01073 }
01074
01075 splt_d_print_debug(state,"Output tags version is ID3v _%d_\n", output_tags_version);
01076
01077 return output_tags_version;
01078 #endif
01079 }
01080
01081
01082
01083
01092 static splt_mp3_state *splt_mp3_info(FILE *file_input, splt_state *state, int framemode, int *error)
01093 {
01094 splt_mp3_state *mp3state = state->codec;
01095
01096 int prev = -1;
01097 long len;
01098
01099 if ((mp3state = malloc(sizeof(splt_mp3_state)))==NULL)
01100 {
01101 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
01102 return NULL;
01103 }
01104 memset(mp3state, 0x0, sizeof(splt_mp3_state));
01105
01106 char *filename = splt_t_get_filename_to_split(state);
01107
01108
01109 mp3state->syncdetect = 0;
01110
01111 mp3state->frames = 1;
01112 mp3state->end = 0;
01113 mp3state->end_non_zero = 0;
01114 mp3state->first = 1;
01115 mp3state->file_input = file_input;
01116 mp3state->framemode = framemode;
01117 mp3state->headw = 0;
01118 mp3state->mp3file.xing = 0;
01119 mp3state->mp3file.xing_offset = 0;
01120 mp3state->mp3file.xingbuffer = NULL;
01121
01122 mp3state->mp3file.len = splt_io_get_file_length(state, file_input, filename, error);
01123 splt_t_set_total_time(state, 0);
01124 mp3state->data_ptr = NULL;
01125 mp3state->data_len = 0;
01126 mp3state->buf_len = 0;
01127 mp3state->bytes = 0;
01128
01129
01130 splt_mp3_init_stream_frame(mp3state);
01131 mad_synth_init(&mp3state->synth);
01132
01133 mad_timer_reset(&mp3state->timer);
01134
01135
01136 do
01137 {
01138 int ret = splt_mp3_get_frame(mp3state);
01139
01140 if (ret == -2)
01141 {
01142 splt_e_set_error_data(state,filename);
01143 *error = SPLT_ERROR_INVALID;
01144 goto function_end;
01145 }
01146
01147 if (mp3state->stream.error == MAD_ERROR_LOSTSYNC)
01148 {
01149 #ifndef NO_ID3TAG
01150 signed long tag_size = id3_tag_query(mp3state->stream.this_frame,
01151 mp3state->stream.bufend - mp3state->stream.this_frame);
01152 if (tag_size > 0)
01153 {
01154 mad_stream_skip(&mp3state->stream, tag_size);
01155 }
01156 #else
01157 splt_c_put_info_message_to_client(state,
01158 _(" warning: lost sync and compiled without id3tag support - the split might be corrupt\n"));
01159 #endif
01160 }
01161
01162 if ((prev == 0) &&
01163 ((ret == 0) || (mp3state->stream.error == MAD_ERROR_BUFLEN)))
01164 {
01165 break;
01166 }
01167
01168
01169 if (ret == 0)
01170 {
01171
01172 mp3state->data_ptr = (unsigned char *) mp3state->stream.this_frame;
01173
01174 if(mp3state->stream.next_frame!=NULL)
01175 {
01176 mp3state->data_len = (long) (mp3state->stream.next_frame - mp3state->stream.this_frame);
01177 }
01178
01179 if (mp3state->stream.anc_bitlen > 64)
01180 {
01181 int tag = 0;
01182 struct mad_bitptr ptr = mp3state->stream.anc_ptr;
01183 struct mad_bitptr start = ptr;
01184
01185 unsigned long xing_word = mad_bit_read(&ptr, 32);
01186 if ((xing_word==SPLT_MP3_XING_MAGIC) ||
01187 (xing_word==SPLT_MP3_INFO_MAGIC))
01188 {
01189 tag = 1;
01190 }
01191
01192 else
01193 {
01194 if (xing_word == ((SPLT_MP3_XING_MAGIC << 16) & 0xffffffffL)
01195 || xing_word == ((SPLT_MP3_INFO_MAGIC << 16) & 0xffffffffL))
01196 {
01197 ptr = start;
01198 mad_bit_skip(&ptr, 16);
01199 tag = 1;
01200 }
01201 }
01202
01203
01204 if (tag)
01205 {
01206 xing_word = mad_bit_read(&ptr, 32);
01207 if (xing_word & SPLT_MP3_XING_FRAMES)
01208 {
01209 mad_timer_t total;
01210 mp3state->frames = mad_bit_read(&ptr, 32);
01211 total = mp3state->frame.header.duration;
01212 mad_timer_multiply(&total, mp3state->frames);
01213 float total_time_milliseconds = (float) mad_timer_count(total, MAD_UNITS_MILLISECONDS);
01214 total_time_milliseconds /= 10.f;
01215 splt_t_set_total_time(state, (long) ceilf(total_time_milliseconds));
01216 }
01217
01218 if (xing_word & SPLT_MP3_XING_BYTES)
01219 {
01220 if (mp3state->mp3file.len == 0)
01221 mp3state->mp3file.len = mad_bit_read(&ptr, 32);
01222 }
01223
01224 if (splt_o_get_int_option(state, SPLT_OPT_XING))
01225 {
01226 mp3state->mp3file.xing = mp3state->data_len;
01227
01228 if ((mp3state->mp3file.xingbuffer =
01229 malloc(mp3state->mp3file.xing))==NULL)
01230 {
01231 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
01232 goto function_end;
01233 }
01234
01235 memcpy(mp3state->mp3file.xingbuffer, mp3state->data_ptr,
01236 mp3state->mp3file.xing);
01237 mp3state->mp3file.xing_offset = splt_mp3_xing_info_off(mp3state);
01238 }
01239
01240 splt_o_set_int_option(state, SPLT_OPT_FRAME_MODE, SPLT_TRUE);
01241 mp3state->framemode = 1;
01242
01243 if (!splt_o_messages_locked(state))
01244 {
01245 if (!splt_o_get_iopt(state, SPLT_INTERNAL_FRAME_MODE_ENABLED))
01246 {
01247 int split_mode =
01248 splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE);
01249
01250 if (split_mode != SPLT_OPTION_WRAP_MODE &&
01251 split_mode != SPLT_OPTION_ERROR_MODE)
01252 {
01253 splt_c_put_info_message_to_client(state,
01254 _(" info: found Xing or Info header. Switching to frame mode... \n"));
01255 splt_o_set_iopt(state, SPLT_INTERNAL_FRAME_MODE_ENABLED, SPLT_TRUE);
01256 }
01257 }
01258 }
01259 continue;
01260 }
01261 }
01262 }
01263
01264 prev = ret;
01265 } while (1);
01266
01267 len = (long) (mp3state->buf_len - (mp3state->data_ptr - mp3state->inputBuffer));
01268
01269 if (len < 0)
01270 {
01271 splt_e_set_error_data(state,filename);
01272 *error = SPLT_ERROR_INVALID;
01273 goto function_end;
01274 }
01275
01276
01277 mp3state->mp3file.firsth = (off_t) (mp3state->bytes - len);
01278 splt_d_print_debug(state, "mp3 firsth bytes = %ld\n", mp3state->bytes);
01279 splt_d_print_debug(state, "mp3 firsth len = %ld\n", len);
01280 mp3state->bytes = mp3state->mp3file.firsth;
01281 mp3state->headw =
01282 (unsigned long) ((mp3state->data_ptr[0] << 24) |
01283 (mp3state->data_ptr[1] << 16) |
01284 (mp3state->data_ptr[2] << 8) | (mp3state->data_ptr[3]));
01285 mp3state->mp3file.mpgid = (int) ((mp3state->headw >> 19)&1);
01286 mp3state->mp3file.layer = mp3state->frame.header.layer;
01287
01288 mp3state->mp3file.freq = mp3state->frame.header.samplerate;
01289 mp3state->mp3file.bitrate = mp3state->frame.header.bitrate/SPLT_MP3_BYTE;
01290
01291 mp3state->mp3file.firsthead =
01292 splt_mp3_makehead(mp3state->headw, mp3state->mp3file, mp3state->mp3file.firsthead, mp3state->mp3file.firsth);
01293
01294 mp3state->mp3file.fps = (float) (mp3state->mp3file.freq*(2-mp3state->mp3file.mpgid));
01295 mp3state->mp3file.fps /= SPLT_MP3_PCM;
01296
01297
01298 switch(mp3state->frame.header.mode)
01299 {
01300 case MAD_MODE_SINGLE_CHANNEL:
01301 mp3state->mp3file.channels = 0;
01302 break;
01303 case MAD_MODE_DUAL_CHANNEL:
01304 mp3state->mp3file.channels = 1;
01305 break;
01306 case MAD_MODE_JOINT_STEREO:
01307 mp3state->mp3file.channels = 2;
01308 break;
01309 case MAD_MODE_STEREO:
01310 mp3state->mp3file.channels = 3;
01311 break;
01312 default:
01313 mp3state->mp3file.channels = 4;
01314 break;
01315 }
01316
01317
01318
01319 if (splt_t_get_total_time(state) == 0)
01320 {
01321 if (mp3state->mp3file.len > 0)
01322 {
01323 long temp = (long)
01324 (((double)(mp3state->mp3file.len - mp3state->mp3file.firsth)
01325 / (double)mp3state->mp3file.bitrate) * 100.0);
01326
01327 splt_t_set_total_time(state, temp);
01328 }
01329 }
01330
01331 function_end:
01332
01333
01334
01335 mad_synth_finish(&mp3state->synth);
01336
01337 return mp3state;
01338 }
01339
01341 static void splt_mp3_end(splt_state *state, int *error)
01342 {
01343 splt_mp3_state *mp3state = state->codec;
01344 if (mp3state)
01345 {
01346 splt_mp3_finish_stream_frame(mp3state);
01347 if (mp3state->file_input)
01348 {
01349 if (mp3state->file_input != stdin)
01350 {
01351 if (fclose(mp3state->file_input) != 0)
01352 {
01353 splt_e_set_strerror_msg_with_data(state, splt_t_get_filename_to_split(state));
01354 *error = SPLT_ERROR_CANNOT_CLOSE_FILE;
01355 }
01356 }
01357 mp3state->file_input = NULL;
01358 }
01359
01360 splt_mp3_state_free(state);
01361 }
01362 state->codec = NULL;
01363 }
01364
01366 static void splt_mp3_get_info(splt_state *state, FILE *file_input, int *error)
01367 {
01368
01369
01370
01371 state->codec = splt_mp3_info(file_input, state,
01372 splt_o_get_int_option(state, SPLT_OPT_FRAME_MODE), error);
01373
01374 if ((*error < 0) || (state->codec == NULL))
01375 {
01376 if (state->codec != NULL)
01377 {
01378 splt_mp3_end(state, error);
01379 }
01380 return;
01381 }
01382
01383 else
01384 {
01385 if ((! splt_o_messages_locked(state)) &&
01386 (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_WRAP_MODE) &&
01387 (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_ERROR_MODE))
01388 {
01389 splt_mp3_state *mp3state = state->codec;
01390 struct splt_mp3 *mfile = &mp3state->mp3file;
01391
01392 char mpeg_infos[1024] = { '\0' };
01393 snprintf(mpeg_infos, 1024, _(" info: MPEG %d Layer %d - %d Hz - %s"),
01394 (2-mfile->mpgid), mfile->layer, mfile->freq, splt_mp3_chan[mfile->channels]);
01395
01396 char frame_mode_infos[256] = { '\0' };
01397 if (mp3state->framemode)
01398 {
01399 if (splt_o_get_int_option(state, SPLT_OPT_INPUT_NOT_SEEKABLE))
01400 {
01401 snprintf(frame_mode_infos, 255, _(" - FRAME MODE NS"));
01402 }
01403 else
01404 {
01405 snprintf(frame_mode_infos, 255, _(" - FRAME MODE"));
01406 }
01407 }
01408 else if (splt_o_get_int_option(state, SPLT_OPT_INPUT_NOT_SEEKABLE))
01409 {
01410 snprintf(frame_mode_infos, 255, _(" - NS - %d Kb/s"),
01411 mfile->bitrate * SPLT_MP3_BYTE / 1000);
01412 }
01413 else
01414 {
01415 snprintf(frame_mode_infos, 255, _(" - %d Kb/s"),
01416 mfile->bitrate * SPLT_MP3_BYTE / 1000);
01417 }
01418
01419 char total_time[256] = { '\0' };
01420 int total_seconds = (int) (splt_t_get_total_time(state) / 100);
01421 int minutes = total_seconds / 60;
01422 int seconds = total_seconds % 60;
01423 snprintf(total_time,255, _(" - Total time: %dm.%02ds"), minutes, seconds%60);
01424
01425 splt_c_put_info_message_to_client(state,
01426 "%s%s%s\n", mpeg_infos, frame_mode_infos, total_time);
01427 }
01428 }
01429 }
01430
01431
01432
01433
01434 static off_t splt_mp3_write_data_ptr(splt_state *state, const char *filename,
01435 const char *output_fname, FILE *file_output, int *error)
01436 {
01437 splt_mp3_state *mp3state = state->codec;
01438
01439 long len = (long) (mp3state->inputBuffer + mp3state->buf_len - mp3state->data_ptr);
01440
01441 if (len < 0)
01442 {
01443 splt_e_set_error_data(state, filename);
01444 *error = SPLT_ERROR_WHILE_READING_FILE;
01445 return len;
01446 }
01447
01448 if (splt_io_fwrite(state, mp3state->data_ptr, 1, len, file_output) < len)
01449 {
01450 splt_e_set_error_data(state,output_fname);
01451 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
01452 return len;
01453 }
01454
01455 mp3state->data_len = 0;
01456
01457 return len;
01458 }
01459
01460
01473 static int splt_mp3_simple_split(splt_state *state, const char *output_fname,
01474 off_t begin, off_t end, int do_write_tags, short write_first_frame)
01475 {
01476 splt_d_print_debug(state,"Mp3 simple split on output _%s_\n", output_fname);
01477 splt_d_print_debug(state,"Mp3 simple split offset begin is _%ld_\n", begin);
01478 splt_d_print_debug(state,"Mp3 simple split offset end is _%ld_\n", end);
01479
01480 splt_mp3_state *mp3state = state->codec;
01481
01482 int error = SPLT_OK_SPLIT;
01483
01484 FILE *file_output = NULL;
01485 off_t position = 0;
01486 unsigned char buffer[SPLT_MP3_READBSIZE] = { '\0' };
01487 long readed = 0;
01488
01489 off_t temp_end = 0;
01490
01491 long start = begin;
01492 int split_mode = splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE);
01493
01494 splt_c_put_progress_text(state, SPLT_PROGRESS_CREATE);
01495
01496 char *filename = splt_t_get_filename_to_split(state);
01497
01498 position = ftello(mp3state->file_input);
01499
01500 if (fseeko(mp3state->file_input, begin, SEEK_SET)==-1)
01501 {
01502 return SPLT_ERROR_BEGIN_OUT_OF_FILE;
01503 }
01504
01505
01506 off_t st_size;
01507 char *fname_to_split = splt_t_get_filename_to_split(state);
01508 if(splt_io_stat(fname_to_split, NULL, &st_size) == 0)
01509 {
01510 mp3state->end2 = st_size;
01511 }
01512 else
01513 {
01514 splt_e_set_strerror_msg_with_data(state, fname_to_split);
01515 return SPLT_ERROR_CANNOT_OPEN_FILE;
01516 }
01517
01518 if (! splt_o_get_int_option(state, SPLT_OPT_PRETEND_TO_SPLIT))
01519 {
01520 file_output = splt_mp3_open_file_write(state, output_fname, &error);
01521 if (error < 0) { return error; }
01522 }
01523
01524 int output_tags_version = splt_mp3_get_output_tags_version(state);
01525
01526 #ifndef NO_ID3TAG
01527
01528 if (do_write_tags && (output_tags_version == 2 || output_tags_version == 12))
01529 {
01530 int err = SPLT_OK;
01531 if ((err = splt_mp3_write_id3v2_tags(state, file_output,
01532 output_fname, NULL)) < 0)
01533 {
01534 error = err;
01535 goto function_end;
01536 }
01537 }
01538 #endif
01539
01540 if (mp3state->mp3file.xing != 0)
01541 {
01542 if (splt_o_get_int_option(state, SPLT_OPT_XING))
01543 {
01544
01545 if (state->options.split_mode != SPLT_OPTION_ERROR_MODE)
01546 {
01547 if (splt_io_fwrite(state, mp3state->mp3file.xingbuffer, 1,
01548 mp3state->mp3file.xing, file_output) < mp3state->mp3file.xing)
01549 {
01550 splt_e_set_error_data(state, output_fname);
01551 error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
01552 goto function_end;
01553 }
01554 }
01555 }
01556 }
01557
01558 if (write_first_frame)
01559 {
01560 splt_mp3_write_data_ptr(state, filename, output_fname, file_output, &error);
01561 if (error < 0) { goto function_end; }
01562 }
01563
01564 while (!feof(mp3state->file_input))
01565 {
01566 readed = SPLT_MP3_READBSIZE;
01567 if (end != -1)
01568 {
01569 if (begin >= end)
01570 {
01571 break;
01572 }
01573 if ((end - begin) < SPLT_MP3_READBSIZE)
01574 {
01575 readed = end - begin;
01576 }
01577 }
01578
01579 if ((readed = fread(buffer, 1, readed, mp3state->file_input))==-1)
01580 {
01581 break;
01582 }
01583
01584 if (splt_io_fwrite(state, buffer, 1, readed, file_output) < readed)
01585 {
01586 splt_e_set_error_data(state,output_fname);
01587 error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
01588 goto function_end;
01589 }
01590 begin += readed;
01591
01592
01593 if ((split_mode == SPLT_OPTION_WRAP_MODE) ||
01594 (split_mode == SPLT_OPTION_ERROR_MODE) ||
01595 ((split_mode == SPLT_OPTION_NORMAL_MODE)
01596 && (!splt_o_get_int_option(state, SPLT_OPT_AUTO_ADJUST))
01597 && (!splt_o_get_int_option(state, SPLT_OPT_FRAME_MODE))))
01598 {
01599 temp_end = end;
01600
01601 if (end == -1)
01602 {
01603 temp_end = mp3state->end2;
01604 }
01605
01606 splt_c_update_progress(state,(double)(begin-start),
01607 (double)(temp_end-start),1,0,
01608 SPLT_DEFAULT_PROGRESS_RATE);
01609 }
01610 else
01611 {
01612
01613 if (splt_o_get_int_option(state, SPLT_OPT_AUTO_ADJUST))
01614 {
01615 splt_c_update_progress(state,(double)(begin-start),
01616 (double)(end-start),
01617 2,0.5, SPLT_DEFAULT_PROGRESS_RATE);
01618 }
01619 else
01620 {
01621 if (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE)
01622 == SPLT_OPTION_TIME_MODE)
01623 {
01624 temp_end = end;
01625
01626 if (end == -1)
01627 {
01628 temp_end = mp3state->end2;
01629 }
01630
01631
01632 if (splt_o_get_int_option(state, SPLT_OPT_FRAME_MODE))
01633 {
01634 splt_c_update_progress(state,(double)(begin-start),
01635 (double)(temp_end-start),
01636 2,0.5, SPLT_DEFAULT_PROGRESS_RATE);
01637 }
01638 else
01639 {
01640 splt_c_update_progress(state,(double)(begin-start),
01641 (double)(temp_end-start),
01642 1,0, SPLT_DEFAULT_PROGRESS_RATE);
01643 }
01644 }
01645 else
01646 {
01647 splt_c_update_progress(state,(double)(begin-start),
01648 (double)(end-start),
01649 2,0.5, SPLT_DEFAULT_PROGRESS_RATE);
01650 }
01651 }
01652 }
01653 }
01654
01655
01656 if (do_write_tags && (output_tags_version == 1 || output_tags_version == 12))
01657 {
01658 int err = SPLT_OK;
01659 if ((err = splt_mp3_write_id3v1_tags(state, file_output, output_fname)) < 0)
01660 {
01661 error = err;
01662 goto function_end;
01663 }
01664 }
01665
01666 if (fseeko(mp3state->file_input, position, SEEK_SET)==-1)
01667 {
01668 splt_e_set_strerror_msg_with_data(state, filename);
01669 goto function_end;
01670 }
01671
01672 function_end:
01673 if (file_output)
01674 {
01675 if (file_output != stdout)
01676 {
01677 if (fclose(file_output) != 0)
01678 {
01679 splt_e_set_strerror_msg_with_data(state, filename);
01680 return SPLT_ERROR_CANNOT_CLOSE_FILE;
01681 }
01682 }
01683 file_output = NULL;
01684 }
01685
01686 return error;
01687 }
01688
01704 static double splt_mp3_split(const char *output_fname, splt_state *state,
01705 double fbegin_sec, double fend_sec, int *error, int save_end_point)
01706 {
01707 splt_d_print_debug(state,"Mp3 split...\n");
01708 splt_d_print_debug(state,"Output filename is _%s_\n", output_fname);
01709 splt_d_print_debug(state,"Begin position is _%lf_\n", fbegin_sec);
01710 splt_d_print_debug(state,"End position is _%lf_\n", fend_sec);
01711
01712 splt_mp3_state *mp3state = state->codec;
01713
01714 int adjustoption = splt_o_get_int_option(state, SPLT_OPT_PARAM_GAP);
01715 short seekable = ! splt_o_get_int_option(state, SPLT_OPT_INPUT_NOT_SEEKABLE);
01716 float threshold = splt_o_get_float_option(state, SPLT_OPT_PARAM_THRESHOLD);
01717 int shots = splt_o_get_int_option(state, SPLT_OPT_PARAM_SHOTS);
01718
01719 short fend_sec_is_not_eof =
01720 !splt_u_fend_sec_is_bigger_than_total_time(state, fend_sec);
01721
01722 short eof=0, check_bitrate=0;
01723
01724 char *filename = splt_t_get_filename_to_split(state);
01725
01726 FILE *file_output = NULL;
01727 short writing = 0, finished=0;
01728 unsigned long fbegin=0;
01729 off_t wrote = 0;
01730 long len = 0;
01731
01732 unsigned long stopped_frames = 0;
01733 int progress_adjust_val = 2;
01734
01735 if (adjustoption)
01736 {
01737 progress_adjust_val = 4;
01738 }
01739
01740 splt_c_put_progress_text(state,SPLT_PROGRESS_CREATE);
01741
01742 double sec_end_time = fend_sec;
01743
01744
01745 if (!seekable)
01746 {
01747 if (! splt_o_get_int_option(state, SPLT_OPT_PRETEND_TO_SPLIT))
01748 {
01749 file_output = splt_mp3_open_file_write(state, output_fname, error);
01750 if (*error < 0) { return sec_end_time; };
01751 }
01752
01753 int output_tags_version = splt_mp3_get_output_tags_version(state);
01754
01755 off_t id3v2_end_offset = 0;
01756 #ifndef NO_ID3TAG
01757
01758 if (output_tags_version == 2 || output_tags_version == 12)
01759 {
01760 int err = SPLT_OK;
01761 if ((err = splt_mp3_write_id3v2_tags(state, file_output,
01762 output_fname, &id3v2_end_offset)) < 0)
01763 {
01764 *error = err;
01765 goto bloc_end;
01766 }
01767 }
01768 #endif
01769
01770
01771 if (mp3state->framemode)
01772 {
01773 splt_d_print_debug(state,"Starting not seekable mp3 frame mode...\n");
01774
01775 long begin_c, end_c, time;
01776
01777 begin_c = (long) (fbegin_sec * 100);
01778 if (fend_sec > 0)
01779 {
01780 end_c = (long) (fend_sec * 100);
01781 }
01782 else
01783 {
01784 end_c = 0;
01785 }
01786 time = 0;
01787
01788 do
01789 {
01790
01791 if (!writing && (time >= begin_c))
01792 {
01793 writing = 1;
01794 fbegin = mp3state->frames;
01795
01796 if (mp3state->mp3file.xing > 0)
01797 {
01798 wrote = splt_io_fwrite(state, mp3state->mp3file.xingbuffer,
01799 1, mp3state->mp3file.xing, file_output);
01800 if (wrote < mp3state->mp3file.xing)
01801 {
01802 splt_e_set_error_data(state,output_fname);
01803 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
01804 goto bloc_end;
01805 }
01806 }
01807 }
01808
01809
01810 if (writing)
01811 {
01812 if (mp3state->data_len > 0)
01813 {
01814 if ((len = splt_io_fwrite(state, mp3state->data_ptr, 1, mp3state->data_len, file_output))
01815 < mp3state->data_len)
01816 {
01817 splt_e_set_error_data(state,output_fname);
01818 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
01819 goto bloc_end;
01820 }
01821 wrote = (off_t) (wrote + len);
01822 mp3state->data_len = 0;
01823 }
01824
01825 if ((end_c > 0) && (time >= end_c))
01826 {
01827 finished = 1;
01828 }
01829 if (eof || finished)
01830 {
01831 finished = 1;
01832 if (eof) { *error = SPLT_OK_SPLIT_EOF; }
01833 break;
01834 }
01835 }
01836
01837
01838 if (splt_o_get_int_option(state,SPLT_OPT_SPLIT_MODE)
01839 == SPLT_OPTION_TIME_MODE)
01840 {
01841 splt_c_update_progress(state,(double)(time-begin_c),
01842 (double)(end_c-begin_c),1,0,
01843 SPLT_DEFAULT_PROGRESS_RATE);
01844 }
01845 else
01846 {
01847 splt_c_update_progress(state,(double)(time),
01848 (double)(end_c),1,0,
01849 SPLT_DEFAULT_PROGRESS_RATE);
01850 }
01851
01852 int mad_err = SPLT_OK;
01853 switch (splt_mp3_get_valid_frame(state, &mad_err))
01854 {
01855 case 1:
01856 mad_timer_add(&mp3state->timer, mp3state->frame.header.duration);
01857 mp3state->frames++;
01858 time = (unsigned long) mad_timer_count(mp3state->timer, MAD_UNITS_CENTISECONDS);
01859 break;
01860 case 0:
01861 break;
01862 case -1:
01863 eof = 1;
01864 *error = SPLT_OK_SPLIT_EOF;
01865 break;
01866 case -3:
01867
01868 *error = mad_err;
01869 goto bloc_end;
01870 break;
01871 default:
01872 break;
01873 }
01874
01875 } while (!finished);
01876 }
01877
01878 else
01879 {
01880 splt_d_print_debug(state,"Starting mp3 not seekable non frame mode...\n");
01881
01882 off_t begin = 0, end = 0;
01883 if (fend_sec_is_not_eof)
01884 {
01885 end = (off_t) (fend_sec * mp3state->mp3file.bitrate + mp3state->mp3file.firsth);
01886 }
01887 else
01888 {
01889 end = -1;
01890 }
01891
01892
01893 if (mp3state->end == 0)
01894 {
01895 begin = (off_t) (fbegin_sec * mp3state->mp3file.bitrate + mp3state->mp3file.firsth);
01896
01897 if ((mp3state->bytes == begin) && (mp3state->data_len > 0))
01898 {
01899 wrote += splt_mp3_write_data_ptr(state, filename, output_fname, file_output, error);
01900 if (*error < 0) { goto bloc_end; }
01901 }
01902 else
01903 {
01904 while (mp3state->bytes < begin)
01905 {
01906 off_t to_read;
01907 if (feof(mp3state->file_input))
01908 {
01909 *error = SPLT_ERROR_BEGIN_OUT_OF_FILE;
01910 goto bloc_end;
01911 }
01912 to_read = (begin - mp3state->bytes);
01913 if (to_read > SPLT_MAD_BSIZE)
01914 to_read = SPLT_MAD_BSIZE;
01915 if ((mp3state->data_len = fread(mp3state->inputBuffer, 1, to_read, mp3state->file_input))<=0)
01916 {
01917 *error = SPLT_ERROR_BEGIN_OUT_OF_FILE;
01918 goto bloc_end;
01919 }
01920 mp3state->bytes+=mp3state->data_len;
01921 }
01922
01923 int mad_err = SPLT_OK;
01924 splt_mp3_init_stream_frame(mp3state);
01925 switch (splt_mp3_get_valid_frame(state, &mad_err))
01926 {
01927 case 1:
01928 len = (long) (mp3state->inputBuffer + mp3state->buf_len - mp3state->data_ptr);
01929 if (len < 0)
01930 {
01931 splt_e_set_error_data(state,filename);
01932 *error = SPLT_ERROR_WHILE_READING_FILE;
01933 goto bloc_end;
01934 }
01935 if (splt_io_fwrite(state, mp3state->data_ptr, 1, len, file_output) < len)
01936 {
01937 splt_e_set_error_data(state,output_fname);
01938 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
01939 goto bloc_end;
01940 }
01941 wrote = (off_t) (wrote + len);
01942 mp3state->data_len = 0;
01943 break;
01944 case 0:
01945 break;
01946 case -1:
01947 eof = 1;
01948 *error = SPLT_ERROR_BEGIN_OUT_OF_FILE;
01949 break;
01950 case -3:
01951
01952 *error = mad_err;
01953 goto bloc_end;
01954 break;
01955 default:
01956 break;
01957 }
01958 }
01959 }
01960
01961 else
01962 {
01963 len = (long) (mp3state->inputBuffer + mp3state->buf_len - mp3state->data_ptr);
01964 if (len < 0)
01965 {
01966 splt_e_set_error_data(state,filename);
01967 *error = SPLT_ERROR_WHILE_READING_FILE;
01968 goto bloc_end;
01969 }
01970 if (splt_io_fwrite(state, mp3state->data_ptr, 1, len, file_output) < len)
01971 {
01972 splt_e_set_error_data(state,output_fname);
01973 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
01974 goto bloc_end;
01975 }
01976 wrote = (off_t) (wrote + len);
01977 mp3state->data_len = 0;
01978 begin = mp3state->end;
01979 }
01980
01981 long split_begin_point = mp3state->bytes;
01982
01983 while (!eof)
01984 {
01985 off_t to_read = SPLT_MAD_BSIZE;
01986 if (end > 0)
01987 {
01988 to_read = (end - mp3state->bytes);
01989 if (to_read <= 0)
01990 {
01991 break;
01992 }
01993 if (to_read > SPLT_MAD_BSIZE)
01994 to_read = SPLT_MAD_BSIZE;
01995 }
01996
01997 if (feof(mp3state->file_input) ||
01998 ((mp3state->data_len =
01999 fread(mp3state->inputBuffer, 1, to_read, mp3state->file_input))<=0))
02000 {
02001 eof = 1;
02002 *error = SPLT_OK_SPLIT_EOF;
02003 break;
02004 }
02005
02006 if (splt_io_fwrite(state, mp3state->inputBuffer, 1,
02007 mp3state->data_len, file_output) < mp3state->data_len)
02008 {
02009 splt_e_set_error_data(state,output_fname);
02010 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
02011 goto bloc_end;
02012 }
02013
02014 mp3state->bytes += mp3state->data_len;
02015
02016 splt_c_update_progress(state, (double) (mp3state->bytes-split_begin_point),
02017 (double)(end-split_begin_point), 1,0,SPLT_DEFAULT_PROGRESS_RATE);
02018 }
02019
02020 splt_mp3_save_end_point(state, mp3state, save_end_point, end);
02021
02022 if (!eof)
02023 {
02024
02025
02026 int mad_err = SPLT_OK;
02027 splt_mp3_init_stream_frame(mp3state);
02028 switch (splt_mp3_get_valid_frame(state, &mad_err))
02029 {
02030 case 1:
02031 len = (long) (mp3state->data_ptr - mp3state->inputBuffer);
02032 if (len < 0)
02033 {
02034 splt_e_set_error_data(state,filename);
02035 *error = SPLT_ERROR_WHILE_READING_FILE;
02036 goto bloc_end;
02037 }
02038 if (splt_io_fwrite(state, mp3state->inputBuffer, 1, len, file_output) < len)
02039 {
02040 splt_e_set_error_data(state,output_fname);
02041 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE;
02042 goto bloc_end;
02043 }
02044 break;
02045 case 0:
02046 break;
02047 case -1:
02048 eof = 1;
02049 *error = SPLT_OK_SPLIT_EOF;
02050 break;
02051 case -3:
02052 *error = mad_err;
02053 goto bloc_end;
02054 break;
02055 default:
02056 break;
02057 }
02058 }
02059 }
02060
02061
02062 if (file_output)
02063 {
02064 if (mp3state->mp3file.xing > 0)
02065 {
02066 if (fseeko(file_output, mp3state->mp3file.xing_offset+4+id3v2_end_offset, SEEK_SET)!=-1)
02067 {
02068 unsigned long headw = (unsigned long) (mp3state->frames - fbegin + 1);
02069 fputc((headw >> 24) & 0xFF, file_output);
02070 fputc((headw >> 16) & 0xFF, file_output);
02071 fputc((headw >> 8) & 0xFF, file_output);
02072 fputc((headw >> 0) & 0xFF, file_output);
02073 headw = (unsigned long) (wrote);
02074 fputc((headw >> 24) & 0xFF, file_output);
02075 fputc((headw >> 16) & 0xFF, file_output);
02076 fputc((headw >> 8) & 0xFF, file_output);
02077 fputc((headw >> 0) & 0xFF, file_output);
02078 }
02079 else
02080 {
02081 splt_e_set_strerror_msg_with_data(state, output_fname);
02082 *error = SPLT_ERROR_SEEKING_FILE;
02083 goto bloc_end;
02084 }
02085 }
02086
02087
02088 if (output_tags_version == 1 || output_tags_version == 12)
02089 {
02090 int err = SPLT_OK;
02091 if ((err = splt_mp3_write_id3v1_tags(state, file_output, output_fname)) < 0)
02092 {
02093 *error = err;
02094 goto bloc_end;
02095 }
02096 }
02097 }
02098
02099 bloc_end:
02100 if (file_output)
02101 {
02102 if (file_output != stdout)
02103 {
02104 if (fclose(file_output) != 0)
02105 {
02106 splt_e_set_strerror_msg_with_data(state, output_fname);
02107 *error = SPLT_ERROR_CANNOT_CLOSE_FILE;
02108 }
02109 }
02110 }
02111 file_output = NULL;
02112
02113 if (*error == SPLT_OK) { *error = SPLT_OK_SPLIT; }
02114
02115 return sec_end_time;
02116 }
02117
02118 else
02119 {
02120 short write_first_frame = SPLT_FALSE;
02121 off_t begin = 0, end = 0;
02122
02123 if (mp3state->framemode)
02124 {
02125 splt_d_print_debug(state,"Starting seekable mp3 frame mode...\n");
02126
02127 unsigned long fbegin, fend, adjust;
02128 fbegin = fend = adjust = 0;
02129
02130
02131 fbegin = fbegin_sec * mp3state->mp3file.fps;
02132
02133 if (fend_sec_is_not_eof)
02134 {
02135
02136 if (adjustoption)
02137 {
02138 if (fend_sec_is_not_eof)
02139 {
02140 float adj = (float) (adjustoption);
02141 float len = (fend_sec - fbegin_sec);
02142 if (adj > len)
02143 {
02144 adj = len;
02145 }
02146 if (fend_sec > adj)
02147 {
02148 fend_sec -= adj;
02149 }
02150 adjust = (unsigned long) (adj * 100.f);
02151 }
02152 else
02153 {
02154 adjust = 0;
02155 }
02156 }
02157
02158
02159 fend = (unsigned long) ceilf(fend_sec * mp3state->mp3file.fps);
02160 }
02161 else
02162 {
02163 fend = 0xFFFFFFFF;
02164 }
02165
02166 splt_d_print_debug(state,"Finding begin...\n");
02167
02168 if (mp3state->end == 0)
02169 {
02170 if (mp3state->first)
02171 {
02172 mp3state->h.ptr = mp3state->mp3file.firsthead.ptr;
02173 mp3state->h.framesize = mp3state->mp3file.firsthead.framesize;
02174 begin = mp3state->mp3file.firsthead.ptr;
02175 mp3state->first = 0;
02176 }
02177
02178 splt_c_put_progress_text(state,SPLT_PROGRESS_PREPARE);
02179
02180
02181 if (mp3state->frames >= fbegin && mp3state->end_non_zero != 0)
02182 {
02183 begin = mp3state->end_non_zero;
02184 }
02185
02186
02187 while (mp3state->frames < fbegin)
02188 {
02189 begin = splt_mp3_findhead(mp3state, mp3state->h.ptr + mp3state->h.framesize);
02190 if (begin == -1) { *error = SPLT_ERROR_BEGIN_OUT_OF_FILE; goto bloc_end2; }
02191
02192
02193 if ((begin!=mp3state->h.ptr + mp3state->h.framesize)&&(state->syncerrors>=0))
02194 {
02195 state->syncerrors++;
02196 }
02197 if ((mp3state->syncdetect)&&(state->syncerrors> SPLT_MAXSYNC))
02198 {
02199 splt_mp3_checksync(mp3state);
02200 }
02201
02202 mp3state->h = splt_mp3_makehead(mp3state->headw, mp3state->mp3file, mp3state->h, begin);
02203 mp3state->frames++;
02204
02205
02206
02207 if (adjustoption)
02208 {
02209 splt_c_update_progress(state,(double)(mp3state->frames),
02210 (double)fend, 8,
02211 0,SPLT_DEFAULT_PROGRESS_RATE);
02212 }
02213 else
02214 {
02215 splt_c_update_progress(state,(double)(mp3state->frames),
02216 (double)fend,progress_adjust_val,
02217 0,SPLT_DEFAULT_PROGRESS_RATE);
02218 }
02219 }
02220 }
02221 else
02222 {
02223 begin = mp3state->end;
02224 }
02225
02226 splt_d_print_debug(state,"Begin is _%ld_\n", begin);
02227
02228 if (mp3state->mp3file.len > 0)
02229 {
02230 if (begin >= mp3state->mp3file.len)
02231 {
02232 *error = SPLT_ERROR_BEGIN_OUT_OF_FILE;
02233 goto bloc_end2;
02234 }
02235 }
02236
02237 splt_c_put_progress_text(state,SPLT_PROGRESS_PREPARE);
02238
02239 long int frames_begin = mp3state->frames;
02240
02241 while (mp3state->frames <= fend)
02242 {
02243 mp3state->frames++;
02244 end = splt_mp3_findhead(mp3state, mp3state->h.ptr + mp3state->h.framesize);
02245 if (end == -1)
02246 {
02247 end = mp3state->h.ptr + mp3state->h.framesize;
02248 eof=1;
02249 *error = SPLT_OK_SPLIT_EOF;
02250 break;
02251 }
02252
02253
02254 if ((end != mp3state->h.ptr + mp3state->h.framesize)&&(state->syncerrors>=0))
02255 {
02256 state->syncerrors++;
02257 }
02258 if ((mp3state->syncdetect)&&(state->syncerrors>SPLT_MAXSYNC))
02259 {
02260 splt_mp3_checksync(mp3state);
02261 }
02262
02263 mp3state->h = splt_mp3_makehead (mp3state->headw, mp3state->mp3file, mp3state->h, end);
02264
02265
02266
02267
02268 int split_mode = splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE);
02269 if (((split_mode == SPLT_OPTION_TIME_MODE) ||
02270 (split_mode == SPLT_OPTION_SILENCE_MODE) ||
02271 (split_mode == SPLT_OPTION_TRIM_SILENCE_MODE))
02272 && (!splt_o_get_int_option(state,SPLT_OPT_AUTO_ADJUST)))
02273 {
02274 splt_c_update_progress(state, (double)(mp3state->frames-fbegin),
02275 (double)(fend-fbegin), progress_adjust_val,
02276 0, SPLT_DEFAULT_PROGRESS_RATE);
02277 }
02278 else
02279 {
02280 if (adjustoption)
02281 {
02282 if(adjust)
02283 {
02284 if (split_mode == SPLT_OPTION_TIME_MODE)
02285 {
02286 splt_c_update_progress(state,
02287 (double)(mp3state->frames-frames_begin),
02288 (double)(fend-frames_begin),
02289 4,0,SPLT_DEFAULT_PROGRESS_RATE);
02290 }
02291 else
02292 {
02293 splt_c_update_progress(state,
02294 (double)(mp3state->frames-frames_begin),
02295 (double)(fend-frames_begin),
02296 8,1/(float)8,SPLT_DEFAULT_PROGRESS_RATE);
02297 }
02298 }
02299 }
02300 else
02301 {
02302 splt_c_update_progress(state,
02303 (double)(mp3state->frames-stopped_frames),
02304 (double)(fend-stopped_frames),
02305 progress_adjust_val,
02306 0,SPLT_DEFAULT_PROGRESS_RATE);
02307 }
02308 }
02309
02310
02311 if ((adjust) && (mp3state->frames >= fend))
02312 {
02313 int silence_points_found =
02314 splt_mp3_scan_silence(state, end, 2 * adjust, threshold, 0.f, shots, 0, error,
02315 splt_scan_silence_processor);
02316
02317 if (silence_points_found == -1)
02318 {
02319 goto bloc_end2;
02320 }
02321 else if (silence_points_found > 0)
02322 {
02323 adjust = (unsigned long) (splt_siu_silence_position(state->silence_list, mp3state->off)
02324 * mp3state->mp3file.fps);
02325 }
02326 else
02327 {
02328 adjust = (unsigned long) (adjustoption * mp3state->mp3file.fps);
02329 }
02330 fend += adjust;
02331 end = splt_mp3_findhead(mp3state, end);
02332
02333 sec_end_time = mp3state->frames / mp3state->mp3file.fps;
02334
02335 splt_siu_ssplit_free(&state->silence_list);
02336 adjust=0;
02337
02338 splt_c_put_progress_text(state,SPLT_PROGRESS_PREPARE);
02339 stopped_frames = mp3state->frames;
02340 }
02341 }
02342
02343 splt_mp3_save_end_point(state, mp3state, save_end_point, end);
02344
02345
02346 if (mp3state->mp3file.xing > 0)
02347 {
02348 unsigned long headw;
02349 headw = (unsigned long) (mp3state->frames - fbegin + 1);
02350 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+4] = (headw >> 24) & 0xFF;
02351 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+5] = (headw >> 16) & 0xFF;
02352 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+6] = (headw >> 8) & 0xFF;
02353 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+7] = headw & 0xFF;
02354
02355 if (end == -1)
02356 {
02357 end = mp3state->mp3file.len;
02358 }
02359 headw = (unsigned long) (end - begin + mp3state->mp3file.xing);
02360 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+8] = (headw >> 24) & 0xFF;
02361 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+9] = (headw >> 16) & 0xFF;
02362 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+10] = (headw >> 8) & 0xFF;
02363 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+11] = headw & 0xFF;
02364 }
02365 }
02366 else
02367
02368 {
02369 splt_d_print_debug(state,"Starting mp3 seekable non frame mode...\n");
02370
02371 long first_frame_offset = mp3state->inputBuffer + mp3state->buf_len - mp3state->data_ptr;
02372
02373
02374 if (mp3state->end == 0)
02375 {
02376 begin = (off_t) (fbegin_sec * mp3state->mp3file.bitrate + mp3state->mp3file.firsth);
02377
02378 if ((mp3state->bytes == begin) && (mp3state->data_len > 0))
02379 {
02380 write_first_frame = SPLT_TRUE;
02381 begin += first_frame_offset;
02382 }
02383 else
02384 {
02385 begin = splt_mp3_findvalidhead(mp3state, begin);
02386 }
02387
02388 if (begin == -1)
02389 {
02390 *error = SPLT_ERROR_BEGIN_OUT_OF_FILE;
02391 goto bloc_end2;
02392 }
02393 if (splt_mp3_tabsel_123[1 - mp3state->mp3file.mpgid][mp3state->mp3file.layer-1][splt_mp3_c_bitrate(mp3state->headw)] !=
02394 mp3state->mp3file.firsthead.bitrate)
02395 {
02396 check_bitrate = 1;
02397 }
02398 }
02399
02400 else
02401 {
02402 begin = mp3state->end;
02403 }
02404
02405 if (fend_sec_is_not_eof)
02406 {
02407 end = (off_t) (fend_sec * mp3state->mp3file.bitrate + mp3state->mp3file.firsth);
02408 if (write_first_frame)
02409 {
02410 end += first_frame_offset;
02411 }
02412
02413
02414 end = splt_mp3_findvalidhead(mp3state, end);
02415 if (splt_mp3_tabsel_123[1 - mp3state->mp3file.mpgid][mp3state->mp3file.layer-1][splt_mp3_c_bitrate(mp3state->headw)] !=
02416 mp3state->mp3file.firsthead.bitrate)
02417 check_bitrate = 1;
02418 }
02419 else
02420 {
02421 end = -1;
02422 }
02423
02424 splt_mp3_save_end_point(state, mp3state, save_end_point, end);
02425 }
02426
02427
02428 int err = splt_mp3_simple_split(state, output_fname, begin, end,
02429 SPLT_TRUE, write_first_frame);
02430 if (err < 0) { *error = err; }
02431
02432 if (!save_end_point)
02433 {
02434 if (splt_o_get_long_option(state, SPLT_OPT_OVERLAP_TIME) > 0)
02435 {
02436 mp3state->frames = 1;
02437 mp3state->first = 1;
02438 }
02439 }
02440 }
02441
02442 if (check_bitrate)
02443 {
02444 *error = SPLT_MIGHT_BE_VBR;
02445 }
02446
02447 if (*error == SPLT_OK) { *error = SPLT_OK_SPLIT; }
02448
02449 bloc_end2:
02450
02451 return sec_end_time;
02452 }
02453
02454
02455
02456
02459 static off_t splt_mp3_adjustsync(splt_mp3_state *mp3state, off_t begin, off_t end)
02460 {
02461 off_t position;
02462 position = begin;
02463 if (fseeko(mp3state->file_input, position, SEEK_SET)==-1)
02464 {
02465 return (off_t) (-1);
02466 }
02467
02468
02469 while (position++ < end)
02470 {
02471 if (fgetc(mp3state->file_input)=='T') {
02472 if (fgetc(mp3state->file_input)=='A') {
02473 if (fgetc(mp3state->file_input)=='G')
02474 return (position + 127);
02475 else position++;
02476 }
02477 if (fseeko(mp3state->file_input, -1, SEEK_CUR) == -1)
02478 {
02479 return (off_t) (-1);
02480 }
02481 }
02482 }
02483
02484 position = begin;
02485
02486 if (fseeko(mp3state->file_input, position, SEEK_SET)==-1)
02487 {
02488 return (off_t) (-1);
02489 }
02490
02491
02492 while (position++ < end)
02493 {
02494 if (fgetc(mp3state->file_input)=='I')
02495 {
02496 if (fgetc(mp3state->file_input)=='D')
02497 {
02498 if (fgetc(mp3state->file_input)=='3')
02499 {
02500 return (position - 1);
02501 }
02502 else
02503 {
02504 position++;
02505 }
02506 }
02507 if(fseeko(mp3state->file_input, -1, SEEK_CUR)==-1)
02508 {
02509 return (off_t) (-1);
02510 }
02511 }
02512 }
02513
02514 return end;
02515 }
02516
02518 static void splt_mp3_syncerror_search(splt_state *state, int *error)
02519 {
02520 off_t offset = 0;
02521 char *filename = splt_t_get_filename_to_split(state);
02522 int sync_err = SPLT_OK;
02523
02524 splt_mp3_state *mp3state = state->codec;
02525
02526 splt_c_put_progress_text(state,SPLT_PROGRESS_SEARCH_SYNC);
02527
02528 mp3state->h.ptr = mp3state->mp3file.firsthead.ptr;
02529 mp3state->h.framesize = mp3state->mp3file.firsthead.framesize;
02530
02531
02532 off_t st_size;
02533 if(splt_io_stat(filename, NULL, &st_size) == 0)
02534 {
02535
02536 sync_err = splt_se_serrors_append_point(state, 0);
02537 if (sync_err != SPLT_OK)
02538 {
02539 *error = sync_err;
02540 return;
02541 }
02542
02543
02544 while (state->serrors->serrors_points_num < SPLT_MAXSYNC)
02545 {
02546 offset = splt_mp3_findhead(mp3state, mp3state->h.ptr + mp3state->h.framesize);
02547 if (offset==-1)
02548 {
02549 break;
02550 }
02551
02552 if (offset != mp3state->h.ptr + mp3state->h.framesize)
02553 {
02554 off_t serror_point =
02555 splt_mp3_adjustsync(mp3state, mp3state->h.ptr, offset);
02556
02557 sync_err = splt_se_serrors_append_point(state, serror_point);
02558 if (sync_err != SPLT_OK)
02559 {
02560 *error = sync_err;
02561 return;
02562 }
02563 offset = splt_mp3_findvalidhead(mp3state, serror_point);
02564 if (splt_io_get_word(mp3state->file_input, offset, SEEK_SET, &mp3state->headw) == -1)
02565 {
02566 *error = SPLT_ERR_SYNC;
02567 return;
02568 }
02569 }
02570
02571 mp3state->h = splt_mp3_makehead (mp3state->headw, mp3state->mp3file,
02572 mp3state->h, offset);
02573
02574 if (splt_t_split_is_canceled(state))
02575 {
02576 *error = SPLT_SPLIT_CANCELLED;
02577 return;
02578 }
02579
02580
02581 splt_c_update_progress(state,(double)(offset),
02582 (double)(st_size),1,0,
02583 SPLT_DEFAULT_PROGRESS_RATE);
02584 }
02585 }
02586 else
02587 {
02588 splt_e_set_strerror_msg_with_data(state, filename);
02589 *error = SPLT_ERROR_CANNOT_OPEN_FILE;
02590 return;
02591 }
02592
02593 if (state->serrors->serrors_points_num == 0)
02594 {
02595 *error = SPLT_ERR_NO_SYNC_FOUND;
02596 return;
02597 }
02598
02599 if (state->serrors->serrors_points_num == SPLT_MAXSYNC)
02600 {
02601 *error = SPLT_ERR_TOO_MANY_SYNC_ERR;
02602 return;
02603 }
02604
02605
02606 sync_err = splt_se_serrors_append_point(state, LONG_MAX);
02607 if (sync_err != SPLT_OK)
02608 {
02609 *error = sync_err;
02610 return;
02611 }
02612
02613 *error = SPLT_SYNC_OK;
02614
02615 return;
02616 }
02617
02618
02619
02620
02622 static const unsigned char splt_mp3_albumwraphead[22] =
02623 {
02624 0xa, 0x23, 0x54, 0x49, 0x54, 0x32, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x41, 0x6c, 0x62, 0x75, 0x6d, 0x57, 0x72, 0x61, 0x70,
02625 };
02626
02632 static void splt_mp3_dewrap(int listonly, const char *dir, int *error, splt_state *state)
02633 {
02634 if (listonly)
02635 {
02636 *error = SPLT_OK;
02637 }
02638 else
02639 {
02640 *error = SPLT_DEWRAP_OK;
02641 }
02642
02643
02644 short albumwrap=0, mp3wrap=0;
02645
02646 int wrapfiles=0, i, j, k=0;
02647 unsigned char c;
02648 char filename[2048] = { '\0' };
02649 off_t begin=0, end=0, len = 0, id3offset = 0;
02650 char junk[2048] = { '\0' };
02651 char *file_to_dewrap = splt_t_get_filename_to_split(state);
02652
02653
02654 if (*error < 0)
02655 {
02656 return;
02657 }
02658 else
02659 {
02660 splt_mp3_state *mp3state = state->codec;
02661
02662 if (*error >= 0)
02663 {
02664 len = splt_io_get_file_length(state, mp3state->file_input, file_to_dewrap, error);
02665 if (error < 0) { return; }
02666
02667 id3offset = splt_mp3_getid3v2_end_offset(mp3state->file_input, 0);
02668
02669
02670 if (fseeko(mp3state->file_input, id3offset, SEEK_SET)==-1)
02671 {
02672 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED;
02673 return;
02674 }
02675
02676 splt_d_print_debug(state,"Searching for wrap string...\n");
02677
02678
02679
02680 for (i=0; i<16384; i++)
02681 {
02682 if (feof(mp3state->file_input))
02683 {
02684 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED;
02685 return;
02686 }
02687 if ((id3offset = ftello(mp3state->file_input))==-1)
02688 {
02689 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED;
02690 return;
02691 }
02692 if (fgetc(mp3state->file_input)=='W')
02693 if (fgetc(mp3state->file_input)=='R')
02694 if (fgetc(mp3state->file_input)=='A')
02695 if (fgetc(mp3state->file_input)=='P')
02696 {
02697 mp3wrap = 1;
02698 break;
02699 }
02700 }
02701
02702
02703
02704 if (!mp3wrap && (id3offset!=0))
02705 {
02706 if (fseeko(mp3state->file_input, (off_t) 8, SEEK_SET)==-1)
02707 {
02708 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED;
02709 return;
02710 }
02711 albumwrap = 1;
02712 for (i=0; i<22; i++)
02713 {
02714 if (splt_mp3_albumwraphead[i]!=fgetc(mp3state->file_input))
02715 {
02716 albumwrap = 0;
02717 break;
02718 }
02719 }
02720 }
02721
02722
02723 if (albumwrap || mp3wrap)
02724 {
02725 splt_d_print_debug(state,"Effective dewrap...\n");
02726
02727
02728 if (mp3wrap) {
02729 splt_d_print_debug(state,"Mp3 mp3wrap check...\n");
02730 short indexver;
02731
02732
02733 char major_v = fgetc(mp3state->file_input);
02734 char minor_v = fgetc(mp3state->file_input);
02735
02736 splt_c_put_info_message_to_client(state,
02737 _(" Detected file created with: Mp3Wrap v. %c.%c\n"),
02738 major_v,minor_v);
02739
02740 indexver = fgetc(mp3state->file_input);
02741 if (indexver > SPLT_MP3_INDEXVERSION)
02742 {
02743 *error = SPLT_DEWRAP_ERR_VERSION_OLD;
02744 return;
02745 }
02746 wrapfiles = (int) fgetc(mp3state->file_input);
02747 if (feof(mp3state->file_input))
02748 {
02749 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED;
02750 return;
02751 }
02752
02753 if (indexver > 0x0)
02754 {
02755 unsigned long crc = 0, fcrc = 0;
02756 if (splt_io_get_word(mp3state->file_input, 0, SEEK_CUR, &fcrc)==-1)
02757 {
02758 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED;
02759 return;
02760 }
02761
02762
02763 if (! splt_o_get_int_option(state, SPLT_OPT_QUIET_MODE))
02764 {
02765 begin = ftello(mp3state->file_input);
02766 if (fseeko(mp3state->file_input,
02767 splt_mp3_getid3v1_offset(mp3state->file_input), SEEK_END)==-1)
02768 {
02769 splt_e_set_strerror_msg_with_data(state, file_to_dewrap);
02770 *error = SPLT_ERROR_SEEKING_FILE;
02771 return;
02772 }
02773 end = ftello(mp3state->file_input);
02774 splt_c_put_info_message_to_client(state,
02775 _(" Check for file integrity: calculating CRC please wait... "));
02776 crc = splt_mp3_c_crc(state, mp3state->file_input, begin, end, error);
02777 if (*error < 0)
02778 {
02779 return;
02780 }
02781 if (crc != fcrc)
02782 {
02783
02784
02785
02786
02787
02788
02789 *error = SPLT_ERROR_CRC_FAILED;
02790 return;
02791 }
02792 else
02793 {
02794 splt_c_put_info_message_to_client(state, _(" OK\n"));
02795 }
02796 if (fseeko(mp3state->file_input, begin, SEEK_SET)==-1)
02797 {
02798 splt_e_set_strerror_msg_with_data(state, file_to_dewrap);
02799 *error = SPLT_ERROR_SEEKING_FILE;
02800 return;
02801 }
02802 }
02803 }
02804 }
02805
02806
02807
02808 if (albumwrap)
02809 {
02810 splt_d_print_debug(state,"Mp3 albumwrap check...\n");
02811
02812 splt_c_put_info_message_to_client(state,
02813 _(" Detected file created with: AlbumWrap\n"));
02814
02815 if (fseeko(mp3state->file_input, (off_t) 0x52d, SEEK_SET)==-1)
02816 {
02817 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED;
02818 return;
02819 }
02820 i = 0;
02821 while (((c=fgetc(mp3state->file_input))!=0x20) &&(i<2048))
02822 junk[i++] = c;
02823 junk[i] = '\0';
02824 wrapfiles = atoi (junk);
02825 }
02826 if (wrapfiles<=0)
02827 {
02828 *error = SPLT_DEWRAP_ERR_NO_FILE_OR_BAD_INDEX;
02829 return;
02830 }
02831
02832
02833 state->split.splitnumber = wrapfiles+1;
02834
02835 splt_c_put_info_message_to_client(state, _(" Total files: %d\n"),wrapfiles);
02836
02837
02838 for (i=0; i<wrapfiles; i++)
02839 {
02840 if (!splt_t_split_is_canceled(state))
02841 {
02842
02843 splt_t_set_current_split(state, i+1);
02844
02845
02846
02847 if (i==0)
02848 {
02849
02850 if (mp3wrap)
02851 {
02852 unsigned long w;
02853 if (splt_io_get_word (mp3state->file_input, 0, SEEK_CUR, &w)==-1)
02854 {
02855 splt_e_set_error_data(state,file_to_dewrap);
02856 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
02857 return;
02858 }
02859 begin = (off_t) (w + id3offset);
02860 }
02861
02862
02863 if (albumwrap)
02864 {
02865 if (fseeko (mp3state->file_input,
02866 (off_t) SPLT_MP3_ABWINDEXOFFSET, SEEK_SET)==-1)
02867 {
02868 splt_e_set_error_data(state,file_to_dewrap);
02869 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
02870 return;
02871 }
02872 j = 0;
02873 while ((c=fgetc(mp3state->file_input))!='[')
02874 if (j++ > 32)
02875 {
02876 splt_e_set_error_data(state,file_to_dewrap);
02877 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
02878 return;
02879 }
02880 if (fseeko(mp3state->file_input, (off_t) 3, SEEK_CUR)==-1)
02881 {
02882 splt_e_set_error_data(state,file_to_dewrap);
02883 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
02884 return;
02885 }
02886 j = 0;
02887 while ((j<2048) && ((c = fgetc(mp3state->file_input))!='['))
02888 if (c!='.') junk[j++] = c;
02889 else k = j;
02890 junk[j] = '\0';
02891 begin = (off_t) atol (junk);
02892 k = j - k;
02893 if (k<4)
02894 {
02895 for (j=0; j<(4-k); j++)
02896 {
02897 begin = begin * 10;
02898 }
02899 }
02900 }
02901 }
02902 else
02903 {
02904 begin = end;
02905 }
02906
02907
02908 if (mp3wrap)
02909 {
02910 unsigned long w;
02911 j = 0;
02912 do
02913 {
02914 c = fgetc(mp3state->file_input);
02915
02916 if (c==SPLT_NDIRCHAR)
02917 {
02918 c=SPLT_DIRCHAR;
02919 }
02920 filename[j++] = c;
02921 } while ((c!=0x00)&&(j<2048));
02922
02923 if (splt_io_get_word (mp3state->file_input, 0, SEEK_CUR, &w) == -1)
02924 {
02925 splt_e_set_error_data(state,file_to_dewrap);
02926 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
02927 return;
02928 }
02929
02930 end = (off_t) (w + id3offset);
02931
02932
02933
02934
02935 if (!listonly && (!dir || dir[0] == '\0'))
02936 {
02937 memset(junk, 0x00, 2048);
02938 char *ptr = filename;
02939 while (((ptr = strchr(ptr, SPLT_DIRCHAR))!=NULL)&&((ptr-filename)<2048))
02940 {
02941 ptr++;
02942 strncpy(junk, filename, ptr-filename);
02943 if (! splt_io_check_if_directory(junk))
02944 {
02945 if ((splt_io_mkdir(state, junk)) == -1)
02946 {
02947 *error = SPLT_ERROR_CANNOT_CREATE_DIRECTORY;
02948 splt_e_set_strerror_msg_with_data(state, junk);
02949 return;
02950 }
02951 }
02952 }
02953 }
02954 }
02955
02956
02957
02958 if (albumwrap)
02959 {
02960 if (i<wrapfiles-1)
02961 {
02962 if (fseeko (mp3state->file_input,
02963 (off_t) (SPLT_MP3_ABWINDEXOFFSET + (i * SPLT_MP3_ABWLEN)), SEEK_SET)==-1)
02964 {
02965 splt_e_set_error_data(state,file_to_dewrap);
02966 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
02967 return;
02968 }
02969 j = 0;
02970 while ((j<2048) && ((c = fgetc(mp3state->file_input))!='['))
02971 if (c!='.') junk[j++] = c;
02972 else k = j;
02973 junk[j] = '\0';
02974 end = (off_t) atol (junk);
02975 k = j - k;
02976 if (k<4)
02977 for (j=0; j<(4-k); j++)
02978 end = end * 10;
02979 end += begin;
02980 }
02981 else end = len;
02982
02983 if (fseeko (mp3state->file_input,
02984 (off_t) (SPLT_MP3_ABWINDEXOFFSET + (i*SPLT_MP3_ABWLEN)), SEEK_SET)==-1)
02985 {
02986 splt_e_set_error_data(state,file_to_dewrap);
02987 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
02988 }
02989 j = 0;
02990 while ((c=fgetc(mp3state->file_input))!='[')
02991 if (j++ > 32)
02992 {
02993 splt_e_set_error_data(state,file_to_dewrap);
02994 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
02995 return;
02996 }
02997 if (fseeko (mp3state->file_input, (off_t) 3, SEEK_CUR)==-1)
02998 {
02999 splt_e_set_error_data(state,file_to_dewrap);
03000 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
03001 return;
03002 }
03003 j = 0;
03004 while ((c=fgetc(mp3state->file_input))!='[')
03005 if (j++ > 32)
03006 {
03007 splt_e_set_error_data(state,file_to_dewrap);
03008 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
03009 return;
03010 }
03011 if (fseeko(mp3state->file_input, (off_t) 3, SEEK_CUR)==-1)
03012 {
03013 splt_e_set_error_data(state,file_to_dewrap);
03014 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
03015 return;
03016 }
03017 j = 0;
03018 while (j<=400)
03019 filename[j++] = fgetc(mp3state->file_input);
03020 for (j=400; j>0; j--) {
03021 if (filename[j]==0x20)
03022 filename[j]='\0';
03023 else break;
03024 }
03025 filename[j+1] = '\0';
03026 }
03027
03028 splt_d_print_debug(state,"Found the file _%s_\n", filename);
03029 splt_d_print_debug(state,"Cut the dirchar");
03030
03031
03032 char str_temp[4];
03033 snprintf(str_temp,4,"%c%c",'.',SPLT_DIRCHAR);
03034 if (strstr(filename,str_temp) != NULL)
03035 {
03036 char *filename2 = strdup(filename);
03037 if (!filename2)
03038 {
03039 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
03040 return;
03041 }
03042 else
03043 {
03044 snprintf(filename,2048, "%s", filename2+2);
03045 free(filename2);
03046 filename2 = NULL;
03047 }
03048 }
03049
03050 if (feof(mp3state->file_input))
03051 {
03052 splt_e_set_error_data(state,file_to_dewrap);
03053 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE;
03054 return;
03055 }
03056
03057
03058
03059 if (listonly)
03060 {
03061 splt_d_print_debug(state,"Only list wrapped files\n");
03062
03063 int put_file_error = SPLT_OK;
03064 put_file_error = splt_w_wrap_put_file(state, wrapfiles, i, filename);
03065 if (put_file_error != SPLT_OK)
03066 {
03067 *error = put_file_error;
03068 return;
03069 }
03070 }
03071
03072
03073 else
03074 {
03075 splt_d_print_debug(state,"Split wrapped file\n");
03076
03077 int ret = 0;
03078
03079
03080 if (dir && (dir[0] != '\0'))
03081 {
03082 char temp[2048] = { '\0' };
03083 strncpy(temp, filename, 2048);
03084 char *ptr = temp;
03085
03086 if ((ptr = strrchr(temp,SPLT_DIRCHAR)) == NULL)
03087 {
03088 ptr = temp;
03089 }
03090 else
03091 {
03092 if (ptr-temp > 0)
03093 {
03094 ptr++;
03095 }
03096 }
03097
03098 if (strcmp(dir,str_temp) == 0)
03099 {
03100 snprintf(filename, 2048,"%s%s", dir, ptr);
03101 }
03102 else
03103 {
03104 if (dir[strlen(dir)-1] == SPLT_DIRCHAR)
03105 {
03106 snprintf(filename, 2048,"%s%s", dir, ptr);
03107 }
03108 else
03109 {
03110 snprintf(filename, 2048,"%s%c%s", dir, SPLT_DIRCHAR, ptr);
03111 }
03112 }
03113 splt_d_print_debug(state,"wrap dir _%s_\n", dir);
03114 splt_d_print_debug(state,"wrap after dir _%s_\n", ptr);
03115 }
03116
03117
03118 if (mp3state->mp3file.xingbuffer)
03119 {
03120 free(mp3state->mp3file.xingbuffer);
03121 mp3state->mp3file.xingbuffer = NULL;
03122 }
03123 mp3state->mp3file.xing = 0;
03124
03125 int append_err = SPLT_OK;
03126 append_err = splt_sp_append_splitpoint(state,0,
03127 splt_su_get_fname_without_path(filename), SPLT_SPLITPOINT);
03128 if (append_err != SPLT_OK)
03129 {
03130 *error = append_err;
03131 return;
03132 }
03133
03134
03135 int cut_err = splt_sp_cut_splitpoint_extension(state,i);
03136 if (cut_err != SPLT_OK)
03137 {
03138 *error = cut_err;
03139 return;
03140 }
03141
03142
03143 ret = splt_mp3_simple_split(state, filename, begin, end,
03144 SPLT_FALSE, SPLT_FALSE);
03145
03146
03147 if (ret >= 0)
03148 {
03149 ret = splt_c_put_split_file(state, filename);
03150 if (ret < 0) { *error = ret; }
03151 }
03152 else
03153 {
03154 *error = ret;
03155 }
03156 }
03157 }
03158 }
03159 }
03160 else
03161 {
03162 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED;
03163 return;
03164 }
03165 }
03166 }
03167 }
03168
03170 void splt_mp3_init(splt_state *state, int *error)
03171 {
03172 FILE *file_input = NULL;
03173 char *filename = splt_t_get_filename_to_split(state);
03174
03175 state->syncerrors = 0;
03176
03177 if ((file_input = splt_mp3_open_file_read(state, filename, error)) == NULL)
03178 {
03179 return;
03180 }
03181
03182 splt_mp3_get_info(state, file_input, error);
03183
03184 if (*error >= 0)
03185 {
03186 splt_mp3_state *mp3state = state->codec;
03187 mp3state->off = splt_o_get_float_option(state, SPLT_OPT_PARAM_OFFSET);
03188
03189 if (splt_t_get_total_time(state) > 0)
03190 {
03191 mp3state->frames = 1;
03192 }
03193 }
03194 }
03195
03208 void splt_pl_set_plugin_info(splt_plugin_info *info, int *error)
03209 {
03210 float plugin_version = 1.0;
03211
03212
03213 info->version = plugin_version;
03214
03215
03216 info->name = malloc(sizeof(char) * 40);
03217 if (info->name != NULL)
03218 {
03219 snprintf(info->name, 39, "mp3 (libmad)");
03220 }
03221 else
03222 {
03223 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
03224 return;
03225 }
03226
03227
03228 info->extension = malloc(sizeof(char) * (strlen(SPLT_MP3EXT)+2));
03229 if (info->extension != NULL)
03230 {
03231 snprintf(info->extension, strlen(SPLT_MP3EXT)+1, SPLT_MP3EXT);
03232 }
03233 else
03234 {
03235 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY;
03236 return;
03237 }
03238
03239 info->upper_extension = splt_su_convert(info->extension, SPLT_TO_UPPERCASE, error);
03240 }
03241
03243 void splt_pl_init(splt_state *state, int *error)
03244 {
03245 if (splt_io_input_is_stdin(state))
03246 {
03247 char *filename = splt_t_get_filename_to_split(state);
03248 if (filename[1] == '\0')
03249 {
03250 splt_c_put_info_message_to_client(state,
03251 _(" warning: stdin '-' is supposed to be mp3 stream.\n"));
03252 }
03253 }
03254
03255 splt_mp3_init(state, error);
03256 }
03257
03259 void splt_pl_end(splt_state *state, int *error)
03260 {
03261
03262
03263 if ((splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_SILENCE_MODE)
03264 && (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_TRIM_SILENCE_MODE)
03265 && (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_ERROR_MODE)
03266 && (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_WRAP_MODE))
03267 {
03268 if (splt_o_get_int_option(state, SPLT_OPT_FRAME_MODE))
03269 {
03270 if (*error >= 0)
03271 {
03272 splt_mp3_state *mp3state = state->codec;
03273
03274
03275 if (mp3state->frames != 1)
03276 {
03277 splt_c_put_info_message_to_client(state,
03278 _(" Processed %lu frames - Sync errors: %lu\n"),
03279 mp3state->frames, state->syncerrors);
03280 }
03281 }
03282 }
03283 }
03284 splt_mp3_end(state, error);
03285 }
03286
03288 int splt_pl_check_plugin_is_for_file(splt_state *state, int *error)
03289 {
03290 char *filename = splt_t_get_filename_to_split(state);
03291
03292 if (filename != NULL && ((strcmp(filename,"-") == 0) ||
03293 (strcmp(filename,"m-") == 0)))
03294 {
03295 return SPLT_TRUE;
03296 }
03297
03298 int is_mp3 = SPLT_FALSE;
03299
03300 splt_o_lock_messages(state);
03301 splt_mp3_init(state, error);
03302 splt_o_unlock_messages(state);
03303 if (*error >= 0)
03304 {
03305 splt_mp3_state *mp3state = state->codec;
03306 if (mp3state)
03307 {
03308 is_mp3 = SPLT_TRUE;
03309 }
03310 }
03311 splt_mp3_end(state, error);
03312
03313 return is_mp3;
03314 }
03315
03317 void splt_pl_search_syncerrors(splt_state *state, int *error)
03318 {
03319
03320 splt_mp3_syncerror_search(state, error);
03321 }
03322
03324 void splt_pl_dewrap(splt_state *state, int listonly, const char *dir, int *error)
03325 {
03326 splt_w_wrap_free(state);
03327 splt_mp3_dewrap(listonly, dir, error, state);
03328 }
03329
03330 double splt_pl_split(splt_state *state, const char *final_fname,
03331 double begin_point, double end_point, int *error, int save_end_point)
03332 {
03333 return splt_mp3_split(final_fname, state, begin_point, end_point, error, save_end_point);
03334 }
03335
03337 int splt_pl_simple_split(splt_state *state, char *output_fname, off_t begin, off_t end)
03338 {
03339 int error = SPLT_OK;
03340
03341 splt_mp3_state *mp3state = state->codec;
03342
03343
03344 if (splt_t_get_total_time(state) > 0)
03345 {
03346 mp3state->frames = 1;
03347 }
03348
03349
03350 error = splt_mp3_simple_split(state, output_fname, begin, end,
03351 SPLT_FALSE, SPLT_FALSE);
03352
03353 return error;
03354 }
03355
03357 int splt_pl_scan_silence(splt_state *state, int *error)
03358 {
03359 float offset = splt_o_get_float_option(state,SPLT_OPT_PARAM_OFFSET);
03360 float threshold = splt_o_get_float_option(state, SPLT_OPT_PARAM_THRESHOLD);
03361 float min_length = splt_o_get_float_option(state, SPLT_OPT_PARAM_MIN_LENGTH);
03362 int shots = splt_o_get_int_option(state, SPLT_OPT_PARAM_SHOTS);
03363
03364 splt_mp3_state *mp3state = state->codec;
03365 mp3state->off = offset;
03366
03367 int found = splt_mp3_scan_silence(state, mp3state->mp3file.firsthead.ptr, 0,
03368 threshold, min_length, shots, 1, error, splt_scan_silence_processor);
03369 if (*error < 0) { return -1; }
03370
03371 return found;
03372 }
03373
03375 int splt_pl_scan_trim_silence(splt_state *state, int *error)
03376 {
03377 float threshold = splt_o_get_float_option(state, SPLT_OPT_PARAM_THRESHOLD);
03378 int shots = splt_o_get_int_option(state, SPLT_OPT_PARAM_SHOTS);
03379
03380 splt_mp3_state *mp3state = state->codec;
03381
03382 int found = splt_mp3_scan_silence(state, mp3state->mp3file.firsthead.ptr, 0,
03383 threshold, 0, shots, 1, error, splt_trim_silence_processor);
03384 if (*error < 0) { return -1; }
03385
03386 return found;
03387 }
03388
03390 void splt_pl_set_original_tags(splt_state *state, int *error)
03391 {
03392 splt_d_print_debug(state, "Getting original tags ...");
03393 #ifndef NO_ID3TAG
03394 splt_d_print_debug(state, "Taking original ID3 tags from file using libid3tag ...\n");
03395 splt_mp3_get_original_tags(splt_t_get_filename_to_split(state), state, error);
03396 #else
03397 splt_d_print_debug(state, "Warning ! NO_ID3TAG");
03398
03399 #endif
03400 }
03401
03402 void splt_pl_clear_original_tags(splt_original_tags *original_tags)
03403 {
03404 #ifndef NO_ID3TAG
03405 tag_bytes_and_size *bytes_and_size = (tag_bytes_and_size *) original_tags->all_original_tags;
03406
03407 if (!bytes_and_size) {
03408 return;
03409 }
03410
03411 if (bytes_and_size->tag_bytes)
03412 {
03413 free(bytes_and_size->tag_bytes);
03414 bytes_and_size->tag_bytes = NULL;
03415 }
03416
03417 bytes_and_size->tag_length = 0;
03418
03419 free(original_tags->all_original_tags);
03420 original_tags->all_original_tags = NULL;
03421 #endif
03422 }
03423