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

📄 wavestorage.pas

📁 一整套声音录制控件
💻 PAS
📖 第 1 页 / 共 3 页
字号:
      if NeededBytes > DstBufferSize then
      begin
        DstBufferSize := NeededBytes;
        ReallocMem(DstBuffer, DstBufferSize);
      end;
      FillChar(ACMHeader, SizeOf(TACMSTREAMHEADER), 0);
      ACMHeader.cbStruct := SizeOf(TACMSTREAMHEADER);
      ACMHeader.pbSrc := SrcBuffer;
      ACMHeader.cbSrcLength := BufferOffset;
      ACMHeader.pbDst := DstBuffer;
      ACMHeader.cbDstLength := NeededBytes;
      acmStreamPrepareHeader(ACMStream, ACMHeader, 0);
      acmStreamConvert(ACMStream, ACMHeader, ACM_STREAMCONVERTF_END);
      acmStreamUnprepareHeader(ACMStream, ACMHeader, 0);
      inherited Write(ACMHeader.pbDst^, ACMHeader.cbDstLengthUsed);
    end;
    acmStreamClose(ACMStream, 0);
    Reset;
  end;
  Result := inherited EndRewrite;
end;

function TWaveStreamConverter.Write(const Buffer; Count: Integer): Integer;
var
  NeededBytes: DWORD;
  Flags: Integer;
begin
  if ACMStream <> 0 then
  begin
    Result := -1;
    Flags := ACM_STREAMCONVERTF_BLOCKALIGN;
    if Position = 0 then
      Flags := Flags or ACM_STREAMCONVERTF_START;
    if BufferOffset > 0 then
    begin
      if BufferOffset + DWORD(Count) > SrcBufferSize then
      begin
        SrcBufferSize := BufferOffset + DWORD(Count);
        ReallocMem(SrcBuffer, SrcBufferSize);
      end;
      CopyMemory(Pointer(DWORD(SrcBuffer) + BufferOffset), @Buffer, Count);
    end;
    acmStreamSize(ACMStream, DWORD(Count) + BufferOffset, NeededBytes, ACM_STREAMSIZEF_SOURCE);
    if NeededBytes > DstBufferSize then
    begin
      DstBufferSize := NeededBytes;
      ReallocMem(DstBuffer, DstBufferSize);
    end;
    FillChar(ACMHeader, SizeOf(TACMSTREAMHEADER), 0);
    ACMHeader.cbStruct := SizeOf(TACMSTREAMHEADER);
    if BufferOffset <> 0 then
      ACMHeader.pbSrc := SrcBuffer
    else
      ACMHeader.pbSrc := @Buffer;
    ACMHeader.cbSrcLength := BufferOffset + DWORD(Count);
    ACMHeader.pbDst := DstBuffer;
    ACMHeader.cbDstLength := NeededBytes;
    acmStreamPrepareHeader(ACMStream, ACMHeader, 0);
    acmStreamConvert(ACMStream, ACMHeader, Flags);
    acmStreamUnprepareHeader(ACMStream, ACMHeader, 0);
    if inherited Write(ACMHeader.pbDst^, ACMHeader.cbDstLengthUsed) >= 0 then
      Result := Count;
    BufferOffset := 0;
    if ACMHeader.cbSrcLength <> ACMHeader.cbSrcLengthUsed then
    begin
      BufferOffset := ACMHeader.cbSrcLength - ACMHeader.cbSrcLengthUsed;
      if BufferOffset > SrcBufferSize then
      begin
        SrcBufferSize := BufferOffset;
        ReallocMem(SrcBuffer, SrcBufferSize);
      end;
      CopyMemory(SrcBuffer, Pointer(DWORD(ACMHeader.pbSrc) +
        ACMHeader.cbSrcLengthUsed), BufferOffset);
    end;
  end
  else
    Result := inherited Write(Buffer, Count);
end;

function TWaveStreamConverter.CanRead: Boolean;
var
  Dummy: HACMSTREAM;
begin
  Result := Valid and (not Assigned(fBufferFormat) or
    (acmStreamOpen(Dummy, 0, fWaveFormat, fBufferFormat, nil, 0, 0,
     ACM_STREAMOPENF_QUERY) = 0));
end;

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

function TWaveStreamConverter.EndRead: Boolean;
begin
  if ACMStream <> 0 then
  begin
    acmStreamClose(ACMStream, 0);
    Reset;
  end;
  Result := inherited EndRead;
end;

function TWaveStreamConverter.Read(var Buffer; Count: Integer): Integer;
var
  NeededBytes: DWORD;
  ReadBytes: Integer;
  Flags: Integer;
