/usr/share/perl5/Audio/Nama/Mix.pm is in nama 1.208-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | 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__
|