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

📄 amixer.pas

📁 delphi 多媒体声音控制控件 AMixer
💻 PAS
📖 第 1 页 / 共 2 页
字号:
end;

function TMixerConnections.GetCount:Integer;
begin
  Result:=FConnections.Count;
end;

{-----------------}
{TMixerDestination}
{-----------------}

constructor TMixerDestination.Create (AMixer:TAudioMixer;AData:TMixerLine);
begin
  FData:=AData;
  XMixer:=AMixer;
  FConnections:=TMixerConnections.Create (XMixer,FData);
  FControls:=TMixerControls.Create (XMixer,AData);
end;

destructor TMixerDestination.Destroy;
begin
  Fcontrols.free;
  FConnections.Free;
  inherited;
end;

{------------------}
{TMixerDestinations}
{------------------}

constructor TMixerDestinations.Create (AMixer:TAudioMixer);
var A,B:Integer;
    ML:TMixerLine;
begin
  FDestinations:=TPointerList.Create;
  FDestinations.OnFreeItem:=DoFreeItem;
  For A:=0 to AMixer.MixerCaps.cDestinations-1 do
  begin
    ML.cbStruct:=SizeOf(TMixerLine);
    ML.dwDestination:=A;
    B:=MixerGetLineInfo (AMixer.MixerHandle,@ML,MIXER_GETLINEINFOF_DESTINATION);
    If B=MMSYSERR_NOERROR then
      FDestinations.Add(Pointer(TMixerDestination.Create (AMixer,ML)));
  end;
end;

procedure TMixerDestinations.DoFreeItem (Pntr:Pointer);
begin
  TMixerDestination(Pntr).Free;
end;

destructor TMixerDestinations.Destroy;
begin
  FDestinations.Free;
  inherited;
end;

function TMixerDestinations.GetDestination (Ind:Integer):TMixerDestination;
begin
  Result:=FDestinations.Pointer[Ind];
end;

function TMixerDestinations.GetCount:Integer;
begin
  Result:=FDestinations.Count;
end;

{-----------}
{TAudioMixer}
{-----------}

constructor TAudioMixer.Create (AOwner:TComponent);
begin
  inherited Create (AOwner);
  FDestinations:=nil;
  XWndHandle:=AllocateHWnd (MixerCallBack);
  FMixersCount:=mixerGetNumDevs;
  FMixerID:=-1;
  SetMixerID (0);
end;

destructor TAudioMixer.Destroy;
begin
  CloseMixer;
  if XWndHandle<>0 then
    DeAllocateHwnd(XWndHandle);
  inherited;
end;

procedure TAudioMixer.CloseMixer;
begin
  If FMixerID>=0 then
  begin
    mixerClose (FMixerHandle);
    FMixerID:=-1;
  end;
  FDestinations.Free;
  FDestinations:=nil;
end;

procedure TAudioMixer.SetMixerID (Value:Integer);
begin
  If FMixersCount=0 then
    Exit;
  If Value>=FMixersCount then
    Value:=FMixersCount-1;
  CloseMixer;
  If Value>=0 then
  begin
    If mixerOpen (@FMixerHandle,Value,XWndHandle,0,CALLBACK_WINDOW OR MIXER_OBJECTF_MIXER)=MMSYSERR_NOERROR then
    begin
      FMixerID:=Value;
      mixerGetDevCaps (MixerID,@FMixerCaps,SizeOf (TMixerCaps));
      FDestinations:=TMixerDestinations.Create (Self);
    end;
  end;
end;

procedure TAudioMixer.MixerCallBack (var Msg:TMessage);
begin
  case Msg.Msg of
    MM_MIXM_LINE_CHANGE:
        If Assigned (OnLineChange) then
          OnLineChange (Self,Msg.wParam,Msg.lParam);
    MM_MIXM_CONTROL_CHANGE:
        If Assigned (OnControlChange) then
          OnControlChange (Self,Msg.wParam,Msg.lParam);
    else
      Msg.Result := DefWindowProc (XWndHandle, Msg.Msg, Msg.WParam, Msg.LParam);
  end;
end;

function TAudioMixer.GetVolume (ADestination,AConnection:Integer;var LeftVol,RightVol,Mute:Integer;var VolDisabled,MuteDisabled:Boolean):Boolean;
var MD:TMixerDestination;
    MC:TMixerConnection;
    Cntrls:TMixerControls;
    MCD:TMixerControlDetails;
    Cntrl:PMixerControl;
    A,B:Integer;
    ML:TMixerLine;
    details:array [0..30] of Integer;
begin
  Result:=False;
  MD:=Destinations[ADestination];
  If MD<>nil then
  begin
    If AConnection=-1 then
    begin
      Cntrls:=MD.Controls;
      ML:=MD.Data;
    end
    else
    begin
      MC:=MD.Connections[AConnection];
      If MC<>nil then
      begin
        Cntrls:=MC.Controls;
        ML:=MC.Data;
      end
      else
        Cntrls:=nil;
    end;
    If Cntrls<>nil then
    begin
      A:=0;
      Result:=True;
      LeftVol:=-1;
      RightVol:=-1;
      Mute:=-1;
      while ((LeftVol=-1) OR (Mute=-1)) AND (A<Cntrls.Count) do
      begin
        Cntrl:=Cntrls[A];
        If Cntrl<>nil then
        begin
          If ((Cntrl.dwControlType=MIXERCONTROL_CONTROLTYPE_VOLUME) OR
             (Cntrl.dwControlType=MIXERCONTROL_CONTROLTYPE_MUTE)) AND
             (Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_MULTIPLE<>MIXERCONTROL_CONTROLF_MULTIPLE)
             then
          begin
            MCD.cbStruct:=SizeOf(TMixerControlDetails);
            MCD.dwControlID:=Cntrl.dwControlID;
            If Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_UNIFORM>0 then
              MCD.cChannels:=1
            else
              MCD.cChannels:=ML.cChannels;
            MCD.cMultipleItems:=0;
            MCD.cbDetails:=SizeOf(Integer);
            MCD.paDetails:=@details;
            B:=mixerGetControlDetails (FMixerHandle,@MCD,MIXER_GETCONTROLDETAILSF_VALUE);
            If B=MMSYSERR_NOERROR then
            begin
              If (Cntrl.dwControlType=MIXERCONTROL_CONTROLTYPE_VOLUME) AND (LeftVol=-1) then
              begin
                VolDisabled:=Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_DISABLED>0;
                If not VolDisabled then
                begin
                  LeftVol:=details[0];
                  If MCD.cChannels>1 then
                    RightVol:=Details[1];
                end;
              end
              else
                If (Cntrl.dwControlType=MIXERCONTROL_CONTROLTYPE_MUTE) AND (Mute=-1) then
                begin
                  MuteDisabled:=Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_DISABLED>0;
                  If not MuteDisabled then
                  begin
                    If Details[0]<>0 then
                      Mute:=1
                    else
                      Mute:=0;
                  end;
                end;
            end;
          end;
        end;
        Inc (A);
      end;
      If Mute=-1 then
      begin
        If AConnection<>-1 then
        begin
          Cntrls:=MD.Controls;
          ML:=MD.Data;
          If Cntrls<>nil then
          begin
            A:=0;
            while (Mute=-1) AND (A<Cntrls.Count) do
            begin
              Cntrl:=Cntrls[A];
              If (Cntrl.dwControlType AND MIXERCONTROL_CONTROLTYPE_MIXER=MIXERCONTROL_CONTROLTYPE_MIXER) OR
                 (Cntrl.dwControlType AND MIXERCONTROL_CONTROLTYPE_MUX=MIXERCONTROL_CONTROLTYPE_MUX) then
                 // Mux is similar to mixer, but only one line can be selected at a time
              begin
                MCD.cbStruct:=SizeOf(TMixerControlDetails);
                MCD.dwControlID:=Cntrl.dwControlID;
                If Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_UNIFORM>0 then
                  MCD.cChannels:=1
                else
                  MCD.cChannels:=ML.cChannels;
                If Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_MULTIPLE=MIXERCONTROL_CONTROLF_MULTIPLE then
                  MCD.cMultipleItems:=Cntrl.cMultipleItems
                else
                  MCD.cMultipleItems:=0;
                MCD.cbDetails:=4;
                MCD.paDetails:=@Details;
                B:=mixerGetControlDetails (FMixerHandle,@MCD,MIXER_GETCONTROLDETAILSF_VALUE);
                If B=MMSYSERR_NOERROR then
                  Mute:=Details[AConnection];
              end;
              Inc (A);
            end;
          end;
        end;
      end;
      If LeftVol=-1 then
        VoldIsabled:=True;
      If Mute=-1 then
        MuteDisabled:=True;
    end;
  end;
end;

function TAudioMixer.SetVolume (ADestination,AConnection:Integer;LeftVol,RightVol,Mute:Integer):Boolean;
var MD:TMixerDestination;
    MC:TMixerConnection;
    Cntrls:TMixerControls;
    MCD:TMixerControlDetails;
    Cntrl:PMixerControl;
    A,B:Integer;
    ML:TMixerLine;
    details:array [0..30] of Integer;
    VolSet,MuteSet:Boolean;
begin
  Result:=False;
  MD:=Destinations[ADestination];
  If MD<>nil then
  begin
    If AConnection=-1 then
    begin
      Cntrls:=MD.Controls;
      ML:=MD.Data;
    end
    else
    begin
      MC:=MD.Connections[AConnection];
      If MC<>nil then
      begin
        Cntrls:=MC.Controls;
        ML:=MC.Data;
      end
      else
        Cntrls:=nil;
    end;
    If Cntrls<>nil then
    begin
      A:=0;
      VolSet:=LeftVol=-1;
      MuteSet:=Mute=-1;
      Result:=True;
      while (not VolSet OR not MuteSet) AND (A<Cntrls.Count) do
      begin
        Cntrl:=Cntrls[A];
        If Cntrl<>nil then
        begin
          If ((Cntrl.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME) OR
             (Cntrl.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE)) AND
             (Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_MULTIPLE<>MIXERCONTROL_CONTROLF_MULTIPLE)
             then
          begin
            MCD.cbStruct:=SizeOf(TMixerControlDetails);
            MCD.dwControlID:=Cntrl.dwControlID;
            If Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_UNIFORM>0 then
              MCD.cChannels:=1
            else
              MCD.cChannels:=ML.cChannels;
            MCD.cMultipleItems:=0;
            MCD.cbDetails:=SizeOf(Integer);
            MCD.paDetails:=@Details;
            If (Cntrl.dwControlType=MIXERCONTROL_CONTROLTYPE_VOLUME) AND not VolSet then
            begin
              Details[0]:=LeftVol;
              If RightVol=-1 then
                Details[1]:=LeftVol
              else
                Details[1]:=RightVol;
              VolSet:=True;
            end
            else
              If (Cntrl.dwControlType=MIXERCONTROL_CONTROLTYPE_MUTE) AND not MuteSet then
              begin
                Details[0]:=Mute;
                MuteSet:=True;
              end;
            mixerSetControlDetails (FMixerHandle,@MCD,MIXER_GETCONTROLDETAILSF_VALUE);
          end;
        end;
        Inc (A);
      end;
      If not MuteSet then
      begin
        If AConnection<>-1 then
        begin
          Cntrls:=MD.Controls;
          ML:=MD.Data;
          If Cntrls<>nil then
          begin
            A:=0;
            while not MuteSet AND (A<Cntrls.Count) do
            begin
              Cntrl:=Cntrls[A];
              If (Cntrl.dwControlType = MIXERCONTROL_CONTROLTYPE_MIXER) OR
                 (Cntrl.dwControlType = MIXERCONTROL_CONTROLTYPE_MUX) then
              begin
                MCD.cbStruct:=SizeOf(TMixerControlDetails);
                MCD.dwControlID:=Cntrl.dwControlID;
                If Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_UNIFORM>0 then
                  MCD.cChannels:=1
                else
                  MCD.cChannels:=ML.cChannels;
                If Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_MULTIPLE=MIXERCONTROL_CONTROLF_MULTIPLE then
                  MCD.cMultipleItems:=Cntrl.cMultipleItems
                else
                  MCD.cMultipleItems:=0;
                MCD.cbDetails:=4;
                MCD.paDetails:=@Details;
                MuteSet:=True;
                mixerGetControlDetails (FMixerHandle,@MCD,MIXER_GETCONTROLDETAILSF_VALUE);
                if (Cntrl.dwControlType = MIXERCONTROL_CONTROLTYPE_MUX) then
                  For B:=0 to Cntrl.cMultipleItems-1 do
                    Details[B]:=0;
                Details[AConnection]:=Mute;
                mixerSetControlDetails (FMixerHandle,@MCD,MIXER_GETCONTROLDETAILSF_VALUE);
              end;
              Inc (A);
            end;
          end;
        end;
      end;
    end;
  end;
end;

procedure Register;
begin
  RegisterComponents('Samples', [TAudioMixer]);
end;

end.

⌨️ 快捷键说明

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