Games:
Seafox
Pages:
Syntax Error Software
itch.io page
Online Chess
http://gameknot.com/#paul_nicholls
Just dropping a line to say two things really:
1. OpenAL
2.
That wasn't entirely true when I started out, but now I'd have to almost agree. Ever since I stopped using a mouse for most things and replaced it by Ctrl + Alt + t and Alt + F2 with the ls, top, cat and similar reflexes - windows feels ancientlinux users shouldn't need user-friendliness, they're all super-geeks anyways.
I once tried to change the world. But they wouldn't give me the source code. Damned evil cunning.
Games:
Seafox
Pages:
Syntax Error Software
itch.io page
Online Chess
http://gameknot.com/#paul_nicholls
Ok, I have now made an OpenAL sound audio class, but i am having troubles;
I have the code below:
Code:const cMaxSources = 10; type TxeAudio = class(TxeBaseObject) private FSounds : TStringList; FSourcePool : array[0..cMaxSources - 1] of TALuint; publicBut for some reason when I call alGenSources(), my FSourcePool array is all zeros still, and I am getting no error (or log file output).Code:constructor TxeAudio.Create; var ALResult: TALenum; begin inherited Create(False); if not InitOpenAL then begin LogFile_LogMessage('Error initializing OpenAL!'); end; alGenSources(cMaxSources,@FSourcePool[0]); ALResult := alGetError; if ALResult <> AL_NO_ERROR then begin LogFile_LogMessage('Error creating OpenAL sources!'); end;
Is this normal?
cheers,
Paul
Games:
Seafox
Pages:
Syntax Error Software
itch.io page
Online Chess
http://gameknot.com/#paul_nicholls
I don't know if I am having trouble as I had to modify the openal.pas file to compile under Delphi 2010?
I changed al PChar to PAnsiChar and Char to AnsiChar for example...
Does anyone here have an openal.pas file that is already updated to work under D2010/freepascal?
cheers,
Paul
Games:
Seafox
Pages:
Syntax Error Software
itch.io page
Online Chess
http://gameknot.com/#paul_nicholls
Here is my OpenAL audio unit to see if anyone might be able to see what is going on, and the openal unit + dll too:
openal.zip
OpenAL32.zip
The audio class loads sound files (the TxeSoundBuffer class), and stores them so only one instance of any sound is loaded...this instance is added to the actual loaded TxeSound class for playing.Code:unit xeEngine_audio_openal; interface {$I xeEngine_include.inc} uses Classes, xeEngine_base, xeEngine_types, openal; const cMaxSources = 10; type TxeAudio = class; // // TxeSoundBuffer // TxeSoundBuffer = class(TxeBaseObject) private FFormat : TALenum; FData : TALvoid; FSize : TALsizei; FFreq : TALsizei; FLoop : TALint; FBuffer : TALuint; public constructor Create; destructor Destroy; override; function LoadWavFromStream(Stream: TStream): Boolean; function LoadWavFromFile(FileName: PWideChar): Boolean; property Format : TALenum read FFormat; property Data : TALvoid read FData; property Size : TALsizei read FSize; property Freq : TALsizei read FFreq; property Loop : TALint read FLoop; property Buffer : TALuint read FBuffer; end; // // TxeSound // TxeSound = class(TxeBaseObject) private FParent : TxeAudio; FVolume : Single; FSource : TALuint; FBuffer : TxeSoundBuffer; public constructor Create(aParent: TxeAudio; aSoundBuffer: TxeSoundBuffer); destructor Destroy; override; procedure Play(aVolume,aPan: Single); end; // // TxeAudio // TxeAudio = class(TxeBaseObject) private FSounds : TStringList; FSourcePool : array[0..cMaxSources - 1] of TALuint; // function get a free source for playing purposes function AcquireSource: TALuint; public constructor Create; destructor Destroy; override; procedure Clear; function LoadSoundFromFile(aFileName: PWideChar): TxeSound; end; // DLL interface routines function Audio_LoadSoundFromFile(AudioInst: LongWord; aFileName: PWideChar): LongWord; cdecl; procedure Sound_Play (SoundInst: LongWord; aVolume: Single); cdecl; implementation uses SysUtils, xeEngine_logfile, unit_wavbuffer, WaveFileParser; // DLL interface routines function Audio_LoadSoundFromFile(AudioInst: LongWord; aFileName: PWideChar): LongWord; begin Result := LongWord(TxeAudio(AudioInst).LoadSoundFromFile(aFileName)); end; procedure Sound_Play(SoundInst: LongWord; aVolume: Single); begin TxeSound(SoundInst).Play(aVolume,1); end; const listenerPos: array[1..3] of TALfloat =(0.0,0.0,0.0); listenerVel: array[1..3] of TALfloat =(0.0,0.0,0.0); listenerOri: array[1..6] of TAlfloat =(0.0,0.0,1.0, 0.0,1.0,0.0); source0Pos : array[1..3] of TALfloat =( 0.0, 0.0, 0.0); source0Vel : array[1..3] of TALfloat =( 0.0, 0.0, 0.0); // // TxeAudio // constructor TxeAudio.Create; var ALResult: TALenum; begin inherited Create(False); alGenSources(cMaxSources,@FSourcePool[0]); ALResult := alGetError; if ALResult <> AL_NO_ERROR then begin LogFile_LogMessage('Error creating OpenAL sources!'); end; alListenerfv(AL_POSITION ,@listenerPos); alListenerfv(AL_VELOCITY ,@listenerVel); alListenerfv(AL_ORIENTATION,@listenerOri); FSounds := TStringList.Create; FSounds.Sorted := True; FSounds.Duplicates := dupIgnore; end; destructor TxeAudio.Destroy; var i: Integer; begin Clear; alDeleteSources(cMaxSources,@FSourcePool); FSounds.Free; inherited Destroy; end; procedure TxeAudio.Clear; var i: Integer; begin for i := 0 to cMaxSources - 1 do alSourceStop(FSourcePool[i]); for i := FSounds.Count - 1 downto 0 do TxeSoundBuffer(FSounds.Objects[i]).Free; FSounds.Clear; end; function TxeAudio.LoadSoundFromFile(aFileName: PWideChar): TxeSound; var FileName: WideString; Name : WideString; Index : Integer; Buffer : TxeSoundBuffer; Ext : WideString; begin Result := nil; if not FileExists(aFileName) then Exit; FileName := ExtractFileName(WideString(aFileName)); Ext := LowerCase(ExtractFileExt(FileName)); if Ext <> '.wav' then Exit; Name := ChangeFileExt(FileName,''); if FSounds.Find(Name,Index) then Buffer := TxeSoundBuffer(FSounds.Objects[Index]) else begin Buffer := TxeSoundBuffer.Create; Buffer.LoadWavFromFile(aFileName); end; Result := TxeSound.Create(Self,Buffer); end; function TxeAudio.AcquireSource: TALuint; var i : Integer; State: PALint; begin Result := 0; for i := 0 to cMaxSources - 1 do begin alGetSourcei(FSourcePool[i],AL_SOURCE_STATE,@State); if State <> PALint(AL_PLAYING) then // this source is free so return it begin Result := FSourcePool[i]; Exit; end; end; end; // // TxeSoundBuffer // constructor TxeSoundBuffer.Create; begin inherited Create(True); FFormat := 0; FData := nil; FSize := 0; FFreq := 0; FBuffer := 0; end; destructor TxeSoundBuffer.Destroy; begin if FBuffer <> 0 then alDeleteBuffers(1,@FBuffer); inherited Destroy; end; function TxeSoundBuffer.LoadWavFromStream(Stream: TStream): Boolean; var Mem: TMemoryStream; begin Mem := TMemoryStream.Create; try Mem.LoadFromStream(Stream); Mem.Seek(0,soFromBeginning); alutLoadWAVMemory(Mem.Memory,FFormat,FData,FSize,FFreq,FLoop); alGenBuffers(1,@FBuffer); alBufferData(FBuffer,FFormat,FData,FSize,FFreq); alutUnloadWAV(FFormat,FData,FSize,FFreq); finally Mem.Free; end; Result := True; end; function TxeSoundBuffer.LoadWavFromFile(FileName: PWideChar): Boolean; var WAVFile: TFileStream; begin Result := False; if not FileExists(String(FileName)) then Exit; WAVFile := TFileStream.Create(String(FileName),fmOpenRead or fmShareDenyWrite); try Result := LoadWavFromStream(WAVFile); finally WAVFile.Free; end; end; // // TxeSound // constructor TxeSound.Create(aParent: TxeAudio; aSoundBuffer: TxeSoundBuffer); begin inherited Create(True); FSource := 0; FVolume := 1.0; FBuffer := aSoundBuffer; FParent := aParent; end; destructor TxeSound.Destroy; begin inherited Destroy; end; procedure TxeSound.Play(aVolume,aPan: Single); begin FSource := FParent.AcquireSource; if FSource = 0 then Exit; FVolume := aVolume; alSourcef (FSource, AL_PITCH , 1.0); alSourcef (FSource, AL_GAIN , FVolume); alSourcefv(FSource, AL_POSITION , @source0Pos); alSourcefv(FSource, AL_VELOCITY , @source0Vel); alSourcei (FSource, AL_BUFFER , FBuffer.Buffer); alSourcei (FSource, AL_LOOPING , AL_FALSE); alSourcePlay(FSource); end; procedure InitAudio; begin if not InitOpenAL then begin LogFile_LogMessage('Error initializing OpenAL!'); end; end; initialization InitAudio; end.
I have noticed that loading the sound doesn't seem to do anything either...the FBuffer is zero as well as all the sources, and so is most of the data returned from the alutLoadWAVFile() routine. All this is probably related!!
I'm not getting any crashes, it just isn't working
cheers,
Paul
Last edited by paul_nicholls; 09-09-2011 at 12:37 AM.
Games:
Seafox
Pages:
Syntax Error Software
itch.io page
Online Chess
http://gameknot.com/#paul_nicholls
Ok, I have fixed my OpenAL issues now
1) I was missing this code:2) The WAV loading routines weren't working correctly in the openal.pas for me so I replaced them from an ALut.pas file I found in the Project JEDI.Code:alutInit(nil,[]);
I found there was still a bug fix in the loading code so I fixed it, and added a alutLoadWAVStream routine which the other loaders now use.
I have attached my fixed code, and the altered version of openal.pas
openal.zipCode:unit xeEngine_audio_openal; interface {$I xeEngine_include.inc} uses Classes, xeEngine_base, xeEngine_types, openal; const cMaxSources = 10; type TxeAudio = class; // // TxeSoundBuffer // TxeSoundBuffer = class(TxeBaseObject) private FFormat : TALenum; FData : TALvoid; FSize : TALsizei; FFreq : TALsizei; FLoop : TALint; FBuffer : TALuint; public constructor Create; destructor Destroy; override; function LoadWavFromStream(Stream: TStream): Boolean; function LoadWavFromFile(FileName: PWideChar): Boolean; property Format : TALenum read FFormat; property Data : TALvoid read FData; property Size : TALsizei read FSize; property Freq : TALsizei read FFreq; property Loop : TALint read FLoop; property Buffer : TALuint read FBuffer; end; // // TxeSound // TxeSound = class(TxeBaseObject) private FParent : TxeAudio; FVolume : Single; FSource : TALuint; FBuffer : TxeSoundBuffer; public constructor Create(aParent: TxeAudio; aSoundBuffer: TxeSoundBuffer); destructor Destroy; override; procedure Play(aVolume,aPan: Single); end; // // TxeAudio // TxeAudio = class(TxeBaseObject) private FSounds : TStringList; FSourcePool : array[0..cMaxSources - 1] of TALuint; // function get a free source for playing purposes function AcquireSource: TALuint; public constructor Create; destructor Destroy; override; procedure Clear; function LoadSoundFromFile(aFileName: PWideChar): TxeSound; end; // DLL interface routines function Audio_LoadSoundFromFile(AudioInst: LongWord; aFileName: PWideChar): LongWord; cdecl; procedure Sound_Play (SoundInst: LongWord; aVolume: Single); cdecl; implementation uses SysUtils, xeEngine_logfile, unit_wavbuffer, WaveFileParser; // DLL interface routines function Audio_LoadSoundFromFile(AudioInst: LongWord; aFileName: PWideChar): LongWord; begin Result := LongWord(TxeAudio(AudioInst).LoadSoundFromFile(aFileName)); end; procedure Sound_Play(SoundInst: LongWord; aVolume: Single); begin TxeSound(SoundInst).Play(aVolume,1); end; const listenerPos: array[1..3] of TALfloat =(0.0,0.0,0.0); listenerVel: array[1..3] of TALfloat =(0.0,0.0,0.0); listenerOri: array[1..6] of TAlfloat =(0.0,0.0,1.0, 0.0,1.0,0.0); source0Pos : array[1..3] of TALfloat =( 0.0, 0.0, 0.0); source0Vel : array[1..3] of TALfloat =( 0.0, 0.0, 0.0); // // TxeAudio // constructor TxeAudio.Create; var ALResult: TALenum; begin inherited Create(False); if not InitOpenAL then begin LogFile_LogMessage('Error initializing OpenAL!'); end; alutInit(nil,[]); alGenSources(cMaxSources,@FSourcePool[0]); ALResult := alGetError; if ALResult <> AL_NO_ERROR then begin LogFile_LogMessage('Error creating OpenAL sources!'); end; alListenerfv(AL_POSITION ,@listenerPos); alListenerfv(AL_VELOCITY ,@listenerVel); alListenerfv(AL_ORIENTATION,@listenerOri); FSounds := TStringList.Create; FSounds.Sorted := True; FSounds.Duplicates := dupIgnore; end; destructor TxeAudio.Destroy; var i: Integer; begin Clear; alDeleteSources(cMaxSources,@FSourcePool); FSounds.Free; alutExit; inherited Destroy; end; procedure TxeAudio.Clear; var i: Integer; begin for i := 0 to cMaxSources - 1 do alSourceStop(FSourcePool[i]); for i := FSounds.Count - 1 downto 0 do TxeSoundBuffer(FSounds.Objects[i]).Free; FSounds.Clear; end; function TxeAudio.LoadSoundFromFile(aFileName: PWideChar): TxeSound; var FileName: WideString; Name : WideString; Index : Integer; Buffer : TxeSoundBuffer; Ext : WideString; begin Result := nil; if not FileExists(aFileName) then Exit; FileName := ExtractFileName(WideString(aFileName)); Ext := LowerCase(ExtractFileExt(FileName)); if Ext <> '.wav' then Exit; Name := ChangeFileExt(FileName,''); if FSounds.Find(Name,Index) then Buffer := TxeSoundBuffer(FSounds.Objects[Index]) else begin Buffer := TxeSoundBuffer.Create; Buffer.LoadWavFromFile(aFileName); FSounds.AddObject(Name,Buffer); end; Result := TxeSound.Create(Self,Buffer); end; function TxeAudio.AcquireSource: TALuint; var i : Integer; State: PALint; begin Result := 0; for i := 0 to cMaxSources - 1 do begin alGetSourcei(FSourcePool[i],AL_SOURCE_STATE,@State); if State <> PALint(AL_PLAYING) then // this source is free so return it begin Result := FSourcePool[i]; Exit; end; end; end; // // TxeSoundBuffer // constructor TxeSoundBuffer.Create; begin inherited Create(True); FFormat := 0; FData := nil; FSize := 0; FFreq := 0; FBuffer := 0; end; destructor TxeSoundBuffer.Destroy; begin if FBuffer <> 0 then alDeleteBuffers(1,@FBuffer); inherited Destroy; end; function TxeSoundBuffer.LoadWavFromStream(Stream: TStream): Boolean; var Mem: TMemoryStream; begin Mem := TMemoryStream.Create; try Stream.Seek(0,soFromBeginning); Mem.LoadFromStream(Stream); Mem.Seek(0,soFromBeginning); alutLoadWAVStream(Mem,FFormat,FData,FSize,FFreq,FLoop); alGenBuffers(1,@FBuffer); alBufferData(FBuffer,FFormat,FData,FSize,FFreq); alutUnloadWAV(FFormat,FData,FSize,FFreq); finally Mem.Free; end; Result := True; end; function TxeSoundBuffer.LoadWavFromFile(FileName: PWideChar): Boolean; var WAVFile: TFileStream; begin Result := False; if not FileExists(String(FileName)) then Exit; WAVFile := TFileStream.Create(String(FileName),fmOpenRead or fmShareDenyWrite); try Result := LoadWavFromStream(WAVFile); finally WAVFile.Free; end; end; // // TxeSound // constructor TxeSound.Create(aParent: TxeAudio; aSoundBuffer: TxeSoundBuffer); begin inherited Create(True); FSource := 0; FVolume := 1.0; FBuffer := aSoundBuffer; FParent := aParent; end; destructor TxeSound.Destroy; begin inherited Destroy; end; procedure TxeSound.Play(aVolume,aPan: Single); begin FSource := FParent.AcquireSource; if FSource = 0 then Exit; FVolume := aVolume; alSourcef (FSource, AL_PITCH , 1.0); alSourcef (FSource, AL_GAIN , FVolume); alSourcefv(FSource, AL_POSITION , @source0Pos); alSourcefv(FSource, AL_VELOCITY , @source0Vel); alSourcei (FSource, AL_BUFFER , FBuffer.Buffer); alSourcei (FSource, AL_LOOPING , AL_FALSE); alSourcePlay(FSource); end; end.
cheers,
Paul
Games:
Seafox
Pages:
Syntax Error Software
itch.io page
Online Chess
http://gameknot.com/#paul_nicholls
Bookmarks