/* This file is part of Darling. Copyright (C) 2020 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 . */ #ifndef CAC_AUHAL_H #define CAC_AUHAL_H #include "AUBase.h" #include #include #include #include #include class AUHAL : public AUBase { public: AUHAL(AudioComponentInstance inInstance, bool supportRecording = true); ~AUHAL(); bool CanScheduleParameters() const override; bool StreamFormatWritable(AudioUnitScope scope, AudioUnitElement element) override; OSStatus Version() override; OSStatus Start() override; OSStatus Stop() override; OSStatus SetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, const void* inData, UInt32 inDataSize) override; OSStatus GetPropertyInfo(AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, UInt32& outDataSize, Boolean& outWritable) override; OSStatus GetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void* outData) override; OSStatus Render(AudioUnitRenderActionFlags& ioActionFlags, const AudioTimeStamp& inTimeStamp, UInt32 inNumberFrames) override; static OSStatus ComponentEntryDispatch(ComponentParameters *params, AUHAL *This); private: static OSStatus playbackCallback(AudioObjectID inObjectID, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData); static OSStatus recordCallback(AudioObjectID inObjectID, const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime, void* inClientData); OSStatus doPlayback(const AudioTimeStamp* inNow, AudioBufferList* outOutputData, const AudioTimeStamp* inOutputTime); OSStatus doRecord(const AudioTimeStamp* inNow, const AudioBufferList* inInputData, const AudioTimeStamp* inInputTime); protected: AURenderCallbackStruct m_outputAvailableCb = { 0 }; bool m_enableOutput = true, m_enableInput = false; bool m_running = false; AudioDeviceID m_outputDevice, m_inputDevice; AudioDeviceIOProcID m_outputProcID = 0, m_inputProcID = 0; bool m_dataAvailable = false; std::condition_variable m_dataAvailableCV; std::mutex m_dataAvailableMutex; // TODO: Prepare for non-interleaved audio std::unique_ptr m_buffer; size_t m_bufferSize = 0, m_bufferUsed = 0; }; #endif