⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wavestorage.pas

📁 一整套声音录制控件
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  Result := fValid;
end;

function TWaveStreamAdapter.GetPosition: Integer;
begin
  if fState <> wssReady then
    Result := mmioSeek(mmIO, 0, SEEK_CUR) - Integer(fDataOffset)
  else
    Result := -1;
end;

procedure TWaveStreamAdapter.SetPosition(Value: Integer);
begin
  if fState <> wssReady then
    mmioSeek(mmIO, Integer(fDataOffset) + Value, SEEK_SET);
end;

function TWaveStreamAdapter.GetAudioFormat: String;
begin
  if UpdateWaveInfo then
    Result := GetWaveAudioFormat(fWaveFormat)
  else
    Result := '';
end;

function TWaveStreamAdapter.GetBitRate: DWORD;
begin
  if UpdateWaveInfo then
    Result := GetWaveAudioBitRate(fWaveFormat)
  else
    Result := 0;
end;

function TWaveStreamAdapter.GetPeakLevel: Integer;
var
  Data: Pointer;
begin
  Result := -1;
  if LockData(Data, False) then
    try
      Result := GetWaveAudioPeakLevel(Data, fDataSize, fWaveFormat)
    finally
      UnlockData(Data, False);
    end;
end;

function TWaveStreamAdapter.GetLength: DWORD;
begin
  if UpdateWaveInfo then
    Result := GetWaveAudioLength(fWaveFormat, fDataSize)
  else
    Result := 0;
end;

function TWaveStreamAdapter.GetDataSize: DWORD;
begin
  if UpdateWaveInfo then
    Result := fDataSize
  else
    Result := 0;
end;

function TWaveStreamAdapter.GetDataOffset: DWORD;
begin
  if UpdateWaveInfo then
    Result := fDataOffset
  else
    Result := 0;
end;

function TWaveStreamAdapter.GetValid: Boolean;
begin
  Result := UpdateWaveInfo;
end;

function TWaveStreamAdapter.GetEmpty: Boolean;
begin
  Result := (Stream.Size = 0);
end;

function TWaveStreamAdapter.GetPCMFormat: TPCMFormat;
begin
  if UpdateWaveInfo then
    Result := GetPCMAudioFormat(fWaveFormat)
  else
    Result := nonePCM;
end;

function TWaveStreamAdapter.GetWaveFormat: PWaveFormatEx;
begin
  if UpdateWaveInfo then
    Result := fWaveFormat
  else
    Result := nil;
end;

procedure TWaveStreamAdapter.Assign(Source: TPersistent);
begin
  if Source is TWaveStreamAdapter then
  begin
    TWaveStreamAdapter(Source).Stream.Position := 0;
    LoadFromStream(TWaveStreamAdapter(Source).Stream)
  end
  else
    inherited Assign(Source);
end;

procedure TWaveStreamAdapter.LoadFromStream(AStream: TStream);
begin
  DoChanging;
  fStream.Position := 0;
  fStream.CopyFrom(AStream, AStream.Size);
  fStream.Size := AStream.Size;
  fState := wssReady;
  UpdateWaveInfo;
end;

procedure TWaveStreamAdapter.SaveToStream(AStream: TStream);
begin
  fStream.Position := 0;
  AStream.CopyFrom(fStream, fStream.Size);
end;

procedure TWaveStreamAdapter.LoadFromFile(const AFileName: String);
var
  FileStream: TFileStream;
begin
  FileStream := TFileStream.Create(AFileName, fmOpenRead or fmShareDenyWrite);
  try
    LoadFromStream(FileStream);
  finally
    FileStream.Free;
  end;
end;

procedure TWaveStreamAdapter.SaveToFile(const AFileName: String);
var
  FileStream: TFileStream;
begin
  FileStream := TFileStream.Create(AFileName, fmCreate or fmShareExclusive);
  try
    SaveToStream(FileStream);
  finally
    FileStream.Free;
  end;
end;

procedure TWaveStreamAdapter.Clear;
begin
  DoChanging;
  fStream.Size := 0;
  fState := wssReady;
  DoChange;
end;

procedure TWaveStreamAdapter.Refresh;
begin
  fModified := True;
end;

function TWaveStreamAdapter.Equals(Wave: TWaveStreamAdapter): Boolean;
var
  SelfData, WaveData: Pointer;
begin
  if SameFormat(Wave) and (fDataSize = Wave.fDataSize) then
  begin
    LockData(SelfData, False);
    try
      Wave.LockData(WaveData, False);
      try
        Result := CompareMem(SelfData, WaveData, fDataSize);
      finally
        Wave.UnlockData(WaveData, False);
      end;
    finally
      UnlockData(SelfData, False);
    end;
  end
  else
    Result := False;
