Audio-Nama
view release on metacpan or search on metacpan
lib/Audio/Nama/CacheTrack.pm view on Meta::CPAN
# -------- CacheTrack ------
package Audio::Nama;
use v5.36;
use Storable 'dclone';
use Try::Tiny;
use Audio::Nama::Globals qw(:all);
use Audio::Nama::Util qw(timer start_event stop_event);
# The $args hashref passed among the subroutines in this file
# has these fields:
# track
# additional_time
# processing_time
# original_version
# output_wav
# orig_volume
# orig_pan
# bus - we are caching a bus
sub cache_track { # launch subparts if conditions are met
logsub((caller(0))[3]);
my $args = {}; # to pass params to routines involved in caching
(my $track, $args->{additional_time}) = @_;
my $bus = $track->is_mixing;
my $obj; # track or bus
my $name = $track->name;
if( $track->off ){
my $bus = $track->is_mixer && ! $track->playback_version;
my $status = $bus ? MON : PLAY;
throw(qq(Cannot cache track "$name" with status OFF. Set to $status and try again));
return;
}
local $this_track;
$args->{track} = $track;
$args->{bus} = $bus;
$args->{additional_time} //= 0;
$args->{original_version} = $bus ? 0 : $track->playback_version;
$args->{cached_version} = $track->last + 1;
$args->{track_rw} = $track->rw;
$args->{main_rw} = $tn{Main}->rw;
$tn{Main}->set( rw => OFF);
$track->set( rw => REC);
my @to_cache = cachable($track) or throw("Nothing to cache, skipping."), return;
$obj = $bus ? 'bus' : 'track';
pager("$name: Preparing to cache $obj with ",join ', ',@to_cache);
if($bus)
{ generate_cache_bus_graph($args) }
else
{ generate_cache_track_graph($args) }
my $result = process_cache_graph($g);
if ( $result )
{
pager("generated graph");
deactivate_vol_pan($args);
cache_engine_run($args);
reactivate_vol_pan($args);
return $args->{output_wav}
}
else
lib/Audio/Nama/CacheTrack.pm view on Meta::CPAN
my $to_path = join_path($args->{track}->dir, $to_name);
$g->set_vertex_attributes(
$cooked->name,
{ format => signal_format($config->{cache_to_disk_format},$cooked->width),
full_version => $to_path,
}
);
# set the input path
$g->add_path('wav_in',$args->{track}->name);
logpkg(__FILE__,__LINE__,'debug', "The graph after setting input path:\n$g");
my $from_name = $args->{track}->name . '_' . $args->{original_version} . '.wav';
my $from_path = join_path($args->{track}->dir, $from_name);
$g->set_vertex_attributes(
$args->{track}->name,
{ full_path => $from_path }
);
}
sub process_cache_graph {
logsub((caller(0))[3]);
my $g = shift;
logpkg(__FILE__,__LINE__,'debug', "The graph after bus routing:\n$g");
Audio::Nama::ChainSetup::prune_graph();
logpkg(__FILE__,__LINE__,'debug', "The graph after pruning:\n$g");
Audio::Nama::Graph::expand_graph($g);
logpkg(__FILE__,__LINE__,'debug', "The graph after adding loop devices:\n$g");
Audio::Nama::Graph::add_inserts($g);
logpkg(__FILE__,__LINE__,'debug', "The graph with inserts:\n$g");
my $success = Audio::Nama::ChainSetup::process_routing_graph();
if ($success)
{
Audio::Nama::ChainSetup::write_chains();
Audio::Nama::ChainSetup::remove_temporary_tracks();
}
$success
}
sub cache_engine_run {
logsub((caller(0))[3]);
my $args = shift;
connect_transport()
or throw("Couldn't connect engine! Aborting."), return;
$args->{processing_time} = $setup->{audio_length} + $args->{additional_time};
pager($args->{track}->name.": processing time: ". d2($args->{processing_time}). " seconds");
pager("Starting cache operation. Please wait.");
revise_prompt(" ");
# we try to set processing time this way
ecasound_iam("cs-set-length $args->{processing_time}");
ecasound_iam("start");
# ensure that engine stops at completion time
$setup->{cache_track_args} = $args;
start_event(poll_engine => timer(1, 0.5, \&poll_progress));
}
sub complete_caching {
logsub((caller(0))[3]);
my $args = shift;
my $name = $args->{track}->name;
my @files = grep{/$name/} new_files_were_recorded();
if (@files ){
update_cache_map($args);
caching_cleanup($args);
} else { throw("track cache operation failed!") }
undef $setup->{cache_track_args};
}
sub update_cache_map {
logsub((caller(0))[3]);
my $args = shift;
logpkg(__FILE__,__LINE__,'debug', "updating track cache_map");
logpkg(__FILE__,__LINE__,'debug', "current track cache entries:",
sub {
join "\n","cache map",
map{($_->dump)} Audio::Nama::EffectChain::find(track_cache => 1)
});
my $track = $args->{track};
my @inserts = $track->get_inserts;
my @all_ops = @{$track->ops};
my @ops_to_remove = $track->user_ops;
my %constructor_args =
(
track_cache => 1,
track_name => $track->name,
track_version_original => $args->{original_version},
track_version_result => $args->{cached_version},
project => 1,
system => 1,
ops_list => \@all_ops,
inserts_data => \@inserts,
);
$constructor_args{region} = [ $track->region_start, $track->region_end ] if $track->is_region;
$constructor_args{fade_data} = [ map { $_->as_hash } $track->fades ]
if $track->fades;
$constructor_args{track_target_original} = $track->target if $track->target;
#say "constructor args: ",Dumper \%constructor_args;
my $ec = Audio::Nama::EffectChain->new( %constructor_args );
# update track settings
map{ delete $track->{$_} } qw(target);
map{ $_->remove } $track->fades;
map{ remove_effect($_) } @ops_to_remove;
map{ $_->remove } @inserts;
map{ delete $track->{$_} } qw( region_start region_end target );
my $obj = $args->{bus} ? 'bus' : 'track';
my $act = $args->{bus} ? 'reactivate bus'
: "restore version $args->{original_version}";
pager(qq(Saving attributes for cached $obj "$track->name"));
( run in 0.616 second using v1.01-cache-2.11-cpan-39bf76dae61 )