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

Playing a Resource Audio File

6 views
Skip to first unread message

oLiVeS

unread,
Nov 27, 2005, 1:46:01 AM11/27/05
to
What is the best way to play a .wav or .mid file stored in the resource?


Vladimir Stefanovic

unread,
Nov 27, 2005, 2:58:17 AM11/27/05
to
> What is the best way to play a .wav or .mid file stored
> in the resource?


Make a *.RC file (Unit1.RC), and let it look like this:

#define IDW_SOUND 1000
#ifdef RC_INVOKED
IDW_SOUND WAVE "sound.wav"
#endif

Place the RC file in the same root with Unit1.cpp i Unit1.h.
Also, in the same folder plase your "sound.wav" file (because
of compiling).

Later, when EXE is made, you do not need "sound.wav" any more.

Add (Add to project...) that Unit1.RC to the project.

Later, from the program, you can play the sound like this:

PlaySound( MAKEINTRESOURCE( IDW_SOUND ), HInstance, SND_RESOURCE |
SND_ASYNC );


--
Best regards,
Vladimir Stefanovic


oLiVeS

unread,
Nov 27, 2005, 8:50:15 PM11/27/05
to
Ok thanks that works.
Is there a way I can do the same thing with a midi file because
PlaySound seems to be limited to wave files?

Thanks.

Bruce Salzman

unread,
Nov 28, 2005, 11:25:44 AM11/28/05
to

"oLiVeS" <olives3#Remove#@earthlink.net> wrote in message
news:438a62f4$1...@newsgroups.borland.com...

> Ok thanks that works.
> Is there a way I can do the same thing with a midi file because
> PlaySound seems to be limited to wave files?
>

MIDI is a much more complicated beast. You need a MIDI device
installed (supported by an installed sound card, or the software MIDI
player included with Windows XP Pro). Then you'll need the MIDI API
http://tinyurl.com/awvtv functions to open and play a MIDI stream. I
googled and came up with this example: http://tinyurl.com/7nf6z

HTH,
Bruce


JD

unread,
Nov 28, 2005, 1:51:24 PM11/28/05
to

"oLiVeS" <olives3#Remove#@earthlink.net> wrote:
>
> [...] Is there a way I can do the same thing with a midi

> file because PlaySound seems to be limited to wave files?

TMediaPlayer handles MIDI files but only from disk.

//--- The sound resource header - SoundResource.rh ------------
#ifndef SoundResource_RH
#define SoundResource_RH

#define ID_SoundFileName1WithoutExtension 1000
#define ID_SoundFileName2WithoutExtension 2000

#endif

//--- The sound resource source - SoundResource.rc ------------
SoundFileName1WithoutExtension MIDI SoundFileName1.mid
SoundFileName2WithoutExtension WAVE SoundFileName1.wav

//--- SoundResource.bat ---------------------------------------
rc SoundResource
pause


//--- in the unit ---------------------------------------------
AnsiString Path = "";
//-------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner)
{
MediaPlayer1->AutoOpen = false;
MediaPlayer1->Visible = false;
Path = ExtractFilePath( Application->ExeName );
}
//-------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
PlayMidiSound( "SoundFileName1WithoutExtension" );
}
//-------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
::PlaySound( "SoundFileName2WithoutExtension", HInstance, SND_ASYNC | SND_NODEFAULT | SND_NOWAIT );
}
//-------------------------------------------------------------
void __fastcall TForm1::PlayMidiSound( AnsiString ID )
{
HRSRC SoundResource = ::FindResource( HInstance, ID.c_str(), "MIDI" );
if( SoundResource )
{
DWORD Size = ::SizeofResource( HInstance, SoundResource );
if( Size )
{
HGLOBAL SoundLoad = ::LoadResource( HInstance, SoundResource );
if( SoundLoad )
{
LPVOID SoundPointer = ::LockResource( SoundLoad );
if( SoundPointer )
{
MediaPlayer1->FileName = Path + ID + ".mid";
TFileStream *fStream = new TFileStream( MediaPlayer1->FileName, fmCreate );
fStream->Seek( 0, soFromBeginning );
fStream->Write( SoundPointer, Size );
delete fStream;
MediaPlayer1->Open();
MediaPlayer1->Play();
}
}
}
}
}
//-------------------------------------------------------------

