| 
							- /*!
 - 	@file		AudioUnitSDK/AUBuffer.h
 - 	@copyright	© 2000-2021 Apple Inc. All rights reserved.
 - */
 - #ifndef AudioUnitSDK_AUBuffer_h
 - #define AudioUnitSDK_AUBuffer_h
 - 
 - #include <AudioUnitSDK/AUUtility.h>
 - 
 - #include <AudioToolbox/AudioUnit.h>
 - 
 - #include <cstddef>
 - #include <optional>
 - 
 - namespace ausdk {
 - 
 - /// struct created/destroyed by allocator. Do not attempt to manually create/destroy.
 - struct AllocatedBuffer {
 - 	const UInt32 mMaximumNumberBuffers;
 - 	const UInt32 mMaximumBytesPerBuffer;
 - 	const UInt32 mReservedA[2]; // NOLINT C-style array
 - 	const UInt32 mHeaderSize;
 - 	const UInt32 mBufferDataSize;
 - 	const UInt32 mReservedB[2]; // NOLINT C-style array
 - 	void* const mBufferData;
 - 	void* const mReservedC;
 - 
 - 	AudioBufferList mAudioBufferList;
 - 	// opaque variable-length data may follow the AudioBufferList
 - 
 - 	AudioBufferList& Prepare(UInt32 channelsPerBuffer, UInt32 bytesPerBuffer);
 - 	AudioBufferList& PrepareNull(UInt32 channelsPerBuffer, UInt32 bytesPerBuffer);
 - };
 - 
 - /*!
 - 	@class	BufferAllocator
 - 	@brief	Class which allocates memory for internal audio buffers.
 - 
 - 	To customize, create a subclass and install an instance into the global via set_instance().
 - */
 - class BufferAllocator {
 - public:
 - 	/// Obtain the global instance, creating it if necessary.
 - 	static BufferAllocator& instance();
 - 
 - 	/// A client may install a custom global instance via this method. Throws an exception if
 - 	/// a default instance has already been created.
 - 	static void set_instance(BufferAllocator& instance);
 - 
 - 	BufferAllocator() = default;
 - 	virtual ~BufferAllocator() = default;
 - 
 - 	// Rule of 5
 - 	BufferAllocator(const BufferAllocator&) = delete;
 - 	BufferAllocator(BufferAllocator&&) = delete;
 - 	BufferAllocator& operator=(const BufferAllocator&) = delete;
 - 	BufferAllocator& operator=(BufferAllocator&&) = delete;
 - 
 - 	// N.B. Must return zeroed memory aligned to at least 16 bytes.
 - 	virtual AllocatedBuffer* Allocate(
 - 		UInt32 numberBuffers, UInt32 maxBytesPerBuffer, UInt32 reservedFlags);
 - 	virtual void Deallocate(AllocatedBuffer* allocatedBuffer);
 - };
 - 
 - /*!
 - 	@class	AUBufferList
 - 	@brief	Manages an `AudioBufferList` backed by allocated memory buffers.
 - */
 - class AUBufferList {
 - 	enum class EPtrState { Invalid, ToMyMemory, ToExternalMemory };
 - 
 - public:
 - 	AUBufferList() = default;
 - 	~AUBufferList() { Deallocate(); }
 - 
 - 	AUBufferList(const AUBufferList&) = delete;
 - 	AUBufferList(AUBufferList&&) = delete;
 - 	AUBufferList& operator=(const AUBufferList&) = delete;
 - 	AUBufferList& operator=(AUBufferList&&) = delete;
 - 
 - 	AudioBufferList& PrepareBuffer(const AudioStreamBasicDescription& format, UInt32 nFrames);
 - 	AudioBufferList& PrepareNullBuffer(const AudioStreamBasicDescription& format, UInt32 nFrames);
 - 
 - 	AudioBufferList& SetBufferList(const AudioBufferList& abl)
 - 	{
 - 		ausdk::ThrowExceptionIf(mAllocatedStreams < abl.mNumberBuffers, -1);
 - 		mPtrState = EPtrState::ToExternalMemory;
 - 		auto& myabl = mBuffers->mAudioBufferList;
 - 		memcpy(&myabl, &abl,
 - 			static_cast<size_t>(
 - 				reinterpret_cast<const std::byte*>(&abl.mBuffers[abl.mNumberBuffers]) - // NOLINT
 - 				reinterpret_cast<const std::byte*>(&abl)));                             // NOLINT
 - 		return myabl;
 - 	}
 - 
 - 	void SetBuffer(UInt32 index, const AudioBuffer& ab)
 - 	{
 - 		auto& myabl = mBuffers->mAudioBufferList;
 - 		ausdk::ThrowExceptionIf(
 - 			mPtrState == EPtrState::Invalid || index >= myabl.mNumberBuffers, -1);
 - 		mPtrState = EPtrState::ToExternalMemory;
 - 		myabl.mBuffers[index] = ab; // NOLINT
 - 	}
 - 
 - 	void InvalidateBufferList() noexcept { mPtrState = EPtrState::Invalid; }
 - 
 - 	[[nodiscard]] AudioBufferList& GetBufferList() const
 - 	{
 - 		ausdk::ThrowExceptionIf(mPtrState == EPtrState::Invalid, -1);
 - 		return mBuffers->mAudioBufferList;
 - 	}
 - 
 - 	void CopyBufferListTo(AudioBufferList& abl) const
 - 	{
 - 		ausdk::ThrowExceptionIf(mPtrState == EPtrState::Invalid, -1);
 - 		memcpy(&abl, &mBuffers->mAudioBufferList,
 - 			static_cast<size_t>(
 - 				reinterpret_cast<std::byte*>(&abl.mBuffers[abl.mNumberBuffers]) - // NOLINT
 - 				reinterpret_cast<std::byte*>(&abl)));                             // NOLINT
 - 	}
 - 
 - 	void CopyBufferContentsTo(AudioBufferList& destabl) const
 - 	{
 - 		ausdk::ThrowExceptionIf(mPtrState == EPtrState::Invalid, -1);
 - 		const auto& srcabl = mBuffers->mAudioBufferList;
 - 		const AudioBuffer* srcbuf = srcabl.mBuffers; // NOLINT
 - 		AudioBuffer* destbuf = destabl.mBuffers;     // NOLINT
 - 
 - 		for (UInt32 i = 0; i < destabl.mNumberBuffers; ++i, ++srcbuf, ++destbuf) { // NOLINT
 - 			if (i >=
 - 				srcabl.mNumberBuffers) { // duplicate last source to additional outputs [4341137]
 - 				--srcbuf;                // NOLINT
 - 			}
 - 			if (destbuf->mData != srcbuf->mData) {
 - 				memmove(destbuf->mData, srcbuf->mData, srcbuf->mDataByteSize);
 - 			}
 - 			destbuf->mDataByteSize = srcbuf->mDataByteSize;
 - 		}
 - 	}
 - 
 - 	void Allocate(const AudioStreamBasicDescription& format, UInt32 nFrames);
 - 
 - 	void Deallocate();
 - 
 - 	// AudioBufferList utilities
 - 	static void ZeroBuffer(AudioBufferList& abl)
 - 	{
 - 		AudioBuffer* buf = abl.mBuffers;                         // NOLINT
 - 		for (UInt32 i = 0; i < abl.mNumberBuffers; ++i, ++buf) { // NOLINT
 - 			memset(buf->mData, 0, buf->mDataByteSize);
 - 		}
 - 	}
 - 
 - 	[[nodiscard]] UInt32 GetAllocatedFrames() const noexcept { return mAllocatedFrames; }
 - 
 - private:
 - 	EPtrState mPtrState{ EPtrState::Invalid };
 - 	AllocatedBuffer* mBuffers = nullptr; // only valid between Allocate and Deallocate
 - 
 - 	UInt32 mAllocatedStreams{ 0 };
 - 	UInt32 mAllocatedFrames{ 0 };
 - };
 - 
 - } // namespace ausdk
 - 
 - #endif // AudioUnitSDK_AUBuffer_h
 
 
  |