Solved

Playing WAV files

Posted on 1998-10-22
23
399 Views
Last Modified: 2010-04-06
How can I play a wav file, and make and event-handler
 so when the wav has finished playing i can play another ?

bryan
0
Comment
Question by:bryan7
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 10
  • 7
  • 5
  • +1
23 Comments
 
LVL 8

Expert Comment

by:ZifNab
ID: 1343895
Hi bryan7,

Use TMediaPlayer with its TNotify Event.

procedure TForm1.MediaPlayer1Notify(Sender: TObject);

begin
  with Sender as TMediaPlayer do
  begin
    If Mode = mpStopped then {start new wav}
    { Note we must reset the Notify property to True }
    { so that we are notified the next time the }
    { mode changes }
    Notify := True;
  end;
end;

Regards, Zif.
0
 
LVL 3

Author Comment

by:bryan7
ID: 1343896
but, how do I play, stop, etc.. the wav files ?

bryan

0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1343897
bryan7,

 with the TMediaplayer!

 Or am I missing something?

Zif.
0
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 8

Expert Comment

by:ZifNab
ID: 1343898
here is an example from Delphi help :

procedure TForm1.FormActivate(Sender: TObject);

var
  WinDir: PChar;
begin
  MediaPlayer1.Visible := False;
  GetMem(WinDir, 144);
  GetWindowsDirectory(WinDir, 144);
  StrCat(WinDir, '\chimes.wav');
  MediaPlayer1.FileName := StrPas(WinDir);
  MediaPlayer1.Open;
  FreeMem(WinDir, 144);
  Button1.Caption := 'Play';

end;

procedure TForm1.Button1Click(Sender: TObject);

begin
  if Button1.Caption = 'Play' then
  begin
    Button1.Caption := 'Pause';
    MediaPlayer1.Play;
  end
  else
  begin
    Button1.Caption := 'Play';
    MediaPlayer1.Pause;
  end;

end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if MediaPlayer1.Mode = mpStopped then
    Button1.Caption := 'Play';
end;

Zif.
0
 
LVL 3

Author Comment

by:bryan7
ID: 1343899
Well, I've never used it..
I found a way to play it: ( on an answered question from somebody else )

  MediaPlayer1.FileName := 'C:\WINDOWS\MEDIA\CHIMES.WAV';
  MediaPlayer1.Open;
  MediaPlayer1.Play;

ok, this works,
but, why doesn't this: ?

PlaySound(PChar('The path'), 0, snd_Async);  

bryan

0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1343900
Sorry, never heard of PlaySound sorry. Zif.
0
 
LVL 3

Author Comment

by:bryan7
ID: 1343901
Which should I use ?

The one with TNotify, or th other one with a timer ?
( both work alright )

bryan
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343902
you can use PLaySound() as follows....

PlaySound('C:\windows\desktop\test.wav', 0, snd_Async);

which works for sure... By the way have you added MMSystems to your uses clause... I believe it was MMSystems/or was it MMSystem???

Don;t exactly remember...
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1343903
bryan7, better use notify event.
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343904
Zif is right.,, I just wanted to point out how to use the PlaySound() function ;->

Cheers,
Viktor
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1343905
Hi viktor,

 wasn't pointing at you with my last comment (just answered bryans last question). Thanks for letting me no of PlaySound!

Zif

0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343906
Anyway, I still think the Notify event is better than the PlaySound() procedure :-)

Cheers,
Viktor
0
 
LVL 3

Author Comment

by:bryan7
ID: 1343907
delphi says: "Undeclared Identifier: Playsound"

Zifnab, choose"answer" so you can get the points.

bryan

0
 
LVL 8

Accepted Solution

by:
ZifNab earned 10 total points
ID: 1343908
thanks bryan.

Have fun with the TMediaPlayer.

Zif.
0
 
LVL 2

Expert Comment

by:Thaddy
ID: 1343909
This records and plays *without* the mediaplayer:

unit Echo1;
{Code by Darryl Gove 27/8/97}
{D.J.Gove@open.ac.uk}

interface

uses
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  Forms, Dialogs, mmsystem;

const
     {The larger the size of the block the fewer blocks recorded}
     {per second and therefore the longer the delay between}
     {recording and playback}
     memBlockLength = 500;
     {500 bytes at 11k/sec = delay of 500/11000 of a second}
     {roughly a 20th}

type
    Tmemblock = array[0..memblocklength] of byte;
    PmemBlock = ^TmemBlock;

    TForm1 = class(TForm)
             procedure FormCreate(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
           private
             { Private declarations }
             HwaveIn:PHWaveIn;
             HWaveOut:PHWaveOut;
             close_invoked,close_complete:boolean;
             in_count,out_count:integer;
             procedure MMOutDone(var msg:Tmessage);message MM_WOM_DONE;
             procedure MMInDone(var msg:Tmessage);message MM_WIM_DATA;
           public
             { Public declarations }
           end;

var
   Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
var
   WaveFormat:PPCMWaveFormat;
   Header:PWaveHdr;
   memBlock:PmemBlock;
   i,j:integer;
begin
     WaveFormat:=new(PPCMwaveFormat);
     with WaveFormat^.wf do
     begin
          WFormatTag := WAVE_FORMAT_PCM; {PCM format - the only option!}
          NChannels:=1; {mono}
          NSamplesPerSec:=11000; {11kHz sampling}
          NAvgBytesPerSec:=11000; {we aim to use 8 bit sound so only 11k per second}
          NBlockAlign:=1; {only one byte in each sample}
          waveformat^.wBitsPerSample:=8; {8 bits in each sample}
     end;
     i:=waveOutOpen(nil,0,PWaveFormat(WaveFormat),0,0,WAVE_FORMAT_QUERY);
     if i<>0 then application.messagebox('Error', 'Play format not supported', mb_OK);

     i:=waveInOpen(nil,0,PWaveFormat(WaveFormat),0,0,WAVE_FORMAT_QUERY);
     if i<>0 then application.messagebox('Error', 'Record format not supported', mb_OK);

     HwaveOut:=new(PHwaveOut);
i:=waveOutOpen(HWaveOut,0,Pwaveformat(WaveFormat),form1.handle,0,CALLBACK_WINDOW);
     if i<>0 then application.messagebox('Error', 'Problem creating play handle', mb_OK);

     HwaveIn:=new(PHwaveIn);
     i:=waveInOpen(HWaveIn,0,Pwaveformat(WaveFormat),form1.handle,0,CALLBACK_WINDOW);
     if i<>0 then application.messagebox('Error', 'Problem creating record handle', mb_OK);


     {these are the count of the number of blocks sent to}
     {the audio device}
     in_count:=0;
     out_count:=0;

     {need to add some buffers to the recording queue}
     {in case the messages that blocks have been recorded}
     {are delayed}
     for j:= 1 to 3 do
     begin
          {make a new block}
          Header:=new(PWaveHdr);
          memBlock:=new(PmemBlock);

          Header:=new(PwaveHdr);
          with header^ do
          begin
               lpdata:=pointer(memBlock);
               dwbufferlength:=memblocklength;
               dwbytesrecorded:=0;
               dwUser:=0;
               dwflags:=0;
               dwloops:=0;
          end;

          {prepare the new block}
          i:=waveInPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr));
          if i<>0 then application.messagebox('In Prepare error','error',mb_ok);

          {add it to the buffer}
          i:=waveInAddBuffer(HWaveIn^,Header,sizeof(TWaveHdr));
          if i<>0 then application.messagebox('Add buffer error','error',mb_ok);

          inc(in_count);

     end; {of loop}

     {finally start recording}
     i:=waveInStart(HwaveIn^);
     if i<>0 then application.messagebox('Start error','error',mb_ok);

     close_invoked:=false;
     close_complete:=false;
end;

procedure TForm1.MMOutDone(var msg:Tmessage);
var
   Header:PWaveHdr;
   i:integer;
