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

📄 windowsaudioinputdevice_mixer.cpp

📁 Live media server used to transfer mpeg or other video/audio media
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/**********This library is free software; you can redistribute it and/or modify it underthe terms of the GNU Lesser General Public License as published by theFree Software Foundation; either version 2.1 of the License, or (at youroption) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)This library is distributed in the hope that it will be useful, but WITHOUTANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESSFOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License formore details.You should have received a copy of the GNU Lesser General Public Licensealong with this library; if not, write to the Free Software Foundation, Inc.,59 Temple Place, Suite 330, Boston, MA  02111-1307  USA**********/// Copyright (c) 2001-2004 Live Networks, Inc.  All rights reserved.// Windows implementation of a generic audio input device// This version uses Windows' built-in software mixer.// Implementation#include <WindowsAudioInputDevice_mixer.hh>////////// Mixer and AudioInputPort definition //////////class AudioInputPort {public:  int tag;  DWORD dwComponentType;  char name[MIXER_LONG_NAME_CHARS];};class Mixer {public:  Mixer();  virtual ~Mixer();    void open(unsigned numChannels, unsigned samplingFrequency, unsigned granularityInMS);  void open(); // open with default parameters  void getPortsInfo();  Boolean enableInputPort(unsigned portIndex, char const*& errReason, MMRESULT& errCode);  void close();    unsigned index;  HMIXER hMixer; // valid when open  DWORD dwRecLineID; // valid when open  unsigned numPorts;  AudioInputPort* ports;  char name[MAXPNAMELEN];};////////// AudioInputDevice (remaining) implementation //////////AudioInputDevice*AudioInputDevice::createNew(UsageEnvironment& env, int inputPortNumber,			    unsigned char bitsPerSample,			    unsigned char numChannels,			    unsigned samplingFrequency,			    unsigned granularityInMS) {  Boolean success;  WindowsAudioInputDevice* newSource    = new WindowsAudioInputDevice(env, inputPortNumber,				  bitsPerSample, numChannels,				  samplingFrequency, granularityInMS,				  success);  if (!success) {delete newSource; newSource = NULL;}    return newSource;}AudioPortNames* AudioInputDevice::getPortNames() {  WindowsAudioInputDevice::initializeIfNecessary();    AudioPortNames* portNames = new AudioPortNames;  portNames->numPorts = WindowsAudioInputDevice::numInputPortsTotal;  portNames->portName = new char*[WindowsAudioInputDevice::numInputPortsTotal];    // If there's more than one mixer, print only the port name.  // If there's two or more mixers, also include the mixer name  // (to disambiguate port names that may be the same name in different mixers)  char portNameBuffer[2*MAXPNAMELEN+10/*slop*/];  char mixerNameBuffer[MAXPNAMELEN];  char const* portNameFmt;  if (WindowsAudioInputDevice::numMixers <= 1) {    portNameFmt = "%s";  } else {    portNameFmt = "%s (%s)";  }    unsigned curPortNum = 0;  for (unsigned i = 0; i < WindowsAudioInputDevice::numMixers; ++i) {    Mixer& mixer = WindowsAudioInputDevice::ourMixers[i];        if (WindowsAudioInputDevice::numMixers <= 1) {      mixerNameBuffer[0] = '\0';    } else {      strncpy(mixerNameBuffer, mixer.name, sizeof mixerNameBuffer);#if 0      // Hack: Simplify the mixer name, by truncating after the first space character:      for (int k = 0; k < sizeof mixerNameBuffer && mixerNameBuffer[k] != '\0'; ++k) {	if (mixerNameBuffer[k] == ' ') {	  mixerNameBuffer[k] = '\0';	  break;	}      }#endif    }        for (unsigned j = 0; j < mixer.numPorts; ++j) {      sprintf(portNameBuffer, portNameFmt, mixer.ports[j].name, mixerNameBuffer);      portNames->portName[curPortNum++] = strDup(portNameBuffer);    }  }    return portNames;}////////// WindowsAudioInputDevice implementation //////////WindowsAudioInputDevice::WindowsAudioInputDevice(UsageEnvironment& env, int inputPortNumber,			  unsigned char bitsPerSample,			  unsigned char numChannels,			  unsigned samplingFrequency,			  unsigned granularityInMS,			  Boolean& success)  : WindowsAudioInputDevice_common(env, inputPortNumber,		bitsPerSample, numChannels, samplingFrequency, granularityInMS),	fCurMixerId(-1) {	success = initialSetInputPort(inputPortNumber);}WindowsAudioInputDevice::~WindowsAudioInputDevice() {  if (fCurMixerId >= 0) ourMixers[fCurMixerId].close();    delete[] ourMixers; ourMixers = NULL;  numMixers = numInputPortsTotal = 0;}void WindowsAudioInputDevice::initializeIfNecessary() {  if (ourMixers != NULL) return; // we've already been initialized  numMixers = mixerGetNumDevs();  ourMixers = new Mixer[numMixers];    // Initialize each mixer:  numInputPortsTotal = 0;  for (unsigned i = 0; i < numMixers; ++i) {    Mixer& mixer = ourMixers[i];    mixer.index = i;    mixer.open();    if (mixer.hMixer != NULL) {      // This device has a valid mixer.  Get information about its ports:      mixer.getPortsInfo();      mixer.close();            if (mixer.numPorts == 0) continue;            numInputPortsTotal += mixer.numPorts;    } else {      mixer.ports = NULL;      mixer.numPorts = 0;    }  }}Boolean WindowsAudioInputDevice::setInputPort(int portIndex) {  initializeIfNecessary();    if (portIndex < 0 || portIndex >= (int)numInputPortsTotal) { // bad index    envir().setResultMsg("Bad input port index\n");    return False;  }    // Find the mixer and port that corresponds to "portIndex":  int newMixerId, portWithinMixer, portIndexCount = 0;  for (newMixerId = 0; newMixerId < (int)numMixers; ++newMixerId) {    int prevPortIndexCount = portIndexCount;    portIndexCount += ourMixers[newMixerId].numPorts;    if (portIndexCount > portIndex) { // it's with this mixer      portWithinMixer = portIndex - prevPortIndexCount;      break;    }  }    // Check that this mixer is allowed:  if (allowedDeviceNames != NULL) {	  int i;	  for (i = 0; allowedDeviceNames[i] != NULL; ++i) {		  if (strncmp(ourMixers[newMixerId].name, allowedDeviceNames[i],			  strlen(allowedDeviceNames[i])) == 0) {			  // The allowed device name is a prefix of this mixer's name			  break; // this mixer is allowed		  }	  }	  if (allowedDeviceNames[i] == NULL) { // this mixer is not on the allowed list		envir().setResultMsg("Access to this audio device is not allowed\n");		return False;	  }  }    if (newMixerId != fCurMixerId) {     // The mixer has changed, so close the old one and open the new one:    if (fCurMixerId >= 0) ourMixers[fCurMixerId].close();    fCurMixerId = newMixerId;    ourMixers[fCurMixerId].open(fNumChannels, fSamplingFrequency, fGranularityInMS);  }  if (portIndex != fCurPortIndex) {    // Change the input port:    fCurPortIndex = portIndex;    char const* errReason;    MMRESULT errCode;    if (!ourMixers[newMixerId].enableInputPort(portWithinMixer, errReason, errCode)) {      char resultMsg[100];      sprintf(resultMsg, "Failed to enable input port: %s failed (0x%08x)\n", errReason, errCode);      envir().setResultMsg(resultMsg);      return False;    }    // Later, may also need to transfer 'gain' to new port #####  }  return True;}unsigned WindowsAudioInputDevice::numMixers = 0;Mixer* WindowsAudioInputDevice::ourMixers = NULL;unsigned WindowsAudioInputDevice::numInputPortsTotal = 0;////////// Mixer and AudioInputPort implementation //////////Mixer::Mixer()

⌨️ 快捷键说明

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