1package Audio::Ecasound; 2 3require 5.005_62; 4use Carp; 5use strict; 6use vars qw(@ISA @EXPORT %EXPORT_TAGS @EXPORT_OK $VERSION $AUTOLOAD); 7 8require Exporter; 9require DynaLoader; 10 11@ISA = qw(Exporter DynaLoader); 12 13# base names for methods (correspond to the C eci_X and eci_X_r versions) 14my @cmds = qw( 15 command 16 command_float_arg 17 18 last_float 19 last_integer 20 last_long_integer 21 last_string 22 last_string_list_count 23 last_string_list_item 24 last_type 25 26 error 27 last_error 28 ); 29 30%EXPORT_TAGS = ( 31 simple => [qw( eci on_error errmsg )], 32 std => [ @cmds ], 33 raw => [ map { "eci_$_" } @cmds ], 34 raw_r => [ qw(eci_init_r eci_cleanup_r), map { "eci_$_"."_r" } @cmds ], 35 # NOTE the :iam tag is added dynamically in &import 36); 37 38# NOTE :iam adds to this in &import 39@EXPORT_OK = ( map { @{$_} } @EXPORT_TAGS{'simple', 'std','raw','raw_r'} ); 40 41my %iam_cmds; 42sub get_iam_cmds { return keys %iam_cmds; } 43 44sub import { 45 # When :iam is imported, the internal commands (len >=2) 46 # are found with eci 'int-cmd-list' and declared 47 # hyphens are converted to underscores to produce legal names 48 if(grep { /^:iam$/ } @_) { 49 my @iam_cmds = map { s/-/_/g; (/^\w{2,}$/)? $_ : () } eci('int-cmd-list'); 50 $EXPORT_TAGS{iam} = [ @iam_cmds ]; 51 push @EXPORT_OK, @iam_cmds; 52 $iam_cmds{$_} = 1 for (@iam_cmds); 53 } 54 Audio::Ecasound->export_to_level(1,@_); 55} 56 57# AUTOLOAD to proxy iam commands as functions 58# defines iam commands as they are used 59sub AUTOLOAD { 60 my $cmd = $AUTOLOAD; 61 $cmd =~ s/.*:://; 62 63 unless($iam_cmds{$cmd}) { 64 # can't you pass? Just pretend by doing what perl would do 65 croak "Undefined subroutine $AUTOLOAD called"; 66 } 67 68 no strict 'refs'; 69 *$cmd = sub { 70 $cmd =~ s/_/-/g; # eg cop_list => cop-list; 71 eci(join ' ', $cmd, @_); 72 }; 73 goto &$cmd; 74} 75 76$VERSION = '1.01'; 77bootstrap Audio::Ecasound $VERSION; 78 79# Generate wrappers(OO or not-OO) for raw C functions 80for my $cmd (@cmds) { 81 # eg. the 'command' sub is a perl wrapper which 82 # calls 'eci_command' or 'eci_command_r' depending 83 # on whether it's called as a method 84 no strict 'refs'; 85 *$cmd = sub { 86 my $self = &_shift_self; 87 if(ref $self) { 88 # treat string as function name (symref), pass handle 89 "eci_${cmd}_r"->($self->{eci_handle}, @_); 90 } else { 91 "eci_$cmd"->(@_); 92 } 93 }; 94} 95 96# Overriding DynaLoader's method so that .so symbols are 97# globally visible, hence ecasound-plugins (like libaudioio_af.so) 98# can link to them 99sub dl_load_flags { 0x01 } 100 101my %opts = ( 102 on_error => 'warn', # 'die', '', 'cluck', 'confess' 103 errmsg => '', 104 ); 105 106# generate accessors 107for my $option (keys %opts) { 108 no strict 'refs'; 109 *$option = sub { 110 111 my $self = &_shift_self; 112 my $opts = \%opts; 113 114 if(ref $self) { 115 # use object's hash 116 $opts = $self; 117 } 118 $opts->{$option} = shift if @_; 119 return $opts->{$option}; 120 }; 121} 122 123sub new { 124 my $arg = shift; 125 my $class = ref($arg) || $arg; 126 my $self = { %opts }; # object gets current package values 127 $self->{eci_handle} = eci_init_r(); 128 bless $self, $class; 129} 130 131sub do_error { 132 my $self = &_shift_self; 133 my $errstr = shift; 134 135 $self->errmsg($errstr); 136 137 my $on_error = $self->on_error; 138 no strict 'refs'; 139 if($on_error eq 'die') { 140 die "Audio::Ecasound::error: $errstr\n"; 141 } elsif($on_error eq 'warn') { 142 warn "Audio::Ecasound::error: $errstr\n"; 143 } elsif(exists &{"Carp::$on_error"}) { 144 &{"Carp::$on_error"}("Audio::Ecasound::error: $errstr\n"); 145 } elsif($on_error) { 146 die "Audio::Ecasound::error: $errstr\n" 147 ."(And on_error=$on_error is bad)\n"; 148 } 149 return; 150} 151 152# do everything in one function 153sub eci { 154 155 my $self = &_shift_self; 156 157 my $cmdstr = shift; 158 if(@_) { 159 my $float = shift; 160 $self->command_float_arg($cmdstr, $float); 161 $cmdstr .= ' ' . $float; 162 # Handle an eci error 163 if($self->error()) { 164 my $errstr = $self->last_error() . "(in $cmdstr)"; 165 return $self->do_error($errstr); 166 } 167 } else { 168 # multiline commands 169 for my $mcmdstr (split /\n/, $cmdstr) { 170 171 # Comments 172 $mcmdstr =~ s/#.*//; 173 $mcmdstr =~ s/^\s+//; 174 $mcmdstr =~ s/\s+$//; 175 # Skip blanks 176 next if $mcmdstr =~ /^$/; 177 178 $self->command($mcmdstr); 179 180 # Handle an eci error ( would be 'e' return code ) 181 if($self->error()) { 182 my $errstr = $self->last_error() . "(in $mcmdstr)"; 183 return $self->do_error($errstr); 184 } 185 } 186 } 187 188 # do return value 189 return unless defined wantarray; 190 my $ret; 191 my $type = $self->last_type(); 192 if($type eq 'i') { 193 return $self->last_integer(); 194 } elsif($type eq 'f') { 195 return $self->last_float(); 196 } elsif($type eq 's') { 197 return $self->last_string(); 198 } elsif($type eq 'li') { 199 return $self->last_long_integer(); 200 } elsif($type eq '' || $type eq '-') { # - from python 201 return ''; # false but defined 202 } elsif($type eq 'S') { 203 my $count = $self->last_string_list_count(); 204 # differentiate from () err when ambiguous 205 return ('') unless ($count && $self->on_error); 206 my @ret; 207 for my $n (0..$count-1) { 208 push @ret, $self->last_string_list_item($n); 209 } 210 return @ret; 211 } elsif($type eq 'e') { # should be handled above... 212 my $errstr = $self->last_error() . "(in $cmdstr)"; 213 return $self->do_error($errstr); 214 } else { 215 die "last_type() returned unexpected type <$type>"; 216 } 217} 218 219 220# Look at first argument and return something that 221# can be used as an object, either a blessed ref 222# a class name which isa A::E or the string 223# 'Audio::Ecasound' (can be used 'Audio::Ecasound'->eci($c)) 224# NOTE: should be called &_shift_self to shift @_ for parent; 225sub _shift_self { 226 if(!defined $_[0]) { 227 return __PACKAGE__; 228 } elsif(ref $_[0]) { 229 return shift; 230 } elsif ( $_[0] =~ /^[_a-zA-Z][\w:']*$/ # Common package names 231 && UNIVERSAL::isa($_[0],__PACKAGE__) ) { 232 #&& $_[0]->isa(__PACKAGE__) ) { 233 return shift; 234 } else { 235 return __PACKAGE__; 236 } 237} 238 239DESTROY { 240 my $self = shift; 241 eci_cleanup_r($self->{eci_handle}); 242} 243 244END { 245 # Partner eci_init in XS BOOT: 246 eci_cleanup(); 247} 248 249 2501; 251__END__ 252 253=head1 NAME 254 255Audio::Ecasound - Perl binding to the ecasound sampler, recorder, fx-processor 256 257=head1 SYNOPSIS 258 259One function interface: 260 261 use Audio::Ecasound qw(:simple); 262 263 eci("cs-add play_chainsetup"); 264 eci("c-add 1st_chain"); 265 eci("-i:some_file.wav"); 266 eci("-o:/dev/dsp"); 267 # multiple \n separated commands 268 eci("cop-add -efl:100 269 # with comments 270 cop-select 1 271 copp-select 1 272 cs-connect"); 273 eci("start"); 274 my $cutoff_inc = 500.0; 275 while (1) { 276 sleep(1); 277 last if eci("engine-status") ne "running"; 278 279 my $curpos = eci("get-position"); 280 last if $curpos > 15; 281 282 my $next_cutoff = $cutoff_inc + eci("copp-get"); 283 # Optional float argument 284 eci("copp-set", $next_cutoff); 285 } 286 eci("stop"); 287 eci("cs-disconnect"); 288 print "Chain operator status: ", eci("cop-status"); 289 290Object Interface 291 292 use Audio::Ecasound; 293 294 my $e = new Audio::Ecasound; 295 $e->on_error(''); 296 $e->eci("cs-add play_chainsetup"); 297 # etc. 298 299Vanilla Ecasound Control Interface (See Ecasound's Programmer Guide): 300 301 use Audio::Ecasound qw(:std); 302 303 command("copp-get"); 304 $precise_float = last_float() / 2; 305 command_float_arg("copp-set", $precise_float); 306 warn last_error() if error(); 307 308IAM Interface, pretend interactive mode commands are functions. 309 310 use Audio::Ecasound qw(:iam :simple); 311 312 # iam commands as functions with s/-/_/g 313 my $val = copp_get; 314 copp_set $val+0.1; # floats are stringified so beware 315 eci("-i /dev/dsp"); # not all commands are exported 316 317=head1 DESCRIPTION 318 319Audio::Ecasound provides perl bindings to the ecasound control interface of the 320ecasound program. You can use perl to automate or interact with 321ecasound so you don't have to turn you back on the adoring masses 322packed into Wembly Stadium. 323 324Ecasound is a software package designed for multitrack audio processing. 325It can be used for audio playback, recording, format conversions, 326effects processing, mixing, as a LADSPA plugin host and JACK node. 327Version E<gt>= 2.2.X must be installed to use this package. 328L<SEE ALSO> for more info. 329 330=head1 INSTALLATION 331 332 perl Makefile.PL 333 334If your perl wasn't built with -Dusethreads or -D_REENTRANT you 335will be prompted whether to continue with the install. It's in 336your hands... See L<THREADING NOTE> 337 338 make 339 make test 340 make install 341 342=head1 THREADING NOTE 343 344The ecasoundc library uses pthreads so will may only work if 345your perl was compiled with threading enabled, check with: 346 347 % perl -V:usethreads 348 349You are welcome to try using the module with non-threaded perls 350(perhaps -D_REENTRANT alone would work) it have worked for some. 351 352=head1 EXPORT 353 354=over 4 355 356=item * 357 358Nothing by default as when going OO. 359 360=item * 361 362:simple gives eci() which does most everything, also errmsg and on_error. 363Or you could just import 'eci' and call the others C<Audio::Ecasound::errmsg()> 364 365=item * 366 367:iam imports many iam commands so that you can use them as perl functions. 368Basically everything listed by ecasound's 'int-cmd-list' except the single 369letter commands and hyphens are replaced by underscores. 370The list is produced at run-time and returned by Audio::Ecasound::get_iam_cmds(). 371See L<IAM COMMANDS>; 372 373=item * 374 375:std to import the full ecasound control interface detailed in the 376Ecasound Programmer's Guide. 377 378=item * 379 380:raw and raw_r, C functions with minimal wrapping, _r ones are reentrant 381and must be passed the object returned by eci_init_r(). I don't know why 382you would use these, presumably you do. These options may be removed in 383future. 384 385=back 386 387=head1 METHODS AND FUNCTIONS 388 389The procedural and OO interfaces use the same functions, the differences 390are that when called on an Audio::Ecasound object the reentrant C versions 391are used so you can have multiple independent engine (with independent 392options). 393 394=over 2 395 396=item B<new()> 397 398Constructor for Audio::Ecasound objects, inherits the on_error and 399other options from the current package settings (defaults if untouched). 400 401=item B<eci('ecasound command string', [$float_argument])> 402 403Sends commands to the Ecasound engine. A single command may be called with an 404optional float argument (to avoid precision loss). Alternatively, 405multiple commands may be given separated by newlines (with C<#> starting 406a comment). 407 408If called in non-void context the result of the last command is 409returned, it may be an integer, float, string (ie. scalar) or a list of 410strings. Which will depend on the ecasound command, see L<ecasound-iam> 411for each function's return value. 412 413If there is an error the action given to on_error will be taken. 414See on_error below for return value caveats when on_error = ''. 415Error processing is performed for each command in a multiline command. 416 417=item B<on_error('die')> 418 419Set the action to be taken when an error occurs from and C<eci> 420command, may be 'die', 'warn', '', 'confess', ... (default is 'warn'). 421 422When '' is selected C<return;> is used for an error, that is undef or 423(). To disamibiguate eci will return '' or ('') for no return value 424and no string list respectively. 425 426=item B<errmsg()> 427 428The last error message from an C<eci> command. It is not reset 429so clear it yourself if required C<errmsg('')>. This shouldn't 430be necessary as you can use C<defined> or on_error to find out 431when errors occur. 432 433=back 434 435The remainder of the functions/methods are the standard Ecasound 436Control Interface methods but they come in three flavours. 437The bare function name may be called with or without an object: 438 439 use Audio::Ecasound ':simple': 440 command($cmd); 441 # or 442 my $e = new Audio::Ecasound; 443 $e = command($cmd); 444 445The other two flavours are low-level, reentrant and non-reentrant. 446These are thinly wrapped C functions better documented in the ECI 447document with the ecasound distribution. Just add 'eci_' to the 448names below for the non-reentrant version and then add a '_r' 449to the end for the reentrant version. The reentrant version takes 450an extra first argument, the object returned by eci_init_r() which 451must be destroyed with eci_cleanup_r(). 452 453=over 4 454 455=item B<command($cmd_string)> 456 457=item B<eci_command_float_arg($cmd_string, $float_arg)> 458 459=item B<$bool = eci_error()> 460 461=item B<$err_str = eci_last_error()> 462 463=item B<$float = eci_last_float()> 464 465=item B<$int = eci_last_integer()> 466 467=item B<$lint = eci_last_long_integer()> 468 469=item B<$str = eci_last_string()> 470 471=item B<$n = eci_last_string_list_count()> 472 473=item B<$str_n = eci_last_string_list_item($n)> 474 475=item B<$type_str = eci_last_type()> 's' 'S' 'i' 'li' 'f' '' 476 477=back 478 479=head1 IAM COMMANDS 480 481When the :iam tag is imported most of the commands in ecasounds 482interactive mode become perl functions. The '-'s become '_'s 483to become valid perl names ('cop-get' is cop_get, etc.) 484The list is printed with: 485 486 use Audio::Ecasound qw(:iam :simple); 487 print join ' ', Audio::Ecasound::get_iam_cmds(); 488 489The arguments joined together as a string and then sent to ecasound. 490This means that float precision is lost, unlike with the two 491argument C<eci> so use it. Also use C<eci> for command-line style 492commands like C<eci "-i /dev/dsp">. But most other things you 493can just use the iam command itself (s/-/_/g): 494 495 use Audio::Ecasound qw(:iam :simple); 496 ... # setup stuff 497 print status; 498 start; 499 $v = copp_get; 500 copp_set $v + 1.2; 501 502I would never encourage anyone to use C<no strict 'subs';> but with :iam you 503may enjoy a little less discipline. 504 505See the iam_int.pl example file in the eg directory. 506 507=head1 EXAMPLES 508 509See the C<eg/> subdirectory. 510 511=head1 TROUBLESHOOTING 512 513The ecasound command 'debug' could be useful, add C<eci "debug 63"> 514to the top of your program. The argument is various bits OR'd 515and controls the amount and type of debugging information, see the 516ecasound documentation of source or just try your favorite powers 517of two. 518 519There was a bug effecting Audio::Ecasound with ecasound version 5202.4.4, causing problems with :iam mode, and test failure 521("Do you need to predeclare cs_set_length"). See 522L<http://www.eca.cx/ecasound-list/2006/12/0007.html> and 523L<http://www.eca.cx/ecasound-list/2006/06/0004.html>. 524 525=head1 FILES AND ENVIRONMENT 526 527The libecasoundc library now uses the environment variable 528"ECASOUND" to find the ecasound executable. If it is not set then 529the libarary will print a warning. To suppress it, simply set 530the ECASOUND variable: eg. export ECASOUND=ecaosund 531 532The ecasound library will still process ~/.ecasoundrc and other 533setup files for default values. See the library documentation. 534 535=head1 AUTHOR 536 537(c) 2001-2007 Brad Bowman E<lt>eci-perl@bereft.netE<gt> 538This software may be distributed under the same terms as Perl itself. 539 540=head1 SEE ALSO 541 542The Ecasound Programmer's Guide and ECI doc, 543L<ecasound>, L<ecasound-iam> http://eca.cx/, http://www.ladspa.org/ 544 545The internals of libecasoundc have been rebuilt and now interact with 546a running ecasound via a socket using a protocol defined in the 547Programmer's Guide. The C library is now just a compatibility layer 548and the Python version now talks directly to the socket. 549It would be straight forward to write an equivalent Perl version 550should the need arise. 551 552=cut 553