Board index » cppbuilder » Playing a Resource Audio File

Playing a Resource Audio File


2005-11-27 02:46:01 PM
cppbuilder92
What is the best way to play a .wav or .mid file stored in the resource?
 
 

Re:Playing a Resource Audio File

Quote
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
 

Re:Playing a Resource Audio File

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.
Quote
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 );
 

{smallsort}

Re:Playing a Resource Audio File

"oLiVeS" <olives3#Remove#@earthlink.net>wrote in message
Quote
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
tinyurl.com/awvtv functions to open and play a MIDI stream. I
googled and came up with this example: tinyurl.com/7nf6z
HTH,
Bruce
 

Re:Playing a Resource Audio File

"oLiVeS" <olives3#Remove#@earthlink.net>wrote:
Quote

[...] 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
 

Re:Playing a Resource Audio File

"oLiVeS" <olives3#Remove#@earthlink.net>wrote in message
Quote
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
 

Re:Playing a Resource Audio File

"JD" < XXXX@XXXXX.COM >wrote in message
Quote
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
 

Re:Playing a Resource Audio File

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

Look at the TResourceStream class, ie:
Another Stream class!!
Quote
MediaPlayer1->FileName = MediaFileName;
MediaPlayer1->Open();
MediaPlayer1->Play();
The way it's coded, won't TMediaPlayer throw if extraction
from the resource fails?
~ JD
 

Re:Playing a Resource Audio File

"Remy Lebeau \(TeamB\)" < XXXX@XXXXX.COM >wrote:
Quote

"oLiVeS" <olives3#Remove#@earthlink.net>wrote in message
news:438956ca$ XXXX@XXXXX.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.
I couldn't get it to play MIDI files (?) and I tried all 3.
~ JD
 

Re:Playing a Resource Audio File

"JD" < XXXX@XXXXX.COM >wrote in message
Quote
Another Stream class!!
The VCL has many stream classes.
Quote
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
 

Re:Playing a Resource Audio File

"JD" < XXXX@XXXXX.COM >wrote in message
Quote
I couldn't get it to play MIDI files (?) and I tried all 3.
PlaySound() only supports waveform audio.
Gambit
 

Re:Playing a Resource Audio File

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.
Quote

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

 

Re:Playing a Resource Audio File

"poojo hackma" <poojo.com/mail>wrote in message
Quote
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.
Quote
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);
}
Quote
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