/**********
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 2.1 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 does not use Windows' built-in software mixer.
// Implementation

#include <WindowsAudioInputDevice_noMixer.hh>

////////// AudioInputPort definition //////////

class AudioInputPort {
public:
  void open(unsigned numChannels, unsigned samplingFrequency, unsigned granularityInMS);
  void open(); // open with default parameters
  void close();

public:
  int index;
  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::numAudioInputPorts;
  portNames->portName = new char*[WindowsAudioInputDevice::numAudioInputPorts];

  for (unsigned i = 0; i < WindowsAudioInputDevice::numAudioInputPorts; ++i) {
    AudioInputPort& audioInputPort = WindowsAudioInputDevice::ourAudioInputPorts[i];

    portNames->portName[i] = strDup(audioInputPort.name);
  }

  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) {
	success = initialSetInputPort(inputPortNumber);
}

WindowsAudioInputDevice::~WindowsAudioInputDevice() {
  if (fCurPortIndex >= 0) ourAudioInputPorts[fCurPortIndex].close();

  delete[] ourAudioInputPorts; ourAudioInputPorts = NULL;
  numAudioInputPorts = 0;
}

void WindowsAudioInputDevice::initializeIfNecessary() {
  if (ourAudioInputPorts != NULL) return; // we've already been initialized
  numAudioInputPorts = waveInGetNumDevs();
  ourAudioInputPorts = new AudioInputPort[numAudioInputPorts];

  // Initialize each audio input port
  for (unsigned i = 0; i < numAudioInputPorts; ++i) {
    AudioInputPort& port = ourAudioInputPorts[i];
    port.index = i;
    port.open(); // to set the port name
    port.close();
  }
}

Boolean WindowsAudioInputDevice::setInputPort(int portIndex) {
  initializeIfNecessary();

  if (portIndex < 0 || portIndex >= (int)numAudioInputPorts) { // bad index
    envir().setResultMsg("Bad input port index\n");
    return False;
  }

  // Check that this port is allowed:
  if (allowedDeviceNames != NULL) {
	  int i;
	  for (i = 0; allowedDeviceNames[i] != NULL; ++i) {
		  if (strncmp(ourAudioInputPorts[portIndex].name, allowedDeviceNames[i],
			  strlen(allowedDeviceNames[i])) == 0) {
			  // The allowed device name is a prefix of this port's name
			  break; // this port is allowed
		  }
	  }
	  if (allowedDeviceNames[i] == NULL) { // this port is not on the allowed list
		envir().setResultMsg("Access to this audio device is not allowed\n");
		return False;
	  }
  }

  if (portIndex != fCurPortIndex) {
    // The port has changed, so close the old one and open the new one:
    if (fCurPortIndex >= 0) ourAudioInputPorts[fCurPortIndex].close();;
    fCurPortIndex = portIndex;
    ourAudioInputPorts[fCurPortIndex].open(fNumChannels, fSamplingFrequency, fGranularityInMS);
  }
  fCurPortIndex = portIndex;
  return True;
}

unsigned WindowsAudioInputDevice::numAudioInputPorts = 0;

AudioInputPort* WindowsAudioInputDevice::ourAudioInputPorts = NULL;


////////// AudioInputPort implementation //////////

void AudioInputPort::open(unsigned numChannels, unsigned samplingFrequency, unsigned granularityInMS) {
  do {
    // Get the port name:
    WAVEINCAPS wic;
    if (waveInGetDevCaps(index, &wic, sizeof wic) != MMSYSERR_NOERROR) {
	    name[0] = '\0';
	    break;
	}
    
    #ifdef UNICODE
    // Copy the mixer name:
        wcstombs(name, wic.szPname, MAXPNAMELEN);
    #else
        strncpy(name, wic.szPname, MAXPNAMELEN);
    #endif

	if (!WindowsAudioInputDevice_common::openWavInPort(index, numChannels, samplingFrequency, granularityInMS)) break;

    return;
  } while (0);

  // An error occurred:
  close();
}

void AudioInputPort::open() {
  open(1, 8000, 20);
}

void AudioInputPort::close() {
  WindowsAudioInputDevice_common::waveIn_close();
}


