PDA

View Full Version : SDL_mizer problems



cairnswm
04-05-2005, 05:05 AM
Hi All

I have written a wrapper unit for my S2DL libraries over the SDL_mixer unit. Unformtunatly it just doesn;t work very well. All my sounds are played very irregularly (stuttering) and they are all delayed - I ask for a sounf to be played and a second later it plays. All my sounds have been resampled (using GoldWave) to the correct sample rate (I've tried 22k and 11k).

I have gone through the JEDI-SDL examples that use sound quite a few times trying to see what I missed and I still have the problem.

Here is the full source from my Sound unit.

(** S2DLDraws
@Name: Simple 2D Library - Sounds
This file is part of the Free Pascal Simple 2D Libraries
@Version: 1.03

@Change_History:
@Copyright: (c) 2004-2005 by William Cairns (CairnsGames) and
the Pascal Game Development (PGD) Site

@License: This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
(I got this from the JEDI-SDL files and it sounds Cool!)
@
By using this work you have immediatly agreed with the above.
@
The work can be used for any purpose. You may sell it, use it in a game
delete it or change it as you wish with no reward to the the original
developers.
@
We do however ask that if this work is used that some mention of it be made
on the PGD web site.

@Usage: Automatically creates a sound engine. You need to load sounds into the
sound engine and then call the sounds play method.

@Author: W.Cairns **)
unit S2DLSound;

{$ifdef FPC}
{$mode delphi}
{$endif}

interface

uses
Classes, SysUtils, S2DLLogger, sdl, sdl_mixer,
Windows;

Type
TS2DLSound = Class;
TS2DLSoundEngine = Class
Private
FItems : TList;
FVolume : Integer;
Function GetSound(Index : Integer) : TS2DLSound;
Function GetSoundByName(Name : String) : TS2DLSound;
procedure SetVolume(const AValue : Integer);
Public
Property Sound[Index : Integer] : TS2DLSound read GetSound; default;
Property SoundByName[Name : String] : TS2DLSound read GetSoundByName;
Property Volume : Integer read FVolume write SetVolume;
Constructor Create;
Destructor Destroy; Override;
Function Find(Name : String) : TS2DLSound;
Procedure Add(Item : TS2DLSound);
Function Count : Integer;
Function Delete(Item : Integer) : Boolean;
Procedure LoadSound(Name : String; FileName : String);
End;
TS2DLSound = Class
Name : String;
Sound: PMix_Chunk;
Volume : Integer;
Engine : TS2DLSoundEngine;
Channel : Integer;
LastPlay : Cardinal;
Constructor Create;
Destructor Destroy; Override;
Procedure LoadFromFile(FileName : PChar);
Procedure Play(NewVolume : Integer); Overload;
Procedure Play(NewChannel : Integer; NewVolume : Integer); Overload;
Procedure Stop;
End;

Var
Sounds : TS2DLSoundEngine;

procedure PlaySound(Name: String);


implementation

{ TS2DLSound }

constructor TS2DLSound.Create;
begin

end;

destructor TS2DLSound.Destroy;
begin
Mix_FreeChunk(Sound);

inherited Destroy;
end;

procedure TS2DLSound.LoadFromFile(FileName : PChar);
begin
Sound := Mix_LoadWAV(PChar(FileName));
If Sound = Nil then
Begin
Sound := Nil;
End;
end;

procedure TS2DLSound.Play(NewVolume : Integer);
begin
If GetTickCount - LastPlay < 500 then
Exit;
LastPlay := GetTickCount;
Channel := Mix_PlayChannel(-1, Sound, 0);
Mix_Volume(Channel, NewVolume);
end;

procedure TS2DLSound.Play(NewChannel : Integer; NewVolume : Integer);
begin
If GetTickCount - LastPlay < 500 then
Exit;
LastPlay := GetTickCount;
Channel := Mix_PlayChannel(NewChannel, Sound, 0);
Mix_Volume(Channel, NewVolume);
end;

procedure TS2DLSound.Stop;
begin
Mix_HaltChannel(Channel);
end;

{ TS2DLSoundEngine }

function TS2DLSoundEngine.GetSound(Index : Integer) : TS2DLSound;
begin
Result := TS2DLSound(FItems[Index]);
end;

function TS2DLSoundEngine.GetSoundByName(Name : String) : TS2DLSound;
Var
I : Integer;
begin
For I := 0 to FItems.Count - 1 do
Begin
If TS2DLSound(FItems[I]).Name = Name then
Begin
Result := TS2DLSound(FItems[I]);
Exit;
End;
end;
Result := Nil;
end;

procedure TS2DLSoundEngine.SetVolume(const AValue : Integer);
begin
if FVolume = AValue then
exit;
FVolume := AValue;
end;

constructor TS2DLSoundEngine.Create;
begin
FItems := TList.Create;
end;

destructor TS2DLSoundEngine.Destroy;
begin
While FItems.Count > 0 do
Begin
TS2DLSound(FItems[0]).Free;
FItems.Delete(0);
End;
inherited Destroy;
end;

function TS2DLSoundEngine.Find(Name : String) : TS2DLSound;
begin
Result := GetsoundByName(Name);
end;

procedure TS2DLSoundEngine.Add(Item : TS2DLSound);
begin
FItems.Add(Item);
Item.Engine := Self;
end;

function TS2DLSoundEngine.Count : Integer;
begin
Result := FItems.Count;
end;

function TS2DLSoundEngine.Delete(Item : Integer) : Boolean;
begin
TS2DLSound(FItems[Item]).Free;
FItems.Delete(Item);
end;

procedure TS2DLSoundEngine.LoadSound(Name: String; FileName: String);
Var
Sound : TS2DLSound;
Begin
Sound := TS2DLSound.Create;
Sound.LoadFromFile(PChar(FileName));
Sound.Name := Name;
Add(Sound);
end;

procedure PlaySound(Name: String);
Var
Sound : TS2DLSound;
begin
Sound := Sounds.Find(Name);
If Sound = Nil then
Begin
Sounds.LoadSound(Name,'sound\'+Name+'.wav');
Sound := Sounds.Find(Name);
End;
Sound.Play(100);
end;


Initialization
if (Mix_OpenAudio(22050, AUDIO_U8, 1, 512) < 0) then
begin
Log.LogError(Format('Couldn''t set 22050 Hz 8-bit audio - Reason : %s',
[Mix_GetError]), 'Main');
end
Else
Sounds := TS2DLSoundEngine.Create;

Finalization
Sounds.Free;
Mix_CloseAudio();

end.