9

I'm trying to add sound to a Perl script to alert the user that the transaction was OK (user may not be looking at the screen all the time while working). I'd like to stay as portable as possible, as the script runs on Windows and Linux stations.
I can

use Win32::Sound;
Win32::Sound::Play('SystemDefault',SND_ASYNC);

for Windows. But I'm not sure how to call a generic sound on Linux (Gnome). So far, I've come up with

system('paplay /usr/share/sounds/gnome/default/alert/sonar.ogg');

But I'm not sure if I can count on that path being available.
So, three questions:

  1. Is there a better way to call a default sound in Gnome
  2. Is that path pretty universal (at least among Debain/Ubuntu flavors)
  3. paplay takes a while to exit after playing a sound, is there a better way to call it?

I'd rather stay away from beeping the system speaker, it sounds awful (this is going to get played a lot) and Ubuntu blacklists the PC Speaker anyway.
Thanks!

charlesbridge
  • 1,172
  • 10
  • 21

1 Answers1

3

A more portable way to get the path to paplay (assuming it's there) might be to use File::Which. Then you could get the path like:

use File::Which;
my $paplay_path = which 'paplay';

And to play the sound asynchronously, you can fork a subprocess:

my $pid = fork;
if ( !$pid ) { 
    # in the child process
    system $paplay_path, '/usr/share/sounds/gnome/default/alert/sonar.ogg';
}

# parent proc continues here

Notice also that I've used the multi-argument form of system; doing so avoids the shell and runs the requested program directly. This avoids dangerous bugs (and is more efficient.)

friedo
  • 65,762
  • 16
  • 114
  • 184
  • I was thinking of `fork`, but I wasn't sure if that would cause more problems being called repeatedly. I'll give it a try. Thanks! – charlesbridge Oct 11 '12 at 11:15
  • Also, I meant the path to a sound file that I can count on being available to play (not `paplay` itself). But I think it's the same idea, I'll just (-R $path) until I find one that works. – charlesbridge Oct 11 '12 at 11:18
  • Also Also, I'm writing this in Perl/Tk. `fork` has to explicitly call `CORE::exit()` or `POSIX::_exit()` or horrible things happen. – charlesbridge Oct 24 '12 at 11:23