mp3splt-gtk
|
00001 /********************************************************** 00002 * 00003 * mp3splt-gtk -- utility based on mp3splt, 00004 * for mp3/ogg splitting without decoding 00005 * 00006 * Copyright: (C) 2005-2011 Alexandru Munteanu 00007 * Contact: 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 02111-1307, 00028 * USA. 00029 * 00030 *********************************************************/ 00031 00032 /*!******************************************************** 00033 * \file 00034 * The main file, 00035 * 00036 * this file contains the main() function as well as some 00037 * globally used functions. 00038 *********************************************************/ 00039 00040 #include <signal.h> 00041 #include <locale.h> 00042 #include <string.h> 00043 #include <ctype.h> 00044 #include <unistd.h> 00045 00046 #include <sys/stat.h> 00047 #include <sys/types.h> 00048 00049 #include <glib/gi18n.h> 00050 #include <glib.h> 00051 00052 #include <gtk/gtk.h> 00053 #include <libmp3splt/mp3splt.h> 00054 00055 #ifdef __WIN32__ 00056 #include <windows.h> 00057 #include <shlwapi.h> 00058 #endif 00059 00060 #include "util.h" 00061 #include "special_split.h" 00062 #include "player.h" 00063 #include "utilities.h" 00064 #include "tree_tab.h" 00065 #include "main_win.h" 00066 #include "snackamp_control.h" 00067 #include "split_files.h" 00068 #include "preferences_tab.h" 00069 #include "multiple_files.h" 00070 #include "preferences_manager.h" 00071 #include "player_tab.h" 00072 #include "import.h" 00073 #include "mp3splt-gtk.h" 00074 00075 #include "ui_manager.h" 00076 00077 //the state 00078 splt_state *the_state = NULL; 00079 00080 //the progress bar 00081 GtkWidget *progress_bar; 00082 00083 extern GArray *splitpoints; 00084 extern gint splitnumber; 00085 extern GtkWidget *queue_files_button; 00086 extern gchar *filename_to_split; 00087 extern gchar *filename_path_of_split; 00088 00089 //EXTERNAL OPTIONS 00090 //frame mode option 00091 extern GtkWidget *frame_mode; 00092 //auto-adjust option 00093 extern GtkWidget *adjust_mode; 00094 //gap parameter 00095 extern GtkWidget *spinner_adjust_gap; 00096 //offset parameter 00097 extern GtkWidget *spinner_adjust_offset; 00098 //threshold parameter 00099 extern GtkWidget *spinner_adjust_threshold; 00100 00101 extern GtkWidget *create_dirs_from_output_files; 00102 00103 //silence mode parameters 00104 //number of tracks parameter 00105 extern GtkWidget *spinner_silence_number_tracks; 00106 //number of tracks parameter 00107 extern GtkWidget *spinner_silence_minimum; 00108 //offset parameter 00109 extern GtkWidget *spinner_silence_offset; 00110 //threshold parameter 00111 extern GtkWidget *spinner_silence_threshold; 00112 //remove silence check button (silence mode parameter 00113 extern GtkWidget *silence_remove_silence; 00114 00115 //spinner time 00116 extern GtkWidget *spinner_time; 00117 00118 //player 00119 extern gint selected_player; 00120 00121 //if we are currently splitting 00122 extern gint we_are_splitting; 00123 //if we quit the main program while splitting 00124 extern gint we_quit_main_program; 00125 //the percent progress bar 00126 extern GtkWidget *percent_progress_bar; 00127 00128 //stop button to cancel the split 00129 extern GtkWidget *cancel_button; 00130 00131 //the output entry 00132 extern GtkWidget *output_entry; 00133 00134 extern GtkWidget *remove_all_files_button; 00135 00136 extern gint split_file_mode; 00137 extern GtkWidget *multiple_files_tree; 00138 extern gint multiple_files_tree_number; 00139 00140 //how many split files 00141 gint split_files = 0; 00142 00144 ui_state *ui = NULL; 00145 00147 void put_split_filename(const char *filename,int progress_data) 00148 { 00149 enter_threads(); 00150 00151 if (!gtk_widget_get_sensitive(queue_files_button)) 00152 { 00153 gtk_widget_set_sensitive(queue_files_button, TRUE); 00154 } 00155 if (!gtk_widget_get_sensitive(remove_all_files_button)) 00156 { 00157 gtk_widget_set_sensitive(remove_all_files_button,TRUE); 00158 } 00159 00160 add_split_row(filename); 00161 split_files++; 00162 00163 gint fname_status_size = (strlen(filename) + 255); 00164 gchar *fname_status = g_malloc(sizeof(char) * fname_status_size); 00165 g_snprintf(fname_status, fname_status_size, 00166 _(" File '%s' created"), filename); 00167 put_status_message(fname_status); 00168 if (fname_status) 00169 { 00170 free(fname_status); 00171 fname_status = NULL; 00172 } 00173 00174 #ifdef __WIN32__ 00175 while (gtk_events_pending()) 00176 { 00177 gtk_main_iteration(); 00178 } 00179 gdk_flush(); 00180 #endif 00181 00182 exit_threads(); 00183 } 00184 00186 void change_window_progress_bar(splt_progress *p_bar) 00187 { 00188 gchar progress_text[1024] = " "; 00189 00190 switch (p_bar->progress_type) 00191 { 00192 case SPLT_PROGRESS_PREPARE: 00193 g_snprintf(progress_text,1023, _(" preparing \"%s\" (%d of %d)"), 00194 p_bar->filename_shorted, 00195 p_bar->current_split, 00196 p_bar->max_splits); 00197 break; 00198 case SPLT_PROGRESS_CREATE: 00199 g_snprintf(progress_text,1023, _(" creating \"%s\" (%d of %d)"), 00200 p_bar->filename_shorted, 00201 p_bar->current_split, 00202 p_bar->max_splits); 00203 break; 00204 case SPLT_PROGRESS_SEARCH_SYNC: 00205 g_snprintf(progress_text,1023, _(" searching for sync errors...")); 00206 break; 00207 case SPLT_PROGRESS_SCAN_SILENCE: 00208 g_snprintf(progress_text,1023, 00209 _("S: %02d, Level: %.2f dB; scanning for silence..."), 00210 p_bar->silence_found_tracks, p_bar->silence_db_level); 00211 break; 00212 default: 00213 g_snprintf(progress_text,1023, " "); 00214 break; 00215 } 00216 00217 gchar printed_value[1024] = { '\0' }; 00218 00219 enter_threads(); 00220 00221 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(percent_progress_bar), 00222 p_bar->percent_progress); 00223 g_snprintf(printed_value,1023,"%6.2f %% %s", p_bar->percent_progress * 100, 00224 progress_text); 00225 00226 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(percent_progress_bar), 00227 printed_value); 00228 00229 #ifdef __WIN32__ 00230 while (gtk_events_pending()) 00231 { 00232 gtk_main_iteration(); 00233 } 00234 gdk_flush(); 00235 #endif 00236 00237 exit_threads(); 00238 } 00239 00241 gpointer split_it(gpointer data) 00242 { 00243 gint confirmation = SPLT_OK; 00244 00245 enter_threads(); 00246 00247 remove_all_split_rows(); 00248 00249 exit_threads(); 00250 00251 gint err = SPLT_OK; 00252 00253 mp3splt_erase_all_splitpoints(the_state,&err); 00254 00255 //we erase previous tags if we don't have the option 00256 //splt_current_tags 00257 if ((mp3splt_get_int_option(the_state, SPLT_OPT_TAGS, &err) != 00258 (SPLT_CURRENT_TAGS) || split_file_mode == FILE_MODE_MULTIPLE)) 00259 { 00260 mp3splt_erase_all_tags(the_state,&err); 00261 } 00262 00263 gint split_mode = 00264 mp3splt_get_int_option(the_state, SPLT_OPT_SPLIT_MODE, &err); 00265 00266 enter_threads(); 00267 print_status_bar_confirmation(err); 00268 00269 gchar *format = strdup(gtk_entry_get_text(GTK_ENTRY(output_entry))); 00270 exit_threads(); 00271 00272 mp3splt_set_oformat(the_state, format, &err); 00273 if (format) 00274 { 00275 free(format); 00276 format = NULL; 00277 } 00278 00279 //if we have the normal split mode, enable default output 00280 gint output_filenames = 00281 mp3splt_get_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,&err); 00282 if (mp3splt_get_int_option(the_state, SPLT_OPT_SPLIT_MODE,&err) 00283 == SPLT_OPTION_NORMAL_MODE) 00284 { 00285 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES, 00286 SPLT_OUTPUT_CUSTOM); 00287 } 00288 00289 mp3splt_set_path_of_split(the_state,filename_path_of_split); 00290 00291 gint multiple_files_error = SPLT_FALSE; 00292 if (split_file_mode == FILE_MODE_SINGLE) 00293 { 00294 enter_threads(); 00295 00296 if (split_mode == SPLT_OPTION_NORMAL_MODE) 00297 { 00298 put_splitpoints_in_the_state(the_state); 00299 } 00300 00301 print_processing_file(filename_to_split); 00302 exit_threads(); 00303 00304 mp3splt_set_filename_to_split(the_state, filename_to_split); 00305 confirmation = mp3splt_split(the_state); 00306 } 00307 else 00308 { 00309 if (multiple_files_tree_number > 0) 00310 { 00311 enter_threads(); 00312 00313 gchar *filename = NULL; 00314 GtkTreeIter iter; 00315 GtkTreePath *path; 00316 GtkTreeModel *model = 00317 gtk_tree_view_get_model(GTK_TREE_VIEW(multiple_files_tree)); 00318 00319 exit_threads(); 00320 00321 gint row_number = 0; 00322 while (row_number < multiple_files_tree_number) 00323 { 00324 enter_threads(); 00325 00326 if (split_mode == SPLT_OPTION_NORMAL_MODE) 00327 { 00328 put_splitpoints_in_the_state(the_state); 00329 } 00330 00331 path = gtk_tree_path_new_from_indices(row_number ,-1); 00332 gtk_tree_model_get_iter(model, &iter, path); 00333 gtk_tree_model_get(model, &iter, MULTIPLE_COL_FILENAME, 00334 &filename, -1); 00335 00336 print_processing_file(filename); 00337 00338 exit_threads(); 00339 00340 mp3splt_set_filename_to_split(the_state, filename); 00341 confirmation = mp3splt_split(the_state); 00342 00343 if (filename) 00344 { 00345 g_free(filename); 00346 filename = NULL; 00347 } 00348 00349 if (confirmation < 0) 00350 { 00351 break; 00352 } 00353 00354 row_number++; 00355 00356 enter_threads(); 00357 00358 mp3splt_erase_all_tags(the_state, &err); 00359 print_status_bar_confirmation(err); 00360 err = SPLT_OK; 00361 mp3splt_erase_all_splitpoints(the_state, &err); 00362 print_status_bar_confirmation(err); 00363 00364 exit_threads(); 00365 } 00366 } 00367 else 00368 { 00369 multiple_files_error = SPLT_TRUE; 00370 00371 enter_threads(); 00372 put_status_message(_(" error: no files found in multiple files mode")); 00373 exit_threads(); 00374 } 00375 } 00376 00379 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES, output_filenames); 00380 00381 enter_threads(); 00382 00383 //we show infos about the split action 00384 print_status_bar_confirmation(confirmation); 00385 00386 //see the cancel button 00387 gtk_widget_set_sensitive(GTK_WIDGET(cancel_button), FALSE); 00388 00389 //we look if we have pushed the exit button 00390 if (we_quit_main_program) 00391 { 00392 quit(NULL,NULL); 00393 } 00394 00395 if (confirmation >= 0 && !multiple_files_error) 00396 { 00397 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(percent_progress_bar), 1.0); 00398 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(percent_progress_bar), 00399 _(" finished")); 00400 } 00401 00402 we_are_splitting = FALSE; 00403 00404 exit_threads(); 00405 00406 return NULL; 00407 } 00408 00413 void sigpipe_handler(gint sig) 00414 { 00415 if (player_is_running() && selected_player == PLAYER_SNACKAMP) 00416 { 00417 disconnect_snackamp(); 00418 } 00419 } 00420 00421 gboolean sigint_called = FALSE; 00423 void sigint_handler(gint sig) 00424 { 00425 if (!sigint_called) 00426 { 00427 sigint_called = TRUE; 00428 we_quit_main_program = TRUE; 00429 quit(NULL,NULL); 00430 } 00431 } 00432 00434 void put_message_from_library(const char *message, splt_message_type mess_type) 00435 { 00436 gchar *mess = g_strdup(message); 00437 if (mess) 00438 { 00439 gint i = 0; 00440 //replace '\n' with ' ' 00441 for (i = 0;i < strlen(mess);i++) 00442 { 00443 if (mess[i] == '\n') 00444 { 00445 mess[i] = ' '; 00446 } 00447 } 00448 enter_threads(); 00449 00450 put_status_message_with_type(mess, mess_type); 00451 00452 #ifdef __WIN32__ 00453 while (gtk_events_pending()) 00454 { 00455 gtk_main_iteration(); 00456 } 00457 gdk_flush(); 00458 #endif 00459 00460 exit_threads(); 00461 g_free(mess); 00462 mess = NULL; 00463 } 00464 } 00465 00466 GThread *create_thread(GThreadFunc func, gpointer data, 00467 gboolean joinable, GError **error) 00468 { 00469 /*#ifdef __WIN32__ 00470 func(data); 00471 return NULL; 00472 return g_thread_create(func, data, joinable, error); 00473 #else*/ 00474 return g_thread_create(func, data, joinable, error); 00475 //#endif 00476 } 00477 00478 void enter_threads() 00479 { 00480 gdk_threads_enter(); 00481 } 00482 00483 void exit_threads() 00484 { 00485 gdk_threads_leave(); 00486 } 00487 00511 gint main(gint argc, gchar *argv[], gchar **envp) 00512 { 00513 ui = ui_state_new(); 00514 00515 int OptionChar; 00516 00517 //init threads 00518 g_thread_init(NULL); 00519 gdk_threads_init(); 00520 00521 gint error = 0; 00522 00523 //close nicely 00524 signal (SIGINT, sigint_handler); 00525 00526 #ifndef __WIN32__ 00527 signal (SIGPIPE, sigpipe_handler); 00528 #endif 00529 00530 //create new state 00531 the_state = mp3splt_new_state(&error); 00532 00533 //used for gettext 00534 setlocale (LC_ALL, ""); 00535 textdomain ("mp3splt-gtk"); 00536 00537 #ifdef __WIN32__ 00538 char mp3splt_uninstall_file[2048] = { '\0' }; 00539 DWORD dwType, dwSize = sizeof(mp3splt_uninstall_file) - 1; 00540 SHGetValue(HKEY_LOCAL_MACHINE, 00541 TEXT("SOFTWARE\\mp3splt-gtk"), 00542 TEXT("UninstallString"), 00543 &dwType, 00544 mp3splt_uninstall_file, 00545 &dwSize); 00546 00547 gchar *end = strrchr(mp3splt_uninstall_file, SPLT_DIRCHAR); 00548 if (end) { *end = '\0'; } 00549 00550 gchar *executable_dir = NULL; 00551 gchar *executable = strdup(argv[0]); 00552 00553 end = strrchr(executable, SPLT_DIRCHAR); 00554 if (end) 00555 { 00556 *end = '\0'; 00557 executable_dir = executable; 00558 } 00559 else 00560 { 00561 if (mp3splt_uninstall_file[0] != '\0') 00562 { 00563 executable_dir = mp3splt_uninstall_file; 00564 } 00565 } 00566 00567 bindtextdomain(MP3SPLT_LIB_GETTEXT_DOMAIN, "translations"); 00568 bindtextdomain("mp3splt-gtk", "translations"); 00569 00570 #else 00571 bindtextdomain("mp3splt-gtk", LOCALEDIR); 00572 #endif 00573 00574 bind_textdomain_codeset("mp3splt-gtk", "UTF-8"); 00575 00576 // Allow the gtk to parse all gtk arguments from the command 00577 // line first 00578 gtk_init(&argc, &argv); 00579 00580 // Now pass all remaining arguments to getopt. 00581 opterr = 0; 00582 00583 while ((OptionChar = getopt (argc, argv, "d:")) != -1) 00584 switch (OptionChar) 00585 { 00586 case 'd': 00587 fprintf (stderr, _("Trying to set the output directory to %s.\n"), optarg); 00588 outputdirectory_set((gchar *)optarg); 00589 #ifdef __WIN32__ 00590 mkdir(optarg); 00591 #else 00592 mkdir(optarg, 0777); 00593 #endif 00594 if(!check_if_dir((guchar *)optarg)) 00595 { 00596 fprintf(stderr,_("Error: The specified output directory is inaccessible!\n")); 00597 exit(-1); 00598 } 00599 break; 00600 case '?': 00601 if (optopt == 'd') 00602 fprintf (stderr, _("Option -%c requires an argument.\n"), optopt); 00603 else if (isprint (optopt)) 00604 fprintf (stderr, _("Unknown option `-%c'.\n"), optopt); 00605 else 00606 fprintf (stderr, 00607 _("Unknown option character `\\x%x'.\n"), 00608 optopt); 00609 return 1; 00610 default: 00611 abort (); 00612 } 00613 00614 // If we have a filename at the command line is checked after the 00615 // GUI is up. 00616 00617 //We initialise the splitpoints array 00618 splitpoints = g_array_new(FALSE, FALSE, sizeof (Split_point)); 00619 00620 //check if preferences file exists 00621 //and if it does not create it 00622 check_pref_file(); 00623 00624 mp3splt_set_progress_function(the_state,change_window_progress_bar); 00625 mp3splt_set_split_filename_function(the_state,put_split_filename); 00626 mp3splt_set_message_function(the_state, put_message_from_library); 00627 00628 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, SPLT_FALSE); 00629 mp3splt_set_int_option(the_state, 00630 SPLT_OPT_SET_FILE_FROM_CUE_IF_FILE_TAG_FOUND, SPLT_TRUE); 00631 00632 //add special directory search for plugins on Windows 00633 #ifdef __WIN32__ 00634 if (executable != NULL) 00635 { 00636 if (executable[0] != '\0') 00637 { 00638 g_setenv("GST_PLUGIN_PATH", ".\\", TRUE); 00639 mp3splt_append_plugins_scan_dir(the_state, executable); 00640 _chdir(executable); 00641 } 00642 } 00643 #endif 00644 00645 //main program 00646 create_all(); 00647 error = mp3splt_find_plugins(the_state); 00648 if (error < 0) 00649 { 00650 print_status_bar_confirmation(error); 00651 } 00652 00653 // Now let's see if we found a filename at the command line. 00654 if (optind != argc) 00655 { 00656 if(!check_if_file((guchar *)argv[optind])) 00657 { 00658 fprintf (stderr, 00659 _("Cannot open input file %s\n"), 00660 argv[optind]); 00661 return 1; 00662 } 00663 00664 #ifndef __WIN32__ 00665 // If we start the player it will find a file with a relative 00666 // pathname. But if the player is already running it might 00667 // need an absolute path. 00668 char *inputfilename=realpath(argv[optind],NULL); 00669 handle_import(inputfilename); 00670 free(inputfilename); 00671 #else 00672 handle_import(argv[optind]); 00673 #endif 00674 } 00675 00676 gdk_threads_enter(); 00677 gtk_main(); 00678 exit_threads(); 00679 00680 mp3splt_free_state(the_state, &error); 00681 00682 ui_state_free(ui); 00683 00684 return 0; 00685 } 00686