?? mmwave.pas
字號(hào):
{ set the bytes to play }
FTotalBytes:= LengthBytes;
FBytesLeft := FTotalBytes - SamplesToBytes(aPos);
FCurRegion := -1;
FRegionLeft:= -1;
InitPlayFadeList(True); { reset fade params }
i := 0;
SampleCount := 0;
while (i < FRegions.Count) do
begin
inc(SampleCount,FRegions[i].dwLength);
if (SampleCount >= aPos) then
begin
aPosition := FRegions[i].dwStartPos + (FRegions[i].dwLength-(SampleCount-aPos));
if wioWaveSetPosition(FPWAVEIOCB, SamplesToRealSamples(aPosition)) <> 0 then
if wioWaveSetPosition(FPWAVEIOCB, SamplesToRealSamples(aPosition)) <> 0 then
raise EMMWaveError.Create(LoadResStr(IDS_WFSEEKERROR));
FRegionLeft := SamplesToBytes(SampleCount-aPos);
FCurRegion := i;
exit;
end;
inc(i);
end;
raise EMMWaveError.Create(LoadResStr(IDS_WFSEEKERROR));
end;
end;
end;
{-- TMMWave --------------------------------------------------------------}
function TMMWave.GetPosition: Longint;
begin
Result := -1;
if (FPWAVEIOCB <> Nil) then
with FPWaveIOCB^ do
begin
Result := SamplesToTimeFormat(FPosition);
end;
end;
{-- TMMWave --------------------------------------------------------------}
function TMMWave.GetLengthSamples: Longint;
var
i: integer;
begin
Result := 0;
if (FPWAVEIOCB <> Nil) then
begin
if (FRegions.Count = 0) then
begin
Result := RealSamplesToSamples(FEndPos-FStartPos);
end
else
begin
Result := 0;
for i := 0 to FRegions.Count-1 do inc(Result,FRegions[i].dwLength);
end;
end;
end;
{-- TMMWave --------------------------------------------------------------}
function TMMWave.GetLengthBytes: Longint;
begin
Result := SamplesToBytes(LengthSamples);
end;
{-- TMMWave --------------------------------------------------------------}
function TMMWave.GetLength: Longint;
begin
Result := SamplesToTimeFormat(LengthSamples);
end;
{-- TMMWave --------------------------------------------------------------}
function TMMWave.ReadInternal(Buffer: PChar; NumBytes: Longint): Longint;
begin
Result := wioWaveReadData(FPWaveIOCB, Buffer, NumBytes);
end;
{-- TMMWave --------------------------------------------------------------}
function TMMWave.ReadDataBytes(Buffer: PChar; NumBytes: Longint): Longint;
var
nBytes,nRead,Res: Longint;
begin
Result := -1;
if (FPWAVEIOCB <> Nil) and (FBytesLeft > 0) then
begin
nRead := 0;
NumBytes := Min(NumBytes,FBytesLeft);
while (NumBytes > 0) do
begin
if (FRegionLeft > 0) then
begin
nBytes := Min(NumBytes,FRegionLeft);
Res := ReadInternal(Buffer+nRead, nBytes);
if (Res <= 0) then break;
dec(NumBytes,Res);
inc(nRead, Res);
dec(FRegionLeft, Res);
end
else if (FCurRegion < FRegions.Count-1) then
begin
inc(FCurRegion);
FRegionLeft := FRegions[FCurRegion].dwLengthBytes;
wioWaveSetPosition(FPWAVEIOCB, SamplesToRealSamples(FRegions[FCurRegion].dwStartPos));
end
else
begin
{ should not happen, however, no more data to read }
FBytesLeft := 0;
break;
end;
end;
Result := nRead;
if (Result > 0) then
begin
if (FPlayFadeList <> nil) and (FPlayFadeList.Count > 1) and not FIgnoreFades then
begin
if (PWaveFormat.wFormatTag = WAVE_FORMAT_PCM) then
begin
pcmVolumeFade(PWaveFormat,Buffer, Result, FPlayFadeList);
end;
end;
dec(FBytesLeft, Result);
FPosition := SamplesToRealSamples(BytesToSamples(FTotalBytes - FBytesLeft));
end
else
begin
Result := 4;
PLongint(Buffer)^ := 0;
FBytesLeft := 0;
FRegionLeft := 0;
FPosition := Length;
end;
end;
end;
{-- TMMWave --------------------------------------------------------------}
function TMMWave.ReadDataSamples(Buffer: PChar; NumSamples: Longint): Longint;
var
nBytes: Longint;
begin
Result := -1;
if (FPWAVEIOCB <> Nil) then
begin
nBytes := SamplesToBytes(NumSamples);
nBytes := ReadDataBytes(Buffer,nBytes);
if (nBytes > 0) then
Result := BytesToSamples(nBytes);
end;
end;
{-- TMMWave --------------------------------------------------------------}
function TMMWave.WriteDataBytes(Buffer: PChar; NumBytes: Longint): Longint;
begin
Result := -1;
if (FMemoryWave <> nil) then
raise EMMWaveError.Create(LoadResStr(IDS_WFMEMFILEERROR));
if (FPWAVEIOCB <> Nil) then
with FPWAVEIOCB^ do
begin
Result := wioWaveWriteData(FPWaveIOCB, Buffer, NumBytes);
FEndPos := dwLastSample;
InitRegionList;
end;
end;
{-- TMMWave --------------------------------------------------------------}
function TMMWave.WriteDataSamples(Buffer: PChar; NumSamples: Longint): Longint;
begin
Result := -1;
if (FMemoryWave <> nil) then
raise EMMWaveError.Create(LoadResStr(IDS_WFMEMFILEERROR));
if (FPWAVEIOCB <> Nil) then
with FPWAVEIOCB^ do
begin
Result := wioWaveWriteSamples(FPWaveIOCB, Buffer, NumSamples);
FEndPos := dwLastSample;
InitRegionList;
end;
end;
{-- TMMWave --------------------------------------------------------------}
function TMMWave.PlaySound(aValue: TMMPlayMode): Boolean;
Var
aBuf: PChar;
uFlags: Word;
begin
Result := False;
case aValue of
pmSync : uFlags := SND_SYNC OR SND_NoDefault;
pmASync: uFlags := SND_ASYNC OR SND_NoDefault;
pmLoop : uFlags := SND_ASYNC OR SND_LOOP OR SND_NoDefault;
else uFlags := 0;
end;
if (Not Empty) then
begin
if (FMemoryWave <> nil) then
begin
uFlags := uFlags OR SND_MEMORY;
Result := SndPlaySound(FMemoryWave.Memory, uFlags)
end
else
begin
aBuf := StrAlloc(System.Length(FFileName)+1);
try
StrPCopy(aBuf, FFileName);
Result := SndPlaySound(aBuf, uFlags);
finally
StrDispose(aBuf);
end;
end;
end;
end;
{-- TMMWave --------------------------------------------------------------}
Procedure TMMWave.StopSound;
Var
uFlags: Word;
begin
uFlags := 0;
if (FMemoryWave <> nil) then uFlags := SND_MEMORY;
SndPlaySound(nil, uFlags);
end;
{== TMMCustomWaveFile ====================================================}
constructor TMMCustomWaveFile.Create(aOwner: TComponent);
begin
inherited Create(aOwner);
FObserver := TMMObserver.Create;
FObserver.OnNotify := WaveChanged;
SetWaveEx(TMMWave.Create);
FEnabled := True;
FOpen := False;
FStarted := False;
FSilence := 128;
FOverwrite:= True;
ErrorCode := ComponentRegistered(InitCode, Self, ClassName);
if (ErrorCode <> 0) then RegisterFailed(InitCode, Self , ClassName);
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
Destructor TMMCustomWaveFile.Destroy;
begin
Closed;
FWave.OnChange := nil;
SetWaveEx(nil);
FObserver.Free;
inherited Destroy;
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.DoOpen;
begin
if assigned(FOnOpen) then FOnOpen(Self);
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.DoClose;
begin
if assigned(FOnClose) then FOnClose(Self);
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.SetWave(aValue: TMMWave);
begin
if (aValue <> FWave) then FWave.assign(aValue);
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.SetWaveEx(aValue: TMMWave);
begin
if (aValue <> FWave) then
begin
if (FWave <> nil) then
begin
FWave.RemoveObserver(FObserver);
FWave.Free;
end;
FWave := aValue;
if (FWave <> nil) then FWave.AddObserver(FObserver);
end;
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.LoadFromFile(const Filename: string);
begin
FWave.LoadFromFile(FileName);
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.SaveToFile(const Filename: string);
begin
FWave.SaveToFile(FileName);
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
function TMMCustomWaveFile.PlaySound(aValue: TMMPlayMode): Boolean;
begin
Result := FWave.PlaySound(aValue);
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.StopSound;
begin
FWave.StopSound;
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.DoChanged;
begin
if assigned(FOnChange) then FOnChange(Self);
try
{ when we would create a new file we use the previous wave format }
if not FWave.FileMustExist and (FWave.PWaveFormat = nil) then exit;
{ Set the new pWaveFormat }
PWaveFormat := FWave.PWaveFormat;
finally
if assigned(FOnChanged) then FOnChanged(Self);
end;
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.WaveChanged(Sender, Data: TObject);
begin
DoChanged;
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.SetPWaveFormat(aValue: PWaveFormatEx);
begin
inherited SetPWaveFormat(aValue);
if (PWaveFormat <> nil) and
(PWaveFormat^.wFormatTag = WAVE_FORMAT_PCM) and (PWaveFormat^.wBitsPerSample = 8) then
FSilence := 128
else
FSilence := 0;
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.Opened;
begin
inherited Opened;
if not FOpen then
begin
if (Input <> nil) then
begin{ we are a Output port }
{ make sure we have the right WaveFormat }
PWaveFormat := Input.PWaveFormat;
{ we should save anything to the file, create it }
if (PWaveFormat <> nil) and (Wave.FFileName <> '') then
begin
if not FOverWrite and not Wave.Empty then
Wave.OpenFile
else
Wave.CreateFile(Wave.FFileName, PWaveFormat);
FOpen := True;
end;
end
else
begin{ we are the Input Data port }
{ if we have a WaveFile then open the file for reading }
if (not Wave.Empty) then
begin
Wave.OpenFile;
FOldStart := Wave.Position;
FOpen := True;
end;
end;
{ this can occur in a different thread, so we must synchronize }
if FOpen and assigned(FOnOpen) then
{$IFNDEF BUILD_ACTIVEX}
GlobalSynchronize(DoOpen);
{$ELSE}
DoOpen;
{$ENDIF}
end;
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.Started;
begin
inherited Started;
if not FStarted and FOpen then
begin
FStarted := True;
if (Input = nil) then
Wave.Position := FOldStart;
Wave.InitPlayFadeList(False);
end;
end;
{-- TMMCustomWaveFile ----------------------------------------------------}
procedure TMMCustomWaveFile.Stopped;
begin
if FOpen and FStarted then
begin
FStarted := False;
if (Wave.PlayFadeList <> nil) then Wave.PlayFadeList.Clear;
end;
inherited Stopped;
end;
{-- TMMCustomWaveFile --------
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -