File Coverage

blib/lib/Audio/Nama/Mark.pm
Criterion Covered Total %
statement 40 184 21.7
branch 2 62 3.2
condition 0 6 0.0
subroutine 11 41 26.8
pod 0 15 0.0
total 53 308 17.2


line stmt bran cond sub pod time code
1              
2             # ----------- Mark ------------
3              
4             package Audio::Nama::Mark;
5             our $VERSION = 1.0;
6 2     2   20526 use Carp;
  2         3  
  2         132  
7 2     2   10 use warnings;
  2         4  
  2         55  
8 2     2   9 no warnings qw(uninitialized);
  2         4  
  2         90  
9             our @ISA;
10 2     2   10 use vars qw($n %by_name @all);
  2         4  
  2         120  
11 2     2   569 use Audio::Nama::Log qw(logpkg);
  2         5  
  2         103  
12 2     2   560 use Audio::Nama::Globals qw(:all);
  2         4  
  2         1091  
13 2         15 use Audio::Nama::Object qw(
14             name
15             time
16             active
17 2     2   518 );
  2         3  
18              
19             sub initialize {
20 0     0 0 0 map{ $_->remove} Audio::Nama::Mark::all();
  0         0  
21 0         0 @all = ();
22 0         0 %by_name = (); # return ref to Mark by name
23 0         0 $by_name{Here} = bless {}, 'Audio::Nama::HereMark';
24 0         0 @Audio::Nama::marks_data = (); # for save/restore
25             }
26             sub next_id { # returns incremented 4-digit
27 0   0 0 0 0 $project->{mark_sequence_counter} ||= '0000';
28 0         0 $project->{mark_sequence_counter}++
29             }
30             sub new {
31 1     1 0 11 my $class = shift;
32 1         3 my %vals = @_;
33 1 50       4 croak "undeclared field: @_" if grep{ ! $_is_field{$_} } keys %vals;
  1         6  
34              
35             # to support set_edit_points, we now allow marks to be overwritten
36             #
37             #croak "name already in use: $vals{name}\n"
38             # if $by_name{$vals{name}}; # null name returns false
39            
40 1         5 my $object = bless {
41              
42             ## defaults ##
43              
44             active => 1,
45             name => "",
46              
47             @_ }, $class;
48              
49             #print "object class: $class, object type: ", ref $object, $/;
50 1 50       33 if ($object->name) {
51 1         27 $by_name{ $object->name } = $object;
52             }
53 1         2 push @all, $object;
54 1         3 $Audio::Nama::this_mark = $object;
55            
56 1         3 $object;
57            
58             }
59              
60             sub set_name {
61 0     0 0   my $mark = shift;
62 0           my $name = shift;
63 0           pager("name: $name\n");
64 0 0         if ( defined $by_name{ $name } ){
65 0           carp "you attempted to assign to name already in use\n";
66             }
67             else {
68 0           $mark->set(name => $name);
69 0           $by_name{ $name } = $mark;
70             }
71             }
72              
73             sub jump_here {
74 0     0 0   my $mark = shift;
75 0           Audio::Nama::set_position($mark->time);
76 0           $Audio::Nama::this_mark = $mark;
77             }
78             sub shifted_time { # for marks within current edit
79 0     0 0   my $mark = shift;
80 0 0         return $mark->time unless $mode->{offset_run};
81 0           my $time = $mark->time - Audio::Nama::play_start_time();
82 0 0         $time > 0 ? $time : 0
83             }
84             sub remove {
85 0     0 0   my $mark = shift;
86 0 0         Audio::Nama::throw('Fades depend on this mark. Remove failed.'), return
87             if Audio::Nama::fade_uses_mark($mark->name);
88 0 0         if ( $mark->name ) {
89 0           delete $by_name{$mark->name};
90             }
91 0           @all = grep { $_->time != $mark->time } @all;
  0            
92             }
93             sub next {
94 0     0 0   my $mark = shift;
95 0           Audio::Nama::next_mark();
96             }
97             sub previous {
98 0     0 0   my $mark = shift;
99 0           Audio::Nama::previous_mark();
100             }
101              
102             # -- Class Methods
103              
104 0     0 0   sub all { sort { $a->{time} <=> $b->{time} }@all }
  0            
