web-dev-qa-db-ja.com

マスター音量レベルの変更

マスターボリュームレベルを変更するにはどうすればよいですか?このコードを使用する

[DllImport ("winmm.dll")]
public static extern int waveOutSetVolume (IntPtr hwo, uint dwVolume);

waveOutSetVolume (IntPtr.Zero, (((uint)uint.MaxValue & 0x0000ffff) | ((uint)uint.MaxValue << 16)));

ウェーブボリュームは設定できますが、マスターボリュームが小さすぎると効果がありません。

助けてくれてありがとう。

15
lacop

さて、ここに行きます:

const int MAXPNAMELEN            = 32;
const int MIXER_SHORT_NAME_CHARS = 16;
const int MIXER_LONG_NAME_CHARS  = 64;

[Flags] enum MIXERLINE_LINEF : uint{
    ACTIVE       = 0x00000001,
    DISCONNECTED = 0x00008000,
    SOURCE       = 0x80000000
}
[Flags] enum MIXER           : uint{
    GETLINEINFOF_DESTINATION     = 0x00000000,
    GETLINEINFOF_SOURCE          = 0x00000001,
    GETLINEINFOF_LINEID          = 0x00000002,
    GETLINEINFOF_COMPONENTTYPE   = 0x00000003,
    GETLINEINFOF_TARGETTYPE      = 0x00000004,
    GETLINEINFOF_QUERYMASK       = 0x0000000F,

    GETLINECONTROLSF_ALL         = 0x00000000,
    GETLINECONTROLSF_ONEBYID     = 0x00000001,
    GETLINECONTROLSF_ONEBYTYPE   = 0x00000002,
    GETLINECONTROLSF_QUERYMASK   = 0x0000000F,

    GETCONTROLDETAILSF_VALUE     = 0x00000000,
    GETCONTROLDETAILSF_LISTTEXT  = 0x00000001,
    GETCONTROLDETAILSF_QUERYMASK = 0x0000000F,

    OBJECTF_MIXER                = 0x00000000,
    OBJECTF_WAVEOUT              = 0x10000000,
    OBJECTF_WAVEIN               = 0x20000000,
    OBJECTF_MIDIOUT              = 0x30000000,
    OBJECTF_MIDIIN               = 0x40000000,
    OBJECTF_AUX                  = 0x50000000,
    OBJECTF_HANDLE               = 0x80000000,
    OBJECTF_HMIXER               = OBJECTF_HANDLE | OBJECTF_MIXER,
    OBJECTF_HWAVEOUT             = OBJECTF_HANDLE | OBJECTF_WAVEOUT,
    OBJECTF_HWAVEIN              = OBJECTF_HANDLE | OBJECTF_WAVEIN,
    OBJECTF_HMIDIOUT             = OBJECTF_HANDLE | OBJECTF_MIDIOUT,
    OBJECTF_HMIDIIN              = OBJECTF_HANDLE | OBJECTF_MIDIIN
}
[Flags] enum MIXERCONTROL_CT : uint{
    CLASS_MASK        = 0xF0000000,
    CLASS_CUSTOM      = 0x00000000,
    CLASS_METER       = 0x10000000,
    CLASS_SWITCH      = 0x20000000,
    CLASS_NUMBER      = 0x30000000,
    CLASS_SLIDER      = 0x40000000,
    CLASS_FADER       = 0x50000000,
    CLASS_TIME        = 0x60000000,
    CLASS_LIST        = 0x70000000,

    SUBCLASS_MASK     = 0x0F000000,

    SC_SWITCH_BOOLEAN = 0x00000000,
    SC_SWITCH_BUTTON  = 0x01000000,

    SC_METER_POLLED   = 0x00000000,

    SC_TIME_MICROSECS = 0x00000000,
    SC_TIME_MILLISECS = 0x01000000,

    SC_LIST_SINGLE    = 0x00000000,
    SC_LIST_MULTIPLE  = 0x01000000,

    UNITS_MASK        = 0x00FF0000,
    UNITS_CUSTOM      = 0x00000000,
    UNITS_BOOLEAN     = 0x00010000,
    UNITS_SIGNED      = 0x00020000,
    UNITS_UNSIGNED    = 0x00030000,
    UNITS_DECIBELS    = 0x00040000, /* in 10ths */
    UNITS_PERCENT     = 0x00050000, /* in 10ths */
}
[Flags] enum MIXERCONTROL_CONTROLTYPE : uint{
    CUSTOM         = MIXERCONTROL_CT.CLASS_CUSTOM | MIXERCONTROL_CT.UNITS_CUSTOM,
    BOOLEANMETER   = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_BOOLEAN,
    SIGNEDMETER    = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_SIGNED,
    PEAKMETER      = SIGNEDMETER + 1,
    UNSIGNEDMETER  = MIXERCONTROL_CT.CLASS_METER | MIXERCONTROL_CT.SC_METER_POLLED | MIXERCONTROL_CT.UNITS_UNSIGNED,
    BOOLEAN        = MIXERCONTROL_CT.CLASS_SWITCH | MIXERCONTROL_CT.SC_SWITCH_BOOLEAN | MIXERCONTROL_CT.UNITS_BOOLEAN,
    ONOFF          = BOOLEAN + 1,
    MUTE           = BOOLEAN + 2,
    MONO           = BOOLEAN + 3,
    LOUDNESS       = BOOLEAN + 4,
    STEREOENH      = BOOLEAN + 5,
    BASS_BOOST     = BOOLEAN + 0x00002277,
    BUTTON         = MIXERCONTROL_CT.CLASS_SWITCH | MIXERCONTROL_CT.SC_SWITCH_BUTTON | MIXERCONTROL_CT.UNITS_BOOLEAN,
    DECIBELS       = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_DECIBELS,
    SIGNED         = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_SIGNED,
    UNSIGNED       = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_UNSIGNED,
    PERCENT        = MIXERCONTROL_CT.CLASS_NUMBER | MIXERCONTROL_CT.UNITS_PERCENT,
    SLIDER         = MIXERCONTROL_CT.CLASS_SLIDER | MIXERCONTROL_CT.UNITS_SIGNED,
    PAN            = SLIDER + 1,
    QSOUNDPAN      = SLIDER + 2,
    FADER          = MIXERCONTROL_CT.CLASS_FADER | MIXERCONTROL_CT.UNITS_UNSIGNED,
    VOLUME         = FADER + 1,
    BASS           = FADER + 2,
    TREBLE         = FADER + 3,
    EQUALIZER      = FADER + 4,
    SINGLESELECT   = MIXERCONTROL_CT.CLASS_LIST | MIXERCONTROL_CT.SC_LIST_SINGLE | MIXERCONTROL_CT.UNITS_BOOLEAN,
    MUX            = SINGLESELECT + 1,
    MULTIPLESELECT = MIXERCONTROL_CT.CLASS_LIST | MIXERCONTROL_CT.SC_LIST_MULTIPLE | MIXERCONTROL_CT.UNITS_BOOLEAN,
    MIXER          = MULTIPLESELECT + 1,
    MICROTIME      = MIXERCONTROL_CT.CLASS_TIME | MIXERCONTROL_CT.SC_TIME_MICROSECS | MIXERCONTROL_CT.UNITS_UNSIGNED,
    MILLITIME      = MIXERCONTROL_CT.CLASS_TIME | MIXERCONTROL_CT.SC_TIME_MILLISECS | MIXERCONTROL_CT.UNITS_UNSIGNED
}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
struct MIXERLINE{
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
    public struct TargetInfo{
        public uint   dwType;
        public uint   dwDeviceID;
        public ushort wMid;
        public ushort wPid;
        public uint   vDriverVersion;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MAXPNAMELEN)]
        public string szPname;
    }

    public uint            cbStruct;
    public uint            dwDestination;
    public uint            dwSource;
    public uint            dwLineID;
    public MIXERLINE_LINEF fdwLine;
    public uint            dwUser;
    public uint            dwComponentType;
    public uint            cChannels;
    public uint            cConnection;
    public uint            cControls;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_SHORT_NAME_CHARS)]
    public string          szShortName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_LONG_NAME_CHARS)]
    public string          szName;
    public TargetInfo      Target;
}
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]
struct MIXERCONTROL{
    [StructLayout(LayoutKind.Explicit)]
    public struct BoundsInfo{
        [FieldOffset(0)]
        public int    lMinimum;
        [FieldOffset(4)]
        public int    lMaximum;
        [FieldOffset(0)]
        public uint   dwMinimum;
        [FieldOffset(4)]
        public uint   dwMaximum;
        [FieldOffset(8), MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
        public uint[] dwReserved;
    }
    [StructLayout(LayoutKind.Explicit)]
    public struct MetricsInfo{
        [FieldOffset(0)]
        public uint   cSteps;
        [FieldOffset(0)]
        public uint   cbCustomData;
        [FieldOffset(4), MarshalAs(UnmanagedType.ByValArray, SizeConst=5)]
        public uint[] dwReserved;
    }

    public uint                     cbStruct;
    public uint                     dwControlID;
    public MIXERCONTROL_CONTROLTYPE dwControlType;
    public uint                     fdwControl;
    public uint                     cMultipleItems;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_SHORT_NAME_CHARS)]
    public string                   szShortName;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=MIXER_LONG_NAME_CHARS)]
    public string                   szName;
    public BoundsInfo               Bounds;
    public MetricsInfo              Metrics;
}
[StructLayout(LayoutKind.Explicit)]
struct MIXERLINECONTROLS{
    [FieldOffset(0)]
    public uint   cbStruct;
    [FieldOffset(4)]
    public uint   dwLineID;
    [FieldOffset(8)]
    public uint   dwControlID;
    [FieldOffset(8)] // not a typo!  overlaps previous field
    public uint   dwControlType;
    [FieldOffset(12)]
    public uint   cControls;
    [FieldOffset(16)]
    public uint   cbmxctrl;
    [FieldOffset(20)]
    public IntPtr pamxctrl;
}
[StructLayout(LayoutKind.Explicit)]
struct MIXERCONTROLDETAILS{
    [FieldOffset(0)]
    public uint   cbStruct;
    [FieldOffset(4)]
    public uint   dwControlID;
    [FieldOffset(8)]
    public uint   cChannels;
    [FieldOffset(12)]
    public IntPtr hwndOwner;
    [FieldOffset(12)] // not a typo!
    public uint   cMultipleItems;
    [FieldOffset(16)]
    public uint   cbDetails;
    [FieldOffset(20)]
    public IntPtr paDetails;
}
[StructLayout(LayoutKind.Sequential)]
struct VOLUME{
    public int left;
    public int right;
}
struct MixerInfo{
    public uint volumeCtl;
    public uint muteCtl;
    public int  minVolume;
    public int  maxVolume;
}

