HOME - - - - - Delphi Tutorials TOC - - - - - - Other material for programmers

Lazarus (Delphi): How To: Make 'beep' or other sound

This has good information, and a search button at the bottom of the page

Please don't dismiss it because it isn't full of graphics, scripts, cookies, etc!

Click here if you want to know more about the source and format of these pages.

((q-alt text for image dt2g-mee-meep.jpg))

Making a beep....

New (November 2021) and improved!


Start a project. Put a button on it. Make the button's OnClick handler do.....


Delphi users: for you, this page is very dated. I was driven from the Delphi fold when the cost of the IDE became high. Try a Google search on "windows.beep". You may, 11/21, need to use winApi.windows.beep in both cases, if Delphi is as before, you need two parameters. More current webpages will set you straight, I'm sure. Another option that looked good was to use the Midi player.

N.B.: The Delphi version of this function was synchronous long ago... a bad thing: it did not return control to its caller until the sound finishes. (So it was unsuitable for make long sounds, e.g. more than a second.)


In Lazarus, a simple beep is simple... Just make the "Test Beep" button execute...

Beep;

I can do that!

Well... when I remember my own advice....

Make sure your sound system is working and turned on before embarking on the following! (Mine wasn't, and it took a little fooling about to get that right.) Go to YouTube or similar. Make sure the sounds you expect to hear are coming out of a "known good" app. (That may seem obvious. But TWICE when working on making sounds, I've wasted time because my sound was not turned on. The apps were sending sounds to the right places... but my sound was either muted, or turned off... which is almost never its state, in my case. Hence the time it took to consider if it was. Mr. Murphy never sleeps. The fact that my sound system is very rarely muted led me to assume things. Assumptions are, of course, often the source of unnecessary problems. But do I ever learn?

Beyond "Beep"

You could consult the "official" wiki.lazarus.freepascal.org documentation, of course! (The link takes you to the right page within it, with answers for many operating systems.) Always start there!

There's a nice thread at forum.lazarus.freepascal.org. (The link will take you into that link.

It started with "How can a make a metronome", which was very nearly what I wanted to do when I revisited this page 11/21. I comment that to you for the several approaches that it would introduce you to.

But I think my own "take" on it all may appeal to some readers.

Something I haven't explored (because it requires a library download), but which looks good.... https://wiki.freepascal.org/Play_Sound_Multiplatform

A Windows-only answer is in...

uses MMSystem;
...

sndPlaySound('C:\sounds\test.wav',
  snd_Async or snd_NoDefault);

You need a small .wav file to play. That "Async" part is important.

By using "Async", all of the processes necessary to cause the sounds will be operating "outside" of the rest of your program. While they are making the sounds, your program can do whatever the code in it calls for.

"Async" is short for "asynchronous", which means "without (being) synchronized.

If you were doing this the "synchronized" way, nothing else of your code would execute until the computer had finished making the sound you wanted made. In some cases, that might be helpful. But I suspect they will be rare.

=============
ARGH! How could what follows have been so difficult???

It has taken me several hours later, but I finally got those simple few lines of code to work! Hours I hope you won't have to spend.

Some notes...

Beware using an old .wav file....

There are ".wav files" and ".wav files".

    WOULD play.... (Specs found with File Explorer: Rt-click/properties/details
    .wav file with bitrate 352k bps  (Size:124kb  Length: 00:00:02  )

    would NOT play... treated as "not found", PlaySound gave the default "ding"...
       .wav file with bitrate 1411 kbps  (Size:238kb  Length:  )
       .m4a file recorded 11/21 with Win10 "Voice Recorder"
       .. but see below

To catch a .wav file...

Of course, Microsoft have phased good old, worked just fine, Sound Recorder out.

11/21: This week's wonder is "Voice Recorder". Took half an hour to get that working...

a) When you click "Record", it can be very slow to start recording. A "time elapsed since recording started" indicator tells you when it has started.
b) Voice Recorder saves things where it wants. And it wants to save them in Documents/Sound Recordings. Whether you want another folder in the root of Documents or not. It does at least set one up, if one doesn't exist.
c) It only records in one format. A new one, of course. .m4a. (And the ways of playing audio files we are discussing here won't play .m4a files, of course.) Happily, .m4a files can be converted to .wav files... ones that are acceptable to PlaySound... with...
https://cloudconvert.com/m4a-to-wav
... which is a free, works-in-browser converter. You don't have to register or anything. The resulting file goes to your browser's normal "downloads" destination when you click "Download".

Going back to the sample code...

If the file you've asked sndPlaySound to play for you, "C:\sounds\test.wav" in the example, isn't present, you get the standard "ding" beep. The same thing happens if the file exists, but isn't acceptable (wrong format, etc... see note above about .wav file bitrates) to PlaySound.

If you give no path to the file, as in...

sndPlaySound('test.wav', snd_Async or snd_NoDefault);

... then PlaySound will look in the folder that the .exe which is running is in.

If you decide to use VLC Player... to test the .wav file you are trying to make PlaySound deliver, be sure to at least stop the VLC Player playing it. If yours is configured as mine is, it will play the sound over and over again otherwise.

Historic moment! I have never before commended a YouTube tutorial. (I much prefer text- with- graphics). But I would not still be sane, had I not found the very well done... of it's kind...

http://www.schoolfreeware.com/Free_Pascal_Lazarus_App_GUI_Tutorial_10.html


Drive yourself loopy?

Sorry. Couldn't resist that.

Suppose you have a .wav file that produces "Warning" (in "speech")? Or makes pretty, new-age, wind-chime tinkles? Or a short burst of the sound of a fire alarm bell?

And you want it to be played over and over?

(If you want "Warning", (slight gap), "Warning", (slight gap), "Warning", (slight gap)... record your "Warning" with a "slight gap's worth" of silence at the end.)

Easy! To get a sound played over and over again...

uses MMSystem;
...

sndPlaySound('C:\sounds\test.wav',0,snd_Async or snd_NoDefault or Snd_Loop););

That should work just find. (Famous last words. DO, by the way, write and "complain" if anything isn't quite right. Think of the future readers you can spare headaches, hassles, heartache! I don't know where I misled you unless you TELL ME. (Contact info at bottom of page.))

Just one little thing... Now that you've started it- How do you STOP it? (I hope the sound in your text file is a nice soothing sound?)

Well, here's the answer. It only took about an hour to get fully right.

For a simple demo, you'll want two buttons... one to start the looped sound, one to stop it.

(In due course, you can put the code behind the buttons into your code wherever it is wanted. I wanted to have a beep-beep-beep start when the temperature coming from a sensor fell below a certain point.)

The code for the second button...

PlaySound('stop.wav',0,snd_Async or snd_NoDefault);

The 'stop.wav' file is just a very short Sound of Silence. (You're supposed to be able to put "Null" in place of the file spec, but I couldn't get that to work.) (Or you might want to have some "Okay, I'll stop" message play, to confirm that the sound has been stopped... as opposed to it stopping because something went wrong.)

------------
Yeah, but...

a) The sound won't stop the instant that you click the "Stop" button. The currently-playing .wav must first play to the end. Now... for most applications that I can see using this code, the .wav file would be very short, so the issue moot. But don't be fooled by "last playback started must play to end" thing while you are de-bugging. And it is just untidy, anyway. So....

------------
More better:

Crude? I don't know. I like simple. And the following works!

As already mentioned, I have two buttons on the form... both of which merely invoke code that (mostly) can be used "internally", if you wish to start/ stop the "beeping" programmatically.

In the buStopLoopedBeep OnClick handler, I change the caption of that button to "Please wait a moment..."

buStopLoopedBeep.caption:='One moment...';{Won't take effect until currently playing .wav plays to end}

Besides that, I created a constant: kbuStopLoopedBeepCaption. I set it to 'Stop Audio Msg'.

I set the button's caption to kbuStopLoopedBeepCaption during OnFormCreate, and again whenever I start the beeping. I.e. as part of what buTestBeep does...

buTestBeep.caption:=kbuStopLoopedBeepCaption;

This cannot be done within what buStopLoopedBeep. If you do it there, it happens "instantly", so you never see the "One moment" message.

See? It isn't(?) as bad to DO as it is to READ ABOUT! (^_^)

Well, I hope not, anyway. However long you spent working through this, I would bet it was less time than discovering what's here and writing it up has taken me! (Please mention the page in suitable places?)

--------
I didn't dig into every implication of the following. Maybe I've missed something good! It is bits from a discussion at stackoverflow.com... the link is longer, takes you to the right place.

The interesting setting is in the third parameter, fdwSound and
  here what is said about SND_LOOP which can be used there:

    SND_LOOP makes the sound play repeatedly until PlaySound
      is called again with the pszSound parameter set to NULL.
      If this flag is set, you must also set the SND_ASYNC flag.

    Note the last sentence. So the proper call would be:

    PlaySound('test.wav', 0, SND_ASYNC or SND_LOOP);

I hope you can see that elements of the above are already in my page. I've even referred to the "NULL" business... even though I couldn't get that to work, and had to use my small but inelegant kludge to end the looping sound. If you can get the elegant solution to work, I'd be grateful for help on that.

--------
One last wrinkle...

It might occur to you to try...

sndPlaySound('the_quick.wav', snd_Async or snd_NoDefault);
sndPlaySound('brown_fox.wav', snd_Async or snd_NoDefault);
sndPlaySound('jumped_over.wav', snd_Async or snd_NoDefault);

I'm sorry to have to tell you that you can't get three .wav files played, one after the other, like that. (You'd only hear the 'jumped_over.wav' file's contents. Sigh.)

Perhaps you can find the "bit" to make that work at the relevant docs.microsoft.com page? (That page documents the Windows PlaySound function.)

I hope so! If you do... please let me know? Contact details at bottom of page. (My thanks to the post at stackoverflow.com/ (a Lazarus region) for putting me onto the Microsoft page, and to Snd_Loop)

Want more? Scraps from an old version of this page are still available, and mention some older alternatives.



To search THIS site....
Click this to search this site without using forms, or just use......
powered by FreeFind
Site search Web search
Be sure to spell the words you are searching for correctly!
The search engine doesn't understand English. Searching for "How do I use repeat" will just return pages with "how", "do", "I", "use", or "repeat".
(Go to my other sites (see bottom of page) and use their search buttons if you want to search them.)...


Click here if you're feeling kind! (Promotes my site via "Top100Borland")
Ad from page's editor: Yes.. I do enjoy compiling these things for you... hope they are helpful. However.. this doesn't pay my bills!!! If you find this stuff useful, (and you run an MS-DOS or Windows computer) please visit my freeware and shareware page, download something, and circulate it for me? Links on your page to this page would also be appreciated!

Click here to visit editor's freeware, shareware page.


Link to Tutorials main page
Here is how you can contact this page's author, Tom Boyd.


Test for valid HTML Page has been tested for compliance with INDUSTRY (not MS-only) standards, using the free, publicly accessible validator at validator.w3.org. It passes in some important ways, but still needs work to fully meet HTML 5 expectations. (If your browser hides your history, you may have to put the page's URL into the validator by hand. Check what page the validator looked at before becoming alarmed by a "not found" or "wrong doctype".)

AND tested for  Test for valid CSS


One last bit of advice: Be sure you know all you need to about spyware.

....... P a g e . . . E n d s .....