blob: f9d9058c25121b077556c6b7fe02af8178d906a9 [file] [log] [blame]
/**********
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 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();
}