Originally Posted by
KidPaddle
Paul,
have you any working sample with playing music/sound und timer? And if, coud you send me this sample?
Best Regards
Thomas
Hi Thomas,
The only sound stuff I could get working on the GP2X (and Win32) was using .wav files only and the code below (hacked together from C examples off the web). I still can't get SDL_Mixer working under the GP2X
The following code is not complete, but at least it plays .wav sounds...
The StopSound and all music methods don''t do anything yet (I was going to see if I could stream a large .wav file in chunks as music).
You use it like so:
First, you 'register' any sounds you want to load and play later:
Code:
FAudioModule.RegisterSound_WAV('miss_sound' ,FDataPath + 'miss.wav');
then later on when you want to play the sound:
Code:
FAudioModule.PlaySound_WAV('miss_sound');
Code:
Unit EngineAudio_sdl;
{$IFDEF fpc}
{$mode delphi}{$H+}
{$ENDIF}
Interface
Uses
SDL,
Classes;
Type
{..............................................................................}
TAudioModule_sdl = Class
Private
FSoundNames : TStringList;
FAudioInitialized : Boolean;
Public
Constructor Create;
Destructor Destroy; Override;
Function InitAudio: Boolean;
Procedure RegisterSound_WAV(AName,AFileName: AnsiString);
Function PlaySound_WAV (AName : AnsiString): Boolean;
Procedure StopSound_WAV (AChannel: Integer);
Procedure RegisterMusic_WAV(AName,AFileName: AnsiString);
Function PlayMusic_WAV (AName : AnsiString): Boolean;
Procedure StopMusic_WAV;
Procedure CloseAudio;
End;
{..............................................................................}
Implementation
Uses
SDL_Mixer;
Const
{..............................................................................}
cMaxSounds = 40;
{..............................................................................}
Type
{..............................................................................}
TSound = Class
Public
channel : Integer;
data : PUint8;
dpos : Uint32;
dlen : Uint32;
Constructor Create;
Destructor Destroy; Override;
Procedure Update(stream: PUint8; len: Integer); Virtual;
Function Playing : Boolean;
End;
{..............................................................................}
{..............................................................................}
TMusic = Class(TSound)
Public
Procedure Update(stream: PUint8; len: Integer); Override;
End;
{..............................................................................}
Var
Sounds : Array[0..cMaxSounds - 1] Of TSound;
Music : TMusic;
{..............................................................................}
{..............................................................................}
Constructor TSound.Create;
Begin
Inherited Create;
data := Nil;
End;
{..............................................................................}
{..............................................................................}
Destructor TSound.Destroy;
Begin
If data <Nil> len Then
amount := len;
SDL_MixAudio(stream, @PByteArray(data)^[dpos], amount, SDL_MIX_MAXVOLUME);
Inc(dpos,amount);
End;
{..............................................................................}
{..............................................................................}
Function TSound.Playing : Boolean;
Begin
Result := dpos < dlen;
End;
{..............................................................................}
{..............................................................................}
Procedure TMusic.Update(stream: PUint8; len: Integer);
Begin
End;
{..............................................................................}
{..............................................................................}
Procedure MixAudioProc(unused: Pointer; stream: PUint8; len: Integer); cdecl;
Var
i : Integer;
Begin
For i := 0 To cMaxSounds - 1 Do
Begin
If Sounds[i] <> Nil Then
Begin
Sounds[i].Update(stream,len);
If Not Sounds[i].Playing Then
Begin
Sounds[i].Free;
Sounds[i] := Nil;
End;
End;
End;
End;
{..............................................................................}
{..............................................................................}
Constructor TAudioModule_sdl.Create;
Begin
Inherited Create;
FSoundNames := TStringList.Create;
FAudioInitialized := False;
End;
{..............................................................................}
{..............................................................................}
Destructor TAudioModule_sdl.Destroy;
Begin
FSoundNames.Free;
Inherited Destroy;
End;
{..............................................................................}
{..............................................................................}
Function TAudioModule_sdl.InitAudio: Boolean;
Var
fmt : TSDL_AudioSpec;
Begin
Result := False;
// Set 16-bit stereo audio at 22Khz
fmt.freq := 22050;
fmt.format := AUDIO_S16;
fmt.channels := 2;
fmt.samples := 512; // A good value for games
fmt.callback := MixAudioProc;
fmt.userdata := Nil;
// Open the audio device
If SDL_OpenAudio(@fmt, Nil) < 0 Then
Begin
//fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
Exit;
End;
SDL_PauseAudio(0);
Result := True;
FAudioInitialized := True;
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl.CloseAudio;
Begin
If FAudioInitialized Then
SDL_CloseAudio;
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl.RegisterSound_WAV(AName,AFileName: AnsiString);
Begin
FSoundNames.Add(AName + '=' + AFileName);
End;
{..............................................................................}
{..............................................................................}
Function TAudioModule_sdl.PlaySound_WAV(AName: AnsiString) : Boolean;
Var
index : Integer;
wave : TSDL_AudioSpec;
data : PUint8;
dlen : Uint32;
cvt : TSDL_AudioCVT;
FileName : AnsiString;
Begin
Result := False;
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;
FileName := FSoundNames.Values[AName];
// Load the sound file and convert it to 16-bit stereo at 22kHz
If SDL_LoadWAV(PChar(FileName), @wave, @data, @dlen) = Nil Then
Begin
// fprintf(stderr, "Couldn't load %s: %s\n", file, SDL_GetError());
// return;
Exit;
End;
SDL_BuildAudioCVT(@cvt,
wave.format,
wave.channels,
wave.freq,
AUDIO_S16,
2,
22050);
GetMem(cvt.buf,dlen * cvt.len_mult);
Move(data^,cvt.buf^,dlen);
cvt.len := dlen;
SDL_ConvertAudio(@cvt);
SDL_FreeWAV(data);
// Put the sound data in the slot (it starts playing immediately)
SDL_LockAudio;
sounds[index] := TSound.Create;
sounds[index].channel := index;
sounds[index].data := cvt.buf;
sounds[index].dlen := cvt.len_cvt;
sounds[index].dpos := 0;
SDL_UnlockAudio;
Result := True;
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl.StopSound_WAV(AChannel : Integer);
Begin
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl.RegisterMusic_WAV(AName,AFileName: AnsiString);
Begin
End;
{..............................................................................}
{..............................................................................}
Function TAudioModule_sdl.PlayMusic_WAV(AName : AnsiString): Boolean;
Begin
End;
{..............................................................................}
{..............................................................................}
Procedure TAudioModule_sdl.StopMusic_WAV;
Begin
End;
{..............................................................................}
{..............................................................................}
Procedure InitSounds;
Var
i : Integer;
Begin
For i := 0 To cMaxSounds - 1 Do
Sounds[i] := Nil;
End;
{..............................................................................}
{..............................................................................}
Initialization
InitSounds;
{..............................................................................}
{..............................................................................}
End.
I hope this helps,
cheers,
Paul
Bookmarks