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

📄 mixer.cpp

📁 游戏音频程序设计-Beginning.Game.Audio.Programming
💻 CPP
字号:
// Mixer.cpp: implementation of the CMixer class.
//
//////////////////////////////////////////////////////////////////////

#include "Mixer.h"
#include "ErrorHandling.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

namespace AudioEngine {

const CMixerLine CMixer::Master(MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS);
const CMixerLine CMixer::WaveOut(MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS);
const CMixerLine CMixer::CDAudio(MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS);


// returns true if the given mixer supports this line
bool CMixerLine::IsValidForMixer(HMIXER mixer, int &lineid, int &channels) const
{
  int result;
  // make sure the destination line is valid
  MIXERLINE line;
  line.cbStruct = sizeof(MIXERLINE);
  line.dwComponentType = m_Dest;
  result = mixerGetLineInfo((HMIXEROBJ)mixer, &line, MIXER_GETLINEINFOF_COMPONENTTYPE);
  if (result) {
    // failed!
    return(false);
  }
  
  lineid = line.dwLineID; // just in case source is undefined...
  channels = line.cChannels;

  // make sure source line is valid... to do this, iterate through each connection
  // of the (known valid) destination line.
  if (m_Source != MIXERLINE_COMPONENTTYPE_SRC_UNDEFINED) {
    bool valid = false;
    for (int connection=0; connection < line.cConnections; connection++) {
      MIXERLINE srcline;
      memcpy(&srcline, &line, sizeof(MIXERLINE));
      
      srcline.cbStruct = sizeof(MIXERLINE);
      srcline.dwSource = connection;

      result = mixerGetLineInfo((HMIXEROBJ)mixer, &srcline, MIXER_GETLINEINFOF_SOURCE);
      if (result) {
        // failed!
        Throw("CMixerLine::IsValidForMixer: mixerGetLineInfo failed while trying to validate source.");
      }

      if (srcline.dwComponentType == m_Source) {
        // it's valid!
        valid = true;
        lineid = srcline.dwLineID;
        channels = srcline.cChannels;
        break;
      }

      if (!valid) return(false);
    }
  }
  
  return(true);
}

void CMixerLine::GetControlInfo(HMIXER mixer, int controltype, int lineid, int &id) const
{
  MIXERCONTROL control;
  MIXERLINECONTROLS linecontrols;
  ZeroMemory(&control, sizeof(MIXERCONTROL));
  ZeroMemory(&linecontrols, sizeof(MIXERLINECONTROLS));

  linecontrols.cbStruct = sizeof(MIXERLINECONTROLS);
  linecontrols.dwLineID = lineid;
  linecontrols.dwControlType = controltype;
  linecontrols.cControls = 1;
  linecontrols.cbmxctrl = sizeof(MIXERCONTROL);
  linecontrols.pamxctrl = &control;
  control.cbStruct = sizeof(MIXERCONTROL);


  if (mixerGetLineControls((HMIXEROBJ)mixer, &linecontrols, MIXER_GETLINECONTROLSF_ONEBYTYPE)) {
    Throw("CMixerLine::GetControlInfo: mixerGetLineControls failed.");
  }

  id = control.dwControlID;
  
  


}

bool CMixerLine::SetControlValue(HMIXER mixer, int lineid, int control, int channels, int value) const
{
  MIXERCONTROLDETAILS controldetails;
  MIXERCONTROLDETAILS_UNSIGNED controldetailsunsigned[128];

  if (channels > 128) { Throw("CMixerLine::SetControlValue: Channel overflow."); }

  int id=0; GetControlInfo(mixer, control, lineid, id);
  
  ZeroMemory(&controldetails, sizeof(MIXERCONTROLDETAILS));

  controldetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
  controldetails.dwControlID = id;
  controldetails.cChannels = channels;
  controldetails.cbDetails = sizeof(controldetailsunsigned);
  controldetails.paDetails = &controldetailsunsigned[0];

  // all channels of this control get the same value.
  // if you want to do things like set the left and right volume
  // independently, you'll need to change this.
  for (int q=0; q < controldetails.cChannels; q++) {
    controldetailsunsigned[q].dwValue = value;
  }

  // set
  if (mixerSetControlDetails((HMIXEROBJ)mixer, &controldetails, MIXER_OBJECTF_HMIXER | MIXER_SETCONTROLDETAILSF_VALUE )) {
    return(false);
  }
  return(true);
}

int CMixerLine::GetControlValue(HMIXER mixer, int lineid, int control, int channels) const
{
  MIXERCONTROLDETAILS controldetails;
  MIXERCONTROLDETAILS_UNSIGNED controldetailsunsigned;

  int id; GetControlInfo(mixer, control, lineid, id);
  
  ZeroMemory(&controldetails, sizeof(MIXERCONTROLDETAILS));

  controldetails.cbStruct = sizeof(MIXERCONTROLDETAILS);
  controldetails.dwControlID = id;
  controldetails.cChannels = channels;
  controldetails.cbDetails = sizeof(controldetailsunsigned);
  controldetails.paDetails = &controldetailsunsigned;

  // validate
  if (mixerGetControlDetails((HMIXEROBJ)mixer, &controldetails, 0)) {
    Throw("CMixerLine::GetControlValue: mixerGetControlDetails failed.");
  }

  return(controldetailsunsigned.dwValue);
}

CMixer::CMixer()
{
  m_hMixer = NULL;
}

CMixer::~CMixer()
{

}

void CMixer::Init()
{
  if (mixerOpen(&m_hMixer, 0, 0, 0, CALLBACK_NULL)) {
    Throw("CMixer::Init(): mixerOpen failed.");
  }
}

void CMixer::UnInit()
{
  mixerClose(m_hMixer);
  m_hMixer = NULL;
}

bool CMixer::SetVolume(const CMixerLine &line, int vol_0_to_65535)
{
  int lineid, channels;
  if (!line.IsValidForMixer(m_hMixer, lineid, channels)) return(false);
  return(line.SetControlValue(m_hMixer, lineid, MIXERCONTROL_CONTROLTYPE_VOLUME, channels, vol_0_to_65535));
}

int CMixer::GetVolume(const CMixerLine &line)
{
  int lineid, channels;
  if (!line.IsValidForMixer(m_hMixer, lineid, channels)) return(false);
  return(line.GetControlValue(m_hMixer, lineid, MIXERCONTROL_CONTROLTYPE_VOLUME, channels));
}

bool CMixer::Mute(const CMixerLine &line)
{
  int lineid, channels;
  if (!line.IsValidForMixer(m_hMixer, lineid, channels)) return(false);
  return(line.SetControlValue(m_hMixer, lineid, MIXERCONTROL_CONTROLTYPE_MUTE, channels, 1));
}

bool CMixer::UnMute(const CMixerLine &line)
{
  int lineid, channels;
  if (!line.IsValidForMixer(m_hMixer, lineid, channels)) return(false);
  return(line.SetControlValue(m_hMixer, lineid, MIXERCONTROL_CONTROLTYPE_MUTE, channels, 0));
}





}; // namespace

⌨️ 快捷键说明

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