/usr/local/CPAN/Audio-PortAudio/Audio/PortAudio.pm
# Audio::PortAudio perl modules for portable audio I/O
# Copyright (C) 2007 Joost Diepenmaat.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# See the COPYING file for more information.
package Audio::PortAudio;
use strict;
use base qw(DynaLoader);
our $VERSION = 0.03;
__PACKAGE__->bootstrap($VERSION);
initialize();
sub host_apis {
my $count = host_api_count();
return if $count < 1;
return map { host_api($_) } 0 .. $count -1;
}
sub open_read_stream {
my ($streamparameters, $sample_rate, $frames_per_buffer, $stream_flags) = @_;
open_stream($streamparameters,undef,$sample_rate, $frames_per_buffer, $stream_flags);
}
sub open_write_stream {
my ($streamparameters, $sample_rate, $frames_per_buffer, $stream_flags) = @_;
open_stream(undef,$streamparameters,$sample_rate, $frames_per_buffer, $stream_flags);
}
*open_rw_stream = \&open_stream;
END {
terminate();
}
package Audio::PortAudio::HostAPI;
sub devices {
my ($self) = @_;
my $count = $self->device_count();
return if $count < 1;
return map { $self->device($_) } 0 .. $count - 1;
}
package Audio::PortAudio::Stream;
use Config;
my %closed;
my %started;
my %stream_typesize_in;
my %stream_typesize_out;
my %channels_in;
my %channels_out;
sub DESTROY {
my ($self) = @_;
$self->stop;
delete $stream_typesize_in{$self};
delete $stream_typesize_out{$self};
delete $channels_in{$self};
delete $channels_out{$self};
}
sub start {
my ($self) = @_;
if (!$started{$self}++) {
$self->_start;
}
}
sub stop {
my ($self) = @_;
if ($started{$self}) {
$self->_stop;
delete $started{$self};
}
}
sub close {
my ($self) = @_;
if (!$closed{$self}++) {
$self->_close;
}
$self->stop;
}
my %typesize = (
float32() => 4,
int16() => $Config{u16size},
int32() => $Config{u32size},
int24() => $Config{u32size}, # not sure, but probably
int8() => $Config{charsize},
uint8() => $Config{charsize},
);
my %typevalue = (
float32 => float32(),
int16 => int16(),
int32 => int32(),
int24 => int24(),
int8 => int8(),
uint8 => int8(),
);
sub read {
my ($self, undef, $frames) = @_;
$self->start unless ($started{$self});
$self->_internal_read_stream($_[1],$frames,$stream_typesize_in{$self},$self->input_channels);
}
sub write {
my ($self) = @_;
$self->start unless ($started{$self});
# warn "(buffer),$stream_typesize_out{$self})",$self->output_channels;
$self->_internal_write_stream($_[1],$stream_typesize_out{$self},$self->output_channels);
}
sub input_channels {
$channels_in{$_[0]} || 0;
}
sub output_channels {
$channels_out{$_[0]} || 0;
}
package Audio::PortAudio;
sub open_stream {
my ($iargs,$oargs) = splice @_,0,2;
if ($iargs) {
$iargs->{sample_format} = $typevalue{$iargs->{sample_format} || "float32"} || $iargs->{sample_format};
}
if ($oargs) {
$oargs->{sample_format} = $typevalue{$oargs->{sample_format} || "float32"} || $oargs->{sample_format};
}
my $stream = _open_stream($iargs,$oargs,@_);
$stream_typesize_in{$stream} = $typesize{$iargs->{sample_format}} if $iargs;
$stream_typesize_out{$stream} = $typesize{$oargs->{sample_format}} if $oargs;
$channels_in{$stream} = $iargs->{channel_count} if $iargs;
$channels_out{$stream} = $oargs->{channel_count} if $oargs;
return $stream;
}
package Audio::PortAudio::Device;
sub open_read_stream {
my ($self,$streamparameters, $sample_rate, $frames_per_buffer, $stream_flags) = @_;
$self->open_stream($streamparameters,undef,$sample_rate, $frames_per_buffer, $stream_flags);
}
sub open_write_stream {
my ($self,$streamparameters, $sample_rate, $frames_per_buffer, $stream_flags) = @_;
$self->open_stream(undef,$streamparameters,$sample_rate, $frames_per_buffer, $stream_flags);
}
sub open_stream {
my ($self,$inparameters, $outparameters, $sample_rate, $frames_per_buffer, $stream_flags) = @_;
$inparameters->{device} = $self if $inparameters;
$outparameters->{device} = $self if $outparameters;
Audio::PortAudio::open_stream($inparameters, $outparameters, $sample_rate, $frames_per_buffer, $stream_flags);
}
*open_rw_stream = \&open_stream;
1;