//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // Teardown() // This is invoked when the DAL is torn down by CMIOHardwareUnload(). If the process quits or crashes, the DAL just vanishes. //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void PlugIn::Teardown() { // Grab the muxtex for the plugIn's state CAMutex::Locker locker(GetStateMutex()); // Cancel the dispatch source for the device event notifications if (NULL != mDeviceEventDispatchSource) { dispatch_source_cancel(mDeviceEventDispatchSource); dispatch_release(mDeviceEventDispatchSource); mDeviceEventDispatchSource = NULL; } // Do the full teardown if this is outside of the process being torn down or this is the master process if (not DALA::System::IsInitingOrExiting() or DALA::System::IsMaster()) { // Teardown all the devices currently being managed while (0 != GetNumberDevices()) DeviceRemoved(*static_cast<Device*>(GetDeviceByIndex(0))); // Teardown the super class DP::PlugIn::Teardown(); } else { // Iterate over the devices and suspend and finalize them for (UInt32 i = 0 ; i < GetNumberDevices() ; ++i) { Device* device = static_cast<Device*>(GetDeviceByIndex(i)); // Suspend the device device->Unplug(); // Finalize (rather than teardown) the device device->Finalize(); } // Teardown the super class DP::PlugIn::Teardown(); // And leave the rest to die with the process... } }
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // UpdateDeviceStates() //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- void PlugIn::UpdateDeviceStates() { // Get the current state of all the devices plugged in from the SampleAssistant DPA::Sample::AutoFreeUnboundedArray<DPA::Sample::DeviceState> deviceStates; DPA::Sample::GetDeviceStates(mAssistantPort, mDeviceEventPort->GetMachPort(), deviceStates); // Determine how many devices have been removed (if any). // This will be done by iterating over all the devices the PlugIn knows about and making sure they are present in the deviceStates array { std::vector<Device*> removedDevices; for (UInt32 i = 0 ; i < GetNumberDevices() ; ++i) { Device* device = static_cast<Device*>(GetDeviceByIndex(i)); bool found = false; // See if it can be located in the deviceStates array for (UInt32 ii = 0; ii < deviceStates.GetLength() ; ++ii) { if (deviceStates[ii].mGUID == device->GetDeviceGUID()) { found = true; break; } } // If the device was not found, stick into the vector of unplugged devices if (not found) removedDevices.push_back(device); } // Remove all the unplugged devices for (std::vector<Device*>::iterator i = removedDevices.begin() ; i != removedDevices.end() ; ++i) DeviceRemoved(**i); } // Determine how many new devices are present { for (UInt32 i = 0; i < deviceStates.GetLength() ; ++i) { try { // This will throw an exception if the device is not found (void) GetDeviceByGUID(deviceStates[i].mGUID); } catch (...) { // No device was found with the indicated GUID, so it is a new device DeviceArrived(deviceStates[i].mGUID, deviceStates[i].mRegistryPath); } } } }
AudioDeviceID CAAudioHardwareSystem::GetDeviceAtIndex(UInt32 inIndex) { AudioDeviceID theAnswer = 0; UInt32 theNumberDevices = GetNumberDevices(); if((theNumberDevices > 0) && (inIndex < theNumberDevices)) { CAAutoArrayDelete<AudioDeviceID> theDeviceList(theNumberDevices); UInt32 theSize = theNumberDevices * sizeof(AudioDeviceID); GetPropertyData(kAudioHardwarePropertyDevices, theSize, theDeviceList); theAnswer = theDeviceList[inIndex]; } return theAnswer; }
UInt32 CAAudioHardwareSystem::GetIndexForDevice(const AudioDeviceID inDevice) { UInt32 theAnswer = 0xFFFFFFFF; UInt32 theNumberDevices = GetNumberDevices(); if(theNumberDevices > 0) { CAAutoArrayDelete<AudioDeviceID> theDeviceList(theNumberDevices); UInt32 theSize = theNumberDevices * sizeof(AudioDeviceID); GetPropertyData(kAudioHardwarePropertyDevices, theSize, theDeviceList); for(UInt32 theIndex = 0; theIndex < theNumberDevices; ++theIndex) { if(inDevice == theDeviceList[theIndex]) { theAnswer = theIndex; break; } } } return theAnswer; }
//----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- // GetDeviceByGUID() //----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Device& PlugIn::GetDeviceByGUID(UInt64 guid) const { Device* device = 0; bool found = false; // Iterate over the plugIn's devices and find the one whose guid matches for (UInt32 i = 0 ; i < GetNumberDevices() ; ++i) { device = static_cast<Device*>(GetDeviceByIndex(i)); ThrowIfNULL(device, CAException(kCMIOHardwareBadDeviceError), "CMIO::DP::Sample::PlugIn::GetDeviceByGUID: no device for index"); if (guid == device->GetDeviceGUID()) { found = true; break; } } // Make sure that a device was actually found if (not found) throw CAException(kCMIOHardwareBadDeviceError); return *device; }