📄 mmwmixer.pas
字号:
{ don't allow ring connection }
if (Output <> nil) then
Result := Output.CanConnectInput(aComponent)
else
Result := True;
end;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.CanConnectInput3(aComponent: TComponent): Boolean;
begin
Result := False;
if (aComponent <> Self) and (aComponent is TMMDSPComponent) and
(aComponent <> Input1) and (aComponent <> Input2) and (aComponent <> Input4) and
(GetPropInfo(TMMDSPComponent(aComponent).ClassInfo, 'Output') <> nil) then
begin
{ don't allow ring connection }
if (Output <> nil) then
Result := Output.CanConnectInput(aComponent)
else
Result := True;
end;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.CanConnectInput4(aComponent: TComponent): Boolean;
begin
Result := False;
if (aComponent <> Self) and (aComponent is TMMDSPComponent) and
(aComponent <> Input1) and (aComponent <> Input2) and (aComponent <> Input3) and
(GetPropInfo(TMMDSPComponent(aComponent).ClassInfo, 'Output') <> nil) then
begin
{ don't allow ring connection }
if (Output <> nil) then
Result := Output.CanConnectInput(aComponent)
else
Result := True;
end;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.TimeFormatToSamples(aValue: int64): int64;
begin
Result := 0;
if (PWaveFormat <> Nil) then
begin
case FTimeFormat of
tfMilliSecond: Result := wioTimeToSamples64(PWaveFormat, aValue);
tfByte : Result := wioBytesToSamples64(PWaveFormat, aValue);
tfSample : Result := aValue;
end;
end;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.SamplesToTimeFormat(aValue: int64): int64;
begin
Result := 0;
if (PWaveFormat <> Nil) then
begin
case FTimeFormat of
tfMilliSecond: Result := wioSamplesToTime64(PWaveFormat, aValue);
tfByte : Result := wioSamplesToBytes64(PWaveFormat, aValue);
tfSample : Result := aValue;
end;
end;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.SetTimeFormat(aValue: TMMTimeFormats);
begin
if (aValue <> FTimeFormat) then FTimeFormat := aValue;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.SetInputs(index: integer; aValue: TMMDSPComponent);
procedure SetPort(idx: integer; PortName: string; C: TMMDSPComponent);
type
TCheckProc = function(aComponent: TComponent): Boolean of object;
var
CheckProc: TCheckProc;
begin
case index of
0: CheckProc := CanConnectInput1;
1: CheckProc := CanConnectInput2;
2: CheckProc := CanConnectInput3;
3: CheckProc := CanConnectInput4;
end;
with FTracks[idx] do
if (C <> InPort) and ((C = nil) or CheckProc(C)) then
begin
CloseInput(idx);
if (InPort <> nil) then
begin
GlobalDeconnectNotification(Self,poInput,PortName);
InPort := nil;
FInpPropName := '';
end;
if (C <> nil) then
begin
GlobalDeconnectNotification(C,poOutput,'Output');
InPort := C;
FInpPropName := 'Output';
InPort.SetOutputPort(Self,PortName);
if FOpen and (StartSamplePos < FLocator) then Done := False;
end;
end;
end;
begin
SetPort(index,'Input'+IntToStr(index+1),aValue);
{$IFDEF WIN32}
{$IFDEF TRIAL}
{$DEFINE _HACK1}
{$I MMHACK.INC}
{$ENDIF}
{$ENDIF}
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.GetTracks(index: integer): PMMMixerTrack;
begin
Result := @FTracks[index];
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.GetInputs(index: integer): TMMDSPComponent;
begin
Result := FTracks[index].InPort;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.SetStartPos(index: integer; aValue: int64);
procedure SetPosition(var aTrack: TMMMixerTrack; aValue: int64);
begin
if (aTrack.StartPosition <> aValue) then
begin
aTrack.StartPosition := aValue;
aTrack.StartSamplePos:= TimeFormatToSamples(aValue);
if FOpen and (aTrack.StartSamplePos <= FLocator) then aTrack.Done := False;
end;
end;
begin
SetPosition(FTracks[index],Min64(aValue,SamplesToTimeFormat(MIX_MAX_INT64)));
{$IFDEF WIN32}
{$IFDEF TRIAL}
{$DEFINE _HACK2}
{$I MMHACK.INC}
{$ENDIF}
{$ENDIF}
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.GetStartPos(index: integer): int64;
begin
Result := 0;
if (FTracks[index].InPort <> nil) then
Result := FTracks[index].StartPosition;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.SetLoops(index: integer; aValue: Boolean);
procedure SetLoop(var aTrack: TMMMixerTrack; aValue: Boolean);
begin
if (aTrack.Loop <> aValue) then
begin
aTrack.Loop := aValue;
aTrack.LoopTempCount := aTrack.LoopCount;
if FOpen and (aTrack.StartSamplePos <= FLocator) then aTrack.Done := False;
end;
end;
begin
SetLoop(FTracks[index],aValue);
{$IFDEF WIN32}
{$IFDEF TRIAL}
{$DEFINE _HACK3}
{$I MMHACK.INC}
{$ENDIF}
{$ENDIF}
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.GetLoops(index: integer): Boolean;
begin
Result := False;
if (FTracks[index].InPort <> nil) then
Result := FTracks[index].Loop;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.SetLoopCounts(index: integer; aValue: integer);
procedure SetLoopCount(var aTrack: TMMMixerTrack; aValue: integer);
begin
if (aTrack.LoopCount <> aValue) then
begin
aTrack.LoopCount := aValue;
aTrack.LoopTempCount := aValue;
end;
end;
begin
SetLoopCount(FTracks[index],aValue);
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.GetLoopCounts(index: integer): integer;
begin
Result := 0;
if (FTracks[index].InPort <> nil) then
Result := FTracks[index].LoopCount;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.GetMixPosition: int64;
begin
Result := 0;
if FOpen and FStarted then
Result := SamplesToTimeFormat(FLocator);
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.SetMaxPlayTime(aValue: int64);
begin
FMaxPlayTime := TimeFormatToSamples(Min64(aValue,SamplesToTimeFormat(MIX_MAX_INT64)));
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.GetMaxPlayTime: int64;
begin
Result := SamplesToTimeFormat(FMaxPlayTime);
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.SetVolumeValues(index: integer; aValue: Longint);
begin
case index of
0: if (FVolume = aValue) then exit else FVolume := aValue;
1: if (FPanning = aValue) then exit else FPanning:= aValue;
end;
CalcVolume(VOLUMEBASE, FVolume, FPanning, FLeftVolume, FRightVolume);
end;
{-- TMMWaveMixer --------------------------------------------------------------}
function TMMWaveMixer.AllocBuffer(Size: Longint): PBufferItem;
begin
Result := GlobalAllocMem(SizeOf(TBufferItem)+Size);
Result^.lpData := PChar(Result)+sizeOf(TBufferItem);
Result^.dwBufferLength := Size;
Result^.dwBytesLoaded := 0;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.CreateBuffers;
var
i: integer;
begin
FRealBufSize := Max(QUEUE_READ_SIZE,BufferSize);
{ create the MixPool }
FMixPool := pcmAllocMixPool(MAXTRACKS);
{ create the Temp Buffer }
FTempBuffer := GlobalAllocMem(2*FRealBufSize);
{ create the BufferPool }
FBufferPool := GlobalAllocMem(MAXTRACKS*sizeOf(PBufferItem));
for i := 0 to MAXTRACKS-1 do
begin
FBufferPool^[i] := AllocBuffer(FRealBufSize);
end;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.FreeBuffers;
var
i: integer;
begin
if (FBufferPool <> nil) then
begin
for i := 0 to MAXTRACKS-1 do
begin
{ unlock and free memory for Buffer }
GlobalFreeMem(Pointer(FBufferPool^[i]));
end;
GlobalFreeMem(Pointer(FBufferPool));
end;
GlobalFreeMem(Pointer(FMixPool));
GlobalFreeMem(Pointer(FTempBuffer));
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.CloseAllTracks;
var
i: integer;
begin
{ close all controls }
for i := 0 to MAXTRACKS-1 do
begin
CloseInput(i);
end;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.Open;
begin
if not FOpen then
begin
CreateBuffers;
{ create a critical section }
InitCritical;
FOpen := True;
FStarted := False;
FOverflow := False;
end;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.Close;
begin
if FOpen then
begin
{ reset the open flag }
FOpen := False;
{ make sure all samples closed }
CloseAllTracks;
{ release all buffers }
FreeBuffers;
{ release the critical section }
DoneCritical;
end;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.Reset;
var
i: integer;
begin
if FOpen then
begin
{ make sure all samples closed }
CloseAllTracks;
FOverflow := False;
FLocator := 0;
for i := 0 to MAXTRACKS-1 do
begin
FTracks[i].Done := False;
end;
end;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.Opened;
begin
inherited Opened;
Open;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.Closed;
begin
Close;
inherited Closed;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.Started;
var
i: integer;
begin
inherited Started;
Reset;
FStarted := True;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.Stopped;
begin
if FStarted then
begin
EnterCritical;
try
FStarted := False;
{ make sure all samples closed }
CloseAllTracks;
finally
LeaveCritical;
end;
end;
inherited Stopped;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.Reseting;
begin
Reset;
inherited Reseting;
end;
{-- TMMWaveMixer --------------------------------------------------------------}
procedure TMMWaveMixer.SetInputDone(index: integer; aValue: Boolean);
begin
if (index >= 0) and (index < MAXTRACKS) then
begin
if (FTracks[index].InPort <> nil) then
begin
EnterCritical;
try
if aValue then CloseInput(index);
FTracks[index].Done := aValue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -