Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PlaySound - wav files back to back

31 views
Skip to first unread message

Tundarum

unread,
Mar 25, 2001, 10:42:10 AM3/25/01
to
Peter, I'm sure you've already tried this, but it seems to me that it should
work...here's a very simple possible solution: it seems that simply setting
the button's enabled property to false at the beginning of your ButtonClick
event handler and then back to true at the end of the event should prevent
any event handler from triggering until the event has completed.
begin Forgive me if you've already tried this to no avail.

begin
Button1.enabled:= false;
> PlaySound('SND_ONE', HInstance, SND_NOSTOP or SND_SYNC or SND_RESOURCE);
> Sleep(2000);
> PlaySound('SND_TWO', HInstance, SND_NOSTOP or SND_SYNC or SND_RESOURCE);
> Sleep(2000);
> PlaySound('SND_THREE', HInstance, SND_NOSTOP or SND_SYNC or
SND_RESOURCE);
Button1.enabled:= true;
> end;


"Peter Barrett" <peter-...@talk21.com> wrote in message
news:3abdf0e2_2@dnews...
> Hi,
> I'm encountering some difficulty with PlaySound - specifically with
> playing wav files back to back. Given the following code in a ButtonClick
> event handler :-
>
> begin
> PlaySound('SND_ONE', HInstance, SND_NOSTOP or SND_SYNC or SND_RESOURCE);
> Sleep(2000);
> PlaySound('SND_TWO', HInstance, SND_NOSTOP or SND_SYNC or SND_RESOURCE);
> Sleep(2000);
> PlaySound('SND_THREE', HInstance, SND_NOSTOP or SND_SYNC or
SND_RESOURCE);
> end;
>
> - as you can see the wav files are extracted from a res file with a 2 sec
> gap between. This works fine unless the user clicks the button more than
> once, in which case the 3 sounds play as many times as the user clicks the
> button EVEN if the sounds are already playing. I expected (wrongly) that
use
> of the SND_SYNC flag would cure this by not returning user control to the
> button (which it does visually - ie. the button doesn't appear to press)
but
> obviously the onClick event handler is still triggered. I want to make
sure
> the 3 sounds can't be played again until they are finished and the button
> can be pressed.
> I've tried to write code to test if the event handler is operating using
a
> boolean test but it has always not worked, it seems as the PlaySounds are
> all queued up right from the beginning. My books and the delphi help files
> are a bit light on things audio. Could anybody help me sort this please.
> Thanks in anticipation.
>
> Peter B.
>
>
>


Peter Barrett

unread,
Mar 25, 2001, 8:19:50 AM3/25/01
to

Peter Barrett

unread,
Mar 25, 2001, 4:34:09 PM3/25/01
to
Tundarum,
Yes, I'm afraid you're correct. I have already tried this(disabling the
button). Unfortunately the effect remains exactly as per the original posted
message. Thanks anyhow. Anybody have any more ideas please ?

Peter B.

William Meyer

unread,
Mar 26, 2001, 9:21:15 AM3/26/01
to
"Peter Barrett" <peter-...@talk21.com> wrote in message
news:3abdf0e2_2@dnews...

> I'm encountering some difficulty with PlaySound - specifically with


> playing wav files back to back. Given the following code in a ButtonClick
> event handler :-
>

> - as you can see the wav files are extracted from a res file with a 2 sec
> gap between. This works fine unless the user clicks the button more than
> once, in which case the 3 sounds play as many times as the user clicks the
> button EVEN if the sounds are already playing. I expected (wrongly) that
use
> of the SND_SYNC flag would cure this by not returning user control to the
> button (which it does visually - ie. the button doesn't appear to press)
but
> obviously the onClick event handler is still triggered. I want to make
sure
> the 3 sounds can't be played again until they are finished and the button
> can be pressed.

Let the first action of the button be to disable the button. Then you have
to re-enable when the sounds have finished playing.

Bill


William Meyer

unread,
Mar 26, 2001, 9:22:18 AM3/26/01
to
"Peter Barrett" <peter-...@talk21.com> wrote in message
news:3abe6460_2@dnews...

This makes no sense. If the button is disabled, it can't process messages.

Bill


Chris Willig

unread,
Mar 26, 2001, 5:05:00 AM3/26/01
to
Have you tried:

Button.Enabled := false;
{play sounds}
Application.ProcessMessages; // flush the msgs
Button.Enabled := true;

Peter Barrett

unread,
Mar 26, 2001, 4:25:55 PM3/26/01
to
Bill,
Thanks for the suggestion. I already tried this (initial action to disable
button in the onClick event handler) fairly early in my exploration of this
little problem - it doesn't work as you might think. I've also set up a
conditional test to check it the button is enabled, if it is then process
playsounds if not skip them. Even that doesn't work ! Chris Willig's
suggestion of using Application.ProcessMessages was tried - to no avail
though (have to say this is similar to use of SND_ASYNC flag). Any further
suggestions gratefully received - at present I can't see a way round this
I'm sure a solution must lurk deep in the bowels of Windows - somewhere.

Peter B.

"William Meyer" <wme...@earthlink.net> wrote in message
news:3abf504a_2@dnews...

William Meyer

unread,
Mar 26, 2001, 5:25:14 PM3/26/01
to
"Peter Barrett" <peter-...@talk21.com> wrote in message
news:3abfb3f5_1@dnews...

> Thanks for the suggestion. I already tried this (initial action to
disable
> button in the onClick event handler) fairly early in my exploration of
this
> little problem - it doesn't work as you might think.

If the button is disabled, it *cannot* react to additional mouse clicks.

Bill


Peter Barrett

unread,
Mar 26, 2001, 5:41:16 PM3/26/01
to
Bill
It *does* trigger the onClick event handler even when disabled. At the
moment I'm trying to determine if incorporating wav files into a resource
instead of reading them directly is perhaps an issue. I know what the
behaviour of the button should be - in this case it isn't.

Peter B.

"William Meyer" <wme...@earthlink.net> wrote in message

news:3abfc1b5$1_2@dnews...

Chris Willig

unread,
Mar 26, 2001, 6:36:21 PM3/26/01
to
This is overkill but...

procedure Button1Click(Sender: TObject);
begin
Button1.OnClick := nil;
try


finally
Application.ProcessMessages;
Button1.OnClick := Button1Click;
end;
end;

Krasimir Stoyanov

unread,
Mar 27, 2001, 5:36:03 AM3/27/01
to
Peter Barrett wrote:

> Hi,


> - as you can see the wav files are extracted from a res file with a 2 sec
> gap between. This works fine unless the user clicks the button more than
> once, in which case the 3 sounds play as many times as the user clicks the
> button EVEN if the sounds are already playing.

Because the mouse messages are buffered in the message queue, you can use:

Button1.Enabled:=false;
try
bla bla bla
finally
Application.ProcessMessages; // or PeekMessage to remove mouse clicks
button1.Enabled:=true
end;

or something similar.


Peter Barrett

unread,
Mar 27, 2001, 3:38:08 PM3/27/01
to
Krasimir,
Thanks for this but I'm afraid we've already proven that it doesn't work.
See previous posts.
My thanks to Chris Willig, setting the OnClick event handler to nil and
coding in a try/finally
block *DOES* work - it is positively the only thing found so far which
does, heavy I know but ...

Thats about it folks - thanks to everyone who participated in this.

Peter B.

"Krasimir Stoyanov" <kras...@writeme.com> wrote in message
news:3AC06D13...@writeme.com...

William Meyer

unread,
Mar 27, 2001, 6:06:15 PM3/27/01
to
"Peter Barrett" <peter-...@talk21.com> wrote in message
news:3ac0fa42_2@dnews...

> Thanks for this but I'm afraid we've already proven that it doesn't
work.
> See previous posts.
> My thanks to Chris Willig, setting the OnClick event handler to nil and
> coding in a try/finally
> block *DOES* work - it is positively the only thing found so far which
> does, heavy I know but ...

Peter, since I have used the button.enabled property for years with no
;problems, and since I have just recently been bitten by a side-effect in a
test program which does not relate to a button, but to the interactions
which we can create, I have to ask whether there is *any* possibility that
something else in your code invokes the buttonClick code. If so, that would
explain why disabling the button does not work, as the code is accessible to
*other* code, whether the button is enabled or not.

Bill


Peter Barrett

unread,
Mar 29, 2001, 5:39:24 AM3/29/01
to
Bill,
I know what I 've posted goes against pretty rational thinking but I can
only post what actually
occurs under the circumstances prevailing. The interference from other code
is obviously a very valid point but in this case I was simply using one
form, one button, one onclick event handler coded schematically as follows
:-
Button.Enabled := false;
PlaySound(x1);
Sleep(n);
PlaySound(x1);
Sleep(n);
PlaySound(x3);
Button.Enabled := true;
- it really was all I did and was simply a tiny test project for a bigger
program. Given your fair interest in this matter, would you like to emulate
this code to see if you can reproduce the effect ?. Remember the wave files
are extracted from a resource file though.
best regards
Peter B.

"William Meyer" <wme...@earthlink.net> wrote in message

news:3ac11cce_2@dnews...

David Taylor

unread,
Mar 29, 2001, 6:05:16 AM3/29/01
to
Would a semaphore work (not sure if that's the correct term)? I.e.

const
active: boolean = False;

begin
if active then Exit;
active := True;
.
.
.
active := False;
end;


"Peter Barrett" <peter-...@talk21.com> wrote in message

news:3ac310ee$1_2@dnews...


Peter Barrett

unread,
Mar 30, 2001, 5:39:05 PM3/30/01
to
David,
Thanks, I tried this but I'm afraid it doesn't work. Chris Willig's
solution remains the only operable one.
Peter B.

"David Taylor" <david.j...@baesystems.com> wrote in message
news:3ac316f1_2@dnews...

William Meyer

unread,
Mar 30, 2001, 5:44:15 PM3/30/01
to
"Peter Barrett" <peter-...@talk21.com> wrote in message
news:3ac310ee$1_2@dnews...

> I know what I 've posted goes against pretty rational thinking but I can
> only post what actually
> occurs under the circumstances prevailing. The interference from other
code
> is obviously a very valid point but in this case I was simply using one
> form, one button, one onclick event handler coded schematically as follows

Ito does, indeed, but having tripped myself up in the past, I had to ask
<g>.

> - it really was all I did and was simply a tiny test project for a bigger
> program. Given your fair interest in this matter, would you like to
emulate
> this code to see if you can reproduce the effect ?. Remember the wave
files
> are extracted from a resource file though.

I've been swamped the last few days with a push toward a release deadline,
and haven't had the chance (or energy) to dive into this. The biggest
impediment for me is putting the wav viles into a resource, as it's simply
not something I have done before. If you can tell me, in a few words, how to
do it, I can give this a try on the weekend.

Bill


Peter Barrett

unread,
Mar 31, 2001, 9:21:23 AM3/31/01
to
Bill,
Incorporate a resource file as follows :-
1. Using a trusty old text editor (one that doesn't litter the text with
any formatting characters)
create a text file mysounds.RC with this format
SOUND_1 WAVE Path to wave file 1
SOUND_2 WAVE Path to wave file 2
SOUND_3 WAVE Path to wave file 3
and so on.
2. Using the Borland resource compiler from the command line
brcc32 mysounds.RC
this compiles to mysounds.RES
3. Place the compiler directive {$R mysounds.RES} into your Delphi unit
between the uses and type declarations.
Have a good weekend !

Peter B.

"William Meyer" <wme...@earthlink.net> wrote in message

news:3ac50c15_2@dnews...

William Meyer

unread,
Apr 1, 2001, 5:39:37 AM4/1/01
to
"Peter Barrett" <peter-...@talk21.com> wrote in message
news:3ac5e88e_2@dnews...

> Incorporate a resource file as follows :-
> 1. Using a trusty old text editor (one that doesn't litter the text with
> any formatting characters)
> create a text file mysounds.RC with this format
> SOUND_1 WAVE Path to wave file 1
> SOUND_2 WAVE Path to wave file 2
> SOUND_3 WAVE Path to wave file 3
> and so on.

Did that.

> 2. Using the Borland resource compiler from the command line
> brcc32 mysounds.RC
> this compiles to mysounds.RES

And that.

> 3. Place the compiler directive {$R mysounds.RES} into your Delphi unit
> between the uses and type declarations.

Now, having added mmsystem to my uses clause, cannot satisfy the compiler.
What is the magic, here, wrt the argument, in making access to a wav in the
resource? This is something I've not done before, as the wav files I needed
to play were always external. I'll be glad to help, and to invest some time,
but preferably on the debug side, not on the discovery of how to duplicate
the setup.

Bill

Peter Barrett

unread,
Apr 1, 2001, 2:22:02 PM4/1/01
to
Bill,
Try :-
PlaySound('SOUND_1', HInstance, SND_SYNC or SND_RESOURCE);

BTW the or does not indicate an option.

Peter B.

"William Meyer" <wme...@earthlink.net> wrote in message

news:3ac6f72a_1@dnews...

Krasimir Stoyanov

unread,
Apr 1, 2001, 4:49:27 PM4/1/01
to
Peter Barrett wrote:

> David,
> Thanks, I tried this but I'm afraid it doesn't work. Chris Willig's
> solution remains the only operable one.

Why don't you use Application.ProcessMessages? This is ESSENTIAL. It will make all
solutions work, including using Enabled property.


William Meyer

unread,
Apr 1, 2001, 8:27:33 PM4/1/01
to
"Peter Barrett" <peter-...@talk21.com> wrote in message
news:3ac771e6_1@dnews...

> Bill,
> Try :-
> PlaySound('SOUND_1', HInstance, SND_SYNC or SND_RESOURCE);
>

Interesting. My results duplicate yours, but I don't yet understand the
mechanism which is at work here.

Bill


Peter Barrett

unread,
Apr 2, 2001, 7:47:19 AM4/2/01
to
Krasimir,
Yes, that is correct and was established in a previous thread. Please see
Chris Willig's solution.
Peter B.

"Krasimir Stoyanov" <kras...@writeme.com> wrote in message

news:3AC79457...@writeme.com...

Peter Barrett

unread,
Apr 2, 2001, 7:57:03 AM4/2/01
to
Bill,
Glad I'm not alone !
I don't know the answer to this, if I ever find out, I'll let you know -
please reciprocate.
I suspect it's to do as I said originally with the way in which extraction
from the resource is handled by Windows but this is out of my depth and
requires a bit of guru deliberation. Any offers. Some have said, quite
fairly, use Application.ProcessMessages, set the event handler to nil etc.
which is fine but it's as Chris Willig said, bludgeoning code. I would
simply like to know why it behaves like this and possibly employ a more
subtle solution.
My thanks to all who have participated in this debate.
regards
Peter B.

"William Meyer" <wme...@earthlink.net> wrote in message

news:3ac7c740$1_2@dnews...

Krasimir Stoyanov

unread,
Apr 2, 2001, 4:22:57 PM4/2/01
to
Peter Barrett wrote:

> Krasimir,
> Yes, that is correct and was established in a previous thread. Please see

> Chris Willig's solution.

And when you use the code below it behaves differently than his solution? What is
the OS version and is the button a standard TButton?

Button1.Enabled:=false;
try

finally
Application.ProcessMessages;
Button1.Enabled:=true
end

Peter Barrett

unread,
Apr 2, 2001, 4:36:13 PM4/2/01
to
Krasimir
Win 98 SE 4.10.2222A in use. Yes it does behave differently and it is a
standard TButton. Please note that Bill Meyer has emulated this and that IMO
it is to do with extraction and buffering from a resource file but I don't
know why exactly.

Peter B..

"Krasimir Stoyanov" <kras...@writeme.com> wrote in message

news:3AC8DFA1...@writeme.com...

William Meyer

unread,
Apr 2, 2001, 5:40:02 PM4/2/01
to
"Peter Barrett" <peter-...@talk21.com> wrote in message
news:3ac8e2d0_1@dnews...

> Krasimir
> Win 98 SE 4.10.2222A in use. Yes it does behave differently and it is a
> standard TButton. Please note that Bill Meyer has emulated this and that
IMO
> it is to do with extraction and buffering from a resource file but I don't
> know why exactly.

Also note that my results were obtained under Win2K. I also tried using a
separate global boolean in place of the button status, setting it true in
the onclick, and false at the end of play, and then testing the boolean in
the onclick, and if true, doing an Exit. That did not work.

It is is though the code had all executed before the sounds played, but the
repaint of the button was held off until the end of the sounds. Very
strange.

Bill


ozbear

unread,
Apr 3, 2001, 6:13:16 AM4/3/01
to
Peter...

have you tried the sequence...
button.Enabled := False;
Application.ProcessMessages;
<all the playsounds/sleeps>
button.Enabled := True;

In otherwords, disabling the button but calling
Application.Processmessage immediately -after- the
disablement so the disable message can be processed.

The other disablement solutions I've read in the thread
were doing the Application.ProcessMessages -after- the
calls to Playsnd/Sleep, not before (unless I missed one).

Regards, Oz

Peter Barrett

unread,
Apr 3, 2001, 3:36:10 PM4/3/01
to
Oz,
Many thanks for this but I'm afraid it again does not work as you might
expect. Even with the button disabled and App.ProcMsgs called immediately
after disablement you can click the button and invoke the PlaySound calls as
many times as you click the button. If you go back through the threads,

Chris Willig's solution remains the only operable one.

best regards
Peter B.

"ozbear" <ozb...@bigpond.com> wrote in message
news:3ac9a179....@newsgroups.borland.com...

William Meyer

unread,
Apr 3, 2001, 4:36:20 PM4/3/01
to
"Peter Barrett" <peter-...@talk21.com> wrote in message
news:3aca263f_1@dnews...

> If you go back through the threads,
> Chris Willig's solution remains the only operable one.

Might be interesting to post a note on b.p.d.components.using with a heading
about button.enabled not working, and see if one of the heavywiehgt gurus
responds.

Bill


Krasimir Stoyanov

unread,
Apr 3, 2001, 5:45:49 PM4/3/01
to
William Meyer wrote:

> Might be interesting to post a note on b.p.d.components.using with a heading
> about button.enabled not working, and see if one of the heavywiehgt gurus
> responds.

Still, why don't you send me the code in question? The resource file and the
simple form with TButton on it?


William Meyer

unread,
Apr 3, 2001, 7:25:44 PM4/3/01
to
"Krasimir Stoyanov" <kras...@writeme.com> wrote in message
news:3ACA448D...@writeme.com...

>
> Still, why don't you send me the code in question? The resource file and
the
> simple form with TButton on it?

I did, by e-mail to you directly.

Bill


Krasimir Stoyanov

unread,
Apr 4, 2001, 5:29:11 AM4/4/01
to
I used your program and changed it to:

Button1.Enabled:=false;


PlaySound('SOUND_1', HInstance, SND_SYNC or SND_RESOURCE);

Sleep(1);
PlaySound('SOUND_2', HInstance, SND_SYNC or SND_RESOURCE);
Sleep(1);
PlaySound('SOUND_3', HInstance, SND_SYNC or SND_RESOURCE);
Sleep(1);
Application.ProcessMessages;
Button1.Enabled:=true

It works without problem! The button is disabled and no matter how many times the
user
clicks it while playing, the sounds are not replayed.


William Meyer

unread,
Apr 4, 2001, 12:55:02 PM4/4/01
to
"Krasimir Stoyanov" <kras...@writeme.com> wrote in message
news:3ACAE967...@writeme.com...

>
> It works without problem! The button is disabled and no matter how many
times the
> user
> clicks it while playing, the sounds are not replayed.

Interesting. I wonder why Sleep() makes it work.... and what made you think
to try that?

Bill


Krasimir Stoyanov

unread,
Apr 4, 2001, 2:25:55 PM4/4/01
to
William Meyer wrote:

> Interesting. I wonder why Sleep() makes it work.... and what made you think
> to try that?

You are very absent minded, the Sleep() calls were in the code that you sent me,
they make no difference, you can delete them.

The one thing that makes it work is Application.ProcessMessages, as I already
said.
But it MUST be immediately before Button.Enabled:=true, or Playing:=false, or
OnClick:=Button1Click, depending on which way you choose. Button
enabling/disabling is the best way according to me, it works fine and gives the
user visual feedback.

William Meyer

unread,
Apr 4, 2001, 3:24:17 PM4/4/01
to
"Krasimir Stoyanov" <kras...@writeme.com> wrote in message
news:3ACB6733...@writeme.com...

>
> You are very absent minded, the Sleep() calls were in the code that you
sent me,
> they make no difference, you can delete them.

No, just preparing for a trade show, and juggling too many tasks <g>.

> The one thing that makes it work is Application.ProcessMessages, as I
already
> said.
> But it MUST be immediately before Button.Enabled:=true, or Playing:=false,
or
> OnClick:=Button1Click, depending on which way you choose. Button
> enabling/disabling is the best way according to me, it works fine and
gives the
> user visual feedback.

Weird. And makes no sense to me, as putting it *before* the button state
change would seem to be the wrong thing.

Bill


Krasimir Stoyanov

unread,
Apr 4, 2001, 5:13:58 PM4/4/01
to
William Meyer wrote:

> Weird. And makes no sense to me, as putting it *before* the button state
> change would seem to be the wrong thing.

It is the right thing, you want the button to ignore the clicks, right?
So you want to process the mouse messages when the button is disabled, effectively
ignoring them.
Then, when there are no more messages, you enable the button.


Chris Willig

unread,
Apr 4, 2001, 7:51:27 PM4/4/01
to
Subject: Re: PlaySound - wav files back to back
Date: Mon, 26 Mar 2001 04:05:00 -0600
From: Chris Willig <ch...@5thelephant.com>
Newsgroups: borland.public.delphi.winapi
References: 1 , 2 , 3

Have you tried:

Button.Enabled := false;
{play sounds}
Application.ProcessMessages; // flush the msgs
Button.Enabled := true;

Krasimir Stoyanov

unread,
Apr 4, 2001, 11:40:09 PM4/4/01
to
Chris Willig wrote:

> Have you tried:
>
> Button.Enabled := false;
> {play sounds}
> Application.ProcessMessages; // flush the msgs
> Button.Enabled := true;

Yes, and it works as expected, but I am trying to convince the others :-)


0 new messages