PDA

View Full Version : Sound problem...



Ultra
07-01-2003, 04:30 PM
First post! :D

I have two problems and I would be grateful if you could help me out with anyone of them.

First I'm trying to make a space shoot'em up game. Of course this game needs some sounds. :wink: For this I use something similar to:


if FileExists(ExtractFilePath(Application.ExeName)+Fi leName) then
SndPlaySound(PChar(FileName), SND_ASYNC or SND_NODEFAULT)
else
begin
{error code}
end;


The problem is that after the sound is played the program freezes for a short while. That's not good and I wonder if there is any way to solve this?

Next problem is that when I use the TMediaPlayer I get an error saying that my system can't play the file (I'd post this message, but it's in Swedish). This problem occure no matter what file type I try to load. I can't figure out what the problem is, especially since it has work earlier on my computer. Anyone knows what it can be so that I at least could tell the user what causes the problem.

Thanks in advance!

Alimonster
08-01-2003, 10:36 AM
The first two questions: what format (wav, mp3, ...) is the sound and how big is it?

Remember that the hard disc will be accessed whenever you play that sound - so if it's big, that could slow things down (think of how slow your computer goes when it's thrashing the hard disc - the hard disc ain't very quick). Maybe that's not the case, mind you (just a wild guess).

It should be possible to load the sound into memory, which might be a bit quicker. You could then use PlaySound with the SND_MEMORY flag. That's just a guess, mind you, since I've not tried it out. Example, not-thought-about code:

uses
MMSystem;

type
TDynamicByteArray = array of Byte;

var
sound1: TDynamicByteArray;

procedure LoadSound(const Filename: String; var x: TDynamicByteArray);
var
F: File;
Size: Int64;
begin
if not FileExists(Filename) then
begin
x := nil;
raise Exception.Create('The sound ' + Filename + ' does not exist!');
end;

// open the file, resize the array to the wanted
// length, then read in the entire file to the
// array
AssignFile(F, Filename);
try
Reset(F, 1);
Size := FileSize(F);

SetLength(x, Size);
BlockRead(F, x[0], Size);
finally
CloseFile(F);
end;
end;

// play the sound that's sitting in memory
procedure PlayWav(const x: array of Byte);
begin
PlaySound(@sound1[0], 0, SND_ASYNC or SND_NODEFAULT or SND_MEMORY);
end;

procedure TfrmSoundMain.FormCreate(Sender: TObject);
begin
LoadSound('c:\windows\media\Chord.wav', sound1);
end;

procedure TfrmSoundMain.FormDestroy(Sender: TObject);
begin
PlaySound(nil, 0, SND_PURGE or SND_ASYNC);
sound1 := nil;
end;

procedure TfrmSoundMain.btnPlayWavClick(Sender: TObject);
begin
PlayWav(sound1);
end;
Apologies if the above doesn't speed things up or if there are bugs - it was the first thing that came to mind.

I think that the main drawback to using PlaySound is that you only get one sound at a time (IIRC), with others cutting off the first playing.

To be honest, you'd be much better off with a more advanced sound API like FMod (http://www.fmod.org) or BASS (http://www.un4seen.com/music/). They'll give you much faster sound, plus extras like dozens of file formats to pick from, 3D positional sound, EAX, (and possibly less hassle, maybe not though :)), etc.

Ultra
12-01-2003, 03:00 AM
Currently I'm using a wav-file that is 24kB for some SFX etc. What I'll use in the final version is still very uncertain, but it'll probably be somthing similar.

My hard disc is 70 GB so it's quite big, but I belive that the same problem ocurred on my old computer which only had a 8 GB hard disc so I don't think that is the problem!

I still haven't tried out the code (I haven't had acces to my computer for some days and now it's late :wink: ), but when I do I'll report. The links are a bit interesting though. :D

I don't get the problem if I play some music with WinAmp or with the TMediaPlayer component, but since that doesn't work anymore for me I'll have to use another approach. :( But hey, problems are made to be solved.