Audio-Nama
view release on metacpan or search on metacpan
lib/Audio/Nama/Effect.pm view on Meta::CPAN
{
package Audio::Nama::Effect;
use v5.36;
our $VERSION = 1.0;
use List::MoreUtils qw(first_index insert_after_string);
use Carp qw(carp cluck croak confess);
use Data::Dumper::Concise;
use Audio::Nama::Assign qw(json_out);
use Audio::Nama::Log qw(logsub logpkg);
use Audio::Nama::Util qw(timer start_event stop_event);
use Audio::Nama::Globals qw(
$fx
$fx_cache
$ui
%ti
%tn
%bn
%en
$config
$setup
$project
$this_engine
$this_track);
use Audio::Nama::Object qw(
id
type
chain
class
params
params_log
display
parent
owns
bypassed
name
surname
predecessor
);
*this_op = \&Audio::Nama::this_op;
*this_param = \&Audio::Nama::this_param;
*this_stepsize = \&Audio::Nama::this_stepsize;
our %by_id;
our $AUTOLOAD;
import_engine_subs();
sub initialize {
%by_id = () ;
# effect variables - no object code (yet)
$fx->{id_counter} = "A"; # autoincrement counter
# volume settings
$fx->{muted} = [];
}
sub AUTOLOAD {
my $self = shift;
#say "got self: $self", Audio::Nama::Dumper $self;
die 'not object' unless ref $self;
# get tail of method call
my ($call) = $AUTOLOAD =~ /([^:]+)$/;
# see if this can be satisfied by a field from
# the corresponding effects registry entry
$call = 'name' if $call eq 'fxname';
$self->about->{$call}
}
sub DESTROY {}
lib/Audio/Nama/Effect.pm view on Meta::CPAN
$is_track_error++, $result->{track}->{$name}->{orphan_vol} = $track->vol
if $track->vol and ! grep { $track->vol eq $_ } @ops;
$is_track_error++,$result->{track}->{$name}->{orphan_pan} = $track->pan
if $track->pan and ! grep { $track->pan eq $_ } @ops;
# we don't check for orphan latency ops as this is
# allowed in order to keep constant $op_id over
# time (slower incrementing of fx counter)
#$is_track_error++,$result->{track}->{$name}->{orphan_latency_op} = $track->latency_op
# if $track->latency_op and ! grep { $track->latency_op eq $_ } @ops;
# check for undefined op ids
my @track_undef_op_pos;
my $i = 0;
map { defined $_ or push @track_undef_op_pos, $i; $i++ } @ops;
$is_track_error++,$result->{track}->{$name}->{undef_op_pos}
= \@track_undef_op_pos if @track_undef_op_pos;
# remove undefined op ids from list
@ops = grep{ $_ } @ops;
# check for op ids without corresponding entry
my @uninstantiated_op_ids;
map { fxn($_) or push @uninstantiated_op_ids, $_ } @ops;
$is_track_error++, $result->{track}->{$name}->{uninstantiated_op_ids}
= \@uninstantiated_op_ids if @uninstantiated_op_ids;
$result->{track}->{$name}->{is_error}++ if $is_track_error;
$result->{is_error}++ if $is_track_error;
} Audio::Nama::audio_tracks();
# check for objects missing fields
my @incomplete_entries =
grep { ! fxn($_)->params or ! fxn($_)->type or ! fxn($_)->chain }
grep { $_ } keys %Audio::Nama::Effect::by_id;
if(@incomplete_entries)
{
$result->{incomplete_entries} = \@incomplete_entries;
$result->{is_error}++
}
$result;
}
sub fade {
my $self = shift;
# parameter starts at one
my ($param, $from, $to, $seconds) = @_;
my $id = $self->id;
# no fade without Time::HiRes
# no fade unless engine is running
if ( $this_engine->started() and $config->{hires_timer} )
{
my $steps = $seconds * $config->{fade_resolution};
my $wink = 1/$config->{fade_resolution};
my $size = ($to - $from)/$steps;
logpkg(__FILE__,__LINE__,'debug', "id: $id, param: $param, from: $from, to: $to, seconds: $seconds");
# first step by step
for (1..$steps - 1){
$self->_modify_effect($param, $size, '+');
sleeper( $wink );
}
}
$self->_modify_effect($param, $to)
}
sub plan_fade {
return unless $this_engine->started();
my $self = shift;
my %args = @_;
my $param = $args{param} || 1;
my $from = $args{from} || 0;
my $to = $args{to} || 0;
my $seconds = $args{seconds} || 1;
my $in_future = $args{in_future};
my $steps = $seconds * $config->{fade_resolution};
my $wink = 1/$config->{fade_resolution};
my $id = $self->id;
my $size = ($to - $from)/$steps;
logpkg(__FILE__,__LINE__,'debug', "id: $id, param: $param, from: $from, to: $to, seconds: $seconds");
if ( not $in_future ){
for (1..$steps - 1){
$self->_modify_effect($param, $size, '+');
sleeper( $wink );
}
$self->_modify_effect($param, $to)
}
else {
my $advance = $in_future;
my $coderef = sub { $self->_modify_effect($param, $size, '+') };
for (1..$steps - 1){
$advance += $wink;
schedule_fade($advance, $coderef)
}
$advance += $wink;
schedule_fade($advance, sub { $self->_modify_effect($param, $to) } );
sub schedule_fade {
my ($after, $sub) = @_;
start_event("fade_".$setup->{fade_counter}++ => timer( $after, 0, $sub ));
}
}
}
sub fadein {
my $self = shift;
my $to = shift;
my $from = $config->{fade_out_level}->{$self->type};
$self->_modify_effect(1, $from);
$self->fade(1, $from, $to, $config->{engine_fade_length_on_start_stop});
}
sub fadeout {
my $self = shift;
my $from = $self->params->[0];
my $to = $config->{fade_out_level}->{$self->type};
$self->fade(1, $from, $to, $config->{engine_fade_length_on_start_stop} );
$self->_modify_effect(1, $config->{mute_level}->{$self->type});
}
sub mute_level {
my $self = shift;
my $level = $config->{mute_level}->{$self->type};
#defined $level or die $self->nameline . " cannot be muted."
$level
}
sub fade_out_level {
my $self = shift;
$config->{fade_out_level}->{$self->type}
}
sub ecasound_format {
my $self = shift;
my $cmd = '-'.$self->code;
$cmd .= ':'.join ',' ,@{$self->{params}} if $self->{params} and @{$self->{params}} > 0;
$cmd
}
} # end package Effect
1
( run in 2.652 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )