File Coverage

blib/lib/Audio/Nama/AnalyseLV2.pm
Criterion Covered Total %
statement 6 169 3.5
branch 0 86 0.0
condition 0 27 0.0
subroutine 2 15 13.3
pod 0 12 0.0
total 8 309 2.5


line stmt bran cond sub pod time code
1             # ----------------- Analyse LV2 Plugins ------------------
2              
3             # contributed by S. Massy
4             #
5             package Audio::Nama::AnalyseLV2;
6 1     1   5 use Audio::Nama::Log qw(logpkg);
  1         2  
  1         46  
7             # Initialise our global variables:
8             # Store the plugin info:
9              
10 1     1   6 use strict;
  1         2  
  1         2690  
11              
12             my %plugin;
13             my %scalepoints;
14              
15             # Path to utilities
16             my $lv2info;
17             my $lv2ls;
18              
19             # Various internals:
20             my $currentport;
21              
22             my @contents;
23              
24             sub _analyse_lv2 {
25 0     0     %plugin = ();
26             # Some variables used here.
27 0           my ($uri) = @_;
28 0           my $linecount = my $match;
29              
30 0           $currentport = -1;
31 0 0         unless (acquire_lv2($uri))
32 0           { $plugin{error} = "Plugin not found."; return \%plugin; }
  0            
33              
34 0           foreach my $line (@contents) {
35 0           logpkg(__FILE__,__LINE__,'debug',"Parsing $line");
36 0           $linecount++;
37 0 0         $plugin{general}{uri} = $line if ($linecount == 1);
38 0 0 0       if ($line =~ /^(\t| )+Name\:(\t| )+(.*+)/
39             && $currentport == -1)
40 0           { $plugin{general}{name} = $3; }
41 0 0 0       if (($line =~ /^(\t| )+Class\:(\t| )+(.*+)/) && !($line =~ /(\:\/\/)/) )
42 0           { $plugin{general}{class} = $3; }
43 0 0         if ($line =~ /^(\t| )+Author\:(\t| )+(.*+)/)
44 0           { $plugin{general}{author} = $3; }
45 0 0         if ($line =~ /^(\t| )+Has latency\:(\t| )+(.*+)/)
46 0           { $plugin{general}{has_latency} = $3; }
47             # Next we embark on port data collection.
48             # ...fffirst acquire current port.
49 0 0 0       if ($line =~ /^(\t| )+file\:\/\/.*\.ttl$/
50             && ($currentport == -1) ) {
51 0           chomp($line);
52 0           $line =~ s/(\t| )+file\:\/\///;
53 0           $plugin{'general'}{'datafile'} = $line;
54 0           logpkg(__FILE__,__LINE__,'debug',"datafile: $plugin{'general'}{'datafile'}\n");
55             }
56 0 0         if ($line =~ /(\t| )+Port (\d+)\:$/) {
57 0           $currentport = $2;
58 0           logpkg(__FILE__,__LINE__,'debug',"Acquiring info for $currentport\n");
59             }
60             # type
61 0 0         if ($line =~ /lv2core#(.+)Port$/) {
62 0           $match = $1;
63 0 0         if ($match =~ /Input|Output/) {
64 0           $plugin{$currentport}{iotype} = $match;
65 0           logpkg(__FILE__,__LINE__,'debug',"IOTYPE $plugin{$currentport}{iotype}\n");
66             } else {
67 0 0         if (exists($plugin{$currentport}{etype})) {
68 0           $plugin{$currentport}{etype} .= " ";
69             }
70 0           $plugin{$currentport}{etype} .= $match;
71 0           logpkg(__FILE__,__LINE__,'debug',"Acquired ETYPE $1 \n");
72             }
73             }
74             # A special case for events.
75 0 0         if ($line =~ /http.+\#(.+)Event$/ ) {
76 0           $match = $1;
77 0 0         if ( exists($plugin{$currentport}{etype}) ) {
78 0           $plugin{$currentport}{etype} .= ", ";
79             }
80 0           $plugin{$currentport}{etype} .= $match;
81             }
82              
83             # Name
84 0 0 0       if ($line =~ /(\t| )+Name\:(\t| )+(.+$)/
85             && ($currentport != -1)) {
86 0           $plugin{$currentport}{name} = $3;
87 0           logpkg(__FILE__,__LINE__,'debug',"Port name is $plugin{$currentport}{name}\n");
88             }
89             # MINVAL/MAXVAL/DEFVAL
90 0 0         if ($line =~ /(\t| )+Minimum\:(\t| )+(.+$)/) {
91 0           $plugin{$currentport}{minval} = $3;
92 0           logpkg(__FILE__,__LINE__,'debug',"Acquired minval $plugin{$currentport}{minval}\n");
93             }
94 0 0         if ($line =~ /(\t| )+Maximum\:(\t| )+(.+$)/) {
95 0           $plugin{$currentport}{maxval} = $3;
96             }
97 0 0         if ($line =~ /(\t| )+Default\:(\t| )+(.+$)/) {
98 0           $plugin{$currentport}{defval} = $3;
99             }
100             # Properties
101 0 0         if ($line =~ /extportinfo#(.+$)/) {
102 0 0         if (exists($plugin{$currentport}{props})) {
103 0           $plugin{$currentport}{props} .= ", ";
104             }
105 0           $plugin{$currentport}{props} .= $1;
106             }
107 0 0 0       if ($currentport != -1 && $line =~ /Scale Points\:/) {
108 0           $plugin{$currentport}{scalepoints} = 0;
109             }
110 0 0 0       if ($line =~ /(\t+| +)+(-?\d+\.?\d*) = \"(.*)\"$/
111             && exists($plugin{$currentport}{scalepoints})) {
112 0           $plugin{$currentport}{scalepoints}++;
113 0           $scalepoints{$currentport}{$2} = $3;
114             }
115             }
116              
117              
118              
119              
120 0           $plugin{general}{maxport} = $currentport;
121 0           $currentport = -1;
122              
123              
124             # We iterate over the ports to add the selector property.
125 0           for ($currentport = 0; $currentport <= $plugin{general}{maxport};
126             $currentport++) {
127 0 0         if (exists($plugin{$currentport}{scalepoints})) {
128 0 0         if (exists($plugin{$currentport}{props})) {
129 0           $plugin{$currentport}{props} .= ", ";
130             }
131 0           $plugin{$currentport}{props} .= $plugin{$currentport}{scalepoints} . "-way Selector";
132             }
133             }
134              
135             # Gather info from datafile
136 0           proc_datafile($plugin{'general'}{'datafile'});
137              
138 0           return (\%plugin, \%scalepoints);
139              
140             } # end of sub crunch
141              
142             sub stripzeros {
143 0     0 0   my ($value) = @_;
144 0           $value =~ s/\.0+$|0+$//;
145 0           return $value;
146             }
147              
148             sub generateportinfo {
149 0     0 0   my $portinfo;
150 0           $portinfo .= "\"$plugin{$currentport}{'name'}";
151             # For units
152 0 0         if (exists($plugin{$currentport}{'units'})) {
153 0           $portinfo .= " (" . cunits($plugin{$currentport}{'units'}) . ")";
154             }
155 0           $portinfo .= "\" ";
156 0           $portinfo .= "$plugin{$currentport}{iotype}, ";
157 0           $portinfo .= "$plugin{$currentport}{etype}";
158             $portinfo .= ", " . &stripzeros($plugin{$currentport}{minval})
159 0 0         if exists($plugin{$currentport}{minval});
160             $portinfo .= " to " . &stripzeros($plugin{$currentport}{maxval})
161 0 0         if exists($plugin{$currentport}{maxval});
162             $portinfo .= ", default " . &stripzeros($plugin{$currentport}{defval})
163             if (exists($plugin{$currentport}{defval})
164              
165 0 0 0       && $plugin{$currentport}{defval} ne "nan");
166             $portinfo .= ", " . filterprops($plugin{$currentport}{props})
167             if (exists($plugin{$currentport}{props})
168 0 0 0       && filterprops($plugin{$currentport}{props}) ne "");
169 0           $portinfo .= "\n";
170 0           return $portinfo;
171             }
172              
173             sub filterprops { # Try to limit output
174 0     0 0   my ($props) = @_;
175             # Cut HasStrictBounds is long, uuuuuuseless?, and not in ladspa
176 0           $props =~ s/, hasStrictBounds|hasStrictBounds, |hasStrictBounds//;
177             # Don't just leave a comma and space
178 0           $props =~ s/^, $|^ +$//;
179 0           logpkg(__FILE__,__LINE__,'debug',"props: $props\n");
180 0           return $props;;
181             }
182              
183             sub print_lv2 {
184 0     0 0   my @buffer;
185             push @buffer, "Name: $plugin{general}{name}\n"
186 0 0         if exists($plugin{general}{name});
187 0           push @buffer, "URI: $plugin{general}{uri}";
188             push @buffer, "Class: $plugin{general}{class}\n"
189 0 0         if exists($plugin{general}{class});
190             push @buffer, "Author: $plugin{general}{author}\n"
191 0 0         if exists($plugin{general}{author});
192             push @buffer, "Latency: $plugin{general}{has_latency}\n"
193 0 0         if exists($plugin{general}{has_latency});
194 0           for ($currentport = 0; $currentport <= $plugin{general}{maxport}; $currentport++) {
195 0 0         if ($currentport == 0) {
196 0           push @buffer, "Ports: ";
197             } else {
198 0           push @buffer, "\t";
199             }
200 0           push @buffer, generateportinfo();
201             }
202 0           push @buffer, "\n";
203 0           return @buffer;
204             }
205              
206             sub acquire_lv2 {
207 0     0 0   my ($uri) = @_;
208 0           @contents = `$lv2info $uri`;
209 0           logpkg(__FILE__,__LINE__,'debug',"Acquiring contents for $uri\n");
210             # logpkg(__FILE__,__LINE__,'debug',"$contents[0]\n";
211 0 0         return 0 if ($contents[0] eq "");
212 0           return 1;
213             }
214              
215             sub find_utils {
216 0     0 0   my $output;
217 0           $output = `which lv2info`;
218 0           chomp($output);
219 0 0         if ( $output =~ /^\/.+lv2info$/ ) {
220 0           $lv2info = $output;;
221 0           } else { return 0; }
222 0           $output = `which lv2ls`;
223 0           chomp($output);
224 0 0         if ( $output =~ /^\/.+lv2ls$/ ) {
225 0           $lv2ls = $output;
226 0           } else { return 0; }
227 0           return 1;
228             }
229              
230             sub trymatch {
231 0     0 0   my ($string) = @_;
232 0           my @lv2lsoutput = `$lv2ls`;
233 0           my @results;
234 0           foreach my $uline (@lv2lsoutput) {
235 0           chomp($uline);
236 0 0         push(@results, ($uline)) if ($uline =~ /$string/i);
237             }
238 0           return @results;
239             }
240              
241             sub print_lv2_scalepoints {
242 0     0 0   my @buffer;
243 0 0         if (keys(%scalepoints) > 0) {
244 0           push @buffer, "Printing full information for ports with scale points in plugin...\n$plugin{general}{name}\n";
245 0           foreach my $port (sort {$a <=> $b} (keys(%scalepoints))) {
  0            
246 0           $currentport = $port;
247 0           push @buffer, "Port $currentport: " . generateportinfo();
248 0           foreach my $point ( sort {$a <=> $b} (keys(%{ $scalepoints{$currentport} })) ) {
  0            
  0            
249 0           push @buffer, "\t $point \= $scalepoints{$currentport}{$point}\n";
250             }
251             }
252             }
253 0           else { push @buffer, "Plugin $plugin{general}{name} does not have any port with scale points.\n\n"; }
254 0           return @buffer;
255             }
256              
257             sub analyse_lv2 {
258 0     0 0   my ($uri) = @_;
259 0 0         if ( find_utils() ) {
260 0           return _analyse_lv2($uri);
261             } else {
262 0           $plugin{error} = "Utilities not found.";
263 0           return \%plugin;
264             }
265             }
266              
267             sub lv2_help {
268 0     0 0   my $uri = shift;
269 0           find_utils();
270 0           analyse_lv2($uri);
271 0           print_lv2();
272             }
273              
274             #print lv2_help('http://plugin.org.uk/swh-plugins/zm1');
275             #print lv2_help('urn:50m30n3:plugins:SO-404');
276              
277             sub proc_datafile {
278 0     0 0   my ($file) = @_;
279 0 0         open(my $fh, "<", $file) || return 0;
280 0           $currentport = -1;
281 0           while (my $curline = <$fh>) {
282 0 0         if ($curline =~ /lv2\:index +(\d+) *;$/ ) {
283 0           $currentport = $1;
284             }
285 0 0 0       if ($curline =~ /ue\:unit +ue\:([a-zA-Z0-9_]+) *;$/
286             && ($currentport != -1)) {
287 0           $plugin{$currentport}{'units'} = $1;
288             }
289             }
290 0           close($fh);
291 0           $currentport = -1;
292 0           return 1;
293             }
294              
295             sub cunits {
296 0     0 0   (my $units) = @_;
297 0 0         $units =~ s/pc/\%/ if $units =~ /pc/;
298 0           return $units;
299             }
300              
301              
302             1;