Hi Ixy, if it helps, here are my units I use for manipulating audio when using SDL_Mixer. Music load/play hasn't been aded yet, but it could easily be.
Code:
Unit EngineAudio;
{$IFDEF fpc}
{$mode delphi}
{$ENDIF}
{$H+}
Interface
Uses
Classes;
Type
{..............................................................................}
TAudioModule = Class
Function InitAudio: Boolean; Virtual; Abstract;
Procedure RegisterSound_WAV(AName,AFileName: AnsiString); Overload; Virtual; Abstract;
Procedure RegisterSound_WAV(Const AName : AnsiString;
Const AStream : TMemoryStream); Overload; Virtual; AbStract;
Function PlaySound_WAV (AName : AnsiString) : Integer; Virtual; Abstract;
Procedure StopSound_WAV (AChannel: Integer); Virtual; Abstract;
Procedure RegisterMusic_WAV(AName,AFileName: AnsiString); Virtual; Abstract;
Function PlayMusic_WAV (AName : AnsiString): Boolean; Virtual; Abstract;
Procedure StopMusic_WAV; Virtual; Abstract;
Procedure CloseAudio; Virtual; Abstract;
End;
{..............................................................................}
Implementation
End.
Code:
Unit EngineAudio_sdl_mixer;
{$IFDEF fpc}
{$mode delphi}
{$ENDIF}
{$H+}
Interface
Uses
EngineAudio,
Classes;
Type
{..............................................................................}
TSoundInfo = Class
IsPhysicalFile : Boolean;
FileName : AnsiString;
Stream : TMemoryStream;
End;
{..............................................................................}
{..............................................................................}
TAudioModule_sdl_mixer = Class(TAudioModule)
Private
FSoundNames : TStringList;
FAudioInitialized : Boolean;
Public
Constructor Create;
Destructor Destroy; Override;
Function InitAudio: Boolean; Override;
Procedure RegisterSound_WAV(AName,AFileName: AnsiString); Override;
Procedure RegisterSound_WAV(Const AName : AnsiString;
Const AStream : TMemoryStream); Override;
Function PlaySound_WAV (AName : AnsiString) : Integer; Override;
Procedure StopSound_WAV (AChannel: Integer); Override;
Procedure RegisterMusic_WAV(AName,AFileName: AnsiString); Override;
Function PlayMusic_WAV (AName : AnsiString): Boolean; Override;
Procedure StopMusic_WAV; Override;
Procedure CloseAudio; Override;
End;
{..............................................................................}
Implementation
Uses
SDL,
SDL_Mixer;
Const
{..............................................................................}
cMaxSounds = 40;
{..............................................................................}
Type
{..............................................................................}
TSound = Class
Private
Sound : PMix_Chunk;
channel : Integer;
Public
Constructor Create;
Destructor Destroy; Override;
Function Playing : Boolean; Virtual;
End;
{..............................................................................}
{..............................................................................}
TMusic = Class(TSound)
Private
Music : PMix_Music;
Public
Constructor Create;
Destructor Destroy; Override;
Function Playing : Boolean; Override;
End;
{..............................................................................}
Var
Sounds : Array[0..cMaxSounds - 1] Of TSound;
Music : TMusic;
{..............................................................................}
{..............................................................................}
Constructor TSound.Create;
Begin
Inherited Create;
Sound := Nil;
End;
{..............................................................................}
{..............................................................................}
Destructor TSound.Destroy;
Begin
If Sound <> Nil Then Mix_FreeChunk(Sound);
Inherited Destroy;
End;
{..............................................................................}
{..............................................................................}
Function TSound.Playing : Boolean;
Begin
Result := Mix_Playing(Channel) = 0;
End;
{..............................................................................}
{..............................................................................}
Constructor TMusic.Create;
Begin
Inherited Create;
Music := Nil;
End;
{..............................................................................}
{..............................................................................}
Destructor TMusic.Destroy;
Begin
If Music <> Nil Then Mix_FreeMusic(Music);
Inherited Destroy;
End;
{..............................................................................}
{..............................................................................}
Function TMusic.Playing : Boolean;
Begin
Result := Mix_PlayingMusic = 0;
End;
{..............................................................................}
{..............................................................................}
Constructor TAudioModule_sdl_mixer.Create;
Begin
Inherited Create;
FSoundNames := TStringList.Create;
FAudioInitialized := False;
End;
{..............................................................................}
{..............................................................................}
Destructor TAudioModule_sdl_mixer.Destroy;
Var
i : Integer;
si : TSoundInfo;
Begin
For i := 0 To FSoundNames.Count - 1 Do
Begin
si := TSoundInfo(FSoundNames.Objects[i]);
If Not si.IsPhysicalFile Then si.Stream.Free;
si.Free;
End;
FSoundNames.Free;
Inherited Destroy;
End;
{..............................................................................}
{..............................................................................}
Function TAudioModule_sdl_mixer.InitAudio: Boolean;
Begin
Result := False;
// Open the audio device
If Mix_OpenAudio(22050,AUDIO_S16SYS,2,512) < 0 Then
Begin
//fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
Exit;
End;
Result := True;
FAudioInitialized := True;
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl_mixer.CloseAudio;
Begin
If FAudioInitialized Then Mix_CloseAudio;
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl_mixer.RegisterSound_WAV(AName,AFileName : AnsiString);
Var
SoundInfo : TSoundInfo;
Begin
SoundInfo := TSoundInfo.Create;
SoundInfo.IsPhysicalFile := True;
SoundInfo.FileName := AFileName;
SoundInfo.Stream := Nil;
FSoundNames.AddObject(AName,SoundInfo);
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl_mixer.RegisterSound_WAV(Const AName : AnsiString;
Const AStream : TMemoryStream);
Var
SoundInfo : TSoundInfo;
Begin
SoundInfo := TSoundInfo.Create;
SoundInfo.IsPhysicalFile := False;
SoundInfo.FileName := '';
SoundInfo.Stream := AStream;
FSoundNames.AddObject(AName,SoundInfo);
End;
{..............................................................................}
{..............................................................................}
Function TAudioModule_sdl_mixer.PlaySound_WAV(AName: AnsiString) : Integer;
Var
index : Integer;
Sound : TSound;
FileName : AnsiString;
i : Integer;
SoundInfo : TSoundInfo;
RWops : PSDL_RWops;
Begin
Result := -1;
If Not FAudioInitialized Then Exit;
// Look for an empty (or finished) sound slot
index := 0;
While index < cMaxSounds Do
Begin
If sounds[index] = Nil Then Break;
Inc(index);
End;
If index = cMaxSounds Then Exit;
i := FSoundNames.IndexOf(AName);
If i = -1 Then Exit;
Sound := TSound.Create;
SoundInfo := TSoundInfo(FSoundNames.Objects[i]);
If SoundInfo.IsPhysicalFile Then
Begin
FileName := SoundInfo.FileName;
// Load the sound file
Sound.Sound := Mix_LoadWAV(PChar(FileName));
If Sound.Sound = Nil Then
Begin
// fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
// return;
Sound.Free;
Exit;
End;
End
Else
Begin
If SoundInfo.Stream = Nil Then Exit;
If SoundInfo.Stream.Size = 0 Then Exit;
RWops := SDL_RWFromMem(SoundInfo.Stream.Memory,SoundInfo.Stream.Size);
If RWops = Nil Then Exit;
Sound.Sound := Mix_LoadWAV_RW(RWops, 0);
If Sound.Sound = Nil Then
Begin
SDL_FreeRW(RWops);
Sound.Free;
Exit;
End;
SDL_FreeRW(RWops);
End;
Sound.channel := Mix_PlayChannel(-1,Sound.Sound,0);
sounds[index] := Sound;
Result := Sound.channel;
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl_mixer.StopSound_WAV(AChannel : Integer);
Begin
Mix_HaltChannel(AChannel);
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl_mixer.RegisterMusic_WAV(AName,AFileName: AnsiString);
Begin
End;
{..............................................................................}
{..............................................................................}
Function TAudioModule_sdl_mixer.PlayMusic_WAV(AName : AnsiString): Boolean;
Begin
Result := False;
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl_mixer.StopMusic_WAV;
Begin
End;
{..............................................................................}
{..............................................................................}
Procedure InitSounds;
Var
i : Integer;
Begin
For i := 0 To cMaxSounds - 1 Do
Sounds[i] := Nil;
End;
{..............................................................................}
{..............................................................................}
Initialization
InitSounds;
{..............................................................................}
{..............................................................................}
End.
cheers,
Paul
Bookmarks