#!/usr/bin/perl -w # If your Perl implementation resides somewhere other than # /usr/bin/perl, change the above line to reflect that. ## pcmplay -- libao-based raw PCM data player ## Created: ## Time-stamp: ## Author: Alex Shinn =head1 NAME pcmplay - utility to play raw PCM data =head1 SYNOPSIS pcmplay [options] [file1.pcm file2.pcm...] =head1 DESCRIPTION pcmplay is a simple filter for sending raw PCM data to the cross-platform ao audio library. It will read from files specified on the command line, or standard input if no files are specified. To obtain PCM data, check if your audio programs have an option to redirect output to a file. With mpg123 this is the -s option. Included with the Ogg Vorbis library is a sample decoder that generates PCM output. Many mixers and audio programs come with PCM samples. =head1 OPTIONS =over 4 =item -h, --help Print a brief usage message. =item -v, --version Display version info. =item -d, --device DEVICE Add a device to play to. The device may be any of oss, esd, alsa, irix or solaris as the output device, or wav to write to a wav file. You may specify additional options to a device by appending a colon and comma-separated list of key=value pairs. Examples: pcmplay file.pcm -d wav:file=output.wav pcmplay file.pcm -d esd -d alsa:card=0,dev=1 =item -b, --bits BITS Set the number of bits per sample (8 or 16, default 16). =item -r, --rate RATE Set the number of samples per second (default 44100). =item -c, --channels CHANNELS Set the number of channels (1 = mono, 2 = stereo). =item -s, --buffer SIZE Set buffer size (default 4096). =back =cut # Modules use strict; use Getopt::Long; use Ao; # Variables my $VERSION = '0.1'; my %options = ('bits' => 16, 'rate' => 44100, 'channels' => 2, 'buffer' => 4096); my @devices = (); my $buffer; # Parse Options GetOptions(\%options,'help|h|?','version|v','device|dev|d=s@', 'bits|b=i','rate|r=i','channels|c=i','buffer|s=i') or usage(); usage() if $options{help}; version() if $options{version}; # Default to OSS driver $options{device} = ['oss'] unless $options{device}; # Create buffer $buffer = 'x' x $options{buffer}; # Open Devices foreach my $dev (@{$options{device}}) { my $opt_string = ''; my %dev_opts = (); if ($dev =~ /([^:]*):(.*)/) { $dev = $1; $opt_string = $2; %dev_opts = split(/[,=]/, $opt_string); } my $dev_id = Ao::get_driver_id($dev); print "Opening device $dev($dev_id):$opt_string\n"; my $ao = Ao::open($dev_id, $options{bits}, $options{rate}, $options{channels}, \%dev_opts) || die "error: couldn't open device $dev\n"; push @devices, $ao; } # Play each file (or stdin) push @ARGV, '-' unless @ARGV; foreach my $file (@ARGV) { my $len; open(INPUT, "< $file"); while ($len = sysread(INPUT, $buffer, $options{buffer})) { # Play to each device foreach my $ao (@devices) { $ao->play($buffer, $len); } } close(INPUT); } # Close devices foreach my $ao (@devices) { $ao->close(); } # Print a usage summary sub usage { print <