mp3splt-gtk

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

mp3splt-gtk.c
Go to the documentation of this file.
1 /**********************************************************
2 *
3 * mp3splt-gtk -- utility based on mp3splt,
4 * for mp3/ogg splitting without decoding
5 *
6 * Copyright: (C) 2005-2012 Alexandru Munteanu
7 * Contact: io_fx@yahoo.fr
8 *
9 * http://mp3splt.sourceforge.net/
10 *
11 *********************************************************/
12
13 /**********************************************************
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
28 * USA.
29 *
30 *********************************************************/
31
32 /*!********************************************************
33 * \file
34 * The main file,
35 *
36 * this file contains the main() function as well as some
37 * globally used functions.
38 *********************************************************/
39
40 #include <signal.h>
41 #include <locale.h>
42 #include <string.h>
43 #include <ctype.h>
44 #include <unistd.h>
45
46 #include <sys/stat.h>
47 #include <sys/types.h>
48
49 #include <glib/gi18n.h>
50 #include <glib.h>
51
52 #include <gtk/gtk.h>
53 #include <libmp3splt/mp3splt.h>
54
55 #ifdef __WIN32__
56 #include <windows.h>
57 #include <shlwapi.h>
58 #endif
59
60 #include "util.h"
61 #include "special_split.h"
62 #include "player.h"
63 #include "utilities.h"
64 #include "tree_tab.h"
65 #include "main_win.h"
66 #include "snackamp_control.h"
67 #include "split_files.h"
68 #include "preferences_tab.h"
69 #include "multiple_files.h"
70 #include "preferences_manager.h"
71 #include "player_tab.h"
72 #include "import.h"
73 #include "mp3splt-gtk.h"
74
75 #include "ui_manager.h"
76
77 //the state
78 splt_state *the_state = NULL;
79
80 //the progress bar
81 GtkWidget *progress_bar;
82
83 extern GArray *splitpoints;
84 extern gint splitnumber;
85 extern GtkWidget *queue_files_button;
86 extern gchar *filename_to_split;
87 extern gchar *filename_path_of_split;
88
89 //EXTERNAL OPTIONS
90 //frame mode option
91 extern GtkWidget *frame_mode;
92 //auto-adjust option
93 extern GtkWidget *adjust_mode;
94 //gap parameter
95 extern GtkWidget *spinner_adjust_gap;
96 //offset parameter
97 extern GtkWidget *spinner_adjust_offset;
98 //threshold parameter
99 extern GtkWidget *spinner_adjust_threshold;
100
101 extern GtkWidget *create_dirs_from_output_files;
102
103 //silence mode parameters
104 //number of tracks parameter
105 extern GtkWidget *spinner_silence_number_tracks;
106 //number of tracks parameter
107 extern GtkWidget *spinner_silence_minimum;
108 //offset parameter
109 extern GtkWidget *spinner_silence_offset;
110 //threshold parameter
111 extern GtkWidget *spinner_silence_threshold;
112 //remove silence check button (silence mode parameter
113 extern GtkWidget *silence_remove_silence;
114
115 //spinner time
116 extern GtkWidget *spinner_time;
117
118 //player
119 extern gint selected_player;
120
121 //if we are currently splitting
122 extern gint we_are_splitting;
123 //if we quit the main program while splitting
124 extern gint we_quit_main_program;
125 //the percent progress bar
126 extern GtkWidget *percent_progress_bar;
127
128 //stop button to cancel the split
129 extern GtkWidget *cancel_button;
130
131 //the output entry
132 extern GtkWidget *output_entry;
133
134 extern GtkWidget *remove_all_files_button;
135
136 extern gint split_file_mode;
137 extern GtkWidget *multiple_files_tree;
138 extern gint multiple_files_tree_number;
139
140 //how many split files
141 gint split_files = 0;
142
144 ui_state *ui = NULL;
145
147 void put_split_filename(const char *filename,int progress_data)
148 {
149 enter_threads();
150
151 if (!gtk_widget_get_sensitive(queue_files_button))
152 {
153 gtk_widget_set_sensitive(queue_files_button, TRUE);
154 }
155 if (!gtk_widget_get_sensitive(remove_all_files_button))
156 {
157 gtk_widget_set_sensitive(remove_all_files_button,TRUE);
158 }
159
160 add_split_row(filename);
161 split_files++;
162
163 gint fname_status_size = (strlen(filename) + 255);
164 gchar *fname_status = g_malloc(sizeof(char) * fname_status_size);
165 g_snprintf(fname_status, fname_status_size,
166 _(" File '%s' created"), filename);
167 put_status_message(fname_status);
168 if (fname_status)
169 {
170 free(fname_status);
171 fname_status = NULL;
172 }
173
174 #ifdef __WIN32__
175 while (gtk_events_pending())
176 {
177 gtk_main_iteration();
178 }
179 gdk_flush();
180 #endif
181
182 exit_threads();
183 }
184
186 void change_window_progress_bar(splt_progress *p_bar)
187 {
188 gchar progress_text[1024] = " ";
189
190 switch (p_bar->progress_type)
191 {
192 case SPLT_PROGRESS_PREPARE:
193 g_snprintf(progress_text,1023, _(" preparing \"%s\" (%d of %d)"),
194 p_bar->filename_shorted,
195 p_bar->current_split,
196 p_bar->max_splits);
197 break;
198 case SPLT_PROGRESS_CREATE:
199 g_snprintf(progress_text,1023, _(" creating \"%s\" (%d of %d)"),
200 p_bar->filename_shorted,
201 p_bar->current_split,
202 p_bar->max_splits);
203 break;
204 case SPLT_PROGRESS_SEARCH_SYNC:
205 g_snprintf(progress_text,1023, _(" searching for sync errors..."));
206 break;
207 case SPLT_PROGRESS_SCAN_SILENCE:
208 g_snprintf(progress_text,1023,
209 _("S: %02d, Level: %.2f dB; scanning for silence..."),
210 p_bar->silence_found_tracks, p_bar->silence_db_level);
211 break;
212 default:
213 g_snprintf(progress_text,1023, " ");
214 break;
215 }
216
217 gchar printed_value[1024] = { '\0' };
218
219 enter_threads();
220
221 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(percent_progress_bar),
222 p_bar->percent_progress);
223 g_snprintf(printed_value,1023,"%6.2f %% %s", p_bar->percent_progress * 100,
224 progress_text);
225
226 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(percent_progress_bar),
227 printed_value);
228
229 #ifdef __WIN32__
230 while (gtk_events_pending())
231 {
232 gtk_main_iteration();
233 }
234 gdk_flush();
235 #endif
236
237 exit_threads();
238 }
239
241 gpointer split_it(gpointer data)
242 {
243 gint confirmation = SPLT_OK;
244
245 enter_threads();
246
247 remove_all_split_rows();
248
249 exit_threads();
250
251 gint err = SPLT_OK;
252
253 mp3splt_erase_all_splitpoints(the_state,&err);
254
255 //we erase previous tags if we don't have the option
256 //splt_current_tags
257 if ((mp3splt_get_int_option(the_state, SPLT_OPT_TAGS, &err) !=
258 (SPLT_CURRENT_TAGS) || split_file_mode == FILE_MODE_MULTIPLE))
259 {
260 mp3splt_erase_all_tags(the_state,&err);
261 }
262
263 gint split_mode =
264 mp3splt_get_int_option(the_state, SPLT_OPT_SPLIT_MODE, &err);
265
266 enter_threads();
267 print_status_bar_confirmation(err);
268
269 gchar *format = strdup(gtk_entry_get_text(GTK_ENTRY(output_entry)));
270 exit_threads();
271
272 mp3splt_set_oformat(the_state, format, &err);
273 if (format)
274 {
275 free(format);
276 format = NULL;
277 }
278
279 //if we have the normal split mode, enable default output
280 gint output_filenames =
281 mp3splt_get_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,&err);
282 if (mp3splt_get_int_option(the_state, SPLT_OPT_SPLIT_MODE,&err)
283 == SPLT_OPTION_NORMAL_MODE)
284 {
285 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES,
286 SPLT_OUTPUT_CUSTOM);
287 }
288
289 mp3splt_set_path_of_split(the_state,filename_path_of_split);
290
291 gint multiple_files_error = SPLT_FALSE;
292 if (split_file_mode == FILE_MODE_SINGLE)
293 {
294 enter_threads();
295
296 if (split_mode == SPLT_OPTION_NORMAL_MODE)
297 {
298 put_splitpoints_in_the_state(the_state);
299 }
300
301 print_processing_file(filename_to_split);
302 exit_threads();
303
304 mp3splt_set_filename_to_split(the_state, filename_to_split);
305 confirmation = mp3splt_split(the_state);
306 }
307 else
308 {
309 if (multiple_files_tree_number > 0)
310 {
311 enter_threads();
312
313 gchar *filename = NULL;
314 GtkTreeIter iter;
315 GtkTreePath *path;
316 GtkTreeModel *model =
317 gtk_tree_view_get_model(GTK_TREE_VIEW(multiple_files_tree));
318
319 exit_threads();
320
321 gint row_number = 0;
322 while (row_number < multiple_files_tree_number)
323 {
324 enter_threads();
325
326 if (split_mode == SPLT_OPTION_NORMAL_MODE)
327 {
328 put_splitpoints_in_the_state(the_state);
329 }
330
331 path = gtk_tree_path_new_from_indices(row_number ,-1);
332 gtk_tree_model_get_iter(model, &iter, path);
333 gtk_tree_model_get(model, &iter, MULTIPLE_COL_FILENAME,
334 &filename, -1);
335
336 print_processing_file(filename);
337
338 exit_threads();
339
340 mp3splt_set_filename_to_split(the_state, filename);
341 confirmation = mp3splt_split(the_state);
342
343 if (filename)
344 {
345 g_free(filename);
346 filename = NULL;
347 }
348
349 if (confirmation < 0)
350 {
351 break;
352 }
353
354 row_number++;
355
356 enter_threads();
357
358 mp3splt_erase_all_tags(the_state, &err);
359 print_status_bar_confirmation(err);
360 err = SPLT_OK;
361 mp3splt_erase_all_splitpoints(the_state, &err);
362 print_status_bar_confirmation(err);
363
364 exit_threads();
365 }
366 }
367 else
368 {
369 multiple_files_error = SPLT_TRUE;
370
371 enter_threads();
372 put_status_message(_(" error: no files found in multiple files mode"));
373 exit_threads();
374 }
375 }
376
379 mp3splt_set_int_option(the_state, SPLT_OPT_OUTPUT_FILENAMES, output_filenames);
380
381 enter_threads();
382
383 //we show infos about the split action
384 print_status_bar_confirmation(confirmation);
385
386 //see the cancel button
387 gtk_widget_set_sensitive(GTK_WIDGET(cancel_button), FALSE);
388
389 //we look if we have pushed the exit button
390 if (we_quit_main_program)
391 {
392 quit(NULL,NULL);
393 }
394
395 if (confirmation >= 0 && !multiple_files_error)
396 {
397 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(percent_progress_bar), 1.0);
398 gtk_progress_bar_set_text(GTK_PROGRESS_BAR(percent_progress_bar),
399 _(" finished"));
400 }
401
402 we_are_splitting = FALSE;
403
404 exit_threads();
405
406 return NULL;
407 }
408
413 void sigpipe_handler(gint sig)
414 {
415 if (player_is_running() && selected_player == PLAYER_SNACKAMP)
416 {
417 disconnect_snackamp();
418 }
419 }
420
421 gboolean sigint_called = FALSE;
423 void sigint_handler(gint sig)
424 {
425 if (!sigint_called)
426 {
427 sigint_called = TRUE;
428 we_quit_main_program = TRUE;
429 quit(NULL,NULL);
430 }
431 }
432
434 void put_message_from_library(const char *message, splt_message_type mess_type)
435 {
436 gchar *mess = g_strdup(message);
437 if (mess)
438 {
439 gint i = 0;
440 //replace '\n' with ' '
441 for (i = 0;i < strlen(mess);i++)
442 {
443 if (mess[i] == '\n')
444 {
445 mess[i] = ' ';
446 }
447 }
448 enter_threads();
449
450 put_status_message_with_type(mess, mess_type);
451
452 #ifdef __WIN32__
453 while (gtk_events_pending())
454 {
455 gtk_main_iteration();
456 }
457 gdk_flush();
458 #endif
459
460 exit_threads();
461 g_free(mess);
462 mess = NULL;
463 }
464 }
465
466 GThread *create_thread(GThreadFunc func, gpointer data,
467 gboolean joinable, GError **error)
468 {
469 /*#ifdef __WIN32__
470 func(data);
471 return NULL;
472 return g_thread_create(func, data, joinable, error);
473 #else*/
474 return g_thread_create(func, data, joinable, error);
475 //#endif
476 }
477
478 void enter_threads()
479 {
480 gdk_threads_enter();
481 }
482
483 void exit_threads()
484 {
485 gdk_threads_leave();
486 }
487
511 gint main(gint argc, gchar *argv[], gchar **envp)
512 {
513 ui = ui_state_new();
514
515 int OptionChar;
516
517 //init threads
518 g_thread_init(NULL);
519 gdk_threads_init();
520
521 gint error = 0;
522
523 //close nicely
524 signal (SIGINT, sigint_handler);
525
526 #ifndef __WIN32__
527 signal (SIGPIPE, sigpipe_handler);
528 #endif
529
530 //create new state
531 the_state = mp3splt_new_state(&error);
532
533 //used for gettext
534 setlocale (LC_ALL, "");
535 textdomain ("mp3splt-gtk");
536
537 #ifdef __WIN32__
538 char mp3splt_uninstall_file[2048] = { '\0' };
539 DWORD dwType, dwSize = sizeof(mp3splt_uninstall_file) - 1;
540 SHGetValue(HKEY_LOCAL_MACHINE,
541 TEXT("SOFTWARE\\mp3splt-gtk"),
542 TEXT("UninstallString"),
543 &dwType,
544 mp3splt_uninstall_file,
545 &dwSize);
546
547 gchar *end = strrchr(mp3splt_uninstall_file, SPLT_DIRCHAR);
548 if (end) { *end = '\0'; }
549
550 gchar *executable_dir = NULL;
551 gchar *executable = strdup(argv[0]);
552
553 end = strrchr(executable, SPLT_DIRCHAR);
554 if (end)
555 {
556 *end = '\0';
557 executable_dir = executable;
558 }
559 else
560 {
561 if (mp3splt_uninstall_file[0] != '\0')
562 {
563 executable_dir = mp3splt_uninstall_file;
564 }
565 }
566
567 bindtextdomain(MP3SPLT_LIB_GETTEXT_DOMAIN, "translations");
568 bindtextdomain("mp3splt-gtk", "translations");
569
570 #else
571 bindtextdomain("mp3splt-gtk", LOCALEDIR);
572 #endif
573
574 bind_textdomain_codeset("mp3splt-gtk", "UTF-8");
575
576 // Allow the gtk to parse all gtk arguments from the command
577 // line first
578 gtk_init(&argc, &argv);
579
580 // Now pass all remaining arguments to getopt.
581 opterr = 0;
582
583 while ((OptionChar = getopt (argc, argv, "d:")) != -1)
584 switch (OptionChar)
585 {
586 case 'd':
587 fprintf (stderr, _("Trying to set the output directory to %s.\n"), optarg);
588 outputdirectory_set((gchar *)optarg);
589 #ifdef __WIN32__
590 mkdir(optarg);
591 #else
592 mkdir(optarg, 0777);
593 #endif
594 if(!check_if_dir((guchar *)optarg))
595 {
596 fprintf(stderr,_("Error: The specified output directory is inaccessible!\n"));
597 exit(-1);
598 }
599 break;
600 case '?':
601 if (optopt == 'd')
602 fprintf (stderr, _("Option -%c requires an argument.\n"), optopt);
603 else if (isprint (optopt))
604 fprintf (stderr, _("Unknown option `-%c'.\n"), optopt);
605 else
606 fprintf (stderr,
607 _("Unknown option character `\\x%x'.\n"),
608 optopt);
609 return 1;
610 default:
611 abort ();
612 }
613
614 // If we have a filename at the command line is checked after the
615 // GUI is up.
616
617 //We initialise the splitpoints array
618 splitpoints = g_array_new(FALSE, FALSE, sizeof (Split_point));
619
620 //check if preferences file exists
621 //and if it does not create it
622 check_pref_file();
623
624 mp3splt_set_progress_function(the_state,change_window_progress_bar);
625 mp3splt_set_split_filename_function(the_state,put_split_filename);
626 mp3splt_set_message_function(the_state, put_message_from_library);
627
628 mp3splt_set_int_option(the_state, SPLT_OPT_DEBUG_MODE, SPLT_FALSE);
629 mp3splt_set_int_option(the_state,
630 SPLT_OPT_SET_FILE_FROM_CUE_IF_FILE_TAG_FOUND, SPLT_TRUE);
631
632 //add special directory search for plugins on Windows
633 #ifdef __WIN32__
634 if (executable != NULL)
635 {
636 if (executable[0] != '\0')
637 {
638 g_setenv("GST_PLUGIN_PATH", ".\\", TRUE);
639 mp3splt_append_plugins_scan_dir(the_state, executable);
640 _chdir(executable);
641 }
642 }
643 #endif
644
645 //main program
646 create_all();
647 error = mp3splt_find_plugins(the_state);
648 if (error < 0)
649 {
650 print_status_bar_confirmation(error);
651 }
652
653 // Now let's see if we found a filename at the command line.
654 if (optind != argc)
655 {
656 if(!check_if_file((guchar *)argv[optind]))
657 {
658 fprintf (stderr,
659 _("Cannot open input file %s\n"),
660 argv[optind]);
661 return 1;
662 }
663
664 #ifndef __WIN32__
665 // If we start the player it will find a file with a relative
666 // pathname. But if the player is already running it might
667 // need an absolute path.
668 char *inputfilename=realpath(argv[optind],NULL);
669 handle_import(inputfilename);
670 free(inputfilename);
671 #else
672 handle_import(argv[optind]);
673 #endif
674 }
675
676 gdk_threads_enter();
677 gtk_main();
678 exit_threads();
679
680 mp3splt_free_state(the_state, &error);
681
682 ui_state_free(ui);
683
684 return 0;
685 }
686