[DllImport("WinMM.dll", CharSet=CharSet.Auto)]
static extern uint mixerGetLineInfo      (IntPtr hmxobj, ref MIXERLINE pmxl, MIXER flags);

[DllImport("WinMM.dll", CharSet=CharSet.Auto)]
static extern uint mixerGetLineControls  (IntPtr hmxobj, ref MIXERLINECONTROLS pmxlc, MIXER flags);

[DllImport("WinMM.dll", CharSet=CharSet.Auto)]
static extern uint mixerGetControlDetails(IntPtr hmxobj, ref MIXERCONTROLDETAILS pmxcd, MIXER flags);

[DllImport("WinMM.dll", CharSet=CharSet.Auto)]
static extern uint mixerSetControlDetails(IntPtr hmxobj, ref MIXERCONTROLDETAILS pmxcd, MIXER flags);

static MixerInfo GetMixerControls(){
    MIXERLINE         mxl = new MIXERLINE();
    MIXERLINECONTROLS mlc = new MIXERLINECONTROLS();
    mxl.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERLINE));
    mlc.cbStruct = (uint)Marshal.SizeOf(typeof(MIXERLINECONTROLS));

    mixerGetLineInfo(IntPtr.Zero, ref mxl, MIXER.OBJECTF_MIXER | MIXER.GETLINEINFOF_DESTINATION);

    mlc.dwLineID  = mxl.dwLineID;
    mlc.cControls = mxl.cControls;
    mlc.cbmxctrl  = (uint)Marshal.SizeOf(typeof(MIXERCONTROL));
    mlc.pamxctrl  = Marshal.AllocHGlobal((int)(mlc.cbmxctrl * mlc.cControls));

    mixerGetLineControls(IntPtr.Zero, ref mlc, MIXER.OBJECTF_MIXER | MIXER.GETLINECONTROLSF_ALL);

    MixerInfo rtn = new MixerInfo();

    for(int i = 0; i < mlc.cControls; i++){
        MIXERCONTROL mxc = (MIXERCONTROL)Marshal.PtrToStructure((IntPtr)((int)mlc.pamxctrl + (int)mlc.cbmxctrl * i), typeof(MIXERCONTROL));
        switch(mxc.dwControlType){
        case MIXERCONTROL_CONTROLTYPE.VOLUME:
            rtn.volumeCtl = mxc.dwControlID;
            rtn.minVolume = mxc.Bounds.lMinimum;
            rtn.maxVolume = mxc.Bounds.lMaximum;
            break;
        case MIXERCONTROL_CONTROLTYPE.MUTE:
            rtn.muteCtl = mxc.dwControlID;
            break;
        }
    }

    Marshal.FreeHGlobal(mlc.pamxctrl);

    return rtn;
}
static VOLUME GetVolume(MixerInfo mi){
    MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS();
    mcd.cbStruct       = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
    mcd.dwControlID    = mi.volumeCtl;
    mcd.cMultipleItems = 0;
    mcd.cChannels      = 2;
    mcd.cbDetails      = (uint)Marshal.SizeOf(typeof(int));
    mcd.paDetails      = Marshal.AllocHGlobal((int)mcd.cbDetails);

    mixerGetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER);

    VOLUME rtn = (VOLUME)Marshal.PtrToStructure(mcd.paDetails, typeof(VOLUME));

    Marshal.FreeHGlobal(mcd.paDetails);

    return rtn;
}
static bool IsMuted(MixerInfo mi){
    MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS();
    mcd.cbStruct       = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
    mcd.dwControlID    = mi.muteCtl;
    mcd.cMultipleItems = 0;
    mcd.cChannels      = 1;
    mcd.cbDetails      = 4;
    mcd.paDetails      = Marshal.AllocHGlobal((int)mcd.cbDetails);

    mixerGetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER);

    int rtn = Marshal.ReadInt32(mcd.paDetails);

    Marshal.FreeHGlobal(mcd.paDetails);

    return rtn != 0;
}
static void AdjustVolume(MixerInfo mi, int delta){
    VOLUME volume = GetVolume(mi);

    if(delta > 0){
        volume.left  = Math.Min(mi.maxVolume, volume.left  + delta);
        volume.right = Math.Min(mi.maxVolume, volume.right + delta);
    }else{
        volume.left  = Math.Max(mi.minVolume, volume.left  + delta);
        volume.right = Math.Max(mi.minVolume, volume.right + delta);
    }

    SetVolume(mi, volume);
}
static void SetVolume(MixerInfo mi, VOLUME volume){
    MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS();
    mcd.cbStruct       = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
    mcd.dwControlID    = mi.volumeCtl;
    mcd.cMultipleItems = 0;
    mcd.cChannels      = 2;
    mcd.cbDetails      = (uint)Marshal.SizeOf(typeof(int));
    mcd.paDetails      = Marshal.AllocHGlobal((int)mcd.cbDetails);

    Marshal.StructureToPtr(volume, mcd.paDetails, false);

    mixerSetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER);

    Marshal.FreeHGlobal(mcd.paDetails);
}
static void SetMute(MixerInfo mi, bool mute){
    MIXERCONTROLDETAILS mcd = new MIXERCONTROLDETAILS();
    mcd.cbStruct       = (uint)Marshal.SizeOf(typeof(MIXERCONTROLDETAILS));
    mcd.dwControlID    = mi.muteCtl;
    mcd.cMultipleItems = 0;
    mcd.cChannels      = 1;
    mcd.cbDetails      = 4;
    mcd.paDetails      = Marshal.AllocHGlobal((int)mcd.cbDetails);

    Marshal.WriteInt32(mcd.paDetails, mute ? 1 : 0);

    mixerSetControlDetails(IntPtr.Zero, ref mcd, MIXER.GETCONTROLDETAILSF_VALUE | MIXER.OBJECTF_MIXER);

    Marshal.FreeHGlobal(mcd.paDetails);
}

このコードは巨大で醜いです。これはいくつかのC++コードの翻訳であり、すべてのP/Invokeのものを定義する必要があるため、はるかに多くのコードになります。しかし、私はそれをテストしました、そしてそれは働きます。それを使用するには、次のようなものが必要です。

MixerInfo mi = GetMixerControls();
AdjustVolume(mi, 100);    // add 100 to the current volume

または

MixerInfo mi = GetMixerControls();
AdjustVolume(mi, (mi.maxVolume - mi.minVolume) / 10);    // increase the volume by 10% of total range

または

MixerInfo mi = GetMixerControls();
SetVolume(mi, mi.maxVolume);    // let's get this party crunk'd!

または

MixerInfo mi = GetMixerControls();
SetMute(mi, true);    // shhhh!!!!!!

[〜#〜]警告[〜#〜]

固定サイズのintとフィールドオフセットを使用しているため、64ビットWindowsではこれが失敗する可能性があります。私はそれをテストしておらず、これらのフィールドサイズが64ビットに拡張されるかどうかを知るのに十分な注意を払っていません。 警告codor

[〜#〜]編集[〜#〜]

簡単にするために(比較的言えば)、エラー処理は省略しました。すべてのmixerXXX関数の戻りコードを実際に確認する必要がありますが、それは読者の演習として残しておきます(次のように読んでください:私はこれを行うのが面倒でした)。

31
P Daddy

マスターボリューム(Vista以降の場合)の場合、次のようになります。

ISimpleAudioVolume :: SetMasterVolume

説明したように ここ 、あなたはセクションを参照するかもしれません:

Windows VistaのコアオーディオAPI 詳細。

この呼び出しは、Media Foundation呼び出しではなく、WASAPI(WindowsオーディオセッションAPI)呼び出しです。ISimpleAudioVolume:: SetMasterVolume(SetMasterVolumeメソッドは、オーディオセッションのマスターボリュームレベルを設定します。)

ただし、これは、Media CenterのUIに、その呼び出しによって設定された新しいサウンドレベルを反映させるのが難しい場合があります。これは、 スレッドが示す です。

Windows XPの場合、これを調べることができます スクリプト そして多分 この他のスクリプト
オーディオライブラリ も興味深いかもしれません。

この古い オーディオプロジェクト マスターボリューム部分もあります:

BOOL CVolumeDlg::amdInitialize()
{
    ASSERT(m_hMixer == NULL);

    // get the number of mixer devices present in the system
    m_nNumMixers = ::mixerGetNumDevs();

    m_hMixer = NULL;
    ::ZeroMemory(&m_mxcaps, sizeof(MIXERCAPS));

    m_strDstLineName.Empty();
    m_strVolumeControlName.Empty();
    m_dwMinimum = 0;
    m_dwMaximum = 0;
    m_dwVolumeControlID = 0;

    // open the first mixer
    // A "mapper" for audio mixer devices does not currently exist.
    if (m_nNumMixers != 0)
    {
        if (::mixerOpen(&m_hMixer,
                        0,
                        reinterpret_cast<DWORD>(this->GetSafeHwnd()),
                        NULL,
                        MIXER_OBJECTF_MIXER | CALLBACK_WINDOW)
            != MMSYSERR_NOERROR)
        {
            return FALSE;
        }

        if (::mixerGetDevCaps(reinterpret_cast<UINT>(m_hMixer),
                              &m_mxcaps, sizeof(MIXERCAPS))
            != MMSYSERR_NOERROR)
        {
            return FALSE;
        }
    }

    return TRUE;
}

BOOL CVolumeDlg::amdUninitialize()
{
    BOOL bSucc = TRUE;

    if (m_hMixer != NULL)
    {
        bSucc = (::mixerClose(m_hMixer) == MMSYSERR_NOERROR);
        m_hMixer = NULL;
    }

    return bSucc;
}

BOOL CVolumeDlg::amdGetMasterVolumeControl()
{
    if (m_hMixer == NULL)
    {
        return FALSE;
    }

    // get dwLineID
    MIXERLINE mxl;
    mxl.cbStruct = sizeof(MIXERLINE);
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
    if (::mixerGetLineInfo(reinterpret_cast<HMIXEROBJ>(m_hMixer),
                           &mxl,
                           MIXER_OBJECTF_HMIXER |
                           MIXER_GETLINEINFOF_COMPONENTTYPE)
        != MMSYSERR_NOERROR)
    {
        return FALSE;
    }

    // get dwControlID
    MIXERCONTROL mxc;
    MIXERLINECONTROLS mxlc;
    mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
    mxlc.dwLineID = mxl.dwLineID;
    mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
    mxlc.cControls = 1;
    mxlc.cbmxctrl = sizeof(MIXERCONTROL);
    mxlc.pamxctrl = &mxc;
    if (::mixerGetLineControls(reinterpret_cast<HMIXEROBJ>(m_hMixer),
                               &mxlc,
                               MIXER_OBJECTF_HMIXER |
                               MIXER_GETLINECONTROLSF_ONEBYTYPE)
        != MMSYSERR_NOERROR)
    {
        return FALSE;
    }

    // store dwControlID
    m_strDstLineName = mxl.szName;
    m_strVolumeControlName = mxc.szName;
    m_dwMinimum = mxc.Bounds.dwMinimum;
    m_dwMaximum = mxc.Bounds.dwMaximum;
    m_dwVolumeControlID = mxc.dwControlID;

    return TRUE;
}

BOOL CVolumeDlg::amdGetMasterVolumeValue(DWORD &dwVal) const
{
    if (m_hMixer == NULL)
    {
        return FALSE;
    }

    MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;
    MIXERCONTROLDETAILS mxcd;
    mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID = m_dwVolumeControlID;
    mxcd.cChannels = 1;
    mxcd.cMultipleItems = 0;
    mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
    mxcd.paDetails = &mxcdVolume;
    if (::mixerGetControlDetails(reinterpret_cast<HMIXEROBJ>(m_hMixer),
                                 &mxcd,
                                 MIXER_OBJECTF_HMIXER |
                                 MIXER_GETCONTROLDETAILSF_VALUE)
        != MMSYSERR_NOERROR)
    {
        return FALSE;
    }

    dwVal = mxcdVolume.dwValue;

    return TRUE;
}

BOOL CVolumeDlg::amdSetMasterVolumeValue(DWORD dwVal) const
{
    if (m_hMixer == NULL)
    {
        return FALSE;
    }

    MIXERCONTROLDETAILS_UNSIGNED mxcdVolume = { dwVal };
    MIXERCONTROLDETAILS mxcd;
    mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID = m_dwVolumeControlID;
    mxcd.cChannels = 1;
    mxcd.cMultipleItems = 0;
    mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
    mxcd.paDetails = &mxcdVolume;
    if (::mixerSetControlDetails(reinterpret_cast<HMIXEROBJ>(m_hMixer),
                                 &mxcd,
                                 MIXER_OBJECTF_HMIXER |
                                 MIXER_SETCONTROLDETAILSF_VALUE)
        != MMSYSERR_NOERROR)
    {
        return FALSE;
    }

    return TRUE;
}
6
VonC

この無料のライブラリを使用してください、それは簡単で、仕事をします。 InputSimulator

キーの押下をシミュレートします。この参照を追加して、次のような静的メソッドが必要な場所で呼び出すだけです。

  InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_UP);

  InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_DOWN);

  InputSimulator.SimulateKeyPress(VirtualKeyCode.VOLUME_MUTE);

次に、マスターvokumeレベルを取得する場合は、次のようにします。

  // volume update
  MMDevice defaultDevice = new MMDeviceEnumerator()
        .GetDefaultAudioEndpoint(DataFlow.Render‌​, Role.Multimedia);
  // veloce attesa per l'aggiornamento del volume
  Thread.Sleep(100);
  float level = defaultDevice.AudioEndpointVolume.MasterVolumeLevelScalar; 

これを行うと、現在のボリュームが0-1形式で水平になります(たとえば、52%は0.52です)0-100形式にしたい場合は、単にlevel * 100を実行します。

0