vista/xp中如何调整主音量

Posted

技术标签:

【中文标题】vista/xp中如何调整主音量【英文标题】:how to adjust master volume in vista/xp 【发布时间】:2011-03-27 02:36:03 【问题描述】:

我想像 vista 和 xp 中的 Get/SetMasterVolume 那样以编程方式调整音量?使用 mmsystem 单元?

【问题讨论】:

【参考方案1】:

这是一个通用的音频 api 的实现:MMDevApi

http://social.msdn.microsoft.com/Forums/en/windowspro-audiodevelopment/thread/5ce74d5d-2b1e-4ca9-a8c9-2e27eb9ec058

还有一个带按钮的例子

unit Unit33;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, MMDevApi, ActiveX, StdCtrls;

type
  TForm33 = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
     Private declarations 
  public
     Public declarations 
  end;

var
  Form33: TForm33;
  endpointVolume: IAudioEndpointVolume = nil;

implementation

$R *.dfm


procedure TForm33.Button1Click(Sender: TObject);
var
  VolumeLevel: Single;
begin
  if endpointVolume = nil then Exit;
  VolumeLevel := 0.50;
  endpointVolume.SetMasterVolumeLevelScalar(VolumeLevel, nil);
  Caption := Format('%1.8f', [VolumeLevel])
end;

procedure TForm33.FormCreate(Sender: TObject);
var
  deviceEnumerator: IMMDeviceEnumerator;
  defaultDevice: IMMDevice;
begin
  CoCreateInstance(CLASS_IMMDeviceEnumerator, nil, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, deviceEnumerator);
  deviceEnumerator.GetDefaultAudioEndpoint(eRender, eConsole, defaultDevice);
  defaultDevice.Activate(IID_IAudioEndpointVolume, CLSCTX_INPROC_SERVER, nil, endpointVolume);
end;

end.

【讨论】:

抱歉,我找不到在没有 SP3 的 XP 上运行的版本;可能是delphi.about.com/cs/adptips2000/a/bltip0800_4.htm 或torry.net/vcl/sound/mixer/amixer.zip 或area-6.co.uk/delphihard.htm【参考方案2】:

Windows XP:

function SetMasterVolume(VolToSet: word; out VolSet: word): MMResult;
var
  MixerHandle: HMixer;
  Volume: TMixerControlDetails_Unsigned;
  MixerLine: TMixerLine;
  MixerLineControls: TMixerLineControls;
  VolumeCtrl: TMixerControl;
  MixerControlDetails: TMixerControlDetails;
begin
  // Get mixer handle
  Result := mixerOpen(@MixerHandle, 0, 0, 0, 0);
  if Result <> MMSYSERR_NOERROR then Exit;
  try
    // Get master volume line
    FillChar(MixerLine, SizeOf(TMixerLine), 0);
    MixerLine.cbStruct := SizeOf(TMixerLine);
    MixerLine.dwComponentType := MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
    Result := mixerGetLineInfo(MixerHandle, @MixerLine, MIXER_GETLINEINFOF_COMPONENTTYPE);

    if Result <> MMSYSERR_NOERROR then Exit;
    // Get the volume control of the master volume line
    FillChar(VolumeCtrl, SizeOf(TMixerControl), 0);
    MixerLineControls.cbStruct := SizeOf(TMixerLineControls);
    MixerLineControls.dwLineID := MixerLine.dwLineID;
    MixerLineControls.dwControlType := MIXERCONTROL_CONTROLTYPE_VOLUME;
    MixerLineControls.cControls := 1;
    MixerLineControls.cbmxctrl := SizeOf(TMixerControl);
    MixerLineControls.pamxctrl := @VolumeCtrl;
    Result := mixerGetLineControls(MixerHandle,@MixerLineControls,MIXER_GETLINECONTROLSF_ONEBYTYPE);

    if Result <> MMSYSERR_NOERROR then Exit;
    // Set details (volume) for the volume control of the master volume line
    FillChar(MixerControlDetails, SizeOf(TMixerControlDetails), 0);
    MixerControlDetails.cbStruct := SizeOf(TMixerControlDetails);
    MixerControlDetails.dwControlID := VolumeCtrl.dwControlID;
    MixerControlDetails.cChannels := 1;
    MixerControlDetails.cMultipleItems := 0;
    MixerControlDetails.cbDetails := SizeOf(TMixerControlDetails_Unsigned);
    MixerControlDetails.paDetails := @Volume;
    Volume.dwValue := VolToSet;
    Result := mixerSetControlDetails(MixerHandle, @MixerControlDetails,MIXER_SETCONTROLDETAILSF_VALUE);
  finally
    mixerClose(MixerHandle);
  end;
end;

然后打电话:

var y:word;
begin
  SetMasterVolume(2000,y);
end;

【讨论】:

【参考方案3】:

最终代码是(对于Delphi 7):

unit DevUnit;


interface

uses Windows, ActiveX, Classes, Graphics, OleServer, OleCtrls, StdVCL,ComObj;


const
  // TypeLibrary Major and minor versions
  CLASS_IMMDeviceEnumerator: TGUID             = 'BCDE0395-E52F-467C-8E3D-C4579291692E';
  IID_IMMDeviceEnumerator: TGUID                = 'A95664D2-9614-4F35-A746-DE8DB63617E6';
  IID_IMMDevice: TGUID                          = 'D666063F-1587-4E43-81F1-B948E807363F';
  IID_IMMDeviceCollection: TGUID                = '0BD7A1BE-7A1A-44DB-8397-CC5392387B5E';
  IID_IAudioEndpointVolume: TGUID               = '5CDF2C82-841E-4546-9722-0CF74078229A';
  IID_IAudioMeterInformation : TGUID            = 'C02216F6-8C67-4B5B-9D00-D008E73E0064';
  IID_IAudioEndpointVolumeCallback: TGUID       = '657804FA-D6AD-4496-8A60-352752AF4F89';
  DEVICE_STATE_ACTIVE                   = $00000001;
  DEVICE_STATE_UNPLUGGED                = $00000002;
  DEVICE_STATE_NOTPRESENT               = $00000004;
  DEVICE_STATEMASK_ALL                  = $00000007;

