File Coverage

blib/lib/Audio/GtkGramofile/Signals.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             package Audio::GtkGramofile::Signals;
2              
3 1     1   2055 use strict;
  1         12  
  1         30  
4 1     1   5 use warnings;
  1         1  
  1         24  
5 1     1   6 use Carp;
  1         1  
  1         63  
6              
7 1     1   6 use File::Basename;
  1         2  
  1         123  
8 1     1   938 use DirHandle;
  1         2566  
  1         81  
9 1     1   928 use IO::File;
  1         66771  
  1         617  
10 1     1   561 use Gtk2;
  0            
  0            
11             use Glib 1.040, qw(TRUE FALSE);
12              
13             use Audio::GtkGramofile::Settings;
14             use Audio::GtkGramofile::GUI;
15              
16             use vars qw($VERSION);
17             $VERSION = do { my @r = (q$Revision: 1.5 $ =~ /\d+/g); shift @r; sprintf("0.%04d",@r) }; # must be all one line, for MakeMaker
18              
19             sub new {
20             my $proto = shift;
21             my $class = ref($proto) || $proto;
22              
23             my $self = {};
24             bless $self, $class;
25              
26             return $self;
27             }
28              
29             sub set_gtkgramofile {
30             my $self = shift;
31             my $gtkgramofile = shift;
32            
33             $self->{gtkgramofile} = $gtkgramofile;
34             }
35              
36             sub set_times_dialog {
37             my $self = shift;
38              
39             $self->{times_dialog} = $self->times_dialog;
40             $self->{times_dialog};
41             }
42              
43             sub set_frame_dialog {
44             my $self = shift;
45              
46             $self->{frame_dialog} = $self->frame_dialog;
47             $self->{frame_dialog};
48             }
49              
50             sub get_callback {
51             my $self = shift;
52             my $string = shift;
53              
54             return \&{"on_".$string."_clicked"};
55             }
56              
57             sub on_quit_clicked {Gtk2->main_quit;}
58             sub quit_gramofile {shift->on_quit_clicked}
59              
60             sub on_record_clicked {
61             system("gnome-sound-recorder") == 0 or croak "system gnome-sound-recorder failed: $?";
62             }
63              
64             sub on_play_clicked {
65             system("gnome-sound-recorder") == 0 or croak "system gnome-sound-recorder failed: $?";
66             }
67              
68             sub on_generic_browse_clicked {
69             my $self = shift;
70             my $setting = shift;
71             my $button = shift;
72             my $windowname = shift;
73             my $labeltext = shift;
74             my $filename = shift;
75             my $filename_entry = shift;
76              
77             $self->{gtkgramofile}->{gui}->{$button}->set_sensitive(0);
78             my $window = Gtk2::FileSelection->new($windowname);
79             my $label = Gtk2::Label->new($labeltext);
80             $label->show;
81             $window->vbox->add($label);
82             $window->vbox->set_border_width(30);
83            
84             $window->signal_connect (delete_event => sub {1}); # inhibit destruction by pretending to handle delete-event
85             $window->signal_connect (response => sub { # handle the response, and hide the window, never destroy it
86             my ($me, $response) = @_;
87             $self->{gtkgramofile}->set_value($setting,$filename, ($response eq "ok") ? $window->get_filename : "");
88             $self->{gtkgramofile}->{gui}->{$filename_entry}->set_text($self->{gtkgramofile}->get_value($setting,$filename));
89             $self->{gtkgramofile}->{gui}->{$filename_entry}->show;
90             $self->{gtkgramofile}->{gui}->{$button}->set_sensitive(1);
91             $me->hide;
92             1;
93             });
94             $window->show;
95             }
96              
97             sub on_tracksplit_browse_clicked {
98             my $widget = shift;
99             my $self = shift;
100              
101             $self->on_generic_browse_clicked('tracksplit_general', 'tracksplit_browse_button', 'Record Audio',
102             'Locate Tracks : Choose a file or directory', 'tracksplit_filename', 'tracksplit_filename_entry');
103             }
104              
105             sub on_start_tracksplit_clicked {
106             my $widget = shift;
107             my $self = shift;
108             my $parent = $self->{gtkgramofile}->{gui}->{gramofile};
109              
110             $self->{gtkgramofile}->set_value('tracksplit_general','tracksplit_stopped', 0);
111             $self->{gtkgramofile}->{gui}->{stop_tracksplit_button}->set_sensitive(1);
112              
113             my $filelist = [];
114             my $filedir = $self->{gtkgramofile}->get_value('tracksplit_general','tracksplit_filename');
115             if (-f $filedir) {
116             push @$filelist, $filedir;
117             } elsif (-d $filedir) {
118             my $filter = $self->{gtkgramofile}->get_value('tracksplit_params','tracksplit_filename_filter');
119             my $d = DirHandle->new($filedir);
120             if (defined $d) {
121             while (defined($_ = $d->read)) {
122             next if (/^\.\.?$/);
123             next if ($filter and not /$filter/);
124             push @$filelist, join ("/",$filedir,$_);
125             }
126             undef $d;
127             }
128             } else {
129             my $message = $filedir . ' does not exist';
130             my $dialog = Gtk2::Dialog->new ( $message, $parent,
131             'destroy-with-parent',
132             'gtk-ok' => 'none');
133             my $label = Gtk2::Label->new ($message);
134             $dialog->vbox->add ($label);
135              
136             # Ensure that the dialog box is destroyed when the user responds.
137             $dialog->signal_connect (response => sub { $_[0]->destroy });
138             $dialog->show_all;
139             $self->{gtkgramofile}->{gui}->{stop_tracksplit_button}->set_sensitive(0);
140             return;
141             }
142             $self->{gtkgramofile}->{logic}->tracksplit($filelist,
143             $self->{gtkgramofile}->get_value('tracksplit_params','tracksplit_rms_file'),
144             $self->{gtkgramofile}->get_value('tracksplit_params','tracksplit_generate_graph'),
145             $self->{gtkgramofile}->get_value('tracksplit_params','signal_power_data_blocklen'),
146             $self->{gtkgramofile}->get_value('tracksplit_params','global_silence_factor'),
147             $self->{gtkgramofile}->get_value('tracksplit_params','local_silence_factor'),
148             $self->{gtkgramofile}->get_value('tracksplit_params','inter_track_silence_minlen'),
149             $self->{gtkgramofile}->get_value('tracksplit_params','track_minlen'),
150             $self->{gtkgramofile}->get_value('tracksplit_params','track_start_extra_blocks'),
151             $self->{gtkgramofile}->get_value('tracksplit_params','track_end_extra_blocks'));
152             }
153              
154             sub on_stop_generic_clicked {
155             my $self = shift;
156             my $section = shift;
157             my $pid_f = shift;
158             my $stopped = shift;
159             my $cancel = shift;
160            
161             my $pid_file = $self->{gtkgramofile}->get_value($section, $pid_f);
162             my $pid_fh = IO::File->new("<$pid_file") or croak "Can't read $pid_file, $!";
163             my $pid = <$pid_fh>;
164             kill 9, $pid or croak "Can't kill process id, $pid, $!";
165             $pid_fh->close;
166             $self->{gtkgramofile}->set_value($section, $stopped, 1);
167             $self->{gtkgramofile}->get_value($section, $cancel)->set_sensitive(TRUE);
168             }
169              
170             sub on_stop_tracksplit_clicked {
171             my $widget = shift;
172             my $self = shift;
173            
174             $self->on_stop_generic_clicked('tracksplit_general', 'tracksplit_pid_file',
175             'tracksplit_stopped', 'tracksplit_cancel_button');
176             }
177              
178             sub on_process_infile_clicked {
179             my $widget = shift;
180             my $self = shift;
181              
182             $self->on_generic_browse_clicked('process_general', 'process_infile_button', 'Process Audio',
183             'Process Audio : Choose an input file or directory', 'process_infile', 'process_infile_entry');
184             }
185              
186             sub on_process_outfile_clicked {
187             my $widget = shift;
188             my $self = shift;
189              
190             $self->on_generic_browse_clicked('process_general', 'process_outfile_button', 'Process Audio',
191             'Process Audio : Choose an output file or directory', 'process_outfile', 'process_outfile_entry');
192             }
193              
194             sub label_and_spin {
195             my $self = shift;
196             my $dialog = shift;
197             my $label_text = shift;
198             my $parameter = shift;
199             my $first = shift;
200             my $last = shift;
201             my $step = shift;
202             my $backwards = @_ ? shift : undef;
203              
204             my $hbox = Gtk2::HBox->new;
205             my $label = Gtk2::Label->new($label_text);
206             my $spin = Gtk2::SpinButton->new_with_range($first, $last, $step);
207             $spin->set_value($backwards) if (defined $backwards);
208             $hbox->pack_start_defaults($label);
209             $hbox->pack_end_defaults($spin);
210             $dialog->vbox->add($hbox);
211             return $spin;
212             }
213              
214             sub on_generic_1par_filter_clicked {
215             my $self = shift;
216             my $button = shift;
217             my $message = shift;
218             my $label_text = shift;
219             my $parameter = shift;
220             my $first = shift;
221             my $last = shift;
222             my $step = shift;
223              
224             my $parent = $self->{gtkgramofile}->{gui}->{gramofile};
225             $self->{gtkgramofile}->{gui}->{$button}->set_sensitive(0);
226              
227             my $dialog = Gtk2::Dialog->new( $message, $parent,
228             'destroy-with-parent',
229             'gtk-ok' => 'none',
230             'gtk-cancel' => 'cancel');
231             $dialog->vbox->add(Gtk2::Label->new($message));
232             $dialog->vbox->add(Gtk2::HSeparator->new);
233             my $spin = $self->label_and_spin($dialog, $label_text, $parameter, $first, $last, $step);
234              
235             $dialog->signal_connect (response => sub {
236             my $window = shift;
237             $self->{gtkgramofile}->set_value('process_general',$window,0);
238             $self->{gtkgramofile}->set_value('process_params',$parameter,$spin->get_value_as_int);
239             $self->{gtkgramofile}->{gui}->{$button}->set_sensitive(1);
240             $window->destroy;
241             });
242             $dialog->show_all;
243             }
244              
245             sub on_simple_median_filter_clicked {
246             my $widget = shift;
247             my $self = shift;
248              
249             $self->on_generic_1par_filter_clicked('simple_median_filter_button', "Simple Median Filter Properties",
250             "Number of samples to take the median of", 'simple_median_num_samples', 1, 101, 2);
251             }
252              
253             sub on_double_median_filter_clicked {
254             my $widget = shift;
255             my $self = shift;
256              
257             my $parent = $self->{gtkgramofile}->{gui}->{gramofile};
258             $self->{gtkgramofile}->{gui}->{double_median_filter_button}->set_sensitive(0);
259              
260             my $message = "Double Median Filter Properties";
261             my $dialog = Gtk2::Dialog->new ( $message, $parent,
262             'destroy-with-parent',
263             'gtk-ok' => 'none',
264             'gtk-cancel' => 'cancel');
265             $dialog->vbox->add(Gtk2::Label->new($message));
266             $dialog->vbox->add(Gtk2::HSeparator->new);
267             my $spin1 = $self->label_and_spin($dialog, "Number of samples for the first median", 'double_median_first_num_samples', 1, 101, 2);
268             my $spin2 = $self->label_and_spin($dialog, "Number of samples for the second median", 'double_median_second_num_samples', 1, 101, 2);
269             # Ensure that the dialog box is destroyed when the user responds.
270             $dialog->signal_connect (response => sub {
271             my $window = shift;
272             $self->{gtkgramofile}->get_value('process_params','double_median_first_num_samples', $spin1->get_value_as_int);
273             $self->{gtkgramofile}->get_value('process_params','double_median_second_num_samples', $spin2->get_value_as_int);
274             $self->{gtkgramofile}->{gui}->{double_median_filter_button}->set_sensitive(1);
275             $window->destroy;
276             });
277             $dialog->show_all;
278             }
279              
280             sub on_simple_mean_filter_clicked {
281             my $widget = shift;
282             my $self = shift;
283              
284             $self->on_generic_1par_filter_clicked('simple_mean_filter_button', "Simple Mean Filter Properties",
285             "Number of samples to take the mean of", 'simple_mean_num_samples', 1, 101, 2);
286             }
287              
288             sub on_rms_filter_clicked {
289             my $widget = shift;
290             my $self = shift;
291              
292             $self->on_generic_1par_filter_clicked('rms_filter_button', "RMS Filter Properties",
293             "Number of samples to compute RMS of", 'rms_num_samples', 1, 101, 2);
294             }
295              
296             sub on_cond_median_filter_clicked {
297             my $widget = shift;
298             my $self = shift;
299              
300             my $parent = $self->{gtkgramofile}->{gui}->{gramofile};
301             $self->{gtkgramofile}->{gui}->{cond_median_filter_button}->set_sensitive(0);
302              
303             my $message = "Conditional Median Filter Properties";
304             my $dialog = Gtk2::Dialog->new ( $message, $parent,
305             'destroy-with-parent',
306             'gtk-ok' => 'ok',
307             'gtk-refresh' => 9,
308             'gtk-cancel' => 'cancel');
309             $dialog->vbox->add(Gtk2::Label->new($message));
310             $dialog->vbox->add(Gtk2::HSeparator->new);
311             my $spin1 = $self->label_and_spin($dialog, "Number of samples for median to interpolate ticks", 'cmf_median_tick_num_samples', 1, 101, 2);
312             my $spin2 = $self->label_and_spin($dialog, "Length of the RMS operation (samples)", 'cmf_rms_length', 1, 101, 2);
313             my $spin3 = $self->label_and_spin($dialog, "Length of the recursive median operation (samples)", 'cmf_recursive_median_length', 1, 101, 2);
314             my $spin4 = $self->label_and_spin($dialog, "Decimation factor for the recursive median", 'cmf_decimation_factor', 1, 101, 1);
315             my $spin5 = $self->label_and_spin($dialog, "Threshold for tick detection (thousandths)", 'cmf_tick_detection_threshold', 1000, 5000, 1);
316             # Ensure that the dialog box is destroyed when the user responds.
317             $dialog->signal_connect (response => sub {
318             my ($window, $response) = @_;
319             if ($response eq "ok") {
320             $self->{gtkgramofile}->set_value('process_params','cmf_median_tick_num_samples', $spin1->get_value_as_int);
321             $self->{gtkgramofile}->set_value('process_params','cmf_rms_length', $spin2->get_value_as_int);
322             $self->{gtkgramofile}->set_value('process_params','cmf_recursive_median_length', $spin3->get_value_as_int);
323             $self->{gtkgramofile}->set_value('process_params','cmf_decimation_factor', $spin4->get_value_as_int);
324             $self->{gtkgramofile}->set_value('process_params','cmf_tick_detection_threshold', $spin5->get_value_as_int);
325             } elsif ($response ne "cancel") {
326             $self->{gtkgramofile}->set_default('process_params','cmf_median_tick_num_samples');
327             $self->{gtkgramofile}->set_default('process_params','cmf_rms_length');
328             $self->{gtkgramofile}->set_default('process_params','cmf_recursive_median_length');
329             $self->{gtkgramofile}->set_default('process_params','cmf_decimation_factor');
330             $self->{gtkgramofile}->set_default('process_params','cmf_tick_detection_threshold');
331             }
332             $self->{gtkgramofile}->{gui}->{cond_median_filter_button}->set_sensitive(1);
333             $window->destroy;
334             });
335             $dialog->show_all;
336             }
337              
338             sub on_cond_median2_filter_clicked {
339             my $widget = shift;
340             my $self = shift;
341              
342             my $parent = $self->{gtkgramofile}->{gui}->{gramofile};
343             $self->{gtkgramofile}->{gui}->{cond_median2_filter_button}->set_sensitive(0);
344              
345             my $message = "Conditional Median Filter II Properties";
346             my $dialog = Gtk2::Dialog->new ( $message, $parent,
347             'destroy-with-parent',
348             'gtk-ok' => 'ok',
349             'gtk-refresh' => 9,
350             'gtk-cancel' => 'cancel');
351             $dialog->vbox->add(Gtk2::Label->new($message));
352             $dialog->vbox->add(Gtk2::HSeparator->new);
353             my $spin1 = $self->label_and_spin($dialog, "Length of the RMS operation (samples)", 'cmf2_rms_length', 1, 101, 2);
354             my $spin2 = $self->label_and_spin($dialog, "Length of the recursive median operation (samples)", 'cmf2_recursive_median_length', 1, 101, 2);
355             my $spin3 = $self->label_and_spin($dialog, "Decimation factor for the recursive median", 'cmf2_decimation_factor', 1, 101, 1);
356             my $spin4 = $self->label_and_spin($dialog, "Fine threshold for tick start/end (thousandths)", 'cmf2_tick_fine_threshold', 1, 5000, 1);
357             my $spin5 = $self->label_and_spin($dialog, "Threshold for detection of tick presence (thousandths)", 'cmf2_tick_detection_threshold', 1000, 18000, 1);
358             # Ensure that the dialog box is destroyed when the user responds.
359             $dialog->signal_connect (response => sub {
360             my ($window, $response) = @_;
361             if ($response eq "ok") {
362             $self->{gtkgramofile}->set_value('process_params','cmf2_rms_length', $spin1->get_value_as_int);
363             $self->{gtkgramofile}->set_value('process_params','cmf2_recursive_median_length', $spin2->get_value_as_int);
364             $self->{gtkgramofile}->set_value('process_params','cmf2_decimation_factor', $spin3->get_value_as_int);
365             $self->{gtkgramofile}->set_value('process_params','cmf2_tick_fine_threshold', $spin4->get_value_as_int);
366             $self->{gtkgramofile}->set_value('process_params','cmf2_tick_detection_threshold', $spin5->get_value_as_int);
367             } elsif ($response ne "cancel") {
368             $self->{gtkgramofile}->set_default('process_params','cmf2_rms_length');
369             $self->{gtkgramofile}->set_default('process_params','cmf2_recursive_median_length');
370             $self->{gtkgramofile}->set_default('process_params','cmf2_decimation_factor');
371             $self->{gtkgramofile}->set_default('process_params','cmf2_tick_fine_threshold');
372             $self->{gtkgramofile}->set_default('process_params','cmf2_tick_detection_threshold');
373             }
374             $self->{gtkgramofile}->{gui}->{cond_median2_filter_button}->set_sensitive(1);
375             $window->destroy;
376             });
377             $dialog->show_all;
378             }
379              
380             sub on_cond_median3_filter_clicked {
381             my $widget = shift;
382             my $self = shift;
383              
384             my $parent = $self->{gtkgramofile}->{gui}->{gramofile};
385             $self->{gtkgramofile}->{gui}->{cond_median3_filter_button}->set_sensitive(0);
386              
387             my $message = "Conditional Median Filter IIF Properties";
388             my $dialog = Gtk2::Dialog->new ( $message, $parent,
389             'destroy-with-parent',
390             'gtk-ok' => 'ok',
391             'gtk-refresh' => 9,
392             'gtk-cancel' => 'cancel');
393             $dialog->vbox->add(Gtk2::Label->new($message));
394             $dialog->vbox->add(Gtk2::HSeparator->new);
395             my $spin1 = $self->label_and_spin($dialog, "Length of the RMS operation (samples)", 'cmf3_rms_length', 1, 101, 2);
396             my $spin2 = $self->label_and_spin($dialog, "Length of the recursive median operation (samples)", 'cmf3_recursive_median_length', 1, 101, 2);
397             my $spin3 = $self->label_and_spin($dialog, "Decimation factor for the recursive median", 'cmf3_decimation_factor', 1, 101, 1);
398             my $spin4 = $self->label_and_spin($dialog, "Fine threshold for tick start/end (thousandths)", 'cmf3_tick_fine_threshold', 1, 5000, 1);
399             my $spin5 = $self->label_and_spin($dialog, "Threshold for detection of tick presence (thousandths)", 'cmf3_tick_detection_threshold', 1000, 18000, 1);
400             my $spin6 = $self->label_and_spin($dialog, "Length for fft to interpolate (2^n)", 'cmf3_fft_length', 6, 12, 1);
401             # Ensure that the dialog box is destroyed when the user responds.
402             $dialog->signal_connect (response => sub {
403             my ($window, $response) = @_;
404             if ($response eq "ok") {
405             $self->{gtkgramofile}->set_value('process_params','cmf3_rms_length', $spin1->get_value_as_int);
406             $self->{gtkgramofile}->set_value('process_params','cmf3_recursive_median_length', $spin2->get_value_as_int);
407             $self->{gtkgramofile}->set_value('process_params','cmf3_decimation_factor', $spin3->get_value_as_int);
408             $self->{gtkgramofile}->set_value('process_params','cmf3_tick_fine_threshold', $spin4->get_value_as_int);
409             $self->{gtkgramofile}->set_value('process_params','cmf3_tick_detection_threshold', $spin5->get_value_as_int);
410             $self->{gtkgramofile}->set_value('process_params','cmf3_fft_length', $spin6->get_value_as_int);
411             } elsif ($response ne "cancel") {
412             $self->{gtkgramofile}->set_default('process_params','cmf3_rms_length');
413             $self->{gtkgramofile}->set_default('process_params','cmf3_recursive_median_length');
414             $self->{gtkgramofile}->set_default('process_params','cmf3_decimation_factor');
415             $self->{gtkgramofile}->set_default('process_params','cmf3_tick_fine_threshold');
416             $self->{gtkgramofile}->set_default('process_params','cmf3_tick_detection_threshold');
417             $self->{gtkgramofile}->set_default('process_params','cmf3_fft_length');
418             }
419             $self->{gtkgramofile}->{gui}->{cond_median3_filter_button}->set_sensitive(0);
420             $window->destroy;
421             });
422             $dialog->show_all;
423             }
424              
425             sub on_simple_normalize_filter_clicked {
426             my $widget = shift;
427             my $self = shift;
428              
429             $self->on_generic_1par_filter_clicked('simple_normalize_filter_button', "Simple Normalize Filter Properties",
430             "Enter normalize factor - Increase or reduce signal by 0 to +/- 100 %", 'simple_normalize_num_samples', 0, 100, 1);
431             }
432              
433             sub on_start_process_clicked {
434             my $widget = shift;
435             my $self = shift;
436             my $parent = $self->{gtkgramofile}->{gui}->{gramofile};
437              
438             $self->{gtkgramofile}->set_value('process_general','process_stopped', 0);
439             $self->{gtkgramofile}->{gui}->{stop_process_button}->set_sensitive(1);
440              
441             my $filter_list_ref = [];
442             foreach my $key ($self->{gtkgramofile}->get_section_keys('process_filters')) {
443             push @$filter_list_ref, $key if $self->{gtkgramofile}->get_value('process_filters',$key);
444             }
445              
446             my $in_file_list_ref = [];
447             my $out_file_list_ref = [];
448             my $infiledir = $self->{gtkgramofile}->get_value('process_general','process_infile');
449             my $outfiledir = $self->{gtkgramofile}->get_value('process_general','process_outfile');
450             if (-f $infiledir) {
451             push @$in_file_list_ref, $infiledir;
452             if (-f $outfiledir) {
453             push @$out_file_list_ref, $outfiledir;
454             } elsif (-d $outfiledir) {
455             my $filename = basename $infiledir;
456             my $outfile = join "/", $outfiledir, $filename;
457             push @$out_file_list_ref, $outfile;
458             } else {
459             my $message = $outfiledir . ' does not exist';
460             my $dialog = Gtk2::Dialog->new ( $message, $parent,
461             'destroy-with-parent',
462             'gtk-ok' => 'none');
463             my $label = Gtk2::Label->new ($message);
464             $dialog->vbox->add ($label);
465             $dialog->signal_connect (response => sub { $_[0]->destroy });
466             $self->{gtkgramofile}->{gui}->{stop_process_button}->set_sensitive(0);
467             $dialog->show_all;
468             return;
469             }
470             } elsif (-d $infiledir) {
471             my $infile_filter = $self->{gtkgramofile}->get_value('process_params','process_infile_filter');
472             my $outfile_filter = $self->{gtkgramofile}->get_value('process_params','process_outfile_filter');
473             my $d = DirHandle->new($infiledir);
474             if (defined $d) {
475             while (defined($_ = $d->read)) {
476             next if (/^\.\.?$/);
477             next if ($infile_filter and not /$infile_filter/);
478             my $infile = join "/", $infiledir, $_;
479             push @$in_file_list_ref, $infile;
480             my $outfile;
481             if (-d $outfiledir) {
482             $outfile = join "/", $outfiledir, $_;
483             if ($outfile_filter) {
484             if ($self->{gtkgramofile}->get_value('process_params','process_op_regexp')) {
485             my $regexp = $outfile_filter;
486             $_ =~ $regexp;
487             $outfile = join "/", $outfiledir, $_;
488             } else {
489             $outfile = join "/", $outfiledir, $_ . $outfile_filter;
490             }
491             }
492             push @$out_file_list_ref, $outfile;
493             } else {
494             if ($outfile_filter) {
495             if ($self->{gtkgramofile}->get_value('process_params','process_op_regexp')) {
496             my $regexp = $outfile_filter;
497             $_ =~ $regexp;
498             $outfile = join "/", $infiledir, $_;
499             } else {
500             $outfile = join "/", $infiledir, $_ . $outfile_filter;
501             }
502             push @$out_file_list_ref, $outfile;
503             } else {
504             my $message = $outfiledir . ' does not exist';
505             my $dialog = Gtk2::Dialog->new ( $message, $parent,
506             'destroy-with-parent',
507             'gtk-ok' => 'none');
508             my $label = Gtk2::Label->new ($message);
509             $dialog->vbox->add ($label);
510             $dialog->signal_connect (response => sub { $_[0]->destroy });
511             $dialog->show_all;
512             $self->{gtkgramofile}->{gui}->{stop_process_button}->set_sensitive(0);
513             return;
514             }
515             }
516             }
517             undef $d;
518             }
519             } else {
520             my $message = $infiledir . ' does not exist';
521             my $dialog = Gtk2::Dialog->new ( $message, $parent,
522             'destroy-with-parent',
523             'gtk-ok' => 'none');
524             my $label = Gtk2::Label->new ($message);
525             $dialog->vbox->add ($label);
526              
527             # Ensure that the dialog box is destroyed when the user responds.
528             $dialog->signal_connect (response => sub { $_[0]->destroy });
529             $dialog->show_all;
530             $self->{gtkgramofile}->{gui}->{stop_process_button}->set_sensitive(0);
531             return;
532             }
533              
534             my $start_time = sprintf("%02d:%02d:%02d.%03d",
535             $self->{gtkgramofile}->get_value('process_params','start_hours'),
536             $self->{gtkgramofile}->get_value('process_params','start_minutes'),
537             $self->{gtkgramofile}->get_value('process_params','start_seconds'),
538             $self->{gtkgramofile}->get_value('process_params','start_thousandths'));
539              
540             my $end_time = sprintf("%02d:%02d:%02d.%03d",
541             $self->{gtkgramofile}->get_value('process_params','end_hours'),
542             $self->{gtkgramofile}->get_value('process_params','end_minutes'),
543             $self->{gtkgramofile}->get_value('process_params','end_seconds'),
544             $self->{gtkgramofile}->get_value('process_params','end_thousandths'));
545              
546             $self->{gtkgramofile}->{logic}->process_signal($in_file_list_ref, $out_file_list_ref, $filter_list_ref,
547             $self->{gtkgramofile}->get_value('process_params','simple_median_num_samples'),
548             $self->{gtkgramofile}->get_value('process_params','double_median_first_num_samples'),
549             $self->{gtkgramofile}->get_value('process_params','double_median_second_num_samples'),
550             $self->{gtkgramofile}->get_value('process_params','simple_mean_num_samples'),
551             $self->{gtkgramofile}->get_value('process_params','rms_filter_num_samples'),
552             $self->{gtkgramofile}->get_value('process_params','cmf_median_tick_num_samples'),
553             $self->{gtkgramofile}->get_value('process_params','cmf_rms_length'),
554             $self->{gtkgramofile}->get_value('process_params','cmf_recursive_median_length'),
555             $self->{gtkgramofile}->get_value('process_params','cmf_decimation_factor'),
556             $self->{gtkgramofile}->get_value('process_params','cmf_tick_detection_threshold'),
557             $self->{gtkgramofile}->get_value('process_params','cmf2_rms_length'),
558             $self->{gtkgramofile}->get_value('process_params','cmf2_recursive_median_length'),
559             $self->{gtkgramofile}->get_value('process_params','cmf2_decimation_factor'),
560             $self->{gtkgramofile}->get_value('process_params','cmf2_tick_fine_threshold'),
561             $self->{gtkgramofile}->get_value('process_params','cmf2_tick_detection_threshold'),
562             $self->{gtkgramofile}->get_value('process_params','cmf3_rms_length'),
563             $self->{gtkgramofile}->get_value('process_params','cmf3_recursive_median_length'),
564             $self->{gtkgramofile}->get_value('process_params','cmf3_decimation_factor'),
565             $self->{gtkgramofile}->get_value('process_params','cmf3_tick_fine_threshold'),
566             $self->{gtkgramofile}->get_value('process_params','cmf3_tick_detection_threshold'),
567             $self->{gtkgramofile}->get_value('process_params','cmf3_fft_length'),
568             $self->{gtkgramofile}->get_value('process_params','simple_normalize_factor'),
569             $self->{gtkgramofile}->{gui}->{begin_and_end_times_radio}->get_active,
570             $start_time,
571             $end_time,
572             $self->{gtkgramofile}->{gui}->{whole_frames_check}->get_active,
573             $self->{gtkgramofile}->get_value('process_params','frame_size'),
574             );
575             }
576              
577             sub on_stop_process_clicked {
578             my $widget = shift;
579             my $self = shift;
580              
581             $self->on_stop_generic_clicked('process_general', 'process_pid_file',
582             'process_stopped', 'process_cancel_button');
583             }
584              
585             sub on_save_clicked {
586             my $widget = shift;
587             my $self = shift;
588              
589             $self->{gtkgramofile}->{gui}->message("Settings saved");
590             $self->{gtkgramofile}->save_settings;
591             }
592              
593             sub times_dialog {
594             my $self = shift;
595              
596             my $parent = $self->{gtkgramofile}->{gui}->{gramofile};
597             my $message = "Enter Begin and End times to process";
598             my $dialog = Gtk2::Dialog->new ( $message, $parent,
599             'destroy-with-parent',
600             'gtk-ok' => 'ok',
601             'gtk-refresh' => 9,
602             'gtk-cancel' => 'cancel');
603             $dialog->vbox->add(Gtk2::Label->new($message));
604             $dialog->vbox->add(Gtk2::HSeparator->new);
605             my $end_times = $self->get_end_times;
606             my $end_list = [qw(11 59 59 999)];
607             foreach my $num (0 .. @$end_times) {
608             if ($end_times->[$num]) {
609             $end_list->[$num] = $end_times->[$num];
610             last;
611             } else {
612             $end_list->[$num] = 0;
613             }
614             }
615            
616             my $spin1 = $self->label_and_spin($dialog, "Start hours", 'start_hours', 0, $end_list->[0], 1);
617             my $spin2 = $self->label_and_spin($dialog, "Start minutes", 'start_minutes', 0, $end_list->[1], 1);
618             my $spin3 = $self->label_and_spin($dialog, "Start seconds", 'start_seconds', 0, $end_list->[2], 1);
619             my $spin4 = $self->label_and_spin($dialog, "Start thousandths", 'start_thousandths', 0, $end_list->[3], 1);
620             my $spin5 = $self->label_and_spin($dialog, "End hours", 'end_hours', 0, $end_list->[0], 1, $end_times->[0]);
621             my $spin6 = $self->label_and_spin($dialog, "End minutes", 'end_minutes', 0, $end_list->[1], 1, $end_times->[1]);
622             my $spin7 = $self->label_and_spin($dialog, "End seconds", 'end_seconds', 0, $end_list->[2], 1, $end_times->[2]);
623             my $spin8 = $self->label_and_spin($dialog, "End thousandths", 'end_thousandths', 0, $end_list->[3], 1, $end_times->[3]);
624              
625             $dialog->signal_connect (response => sub {
626             my ($window, $response) = @_;
627             if ($response eq "ok") {
628             $self->{gtkgramofile}->set_value('process_params','start_hours', $spin1->get_value_as_int);
629             $self->{gtkgramofile}->set_value('process_params','start_minutes', $spin2->get_value_as_int);
630             $self->{gtkgramofile}->set_value('process_params','start_seconds', $spin3->get_value_as_int);
631             $self->{gtkgramofile}->set_value('process_params','start_thousandths', $spin4->get_value_as_int);
632             $self->{gtkgramofile}->set_value('process_params','end_hours', $spin5->get_value_as_int);
633             $self->{gtkgramofile}->set_value('process_params','end_minutes', $spin6->get_value_as_int);
634             $self->{gtkgramofile}->set_value('process_params','end_seconds', $spin7->get_value_as_int);
635             $self->{gtkgramofile}->set_value('process_params','end_thousandths', $spin8->get_value_as_int);
636             } elsif ($response ne "cancel") {
637             $self->{gtkgramofile}->set_default('process_params','start_hours');
638             $self->{gtkgramofile}->set_default('process_params','start_minutes');
639             $self->{gtkgramofile}->set_default('process_params','start_seconds');
640             $self->{gtkgramofile}->set_default('process_params','start_thousandths');
641             $self->{gtkgramofile}->set_default('process_params','end_hours');
642             $self->{gtkgramofile}->set_default('process_params','end_minutes');
643             $self->{gtkgramofile}->set_default('process_params','end_seconds');
644             $self->{gtkgramofile}->set_default('process_params','end_thousandths');
645             }
646             $window->destroy;
647             });
648              
649             $dialog;
650             }
651              
652             sub on_begin_and_end_times_radio_clicked {
653             my $widget = shift;
654             my $self = shift;
655              
656             if ($self->{gtkgramofile}->{gui}->{begin_and_end_times_radio}->get_active) {
657             my $dialog = (defined $self->{times_dialog}) ? $self->{times_dialog} : $self->set_times_dialog;
658             $dialog->show_all;
659             } else {
660             $self->{times_dialog}->hide;
661             $self->{times_dialog} = undef;
662             $self->{gtkgramofile}->set_default('process_params','start_hours');
663             $self->{gtkgramofile}->set_default('process_params','start_minutes');
664             $self->{gtkgramofile}->set_default('process_params','start_seconds');
665             $self->{gtkgramofile}->set_default('process_params','start_thousandths');
666             $self->{gtkgramofile}->set_default('process_params','end_hours');
667             $self->{gtkgramofile}->set_default('process_params','end_minutes');
668             $self->{gtkgramofile}->set_default('process_params','end_seconds');
669             $self->{gtkgramofile}->set_default('process_params','end_thousandths');
670             }
671             }
672              
673             sub frame_dialog {
674             my $self = shift;
675             my $setting = shift;
676             my $button = shift;
677             my $windowname = shift;
678             my $labeltext = shift;
679             my $filename = shift;
680             my $filename_entry = shift;
681              
682             my $parent = $self->{gtkgramofile}->{gui}->{gramofile};
683             my $message = "Enter Frame Size";
684             my $entry = Gtk2::Entry->new;
685             $entry->set_text($self->{gtkgramofile}->get_default('process_params','frame_size'));
686             my $dialog = Gtk2::Dialog->new ( $message, $parent,
687             'destroy-with-parent',
688             'gtk-ok' => 'ok',
689             'gtk-refresh' => 9,
690             'gtk-cancel' => 'cancel');
691             $dialog->vbox->add(Gtk2::Label->new($message));
692             $dialog->vbox->add(Gtk2::HSeparator->new);
693             $dialog->vbox->add($entry);
694              
695             $dialog->signal_connect (response => sub {
696             my ($window, $response) = @_;
697             if ($response eq "ok") {
698             $self->{gtkgramofile}->set_value('process_params','frame_size', $entry->get_text);
699             } elsif ($response ne "cancel") {
700             $self->{gtkgramofile}->set_default('process_params','frame_size');
701             }
702             $window->destroy;
703             });
704              
705             $dialog;
706             }
707              
708             sub on_whole_frames_check_clicked {
709             my $widget = shift;
710             my $self = shift;
711              
712             if ($self->{gtkgramofile}->{gui}->{whole_frames_check}->get_active) {
713             my $dialog = (defined $self->{frame_dialog}) ? $self->{frame_dialog} : $self->set_frame_dialog;
714             $dialog->show_all;
715             } else {
716             $self->{frame_dialog}->hide;
717             $self->{frame_dialog} = undef;
718             $self->{gtkgramofile}->set_default('process_params','frame_size');
719             }
720             }
721              
722             sub get_end_times {
723             my $self = shift;
724              
725             my $end_list = [qw(11 59 59 999)];
726             my $wav_file = $self->{gtkgramofile}->get_value('process_general','process_infile');
727            
728             return $end_list unless (-e $wav_file and -f _);
729              
730             my $tracks_file = $wav_file . ".tracks";
731             return $end_list unless (-e $tracks_file and -f _);
732              
733             my $end;
734             my $tracks_fh = IO::File->new($tracks_file, "r")
735             or croak "Can't read from $tracks_file, $!";
736             while (<$tracks_fh>) {
737             $end=$_ if (s/^Track\d+end=//);
738             }
739             chomp $end;
740             $end_list = [ $end =~ /^(\d+):(\d+):(\d+)\.(\d+)$/ ];
741             return $end_list;
742             }
743              
744             1;