The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
package Audio::Nama;
use Modern::Perl;

sub check_level {

	my $track = shift;

	my $ev = add_effect( { track => $track, type => 'ev' } );

	# disable Master so unused tracks are pruned
	
	$tn{Master}->set(rw => OFF); 

	# direct target track to null
	
	my $null_routing = 
	sub { 	my $g = shift;
			$g->add_path($track->name, output_node('null')) };
	generate_setup($null_routing) 
		or throw("check_level: generate_setup failed!"), return;
	connect_transport();
	
	eval_iam('start'); # don't use heartbeat
	sleep 2; # time for engine to stabilize
	while( eval_iam('engine-status') ne 'finished'){ 
		print q(.); sleep 1; update_clock_display()}; 
	print " Done\n";

	my $cs = eval_iam('cop-status');

	my ($level_output) = $cs =~ /Status info:\s*?\n(.+)\z/s;
	Audio::Nama::mandatory_pager($level_output);

	# restore previous state
	
	remove_effect($ev);
	$tn{Master}->set(rw => MON); 
	Audio::Nama::request_setup();
}

sub automix {

	# get working track set
	
	my @tracks = grep{
					$tn{$_}->rec_status eq PLAY or
					$bn{$_} and $tn{$_}->rec_status eq REC
				 } $bn{Main}->tracks;

	pager("tracks: @tracks");

	## we do not allow automix if inserts are present	

	throw("Cannot perform automix if inserts are present. Skipping."), return
		if grep{$tn{$_}->prefader_insert || $tn{$_}->postfader_insert} @tracks;

	#use Smart::Comments '###';
	# add -ev to summed signal
	my $ev = add_effect( { chain => $tn{Master}->n, type => 'ev' } );
	### ev id: $ev

	# turn off audio output
	
	my $old_send_type = $tn{Master}->{send_type};
	my $old_send_id   = $tn{Master}->{send_id};

	$tn{Master}->set(send_type => 'null', send_id => 'null');

	### Status before mixdown:

	process_command('show');

	
	### reduce track volume levels  to 10%

	## accommodate ea and eadb volume controls

	my $vol_operator = fxn($tn{$tracks[0]}->vol)->type;

	my $reduce_vol_command  = $vol_operator eq 'ea' ? 'vol / 10' : 'vol - 10';
	my $restore_vol_command = $vol_operator eq 'ea' ? 'vol * 10' : 'vol + 10';

	### reduce vol command: $reduce_vol_command

	for (@tracks){ process_command("$_  $reduce_vol_command") }

	process_command('show');

	generate_setup('automix') # pass a bit of magic
		or throw("automix: generate_setup failed!"), return;
	connect_transport();
	
	# start_transport() does a rec_cleanup() on transport stop
	
	eval_iam('start'); # don't use heartbeat
	sleep 2; # time for engine to stabilize
	while( eval_iam('engine-status') ne 'finished'){ 
		print q(.); sleep 1; update_clock_display()}; 
	print " Done\n";

	# parse cop status
	my $cs = eval_iam('cop-status');
	### cs: $cs
	my $cs_re = qr/Chain "1".+?result-max-multiplier ([\.\d]+)/s;
	my ($multiplier) = $cs =~ /$cs_re/;

	### multiplier: $multiplier

	remove_effect($ev);

	# deal with all silence case, where multiplier is 0.00000
	
	if ( $multiplier < 0.00001 ){

		throw("Signal appears to be silence. Skipping.");
		for (@tracks){ process_command("$_  $restore_vol_command") }
		$tn{Master}->set(rw => MON);
		return;
	}

	### apply multiplier to individual tracks

	for (@tracks){ process_command( "$_ vol*$multiplier" ) }

	### mixdown
	process_command('mixdown; arm; start');

	### restore audio output

	$tn{Master}->set( send_type => $old_send_type, send_id => $old_send_id); 

	#no Smart::Comments;
	
}
1
__END__