line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
{ |
2
|
|
|
|
|
|
|
package Audio::Nama::Engine; |
3
|
|
|
|
|
|
|
our $VERSION = 1.0; |
4
|
1
|
|
|
1
|
|
5
|
use Modern::Perl; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
7
|
|
5
|
1
|
|
|
1
|
|
105
|
use Carp; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
119
|
|
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
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
523
|
|
14
|
1
|
|
|
|
|
8
|
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
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
5
|
|
56
|
1
|
|
|
1
|
|
107
|
use Audio::Nama::Log qw(logpkg); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
46
|
|
57
|
1
|
|
|
1
|
|
5
|
use Audio::Nama::Globals qw(:all); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
467
|
|
58
|
1
|
|
|
1
|
|
6
|
use Audio::Nama::Log qw(logit); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
43
|
|
59
|
1
|
|
|
1
|
|
6
|
use Carp qw(carp); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
615
|
|
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
|
|
|
|
|
207
|
|
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
|
|
6
|
use Modern::Perl; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
4
|
|
148
|
1
|
|
|
1
|
|
112
|
use Audio::Nama::Globals qw(:all); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
465
|
|
149
|
1
|
|
|
1
|
|
7
|
use Audio::Nama::Log qw(logit); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
374
|
|
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__ |