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

📄 unamsmixer.pas

📁 Voice Commnucation Components for Delphi
💻 PAS
📖 第 1 页 / 共 4 页
字号:
       (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 + -