=head1 NAME
Audio::Beep - a module to use your computer beeper in fancy ways
=head1 SYNOPSIS
#functional simple way
use Audio::Beep;
beep($freq, $milliseconds);
#OO more musical way
use Audio::Beep;
my $beeper = Audio::Beep->new();
# lilypond subset syntax accepted
# relative notation is the default
# (now correctly implemented)
my $music = "g' f bes' c8 f d4 c8 f d4 bes c g f2";
# Pictures at an Exhibition by Modest Mussorgsky
$beeper->play( $music );
=head1 USAGE
=head2 Exported Functions
=over 4
=item beep([FREQUENCY], [DURATION]);
Plays a customizable beep out of your computer beeper.
FREQUENCY is in Hz. Defaults to 440.
DURATION is in milliseconds. Defaults to 100.
=back
=head2 OO Methods
=over 4
=item Audio::Beep->new([%options])
Returns a new "beeper" object.
Follow the available options for the C<new> method
to be passed in hash fashion.
=back
=over 8
=item player => [player object | player module]
You are free to initialize your player object and then give it to the
Audio::Beep object.
Player objects come from Audio::Beep submodules (like
C<Audio::Beep::Linux::beep>).
If you're lazy (as any good programmer should be)
you can pass a string as a player,
like C<"Audio::Beep::Linux::PP"> or even just C<"Linux::PP">: the method
will prepend the C<Audio::Beep> namespace, require the module and call
the C<new> method on it for you.
The C<new> method will try to look up the best player
on your platform if you don't specify one.
So the following is all valid:
use Audio::Beep;
#super lazy (should do the right thing most of the time)
my $beeper = Audio::Beep->new();
#still lazy
my $beeper2 = Audio::Beep->new(player => 'Linux::PP');
#medium lazy
my $beeper3 = Audio::Beep->new(
player => 'Audio::Beep::Win32::API'
);
#not so lazy, but more versatile
require Audio::Beep::Linux::beep;
my $beeper4 = Audio::Beep->new(
player => Audio::Beep::Linux::beep->new(
path => '/home/foo/bin/beep'
)
);
=item rest => [ms]
Sets the rest in milliseconds between every sound played (and
even pause). This is useful for users which computer beeper has problems
and would just stick to the first sound played.
For example on my PowerbookG3 i have to set this around 120 milliseconds.
In that way i can still hear some music. Otherwise is just a long single beep.
=back
=over 4
=item $beeper->play( $music )
Plays the "music" written in C<$music>.
The accepted format is a subset of L<http://lilypond.org> syntax.
The string is a space separated list of notes to play.
See the L</NOTATION> section below for more info.
=item $beeper->player( [player] )
Sets the player object that will be used to play your music.
See the player option above at the C<new> method for more info.
With no parameter it just gives you back the current player.
=item $beeper->rest( [ms] )
Sets the extra rest between each note.
See the rest option above at the C<new> method for more info.
With no parameter it gives you back the current rest.
=back
=head1 NOTATION
The defaults at start are middle octave C and a quarter length.
Standard notation is the relative notation.
Here is an explanation from Lilypond documentation:
If no octave changing marks are used, the basic interval between
this and the last note is always taken to be a fourth or less
(This distance is determined without regarding alterations;
a fisis following a ceses will be put above the ceses)
The octave changing marks ' and , can be added to raise or lower
the pitch by an extra octave.
You can switch from relative to non relative notation (in which you specify for
every note the octave) using the C<\norel> and C<\rel> commands (see below)
=head2 Notes
Every note has the following structure:
[note][flat|sharp][octave][duration][dots]
NB: previous note duration is used if omitted.
"Flatness", "Sharpness" and "Dottiness" are reset after each note.
=over 4
=item note
A note can be any of [c d e f g a b] or [r] for rest.
=item flat or sharp
A sharp note is produced postponing a "is" to the note itself
(like "cis" for a C#).
A flat note is produced adding a "es" or "s"
(so "aes" and "as" are both an A flat).
=item octave
A ' (apostrophe) raise one octave, while a , (comma) lower it.
=item duration
A duration is expressed with a number.
A 4 is a beat, a 1 is a whole 4/4 measure. Higher the number, shorter the note.
=item dots
You can add dots after the duration number to add half its length.
So a4. is an A note long 1/4 + 1/8 and gis2.. is a G# long 7/8 (1/2 + 1/4 + 1/8)
=item special note: "r"
A r note means a rest. You can still use duration and dots parameters.
=back
=head2 Special Commands
Special commands always begin with a "\". They change the behavior of the
parser or the music played. Unlike in the Lilypond original syntax, these
commands are embedded between notes so they have a slightly different syntax.
=over 4
=item \bpm(\d+)
You can use this option to change the tempo of the music.
The only parameter you can use is a number following the bpm string
(like "\bpm144").
BPM stands for Beats Per Minute.
The default is 120 BPM.
You can also invoke this command as C<\tempo>
=item \norel
Switches the relative mode off. From here afterward you have to always specify
the octave where the note is.
=item \rel
Switches the relative mode on. This is the default.
=item \transpose([',]+)
You can transpose all your music up or down some octave.
' (apostrophe) raise octave. , (comma) lowers it. This has effect just
if you are in non-relative mode.
=back
=head2 Comments
You can embed comments in your music the Perl way. Everything after a #
will be ignored until end of line.
=head2 Music Examples
my $scale = <<'EOS';
\rel \bpm144
c d e f g a b c2. r4 # a scale going up
c b a g f e d c1 # and then down
EOS
my $music = <<'EOM'; # a Smashing Pumpkins tune
\bpm90 \norel \transpose''
d8 a, e a, d a, fis16 d a,8
d a, e a, d a, fis16 d a,8
EOM
my $love_will_tear_us_apart = <<'EOLOVE'; # a happier tune
\bpm160
d'8
e1 fis4 g8 fis4 e8 d4
b2.. d8 a2.. d8
e1 fis4 g8 fis4 e8 d4
b2.. d8 a1
EOLOVE
There should be extra examples in the "music" directory of this tarball.
=head1 EXAMPLES
#a louder beep
perl -MAudio::Beep -ne 'print and beep(550, 1000) if /ERROR/i' logfile
#turn your PC in Hofmann mode (courtesy of Thomas Klausner)
perl -MAudio::Beep -e 'beep(21 + rand 1000, rand 300) while 1'
#your new music player
perl -mAudio::Beep -0777e 'Audio::Beep->new->play(<>)' musicfile
=head1 REQUIREMENTS
=head2 Linux
Requires either the B<beep> program by Johnathan Nightingale
(you should find sources in this tarball) SUID root or you to be root (that's
because we need writing access to the /dev/console device).
If you don't have the B<beep> program this library will also assume some kernel
constants which may vary from kernel to kernel (or not, i'm no kernel expert).
Anyway this was tested on a 2.4.20 kernel compiled for i386 and it worked
with all 2.4 kernel since. It also works with the 2.6 kernel series.
With 2.4 kernels i have problems on my PowerBook G3 (it plays a continous
single beep). See the C<rest> method if you'd like to play something anyway.
=head2 Windows
Requires Windows NT, 2000 or XP and the Win32::API module.
You can find sources on CPAN or you can install it using ActiveState B<ppm>.
No support is available for Windows 95, 98 and ME yet:
that would require some assembler and an XS module.
=head2 BSD
IMPORTANT! This IS NOT TESTED ON BSD! It may work, it may not.
Try it, let me know what you got.
BTW, you need the B<beep> program wrote by Andrew Stevenson.
I found it at L<http://www.freshports.org/audio/beep/> , but
you can even find it at L<http://www.freebsd.org/ports/audio.html>
=head1 BACKEND
If you are a developer interested in having Audio::Beep working on your
platform, you should think about writing a backend module.
A backend module for Beep should offer just a couple of methods:
NB: FREQUENCY is in Hertz. DURATION in milliseconds
=over 4
=item new([%options])
This is kinda obvious. Take in the options you like. Keep the hash fashion
for parameters, thanks.
=item play(FREQUENCY, DURATION)
Plays a single sound.
=item rest(DURATION)
Rests a DURATION amount of time
=back
=head1 TODO
This module works for me, but if someone wants to help here is some cool stuff
to do:
- an XS Windoze backend (look at the Prima project for some useful code)
- test this on BSD (cause it's not tested yet!)
=head1 BUGS
Some of course.
=head1 COPYRIGHT
Copyright 2003-2004 Giulio Motta L<giulienk@cpan.org>.
This library is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
=cut