现在的位置: 首页 > 综合 > 正文

混音器音量控制

2013年10月01日 ⁄ 综合 ⁄ 共 5988字 ⁄ 字号 评论关闭
//MixVolumeCtrl.h

#pragma once

#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")

class CMixVolumeCtrl
{
  HMIXER m_hMixer;
  DWORD dwMinVol, dwMaxVol;
  UINT nVolumeControlID;
  UINT nMuteControlID;

//构析
public:
  CMixVolumeCtrl()
  {
    m_hMixer = NULL;
    dwMinVol = dwMaxVol = 0;
    nVolumeControlID = -1;
    nMuteControlID = -1;
  }

  ~CMixVolumeCtrl()
  {
    MixClose();
  }

  //打开设备
  //当调用的窗口句柄非0时,调用窗口可以加入MM_MIXM_CONTROL_CHANGE消息处理
  //成功打开设备返回非0
  BOOL MixOpen(DWORD dwType=MIXERLINE_COMPONENTTYPE_SRC_LINE, HWND hCallbackWnd=NULL)
  {
    BOOL bRet = FALSE;
    MixClose();
    if( mixerGetNumDevs() > 0)
    {
      MMRESULT hr;
      DWORD fdwOpen = MIXER_OBJECTF_MIXER | (hCallbackWnd? CALLBACK_WINDOW:0);
      hr = mixerOpen(&m_hMixer, 0,	(DWORD_PTR)hCallbackWnd, 0, fdwOpen);
      if (hr == MMSYSERR_NOERROR)
      {      
        // get dwLineID
        MIXERLINE mxl = {0};
        mxl.cbStruct = sizeof(MIXERLINE);
        mxl.dwComponentType = dwType;
        hr = mixerGetLineInfo((HMIXEROBJ)m_hMixer,
          &mxl,
          MIXER_OBJECTF_HMIXER |
          MIXER_GETLINEINFOF_COMPONENTTYPE);
        if (hr == MMSYSERR_NOERROR)
        {
          MIXERCONTROL mxc = {0};
          MIXERLINECONTROLS mxlc = {0};
          mxlc.cbStruct = sizeof(MIXERLINECONTROLS);
          mxlc.dwLineID = mxl.dwLineID;
          mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
          mxlc.cControls = 1;
          mxlc.cbmxctrl = sizeof(MIXERCONTROL);
          mxlc.pamxctrl = &mxc;
          hr = mixerGetLineControls((HMIXEROBJ)m_hMixer,
            &mxlc,
            MIXER_OBJECTF_HMIXER |
            MIXER_GETLINECONTROLSF_ONEBYTYPE);
          if (hr == MMSYSERR_NOERROR)// get volume ControlID
          {	          
            dwMinVol = mxc.Bounds.dwMinimum;
            dwMaxVol = mxc.Bounds.dwMaximum;
            nVolumeControlID = mxc.dwControlID;
            bRet |= 0x01;
          }

          mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MUTE;
          hr = mixerGetLineControls((HMIXEROBJ)m_hMixer,
            &mxlc,
            MIXER_OBJECTF_HMIXER |
            MIXER_GETLINECONTROLSF_ONEBYTYPE);
          if (hr == MMSYSERR_NOERROR)// get mute ControlID
          {
            nMuteControlID = mxc.dwControlID;
            bRet |= 0x02;
          }

          /*
          mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_SIGNEDMETER;
          hr = mixerGetLineControls((HMIXEROBJ)m_hMixer,
            &mxlc,
            MIXER_OBJECTF_HMIXER |
            MIXER_GETLINECONTROLSF_ONEBYTYPE);
          if(hr == MMSYSERR_NOERROR)
          {
            bRet |= 0x04;
          }
          */
        }
      }
    }
    return bRet;
  }

  void MixClose()
  {
    if(m_hMixer)
    {
      mixerClose(m_hMixer);
      m_hMixer = NULL;
    }
    dwMinVol = dwMaxVol = 0;
    nVolumeControlID = -1;
    nMuteControlID = -1;
  }

  HMIXER Get_hMixer() const { return m_hMixer; }
  DWORD GetMinVolume() const { return dwMinVol; }
  DWORD GetMaxVolume() const { return dwMaxVol; }
  UINT GetVolumeControlID() const { return nVolumeControlID; }
  UINT GetMuteControlID() const { return nMuteControlID; }

