Audio-Nama
view release on metacpan or search on metacpan
lib/Audio/Nama/IO.pm view on Meta::CPAN
# we will use the following to map from graph node names
# to IO class names
our %io_class = qw(
null_in Audio::Nama::IO::from_null
null_out Audio::Nama::IO::to_null
soundcard_in Audio::Nama::IO::from_soundcard
soundcard_out Audio::Nama::IO::to_soundcard
soundcard_device_in Audio::Nama::IO::from_alsa_soundcard_device
soundcard_device_out Audio::Nama::IO::to_alsa_soundcard_device
wav_in Audio::Nama::IO::from_wav
wav_out Audio::Nama::IO::to_wav
loop_source Audio::Nama::IO::from_loop
loop_sink Audio::Nama::IO::to_loop
jack_manual_in Audio::Nama::IO::from_jack_port
jack_manual_out Audio::Nama::IO::to_jack_port
jack_ports_list_in Audio::Nama::IO::from_jack_port
jack_ports_list_out Audio::Nama::IO::to_jack_port
jack_multi_in Audio::Nama::IO::from_jack_multi
jack_multi_out Audio::Nama::IO::to_jack_multi
jack_client_in Audio::Nama::IO::from_jack_multi
jack_client_out Audio::Nama::IO::to_jack_multi
bus_in Audio::Nama::IO::from_bus
);
#bus_out Audio::Nama::IO::to_bus #
### class descriptions
# === CLASS Audio::Nama::IO::from_jack_port ===
#
# is triggered by source_type codes:
#
# + jack_manual_in
# + jack_ports_list_in
#
# For track 'piano', the class creates an input similar to:
#
# -i:jack,,piano_in
#
# which receives input from JACK node:
#
# + Nama:piano_in,
#
# If piano is stereo, the actual ports will be:
#
# + Nama:piano_in_1
# + Nama:piano_in_2
# (CLASS Audio::Nama::IO::to_jack_port is similar)
### class definition
our $AUTOLOAD;
# add underscore to field names so that regular method
# access will go through AUTOLOAD
# we add an underscore to each key
use Audio::Nama::Object qw(track_ chain_id_ endpoint_ format_ format_template_ width_ ecs_extra_ direction_ device_id_);
sub new {
my $class = shift;
my %vals = @_;
my @args = map{$_."_", $vals{$_}} keys %vals; # add underscore to key
# note that we won't check for illegal fields
# so we can pass any value and allow AUTOLOAD to
# check the hash for it.
my $self = bless {@args}, $class;
my $direction = $self->direction; # input or output
# join IO objects to graph
my $name;
try{ $name = $self->name }
catch {}; # we do nothing
{ no warnings 'uninitialized';
Audio::Nama::logpkg(__FILE__,__LINE__,'debug',"I belong to track $name\n",
sub{Audio::Nama::Dumper($self)} );
}
if($name){
$by_name{$name}->{$direction} = $self;
}
$self
}
# latency stubs
sub capture_latency {
my $self = shift;
return unless $self->client;
Audio::Nama::jack_port_latency('input', $self->client);
}
sub playback_latency {
my $self = shift;
return unless $self->client;
Audio::Nama::jack_port_latency('output', $self->client);
}
# we need at least stubs for subclasses' methods
# for AUTOLOAD to be happy - so we include
sub client {}
#### JACK related methods
# inherited by all, the methods defined below are called in
# these classes:
#
# to_jack_multi,
# from_jack_multi
# to_jack_client
# from_jack_client
#
# They have no function in other classes.
lib/Audio/Nama/IO.pm view on Meta::CPAN
{
package Audio::Nama::IO::to_null;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub _device_id { 'null' }
}
{
package Audio::Nama::IO::from_rtnull;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub _device_id { 'rtnull' }
}
{
package Audio::Nama::IO::to_rtnull;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub _device_id { 'rtnull' }
}
{
package Audio::Nama::IO::from_wav;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub device_id {
my $self = shift;
my @modifiers;
push @modifiers, $self->playat_output if $self->playat_output;
push @modifiers, $self->select_output if $self->select_output;
push @modifiers, split " ", $self->modifiers if $self->modifiers;
push @modifiers, $self->full_path;
join(q[,],@modifiers);
}
sub _format { $Audio::Nama::setup->{wav_info}->{$_[0]->full_path}->{format} };
sub ecs_extra { $_[0]->mono_to_stereo}
sub client { 'system' if $jack->{jackd_running} }
sub ports { 'system:capture_1' }
}
{
package Audio::Nama::IO::to_wav;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub device_id { $_[0]->full_path }
sub _format_template { $config->{raw_to_disk_format} }
}
{
package Audio::Nama::IO::from_loop;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub new {
my $class = shift;
my %vals = @_;
$class->SUPER::new( %vals, device_id => "loop,$vals{endpoint}");
}
sub _format {
my $self = shift;
return if $Audio::Nama::config->{opts}->{T}; # XX don't break tests
Audio::Nama::signal_format($self->format_template, $config->{loop_chain_channel_width});
}
sub _format_template { $config->{cache_to_disk_format} }
}
{
package Audio::Nama::IO::to_loop;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO::from_loop';
}
{
package Audio::Nama::IO::from_soundcard;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub new {
shift; # throw away class
my $class = $io_class{Audio::Nama::IO::soundcard_input_type_string()};
$class->new(@_);
}
}
{
package Audio::Nama::IO::to_soundcard;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub new {
shift; # throw away class
my $class = $io_class{Audio::Nama::IO::soundcard_output_type_string()};
$class->new(@_);
}
}
{
package Audio::Nama::IO::to_jack_multi;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub client {
my $self = shift;
# say "to_jack_multi: target_id: ",$self->target_id;
# say "to_jack_multi: rectified target_id: ",Audio::Nama::IO::rectified($self->target_id);
Audio::Nama::IO::rectified($self->target_id)
}
sub device_id {
my $self = shift;
Audio::Nama::IO::jack_multi_route($self->ports)
}
}
{
package Audio::Nama::IO::from_jack_multi;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO::to_jack_multi';
sub ecs_extra { $_[0]->mono_to_stereo }
lib/Audio/Nama/IO.pm view on Meta::CPAN
sub ecs_extra { $_[0]->mono_to_stereo}
sub client { Audio::Nama::IO::rectified($_[0]->source_id) }
}
{
package Audio::Nama::IO::from_alsa_soundcard_device;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub ecs_extra { join ' ', $_[0]->rec_route, $_[0]->mono_to_stereo }
sub device_id { $config->{devices}->{$config->{alsa_capture_device}}->{ecasound_id} }
sub input_channel { $_[0]->source_id }
sub rec_route {
# works for mono/stereo only!
no warnings qw(uninitialized);
my $self = shift;
# needed only if input channel is greater than 1
return '' if ! $self->input_channel or $self->input_channel == 1;
my $route = "-chmove:" . $self->input_channel . ",1";
if ( $self->width == 2){
$route .= " -chmove:" . ($self->input_channel + 1) . ",2";
}
return $route;
}
}
{
package Audio::Nama::IO::to_alsa_soundcard_device;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub device_id { $config->{devices}->{$config->{alsa_playback_device}}{ecasound_id} }
sub ecs_extra {route($_[0]->width,$_[0]->output_channel) }
sub output_channel { $_[0]->send_id }
sub route2 {
my ($from, $to, $width) = @_;
}
sub route {
# routes signals (1..$width) to ($dest..$dest+$width-1 )
my ($width, $dest) = @_;
return '' if ! $dest or $dest == 1;
# print "route: width: $width, destination: $dest\n\n";
my $offset = $dest - 1;
my $route ;
for my $c ( map{$width - $_ + 1} 1..$width ) {
$route .= " -chmove:$c," . ( $c + $offset);
}
$route;
}
}
{
package Audio::Nama::IO::from_bus;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
sub new {
my $class = shift;
my %vals = @_;
print "from_bus: ", Audio::Nama::Dumper \%vals;
#$class->SUPER::new( %vals, device_id => "loop,$vals{endpoint}");
}
}
{
package Audio::Nama::IO::any;
use v5.36;
our $VERSION = 1.0;
our @ISA = 'Audio::Nama::IO';
}
1;
__END__
( run in 0.605 second using v1.01-cache-2.11-cpan-5735350b133 )