105              
106             sub loop_start {
107 0           my @points = sort { $a <=> $b }
108 0     0 0   grep{ $_ } map{ mark_time($_)} @{$setup->{loop_endpoints}}[0,1];
  0            
  0            
  0            
109             #print "points @points\n";
110 0           $points[0];
111             }
112             sub loop_end {
113 0           my @points =sort { $a <=> $b }
114 0     0 0   grep{ $_ } map{ mark_time($_)} @{$setup->{loop_endpoints}}[0,1];
  0            
  0            
  0            
115 0           $points[1];
116             }
117             sub time_from_tag {
118 0     0 0   my $tag = shift;
119 0 0         $tag or $tag = '';
120             #print "tag: $tag\n";
121 0           my $mark;
122 0 0         if ($tag =~ /\./) { # we assume raw time if decimal
    0          
123             #print "mark time: ", $tag, $/;
124 0           return $tag;
125             } elsif ($tag =~ /^\d+$/){
126             #print "mark index found\n";
127 0           $mark = $Audio::Nama::Mark::all[$tag];
128             } else {
129             #print "mark name found\n";
130 0           $mark = $Audio::Nama::Mark::by_name{$tag};
131             }
132 0 0         return undef if ! defined $mark;
133             #print "mark time: ", $mark->time, $/;
134 0           return $mark->time;
135             }
136             sub duration_from_tag {
137 0     0 0   my $tag = shift;
138 0 0         $tag or $tag = '';
139             #print "tag: $tag\n";
140 0           my $mark;
141 0 0         if ($tag =~ /[\d.-]+/) { # we assume time
142             #print "mark time: ", $tag, $/;
143 0           return $tag;
144             } else {
145             #print "mark name found\n";
146 0           $mark = $Audio::Nama::Mark::by_name{$tag};
147             }
148 0 0         return undef if ! defined $mark;
149             #print "mark time: ", $mark->time, $/;
150 0           return $mark->time;
151             }
152             sub mark_time {
153 0     0 0   my $tag = shift;
154 0           my $time = time_from_tag($tag);
155 0 0         return unless defined $time;
156 0 0         $time -= Audio::Nama::play_start_time() if $mode->{offset_run};
157 0           $time
158             }
159              
160              
161              
162             # ---------- Mark and jump routines --------
163             {
164             package Audio::Nama;
165 2     2   13 use Modern::Perl;
  2         3  
  2         15  
166 2     2   283 use Audio::Nama::Globals qw(:all);
  2         3  
  2         3508  
167              
168             sub drop_mark {
169 0     0     logsub("&drop_mark");
170 0           my $name = shift;
171 0           my $here = eval_iam("getpos");
172              
173 0 0         if( my $mark = $Audio::Nama::Mark::by_name{$name}){
174 0           pager("$name: a mark with this name exists already at: ",
175             colonize($mark->time));
176             return
177 0           }
178 0 0         if( my ($mark) = grep { $_->time == $here} Audio::Nama::Mark::all()){
  0            
179 0           pager( q(This position is already marked by "),$mark->name,q(") );
180             return
181 0           }
182              
183 0           my $mark = Audio::Nama::Mark->new( time => $here,
184             name => $name);
185              
186 0           $ui->marker($mark); # for GUI
187             }
188             sub mark { # GUI_CODE
189 0     0     logsub("&mark");
190 0           my $mark = shift;
191 0           my $pos = $mark->time;
192 0 0         if ($gui->{_markers_armed}){
193 0           $ui->destroy_marker($pos);
194 0           $mark->remove;
195 0           arm_mark_toggle(); # disarm
196             }
197             else{
198              
199 0           set_position($pos);
200             }
201             }
202              
203             sub next_mark {
204 0     0     logsub("&next_mark");
205 0   0       my $jumps = shift || 0;
206 0 0         $jumps and $jumps--;
207 0           my $here = eval_iam("cs-get-position");
208 0           my @marks = Audio::Nama::Mark::all();
209 0           for my $i ( 0..$#marks ){
210 0 0         if ($marks[$i]->time - $here > 0.001 ){
211 0           logpkg(__FILE__,__LINE__,'debug', "here: $here, future time: ", $marks[$i]->time);
212 0           set_position($marks[$i+$jumps]->time);
213 0           $this_mark = $marks[$i];
214 0           return;
215             }
216             }
217             }
218             sub previous_mark {
219 0     0     logsub("&previous_mark");
220 0   0       my $jumps = shift || 0;
221 0 0         $jumps and $jumps--;
222 0           my $here = eval_iam("getpos");
223 0           my @marks = Audio::Nama::Mark::all();
224 0           for my $i ( reverse 0..$#marks ){
225 0 0         if ($marks[$i]->time < $here ){
226 0           set_position($marks[$i+$jumps]->time);
227 0           $this_mark = $marks[$i];
228 0           return;
229             }
230             }
231             }
232            
233              
234             ## jump recording head position
235              
236             sub to_start {
237 0     0     logsub("&to_start");
238 0 0         return if Audio::Nama::ChainSetup::really_recording();
239 0           set_position( 0 );
240             }
241             sub to_end {
242 0     0     logsub("&to_end");
243             # ten seconds shy of end
244 0 0         return if Audio::Nama::ChainSetup::really_recording();
245 0           my $end = eval_iam('cs-get-length') - 10 ;
246 0           set_position( $end);
247             }
248             sub jump {
249 0 0   0     return if Audio::Nama::ChainSetup::really_recording();
250 0           my $delta = shift;
251 0           logsub("&jump");
252 0           my $here = eval_iam('getpos');
253 0           logpkg(__FILE__,__LINE__,'debug', "delta: $delta, here: $here, unit: $gui->{_seek_unit}");
254 0           my $new_pos = $here + $delta * $gui->{_seek_unit};
255 0 0         if ( $setup->{audio_length} )
256             {
257             $new_pos = $new_pos < $setup->{audio_length}
258             ? $new_pos
259 0 0         : $setup->{audio_length} - 10
260             }
261 0           set_position( $new_pos );
262             }
263 0     0     sub set_position { fade_around(\&_set_position, @_) }
264              
265             sub _set_position {
266 0     0     logsub("&set_position");
267              
268 0 0         return if Audio::Nama::ChainSetup::really_recording(); # don't allow seek while recording
269              
270 0           my $seconds = shift;
271 0     0     my $coderef = sub{ eval_iam("setpos $seconds") };
  0            
272              
273             $jack->{jackd_running}
274             ? Audio::Nama::stop_do_start( $coderef, $jack->{seek_delay} )
275 0 0         : $coderef->();
276              
277 0           update_clock_display();
278             }
279              
280             sub forward {
281 0     0     my $delta = shift;
282 0           my $here = eval_iam('getpos');
283 0           my $new = $here + $delta;
284 0           set_position( $new );
285             }
286              
287             sub rewind {
288 0     0     my $delta = shift;
289 0           forward( -$delta );
290             }
291             sub jump_forward {
292 0     0     my $multiplier = shift;
293             forward( $multiplier * $text->{hotkey_playback_jumpsize})
294 0           }
295 0     0     sub jump_backward { jump_forward( - shift()) }
296              
297            
298             } # end package
299             { package Audio::Nama::HereMark;
300             our @ISA = 'Audio::Nama::Mark';
301             our $last_time;
302 0     0     sub name { 'Here' }
303 0 0   0     sub time { Audio::Nama::eval_iam('cs-connected') ? ($last_time = Audio::Nama::eval_iam('getpos')) : $last_time }
304             }
305              
306             { package Audio::Nama::ClipMark;
307 2     2   12 use Modern::Perl;
  2         3  
  2         12  
308             our @ISA = 'Audio::Nama::Mark';
309              
310              
311             }
312              
313             1;
314             __END__