📄 wavestorage.pas
字号:
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 + -