libmp3splt
|
00001 /********************************************************** 00002 * libmp3splt -- library based on mp3splt, 00003 * for mp3/ogg splitting without decoding 00004 * 00005 * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net> 00006 * Copyright (c) 2005-2011 Alexandru Munteanu - io_fx@yahoo.fr 00007 * 00008 *********************************************************/ 00009 00010 /********************************************************** 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software 00023 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00024 * 02111-1307, 00025 * USA. 00026 *********************************************************/ 00032 #include <string.h> 00033 #include <unistd.h> 00034 #include <sys/stat.h> 00035 #include <dirent.h> 00036 #include <math.h> 00037 #include <ctype.h> 00038 00039 #ifdef __WIN32__ 00040 #include <io.h> 00041 #include <fcntl.h> 00042 #endif 00043 00044 #include "splt.h" 00045 #include "mp3.h" 00046 00047 /****************************/ 00048 /* mp3 constants */ 00049 00054 static const char *splt_mp3_chan[] = 00055 { 00056 "Mono", 00057 "Dual Mono", 00058 "Joint Stereo", 00059 "Stereo", 00060 "?" 00061 }; 00062 00064 static const int splt_mp3_tabsel_123[2][3][16] = { 00065 { {128,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, 00066 {128,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, 00067 {128,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} }, 00068 00069 { {128,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, 00070 {128,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, 00071 {128,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} } 00072 }; 00073 00077 static const unsigned long splt_mp3_crctab[256] = { 00078 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 00079 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, 00080 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 00081 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 00082 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 00083 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 00084 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 00085 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, 00086 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 00087 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 00088 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 00089 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 00090 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 00091 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, 00092 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 00093 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 00094 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 00095 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 00096 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 00097 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, 00098 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 00099 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 00100 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 00101 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 00102 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 00103 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 00104 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 00105 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 00106 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 00107 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 00108 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 00109 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 00110 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 00111 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 00112 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 00113 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 00114 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 00115 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, 00116 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 00117 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 00118 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 00119 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 00120 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 00121 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, 00122 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 00123 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 00124 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 00125 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 00126 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 00127 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, 00128 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 00129 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 00130 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 00131 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 00132 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 00133 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 00134 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 00135 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 00136 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 00137 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 00138 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 00139 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, 00140 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 00141 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d, 00142 }; 00143 00144 static void splt_mp3_save_end_point(splt_state *state, splt_mp3_state *mp3state, 00145 int save_end_point, off_t end) 00146 { 00147 if (save_end_point) 00148 { 00149 mp3state->end = end; 00150 } 00151 else 00152 { 00153 mp3state->end = 0; 00154 } 00155 } 00156 00164 static FILE *splt_mp3_open_file_read(splt_state *state, const char *filename, 00165 int *error) 00166 { 00167 FILE *file_input = NULL; 00168 00169 if (filename != NULL && ((strcmp(filename,"-") == 0) || 00170 (strcmp(filename,"m-") == 0))) 00171 { 00172 file_input = stdin; 00173 #ifdef __WIN32__ 00174 _setmode(fileno(file_input), _O_BINARY); 00175 #endif 00176 } 00177 else 00178 { 00179 file_input = splt_io_fopen(filename, "rb"); 00180 if (file_input == NULL) 00181 { 00182 splt_e_set_strerror_msg_with_data(state, filename); 00183 *error = SPLT_ERROR_CANNOT_OPEN_FILE; 00184 } 00185 } 00186 00187 return file_input; 00188 } 00189 00193 static FILE *splt_mp3_open_file_write(splt_state *state, const char *output_fname, int *error) 00194 { 00195 FILE *file_output = NULL; 00196 00197 //for the stdout 00198 if (strcmp(output_fname, "-")==0) 00199 { 00200 file_output = stdout; 00201 #ifdef __WIN32__ 00202 _setmode(fileno(file_output), _O_BINARY); 00203 #endif 00204 } 00205 else 00206 { 00207 if (!(file_output = splt_io_fopen(output_fname, "wb+"))) 00208 { 00209 splt_e_set_strerror_msg_with_data(state, output_fname); 00210 *error = SPLT_ERROR_CANNOT_OPEN_DEST_FILE; 00211 } 00212 } 00213 00214 return file_output; 00215 } 00216 00217 00218 /****************************/ 00219 /* CRC functions */ 00220 00222 static unsigned long splt_mp3_c_crc(splt_state *state, 00223 FILE *in, off_t begin, off_t end, int *error) 00224 { 00225 register unsigned long crc; 00226 int c; 00227 00228 crc = 0xFFFFFFFF; 00229 00230 if (fseeko(in, begin, SEEK_SET) == -1) 00231 { 00232 splt_e_set_strerror_msg_with_data(state, splt_t_get_filename_to_split(state)); 00233 *error = SPLT_ERROR_SEEKING_FILE; 00234 return 0; 00235 } 00236 00237 while(begin++ < end) 00238 { 00239 c = fgetc(in); 00240 crc = ((crc >> 8) & 0x00FFFFFF) ^ splt_mp3_crctab[(crc ^ c) & 0xFF]; 00241 } 00242 00243 return (crc ^ 0xFFFFFFFF); 00244 } 00245 00246 /****************************/ 00247 /* mp3 utils */ 00248 00250 static void splt_mp3_init_stream_frame(splt_mp3_state *mp3state) 00251 { 00252 mad_stream_init(&mp3state->stream); 00253 mad_frame_init(&mp3state->frame); 00254 } 00255 00257 static void splt_mp3_finish_stream_frame(splt_mp3_state *mp3state) 00258 { 00259 mad_stream_finish(&mp3state->stream); 00260 mad_frame_finish(&mp3state->frame); 00261 } 00262 00267 static void splt_mp3_checksync (splt_mp3_state *mp3state) 00268 { 00269 //char junk[32]; 00270 //fprintf(stderr, "\nWarning: Too many sync errors! This may not be a mp3 file. Continue? (y/n) "); 00271 //fgets(junk, 31, stdin); 00272 //if (junk[0]=='y') 00273 00274 //we don't use user interactivity in a library 00275 //always continue 00276 mp3state->syncdetect = 0; 00277 00278 //else error("Aborted.",125); 00279 } 00280 00282 static int splt_mp3_c_bitrate (unsigned long head) 00283 { 00284 if ((head & 0xffe00000) != 0xffe00000) return 0; 00285 if (!((head>>17)&3)) return 0; 00286 if (((head>>12)&0xf) == 0xf) return 0; 00287 if (!((head >> 12) & 0xf)) return 0; 00288 if (((head>>10)&0x3) == 0x3 ) return 0; 00289 if (((head >> 19) & 1)==1 && ((head>>17)&3)==3 && 00290 ((head>>16)&1)==1) return 0; 00291 if ((head & 0xffff0000) == 0xfffe0000) return 0; 00292 00293 return ((head>>12)&0xf); 00294 } 00295 00297 static struct splt_header splt_mp3_makehead (unsigned long headword, 00298 struct splt_mp3 mp3f, struct splt_header head, off_t ptr) 00299 { 00300 head.ptr = ptr; 00301 head.bitrate = splt_mp3_tabsel_123[1 - mp3f.mpgid][mp3f.layer-1][splt_mp3_c_bitrate(headword)]; 00302 head.padding = ((headword>>9)&0x1); 00303 head.framesize = (head.bitrate*144000)/ 00304 (mp3f.freq<<(1 - mp3f.mpgid)) + head.padding; 00305 00306 return head; 00307 } 00308 00310 static off_t splt_mp3_findhead (splt_mp3_state *mp3state, off_t start) 00311 { 00312 if (splt_io_get_word(mp3state->file_input, 00313 start, SEEK_SET, &mp3state->headw) == -1) 00314 { 00315 return -1; 00316 } 00317 if (feof(mp3state->file_input)) 00318 { 00319 return -1; 00320 } 00321 while (!(splt_mp3_c_bitrate(mp3state->headw))) 00322 { 00323 if (feof(mp3state->file_input)) 00324 { 00325 return -1; 00326 } 00327 mp3state->headw <<= 8; 00328 mp3state->headw |= fgetc(mp3state->file_input); 00329 start++; 00330 } 00331 00332 return start; 00333 } 00334 00336 static off_t splt_mp3_findvalidhead (splt_mp3_state *mp3state, off_t start) 00337 { 00338 off_t begin; 00339 struct splt_header h; 00340 00341 begin = splt_mp3_findhead(mp3state, start); 00342 00343 do { 00344 start = begin; 00345 if (start == -1) 00346 { 00347 break; 00348 } 00349 h = splt_mp3_makehead (mp3state->headw, mp3state->mp3file, h, start); 00350 begin = splt_mp3_findhead(mp3state, (start + 1)); 00351 } while (begin!=(start + h.framesize)); 00352 00353 return start; 00354 } 00355 00357 static int splt_mp3_xing_info_off(splt_mp3_state *mp3state) 00358 { 00359 unsigned long headw = 0; 00360 int i; 00361 00362 for (i=0; i<mp3state->mp3file.xing; i++) 00363 { 00364 if ((headw == SPLT_MP3_XING_MAGIC) || 00365 (headw == SPLT_MP3_INFO_MAGIC)) // "Xing" or "Info" 00366 { 00367 return i; 00368 } 00369 headw <<= 8; 00370 headw |= mp3state->mp3file.xingbuffer[i]; 00371 } 00372 00373 return 0; 00374 } 00375 00380 static int splt_mp3_get_frame(splt_mp3_state *mp3state) 00381 { 00382 if(mp3state->stream.buffer==NULL || 00383 mp3state->stream.error==MAD_ERROR_BUFLEN) 00384 { 00385 size_t readSize, remaining; 00386 unsigned char *readStart; 00387 00388 if (feof(mp3state->file_input)) 00389 { 00390 return -2; 00391 } 00392 00393 if(mp3state->stream.next_frame!=NULL) 00394 { 00395 remaining = mp3state->stream.bufend - mp3state->stream.next_frame; 00396 memmove(mp3state->inputBuffer, mp3state->stream.next_frame, remaining); 00397 readStart = mp3state->inputBuffer + remaining; 00398 readSize = SPLT_MAD_BSIZE - remaining; 00399 } 00400 else 00401 { 00402 readSize = SPLT_MAD_BSIZE; 00403 readStart=mp3state->inputBuffer; 00404 remaining=0; 00405 } 00406 00407 readSize=fread(readStart, 1, readSize, mp3state->file_input); 00408 if (readSize <= 0) 00409 { 00410 return -2; 00411 } 00412 00413 mp3state->buf_len = readSize + remaining; 00414 mp3state->bytes += readSize; 00415 //does not set any error 00416 mad_stream_buffer(&mp3state->stream, mp3state->inputBuffer, 00417 readSize+remaining); 00418 mp3state->stream.error = MAD_ERROR_NONE; 00419 } 00420 00421 //mad_frame_decode() returns -1 if error, 0 if no error 00422 return mad_frame_decode(&mp3state->frame,&mp3state->stream); 00423 } 00424 00442 static int splt_mp3_get_valid_frame(splt_state *state, int *error) 00443 { 00444 splt_mp3_state *mp3state = state->codec; 00445 int ok = 0; 00446 do 00447 { 00448 int ret = splt_mp3_get_frame(mp3state); 00449 if(ret != 0) 00450 { 00451 if (ret == -2) 00452 { 00453 return -1; 00454 } 00455 if (mp3state->stream.error == MAD_ERROR_LOSTSYNC) 00456 { 00457 //syncerrors 00458 state->syncerrors++; 00459 if ((mp3state->syncdetect) && (state->syncerrors>SPLT_MAXSYNC)) 00460 { 00461 splt_mp3_checksync(mp3state); 00462 } 00463 } 00464 if(MAD_RECOVERABLE(mp3state->stream.error)) 00465 { 00466 continue; 00467 } 00468 else 00469 { 00470 if(mp3state->stream.error==MAD_ERROR_BUFLEN) 00471 { 00472 continue; 00473 } 00474 else 00475 { 00476 splt_e_set_error_data(state, mad_stream_errorstr(&mp3state->stream)); 00477 *error = SPLT_ERROR_PLUGIN_ERROR; 00478 return -3; 00479 } 00480 } 00481 } 00482 else 00483 { 00484 //the important stuff 00485 mp3state->data_ptr = (unsigned char *) mp3state->stream.this_frame; 00486 if (mp3state->stream.next_frame!=NULL) 00487 { 00488 mp3state->data_len = (long) (mp3state->stream.next_frame - mp3state->stream.this_frame); 00489 } 00490 ok = 1; 00491 } 00492 00493 } while (!ok); 00494 00495 return ok; 00496 } 00497 00506 static int splt_mp3_getid3v1_offset(FILE *file_input) 00507 { 00508 if (fseeko(file_input, (off_t) -128, SEEK_END)==-1) 00509 { 00510 return 0; 00511 } 00512 00513 if (fgetc(file_input)=='T') 00514 if (fgetc(file_input)=='A') 00515 if (fgetc(file_input)=='G') 00516 return -128; 00517 00518 return 0; 00519 } 00520 00529 static off_t splt_mp3_getid3v2_end_offset(FILE *in, off_t start) 00530 { 00531 unsigned long oword = 0; 00532 if (fseeko(in, start, SEEK_SET)==-1) 00533 { 00534 return 0; 00535 } 00536 00537 if (fgetc(in)=='I') 00538 if (fgetc(in)=='D') 00539 if (fgetc(in)=='3') 00540 { 00541 int i; 00542 if (fseeko(in, (off_t) 3, SEEK_CUR)==-1) 00543 { 00544 return 0; 00545 } 00546 00547 for (i=0; i<4; i++) 00548 { 00549 oword = (oword << 7) | fgetc(in); 00550 } 00551 00552 return (off_t) (oword); 00553 } 00554 00555 return 0; 00556 } 00557 00562 static void splt_mp3_state_free(splt_state *state) 00563 { 00564 splt_mp3_state *mp3state = state->codec; 00565 00566 if (mp3state) 00567 { 00568 if (mp3state->mp3file.xingbuffer) 00569 { 00570 free(mp3state->mp3file.xingbuffer); 00571 mp3state->mp3file.xingbuffer = NULL; 00572 } 00573 00574 //we free the state 00575 free(mp3state); 00576 state->codec = NULL; 00577 } 00578 } 00579 00580 /****************************/ 00581 /* mp3 tags */ 00582 00583 #ifndef NO_ID3TAG 00584 00586 static id3_byte_t *splt_mp3_get_id3v2_tag_bytes(FILE *file, id3_length_t *length) 00587 { 00588 id3_byte_t *bytes = NULL; 00589 *length = 0; 00590 00591 off_t id3v2_end_offset = splt_mp3_getid3v2_end_offset(file, 0); 00592 00593 if (id3v2_end_offset != 0) 00594 { 00595 size_t id3v2_size = (size_t) (id3v2_end_offset + 10); 00596 00597 rewind(file); 00598 bytes = splt_io_fread(file, 1, id3v2_size); 00599 00600 if (! bytes) 00601 { 00602 return NULL; 00603 } 00604 00605 *length = (unsigned long) id3v2_size; 00606 } 00607 00608 return bytes; 00609 } 00610 00611 static id3_byte_t *splt_mp3_get_id3v1_tag_bytes(FILE *file, id3_length_t *length) 00612 { 00613 id3_byte_t *bytes = NULL; 00614 *length = 0; 00615 00616 off_t id3v1_offset = splt_mp3_getid3v1_offset(file); 00617 00618 if (id3v1_offset != 0) 00619 { 00620 if (fseeko(file, id3v1_offset, SEEK_END) !=-1) 00621 { 00622 bytes = malloc(sizeof(unsigned char) * 128); 00623 00624 if (! bytes) 00625 { 00626 return NULL; 00627 } 00628 00629 if (fread(bytes, 1 , 128, file) != 128) 00630 { 00631 if (bytes) 00632 { 00633 free(bytes); 00634 bytes = NULL; 00635 return NULL; 00636 } 00637 } 00638 else 00639 { 00640 *length = (unsigned long) 128; 00641 } 00642 } 00643 } 00644 00645 return bytes; 00646 } 00647 00657 static id3_byte_t *splt_mp3_get_id3_tag_bytes(splt_state *state, const char *filename, 00658 id3_length_t *length, int *error, int *tags_version) 00659 { 00660 *length = 0; 00661 id3_byte_t *bytes = NULL; 00662 00663 FILE *file = splt_io_fopen(filename, "rb"); 00664 00665 if (! file) 00666 { 00667 splt_e_set_strerror_msg_with_data(state, filename); 00668 *error = SPLT_ERROR_CANNOT_OPEN_FILE; 00669 goto end; 00670 } 00671 else 00672 { 00673 id3_length_t id3v1_length = 0; 00674 id3_byte_t *id3v1_bytes = splt_mp3_get_id3v1_tag_bytes(file, &id3v1_length); 00675 00676 id3_length_t id3v2_length = 0; 00677 id3_byte_t *id3v2_bytes = splt_mp3_get_id3v2_tag_bytes(file, &id3v2_length); 00678 00679 if (id3v2_bytes) 00680 { 00681 *tags_version = 2; 00682 bytes = id3v2_bytes; 00683 *length = id3v2_length; 00684 00685 if (id3v1_bytes) 00686 { 00687 *tags_version = 12; 00688 free(id3v1_bytes); 00689 id3v1_bytes = NULL; 00690 } 00691 } 00692 else if (id3v1_bytes) 00693 { 00694 *tags_version = 1; 00695 bytes = id3v1_bytes; 00696 *length = id3v1_length; 00697 } 00698 } 00699 00700 end: 00701 if (file) 00702 { 00703 if (fclose(file) != 0) 00704 { 00705 if (bytes) 00706 { 00707 free(bytes); 00708 bytes = NULL; 00709 } 00710 return NULL; 00711 } 00712 } 00713 00714 return bytes; 00715 } 00716 00718 static int splt_mp3_put_original_libid3_frame(splt_state *state, 00719 const struct id3_tag *id3tag, const char *frame_type, int id_type) 00720 { 00721 struct id3_frame *frame = NULL; 00722 union id3_field *field = NULL; 00723 id3_ucs4_t *ucs4 = NULL; 00724 id3_utf8_t *tag_value = NULL; 00725 00726 int err = SPLT_OK; 00727 00728 frame = id3_tag_findframe(id3tag, frame_type,0); 00729 if (frame != NULL) 00730 { 00731 if (id_type == SPLT_MP3_ID3_COMMENT) 00732 { 00733 field = id3_frame_field(frame, 3); 00734 ucs4 = (id3_ucs4_t *) id3_field_getfullstring(field); 00735 } 00736 else 00737 { 00738 field = id3_frame_field(frame, 1); 00739 ucs4 = (id3_ucs4_t *) id3_field_getstrings(field,0); 00740 } 00741 if (ucs4 != NULL) 00742 { 00743 tag_value = id3_ucs4_utf8duplicate(ucs4); 00744 00745 if (tag_value != NULL) 00746 { 00747 switch (id_type) 00748 { 00749 case SPLT_MP3_ID3_ALBUM: 00750 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_ALBUM, tag_value); 00751 break; 00752 case SPLT_MP3_ID3_ARTIST: 00753 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_ARTIST, tag_value); 00754 break; 00755 case SPLT_MP3_ID3_TITLE: 00756 if (strcmp(frame_type,ID3_FRAME_TITLE) == 0) 00757 { 00758 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_TITLE, tag_value); 00759 } 00760 break; 00761 case SPLT_MP3_ID3_YEAR: 00762 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_YEAR, tag_value); 00763 break; 00764 case SPLT_MP3_ID3_TRACK: 00765 ; 00766 int track = atoi((char *)tag_value); 00767 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_TRACK, &track); 00768 break; 00769 case SPLT_MP3_ID3_COMMENT: 00770 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_COMMENT, tag_value); 00771 break; 00772 case SPLT_MP3_ID3_GENRE: 00773 ; 00774 char *genre = (char *)tag_value; 00775 00776 int id3v1 = atoi(genre); 00777 if ((id3v1 != 0) && 00778 (id3v1 < SPLT_ID3V1_NUMBER_OF_GENRES) && 00779 (state->original_tags.genre == NULL)) 00780 { 00781 err = splt_tu_set_original_tags_field(state, SPLT_TAGS_GENRE, splt_id3v1_genres[id3v1]); 00782 } 00783 else if (strcmp(genre, "0") == 0) 00784 { 00785 err = splt_tu_set_original_tags_field(state, SPLT_TAGS_GENRE, SPLT_UNDEFINED_GENRE); 00786 } 00787 else 00788 { 00789 err = splt_tu_set_original_tags_field(state, SPLT_TAGS_GENRE, genre); 00790 } 00791 break; 00792 default: 00793 break; 00794 } 00795 free(tag_value); 00796 tag_value = NULL; 00797 } 00798 else 00799 { 00800 err = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY; 00801 } 00802 } 00803 } 00804 00805 return err; 00806 } 00807 00809 #define MP3_VERIFY_ERROR() \ 00810 if (err != SPLT_OK) \ 00811 { \ 00812 *tag_error = err; \ 00813 goto end; \ 00814 }; 00815 00821 static void splt_mp3_get_original_tags(const char *filename, 00822 splt_state *state, int *tag_error) 00823 { 00824 //we get the id3 from the original file using libid3tag 00825 struct id3_tag *id3tag = NULL; 00826 00827 //get out the tags from the file; id3_file_open doesn't work with win32 utf16 filenames 00828 id3_length_t id3_tag_length = 0; 00829 int tags_version = 0; 00830 id3_byte_t *id3_tag_bytes = 00831 splt_mp3_get_id3_tag_bytes(state, filename, &id3_tag_length, tag_error, 00832 &tags_version); 00833 00834 if (*tag_error >= 0) 00835 { 00836 if (id3_tag_bytes) 00837 { 00838 id3tag = id3_tag_parse(id3_tag_bytes, id3_tag_length); 00839 00840 if (id3tag) 00841 { 00842 int err = SPLT_OK; 00843 00844 err = splt_tu_set_original_tags_field(state,SPLT_TAGS_VERSION, &tags_version); 00845 MP3_VERIFY_ERROR(); 00846 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_ARTIST, 00847 SPLT_MP3_ID3_ARTIST); 00848 MP3_VERIFY_ERROR(); 00849 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_ALBUM, 00850 SPLT_MP3_ID3_ALBUM); 00851 MP3_VERIFY_ERROR(); 00852 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_TITLE, 00853 SPLT_MP3_ID3_TITLE); 00854 MP3_VERIFY_ERROR(); 00855 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_YEAR, 00856 SPLT_MP3_ID3_YEAR); 00857 MP3_VERIFY_ERROR(); 00858 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_GENRE, 00859 SPLT_MP3_ID3_GENRE); 00860 MP3_VERIFY_ERROR(); 00861 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_COMMENT, 00862 SPLT_MP3_ID3_COMMENT); 00863 MP3_VERIFY_ERROR(); 00864 err = splt_mp3_put_original_libid3_frame(state,id3tag,ID3_FRAME_TRACK, 00865 SPLT_MP3_ID3_TRACK); 00866 MP3_VERIFY_ERROR(); 00867 00868 id3_tag_delete(id3tag); 00869 } 00870 } 00871 00872 end: 00873 ; 00874 } 00875 00876 if (id3_tag_bytes) 00877 { 00878 free(id3_tag_bytes); 00879 id3_tag_bytes = NULL; 00880 } 00881 } 00882 00884 void splt_mp3_put_libid3_frame_in_tag_with_content(struct id3_tag *id, 00885 const char *frame_type, int field_number, const char *content, int *error) 00886 { 00887 struct id3_frame *id_frame = NULL; 00888 id3_ucs4_t *field_content = NULL; 00889 union id3_field *id_field = NULL; 00890 00891 if (content) 00892 { 00893 id_frame = id3_frame_new(frame_type); 00894 if (!id_frame) 00895 { 00896 goto error; 00897 } 00898 00899 id_field = id3_frame_field(id_frame, field_number); 00900 00901 id3_field_settextencoding(id3_frame_field(id_frame, 0), 00902 ID3_FIELD_TEXTENCODING_UTF_16); 00903 00904 field_content = id3_utf8_ucs4duplicate((signed char *)content); 00905 if (! field_content) 00906 { 00907 goto error; 00908 } 00909 00910 //1 is usually a string list 00911 if (field_number == 1) 00912 { 00913 if (id3_field_addstring(id_field, field_content) == -1) 00914 { 00915 goto error; 00916 } 00917 } 00918 //the comment is a full string: field number 3 00919 else if (field_number == 3) 00920 { 00921 if (id3_field_setfullstring(id_field, field_content) == -1) 00922 { 00923 goto error; 00924 } 00925 } 00926 if (field_content) 00927 { 00928 free(field_content); 00929 field_content = NULL; 00930 } 00931 if (id3_tag_attachframe(id, id_frame) == -1) 00932 { 00933 goto error; 00934 } 00935 id3_frame_delete(id_frame); 00936 } 00937 00938 return; 00939 00940 error: 00941 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY; 00942 if (id_frame) 00943 { 00944 id3_frame_delete(id_frame); 00945 } 00946 if (field_content) 00947 { 00948 free(field_content); 00949 field_content = NULL; 00950 } 00951 return; 00952 } 00953 00954 static char *splt_mp3_build_libid3tag(const char *title, const char *artist, 00955 const char *album, const char *year, const char *genre, 00956 const char *comment, int track, int *error, unsigned long *number_of_bytes, 00957 int tags_version) 00958 { 00959 struct id3_tag *id = id3_tag_new(); 00960 00961 id3_byte_t *bytes = NULL; 00962 id3_length_t bytes_length = 0; 00963 00964 if (tags_version == 1) 00965 { 00966 id3_tag_options(id, ID3_TAG_OPTION_ID3V1, ID3_TAG_OPTION_ID3V1); 00967 } 00968 else 00969 { 00970 //turn off CRC and COMPRESSION; many players don't support that ?, 00971 //resulting in No tags (oh !) 00972 id3_tag_options(id, ID3_TAG_OPTION_CRC, 0); 00973 id3_tag_options(id, ID3_TAG_OPTION_COMPRESSION, 0); 00974 } 00975 00976 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_TITLE, 1, title, error); 00977 if (*error < 0) { goto error; } 00978 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_ARTIST, 1, artist, error); 00979 if (*error < 0) { goto error; } 00980 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_ALBUM, 1, album, error); 00981 if (*error < 0) { goto error; } 00982 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_YEAR, 1, year, error); 00983 if (*error < 0) { goto error; } 00984 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_COMMENT, 3, comment, error); 00985 if (*error < 0) { goto error; } 00986 if (track != -1) 00987 { 00988 char track_str[255] = { '\0' }; 00989 snprintf(track_str,254,"%d",track); 00990 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_TRACK, 1, 00991 track_str, error); 00992 if (*error < 0) { goto error; } 00993 } 00994 00995 splt_mp3_put_libid3_frame_in_tag_with_content(id, ID3_FRAME_GENRE, 1, genre, error); 00996 if (*error < 0) { goto error; } 00997 00998 //get the number of bytes needed for the tags 00999 bytes_length = id3_tag_render(id, NULL); 01000 01001 if (bytes_length > 0) 01002 { 01003 //allocate memory for the tags 01004 bytes = malloc(sizeof(id3_byte_t) * bytes_length); 01005 if (!bytes) 01006 { 01007 goto error; 01008 } 01009 memset(bytes, '\0', sizeof(id3_byte_t) * bytes_length); 01010 01011 bytes_length = id3_tag_render(id, bytes); 01012 01013 *number_of_bytes = (unsigned long) bytes_length; 01014 } 01015 01016 id3_tag_delete(id); 01017 01018 return (char *) bytes; 01019 01020 error: 01021 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY; 01022 id3_tag_delete(id); 01023 *number_of_bytes = 0; 01024 if (bytes) 01025 { 01026 free(bytes); 01027 bytes = NULL; 01028 } 01029 01030 return NULL; 01031 } 01032 01033 #else 01034 01036 static const char unsigned splt_mp3_id3v1_genre_mapping[SPLT_ID3V1_NUMBER_OF_GENRES] = 01037 { 0x00, 01038 01039 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 01040 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 01041 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 01042 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 01043 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 01044 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 01045 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 01046 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 01047 01048 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 01049 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 01050 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 01051 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 01052 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 01053 01054 0xFF }; 01055 01057 static unsigned char splt_mp3_get_id3v1_mapping(const char *genre_string) 01058 { 01059 if (genre_string == NULL) 01060 { 01061 return 0xFF; 01062 } 01063 01064 int i = 0; 01065 for (i = 0; i < SPLT_ID3V1_NUMBER_OF_GENRES; i++) 01066 { 01067 if (strncmp(genre_string, splt_id3v1_genres[i], strlen(genre_string)) == 0) 01068 { 01069 return splt_mp3_id3v1_genre_mapping[i]; 01070 } 01071 } 01072 01073 return 0xFF; 01074 } 01075 01082 static char *splt_mp3_build_simple_id3v1(const char *title, const char *artist, 01083 const char *album, const char *year, const char *genre, 01084 const char *comment, int track, int *error, unsigned long *number_of_bytes) 01085 { 01086 char *id = NULL; 01087 char buffer[30] = { '\0' }; 01088 int j = 3,i = 0; 01089 01090 if ((id = malloc(sizeof(char) * 128)) != NULL) 01091 { 01092 memset(id,'\0',128); 01093 01094 strncpy(id, SPLT_MP3_TAG, 4); 01095 01096 memset(buffer, '\0', 30); 01097 if (title!=NULL) strncpy(buffer, title, 30); 01098 for (i=0; i<30; i++) id[j++]=buffer[i]; 01099 01100 memset(buffer, '\0', 30); 01101 if (artist!=NULL) strncpy(buffer, artist, 30); 01102 for (i=0; i<30; i++) id[j++]=buffer[i]; 01103 01104 memset(buffer, '\0', 30); 01105 if (album!=NULL) strncpy(buffer, album, 30); 01106 for (i=0; i<30; i++) id[j++]=buffer[i]; 01107 01108 memset(buffer, '\0', 30); 01109 if (year!=NULL) strncpy(buffer, year, 4); 01110 for (i=0; i<4; i++) id[j++]=buffer[i]; 01111 01112 memset(buffer, '\0', 30); 01113 if (comment!=NULL) strncpy(buffer, comment, 30); 01114 for (i=0; i<30; i++) 01115 { 01116 id[j++]=buffer[i]; 01117 } 01118 //if we have a positive track 01119 if (track != -1) 01120 { 01121 if (track != 0x00) 01122 { 01123 id[j-1] = (char) track; 01124 } 01125 } 01126 id[j] = (char) splt_mp3_get_id3v1_mapping(genre); 01127 } 01128 else 01129 { 01130 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY; 01131 return NULL; 01132 } 01133 01134 *number_of_bytes = 128; 01135 01136 return id; 01137 } 01138 #endif 01139 01146 static char *splt_mp3_build_id3_tags(splt_state *state, 01147 const char *title, const char *artist, 01148 const char *album, const char *year, const char *genre, 01149 const char *comment, int track, int *error, 01150 unsigned long *number_of_bytes, int version) 01151 { 01152 char *id = NULL; 01153 01154 #ifdef NO_ID3TAG 01155 if (version == 1) 01156 { 01157 splt_d_print_debug(state,"Setting ID3v1 tags without libid3tag\n"); 01158 id = splt_mp3_build_simple_id3v1(title, artist, album, year, genre, comment, track, 01159 error, number_of_bytes); 01160 } 01161 #else 01162 if (version == 1) 01163 { 01164 splt_d_print_debug(state,"Setting ID3v1 tags with libid3tag\n"); 01165 id = splt_mp3_build_libid3tag(title, artist, album, year, genre, comment, track, 01166 error, number_of_bytes, 1); 01167 } 01168 else 01169 { 01170 splt_d_print_debug(state,"Setting ID3v2 tags with libid3tag\n"); 01171 id = splt_mp3_build_libid3tag(title, artist, album, year, genre, comment, track, 01172 error, number_of_bytes, 2); 01173 } 01174 #endif 01175 01176 return id; 01177 } 01178 01185 static char *splt_mp3_build_tags(const char *filename, splt_state *state, int *error, 01186 unsigned long *number_of_bytes, int id3_version) 01187 { 01188 char *id3_data = NULL; 01189 01190 if (splt_o_get_int_option(state,SPLT_OPT_TAGS) != SPLT_NO_TAGS) 01191 { 01192 splt_tags *tags = splt_tu_get_current_tags(state); 01193 01194 if (tags) 01195 { 01196 char *artist_or_performer = splt_tu_get_artist_or_performer_ptr(tags); 01197 id3_data = splt_mp3_build_id3_tags(state, 01198 tags->title, artist_or_performer, tags->album, 01199 tags->year, tags->genre, tags->comment, 01200 tags->track, error, number_of_bytes, id3_version); 01201 } 01202 } 01203 01204 return id3_data; 01205 } 01206 01208 int splt_mp3_write_id3v1_tags(splt_state *state, FILE *file_output, 01209 const char *output_fname) 01210 { 01211 const char *filename = splt_t_get_filename_to_split(state); 01212 unsigned long number_of_bytes = 0; 01213 int error = SPLT_OK; 01214 01215 char *id3_tags = splt_mp3_build_tags(filename, state, &error, &number_of_bytes, 1); 01216 01217 if ((error >= 0) && (id3_tags) && (number_of_bytes > 0)) 01218 { 01219 if (file_output) 01220 { 01221 if (fseeko(file_output, splt_mp3_getid3v1_offset(file_output), SEEK_END)!=-1) 01222 { 01223 if (splt_io_fwrite(state, id3_tags, 1, number_of_bytes, file_output) < number_of_bytes) 01224 { 01225 splt_e_set_error_data(state, output_fname); 01226 error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 01227 } 01228 } 01229 else 01230 { 01231 splt_e_set_strerror_msg_with_data(state, output_fname); 01232 error = SPLT_ERROR_SEEKING_FILE; 01233 } 01234 } 01235 } 01236 01237 if (id3_tags) 01238 { 01239 free(id3_tags); 01240 id3_tags = NULL; 01241 } 01242 01243 return error; 01244 } 01245 01246 #ifndef NO_ID3TAG 01247 int splt_mp3_write_id3v2_tags(splt_state *state, FILE *file_output, 01248 const char *output_fname, off_t *end_offset) 01249 { 01250 const char *filename = splt_t_get_filename_to_split(state); 01251 unsigned long number_of_bytes = 0; 01252 int error = SPLT_OK; 01253 01254 char *id3_tags = splt_mp3_build_tags(filename, state, &error, &number_of_bytes, 2); 01255 01256 if ((error >= 0) && (id3_tags) && (number_of_bytes > 0)) 01257 { 01258 if (splt_io_fwrite(state, id3_tags, 1, number_of_bytes, file_output) < number_of_bytes) 01259 { 01260 splt_e_set_error_data(state, output_fname); 01261 error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 01262 } 01263 else 01264 { 01265 if (end_offset != NULL) 01266 { 01267 *end_offset = number_of_bytes; 01268 } 01269 } 01270 } 01271 01272 if (id3_tags) 01273 { 01274 free(id3_tags); 01275 id3_tags = NULL; 01276 } 01277 01278 return error; 01279 } 01280 #endif 01281 01283 int splt_mp3_get_output_tags_version(splt_state *state) 01284 { 01285 #ifdef NO_ID3TAG 01286 splt_d_print_debug(state,"Output tags version is ID3v1 without libid3tag\n"); 01287 return 1; 01288 #else 01289 int original_tags_version = state->original_tags.tags_version; 01290 int force_tags_version = splt_o_get_int_option(state, SPLT_OPT_FORCE_TAGS_VERSION); 01291 01292 int output_tags_version = original_tags_version; 01293 if (force_tags_version != 0) 01294 { 01295 output_tags_version = force_tags_version; 01296 } 01297 01298 if ((output_tags_version == 0) && 01299 (splt_o_get_int_option(state, SPLT_OPT_TAGS) == SPLT_CURRENT_TAGS)) 01300 { 01301 char *filename = splt_t_get_filename_to_split(state); 01302 if (strcmp(filename, "-") != 0) 01303 { 01304 output_tags_version = 12; 01305 } 01306 } 01307 01308 splt_d_print_debug(state,"Output tags version is ID3v _%d_\n", output_tags_version); 01309 01310 return output_tags_version; 01311 #endif 01312 } 01313 01314 /****************************/ 01315 /* mp3 infos */ 01316 01325 static splt_mp3_state *splt_mp3_info(FILE *file_input, splt_state *state, 01326 int framemode, int *error) 01327 { 01328 splt_mp3_state *mp3state = state->codec; 01329 01330 int prev = -1; 01331 long len; 01332 01333 if ((mp3state = malloc(sizeof(splt_mp3_state)))==NULL) 01334 { 01335 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY; 01336 return NULL; 01337 } 01338 memset(mp3state, 0x0, sizeof(splt_mp3_state)); 01339 01340 char *filename = splt_t_get_filename_to_split(state); 01341 01342 //always quiet 01343 mp3state->syncdetect = 0; 01344 01345 //we initialise default values 01346 mp3state->frames = 1; 01347 mp3state->end = 0; 01348 mp3state->first = 1; 01349 mp3state->file_input = file_input; 01350 mp3state->framemode = framemode; 01351 mp3state->headw = 0; 01352 mp3state->mp3file.xing = 0; 01353 mp3state->mp3file.xing_offset = 0; 01354 mp3state->mp3file.xingbuffer = NULL; 01355 //ignore flength error (ex for non seekable stdin) 01356 mp3state->mp3file.len = splt_io_get_file_length(state, file_input, filename, error); 01357 splt_t_set_total_time(state, 0); 01358 mp3state->data_ptr = NULL; 01359 mp3state->data_len = 0; 01360 mp3state->buf_len = 0; 01361 mp3state->bytes = 0; 01362 01363 //we initialise the mad structures 01364 splt_mp3_init_stream_frame(mp3state); 01365 mad_synth_init(&mp3state->synth); 01366 01367 mad_timer_reset(&mp3state->timer); 01368 01369 //we read mp3 infos and set pointers to read the mp3 data 01370 do 01371 { 01372 int ret = splt_mp3_get_frame(mp3state); 01373 01374 if (ret == -2) 01375 { 01376 splt_e_set_error_data(state,filename); 01377 *error = SPLT_ERROR_INVALID; 01378 goto function_end; 01379 } 01380 01381 if ((prev == 0) && 01382 ((ret == 0) || (mp3state->stream.error == MAD_ERROR_BUFLEN))) 01383 { 01384 break; 01385 } 01386 01387 //if we have succeeded to read a frame 01388 if (ret == 0) 01389 { 01390 //we set pointer to the frame 01391 mp3state->data_ptr = (unsigned char *) mp3state->stream.this_frame; 01392 //we set length of frame 01393 if(mp3state->stream.next_frame!=NULL) 01394 { 01395 mp3state->data_len = (long) (mp3state->stream.next_frame - mp3state->stream.this_frame); 01396 } 01397 01398 if (mp3state->stream.anc_bitlen > 64) 01399 { 01400 int tag = 0; 01401 struct mad_bitptr ptr = mp3state->stream.anc_ptr; 01402 struct mad_bitptr start = ptr; 01403 //we search for xing (variable bit rate) 01404 unsigned long xing_word = mad_bit_read(&ptr, 32); 01405 if ((xing_word==SPLT_MP3_XING_MAGIC) || 01406 (xing_word==SPLT_MP3_INFO_MAGIC)) 01407 { 01408 tag = 1; 01409 } 01410 //Handle misplaced Xing header in mp3 files with CRC 01411 else 01412 { 01413 if (xing_word == ((SPLT_MP3_XING_MAGIC << 16) & 0xffffffffL) 01414 || xing_word == ((SPLT_MP3_INFO_MAGIC << 16) & 0xffffffffL)) 01415 { 01416 ptr = start; 01417 mad_bit_skip(&ptr, 16); 01418 tag = 1; 01419 } 01420 } 01421 01422 //if we have xing, put infos 01423 if (tag) 01424 { 01425 xing_word = mad_bit_read(&ptr, 32); 01426 if (xing_word & SPLT_MP3_XING_FRAMES) 01427 { 01428 mad_timer_t total; 01429 mp3state->frames = mad_bit_read(&ptr, 32); 01430 total = mp3state->frame.header.duration; 01431 mad_timer_multiply(&total, mp3state->frames); 01432 float total_time_milliseconds = (float) mad_timer_count(total, MAD_UNITS_MILLISECONDS); 01433 total_time_milliseconds /= 10.f; 01434 splt_t_set_total_time(state, (long) ceilf(total_time_milliseconds)); 01435 } 01436 01437 if (xing_word & SPLT_MP3_XING_BYTES) 01438 { 01439 if (mp3state->mp3file.len == 0) 01440 mp3state->mp3file.len = mad_bit_read(&ptr, 32); 01441 } 01442 01443 if (splt_o_get_int_option(state, SPLT_OPT_XING)) 01444 { 01445 mp3state->mp3file.xing = mp3state->data_len; 01446 01447 if ((mp3state->mp3file.xingbuffer = 01448 malloc(mp3state->mp3file.xing))==NULL) 01449 { 01450 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY; 01451 goto function_end; 01452 } 01453 01454 memcpy(mp3state->mp3file.xingbuffer, mp3state->data_ptr, 01455 mp3state->mp3file.xing); 01456 mp3state->mp3file.xing_offset = splt_mp3_xing_info_off(mp3state); 01457 } 01458 01459 splt_o_set_int_option(state, SPLT_OPT_FRAME_MODE, SPLT_TRUE); 01460 mp3state->framemode = 1; 01461 01462 if (!splt_o_messages_locked(state)) 01463 { 01464 if (!splt_o_get_iopt(state, SPLT_INTERNAL_FRAME_MODE_ENABLED)) 01465 { 01466 int split_mode = 01467 splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE); 01468 01469 if (split_mode != SPLT_OPTION_WRAP_MODE && 01470 split_mode != SPLT_OPTION_ERROR_MODE) 01471 { 01472 splt_c_put_info_message_to_client(state, 01473 _(" info: found Xing or Info header. Switching to frame mode... \n")); 01474 splt_o_set_iopt(state, SPLT_INTERNAL_FRAME_MODE_ENABLED, SPLT_TRUE); 01475 } 01476 } 01477 } 01478 continue; 01479 } 01480 } 01481 } 01482 01483 prev = ret; 01484 } while (1); 01485 01486 len = (long) (mp3state->buf_len - (mp3state->data_ptr - mp3state->inputBuffer)); 01487 01488 if (len < 0) 01489 { 01490 splt_e_set_error_data(state,filename); 01491 *error = SPLT_ERROR_INVALID; 01492 goto function_end; 01493 } 01494 01495 //we put useful infos in the state 01496 mp3state->mp3file.firsth = (off_t) (mp3state->bytes - len); 01497 mp3state->bytes = mp3state->mp3file.firsth; 01498 mp3state->headw = 01499 (unsigned long) ((mp3state->data_ptr[0] << 24) | 01500 (mp3state->data_ptr[1] << 16) | 01501 (mp3state->data_ptr[2] << 8) | (mp3state->data_ptr[3])); 01502 mp3state->mp3file.mpgid = (int) ((mp3state->headw >> 19)&1); 01503 mp3state->mp3file.layer = mp3state->frame.header.layer; 01504 01505 mp3state->mp3file.freq = mp3state->frame.header.samplerate; 01506 mp3state->mp3file.bitrate = mp3state->frame.header.bitrate/SPLT_MP3_BYTE; 01507 01508 mp3state->mp3file.firsthead = 01509 splt_mp3_makehead(mp3state->headw, mp3state->mp3file, mp3state->mp3file.firsthead, mp3state->mp3file.firsth); 01510 01511 mp3state->mp3file.fps = (float) (mp3state->mp3file.freq*(2-mp3state->mp3file.mpgid)); 01512 mp3state->mp3file.fps /= SPLT_MP3_PCM; 01513 01514 //we put the channels stuff (mono, stereo) 01515 switch(mp3state->frame.header.mode) 01516 { 01517 case MAD_MODE_SINGLE_CHANNEL: 01518 mp3state->mp3file.channels = 0; 01519 break; 01520 case MAD_MODE_DUAL_CHANNEL: 01521 mp3state->mp3file.channels = 1; 01522 break; 01523 case MAD_MODE_JOINT_STEREO: 01524 mp3state->mp3file.channels = 2; 01525 break; 01526 case MAD_MODE_STEREO: 01527 mp3state->mp3file.channels = 3; 01528 break; 01529 default: 01530 mp3state->mp3file.channels = 4; 01531 break; 01532 } 01533 01534 //we put the total time for constant bit rate 01535 //if it was not set for the variable bit rate 01536 if (splt_t_get_total_time(state) == 0) 01537 { 01538 if (mp3state->mp3file.len > 0) 01539 { 01540 long temp = (long) 01541 (((double)(mp3state->mp3file.len - mp3state->mp3file.firsth) 01542 / (double)mp3state->mp3file.bitrate) * 100.0); 01543 01544 splt_t_set_total_time(state, temp); 01545 } 01546 } 01547 01548 function_end: 01549 //we free memory allocated by mad_frame_decode(..) 01550 //TODO: memory leak 01551 //splt_mp3_finish_stream_frame(mp3state); 01552 mad_synth_finish(&mp3state->synth); 01553 01554 return mp3state; 01555 } 01556 01558 static void splt_mp3_end(splt_state *state, int *error) 01559 { 01560 splt_mp3_state *mp3state = state->codec; 01561 if (mp3state) 01562 { 01563 splt_mp3_finish_stream_frame(mp3state); 01564 if (mp3state->file_input) 01565 { 01566 if (mp3state->file_input != stdin) 01567 { 01568 if (fclose(mp3state->file_input) != 0) 01569 { 01570 splt_e_set_strerror_msg_with_data(state, splt_t_get_filename_to_split(state)); 01571 *error = SPLT_ERROR_CANNOT_CLOSE_FILE; 01572 } 01573 } 01574 mp3state->file_input = NULL; 01575 } 01576 //we free the mp3 state 01577 splt_mp3_state_free(state); 01578 } 01579 state->codec = NULL; 01580 } 01581 01583 static void splt_mp3_get_info(splt_state *state, FILE *file_input, int *error) 01584 { 01585 //checks if valid mp3 file 01586 //before last argument, if framemode or not 01587 //last argument if we put messages to clients or not 01588 state->codec = splt_mp3_info(file_input, state, 01589 splt_o_get_int_option(state,SPLT_OPT_FRAME_MODE), error); 01590 //if error 01591 if ((*error < 0) || (state->codec == NULL)) 01592 { 01593 if (state->codec != NULL) 01594 { 01595 splt_mp3_end(state, error); 01596 } 01597 return; 01598 } 01599 //print informations about the current file to the client 01600 else 01601 { 01602 if ((! splt_o_messages_locked(state)) && 01603 (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_WRAP_MODE) && 01604 (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_ERROR_MODE)) 01605 { 01606 splt_mp3_state *mp3state = state->codec; 01607 struct splt_mp3 *mfile = &mp3state->mp3file; 01608 01609 char mpeg_infos[1024] = { '\0' }; 01610 snprintf(mpeg_infos, 1024, _(" info: MPEG %d Layer %d - %d Hz - %s"), 01611 (2-mfile->mpgid), mfile->layer, mfile->freq, splt_mp3_chan[mfile->channels]); 01612 01613 char frame_mode_infos[256] = { '\0' }; 01614 if (mp3state->framemode) 01615 { 01616 if (splt_o_get_int_option(state, SPLT_OPT_INPUT_NOT_SEEKABLE)) 01617 { 01618 snprintf(frame_mode_infos, 255, _(" - FRAME MODE NS")); 01619 } 01620 else 01621 { 01622 snprintf(frame_mode_infos, 255, _(" - FRAME MODE")); 01623 } 01624 } 01625 else if (splt_o_get_int_option(state, SPLT_OPT_INPUT_NOT_SEEKABLE)) 01626 { 01627 snprintf(frame_mode_infos, 255, _(" - NS - %d Kb/s"), 01628 mfile->bitrate * SPLT_MP3_BYTE / 1000); 01629 } 01630 else 01631 { 01632 snprintf(frame_mode_infos, 255, _(" - %d Kb/s"), 01633 mfile->bitrate * SPLT_MP3_BYTE / 1000); 01634 } 01635 01636 char total_time[256] = { '\0' }; 01637 int total_seconds = (int) (splt_t_get_total_time(state) / 100); 01638 int minutes = total_seconds / 60; 01639 int seconds = total_seconds % 60; 01640 snprintf(total_time,255, _(" - Total time: %dm.%02ds"), minutes, seconds%60); 01641 01642 splt_c_put_info_message_to_client(state, 01643 "%s%s%s\n", mpeg_infos, frame_mode_infos, total_time); 01644 } 01645 } 01646 } 01647 01648 /****************************/ 01649 /* mp3 scan for silence */ 01650 01661 static int splt_mp3_silence(splt_mp3_state *mp3state, int channels, mad_fixed_t threshold) 01662 { 01663 int i, j; 01664 mad_fixed_t sample; 01665 int silence = 1; 01666 01667 for (j=0; j<channels; j++) 01668 { 01669 for(i=0; i<mp3state->synth.pcm.length; i++) 01670 { 01671 //get silence spot ? 01672 sample = mad_f_abs(mp3state->synth.pcm.samples[j][i]); 01673 mp3state->temp_level = mp3state->temp_level * 0.999 + sample * 0.001; 01674 01675 if (sample > threshold) 01676 { 01677 silence = 0; 01678 } 01679 } 01680 } 01681 01682 return silence; 01683 } 01684 01695 static int splt_mp3_scan_silence(splt_state *state, off_t begin, 01696 unsigned long length, float threshold, 01697 float min, short output, int *error) 01698 { 01699 int len = 0, found = 0, shot; 01700 short first, flush = 0, stop = 0; 01701 unsigned long silence_begin = 0, silence_end = 0, time; 01702 //unsigned long count = 0; 01703 off_t pos; 01704 mad_fixed_t th; 01705 01706 splt_mp3_state *mp3state = state->codec; 01707 01708 splt_c_put_progress_text(state,SPLT_PROGRESS_SCAN_SILENCE); 01709 01710 pos = begin; 01711 th = mad_f_tofixed(splt_co_convert_from_dB(threshold)); 01712 01713 //we seek to the begin 01714 if (fseeko(mp3state->file_input, begin, SEEK_SET)==-1) 01715 { 01716 splt_e_set_strerror_msg_with_data(state, splt_t_get_filename_to_split(state)); 01717 *error = SPLT_ERROR_SEEKING_FILE; 01718 return -1; 01719 } 01720 01721 first = output; 01722 shot = SPLT_DEFAULTSHOT; 01723 01724 //initialise mad stuff 01725 splt_mp3_init_stream_frame(mp3state); 01726 mad_synth_init(&mp3state->synth); 01727 01728 mad_timer_reset(&mp3state->timer); 01729 01730 mp3state->temp_level = 0.0; 01731 01732 //we do the effective scan 01733 do 01734 { 01735 int mad_err = SPLT_OK; 01736 switch (splt_mp3_get_valid_frame(state, &mad_err)) 01737 { 01738 case 1: 01739 //1 we have a valid frame 01740 //we get mad infos and put them in the mp3state 01741 mad_timer_add(&mp3state->timer, mp3state->frame.header.duration); 01742 mad_synth_frame(&mp3state->synth,&mp3state->frame); 01743 time = (unsigned long) mad_timer_count(mp3state->timer, MAD_UNITS_CENTISECONDS); 01744 01745 if (length > 0) 01746 { 01747 if (time >= length) 01748 { 01749 flush = 1; 01750 stop = 1; 01751 } 01752 } 01753 01754 if ((!flush) && (splt_mp3_silence(mp3state, MAD_NCHANNELS(&mp3state->frame.header), th))) 01755 { 01756 if (len == 0) silence_begin = time; 01757 if (first == 0) 01758 { 01759 len++; 01760 } 01761 if (shot < SPLT_DEFAULTSHOT) 01762 shot+=2; 01763 silence_end = time; 01764 } 01765 else 01766 { 01767 if (len > SPLT_DEFAULTSILLEN) 01768 { 01769 if ((flush) || (shot <= 0)) 01770 { 01771 double begin_position, end_position; 01772 begin_position = (double) (silence_begin / 100.f); 01773 end_position = (double) (silence_end / 100.f); 01774 len = (int) (silence_end - silence_begin); 01775 01776 if ((end_position - begin_position - min) >= 0.f) 01777 { 01778 if (splt_siu_ssplit_new(&state->silence_list, begin_position, end_position, 01779 len, error) == -1) 01780 { 01781 stop = 1; 01782 found = -1; 01783 break; 01784 } 01785 found++; 01786 } 01787 01788 len = 0; 01789 shot = SPLT_DEFAULTSHOT; 01790 } 01791 } 01792 else 01793 { 01794 len = 0; 01795 } 01796 01797 if ((first) && (shot <= 0)) 01798 { 01799 first = 0; 01800 } 01801 01802 if (shot > 0) 01803 { 01804 shot--; 01805 } 01806 } 01807 01808 if (mp3state->mp3file.len > 0) 01809 { 01810 pos = ftello(mp3state->file_input); 01811 01812 //if (count++ % 10 == 0) 01813 { 01814 float level = splt_co_convert_to_dB(mad_f_todouble(mp3state->temp_level)); 01815 if (state->split.get_silence_level) 01816 { 01817 state->split.get_silence_level(time, level, state->split.silence_level_client_data); 01818 } 01819 state->split.p_bar->silence_db_level = level; 01820 state->split.p_bar->silence_found_tracks = found; 01821 } 01822 01823 //if we don't have silence split, 01824 //put the 1/4 of progress 01825 if (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != 01826 SPLT_OPTION_SILENCE_MODE) 01827 { 01828 splt_c_update_progress(state,(double)(time), 01829 (double)(length), 4,1/(float)4, 01830 SPLT_DEFAULT_PROGRESS_RATE); 01831 } 01832 else 01833 { 01834 //if we have cancelled the split 01835 if (splt_t_split_is_canceled(state)) 01836 { 01837 stop = 1; 01838 } 01839 splt_c_update_progress(state,(double)pos, 01840 (double)(mp3state->mp3file.len), 01841 1,0,SPLT_DEFAULT_PROGRESS_RATE); 01842 } 01843 } 01844 break; 01845 case 0: 01846 //0 we do nothing 01847 break; 01848 case -1: 01849 // -1 means eof 01850 stop = 1; 01851 break; 01852 case -3: 01853 //error from libmad 01854 stop = 1; 01855 *error = mad_err; 01856 found = -1; 01857 break; 01858 default: 01859 break; 01860 } 01861 } while (!stop && (found < SPLT_MAXSILENCE)); 01862 01863 //only if we have silence mode, we set progress to 100% 01864 if (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) == 01865 SPLT_OPTION_SILENCE_MODE) 01866 { 01867 splt_c_update_progress(state,1.0,1.0,1,1,1); 01868 } 01869 01870 //we finish with mad_* 01871 splt_mp3_finish_stream_frame(mp3state); 01872 mad_synth_finish(&mp3state->synth); 01873 01874 return found; 01875 } 01876 01877 /****************************/ 01878 /* mp3 split */ 01879 01880 static off_t splt_mp3_write_data_ptr(splt_state *state, const char *filename, 01881 const char *output_fname, FILE *file_output, int *error) 01882 { 01883 splt_mp3_state *mp3state = state->codec; 01884 01885 long len = (long) (mp3state->inputBuffer + mp3state->buf_len - mp3state->data_ptr); 01886 01887 if (len < 0) 01888 { 01889 splt_e_set_error_data(state, filename); 01890 *error = SPLT_ERROR_WHILE_READING_FILE; 01891 return len; 01892 } 01893 01894 if (splt_io_fwrite(state, mp3state->data_ptr, 1, len, file_output) < len) 01895 { 01896 splt_e_set_error_data(state,output_fname); 01897 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 01898 return len; 01899 } 01900 01901 mp3state->data_len = 0; 01902 01903 return len; 01904 } 01905 01906 01919 static int splt_mp3_simple_split(splt_state *state, const char *output_fname, 01920 off_t begin, off_t end, int do_write_tags, short write_first_frame) 01921 { 01922 splt_d_print_debug(state,"Mp3 simple split on output _%s_\n", output_fname); 01923 splt_d_print_debug(state,"Mp3 simple split offset begin is _%ld_\n", begin); 01924 splt_d_print_debug(state,"Mp3 simple split offset end is _%ld_\n", end); 01925 01926 splt_mp3_state *mp3state = state->codec; 01927 01928 int error = SPLT_OK_SPLIT; 01929 01930 FILE *file_output = NULL; 01931 off_t position = 0; 01932 unsigned char buffer[SPLT_MP3_READBSIZE] = { '\0' }; 01933 long readed = 0; 01934 //for the progress 01935 off_t temp_end = 0; 01936 //the start point of the split 01937 long start = begin; 01938 int split_mode = splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE); 01939 01940 splt_c_put_progress_text(state, SPLT_PROGRESS_CREATE); 01941 01942 char *filename = splt_t_get_filename_to_split(state); 01943 01944 position = ftello(mp3state->file_input); // Save current position 01945 01946 if (fseeko(mp3state->file_input, begin, SEEK_SET)==-1) 01947 { 01948 return SPLT_ERROR_BEGIN_OUT_OF_FILE; 01949 } 01950 01951 //get the file size 01952 off_t st_size; 01953 char *fname_to_split = splt_t_get_filename_to_split(state); 01954 if(splt_io_stat(fname_to_split, NULL, &st_size) == 0) 01955 { 01956 mp3state->end2 = st_size; 01957 } 01958 else 01959 { 01960 splt_e_set_strerror_msg_with_data(state, fname_to_split); 01961 return SPLT_ERROR_CANNOT_OPEN_FILE; 01962 } 01963 01964 if (! splt_o_get_int_option(state, SPLT_OPT_PRETEND_TO_SPLIT)) 01965 { 01966 file_output = splt_mp3_open_file_write(state, output_fname, &error); 01967 if (error < 0) { return error; } 01968 } 01969 01970 int output_tags_version = splt_mp3_get_output_tags_version(state); 01971 01972 #ifndef NO_ID3TAG 01973 //write id3 tags version 2 at the start of the file, if necessary 01974 if (do_write_tags && (output_tags_version == 2 || output_tags_version == 12)) 01975 { 01976 int err = SPLT_OK; 01977 if ((err = splt_mp3_write_id3v2_tags(state, file_output, 01978 output_fname, NULL)) < 0) 01979 { 01980 error = err; 01981 goto function_end; 01982 } 01983 } 01984 #endif 01985 01986 if (mp3state->mp3file.xing != 0) 01987 { 01988 if (splt_o_get_int_option(state, SPLT_OPT_XING)) 01989 { 01990 //error mode split must only contain original file data 01991 if (state->options.split_mode != SPLT_OPTION_ERROR_MODE) 01992 { 01993 if (splt_io_fwrite(state, mp3state->mp3file.xingbuffer, 1, 01994 mp3state->mp3file.xing, file_output) < mp3state->mp3file.xing) 01995 { 01996 splt_e_set_error_data(state, output_fname); 01997 error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 01998 goto function_end; 01999 } 02000 } 02001 } 02002 } 02003 02004 if (write_first_frame) 02005 { 02006 splt_mp3_write_data_ptr(state, filename, output_fname, file_output, &error); 02007 if (error < 0) { goto function_end; } 02008 } 02009 02010 while (!feof(mp3state->file_input)) 02011 { 02012 readed = SPLT_MP3_READBSIZE; 02013 if (end != -1) 02014 { 02015 if (begin >= end) 02016 { 02017 break; 02018 } 02019 if ((end - begin) < SPLT_MP3_READBSIZE) 02020 { 02021 readed = end - begin; 02022 } 02023 } 02024 02025 if ((readed = fread(buffer, 1, readed, mp3state->file_input))==-1) 02026 { 02027 break; 02028 } 02029 02030 if (splt_io_fwrite(state, buffer, 1, readed, file_output) < readed) 02031 { 02032 splt_e_set_error_data(state,output_fname); 02033 error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 02034 goto function_end; 02035 } 02036 begin += readed; 02037 02038 //we update the progress bar 02039 if ((split_mode == SPLT_OPTION_WRAP_MODE) || 02040 (split_mode == SPLT_OPTION_ERROR_MODE) || 02041 ((split_mode == SPLT_OPTION_NORMAL_MODE) 02042 && (!splt_o_get_int_option(state, SPLT_OPT_AUTO_ADJUST)) 02043 && (!splt_o_get_int_option(state, SPLT_OPT_FRAME_MODE)))) 02044 { 02045 temp_end = end; 02046 //for the last split 02047 if (end == -1) 02048 { 02049 temp_end = mp3state->end2; 02050 } 02051 02052 splt_c_update_progress(state,(double)(begin-start), 02053 (double)(temp_end-start),1,0, 02054 SPLT_DEFAULT_PROGRESS_RATE); 02055 } 02056 else 02057 { 02058 //if auto adjust, we have 50% 02059 if (splt_o_get_int_option(state, SPLT_OPT_AUTO_ADJUST)) 02060 { 02061 splt_c_update_progress(state,(double)(begin-start), 02062 (double)(end-start), 02063 2,0.5, SPLT_DEFAULT_PROGRESS_RATE); 02064 } 02065 else 02066 { 02067 if (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) 02068 == SPLT_OPTION_TIME_MODE) 02069 { 02070 temp_end = end; 02071 //for the last split 02072 if (end == -1) 02073 { 02074 temp_end = mp3state->end2; 02075 } 02076 02077 //if framemode 02078 if (splt_o_get_int_option(state, SPLT_OPT_FRAME_MODE)) 02079 { 02080 splt_c_update_progress(state,(double)(begin-start), 02081 (double)(temp_end-start), 02082 2,0.5, SPLT_DEFAULT_PROGRESS_RATE); 02083 } 02084 else 02085 { 02086 splt_c_update_progress(state,(double)(begin-start), 02087 (double)(temp_end-start), 02088 1,0, SPLT_DEFAULT_PROGRESS_RATE); 02089 } 02090 } 02091 else 02092 { 02093 splt_c_update_progress(state,(double)(begin-start), 02094 (double)(end-start), 02095 2,0.5, SPLT_DEFAULT_PROGRESS_RATE); 02096 } 02097 } 02098 } 02099 } 02100 02101 //write id3 tags version 1 at the end of the file, if necessary 02102 if (do_write_tags && (output_tags_version == 1 || output_tags_version == 12)) 02103 { 02104 int err = SPLT_OK; 02105 if ((err = splt_mp3_write_id3v1_tags(state, file_output, output_fname)) < 0) 02106 { 02107 error = err; 02108 goto function_end; 02109 } 02110 } 02111 02112 if (fseeko(mp3state->file_input, position, SEEK_SET)==-1) 02113 { 02114 splt_e_set_strerror_msg_with_data(state, filename); 02115 goto function_end; 02116 } 02117 02118 function_end: 02119 if (file_output) 02120 { 02121 if (file_output != stdout) 02122 { 02123 if (fclose(file_output) != 0) 02124 { 02125 splt_e_set_strerror_msg_with_data(state, filename); 02126 return SPLT_ERROR_CANNOT_CLOSE_FILE; 02127 } 02128 } 02129 file_output = NULL; 02130 } 02131 02132 return error; 02133 } 02134 02150 static double splt_mp3_split(const char *output_fname, splt_state *state, 02151 double fbegin_sec, double fend_sec, int *error, int save_end_point) 02152 { 02153 splt_d_print_debug(state,"Mp3 split...\n"); 02154 splt_d_print_debug(state,"Output filename is _%s_\n", output_fname); 02155 splt_d_print_debug(state,"Begin position is _%lf_\n", fbegin_sec); 02156 splt_d_print_debug(state,"End position is _%lf_\n", fend_sec); 02157 02158 splt_mp3_state *mp3state = state->codec; 02159 02160 int adjustoption = splt_o_get_int_option(state, SPLT_OPT_PARAM_GAP); 02161 short seekable = ! splt_o_get_int_option(state, SPLT_OPT_INPUT_NOT_SEEKABLE); 02162 float threshold = splt_o_get_float_option(state, SPLT_OPT_PARAM_THRESHOLD); 02163 02164 short fend_sec_is_not_eof = 02165 !splt_u_fend_sec_is_bigger_than_total_time(state, fend_sec); 02166 02167 short eof=0, check_bitrate=0; 02168 02169 char *filename = splt_t_get_filename_to_split(state); 02170 02171 FILE *file_output = NULL; 02172 short writing = 0, finished=0; 02173 unsigned long fbegin=0; 02174 off_t wrote = 0; 02175 long len = 0; 02176 //for the progress 02177 unsigned long stopped_frames = 0; 02178 int progress_adjust_val = 2; 02179 02180 if (adjustoption) 02181 { 02182 progress_adjust_val = 4; 02183 } 02184 02185 splt_c_put_progress_text(state,SPLT_PROGRESS_CREATE); 02186 02187 double sec_end_time = fend_sec; 02188 02189 //if not seekable 02190 if (!seekable) 02191 { 02192 if (! splt_o_get_int_option(state, SPLT_OPT_PRETEND_TO_SPLIT)) 02193 { 02194 file_output = splt_mp3_open_file_write(state, output_fname, error); 02195 if (*error < 0) { return sec_end_time; }; 02196 } 02197 02198 int output_tags_version = splt_mp3_get_output_tags_version(state); 02199 02200 off_t id3v2_end_offset = 0; 02201 #ifndef NO_ID3TAG 02202 //write id3 tags version 2 at the start of the file 02203 if (output_tags_version == 2 || output_tags_version == 12) 02204 { 02205 int err = SPLT_OK; 02206 if ((err = splt_mp3_write_id3v2_tags(state, file_output, 02207 output_fname, &id3v2_end_offset)) < 0) 02208 { 02209 *error = err; 02210 goto bloc_end; 02211 } 02212 } 02213 #endif 02214 02215 //if we have the framemode 02216 if (mp3state->framemode) 02217 { 02218 splt_d_print_debug(state,"Starting not seekable mp3 frame mode...\n"); 02219 02220 long begin_c, end_c, time; 02221 //convert seconds to hundreths 02222 begin_c = (long) (fbegin_sec * 100); 02223 if (fend_sec > 0) 02224 { 02225 end_c = (long) (fend_sec * 100); 02226 } 02227 else 02228 { 02229 end_c = 0; 02230 } 02231 time = 0; 02232 02233 do 02234 { 02235 //we write xing if necessary 02236 if (!writing && (time >= begin_c)) 02237 { 02238 writing = 1; 02239 fbegin = mp3state->frames; 02240 02241 if (mp3state->mp3file.xing > 0) 02242 { 02243 wrote = splt_io_fwrite(state, mp3state->mp3file.xingbuffer, 02244 1, mp3state->mp3file.xing, file_output); 02245 if (wrote < mp3state->mp3file.xing) 02246 { 02247 splt_e_set_error_data(state,output_fname); 02248 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 02249 goto bloc_end; 02250 } 02251 } 02252 } 02253 02254 //we do the split 02255 if (writing) 02256 { 02257 if (mp3state->data_len > 0) 02258 { 02259 if ((len = splt_io_fwrite(state, mp3state->data_ptr, 1, mp3state->data_len, file_output)) 02260 < mp3state->data_len) 02261 { 02262 splt_e_set_error_data(state,output_fname); 02263 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 02264 goto bloc_end; 02265 } 02266 wrote = (off_t) (wrote + len); 02267 mp3state->data_len = 0; 02268 } 02269 02270 if ((end_c > 0) && (time >= end_c)) 02271 { 02272 finished = 1; 02273 } 02274 if (eof || finished) 02275 { 02276 finished = 1; 02277 if (eof) { *error = SPLT_OK_SPLIT_EOF; } 02278 break; 02279 } 02280 } 02281 02282 //progress bar 02283 if (splt_o_get_int_option(state,SPLT_OPT_SPLIT_MODE) 02284 == SPLT_OPTION_TIME_MODE) 02285 { 02286 splt_c_update_progress(state,(double)(time-begin_c), 02287 (double)(end_c-begin_c),1,0, 02288 SPLT_DEFAULT_PROGRESS_RATE); 02289 } 02290 else 02291 { 02292 splt_c_update_progress(state,(double)(time), 02293 (double)(end_c),1,0, 02294 SPLT_DEFAULT_PROGRESS_RATE); 02295 } 02296 02297 int mad_err = SPLT_OK; 02298 switch (splt_mp3_get_valid_frame(state, &mad_err)) 02299 { 02300 case 1: 02301 mad_timer_add(&mp3state->timer, mp3state->frame.header.duration); 02302 mp3state->frames++; 02303 time = (unsigned long) mad_timer_count(mp3state->timer, MAD_UNITS_CENTISECONDS); 02304 break; 02305 case 0: 02306 break; 02307 case -1: 02308 eof = 1; 02309 *error = SPLT_OK_SPLIT_EOF; 02310 break; 02311 case -3: 02312 //error from libmad 02313 *error = mad_err; 02314 goto bloc_end; 02315 break; 02316 default: 02317 break; 02318 } 02319 02320 } while (!finished); 02321 } 02322 //if we don't have the framemode 02323 else 02324 { 02325 splt_d_print_debug(state,"Starting mp3 not seekable non frame mode...\n"); 02326 02327 off_t begin = 0, end = 0; 02328 if (fend_sec_is_not_eof) 02329 { 02330 end = (off_t) (fend_sec * mp3state->mp3file.bitrate + mp3state->mp3file.firsth); 02331 } 02332 else 02333 { 02334 end = -1; 02335 } 02336 02337 //find begin point because no 'end' saved point 02338 if (mp3state->end == 0) 02339 { 02340 begin = (off_t) (fbegin_sec * mp3state->mp3file.bitrate + mp3state->mp3file.firsth); 02341 02342 if ((mp3state->bytes == begin) && (mp3state->data_len > 0)) 02343 { 02344 wrote += splt_mp3_write_data_ptr(state, filename, output_fname, file_output, error); 02345 if (*error < 0) { goto bloc_end; } 02346 } 02347 else 02348 { 02349 while (mp3state->bytes < begin) 02350 { 02351 off_t to_read; 02352 if (feof(mp3state->file_input)) 02353 { 02354 *error = SPLT_ERROR_BEGIN_OUT_OF_FILE; 02355 goto bloc_end; 02356 } 02357 to_read = (begin - mp3state->bytes); 02358 if (to_read > SPLT_MAD_BSIZE) 02359 to_read = SPLT_MAD_BSIZE; 02360 if ((mp3state->data_len = fread(mp3state->inputBuffer, 1, to_read, mp3state->file_input))<=0) 02361 { 02362 *error = SPLT_ERROR_BEGIN_OUT_OF_FILE; 02363 goto bloc_end; 02364 } 02365 mp3state->bytes+=mp3state->data_len; 02366 } 02367 02368 int mad_err = SPLT_OK; 02369 splt_mp3_init_stream_frame(mp3state); 02370 switch (splt_mp3_get_valid_frame(state, &mad_err)) 02371 { 02372 case 1: 02373 len = (long) (mp3state->inputBuffer + mp3state->buf_len - mp3state->data_ptr); 02374 if (len < 0) 02375 { 02376 splt_e_set_error_data(state,filename); 02377 *error = SPLT_ERROR_WHILE_READING_FILE; 02378 goto bloc_end; 02379 } 02380 if (splt_io_fwrite(state, mp3state->data_ptr, 1, len, file_output) < len) 02381 { 02382 splt_e_set_error_data(state,output_fname); 02383 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 02384 goto bloc_end; 02385 } 02386 wrote = (off_t) (wrote + len); 02387 mp3state->data_len = 0; 02388 break; 02389 case 0: 02390 break; 02391 case -1: 02392 eof = 1; 02393 *error = SPLT_ERROR_BEGIN_OUT_OF_FILE; 02394 break; 02395 case -3: 02396 //error from libmad 02397 *error = mad_err; 02398 goto bloc_end; 02399 break; 02400 default: 02401 break; 02402 } 02403 } 02404 } 02405 //set the 'begin' as the saved 'end' 02406 else 02407 { 02408 len = (long) (mp3state->inputBuffer + mp3state->buf_len - mp3state->data_ptr); 02409 if (len < 0) 02410 { 02411 splt_e_set_error_data(state,filename); 02412 *error = SPLT_ERROR_WHILE_READING_FILE; 02413 goto bloc_end; 02414 } 02415 if (splt_io_fwrite(state, mp3state->data_ptr, 1, len, file_output) < len) 02416 { 02417 splt_e_set_error_data(state,output_fname); 02418 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 02419 goto bloc_end; 02420 } 02421 wrote = (off_t) (wrote + len); 02422 mp3state->data_len = 0; 02423 begin = mp3state->end; 02424 } 02425 02426 long split_begin_point = mp3state->bytes; 02427 //while not end of file, read write: 02428 while (!eof) 02429 { 02430 off_t to_read = SPLT_MAD_BSIZE; 02431 if (end > 0) 02432 { 02433 to_read = (end - mp3state->bytes); 02434 if (to_read <= 0) 02435 { 02436 break; 02437 } 02438 if (to_read > SPLT_MAD_BSIZE) 02439 to_read = SPLT_MAD_BSIZE; 02440 } 02441 02442 if (feof(mp3state->file_input) || 02443 ((mp3state->data_len = 02444 fread(mp3state->inputBuffer, 1, to_read, mp3state->file_input))<=0)) 02445 { 02446 eof = 1; 02447 *error = SPLT_OK_SPLIT_EOF; 02448 break; 02449 } 02450 02451 if (splt_io_fwrite(state, mp3state->inputBuffer, 1, 02452 mp3state->data_len, file_output) < mp3state->data_len) 02453 { 02454 splt_e_set_error_data(state,output_fname); 02455 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 02456 goto bloc_end; 02457 } 02458 02459 mp3state->bytes += mp3state->data_len; 02460 02461 splt_c_update_progress(state, (double) (mp3state->bytes-split_begin_point), 02462 (double)(end-split_begin_point), 1,0,SPLT_DEFAULT_PROGRESS_RATE); 02463 } 02464 02465 splt_mp3_save_end_point(state, mp3state, save_end_point, end); 02466 02467 if (!eof) 02468 { 02469 //take the whole last frame : might result in more frames 02470 //but if we don't do it, we might have less frames 02471 int mad_err = SPLT_OK; 02472 splt_mp3_init_stream_frame(mp3state); 02473 switch (splt_mp3_get_valid_frame(state, &mad_err)) 02474 { 02475 case 1: 02476 len = (long) (mp3state->data_ptr - mp3state->inputBuffer); 02477 if (len < 0) 02478 { 02479 splt_e_set_error_data(state,filename); 02480 *error = SPLT_ERROR_WHILE_READING_FILE; 02481 goto bloc_end; 02482 } 02483 if (splt_io_fwrite(state, mp3state->inputBuffer, 1, len, file_output) < len) 02484 { 02485 splt_e_set_error_data(state,output_fname); 02486 *error = SPLT_ERROR_CANT_WRITE_TO_OUTPUT_FILE; 02487 goto bloc_end; 02488 } 02489 break; 02490 case 0: 02491 break; 02492 case -1: 02493 eof = 1; 02494 *error = SPLT_OK_SPLIT_EOF; 02495 break; 02496 case -3: 02497 *error = mad_err; 02498 goto bloc_end; 02499 break; 02500 default: 02501 break; 02502 } 02503 } 02504 } 02505 02506 //we write id3 and other stuff 02507 if (file_output) 02508 { 02509 if (mp3state->mp3file.xing > 0) 02510 { 02511 if (fseeko(file_output, mp3state->mp3file.xing_offset+4+id3v2_end_offset, SEEK_SET)!=-1) 02512 { 02513 unsigned long headw = (unsigned long) (mp3state->frames - fbegin + 1); // Frames 02514 fputc((headw >> 24) & 0xFF, file_output); 02515 fputc((headw >> 16) & 0xFF, file_output); 02516 fputc((headw >> 8) & 0xFF, file_output); 02517 fputc((headw >> 0) & 0xFF, file_output); 02518 headw = (unsigned long) (wrote); // Bytes 02519 fputc((headw >> 24) & 0xFF, file_output); 02520 fputc((headw >> 16) & 0xFF, file_output); 02521 fputc((headw >> 8) & 0xFF, file_output); 02522 fputc((headw >> 0) & 0xFF, file_output); 02523 } 02524 else 02525 { 02526 splt_e_set_strerror_msg_with_data(state, output_fname); 02527 *error = SPLT_ERROR_SEEKING_FILE; 02528 goto bloc_end; 02529 } 02530 } 02531 02532 //write id3 tags version 1 at the end of the file 02533 if (output_tags_version == 1 || output_tags_version == 12) 02534 { 02535 int err = SPLT_OK; 02536 if ((err = splt_mp3_write_id3v1_tags(state, file_output, output_fname)) < 0) 02537 { 02538 *error = err; 02539 goto bloc_end; 02540 } 02541 } 02542 } 02543 02544 bloc_end: 02545 if (file_output) 02546 { 02547 if (file_output != stdout) 02548 { 02549 if (fclose(file_output) != 0) 02550 { 02551 splt_e_set_strerror_msg_with_data(state, output_fname); 02552 *error = SPLT_ERROR_CANNOT_CLOSE_FILE; 02553 } 02554 } 02555 } 02556 file_output = NULL; 02557 02558 if (*error == SPLT_OK) { *error = SPLT_OK_SPLIT; } 02559 02560 return sec_end_time; 02561 } 02562 //if seekable: 02563 else 02564 { 02565 short write_first_frame = SPLT_FALSE; 02566 off_t begin = 0, end = 0; 02567 //if framemode 02568 if (mp3state->framemode) 02569 { 02570 splt_d_print_debug(state,"Starting seekable mp3 frame mode...\n"); 02571 02572 unsigned long fbegin, fend, adjust; 02573 fbegin = fend = adjust = 0; 02574 //prefer to split a bit before the start than loosing some frame 02575 //so we don't 'ceilf' 02576 fbegin = fbegin_sec * mp3state->mp3file.fps; 02577 02578 if (fend_sec_is_not_eof) 02579 { 02580 //if adjustoption 02581 if (adjustoption) 02582 { 02583 if (fend_sec_is_not_eof) 02584 { 02585 float adj = (float) (adjustoption); 02586 float len = (fend_sec - fbegin_sec); 02587 if (adj > len) 02588 { 02589 adj = len; 02590 } 02591 if (fend_sec > adj) 02592 { 02593 fend_sec -= adj; 02594 } 02595 adjust = (unsigned long) (adj * 100.f); 02596 } 02597 else 02598 { 02599 adjust = 0; 02600 } 02601 } 02602 //prefer to split a bit after the end than loosing some frame 02603 //before the end 02604 fend = (unsigned long) ceilf(fend_sec * mp3state->mp3file.fps); 02605 } 02606 else 02607 { 02608 fend = 0xFFFFFFFF; 02609 } 02610 02611 splt_d_print_debug(state,"Finding begin...\n"); 02612 02613 if (mp3state->end == 0) 02614 { 02615 if (mp3state->first) 02616 { 02617 mp3state->h.ptr = mp3state->mp3file.firsthead.ptr; 02618 mp3state->h.framesize = mp3state->mp3file.firsthead.framesize; 02619 begin = mp3state->mp3file.firsthead.ptr; 02620 mp3state->first = 0; 02621 } 02622 02623 splt_c_put_progress_text(state,SPLT_PROGRESS_PREPARE); 02624 02625 // Finds begin by counting frames 02626 while (mp3state->frames < fbegin) 02627 { 02628 begin = splt_mp3_findhead(mp3state, mp3state->h.ptr + mp3state->h.framesize); 02629 if (begin == -1) { *error = SPLT_ERROR_BEGIN_OUT_OF_FILE; goto bloc_end2; } 02630 02631 //count the number of syncerrors 02632 if ((begin!=mp3state->h.ptr + mp3state->h.framesize)&&(state->syncerrors>=0)) 02633 { 02634 state->syncerrors++; 02635 } 02636 if ((mp3state->syncdetect)&&(state->syncerrors> SPLT_MAXSYNC)) 02637 { 02638 splt_mp3_checksync(mp3state); 02639 } 02640 02641 mp3state->h = splt_mp3_makehead(mp3state->headw, mp3state->mp3file, mp3state->h, begin); 02642 mp3state->frames++; 02643 02644 //if we have adjust mode, then put only 25% 02645 //else put 50% 02646 if (adjustoption) 02647 { 02648 splt_c_update_progress(state,(double)(mp3state->frames), 02649 (double)fend, 8, 02650 0,SPLT_DEFAULT_PROGRESS_RATE); 02651 } 02652 else 02653 { 02654 splt_c_update_progress(state,(double)(mp3state->frames), 02655 (double)fend,progress_adjust_val, 02656 0,SPLT_DEFAULT_PROGRESS_RATE); 02657 } 02658 } 02659 } 02660 else 02661 { 02662 begin = mp3state->end; 02663 } 02664 02665 splt_d_print_debug(state,"Begin is _%ld_\n", begin); 02666 02667 if (mp3state->mp3file.len > 0) 02668 { 02669 if (begin >= mp3state->mp3file.len) // If we can check, we just do that :) 02670 { 02671 *error = SPLT_ERROR_BEGIN_OUT_OF_FILE; 02672 goto bloc_end2; 02673 } 02674 } 02675 02676 splt_c_put_progress_text(state,SPLT_PROGRESS_PREPARE); 02677 02678 long int frames_begin = mp3state->frames; 02679 // Finds end by counting frames 02680 while (mp3state->frames <= fend) 02681 { 02682 mp3state->frames++; 02683 end = splt_mp3_findhead(mp3state, mp3state->h.ptr + mp3state->h.framesize); 02684 if (end == -1) 02685 { 02686 end = mp3state->h.ptr + mp3state->h.framesize; // Last valid offset 02687 eof=1; 02688 *error = SPLT_OK_SPLIT_EOF; 02689 break; 02690 } 02691 02692 //count the number of syncerrors 02693 if ((end != mp3state->h.ptr + mp3state->h.framesize)&&(state->syncerrors>=0)) 02694 { 02695 state->syncerrors++; 02696 } 02697 if ((mp3state->syncdetect)&&(state->syncerrors>SPLT_MAXSYNC)) 02698 { 02699 splt_mp3_checksync(mp3state); 02700 } 02701 02702 mp3state->h = splt_mp3_makehead (mp3state->headw, mp3state->mp3file, mp3state->h, end); 02703 02704 //if we have a progress callback function 02705 //time split only calculates the end of the 02706 //split 02707 int split_mode = splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE); 02708 if (((split_mode == SPLT_OPTION_TIME_MODE) || 02709 (split_mode == SPLT_OPTION_SILENCE_MODE)) 02710 && (!splt_o_get_int_option(state,SPLT_OPT_AUTO_ADJUST))) 02711 { 02712 splt_c_update_progress(state, (double)(mp3state->frames-fbegin), 02713 (double)(fend-fbegin), progress_adjust_val, 02714 0, SPLT_DEFAULT_PROGRESS_RATE); 02715 } 02716 else 02717 { 02718 if (adjustoption) 02719 { 02720 if(adjust) 02721 { 02722 if (split_mode == SPLT_OPTION_TIME_MODE) 02723 { 02724 splt_c_update_progress(state, 02725 (double)(mp3state->frames-frames_begin), 02726 (double)(fend-frames_begin), 02727 4,0,SPLT_DEFAULT_PROGRESS_RATE); 02728 } 02729 else 02730 { 02731 splt_c_update_progress(state, 02732 (double)(mp3state->frames-frames_begin), 02733 (double)(fend-frames_begin), 02734 8,1/(float)8,SPLT_DEFAULT_PROGRESS_RATE); 02735 } 02736 } 02737 } 02738 else 02739 { 02740 splt_c_update_progress(state, 02741 (double)(mp3state->frames-stopped_frames), 02742 (double)(fend-stopped_frames), 02743 progress_adjust_val, 02744 0,SPLT_DEFAULT_PROGRESS_RATE); 02745 } 02746 } 02747 02748 //if adjust option, scans for silence 02749 if ((adjust) && (mp3state->frames >= fend)) 02750 { 02751 int silence_points_found = 02752 splt_mp3_scan_silence(state, end, 2 * adjust, threshold, 0.f, 0, error); 02753 //if error, go out 02754 if (silence_points_found == -1) 02755 { 02756 goto bloc_end2; 02757 } 02758 else if (silence_points_found > 0) 02759 { 02760 adjust = (unsigned long) (splt_siu_silence_position(state->silence_list, mp3state->off) 02761 * mp3state->mp3file.fps); 02762 } 02763 else 02764 { 02765 adjust = (unsigned long) (adjustoption * mp3state->mp3file.fps); 02766 } 02767 fend += adjust; 02768 end = splt_mp3_findhead(mp3state, end); 02769 02770 sec_end_time = mp3state->frames / mp3state->mp3file.fps; 02771 02772 splt_siu_ssplit_free(&state->silence_list); 02773 adjust=0; 02774 //progress 02775 splt_c_put_progress_text(state,SPLT_PROGRESS_PREPARE); 02776 stopped_frames = mp3state->frames; 02777 } 02778 } 02779 02780 splt_mp3_save_end_point(state, mp3state, save_end_point, end); 02781 02782 //if xing, we get xing 02783 if (mp3state->mp3file.xing > 0) 02784 { 02785 unsigned long headw; 02786 headw = (unsigned long) (mp3state->frames - fbegin + 1); // Frames 02787 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+4] = (headw >> 24) & 0xFF; 02788 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+5] = (headw >> 16) & 0xFF; 02789 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+6] = (headw >> 8) & 0xFF; 02790 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+7] = headw & 0xFF; 02791 //we put the length of the file if end is -1 02792 if (end == -1) 02793 { 02794 end = mp3state->mp3file.len; 02795 } 02796 headw = (unsigned long) (end - begin + mp3state->mp3file.xing); // Bytes 02797 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+8] = (headw >> 24) & 0xFF; 02798 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+9] = (headw >> 16) & 0xFF; 02799 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+10] = (headw >> 8) & 0xFF; 02800 mp3state->mp3file.xingbuffer[mp3state->mp3file.xing_offset+11] = headw & 0xFF; 02801 } 02802 } 02803 else 02804 //if not framemode 02805 { 02806 splt_d_print_debug(state,"Starting mp3 seekable non frame mode...\n"); 02807 02808 long first_frame_offset = mp3state->inputBuffer + mp3state->buf_len - mp3state->data_ptr; 02809 02810 //find begin point if the last 'end' not saved 02811 if (mp3state->end == 0) 02812 { 02813 begin = (off_t) (fbegin_sec * mp3state->mp3file.bitrate + mp3state->mp3file.firsth); 02814 02815 if ((mp3state->bytes == begin) && (mp3state->data_len > 0)) 02816 { 02817 write_first_frame = SPLT_TRUE; 02818 begin += first_frame_offset; 02819 } 02820 else 02821 { 02822 begin = splt_mp3_findvalidhead(mp3state, begin); 02823 } 02824 02825 if (begin == -1) 02826 { 02827 *error = SPLT_ERROR_BEGIN_OUT_OF_FILE; 02828 goto bloc_end2; 02829 } 02830 if (splt_mp3_tabsel_123[1 - mp3state->mp3file.mpgid][mp3state->mp3file.layer-1][splt_mp3_c_bitrate(mp3state->headw)] != 02831 mp3state->mp3file.firsthead.bitrate) 02832 { 02833 check_bitrate = 1; 02834 } 02835 } 02836 //set the begin point from the last 'end' saved 02837 else 02838 { 02839 begin = mp3state->end; 02840 } 02841 02842 if (fend_sec_is_not_eof) 02843 { 02844 end = (off_t) (fend_sec * mp3state->mp3file.bitrate + mp3state->mp3file.firsth); 02845 if (write_first_frame) 02846 { 02847 end += first_frame_offset; 02848 } 02849 //take the whole last frame : might result in more frames 02850 //but if we don't do it, we might have less frames 02851 end = splt_mp3_findvalidhead(mp3state, end); 02852 if (splt_mp3_tabsel_123[1 - mp3state->mp3file.mpgid][mp3state->mp3file.layer-1][splt_mp3_c_bitrate(mp3state->headw)] != 02853 mp3state->mp3file.firsthead.bitrate) 02854 check_bitrate = 1; 02855 } 02856 else 02857 { 02858 end = -1; 02859 } 02860 02861 splt_mp3_save_end_point(state, mp3state, save_end_point, end); 02862 } 02863 02864 //seekable real split 02865 int err = splt_mp3_simple_split(state, output_fname, begin, end, 02866 SPLT_TRUE, write_first_frame); 02867 if (err < 0) { *error = err; } 02868 02869 if (!save_end_point) 02870 { 02871 if (splt_o_get_long_option(state, SPLT_OPT_OVERLAP_TIME) > 0) 02872 { 02873 mp3state->frames = 1; 02874 mp3state->first = 1; 02875 } 02876 } 02877 } 02878 02879 if (check_bitrate) 02880 { 02881 *error = SPLT_MIGHT_BE_VBR; 02882 } 02883 02884 if (*error == SPLT_OK) { *error = SPLT_OK_SPLIT; } 02885 02886 bloc_end2: 02887 02888 return sec_end_time; 02889 } 02890 02891 /****************************/ 02892 /* mp3 syncerror */ 02893 02896 static off_t splt_mp3_adjustsync(splt_mp3_state *mp3state, off_t begin, off_t end) 02897 { 02898 off_t position; 02899 position = begin; 02900 if (fseeko(mp3state->file_input, position, SEEK_SET)==-1) 02901 { 02902 return (off_t) (-1); 02903 } 02904 02905 // First we search for ID3v1 02906 while (position++ < end) 02907 { 02908 if (fgetc(mp3state->file_input)=='T') { 02909 if (fgetc(mp3state->file_input)=='A') { 02910 if (fgetc(mp3state->file_input)=='G') 02911 return (position + 127); 02912 else position++; 02913 } 02914 if (fseeko(mp3state->file_input, -1, SEEK_CUR) == -1) 02915 { 02916 return (off_t) (-1); 02917 } 02918 } 02919 } 02920 02921 position = begin; 02922 02923 if (fseeko(mp3state->file_input, position, SEEK_SET)==-1) 02924 { 02925 return (off_t) (-1); 02926 } 02927 02928 // Now we search for ID3v2 02929 while (position++ < end) 02930 { 02931 if (fgetc(mp3state->file_input)=='I') 02932 { 02933 if (fgetc(mp3state->file_input)=='D') 02934 { 02935 if (fgetc(mp3state->file_input)=='3') 02936 { 02937 return (position - 1); 02938 } 02939 else 02940 { 02941 position++; 02942 } 02943 } 02944 if(fseeko(mp3state->file_input, -1, SEEK_CUR)==-1) 02945 { 02946 return (off_t) (-1); 02947 } 02948 } 02949 } 02950 02951 return end; 02952 } 02953 02955 static void splt_mp3_syncerror_search(splt_state *state, int *error) 02956 { 02957 off_t offset = 0; 02958 char *filename = splt_t_get_filename_to_split(state); 02959 int sync_err = SPLT_OK; 02960 02961 splt_mp3_state *mp3state = state->codec; 02962 02963 splt_c_put_progress_text(state,SPLT_PROGRESS_SEARCH_SYNC); 02964 02965 mp3state->h.ptr = mp3state->mp3file.firsthead.ptr; 02966 mp3state->h.framesize = mp3state->mp3file.firsthead.framesize; 02967 02968 //we get the file length for the progress 02969 off_t st_size; 02970 if(splt_io_stat(filename, NULL, &st_size) == 0) 02971 { 02972 //put the start point 02973 sync_err = splt_se_serrors_append_point(state, 0); 02974 if (sync_err != SPLT_OK) 02975 { 02976 *error = sync_err; 02977 return; 02978 } 02979 02980 //search for sync errors and put in splitpoints 02981 while (state->serrors->serrors_points_num < SPLT_MAXSYNC) 02982 { 02983 offset = splt_mp3_findhead(mp3state, mp3state->h.ptr + mp3state->h.framesize); 02984 if (offset==-1) 02985 { 02986 break; 02987 } 02988 02989 if (offset != mp3state->h.ptr + mp3state->h.framesize) 02990 { 02991 off_t serror_point = 02992 splt_mp3_adjustsync(mp3state, mp3state->h.ptr, offset); 02993 02994 sync_err = splt_se_serrors_append_point(state, serror_point); 02995 if (sync_err != SPLT_OK) 02996 { 02997 *error = sync_err; 02998 return; 02999 } 03000 offset = splt_mp3_findvalidhead(mp3state, serror_point); 03001 if (splt_io_get_word(mp3state->file_input, offset, SEEK_SET, &mp3state->headw) == -1) 03002 { 03003 *error = SPLT_ERR_SYNC; 03004 return; 03005 } 03006 } 03007 03008 mp3state->h = splt_mp3_makehead (mp3state->headw, mp3state->mp3file, 03009 mp3state->h, offset); 03010 03011 if (splt_t_split_is_canceled(state)) 03012 { 03013 *error = SPLT_SPLIT_CANCELLED; 03014 return; 03015 } 03016 03017 //progress 03018 splt_c_update_progress(state,(double)(offset), 03019 (double)(st_size),1,0, 03020 SPLT_DEFAULT_PROGRESS_RATE); 03021 } 03022 } 03023 else 03024 { 03025 splt_e_set_strerror_msg_with_data(state, filename); 03026 *error = SPLT_ERROR_CANNOT_OPEN_FILE; 03027 return; 03028 } 03029 03030 if (state->serrors->serrors_points_num == 0) 03031 { 03032 *error = SPLT_ERR_NO_SYNC_FOUND; 03033 return; 03034 } 03035 03036 if (state->serrors->serrors_points_num == SPLT_MAXSYNC) 03037 { 03038 *error = SPLT_ERR_TOO_MANY_SYNC_ERR; 03039 return; 03040 } 03041 03042 //put the end point 03043 sync_err = splt_se_serrors_append_point(state, LONG_MAX); 03044 if (sync_err != SPLT_OK) 03045 { 03046 *error = sync_err; 03047 return; 03048 } 03049 03050 *error = SPLT_SYNC_OK; 03051 03052 return; 03053 } 03054 03055 /****************************/ 03056 /* mp3 dewrap */ 03057 03059 static const unsigned char splt_mp3_albumwraphead[22] = 03060 { 03061 0xa, 0x23, 0x54, 0x49, 0x54, 0x32, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x41, 0x6c, 0x62, 0x75, 0x6d, 0x57, 0x72, 0x61, 0x70, 03062 }; 03063 03069 static void splt_mp3_dewrap(int listonly, const char *dir, int *error, splt_state *state) 03070 { 03071 if (listonly) 03072 { 03073 *error = SPLT_OK; 03074 } 03075 else 03076 { 03077 *error = SPLT_DEWRAP_OK; 03078 } 03079 03080 //if albumwrap or mp3wrap 03081 short albumwrap=0, mp3wrap=0; 03082 //wrapfiles = the wrapped files number 03083 int wrapfiles=0, i, j, k=0; 03084 unsigned char c; 03085 char filename[2048] = { '\0' }; 03086 off_t begin=0, end=0, len = 0, id3offset = 0; 03087 char junk[2048] = { '\0' }; 03088 char *file_to_dewrap = splt_t_get_filename_to_split(state); 03089 03090 //if error 03091 if (*error < 0) 03092 { 03093 return; 03094 } 03095 else 03096 { 03097 splt_mp3_state *mp3state = state->codec; 03098 03099 if (*error >= 0) 03100 { 03101 len = splt_io_get_file_length(state, mp3state->file_input, file_to_dewrap, error); 03102 if (error < 0) { return; } 03103 03104 id3offset = splt_mp3_getid3v2_end_offset(mp3state->file_input, 0); 03105 03106 //we go at the beginning of the file 03107 if (fseeko(mp3state->file_input, id3offset, SEEK_SET)==-1) 03108 { 03109 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED; 03110 return; 03111 } 03112 03113 splt_d_print_debug(state,"Searching for wrap string...\n"); 03114 03115 //we search the WRAP string in the file to see if it was wrapped 03116 //with mp3wrap 03117 for (i=0; i<16384; i++) 03118 { 03119 if (feof(mp3state->file_input)) 03120 { 03121 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED; 03122 return; 03123 } 03124 if ((id3offset = ftello(mp3state->file_input))==-1) 03125 { 03126 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED; 03127 return; 03128 } 03129 if (fgetc(mp3state->file_input)=='W') 03130 if (fgetc(mp3state->file_input)=='R') 03131 if (fgetc(mp3state->file_input)=='A') 03132 if (fgetc(mp3state->file_input)=='P') 03133 { 03134 mp3wrap = 1; 03135 break; 03136 } 03137 } 03138 03139 //we check if the file was wrapped with albumwrap 03140 //only if not mp3wrap 03141 if (!mp3wrap && (id3offset!=0)) 03142 { 03143 if (fseeko(mp3state->file_input, (off_t) 8, SEEK_SET)==-1) 03144 { 03145 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED; 03146 return; 03147 } 03148 albumwrap = 1; 03149 for (i=0; i<22; i++) 03150 { 03151 if (splt_mp3_albumwraphead[i]!=fgetc(mp3state->file_input)) 03152 { 03153 albumwrap = 0; 03154 break; 03155 } 03156 } 03157 } 03158 03159 //we do the mp3wrap or albumwrap 03160 if (albumwrap || mp3wrap) 03161 { 03162 splt_d_print_debug(state,"Effective dewrap...\n"); 03163 03164 //mp3wrap checkings and we get the wrap file number 03165 if (mp3wrap) { 03166 splt_d_print_debug(state,"Mp3 mp3wrap check...\n"); 03167 short indexver; 03168 03169 //Mp3Wrap version 03170 char major_v = fgetc(mp3state->file_input); 03171 char minor_v = fgetc(mp3state->file_input); 03172 03173 splt_c_put_info_message_to_client(state, 03174 _(" Detected file created with: Mp3Wrap v. %c.%c\n"), 03175 major_v,minor_v); 03176 03177 indexver = fgetc(mp3state->file_input); 03178 if (indexver > SPLT_MP3_INDEXVERSION) 03179 { 03180 *error = SPLT_DEWRAP_ERR_VERSION_OLD; 03181 return; 03182 } 03183 wrapfiles = (int) fgetc(mp3state->file_input); 03184 if (feof(mp3state->file_input)) 03185 { 03186 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED; 03187 return; 03188 } 03189 //crc 03190 if (indexver > 0x0) 03191 { 03192 unsigned long crc = 0, fcrc = 0; 03193 if (splt_io_get_word(mp3state->file_input, 0, SEEK_CUR, &fcrc)==-1) 03194 { 03195 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED; 03196 return; 03197 } 03198 03199 //perform CRC only if we don't have quiet mode 03200 if (! splt_o_get_int_option(state, SPLT_OPT_QUIET_MODE)) 03201 { 03202 begin = ftello(mp3state->file_input); 03203 if (fseeko(mp3state->file_input, 03204 splt_mp3_getid3v1_offset(mp3state->file_input), SEEK_END)==-1) 03205 { 03206 splt_e_set_strerror_msg_with_data(state, file_to_dewrap); 03207 *error = SPLT_ERROR_SEEKING_FILE; 03208 return; 03209 } 03210 end = ftello(mp3state->file_input); 03211 splt_c_put_info_message_to_client(state, 03212 _(" Check for file integrity: calculating CRC please wait... ")); 03213 crc = splt_mp3_c_crc(state, mp3state->file_input, begin, end, error); 03214 if (*error < 0) 03215 { 03216 return; 03217 } 03218 if (crc != fcrc) 03219 { 03220 //No interactivity in the library (for the moment) 03221 //fprintf (stderr, "BAD\nWARNING: Bad CRC. File might be damaged. Continue anyway? (y/n) "); 03222 //fgets(junk, 32, stdin); 03223 //if (junk[0]!='y') 03224 //error("Aborted.",125); 03225 //- no interactivity in the library for the moment 03226 *error = SPLT_ERROR_CRC_FAILED; 03227 return; 03228 } 03229 else 03230 { 03231 splt_c_put_info_message_to_client(state, _(" OK\n")); 03232 } 03233 if (fseeko(mp3state->file_input, begin, SEEK_SET)==-1) 03234 { 03235 splt_e_set_strerror_msg_with_data(state, file_to_dewrap); 03236 *error = SPLT_ERROR_SEEKING_FILE; 03237 return; 03238 } 03239 } 03240 } 03241 } 03242 03243 //the albumwrap checkings and we get the wrap files number in 03244 //wrapfiles variable 03245 if (albumwrap) 03246 { 03247 splt_d_print_debug(state,"Mp3 albumwrap check...\n"); 03248 03249 splt_c_put_info_message_to_client(state, 03250 _(" Detected file created with: AlbumWrap\n")); 03251 03252 if (fseeko(mp3state->file_input, (off_t) 0x52d, SEEK_SET)==-1) 03253 { 03254 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED; 03255 return; 03256 } 03257 i = 0; 03258 while (((c=fgetc(mp3state->file_input))!=0x20) &&(i<2048)) 03259 junk[i++] = c; 03260 junk[i] = '\0'; 03261 wrapfiles = atoi (junk); 03262 } 03263 if (wrapfiles<=0) 03264 { 03265 *error = SPLT_DEWRAP_ERR_NO_FILE_OR_BAD_INDEX; 03266 return; 03267 } 03268 03269 //we put the number of "splitpoints" 03270 state->split.splitnumber = wrapfiles+1; 03271 03272 splt_c_put_info_message_to_client(state, _(" Total files: %d\n"),wrapfiles); 03273 03274 //we do the dewrap 03275 for (i=0; i<wrapfiles; i++) 03276 { 03277 if (!splt_t_split_is_canceled(state)) 03278 { 03279 //we put the current file to split 03280 splt_t_set_current_split(state, i+1); 03281 03282 //if the first time, we get the begin, 03283 //otherwise the begin will be the end of the previous 03284 if (i==0) 03285 { 03286 //we get the begin wrap 03287 if (mp3wrap) 03288 { 03289 unsigned long w; 03290 if (splt_io_get_word (mp3state->file_input, 0, SEEK_CUR, &w)==-1) 03291 { 03292 splt_e_set_error_data(state,file_to_dewrap); 03293 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03294 return; 03295 } 03296 begin = (off_t) (w + id3offset); 03297 } 03298 03299 //we get the begin wrap 03300 if (albumwrap) 03301 { 03302 if (fseeko (mp3state->file_input, 03303 (off_t) SPLT_MP3_ABWINDEXOFFSET, SEEK_SET)==-1) 03304 { 03305 splt_e_set_error_data(state,file_to_dewrap); 03306 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03307 return; 03308 } 03309 j = 0; 03310 while ((c=fgetc(mp3state->file_input))!='[') 03311 if (j++ > 32) 03312 { 03313 splt_e_set_error_data(state,file_to_dewrap); 03314 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03315 return; 03316 } 03317 if (fseeko(mp3state->file_input, (off_t) 3, SEEK_CUR)==-1) 03318 { 03319 splt_e_set_error_data(state,file_to_dewrap); 03320 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03321 return; 03322 } 03323 j = 0; 03324 while ((j<2048) && ((c = fgetc(mp3state->file_input))!='[')) 03325 if (c!='.') junk[j++] = c; 03326 else k = j; 03327 junk[j] = '\0'; 03328 begin = (off_t) atol (junk); 03329 k = j - k; 03330 if (k<4) 03331 { 03332 for (j=0; j<(4-k); j++) 03333 { 03334 begin = begin * 10; 03335 } 03336 } 03337 } 03338 } 03339 else 03340 { 03341 begin = end; 03342 } 03343 03344 //we get the end and checkings.. 03345 if (mp3wrap) 03346 { 03347 unsigned long w; 03348 j = 0; 03349 do 03350 { 03351 c = fgetc(mp3state->file_input); 03352 //for files wrapped using windows 03353 if (c==SPLT_NDIRCHAR) 03354 { 03355 c=SPLT_DIRCHAR; 03356 } 03357 filename[j++] = c; 03358 } while ((c!=0x00)&&(j<2048)); 03359 03360 if (splt_io_get_word (mp3state->file_input, 0, SEEK_CUR, &w) == -1) 03361 { 03362 splt_e_set_error_data(state,file_to_dewrap); 03363 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03364 return; 03365 } 03366 03367 end = (off_t) (w + id3offset); 03368 03369 //create output directories for the wrapped files 03370 //if we don't list only and if we don't have an output 03371 //directory 03372 if (!listonly && (!dir || dir[0] == '\0')) 03373 { 03374 memset(junk, 0x00, 2048); 03375 char *ptr = filename; 03376 while (((ptr = strchr(ptr, SPLT_DIRCHAR))!=NULL)&&((ptr-filename)<2048)) 03377 { 03378 ptr++; 03379 strncpy(junk, filename, ptr-filename); 03380 if (! splt_io_check_if_directory(junk)) 03381 { 03382 if ((splt_io_mkdir(state, junk)) == -1) 03383 { 03384 *error = SPLT_ERROR_CANNOT_CREATE_DIRECTORY; 03385 splt_e_set_strerror_msg_with_data(state, junk); 03386 return; 03387 } 03388 } 03389 } 03390 } 03391 } 03392 03393 //we get the end wrap point for albumwrap and 03394 //checkings.. 03395 if (albumwrap) 03396 { 03397 if (i<wrapfiles-1) 03398 { 03399 if (fseeko (mp3state->file_input, 03400 (off_t) (SPLT_MP3_ABWINDEXOFFSET + (i * SPLT_MP3_ABWLEN)), SEEK_SET)==-1) 03401 { 03402 splt_e_set_error_data(state,file_to_dewrap); 03403 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03404 return; 03405 } 03406 j = 0; 03407 while ((j<2048) && ((c = fgetc(mp3state->file_input))!='[')) 03408 if (c!='.') junk[j++] = c; 03409 else k = j; 03410 junk[j] = '\0'; 03411 end = (off_t) atol (junk); 03412 k = j - k; 03413 if (k<4) 03414 for (j=0; j<(4-k); j++) 03415 end = end * 10; 03416 end += begin; 03417 } 03418 else end = len; 03419 03420 if (fseeko (mp3state->file_input, 03421 (off_t) (SPLT_MP3_ABWINDEXOFFSET + (i*SPLT_MP3_ABWLEN)), SEEK_SET)==-1) 03422 { 03423 splt_e_set_error_data(state,file_to_dewrap); 03424 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03425 } 03426 j = 0; 03427 while ((c=fgetc(mp3state->file_input))!='[') 03428 if (j++ > 32) 03429 { 03430 splt_e_set_error_data(state,file_to_dewrap); 03431 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03432 return; 03433 } 03434 if (fseeko (mp3state->file_input, (off_t) 3, SEEK_CUR)==-1) 03435 { 03436 splt_e_set_error_data(state,file_to_dewrap); 03437 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03438 return; 03439 } 03440 j = 0; 03441 while ((c=fgetc(mp3state->file_input))!='[') 03442 if (j++ > 32) 03443 { 03444 splt_e_set_error_data(state,file_to_dewrap); 03445 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03446 return; 03447 } 03448 if (fseeko(mp3state->file_input, (off_t) 3, SEEK_CUR)==-1) 03449 { 03450 splt_e_set_error_data(state,file_to_dewrap); 03451 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03452 return; 03453 } 03454 j = 0; 03455 while (j<=400) 03456 filename[j++] = fgetc(mp3state->file_input); 03457 for (j=400; j>0; j--) { 03458 if (filename[j]==0x20) 03459 filename[j]='\0'; 03460 else break; 03461 } 03462 filename[j+1] = '\0'; 03463 } 03464 03465 splt_d_print_debug(state,"Found the file _%s_\n", filename); 03466 splt_d_print_debug(state,"Cut the dirchar"); 03467 03468 //we cut the .DIRCHAR before the filename 03469 char str_temp[4]; 03470 snprintf(str_temp,4,"%c%c",'.',SPLT_DIRCHAR); 03471 if (strstr(filename,str_temp) != NULL) 03472 { 03473 char *filename2 = strdup(filename); 03474 if (!filename2) 03475 { 03476 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY; 03477 return; 03478 } 03479 else 03480 { 03481 snprintf(filename,2048, "%s", filename2+2); 03482 free(filename2); 03483 filename2 = NULL; 03484 } 03485 } 03486 03487 if (feof(mp3state->file_input)) 03488 { 03489 splt_e_set_error_data(state,file_to_dewrap); 03490 *error = SPLT_DEWRAP_ERR_FILE_DAMAGED_INCOMPLETE; 03491 return; 03492 } 03493 03494 //if we only list the contents 03495 //we put the files in the wrap_files 03496 if (listonly) 03497 { 03498 splt_d_print_debug(state,"Only list wrapped files\n"); 03499 03500 int put_file_error = SPLT_OK; 03501 put_file_error = splt_w_wrap_put_file(state, wrapfiles, i, filename); 03502 if (put_file_error != SPLT_OK) 03503 { 03504 *error = put_file_error; 03505 return; 03506 } 03507 } 03508 //if we split the file 03509 //we split from begin to end calculated previously 03510 else 03511 { 03512 splt_d_print_debug(state,"Split wrapped file\n"); 03513 03514 int ret = 0; 03515 //if we have an output directory 03516 //-try to create it 03517 if (dir && (dir[0] != '\0')) 03518 { 03519 char temp[2048] = { '\0' }; 03520 strncpy(temp, filename, 2048); 03521 char *ptr = temp; 03522 //if we have an output dir, cut directory path from filename 03523 if ((ptr = strrchr(temp,SPLT_DIRCHAR)) == NULL) 03524 { 03525 ptr = temp; 03526 } 03527 else 03528 { 03529 if (ptr-temp > 0) 03530 { 03531 ptr++; 03532 } 03533 } 03534 //if dir == .DIRCHAR 03535 if (strcmp(dir,str_temp) == 0) 03536 { 03537 snprintf(filename, 2048,"%s%s", dir, ptr); 03538 } 03539 else 03540 { 03541 if (dir[strlen(dir)-1] == SPLT_DIRCHAR) 03542 { 03543 snprintf(filename, 2048,"%s%s", dir, ptr); 03544 } 03545 else 03546 { 03547 snprintf(filename, 2048,"%s%c%s", dir, SPLT_DIRCHAR, ptr); 03548 } 03549 } 03550 splt_d_print_debug(state,"wrap dir _%s_\n", dir); 03551 splt_d_print_debug(state,"wrap after dir _%s_\n", ptr); 03552 } 03553 03554 //free xingbuffer 03555 if (mp3state->mp3file.xingbuffer) 03556 { 03557 free(mp3state->mp3file.xingbuffer); 03558 mp3state->mp3file.xingbuffer = NULL; 03559 } 03560 mp3state->mp3file.xing = 0; 03561 03562 int append_err = SPLT_OK; 03563 append_err = splt_sp_append_splitpoint(state,0, 03564 splt_su_get_fname_without_path(filename), SPLT_SPLITPOINT); 03565 if (append_err != SPLT_OK) 03566 { 03567 *error = append_err; 03568 return; 03569 } 03570 03571 //cut extension 03572 int cut_err = splt_sp_cut_splitpoint_extension(state,i); 03573 if (cut_err != SPLT_OK) 03574 { 03575 *error = cut_err; 03576 return; 03577 } 03578 03579 //do the real wrap split 03580 ret = splt_mp3_simple_split(state, filename, begin, end, 03581 SPLT_FALSE, SPLT_FALSE); 03582 03583 //if we could split put the split file 03584 if (ret >= 0) 03585 { 03586 ret = splt_c_put_split_file(state, filename); 03587 if (ret < 0) { *error = ret; } 03588 } 03589 else 03590 { 03591 *error = ret; 03592 } 03593 } 03594 } 03595 } 03596 } 03597 else 03598 { 03599 *error = SPLT_DEWRAP_ERR_FILE_NOT_WRAPED_DAMAGED; 03600 return; 03601 } 03602 } 03603 } 03604 } 03605 03607 void splt_mp3_init(splt_state *state, int *error) 03608 { 03609 FILE *file_input = NULL; 03610 char *filename = splt_t_get_filename_to_split(state); 03611 03612 state->syncerrors = 0; 03613 03614 //if we can open the file 03615 if ((file_input = splt_mp3_open_file_read(state, filename, error)) != NULL) 03616 { 03617 splt_mp3_get_info(state, file_input, error); 03618 03619 if (*error >= 0) 03620 { 03621 splt_mp3_state *mp3state = state->codec; 03622 mp3state->off = splt_o_get_float_option(state,SPLT_OPT_PARAM_OFFSET); 03623 03624 //we initialise frames to 1 03625 if (splt_t_get_total_time(state) > 0) 03626 { 03627 mp3state->frames = 1; 03628 } 03629 } 03630 } 03631 } 03632 03645 void splt_pl_set_plugin_info(splt_plugin_info *info, int *error) 03646 { 03647 float plugin_version = 1.0; 03648 03649 //set plugin version 03650 info->version = plugin_version; 03651 03652 //set plugin name 03653 info->name = malloc(sizeof(char) * 40); 03654 if (info->name != NULL) 03655 { 03656 snprintf(info->name, 39, "mp3 (libmad)"); 03657 } 03658 else 03659 { 03660 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY; 03661 return; 03662 } 03663 03664 //set plugin extension 03665 info->extension = malloc(sizeof(char) * (strlen(SPLT_MP3EXT)+2)); 03666 if (info->extension != NULL) 03667 { 03668 snprintf(info->extension, strlen(SPLT_MP3EXT)+1, SPLT_MP3EXT); 03669 } 03670 else 03671 { 03672 *error = SPLT_ERROR_CANNOT_ALLOCATE_MEMORY; 03673 return; 03674 } 03675 03676 info->upper_extension = splt_su_convert(info->extension, SPLT_TO_UPPERCASE, error); 03677 } 03678 03680 void splt_pl_init(splt_state *state, int *error) 03681 { 03682 if (splt_io_input_is_stdin(state)) 03683 { 03684 char *filename = splt_t_get_filename_to_split(state); 03685 if (filename[1] == '\0') 03686 { 03687 splt_c_put_info_message_to_client(state, 03688 _(" warning: stdin '-' is supposed to be mp3 stream.\n")); 03689 } 03690 } 03691 03692 splt_mp3_init(state, error); 03693 } 03694 03696 void splt_pl_end(splt_state *state, int *error) 03697 { 03698 //put infos about the frames processed and the number of sync errors 03699 //ONLY if framemode 03700 if ((splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_SILENCE_MODE) 03701 && (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_ERROR_MODE) 03702 && (splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE) != SPLT_OPTION_WRAP_MODE)) 03703 { 03704 if (splt_o_get_int_option(state, SPLT_OPT_FRAME_MODE)) 03705 { 03706 if (*error >= 0) 03707 { 03708 splt_mp3_state *mp3state = state->codec; 03709 //-if we don't save the end point, the ->frames are set to 1 at the 03710 //end of the split 03711 if (mp3state->frames != 1) 03712 { 03713 splt_c_put_info_message_to_client(state, 03714 _(" Processed %lu frames - Sync errors: %lu\n"), 03715 mp3state->frames, state->syncerrors); 03716 } 03717 } 03718 } 03719 } 03720 splt_mp3_end(state, error); 03721 } 03722 03724 int splt_pl_check_plugin_is_for_file(splt_state *state, int *error) 03725 { 03726 char *filename = splt_t_get_filename_to_split(state); 03727 03728 if (filename != NULL && ((strcmp(filename,"-") == 0) || 03729 (strcmp(filename,"m-") == 0))) 03730 { 03731 return SPLT_TRUE; 03732 } 03733 03734 int is_mp3 = SPLT_FALSE; 03735 03736 splt_o_lock_messages(state); 03737 splt_mp3_init(state, error); 03738 splt_o_unlock_messages(state); 03739 if (*error >= 0) 03740 { 03741 splt_mp3_state *mp3state = state->codec; 03742 if (mp3state) 03743 { 03744 is_mp3 = SPLT_TRUE; 03745 } 03746 } 03747 splt_mp3_end(state, error); 03748 03749 return is_mp3; 03750 } 03751 03753 void splt_pl_search_syncerrors(splt_state *state, int *error) 03754 { 03755 //we detect sync errors 03756 splt_mp3_syncerror_search(state, error); 03757 } 03758 03760 void splt_pl_dewrap(splt_state *state, int listonly, const char *dir, int *error) 03761 { 03762 splt_w_wrap_free(state); 03763 splt_mp3_dewrap(listonly, dir, error, state); 03764 } 03765 03766 double splt_pl_split(splt_state *state, const char *final_fname, 03767 double begin_point, double end_point, int *error, int save_end_point) 03768 { 03769 return splt_mp3_split(final_fname, state, begin_point, end_point, error, save_end_point); 03770 } 03771 03773 int splt_pl_simple_split(splt_state *state, char *output_fname, off_t begin, off_t end) 03774 { 03775 int error = SPLT_OK; 03776 03777 splt_mp3_state *mp3state = state->codec; 03778 03779 //we initialise frames to 1 03780 if (splt_t_get_total_time(state) > 0) 03781 { 03782 mp3state->frames = 1; 03783 } 03784 03785 //effective mp3 split 03786 error = splt_mp3_simple_split(state, output_fname, begin, end, 03787 SPLT_FALSE, SPLT_FALSE); 03788 03789 return error; 03790 } 03791 03793 int splt_pl_scan_silence(splt_state *state, int *error) 03794 { 03795 float offset = splt_o_get_float_option(state,SPLT_OPT_PARAM_OFFSET); 03796 float threshold = splt_o_get_float_option(state, SPLT_OPT_PARAM_THRESHOLD); 03797 float min_length = splt_o_get_float_option(state, SPLT_OPT_PARAM_MIN_LENGTH); 03798 int found = 0; 03799 03800 splt_mp3_state *mp3state = state->codec; 03801 mp3state->off = offset; 03802 03803 found = splt_mp3_scan_silence(state, mp3state->mp3file.firsthead.ptr, 0, 03804 threshold, min_length, 1, error); 03805 03806 return found; 03807 } 03808 03810 void splt_pl_set_original_tags(splt_state *state, int *error) 03811 { 03812 splt_d_print_debug(state, "Getting original tags ..."); 03813 #ifndef NO_ID3TAG 03814 splt_d_print_debug(state, "Taking original ID3 tags from file using libid3tag ...\n"); 03815 splt_mp3_get_original_tags(splt_t_get_filename_to_split(state), state, error); 03816 #else 03817 splt_d_print_debug(state, "Warning ! NO_ID3TAG"); 03818 //splt_e_error(SPLT_IERROR_SET_ORIGINAL_TAGS,__func__, 0, NULL); 03819 #endif 03820 } 03821