Audio-Nama

 view release on metacpan or  search on metacpan

lib/Audio/Nama/Util.pm  view on Meta::CPAN

# ----------- Util.pm -----------

# this package is for small subroutines with
# well-defined interfaces

package Audio::Nama::Util;
use v5.36;
our $VERSION = 1.0;
use Carp;
use Data::Dumper::Concise;
use IO::Async::Timer::Periodic;
use IO::Async::Timer::Countdown;
use IO::Async::Loop;
use Audio::Nama::Assign qw(json_out);
use Audio::Nama::Globals qw(:all);
use Audio::Nama::Log qw(logit logsub logpkg);

no warnings 'uninitialized';

require Exporter;

our @ISA = qw(Exporter);

our %EXPORT_TAGS = ( 'all' => [ qw(

	freq
	channels
	input_node
	output_node
	signal_format
	process_is_running
	d1
	d2
	dn
	round
	colonize
	time_tag
	heuristic_time
	dest_type
	dest_string

	create_dir
	join_path
	wav_off
	strip_all
	strip_blank_lines
	strip_comments
	remove_spaces
	expand_tilde
	resolve_path
	dumper
	route_output_channels

	timer
	start_event
	stop_event

) ] );

our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = ();


sub freq { [split ',', $_[0] ]->[2] }  # e.g. s16_le,2,44100

sub channels { [split ',', $_[0] ]->[1] }
	
# these are the names of loop devices corresponding
# to pre- and post-fader nodes of a track signal
sub input_node { $_[0].'_in' }
sub output_node {$_[0].'_out'}

sub signal_format {
	my ($template, $channel_count) = @_;
	$template =~ s/N/$channel_count/;
	my $format = $template;
}
sub process_is_running {
	my $name = shift;
	my @pids = split " ", qx(pgrep $name);
	my @ps_ax  = grep{   my $pid;
						/$name/ and ! /defunct/
						and ($pid) = /(\d+)/
						and grep{ $pid == $_ } @pids 
				} split "\n", qx(ps ax) ;
}
sub d1 {
	my $n = shift;
	sprintf("%.1f", $n)
}
sub d2 {
	my $n = shift;
	sprintf("%.2f", $n)
}
sub dn {
	my ($n, $places) = @_;
	sprintf("%." . $places . "f", $n);
}
sub round {
	my $n = shift;
	return 0 if $n == 0;
	$n = int $n if $n > 10;
	$n = d2($n) if $n < 10;
	$n;
}
sub colonize { # convert seconds to hours:minutes:seconds 
	my $sec = shift || 0;
	my $hours = int ($sec / 3600);
	$sec = $sec % 3600;
	my $min = int ($sec / 60);
	$sec = $sec % 60;
	$sec = "0$sec" if $sec < 10;
	$min = "0$min" if $min < 10 and $hours;

lib/Audio/Nama/Util.pm  view on Meta::CPAN

}
sub expand_tilde { 
	my $path = shift; 

 	my $home = File::HomeDir->my_home;


	# ~bob -> /home/bob
	$path =~ s(
		^ 		# beginning of line
		~ 		# tilde
		(\w+) 	# username
	)
	(File::HomeDir->users_home($1))ex;

	# ~/something -> /home/bob/something
	$path =~ s( 
		^		# beginning of line
		~		# tilde
		/		# slash
	)
	($home/)x;
	$path
}
sub dumper { 
	! defined $_ and "undef"
	or ! (ref $_) and $_ 
	#or (ref $_) =~ /HASH|ARRAY/ and Audio::Nama::json_out($_)
	or ref $_ and Dumper($_)
}
sub route_output_channels {
	# routes signals (1..$width) to ($dest..$dest+$width-1 )
	# returns pairs as arguments to chmove
		
	my ($width, $dest) = @_;
	return '' if ! $dest or $dest == 1;
	# print "route: width: $width, destination: $dest\n\n";
	my $offset = $dest - 1;
	my @route;
	for my $channel ( map{$width - $_ + 1} 1..$width ) {
		push @route,[$channel,($channel + $offset)];
	}
	@route;
}

my @events = qw(
	poll_engine
	update_playback_position_display
	wraparound
	processing_time
	remote_control
	jack_polling
	command_output
);
my %events = map{ $_ => 1} @events;
sub check_event_type ($type) {
	confess "illegal event type: $type"
	unless $events{$type}
}

sub timer ($delay, $interval, $coderef ) {
	my $timer;
	if ($interval == 0){
		$timer = IO::Async::Timer::Countdown->new(
			delay => $delay,
			on_expire => $coderef, 
		);
	}
	else {
		$timer = IO::Async::Timer::Periodic->new(
			interval => $interval,
			on_tick => $coderef,
		);
	}
	$timer->start;
	$text->{loop}->add($timer);
	$timer
}
sub stop_event ($label) {
	check_event_type($label);
	my $event = $Audio::Nama::project->{events}->{$label};
	$event->stop if defined $event 
}
sub start_event ($label, $async) {
	check_event_type($label);
	$Audio::Nama::project->{events}->{$label} = $async
}


1;
__END__



( run in 0.916 second using v1.01-cache-2.11-cpan-39bf76dae61 )