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

📄 amixer.pas

📁 语音与识别技术包含很多C语言处理模块系统
💻 PAS
📖 第 1 页 / 共 3 页
字号:
  FData := AData;
  XMixer := AMixer;
  FControls := TMixerControls.Create (AMixer, AData);
end;

destructor TMixerConnection.Destroy;
begin
  FControls.Free;
  inherited;
end;

{-----------------}
{TMixerConnections}
{-----------------}

constructor TMixerConnections.Create (AMixer:TAudioMixer; AData:TMixerLine);
var A,B:Integer;
    ML:TMixerLine;
begin
  XMixer := AMixer;
  FConnections := TPointerList.Create;
  FConnections.OnFreeItem := Dofreeitem;
  ML.cbStruct := SizeOf(TMixerLine);
  ML.dwDestination := AData.dwDestination;
  For A := 0 to AData.cConnections-1 do
  begin
    ML.dwSource := A;
    B := MixerGetLineInfo (AMixer.MixerHandle, @ML, MIXER_GETLINEINFOF_SOURCE);
    If B = MMSYSERR_NOERROR then
      FConnections.Add (Pointer(TMixerConnection.Create (XMixer, ML)));
  end;
end;

destructor TMixerConnections.Destroy;
begin
  FConnections.Free;
  inherited;
end;

procedure TMixerConnections.DoFreeItem (Pntr:Pointer);
begin
  TMixerConnection(Pntr).Free;
end;

function TMixerConnections.GetConnection (Ind:Integer):TMixerConnection;
begin
  Result := FConnections.Pointer[Ind];
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));

      if FMixerCaps.wMid = MM_MICROSOFT then
        FManufacturer := 'Microsoft'
      else
        FManufacturer := IntToStr(FMixerCaps.wMid) + ' = Unknown';
      FDriverVersion := FMixerCaps.vDriverVersion;
      FProductId := FMixerCaps.wPid;
      FProductName := StrPas(FMixerCaps.szPName);
      FNumberOfLine := FMixerCaps.cDestinations;

      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 Stereo, 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;
  Stereo := 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
            if (Cntrl.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE) then
              MCD.cbStruct := SizeOf(TMixerControlDetails) //1
            else
              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
                  begin
                    RightVol := Details[1];
                    Stereo := True;
                  end;
                end;
              end
              else
                If (Cntrl.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE) AND (Mute = -1) then
                begin
                  MuteDisabled := Cntrl.fdwControl AND MIXERCONTROL_CONTROLF_DISABLED > 0;//2
                  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)

⌨️ 快捷键说明

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