type
  EDataFlow = TOleEnum;
const
  eRender                               = $00000000;
  eCapture                              = $00000001;
  eAll                                  = $00000002;
  EDataFlow_enum_count                  = $00000003;

type
  ERole = TOleEnum;

const
  eConsole                              = $00000000;
  eMultimedia                           = $00000001;
  eCommunications                       = $00000002;
  ERole_enum_count                      = $00000003;

type

  IAudioEndpointVolumeCallback = interface(IUnknown)
  ['657804FA-D6AD-4496-8A60-352752AF4F89']
  end;

  IMMAudioEndpointVolume = interface(IUnknown)
  ['5CDF2C82-841E-4546-9722-0CF74078229A']
    Function RegisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
    Function UnregisterControlChangeNotify( AudioEndPtVol: IAudioEndpointVolumeCallback): Integer; stdcall;
    Function GetChannelCount(out PInteger): Integer; stdcall;
    Function SetMasterVolumeLevel(fLevelDB: single; pguidEventContext: PGUID):Integer; stdcall;
    Function SetMasterVolumeLevelScalar(fLevelDB: single; pguidEventContext: PGUID):Integer; stdcall;
    Function GetMasterVolumeLevel(out fLevelDB: single):Integer; stdcall;
    Function GetMasterVolumeLevelScaler(out fLevel: single):Integer; stdcall;
    Function SetChannelVolumeLevel(nChannel: Integer; fLevelDB: single; pguidEventContext: PGUID):Integer; stdcall;
    Function SetChannelVolumeLevelScalar(nChannel: Integer; fLevelDB: single; pguidEventContext: PGUID):Integer; stdcall;
    Function GetChannelVolumeLevel(nChannel: Integer; out fLevelDB: single) : Integer; stdcall;
    Function GetChannelVolumeLevelScalar(nChannel: Integer; out fLevel: single) : Integer; stdcall;
    Function SetMute(bMute: Boolean ; pguidEventContext: PGUID) :Integer; stdcall;
    Function GetMute(out bMute: Boolean ) :Integer; stdcall;
    Function GetVolumeStepInfo( pnStep: Integer; out pnStepCount: Integer):Integer; stdcall;
    Function VolumeStepUp(pguidEventContext: PGUID) :Integer; stdcall;
    Function VolumeStepDown(pguidEventContext: PGUID) :Integer; stdcall;
    Function QueryHardwareSupport(out pdwHardwareSupportMask): Integer; stdcall;
    Function GetVolumeRange(out pflVolumeMindB: single; out pflVolumeMaxdB: single; out pflVolumeIncrementdB: single): Integer; stdcall;
  end;

  IPropertyStore = interface(IUnknown)
  end;

type
  IMMDevice = interface(IUnknown)
  ['D666063F-1587-4E43-81F1-B948E807363F']
    Function Activate(  refId :PGUID;
                        dwClsCtx: DWORD;
                        pActivationParams: PInteger ;
                        out pEndpointVolume: IMMAudioEndpointVolume): Hresult; stdCall;
    Function OpenPropertyStore(stgmAccess: DWORD; out ppProperties :IPropertyStore): Hresult; stdcall;
    Function GetId(out ppstrId: PLPWSTR ): Hresult; stdcall;
    Function GetState(out State :Integer): Hresult; stdcall;
  end;

  IMMDeviceCollection = interface(IUnknown)
  ['0BD7A1BE-7A1A-44DB-8397-CC5392387B5E']
  end;
  IMMNotificationClient = interface (IUnknown)
  ['7991EEC9-7E89-4D85-8390-6C703CEC60C0']
  end;
  IMMDeviceEnumerator = interface(IUnknown)
  ['A95664D2-9614-4F35-A746-DE8DB63617E6']
    Function EnumAudioEndpoints( dataFlow: EDataFlow; deviceState: SYSUINT; DevCollection:IMMDeviceCollection ): Hresult ; stdcall;
    Function GetDefaultAudioEndpoint(EDF: SYSUINT; ER: SYSUINT; out Dev :IMMDevice ): Hresult ; stdcall;
    Function GetDevice( pwstrId: pointer ; out Dev :IMMDevice) : HResult; stdcall;
    Function RegisterEndpointNotificationCallback(pClient :IMMNotificationClient) :Hresult; stdcall;
  end;
  implementation
end.

【讨论】:

【参考方案4】:

MMDevApi 有许多不正确的声明。双参数应该是单参数。布尔参数作为整数更好地工作。许多(如果不是全部)TGUID 参数应该是 PGUID。更正声明后,我可以设置静音和音量级别。

【讨论】:

以上是关于vista/xp中如何调整主音量的主要内容,如果未能解决你的问题,请参考以下文章

录制的视频主题音量能减吗

如何在Windows 7/8/10中使用热键来调整音量?

如何在javascript中调整音频文件的音量[重复]

如何以编程方式在 Android 中调整麦克风音量

如何在FL Studio中对整首歌曲音量进行调整

无法在我的 iphone 应用程序中调整音量