libmp3splt
src/splt.c
Go to the documentation of this file.
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