begin
  if ACMStream <> 0 then
  begin
    Result := -1;
    Flags := 0;
    if Position = 0 then
      Flags := Flags or ACM_STREAMCONVERTF_START;
    acmStreamSize(ACMStream, Count, NeededBytes, ACM_STREAMSIZEF_DESTINATION);
    if NeededBytes > SrcBufferSize then
    begin
      SrcBufferSize := NeededBytes;
      ReallocMem(SrcBuffer, SrcBufferSize);
    end;
    ReadBytes := inherited Read(Pointer(DWORD(SrcBuffer) + BufferOffset)^, NeededBytes - BufferOffset);
    if ReadBytes >= 0 then
    begin
      if DWORD(ReadBytes) + BufferOffset > 0 then
      begin
        if DWORD(ReadBytes) < NeededBytes - BufferOffset then
          Flags := Flags or ACM_STREAMCONVERTF_END
        else
          Flags := Flags or ACM_STREAMCONVERTF_BLOCKALIGN;
        FillChar(ACMHeader, SizeOf(TACMSTREAMHEADER), 0);
        ACMHeader.cbStruct := SizeOf(TACMSTREAMHEADER);
        ACMHeader.pbSrc := SrcBuffer;
        ACMHeader.cbSrcLength := BufferOffset + DWORD(ReadBytes);
        ACMHeader.pbDst := @Buffer;
        ACMHeader.cbDstLength := Count;
        acmStreamPrepareHeader(ACMStream, ACMHeader, 0);
        acmStreamConvert(ACMStream, ACMHeader, Flags);
        acmStreamUnprepareHeader(ACMStream, ACMHeader, 0);
        BufferOffset := 0;
        if ACMHeader.cbSrcLength <> ACMHeader.cbSrcLengthUsed then
        begin
          BufferOffset := ACMHeader.cbSrcLength - ACMHeader.cbSrcLengthUsed;
          CopyMemory(SrcBuffer, Pointer(DWORD(SrcBuffer) +
            ACMHeader.cbSrcLengthUsed), BufferOffset);
        end;
        Result := ACMHeader.cbDstLengthUsed;
      end
      else
        Result := 0;
    end;
  end
  else
    Result := inherited Read(Buffer, Count);
end;

{ TWave }

constructor TWave.Create;
begin
  inherited Create(TMemoryStream.Create, soOwned);
end;

{ TWaveFile }

constructor TWaveFile.Create(const FileName: String; Mode: Word);
begin
  inherited Create(TFileStream.Create(FileName, Mode), soOwned);
end;

{ TWaveConverter }

constructor TWaveConverter.Create;
begin
  inherited Create(TMemoryStream.Create, soOwned);
end;

{ TWaveFileConverter }

constructor TWaveFileConverter.Create(const FileName: String; Mode: Word);
begin
  inherited Create(TFileStream.Create(FileName, Mode), soOwned);
end;

{ TWaveStorage }

constructor TWaveStorage.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fWave := TWave.Create;
end;

destructor TWaveStorage.Destroy;
begin
  fWave.Free;
  inherited Destroy;
end;

procedure TWaveStorage.SetWave(Value: TWave);
begin
  if Wave <> Value then
  begin
    if Assigned(Value) then
    begin
      Value.Stream.Position := 0;
      Wave.LoadFromStream(Value.Stream);
    end
    else
      Wave.Clear;
  end;
end;

procedure TWaveStorage.ReadData(Stream: TStream);
begin
  Wave.LoadFromStream(Stream);
end;

procedure TWaveStorage.WriteData(Stream: TStream);
begin
  Wave.SaveToStream(Stream);
end;

procedure TWaveStorage.DefineProperties(Filer: TFiler);
begin
  inherited DefineProperties(Filer);
  Filer.DefineBinaryProperty('Data', ReadData, WriteData, not Wave.Empty);
end;

procedure TWaveStorage.Assign(Source: TPersistent);
begin
  if Source is TWaveStorage then
    Wave := TWaveStorage(Source).Wave
  else if Source is TWaveItem then
    Wave := TWaveItem(Source).Wave
  else
    inherited Assign(Source);
end;

function TWaveStorage.GetWaveStream(Index: Integer): TStream;
begin
  Result := Wave.Stream;
end;

function TWaveStorage.Equals(Another: TCustomWaveStorage): Boolean;
begin
  if Another is TWaveStorage then
    Result := Wave.Equals(TWaveStorage(Another).Wave)
  else
    Result := False;
end;

{ TWaveItem }

