analyselv2

"S. Massy" <[email protected]>
Newsgroups gmane.comp.audio.ecasound.general
Message-ID <20120518232822.GA22137@solidbox>
Hello,

With LV2 support now present in ecasound, and hence in nama, I have
found out that the utilities describing the plugins aren't very friendly
to the human reader with their long URI and properties strings. So after
some frustrating time, I finally decided to bite the bullet and write
some ugly code to hopefully make the layout of lv2 plugins more
intelligible at a glance. The result is analyselv2, which I attach to
this message. Right now it will:
- Take a plugin URI (obtained using lv2-register in ecasound,
  find_effects from nama, or lv2ls from the shell) and output plugin
  information closely resembling that of analyseplugin.
- If the string is just alphanumeric, it will perform a search on the
  list of plugins installed and either display the info for the plugin
  if a single match occurs or return the URIs of matching plugins.

You need the lv2info and lv2ls utilities installed in your $PATH. to
use, rename it to analyselv2 and make it executable. Please let me know
if you find this useful so I know whether to bother making this more
generally available.


Oh yes, btw, the code is very ugly, so don't look at it unless you've
had a stiff drink before. :)

Cheers,
S.M.
--

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/

_______________________________________________
Ecasound-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ecasound-list
analyselv2.pl (text/x-perl, 6.1 KB)
#!/usr/bin/perl
#

# Toggle debugging.
my $debug = 0;


# Initialise our global variables:
# Store the plugin info:
my $plugin_uri = my $plugin_name = my $plugin_author = 
my $plugin_class = my $plugin_has_latency = 0;
my %pluginporrts;

# Path to utilities
my $lv2info = $lv2ls = 0;

# Various internals:
my $linecount = $maxport = $match = 0; 
my $currentport = -1;





sub crunch_lv2 {
	foreach my $line (@contents) {
		print "Parsing $line" if $debug;
		$linecount++;
		$plugin_uri = $line if ($linecount == 1);
		$plugin_name = tabtospace($line) if ($line =~ /^(\t| )+Name\:/
			&& $currentport == -1);
		$plugin_class = tabtospace($line) 
			if (($line =~ /^(\t| )+Class\:/) && !($line =~ /(\:\/\/)/) );
		$plugin_author = tabtospace($line) 
			if ($line =~ /^(\t| )+Author\:/);
		$plugin_has_latency = tabtospace($line)  
			if ($line =~ /^(\t| )+Has latency\:/);
		# Next we embark on port data collection.
		# ...fffirst acquire current port.
		if ($line =~ /(\t| )+Port (\d+)\:$/) { 
			$currentport = $2;
			print "Acquiring info for $currentport\n" if $debug;
		}
		# type
		if ($line =~ /lv2core#(.+)Port$/) {
			$match = $1;
			if ($match =~ /Input|Output/) {
				$pluginports{$currentport}{'IOTYPE'} = $match;
				print "IOTYPE $pluginports{$currentport}{'IOTYPE'}\n" if $debug;
			} else {
				if (exists($pluginports{$currentport}{'ETYPE'})) {
					$pluginports{$currentport}{'ETYPE'} .= " ";
				}
				$pluginports{$currentport}{'ETYPE'} .= $match;
				print "Acquired ETYPE $1 \n" if $debug;
			}
		}
		# Name
		if ($line =~ /(\t| )+Name\:(\t| )+(.+$)/
			&& ($currentport != -1)) {
			$pluginports{$currentport}{'NAME'} = $3;
			print "Port name is $pluginports{$currentports}{'NAME'}\n" 
			if $debug;	
		}
		# MINVAL/MAXVAL/DEFVAL
		if ($line =~ /(\t| )+Minimum\:(\t| )+(.+$)/) {
			$pluginports{$currentport}{'MINVAL'} = $3;
		print "Acquired minval $pluginports{$currentport}{'MINVAL'}\n" if $debug;
		}
		if ($line =~ /(\t| )+Maximum\:(\t| )+(.+$)/) {
			$pluginports{$currentport}{'MAXVAL'} = $3;
		}
		if ($line =~ /(\t| )+Default\:(\t| )+(.+$)/) {
			$pluginports{$currentport}{'DEFVAL'} = $3;
		}
		# Properties
		if ($line =~ /extportinfo#(.+$)/) {
			if (exists($pluginports{$currentport}{'PROPS'})) {
				$pluginports{$currentport}{'PROPS'} .= ", ";
			}
			$pluginports{$currentport}{'PROPS'} .= $1;
		}
		if ($line =~ /Scale Points\:/) {
			if (exists($pluginports{$currentport}{'PROPS'})) {
				$pluginports{$currentport}{'PROPS'} .= ", ";
			}
			$pluginports{$currentport}{'PROPS'} .= "Selector";
		}
	}



	$maxport = $currentport;
	$currentport = 0;
} # end of sub crunch

sub stripzeros {
	my ($value) = @_;
	$value =~ s/\.0+$|0+$//;
	return $value;
}

sub generateportinfo {
	my $portinfo;
	$portinfo .= "\"$pluginports{$currentport}{'NAME'}\" ";
	$portinfo .= "$pluginports{$currentport}{'IOTYPE'}, ";
	$portinfo .= "$pluginports{$currentport}{'ETYPE'}";
	$portinfo .= ", " . &stripzeros($pluginports{$currentport}{'MINVAL'})
		if exists($pluginports{$currentport}{'MINVAL'});
        $portinfo .= " to " . &stripzeros($pluginports{$currentport}{'MAXVAL'})
	        if exists($pluginports{$currentport}{'MAXVAL'});
        $portinfo .= ", default " . &stripzeros($pluginports{$currentport}{'DEFVAL'})
	        if (exists($pluginports{$currentport}{'DEFVAL'})
			
			&& $pluginports{$currentport}{'DEFVAL'} ne "nan");
	$portinfo .= ", " . filterprops($pluginports{$currentport}{'PROPS'})
		if (exists($pluginports{$currentport}{'PROPS'})
			&& filterprops($pluginports{$currentport}{'PROPS'}) ne "");
	$portinfo .= "\n";
	return $portinfo;
}

sub tabtospace { # Filter out leading tab, convert tab to space
	my ($text) = @_;
	$text =~ s/^\t+|^ +//g;
	$text =~ s/\t+| +/ /g;
	return $text;
}

sub filterprops { # Try to limit output
	my ($props) = @_;
	# Cut HasStrictBounds is long, uuuuuuseless?, and not in ladspa
	$props =~ s/, hasStrictBounds|hasStrictBounds, |hasStrictBounds//;
	# Don't just leave a comma and space
	$props =~ s/^, $|^ +$//;
	print "props: $props\n" if $debug;
	return $props;;
}

sub print_lv2 {
	crunch_lv2();
	print "$plugin_name";
	print "URI: $plugin_uri";
	print "$plugin_class";
	print "$plugin_author";
	print "$plugin_has_latency";
	for ($currentport = 0; $currentport <= $maxport; $currentport++) {
		if ($currentport == 0) {
			print "Ports:  ";
		} else {
			print "\t";
		}
		print generateportinfo();
	}
	print "\n";
}

sub acquire_lv2 {
	my ($uri) = @_;
	@contents = `$lv2info $uri`;
	print "Acquiring contents for $uri\n" if $debug;
	print "$contents[0]\n";
	die "Plugin not found or invalid URi!\n" if ($contents[0] eq "");
}

sub find_utils {
	my $output;
	$output = `which lv2info`;
	chomp($output);
	if ( $output =~ /^\/.+lv2info$/ ) {
		$lv2info = $output;;
	} else { return 0; }
	$output = `which lv2ls`;
	chomp($output);
	if ( $output =~ /^\/.+lv2ls$/ ) {
		$lv2ls = $output;
	} else { return 0; }
	return 1;
}

sub print_help {
	print "USAGE: 
	analyselv2 <URI|STRING> [<OPTION>]
	(The programme takes exactly ONE argument.\n";
}

sub trymatch {
	my ($string) = @_;
	my @lv2lsoutput = `$lv2ls`;
	my @results;
	foreach my $uline (@lv2lsoutput) {
		chomp($uline);
		push(@results, ($uline)) if ($uline =~ /$string/i);
	}
	return @results;
}

# main Stuff goes here:
# First make sure we have the utilities.
find_utils() || die "Couldn't find lv2 utilities! are they in your \$PATH?";

if ($ARGV[0] =~ /\:|\// ) {
	acquire_lv2($ARGV[0]);
	print_lv2();
} elsif ($ARGV[r] =~ /^-.*/ || $ARGV[0] eq "") { print_help(); }
  elsif ($ARGV[0] =~ /.+/) {
	  print "Performing fuzzy search on $ARGV[0]:\n";;
	  @matches = trymatch($ARGV[0]);
	if ( @matches == 1 ) {
		acquire_lv2($matches[0]);
		print_lv2();
	} elsif (@matches > 1) {
		my $matches = @matches;
		print "($matches matches found.)\n";
		for (my $I=0; $I < @matches; $I++) {
			print "$matches[$I]\n";
		}
	} else{
		print "No matches found.\n";
	}
  } else {

	  print "Something didn't quite work...\n";
	  print_help();
  }





# check for utils
#
#
# parse args (eventually with getopt)
# - URI
#   - read plugin in if exists
#   - crunch
#   - print
# - not URI
#   - match
#     - if 1  match, search, crunch, pring
#     - if >1, print possible URI
#     - no match, print error
# ? give option for scale points?
#
#
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.