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

📄 balancer.pas

📁 TBalncer 音频声道均衡控件 基于 DSPack 的音频均衡控件,可以设置左右声道. 因为原版 DSPack 里是没有对左右声道作选择的,要选择左右声道只能通过一边的喇叭出声,另一边没声.
💻 PAS
📖 第 1 页 / 共 2 页
字号:
    end;
  end;

  MpegAudioDecoder := nil;
  ppEnum := nil;
  ppFilter := nil;
  Result := S_OK;
end;

function TBalancerFilter.CheckInputType(mtIn: PAMMediaType):
  HRESULT;
begin
  if not IsEqualGUID(mtIn^.majortype, MEDIATYPE_Audio) then
  begin
    Result := VFW_E_INVALIDMEDIATYPE;
    Exit;
  end;

  if (not IsEqualGUID(mtIn^.subtype, MEDIASUBTYPE_PCM)) and
    (not IsEqualGUID(mtIn^.subtype, MEDIASUBTYPE_IEEE_FLOAT)) then
  begin
    Result := VFW_E_INVALIDSUBTYPE;
    Exit;
  end;

  if not IsEqualGUID(mtIn^.formattype, FORMAT_WaveFormatEx) then
  begin
    Result := VFW_E_TYPE_NOT_ACCEPTED;
    Exit;
  end;

  Result := S_OK;
end;

constructor TBalancerFilter.Create(ObjName: string; unk:
  IInterface;
  out hr: HRESULT);
var
  pmt: PAMMediaType;
begin
  inherited Create(ObjName, unk, CLSID_Balancer, hr);
  FThisInstance := InterlockedIncrement(InstanceCount);
  pmt := @FPreferred;
  TBCMediaType(pmt).InitMediaType;
  FBalancerLock := TBCCritSec.Create;
  FCurrentChannel := acStereo;
end;

constructor TBalancerFilter.CreateFromFactory(Factory:
  TBCClassFactory;
  const Controller: IInterface);
var
  hr: HRESULT;
begin
  Create(Factory.Name, Controller, hr);
end;

destructor TBalancerFilter.Destroy;
begin
  FBalancerLock.Free;
  inherited;
end;

function TBalancerFilter.get_IPin(out Pin: IPin): HRESULT;
begin
  Result := S_OK;
  FBalancerLock.Lock;
  try
    if (Input = nil) then
    begin
      Pin := nil;
      Exit;
    end;
    if not Input.IsConnected then
      Pin := nil
    else
      Pin := Input.GetConnected;
  finally
    FBalancerLock.UnLock;
  end;
end;

function TBalancerFilter.get_MediaType(out mt: TAMMediaType):
  HRESULT;
begin
  FBalancerLock.Lock;
  try
    mt := FPreferred;
    Result := NOERROR;
  finally
    FBalancerLock.UnLock;
  end;
end;

function TBalancerFilter.get_State(out State: TFilterState):
  HRESULT;
begin
  FBalancerLock.Lock;
  try
    State := self.State;
    Result := NOERROR;
  finally
    FBalancerLock.UnLock;
  end;
end;

function TBalancerFilter.GetPages(out pages: TCAGUID): HResult;
begin
  Pages.cElems := 1;
  Result := NOERROR;
end;

function TBalancerFilter.put_MediaType(mt: PAMMediaType):
  HRESULT;
var
  Pin: IPin;
  pmt: PAMMediaType;
begin
  FBalancerLock.Lock;
  try
    if (State = State_Running) then
    begin
      Result := E_UNEXPECTED;
      Exit;
    end;

    pmt := @FPreferred;
    if (mt = nil) then
      TBCMediaType(pmt).InitMediaType
    else
    begin
      Pin := Input.GetConnected;
      if (Pin <> nil) then
      begin
        if (Pin.QueryAccept(mt^) <> NOERROR) then
        begin
          MessageBox(0,
            PChar('Upstream filter cannot provide this type'),
            PChar('Format Selection'),
            MB_OK or MB_ICONEXCLAMATION);
          Result := VFW_E_TYPE_NOT_ACCEPTED;
          Exit;
        end;
      end;

      Pin := Output.GetConnected;
      if (Pin <> nil) then
      begin
        if (Pin.QueryAccept(mt^) <> NOERROR) then
        begin
          MessageBox(0,
            PChar('Downstream filter cannot accept this type'),
            PChar('Format Selection'),
            MB_OK or MB_ICONEXCLAMATION);
          Result := VFW_E_TYPE_NOT_ACCEPTED;
          Exit;
        end;
      end;
      FPreferred := mt^;
    end;

    if (Input.IsConnected) then
    begin
      pmt := Input.CurrentMediaType.MediaType;
      if not TBCMediaType(pmt).Equal(@FPreferred) then
        Graph.Reconnect(Input);
    end;
    Result := NOERROR;
  finally
    FBalancerLock.Unlock;
  end;
