in reply to Playing wav files

I noticed that someone asked a very similar question on StackOverflow earlier in 2012, but I won't post a link to that page. I don't like that site and its rules. It's just a mess. So, let me copy and paste the whole page here:

Playing Sound in Perl script

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:

Is there a better way to call a default sound in Gnome Is that path pretty universal (at least among Debain/Ubuntu flavors) 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!

asked Oct 10 '12 at 19:11

1 Answer

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.)

answered Oct 10 '12 at 20:27

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

--- END OF PAGE ---

Replies are listed 'Best First'.
Re^2: Playing wav files
by merrymonk (Hermit) on Feb 08, 2019 at 15:26 UTC
    Thank you. Something very similar works on my PC for system sounds. This is shown in the Perl below. I get all the same sound except for SystemHand. ..it is other wav files, which I know give different sounds (I can hear these in another application) which seem to be the problem.
    my (@wsn, $js, @wavf); $wsn[0] = 'SystemDefault'; $wsn[1] = 'SystemAsterisk'; $wsn[2] = 'SystemExclamation'; $wsn[3] = 'SystemExit'; $wsn[4] = 'SystemHand'; $wsn[5] = 'SystemQuestion'; $wsn[6] = 'SystemStart'; for($js = 0; $js <= 6; $js++) { print "before play $wsn[$js]\n"; Win32::Sound::Play($wsn[$js]); print "after play\n"; }

      That seems more like a reply to mine rather than the one it actually replied to. if you agree, I will consider it for reparenting. If you really meant it where you put it, sorry for the misunderstanding.

      The goal of my listing of the various System sounds was to ensure that your soundcard and Win32::Sound installation were correct. Which seems to be the case based on this code.

      My other examples -- running sinus.pl, or directly accessing the welcome.wav, while in the Win32::Sound samples/ directory -- was an attempt to make sure that you're really in the directory you think you are, and to make sure you can really get to a local wav file. If you don't want to download the whole tarball, you could run the code from the EXAMPLE portion of Win32::Sound, which will create sinus.wav in your local directory; you can then run perl -MWin32::Sound -e "Win32::Sound::Play('sinus.wav', SND_NODEFAULT)" and it should play, then perl -MWin32::Sound -e "Win32::Sound::Play('sinus.wavx', SND_NODEFAULT)" and it should do no sound at all, because 'sinus.wavx' doesn't exist.