# 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;