;
use JSON::XS;
use Data::Dumper::Concise;
require Exporter;
our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [ qw(
serialize
assign
assign_singletons
yaml_in
json_in
json_out
config_vars
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = ();
our $to_json = JSON::XS->new->utf8->allow_blessed->pretty->canonical(1) ;
use Carp;
{my $var_map = { qw(
%devi
type: $type
data: $ref
class: $class
vars: @vars
ASSIGN
#logpkg(__FILE__,__LINE__,'debug',sub{json_out($ref)});
# index what sigil an identifier should get
# we need to create search-and-repla
ogpkg(__FILE__,__LINE__,'debug',sub{my %q = %p; delete $q{parent}; print
"=============\n%p\n",json_out(\%q)});
$vol = make_scale( \%p );
# Mute
$mute = $gui->{track_frame}->Button(
-com
logpkg(__FILE__,__LINE__,'debug',sub{ my %q = %p; delete $q{parent}; print "x=============\n%p\n",json_out(\%q) });
$pan = make_scale( \%q );
# Center
$center = $gui->{track_frame}->Button(
cts);#a ref to the object
#logpkg(__FILE__,__LINE__,'debug', "=============$gui->{tracks}\n",sub{json_out($gui->{tracks})});
my $independent_effects_frame
= ${ $gui->{tracks}->{$n}->{effects} }->
fects_cache.json', \&project_root],
gui_palette => ['palette', \&project_root],
state_store => ['State.json', \&project_dir ],
untracked_state_store => ['Aux.json', \&proj
ect_dir ],
effect_profile => ['effect_profiles.json', \&project_root],
chain_setup => ['Setup.ecs', \&project_dir ],
user_customization => ['customize.pl', \&project_root],
roject_dir ],
global_effect_chains => ['global_effect_chains.json', \&project_root],
old_effect_chains => ['effect_chains.json', \&project_root],
_logfile => ['nama.log', \&project_
$file->effects_cache); # scalar assign
}
if ($source)
{
assign(
data => decode($source, 'json'),
vars => [qw($fx_cache)],
class => 'Audio::Nama'
);
}
else
{
logpkg(__FILE__,__LI
le => $file->effects_cache,
vars => [qw($fx_cache)],
class => 'Audio::Nama',
format => 'json') unless is_test_script();
}
generate_mappings_for_shortcuts();
}
sub ladspa_plugin_list
e->{partial_label_to_full}->{$code} = $code;
} keys %{$fx_cache->{full_label_to_index}};
#print json_out $fx_cache->{partial_label_to_full};
}
{ my %dispatch =
(
ctrl => \&generate_help,
lv
$path = $filename || $file->state_store();
# remove extension if present
$filename =~ s/\.json//;
# append filename if warranted
$filename =
$filename =~ m{/}
? $filena
ore,
format => 'json',
vars => [ (grep {! /save_file_version_number/ } @persistent_vars) ],
class => 'Audio::Nama',
);
"$path.json";
}
{ my %decode =
(
json => \&json_in,
yaml => sub
= shift;
$filename //= $file->state_store();
initialize_marshalling_arrays();
my $suffix = 'json';
my $path = $file->untracked_state_store;
if (-r $path)
{
my $source = read_file($path);
"commit message: $message\n") if $message;
if( ! $Audio::Nama::config->{use_git} or $name =~ /\.json$/ )
{
Audio::Nama::pager("saving as file\n"), Audio::Nama::save_state( $name)
}
else
{
as { Audio::Nama::pager( Audio::Nama::json_out(Audio::Nama::fxn($item{fx_alias})->as_hash) ); 1}
dump_effect: _dump_effect { Audio::Nama::pager( Audio::Nama::json_out(Audio::Nama::this_op_o()->as_hash
ck->name};
Audio::Nama::pager( Audio::Nama::json_out($node)) if $node;
1;
}
show_latency_all: _show_latency_all {
Audio::Nama::pager( Audio::Nama::json_out($Audio::Nama::setup->{latency})) if $Aud
ub load_project {
logsub((caller(0))[3]);
my %args = @_;
logpkg(__FILE__,__LINE__,'debug', sub{json_out \%args});
$project->{name} = $args{name};
if (not $project->{name} or not -d project_dir(
}
sub restore_state {
logsub((caller(0))[3]);
my $name = shift;
if( ! $name or $name =~ /.json$/ or ! $config->{use_git})
{
restore_state_from_file($name)
}
else { restore_state_from
t();
# save current project status to temp state file
my $previous_state = '_previous_state.json';
save_state($previous_state);
# edit current project into a template
# No tracks are recor
package Audio::Nama::Sequence;
use v5.36; use Carp;
use Audio::Nama::Assign qw(json_out);
use Audio::Nama::Log qw(logsub logpkg);
use Audio::Nama::Effect qw(fxn modify_effect);
use Audio::Nama::Obje
ms: ",map{json_out($_->as_hash)}map{$Audio::Nama::tn{$_}}@$items) if $items;
$items //= [];
@_ = ($class, %args);
my $self = super();
logpkg(__FILE__,__LINE__,'debug',"new object: ", json_out($sel
f->as_hash));
logpkg(__FILE__,__LINE__,'debug', "items: ",json_out($items));
$self->{clip_counter} = $counter;
$self->{items} = $items;
$Audio::Nama::this_sequence = $self;
$self;
}
sub clip {
ng);
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_eve
ss grep { $id eq $_ } @$owns;
logpkg(__FILE__,__LINE__,'debug',sub{join " ", "my attributes:", json_out($self->as_hash)});
# find position of parent id in the track ops array
# and insert chi
p->{before} )
{
$p->{chain} = fxn($p->{before})->chain;
}
#logpkg(__FILE__,__LINE__,'debug',(json_out($p));
}
# How effect chains are added (by default before fader)
# user command: add_effec
lone);
use Audio::Nama::Util qw(signal_format input_node output_node);
use Audio::Nama::Assign qw(json_out);
no warnings 'uninitialized';
our (
$g, # routing graph object -
# based on project
, $chain_setup;
wantarray() ? @files : scalar @files;
}
sub show_io {
my $output = json_out( \%inputs ). json_out( \%outputs );
Audio::Nama::pager( $output );
}
sub warn_missing_jack_clients {
und edge attributes: ",json_out($eattr)) if $eattr;
my $vattr = $g->get_vertex_attributes($edge->[0]) // {};
logpkg(__FILE__,__LINE__,'debug',"found vertex attributes: ",json_out($vattr)) if $vattr
Effect qw(fxn append_effect);
use Audio::Nama::Log qw(logpkg logsub);
use Audio::Nama::Assign qw(json_out);
use Audio::Nama::Globals qw($fx_cache %tn $fx);
our $AUTOLOAD;
our $VERSION = 0.001;
no w
} xor $vals{attrib}{project});
logpkg(__FILE__,__LINE__,'debug','constructor arguments ', sub{ json_out(\%vals) });
my $ops_data = {};
# ops data is taken preferentially
# from ops_data arg
t_chain => ec_index,
$hash
} @{$vals{inserts_data}}
];
}
#say Audio::Nama::json_out($vals{inserts_data}) if $vals{inserts_data};
}
my $object = bless { %vals }, $class;
$by_i
us ne OFF } grep { $_->group ne 'Temp' } Audio::Nama::all_tracks();
\%snapshot;
}
sub status_snapshot_string {
my $json = json_out(status_snapshot());
$json =~ s/: "(\d+)"/: $1/g;
$json
}
}
1;
Audio::Nama::Util qw(freq input_node dest_type dest_string join_path);
use Audio::Nama::Assign qw(json_out);
use vars qw($n %by_name @by_index %track_names %by_index);
use Audio::Nama::Object qw(
ess $object->hide;
logpkg(__FILE__,__LINE__,'debug',$object->name, ": ","newly created track",$/,json_out($object->as_hash));
$object;
}
### object methods
sub snapshot {
my $track = shift;
my
= super();
#logpkg(__FILE__,__LINE__,'debug',"new object: ", json_out($self->as_hash));
#logpkg(__FILE__,__LINE__,'debug', "items: ",json_out($items));
# set the args removed above
$self->{durati
my @edges = map{ [$_, $sink] } @predecessors;
;
logpkg(__FILE__,__LINE__,'debug',"edges: ",json_out(\@edges));
for my $edge ( @edges ) {
logpkg(__FILE__,__LINE__,'debug',"edge: @$edge");
my @edges = map{ [$source, $_] } @successors;
;
logpkg(__FILE__,__LINE__,'debug',"edges: ",json_out(\@edges));
for my $edge ( @edges ) {
my $input = $g->get_edge_attribute(@$edge, "input"
}->{$direction}->{max}
and Audio::Nama::pager_newline('encountered unmatched latencies',
sub{ json_out($node) });
$node->{$port}->{latency}->{$direction}->{min}
}
}
sub latency_param {
my $op =
fect chains,
stored in F<global_effect_chains.json> in the
Nama project root directory.
=item C<@tracked_vars>
These variables are saved to F<State.json> in the project
directory and placed under v
ersion control.
=item C<@persistent_vars>
These Variables saved to F<Aux.json>, I<not> under version control.
including project-specific effect-chain definitions,
and track/version comments.
=back
m || 'bare' } = $match }
}
logpkg(__FILE__,__LINE__,'debug',sub{"get_version: " , Audio::Nama::json_out(\%versions)});
%versions;
}
sub candidates {
my $dir = shift;
$dir = File::Spec::Link->r
lete $versions{bare};
}
logpkg(__FILE__,__LINE__,'debug',sub{"\%versions\n================\n", json_out(\%versions)});
\%versions;
}
sub _versions {
# $Audio::Nama::debug2 and print "&versions\
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 warnin
! 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
t the command
nama> save initial_mix
creates initial_mix.json, not a tagged commit.
nama> get initial_mix
loads initial_mix.json");
$config->{use_git} = $config->{use_git} && git_executabl
rep{ /^#/ }
expand_cats(split q(,), $cat_string) if $cat_string;
#say("negate\n",Audio::Nama::json_out(\%negate));
my $layout = "[\%r] %c %m%n"; # backslash to protect from source filter
my $lo
#/};
$config->{opts}->{R} = $old_opt_r;
}
sub dump_all {
my $tmp = ".dump_all";
my $format = "json";
my $fname = join_path( project_root(), $tmp);
save_system_state($fname,$format);
file_pager(