constructor TWaveItem.Create(Collection: TCollection);
begin
  inherited Create(Collection);
  fWave := TWave.Create;
end;

destructor TWaveItem.Destroy;
begin
  fWave.Free;
  inherited Destroy;
end;

procedure TWaveItem.SetWave(Value: TWave);
begin
  if Wave <> Value then
  begin
    if Assigned(Value) then
    begin
      Value.Stream.Position := 0;
      Wave.LoadFromStream(Value.Stream);
    end
    else
      Wave.Clear;
  end;
end;

procedure TWaveItem.ReadData(Stream: TStream);
begin
  Wave.LoadFromStream(Stream);
end;

procedure TWaveItem.WriteData(Stream: TStream);
begin
  Wave.SaveToStream(Stream);
end;

procedure TWaveItem.DefineProperties(Filer: TFiler);
begin
  inherited DefineProperties(Filer);
  Filer.DefineBinaryProperty('Data', ReadData, WriteData, not Wave.Empty);
end;

procedure TWaveItem.Assign(Source: TPersistent);
begin
  if Source is TWaveItem then
  begin
    Wave := TWaveItem(Source).Wave;
    Name := TWaveItem(Source).Name;
    Tag := TWaveItem(Source).Tag;
  end
  else if Source is TWaveStorage then
    Wave := TWaveStorage(Source).Wave
  else
    inherited Assign(Source);
end;

function TWaveItem.GetDisplayName: String;
var
  WaveInfo: String;
begin
  if (Wave <> nil) and (Wave.Stream.Size <> 0) then
  begin
    if Wave.Valid then
      WaveInfo := Wave.AudioFormat + ', ' +
                  IntToStr(Wave.BitRate) + ' kbps, ' +
                  MS2Str(Wave.Length, msAh) + ' sec.'
    else
      WaveInfo := 'Invalid Content';
  end
  else
    WaveInfo := 'Empty';
  Result := Name + ' (' + WaveInfo + ')';
end;

{ TWaveItems }

{$IFDEF COMPILER4_UP}
constructor TWaveItems.Create(AOwner: TPersistent; ItemClass: TWaveItemClass);
{$ELSE}
constructor TWaveItems.Create(AOwner: TPersistent; ItemClass: TWaveItemClass);
{$ENDIF}
begin
  inherited Create(ItemClass);
  fOwner := AOwner;
end;

function TWaveItems.GetOwner: TPersistent;
begin
  Result := fOwner;
end;

function TWaveItems.Add: TWaveItem;
begin
  Result := TWaveItem(inherited Add);
end;

{$IFDEF COMPILER4_UP}
function TWaveItems.Insert(Index: Integer): TWaveItem;
begin
  Result := TWaveItem(inherited Insert(Index));
end;
{$ENDIF}

function TWaveItems.GetItem(Index: Integer): TWaveItem;
begin
  Result := TWaveItem(inherited Items[Index]);
end;

procedure TWaveItems.SetItem(Index: Integer; Value: TWaveItem);
begin
  inherited Items[Index] := Value;
end;

{ TWaveCollection }

constructor TWaveCollection.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  fWaves := TWaveItems.Create(Self, TWaveItem);
end;

destructor TWaveCollection.Destroy;
begin
  fWaves.Free;
  inherited Destroy;
end;

procedure TWaveCollection.SetWaves(const Value: TWaveItems);
begin
  if Waves <> Value then
    Waves.Assign(Value);
end;

function TWaveCollection.GetWaveStream(Index: Integer): TStream;
begin
  Result := Waves[Index].Wave.Stream;
end;

function TWaveCollection.Equals(Another: TCustomWaveStorage): Boolean;
var
  I: Integer;
begin
  if (Another is TWaveCollection) and
     (Waves.Count = TWaveCollection(Another).Waves.Count) then
  begin
    Result := True;
    for I := 0 to Waves.Count - 1 do
      if not Waves[I].Wave.Equals(TWaveCollection(Another).Waves[I].Wave) then
      begin
        Result := False;
        Break;
      end;
  end
  else
    Result := False;
end;

function TWaveCollection.ExportWaveNames(const List: TStrings): Integer;
var
  Index: Integer;
begin
  for Index := 0 to Waves.Count - 1 do
    List.Add(Waves[Index].Name);
  Result := Waves.Count;
end;

function TWaveCollection.IndexOfName(const AName: String): Integer;
var
  Index: Integer;
begin
  Result := -1;
  for Index := 0 to Waves.Count - 1 do
    if CompareText(Waves[Index].Name, AName) = 0 then
    begin
      Result := Index;
      Break;
    end;
end;

end.

⌨️ 快捷键说明

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