HoShiMin
9/2/2015 - 8:44 PM

Проигрыватель WAV-файлов на системной пищалке

Проигрыватель WAV-файлов на системной пищалке

unit BeeWave;

interface

uses
  Windows, Classes, WAVParser, BeeperWrapper, TimeManagement;

type
  TBeeWavePlayer = class
    private
      FWAVFile: TWAVFile;
    public
      constructor Create(const FileName: string); overload;
      constructor Create(const MemoryStream: TMemoryStream); overload;

      procedure Play;
  end;

implementation

//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

function GetByte(BaseAddress: Pointer; Offset: NativeUInt): Byte; inline;
begin
  Result := Byte((Pointer(NativeUInt(BaseAddress) + Offset))^);
end;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function GetWord(BaseAddress: Pointer; Offset: NativeUInt): Word; inline;
begin
  Result := Word((Pointer(NativeUInt(BaseAddress) + Offset))^);
end;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function GetDWord(BaseAddress: Pointer; Offset: NativeUInt): LongWord; inline;
begin
  Result := LongWord((Pointer(NativeUInt(BaseAddress) + Offset))^);
end;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

function GetQWord(BaseAddress: Pointer; Offset: NativeUInt): UInt64; inline;
begin
  Result := UInt64((Pointer(NativeUInt(BaseAddress) + Offset))^);
end;

//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

{ TBeeWavePlayer }

constructor TBeeWavePlayer.Create(const FileName: string);
begin
  FWAVFile := TWAVFile.Create(FileName);
end;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

constructor TBeeWavePlayer.Create(const MemoryStream: TMemoryStream);
begin
  FWAVFile := TWAVFile.Create(MemoryStream);
end;

// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

procedure TBeeWavePlayer.Play;
var
  I: Integer;
  T1, ElementDelay: Double;
  Sample: Integer;

  IsMute: Boolean;

  function IsValueInInterval(Value, Min, Max: Single): Boolean; inline;
  begin
    Result := (Value > Min) and (Value < Max);
  end;

begin
  ElementDelay := 1 / FWAVFile.SampleRate;
  SetBeeperRegime;

  IsMute := False;
  SetBeeperFrequency(18200);
  StartBeeper;

  for I := 0 to (FWAVFile.DataSize div FWAVFile.BlockAlign) - 1 do
  begin
    T1 := GetTimer;

    Sample := 0;
    case FWAVFile.BlockAlign of
      1: Sample := GetByte (FWAVFile.Data, I * FWAVFile.BlockAlign);
      2: Sample := GetWord (FWAVFile.Data, I * FWAVFile.BlockAlign);
      4: Sample := GetDWord(FWAVFile.Data, I * FWAVFile.BlockAlign);
    end;

    if Sample > 0 then
    begin
      if IsMute then
      begin
        StartBeeper;
        IsMute := False;
      end;
    end
    else
    begin
      StopBeeper;
      IsMute := True;
    end;

    MicroSleep(ElementDelay - (GetTimer - T1));
  end;

  StopBeeper;
end;

end.