Results 1 to 10 of 27

Thread: Win/Linux/Mac OSX Sound API with no .DLL/.SO dependencies?

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #11
    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

    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.
    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.

    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.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •