/* This file is part of Darling. Copyright (C) 2015-2016 Lubos Dolezel Darling is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Darling 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 General Public License for more details. You should have received a copy of the GNU General Public License along with Darling. If not, see . */ #include "AudioHardware.h" #include "AudioHardwareImpl.h" #include #include static std::unique_ptr g_systemObject; static AudioHardwareImpl* GetSystemObject() { if (!g_systemObject) { static std::mutex singleLock; singleLock.lock(); if (!g_systemObject) g_systemObject.reset(nullptr); // TODO: create ALSA or PA here singleLock.unlock(); } return g_systemObject.get(); } static AudioHardwareImpl* GetObject(AudioObjectID objID) { if (objID == kAudioObjectSystemObject) return GetSystemObject(); return nullptr; } void AudioObjectShow(AudioObjectID inObjectID) { AudioHardwareImpl* obj = GetObject(inObjectID); if (obj) obj->show(); } Boolean AudioObjectHasProperty(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress) { AudioHardwareImpl* obj = GetObject(inObjectID); if (!obj) return kAudioHardwareBadObjectError; return obj->hasProperty(inAddress); } OSStatus AudioObjectIsPropertySettable(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, Boolean* outIsSettable) { AudioHardwareImpl* obj = GetObject(inObjectID); if (!obj) return kAudioHardwareBadObjectError; return obj->isPropertySettable(inAddress, outIsSettable); } OSStatus AudioObjectGetPropertyDataSize(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32* outDataSize) { AudioHardwareImpl* obj = GetObject(inObjectID); if (!obj) return kAudioHardwareBadObjectError; return obj->getPropertyDataSize(inAddress, inQualifierDataSize, inQualifierData, outDataSize); } OSStatus AudioObjectGetPropertyData(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32* ioDataSize, void* outData) { AudioHardwareImpl* obj = GetObject(inObjectID); if (!obj) return kAudioHardwareBadObjectError; return obj->getPropertyData(inAddress, inQualifierDataSize, inQualifierData, ioDataSize, outData); } OSStatus AudioObjectSetPropertyData(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, UInt32 inQualifierDataSize, const void* inQualifierData, UInt32 inDataSize, const void* inData) { AudioHardwareImpl* obj = GetObject(inObjectID); if (!obj) return kAudioHardwareBadObjectError; return obj->setPropertyData(inAddress, inQualifierDataSize, inQualifierData, inDataSize, inData); } OSStatus AudioObjectAddPropertyListener(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, AudioObjectPropertyListenerProc inListener, void* inClientData) { AudioHardwareImpl* obj = GetObject(inObjectID); if (!obj) return kAudioHardwareBadObjectError; return obj->addPropertyListener(inAddress, inListener, inClientData); } OSStatus AudioObjectRemovePropertyListener(AudioObjectID inObjectID, const AudioObjectPropertyAddress* inAddress, AudioObjectPropertyListenerProc inListener, void* inClientData) { AudioHardwareImpl* obj = GetObject(inObjectID); if (!obj) return kAudioHardwareBadObjectError; return obj->removePropertyListener(inAddress, inListener, inClientData); } OSStatus AudioHardwareUnload(void) { g_systemObject.reset(nullptr); return noErr; } OSStatus AudioHardwareCreateAggregateDevice(CFDictionaryRef, AudioObjectID* outDeviceID) { if (outDeviceID) *outDeviceID = 0; return unimpErr; } OSStatus AudioHardwareDestroyAggregateDevice(AudioObjectID inDeviceID) { return unimpErr; } OSStatus AudioDeviceCreateIOProcID(AudioObjectID inDevice, AudioDeviceIOProc inProc, void* inClientData, AudioDeviceIOProcID* outIOProcID) { AudioHardwareImpl* obj = GetObject(inDevice); if (!obj) return kAudioHardwareBadObjectError; return obj->createIOProcID(inProc, inClientData, outIOProcID); } OSStatus AudioDeviceDestroyIOProcID(AudioObjectID inDevice, AudioDeviceIOProcID inIOProcID) { AudioHardwareImpl* obj = GetObject(inDevice); if (!obj) return kAudioHardwareBadObjectError; return obj->destroyIOProcID(inIOProcID); } OSStatus AudioDeviceStart(AudioObjectID inDevice, AudioDeviceIOProcID inProcID) { AudioHardwareImpl* obj = GetObject(inDevice); if (!obj) return kAudioHardwareBadObjectError; return obj->start(inProcID, nullptr, 0); } OSStatus AudioDeviceStartAtTime(AudioObjectID inDevice, AudioDeviceIOProcID inProcID, AudioTimeStamp* ioRequestedStartTime, UInt32 inFlags) { AudioHardwareImpl* obj = GetObject(inDevice); if (!obj) return kAudioHardwareBadObjectError; return obj->start(inProcID, ioRequestedStartTime, inFlags); } OSStatus AudioDeviceStop(AudioObjectID inDevice, AudioDeviceIOProcID inProcID) { AudioHardwareImpl* obj = GetObject(inDevice); if (!obj) return kAudioHardwareBadObjectError; return obj->stop(inProcID); } OSStatus AudioDeviceGetCurrentTime(AudioObjectID inDevice, AudioTimeStamp* outTime) { AudioHardwareImpl* obj = GetObject(inDevice); if (!obj) return kAudioHardwareBadObjectError; return obj->getCurrentTime(outTime); } OSStatus AudioDeviceTranslateTime(AudioObjectID inDevice, const AudioTimeStamp* inTime, AudioTimeStamp* outTime) { AudioHardwareImpl* obj = GetObject(inDevice); if (!obj) return kAudioHardwareBadObjectError; return obj->translateTime(inTime, outTime); } OSStatus AudioDeviceGetNearestStartTime(AudioObjectID inDevice, AudioTimeStamp* ioRequestedStartTime, UInt32 inFlags) { AudioHardwareImpl* obj = GetObject(inDevice); if (!obj) return kAudioHardwareBadObjectError; return obj->getNearestStartTime(ioRequestedStartTime, inFlags); }