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

📄 windowsaudioinputdevice_mixer.cpp

📁 Live media server used to transfer mpeg or other video/audio media
💻 CPP
📖 第 1 页 / 共 2 页
字号:
  : hMixer(NULL), dwRecLineID(0), numPorts(0), ports(NULL) {}Mixer::~Mixer() {  delete[] ports;}void Mixer::open(unsigned numChannels, unsigned samplingFrequency, unsigned granularityInMS) {  HMIXER newHMixer = NULL;  do {    MIXERCAPS mc;    if (mixerGetDevCaps(index, &mc, sizeof mc) != MMSYSERR_NOERROR) break;        // Copy the mixer name:    strncpy(name, mc.szPname, MAXPNAMELEN);        // Find the correct line for this mixer:    unsigned i, uWavIn;    unsigned nWavIn = waveInGetNumDevs();    for (i = 0; i < nWavIn; ++i) {      WAVEINCAPS wic;      if (waveInGetDevCaps(i, &wic, sizeof wic) != MMSYSERR_NOERROR) continue;            MIXERLINE ml;      ml.cbStruct = sizeof ml;      ml.Target.dwType  = MIXERLINE_TARGETTYPE_WAVEIN;      strncpy(ml.Target.szPname, wic.szPname, MAXPNAMELEN);      ml.Target.vDriverVersion = wic.vDriverVersion;      ml.Target.wMid = wic.wMid;      ml.Target.wPid = wic.wPid;            if (mixerGetLineInfo((HMIXEROBJ)index, &ml, MIXER_GETLINEINFOF_TARGETTYPE/*|MIXER_OBJECTF_MIXER*/) == MMSYSERR_NOERROR) {				// this is the right line	uWavIn = i;	dwRecLineID = ml.dwLineID;	break;      }    }    if (i >= nWavIn) break; // error: we couldn't find the right line        if (mixerOpen(&newHMixer, index, (unsigned long)NULL, (unsigned long)NULL, MIXER_OBJECTF_MIXER) != MMSYSERR_NOERROR) break;    if (newHMixer == NULL) break;        // Sanity check: re-call "mixerGetDevCaps()" using the mixer device handle:    if (mixerGetDevCaps((UINT)newHMixer, &mc, sizeof mc) != MMSYSERR_NOERROR) break;    if (mc.cDestinations < 1) break; // error: this mixer has no destinations             	if (!WindowsAudioInputDevice_common::openWavInPort(uWavIn, numChannels, samplingFrequency, granularityInMS)) break;    hMixer = newHMixer;    return;  } while (0);    // An error occurred:  close(); }        void Mixer::open() {  open(1, 8000, 20);}void Mixer::getPortsInfo() {  MIXERCAPS mc;  mixerGetDevCaps((UINT)hMixer, &mc, sizeof mc);    MIXERLINE mlt;  unsigned i;  for (i = 0; i < mc.cDestinations; ++i) {    memset(&mlt, 0, sizeof mlt);    mlt.cbStruct = sizeof mlt;    mlt.dwDestination = i;    if (mixerGetLineInfo((HMIXEROBJ)hMixer, &mlt, MIXER_GETLINEINFOF_DESTINATION) != MMSYSERR_NOERROR) continue;    if (mlt.dwLineID == dwRecLineID) break; // this is the destination we're interested in  }  ports = new AudioInputPort[mlt.cConnections];    numPorts = mlt.cConnections;  for (i = 0; i < numPorts; ++i) {    MIXERLINE mlc;    memcpy(&mlc, &mlt, sizeof mlc);    mlc.dwSource = i;    mixerGetLineInfo((HMIXEROBJ)hMixer, &mlc, MIXER_GETLINEINFOF_SOURCE/*|MIXER_OBJECTF_HMIXER*/);    ports[i].tag = mlc.dwLineID;	ports[i].dwComponentType = mlc.dwComponentType;    strncpy(ports[i].name, mlc.szName, MIXER_LONG_NAME_CHARS);  }    // Make the microphone the first port in the list:  for (i = 1; i < numPorts; ++i) {#ifdef OLD_MICROPHONE_TESTING_CODE    if (_strnicmp("mic", ports[i].name, 3) == 0 ||	_strnicmp("mik", ports[i].name, 3) == 0) {#else	if (ports[i].dwComponentType == MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE) {#endif      AudioInputPort tmp = ports[0];      ports[0] = ports[i];      ports[i] = tmp;    }  }}Boolean Mixer::enableInputPort(unsigned portIndex, char const*& errReason, MMRESULT& errCode) {  errReason = NULL; // unless there's an error  AudioInputPort& port = ports[portIndex];    MIXERCONTROL mc;  mc.cMultipleItems = 1; // in case it doesn't get set below  MIXERLINECONTROLS mlc;#if 0 // the following doesn't seem to be needed, and can fail:  mlc.cbStruct = sizeof mlc;  mlc.pamxctrl = &mc;  mlc.cbmxctrl = sizeof (MIXERCONTROL);  mlc.dwLineID = port.tag;  mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;  if ((errCode = mixerGetLineControls((HMIXEROBJ)hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE/*|MIXER_OBJECTF_HMIXER*/)) != MMSYSERR_NOERROR) {    errReason = "mixerGetLineControls()";    return False;  }#endif    MIXERLINE ml;  memset(&ml, 0, sizeof (MIXERLINE));  ml.cbStruct = sizeof (MIXERLINE);  ml.dwLineID = port.tag;  if ((errCode = mixerGetLineInfo((HMIXEROBJ)hMixer, &ml, MIXER_GETLINEINFOF_LINEID)) != MMSYSERR_NOERROR) {    errReason = "mixerGetLineInfo()1";    return False;  }    char portname[MIXER_LONG_NAME_CHARS+1];  strncpy(portname, ml.szName, MIXER_LONG_NAME_CHARS);    memset(&ml, 0, sizeof (MIXERLINE));  ml.cbStruct = sizeof (MIXERLINE);  ml.dwLineID = dwRecLineID;  if ((errCode = mixerGetLineInfo((HMIXEROBJ)hMixer, &ml, MIXER_GETLINEINFOF_LINEID/*|MIXER_OBJECTF_HMIXER*/)) != MMSYSERR_NOERROR) {    errReason = "mixerGetLineInfo()2";    return False;  }    // Get Mixer/MUX control information (need control id to set and get control details)  mlc.cbStruct = sizeof mlc;  mlc.dwLineID = ml.dwLineID;  mlc.cControls = 1;  mc.cbStruct = sizeof mc; // Needed???#####  mc.dwControlID = 0xDEADBEEF; // For testing #####  mlc.pamxctrl = &mc;  mlc.cbmxctrl = sizeof mc;  mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MUX; // Single Select  if ((errCode = mixerGetLineControls((HMIXEROBJ)hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE/*|MIXER_OBJECTF_HMIXER*/)) != MMSYSERR_NOERROR) {    mlc.dwControlType = MIXERCONTROL_CONTROLTYPE_MIXER; // Multiple Select    mixerGetLineControls((HMIXEROBJ)hMixer, &mlc, MIXER_GETLINECONTROLSF_ONEBYTYPE/*|MIXER_OBJECTF_HMIXER*/);  }    unsigned matchLine = 0;  if (mc.cMultipleItems > 1) {    // Before getting control, we need to know which line to grab.    // We figure this out by listing the lines, and comparing names:    MIXERCONTROLDETAILS mcd;    mcd.cbStruct = sizeof mcd;    mcd.cChannels = ml.cChannels;    mcd.cMultipleItems = mc.cMultipleItems;    MIXERCONTROLDETAILS_LISTTEXT* mcdlText = new MIXERCONTROLDETAILS_LISTTEXT[mc.cMultipleItems];            mcd.cbDetails = sizeof (MIXERCONTROLDETAILS_LISTTEXT);    mcd.paDetails = mcdlText;        if (mc.dwControlID != 0xDEADBEEF) { // we know the control id for real      mcd.dwControlID = mc.dwControlID;      if ((errCode = mixerGetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_GETCONTROLDETAILSF_LISTTEXT/*|MIXER_OBJECTF_HMIXER*/)) != MMSYSERR_NOERROR) {	delete[] mcdlText;	errReason = "mixerGetControlDetails()1";	return False;      }    } else {      // Hack: We couldn't find a MUX or MIXER control, so try to guess the control id:      for (mc.dwControlID = 0; mc.dwControlID < 32; ++mc.dwControlID) {	mcd.dwControlID = mc.dwControlID;	if ((errCode = mixerGetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_GETCONTROLDETAILSF_LISTTEXT/*|MIXER_OBJECTF_HMIXER*/)) == MMSYSERR_NOERROR) break;      }      if (mc.dwControlID == 32) { // unable to guess mux/mixer control id	delete[] mcdlText;	errReason = "mixerGetControlDetails()2";	return False;      }    }        for (unsigned i = 0; i < mcd.cMultipleItems; ++i) {      if (strcmp(mcdlText[i].szName, portname) == 0) {	matchLine = i;	break;      }    }    delete[] mcdlText;  }    // Now get control itself:  MIXERCONTROLDETAILS mcd;  mcd.cbStruct = sizeof mcd;  mcd.dwControlID = mc.dwControlID;  mcd.cChannels = ml.cChannels;  mcd.cMultipleItems = mc.cMultipleItems;  MIXERCONTROLDETAILS_BOOLEAN* mcdbState = new MIXERCONTROLDETAILS_BOOLEAN[mc.cMultipleItems];          mcd.paDetails = mcdbState;  mcd.cbDetails = sizeof (MIXERCONTROLDETAILS_BOOLEAN);    if ((errCode = mixerGetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_GETCONTROLDETAILSF_VALUE/*|MIXER_OBJECTF_HMIXER*/)) != MMSYSERR_NOERROR) {    delete[] mcdbState;    errReason = "mixerGetControlDetails()3";    return False;  }    for (unsigned j = 0; j < mcd.cMultipleItems; ++j) {    mcdbState[j].fValue = (j == matchLine);  }    if ((errCode = mixerSetControlDetails((HMIXEROBJ)hMixer, &mcd, MIXER_OBJECTF_HMIXER)) != MMSYSERR_NOERROR) {    delete[] mcdbState;    errReason = "mixerSetControlDetails()";    return False;  }  delete[] mcdbState;    return True;}void Mixer::close() {  WindowsAudioInputDevice_common::waveIn_close();  if (hMixer != NULL) mixerClose(hMixer);  hMixer = NULL; dwRecLineID = 0;}

⌨️ 快捷键说明

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