end;

function TWaveStreamAdapter.SameFormat(WaveStream: TWaveStreamAdapter): Boolean;
begin
  Result := SameWaveFormat(WaveStream.WaveFormat);
end;

function TWaveStreamAdapter.SameWaveFormat(pWaveFormat: PWaveFormatEx): Boolean;
begin
  Result := Valid and Assigned(pWaveFormat) and
    (fWaveFormat^.cbSize = pWaveFormat^.cbSize) and
     CompareMem(fWaveFormat, pWaveFormat, SizeOf(TWaveFormatEx) + fWaveFormat^.cbSize)
end;

procedure TWaveStreamAdapter.Crop;
begin
  if fState <> wssWriting then
    Stream.Size := DataOffset + DataSize;
end;

function TWaveStreamAdapter.Invert: Boolean;
var
  Data: Pointer;
begin
  Result := False;
  if LockData(Data, False) then
    try
      Result := InvertWaveAudio(Data, fDataSize, fWaveFormat);
    finally
      UnlockData(Data, Result);
    end;
end;

function TWaveStreamAdapter.ChangeVolume(Percent: Integer): Boolean;
var
  Data: Pointer;
begin
  Result := False;
  if LockData(Data, False) then
    try
      Result := ChangeWaveAudioVolume(Data, fDataSize, fWaveFormat, Percent);
    finally
      UnlockData(Data, Result);
    end;
end;

function TWaveStreamAdapter.ConvertTo(const pTargetWaveFormat: PWaveFormatEx): Boolean;
var
  Data: Pointer;
  NewData: Pointer;
  NewDataSize: DWORD;
  Succeeded: Boolean;
begin
  Result := False;
  if SameWaveFormat(pTargetWaveFormat) then
    Result := True
  else if LockData(Data, False) then
  begin
    try
      Succeeded := ConvertWaveFormat(fWaveFormat, Data, fDataSize,
        pTargetWaveFormat, NewData, NewDataSize);
    finally
      UnlockData(Data, False);
    end;
    if Succeeded then
      try
        if BeginRewrite(pTargetWaveFormat) then
          try
            Result := (DWORD(Write(NewData^, NewDataSize)) = NewDataSize);
          finally
            EndRewrite;
          end;
      finally
        ReallocMem(NewData, 0);
      end;
  end;
end;

function TWaveStreamAdapter.ConvertToPCM(TargetFormat: TPCMFormat): Boolean;
var
  NewWaveFormat: TWaveFormatEx;
begin
  Result := False;
  if TargetFormat <> nonePCM then
  begin
    SetPCMAudioFormatS(@NewWaveFormat, TargetFormat);
    Result := ConvertTo(@NewWaveFormat);
  end;
end;

function TWaveStreamAdapter.Delete(Pos, Len: DWORD): Boolean;
var
  Data: Pointer;
  ByteStart, ByteEnd: DWORD;
begin
  Result := False;
  if Valid and (Len > 0) and (Pos < Length) then
  begin
    ByteStart := MSecToByte(Pos);
    ByteEnd := ByteStart + MSecToByte(Len);
    if ByteEnd > fDataSize then
      ByteEnd := fDataSize;
    if LockData(Data, True) then
      try
        Move(Pointer(DWORD(Data) + ByteEnd)^,
             Pointer(DWORD(Data) + ByteStart)^,
             fDataSize - ByteEnd);
        if BeginRewrite(fWaveFormat) then
          try
            Result := Write(Data^, fDataSize - (ByteEnd - ByteStart)) > 0;
          finally
            EndRewrite;
          end;
      finally
        UnlockData(Data, False);
      end;
  end;
end;

function TWaveStreamAdapter.Insert(Pos: DWORD; WaveStream: TWaveStreamAdapter): Boolean;
var
  SelfData, WaveData: Pointer;
  BytePos: DWORD;
begin
  Result := False;
  if SameFormat(WaveStream) then
  begin
    BytePos := MSecToByte(Pos);
    if BytePos > fDataSize then
      BytePos := fDataSize;
    if LockData(SelfData, True) then
      try
        if WaveStream.LockData(WaveData, False) then
        begin
          try
            ReallocMem(SelfData, fDataSize + WaveStream.fDataSize);
            Move(Pointer(DWORD(SelfData) + BytePos)^,
                 Pointer(DWORD(SelfData) + BytePos + WaveStream.fDataSize)^,
                 fDataSize - BytePos);
            Move(WaveData^, Pointer(DWORD(SelfData) + BytePos)^, WaveStream.fDataSize);
          finally
            WaveStream.UnlockData(WaveData, False);
          end;
          if BeginRewrite(fWaveFormat) then
            try
              Result := (Write(SelfData^, fDataSize + WaveStream.fDataSize) > 0);
            finally
              EndRewrite;
            end;
        end;
      finally
        UnlockData(SelfData, False);
      end;
  end;
end;

function TWaveStreamAdapter.InsertSilence(Pos, Len: DWORD): Boolean;
var
  BytePos, SilenceLen: DWORD;
  Data: Pointer;
begin
  Result := False;
  if Valid and (Len > 0) then
  begin
    BytePos := MSecToByte(Pos);
    if BytePos > fDataSize then
      BytePos := fDataSize;
    SilenceLen := MSecToByte(Len);
    if LockData(Data, True) then
      try
        ReallocMem(Data, fDataSize + SilenceLen);
        Move(Pointer(DWORD(Data) + BytePos)^,
             Pointer(DWORD(Data) + BytePos + SilenceLen)^,
             fDataSize - BytePos);
        Result := SilenceWaveAudio(Pointer(DWORD(Data) + BytePos), SilenceLen, fWaveFormat);
        if Result and BeginRewrite(fWaveFormat) then
          try
            Result := (Write(Data^, fDataSize + SilenceLen) > 0);
          finally
            EndRewrite;
          end;
      finally
        UnlockData(Data, False);
      end;
  end;
end;

{ TWaveStreamConverter }

destructor TWaveStreamConverter.Destroy;
begin
  ReallocMem(fBufferFormat, 0);
  ReallocMem(SrcBuffer, 0);
  ReallocMem(DstBuffer, 0);
  inherited Destroy;
end;

procedure TWaveStreamConverter.Reset;
begin
  ReallocMem(SrcBuffer, 0);
  SrcBufferSize := 0;
  ReallocMem(DstBuffer, 0);
  DstBufferSize := 0;
  BufferOffset := 0;
  ACMStream := 0;
end;

procedure TWaveStreamConverter.SetBufferFormat(const pWaveFormat: PWaveFormatEx);
begin
  if Assigned(pWaveFormat) then
  begin
    ReallocMem(fBufferFormat, SizeOf(TWaveFormatEx) + pWaveFormat.cbSize);
    CopyMemory(fBufferFormat, pWaveFormat, SizeOf(TWaveFormatEx) + pWaveFormat.cbSize);
  end
  else
    ReallocMem(fBufferFormat, 0);
end;

procedure TWaveStreamConverter.SetBufferFormatPCM(Format: TPCMFormat);
var
  WaveFormat: TWaveFormatEx;
begin
  SetPCMAudioFormatS(@WaveFormat, Format);
  SetBufferFormat(@WaveFormat);
end;

function TWaveStreamConverter.CanRewrite(pWaveFormat: PWaveFormatEx): Boolean;
var
  Dummy: HACMSTREAM;
begin
  Result := not Assigned(fBufferFormat) or (acmStreamOpen(Dummy, 0,
     fBufferFormat, pWaveFormat, nil, 0, 0, ACM_STREAMOPENF_QUERY) = 0);
end;

function TWaveStreamConverter.CanRewritePCM(Format: TPCMFormat): Boolean;
var
  WaveFormatEx: TWaveFormatEx;
begin
  SetPCMAudioFormatS(@WaveFormatEx, Format);
  Result := CanRewrite(@WaveFormatEx);
end;

function TWaveStreamConverter.BeginRewrite(pWaveFormat: PWaveFormatEx): Boolean;
begin
  Result := False;
  if not Assigned(fBufferFormat) or (acmStreamOpen(ACMStream, 0,
     fBufferFormat, pWaveFormat, nil, 0, 0, ACM_STREAMOPENF_NONREALTIME) = 0) then
  begin
    if not inherited BeginRewrite(pWaveFormat) then
    begin
      acmStreamClose(ACMStream, 0);
      ACMStream := 0;
    end
    else
      Result := True;
  end;
end;

function TWaveStreamConverter.EndRewrite: Boolean;
var
  NeededBytes: DWORD;
begin
  if ACMStream <> 0 then
  begin
    if BufferOffset <> 0 then
    begin
      acmStreamSize(ACMStream, BufferOffset, NeededBytes, ACM_STREAMSIZEF_SOURCE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -