Solved

Playing WAV files

Posted on 1998-10-22
23
387 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
  • 10
  • 7
  • 5
  • +1
23 Comments
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
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
Comment Utility
but, how do I play, stop, etc.. the wav files ?

bryan

0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
bryan7,

 with the TMediaplayer!

 Or am I missing something?

Zif.
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
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
Comment Utility
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
Comment Utility
Sorry, never heard of PlaySound sorry. Zif.
0
 
LVL 3

Author Comment

by:bryan7
Comment Utility
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
Comment Utility
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
Comment Utility
bryan7, better use notify event.
0
 
LVL 10

Expert Comment

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

Cheers,
Viktor
0
 
LVL 8

Expert Comment

by:ZifNab
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 10

Expert Comment

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

Cheers,
Viktor
0
 
LVL 3

Author Comment

by:bryan7
Comment Utility
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
Comment Utility
thanks bryan.

Have fun with the TMediaPlayer.

Zif.
0
 
LVL 2

Expert Comment

by:Thaddy
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
ok, thanx ya all.

bryan

0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

762 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

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now