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