  BOOL GetVolume(DWORD &Vol)
  {
    BOOL bRet = 0;
    if(m_hMixer && (nVolumeControlID != -1))
    {
      MIXERCONTROLDETAILS_UNSIGNED mxcdVolume;
      MIXERCONTROLDETAILS mxcd = {0};
      mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS);
      mxcd.dwControlID = nVolumeControlID;
      mxcd.cChannels = 1;
      mxcd.cMultipleItems = 0;
      mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
      mxcd.paDetails = &mxcdVolume;
      if (::mixerGetControlDetails((HMIXEROBJ)m_hMixer,
        &mxcd,
        MIXER_OBJECTF_HMIXER |
        MIXER_GETCONTROLDETAILSF_VALUE)
        == MMSYSERR_NOERROR)
      {
        Vol = mxcdVolume.dwValue;
        bRet = TRUE;
      }
    }
    return bRet;
  }

  BOOL SetVolume(DWORD Vol)
  {
    BOOL bRet = 0;

    if(m_hMixer && (nVolumeControlID != -1))
    {
      if(Vol < dwMinVol) Vol = dwMinVol;
      if(Vol > dwMaxVol) Vol = dwMaxVol;

      MIXERCONTROLDETAILS_UNSIGNED mixVolume = { Vol };
      MIXERCONTROLDETAILS mixLine = {0};
      mixLine.cbStruct = sizeof(MIXERCONTROLDETAILS);
      mixLine.dwControlID = nVolumeControlID;
      mixLine.cChannels = 1;
      mixLine.cMultipleItems = 0;
      mixLine.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED);
      mixLine.paDetails = &mixVolume;
      if (mixerSetControlDetails((HMIXEROBJ)m_hMixer,
        &mixLine,
        MIXER_OBJECTF_HMIXER |
        MIXER_SETCONTROLDETAILSF_VALUE) == MMSYSERR_NOERROR)
      {
        bRet = 1;
      }  
    }
    return bRet;
  }

  BOOL IsMute(BOOL &bVal)
  {
    BOOL bRet = 0;
    if(m_hMixer && (nMuteControlID != -1))
    {
      MIXERCONTROLDETAILS_BOOLEAN mixMute;
      MIXERCONTROLDETAILS mixd;
      mixd.cbStruct = sizeof(MIXERCONTROLDETAILS);
      mixd.dwControlID = nMuteControlID;
      mixd.cChannels = 1;
      mixd.cMultipleItems = 0;
      mixd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
      mixd.paDetails = &mixMute;
      if (mixerGetControlDetails((HMIXEROBJ)m_hMixer,
        &mixd,
        MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE)
        == MMSYSERR_NOERROR)
      {	    
        bVal = mixMute.fValue ? TRUE:FALSE;
        bRet = TRUE;
      }
    }
    return bRet;
  }

  BOOL SetMute(BOOL bMute)
  {
    BOOL bRet = 0;
    if(m_hMixer && (nMuteControlID!= -1))
    {
      MIXERCONTROLDETAILS_BOOLEAN mixMute ={bMute};
      MIXERCONTROLDETAILS mixd = {0};
      mixd.cbStruct = sizeof(MIXERCONTROLDETAILS);
      mixd.dwControlID = nMuteControlID;
      mixd.cChannels = 1;
      mixd.cMultipleItems = 0;
      mixd.cbDetails = sizeof(MIXERCONTROLDETAILS_BOOLEAN);
      mixd.paDetails = &mixMute;
      if (mixerSetControlDetails((HMIXEROBJ)m_hMixer,
        &mixd,
        MIXER_OBJECTF_HMIXER | MIXER_GETCONTROLDETAILSF_VALUE)
        == MMSYSERR_NOERROR)
      {	    
        bRet = TRUE;
      }
    }
    return bRet;    
  }


};

//测试Microphone 音量控制

//在一标准对话框程序上添加一个Slider控件 IDC_VOLUME_SLIDER, 用DDX_Control(pDX, IDC_VOLUME_SLIDER, m_SliderCtrl);关联控件

 

// MicVolumeControlDlg.h : 头文件
//

#pragma once

#include "MixVolumeCtrl.h"

// CMicVolumeControlDlg 对话框
class CMicVolumeControlDlg : public CDialog
{

public:
  CMixVolumeCtrl m_MicrophonCtrl;
  CSliderCtrl m_SliderCtrl;
protected:
  virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
  virtual BOOL OnInitDialog();

  //其它标准的部分就不再列出

 

// MicVolumeControlDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "MicVolumeControlDlg.h"

BOOL CMicVolumeControlDlg::OnInitDialog()
{
  CDialog::OnInitDialog();

  // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
  //  执行此操作
  SetIcon(m_hIcon, TRUE);			// 设置大图标
  SetIcon(m_hIcon, FALSE);		// 设置小图标

  // TODO: 在此添加额外的初始化代码

  if(m_MicrophonCtrl.MixOpen(MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE, GetSafeHwnd()))
  {
    m_SliderCtrl.SetRange(m_MicrophonCtrl.GetMinVolume(), m_MicrophonCtrl.GetMaxVolume(), TRUE);
    m_SliderCtrl.SetTic(m_MicrophonCtrl.GetMaxVolume());
    m_SliderCtrl.SetTicFreq(m_MicrophonCtrl.GetMaxVolume()/10);

    DWORD dwVolume ;
    if(m_MicrophonCtrl.GetVolume(dwVolume))
      m_SliderCtrl.SetPos(dwVolume);
  }
  else
  {
    AfxMessageBox(_T("open MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE device failed"));
  }

  return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}


LRESULT CMicVolumeControlDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
  // TODO: 在此添加专用代码和/或调用基类
  switch(message)
  {
  case(WM_HSCROLL):
    {
      if(lParam && ((HWND)lParam == m_SliderCtrl.m_hWnd))
      {
        int nPos = m_SliderCtrl.GetPos();
        if(nPos <=0)
          m_MicrophonCtrl.SetMute(TRUE);
        else
        {
          m_MicrophonCtrl.SetMute(FALSE);
          m_MicrophonCtrl.SetVolume(nPos);
        }
      }
      break;
    }
  case(MM_MIXM_CONTROL_CHANGE):
    {
      if(m_MicrophonCtrl.Get_hMixer() == (HMIXER)wParam
        && m_MicrophonCtrl.GetVolumeControlID() == (UINT)lParam)
      {
        DWORD dwVolume;
        if(m_MicrophonCtrl.GetVolume(dwVolume))
          m_SliderCtrl.SetPos(dwVolume);
      }
      break;
    }
  }

  return CDialog::WindowProc(message, wParam, lParam);
}

 

抱歉!评论已关闭.