const
  snd_buffers = 2;
  snd_buffer_size = 4096;

type
  TMotherSoundMan = class //abstract!
  protected
    f_muted: boolean;
    f_current_buffer: integer;
    f_vawdata: TSmallIntArray;
    f_GotNewData: longbool;
  public
    ALVersionMajor, ALVersionMinor: ALCint;
    procedure SetVolume(volume: float); virtual; abstract;
    procedure NewData(begins: TDateTime; samples, rate: integer; data: pointer); virtual; abstract;
    procedure PlaySound(samples, rate: integer; data: pointer); virtual; abstract;
    procedure PlayWav(filename: ansistring);
    procedure Cycle; virtual; abstract;
    procedure Disable; virtual; abstract;
    procedure Enable; virtual; abstract;
    procedure TestGong;
  private
    procedure _Resample(src_ptr, dst_ptr: pointer; src_samples, dst_samples: integer);
  end;

  TOpenALSoundMan = class (TMotherSoundMan)
  protected
    device,
    context: pointer;
    buffers: array [0..snd_buffers - 1] of ALuint;
    source: ALuint; //stereo
    b_source, b_buffer : ALuint;
  public
    constructor Create;
    procedure SetVolume(volume: float); override;
    procedure NewData(begins: TDateTime; samples, rate: integer; data: pointer); override;
    procedure PlaySound(samples, rate: integer; data: pointer); override;
    procedure Cycle; override;
    destructor Destroy; override;
    procedure Disable; override;
    procedure Enable; override;
  end;

 {$ifdef windows}
  TDirectXSoundMan = class (TMotherSoundMan)
  protected
    //CurrentBuffer:
    f_buffer: array [0..snd_buffers - 1] of IDirectSoundBuffer;
    f_b_buffer: IDirectSoundBuffer;
    f_device: IDirectSound8;
    resampleFreq: integer;
  public
    constructor Create;
    procedure SetVolume(volume: float); override;
    procedure NewData(begins: TDateTime; samples, rate: integer; data: pointer); override;
    procedure PlaySound(samples, rate: integer; data: pointer); override;
    procedure Cycle; override;
    destructor Destroy; override;
    procedure Disable; override;
    procedure Enable; override;
  end;
 {$endif}


var
  SoundManager: TMotherSoundMan = nil;
