File Coverage

blib/lib/Audio/Nama/Engine.pm
Criterion Covered Total %
statement 39 102 38.2
branch 0 22 0.0
condition 0 12 0.0
subroutine 13 22 59.0
pod 0 4 0.0
total 52 162 32.1


line stmt bran cond sub pod time code
1             {
2             package Audio::Nama::Engine;
3             our $VERSION = 1.0;
4 1     1   4 use Modern::Perl;
  1         2  
  1         6  
5 1     1   158 use Carp;
  1         3  
  1         134  
6             our @ISA;
7             our %by_name;
8             our @ports = (57000..57050);
9             our %port = (
10             fof => 57201,
11             bus => 57202,
12             );
13 1     1   5 use Audio::Nama::Globals qw(:all);
  1         1  
  1         498  
14 1         7 use Audio::Nama::Object qw(
15             name
16             port
17             jack_seek_delay
18             jack_transport_mode
19             events
20             socket
21             pids
22             ecasound
23             buffersize
24             on_reconfigure
25             on_exit
26 1     1   6 );
  1         2  
27              
28             sub new {
29 0     0 0   my $class = shift;
30 0           my %vals = @_;
31 0 0         croak "undeclared field: @_" if grep{ ! $_is_field{$_} } keys %vals;
  0            
32             Audio::Nama::pager_newline("$vals{name}: returning existing engine"),
33 0 0         return $by_name{$vals{name}} if $by_name{$vals{name}};
34 0           my $self = bless { name => 'default', %vals }, $class;
35             #print "object class: $class, object type: ", ref $self, $/;
36 0           $by_name{ $self->name } = $self;
37 0           $self->initialize_ecasound();
38 0           $this_engine = $self;
39             }
40             sub initialize_ecasound {
41 0     0 0   my $self = shift;
42 0           my @existing_pids = split " ", qx(pgrep ecasound);
43 0           $self->launch_ecasound_server;
44             $self->{pids} = [
45 0           grep{ my $pid = $_; ! grep{ $pid == $_ } @existing_pids }
  0            
  0            
  0            
46             split " ", qx(pgrep ecasound)
47             ];
48             }
49       0 0   sub launch_ecasound_server {}
50       0 0   sub eval_iam {}
51             }
52             {
53             package Audio::Nama::NetEngine;
54             our $VERSION = 1.0;
55 1     1   5 use Modern::Perl;
  1         2  
  1         5  
56 1     1   106 use Audio::Nama::Log qw(logpkg);
  1         3  
  1         44  
57 1     1   5 use Audio::Nama::Globals qw(:all);
  1         2  
  1         451  
58 1     1   5 use Audio::Nama::Log qw(logit);
  1         1  
  1         40  
59 1     1   5 use Carp qw(carp);
  1         2  
  1         603  
60             our @ISA = 'Audio::Nama::Engine';
61              
62             sub init_ecasound_socket {
63 0     0     my $self = shift;
64 0           my $port = $self->port;
65 0           Audio::Nama::pager_newline("Creating socket on port $port.");
66 0           $self->{socket} = new IO::Socket::INET (
67             PeerAddr => 'localhost',
68             PeerPort => $port,
69             Proto => 'tcp',
70             );
71 0 0         die "Could not create socket: $!\n" unless $self->{socket};
72             }
73             sub launch_ecasound_server {
74 0     0     my $self = shift;
75 0           my $port = $self->port;
76            
77             # we'll try to communicate with an existing ecasound
78             # process provided:
79             #
80             # started with --server option
81             # --server-tcp-port option matches
82            
83 0           my $command = "ecasound -K -C --server --server-tcp-port=$port";
84 0           my $redirect = ">/dev/null &";
85 0           my $ps = qx(ps ax);
86 0 0 0       if ( $ps =~ /ecasound/ and $ps =~ /--server/ and ($ps =~ /tcp-port=$port/) )
      0        
87             {
88 0           Audio::Nama::pager_newline("Found existing Ecasound server on port $port")
89             }
90             else
91             {
92            
93 0           Audio::Nama::pager_newline("Starting Ecasound server on port $port");
94 0 0         system("$command $redirect") == 0 or carp("system $command failed: $?\n")
95             }
96 0           sleep 1;
97 0           $self->init_ecasound_socket();
98             }
99             sub eval_iam {
100 0     0     my $self = shift;
101 0           my $cmd = shift;
102             #my $category = Audio::Nama::munge_category(shift());
103 0           my $category = "ECI";
104              
105 0           logit(__LINE__,$category, 'debug', "Net-ECI sent: $cmd");
106              
107 0           $cmd =~ s/\s*$//s; # remove trailing white space
108 0           $this_engine->{socket}->send("$cmd\r\n");
109 0           my $buf;
110             # get socket reply, restart ecasound on error
111 0           my $result = $this_engine->{socket}->recv($buf, $config->{engine_command_output_buffer_size});
112 0 0         defined $result or Audio::Nama::restart_ecasound(), return;
113              
114 0           my ($return_value, $setup_length, $type, $reply) =
115             $buf =~ /(\d+)# digits
116             \ # space
117             (\d+)# digits
118             \ # space
119             ([^\r\n]+) # a line of text, probably one character
120             \r\n # newline
121             (.+) # rest of string
122             /sx; # s-flag: . matches newline
123              
124 0 0         if( ! $return_value == 256 ){
125 0           logit(__LINE__,$category,'error',"Net-ECI bad return value: $return_value (expected 256)");
126             # restart_ecasound(); # TODO
127              
128             }
129 1     1   6 no warnings 'uninitialized';
  1         2  
  1         185  
130 0           $reply =~ s/\s+$//;
131              
132 0 0         if( $type eq 'e')
133             {
134 0           logit(__LINE__,$category,'error',"ECI error! Command: $cmd. Reply: $reply");
135             #restart_ecasound() if $reply =~ /in engine-status/;
136             }
137             else
138 0           { logit(__LINE__,$category,'debug',"Net-ECI got: $reply");
139 0           $reply
140             }
141            
142             }
143             } # end package
144             {
145             package Audio::Nama::LibEngine;
146             our $VERSION = 1.0;
147 1     1   5 use Modern::Perl;
  1         3  
  1         5  
148 1     1   106 use Audio::Nama::Globals qw(:all);
  1         2  
  1         448  
149 1     1   6 use Audio::Nama::Log qw(logit);
  1         1  
  1         444  
150             our @ISA = 'Audio::Nama::Engine';
151             sub launch_ecasound_server {
152 0     0     my $self = shift;
153 0           Audio::Nama::pager_newline("Using Ecasound via Audio::Ecasound (libecasoundc)");
154 0           $self->{ecasound} = Audio::Ecasound->new();
155             }
156             sub eval_iam {
157             #logsub("&eval_iam");
158 0     0     my $self = shift;
159 0           my $cmd = shift;
160 0           my $category = Audio::Nama::munge_category(shift());
161            
162 0           logit(__LINE__,$category,'debug',"ECI sent: $cmd");
163              
164 0           my (@result) = $this_engine->{ecasound}->eci($cmd);
165 0 0 0       logit(__LINE__,$category, 'debug',"ECI got: @result")
      0        
166             if $result[0] and not $cmd =~ /register/ and not $cmd =~ /int-cmd-list/;
167 0           my $errmsg = $this_engine->{ecasound}->errmsg();
168 0 0         if( $errmsg ){
169 0 0         Audio::Nama::restart_ecasound() if $errmsg =~ /in engine-status/;
170 0           $this_engine->{ecasound}->errmsg('');
171             # Audio::Ecasound already prints error
172             }
173 0           "@result";
174             }
175             }
176             1
177              
178             __END__