end;

function TBalancerFilter.Transform(Sample: IMediaSample):
  HRESULT;
var
  PWaveFormat: PWaveFormatEx;
  AudioChannel: TAudioChannel;
  Size: Integer;
  PBuffer: PByte;
begin
  try
    PWaveFormat := FInput.CurrentMediaType.MediaType.pbFormat;

    AudioChannel := FCurrentChannel;

    Sample.GetPointer(PBuffer);
    Size := Sample.GetActualDataLength;

    AudioChannelMix(Pbuffer, Size, AudioChannel,
      PWaveFormat.wBitsPerSample);
  finally
    Result := S_OK;
  end;
end;

function TBalancerFilter.SetAudioChannel(AudioChannel:
  TAudioChannel): HRESULT;
  stdcall;
begin
  try
    FCurrentChannel := AudioChannel;
  finally
    Result := S_OK;
  end;
end;

function TBalancer.GetFilter: IBaseFilter;
begin
  Result := FBaseFilter;
end;

function TBalancer.GetName: string;
begin
  Result := Name_Balancer;
end;

procedure TBalancer.NotifyFilter(operation: TFilterOperation; Param: integer =
  0);
begin
  case operation of
    foAdding: FBaseFilter := FFilter as IBaseFilter;
    foRemoving: if FFilter <> nil then
        FFilter.Stop;
    foRemoved: FFilter := nil;
    foRefresh: if assigned(FFilterGraph) then
      begin
        TBalancerFilterGraph(FFilterGraph).RemoveFilter(self);
        TBalancerFilterGraph(FFilterGraph).InsertFilter(self);
      end;
  end;
end;

procedure TBalancer.SetFilterGraph(AFilterGraph: TFilterGraph);
begin
  if AFilterGraph = FFilterGraph then
    exit;
  if FFilterGraph <> nil then
    TBalancerFilterGraph(FFilterGraph).RemoveFilter(self);
  if AFilterGraph <> nil then
    TBalancerFilterGraph(AFilterGraph).InsertFilter(self);
  FFilterGraph := AFilterGraph;
end;

procedure TBalancer.Notification(AComponent: TComponent; Operation:
  TOperation);
begin
  inherited Notification(AComponent, Operation);
  if ((AComponent = FFilterGraph) and (Operation = opRemove)) then
    FFilterGraph := nil;
end;

constructor TBalancer.Create(AOwner: TComponent);
var
  hr: HRESULT;
begin
  inherited Create(AOwner);
  FFilter := TBalancerFilter.Create(Name, nil, hr);
  FFilter.Parent := Self;
  FBaseFilter := FFilter as IBaseFilter;
  FAudioChannel := acStereo;
end;

destructor TBalancer.Destroy;
begin
  FilterGraph := nil;
  inherited Destroy;
end;

function TBalancer.QueryInterface(const IID: TGUID; out Obj):
  HResult;
begin
  Result := inherited QueryInterface(IID, Obj);
  if not Succeeded(Result) then
    if Assigned(FFilter) then
    begin
      Result := FFilter.QueryInterface(IID, Obj);
    end;
end;

procedure TBalancer.SetAudioChannel(AAudioChannel: TAudioChannel);
begin
  FAudioChannel := AAudioChannel;
  FFilter.SetAudioChannel(FAudioChannel);
end;

procedure Register;
begin
  RegisterComponents('DSPack', [TBalancer]);
end;

end.

⌨️ 快捷键说明

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