libmp3splt
|
00001 /********************************************************** 00002 * 00003 * libmp3splt -- library based on mp3splt, 00004 * for mp3/ogg splitting without decoding 00005 * 00006 * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net> 00007 * Copyright (c) 2005-2011 Alexandru Munteanu - io_fx@yahoo.fr 00008 * 00009 * http://mp3splt.sourceforge.net 00010 * 00011 *********************************************************/ 00012 00013 /********************************************************** 00014 * 00015 * This program is free software; you can redistribute it and/or 00016 * modify it under the terms of the GNU General Public License 00017 * as published by the Free Software Foundation; either version 2 00018 * of the License, or (at your option) any later version. 00019 * 00020 * This program is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * You should have received a copy of the GNU General Public License 00026 * along with this program; if not, write to the Free Software 00027 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00028 * 02111-1307, 00029 * USA. 00030 * 00031 *********************************************************/ 00032 00038 #include <sys/stat.h> 00039 #include <string.h> 00040 #include <math.h> 00041 00042 #include "splt.h" 00043 00044 /****************************/ 00046 static long splt_s_real_split(double splt_beg, double splt_end, 00047 int save_end_point, int *error, splt_state *state) 00048 { 00049 char *final_fname = splt_su_get_fname_with_path_and_extension(state,error); 00050 long new_end_point = splt_co_time_to_long_ceil(splt_end); 00051 00052 if (*error >= 0) 00053 { 00054 double new_sec_end_point = 00055 splt_p_split(state, final_fname, splt_beg, splt_end, error, save_end_point); 00056 new_end_point = splt_co_time_to_long_ceil(new_sec_end_point); 00057 00058 if (*error >= 0) 00059 { 00060 splt_c_update_progress(state,1.0,1.0,1,1,1); 00061 00062 int err = SPLT_OK; 00063 err = splt_c_put_split_file(state, final_fname); 00064 if (err < 0) { *error = err; } 00065 } 00066 } 00067 00068 if (final_fname) 00069 { 00070 free(final_fname); 00071 final_fname = NULL; 00072 } 00073 00074 return new_end_point; 00075 } 00076 00078 static long splt_s_split(splt_state *state, int first_splitpoint, 00079 int second_splitpoint, int *error) 00080 { 00081 int get_error = SPLT_OK; 00082 long split_begin = splt_sp_get_splitpoint_value(state, first_splitpoint, &get_error); 00083 long split_end = splt_sp_get_splitpoint_value(state, second_splitpoint, &get_error); 00084 00085 long new_end_point = split_end; 00086 00087 int save_end_point = SPLT_TRUE; 00088 if (splt_sp_get_splitpoint_type(state, second_splitpoint, &get_error) == SPLT_SKIPPOINT || 00089 splt_o_get_long_option(state, SPLT_OPT_OVERLAP_TIME) > 0) 00090 { 00091 save_end_point = SPLT_FALSE; 00092 } 00093 00094 if (get_error == SPLT_OK) 00095 { 00096 //if no error 00097 if (*error >= 0) 00098 { 00099 //if the first splitpoint different than the end point 00100 if (split_begin != split_end) 00101 { 00102 //convert to float for hundredth 00103 // 34.6 --> 34 seconds and 6 hundredth 00104 double splt_beg = split_begin / 100; 00105 splt_beg += ((split_begin % 100) / 100.); 00106 double splt_end = 0; 00107 00108 //LONG_MAX == EOF 00109 if (split_end == LONG_MAX) 00110 { 00111 //Warning : we might not always have total time with input not seekable 00112 splt_end = splt_t_get_total_time_as_double_secs(state); 00113 } 00114 else 00115 { 00116 splt_end = split_end / 100; 00117 splt_end += ((split_end % 100) / 100.); 00118 } 00119 00120 new_end_point = splt_s_real_split(splt_beg, splt_end, save_end_point, error, state); 00121 } 00122 else 00123 { 00124 splt_e_set_error_data_from_splitpoint(state, split_begin); 00125 *error = SPLT_ERROR_EQUAL_SPLITPOINTS; 00126 } 00127 } 00128 } 00129 else 00130 { 00131 *error = get_error; 00132 } 00133 00134 return new_end_point; 00135 } 00136 00138 void splt_s_multiple_split(splt_state *state, int *error) 00139 { 00140 int split_type = splt_o_get_int_option(state, SPLT_OPT_SPLIT_MODE); 00141 int err = SPLT_OK; 00142 00143 splt_of_set_oformat_digits(state); 00144 00145 if (split_type == SPLT_OPTION_NORMAL_MODE) 00146 { 00147 splt_c_put_info_message_to_client(state, _(" info: starting normal split\n")); 00148 } 00149 00150 splt_u_print_overlap_time(state); 00151 00152 int get_error = SPLT_OK; 00153 00154 splt_array *new_end_points = splt_array_new(); 00155 00156 int i = 0; 00157 int number_of_splitpoints = splt_t_get_splitnumber(state); 00158 while (i < number_of_splitpoints - 1) 00159 { 00160 splt_t_set_current_split(state, i); 00161 00162 if (!splt_t_split_is_canceled(state)) 00163 { 00164 get_error = SPLT_OK; 00165 00166 int first_splitpoint_type = splt_sp_get_splitpoint_type(state, i, &get_error); 00167 if (first_splitpoint_type == SPLT_SKIPPOINT) 00168 { 00169 splt_d_print_debug(state, "SKIP splitpoint at _%d_\n", i); 00170 i++; 00171 continue; 00172 } 00173 00174 splt_tu_auto_increment_tracknumber(state); 00175 00176 long saved_end_point = splt_sp_get_splitpoint_value(state, i+1, &get_error); 00177 splt_sp_overlap_time(state, i + 1); 00178 00179 err = splt_u_finish_tags_and_put_output_format_filename(state, i); 00180 if (err < 0) { *error = err; goto end; } 00181 00182 int end_point_index = i+1; 00183 long new_end_point = splt_s_split(state, i, end_point_index, error); 00184 splt_pair *index_end_point = 00185 splt_pair_new((void *) &end_point_index, (void *) &new_end_point); 00186 splt_array_append(new_end_points, (void *)index_end_point); 00187 00188 splt_sp_set_splitpoint_value(state, i + 1, saved_end_point); 00189 00190 if ((*error < 0) || (*error == SPLT_OK_SPLIT_EOF)) 00191 { 00192 break; 00193 } 00194 } 00195 else 00196 { 00197 *error = SPLT_SPLIT_CANCELLED; 00198 goto end; 00199 } 00200 00201 i++; 00202 } 00203 00204 end: 00205 for (i = 0;i < splt_array_length(new_end_points);i++) 00206 { 00207 splt_pair *index_end_point = (splt_pair *) splt_array_get(new_end_points, i); 00208 00209 splt_sp_set_splitpoint_value(state, 00210 *((int*) splt_pair_first(index_end_point)), 00211 *((long*) splt_pair_second(index_end_point))); 00212 00213 splt_pair_free(&index_end_point); 00214 } 00215 00216 splt_array_free(&new_end_points); 00217 } 00218 00219 void splt_s_normal_split(splt_state *state, int *error) 00220 { 00221 int output_filenames = splt_o_get_int_option(state,SPLT_OPT_OUTPUT_FILENAMES); 00222 if (output_filenames == SPLT_OUTPUT_DEFAULT) 00223 { 00224 splt_of_set_oformat(state, SPLT_DEFAULT_OUTPUT, error, SPLT_TRUE); 00225 if (*error < 0) { return; } 00226 } 00227 00228 splt_s_multiple_split(state, error); 00229 } 00230 00232 void splt_s_error_split(splt_state *state, int *error) 00233 { 00234 splt_c_put_info_message_to_client(state, _(" info: starting error mode split\n")); 00235 char *final_fname = NULL; 00236 00237 //we detect sync errors 00238 splt_p_search_syncerrors(state, error); 00239 00240 //automatically set progress callback to 100% after 00241 //the error detection 00242 splt_c_update_progress(state,1.0,1.0,1,1,1); 00243 00244 int err = SPLT_OK; 00245 00246 //if no error 00247 if (*error >= 0) 00248 { 00249 //we put the number of sync errors 00250 splt_t_set_splitnumber(state, state->serrors->serrors_points_num - 1); 00251 00252 splt_of_set_oformat_digits(state); 00253 00254 if (splt_o_get_int_option(state,SPLT_OPT_OUTPUT_FILENAMES) == SPLT_OUTPUT_DEFAULT) 00255 { 00256 splt_of_set_oformat(state, SPLT_DEFAULT_SYNCERROR_OUTPUT, &err, SPLT_TRUE); 00257 if (err < 0) { *error = err; goto bloc_end; } 00258 } 00259 00260 //we split all sync errors 00261 int i = 0; 00262 for (i = 0; i < state->serrors->serrors_points_num - 1; i++) 00263 { 00264 //if we don't cancel the split 00265 if (!splt_t_split_is_canceled(state)) 00266 { 00267 //we put the current file to split 00268 splt_t_set_current_split(state, i); 00269 00270 splt_tu_auto_increment_tracknumber(state); 00271 00272 //we append a splitpoint 00273 int err = splt_sp_append_splitpoint(state, 0, "", SPLT_SPLITPOINT); 00274 if (err < 0) { *error = err; goto bloc_end; } 00275 00276 err = splt_u_finish_tags_and_put_output_format_filename(state, -1); 00277 if (err < 0) { *error = err; goto bloc_end; } 00278 00279 final_fname = splt_su_get_fname_with_path_and_extension(state, error); 00280 00281 if (*error >= 0) 00282 { 00283 splt_io_create_output_dirs_if_necessary(state, final_fname, error); 00284 if (error < 0) 00285 { 00286 goto bloc_end; 00287 } 00288 00289 //we split with the detected splitpoints 00290 int split_result = splt_p_simple_split(state, final_fname, 00291 (off_t) state->serrors->serrors_points[i], 00292 (off_t) state->serrors->serrors_points[i+1]); 00293 00294 //automatically set progress callback to 100% 00295 splt_c_update_progress(state,1.0,1.0,1,1,1); 00296 00297 if (split_result >= 0) 00298 { 00299 *error = SPLT_SYNC_OK; 00300 } 00301 else 00302 { 00303 *error = split_result; 00304 } 00305 00306 //if the split has been a success 00307 if (*error == SPLT_SYNC_OK) 00308 { 00309 err = splt_c_put_split_file(state, final_fname); 00310 if (err < 0) { *error = err; goto bloc_end; } 00311 } 00312 } 00313 else 00314 { 00315 //error 00316 goto bloc_end; 00317 } 00318 00319 //free some memory 00320 if (final_fname) 00321 { 00322 free(final_fname); 00323 final_fname = NULL; 00324 } 00325 } 00326 //if we cancel the split 00327 else 00328 { 00329 *error = SPLT_SPLIT_CANCELLED; 00330 goto bloc_end; 00331 } 00332 } 00333 } 00334 else 00335 { 00336 if (*error >= 0 && err < 0) 00337 { 00338 *error = err; 00339 } 00340 } 00341 00342 bloc_end: 00343 //free possible unfreed 'final_fname' 00344 if (final_fname) 00345 { 00346 free(final_fname); 00347 final_fname = NULL; 00348 } 00349 } 00350 00351 /************************************/ 00354 static void splt_s_split_by_time(splt_state *state, int *error, 00355 double split_time_length, int number_of_files) 00356 { 00357 char *final_fname = NULL; 00358 int j=0, tracks=1; 00359 double begin = 0.f; 00360 double end = split_time_length; 00361 long total_time = splt_t_get_total_time(state); 00362 00363 if (split_time_length >= 0) 00364 { 00365 splt_u_print_overlap_time(state); 00366 00367 int err = SPLT_OK; 00368 00369 int temp_int = number_of_files + 1; 00370 if (number_of_files == -1) 00371 { 00372 temp_int = (int)floor(((total_time / 100.0) / (split_time_length))+1) + 1; 00373 } 00374 splt_t_set_splitnumber(state, temp_int); 00375 00376 splt_of_set_oformat_digits(state); 00377 00378 //if we have the default output 00379 int output_filenames = splt_o_get_int_option(state, SPLT_OPT_OUTPUT_FILENAMES); 00380 if (output_filenames == SPLT_OUTPUT_DEFAULT) 00381 { 00382 splt_of_set_oformat(state, SPLT_DEFAULT_OUTPUT, &err, SPLT_TRUE); 00383 if (err < 0) { *error = err; return; } 00384 } 00385 00386 //we append a splitpoint 00387 err = splt_sp_append_splitpoint(state, 0, "", SPLT_SPLITPOINT); 00388 if (err >= 0) 00389 { 00390 int save_end_point = SPLT_TRUE; 00391 if (splt_o_get_long_option(state, SPLT_OPT_OVERLAP_TIME) > 0) 00392 { 00393 save_end_point = SPLT_FALSE; 00394 } 00395 00396 int last_file = SPLT_FALSE; 00397 00398 splt_array *new_end_points = splt_array_new(); 00399 00400 do { 00401 if (!splt_t_split_is_canceled(state)) 00402 { 00403 err = splt_sp_append_splitpoint(state, 0, "", SPLT_SPLITPOINT); 00404 if (err < 0) { *error = err; break; } 00405 00406 splt_t_set_current_split(state, tracks-1); 00407 00408 splt_tu_auto_increment_tracknumber(state); 00409 00410 int current_split = splt_t_get_current_split(state); 00411 00412 splt_sp_set_splitpoint_value(state, current_split, 00413 splt_co_time_to_long_ceil(begin)); 00414 long end_splitpoint = splt_co_time_to_long_ceil(end); 00415 if (total_time > 0 && end_splitpoint >= total_time) 00416 { 00417 end_splitpoint = total_time; 00418 //avoid worst scenarios where floor & SPLT_OK_SPLIT_EOF do not work 00419 last_file = SPLT_TRUE; 00420 } 00421 splt_sp_set_splitpoint_value(state, current_split+1, end_splitpoint); 00422 00423 double overlapped_end = (double) 00424 ((double)splt_sp_overlap_time(state, current_split+1) / 100.0); 00425 00426 err = splt_u_finish_tags_and_put_output_format_filename(state, -1); 00427 if (err < 0) { *error = err; break; } 00428 00429 final_fname = splt_su_get_fname_with_path_and_extension(state,&err); 00430 if (err < 0) { *error = err; break; } 00431 00432 double new_sec_end_point = splt_p_split(state, final_fname, 00433 begin, overlapped_end, error, save_end_point); 00434 long new_end_point = splt_co_time_to_long_ceil(new_sec_end_point); 00435 00436 int end_point_index = current_split + 1; 00437 splt_pair *index_end_point = 00438 splt_pair_new((void *) &end_point_index, (void *) &new_end_point); 00439 splt_array_append(new_end_points, (void *) index_end_point); 00440 00441 //if no error for the split, put the split file 00442 if (*error >= 0) 00443 { 00444 err = splt_c_put_split_file(state, final_fname); 00445 if (err < 0) { *error = err; break; } 00446 } 00447 00448 //set new splitpoints 00449 begin = end; 00450 end += split_time_length; 00451 tracks++; 00452 00453 //get out if error 00454 if ((*error == SPLT_MIGHT_BE_VBR) || 00455 (*error == SPLT_OK_SPLIT_EOF) || 00456 (*error < 0)) 00457 { 00458 tracks = 0; 00459 } 00460 00461 if (*error==SPLT_ERROR_BEGIN_OUT_OF_FILE) 00462 { 00463 j--; 00464 } 00465 00466 if (final_fname) 00467 { 00468 //free memory 00469 free(final_fname); 00470 final_fname = NULL; 00471 } 00472 00473 if (last_file) 00474 { 00475 break; 00476 } 00477 } 00478 else 00479 { 00480 *error = SPLT_SPLIT_CANCELLED; 00481 break; 00482 } 00483 00484 } while (j++<tracks); 00485 00486 if (final_fname) 00487 { 00488 free(final_fname); 00489 final_fname = NULL; 00490 } 00491 00492 int i = 0; 00493 for (i = 0;i < splt_array_length(new_end_points);i++) 00494 { 00495 splt_pair *index_end_point = (splt_pair *) splt_array_get(new_end_points, i); 00496 00497 splt_sp_set_splitpoint_value(state, 00498 *((int*) splt_pair_first(index_end_point)), 00499 *((long*) splt_pair_second(index_end_point))); 00500 00501 splt_pair_free(&index_end_point); 00502 } 00503 00504 splt_array_free(&new_end_points); 00505 } 00506 else 00507 { 00508 *error = err; 00509 } 00510 00511 //we put the time split error 00512 switch (*error) 00513 { 00514 /* case SPLT_MIGHT_BE_VBR: 00515 *error = SPLT_TIME_SPLIT_OK; 00516 break; */ 00517 00518 case SPLT_OK_SPLIT: 00519 *error = SPLT_TIME_SPLIT_OK; 00520 break; 00521 case SPLT_OK_SPLIT_EOF: 00522 *error = SPLT_TIME_SPLIT_OK; 00523 break; 00524 case SPLT_ERROR_BEGIN_OUT_OF_FILE: 00525 *error = SPLT_TIME_SPLIT_OK; 00526 break; 00527 default: 00528 break; 00529 } 00530 } 00531 else 00532 { 00533 *error = SPLT_ERROR_NEGATIVE_TIME_SPLIT; 00534 } 00535 } 00536 00542 void splt_s_time_split(splt_state *state, int *error) 00543 { 00544 splt_c_put_info_message_to_client(state, _(" info: starting time mode split\n")); 00545 00546 double split_time_length = (double) splt_o_get_float_option(state, SPLT_OPT_SPLIT_TIME); 00547 if (((long)split_time_length) == 0) 00548 { 00549 *error = SPLT_ERROR_TIME_SPLIT_VALUE_INVALID; 00550 return; 00551 } 00552 00553 splt_s_split_by_time(state, error, split_time_length, -1); 00554 } 00555 00561 void splt_s_equal_length_split(splt_state *state, int *error) 00562 { 00563 splt_c_put_info_message_to_client(state, _(" info: starting 'split in equal tracks' mode\n")); 00564 00565 double total_time = splt_t_get_total_time_as_double_secs(state); 00566 if (total_time > 0) 00567 { 00568 int number_of_files = 00569 splt_o_get_int_option(state, SPLT_OPT_LENGTH_SPLIT_FILE_NUMBER); 00570 00571 if (number_of_files > 0) 00572 { 00573 double split_time_length = total_time / number_of_files; 00574 splt_s_split_by_time(state, error, split_time_length, number_of_files); 00575 } 00576 else 00577 { 00578 *error = SPLT_ERROR_LENGTH_SPLIT_VALUE_INVALID; 00579 return; 00580 } 00581 } 00582 else 00583 { 00584 *error = SPLT_ERROR_CANNOT_GET_TOTAL_TIME; 00585 return; 00586 } 00587 00588 if (*error == SPLT_TIME_SPLIT_OK) 00589 { 00590 *error = SPLT_LENGTH_SPLIT_OK; 00591 } 00592 } 00593 00594 /************************************/ 00602 int splt_s_set_silence_splitpoints(splt_state *state, int *error) 00603 { 00604 splt_d_print_debug(state,"Search and set silence splitpoints...\n"); 00605 00606 int found = 0; 00607 int splitpoints_appended = 0; 00608 struct splt_ssplit *temp = NULL; 00609 int append_error = SPLT_OK; 00610 00611 float offset = splt_o_get_float_option(state,SPLT_OPT_PARAM_OFFSET); 00612 int number_tracks = splt_o_get_int_option(state, SPLT_OPT_PARAM_NUMBER_TRACKS); 00613 00614 int we_read_silence_from_logs = SPLT_FALSE; 00615 00616 FILE *log_file = NULL; 00617 char *log_fname = splt_t_get_silence_log_fname(state); 00618 if (splt_o_get_int_option(state, SPLT_OPT_ENABLE_SILENCE_LOG)) 00619 { 00620 if ((log_file = splt_io_fopen(log_fname, "r"))) 00621 { 00622 char *log_silence_fname = splt_io_readline(log_file, error); 00623 if (*error < 0) 00624 { 00625 if (log_silence_fname) 00626 { 00627 free(log_silence_fname); 00628 log_silence_fname = NULL; 00629 } 00630 fclose(log_file); 00631 return found; 00632 } 00633 00634 if (log_silence_fname && log_silence_fname[0] != '\0') 00635 { 00636 log_silence_fname[strlen(log_silence_fname)-1] = '\0'; 00637 if (strcmp(log_silence_fname, splt_t_get_filename_to_split(state)) == 0) 00638 { 00639 we_read_silence_from_logs = SPLT_TRUE; 00640 float threshold = SPLT_DEFAULT_PARAM_THRESHOLD; 00641 float min = SPLT_DEFAULT_PARAM_MINIMUM_LENGTH; 00642 int i = fscanf(log_file, "%f\t%f", &threshold, &min); 00643 00644 if ((i < 2) || (threshold != splt_o_get_float_option(state, SPLT_OPT_PARAM_THRESHOLD)) 00645 || (splt_o_get_float_option(state, SPLT_OPT_PARAM_MIN_LENGTH) != min)) 00646 { 00647 we_read_silence_from_logs = SPLT_FALSE; 00648 } 00649 else 00650 { 00651 splt_o_set_float_option(state, SPLT_OPT_PARAM_THRESHOLD, threshold); 00652 splt_o_set_float_option(state, SPLT_OPT_PARAM_MIN_LENGTH, min); 00653 } 00654 } 00655 00656 free(log_silence_fname); 00657 log_silence_fname = NULL; 00658 } 00659 00660 if (!we_read_silence_from_logs && log_file) 00661 { 00662 fclose(log_file); 00663 log_file = NULL; 00664 } 00665 } 00666 } 00667 00668 char remove_str[128] = { '\0' }; 00669 if (splt_o_get_int_option(state, SPLT_OPT_PARAM_REMOVE_SILENCE)) 00670 { 00671 snprintf(remove_str,128,_("YES")); 00672 } 00673 else 00674 { 00675 snprintf(remove_str,128,_("NO")); 00676 } 00677 00678 char auto_user_str[128] = { '\0' }; 00679 if (splt_o_get_int_option(state, SPLT_OPT_PARAM_NUMBER_TRACKS) > 0) 00680 { 00681 snprintf(auto_user_str,128,_("User")); 00682 } 00683 else 00684 { 00685 snprintf(auto_user_str,128,_("Auto")); 00686 } 00687 00688 if (! splt_o_get_int_option(state,SPLT_OPT_QUIET_MODE)) 00689 { 00690 splt_c_put_info_message_to_client(state, 00691 _(" Silence split type: %s mode (Th: %.1f dB," 00692 " Off: %.2f, Min: %.2f, Remove: %s)\n"), 00693 auto_user_str, 00694 splt_o_get_float_option(state, SPLT_OPT_PARAM_THRESHOLD), 00695 splt_o_get_float_option(state, SPLT_OPT_PARAM_OFFSET), 00696 splt_o_get_float_option(state, SPLT_OPT_PARAM_MIN_LENGTH), 00697 remove_str); 00698 } 00699 00700 short read_silence_from_logs = SPLT_FALSE; 00701 if (we_read_silence_from_logs) 00702 { 00703 if (state->split.get_silence_level) 00704 { 00705 state->split.get_silence_level(0, INT_MAX, state->split.silence_level_client_data); 00706 } 00707 00708 splt_c_put_info_message_to_client(state, 00709 _(" Found silence log file '%s' ! Reading" 00710 " silence points from file to save time ;)\n"), log_fname); 00711 00712 found = splt_siu_parse_ssplit_file(state, log_file, error); 00713 if (log_file) 00714 { 00715 fclose(log_file); 00716 log_file = NULL; 00717 } 00718 00719 read_silence_from_logs = SPLT_TRUE; 00720 } 00721 else 00722 { 00723 if (state->split.get_silence_level) 00724 { 00725 //TODO 00726 state->split.get_silence_level(0, INT_MAX, state->split.silence_level_client_data); 00727 } 00728 found = splt_p_scan_silence(state, error); 00729 } 00730 00731 //if no error 00732 if (*error >= 0) 00733 { 00734 if (!read_silence_from_logs) 00735 { 00736 splt_c_put_info_message_to_client(state, "\n"); 00737 } 00738 00739 splt_c_put_info_message_to_client(state, _(" Total silence points found: %d."), found); 00740 00741 if (found > 0) 00742 { 00743 int selected_tracks = found + 1; 00744 int param_number_of_tracks = splt_o_get_int_option(state, SPLT_OPT_PARAM_NUMBER_TRACKS); 00745 if (param_number_of_tracks > 0) 00746 { 00747 selected_tracks = param_number_of_tracks; 00748 } 00749 00750 splt_c_put_info_message_to_client(state, 00751 _(" (Selected %d tracks)\n"), selected_tracks); 00752 } 00753 else 00754 { 00755 splt_c_put_info_message_to_client(state, "\n"); 00756 } 00757 00758 //we set the number of tracks 00759 if (!splt_t_split_is_canceled(state)) 00760 { 00761 found++; 00762 if ((number_tracks > 0) && 00763 (number_tracks < SPLT_MAXSILENCE)) 00764 { 00765 if (number_tracks < found) 00766 { 00767 found = number_tracks; 00768 } 00769 } 00770 00771 //put first splitpoint 00772 append_error = splt_sp_append_splitpoint(state, 0, NULL, SPLT_SPLITPOINT); 00773 if (append_error != SPLT_OK) 00774 { 00775 *error = append_error; 00776 } 00777 else 00778 { 00779 temp = state->silence_list; 00780 int i; 00781 00782 //we take all splitpoints found and we remove silence 00783 //if needed 00784 for (i = 1; i < found; i++) 00785 { 00786 if (temp == NULL) 00787 { 00788 found = i; 00789 break; 00790 } 00791 00792 if (splt_o_get_int_option(state, SPLT_OPT_PARAM_REMOVE_SILENCE)) 00793 { 00794 append_error = splt_sp_append_splitpoint(state, 0, NULL, SPLT_SKIPPOINT); 00795 if (append_error < 0) { *error = append_error; found = i; break;} 00796 append_error = splt_sp_append_splitpoint(state, 0, NULL, SPLT_SPLITPOINT); 00797 if (append_error < 0) { *error = append_error; found = i; break;} 00798 splt_sp_set_splitpoint_value(state, 2*i-1,splt_co_time_to_long(temp->begin_position)); 00799 splt_sp_set_splitpoint_value(state, 2*i, splt_co_time_to_long(temp->end_position)); 00800 } 00801 else 00802 { 00803 //TODO 00804 long temp_silence_pos = splt_siu_silence_position(temp, offset) * 100; 00805 append_error = splt_sp_append_splitpoint(state, temp_silence_pos, NULL, SPLT_SPLITPOINT); 00806 if (append_error != SPLT_OK) { *error = append_error; found = i; break; } 00807 } 00808 temp = temp->next; 00809 } 00810 00811 //we order the splitpoints 00812 if (splt_o_get_int_option(state, SPLT_OPT_PARAM_REMOVE_SILENCE)) 00813 { 00814 splitpoints_appended = (found-1)*2+1; 00815 } 00816 else 00817 { 00818 splitpoints_appended = found; 00819 } 00820 00821 splt_d_print_debug(state,"Order splitpoints...\n"); 00822 int err = splt_sp_order_splitpoints(state, splitpoints_appended); 00823 if (err < 0) { *error = err; } 00824 00825 if (*error >= 0) 00826 { 00827 //last splitpoint, end of file 00828 append_error = 00829 splt_sp_append_splitpoint(state, splt_t_get_total_time(state), 00830 NULL, SPLT_SPLITPOINT); 00831 if (append_error != SPLT_OK) { *error = append_error; } 00832 } 00833 } 00834 } 00835 else 00836 { 00837 *error = SPLT_SPLIT_CANCELLED; 00838 } 00839 00840 //if splitpoints are found 00841 if ((found > 0) && !we_read_silence_from_logs) 00842 { 00843 //if we write the silence points log file 00844 if (splt_o_get_int_option(state, SPLT_OPT_ENABLE_SILENCE_LOG)) 00845 { 00846 splt_c_put_info_message_to_client(state, 00847 _(" Writing silence log file '%s' ...\n"), 00848 splt_t_get_silence_log_fname(state)); 00849 00850 char *fname = splt_t_get_silence_log_fname(state); 00851 if (! splt_o_get_int_option(state, SPLT_OPT_PRETEND_TO_SPLIT)) 00852 { 00853 FILE *log_file = NULL; 00854 if (!(log_file = splt_io_fopen(fname, "w"))) 00855 { 00856 splt_e_set_strerror_msg_with_data(state, fname); 00857 *error = SPLT_ERROR_CANNOT_OPEN_FILE; 00858 } 00859 else 00860 { 00861 //do the effective write 00862 struct splt_ssplit *temp = state->silence_list; 00863 fprintf(log_file, "%s\n", splt_t_get_filename_to_split(state)); 00864 fprintf(log_file, "%.2f\t%.2f\n", 00865 splt_o_get_float_option(state, SPLT_OPT_PARAM_THRESHOLD), 00866 splt_o_get_float_option(state, SPLT_OPT_PARAM_MIN_LENGTH)); 00867 while (temp != NULL) 00868 { 00869 fprintf(log_file, "%f\t%f\t%ld\n", 00870 temp->begin_position, temp->end_position, temp->len); 00871 temp = temp->next; 00872 } 00873 fflush(log_file); 00874 if (log_file) 00875 { 00876 fclose(log_file); 00877 log_file = NULL; 00878 } 00879 temp = NULL; 00880 } 00881 } 00882 } 00883 } 00884 } 00885 00886 splt_siu_ssplit_free(&state->silence_list); 00887 00888 splt_t_set_splitnumber(state, splitpoints_appended + 1); 00889 00890 return found; 00891 } 00892 00897 void splt_s_silence_split(splt_state *state, int *error) 00898 { 00899 splt_d_print_debug(state,"Starting silence split ...\n"); 00900 00901 //print some useful infos to the client 00902 splt_c_put_info_message_to_client(state, _(" info: starting silence mode split\n")); 00903 00904 int found = splt_s_set_silence_splitpoints(state, error); 00905 00906 //if no error 00907 if (*error >= 0) 00908 { 00909 //if we have found splitpoints, write the silence tracks 00910 if (found > 1) 00911 { 00912 splt_d_print_debug(state,"Writing silence tracks...\n"); 00913 00914 //set the default silence output 00915 int output_filenames = splt_o_get_int_option(state,SPLT_OPT_OUTPUT_FILENAMES); 00916 if (output_filenames == SPLT_OUTPUT_DEFAULT) 00917 { 00918 splt_of_set_oformat(state, SPLT_DEFAULT_SILENCE_OUTPUT, error, SPLT_TRUE); 00919 if (*error < 0) { return; } 00920 } 00921 00922 splt_s_multiple_split(state, error); 00923 00924 //we put the silence split errors 00925 switch (*error) 00926 { 00927 /* case SPLT_MIGHT_BE_VBR: 00928 *error = SPLT_SILENCE_OK; 00929 break;*/ 00930 case SPLT_OK_SPLIT: 00931 *error = SPLT_SILENCE_OK; 00932 break; 00933 case SPLT_OK_SPLIT_EOF: 00934 *error = SPLT_SILENCE_OK; 00935 break; 00936 default: 00937 break; 00938 } 00939 } 00940 else 00941 { 00942 *error = SPLT_NO_SILENCE_SPLITPOINTS_FOUND; 00943 } 00944 } 00945 } 00946 00947 /****************************/ 00952 void splt_s_wrap_split(splt_state *state, int *error) 00953 { 00954 char *new_filename_path = splt_t_get_new_filename_path(state); 00955 char *filename = splt_t_get_filename_to_split(state); 00956 00957 splt_d_print_debug(state,"Begin wrap split for the file _%s_\n", filename); 00958 00959 splt_c_put_info_message_to_client(state, _(" info: starting wrap mode split\n")); 00960 00961 splt_p_dewrap(state, SPLT_FALSE, new_filename_path, error); 00962 } 00963