Note that if you want to loop the sound, PlaySound has a
SND_LOOP flag. To accomplish the same with the MediaPlayer,
you need to use it's Notify property and OnNotify event to
setup a loop.

~ JD

Remy Lebeau (TeamB)

unread,
Nov 28, 2005, 5:53:52 PM11/28/05
to

"oLiVeS" <olives3#Remove#@earthlink.net> wrote in message
news:438956ca$1...@newsgroups.borland.com...

> What is the best way to play a .wav or .mid file stored in the resource?

The easiest way is via the Win32 Multimedia API PlaySound() function. It
can play sounds from a file, a memory block, or a resource.


Gambit


Remy Lebeau (TeamB)

unread,
Nov 28, 2005, 6:02:21 PM11/28/05
to

"JD" <nos...@nospam.com> wrote in message
news:438b5fbc$1...@newsgroups.borland.com...

> HRSRC SoundResource = ::FindResource( HInstance, ID.c_str(), "MIDI" );

<snip>

Look at the TResourceStream class, ie:

void __fastcall TForm1::PlayMidiSound(const AnsiString &ID)
{
AnsiString MediaFileName = Path + ID + ".mid";

TResourceStream *RS = new TResourceStream(HInstance, ID);
try {
TFileStream *FS = new TFileStream(MediaFileName, fmCreate);
try {
FStream->CopyFrom(RS, 0);
}
__finally { delete FS; }
}
__finally { delete RS; }

MediaPlayer1->FileName = MediaFileName;
MediaPlayer1->Open();
MediaPlayer1->Play();
}


Gambit


JD

unread,
Nov 29, 2005, 12:42:36 AM11/29/05
to

"Remy Lebeau \(TeamB\)" <no....@no.spam.com> wrote:
>
> Look at the TResourceStream class, ie:

Another Stream class!!

> MediaPlayer1->FileName = MediaFileName;
> MediaPlayer1->Open();
> MediaPlayer1->Play();

The way it's coded, won't TMediaPlayer throw if extraction
from the resource fails?

~ JD

JD

unread,
Nov 29, 2005, 12:44:03 AM11/29/05
to

"Remy Lebeau \(TeamB\)" <no....@no.spam.com> wrote:
>

I couldn't get it to play MIDI files (?) and I tried all 3.

~ JD

Remy Lebeau (TeamB)

unread,
Nov 29, 2005, 5:05:36 AM11/29/05
to

"JD" <nos...@nospam.com> wrote in message
news:438bf85c$1...@newsgroups.borland.com...

> Another Stream class!!

The VCL has many stream classes.

> The way it's coded, won't TMediaPlayer throw
> if extraction from the resource fails?

No, because it won't get that far. If extraction fails, an exception will
be thrown before TMediaPlayer is ever touched.


Gambit


Remy Lebeau (TeamB)

unread,
Nov 29, 2005, 5:07:25 AM11/29/05
to

"JD" <nos...@nospam.com> wrote in message
news:438bf8b3$1...@newsgroups.borland.com...

> I couldn't get it to play MIDI files (?) and I tried all 3.

PlaySound() only supports waveform audio.


Gambit


poojo hackma

unread,
Nov 29, 2005, 5:28:50 PM11/29/05
to
That's pretty cool!

Any idea how to tell when the .WAV file is finished? I want to try this in a
test application and have it continually loop or have a second .WAV start
after the first one ends.

Remy Lebeau (TeamB)

unread,
Nov 29, 2005, 6:07:18 PM11/29/05
to

"poojo hackma" <poojo.com/mail> wrote in message
news:438cd5fb$1...@newsgroups.borland.com...

> Any idea how to tell when the .WAV file is finished?

Use SND_SYNC instead of SND_ASYNC when calling PlaySound(). Then
PlaySound() won't return until the sound is finished playing.

> I want to try this in a test application and have it continually loop

PlaySound() has a SND_LOOP flag available as well. You have to use
SND_ASYNC with it, though. For example:

void __fastcall TForm1::StartLoop()
{
PlaySound(MAKEINTRESOURCE(IDW_SOUND), HInstance, SND_RESOURCE |
SND_ASYNC | SND_LOOP);
}

void __fastcall TForm1::StopLoop()
{
PlaySound(NULL, NULL, 0);
}

> or have a second .WAV start after the first one ends.

Using SND_SYNC, you can call PlaySound() again on a second sound immediately
after PlaySound() finishes playing the first sound.


Gambit


0 new messages