[plain text]
#include <libkern/c++/OSArray.h>
#include <IOKit/audio/IOAudioTypes.h>
#include "USBAudioObject.h"
#include "AppleUSBAudioCommon.h"
OSDefineMetaClassAndStructors (USBAudioConfigObject, OSObject);
USBAudioConfigObject * USBAudioConfigObject::create (const IOUSBConfigurationDescriptor * newConfigurationDescriptor, UInt8 controlInterfaceNum) {
USBAudioConfigObject * configObject;
configObject = new USBAudioConfigObject;
FailIf (NULL == configObject, Exit);
if (FALSE == configObject->init (newConfigurationDescriptor, controlInterfaceNum)) {
configObject->release();
configObject = 0;
}
Exit:
return configObject;
}
#if DEBUGLOGGING
void USBAudioConfigObject::DumpConfigMemoryToIOLog (void) {
#if 1
UInt8 * descriptorPtr;
UInt8 descriptorIndex;
UInt8 length;
char descriptor[256];
char num[4];
descriptorPtr = (UInt8*)theConfigurationDescriptorPtr;
while (*descriptorPtr != 0) {
length = *descriptorPtr;
descriptor[0] = 0;
for (descriptorIndex = 0; descriptorIndex < length; descriptorIndex++) {
sprintf (num, "%2x ", *descriptorPtr++);
strcat (descriptor, num);
}
descriptor[length * 3] = 0;
debugIOLog ("%s", descriptor);
}
#endif
}
#endif
bool USBAudioConfigObject::init (const IOUSBConfigurationDescriptor * newConfigurationDescriptor, UInt8 controlInterfaceNum) {
Boolean result;
result = FALSE;
FailIf (FALSE == OSObject::init (), Exit);
FailIf (NULL == newConfigurationDescriptor, Exit);
theControlInterfaceNum = controlInterfaceNum;
debugIOLog ("allocating %d bytes for config descriptor", USBToHostWord (newConfigurationDescriptor->wTotalLength));
theConfigurationDescriptorPtr = (IOUSBConfigurationDescriptor *)IOMalloc (USBToHostWord (newConfigurationDescriptor->wTotalLength) + 1);
FailIf (NULL == theConfigurationDescriptorPtr, Exit);
memcpy (theConfigurationDescriptorPtr, newConfigurationDescriptor, USBToHostWord (newConfigurationDescriptor->wTotalLength));
((UInt8 *)theConfigurationDescriptorPtr)[USBToHostWord (newConfigurationDescriptor->wTotalLength)] = 0;
#if DEBUGLOGGING
DumpConfigMemoryToIOLog ();
#endif
ParseConfigurationDescriptor ();
result = TRUE;
Exit:
if (NULL != theConfigurationDescriptorPtr) {
IOFree (theConfigurationDescriptorPtr, USBToHostWord (newConfigurationDescriptor->wTotalLength) + 1);
theConfigurationDescriptorPtr = NULL;
}
return result;
}
void USBAudioConfigObject::free (void) {
if (NULL != theControls) {
theControls->release ();
theControls = NULL;
}
if (NULL != theStreams) {
theStreams->release ();
theStreams = NULL;
}
if (NULL != theConfigurationDescriptorPtr) {
IOFree (theConfigurationDescriptorPtr, USBToHostWord (theConfigurationDescriptorPtr->wTotalLength) + 1);
}
OSObject::free ();
}
Boolean USBAudioConfigObject::ChannelHasMuteControl (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 featureUnitID, UInt8 channelNum) {
USBAudioControlObject * thisControl;
Boolean theControl;
theControl = FALSE;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
theControl = thisControl->ChannelHasMuteControl (featureUnitID, channelNum);
return theControl;
}
Boolean USBAudioConfigObject::ChannelHasVolumeControl (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 featureUnitID, UInt8 channelNum) {
USBAudioControlObject * thisControl;
Boolean theControl;
theControl = FALSE;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
theControl = thisControl->ChannelHasVolumeControl (featureUnitID, channelNum);
return theControl;
}
UInt8 USBAudioConfigObject::FindNextAltInterfaceWithNumChannels (UInt8 interfaceNum, UInt8 startingAltInterface, UInt8 numChannelsRequested) {
UInt16 numAltInterfaces;
UInt8 altInterface;
UInt8 altInterfaceIndx;
altInterface = 255;
if (startingAltInterface == 0)
startingAltInterface = 1;
numAltInterfaces = GetNumAltStreamInterfaces (interfaceNum);
for (altInterfaceIndx = startingAltInterface; altInterfaceIndx < numAltInterfaces && altInterface == 255; altInterfaceIndx++) {
if (numChannelsRequested == GetNumChannels (interfaceNum, altInterfaceIndx)) {
altInterface = altInterfaceIndx;
}
}
return altInterface;
}
UInt8 USBAudioConfigObject::FindNextAltInterfaceWithSampleSize (UInt8 interfaceNum, UInt8 startingAltInterface, UInt8 sampleSizeRequested) {
UInt16 numAltInterfaces;
UInt8 altInterface;
UInt8 altInterfaceIndx;
altInterface = 255;
if (startingAltInterface == 0)
startingAltInterface = 1;
numAltInterfaces = GetNumAltStreamInterfaces (interfaceNum);
for (altInterfaceIndx = startingAltInterface; altInterfaceIndx < numAltInterfaces && altInterface == 255; altInterfaceIndx++) {
if (sampleSizeRequested == GetSampleSize (interfaceNum, altInterfaceIndx)) {
altInterface = altInterfaceIndx;
}
}
return altInterface;
}
UInt8 USBAudioConfigObject::FindNextAltInterfaceWithSampleRate (UInt8 interfaceNum, UInt8 startingAltInterface, UInt32 sampleRateRequested) {
UInt16 numAltInterfaces;
UInt8 altInterface;
UInt8 altInterfaceIndx;
altInterface = 255;
if (startingAltInterface == 0)
startingAltInterface = 1;
numAltInterfaces = GetNumAltStreamInterfaces (interfaceNum);
for (altInterfaceIndx = startingAltInterface; altInterfaceIndx < numAltInterfaces && altInterface == 255; altInterfaceIndx++) {
if (TRUE == VerifySampleRateIsSupported (interfaceNum, altInterfaceIndx, sampleRateRequested)) {
altInterface = altInterfaceIndx;
}
}
return altInterface;
}
UInt8 USBAudioConfigObject::FindAltInterfaceWithSettings (UInt8 interfaceNum, UInt8 numChannels, UInt8 sampleSize, UInt32 sampleRate) {
UInt8 potentialAltInterface;
UInt8 theAltInterface;
Boolean found;
potentialAltInterface = 1;
theAltInterface = 255;
found = FALSE;
while (!found && potentialAltInterface != 255) {
if ((GetFormat (interfaceNum, potentialAltInterface) & 0x0FFF) != 0) { potentialAltInterface = FindNextAltInterfaceWithNumChannels (interfaceNum, potentialAltInterface, numChannels);
FailIf (255 == potentialAltInterface, Exit);
if (potentialAltInterface == FindNextAltInterfaceWithSampleSize (interfaceNum, potentialAltInterface, sampleSize)) {
FailIf (255 == potentialAltInterface, Exit);
if (0 != sampleRate) {
if (potentialAltInterface == FindNextAltInterfaceWithSampleRate (interfaceNum, potentialAltInterface, sampleRate)) {
found = TRUE;
theAltInterface = potentialAltInterface;
} else {
potentialAltInterface++;
}
} else {
found = TRUE;
theAltInterface = potentialAltInterface;
}
} else {
potentialAltInterface++;
}
} else {
potentialAltInterface++;
}
}
Exit:
return theAltInterface;
}
UInt32 USBAudioConfigObject::GetAC3BSID (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt32 bmBSID;
bmBSID = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
bmBSID = thisStream->GetAC3BSID ();
return bmBSID;
}
UInt8 USBAudioConfigObject::GetFeatureUnitIDConnectedToOutputTerminal (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 outputTerminalID) {
USBAudioControlObject * thisControl;
UInt8 featureUnitID;
debugIOLog ("GetFeatureUnitIDConnectedToOutputTerminal (%d, %d, %d)", interfaceNum, altInterfaceNum, outputTerminalID);
featureUnitID = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
debugIOLog ("GetControlObject returns %p", thisControl);
if (thisControl)
featureUnitID = thisControl->GetFeatureUnitIDConnectedToOutputTerminal (outputTerminalID);
return featureUnitID;
}
UInt8 USBAudioConfigObject::GetFirstStreamInterfaceNum (void) {
USBAudioStreamObject * thisStream;
UInt8 interfaceNum;
thisStream = NULL;
interfaceNum = 0;
if (NULL != theStreams) {
thisStream = OSDynamicCast (USBAudioStreamObject, theStreams->getObject (0));
}
if (thisStream)
interfaceNum = thisStream->GetInterfaceNum ();
return interfaceNum;
}
void USBAudioConfigObject::GetControlledStreamNumbers (UInt8 **controledStreams, UInt8 *numControledStreams) {
USBAudioControlObject * thisControl;
*controledStreams = 0;
*numControledStreams = 0;
thisControl = NULL;
if (NULL != theControls) {
thisControl = OSDynamicCast (USBAudioControlObject, theControls->getObject (0));
} else {
debugIOLog ("couldn't get the control object");
}
if (thisControl) {
*controledStreams = thisControl->GetStreamInterfaceNumbers ();
*numControledStreams = thisControl->GetNumStreamInterfaces ();
}
}
UInt8 USBAudioConfigObject::GetControlInterfaceNum (void) {
USBAudioControlObject * thisControl;
UInt8 interfaceNum;
thisControl = NULL;
interfaceNum = 0;
if (NULL != theControls) {
thisControl = OSDynamicCast (USBAudioControlObject, theControls->getObject (0));
}
if (thisControl)
interfaceNum = thisControl->GetInterfaceNum ();
return interfaceNum;
}
UInt16 USBAudioConfigObject::GetFormat (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt16 formatTag;
formatTag = TYPE_I_UNDEFINED;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
formatTag = USBToHostWord (thisStream->GetFormatTag ());
return formatTag;
}
UInt32 USBAudioConfigObject::GetHighestSampleRate (UInt8 interfaceNum, UInt8 altInterfaceNum) {
UInt32 * sampleRates;
UInt32 highSampleRate;
UInt32 i;
UInt8 numSampleRates;
UInt8 highest;
highSampleRate = 0;
numSampleRates = GetNumSampleRates (interfaceNum, altInterfaceNum);
sampleRates = GetSampleRates (interfaceNum, altInterfaceNum);
FailIf (NULL == sampleRates, Exit);
highest = 0;
for (i = 1; i < numSampleRates; i++) {
if (sampleRates[i] > sampleRates[highest])
highest = i;
}
highSampleRate = sampleRates[highest];
Exit:
return highSampleRate;
}
UInt8 USBAudioConfigObject::GetIsocAssociatedEndpointAddress (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 address) {
USBAudioStreamObject * thisStream;
UInt8 assocEndpointAddress;
assocEndpointAddress = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
assocEndpointAddress = thisStream->GetIsocAssociatedEndpointAddress (address);
return assocEndpointAddress;
}
UInt8 USBAudioConfigObject::GetIsocAssociatedEndpointRefreshInt (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 address) {
USBAudioStreamObject * thisStream;
UInt8 assocEndpointRefresh;
assocEndpointRefresh = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
assocEndpointRefresh = thisStream->GetIsocAssociatedEndpointRefreshInt (address);
return assocEndpointRefresh;
}
UInt8 USBAudioConfigObject::GetIsocEndpointAddress (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 direction) {
USBAudioStreamObject * thisStream;
UInt8 endpointAddress;
endpointAddress = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
endpointAddress = thisStream->GetIsocEndpointAddress (direction);
return endpointAddress;
}
UInt8 USBAudioConfigObject::GetIsocEndpointDirection (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
USBAudioControlObject * thisControl;
UInt8 endpointDirection;
UInt8 terminalLink;
UInt8 numOutputs;
UInt8 numInputs;
UInt8 numEndpoints;
UInt8 index;
UInt8 terminalID;
UInt8 direction;
endpointDirection = 0xFF;
direction = 0xFF;
index = 0;
numEndpoints = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
debugIOLog ("GetIsocEndpointDirection (%d, %d), thisStream = %p", interfaceNum, altInterfaceNum, thisStream);
thisControl = GetControlObject (theControlInterfaceNum, 0);
debugIOLog ("GetIsocEndpointDirection (%d, %d), thisControl = %p", interfaceNum, altInterfaceNum, thisControl);
if (NULL != thisStream && NULL != thisControl) {
terminalLink = thisStream->GetTerminalLink (); debugIOLog ("GetIsocEndpointDirection (%d, %d), terminalLink = %d", interfaceNum, altInterfaceNum, terminalLink);
if (0 != terminalLink) {
numOutputs = thisControl->GetNumOutputTerminals ();
debugIOLog ("GetIsocEndpointDirection (%d, %d), numOutputs = %d", interfaceNum, altInterfaceNum, numOutputs);
while (0xFF == direction && index < numOutputs) {
terminalID = thisControl->GetIndexedOutputTerminalID (index);
debugIOLog ("GetIsocEndpointDirection (%d, %d), terminalID = %d", interfaceNum, altInterfaceNum, terminalID);
if (terminalID == terminalLink) {
direction = kUSBIn;
numEndpoints = numOutputs;
debugIOLog ("GetIsocEndpointDirection (%d, %d), found an output terminal (#%d) at index %d", interfaceNum, altInterfaceNum, terminalID, index);
} else {
index++;
}
}
if (0xFF == direction) {
numInputs = thisControl->GetNumInputTerminals ();
debugIOLog ("GetIsocEndpointDirection (%d, %d), Didn't find an output terminal, checking for an input terminal", interfaceNum, altInterfaceNum);
debugIOLog ("GetIsocEndpointDirection (%d, %d), numInputs = %d", interfaceNum, altInterfaceNum, numInputs);
index = 0;
while (0xFF == direction && index < numInputs) {
terminalID = thisControl->GetIndexedInputTerminalID (index);
debugIOLog ("GetIsocEndpointDirection, terminalID = %d", interfaceNum, altInterfaceNum, terminalID);
if (terminalID == terminalLink) {
direction = kUSBOut;
numEndpoints = numInputs;
debugIOLog ("GetIsocEndpointDirection (%d, %d), found an input terminal (#%d) at index %d", interfaceNum, altInterfaceNum, terminalID, index);
} else {
index++;
}
}
}
}
if (0xFF != direction) {
for (index = 0; index < numEndpoints; index++) {
endpointDirection = thisStream->GetIsocEndpointDirection (index);
if (endpointDirection == direction) {
break; }
}
}
}
debugIOLog ("GetIsocEndpointDirection (%d, %d), endpointDirection = %d", interfaceNum, altInterfaceNum, endpointDirection);
return endpointDirection;
}
UInt8 USBAudioConfigObject::GetIsocEndpointSyncType (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 address) {
USBAudioStreamObject * thisStream;
UInt8 endpointSyncType;
endpointSyncType = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
endpointSyncType = thisStream->GetIsocEndpointSyncType (address);
return endpointSyncType;
}
UInt8 USBAudioConfigObject::GetIndexedFeatureUnitID (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 featureUnitIndex) {
USBAudioControlObject * thisControl;
UInt8 featureUnitID;
featureUnitID = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
featureUnitID = thisControl->GetIndexedFeatureUnitID (featureUnitIndex);
return featureUnitID;
}
UInt8 USBAudioConfigObject::GetIndexedMixerUnitID (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 mixerUnitIndex) {
USBAudioControlObject * thisControl;
UInt8 mixerUnitID;
mixerUnitID = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
mixerUnitID = thisControl->GetIndexedMixerUnitID (mixerUnitIndex);
return mixerUnitID;
}
UInt8 USBAudioConfigObject::GetIndexedSelectorUnitID (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 selectorUnitIndex) {
USBAudioControlObject * thisControl;
UInt8 selectorUnitID;
selectorUnitID = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
selectorUnitID = thisControl->GetIndexedSelectorUnitID (selectorUnitIndex);
return selectorUnitID;
}
UInt16 USBAudioConfigObject::GetIndexedInputTerminalType (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 index) {
USBAudioControlObject * thisControl;
UInt16 terminalType;
terminalType = USBToHostWord (INPUT_UNDEFINED);
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
terminalType = USBToHostWord (thisControl->GetIndexedInputTerminalType (index));
return terminalType;
}
UInt8 USBAudioConfigObject::GetIndexedInputTerminalID (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 index) {
USBAudioControlObject * thisControl;
UInt16 terminalID;
terminalID = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
terminalID = thisControl->GetIndexedInputTerminalID (index);
return terminalID;
}
UInt8 USBAudioConfigObject::GetIndexedOutputTerminalID (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 index) {
USBAudioControlObject * thisControl;
UInt16 terminalID;
terminalID = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
terminalID = thisControl->GetIndexedOutputTerminalID (index);
return terminalID;
}
UInt16 USBAudioConfigObject::GetIndexedOutputTerminalType (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 index) {
USBAudioControlObject * thisControl;
UInt16 terminalType;
terminalType = USBToHostWord (OUTPUT_UNDEFINED);
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
terminalType = USBToHostWord (thisControl->GetIndexedOutputTerminalType (index));
return terminalType;
}
UInt16 USBAudioConfigObject::GetInputTerminalType (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 terminalNum) {
USBAudioControlObject * thisControl;
UInt16 terminalType;
terminalType = USBToHostWord (INPUT_UNDEFINED);
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
terminalType = USBToHostWord (thisControl->GetInputTerminalType (terminalNum));
return terminalType;
}
UInt8 USBAudioConfigObject::GetInterfaceClass (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt8 interfaceClass;
interfaceClass = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
interfaceClass = thisStream->GetInterfaceClass ();
return interfaceClass;
}
UInt8 USBAudioConfigObject::GetInterfaceSubClass (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt8 interfaceSubClass;
interfaceSubClass = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
interfaceSubClass = thisStream->GetInterfaceSubClass ();
return interfaceSubClass;
}
UInt32 USBAudioConfigObject::GetLowestSampleRate (UInt8 interfaceNum, UInt8 altInterfaceNum) {
UInt32 * sampleRates;
UInt32 lowSampleRate;
UInt32 i;
UInt8 numSampleRates;
UInt8 lowest;
lowSampleRate = 0xFFFFFFFF;
numSampleRates = GetNumSampleRates (interfaceNum, altInterfaceNum);
sampleRates = GetSampleRates (interfaceNum, altInterfaceNum);
FailIf (NULL == sampleRates, Exit);
lowest = 0;
for (i = 1; i < numSampleRates; i++) {
if (sampleRates[i] < sampleRates[lowest])
lowest = i;
}
lowSampleRate = sampleRates[lowest];
Exit:
return lowSampleRate;
}
UInt16 USBAudioConfigObject::GetMaxBitRate (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt16 maxBitRate;
maxBitRate = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
maxBitRate = USBToHostWord (thisStream->GetMaxBitRate ());
return maxBitRate;
}
UInt8 USBAudioConfigObject::GetNumAltStreamInterfaces (UInt8 interfaceNum) {
USBAudioStreamObject * thisStream;
UInt16 numAltInterfaces;
UInt16 indx;
numAltInterfaces = 0;
if (NULL != theStreams) {
for (indx = 0; indx < theStreams->getCount (); indx++) {
thisStream = OSDynamicCast (USBAudioStreamObject, theStreams->getObject (indx));
if (thisStream && thisStream->GetInterfaceNum () == interfaceNum) {
numAltInterfaces++;
}
}
}
return numAltInterfaces;
}
UInt8 USBAudioConfigObject::GetNumChannels (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt8 numChannels;
numChannels = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
numChannels = thisStream->GetNumChannels ();
return numChannels;
}
UInt8 USBAudioConfigObject::GetNumControls (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 featureUnitID) {
USBAudioControlObject * thisControl;
UInt8 numControls;
numControls = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
numControls = thisControl->GetNumControls (featureUnitID);
return numControls;
}
UInt8 USBAudioConfigObject::GetNumSampleRates (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt8 numSampleRates;
numSampleRates = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
numSampleRates = thisStream->GetNumSampleRates ();
return numSampleRates;
}
UInt8 USBAudioConfigObject::GetNumInputTerminals (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioControlObject * thisControl;
UInt8 numInputTerminals;
numInputTerminals = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
numInputTerminals = thisControl->GetNumInputTerminals ();
return numInputTerminals;
}
UInt8 USBAudioConfigObject::GetNumOutputTerminals (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioControlObject * thisControl;
UInt8 numOutputTerminals;
numOutputTerminals = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
numOutputTerminals = thisControl->GetNumOutputTerminals ();
return numOutputTerminals;
}
UInt8 USBAudioConfigObject::GetNumSelectorUnits (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioControlObject * thisControl;
UInt8 numSelectorUnits;
numSelectorUnits = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
numSelectorUnits = thisControl->GetNumSelectorUnits ();
return numSelectorUnits;
}
UInt8 USBAudioConfigObject::GetNumSources (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 unitID) {
USBAudioControlObject * thisControl;
UInt8 numSources;
numSources = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
numSources = thisControl->GetNumSources (unitID);
return numSources;
}
UInt8 USBAudioConfigObject::GetNumStreamInterfaces (void) {
USBAudioStreamObject * thisStream;
UInt16 numInterfaces;
UInt16 interfaceNum;
UInt16 indx;
numInterfaces = 0;
interfaceNum = 0;
if (NULL != theStreams) {
for (indx = 0; indx < theStreams->getCount (); indx++) {
thisStream = OSDynamicCast (USBAudioStreamObject, theStreams->getObject (indx));
if (thisStream && thisStream->GetInterfaceNum () != interfaceNum) {
interfaceNum = thisStream->GetInterfaceNum ();
numInterfaces++;
}
}
}
return numInterfaces;
}
UInt16 USBAudioConfigObject::GetSamplesPerFrame (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt16 samplesPerFrame;
samplesPerFrame = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
samplesPerFrame = USBToHostWord (thisStream->GetMaxBitRate ());
return samplesPerFrame;
}
UInt32 * USBAudioConfigObject::GetSampleRates (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt32 * sampleRates;
sampleRates = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
sampleRates = thisStream->GetSampleRates ();
return sampleRates;
}
UInt8 USBAudioConfigObject::GetSampleSize (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt8 sampleSize;
sampleSize = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
sampleSize = thisStream->GetSampleSize ();
return sampleSize;
}
UInt8 * USBAudioConfigObject::GetSelectorSources (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 unitID) {
USBAudioControlObject * thisControl;
UInt8 * sources;
sources = NULL;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
sources = thisControl->GetSelectorSources (unitID);
return sources;
}
UInt8 USBAudioConfigObject::GetSubType (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 unitID) {
USBAudioControlObject * thisControl;
UInt8 subType;
subType = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
subType = thisControl->GetSubType (unitID);
return subType;
}
UInt8 USBAudioConfigObject::GetSourceID (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 unitID) {
USBAudioControlObject * thisControl;
UInt8 sourceID;
sourceID = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
sourceID = thisControl->GetSourceID (unitID);
return sourceID;
}
UInt8 USBAudioConfigObject::GetUnitType (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 unitID) {
USBAudioControlObject * thisControl;
UInt8 unitType;
unitType = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
unitType = thisControl->GetSourceID (unitID);
return unitType;
}
UInt8 * USBAudioConfigObject::GetSourceIDs (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 unitID) {
USBAudioControlObject * thisControl;
UInt8 * sourceIDs;
sourceIDs = 0;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
sourceIDs = thisControl->GetSourceIDs (unitID);
return sourceIDs;
}
UInt8 USBAudioConfigObject::GetSubframeSize (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt8 subframeSize;
subframeSize = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
subframeSize = thisStream->GetSubframeSize ();
return subframeSize;
}
UInt8 USBAudioConfigObject::GetTerminalLink (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt8 terminalLink;
terminalLink = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
terminalLink = thisStream->GetTerminalLink ();
return terminalLink;
}
UInt16 USBAudioConfigObject::GetOutputTerminalType (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 terminalNum) {
USBAudioControlObject * thisControl;
UInt16 terminalType;
terminalType = USBToHostWord (OUTPUT_UNDEFINED);
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
terminalType = USBToHostWord (thisControl->GetOutputTerminalType (terminalNum));
return terminalType;
}
Boolean USBAudioConfigObject::IsocEndpointDoesMaxPacketsOnly (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
Boolean maxPacketsOnly;
maxPacketsOnly = FALSE;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
maxPacketsOnly = thisStream->IsocEndpointDoesMaxPacketsOnly ();
return maxPacketsOnly;
}
UInt8 USBAudioConfigObject::IsocEndpointGetLockDelay (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt8 lockDelay;
lockDelay = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
lockDelay = thisStream->IsocEndpointGetLockDelay ();
return lockDelay;
}
UInt8 USBAudioConfigObject::IsocEndpointGetLockDelayUnits (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt8 lockDelayUnits;
lockDelayUnits = 0;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
lockDelayUnits = thisStream->IsocEndpointGetLockDelayUnits ();
return lockDelayUnits;
}
Boolean USBAudioConfigObject::IsocEndpointHasPitchControl (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
Boolean hasPitchCntrl;
hasPitchCntrl = FALSE;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
hasPitchCntrl = thisStream->IsocEndpointHasPitchControl ();
return hasPitchCntrl;
}
Boolean USBAudioConfigObject::IsocEndpointHasSampleFreqControl (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
Boolean hasSampleFreqCntrl;
hasSampleFreqCntrl = FALSE;
thisStream = GetStreamObject (interfaceNum, altInterfaceNum);
if (thisStream)
hasSampleFreqCntrl = thisStream->IsocEndpointHasSampleFreqControl ();
return hasSampleFreqCntrl;
}
Boolean USBAudioConfigObject::MasterHasMuteControl (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt8 featureUnitID) {
USBAudioControlObject * thisControl;
Boolean theControl;
theControl = FALSE;
thisControl = GetControlObject (interfaceNum, altInterfaceNum);
if (thisControl)
theControl = thisControl->MasterHasMuteControl (featureUnitID);
return theControl;
}
Boolean USBAudioConfigObject::VerifySampleRateIsSupported (UInt8 interfaceNum, UInt8 altInterfaceNum, UInt32 verifyRate) {
IOReturn result;
UInt32 * sampleRates;
UInt8 rateIndx;
UInt8 numSampleRates;
result = FALSE;
numSampleRates = GetNumSampleRates (interfaceNum, altInterfaceNum);
sampleRates = GetSampleRates (interfaceNum, altInterfaceNum);
if (numSampleRates) {
for (rateIndx = 0; rateIndx < numSampleRates && result == FALSE; rateIndx++) {
if (sampleRates[rateIndx] == verifyRate) {
result = TRUE;
}
}
} else if (sampleRates) {
if (sampleRates[0] <= verifyRate && sampleRates[1] >= verifyRate) {
result = TRUE;
}
} else {
debugIOLog ("!!!!There aren't any sample rates!!!!");
}
return result;
}
USBAudioStreamObject * USBAudioConfigObject::GetStreamObject (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioStreamObject * thisStream;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisStream = NULL;
if (NULL != theStreams) {
while (!found && indx < theStreams->getCount ()) {
thisStream = OSDynamicCast (USBAudioStreamObject, theStreams->getObject (indx));
if (thisStream && interfaceNum == thisStream->GetInterfaceNum () && altInterfaceNum == thisStream->GetAltInterfaceNum ()) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisStream = NULL;
return thisStream;
}
USBAudioControlObject * USBAudioConfigObject::GetControlObject (UInt8 interfaceNum, UInt8 altInterfaceNum) {
USBAudioControlObject * thisControl;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisControl = NULL;
if (NULL != theControls) {
while (!found && indx < theControls->getCount ()) {
thisControl = OSDynamicCast (USBAudioControlObject, theControls->getObject (indx));
if (thisControl && interfaceNum == thisControl->GetInterfaceNum () && altInterfaceNum == thisControl->GetAltInterfaceNum ()) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisControl = NULL;
return thisControl;
}
void USBAudioConfigObject::ParseConfigurationDescriptor (void) {
USBInterfaceDescriptorPtr theInterfacePtr;
USBAudioControlObject * theControlObject;
USBAudioStreamObject * theStreamObject;
UInt8 * streamInterfaceNumbers;
UInt8 thisInterfaceNumber;
UInt8 lastInterfaceNumber;
UInt8 numStreamInterfaces;
UInt8 interfaceClass;
UInt8 interfaceSubClass;
UInt8 numParsedInterfaces;
UInt8 index;
bool haveControlInterface;
bool foundStreamInterface;
FailIf (NULL == theConfigurationDescriptorPtr, Exit);
FailIf (0 == theConfigurationDescriptorPtr->bLength, Exit);
FailIf (CONFIGURATION != theConfigurationDescriptorPtr->bDescriptorType, Exit);
theControlObject = NULL;
theStreamObject = NULL;
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theConfigurationDescriptorPtr + theConfigurationDescriptorPtr->bLength);
numParsedInterfaces = 0;
numStreamInterfaces = 0;
lastInterfaceNumber = 0;
haveControlInterface = FALSE;
foundStreamInterface = FALSE;
while (theInterfacePtr && 0 != theInterfacePtr->bLength) {
if (INTERFACE == ((ACInterfaceDescriptorPtr)theInterfacePtr)->bDescriptorType) {
debugIOLog ("in INTERFACE in ParseConfigurationDescriptor");
thisInterfaceNumber = ((ACInterfaceDescriptorPtr)theInterfacePtr)->bInterfaceNumber;
theInterfacePtr = ParseInterfaceDescriptor (theInterfacePtr, &interfaceClass, &interfaceSubClass);
debugIOLog ("theControlInterfaceNum = %d, thisInterfaceNumber = %d", theControlInterfaceNum, thisInterfaceNumber);
if (AUDIOCONTROL == interfaceSubClass && theControlInterfaceNum == thisInterfaceNumber) {
debugIOLog ("found a AUDIOCONTROL CS_INTERFACE ");
if (NULL != theControls) {
theControlObject = OSDynamicCast (USBAudioControlObject, theControls->getLastObject ());
}
FailIf (NULL == theControlObject, Exit);
theInterfacePtr = theControlObject->ParseACInterfaceDescriptor (theInterfacePtr, ((ACInterfaceDescriptorPtr)theInterfacePtr)->bInterfaceNumber);
GetControlledStreamNumbers (&streamInterfaceNumbers, &numStreamInterfaces);
haveControlInterface = TRUE;
} else if (haveControlInterface && AUDIOSTREAMING == interfaceSubClass) {
debugIOLog ("in CS_INTERFACE in ParseConfigurationDescriptor");
for (index = 0; index < numStreamInterfaces; index++) {
debugIOLog ("comparing thisInterfaceNum = %d with %d", thisInterfaceNumber, streamInterfaceNumbers[index]);
if (thisInterfaceNumber == streamInterfaceNumbers[index]) {
debugIOLog ("found a AUDIOSTREAMING CS_INTERFACE ");
if (NULL != theStreams) {
theStreamObject = OSDynamicCast (USBAudioStreamObject, theStreams->getLastObject ());
}
FailIf (NULL == theStreamObject, Exit);
theInterfacePtr = theStreamObject->ParseASInterfaceDescriptor (theInterfacePtr, ((ACInterfaceDescriptorPtr)theInterfacePtr)->bInterfaceNumber);
foundStreamInterface = TRUE;
break; }
}
if (thisInterfaceNumber != lastInterfaceNumber) {
lastInterfaceNumber = thisInterfaceNumber;
numParsedInterfaces++;
if (numParsedInterfaces > numStreamInterfaces) {
break; }
}
} else if (MIDISTREAMING == interfaceSubClass) {
debugIOLog ("MIDI, jumping forward %d bytes", theInterfacePtr->bLength);
for (index = 0; index < numStreamInterfaces; index++) {
if (thisInterfaceNumber == streamInterfaceNumbers[index]) {
break;
}
}
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
} else if (AUDIOCONTROL == interfaceSubClass) {
debugIOLog ("Found a control interface that we don't care about");
debugIOLog ("jumping forward %d bytes", ((((ACInterfaceHeaderDescriptorPtr)theInterfacePtr)->wTotalLength[1] << 8) | (((ACInterfaceHeaderDescriptorPtr)theInterfacePtr)->wTotalLength[0])));
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + ((((ACInterfaceHeaderDescriptorPtr)theInterfacePtr)->wTotalLength[1] << 8) | (((ACInterfaceHeaderDescriptorPtr)theInterfacePtr)->wTotalLength[0])));
} else {
debugIOLog ("Unknown, jumping forward %d bytes", theInterfacePtr->bLength);
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
}
} else {
debugIOLog ("in default in ParseConfigurationDescriptor, jumping forward %d bytes", theInterfacePtr->bLength);
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
}
}
if (theControlObject && FALSE == foundStreamInterface) {
theControls->removeObject (theControls->getCount () - 1);
}
Exit:
return;
}
USBInterfaceDescriptorPtr USBAudioConfigObject::ParseInterfaceDescriptor (USBInterfaceDescriptorPtr theInterfacePtr, UInt8 * interfaceClass, UInt8 * interfaceSubClass) {
USBAudioControlObject * theControlObject;
USBAudioStreamObject * theStreamObject;
debugIOLog ("in ParseInterfaceDescriptor");
FailIf (NULL == theInterfacePtr, Exit);
FailIf (0 == theInterfacePtr->bLength, Exit);
if (NULL != interfaceClass)
*interfaceClass = theInterfacePtr->bInterfaceClass;
if (NULL != interfaceSubClass)
*interfaceSubClass = theInterfacePtr->bInterfaceSubClass;
if (AUDIOCONTROL == theInterfacePtr->bInterfaceSubClass) {
debugIOLog ("found a AUDIOCONTROL interface");
if (theControlInterfaceNum == theInterfacePtr->bDescriptorSubtype) {
theControlObject = USBAudioControlObject::create ();
FailIf (NULL == theControlObject, Exit);
theControlObject->SetInterfaceNumber (theInterfacePtr->bDescriptorSubtype);
theControlObject->SetAlternateSetting (theInterfacePtr->bAlternateSetting);
theControlObject->SetNumEndpoints (theInterfacePtr->bNumEndpoints);
theControlObject->SetInterfaceClass (theInterfacePtr->bInterfaceClass);
theControlObject->SetInterfaceSubClass (theInterfacePtr->bInterfaceSubClass);
theControlObject->SetInterfaceProtocol (theInterfacePtr->bInterfaceProtocol);
if (NULL == theControls) {
theControls = OSArray::withObjects ((const OSObject **)&theControlObject, 1);
FailIf (NULL == theControls, Exit);
} else {
theControls->setObject (theControlObject);
}
theControlObject->release ();
}
} else if (AUDIOSTREAMING == theInterfacePtr->bInterfaceSubClass) {
debugIOLog ("found a AUDIOSTREAMING interface");
theStreamObject = USBAudioStreamObject::create ();
FailIf (NULL == theStreamObject, Exit);
theStreamObject->SetInterfaceNumber (theInterfacePtr->bDescriptorSubtype);
theStreamObject->SetAlternateSetting (theInterfacePtr->bAlternateSetting);
theStreamObject->SetNumEndpoints (theInterfacePtr->bNumEndpoints);
theStreamObject->SetInterfaceClass (theInterfacePtr->bInterfaceClass);
theStreamObject->SetInterfaceSubClass (theInterfacePtr->bInterfaceSubClass);
theStreamObject->SetInterfaceProtocol (theInterfacePtr->bInterfaceProtocol);
if (NULL == theStreams) {
theStreams = OSArray::withObjects ((const OSObject **)&theStreamObject, 1);
FailIf (NULL == theStreams, Exit);
} else {
theStreams->setObject (theStreamObject);
}
theStreamObject->release ();
}
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
Exit:
return theInterfacePtr;
}
OSDefineMetaClassAndStructors (USBAudioControlObject, OSObject);
USBAudioControlObject * USBAudioControlObject::create (void) {
USBAudioControlObject * controlObject;
controlObject = new USBAudioControlObject;
FailIf (NULL == controlObject, Exit);
if (FALSE == controlObject->init ()) {
controlObject->release ();
controlObject = 0;
}
Exit:
return controlObject;
}
void USBAudioControlObject::free (void) {
if (NULL != theInputTerminals) {
theInputTerminals->release ();
theInputTerminals = NULL;
}
if (NULL != theOutputTerminals) {
theOutputTerminals->release ();
theOutputTerminals = NULL;
}
if (NULL != theFeatureUnits) {
theFeatureUnits->release ();
theFeatureUnits = NULL;
}
if (NULL != theMixerUnits) {
theMixerUnits->release ();
theMixerUnits = NULL;
}
if (NULL != theSelectorUnits) {
theSelectorUnits->release ();
theSelectorUnits = NULL;
}
if (NULL != theProcessingUnits) {
theProcessingUnits->release ();
theProcessingUnits = NULL;
}
if (NULL != theExtensionUnits) {
theExtensionUnits->release ();
theExtensionUnits = NULL;
}
OSObject::free ();
}
UInt8 USBAudioControlObject::GetNumControls (UInt8 featureUnitID) {
USBFeatureUnitObject * thisFeatureUnit;
UInt8 numControls;
numControls = 0;
thisFeatureUnit = GetFeatureUnitObject (featureUnitID);
if (thisFeatureUnit)
numControls = thisFeatureUnit->GetNumControls ();
return numControls;
}
Boolean USBAudioControlObject::ChannelHasMuteControl (UInt8 featureUnitID, UInt8 channelNum) {
USBFeatureUnitObject * thisFeatureUnit;
Boolean result;
result = FALSE;
thisFeatureUnit = GetFeatureUnitObject (featureUnitID);
if (thisFeatureUnit)
result = thisFeatureUnit->ChannelHasMuteControl (channelNum);
return result;
}
Boolean USBAudioControlObject::ChannelHasVolumeControl (UInt8 featureUnitID, UInt8 channelNum) {
USBFeatureUnitObject * thisFeatureUnit;
Boolean result;
result = FALSE;
thisFeatureUnit = GetFeatureUnitObject (featureUnitID);
if (thisFeatureUnit)
result = thisFeatureUnit->ChannelHasVolumeControl (channelNum);
return result;
}
USBACDescriptorObject * USBAudioControlObject::GetACDescriptorObject (UInt8 unitID) {
USBACDescriptorObject * thisACDescriptorObject;
thisACDescriptorObject = GetInputTerminalObject (unitID);
if (!thisACDescriptorObject)
thisACDescriptorObject = GetOutputTerminalObject (unitID);
if (!thisACDescriptorObject)
thisACDescriptorObject = GetMixerObject (unitID);
if (!thisACDescriptorObject)
thisACDescriptorObject = GetSelectorUnitObject (unitID);
if (!thisACDescriptorObject)
thisACDescriptorObject = GetFeatureUnitObject (unitID);
if (!thisACDescriptorObject)
thisACDescriptorObject = GetProcessingUnitObject (unitID);
if (!thisACDescriptorObject)
thisACDescriptorObject = GetExtensionUnitObject (unitID);
return thisACDescriptorObject;
}
UInt8 USBAudioControlObject::GetFeatureSourceID (UInt8 featureUnitID) {
USBFeatureUnitObject * theFeatureUnit;
UInt8 sourceID;
sourceID = 0;
theFeatureUnit = GetFeatureUnitObject (featureUnitID);
if (theFeatureUnit)
sourceID = theFeatureUnit->GetSourceID ();
return sourceID;
}
UInt8 USBAudioControlObject::GetIndexedFeatureUnitID (UInt8 featureUnitIndex) {
USBFeatureUnitObject * theFeatureUnit;
UInt8 unitID;
unitID = 0;
theFeatureUnit = GetIndexedFeatureUnitObject (featureUnitIndex);
if (theFeatureUnit)
unitID = theFeatureUnit->GetUnitID ();
return unitID;
}
UInt8 USBAudioControlObject::GetIndexedMixerUnitID (UInt8 mixerUnitIndex) {
USBMixerUnitObject * theMixerUnit;
UInt8 unitID;
unitID = 0;
theMixerUnit = GetIndexedMixerUnitObject (mixerUnitIndex);
if (theMixerUnit)
unitID = theMixerUnit->GetUnitID ();
return unitID;
}
UInt8 USBAudioControlObject::GetIndexedSelectorUnitID (UInt8 selectorUnitIndex) {
USBSelectorUnitObject * theSelectorUnit;
UInt8 unitID;
unitID = 0;
theSelectorUnit = GetIndexedSelectorUnitObject (selectorUnitIndex);
if (theSelectorUnit)
unitID = theSelectorUnit->GetUnitID ();
return unitID;
}
UInt8 USBAudioControlObject::GetFeatureUnitIDConnectedToOutputTerminal (UInt8 outputTerminalID) {
USBOutputTerminalObject * thisOutputTerminal;
USBFeatureUnitObject * thisFeatureUnit;
UInt8 outputTerminalSourceID;
UInt8 featureUnitID;
outputTerminalSourceID = 0;
featureUnitID = 0;
thisOutputTerminal = GetOutputTerminalObject (outputTerminalID);
if (thisOutputTerminal)
outputTerminalSourceID = thisOutputTerminal->GetSourceID ();
if (0 != outputTerminalSourceID) {
thisFeatureUnit = GetFeatureUnitObject (outputTerminalSourceID);
if (thisFeatureUnit)
featureUnitID = outputTerminalSourceID;
else {
}
}
return featureUnitID;
}
UInt16 USBAudioControlObject::GetIndexedInputTerminalType (UInt8 index) {
USBInputTerminalObject * thisInputTerminal;
UInt16 terminalType;
thisInputTerminal = NULL;
terminalType = USBToHostWord (INPUT_UNDEFINED);
if (NULL != theInputTerminals) {
thisInputTerminal = OSDynamicCast (USBInputTerminalObject, theInputTerminals->getObject (index));
}
if (thisInputTerminal)
terminalType = USBToHostWord (thisInputTerminal->GetTerminalType ());
return terminalType;
}
UInt8 USBAudioControlObject::GetIndexedInputTerminalID (UInt8 index) {
USBInputTerminalObject * thisInputTerminal;
UInt8 terminalID;
thisInputTerminal = NULL;
terminalID = 0;
if (NULL != theInputTerminals) {
thisInputTerminal = OSDynamicCast (USBInputTerminalObject, theInputTerminals->getObject (index));
}
if (thisInputTerminal)
terminalID = thisInputTerminal->GetUnitID ();
return terminalID;
}
UInt8 USBAudioControlObject::GetIndexedOutputTerminalID (UInt8 index) {
USBOutputTerminalObject * thisOutputTerminal;
UInt8 terminalID;
thisOutputTerminal = NULL;
terminalID = 0;
if (NULL != theOutputTerminals) {
thisOutputTerminal = OSDynamicCast (USBOutputTerminalObject, theOutputTerminals->getObject (index));
}
if (thisOutputTerminal)
terminalID = thisOutputTerminal->GetUnitID ();
return terminalID;
}
UInt16 USBAudioControlObject::GetIndexedOutputTerminalType (UInt8 index) {
USBOutputTerminalObject * thisOutputTerminal;
UInt16 terminalType;
thisOutputTerminal = NULL;
terminalType = USBToHostWord (OUTPUT_UNDEFINED);
if (NULL != theOutputTerminals) {
thisOutputTerminal = OSDynamicCast (USBOutputTerminalObject, theOutputTerminals->getObject (index));
}
if (thisOutputTerminal)
terminalType = USBToHostWord (thisOutputTerminal->GetTerminalType ());
return terminalType;
}
USBFeatureUnitObject * USBAudioControlObject::GetIndexedFeatureUnitObject (UInt8 index) {
USBFeatureUnitObject * indexedFeatureUnit;
indexedFeatureUnit = NULL;
if (NULL != theFeatureUnits) {
indexedFeatureUnit = OSDynamicCast (USBFeatureUnitObject, theFeatureUnits->getObject (index));
}
return indexedFeatureUnit;
}
USBMixerUnitObject * USBAudioControlObject::GetIndexedMixerUnitObject (UInt8 index) {
USBMixerUnitObject * indexedMixerUnit;
indexedMixerUnit = NULL;
if (NULL != theMixerUnits) {
indexedMixerUnit = OSDynamicCast (USBMixerUnitObject, theMixerUnits->getObject (index));
}
return indexedMixerUnit;
}
USBSelectorUnitObject * USBAudioControlObject::GetIndexedSelectorUnitObject (UInt8 index) {
USBSelectorUnitObject * indexedSelectorUnit;
indexedSelectorUnit = NULL;
if (NULL != theSelectorUnits) {
indexedSelectorUnit = OSDynamicCast (USBSelectorUnitObject, theSelectorUnits->getObject (index));
}
return indexedSelectorUnit;
}
USBFeatureUnitObject * USBAudioControlObject::GetFeatureUnitObject (UInt8 unitID) {
USBFeatureUnitObject * thisFeatureUnit;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisFeatureUnit = NULL;
if (NULL != theFeatureUnits) {
while (!found && indx < theFeatureUnits->getCount ()) {
thisFeatureUnit = OSDynamicCast (USBFeatureUnitObject, theFeatureUnits->getObject (indx));
if (thisFeatureUnit && unitID == thisFeatureUnit->GetUnitID ()) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisFeatureUnit = NULL;
return thisFeatureUnit;
}
USBInputTerminalObject * USBAudioControlObject::GetInputTerminalObject (UInt8 unitID) {
USBInputTerminalObject * thisInputTerminal;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisInputTerminal = NULL;
if (NULL != theInputTerminals) {
while (!found && indx < theInputTerminals->getCount ()) {
thisInputTerminal = OSDynamicCast (USBInputTerminalObject, theInputTerminals->getObject (indx));
if (thisInputTerminal && unitID == thisInputTerminal->GetUnitID ()) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisInputTerminal = NULL;
return thisInputTerminal;
}
USBOutputTerminalObject * USBAudioControlObject::GetOutputTerminalObject (UInt8 unitID) {
USBOutputTerminalObject * thisOutputTerminal;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisOutputTerminal = NULL;
if (NULL != theOutputTerminals) {
while (!found && indx < theOutputTerminals->getCount ()) {
thisOutputTerminal = OSDynamicCast (USBOutputTerminalObject, theOutputTerminals->getObject (indx));
if (thisOutputTerminal && unitID == thisOutputTerminal->GetUnitID ()) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisOutputTerminal = NULL;
return thisOutputTerminal;
}
UInt16 USBAudioControlObject::GetInputTerminalType (UInt8 unitID) {
USBInputTerminalObject * thisInputTerminal;
UInt16 terminalType;
terminalType = USBToHostWord (INPUT_UNDEFINED);
thisInputTerminal = GetInputTerminalObject (unitID);
if (thisInputTerminal)
terminalType = USBToHostWord (thisInputTerminal->GetTerminalType ());
return terminalType;
}
UInt8 USBAudioControlObject::GetNumInputTerminals (void) {
UInt8 count;
count = 0;
if (NULL != theInputTerminals) {
count = theInputTerminals->getCount ();
}
return count;
}
UInt8 USBAudioControlObject::GetNumOutputTerminals (void) {
UInt8 count;
count = 0;
if (NULL != theOutputTerminals) {
count = theOutputTerminals->getCount ();
}
return count;
}
UInt8 USBAudioControlObject::GetNumSelectorUnits (void) {
UInt8 count;
count = 0;
if (NULL != theSelectorUnits) {
count = theSelectorUnits->getCount ();
}
return count;
}
UInt8 USBAudioControlObject::GetNumSources (UInt8 unitID) {
USBACDescriptorObject * thisProcessingUnit;
UInt8 numSources;
numSources = 0;
thisProcessingUnit = GetACDescriptorObject (unitID);
if (thisProcessingUnit)
numSources = thisProcessingUnit->GetNumInPins ();
return numSources;
}
UInt8 USBAudioControlObject::GetSourceID (UInt8 unitID) {
USBACDescriptorObject * theUnit;
UInt8 sourceID;
sourceID = 0;
theUnit = GetACDescriptorObject (unitID);
if (NULL != theUnit) {
sourceID = theUnit->GetSourceID ();
}
return sourceID;
}
UInt8 * USBAudioControlObject::GetSourceIDs (UInt8 unitID) {
USBACDescriptorObject * theUnit;
UInt8 * sourceIDs;
sourceIDs = NULL;
theUnit = GetACDescriptorObject (unitID);
if (NULL != theUnit) {
switch (theUnit->GetDescriptorSubType ()) {
case MIXER_UNIT:
sourceIDs = GetMixerSources (unitID);
break;
case SELECTOR_UNIT:
sourceIDs = GetSelectorSources (unitID);
break;
case PROCESSING_UNIT:
sourceIDs = GetProcessingUnitSources (unitID);
break;
case EXTENSION_UNIT:
sourceIDs = GetExtensionUnitSources (unitID);
break;
}
}
return sourceIDs;
}
UInt8 USBAudioControlObject::GetSubType (UInt8 unitID) {
USBACDescriptorObject * theUnit;
UInt8 subType;
subType = 0;
theUnit = GetACDescriptorObject (unitID);
if (NULL != theUnit) {
subType = theUnit->GetDescriptorSubType ();
}
return subType;
}
USBProcessingUnitObject * USBAudioControlObject::GetProcessingUnitObject (UInt8 unitID) {
USBProcessingUnitObject * thisProcessingUnit;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisProcessingUnit = NULL;
if (NULL != theProcessingUnits) {
while (!found && indx < theProcessingUnits->getCount ()) {
thisProcessingUnit = OSDynamicCast (USBProcessingUnitObject, theProcessingUnits->getObject (indx));
if (thisProcessingUnit && unitID == thisProcessingUnit->GetUnitID ()) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisProcessingUnit = NULL;
return thisProcessingUnit;
}
USBMixerUnitObject * USBAudioControlObject::GetMixerObject (UInt8 unitID) {
USBMixerUnitObject * thisMixerObject;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisMixerObject = NULL;
if (NULL != theMixerUnits) {
while (!found && indx < theMixerUnits->getCount ()) {
thisMixerObject = OSDynamicCast (USBMixerUnitObject, theMixerUnits->getObject (indx));
if (thisMixerObject && unitID == thisMixerObject->GetUnitID ()) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisMixerObject = NULL;
return thisMixerObject;
}
USBExtensionUnitObject * USBAudioControlObject::GetExtensionUnitObject (UInt8 unitID) {
USBExtensionUnitObject * thisExtensionUnit;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisExtensionUnit = NULL;
if (NULL != theExtensionUnits) {
while (!found && indx < theExtensionUnits->getCount ()) {
thisExtensionUnit = OSDynamicCast (USBExtensionUnitObject, theExtensionUnits->getObject (indx));
if (thisExtensionUnit && unitID == thisExtensionUnit->GetUnitID ()) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisExtensionUnit = NULL;
return thisExtensionUnit;
}
USBSelectorUnitObject * USBAudioControlObject::GetSelectorUnitObject (UInt8 unitID) {
USBSelectorUnitObject * thisSelectorObject;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisSelectorObject = NULL;
if (NULL != theSelectorUnits) {
while (!found && indx < theSelectorUnits->getCount ()) {
thisSelectorObject = OSDynamicCast (USBSelectorUnitObject, theSelectorUnits->getObject (indx));
if (thisSelectorObject && unitID == thisSelectorObject->GetUnitID ()) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisSelectorObject = NULL;
return thisSelectorObject;
}
UInt16 USBAudioControlObject::GetOutputTerminalType (UInt8 unitID) {
USBOutputTerminalObject * thisOutputTerminal;
UInt16 terminalType;
terminalType = USBToHostWord (OUTPUT_UNDEFINED);
thisOutputTerminal = GetOutputTerminalObject (unitID);
if (thisOutputTerminal)
terminalType = USBToHostWord (thisOutputTerminal->GetTerminalType ());
return terminalType;
}
UInt8 * USBAudioControlObject::GetSelectorSources (UInt8 unitID) {
USBSelectorUnitObject * thisSelectorUnit;
UInt8 * selectorSources;
selectorSources = NULL;
thisSelectorUnit = GetSelectorUnitObject (unitID);
if (thisSelectorUnit)
selectorSources = thisSelectorUnit->GetSelectorSources ();
return selectorSources;
}
UInt8 * USBAudioControlObject::GetMixerSources (UInt8 unitID) {
USBMixerUnitObject * thisMixerUnit;
UInt8 * mixerSources;
mixerSources = NULL;
thisMixerUnit = GetMixerObject (unitID);
if (thisMixerUnit)
mixerSources = thisMixerUnit->GetSources ();
return mixerSources;
}
UInt8 * USBAudioControlObject::GetExtensionUnitSources (UInt8 unitID) {
USBExtensionUnitObject * thisExtensionUnit;
UInt8 * extensionUnitSources;
extensionUnitSources = NULL;
thisExtensionUnit = GetExtensionUnitObject (unitID);
if (thisExtensionUnit)
extensionUnitSources = thisExtensionUnit->GetSources ();
return extensionUnitSources;
}
UInt8 * USBAudioControlObject::GetProcessingUnitSources (UInt8 unitID) {
USBProcessingUnitObject * thisProcessingUnit;
UInt8 * processingUnitSources;
processingUnitSources = NULL;
thisProcessingUnit = GetProcessingUnitObject (unitID);
if (thisProcessingUnit)
processingUnitSources = thisProcessingUnit->GetSources ();
return processingUnitSources;
}
Boolean USBAudioControlObject::MasterHasMuteControl (UInt8 featureUnitID) {
USBFeatureUnitObject * thisFeatureUnit;
Boolean result;
result = FALSE;
thisFeatureUnit = GetFeatureUnitObject (featureUnitID);
if (thisFeatureUnit)
result = thisFeatureUnit->MasterHasMuteControl ();
return result;
}
USBInterfaceDescriptorPtr USBAudioControlObject::ParseACInterfaceDescriptor (USBInterfaceDescriptorPtr theInterfacePtr, UInt8 const currentInterface) {
USBInputTerminalObject * inputTerminal;
USBOutputTerminalObject * outputTerminal;
USBFeatureUnitObject * featureUnit;
USBMixerUnitObject * mixerUnit;
USBSelectorUnitObject * selectorUnit;
USBProcessingUnitObject * processingUnit;
USBExtensionUnitObject * extensionUnit;
UInt8 index;
debugIOLog ("+USBAudioControlObject::ParseACInterfaceDescriptor (%p, %d)", theInterfacePtr, currentInterface);
FailIf (NULL == theInterfacePtr, Exit);
FailIf (0 == theInterfacePtr->bLength, Exit);
FailIf (CS_INTERFACE != theInterfacePtr->bDescriptorType, Exit);
while (theInterfacePtr->bLength && CS_INTERFACE == theInterfacePtr->bDescriptorType) {
switch (theInterfacePtr->bDescriptorSubtype) {
case HEADER:
debugIOLog ("in HEADER in ParseACInterfaceDescriptor");
adcVersion = USBToHostWord (((ACInterfaceHeaderDescriptorPtr)theInterfacePtr)->bcdADC[0]);
if (adcVersion != 0x0100) {
}
numStreamInterfaces = ((ACInterfaceHeaderDescriptorPtr)theInterfacePtr)->bInCollection;
debugIOLog ("numStreamInterfaces = %d", numStreamInterfaces);
streamInterfaceNumbers = (UInt8 *)IOMalloc (numStreamInterfaces);
memcpy (streamInterfaceNumbers, ((ACInterfaceHeaderDescriptorPtr)theInterfacePtr)->baInterfaceNr, numStreamInterfaces);
debugIOLog ("they are: ");
for (index = 0; index < numStreamInterfaces; index++) {
debugIOLog ("%d, ", streamInterfaceNumbers[index]);
}
debugIOLog ("");
break;
case INPUT_TERMINAL:
debugIOLog ("in INPUT_TERMINAL in ParseACInterfaceDescriptor");
inputTerminal = new USBInputTerminalObject;
FailIf (NULL == inputTerminal, Exit);
inputTerminal->SetDescriptorSubType (theInterfacePtr->bDescriptorSubtype);
inputTerminal->SetUnitID (((ACInputTerminalDescriptorPtr)theInterfacePtr)->bTerminalID);
inputTerminal->SetTerminalType (USBToHostWord (((ACInputTerminalDescriptorPtr)theInterfacePtr)->wTerminalType));
inputTerminal->SetAssocTerminal (((ACInputTerminalDescriptorPtr)theInterfacePtr)->bAssocTerminal);
inputTerminal->SetNumChannels (((ACInputTerminalDescriptorPtr)theInterfacePtr)->bNrChannels);
inputTerminal->SetChannelConfig (USBToHostWord (((ACInputTerminalDescriptorPtr)theInterfacePtr)->wChannelConfig));
if (NULL == theInputTerminals) {
theInputTerminals = OSArray::withObjects ((const OSObject **)&inputTerminal, 1);
FailIf (NULL == theInputTerminals, Exit);
} else {
theInputTerminals->setObject (inputTerminal);
}
inputTerminal->release ();
break;
case OUTPUT_TERMINAL:
debugIOLog ("in OUTPUT_TERMINAL in ParseACInterfaceDescriptor");
outputTerminal = new USBOutputTerminalObject;
FailIf (NULL == outputTerminal, Exit);
outputTerminal->SetDescriptorSubType (theInterfacePtr->bDescriptorSubtype);
outputTerminal->SetUnitID (((ACOutputTerminalDescriptorPtr)theInterfacePtr)->bTerminalID);
outputTerminal->SetTerminalType (USBToHostWord (((ACOutputTerminalDescriptorPtr)theInterfacePtr)->wTerminalType));
outputTerminal->SetAssocTerminal (((ACOutputTerminalDescriptorPtr)theInterfacePtr)->bAssocTerminal);
outputTerminal->SetSourceID (((ACOutputTerminalDescriptorPtr)theInterfacePtr)->bSourceID);
if (NULL == theOutputTerminals) {
theOutputTerminals = OSArray::withObjects ((const OSObject **)&outputTerminal, 1);
FailIf (NULL == theOutputTerminals, Exit);
} else {
theOutputTerminals->setObject (outputTerminal);
}
outputTerminal->release ();
break;
case FEATURE_UNIT:
{
UInt8 numControls;
debugIOLog ("in FEATURE_UNIT in ParseACInterfaceDescriptor");
featureUnit = new USBFeatureUnitObject;
FailIf (NULL == featureUnit, Exit);
featureUnit->SetDescriptorSubType (theInterfacePtr->bDescriptorSubtype);
featureUnit->SetUnitID (((ACFeatureUnitDescriptorPtr)theInterfacePtr)->bUnitID);
featureUnit->SetSourceID (((ACFeatureUnitDescriptorPtr)theInterfacePtr)->bSourceID);
featureUnit->SetControlSize (((ACFeatureUnitDescriptorPtr)theInterfacePtr)->bControlSize);
numControls = (((ACFeatureUnitDescriptorPtr)theInterfacePtr)->bLength - 7) / ((ACFeatureUnitDescriptorPtr)theInterfacePtr)->bControlSize;
debugIOLog ("There are %d controls on this feature unit", numControls);
featureUnit->InitControlsArray (&((ACFeatureUnitDescriptorPtr)theInterfacePtr)->bmaControls[0], numControls);
if (NULL == theFeatureUnits) {
theFeatureUnits = OSArray::withObjects ((const OSObject **)&featureUnit, 1);
FailIf (NULL == theFeatureUnits, Exit);
} else {
theFeatureUnits->setObject (featureUnit);
}
featureUnit->release ();
break;
}
case MIXER_UNIT:
{
UInt32 controlSize;
UInt16 * channelConfig;
UInt8 nrChannels;
debugIOLog ("in MIXER_UNIT in ParseACInterfaceDescriptor");
mixerUnit = new USBMixerUnitObject;
FailIf (NULL == mixerUnit, Exit);
debugIOLog ("descriptor length = %d", theInterfacePtr->bLength);
mixerUnit->SetDescriptorSubType (theInterfacePtr->bDescriptorSubtype);
mixerUnit->SetUnitID (((ACMixerUnitDescriptorPtr)theInterfacePtr)->bUnitID);
debugIOLog ("unit ID = %d", ((ACMixerUnitDescriptorPtr)theInterfacePtr)->bUnitID);
debugIOLog ("numInPins = %d", ((ACMixerUnitDescriptorPtr)theInterfacePtr)->bNrInPins);
mixerUnit->InitSourceIDs (&((ACMixerUnitDescriptorPtr)theInterfacePtr)->baSourceID[0], ((ACMixerUnitDescriptorPtr)theInterfacePtr)->bNrInPins);
nrChannels = ((ACMixerUnitDescriptorPtr)theInterfacePtr)->baSourceID[((ACMixerUnitDescriptorPtr)theInterfacePtr)->bNrInPins];
debugIOLog ("nrChannels = %d", nrChannels);
mixerUnit->SetNumChannels (nrChannels);
channelConfig = (UInt16 *)&((ACMixerUnitDescriptorPtr)theInterfacePtr)->baSourceID[((ACMixerUnitDescriptorPtr)theInterfacePtr)->bNrInPins + 1];
*channelConfig = USBToHostWord (*channelConfig);
debugIOLog ("channelConfig = %d", *channelConfig);
mixerUnit->SetChannelConfig (*channelConfig);
controlSize = ((ACMixerUnitDescriptorPtr)theInterfacePtr)->bLength - 10 - ((ACMixerUnitDescriptorPtr)theInterfacePtr)->bNrInPins;
debugIOLog ("controlSize = %d", controlSize);
mixerUnit->InitControlsArray (&((ACMixerUnitDescriptorPtr)theInterfacePtr)->baSourceID[((ACMixerUnitDescriptorPtr)theInterfacePtr)->bNrInPins + 3], controlSize);
if (NULL == theMixerUnits) {
theMixerUnits = OSArray::withObjects ((const OSObject **)&mixerUnit, 1);
FailIf (NULL == theMixerUnits, Exit);
} else {
theMixerUnits->setObject (mixerUnit);
}
mixerUnit->release ();
break;
}
case SELECTOR_UNIT:
debugIOLog ("in SELECTOR_UNIT in ParseACInterfaceDescriptor");
selectorUnit = new USBSelectorUnitObject;
FailIf (NULL == selectorUnit, Exit);
selectorUnit->SetDescriptorSubType (theInterfacePtr->bDescriptorSubtype);
selectorUnit->SetUnitID (((ACSelectorUnitDescriptorPtr)theInterfacePtr)->bUnitID);
selectorUnit->InitSourceIDs (&((ACSelectorUnitDescriptorPtr)theInterfacePtr)->baSourceID[0], ((ACSelectorUnitDescriptorPtr)theInterfacePtr)->bNrInPins);
debugIOLog ("numInPins on selector = %d", ((ACSelectorUnitDescriptorPtr)theInterfacePtr)->bNrInPins);
if (NULL == theSelectorUnits) {
theSelectorUnits = OSArray::withObjects ((const OSObject **)&selectorUnit, 1);
FailIf (NULL == theSelectorUnits, Exit);
} else {
theSelectorUnits->setObject (selectorUnit);
}
selectorUnit->release ();
break;
case PROCESSING_UNIT:
{
UInt16 * channelConfig;
UInt8 controlSize;
UInt8 nrChannels;
debugIOLog ("in PROCESSING_UNIT in ParseACInterfaceDescriptor");
processingUnit = new USBProcessingUnitObject;
FailIf (NULL == processingUnit, Exit);
processingUnit->SetDescriptorSubType (theInterfacePtr->bDescriptorSubtype);
processingUnit->SetUnitID (((ACProcessingUnitDescriptorPtr)theInterfacePtr)->bUnitID);
processingUnit->SetProcessType (((ACProcessingUnitDescriptorPtr)theInterfacePtr)->wProcessType);
debugIOLog ("processing unit type = 0x%x", ((ACProcessingUnitDescriptorPtr)theInterfacePtr)->wProcessType);
processingUnit->InitSourceIDs (&((ACProcessingUnitDescriptorPtr)theInterfacePtr)->baSourceID[0], ((ACProcessingUnitDescriptorPtr)theInterfacePtr)->bNrInPins);
debugIOLog ("numInPins = %d", ((ACProcessingUnitDescriptorPtr)theInterfacePtr)->bNrInPins);
nrChannels = ((ACProcessingUnitDescriptorPtr)theInterfacePtr)->baSourceID[((ACProcessingUnitDescriptorPtr)theInterfacePtr)->bNrInPins];
debugIOLog ("nrChannels = %d", nrChannels);
processingUnit->SetNumChannels (nrChannels);
channelConfig = (UInt16 *)&((ACProcessingUnitDescriptorPtr)theInterfacePtr)->baSourceID[((ACProcessingUnitDescriptorPtr)theInterfacePtr)->bNrInPins + 1];
*channelConfig = USBToHostWord (*channelConfig);
debugIOLog ("channelConfig = %d", *channelConfig);
processingUnit->SetChannelConfig (*channelConfig);
controlSize = ((ACProcessingUnitDescriptorPtr)theInterfacePtr)->baSourceID[((ACProcessingUnitDescriptorPtr)theInterfacePtr)->bNrInPins + 4];
debugIOLog ("controlSize = %d", controlSize);
processingUnit->InitControlsArray (&((ACProcessingUnitDescriptorPtr)theInterfacePtr)->baSourceID[((ACProcessingUnitDescriptorPtr)theInterfacePtr)->bNrInPins + 5], controlSize);
if (NULL == theProcessingUnits) {
theProcessingUnits = OSArray::withObjects ((const OSObject **)&processingUnit, 1);
FailIf (NULL == theProcessingUnits, Exit);
} else {
theProcessingUnits->setObject (processingUnit);
}
processingUnit->release ();
break;
}
case EXTENSION_UNIT:
debugIOLog ("in EXTENSION_UNIT in ParseACInterfaceDescriptor");
extensionUnit = new USBExtensionUnitObject;
FailIf (NULL == extensionUnit, Exit);
extensionUnit->SetDescriptorSubType (theInterfacePtr->bDescriptorSubtype);
extensionUnit->SetUnitID (((ACExtensionUnitDescriptorPtr)theInterfacePtr)->bUnitID);
extensionUnit->InitSourceIDs (&((ACExtensionUnitDescriptorPtr)theInterfacePtr)->baSourceID[0], ((ACExtensionUnitDescriptorPtr)theInterfacePtr)->bNrInPins);
if (NULL == theExtensionUnits) {
theExtensionUnits = OSArray::withObjects ((const OSObject **)&extensionUnit, 1);
FailIf (NULL == theExtensionUnits, Exit);
} else {
theExtensionUnits->setObject (extensionUnit);
}
extensionUnit->release ();
break;
default:
debugIOLog ("in default in ParseACInterfaceDescriptor");
}
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
}
Exit:
debugIOLog ("-USBAudioControlObject::ParseACInterfaceDescriptor (%p, %d)", theInterfacePtr, currentInterface);
return theInterfacePtr;
}
OSDefineMetaClassAndStructors (USBAudioStreamObject, OSObject);
USBAudioStreamObject * USBAudioStreamObject::create (void) {
USBAudioStreamObject * streamObject;
streamObject = new USBAudioStreamObject;
FailIf (NULL == streamObject, Exit);
if (FALSE == streamObject->init ()) {
streamObject->release ();
streamObject = 0;
}
Exit:
return streamObject;
}
void USBAudioStreamObject::free (void) {
IOFree (sampleFreqs, numSampleFreqs * sizeof (UInt32));
if (NULL != theEndpointObjects) {
theEndpointObjects->release ();
theEndpointObjects = NULL;
}
OSObject::free ();
}
USBEndpointObject * USBAudioStreamObject::GetIndexedEndpointObject (UInt8 index) {
USBEndpointObject * thisEndpoint;
if (theEndpointObjects) {
thisEndpoint = OSDynamicCast (USBEndpointObject, theEndpointObjects->getObject (index));
} else {
thisEndpoint = NULL;
}
return thisEndpoint;
}
UInt8 USBAudioStreamObject::GetIsocAssociatedEndpointAddress (UInt8 address) {
USBEndpointObject * thisEndpoint;
UInt8 assocEndpointAddress;
assocEndpointAddress = 0;
thisEndpoint = GetEndpointByAddress (address);
if (thisEndpoint) {
assocEndpointAddress = thisEndpoint->GetSynchAddress ();
}
return assocEndpointAddress;
}
UInt8 USBAudioStreamObject::GetIsocAssociatedEndpointRefreshInt (UInt8 address) {
USBEndpointObject * thisEndpoint;
UInt8 assocEndpointRefresh;
assocEndpointRefresh = 0;
thisEndpoint = GetEndpointByAddress (address);
if (thisEndpoint) {
assocEndpointRefresh = thisEndpoint->GetRefreshInt ();
}
return assocEndpointRefresh;
}
UInt8 USBAudioStreamObject::GetIsocEndpointAddress (UInt8 direction) {
USBEndpointObject * thisEndpointObject;
UInt8 address;
UInt8 indx;
indx = 0;
address = 0;
debugIOLog ("GetIsocEndpointAddress, looking for direction %d", direction);
if (theEndpointObjects) {
while (!address && indx < theEndpointObjects->getCount ()) {
thisEndpointObject = GetIndexedEndpointObject (indx);
debugIOLog ("GetIsocEndpointAddress, this endpoint's direction %d", thisEndpointObject->GetDirection ());
if (thisEndpointObject && direction == thisEndpointObject->GetDirection ()) {
address = thisEndpointObject->GetAddress ();
debugIOLog ("GetIsocEndpointAddress, found endpoint address %d", address);
}
indx++;
}
}
return address;
}
UInt8 USBAudioStreamObject::GetIsocEndpointDirection (UInt8 index) {
USBEndpointObject * thisEndpointObject;
UInt8 direction;
direction = 0xFF;
thisEndpointObject = NULL;
if (theEndpointObjects) {
thisEndpointObject = GetIndexedEndpointObject (index);
}
if (NULL != thisEndpointObject)
direction = thisEndpointObject->GetDirection ();
return direction;
}
UInt8 USBAudioStreamObject::GetIsocEndpointSyncType (UInt8 address) {
USBEndpointObject * thisEndpointObject;
UInt8 syncType;
syncType = 0;
thisEndpointObject = GetEndpointByAddress (address);
if (NULL != thisEndpointObject)
syncType = thisEndpointObject->GetSyncType ();
return syncType;
}
inline UInt32 ConvertSampleFreq(UInt8 *p) {
UInt32 bigEndianSampleFreq = (p[2] << 16) | (p[1] << 8) | p[0];
return (bigEndianSampleFreq);
}
USBInterfaceDescriptorPtr USBAudioStreamObject::ParseASInterfaceDescriptor (USBInterfaceDescriptorPtr theInterfacePtr, UInt8 const currentInterface) {
UInt32 indx;
UInt16 wFormatTag;
Boolean done;
USBEndpointObject * theEndpoint;
debugIOLog ("+USBAudioStreamObject::ParseASInterfaceDescriptor (%x, %d)", theInterfacePtr, currentInterface);
FailIf (NULL == theInterfacePtr, Exit);
FailIf (0 == theInterfacePtr->bLength, Exit);
done = FALSE;
while (theInterfacePtr->bLength && !done) {
if (CS_INTERFACE == theInterfacePtr->bDescriptorType) {
switch (theInterfacePtr->bDescriptorSubtype) {
case AS_GENERAL:
debugIOLog ("in AS_GENERAL in ParseASInterfaceDescriptor");
terminalLink = ((ASInterfaceDescriptorPtr)theInterfacePtr)->bTerminalLink;
delay = ((ASInterfaceDescriptorPtr)theInterfacePtr)->bDelay;
formatTag = USBToHostWord ((((ASInterfaceDescriptorPtr)theInterfacePtr)->wFormatTag[1] << 8) | ((ASInterfaceDescriptorPtr)theInterfacePtr)->wFormatTag[0]);
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
break;
case FORMAT_TYPE:
debugIOLog ("in FORMAT_TYPE in ParseASInterfaceDescriptor");
switch (((ASFormatTypeIDescriptorPtr)theInterfacePtr)->bFormatType) {
case FORMAT_TYPE_I:
case FORMAT_TYPE_III:
debugIOLog ("in FORMAT_TYPE_I/FORMAT_TYPE_III in FORMAT_TYPE");
numChannels = ((ASFormatTypeIDescriptorPtr)theInterfacePtr)->bNrChannels;
subframeSize = ((ASFormatTypeIDescriptorPtr)theInterfacePtr)->bSubframeSize;
bitResolution = ((ASFormatTypeIDescriptorPtr)theInterfacePtr)->bBitResolution;
numSampleFreqs = ((ASFormatTypeIDescriptorPtr)theInterfacePtr)->bSamFreqType;
if (0 != numSampleFreqs) {
debugIOLog ("device has a discrete number of sample rates");
sampleFreqs = (UInt32 *)IOMalloc (numSampleFreqs * sizeof (UInt32));
for (indx = 0; indx < numSampleFreqs; indx++) {
sampleFreqs[indx] = ConvertSampleFreq( &((ASFormatTypeIDescriptorPtr)theInterfacePtr)->sampleFreq[indx * 3] );
}
} else {
debugIOLog ("device has a variable number of sample rates");
sampleFreqs = (UInt32 *)IOMalloc (2 * sizeof (UInt32));
for (indx = 0; indx < 2; indx++) {
sampleFreqs[indx] = ConvertSampleFreq( &((ASFormatTypeIDescriptorPtr)theInterfacePtr)->sampleFreq[indx * 3] );
}
}
break;
case FORMAT_TYPE_II:
debugIOLog ("in FORMAT_TYPE_II in FORMAT_TYPE");
maxBitRate = USBToHostWord (((ASFormatTypeIIDescriptorPtr)theInterfacePtr)->wMaxBitRate);
samplesPerFrame = USBToHostWord (((ASFormatTypeIIDescriptorPtr)theInterfacePtr)->wSamplesPerFrame);
numSampleFreqs = ((ASFormatTypeIIDescriptorPtr)theInterfacePtr)->bSamFreqType;
if (0 != numSampleFreqs) {
debugIOLog ("device has a discrete number of sample rates");
sampleFreqs = (UInt32 *)IOMalloc (numSampleFreqs * sizeof (UInt32));
for (indx = 0; indx < numSampleFreqs; indx++) {
sampleFreqs[indx] = ConvertSampleFreq( &((ASFormatTypeIIDescriptorPtr)theInterfacePtr)->sampleFreq[indx * 3] );
}
} else {
debugIOLog ("device has a variable number of sample rates");
sampleFreqs = (UInt32 *)IOMalloc (2 * sizeof (UInt32));
for (indx = 0; indx < 2; indx++) {
sampleFreqs[indx] = ConvertSampleFreq( &((ASFormatTypeIIDescriptorPtr)theInterfacePtr)->sampleFreq[indx * 3] );
}
}
break;
default:
debugIOLog ("!!!!unknown format type in FORMAT_TYPE!!!!");
}
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
break;
case FORMAT_SPECIFIC:
debugIOLog ("in FORMAT_SPECIFIC in ParseASInterfaceDescriptor");
wFormatTag = USBToHostWord (((ASFormatSpecificDescriptorHeaderPtr)theInterfacePtr)->wFormatTag[1] << 8 | ((ASFormatSpecificDescriptorHeaderPtr)theInterfacePtr)->wFormatTag[0]);
switch (wFormatTag) {
case MPEG:
debugIOLog ("in FORMAT_SPECIFIC in MPEG");
bmMPEGCapabilities = USBToHostWord(
((ASMPEGFormatSpecificDescriptorPtr)theInterfacePtr)->bmMPEGCapabilities[1] << 8 |
((ASMPEGFormatSpecificDescriptorPtr)theInterfacePtr)->bmMPEGCapabilities[0]);
bmMPEGFeatures = ((ASMPEGFormatSpecificDescriptorPtr)theInterfacePtr)->bmMPEGFeatures;
break;
case AC3:
debugIOLog ("in FORMAT_SPECIFIC in AC3");
bmAC3BSID = USBToHostLong(
((ASAC3FormatSpecificDescriptorPtr)theInterfacePtr)->bmBSID[3] << 24 |
((ASAC3FormatSpecificDescriptorPtr)theInterfacePtr)->bmBSID[2] << 16 |
((ASAC3FormatSpecificDescriptorPtr)theInterfacePtr)->bmBSID[1] << 8 |
((ASAC3FormatSpecificDescriptorPtr)theInterfacePtr)->bmBSID[0]);
bmAC3Features = ((ASAC3FormatSpecificDescriptorPtr)theInterfacePtr)->bmAC3Features;
break;
default:
debugIOLog ("!!!!unknown format type 0x%x in FORMAT_SPECIFIC!!!!", wFormatTag);
break;
}
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
break;
default:
debugIOLog ("in default in ParseASInterfaceDescriptor");
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
}
} else {
switch (theInterfacePtr->bDescriptorType) {
case INTERFACE:
debugIOLog ("in INTERFACE in ParseASInterfaceDescriptor");
done = TRUE;
break;
case ENDPOINT:
debugIOLog ("in ENDPOINT in ParseASInterfaceDescriptor");
theEndpoint = USBEndpointObject::create ();
theEndpoint->SetAddress (((USBEndpointDescriptorPtr)theInterfacePtr)->bEndpointAddress);
theEndpoint->SetAttributes (((USBEndpointDescriptorPtr)theInterfacePtr)->bmAttributes);
theEndpoint->SetMaxPacketSize (USBToHostWord (((USBEndpointDescriptorPtr)theInterfacePtr)->wMaxPacketSize));
theEndpoint->SetRefreshInt (((USBEndpointDescriptorPtr)theInterfacePtr)->bRefresh);
theEndpoint->SetSynchAddress (((USBEndpointDescriptorPtr)theInterfacePtr)->bSynchAddress);
if (NULL == theEndpointObjects) {
theEndpointObjects = OSArray::withObjects ((const OSObject **)&theEndpoint, 1);
FailIf (NULL == theEndpointObjects, Exit);
} else {
theEndpointObjects->setObject (theEndpoint);
}
theEndpoint->release ();
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
break;
case CS_ENDPOINT:
debugIOLog ("in CS_ENDPOINT in ParseASInterfaceDescriptor");
if (EP_GENERAL == ((ASEndpointDescriptorPtr)theInterfacePtr)->bDescriptorSubtype) {
debugIOLog ("in EP_GENERAL in CS_ENDPOINT");
theIsocEndpointObject = new USBCSASIsocADEndpointObject (((ASEndpointDescriptorPtr)theInterfacePtr)->bmAttributes & (1 << sampleFreqControlBit),
((ASEndpointDescriptorPtr)theInterfacePtr)->bmAttributes & (1 << pitchControlBit),
((ASEndpointDescriptorPtr)theInterfacePtr)->bmAttributes & (1 << maxPacketsOnlyBit),
((ASEndpointDescriptorPtr)theInterfacePtr)->bLockDelayUnits,
USBToHostWord (((UInt16 *)((ASEndpointDescriptorPtr)theInterfacePtr)->wLockDelay)[0]));
}
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
break;
default:
debugIOLog ("in default in else in ParseASInterfaceDescriptor");
theInterfacePtr = (USBInterfaceDescriptorPtr)((UInt8 *)theInterfacePtr + theInterfacePtr->bLength);
}
}
}
Exit:
debugIOLog ("-USBAudioStreamObject::ParseASInterfaceDescriptor (%x, %d)", theInterfacePtr, currentInterface);
return theInterfacePtr;
}
USBEndpointObject * USBAudioStreamObject::GetEndpointByAddress (UInt8 address) {
USBEndpointObject * thisEndpoint;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisEndpoint = NULL;
if (theEndpointObjects) {
while (!found && indx < theEndpointObjects->getCount ()) {
thisEndpoint = GetIndexedEndpointObject (indx);
if (thisEndpoint && (thisEndpoint->GetAddress () == address)) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisEndpoint = NULL;
return thisEndpoint;
}
USBEndpointObject * USBAudioStreamObject::GetEndpointObjectByAddress (UInt8 address) {
USBEndpointObject * thisEndpointObject;
UInt8 indx;
Boolean found;
indx = 0;
found = FALSE;
thisEndpointObject = NULL;
if (theEndpointObjects) {
while (!found && indx < theEndpointObjects->getCount ()) {
thisEndpointObject = OSDynamicCast (USBEndpointObject, theEndpointObjects->getObject (indx));
if (thisEndpointObject && address == thisEndpointObject->GetAddress ()) {
found = TRUE;
}
indx++;
}
}
if (found != TRUE)
thisEndpointObject = NULL;
return thisEndpointObject;
}
OSDefineMetaClassAndStructors (USBEndpointObject, OSObject);
USBEndpointObject * USBEndpointObject::create (void) {
USBEndpointObject * endpointObject;
endpointObject = new USBEndpointObject;
FailIf (NULL == endpointObject, Exit);
if (FALSE == endpointObject->init ()) {
endpointObject->release ();
endpointObject = 0;
}
Exit:
return endpointObject;
}
void USBEndpointObject::free (void) {
OSObject::free ();
}
USBCSASIsocADEndpointObject::USBCSASIsocADEndpointObject (Boolean theSampleFreqControl, Boolean thePitchControl, Boolean theMaxPacketsOnly, UInt8 theLockDelayUnits, UInt16 theLockDelay)
: sampleFreqControl (theSampleFreqControl),
pitchControl (thePitchControl),
maxPacketsOnly (theMaxPacketsOnly),
lockDelayUnits (theLockDelayUnits),
lockDelay (theLockDelay)
{
}
void USBInputTerminalObject::free (void) {
USBACDescriptorObject::free ();
}
void USBOutputTerminalObject::free (void) {
USBACDescriptorObject::free ();
}
void USBMixerUnitObject::free (void) {
USBACDescriptorObject::free ();
}
void USBMixerUnitObject::InitControlsArray (UInt8 * bmCntrls, UInt8 bmControlSize) {
#if DEBUGLOGGING
UInt8 i;
#endif
controlSize = bmControlSize;
bmControls = ((UInt8 *)IOMalloc (bmControlSize));
FailIf (NULL == bmControls, Exit);
memcpy (bmControls, bmCntrls, bmControlSize);
#if DEBUGLOGGING
for (i = 0; i < bmControlSize; i++) {
debugIOLog ("bmCntrls[%d] = 0x%X", i, bmCntrls[i]);
debugIOLog ("bmControls[%d] = 0x%X", i, bmControls[i]);
}
#endif
Exit:
return;
}
void USBMixerUnitObject::InitSourceIDs (UInt8 * baSrcIDs, UInt8 nrInPins) {
numInPins = nrInPins;
baSourceIDs = (UInt8 *)IOMalloc (nrInPins);
FailIf (NULL == baSourceIDs, Exit);
memcpy (baSourceIDs, baSrcIDs, nrInPins);
#if DEBUGLOGGING
{
UInt8 i;
for (i = 0; i < nrInPins; i++) {
debugIOLog ("baSourceIDs[%d] = %d", i, baSourceIDs[i]);
}
}
#endif
Exit:
return;
}
void USBSelectorUnitObject::free (void) {
USBACDescriptorObject::free ();
}
void USBSelectorUnitObject::InitSourceIDs (UInt8 * baSrcIDs, UInt8 nrInPins) {
numInPins = nrInPins;
baSourceIDs = (UInt8 *)IOMalloc (nrInPins);
FailIf (NULL == baSourceIDs, Exit);
memcpy (baSourceIDs, baSrcIDs, nrInPins);
Exit:
return;
}
void USBProcessingUnitObject::free (void) {
USBACDescriptorObject::free ();
}
void USBProcessingUnitObject::InitSourceIDs (UInt8 * baSrcIDs, UInt8 nrInPins) {
numInPins = nrInPins;
baSourceIDs = (UInt8 *)IOMalloc (nrInPins);
FailIf (NULL == baSourceIDs, Exit);
memcpy (baSourceIDs, baSrcIDs, nrInPins);
Exit:
return;
}
void USBProcessingUnitObject::InitControlsArray (UInt8 * bmCntrls, UInt8 bmControlSize) {
UInt8 i;
controlSize = bmControlSize;
bmControls = ((UInt8 *)IOMalloc (bmControlSize));
FailIf (NULL == bmControls, Exit);
memcpy (bmControls, bmCntrls, bmControlSize);
for (i = 0; i < bmControlSize; i++) {
debugIOLog ("bmCntrls[%d] = 0x%X", i, bmCntrls[i]);
debugIOLog ("bmControls[%d] = 0x%X", i, bmControls[i]);
}
Exit:
return;
}
void USBFeatureUnitObject::free (void) {
IOFree (bmaControls, numControls * controlSize);
USBACDescriptorObject::free ();
}
Boolean USBFeatureUnitObject::MasterHasMuteControl (void) {
return ChannelHasMuteControl (0); }
Boolean USBFeatureUnitObject::ChannelHasMuteControl (UInt8 channelNum) {
Boolean result;
result = FALSE;
if (numControls >= channelNum + 1) {
if (1 == controlSize) {
result = ((UInt8 *)bmaControls)[channelNum] & (1 << kMuteBit);
} else {
result = ((UInt16 *)bmaControls)[channelNum] & (1 << kMuteBit);
}
}
return result;
}
Boolean USBFeatureUnitObject::ChannelHasVolumeControl (UInt8 channelNum) {
Boolean result;
result = FALSE;
if (numControls >= channelNum + 1) {
if (1 == controlSize) {
result = ((UInt8 *)bmaControls)[channelNum] & (1 << kVolumeBit);
} else {
result = ((UInt16 *)bmaControls)[channelNum] & (1 << kVolumeBit);
}
}
return result;
}
void USBFeatureUnitObject::InitControlsArray (UInt8 * bmaControlsArrary, UInt8 numCntrls) {
UInt32 bmaControlIndex;
numControls = numCntrls;
bmaControls = (UInt8 *)IOMalloc (numControls * controlSize);
FailIf (NULL == bmaControls, Exit);
memcpy (bmaControls, bmaControlsArrary, numControls * controlSize);
if (2 == controlSize) {
for (bmaControlIndex = 0; bmaControlIndex < numControls; bmaControlIndex++) {
((UInt16 *)bmaControls)[bmaControlIndex] = USBToHostWord (((UInt16 *)bmaControls)[bmaControlIndex]);
}
}
Exit:
return;
}
void USBExtensionUnitObject::free (void) {
USBACDescriptorObject::free ();
}
void USBExtensionUnitObject::InitControlsArray (UInt8 * bmCntrls, UInt8 bmControlSize) {
UInt8 i;
controlSize = bmControlSize;
bmControls = ((UInt8 *)IOMalloc (bmControlSize));
FailIf (NULL == bmControls, Exit);
memcpy (bmControls, bmCntrls, bmControlSize);
for (i = 0; i < bmControlSize; i++) {
debugIOLog ("bmCntrls[%d] = 0x%X", i, bmCntrls[i]);
debugIOLog ("bmControls[%d] = 0x%X", i, bmControls[i]);
}
Exit:
return;
}
void USBExtensionUnitObject::InitSourceIDs (UInt8 * baSrcIDs, UInt8 nrInPins) {
numInPins = nrInPins;
baSourceIDs = (UInt8 *)IOMalloc (nrInPins);
FailIf (NULL == baSourceIDs, Exit);
memcpy (baSourceIDs, baSrcIDs, nrInPins);
#if DEBUGLOGGING
{
UInt8 i;
for (i = 0; i < nrInPins; i++) {
debugIOLog ("baSourceIDs[%d] = %d", i, baSourceIDs[i]);
}
}
#endif
Exit:
return;
}
OSDefineMetaClassAndStructors (USBACDescriptorObject, OSObject);
void USBACDescriptorObject::free (void) {
OSObject::free ();
}
Generated by GNU enscript 1.6.4.