Solved

Playing WAV files

Posted on 1998-10-22
23
393 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
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
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
This video shows how to quickly and easily add an email signature for all users on Exchange 2016. The resulting signature is applied on a server level by Exchange Online. The email signature template has been downloaded from: www.mail-signatures…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

840 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