begin
     dec(out_count);
     {get the returned header}
     Header:=PWaveHdr(msg.lparam);
     i:=waveOutUnPrepareHeader(HWaveOut^,Header,sizeof(TWavehdr));
     if i<>0 then application.messagebox('Out Un Prepare error','error',mb_ok);


     {free the memory}
     dispose(Header^.lpdata);
     dispose(Header);

     {if there's no more blocks being recorded}
     if (out_count=0) then
     begin
          WaveOutClose(HWaveOut^);
          HwaveOut:=nil;
     end;

     {if there's nothing more to do then close}
     if (in_count=0) and (out_count=0) then
     begin
          close_complete:=true;
          close;
     end;

end;

procedure TForm1.MMInDone(var msg:Tmessage);
var
   Header:PWaveHdr;
   memBlock:PmemBlock;
   i:integer;
begin
     dec(in_count);
     {block has been recorded}
     Header:=PWaveHdr(msg.lparam);
     i:=waveInUnPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr));
     if i<>0 then application.messagebox('In Un Prepare error','error',mb_ok);

     if not(close_invoked) then
     begin
          {prepare it for play back}
          i:=waveOutPrepareHeader(HWaveOut^,Header,sizeof(TWavehdr));
          if i<>0 then application.messagebox('Out Prepare error','error',mb_ok);

          {add it to the playback queue}
          i:=waveOutWrite(HWaveOut^,Header,sizeof(TWaveHdr));
          if i<>0 then application.messagebox('Wave out error','error',mb_ok);

          inc(out_count);

          {make a new block}
          Header:=new(PWaveHdr);
          memBlock:=new(PmemBlock);

          Header:=new(PwaveHdr);
          with header^ do
          begin
               lpdata:=pointer(memBlock);
               dwbufferlength:=memblocklength;
               dwbytesrecorded:=0;
               dwUser:=0;
               dwflags:=0;
               dwloops:=0;
          end;

          {prepare the new block}
          i:=waveInPrepareHeader(HWaveIn^,Header,sizeof(TWavehdr));
          if i<>0 then application.messagebox('In Prepare error','error',mb_ok);

          {add it to the buffer}
          i:=waveInAddBuffer(HWaveIn^,Header,sizeof(TWaveHdr));
          if i<>0 then application.messagebox('Add buffer error','error',mb_ok);

          inc(in_count);
     end;

     {if there's no more blocks being recorded}
     if (in_count=0) then
     begin
          WaveInClose(HWaveIn);
          HwaveIn:=nil;
     end;

     {if there's nothing more to do then close}
     if (in_count=0) and (out_count=0) then
     begin
          close_complete:=true;
          close;
     end;
end;



procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
     {reset the output channel}
     if HWaveOut<>nil then WaveOutReset(HWaveOut^);

     {reset the input channel}
     if HwaveIn<>nil then WaveInReset(HWaveIn^);
     close_invoked:=true;
     canclose:=close_complete;
end;

end.



0
 
LVL 3

Author Comment

by:bryan7
ID: 1343910
Hey Thaddy..  wow.. what a unit.. thanx, I tried to run it, but I got this error:

Incompatible types: 'TWaveFormat' and 'TWaveFormatEx'

at this line:

i:=waveOutOpen(nil,0,PWaveFormat(WaveFormat),0,0,WAVE_FORMAT_QUERY);

bryan ( hold on, zif, I'd like to know about this unit from Thaddy )

0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1343911
No prob bryan7

I guess the problem of the unit above is the version.... nowadays TWaveFormatEx is used instead of TWaveFormat. So you've to change some things to get these older units working on a newer version of Delphi.

Zif.
0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343912
Why don't you guys try using

Windows

in your uses clause instead of

WinProcs, WinTypes....

That might solve ther problem....
0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1343913
hi viktor,

 I don't think it's a library problem. I had this problem also ones and it is the problem that one function changed. It now needs TWaveFormatEx... The error bryan7 gets is also that the type is wrong, not that it doesn't knows the type.

PS. Why not making the TMediaplayer invisible if you don't want to let it see. Or use the mciSendCommand... that's how TMediaplayer itself does it (look at it's source).

Regards, Zif.
0
 
LVL 3

Author Comment

by:bryan7
ID: 1343914
I already set the TMediaPlayer invisible.

The source code ? where's the source code of the components ?

Viktornet: what do u mean "windows" in stead of "Winprocs, wintypes.." ?
is "windows" a lib containing all the default libs ?

bryan

0
 
LVL 10

Expert Comment

by:viktornet
ID: 1343915
Nevermind..... Zif is probably right... Ok, what you could do is to try to typecast the one to the other.,,,,
.......TWaveFormatEx(TheVariableDeclared).........;

Cheers,
Viktor

0
 
LVL 8

Expert Comment

by:ZifNab
ID: 1343916
Hi bryan7,

you've the sources when you've Delphi Professional edition.

They are at the delphi directory :

 ..\source\vcl\mplayer.pas
 ..\source\win\mmsystem.pas

regards, Zif.
0
 
LVL 3

Author Comment

by:bryan7
ID: 1343917
ok, thanx ya all.

bryan

0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This video Micro Tutorial shows how to password-protect PDF files with free software. Many software products can do this, such as Adobe Acrobat (but not Adobe Reader), Nuance PaperPort, and Nuance Power PDF, but they are not free products. This vide…
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …

728 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question