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

📄 unamsmixer.pas

📁 Voice Commnucation Components for Delphi
💻 PAS
📖 第 1 页 / 共 4 页
字号:
      result := getLineIndex(not isOut, 1);
      //
      if (0 < result) then
	result := 0
      else
	if (0 = result) then begin
	  //
	  result := min(1, getLineCount() - 1);
	  if (0 = result) then
	    result := -1;	// no such line
	end
	else
	  if (isOut) then begin
	    //
	    if (0 < getLineCount()) then
	      result := 0	// finally assume 0 is OUT
	    else
	      result := -1
	  end
	  else begin
	    //
	    if (0 < getLineCount()) then
	      result := 1	// finally assume 1 is IN
	    else
	      result := -1
	  end;
    end
    else
      result := f_selectedMixer.f_lines.locate(line);
  end;
end;

// --  --
function unaMsMixerSystem.getLineName(iline: unsigned; shortName: bool): wideString;
begin
  if ((nil <> f_selectedMixer) and (nil <> f_selectedMixer.line[iline])) then begin
    //
    if (shortName) then
      result := f_selectedMixer.line[iline].caps.szShortName
    else
      result := f_selectedMixer.line[iline].caps.szName
  end
  else
    result := '';
end;

// --  --
function unaMsMixerSystem.getMixer(index: unsigned): unaMsMixerDevice;
begin
  result := f_mixers[index];
end;

// --  --
function unaMsMixerSystem.getMixerCount(): unsigned;
begin
  result := f_mixers.count;
end;

const
  // message base for driver specific messages.
  //
  DRVM_MAPPER		= $2000;
  DRVM_USER             = $4000;
  DRVM_MAPPER_STATUS           	= (DRVM_MAPPER+0);
  DRVM_MAPPER_RECONFIGURE	= (DRVM_MAPPER+1);
  DRVM_MAPPER_PREFERRED_GET	= (DRVM_MAPPER+21);
  DRV_QUERYMODULE               = (DRV_RESERVED + 9);
  DRV_PNPINSTALL                = (DRV_RESERVED + 11);

  // MS loves to hide things
  DRV_QUERYDRVENTRY     = (DRV_RESERVED + 1);
  DRV_QUERYDEVNODE      = (DRV_RESERVED + 2);
  DRV_QUERYNAME         = (DRV_RESERVED + 3);
  DRV_QUERYDRIVERIDS	= (DRV_RESERVED + 4);
  DRV_QUERYMAPPABLE     = (DRV_RESERVED + 5);


//
// DRVM_MAPPER_PREFERRED_GET flags
//
  DRVM_MAPPER_PREFERRED_FLAGS_PREFERREDONLY   = $000000001;


// --  --
function unaMsMixerSystem.getMixerId(deviceId: unsigned; isInDevice: bool): int;
var
  mixId: unsigned;
  flags: unsigned;
begin
  if (WAVE_MAPPER = deviceId) then begin
    //
    flags := 0;  //
    case (g_osVersion.dwPlatformId) of

      VER_PLATFORM_WIN32s,
      VER_PLATFORM_WIN32_WINDOWS: begin
	// Win95/Me stuff
	deviceId := mapMixerIdWin9x(deviceId, isInDevice);
      end;

      VER_PLATFORM_WIN32_NT: begin
	// NT stuff
	if (isInDevice) then
	  waveInMessage(int(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, unsigned(@deviceId), unsigned(@flags))
	else
	  waveOutMessage(int(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, unsigned(@deviceId), unsigned(@flags));
      end;

    end;
  end;
  //
  if (MMSYSERR_NOERROR = mixerGetID(int(deviceId), mixId, choice(isInDevice, MIXER_OBJECTF_WAVEIN, unsigned(MIXER_OBJECTF_WAVEOUT)))) then
    result := mixId
  else
    result := -1;
end;

// --  --
function unaMsMixerSystem.getMixerIndex(mixerId: unsigned): int;
var
  i: unsigned;
  curId: unsigned;
begin
  result := -1;
  // locate mixer with this ID
  i := 0;
  while (i < getMixerCount()) do begin
    //
    if (MMSYSERR_NOERROR = mixerGetID(i, curId, MIXER_OBJECTF_MIXER)) then
      //
      if (curId = mixerId) then begin
	//
	result := i;
	break;
      end;
    //
    inc(i);
  end;
end;

// --  --
function unaMsMixerSystem.getMixerName(): wideString;
begin
  if (nil <> f_selectedMixer) then
    result := f_selectedMixer.caps.szPname
  else
    result := '';
end;

// --  --
function unaMsMixerSystem.getMuteControlID(iline: unsigned; iconn: int): int;
var
  control: unaMsMixerControl;
begin
  control := getConnectionControl(iline, iconn, MIXERCONTROL_CT_CLASS_SWITCH, MIXERCONTROL_CONTROLTYPE_MUTE);
  //
  if (nil <> control) then
    result := control.caps.dwControlID
  else
    result := -1;
end;

// --  --
function unaMsMixerSystem.getRecSource(): int;
var
  i: unsigned;
  j: unsigned;
  k: unsigned;
  recIndex: int;
  line: unaMsMixerLine;
  conn: unaMsMixerLine;
  control: unaMsMixerControl;
begin
  result := -1;
  //
  if (nil <> f_selectedMixer) then begin
    //
    recIndex := getLineIndex(false);
    if (0 <= recIndex) then
      line := f_selectedMixer.line[recIndex]
    else
      line := nil;
    //
    if (nil <> line) then begin
      //
      //
      // locate list control(s) for this line
      //
      i := 0;
      while (i < line.getControlCount()) do begin
	//
	control := line[i];
	if (control.isListClass) then begin
	  // locate this line in items list
	  j := 0;
	  while (j < control.caps.cMultipleItems) do begin
	    //
	    if (control.getValue(false, 0, j)) then begin
	      //
	      // now locate this line in connections
	      //
	      k := 0;
	      while (k < line.getConnectionCount) do begin
		//
		conn := line.connections[k];
		if (conn.caps.dwLineId = control.getListItem(0, j).dwParam1) then begin
		  // found
		  result := k;
		  break;
		end;
		//
		inc(k);
	      end;
	      //
	      if (0 <= result) then
		break;
	    end;
	    //
	    inc(j);
	  end;
	end;
	//
	if (0 <= result) then
	  break;
	//
	inc(i);
      end;
    end;
  end;
end;

// --  --
function unaMsMixerSystem.getVolume(iline: unsigned; iconn: int): int;
var
  control: unaMsMixerControl;
  imax: int;
begin
  control := getConnectionControl(iline, iconn, MIXERCONTROL_CT_CLASS_FADER, MIXERCONTROL_CONTROLTYPE_VOLUME);
  //
  if (nil <> control) then begin
    //
    imax := max(control.caps.bounds.lMinimum, control.caps.bounds.lMaximum) - control.caps.bounds.lMinimum;
    //
    result := (control.getValue(unsigned(0), 0) + control.getValue(unsigned(0), 1)) shr 1;
    result := percent(result, imax);
  end
  else
    result := -1;
end;

// --  --
function unaMsMixerSystem.getVolumeControlID(iline: unsigned; iconn: int): int;
var
  control: unaMsMixerControl;
begin
  control := getConnectionControl(iline, iconn, MIXERCONTROL_CT_CLASS_FADER, MIXERCONTROL_CONTROLTYPE_VOLUME);
  //
  if (nil <> control) then
    result := control.caps.dwControlID
  else
    result := -1;
end;

// --  --
function unaMsMixerSystem.isMutedConnection(iline: unsigned; iconn: int): bool;
var
  control: unaMsMixerControl;
begin
  control := getConnectionControl(iline, iconn, MIXERCONTROL_CT_CLASS_SWITCH, MIXERCONTROL_CONTROLTYPE_MUTE);
  //
  if (nil <> control) then
    result := control.getValue(true)
  else
    result := true;
end;

// --  --
function unaMsMixerSystem.mapMixerIdWin9x(deviceId: unsigned; isInDevice: bool): unsigned;
var
  key: HKEY;
  buf: array[0..512] of char;
  lpType: DWORD;
  lpSize: DWORD;
  devCapsIn: WAVEINCAPSA;
  devCapsOut: WAVEOUTCAPSA;
  count: unsigned;
  i: unsigned;
  name: string;
  ok: bool;
begin
  result := deviceId;
  if (WAVE_MAPPER <> result) then
    exit;
  //
  // 1. first try to read mapped device name from registry
  if (ERROR_SUCCESS = regOpenKeyEx(HKEY_CURRENT_USER, 'Software\Microsoft\Multimedia\Sound Mapper', 0, KEY_READ, key)) then try
    lpType := REG_SZ;
    lpSize := sizeof(buf);
    RegQueryValueEx(key, pChar(choice(isInDevice, 'Record', 'Playback')), nil, @lpType, @buf, @lpSize);
  finally
    regCloseKey(key);
  end;

  // 2. now, for all devices, try to compare the name (say thanks to MS)
  if (isInDevice) then
    count := waveInGetNumDevs()
  else
    count := waveOutGetNumDevs();
  //
  i := 0;
  while (i < count) do begin
    //
    name := '';
    if (isInDevice) then begin
      if (MMSYSERR_NOERROR = waveInGetDevCapsA(i, @devCapsIn, sizeof(devCapsIn))) then
	name := devCapsIn.szPname;
    end
    else begin
      if (MMSYSERR_NOERROR = waveOutGetDevCapsA(i, @devCapsOut, sizeof(devCapsOut))) then
	name := devCapsOut.szPname;
    end;
    //
    if (sameString(name, buf)) then begin
      result := i;
      break;
    end;
    //
    inc(i);
  end;

  // 3. if still no success, try DRV_QUERYMAPPABLE
  if (WAVE_MAPPER = result) then begin
    //
    i := 0;
    while (i < count) do begin
      //
      if (isInDevice) then
	ok := (MMSYSERR_NOERROR = waveInMessage(i, DRV_QUERYMAPPABLE, 0, 0))
      else
	ok := (MMSYSERR_NOERROR = waveOutMessage(i, DRV_QUERYMAPPABLE, 0, 0));
      //
      if (ok) then begin
	result := i;
	break;
      end;
      //
      inc(i);
    end;
  end;
end;

// --  --
function unaMsMixerSystem.muteConnection(iline: unsigned; iconn: int; doMute: bool): bool;
var
  control: unaMsMixerControl;
begin
  control := getConnectionControl(iline, iconn, MIXERCONTROL_CT_CLASS_SWITCH, MIXERCONTROL_CONTROLTYPE_MUTE);
  //
  if (nil <> control) then begin
    //
    control.setValue(doMute);
    result := true;
  end
  else
    result := false;
end;

// --  --
function unaMsMixerSystem.selectMixer(imixer: unsigned; handle: unsigned): bool;
begin
  if (nil <> f_selectedMixer) then
    f_selectedMixer.close();
  //
  f_selectedMixer := nil;
  //
  if (imixer < getMixerCount()) then
    f_selectedMixer := mixer[imixer];
  //
  result := (nil <> f_selectedMixer);
  //
  if (result) then begin
    //
    f_selectedMixer.winHandle := handle;
    f_selectedMixer.open();
  end;
end;

// --  --
function unaMsMixerSystem.selectMixer(deviceId: unsigned; isInDevice: bool; handle: unsigned): bool;
var
  mixId: int;
  i: int;
begin
  mixId := getMixerId(deviceId, isInDevice);
  //
  if (0 <= mixId) then
    // locate mixer with this ID
    i := getMixerIndex(mixId)
  else
    i := -1;	// no mixer for this device
  //
  if (0 <= i) then
    result := selectMixer(i, handle)
  else
    result := selectMixer($FFFFFFFF, handle)	// select nil
end;

// --  --
function unaMsMixerSystem.setRecSource(iconn: unsigned; ensureNotMuted: bool): bool;
var
  i: unsigned;
  j: unsigned;
  recIndex: int;
  line: unaMsMixerLine;
  conn: unaMsMixerLine;
  control: unaMsMixerControl;
begin
  result := false;
  //
  if (nil <> f_selectedMixer) then begin
    //
    recIndex := getLineIndex(false);
    if (0 <= recIndex) then
      line := f_selectedMixer.line[recIndex]
    else
      line := nil;
    //
    if (nil <> line) then begin
      //
      conn := line.connections[iconn];
      if (nil <> conn) then begin
	//
	// locate list control(s) for this line
	//
	i := 0;
	while (i < line.getControlCount()) do begin
	  //
	  control := line[i];
	  if (control.isListClass) then begin
	    // locate this line in items list
	    j := 0;
	    while (j < control.caps.cMultipleItems) do begin
	      //
	      if (control.getListItem(0, j).dwParam1 = conn.caps.dwLineId) then begin
		control.setValue(true, 0, j);
		result := true;
		break;
	      end;
	      //
	      inc(j);
	    end;
	    //
	    if (result) then
	      break;
	  end;
	  //
	  inc(i);
	end;
	//
	if (not result and ensureNotMuted) then
	  // at least make sure this line is not muted
	  muteConnection(recIndex, iconn, false);
      end;
    end;
  end;
end;

// --  --
function unaMsMixerSystem.setVolume(iline: unsigned; iconn, value: int): bool;
var
  control: unaMsMixerControl;
  imax: int;
  ivalue: int;
begin
  control := getConnectionControl(iline, iconn, MIXERCONTROL_CT_CLASS_FADER, MIXERCONTROL_CONTROLTYPE_VOLUME);
  if (nil <> control) then begin
    //
    imax := max(control.caps.bounds.lMinimum, control.caps.bounds.lMaximum) - control.caps.bounds.lMinimum;
    ivalue := (imax div 100) * value + control.caps.bounds.lMinimum;
    //
    control.setValueInt(ivalue, 0);
    control.setValueInt(ivalue, 1);
    //
    result := true;
  end
  else
    result := false;
end;


end.

⌨️ 快捷键说明

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