📄 unamsmixer.pas
字号:
(MIXERCONTROL_CONTROLTYPE_MIXER = controlType) or
(MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT = controlType) or
(MIXERCONTROL_CONTROLTYPE_SINGLESELECT = controlType))
and not f_listItemsFilled
) then begin
// fill list items (once)
f_details.cbDetails := sizeOf(MIXERCONTROLDETAILS_LISTTEXT);
if (isMultiple) then
Z := f_details.cChannels * f_details.cMultipleItems * f_details.cbDetails
else
Z := f_details.cChannels * f_details.cbDetails;
//
mrealloc(f_details.paDetails, Z);
f_listItems.clear();
f_listItemsText.clear();
//
if (checkError(mixerGetControlDetails(f_master.f_master.f_index, f_details, MIXER_GETCONTROLDETAILSF_LISTTEXT + MIXER_OBJECTF_MIXER){$IFDEF DEBUG}, 'getDetails.[1]mixerGetControlDetails'{$ENDIF})) then begin
//
offs := 0;
if (isMultiple) then
Z := f_details.cChannels * f_details.cMultipleItems
else
Z := f_details.cChannels;
//
if (0 < Z) then begin
//
for i := 0 to Z - 1 do begin
listItem := malloc(sizeOf(listItem^), pMIXERCONTROLDETAILSLISTTEXT(@pChar(f_details.paDetails)[offs]));
f_listItems.add(listItem);
f_listItemsText.add(listItem.szName);
inc(offs, f_details.cbDetails);
end;
end;
//
f_listItemsFilled := true;
end;
end;
case (controlUnits) of
// custom
MIXERCONTROL_CT_UNITS_CUSTOM:
f_details.cbDetails := f_caps.metrics.cbCustomData;
// bool
MIXERCONTROL_CT_UNITS_BOOLEAN:
f_details.cbDetails := sizeOf(MIXERCONTROLDETAILS_BOOLEAN);
// signed
MIXERCONTROL_CT_UNITS_SIGNED,
MIXERCONTROL_CT_UNITS_DECIBELS:
f_details.cbDetails := sizeOf(MIXERCONTROLDETAILS_SIGNED);
// unsigned
MIXERCONTROL_CT_UNITS_UNSIGNED,
MIXERCONTROL_CT_UNITS_PERCENT:
f_details.cbDetails := sizeOf(MIXERCONTROLDETAILS_UNSIGNED);
else
f_details.cbDetails := 0;
end;
// allocate memory for details
if (0 < f_details.cbDetails) then begin
//
Z := f_details.cChannels * f_details.cbDetails * choice(isMultiple, f_details.cMultipleItems, 1);
//
fillChar(mrealloc(f_details.paDetails, Z)^, Z, #0);
//
checkError(mixerGetControlDetails(f_master.f_master.f_index, f_details, MIXER_GETCONTROLDETAILSF_VALUE + MIXER_OBJECTF_MIXER){$IFDEF DEBUG}, 'getDetails.[2]mixerGetControlDetails'{$ENDIF});
end;
//
result := f_details;
end;
// -- --
function unaMsMixerControl.getIsControl(index: int): bool;
begin
if (-1 = index) then
index := int(MIXERCONTROL_CONTROLF_DISABLED);
//
result := (0 <> (f_caps.fdwControl and index));
//
if (MIXERCONTROL_CONTROLF_MULTIPLE = index) then
// some controls does not have this flag set, while in fact they are multiple
result := result or (0 < f_multipleItems);
end;
// -- --
function unaMsMixerControl.getIsControlClass(index: int): bool;
begin
result := (unsigned(index) = f_controlClass);
end;
// -- --
function unaMsMixerControl.getListItem(channel: unsigned; index: unsigned): pMixerControlDetailsListText;
begin
if (isUniform) then
channel := 0;
//
if (isMultiple) then
result := f_listItems[channel * f_multipleItems + index]
else
result := f_listItems[channel];
end;
// -- --
function unaMsMixerControl.getValue(def: bool; channel: unsigned; index: unsigned): bool;
begin
getDetails();
//
if (isUniform) then
channel := 0;
//
if (isMultiple) then
result := (pBoolArray(f_details.paDetails)[channel * f_multipleItems + index].fValue <> 0)
else
result := (pBoolArray(f_details.paDetails)[channel].fValue <> 0);
end;
// -- --
function unaMsMixerControl.getvalueInt(def: int; channel: unsigned; index: unsigned): int;
begin
getDetails();
//
if (isUniform) then
channel := 0;
if (isMultiple) then
result := pSignedArray(f_details.paDetails)[channel * f_multipleItems + index].lValue
else
result := pSignedArray(f_details.paDetails)[channel].lValue;
end;
// -- --
function unaMsMixerControl.getValue(const def: string; channel: unsigned; index: unsigned): string;
begin
getDetails();
//
if (isUniform) then
channel := 0;
//
if (isMultiple) then
result := f_listItemsText.get(channel * f_multipleItems + index)
else
result := f_listItemsText.get(channel);
end;
// -- --
function unaMsMixerControl.getValue(def: unsigned; channel: unsigned; index: unsigned): unsigned;
begin
getDetails();
//
if (isUniform) then
channel := 0;
if (isMultiple) then
result := pUnsignedArray(f_details.paDetails)[channel * f_multipleItems + index].dwValue
else
result := pUnsignedArray(f_details.paDetails)[channel].dwValue;
end;
// -- --
procedure unaMsMixerControl.setDetails();
begin
checkError(mixerSetControlDetails(f_master.f_master.f_index, f_details, MIXER_SETCONTROLDETAILSF_VALUE + MIXER_OBJECTF_MIXER){$IFDEF DEBUG}, 'setDetails.mixerSetControlDetails'{$ENDIF});
end;
// -- --
procedure unaMsMixerControl.setValue(value: bool; channel: int; index: unsigned);
var
i: int;
ch: unsigned;
begin
beginUpdate();
try
if (isUniform) then
channel := 0;
//
ch := choice(0 > channel, 0, channel);
repeat
//
if (isMultiple) then begin
//
if (MIXERCONTROL_CONTROLTYPE_MUX = controlType) then begin
//
if (not value) then
// do nothing
else begin
//
if (0 < f_multipleItems) then begin
//
for i := 0 to f_multipleItems - 1 do
pBoolArray(f_details.paDetails)[ch * f_multipleItems + unsigned(i)].fValue := choice(unsigned(i) = index, unsigned(1), 0)
//
end;
end
end
else
pBoolArray(f_details.paDetails)[ch * f_multipleItems + index].fValue := choice(value, unsigned(1), 0)
end
else
pBoolArray(f_details.paDetails)[ch].fValue := choice(value, unsigned(1), 0);
//
inc(ch);
//
until ((0 <= channel) or (ch >= f_details.cChannels));
//
finally
endUpdate();
end;
end;
// -- --
procedure unaMsMixerControl.setValueInt(value: int; channel: int; index: unsigned);
var
ch: unsigned;
begin
beginUpdate();
try
if (isUniform) then
channel := 0;
//
ch := choice(0 > channel, 0, channel);
repeat
//
if (isMultiple) then
pSignedArray(f_details.paDetails)[ch * f_multipleItems + index].lValue := value
else
pSignedArray(f_details.paDetails)[ch].lValue := value;
//
inc(ch);
//
until ((0 <= channel) or (ch >= f_details.cChannels));
//
finally
endUpdate();
end;
end;
// -- --
procedure unaMsMixerControl.setValue(value: unsigned; channel: int; index: unsigned);
var
ch: unsigned;
begin
beginUpdate();
try
if (isUniform) then
channel := 0;
//
ch := choice(0 > channel, 0, channel);
repeat
//
if (isMultiple) then
pUnsignedArray(f_details.paDetails)[ch * f_multipleItems + index].dwValue := value
else
pUnsignedArray(f_details.paDetails)[ch].dwValue := value;
//
inc(ch);
//
until ((0 <= channel) or (ch >= f_details.cChannels));
//
finally
endUpdate();
end;
end;
{ unaMsMixerLine }
// -- --
constructor unaMsMixerLine.create(master: unaMsMixerDevice; destIndex: unsigned; isConnection: bool; sourceIndex: unsigned);
begin
inherited create();
//
f_master := master;
//
f_controls := unaObjectList.create();
f_capsW := malloc(sizeOf(f_capsW^), true, 0);
f_capsW.cbStruct := sizeOf(f_capsW^);
f_capsW.dwDestination := destIndex;
f_capsW.dwSource := sourceIndex;
//
getCaps(isConnection);
//
if (not isConnection) then begin
f_connections := unaObjectList.create();
enumConnections();
end;
//
enumControls();
end;
// -- --
destructor unaMsMixerLine.destroy();
begin
inherited;
//
freeAndNil(f_connections);
freeAndNil(f_controls);
mrealloc(f_capsW);
end;
// -- --
procedure unaMsMixerLine.enumConnections();
var
C: unsigned;
begin
f_connections.clear();
C := min(128, caps.cConnections); // sanity check
while (C > 0) do begin
dec(C);
f_connections.add(unaMsMixerLine.create(f_master, f_capsW.dwDestination, true, C));
end;
end;
// -- --
procedure unaMsMixerLine.enumControls();
var
i: unsigned;
{$IFNDEF NO_ANSI_SUPPORT }
detailsA: MixerLineControlsA;
controlA: pMixerControlA;
controlW: MixerControlW;
{$ENDIF }
detailsW: MixerLineControlsW;
offs: unsigned;
size: unsigned;
//
ok: bool;
begin
f_controls.clear();
//
if (0 < caps.cControls) then begin
//
{$IFNDEF NO_ANSI_SUPPORT }
if (not g_wideApiSupported) then begin
//
fillChar(detailsA, sizeOf(detailsA), #0);
with detailsA do begin
cbStruct := sizeOf(detailsA);
dwLineID := caps.dwLineID;
cControls := caps.cControls;
//
size := sizeOf(detailsA.pamxctrl^);
cbmxctrl := size;
mrealloc(pointer(pamxctrl), size * caps.cControls);
end;
end
else begin
// care about wide only if it is supported
{$ENDIF }
fillChar(detailsW, sizeOf(detailsW), #0);
with detailsW do begin
cbStruct := sizeOf(detailsW);
dwLineID := caps.dwLineID;
cControls := caps.cControls;
//
size := sizeOf(detailsW.pamxctrl^);
cbmxctrl := size;
mrealloc(pointer(pamxctrl), size * caps.cControls);
end;
{$IFNDEF NO_ANSI_SUPPORT }
end;
{$ENDIF }
//
try
{$IFNDEF NO_ANSI_SUPPORT }
if (not g_wideApiSupported) then
ok := checkError(mixerGetLineControlsA(f_master.f_index, @detailsA, MIXER_GETLINECONTROLSF_ALL + MIXER_OBJECTF_MIXER){$IFDEF DEBUG}, 'enumControls.mixerGetLineControlsA'{$ENDIF})
else
{$ENDIF }
ok := checkError(mixerGetLineControlsW(f_master.f_index, @detailsW, MIXER_GETLINECONTROLSF_ALL + MIXER_OBJECTF_MIXER){$IFDEF DEBUG}, 'enumControls.mixerGetLineControlsW'{$ENDIF});
//
if (ok) then begin
//
offs := 0;
if (0 < caps.cControls) then
//
for i := 0 to caps.cControls - 1 do begin
{$IFNDEF NO_ANSI_SUPPORT }
if (not g_wideApiSupported) then begin
//
controlA := @pArray(detailsA.pamxctrl)[offs];
with controlW do begin
cbStruct := sizeOf(controlW);
dwControlID := controlA.dwControlID;
dwControlType := controlA.dwControlType;
fdwControl := controlA.fdwControl;
cMultipleItems := controlA.cMultipleItems;
//
wStr2Array(controlA.szShortName, szShortName);
wStr2Array(controlA.szName, szName);
//
move(controlA.Bounds, Bounds, sizeOf(Bounds));
move(controlA.Metrics, Metrics, sizeOf(Metrics));
end;
f_controls.add(unaMsMixerControl.create(self, @controlW));
end
else
{$ENDIF }
f_controls.add(unaMsMixerControl.create(self, @pArray(detailsW.pamxctrl)[offs]));
//
inc(offs, size);
end;
end;
finally
{$IFNDEF NO_ANSI_SUPPORT }
if (not g_wideApiSupported) then
mrealloc(pointer(detailsA.pamxctrl))
else
{$ENDIF }
mrealloc(pointer(detailsW.pamxctrl));
end;
end;
end;
// -- --
function unaMsMixerLine.getCaps(isConnection: bool): pMixerLineW;
var
ok: bool;
{$IFNDEF NO_ANSI_SUPPORT }
capsA: MIXERLINEA;
{$ENDIF}
begin
{$IFNDEF NO_ANSI_SUPPORT }
if (not g_wideApiSupported) then begin
//
fillChar(capsA, sizeOf(capsA), #0);
with capsA do begin
capsA.cbStruct := sizeOf(capsA);
capsA.dwDestination := f_capsW.dwDestination;
capsA.dwSource := f_capsW.dwSource;
end;
//
ok := checkError(mixerGetLineInfoA(f_master.f_index, @capsA, choice(isConnection, unsigned(MIXER_GETLINEINFOF_SOURCE), MIXER_GETLINEINFOF_DESTINATION) + MIXER_OBJECTF_MIXER){$IFDEF DEBUG}, 'getCaps.mixerGetLineInfoA'{$ENDIF});
//
if (ok) then begin
//
with (f_capsW^) do begin
dwLineID := capsA.dwLineID;
fdwLine := capsA.fdwLine;
dwUser := capsA.dwUser;
dwComponentType := capsA.dwComponentType;
cChannels := capsA.cChannels;
cConnections := capsA.cConnections;
cControls := capsA.cControls;
wStr2Array(capsA.szShortName, szShortName);
wStr2Array(capsA.szName, szName);
//
with Target do begin
dwType := capsA.Target.dwType;
dwDeviceID := capsA.Target.dwDeviceID;
wMid := capsA.Target.wMid;
wPid := capsA.Target.wPid;
vDriverVersion := capsA.Target.vDriverVersion;
wStr2Array(capsA.Target.szPname, szPname);
end;
end;
end;
end
else
{$ENDIF }
ok := checkError(mixerGetLineInfoW(f_master.f_index, f_capsW, choice(isConnection, unsigned(MIXER_GETLINEINFOF_SOURCE), MIXER_GETLINEINFOF_DESTINATION) + MIXER_OBJECTF_MIXER){$IFDEF DEBUG}, 'getCaps.mixerGetLineInfoW'{$ENDIF});
//
if (ok) then
result := f_capsW
else
result := nil;
end;
// -- --
function unaMsMixerLine.getConnection(index: unsigned): unaMsMixerLine;
begin
if (nil <> f_connections) then
result := f_connections[index]
else
result := nil;
end;
// -- --
function unaMsMixerLine.getConnectionCount(): unsigned;
begin
if (nil <> f_connections) then
result := f_connections.count
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -