How to play a sound or tone when a program ends?

Hi, I was wondering how to set a julia program to beep or play some tones or music when a long program finally finishes running.

(Googling this question leads to recommendations for old packages, like AudioIO, which aren’t maintained and don’t install properly.)

Thanks!

3 Likes

Probably a little outdated of an answer, but in Tetris.jl I used Howler.js to play a sound:

This was just javascript that got rendered to the page a la:

HTML("""
<script>
  new Howl({
    src: ["pkg/Tetris/tetris-theme.mp3"],
  });
</script>
""")
3 Likes

I need to know how to do this in a julia program running in atom.

You could try Alert.jl, it works pretty well for me!

5 Likes

Thanks but that looks like an alert message printout (which is easy to do anyway). I’m looking for something that plays a sound that I can hear when not looking right at the computer.

This is really basic, but if you’re doing this from the REPL in a terminal, try println("\007").

(Just saw you were using Atom. I don’t know whether this will work there. I confirmed it worked in a REPL on my mac.)

6 Likes

If you’re on a Mac, you can define spoken alerts with this Julia function:

say(what) = run(`osascript -e "say \"$(what)\""`, wait=false)

Then:

say("Finished - you'd better come and take a look....")

If it’s music you’re after, then try:

play() = run(`osascript -e "tell app \"Music\" to play"`, wait=false)

which will resume your music you’ve been playing in iTunes Music. (You’ll have to give permission for this to happen…)

7 Likes

Sbromberger, the sound is nothing fancy, but it does work when executed as a program (not just from the REPL).

Cormullion, thanks, but no Mac, I’m working from 2 Windows computers (one running Win 7.0 and one running Win 10.0).

Ideally, it would be nice to take some interesting mp3 or wav soundclip I could find & download from the web, and play it at when the program ends. For now I’m repeat-playing println("\007") in a while loop.

I am also using Windows (10) and I use a powershell script to accomplish that:

function sound_done()
    script = ```\$sound = New-Object System.Media.SoundPlayer\;
                \$sound.SoundLocation = "<sound file location>"\;
                \$sound.Play\(\)```
    run(`powershell /c $script`)
end

You need to have a wav audio file and then replace <sound file location> with the file location.

1 Like

I just looked it up, you can also use \$sound.PlayLooping\(\) and other commands. You can find the documentation here.

1 Like

Ludwig, I looked at your 2nd suggestion (PlayLooping), and it led to about 10 pages of documentation with no clear examples to try out (not clear to me anyway).

Trying out your first method gives me an error no matter how I try to locate or specify the file. The directory I wanted to put the wav file in had a space in the path, and using quotes or slashes to keep the space in the path name didn’t work. Then I put it in the “home” directory (according to Julia at startup), and it still didn’t work:

function sound_done()
    script = ```\$sound = New-Object System.Media.SoundPlayer\;
                \$sound.SoundLocation = "file_example_WAV_1MG.wav"\;
                \$sound.Play\(\)```
    run(`powershell /c $script`)
end

sound_done()

I get the error:

file_example_WAV_1MG.wav : The term 'file_example_WAV_1MG.wav' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the 
spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:70
+ ... .SoundPlayer; $sound.SoundLocation = file_example_WAV_1MG.wav; $sound ...
+                                          ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (file_example_WAV_1MG.wav:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

That file, "file_example_WAV_1MG.wav", is a sample audio file that plays fine when I click on it in Windows 7.

Actually I DID finally get this working:


function Play_A_Tune(SoundFileName1)
    script = ```\$sound = New-Object System.Media.SoundPlayer\;
                \$sound.SoundLocation = $(SoundFileName1)\;
                \$sound.Play\(\)```
    run(`powershell /c $script`)
end

With a call like:

Play_A_Tune("C:\\JuliaPro\\file_example_WAV_1MG.wav")

But I still can’t get it to run the audio file from a directory path with spaces in it. For example, none of these kinds of things seem to be working:

Play_A_Tune("C:\\Data Area\\Folder\\file_example_WAV_1MG.wav") Play_A_Tune("C:\\Data\ Area\\Folder\\file_example_WAV_1MG.wav") Play_A_Tune("C:\\"Data Area"\\Folder\\file_example_WAV_1MG.wav")

…no matter what I’ve tried.
(It’s possible that one problem may be that my directory path is a really long path name with many subdirectories.)

1 Like

Works on Windows.

4 Likes

Did you try typing raw before the filepath? For example:

Play_A_Tune(raw"C:\\Data Area\\Folder\\file_example_WAV_1MG.wav")

When I want to target a specific file on Windows, I usually Shift+Right Click on the file in Windows Explorer, select Copy as Path, and then paste the path after first typing raw (as above).

1 Like

Hi Joseph M., good idea trying “raw”, I didn’t know about that option, but it didn’t work.

PetrKryslUCSD, I already implemented that, see above.

That doesn’t look right to me. If you have raw"", then you shouldn’t need to do \\ to get a single backslash. As written, this will put literal double backslashes into the path. I’m not sure how Windows handles that.

julia> for character in raw"C:\\Data Area"
         println(character)
       end
C
:
\
\
D
a
t
a
 
A
r
e
a

Edit: unless powershell also needs the \\ to escape the backslashes itself? In which case what you’ve written is probably correct.

Good idea Joseph, but changing the \\ back to \ doesn’t fix it.

Oddly, something like FileName = "C:\\Data Area\\Folder\\file_example_WAV_1MG.wav" IS working for commands like writedlm and readdlm, but NOT for Play_A_Tune here. Strange!

Right, I suspect this is related to spaces in a path with powershell (see this discussion). I think the following will catch Windows folders with and without spaces:

function play_a_tune2(SoundFileName1)
    script = ```\$sound = New-Object System.Media.SoundPlayer\;
                \$sound.SoundLocation = \& \"$SoundFileName1\" \;
                \$sound.Play\(\)```
    run(`powershell /c $script`)
end

I tested this with a .wav file with two paths on my Windows 10 machine:

play_a_tune2("C:\\folder_without_spaces\\elephant.wav")

play_a_tune2("C:\\folder with spaces\\elephant.wav")

I hear an elephant with both function calls. Or I could also be going crazy.

4 Likes

Yes Joseph, that does work in both cases, thanks!

Not sure why you’re hearing elephants though, might want to get your ears checked.

using RCall

beep() = begin
    R"""
      beepr::beep()
    """
end

beep()