/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)

This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  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()
  : 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;

    #ifdef UNICODE
    // Copy the mixer name:
        wcstombs(name, mc.szPname, MAXPNAMELEN);
    #else
        strncpy(name, mc.szPname, MAXPNAMELEN);
    #endif

    // 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;

    #ifdef UNICODE
          wcsncpy(ml.Target.szPname, wic.szPname, MAXPNAMELEN);
    #else
          strncpy(ml.Target.szPname, wic.szPname, MAXPNAMELEN);
    #endif

      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;
#ifdef UNICODE
    wcstombs(ports[i].name, mlc.szName, MIXER_LONG_NAME_CHARS);
#else
    strncpy(ports[i].name, mlc.szName, MIXER_LONG_NAME_CHARS);
#endif
  }

  // 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;
  }

  

  #ifdef UNICODE
    wchar_t portname[MIXER_LONG_NAME_CHARS+1];
    wcsncpy(portname, ml.szName, MIXER_LONG_NAME_CHARS);
  #else
    char portname[MIXER_LONG_NAME_CHARS+1];
    strncpy(portname, ml.szName, MIXER_LONG_NAME_CHARS);
  #endif

  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;
      }
    }

    #ifdef UNICODE
    for (unsigned i = 0; i < mcd.cMultipleItems; ++i) {
        if (wcscmp(mcdlText[i].szName, portname) == 0) {
	    matchLine = i;
	    break;
        }
    }
    #else
    for (unsigned i = 0; i < mcd.cMultipleItems; ++i) {
        if (strcmp(mcdlText[i].szName, portname) == 0) {
	    matchLine = i;
	    break;
        }
    }
    #endif
    
    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;
}
