Full Code of apple/AudioUnitSDK for AI

main bd98b31feff5 cached
50 files
352.1 KB
95.0k tokens
288 symbols
1 requests
Download .txt
Showing preview only (370K chars total). Download the full file or copy to clipboard to get everything.
Repository: apple/AudioUnitSDK
Branch: main
Commit: bd98b31feff5
Files: 50
Total size: 352.1 KB

Directory structure:
gitextract_ldpfski0/

├── .github/
│   └── pull_request_template.md
├── .gitignore
├── AudioUnitSDK.xcodeproj/
│   ├── project.pbxproj
│   └── xcshareddata/
│       └── xcschemes/
│           ├── AudioUnitSDK.xcscheme
│           ├── EmptyPlugIns.xcscheme
│           └── Tests.xcscheme
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── _clang-format
├── _clang-tidy
├── demos/
│   └── EmptyPlugIns/
│       ├── EmptyPlugIns.cpp
│       └── Info.plist
├── hooks/
│   ├── install.sh
│   └── pre-commit
├── include/
│   └── AudioUnitSDK/
│       ├── AUBase.h
│       ├── AUBuffer.h
│       ├── AUConfig.h
│       ├── AUEffectBase.h
│       ├── AUInputElement.h
│       ├── AUMIDIBase.h
│       ├── AUMIDIEffectBase.h
│       ├── AUMIDIUtility.h
│       ├── AUOutputElement.h
│       ├── AUPlugInDispatch.h
│       ├── AUScopeElement.h
│       ├── AUSilentTimeout.h
│       ├── AUThreadSafeList.h
│       ├── AUUtility.h
│       ├── AudioUnitSDK.h
│       ├── ComponentBase.h
│       └── MusicDeviceBase.h
├── readme.md
├── src/
│   └── AudioUnitSDK/
│       ├── AUBase.cpp
│       ├── AUBuffer.cpp
│       ├── AUBufferAllocator.cpp
│       ├── AUEffectBase.cpp
│       ├── AUInputElement.cpp
│       ├── AUMIDIBase.cpp
│       ├── AUMIDIEffectBase.cpp
│       ├── AUOutputElement.cpp
│       ├── AUPlugInDispatch.cpp
│       ├── AUScopeElement.cpp
│       ├── ComponentBase.cpp
│       └── MusicDeviceBase.cpp
├── tests/
│   ├── AUThreadSafeListTests.mm
│   ├── Info.plist
│   └── Tests.mm
└── tools/
    ├── FindUB.sh
    └── build.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/pull_request_template.md
================================================
NOTE: - While you can open new pull requests WE ADVISE AGAINST IT and as such our response may be limited.

This project doesn't accept pull requests. Opening an issue is the recommended method to report a bug or provide feedback. You can also fork the repo if you wish to customize it. If you want to open a pull request anyway, please review [CONTRIBUTING.md](../CONTRIBUTING.md) first and indicate your agreement to the terms outlined in CONTRIBUTING.md by checking the box below.

We appreciate your interest in the project!

Do not erase the below when submitting your pull request:
#########

- [ ] I understand that response time may be limited because the project doesn't accept pull requests.
- [ ] I agree to the terms outlined in CONTRIBUTING.md 


================================================
FILE: .gitignore
================================================
.DS_Store
.cache/
xcuserdata/


================================================
FILE: AudioUnitSDK.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 54;
	objects = {

/* Begin PBXBuildFile section */
		394A97042576BF1700897571 /* AUMIDIUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 394A97032576BF1700897571 /* AUMIDIUtility.h */; settings = {ATTRIBUTES = (Public, ); }; };
		64339772294B5DDC00DCD59F /* AUThreadSafeListTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 64339771294B5DDC00DCD59F /* AUThreadSafeListTests.mm */; };
		643D7987292BF34C00910294 /* AUThreadSafeList.h in Headers */ = {isa = PBXBuildFile; fileRef = 643D7986292BF34C00910294 /* AUThreadSafeList.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100832E24DF0EB6003E57AE /* AUInputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 914EC75924D9181600725ABE /* AUInputElement.cpp */; };
		9100832F24DF0EE7003E57AE /* AUOutputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 914EC75824D9181600725ABE /* AUOutputElement.cpp */; };
		9100833024DF0F2C003E57AE /* AUBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 914EC76224D9181600725ABE /* AUBase.cpp */; };
		9100833D24DF1CCC003E57AE /* EmptyPlugIns.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9100833C24DF1CCC003E57AE /* EmptyPlugIns.cpp */; };
		9100834124DF1EEB003E57AE /* libAudioUnitSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 910C29CE24D910D300B9116B /* libAudioUnitSDK.a */; };
		9100834324DF1EF5003E57AE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9100834224DF1EF5003E57AE /* AudioToolbox.framework */; };
		9100835124DF3D54003E57AE /* AUEffectBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9100834F24DF3245003E57AE /* AUEffectBase.cpp */; };
		9100835424DF4125003E57AE /* AUMIDIBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9100834E24DF3245003E57AE /* AUMIDIBase.cpp */; };
		9100835524DF421A003E57AE /* MusicDeviceBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9100834624DF3245003E57AE /* MusicDeviceBase.cpp */; };
		9100835724DF9BAC003E57AE /* AUMIDIEffectBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9100834C24DF3245003E57AE /* AUMIDIEffectBase.cpp */; };
		9100835824E05892003E57AE /* AUScopeElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 914EC75C24D9181600725ABE /* AUScopeElement.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100835924E05892003E57AE /* AUSilentTimeout.h in Headers */ = {isa = PBXBuildFile; fileRef = 9100835224DF3DAC003E57AE /* AUSilentTimeout.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100835A24E05892003E57AE /* AUInputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 914EC76024D9181600725ABE /* AUInputElement.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100835B24E05892003E57AE /* AUMIDIEffectBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9100834524DF3245003E57AE /* AUMIDIEffectBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100835C24E05892003E57AE /* AUPlugInDispatch.h in Headers */ = {isa = PBXBuildFile; fileRef = 914EC75F24D9181600725ABE /* AUPlugInDispatch.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100835D24E05892003E57AE /* AUMIDIBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9100834424DF3245003E57AE /* AUMIDIBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100835E24E05892003E57AE /* AUOutputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 914EC75B24D9181600725ABE /* AUOutputElement.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100835F24E05892003E57AE /* AUEffectBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9100834924DF3245003E57AE /* AUEffectBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100836024E05892003E57AE /* MusicDeviceBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 9100834B24DF3245003E57AE /* MusicDeviceBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100836124E05892003E57AE /* AUUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 9100832D24DF0C5B003E57AE /* AUUtility.h */; settings = {ATTRIBUTES = (Public, ); }; };
		9100836224E05892003E57AE /* AUBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 914EC76124D9181600725ABE /* AUBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
		910C29D824D9115100B9116B /* ComponentBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 910C29D624D9115100B9116B /* ComponentBase.h */; settings = {ATTRIBUTES = (Public, ); }; };
		910C29D924D9115100B9116B /* ComponentBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 910C29D724D9115100B9116B /* ComponentBase.cpp */; };
		914EC77424D91FFA00725ABE /* AUPlugInDispatch.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 914EC77324D91FFA00725ABE /* AUPlugInDispatch.cpp */; };
		914EC77824D920CC00725ABE /* AUBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 914EC77624D920CC00725ABE /* AUBuffer.h */; settings = {ATTRIBUTES = (Public, ); }; };
		914EC77B24D9225800725ABE /* AudioUnitSDK.h in Headers */ = {isa = PBXBuildFile; fileRef = 914EC77A24D9225800725ABE /* AudioUnitSDK.h */; settings = {ATTRIBUTES = (Public, ); }; };
		914EC77D24D9D91A00725ABE /* AUBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 914EC77524D920CC00725ABE /* AUBuffer.cpp */; };
		914EC77E24D9DB3800725ABE /* AUScopeElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 914EC75D24D9181600725ABE /* AUScopeElement.cpp */; };
		915DA08024E32B37007C6B53 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 915DA07F24E32B37007C6B53 /* CoreFoundation.framework */; };
		91850A902CFA37FC005F9E2F /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9100834224DF1EF5003E57AE /* AudioToolbox.framework */; };
		919B0CC62555C72000C59BDC /* AUBufferAllocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 919B0CC42555C72000C59BDC /* AUBufferAllocator.cpp */; };
		91E93AC324E8962D00BF7289 /* Tests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 91E93AC224E8962D00BF7289 /* Tests.mm */; };
		91E93AC524E8962D00BF7289 /* libAudioUnitSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 910C29CE24D910D300B9116B /* libAudioUnitSDK.a */; };
		B49E353A29E8039C0093D6B7 /* AUConfig.h in Headers */ = {isa = PBXBuildFile; fileRef = B49E353929E8039C0093D6B7 /* AUConfig.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
		9100833E24DF1DEF003E57AE /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = 910C29C624D910D300B9116B /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = 910C29CD24D910D300B9116B;
			remoteInfo = AudioUnitSDK;
		};
		91E93AC624E8962D00BF7289 /* PBXContainerItemProxy */ = {
			isa = PBXContainerItemProxy;
			containerPortal = 910C29C624D910D300B9116B /* Project object */;
			proxyType = 1;
			remoteGlobalIDString = 910C29CD24D910D300B9116B;
			remoteInfo = AudioUnitSDK;
		};
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
		394A97032576BF1700897571 /* AUMIDIUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUMIDIUtility.h; sourceTree = "<group>"; };
		64339771294B5DDC00DCD59F /* AUThreadSafeListTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AUThreadSafeListTests.mm; sourceTree = "<group>"; };
		643D7986292BF34C00910294 /* AUThreadSafeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUThreadSafeList.h; sourceTree = "<group>"; };
		9100832D24DF0C5B003E57AE /* AUUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUUtility.h; sourceTree = "<group>"; };
		9100833524DF1C82003E57AE /* EmptyPlugIns.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EmptyPlugIns.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
		9100833724DF1C82003E57AE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		9100833C24DF1CCC003E57AE /* EmptyPlugIns.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = EmptyPlugIns.cpp; sourceTree = "<group>"; };
		9100834224DF1EF5003E57AE /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
		9100834424DF3245003E57AE /* AUMIDIBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUMIDIBase.h; sourceTree = "<group>"; };
		9100834524DF3245003E57AE /* AUMIDIEffectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUMIDIEffectBase.h; sourceTree = "<group>"; };
		9100834624DF3245003E57AE /* MusicDeviceBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MusicDeviceBase.cpp; sourceTree = "<group>"; };
		9100834924DF3245003E57AE /* AUEffectBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUEffectBase.h; sourceTree = "<group>"; };
		9100834B24DF3245003E57AE /* MusicDeviceBase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MusicDeviceBase.h; sourceTree = "<group>"; };
		9100834C24DF3245003E57AE /* AUMIDIEffectBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUMIDIEffectBase.cpp; sourceTree = "<group>"; };
		9100834E24DF3245003E57AE /* AUMIDIBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUMIDIBase.cpp; sourceTree = "<group>"; };
		9100834F24DF3245003E57AE /* AUEffectBase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUEffectBase.cpp; sourceTree = "<group>"; };
		9100835224DF3DAC003E57AE /* AUSilentTimeout.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUSilentTimeout.h; sourceTree = "<group>"; };
		9100837424E06BA7003E57AE /* build.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build.sh; sourceTree = "<group>"; };
		910C29CE24D910D300B9116B /* libAudioUnitSDK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libAudioUnitSDK.a; sourceTree = BUILT_PRODUCTS_DIR; };
		910C29D624D9115100B9116B /* ComponentBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComponentBase.h; sourceTree = "<group>"; };
		910C29D724D9115100B9116B /* ComponentBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComponentBase.cpp; sourceTree = "<group>"; };
		914EC75824D9181600725ABE /* AUOutputElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AUOutputElement.cpp; sourceTree = "<group>"; };
		914EC75924D9181600725ABE /* AUInputElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AUInputElement.cpp; sourceTree = "<group>"; };
		914EC75B24D9181600725ABE /* AUOutputElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUOutputElement.h; sourceTree = "<group>"; };
		914EC75C24D9181600725ABE /* AUScopeElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUScopeElement.h; sourceTree = "<group>"; };
		914EC75D24D9181600725ABE /* AUScopeElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AUScopeElement.cpp; sourceTree = "<group>"; };
		914EC75F24D9181600725ABE /* AUPlugInDispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUPlugInDispatch.h; sourceTree = "<group>"; };
		914EC76024D9181600725ABE /* AUInputElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUInputElement.h; sourceTree = "<group>"; };
		914EC76124D9181600725ABE /* AUBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUBase.h; sourceTree = "<group>"; };
		914EC76224D9181600725ABE /* AUBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AUBase.cpp; sourceTree = "<group>"; };
		914EC77324D91FFA00725ABE /* AUPlugInDispatch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AUPlugInDispatch.cpp; sourceTree = "<group>"; };
		914EC77524D920CC00725ABE /* AUBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AUBuffer.cpp; sourceTree = "<group>"; };
		914EC77624D920CC00725ABE /* AUBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AUBuffer.h; sourceTree = "<group>"; };
		914EC77A24D9225800725ABE /* AudioUnitSDK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AudioUnitSDK.h; sourceTree = "<group>"; };
		915DA07F24E32B37007C6B53 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
		919B0CC42555C72000C59BDC /* AUBufferAllocator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = AUBufferAllocator.cpp; sourceTree = "<group>"; };
		91E93AC024E8962D00BF7289 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
		91E93AC224E8962D00BF7289 /* Tests.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Tests.mm; sourceTree = "<group>"; };
		91E93AC424E8962D00BF7289 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		B49E353929E8039C0093D6B7 /* AUConfig.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AUConfig.h; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		9100833224DF1C82003E57AE /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				9100834324DF1EF5003E57AE /* AudioToolbox.framework in Frameworks */,
				915DA08024E32B37007C6B53 /* CoreFoundation.framework in Frameworks */,
				9100834124DF1EEB003E57AE /* libAudioUnitSDK.a in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		910C29CC24D910D300B9116B /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		91E93ABD24E8962D00BF7289 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				91850A902CFA37FC005F9E2F /* AudioToolbox.framework in Frameworks */,
				91E93AC524E8962D00BF7289 /* libAudioUnitSDK.a in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		9100833624DF1C82003E57AE /* EmptyPlugIns */ = {
			isa = PBXGroup;
			children = (
				9100833724DF1C82003E57AE /* Info.plist */,
				9100833C24DF1CCC003E57AE /* EmptyPlugIns.cpp */,
			);
			path = EmptyPlugIns;
			sourceTree = "<group>";
		};
		9100834024DF1EEB003E57AE /* Frameworks */ = {
			isa = PBXGroup;
			children = (
				9100834224DF1EF5003E57AE /* AudioToolbox.framework */,
				915DA07F24E32B37007C6B53 /* CoreFoundation.framework */,
			);
			name = Frameworks;
			sourceTree = "<group>";
		};
		9100837324E06B8F003E57AE /* tools */ = {
			isa = PBXGroup;
			children = (
				9100837424E06BA7003E57AE /* build.sh */,
			);
			path = tools;
			sourceTree = "<group>";
		};
		910C29C524D910D300B9116B = {
			isa = PBXGroup;
			children = (
				B487F106284500520074F0B2 /* include */,
				B487F108284500630074F0B2 /* src */,
				9100837324E06B8F003E57AE /* tools */,
				B487F109284501700074F0B2 /* demos */,
				91E93AC124E8962D00BF7289 /* tests */,
				910C29CF24D910D300B9116B /* Products */,
				9100834024DF1EEB003E57AE /* Frameworks */,
			);
			sourceTree = "<group>";
		};
		910C29CF24D910D300B9116B /* Products */ = {
			isa = PBXGroup;
			children = (
				910C29CE24D910D300B9116B /* libAudioUnitSDK.a */,
				9100833524DF1C82003E57AE /* EmptyPlugIns.bundle */,
				91E93AC024E8962D00BF7289 /* Tests.xctest */,
			);
			name = Products;
			sourceTree = "<group>";
		};
		91E93AC124E8962D00BF7289 /* tests */ = {
			isa = PBXGroup;
			children = (
				64339771294B5DDC00DCD59F /* AUThreadSafeListTests.mm */,
				91E93AC224E8962D00BF7289 /* Tests.mm */,
				91E93AC424E8962D00BF7289 /* Info.plist */,
			);
			path = tests;
			sourceTree = "<group>";
		};
		B487F106284500520074F0B2 /* include */ = {
			isa = PBXGroup;
			children = (
				B4888687282AC1D800521D1A /* AudioUnitSDK */,
			);
			path = include;
			sourceTree = "<group>";
		};
		B487F108284500630074F0B2 /* src */ = {
			isa = PBXGroup;
			children = (
				B48885E4282A6D6D00521D1A /* AudioUnitSDK */,
			);
			path = src;
			sourceTree = "<group>";
		};
		B487F109284501700074F0B2 /* demos */ = {
			isa = PBXGroup;
			children = (
				9100833624DF1C82003E57AE /* EmptyPlugIns */,
			);
			path = demos;
			sourceTree = "<group>";
		};
		B48885E4282A6D6D00521D1A /* AudioUnitSDK */ = {
			isa = PBXGroup;
			children = (
				914EC76224D9181600725ABE /* AUBase.cpp */,
				914EC77524D920CC00725ABE /* AUBuffer.cpp */,
				919B0CC42555C72000C59BDC /* AUBufferAllocator.cpp */,
				9100834F24DF3245003E57AE /* AUEffectBase.cpp */,
				914EC75924D9181600725ABE /* AUInputElement.cpp */,
				9100834E24DF3245003E57AE /* AUMIDIBase.cpp */,
				9100834C24DF3245003E57AE /* AUMIDIEffectBase.cpp */,
				914EC75824D9181600725ABE /* AUOutputElement.cpp */,
				914EC77324D91FFA00725ABE /* AUPlugInDispatch.cpp */,
				914EC75D24D9181600725ABE /* AUScopeElement.cpp */,
				910C29D724D9115100B9116B /* ComponentBase.cpp */,
				9100834624DF3245003E57AE /* MusicDeviceBase.cpp */,
			);
			path = AudioUnitSDK;
			sourceTree = "<group>";
		};
		B4888687282AC1D800521D1A /* AudioUnitSDK */ = {
			isa = PBXGroup;
			children = (
				B49E353929E8039C0093D6B7 /* AUConfig.h */,
				914EC76124D9181600725ABE /* AUBase.h */,
				914EC77624D920CC00725ABE /* AUBuffer.h */,
				914EC77A24D9225800725ABE /* AudioUnitSDK.h */,
				9100834924DF3245003E57AE /* AUEffectBase.h */,
				914EC76024D9181600725ABE /* AUInputElement.h */,
				9100834424DF3245003E57AE /* AUMIDIBase.h */,
				9100834524DF3245003E57AE /* AUMIDIEffectBase.h */,
				394A97032576BF1700897571 /* AUMIDIUtility.h */,
				914EC75B24D9181600725ABE /* AUOutputElement.h */,
				914EC75F24D9181600725ABE /* AUPlugInDispatch.h */,
				914EC75C24D9181600725ABE /* AUScopeElement.h */,
				9100835224DF3DAC003E57AE /* AUSilentTimeout.h */,
				643D7986292BF34C00910294 /* AUThreadSafeList.h */,
				9100832D24DF0C5B003E57AE /* AUUtility.h */,
				910C29D624D9115100B9116B /* ComponentBase.h */,
				9100834B24DF3245003E57AE /* MusicDeviceBase.h */,
			);
			path = AudioUnitSDK;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXHeadersBuildPhase section */
		910C29CA24D910D300B9116B /* Headers */ = {
			isa = PBXHeadersBuildPhase;
			buildActionMask = 2147483647;
			files = (
				B49E353A29E8039C0093D6B7 /* AUConfig.h in Headers */,
				9100836224E05892003E57AE /* AUBase.h in Headers */,
				914EC77824D920CC00725ABE /* AUBuffer.h in Headers */,
				914EC77B24D9225800725ABE /* AudioUnitSDK.h in Headers */,
				9100835F24E05892003E57AE /* AUEffectBase.h in Headers */,
				9100835A24E05892003E57AE /* AUInputElement.h in Headers */,
				9100835D24E05892003E57AE /* AUMIDIBase.h in Headers */,
				9100835B24E05892003E57AE /* AUMIDIEffectBase.h in Headers */,
				9100835E24E05892003E57AE /* AUOutputElement.h in Headers */,
				9100835C24E05892003E57AE /* AUPlugInDispatch.h in Headers */,
				394A97042576BF1700897571 /* AUMIDIUtility.h in Headers */,
				9100835824E05892003E57AE /* AUScopeElement.h in Headers */,
				9100835924E05892003E57AE /* AUSilentTimeout.h in Headers */,
				643D7987292BF34C00910294 /* AUThreadSafeList.h in Headers */,
				9100836124E05892003E57AE /* AUUtility.h in Headers */,
				910C29D824D9115100B9116B /* ComponentBase.h in Headers */,
				9100836024E05892003E57AE /* MusicDeviceBase.h in Headers */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXHeadersBuildPhase section */

/* Begin PBXNativeTarget section */
		9100833424DF1C82003E57AE /* EmptyPlugIns */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 9100833824DF1C82003E57AE /* Build configuration list for PBXNativeTarget "EmptyPlugIns" */;
			buildPhases = (
				9100833124DF1C82003E57AE /* Sources */,
				9100833224DF1C82003E57AE /* Frameworks */,
				9100833324DF1C82003E57AE /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
				9100833F24DF1DEF003E57AE /* PBXTargetDependency */,
			);
			name = EmptyPlugIns;
			productName = EmptyPlugIns;
			productReference = 9100833524DF1C82003E57AE /* EmptyPlugIns.bundle */;
			productType = "com.apple.product-type.bundle";
		};
		910C29CD24D910D300B9116B /* AudioUnitSDK */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 910C29D224D910D300B9116B /* Build configuration list for PBXNativeTarget "AudioUnitSDK" */;
			buildPhases = (
				9100837924E1A54B003E57AE /* Install clang-format hook */,
				910C29CA24D910D300B9116B /* Headers */,
				910C29CB24D910D300B9116B /* Sources */,
				910C29CC24D910D300B9116B /* Frameworks */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = AudioUnitSDK;
			productName = AudioUnitSDK;
			productReference = 910C29CE24D910D300B9116B /* libAudioUnitSDK.a */;
			productType = "com.apple.product-type.library.static";
		};
		91E93ABF24E8962D00BF7289 /* Tests */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 91E93ACA24E8962D00BF7289 /* Build configuration list for PBXNativeTarget "Tests" */;
			buildPhases = (
				91E93ABC24E8962D00BF7289 /* Sources */,
				91E93ABD24E8962D00BF7289 /* Frameworks */,
				91E93ABE24E8962D00BF7289 /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
				91E93AC724E8962D00BF7289 /* PBXTargetDependency */,
			);
			name = Tests;
			productName = Tests;
			productReference = 91E93AC024E8962D00BF7289 /* Tests.xctest */;
			productType = "com.apple.product-type.bundle.unit-test";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		910C29C624D910D300B9116B /* Project object */ = {
			isa = PBXProject;
			attributes = {
				LastUpgradeCheck = 1200;
				TargetAttributes = {
					9100833424DF1C82003E57AE = {
						CreatedOnToolsVersion = 12.0;
					};
					910C29CD24D910D300B9116B = {
						CreatedOnToolsVersion = 12.0;
					};
					91E93ABF24E8962D00BF7289 = {
						CreatedOnToolsVersion = 12.0;
					};
				};
			};
			buildConfigurationList = 910C29C924D910D300B9116B /* Build configuration list for PBXProject "AudioUnitSDK" */;
			compatibilityVersion = "Xcode 9.3";
			developmentRegion = en;
			hasScannedForEncodings = 0;
			knownRegions = (
				en,
				Base,
			);
			mainGroup = 910C29C524D910D300B9116B;
			productRefGroup = 910C29CF24D910D300B9116B /* Products */;
			projectDirPath = "";
			projectRoot = "";
			targets = (
				910C29CD24D910D300B9116B /* AudioUnitSDK */,
				9100833424DF1C82003E57AE /* EmptyPlugIns */,
				91E93ABF24E8962D00BF7289 /* Tests */,
			);
		};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
		9100833324DF1C82003E57AE /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		91E93ABE24E8962D00BF7289 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
		9100837924E1A54B003E57AE /* Install clang-format hook */ = {
			isa = PBXShellScriptBuildPhase;
			alwaysOutOfDate = 1;
			buildActionMask = 2147483647;
			files = (
			);
			inputFileListPaths = (
			);
			inputPaths = (
				"$(SRCROOT)/hooks/install.sh",
			);
			name = "Install clang-format hook";
			outputFileListPaths = (
			);
			outputPaths = (
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/sh;
			shellScript = "if [ $CONFIGURATION == Debug ] ; then\n\t\"$SRCROOT/hooks/install.sh\"\nfi\n";
			showEnvVarsInLog = 0;
		};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		9100833124DF1C82003E57AE /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				9100833D24DF1CCC003E57AE /* EmptyPlugIns.cpp in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		910C29CB24D910D300B9116B /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				9100833024DF0F2C003E57AE /* AUBase.cpp in Sources */,
				914EC77D24D9D91A00725ABE /* AUBuffer.cpp in Sources */,
				9100835124DF3D54003E57AE /* AUEffectBase.cpp in Sources */,
				9100832E24DF0EB6003E57AE /* AUInputElement.cpp in Sources */,
				9100835424DF4125003E57AE /* AUMIDIBase.cpp in Sources */,
				9100835724DF9BAC003E57AE /* AUMIDIEffectBase.cpp in Sources */,
				9100832F24DF0EE7003E57AE /* AUOutputElement.cpp in Sources */,
				919B0CC62555C72000C59BDC /* AUBufferAllocator.cpp in Sources */,
				914EC77424D91FFA00725ABE /* AUPlugInDispatch.cpp in Sources */,
				914EC77E24D9DB3800725ABE /* AUScopeElement.cpp in Sources */,
				910C29D924D9115100B9116B /* ComponentBase.cpp in Sources */,
				9100835524DF421A003E57AE /* MusicDeviceBase.cpp in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
		91E93ABC24E8962D00BF7289 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				64339772294B5DDC00DCD59F /* AUThreadSafeListTests.mm in Sources */,
				91E93AC324E8962D00BF7289 /* Tests.mm in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
		9100833F24DF1DEF003E57AE /* PBXTargetDependency */ = {
			isa = PBXTargetDependency;
			target = 910C29CD24D910D300B9116B /* AudioUnitSDK */;
			targetProxy = 9100833E24DF1DEF003E57AE /* PBXContainerItemProxy */;
		};
		91E93AC724E8962D00BF7289 /* PBXTargetDependency */ = {
			isa = PBXTargetDependency;
			target = 910C29CD24D910D300B9116B /* AudioUnitSDK */;
			targetProxy = 91E93AC624E8962D00BF7289 /* PBXContainerItemProxy */;
		};
/* End PBXTargetDependency section */

/* Begin XCBuildConfiguration section */
		9100833924DF1C82003E57AE /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_STYLE = Automatic;
				COMBINE_HIDPI_IMAGES = YES;
				DEVELOPMENT_TEAM = "";
				HEADER_SEARCH_PATHS = include;
				INFOPLIST_FILE = demos/EmptyPlugIns/Info.plist;
				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
				PRODUCT_BUNDLE_IDENTIFIER = com.apple.audio.EmptyPlugIns;
				PRODUCT_NAME = "$(TARGET_NAME)";
				SKIP_INSTALL = YES;
				USE_HEADERMAP = NO;
				WRAPPER_EXTENSION = bundle;
			};
			name = Debug;
		};
		9100833A24DF1C82003E57AE /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_STYLE = Automatic;
				COMBINE_HIDPI_IMAGES = YES;
				DEVELOPMENT_TEAM = "";
				HEADER_SEARCH_PATHS = include;
				INFOPLIST_FILE = demos/EmptyPlugIns/Info.plist;
				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
				PRODUCT_BUNDLE_IDENTIFIER = com.apple.audio.EmptyPlugIns;
				PRODUCT_NAME = "$(TARGET_NAME)";
				SKIP_INSTALL = YES;
				USE_HEADERMAP = NO;
				WRAPPER_EXTENSION = bundle;
			};
			name = Release;
		};
		910C29D024D910D300B9116B /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
				CLANG_CXX_LANGUAGE_STANDARD = "c++23";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_ENABLE_OBJC_WEAK = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_FLOAT_CONVERSION = YES;
				CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;
				COPY_PHASE_STRIP = NO;
				DEAD_CODE_STRIPPING = YES;
				DEBUG_INFORMATION_FORMAT = dwarf;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_TESTABILITY = YES;
				ENABLE_USER_SCRIPT_SANDBOXING = YES;
				GCC_C_LANGUAGE_STANDARD = gnu11;
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 0;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_PEDANTIC = YES;
				GCC_WARN_SIGN_COMPARE = YES;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_PARAMETER = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
				LLVM_LTO = NO;
				MACOSX_DEPLOYMENT_TARGET = 11.0;
				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
				MTL_FAST_MATH = YES;
				SDKROOT = macosx;
				SUPPORTED_PLATFORMS = "macosx iphoneos appletvos watchos";
				SUPPORTS_MACCATALYST = YES;
				WARNING_CFLAGS = (
					"-Wall",
					"-Wextra",
					"-Wimport-preprocessor-directive-pedantic",
					"-Wunreachable-code-break",
					"-Wunreachable-code-return",
					"-Wvla",
					"-Wno-gnu-statement-expression-from-macro-expansion",
				);
			};
			name = Debug;
		};
		910C29D124D910D300B9116B /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
				CLANG_CXX_LANGUAGE_STANDARD = "c++23";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_ENABLE_OBJC_WEAK = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_FLOAT_CONVERSION = YES;
				CLANG_WARN_IMPLICIT_SIGN_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES;
				COPY_PHASE_STRIP = NO;
				DEAD_CODE_STRIPPING = YES;
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
				ENABLE_NS_ASSERTIONS = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_USER_SCRIPT_SANDBOXING = YES;
				GCC_C_LANGUAGE_STANDARD = gnu11;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_PEDANTIC = YES;
				GCC_WARN_SIGN_COMPARE = YES;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_PARAMETER = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				IPHONEOS_DEPLOYMENT_TARGET = 14.0;
				LLVM_LTO = YES;
				MACOSX_DEPLOYMENT_TARGET = 11.0;
				MTL_ENABLE_DEBUG_INFO = NO;
				MTL_FAST_MATH = YES;
				SDKROOT = macosx;
				SUPPORTED_PLATFORMS = "macosx iphoneos appletvos watchos";
				SUPPORTS_MACCATALYST = YES;
				WARNING_CFLAGS = (
					"-Wall",
					"-Wextra",
					"-Wimport-preprocessor-directive-pedantic",
					"-Wunreachable-code-break",
					"-Wunreachable-code-return",
					"-Wvla",
					"-Wno-gnu-statement-expression-from-macro-expansion",
				);
			};
			name = Release;
		};
		910C29D324D910D300B9116B /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_STYLE = Automatic;
				EXECUTABLE_PREFIX = lib;
				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
				HEADER_SEARCH_PATHS = include;
				OTHER_CFLAGS = "-fvisibility=hidden";
				PRODUCT_NAME = "$(TARGET_NAME)";
				PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/AudioUnitSDK;
				SUPPORTS_MACCATALYST = YES;
				USE_HEADERMAP = NO;
			};
			name = Debug;
		};
		910C29D424D910D300B9116B /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				CODE_SIGN_STYLE = Automatic;
				EXECUTABLE_PREFIX = lib;
				GCC_SYMBOLS_PRIVATE_EXTERN = YES;
				HEADER_SEARCH_PATHS = include;
				OTHER_CFLAGS = "-fvisibility=hidden";
				PRODUCT_NAME = "$(TARGET_NAME)";
				PUBLIC_HEADERS_FOLDER_PATH = /usr/local/include/AudioUnitSDK;
				SUPPORTS_MACCATALYST = YES;
				USE_HEADERMAP = NO;
			};
			name = Release;
		};
		91E93AC824E8962D00BF7289 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				COMBINE_HIDPI_IMAGES = YES;
				HEADER_SEARCH_PATHS = include;
				INFOPLIST_FILE = tests/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = (
					"$(inherited)",
					"@executable_path/../Frameworks",
					"@loader_path/../Frameworks",
				);
				PRODUCT_BUNDLE_IDENTIFIER = com.apple.audio.Tests;
				PRODUCT_NAME = "$(TARGET_NAME)";
				USE_HEADERMAP = NO;
				WARNING_CFLAGS = (
					"$(inherited)",
					"-Wno-gnu-statement-expression",
				);
			};
			name = Debug;
		};
		91E93AC924E8962D00BF7289 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				COMBINE_HIDPI_IMAGES = YES;
				HEADER_SEARCH_PATHS = include;
				INFOPLIST_FILE = tests/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = (
					"$(inherited)",
					"@executable_path/../Frameworks",
					"@loader_path/../Frameworks",
				);
				PRODUCT_BUNDLE_IDENTIFIER = com.apple.audio.Tests;
				PRODUCT_NAME = "$(TARGET_NAME)";
				USE_HEADERMAP = NO;
				WARNING_CFLAGS = (
					"$(inherited)",
					"-Wno-gnu-statement-expression",
				);
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		9100833824DF1C82003E57AE /* Build configuration list for PBXNativeTarget "EmptyPlugIns" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				9100833924DF1C82003E57AE /* Debug */,
				9100833A24DF1C82003E57AE /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		910C29C924D910D300B9116B /* Build configuration list for PBXProject "AudioUnitSDK" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				910C29D024D910D300B9116B /* Debug */,
				910C29D124D910D300B9116B /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		910C29D224D910D300B9116B /* Build configuration list for PBXNativeTarget "AudioUnitSDK" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				910C29D324D910D300B9116B /* Debug */,
				910C29D424D910D300B9116B /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		91E93ACA24E8962D00BF7289 /* Build configuration list for PBXNativeTarget "Tests" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				91E93AC824E8962D00BF7289 /* Debug */,
				91E93AC924E8962D00BF7289 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
/* End XCConfigurationList section */
	};
	rootObject = 910C29C624D910D300B9116B /* Project object */;
}


================================================
FILE: AudioUnitSDK.xcodeproj/xcshareddata/xcschemes/AudioUnitSDK.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
   LastUpgradeVersion = "1200"
   version = "1.7">
   <BuildAction
      parallelizeBuildables = "YES"
      buildImplicitDependencies = "YES">
      <BuildActionEntries>
         <BuildActionEntry
            buildForTesting = "YES"
            buildForRunning = "YES"
            buildForProfiling = "YES"
            buildForArchiving = "YES"
            buildForAnalyzing = "YES">
            <BuildableReference
               BuildableIdentifier = "primary"
               BlueprintIdentifier = "910C29CD24D910D300B9116B"
               BuildableName = "libAudioUnitSDK.a"
               BlueprintName = "AudioUnitSDK"
               ReferencedContainer = "container:AudioUnitSDK.xcodeproj">
            </BuildableReference>
         </BuildActionEntry>
      </BuildActionEntries>
   </BuildAction>
   <TestAction
      buildConfiguration = "Debug"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      shouldUseLaunchSchemeArgsEnv = "YES">
      <Testables>
      </Testables>
   </TestAction>
   <LaunchAction
      buildConfiguration = "Debug"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      launchStyle = "0"
      useCustomWorkingDirectory = "NO"
      ignoresPersistentStateOnLaunch = "NO"
      debugDocumentVersioning = "YES"
      debugServiceExtension = "internal"
      allowLocationSimulation = "YES">
   </LaunchAction>
   <ProfileAction
      buildConfiguration = "Release"
      shouldUseLaunchSchemeArgsEnv = "YES"
      savedToolIdentifier = ""
      useCustomWorkingDirectory = "NO"
      debugDocumentVersioning = "YES">
      <MacroExpansion>
         <BuildableReference
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "910C29CD24D910D300B9116B"
            BuildableName = "libAudioUnitSDK.a"
            BlueprintName = "AudioUnitSDK"
            ReferencedContainer = "container:AudioUnitSDK.xcodeproj">
         </BuildableReference>
      </MacroExpansion>
   </ProfileAction>
   <AnalyzeAction
      buildConfiguration = "Debug">
   </AnalyzeAction>
   <ArchiveAction
      buildConfiguration = "Release"
      revealArchiveInOrganizer = "YES">
   </ArchiveAction>
   <InstallAction
      buildConfiguration = "Release">
   </InstallAction>
</Scheme>


================================================
FILE: AudioUnitSDK.xcodeproj/xcshareddata/xcschemes/EmptyPlugIns.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
   LastUpgradeVersion = "1200"
   version = "1.7">
   <BuildAction
      parallelizeBuildables = "YES"
      buildImplicitDependencies = "YES">
      <BuildActionEntries>
         <BuildActionEntry
            buildForTesting = "YES"
            buildForRunning = "YES"
            buildForProfiling = "YES"
            buildForArchiving = "YES"
            buildForAnalyzing = "YES">
            <BuildableReference
               BuildableIdentifier = "primary"
               BlueprintIdentifier = "9100833424DF1C82003E57AE"
               BuildableName = "EmptyPlugIns.bundle"
               BlueprintName = "EmptyPlugIns"
               ReferencedContainer = "container:AudioUnitSDK.xcodeproj">
            </BuildableReference>
         </BuildActionEntry>
      </BuildActionEntries>
   </BuildAction>
   <TestAction
      buildConfiguration = "Debug"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      shouldUseLaunchSchemeArgsEnv = "YES">
      <Testables>
      </Testables>
   </TestAction>
   <LaunchAction
      buildConfiguration = "Debug"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      launchStyle = "0"
      useCustomWorkingDirectory = "NO"
      ignoresPersistentStateOnLaunch = "NO"
      debugDocumentVersioning = "YES"
      debugServiceExtension = "internal"
      allowLocationSimulation = "YES">
   </LaunchAction>
   <ProfileAction
      buildConfiguration = "Release"
      shouldUseLaunchSchemeArgsEnv = "YES"
      savedToolIdentifier = ""
      useCustomWorkingDirectory = "NO"
      debugDocumentVersioning = "YES">
      <MacroExpansion>
         <BuildableReference
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "9100833424DF1C82003E57AE"
            BuildableName = "EmptyPlugIns.bundle"
            BlueprintName = "EmptyPlugIns"
            ReferencedContainer = "container:AudioUnitSDK.xcodeproj">
         </BuildableReference>
      </MacroExpansion>
   </ProfileAction>
   <AnalyzeAction
      buildConfiguration = "Debug">
   </AnalyzeAction>
   <ArchiveAction
      buildConfiguration = "Release"
      revealArchiveInOrganizer = "YES">
   </ArchiveAction>
   <InstallAction
      buildConfiguration = "Release">
   </InstallAction>
</Scheme>


================================================
FILE: AudioUnitSDK.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
   LastUpgradeVersion = "1200"
   version = "1.7">
   <BuildAction
      parallelizeBuildables = "YES"
      buildImplicitDependencies = "YES">
      <BuildActionEntries>
         <BuildActionEntry
            buildForTesting = "YES"
            buildForRunning = "YES"
            buildForProfiling = "NO"
            buildForArchiving = "NO"
            buildForAnalyzing = "NO">
            <BuildableReference
               BuildableIdentifier = "primary"
               BlueprintIdentifier = "91E93ABF24E8962D00BF7289"
               BuildableName = "Tests.xctest"
               BlueprintName = "Tests"
               ReferencedContainer = "container:AudioUnitSDK.xcodeproj">
            </BuildableReference>
         </BuildActionEntry>
      </BuildActionEntries>
   </BuildAction>
   <TestAction
      buildConfiguration = "Debug"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      shouldUseLaunchSchemeArgsEnv = "YES">
      <Testables>
         <TestableReference
            skipped = "NO">
            <BuildableReference
               BuildableIdentifier = "primary"
               BlueprintIdentifier = "91E93ABF24E8962D00BF7289"
               BuildableName = "Tests.xctest"
               BlueprintName = "Tests"
               ReferencedContainer = "container:AudioUnitSDK.xcodeproj">
            </BuildableReference>
         </TestableReference>
      </Testables>
   </TestAction>
   <LaunchAction
      buildConfiguration = "Debug"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      enableAddressSanitizer = "YES"
      enableUBSanitizer = "YES"
      launchStyle = "0"
      useCustomWorkingDirectory = "NO"
      ignoresPersistentStateOnLaunch = "NO"
      debugDocumentVersioning = "YES"
      debugServiceExtension = "internal"
      allowLocationSimulation = "YES">
   </LaunchAction>
   <ProfileAction
      buildConfiguration = "Release"
      shouldUseLaunchSchemeArgsEnv = "YES"
      savedToolIdentifier = ""
      useCustomWorkingDirectory = "NO"
      debugDocumentVersioning = "YES">
      <MacroExpansion>
         <BuildableReference
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "91E93ABF24E8962D00BF7289"
            BuildableName = "Tests.xctest"
            BlueprintName = "Tests"
            ReferencedContainer = "container:AudioUnitSDK.xcodeproj">
         </BuildableReference>
      </MacroExpansion>
   </ProfileAction>
   <AnalyzeAction
      buildConfiguration = "Debug">
   </AnalyzeAction>
   <ArchiveAction
      buildConfiguration = "Release"
      revealArchiveInOrganizer = "YES">
   </ArchiveAction>
   <InstallAction
      buildConfiguration = "Release">
   </InstallAction>
</Scheme>


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

* The use of sexualized language or imagery and unwelcome sexual attention or
  advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
  address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies within all project spaces, and it also applies when
an individual is representing the project or its community in public spaces.
Examples of representing a project or community include using an official
project e-mail address, posting via an official social media account, or acting
as an appointed representative at an online or offline event. Representation of
a project may be further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the open source team at [opensource-conduct@group.apple.com](mailto:opensource-conduct@group.apple.com). All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4,
available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html)

================================================
FILE: CONTRIBUTING.md
================================================
# Contribution Guide

Thank you for your interest in contributing to the AudioUnit SDK! While this is an open-source project in spirit, it is intended to be updated infrequently with new version releases of the SDK. 
While you can open new pull requests WE ADVISE AGAINST IT and as such our response may be limited. Alternatively, you can open an issue which we will endeavour to address in the next official release.

## Submitting a Pull Request

By submitting a pull request, you represent that you have the right to license your contribution to Apple and the community, and agree by submitting the patch that your contributions are licensed under the [LICENSE](LICENSE.md).

*"I agree that all information entered is original and owned by me, and I hereby provide an irrevocable, royalty-free license to Apple to use, modify, copy, publish, prepare derivate works of, distribute (including under the Apache License Version 2.0), such information and all intellectual property therein in whole or part, in perpetuity and worldwide, without any attribution."*


## Code of Conduct

We ask that all community members read and observe our [Code of Conduct](CODE_OF_CONDUCT.md).


================================================
FILE: LICENSE.txt
================================================

                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: _clang-format
================================================
---
# BasedOnStyle:  LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: WebKit
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit:     100
CommentPragmas:  '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerBinding: false
DisableFormat:   false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:   [ foreach, Q_FOREACH, BOOST_FOREACH ]
IndentCaseLabels: false
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
QualifierAlignment: Left
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
StatementMacros: ['AUSDK_Catch']
TabWidth: 4
UseTab: ForContinuationAndIndentation
...


================================================
FILE: _clang-tidy
================================================
---
Checks:
'
*,
clang-diagnostic-*,
clang-analyzer-*,
-clang-diagnostic-pragma-once-outside-header,
-llvm-header-guard,
-fuchsia-default-arguments-calls,
-fuchsia-default-arguments-declarations,
-fuchsia-multiple-inheritance,
-fuchsia-overloaded-operator,
-fuchsia-trailing-return,
-hicpp-uppercase-literal-suffix,
-google-default-arguments,
-google-objc*,
-google-readability-todo,
-google-runtime-references,
-modernize-use-trailing-return-type,
-objc-property-declaration,
-readability-implicit-bool-cast,
-readability-uppercase-literal-suffix
'
WarningsAsErrors: ''
HeaderFilterRegex: ''
FormatStyle:     file
CheckOptions:    
  - key:             cppcoreguidelines-pro-type-member-init.IgnoreArrays
    value:           '1'
  - key: 			 misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
    value:           '1'
...


================================================
FILE: demos/EmptyPlugIns/EmptyPlugIns.cpp
================================================
/*!
    @file        EmptyPlugIns.cpp
    @copyright    © 2000-2025 Apple Inc. All rights reserved.
*/
#include <AudioUnitSDK/AUBase.h>
#include <AudioUnitSDK/AUEffectBase.h>
#include <AudioUnitSDK/MusicDeviceBase.h>

// -------------------------------------------------------------------------------------------------

class AUBase_Derived : public ausdk::AUBase {
	using Base = ausdk::AUBase;

public:
	explicit AUBase_Derived(AudioComponentInstance ci) : Base{ ci, 1, 1 } {}

	bool StreamFormatWritable(AudioUnitScope, AudioUnitElement) override { return true; }

	bool CanScheduleParameters() const noexcept AUSDK_RTSAFE override { return false; }
};

AUSDK_COMPONENT_ENTRY(ausdk::AUBaseFactory, AUBase_Derived)

// -------------------------------------------------------------------------------------------------

class AUEffectBase_Derived : public ausdk::AUEffectBase {
	using Base = ausdk::AUEffectBase;

public:
	explicit AUEffectBase_Derived(AudioComponentInstance ci) : Base{ ci, true } {}
};

AUSDK_COMPONENT_ENTRY(ausdk::AUBaseFactory, AUEffectBase_Derived)

// -------------------------------------------------------------------------------------------------

class MusicDeviceBase_Derived : public ausdk::MusicDeviceBase {
	using Base = ausdk::MusicDeviceBase;

public:
	explicit MusicDeviceBase_Derived(AudioComponentInstance ci) : Base{ ci, 0, 1 } {}

	bool StreamFormatWritable(AudioUnitScope, AudioUnitElement) override { return true; }

	bool CanScheduleParameters() const noexcept AUSDK_RTSAFE override { return false; }
};

AUSDK_COMPONENT_ENTRY(ausdk::AUMusicDeviceFactory, MusicDeviceBase_Derived)


================================================
FILE: demos/EmptyPlugIns/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>$(DEVELOPMENT_LANGUAGE)</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleVersion</key>
	<string>1</string>
	<key>NSPrincipalClass</key>
	<string></string>
</dict>
</plist>


================================================
FILE: hooks/install.sh
================================================
#! /bin/sh

git rev-parse 2> /dev/null
if [ $? != 0 ]; then
	echo "not currently working in a git repository, therefore aborting `basename $0`"
	exit 0
fi

set -e

SOURCE_DIR="`git rev-parse --show-toplevel`/hooks"
INSTALL_DIR=$(git rev-parse --git-path hooks)
FILENAME="pre-commit"

mkdir -p "${INSTALL_DIR}"
cp -f "${SOURCE_DIR}"/${FILENAME} "${INSTALL_DIR}"/${FILENAME}
chmod +x "${INSTALL_DIR}"/${FILENAME}


================================================
FILE: hooks/pre-commit
================================================
#! /bin/zsh
# This pre-commit hook uses clang-format to format the staged changes.

if ! git rev-parse --verify HEAD >/dev/null 2>&1
then
	echo "not currently working in a git repository or unable to verify HEAD, therefore skipping `basename $0`"
	exit 0
fi

set -e

REPO_ROOT=$(git rev-parse --show-toplevel)
DIFF_ARGS="--name-only --diff-filter=ACMRT"
git diff-index ${=DIFF_ARGS} --cached HEAD | grep -E "\.(h|hpp|c|cpp|m|mm)$" | while read -r FILE
do
	FILE_PATH="${REPO_ROOT}"/"${FILE}"
	if [[ `git diff ${=DIFF_ARGS} "${FILE_PATH}"` == $FILE ]]
	then
		echo -e "\xF0\x9F\x94\xA5 \xE2\x98\xA0 \xF0\x9F\x94\xA5 WARNING: creating a stash for file due to unstaged changes: ${FILE}"
		# format before stashing to avoid a merge conflict when applying the stash after commit
		xcrun clang-format -i "${FILE_PATH}"
		git stash push -k -q -m "pre-clang-format: ${FILE}" -- "${FILE_PATH}"
    fi

	xcrun clang-format -i "${FILE_PATH}"
	git add "${FILE_PATH}"
done


================================================
FILE: include/AudioUnitSDK/AUBase.h
================================================
/*!
	@file		AudioUnitSDK/AUBase.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/

#ifndef AudioUnitSDK_AUBase_h
#define AudioUnitSDK_AUBase_h

// module
// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUBuffer.h>
#include <AudioUnitSDK/AUInputElement.h>
#include <AudioUnitSDK/AUOutputElement.h>
#include <AudioUnitSDK/AUPlugInDispatch.h>
#include <AudioUnitSDK/AUScopeElement.h>
#include <AudioUnitSDK/AUThreadSafeList.h>
#include <AudioUnitSDK/AUUtility.h>
#include <AudioUnitSDK/ComponentBase.h>

// OS
#include <AudioToolbox/AudioComponent.h>
#include <AudioToolbox/AudioUnitProperties.h>

#if AUSDK_HAVE_MUSIC_DEVICE
#include <AudioToolbox/MusicDevice.h>
#endif

#if AUSDK_HAVE_MIDI2
#include <CoreMIDI/MIDIServices.h>
#endif

// std
#include <algorithm>
#include <array>
#include <memory>
#include <mutex>
#include <thread>
#include <vector>

// ________________________________________________________________________

namespace ausdk {

AUSDK_BEGIN_NO_RT_WARNINGS

/*!
	@class	AUBase
	@brief	Abstract base class for an Audio Unit implementation.
*/
class AUBase : public ComponentBase {
public:
	constexpr static double kAUDefaultSampleRate = 44100.0;
#if !TARGET_OS_WIN32
	constexpr static UInt32 kAUDefaultMaxFramesPerSlice = 1156;
	// this allows enough default frames for a 512 dest 44K and SRC from 96K
	// add a padding of 4 frames for any vector rounding
#else
	constexpr static UInt32 kAUDefaultMaxFramesPerSlice = 2048;
#endif

	AUBase(AudioComponentInstance inInstance, UInt32 numInputElements, UInt32 numOutputElements,
		UInt32 numGroupElements = 0);
	~AUBase() override;

	AUBase(const AUBase&) = delete;
	AUBase(AUBase&&) = delete;
	AUBase& operator=(const AUBase&) = delete;
	AUBase& operator=(AUBase&&) = delete;

	/// Called immediately after construction, when virtual methods work. Or, a subclass may call
	/// this in order to have access to elements in its constructor.
	void CreateElements();

	virtual void CreateExtendedElements() {}

#pragma mark -
#pragma mark AU dispatch
	// ________________________________________________________________________
	// Virtual methods (mostly) directly corresponding to the entry points.  Many of these
	// have useful implementations here and will not need overriding.

	/// Implements the entry point and ensures that Initialize is called exactly once from an
	/// uninitialized state.
	OSStatus DoInitialize();

	// Overrides to this method can assume that they will only be called exactly once
	// when transitioning from an uninitialized state.
	virtual OSStatus Initialize();

	[[nodiscard]] bool IsInitialized() const noexcept { return mInitialized; }
	[[nodiscard]] bool HasBegunInitializing() const noexcept { return mHasBegunInitializing; }

	/// Implements the entry point and ensures that Cleanup is called exactly once from an
	/// initialized state.
	void DoCleanup();

	// Overrides to this method can assume that they will only be called exactly once
	// when transitioning from an initialized state to an uninitialized state.
	virtual void Cleanup();

	/// Implements the entry point and ensures that critical audio Reset work always occurs
	OSStatus DoReset(AudioUnitScope inScope, AudioUnitElement inElement);

	/// Not realtime-safe by contract, but if a derived class wishes to implement a safe Reset,
	/// it can call BaseReset().
	virtual OSStatus Reset(AudioUnitScope inScope, AudioUnitElement inElement);

	OSStatus BaseReset(AudioUnitScope /*inScope*/, AudioUnitElement /*inElement*/) AUSDK_RTSAFE
	{
		return noErr;
	}

	// Note about GetPropertyInfo, GetProperty, SetProperty:
	// Certain properties are trapped out in these dispatch functions and handled with different
	// virtual methods.  (To discourage hacks and keep vtable size down, these are non-virtual)

	OSStatus DispatchGetPropertyInfo(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, UInt32& outDataSize, bool& outWritable);
	OSStatus DispatchGetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, void* outData);
	OSStatus DispatchSetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, const void* inData, UInt32 inDataSize);
	OSStatus DispatchRemovePropertyValue(
		AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement);

	virtual OSStatus GetPropertyInfo(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, UInt32& outDataSize, bool& outWritable);
	virtual OSStatus GetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, void* outData);
	virtual OSStatus SetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, const void* inData, UInt32 inDataSize);
	virtual OSStatus RemovePropertyValue(
		AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement);

	virtual OSStatus AddPropertyListener(
		AudioUnitPropertyID inID, AudioUnitPropertyListenerProc inProc, void* inProcRefCon);
	virtual OSStatus RemovePropertyListener(AudioUnitPropertyID inID,
		AudioUnitPropertyListenerProc inProc, void* inProcRefCon, bool refConSpecified);

	virtual OSStatus SetRenderNotification(AURenderCallback inProc, void* inRefCon);
	virtual OSStatus RemoveRenderNotification(AURenderCallback inProc, void* inRefCon);

	virtual OSStatus GetParameter(AudioUnitParameterID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, AudioUnitParameterValue& outValue) AUSDK_RTSAFE;

	virtual OSStatus SetParameter(AudioUnitParameterID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, AudioUnitParameterValue inValue,
		UInt32 inBufferOffsetInFrames) AUSDK_RTSAFE;

	// N.B. For internal use; asserts that the ParameterID is valid.
	AudioUnitParameterValue GetParameterRT(AudioUnitParameterID paramID) AUSDK_RTSAFE
	{
		return Globals()->GetParameterRT(paramID);
	}
	void SetParameterRT(AudioUnitParameterID paramID, AudioUnitParameterValue inValue) AUSDK_RTSAFE
	{
		Globals()->SetParameterRT(paramID, inValue);
	}

	[[nodiscard]] virtual bool CanScheduleParameters() const AUSDK_RTSAFE = 0;

	virtual OSStatus ScheduleParameter(
		const AudioUnitParameterEvent* inParameterEvent, UInt32 inNumEvents) AUSDK_RTSAFE;

	// The non-virtual DoRender/etc. methods are noexcept because they catch any exceptions.

	OSStatus DoRender(AudioUnitRenderActionFlags& ioActionFlags, const AudioTimeStamp& inTimeStamp,
		UInt32 inBusNumber, UInt32 inFramesToProcess,
		AudioBufferList& ioData) noexcept AUSDK_RTSAFE;

	OSStatus DoProcess(AudioUnitRenderActionFlags& ioActionFlags, const AudioTimeStamp& inTimeStamp,
		UInt32 inFramesToProcess, AudioBufferList& ioData) noexcept AUSDK_RTSAFE;

	OSStatus DoProcessMultiple(AudioUnitRenderActionFlags& ioActionFlags,
		const AudioTimeStamp& inTimeStamp, UInt32 inFramesToProcess,
		UInt32 inNumberInputBufferLists, const AudioBufferList** inInputBufferLists,
		UInt32 inNumberOutputBufferLists,
		AudioBufferList** ioOutputBufferLists) noexcept AUSDK_RTSAFE;

	virtual OSStatus ProcessBufferLists(AudioUnitRenderActionFlags& /*ioActionFlags*/,
		const AudioBufferList& /*inBuffer*/, AudioBufferList& /*outBuffer*/,
		UInt32 /*inFramesToProcess*/) AUSDK_RTSAFE
	{
		return kAudio_UnimplementedError;
	}

	virtual OSStatus ProcessMultipleBufferLists(AudioUnitRenderActionFlags& /*ioActionFlags*/,
		UInt32 /*inFramesToProcess*/, UInt32 /*inNumberInputBufferLists*/,
		const AudioBufferList** /*inInputBufferLists*/, UInt32 /*inNumberOutputBufferLists*/,
		AudioBufferList** /*ioOutputBufferLists*/) AUSDK_RTSAFE
	{
		return kAudio_UnimplementedError;
	}

	virtual OSStatus ComplexRender(AudioUnitRenderActionFlags& /*ioActionFlags*/,
		const AudioTimeStamp& /*inTimeStamp*/, UInt32 /*inOutputBusNumber*/,
		UInt32 /*inNumberOfPackets*/, UInt32* /*outNumberOfPackets*/,
		AudioStreamPacketDescription* /*outPacketDescriptions*/, AudioBufferList& /*ioData*/,
		void* /*outMetadata*/, UInt32* /*outMetadataByteSize*/) AUSDK_RTSAFE
	{
		return kAudio_UnimplementedError;
	}

	// Override this method if your AU processes multiple output busses completely independently --
	// you'll want to just call Render without the NeedsToRender check.
	// Otherwise, override Render().
	//
	// N.B. Implementations of this method can assume that the output's buffer list has already been
	// prepared and access it with GetOutput(inBusNumber)->GetBufferList() instead of
	// GetOutput(inBusNumber)->PrepareBuffer(nFrames) -- if PrepareBuffer is called, a
	// copy may occur after rendering.
	virtual OSStatus RenderBus(AudioUnitRenderActionFlags& ioActionFlags,
		const AudioTimeStamp& inTimeStamp, UInt32 /*inBusNumber*/,
		UInt32 inNumberFrames) AUSDK_RTSAFE
	{
		if (NeedsToRender(inTimeStamp)) {
			return Render(ioActionFlags, inTimeStamp, inNumberFrames);
		}
		return noErr; // was presumably already rendered via another bus
	}

	// N.B. For a unit with only one output bus, it can assume in its implementation of this
	// method that the output's buffer list has already been prepared and access it with
	// GetOutput(0)->GetBufferList() instead of GetOutput(0)->PrepareBuffer(nFrames)
	//  -- if PrepareBuffer is called, a copy may occur after rendering.
	virtual OSStatus Render(AudioUnitRenderActionFlags& /*ioActionFlags*/,
		const AudioTimeStamp& /*inTimeStamp*/, UInt32 /*inNumberFrames*/) AUSDK_RTSAFE
	{
		return noErr;
	}


#pragma mark -
#pragma mark Property Dispatch

	// ________________________________________________________________________
	// These are called from DispatchGetProperty/DispatchGetPropertyInfo/DispatchSetProperty

	virtual bool BusCountWritable(AudioUnitScope /*inScope*/) { return false; }
	virtual OSStatus SetBusCount(AudioUnitScope inScope, UInt32 inCount);
	virtual OSStatus SetConnection(const AudioUnitConnection& inConnection);
	virtual OSStatus SetInputCallback(
		UInt32 inPropertyID, AudioUnitElement inElement, AURenderCallback inProc, void* inRefCon);

	virtual OSStatus GetParameterList(
		AudioUnitScope inScope, AudioUnitParameterID* outParameterList, UInt32& outNumParameters);
	// outParameterList may be a null pointer
	virtual OSStatus GetParameterInfo(AudioUnitScope inScope, AudioUnitParameterID inParameterID,
		AudioUnitParameterInfo& outParameterInfo);

	virtual OSStatus GetParameterHistoryInfo(AudioUnitScope inScope,
		AudioUnitParameterID inParameterID, Float32& outUpdatesPerSecond,
		Float32& outHistoryDurationInSeconds);
	virtual OSStatus SaveState(CFPropertyListRef* outData);
	virtual void SaveExtendedScopes(CFMutableDataRef /*outData*/) {}
	virtual OSStatus RestoreState(CFPropertyListRef plist);
	virtual OSStatus GetParameterValueStrings(
		AudioUnitScope inScope, AudioUnitParameterID inParameterID, CFArrayRef* outStrings);
	virtual OSStatus CopyClumpName(AudioUnitScope inScope, UInt32 inClumpID,
		UInt32 inDesiredNameLength, CFStringRef* outClumpName);
	virtual OSStatus GetPresets(CFArrayRef* outData) const;

	/// Set the default preset for the unit. The number of the preset must be >= 0 and the name
	/// should be valid, or the preset will be rejected.
	bool SetAFactoryPresetAsCurrent(const AUPreset& inPreset);

	// Called when the host sets a new, valid preset.
	// If this is a valid preset, then the subclass sets its state to that preset
	// and returns noErr.
	// If not a valid preset, return an error, and the pre-existing preset is restored.
	virtual OSStatus NewFactoryPresetSet(const AUPreset& inNewFactoryPreset);
	virtual OSStatus NewCustomPresetSet(const AUPreset& inNewCustomPreset);
#if AUSDK_HAVE_UI
	virtual CFURLRef CopyIconLocation();
#endif

	// default is no latency, and unimplemented tail time
	virtual Float64 GetLatency() AUSDK_RTSAFE { return 0.0; }
	virtual Float64 GetTailTime() AUSDK_RTSAFE { return 0.0; }
	virtual bool SupportsTail() AUSDK_RTSAFE { return false; }

	// Stream formats: scope will always be input or output
	bool IsStreamFormatWritable(AudioUnitScope scope, AudioUnitElement element);

	virtual bool StreamFormatWritable(AudioUnitScope scope, AudioUnitElement element) = 0;

	// pass in a pointer to get the struct, and num channel infos
	// you can pass in NULL to just get the number
	// a return value of 0 (the default in AUBase) means the property is not supported...
	virtual UInt32 SupportedNumChannels(const AUChannelInfo** outInfo);

	/// Will only be called after StreamFormatWritable has succeeded. Default implementation
	/// requires non-interleaved native-endian 32-bit float, any sample rate, any number of
	/// channels; override when other formats are supported.  A subclass's override can choose to
	/// always return true and trap invalid formats in ChangeStreamFormat.
	virtual bool ValidFormat(AudioUnitScope inScope, AudioUnitElement inElement,
		const AudioStreamBasicDescription& inNewFormat);

	virtual AudioStreamBasicDescription GetStreamFormat(
		AudioUnitScope inScope, AudioUnitElement inElement) AUSDK_RTSAFE_LOOSE;

	// Will only be called after StreamFormatWritable
	// and ValidFormat have succeeded.
	virtual OSStatus ChangeStreamFormat(AudioUnitScope inScope, AudioUnitElement inElement,
		const AudioStreamBasicDescription& inPrevFormat,
		const AudioStreamBasicDescription& inNewFormat);

	// ________________________________________________________________________
	// Methods useful for subclasses
	AUScope& GetScope(AudioUnitScope inScope)
	{
		if (inScope >= kNumScopes) {
			AUScope* const scope = GetScopeExtended(inScope);

			ThrowQuietIf(scope == nullptr, kAudioUnitErr_InvalidScope);
			return *scope;
		}
		return mScopes[inScope]; // NOLINT
	}

	virtual AUScope* GetScopeExtended(AudioUnitScope /*inScope*/) AUSDK_RTSAFE { return nullptr; }

	AUScope& GlobalScope() { return mScopes[kAudioUnitScope_Global]; }
	AUScope& Inputs() { return mScopes[kAudioUnitScope_Input]; }
	AUScope& Outputs() { return mScopes[kAudioUnitScope_Output]; }
	AUScope& Groups() { return mScopes[kAudioUnitScope_Group]; }

	AUElement* Globals() AUSDK_RTSAFE
	{
		auto maybeElem = mScopes[kAudioUnitScope_Global].GetElementOrError(0);
		AUSDK_Assert(maybeElem);
		return maybeElem.get();
	}

	void SetNumberOfElements(AudioUnitScope inScope, UInt32 numElements);
	virtual std::unique_ptr<AUElement> CreateElement(
		AudioUnitScope scope, AudioUnitElement element);


	AUElement* GetElement(AudioUnitScope inScope, AudioUnitElement inElement)
	{
		return GetScope(inScope).GetElement(inElement);
	}

	AUSDK_DEPRECATED("Use IOElement()")
	AUIOElement* GetIOElement(AudioUnitScope inScope, AudioUnitElement inElement)
	{
		return &IOElement(inScope, inElement);
	}

	AUIOElement& IOElement(AudioUnitScope inScope, AudioUnitElement inElement)
	{
		return *GetScope(inScope).GetIOElement(inElement);
	}

	AUSDK_DEPRECATED("Use Element()")
	AUElement* SafeGetElement(AudioUnitScope inScope, AudioUnitElement inElement)
	{
		return &Element(inScope, inElement);
	}

	AUElement& Element(AudioUnitScope inScope, AudioUnitElement inElement)
	{
		return *GetScope(inScope).SafeGetElement(inElement);
	}

	AUSDK_DEPRECATED("Use Input()")
	AUInputElement* GetInput(AudioUnitElement inElement) { return &Input(inElement); }
	AUInputElement& Input(AudioUnitElement inElement)
	{
		return static_cast<AUInputElement&>(*Inputs().SafeGetElement(inElement)); // NOLINT downcast
	}

	AUSDK_DEPRECATED("Use Output()")
	AUOutputElement* GetOutput(AudioUnitElement inElement) { return &Output(inElement); }
	AUOutputElement& Output(AudioUnitElement inElement)
	{
		return static_cast<AUOutputElement&>( // NOLINT downcast
			*Outputs().SafeGetElement(inElement));
	}

	AUSDK_DEPRECATED("Use Group()")
	AUElement* GetGroup(AudioUnitElement inElement) { return &Group(inElement); }
	AUElement& Group(AudioUnitElement inElement) { return *Groups().SafeGetElement(inElement); }

	ExpectedPtr<AUScope> GetScopeOrError(AudioUnitScope inScope) AUSDK_RTSAFE
	{
		if (inScope >= kNumScopes) {
			if (auto* scope = GetScopeExtended(inScope)) {
				return *scope;
			}
			return Unexpected(kAudioUnitErr_InvalidScope);
		}
		return mScopes[inScope]; // NOLINT
	}

	ExpectedPtr<AUIOElement> GetIOElementOrError(
		AudioUnitScope inScope, AudioUnitElement inElement) AUSDK_RTSAFE
	{
		AUScope& scope = AUSDK_UnwrapOrReturnUnexpected(GetScopeOrError(inScope));
		return scope.GetIOElementOrError(inElement);
	}

	ExpectedPtr<AUElement> GetElementOrError(
		AudioUnitScope inScope, AudioUnitElement inElement) AUSDK_RTSAFE
	{
		AUScope& scope = AUSDK_UnwrapOrReturnUnexpected(GetScopeOrError(inScope));
		return scope.GetElementOrError(inElement);
	}

	template <typename E = AUInputElement>
	ExpectedPtr<E> GetInputOrError(AudioUnitElement inElement) AUSDK_RTSAFE
	{
		return Inputs().GetElementOrError<E>(inElement);
	}

	template <typename E = AUOutputElement>
	ExpectedPtr<E> GetOutputOrError(AudioUnitElement inElement) AUSDK_RTSAFE
	{
		return Outputs().GetElementOrError<E>(inElement);
	}

	// Since almost every AudioUnit has at least one output element, this method is useful for
	// obtaining output 0 without requiring error checking/handling.
	template <typename E = AUOutputElement>
	E& GetOutput0() AUSDK_RTSAFE
	{
		auto maybeElem = Outputs().GetElementOrError<E>(0);
		AUSDK_Assert(maybeElem);
		return *maybeElem;
	}

	// Most AudioUnits have at least one input element, so this method is useful for
	// obtaining input 0 without requiring error checking/handling.
	template <typename E = AUInputElement>
	E& GetInput0() AUSDK_RTSAFE
	{
		auto maybeElem = Inputs().GetElementOrError<E>(0);
		AUSDK_Assert(maybeElem);
		return *maybeElem;
	}

	ExpectedPtr<AUElement> GetGroupOrError(AudioUnitElement inElement) AUSDK_RTSAFE
	{
		return Groups().GetElementOrError(inElement);
	}

	OSStatus PullInput(UInt32 inBusNumber, AudioUnitRenderActionFlags& ioActionFlags,
		const AudioTimeStamp& inTimeStamp, UInt32 inNumberFrames) AUSDK_RTSAFE
	{
		AUInputElement& input = AUSDK_UnwrapOrReturnError(GetInputOrError(inBusNumber));
		return input.PullInput(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames);
	}

	[[nodiscard]] UInt32 GetMaxFramesPerSlice() const noexcept { return mMaxFramesPerSlice; }

	[[nodiscard]] bool UsesFixedBlockSize() const noexcept { return mUsesFixedBlockSize; }

	void SetUsesFixedBlockSize(bool inUsesFixedBlockSize) noexcept
	{
		mUsesFixedBlockSize = inUsesFixedBlockSize;
	}

	[[nodiscard]] virtual bool InRenderThread() const AUSDK_RTSAFE
	{
		// Marked unsafe because the library function isn't annotated.
		return AUSDK_RT_UNSAFE(std::this_thread::get_id()) == mRenderThreadID;
	}

	/// Says whether an input is connected or has a callback.
	/// Not realtime-safe; use bus->IsActive().
	bool HasInput(AudioUnitElement inElement)
	{
		auto* const in =
			static_cast<AUInputElement*>(Inputs().GetElement(inElement)); // NOLINT downcast
		return in != nullptr && in->IsActive();
	}

	virtual void PropertyChanged(
		AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement);

	// These calls can be used to call a Host's Callbacks. The method returns -1 if the host
	// hasn't supplied the callback. Any other result is returned by the host.
	// As in the API contract, for a parameter's value, you specify a pointer
	// to that data type. Specify NULL for a parameter that you are not interested
	// as this can save work in the host.
	OSStatus CallHostBeatAndTempo(Float64* outCurrentBeat, Float64* outCurrentTempo) const
	{
		return (mHostCallbackInfo.beatAndTempoProc != nullptr
					? (*mHostCallbackInfo.beatAndTempoProc)(
						  mHostCallbackInfo.hostUserData, outCurrentBeat, outCurrentTempo)
					: -1);
	}

	OSStatus CallHostMusicalTimeLocation(UInt32* outDeltaSampleOffsetToNextBeat,
		Float32* outTimeSig_Numerator, UInt32* outTimeSig_Denominator,
		Float64* outCurrentMeasureDownBeat) const
	{
		return (mHostCallbackInfo.musicalTimeLocationProc != nullptr
					? (*mHostCallbackInfo.musicalTimeLocationProc)(mHostCallbackInfo.hostUserData,
						  outDeltaSampleOffsetToNextBeat, outTimeSig_Numerator,
						  outTimeSig_Denominator, outCurrentMeasureDownBeat)
					: -1);
	}

	OSStatus CallHostTransportState(Boolean* outIsPlaying, Boolean* outTransportStateChanged,
		Float64* outCurrentSampleInTimeLine, Boolean* outIsCycling, Float64* outCycleStartBeat,
		Float64* outCycleEndBeat) const
	{
		return (mHostCallbackInfo.transportStateProc != nullptr
					? (*mHostCallbackInfo.transportStateProc)(mHostCallbackInfo.hostUserData,
						  outIsPlaying, outTransportStateChanged, outCurrentSampleInTimeLine,
						  outIsCycling, outCycleStartBeat, outCycleEndBeat)
					: -1);
	}

	[[nodiscard]] const char* GetLoggingString() const noexcept;

	AUMutex* GetMutex() noexcept { return mAUMutex; }
	// The caller of SetMutex is responsible for the managing the lifetime of the
	// mutex object and, if deleted before the AUBase instance, is responsible
	// for calling SetMutex(nullptr)
	void SetMutex(AUMutex* mutex) noexcept { mAUMutex = mutex; }

#pragma mark -
#pragma mark AU Output Base Dispatch
	// ________________________________________________________________________
	// ________________________________________________________________________
	// ________________________________________________________________________
	// output unit methods
	virtual OSStatus Start() { return kAudio_UnimplementedError; }

	virtual OSStatus Stop() { return kAudio_UnimplementedError; }

#pragma mark -
#pragma mark AU Music Base Dispatch
	// ________________________________________________________________________
	// ________________________________________________________________________
	// ________________________________________________________________________
	// music device/music effect methods

	virtual OSStatus MIDIEvent(UInt32 /*inStatus*/, UInt32 /*inData1*/, UInt32 /*inData2*/,
		UInt32 /*inOffsetSampleFrame*/) AUSDK_RTSAFE
	{
		return kAudio_UnimplementedError;
	}

	virtual OSStatus SysEx(const UInt8* /*inData*/, UInt32 /*inLength*/) AUSDK_RTSAFE
	{
		return kAudio_UnimplementedError;
	}

#if AUSDK_HAVE_MIDI2
	virtual OSStatus MIDIEventList(
		UInt32 /*inOffsetSampleFrame*/, const MIDIEventList* /*eventList*/) AUSDK_RTSAFE
	{
		return kAudio_UnimplementedError;
	}
#endif

#if AUSDK_HAVE_MUSIC_DEVICE
	virtual OSStatus StartNote(MusicDeviceInstrumentID /*inInstrument*/,
		MusicDeviceGroupID /*inGroupID*/, NoteInstanceID* /*outNoteInstanceID*/,
		UInt32 /*inOffsetSampleFrame*/, const MusicDeviceNoteParams& /*inParams*/) AUSDK_RTSAFE
	{
		return kAudio_UnimplementedError;
	}

	virtual OSStatus StopNote(MusicDeviceGroupID /*inGroupID*/, NoteInstanceID /*inNoteInstanceID*/,
		UInt32 /*inOffsetSampleFrame*/) AUSDK_RTSAFE
	{
		return kAudio_UnimplementedError;
	}

	/// Obsolete
	static OSStatus PrepareInstrument(MusicDeviceInstrumentID /*inInstrument*/)
	{
		return kAudio_UnimplementedError;
	}

	/// Obsolete
	static OSStatus ReleaseInstrument(MusicDeviceInstrumentID /*inInstrument*/)
	{
		return kAudio_UnimplementedError;
	}
#endif // AUSDK_HAVE_MUSIC_DEVICE

	// ________________________________________________________________________
	// ________________________________________________________________________
	// ________________________________________________________________________

protected:
#pragma mark -
#pragma mark Implementation methods
	void PostConstructorInternal() final;
	void PreDestructorInternal() final;

	/// needs to be called when mMaxFramesPerSlice changes
	virtual void ReallocateBuffers();

	virtual void DeallocateIOBuffers();

	static void FillInParameterName(
		AudioUnitParameterInfo& ioInfo, CFStringRef inName, bool inShouldRelease)
	{
		ioInfo.cfNameString = inName;
		ioInfo.flags |= kAudioUnitParameterFlag_HasCFNameString;
		if (inShouldRelease) {
			ioInfo.flags |= kAudioUnitParameterFlag_CFNameRelease;
		}
		CFStringGetCString(
			inName, std::data(ioInfo.name), std::ssize(ioInfo.name), kCFStringEncodingUTF8);
	}

	static void HasClump(AudioUnitParameterInfo& ioInfo, UInt32 inClumpID) noexcept
	{
		ioInfo.clumpID = inClumpID;
		ioInfo.flags |= kAudioUnitParameterFlag_HasClump;
	}

	virtual void SetMaxFramesPerSlice(UInt32 nFrames);

	[[nodiscard]] virtual OSStatus CanSetMaxFrames() const;

	[[nodiscard]] bool WantsRenderThreadID() const noexcept { return mWantsRenderThreadID; }

	void SetWantsRenderThreadID(bool inFlag);

	OSStatus SetRenderError(OSStatus inErr) AUSDK_RTSAFE
	{
		if (inErr != noErr && mLastRenderError == 0) {
			mLastRenderError = inErr;
			AUSDK_RT_UNSAFE_BEGIN("FIXME: PropertyChanged is unsafe")
			PropertyChanged(kAudioUnitProperty_LastRenderError, kAudioUnitScope_Global, 0);
			AUSDK_RT_UNSAFE_END
		}
		return inErr;
	}

	struct PropertyListener {
		AudioUnitPropertyID propertyID{ 0 };
		AudioUnitPropertyListenerProc listenerProc{ nullptr };
		void* listenerRefCon{ nullptr };
	};
	using PropertyListeners = std::vector<PropertyListener>;

	[[nodiscard]] const PropertyListeners& GetPropertyListeners() const noexcept
	{
		return mPropertyListeners;
	}

	HostCallbackInfo& GetHostCallbackInfo() noexcept { return mHostCallbackInfo; }

private:
	// shared between Render and RenderSlice, inlined to minimize function call overhead
	OSStatus DoRenderBus(AudioUnitRenderActionFlags& ioActionFlags,
		const AudioTimeStamp& inTimeStamp, UInt32 inBusNumber, AUOutputElement& theOutput,
		UInt32 inNumberFrames, AudioBufferList& ioData) AUSDK_RTSAFE
	{
		ExpectedPtr<AudioBufferList> maybeBuf;
		if (ioData.mBuffers[0].mData == nullptr ||
			(theOutput.WillAllocateBuffer() && Outputs().GetNumberOfElements() > 1)) {
			// will render into cache buffer
			maybeBuf = theOutput.PrepareBufferOrError(inNumberFrames);
		} else {
			// will render into caller's buffer
			maybeBuf = theOutput.SetBufferListOrError(ioData);
		}
		if (!maybeBuf) {
			return maybeBuf.error();
		}

		AUSDK_Require_noerr(RenderBus(ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames));
		Expected<void> copyResult;
		if (ioData.mBuffers[0].mData == nullptr) {
			copyResult = theOutput.CopyBufferListToOrError(ioData);
		} else {
			copyResult = theOutput.CopyBufferContentsToOrError(ioData);
			theOutput.InvalidateBufferList();
		}
		if (!copyResult) {
			return copyResult.error();
		}
		return noErr;
	}

	bool HasIcon();

	[[nodiscard]] std::string CreateLoggingString() const;

protected:
	//. Returns size. outLayoutPtr may be null if querying only for size.
	virtual UInt32 GetAudioChannelLayout(AudioUnitScope scope, AudioUnitElement element,
		AudioChannelLayout* outLayoutPtr, bool& outWritable);

	/// Layout is non-null.
	virtual OSStatus SetAudioChannelLayout(
		AudioUnitScope scope, AudioUnitElement element, const AudioChannelLayout* inLayout);

	virtual OSStatus RemoveAudioChannelLayout(AudioUnitScope scope, AudioUnitElement element);

	virtual std::vector<AudioChannelLayoutTag> GetChannelLayoutTags(
		AudioUnitScope scope, AudioUnitElement element);

	bool NeedsToRender(const AudioTimeStamp& inTimeStamp)
	{
		const bool needsToRender = (inTimeStamp.mSampleTime != mCurrentRenderTime.mSampleTime);
		if (needsToRender) { // only copy this if we need to render
			mCurrentRenderTime = inTimeStamp;
		}
		return needsToRender;
	}

	// Scheduled parameter implementation:

	using ParameterEventList = std::vector<AudioUnitParameterEvent>;

	// Usually, you won't override this method.  You only need to call this if your DSP code
	// is prepared to handle scheduled immediate and ramped parameter changes.
	// Before calling this method, it is assumed you have already called PullInput() on the input
	// busses for which the DSP code depends.  ProcessForScheduledParams() will call (potentially
	// repeatedly) virtual method ProcessScheduledSlice() to perform the actual DSP for a given
	// sub-division of the buffer.  The job of ProcessForScheduledParams() is to sub-divide the
	// buffer into smaller pieces according to the scheduled times found in the ParameterEventList
	// (usually coming directly from a previous call to ScheduleParameter() ), setting the
	// appropriate immediate or ramped parameter values for the corresponding scopes and elements,
	// then calling ProcessScheduledSlice() to do the actual DSP for each of these divisions.
	virtual OSStatus ProcessForScheduledParams(
		ParameterEventList& inParamList, UInt32 inFramesToProcess, void* inUserData) AUSDK_RTSAFE;

	//	This method is called (potentially repeatedly) by ProcessForScheduledParams()
	//	in order to perform the actual DSP required for this portion of the entire buffer
	//	being processed.  The entire buffer can be divided up into smaller "slices"
	//	according to the timestamps on the scheduled parameters...
	//
	//	sub-classes wishing to handle scheduled parameter changes should override this method
	//  in order to do the appropriate DSP.  AUEffectBase already overrides this for standard
	//	effect AudioUnits.
	virtual OSStatus ProcessScheduledSlice(void* /*inUserData*/, UInt32 /*inStartFrameInBuffer*/,
		UInt32 /*inSliceFramesToProcess*/, UInt32 /*inTotalBufferFrames*/) AUSDK_RTSAFE
	{
		// default implementation does nothing.
		return noErr;
	}

	[[nodiscard]] const AudioTimeStamp& CurrentRenderTime() const noexcept
	{
		return mCurrentRenderTime;
	}
	void ResetRenderTime();

	// ________________________________________________________________________
	//	Private data members to discourage hacking in subclasses
private:
	struct RenderCallback {
		RenderCallback() : RenderCallback(nullptr, nullptr) {}

		RenderCallback(AURenderCallback proc, void* ref)
			: mRenderNotify(proc), mRenderNotifyRefCon(ref)
		{
		}

		AURenderCallback mRenderNotify{ nullptr };
		void* mRenderNotifyRefCon{ nullptr };

		bool operator==(const RenderCallback& other) const
		{
			return this->mRenderNotify == other.mRenderNotify &&
				   this->mRenderNotifyRefCon == other.mRenderNotifyRefCon;
		}
	};

protected:
	static constexpr AudioUnitScope kNumScopes = 4;

	ParameterEventList& GetParamEventList() noexcept { return mParamEventList; }
	void SetBuffersAllocated(bool b) noexcept { mBuffersAllocated = b; }

	[[nodiscard]] CFStringRef GetContextName() const noexcept { return *mContextName; }
	void SetContextName(CFStringRef str) noexcept { mContextName = str; }

	[[nodiscard]] CFStringRef GetNickName() const noexcept { return *mNickName; }

private:
	bool mElementsCreated{ false };
	bool mInitialized{ false };
	bool mHasBegunInitializing{ false };
	const UInt32 mInitNumInputEls;
	const UInt32 mInitNumOutputEls;
	const UInt32 mInitNumGroupEls;
	std::array<AUScope, kNumScopes> mScopes;
	AUThreadSafeList<RenderCallback> mRenderCallbacks;
	bool mRenderCallbacksTouched{ false };
	std::thread::id mRenderThreadID{};
	bool mWantsRenderThreadID{ false };
	AudioTimeStamp mCurrentRenderTime{};
	UInt32 mMaxFramesPerSlice{ 0 };
	OSStatus mLastRenderError{ noErr };
#ifndef AUSDK_NO_LOGGING
	const double mHostTimeFrequency{
		HostTime::Frequency()
	}; // cache because there is calculation cost
	uint64_t mLastTimeMessagePrinted{ 0 };
#endif
	AUPreset mCurrentPreset{ -1, nullptr };
	bool mUsesFixedBlockSize{ false };

	ParameterEventList mParamEventList;
	PropertyListeners mPropertyListeners;
	bool mBuffersAllocated{ false };
	const std::string mLogString;
	Owned<CFStringRef> mNickName;

	/*! @var mAUMutex
		If non-null, guards all non-realtime entry points into the AudioUnit. Most AudioUnits
		do not need to use this. It's useful for the case of an AU which must synchronize
		an external source of callbacks against entry from the host.
	*/
	AUMutex* mAUMutex{ nullptr };
	HostCallbackInfo mHostCallbackInfo{};
	Owned<CFStringRef> mContextName;
};

AUSDK_END_NO_RT_WARNINGS

} // namespace ausdk

#endif // AudioUnitSDK_AUBase_h


================================================
FILE: include/AudioUnitSDK/AUBuffer.h
================================================
/*!
	@file		AudioUnitSDK/AUBuffer.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUBuffer_h
#define AudioUnitSDK_AUBuffer_h

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUUtility.h>

#include <cstddef>
#include <cstring>
#include <optional>

namespace ausdk {

AUSDK_BEGIN_NO_RT_WARNINGS

/// 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


	AllocatedBuffer(UInt32 maxBuffers, UInt32 maxBytesPerBuffer, UInt32 headerSize,
		UInt32 bufferDataSize, void* bufferData)
		: mMaximumNumberBuffers{ maxBuffers }, mMaximumBytesPerBuffer{ maxBytesPerBuffer },
		  mHeaderSize{ headerSize }, mBufferDataSize{ bufferDataSize }, mBufferData{ bufferData }
	{
	}

	AudioBufferList& Prepare(UInt32 channelsPerBuffer, UInt32 bytesPerBuffer);

	ExpectedPtr<AudioBufferList> PrepareOrError(
		UInt32 channelsPerBuffer, UInt32 bytesPerBuffer) AUSDK_RTSAFE;

	AudioBufferList& PrepareNull(UInt32 channelsPerBuffer, UInt32 bytesPerBuffer);

	ExpectedPtr<AudioBufferList> PrepareNullOrError(
		UInt32 channelsPerBuffer, UInt32 bytesPerBuffer) AUSDK_RTSAFE;
};

/*!
	@class	BufferAllocator
	@brief	Class which allocates memory for internal audio buffers.

	To customize, create a subclass and replace the BufferAllocator::instance() implementation.
*/
class BufferAllocator {
public:
	/// Obtain the global instance, creating it if necessary.
	static 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)
	{
		const auto maybeABL = PrepareBufferOrError(format, nFrames);
		ThrowExceptionIfUnexpected(maybeABL);
		return *maybeABL;
	}

	ExpectedPtr<AudioBufferList> PrepareBufferOrError(
		const AudioStreamBasicDescription& format, UInt32 nFrames) AUSDK_RTSAFE;

	AudioBufferList& PrepareNullBuffer(const AudioStreamBasicDescription& format, UInt32 nFrames)
	{
		const auto maybeABL = PrepareNullBufferOrError(format, nFrames);
		ThrowExceptionIfUnexpected(maybeABL);
		return *maybeABL;
	}

	ExpectedPtr<AudioBufferList> PrepareNullBufferOrError(
		const AudioStreamBasicDescription& format, UInt32 nFrames) AUSDK_RTSAFE;

	AudioBufferList& SetBufferList(const AudioBufferList& abl)
	{
		const auto maybeABL = SetBufferListOrError(abl);
		ThrowExceptionIfUnexpected(maybeABL);
		return *maybeABL;
	}

	ExpectedPtr<AudioBufferList> SetBufferListOrError(const AudioBufferList& abl) AUSDK_RTSAFE
	{
		if (mAllocatedStreams < abl.mNumberBuffers) {
			return Unexpected(-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)
	{
		const auto res = SetBufferOrError(index, ab);
		ThrowExceptionIfUnexpected(res);
	}

	Expected<void> SetBufferOrError(UInt32 index, const AudioBuffer& ab) AUSDK_RTSAFE
	{
		auto& myabl = mBuffers->mAudioBufferList;
		if (mPtrState == EPtrState::Invalid || index >= myabl.mNumberBuffers) {
			return Unexpected(-1);
		}
		mPtrState = EPtrState::ToExternalMemory;
		myabl.mBuffers[index] = ab; // NOLINT
		return {};
	}

	void InvalidateBufferList() noexcept { mPtrState = EPtrState::Invalid; }

	[[nodiscard]] AudioBufferList& GetBufferList() const
	{
		const auto maybeABL = GetBufferListOrError();
		ThrowExceptionIfUnexpected(maybeABL);
		return *maybeABL;
	}

	[[nodiscard]] ExpectedPtr<AudioBufferList> GetBufferListOrError() const AUSDK_RTSAFE
	{
		if (mPtrState == EPtrState::Invalid) {
			return Unexpected(-1);
		}
		return mBuffers->mAudioBufferList;
	}

	void CopyBufferListTo(AudioBufferList& abl) const
	{
		const auto res = CopyBufferListToOrError(abl);
		ThrowExceptionIfUnexpected(res);
	}

	Expected<void> CopyBufferListToOrError(AudioBufferList& abl) const AUSDK_RTSAFE
	{
		if (mPtrState == EPtrState::Invalid) {
			return Unexpected(-1);
		}
		memcpy(&abl, &mBuffers->mAudioBufferList,
			static_cast<size_t>(
				reinterpret_cast<std::byte*>(&abl.mBuffers[abl.mNumberBuffers]) - // NOLINT
				reinterpret_cast<std::byte*>(&abl)));                             // NOLINT
		return {};
	}

	void CopyBufferContentsTo(AudioBufferList& destabl) const
	{
		const auto res = CopyBufferContentsToOrError(destabl);
		ThrowExceptionIfUnexpected(res);
	}

	Expected<void> CopyBufferContentsToOrError(AudioBufferList& destabl) const AUSDK_RTSAFE
	{
		if (mPtrState == EPtrState::Invalid) {
			return Unexpected(-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
			}

			const auto srcByteSize = srcbuf->mDataByteSize;
			const void* srcData = srcbuf->mData;
			void* dstData = destbuf->mData;

			if (srcByteSize > 0 && (srcData == nullptr || dstData == nullptr)) {
				return Unexpected(-1);
			}

			if (dstData != srcData) {
				memmove(dstData, srcData, srcByteSize);
			}
			destbuf->mDataByteSize = srcByteSize;
		}
		return {};
	}

	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

AUSDK_END_NO_RT_WARNINGS

#endif // AudioUnitSDK_AUBuffer_h


================================================
FILE: include/AudioUnitSDK/AUConfig.h
================================================
/*!
	@file		AudioUnitSDK/AUConfig.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/

#ifndef AudioUnitSDK_AUConfig_h
#define AudioUnitSDK_AUConfig_h

#include <TargetConditionals.h>

#if defined(__has_include) && __has_include(<AvailabilityVersions.h>)
#include <AvailabilityVersions.h>
#endif

#if defined(__has_include) && __has_include(<MacTypes.h>)
#include <MacTypes.h>
#else
enum { noErr = 0 };
#endif

#if defined(__has_include) && __has_include(<CoreAudioTypes/CoreAudioTypes.h>)
#include <CoreAudioTypes/CoreAudioTypes.h>
#else
#include <CoreAudio/CoreAudioTypes.h>
#endif

// This optional prefix header allows external customization of the build.
#if defined(__has_include) && __has_include("AudioUnitSDKPrefix.h")
#include "AudioUnitSDKPrefix.h"
#endif

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark Version

#define AUSDK_VERSION_MAJOR 1
#define AUSDK_VERSION_MINOR 4
#define AUSDK_VERSION_PATCH 0

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark Deprecations

#ifdef AUSDK_NO_DEPRECATIONS
#define AUSDK_DEPRECATED(msg)
#else
#define AUSDK_DEPRECATED(msg) [[deprecated(msg)]] // NOLINT macro
#endif                                            // AUSDK_NO_DEPRECATIONS

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark UI

#if !defined(AUSDK_HAVE_UI)
#define AUSDK_HAVE_UI 1
#endif // !defined(AUSDK_HAVE_UI)

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark Mach

#if !defined(AUSDK_HAVE_MACH_TIME)
#if defined(__has_include) && __has_include(<mach/mach_time.h>)
#define AUSDK_HAVE_MACH_TIME 1
#else
#define AUSDK_HAVE_MACH_TIME 0
#endif
#endif // !defined(AUSDK_HAVE_MACH_TIME)

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark MIDI

#if !defined(AUSDK_HAVE_MIDI)
#if defined(__has_include) && __has_include(<CoreMIDI/CoreMIDI.h>)
#define AUSDK_HAVE_MIDI 1
#else
#define AUSDK_HAVE_MIDI 0
#endif
#endif // !defined(AUSDK_HAVE_MIDI)

#if !defined(AUSDK_HAVE_MIDI2)
#if defined(__MAC_12_0) || defined(__IPHONE_15_0)
#define AUSDK_HAVE_MIDI2 (AUSDK_HAVE_MIDI)
#else
#define AUSDK_HAVE_MIDI2 0
#endif
#endif // !defined(AUSDK_HAVE_MIDI2)

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark MusicDevice

#if !defined(AUSDK_HAVE_MUSIC_DEVICE)
#if defined(__has_include) && __has_include(<AudioToolbox/MusicDevice.h>)
#define AUSDK_HAVE_MUSIC_DEVICE 1
#else
#define AUSDK_HAVE_MUSIC_DEVICE 0
#endif
#endif // !defined(AUSDK_HAVE_MUSIC_DEVICE)

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark AudioOutputUnit

#if !defined(AUSDK_HAVE_IO_UNITS)
#if defined(__has_include) && __has_include(<AudioToolbox/AudioOutputUnit.h>)
#define AUSDK_HAVE_IO_UNITS 1
#else
#define AUSDK_HAVE_IO_UNITS 0
#endif
#endif // !defined(AUSDK_HAVE_MUSIC_DEVICE)


#endif /* AUConfig_h */


================================================
FILE: include/AudioUnitSDK/AUEffectBase.h
================================================
/*!
	@file		AudioUnitSDK/AUEffectBase.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUEffectBase_h
#define AudioUnitSDK_AUEffectBase_h

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUBase.h>
#include <AudioUnitSDK/AUSilentTimeout.h>
#include <AudioUnitSDK/AUUtility.h>

#include <memory>

namespace ausdk {

AUSDK_BEGIN_NO_RT_WARNINGS

class AUKernelBase;

/*!
	@class	AUEffectBase
	@brief	Base class for an effect with one input stream, one output stream, and any number of
			channels.
*/
class AUEffectBase : public AUBase {
public:
	explicit AUEffectBase(AudioComponentInstance audioUnit, bool inProcessesInPlace = true);

	AUEffectBase(const AUEffectBase&) = delete;
	AUEffectBase(AUEffectBase&&) = delete;
	AUEffectBase& operator=(const AUEffectBase&) = delete;
	AUEffectBase& operator=(AUEffectBase&&) = delete;

	~AUEffectBase() override = default;

	OSStatus Initialize() override;
	void Cleanup() override;
	OSStatus Reset(AudioUnitScope inScope, AudioUnitElement inElement) override;
	OSStatus GetPropertyInfo(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, UInt32& outDataSize, bool& outWritable) override;
	OSStatus GetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, void* outData) override;
	OSStatus SetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, const void* inData, UInt32 inDataSize) override;
	bool StreamFormatWritable(AudioUnitScope scope, AudioUnitElement element) override;
	OSStatus ChangeStreamFormat(AudioUnitScope inScope, AudioUnitElement inElement,
		const AudioStreamBasicDescription& inPrevFormat,
		const AudioStreamBasicDescription& inNewFormat) override;
	OSStatus Render(AudioUnitRenderActionFlags& ioActionFlags, const AudioTimeStamp& inTimeStamp,
		UInt32 nFrames) AUSDK_RTSAFE override;

	// If a kernel implements ResetRT, this can be used to reset with a realtime-safety assertion.
	template <typename Kernel>
	OSStatus ResetRT(AudioUnitScope /*inScope*/, AudioUnitElement /*inElement*/) AUSDK_RTSAFE
	{
		for (auto& kernel : mKernelList) {
			if (kernel) {
				static_cast<Kernel*>(kernel.get())->ResetRT();
			}
		}
		// Note that AUBase::Reset() is a no-op but not declared safe, so we bypass it.
		return noErr;
	}

	// our virtual methods

	// If your unit processes N to N channels, and there are no interactions between channels,
	// it can override NewKernel to create a mono processing object per channel.  Otherwise,
	// don't override NewKernel, and instead, override ProcessBufferLists.
	virtual std::unique_ptr<AUKernelBase> NewKernel() { return {}; }
	OSStatus ProcessBufferLists(AudioUnitRenderActionFlags& ioActionFlags,
		const AudioBufferList& inBuffer, AudioBufferList& outBuffer,
		UInt32 inFramesToProcess) AUSDK_RTSAFE override;

	// convenience format accessors (use output 0's format)
	Float64 GetSampleRate() AUSDK_RTSAFE { return GetOutput0().GetStreamFormat().mSampleRate; }
	UInt32 GetNumberOfChannels() AUSDK_RTSAFE
	{
		return GetOutput0().GetStreamFormat().mChannelsPerFrame;
	}

	// convenience wrappers for accessing parameters in the global scope
	// TODO: duplication with AUBase?

	using AUBase::SetParameter;

	void SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue value) AUSDK_RTSAFE
	{
		Globals()->SetParameterRT(paramID, value);
	}

	using AUBase::GetParameter;

	AudioUnitParameterValue GetParameter(AudioUnitParameterID paramID) AUSDK_RTSAFE
	{
		return Globals()->GetParameterRT(paramID);
	}

	[[nodiscard]] bool CanScheduleParameters() const AUSDK_RTSAFE override { return true; }

	// This is used for the property value - to reflect to the UI if an effect is bypassed
	[[nodiscard]] bool IsBypassEffect() const noexcept { return mBypassEffect; }

	virtual void SetBypassEffect(bool inFlag) { mBypassEffect = inFlag; }

	void SetParamHasSampleRateDependency(bool inFlag) noexcept { mParamSRDep = inFlag; }
	[[nodiscard]] bool GetParamHasSampleRateDependency() const noexcept { return mParamSRDep; }

	/// Context, passed as `void* userData`, for `ProcessScheduledSlice()`.
	struct ScheduledProcessParams {
		AudioUnitRenderActionFlags* actionFlags = nullptr;
		AudioBufferList* inputBufferList = nullptr;
		AudioBufferList* outputBufferList = nullptr;
	};

	OSStatus ProcessScheduledSlice(void* inUserData, UInt32 inStartFrameInBuffer,
		UInt32 inSliceFramesToProcess, UInt32 inTotalBufferFrames) AUSDK_RTSAFE override;

	[[nodiscard]] bool ProcessesInPlace() const noexcept { return mProcessesInPlace; }
	void SetProcessesInPlace(bool inProcessesInPlace) noexcept
	{
		mProcessesInPlace = inProcessesInPlace;
	}

	using KernelList = std::vector<std::unique_ptr<AUKernelBase>>;

protected:
	void MaintainKernels();

	// This is used in the render call to see if an effect is bypassed
	// It can return a different status than IsBypassEffect (though it MUST take that into account)
	virtual bool ShouldBypassEffect() AUSDK_RTSAFE { return IsBypassEffect(); }

	[[nodiscard]] AUKernelBase* GetKernel(UInt32 index) const
	{
		return (index < mKernelList.size()) ? mKernelList[index].get() : nullptr;
	}
	[[nodiscard]] const KernelList& GetKernelList() const noexcept { return mKernelList; }

	bool IsInputSilent(AudioUnitRenderActionFlags inActionFlags, UInt32 inFramesToProcess)
	{
		bool inputSilent = (inActionFlags & kAudioUnitRenderAction_OutputIsSilence) != 0;

		// take latency and tail time into account when propagating the silent bit
		const auto silentTimeoutFrames =
			static_cast<UInt32>(GetSampleRate() * (GetLatency() + GetTailTime()));
		mSilentTimeout.Process(inFramesToProcess, silentTimeoutFrames, inputSilent);
		return inputSilent;
	}

#if TARGET_OS_IPHONE
	void SetOnlyOneKernel(bool inUseOnlyOneKernel) noexcept
	{
		mOnlyOneKernel = inUseOnlyOneKernel;
	} // set in ctor of subclass that wants it.
#endif

private:
	KernelList mKernelList;
	bool mBypassEffect{ false };
	bool mParamSRDep{ false };
	bool mProcessesInPlace;
	AUSilentTimeout mSilentTimeout;
	AUOutputElement* mMainOutput{ nullptr };
	AUInputElement* mMainInput{ nullptr };

#if TARGET_OS_IPHONE
	bool mOnlyOneKernel;
#endif
	UInt32 mBytesPerFrame = 0;
};


/*!
	@class	AUKernelBase
	@brief	Base class for a signal-processing "kernel", an object that performs DSP on one channel
			of an audio stream.
*/
class AUKernelBase {
public:
	explicit AUKernelBase(AUEffectBase& inAudioUnit) : mAudioUnit(inAudioUnit) {}

	AUSDK_DEPRECATED("Construct with a reference")
	explicit AUKernelBase(AUEffectBase* inAudioUnit) : mAudioUnit(*inAudioUnit) {}

	AUKernelBase(const AUKernelBase&) = delete;
	AUKernelBase(AUKernelBase&&) = delete;
	AUKernelBase& operator=(const AUKernelBase&) = delete;
	AUKernelBase& operator=(AUKernelBase&&) = delete;

	virtual ~AUKernelBase() = default;

	virtual void Reset() {}

	virtual void Process(const Float32* /*inSourceP*/, Float32* /*inDestP*/,
		UInt32 /*inFramesToProcess*/, bool& /*ioSilence*/) AUSDK_RTSAFE = 0;

	Float64 GetSampleRate() AUSDK_RTSAFE { return mAudioUnit.GetSampleRate(); }

	AudioUnitParameterValue GetParameter(AudioUnitParameterID paramID) AUSDK_RTSAFE
	{
		return mAudioUnit.GetParameter(paramID);
	}

	void SetChannelNum(UInt32 inChan) noexcept { mChannelNum = inChan; }
	[[nodiscard]] UInt32 GetChannelNum() const noexcept { return mChannelNum; }

protected:
	AUEffectBase& mAudioUnit; // NOLINT protected
	UInt32 mChannelNum = 0;   // NOLINT protected
};

AUSDK_END_NO_RT_WARNINGS

} // namespace ausdk

#endif // AudioUnitSDK_AUEffectBase_h


================================================
FILE: include/AudioUnitSDK/AUInputElement.h
================================================
/*!
	@file		AudioUnitSDK/AUInputElement.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUInputElement_h
#define AudioUnitSDK_AUInputElement_h

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUBuffer.h>
#include <AudioUnitSDK/AUScopeElement.h>
#include <AudioUnitSDK/AUUtility.h>

#include <AudioToolbox/AUComponent.h>
#include <AudioToolbox/AudioUnitProperties.h>

namespace ausdk {

AUSDK_BEGIN_NO_RT_WARNINGS

/*!
	@class	AUInputElement
	@brief	Implements an audio unit input element, managing the source of input from a callback
			or connection.
*/
class AUInputElement : public AUIOElement {
public:
	using AUIOElement::AUIOElement;

	// AUElement override
	OSStatus SetStreamFormat(const AudioStreamBasicDescription& fmt) override;
	[[nodiscard]] bool NeedsBufferSpace() const override { return IsCallback(); }
	void SetConnection(const AudioUnitConnection& conn);
	void SetInputCallback(AURenderCallback proc, void* refCon);
	[[nodiscard]] bool IsActive() const noexcept { return mInputType != EInputType::NoInput; }
	[[nodiscard]] bool IsCallback() const noexcept
	{
		return mInputType == EInputType::FromCallback;
	}
	[[nodiscard]] bool HasConnection() const noexcept
	{
		return mInputType == EInputType::FromConnection;
	}

	OSStatus PullInput(AudioUnitRenderActionFlags& ioActionFlags, const AudioTimeStamp& inTimeStamp,
		AudioUnitElement inElement, UInt32 nFrames) AUSDK_RTSAFE;

	OSStatus PullInputWithBufferList(AudioUnitRenderActionFlags& ioActionFlags,
		const AudioTimeStamp& inTimeStamp, AudioUnitElement inElement, UInt32 nFrames,
		AudioBufferList& inBufferList) AUSDK_RTSAFE;

protected:
	void Disconnect();

private:
	enum class EInputType { NoInput, FromConnection, FromCallback };
	EInputType mInputType{ EInputType::NoInput };

	// if from callback:
	AURenderCallback mInputProc{ nullptr };
	void* mInputProcRefCon{ nullptr };

	// if from connection:
	AudioUnitConnection mConnection{};
};

inline OSStatus AUInputElement::PullInputWithBufferList(AudioUnitRenderActionFlags& ioActionFlags,
	const AudioTimeStamp& inTimeStamp, AudioUnitElement inElement, UInt32 nFrames,
	AudioBufferList& inBufferList) AUSDK_RTSAFE
{
	OSStatus theResult = noErr;

	if (HasConnection()) {
		// only support connections for V2 audio units
		theResult = AudioUnitRender(mConnection.sourceAudioUnit, &ioActionFlags, &inTimeStamp,
			mConnection.sourceOutputNumber, nFrames, &inBufferList);
	} else {
		// kFromCallback:
		theResult = (mInputProc)(mInputProcRefCon, &ioActionFlags, &inTimeStamp, inElement, nFrames,
			&inBufferList);
	}

	// defense: the upstream could have disconnected.
	// it's a horrible thing to do, but may happen!
	AUSDK_Require(mInputType != EInputType::NoInput, kAudioUnitErr_NoConnection);

#if !TARGET_OS_IPHONE || DEBUG
	if (theResult == noErr) { // if there's already an error, there's no point (and maybe some harm)
							  // in validating.
		AUSDK_Require(
			!(ABL::IsBogusAudioBufferList(inBufferList) & 1), kAudioUnitErr_InvalidPropertyValue);
	}
#endif
	return theResult;
}

AUSDK_END_NO_RT_WARNINGS

} // namespace ausdk

#endif // AudioUnitSDK_AUInputElement_h


================================================
FILE: include/AudioUnitSDK/AUMIDIBase.h
================================================
/*!
	@file		AudioUnitSDK/AUMIDIBase.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUMIDIBase_h
#define AudioUnitSDK_AUMIDIBase_h

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUBase.h>
#include <AudioUnitSDK/AUUtility.h>


#ifndef AUSDK_HAVE_XML_NAMES
#define AUSDK_HAVE_XML_NAMES TARGET_OS_OSX // NOLINT(cppcoreguidelines-macro-usage)
#endif

#ifndef AUSDK_HAVE_MIDI_MAPPING
#define AUSDK_HAVE_MIDI_MAPPING TARGET_OS_OSX // NOLINT(cppcoreguidelines-macro-usage)
#endif

namespace ausdk {

AUSDK_BEGIN_NO_RT_WARNINGS

#if AUSDK_HAVE_MIDI_MAPPING
/// Abstract interface for parameter MIDI mapping
class AUMIDIMapper {
public:
	AUMIDIMapper() = default;
	virtual ~AUMIDIMapper() = default;

	AUMIDIMapper(const AUMIDIMapper&) = delete;
	AUMIDIMapper(AUMIDIMapper&&) = delete;
	AUMIDIMapper& operator=(const AUMIDIMapper&) = delete;
	AUMIDIMapper& operator=(AUMIDIMapper&&) = delete;

	[[nodiscard]] virtual UInt32 GetNumberMaps() const = 0;
	virtual void GetMaps(AUParameterMIDIMapping* outMapping) = 0;
	virtual void GetHotParameterMap(AUParameterMIDIMapping& outMapping) = 0;

	virtual void AddParameterMapping(
		const AUParameterMIDIMapping* maps, UInt32 count, AUBase& auBase) = 0;
	virtual void RemoveParameterMapping(
		const AUParameterMIDIMapping* maps, UInt32 count, bool& outDidChange) = 0;
	virtual void SetHotMapping(const AUParameterMIDIMapping& mapping) = 0;
	virtual void ReplaceAllMaps(
		const AUParameterMIDIMapping* maps, UInt32 count, AUBase& auBase) = 0;

	virtual bool HandleHotMapping(
		UInt8 status, UInt8 channel, UInt8 data1, AUBase& auBase) AUSDK_RTSAFE = 0;
	virtual bool FindParameterMapEventMatch(UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2,
		UInt32 inStartFrame, AUBase& auBase) AUSDK_RTSAFE = 0;
};
#endif

// ________________________________________________________________________
//	AUMIDIBase
//
/*!
	@class	AUMIDIBase
	@brief	Auxiliary class supporting MIDI events.
*/
class AUMIDIBase {
public:
	explicit AUMIDIBase(AUBase& inBase) : mAUBaseInstance(inBase) {}

	virtual ~AUMIDIBase() = default;

	AUMIDIBase(const AUMIDIBase&) = delete;
	AUMIDIBase(AUMIDIBase&&) = delete;
	AUMIDIBase& operator=(const AUMIDIBase&) = delete;
	AUMIDIBase& operator=(AUMIDIBase&&) = delete;

	virtual OSStatus MIDIEvent(
		UInt32 inStatus, UInt32 inData1, UInt32 inData2, UInt32 inOffsetSampleFrame) AUSDK_RTSAFE
	{
		const auto strippedStatus = static_cast<UInt8>(inStatus & 0xf0U); // NOLINT
		const auto channel = static_cast<UInt8>(inStatus & 0x0fU);        // NOLINT

		return HandleMIDIEvent(strippedStatus, channel, inData1, inData2, inOffsetSampleFrame);
	}

#if AUSDK_HAVE_MIDI2
	virtual OSStatus MIDIEventList(
		UInt32 /*inOffsetSampleFrame*/, const MIDIEventList* /*eventList*/) AUSDK_RTSAFE
	{
		return kAudio_UnimplementedError;
	}
#endif

	virtual OSStatus SysEx(const UInt8* inData, UInt32 inLength) AUSDK_RTSAFE;

	virtual OSStatus DelegateGetPropertyInfo(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, UInt32& outDataSize, bool& outWritable);
	virtual OSStatus DelegateGetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, void* outData);
	virtual OSStatus DelegateSetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, const void* inData, UInt32 inDataSize);

protected:
	// MIDI dispatch
	virtual OSStatus HandleMIDIEvent(UInt8 inStatus, UInt8 inChannel, UInt8 inData1, UInt8 inData2,
		UInt32 inStartFrame) AUSDK_RTSAFE;
	virtual OSStatus HandleNonNoteEvent(
		UInt8 status, UInt8 channel, UInt8 data1, UInt8 data2, UInt32 inStartFrame) AUSDK_RTSAFE;

	// Old name
	AUSDK_DEPRECATED("HandleMIDIEvent")
	OSStatus HandleMidiEvent(UInt8 inStatus, UInt8 inChannel, UInt8 inData1, UInt8 inData2,
		UInt32 inStartFrame) AUSDK_RTSAFE
	{
		return HandleMIDIEvent(inStatus, inChannel, inData1, inData2, inStartFrame);
	}

#if AUSDK_HAVE_XML_NAMES
	virtual OSStatus GetXMLNames(CFURLRef* /*outNameDocument*/)
	{
		return kAudioUnitErr_InvalidProperty;
	} // if not overridden, it's unsupported
#endif

	// channel messages
	virtual OSStatus HandleNoteOn(UInt8 /*inChannel*/, UInt8 /*inNoteNumber*/, UInt8 /*inVelocity*/,
		UInt32 /*inStartFrame*/) AUSDK_RTSAFE
	{
		return noErr;
	}
	virtual OSStatus HandleNoteOff(UInt8 /*inChannel*/, UInt8 /*inNoteNumber*/,
		UInt8 /*inVelocity*/, UInt32 /*inStartFrame*/) AUSDK_RTSAFE
	{
		return noErr;
	}
	virtual OSStatus HandleControlChange(UInt8 /*inChannel*/, UInt8 /*inController*/,
		UInt8 /*inValue*/, UInt32 /*inStartFrame*/) AUSDK_RTSAFE
	{
		return noErr;
	}
	virtual OSStatus HandlePitchWheel(UInt8 /*inChannel*/, UInt8 /*inPitch1*/, UInt8 /*inPitch2*/,
		UInt32 /*inStartFrame*/) AUSDK_RTSAFE
	{
		return noErr;
	}
	virtual OSStatus HandleChannelPressure(
		UInt8 /*inChannel*/, UInt8 /*inValue*/, UInt32 /*inStartFrame*/) AUSDK_RTSAFE
	{
		return noErr;
	}
	virtual OSStatus HandleProgramChange(UInt8 /*inChannel*/, UInt8 /*inValue*/) AUSDK_RTSAFE
	{
		return noErr;
	}
	virtual OSStatus HandlePolyPressure(UInt8 /*inChannel*/, UInt8 /*inKey*/, UInt8 /*inValue*/,
		UInt32 /*inStartFrame*/) AUSDK_RTSAFE
	{
		return noErr;
	}
	virtual OSStatus HandleResetAllControllers(UInt8 /*inChannel*/) AUSDK_RTSAFE { return noErr; }
	virtual OSStatus HandleAllNotesOff(UInt8 /*inChannel*/) AUSDK_RTSAFE { return noErr; }
	virtual OSStatus HandleAllSoundOff(UInt8 /*inChannel*/) AUSDK_RTSAFE { return noErr; }

	// System messages
	virtual OSStatus HandleSysEx(const UInt8* /*inData*/, UInt32 /*inLength*/) AUSDK_RTSAFE
	{
		return noErr;
	}

#if AUSDK_HAVE_MIDI_MAPPING
	void SetMIDIMapper(const std::shared_ptr<AUMIDIMapper>& mapper) { mMIDIMapper = mapper; }
#endif

private:
	AUBase& mAUBaseInstance;
#if AUSDK_HAVE_MIDI_MAPPING
	std::shared_ptr<AUMIDIMapper> mMIDIMapper;
#endif
};

AUSDK_END_NO_RT_WARNINGS

} // namespace ausdk

#endif // AudioUnitSDK_AUMIDIBase_h


================================================
FILE: include/AudioUnitSDK/AUMIDIEffectBase.h
================================================
/*!
	@file		AudioUnitSDK/AUMIDIEffectBase.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUMIDIEffectBase_h
#define AudioUnitSDK_AUMIDIEffectBase_h

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUEffectBase.h>
#include <AudioUnitSDK/AUMIDIBase.h>

namespace ausdk {

AUSDK_BEGIN_NO_RT_WARNINGS

/*!
	@class	AUMIDIEffectBase
	@brief	Subclass of AUEffectBase and AUMIDIBase, providing an abstract base class for
			music effects.
*/
class AUMIDIEffectBase : public AUEffectBase, public AUMIDIBase {
public:
	explicit AUMIDIEffectBase(AudioComponentInstance inInstance, bool inProcessesInPlace = false);
	OSStatus MIDIEvent(UInt32 inStatus, UInt32 inData1, UInt32 inData2,
		UInt32 inOffsetSampleFrame) AUSDK_RTSAFE override
	{
		return AUMIDIBase::MIDIEvent(inStatus, inData1, inData2, inOffsetSampleFrame);
	}
	OSStatus SysEx(const UInt8* inData, UInt32 inLength) AUSDK_RTSAFE override
	{
		return AUMIDIBase::SysEx(inData, inLength);
	}
	OSStatus GetPropertyInfo(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, UInt32& outDataSize, bool& outWritable) override;
	OSStatus GetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, void* outData) override;
	OSStatus SetProperty(AudioUnitPropertyID inID, AudioUnitScope inScope,
		AudioUnitElement inElement, const void* inData, UInt32 inDataSize) override;
};

AUSDK_END_NO_RT_WARNINGS

} // namespace ausdk

#endif // AudioUnitSDK_AUMIDIEffectBase_h


================================================
FILE: include/AudioUnitSDK/AUMIDIUtility.h
================================================
/*!
	@file		AudioUnitSDK/AUMIDIUtility.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUMIDIUtility_h
#define AudioUnitSDK_AUMIDIUtility_h

#pragma message("This header is deprecated and will be removed in a future release.")

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on

#endif // AudioUnitSDK_AUMIDIUtility_h


================================================
FILE: include/AudioUnitSDK/AUOutputElement.h
================================================
/*!
	@file		AudioUnitSDK/AUOutputElement.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUOutputElement_h
#define AudioUnitSDK_AUOutputElement_h

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUBuffer.h>
#include <AudioUnitSDK/AUScopeElement.h>
#include <AudioUnitSDK/AUUtility.h>

namespace ausdk {

class AUBase;

/*!
	@class	AUOutputElement
	@brief	Implements an audio unit output element.
*/
class AUOutputElement : public AUIOElement {
public:
	explicit AUOutputElement(AUBase& audioUnit);

	AUOutputElement(AUBase& audioUnit, const AudioStreamBasicDescription& format);

	AUSDK_DEPRECATED("Construct with a reference")
	explicit AUOutputElement(AUBase* audioUnit) : AUOutputElement(*audioUnit) {}

	// AUElement override
	OSStatus SetStreamFormat(const AudioStreamBasicDescription& desc) override;
	[[nodiscard]] bool NeedsBufferSpace() const override { return true; }
};

} // namespace ausdk

#endif // AudioUnitSDK_AUOutputElement_h


================================================
FILE: include/AudioUnitSDK/AUPlugInDispatch.h
================================================
/*!
	@file		AudioUnitSDK/AUPlugInDispatch.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUPlugInDispatch_h
#define AudioUnitSDK_AUPlugInDispatch_h

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/ComponentBase.h>

namespace ausdk {

/// Method lookup for a basic AUBase subclass.
struct AUBaseLookup {
	static AudioComponentMethod Lookup(SInt16 selector);
};

/// Factory for a basic AUBase subclass.
template <class Implementor>
class AUBaseFactory : public APFactory<AUBaseLookup, Implementor> {};

/// Method lookup for a AUBase subclass which implements I/O methods (Start, Stop).
struct AUOutputLookup {
	static AudioComponentMethod Lookup(SInt16 selector);
};

/// Factory for an AUBase subclass which implements I/O methods (Start, Stop).
template <class Implementor>
class AUOutputBaseFactory : public APFactory<AUOutputLookup, Implementor> {};

/// Method lookup for an AUBase subclass which implements I/O methods (Start, Stop) and
/// ComplexRender.
struct AUComplexOutputLookup {
	static AudioComponentMethod Lookup(SInt16 selector);
};

/// Factory for an AUBase subclass which implements I/O methods (Start, Stop) and ComplexRender.
template <class Implementor>
class AUOutputComplexBaseFactory : public APFactory<AUComplexOutputLookup, Implementor> {};

/// Method lookup for an AUBase subclass which implements Process.
struct AUBaseProcessLookup {
	static AudioComponentMethod Lookup(SInt16 selector);
};

/// Factory for an AUBase subclass which implements Process.
template <class Implementor>
class AUBaseProcessFactory : public APFactory<AUBaseProcessLookup, Implementor> {};

/// Method lookup for an AUBase subclass which implements ProcessMultiple.
struct AUBaseProcessMultipleLookup {
	static AudioComponentMethod Lookup(SInt16 selector);
};

/// Factory for an AUBase subclass which implements ProcessMultiple.
template <class Implementor>
class AUBaseProcessMultipleFactory : public APFactory<AUBaseProcessMultipleLookup, Implementor> {};

/// Method lookup for an AUBase subclass which implements Process and ProcessMultiple.
struct AUBaseProcessAndMultipleLookup {
	static AudioComponentMethod Lookup(SInt16 selector);
};

/// Factory for an AUBase subclass which implements Process and ProcessMultiple.
template <class Implementor>
class AUBaseProcessAndMultipleFactory
	: public APFactory<AUBaseProcessAndMultipleLookup, Implementor> {};

#if AUSDK_HAVE_MIDI
/// Method lookup for an AUBase subclass which implements MusicDevice methods (MIDIEvent and SysEx).
struct AUMIDILookup {
	static AudioComponentMethod Lookup(SInt16 selector);
};

/// Factory for an AUBase subclass which implements MusicDevice methods (MIDIEvent and SysEx).
template <class Implementor>
class AUMIDIEffectFactory : public APFactory<AUMIDILookup, Implementor> {};

/// Method lookup for an AUBase subclass which implements Process and MusicDevice methods (MIDIEvent
/// and SysEx).
struct AUMIDIProcessLookup {
	static AudioComponentMethod Lookup(SInt16 selector);
};

/// Factory for an AUBase subclass which implements Process and MusicDevice methods (MIDIEvent
/// and SysEx).
template <class Implementor>
class AUMIDIProcessFactory : public APFactory<AUMIDIProcessLookup, Implementor> {};
#endif // AUSDK_HAVE_MIDI

#if AUSDK_HAVE_MUSIC_DEVICE
/// Method lookup for an AUBase subclass which implements the full set of MusicDevice methods
/// (MIDIEvent, SysEx, StartNote, StopNote).
struct AUMusicLookup {
	static AudioComponentMethod Lookup(SInt16 selector);
};

/// Factory for an AUBase subclass which implements the full set of MusicDevice methods
/// (MIDIEvent, SysEx, StartNote, StopNote).
template <class Implementor>
class AUMusicDeviceFactory : public APFactory<AUMusicLookup, Implementor> {};
#endif // AUSDK_HAVE_MUSIC_DEVICE
} // namespace ausdk

#endif // AudioUnitSDK_AUPlugInDispatch_h


================================================
FILE: include/AudioUnitSDK/AUScopeElement.h
================================================
/*!
	@file		AudioUnitSDK/AUScopeElement.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUScopeElement_h
#define AudioUnitSDK_AUScopeElement_h

// module
// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUBuffer.h>
#include <AudioUnitSDK/AUUtility.h>
#include <AudioUnitSDK/ComponentBase.h>

// OS
#include <AudioToolbox/AUComponent.h>

// std
#include <algorithm>
#include <atomic>
#include <memory>
#include <utility>
#include <vector>

namespace ausdk {

AUSDK_BEGIN_NO_RT_WARNINGS

class AUBase;

/// Wrap an atomic in a copy-constructible/assignable object. This allows storing atomic values in a
/// vector (not directly possible since atomics are not copy-constructible/assignable).
template <typename T>
class AtomicValue {
public:
	AtomicValue() = default;
	explicit AtomicValue(T val) : mValue{ val } {}
	~AtomicValue() = default;

	AtomicValue(const AtomicValue& other) : mValue{ other.mValue.load() } {}
	AtomicValue(AtomicValue&& other) noexcept : mValue{ other.mValue.load() } {}

	AtomicValue& operator=(const AtomicValue& other)
	{
		if (&other != this) {
			mValue.store(other.mValue.load());
		}
		return *this;
	}

	AtomicValue& operator=(AtomicValue&& other) noexcept
	{
		mValue.store(other.mValue.load());
		return *this;
	}

	T load(std::memory_order m = std::memory_order_seq_cst) const { return mValue.load(m); }
	void store(T v, std::memory_order m = std::memory_order_seq_cst) { mValue.store(v, m); }

	operator T() const { return load(); } // NOLINT implicit conversions OK

	AtomicValue& operator=(T value)
	{
		store(value);
		return *this;
	}

private:
	std::atomic<T> mValue{};
	static_assert(decltype(mValue)::is_always_lock_free);
};

/// A bare-bones reinvention of boost::flat_map, just enough to hold parameters in sorted vectors.
template <typename Key, typename Value>
class flat_map {
	using KVPair = std::pair<Key, Value>;
	using Impl = std::vector<std::pair<Key, Value>>;

	static bool keyless(const KVPair& item, Key k) AUSDK_RTSAFE { return k > item.first; }

	Impl mImpl;

public:
	using iterator = typename Impl::iterator;
	using const_iterator = typename Impl::const_iterator;

	[[nodiscard]] bool empty() const noexcept { return mImpl.empty(); }
	[[nodiscard]] size_t size() const noexcept { return mImpl.size(); }
	[[nodiscard]] const_iterator begin() const noexcept { return mImpl.begin(); }
	[[nodiscard]] const_iterator end() const noexcept { return mImpl.end(); }
	iterator begin() noexcept { return mImpl.begin(); }
	iterator end() noexcept { return mImpl.end(); }
	const_iterator cbegin() noexcept { return mImpl.cbegin(); }
	const_iterator cend() noexcept { return mImpl.cend(); }

	[[nodiscard]] const_iterator lower_bound(Key k) const
	{
		return std::lower_bound(mImpl.cbegin(), mImpl.cend(), k, RTSafeFP{ keyless });
	}

	iterator lower_bound(Key k)
	{
		return std::lower_bound(mImpl.begin(), mImpl.end(), k, RTSafeFP{ keyless });
	}

	[[nodiscard]] const_iterator find(Key k) const
	{
		auto iter = lower_bound(k);
		if (iter != mImpl.end()) {
			if (iter->first != k) {
				iter = mImpl.end();
			}
		}
		return iter;
	}

	iterator find(Key k)
	{
		auto iter = lower_bound(k);
		if (iter != mImpl.end()) {
			if (iter->first != k) {
				iter = mImpl.end();
			}
		}
		return iter;
	}

	class ItemProxy {
	public:
		ItemProxy(flat_map& map, Key k) : mMap{ map }, mKey{ k } {}

		operator Value() const // NOLINT implicit conversion is OK
		{
			const auto iter = mMap.find(mKey);
			if (iter == mMap.end()) {
				throw std::runtime_error("Invalid map key");
			}
			return iter->second;
		}

		ItemProxy& operator=(const Value& v)
		{
			const auto iter = mMap.lower_bound(mKey);
			if (iter != mMap.end() && iter->first == mKey) {
				iter->second = v;
			} else {
				mMap.mImpl.insert(iter, { mKey, v });
			}
			return *this;
		}

	private:
		flat_map& mMap;
		const Key mKey;
	};

	ItemProxy operator[](Key k) { return ItemProxy{ *this, k }; }
};

// ____________________________________________________________________________
//
class AUIOElement;

/// An organizational unit for parameters, with a name.
class AUElement {
public:
	explicit AUElement(AUBase& audioUnit) : mAudioUnit(audioUnit), mUseIndexedParameters(false) {}

	AUSDK_DEPRECATED("Construct with a reference")
	explicit AUElement(AUBase* audioUnit) : AUElement(*audioUnit) {}

	AUElement(const AUElement&) = delete;
	AUElement(AUElement&&) = delete;
	AUElement& operator=(const AUElement&) = delete;
	AUElement& operator=(AUElement&&) = delete;

	virtual ~AUElement() = default;

	virtual UInt32 GetNumberOfParameters()
	{
		return mUseIndexedParameters ? static_cast<UInt32>(mIndexedParameters.size())
									 : static_cast<UInt32>(mParameters.size());
	}
	virtual void GetParameterList(AudioUnitParameterID* outList);
	[[nodiscard]] bool HasParameterID(AudioUnitParameterID paramID) const AUSDK_RTSAFE;

	// Use this from the control (non-realtime) context. Throws if the parameter doesn't exist.
	[[nodiscard]] AudioUnitParameterValue GetParameter(AudioUnitParameterID paramID) const
	{
		const auto res = GetParameterOrError(paramID);
		ThrowExceptionIfUnexpected(res);
		return *res;
	}

	// Use this from the render (realtime) context, when you are sure the parameter should exist.
	[[nodiscard]] AudioUnitParameterValue GetParameterRT(
		AudioUnitParameterID paramID) const AUSDK_RTSAFE
	{
		const auto res = GetParameterOrError(paramID);
		AUSDK_Assert(res);
		return *res;
	}

	// Primitive, returns an error if the parameter does not exist.
	[[nodiscard]] Expected<AudioUnitParameterValue> GetParameterOrError(
		AudioUnitParameterID paramID) const AUSDK_RTSAFE;

	// Use this from the control (non-realtime) context. Throws if the parameter doesn't exist.
	// Only set okWhenInitialized to true when you know the outside world cannot access this
	// element. Otherwise the parameter map could get corrupted.
	void SetParameter(
		AudioUnitParameterID paramID, AudioUnitParameterValue value, bool okWhenInitialized = false)
	{
		const auto res = SetParameterOrError(paramID, value, okWhenInitialized);
		ThrowExceptionIfUnexpected(res);
	}

	// Use this from the render (realtime) context, when you are sure the parameter should exist.
	void SetParameterRT(AudioUnitParameterID paramID, AudioUnitParameterValue value,
		bool okWhenInitialized = false) AUSDK_RTSAFE
	{
		const auto res = SetParameterOrError(paramID, value, okWhenInitialized);
		AUSDK_Assert(res);
	}

	// Primitive, returns an error if the parameter does not exist.
	Expected<void> SetParameterOrError(AudioUnitParameterID paramID, AudioUnitParameterValue value,
		bool okWhenInitialized = false) AUSDK_RTSAFE;

	// Only set okWhenInitialized to true when you know the outside world cannot access this
	// element. Otherwise the parameter map could get corrupted. N.B. This only handles
	// immediate parameters. Override to implement ramping. Called from
	// AUBase::ProcessForScheduledParams.
	[[nodiscard]] virtual OSStatus SetScheduledEvent(AudioUnitParameterID paramID,
		const AudioUnitParameterEvent& inEvent, UInt32 inSliceOffsetInBuffer,
		UInt32 inSliceDurationFrames, bool okWhenInitialized = false) AUSDK_RTSAFE;

	[[nodiscard]] AUBase& GetAudioUnit() const noexcept { return mAudioUnit; }

	void SaveState(AudioUnitScope scope, CFMutableDataRef data);
	const UInt8* RestoreState(const UInt8* state);

	[[nodiscard]] Owned<CFStringRef> GetName() const noexcept { return mElementName; }
	void SetName(CFStringRef inName) noexcept { mElementName = inName; }

	[[nodiscard]] bool HasName() const noexcept { return *mElementName != nullptr; }

	virtual void UseIndexedParameters(UInt32 inNumberOfParameters);

	virtual AUIOElement* AsIOElement() AUSDK_RTSAFE { return nullptr; }

private:
	using ParameterValue = AtomicValue<float>;

	AUBase& mAudioUnit;
	flat_map<AudioUnitParameterID, ParameterValue> mParameters;
	bool mUseIndexedParameters;
	std::vector<ParameterValue> mIndexedParameters;
	Owned<CFStringRef> mElementName;
};


// ____________________________________________________________________________
//

/// A subclass of AUElement which represents an input or output bus, and has an associated
/// audio format and buffers.
class AUIOElement : public AUElement {
public:
	explicit AUIOElement(AUBase& audioUnit);

	AUIOElement(AUBase& audioUnit, const AudioStreamBasicDescription& format)
		: AUIOElement{ audioUnit }
	{
		mStreamFormat = format;
	}

	AUSDK_DEPRECATED("Construct with a reference")
	explicit AUIOElement(AUBase* audioUnit) : AUIOElement(*audioUnit) {}

	[[nodiscard]] const AudioStreamBasicDescription& GetStreamFormat() const noexcept
	{
		return mStreamFormat;
	}

	virtual OSStatus SetStreamFormat(const AudioStreamBasicDescription& format);

	virtual void AllocateBuffer(UInt32 inFramesToAllocate = 0);

	void DeallocateBuffer();

	/// Determines (via subclass override) whether the element's buffer list needs to be allocated.
	[[nodiscard]] virtual bool NeedsBufferSpace() const = 0;

	void SetWillAllocateBuffer(bool inFlag) noexcept { mWillAllocate = inFlag; }

	[[nodiscard]] bool WillAllocateBuffer() const noexcept { return mWillAllocate; }

	AudioBufferList& PrepareBuffer(UInt32 nFrames)
	{
		if (mWillAllocate) {
			return mIOBuffer.PrepareBuffer(mStreamFormat, nFrames);
		}
		Throw(kAudioUnitErr_InvalidPropertyValue);
	}

	ExpectedPtr<AudioBufferList> PrepareBufferOrError(UInt32 nFrames) AUSDK_RTSAFE
	{
		if (mWillAllocate) {
			return mIOBuffer.PrepareBufferOrError(mStreamFormat, nFrames);
		}
		return Unexpected(kAudioUnitErr_InvalidPropertyValue);
	}

	AudioBufferList& PrepareNullBuffer(UInt32 nFrames)
	{
		return mIOBuffer.PrepareNullBuffer(mStreamFormat, nFrames);
	}

	ExpectedPtr<AudioBufferList> PrepareNullBufferOrError(UInt32 nFrames) AUSDK_RTSAFE
	{
		return mIOBuffer.PrepareNullBufferOrError(mStreamFormat, nFrames);
	}

	AudioBufferList& SetBufferList(const AudioBufferList& abl)
	{
		return mIOBuffer.SetBufferList(abl);
	}

	ExpectedPtr<AudioBufferList> SetBufferListOrError(const AudioBufferList& abl) AUSDK_RTSAFE
	{
		return mIOBuffer.SetBufferListOrError(abl);
	}

	void SetBuffer(UInt32 index, AudioBuffer& ab) { mIOBuffer.SetBuffer(index, ab); }

	Expected<void> SetBufferOrError(UInt32 index, AudioBuffer& ab) AUSDK_RTSAFE
	{
		return mIOBuffer.SetBufferOrError(index, ab);
	}

	void InvalidateBufferList() { mIOBuffer.InvalidateBufferList(); }

	[[nodiscard]] AudioBufferList& GetBufferList() const { return mIOBuffer.GetBufferList(); }

	ExpectedPtr<AudioBufferList> GetBufferListOrError() const AUSDK_RTSAFE
	{
		return mIOBuffer.GetBufferListOrError();
	}

	[[nodiscard]] float* GetFloat32ChannelData(UInt32 ch) const
	{
		const auto& abl = GetBufferList();
		if (IsInterleaved()) {
			return static_cast<float*>(abl.mBuffers[0].mData) + ch; // NOLINT
		}
		return static_cast<float*>(abl.mBuffers[ch].mData); // NOLINT
	}

	// N.B. Returns null pointers on failure.
	[[nodiscard]] float* GetFloat32ChannelDataRT(UInt32 ch) const AUSDK_RTSAFE
	{
		const auto abl = GetBufferListOrError();
		if (!abl) [[unlikely]] {
			return nullptr;
		}
		if (IsInterleaved()) {
			return static_cast<float*>(abl->mBuffers[0].mData) + ch; // NOLINT
		}
		return static_cast<float*>(abl->mBuffers[ch].mData); // NOLINT
	}

	void CopyBufferListTo(AudioBufferList& abl) const { mIOBuffer.CopyBufferListTo(abl); }
	void CopyBufferContentsTo(AudioBufferList& abl) const { mIOBuffer.CopyBufferContentsTo(abl); }

	Expected<void> CopyBufferListToOrError(AudioBufferList& abl) const AUSDK_RTSAFE
	{
		return mIOBuffer.CopyBufferListToOrError(abl);
	}
	Expected<void> CopyBufferContentsToOrError(AudioBufferList& abl) const AUSDK_RTSAFE
	{
		return mIOBuffer.CopyBufferContentsToOrError(abl);
	}

	[[nodiscard]] bool IsInterleaved() const noexcept { return ASBD::IsInterleaved(mStreamFormat); }
	[[nodiscard]] UInt32 NumberChannels() const noexcept { return mStreamFormat.mChannelsPerFrame; }
	[[nodiscard]] UInt32 NumberInterleavedChannels() const noexcept
	{
		return ASBD::NumberInterleavedChannels(mStreamFormat);
	}
	virtual std::vector<AudioChannelLayoutTag> GetChannelLayoutTags();

	[[nodiscard]] const AUChannelLayout& ChannelLayout() const { return mChannelLayout; }

	// Old layout methods
	virtual OSStatus SetAudioChannelLayout(const AudioChannelLayout& inLayout);
	virtual UInt32 GetAudioChannelLayout(AudioChannelLayout* outLayoutPtr, bool& outWritable);

	virtual OSStatus RemoveAudioChannelLayout();

	/*! @fn AsIOElement*/
	AUIOElement* AsIOElement() AUSDK_RTSAFE override { return this; }

protected:
	AUBufferList& IOBuffer() noexcept { return mIOBuffer; }
	void ForceSetAudioChannelLayout(const AudioChannelLayout& inLayout)
	{
		mChannelLayout = inLayout;
	}

private:
	AudioStreamBasicDescription mStreamFormat{};
	AUChannelLayout mChannelLayout{};
	AUBufferList mIOBuffer; // for input: input proc buffer, only allocated when needed
							// for output: output cache, usually allocated early on
	bool mWillAllocate{ false };
};

// ____________________________________________________________________________
//
/*!
	@class	AUScopeDelegate
	@brief	Provides a way to customize a scope, thereby obtaining virtual scopes.

	Can be used to implement scopes with variable numbers of elements.
*/
class AUScopeDelegate {
public:
	AUScopeDelegate() = default;

	virtual ~AUScopeDelegate() = default;

	AUScopeDelegate(const AUScopeDelegate&) = delete;
	AUScopeDelegate(AUScopeDelegate&&) = delete;
	AUScopeDelegate& operator=(const AUScopeDelegate&) = delete;
	AUScopeDelegate& operator=(AUScopeDelegate&&) = delete;

	void Initialize(AUBase* creator, AudioUnitScope scope, UInt32 numElements)
	{
		mCreator = creator;
		mScope = scope;
		SetNumberOfElements(numElements);
	}
	virtual void SetNumberOfElements(UInt32 numElements) = 0;
	virtual UInt32 GetNumberOfElements() AUSDK_RTSAFE = 0;
	virtual AUElement* GetElement(UInt32 elementIndex) AUSDK_RTSAFE = 0;

	[[nodiscard]] AUBase* GetCreator() const noexcept { return mCreator; }
	[[nodiscard]] AudioUnitScope GetScope() const noexcept { return mScope; }


private:
	AUBase* mCreator{ nullptr };
	AudioUnitScope mScope{ 0 };
};

// ____________________________________________________________________________
//
/*!
	@class	AUScope
	@brief	Organizes one or more elements into an addressable group (e.g. global, input, output).
*/
class AUScope {
public:
	AUScope() = default;

	~AUScope() = default;

	AUScope(const AUScope&) = delete;
	AUScope(AUScope&&) = delete;
	AUScope& operator=(const AUScope&) = delete;
	AUScope& operator=(AUScope&&) = delete;

	void Initialize(AUBase* creator, AudioUnitScope scope, UInt32 numElements)
	{
		mCreator = creator;
		mScope = scope;

		if (mDelegate != nullptr) {
			return mDelegate->Initialize(creator, scope, numElements);
		}

		SetNumberOfElements(numElements);
	}
	void SetNumberOfElements(UInt32 numElements);

	[[nodiscard]] UInt32 GetNumberOfElements() const
	{
		if (mDelegate != nullptr) {
			return mDelegate->GetNumberOfElements();
		}
		return static_cast<UInt32>(mElements.size());
	}

	[[nodiscard]] AUElement* GetElement(UInt32 elementIndex) const AUSDK_RTSAFE
	{
		if (mDelegate != nullptr) {
			return mDelegate->GetElement(elementIndex);
		}
		return elementIndex < mElements.size() ? mElements[elementIndex].get() : nullptr;
	}
	[[nodiscard]] AUElement* SafeGetElement(UInt32 elementIndex) const
	{
		AUElement* const element = GetElement(elementIndex);
		ausdk::ThrowExceptionIf(element == nullptr, kAudioUnitErr_InvalidElement);
		return element;
	}
	[[nodiscard]] AUIOElement* GetIOElement(UInt32 elementIndex) const
	{
		AUElement* const element = GetElement(elementIndex);
		AUIOElement* const ioel = element != nullptr ? element->AsIOElement() : nullptr;
		ausdk::ThrowExceptionIf(ioel == nullptr, kAudioUnitErr_InvalidElement);
		return ioel;
	}

	template <typename Elem = AUElement>
	[[nodiscard]] ExpectedPtr<Elem> GetElementOrError(UInt32 elementIndex) const AUSDK_RTSAFE
	{
		if (mDelegate != nullptr) {
			if (auto* elem = mDelegate->GetElement(elementIndex)) {
				return *static_cast<Elem*>(elem);
			}
		} else if (elementIndex < mElements.size()) {
			if (auto* elem = mElements[elementIndex].get()) {
				return *static_cast<Elem*>(elem);
			}
		}
		return Unexpected(kAudioUnitErr_InvalidElement);
	}

	[[nodiscard]] ExpectedPtr<AUIOElement> GetIOElementOrError(UInt32 elementIndex) const
	{
		auto& element = AUSDK_UnwrapOrReturnUnexpected(GetElementOrError(elementIndex));
		if (AUIOElement* const ioel = element.AsIOElement()) {
			return *ioel;
		}
		return Unexpected(kAudioUnitErr_InvalidElement);
	}

	[[nodiscard]] bool HasElementWithName() const;
	void AddElementNamesToDict(CFMutableDictionaryRef inNameDict) const;

	[[nodiscard]] std::vector<AudioUnitElement> RestoreElementNames(
		CFDictionaryRef inNameDict) const;

	[[nodiscard]] AudioUnitScope GetScope() const noexcept { return mScope; }

	void SetDelegate(AUScopeDelegate* inDelegate) noexcept { mDelegate = inDelegate; }
	void SaveState(CFMutableDataRef data) const;
	const UInt8* RestoreState(const UInt8* state) const;

private:
	using ElementVector = std::vector<std::unique_ptr<AUElement>>;

	AUBase* mCreator{ nullptr };
	AudioUnitScope mScope{ 0 };
	ElementVector mElements;
	AUScopeDelegate* mDelegate{ nullptr };
};

AUSDK_END_NO_RT_WARNINGS

} // namespace ausdk

#endif // AudioUnitSDK_AUScopeElement_h


================================================
FILE: include/AudioUnitSDK/AUSilentTimeout.h
================================================
/*!
	@file		AudioUnitSDK/AUSilentTimeout.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUSilentTimeout_h
#define AudioUnitSDK_AUSilentTimeout_h

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on

#include <CoreFoundation/CFBase.h> // for UInt32

#include <algorithm>

namespace ausdk {

/*!
	@class	AUSilentTimeout
	@brief	Utility to assist in propagating a silence flag from signal-processing
			input to output, factoring in a processing delay.
*/
class AUSilentTimeout {
public:
	AUSilentTimeout() = default;

	void Process(UInt32 inFramesToProcess, UInt32 inTimeoutLimit, bool& ioSilence)
	{
		if (ioSilence) {
			if (mResetTimer) {
				mTimeoutCounter = inTimeoutLimit;
				mResetTimer = false;
			}

			if (mTimeoutCounter > 0) {
				mTimeoutCounter -= std::min(inFramesToProcess, mTimeoutCounter);
				ioSilence = false;
			}
		} else {
			// signal to reset the next time we receive silence
			mResetTimer = true;
		}
	}

	void Reset() { mResetTimer = true; }

private:
	UInt32 mTimeoutCounter{ 0 };
	bool mResetTimer{ false };
};

} // namespace ausdk

#endif // AudioUnitSDK_AUSilentTimeout_h


================================================
FILE: include/AudioUnitSDK/AUThreadSafeList.h
================================================
/*!
	@file		AudioUnitSDK/AUThreadSafeList.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUThreadSafeList_h
#define AudioUnitSDK_AUThreadSafeList_h

// module
// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUUtility.h>

// std
#include <atomic>
#include <concepts>
#include <type_traits>

namespace ausdk {

AUSDK_BEGIN_NO_RT_WARNINGS

/*!
	@class	AUAtomicStack
	@brief	Linked list LIFO or FIFO (popAllReversed) stack, elements are pushed and popped
			atomically.
 */
#ifdef __cpp_lib_concepts
template <std::default_initializable T>
#else
template <typename T, std::enable_if_t<std::is_default_constructible_v<T>, bool> = true>
#endif
class AUAtomicStack {
public:
	AUAtomicStack() = default;

	// Non-atomic routines, for use when initializing/deinitializing, operate NON-atomically
	void PushNonAtomic(T* item) noexcept
	{
		item->Next() = mHead;
		mHead = item;
	}

	T* PopNonAtomic() noexcept
	{
		T* result = mHead;
		if (result)
			mHead = result->Next();
		return result;
	}

	// Atomic routines
	void PushAtomic(T* item) noexcept
	{
		T* head_{};
		do {
			head_ = mHead;
			item->Next() = head_;
		} while (!CompareAndSwap(head_, item));
	}

	// Pushes entire linked list headed by item
	void PushMultipleAtomic(T* item) noexcept
	{
		T *head_{}, *p = item, *tail{};
		// Find the last one -- when done, it will be linked to head
		do {
			tail = p;
			p = p->Next();
		} while (p);
		do {
			head_ = mHead;
			tail->Next() = head_;
		} while (!CompareAndSwap(head_, item));
	}

	// This may only be used when only one thread may potentially pop from the stack.
	// if multiple threads may pop, this suffers from the ABA problem.
	T* PopAtomicSingleReader() noexcept
	{
		T* result{};
		do {
			if ((result = mHead) == nullptr)
				break;
		} while (!CompareAndSwap(result, result->Next()));
		return result;
	}

	// This is inefficient for large linked lists.
	// prefer PopAll() to a series of calls to PopAtomic.
	// PushMultipleAtomic has to traverse the entire list.
	T* PopAtomic() noexcept
	{
		T* result = PopAll();
		if (result) {
			T* next = result->Next();
			if (next)
				// push all the remaining items back onto the stack
				PushMultipleAtomic(next);
		}
		return result;
	}

	T* PopAll() noexcept
	{
		T* result{};
		do {
			if ((result = mHead) == nullptr)
				break;
		} while (!CompareAndSwap(result, nullptr));
		return result;
	}

	T* PopAllReversed() noexcept
	{
		AUAtomicStack<T> reversed;
		T* p = PopAll();
		while (p != nullptr) {
			T* next = p->Next();
			reversed.PushNonAtomic(p);
			p = next;
		}
		return reversed.mHead;
	}

	bool CompareAndSwap(T* oldvalue, T* newvalue) noexcept
	{
		return std::atomic_compare_exchange_strong_explicit(
			&mHead, &oldvalue, newvalue, std::memory_order_seq_cst, std::memory_order_relaxed);
	}

	[[nodiscard]] bool empty() const noexcept { return mHead == nullptr; }

	T* head() const noexcept { return mHead; }

	void SetHead(T* newHead) { this->mHead.store(newHead); }

protected:
	std::atomic<T*> mHead{ nullptr };
	static_assert(decltype(mHead)::is_always_lock_free);
};

// -------------------------------------------------------------------------------------------------
/*!
 @class    AUThreadSafeList
 @brief    A thread-safe linked list.
 */
template <class T>
class AUThreadSafeList {
public:
	enum class EventType { Unknown, Add, Remove, Clear };

	class Node {
	public:
		Node* mNext{ nullptr };
		EventType mEventType{ EventType::Unknown };
		T mObject{};

		Node*& Next() { return mNext; }
	};
	using NodeStack = AUAtomicStack<Node>;

	class iterator {
	public:
		iterator() {}
		iterator(Node* n) : mNode(n) {}

		bool operator==(const iterator& other) const { return this->mNode == other.mNode; }
		bool operator!=(const iterator& other) const { return this->mNode != other.mNode; }

		T& operator*() const { return mNode->mObject; }

		iterator& operator++()
		{
			mNode = mNode->Next();
			return *this;
		} // preincrement

		iterator operator++(int)
		{
			iterator tmp = *this;
			mNode = mNode->next();
			return tmp;
		} // postincrement

		using iterator_category = std::forward_iterator_tag;
		using difference_type = std::ptrdiff_t;
		using value_type = T;
		using reference = T&;
		using pointer = T*;

	private:
		Node* mNode{ nullptr };
	};

	AUThreadSafeList() = default;
	~AUThreadSafeList()
	{
		FreeAll(mActiveList);
		FreeAll(mPendingList);
		FreeAll(mFreeList);
	}

	AUThreadSafeList(const AUThreadSafeList&) = delete;
	AUThreadSafeList(AUThreadSafeList&&) = delete;
	AUThreadSafeList& operator=(const AUThreadSafeList&) = delete;
	AUThreadSafeList& operator=(AUThreadSafeList&&) = delete;

	// These may be called on any thread
	void Add(const T& obj)
	{
		Node* node = AllocNode();
		node->mEventType = EventType::Add;
		node->mObject = obj;
		mPendingList.PushAtomic(node);
	}

	// can be called on any thread
	void Remove(const T& obj)
	{
		Node* node = AllocNode();
		node->mEventType = EventType::Remove;
		node->mObject = obj;
		mPendingList.PushAtomic(node);
	}

	void Clear() // can be called on any thread
	{
		Node* node = AllocNode();
		node->mEventType = EventType::Clear;
		mPendingList.PushAtomic(node);
	}

	// These must be called from only one thread
	void Update() AUSDK_RTSAFE
	{
		NodeStack reversed;
		Node* event{};
		bool workDone = false;

		// reverse the events so they are in order
		event = mPendingList.PopAll();
		while (event != nullptr) {
			Node* next = event->mNext;
			reversed.PushNonAtomic(event);
			event = next;
			workDone = true;
		}

		if (workDone) {
			// now process them
			while ((event = reversed.PopNonAtomic()) != nullptr) {
				switch (event->mEventType) {
				case EventType::Add: {
					Node* endNode{};
					bool needToInsert = true;
					for (Node* node = mActiveList.head(); node != nullptr; node = node->mNext) {
						if (node->mObject == event->mObject) {
							FreeNode(event);
							needToInsert = false;
							break;
						}
						endNode = node;
					}
					if (needToInsert) {
						// link the new event in at the end of the active list
						if (!endNode) {
							mActiveList.PushNonAtomic(event);
						} else {
							endNode->Next() = event;
							event->mNext = nullptr;
						}
					}
				} break;
				case EventType::Remove: {
					// find matching node in the active list, remove it
					Node* previousNode{};
					for (Node* node = mActiveList.head(); node != nullptr; node = node->mNext) {
						if (node->mObject == event->mObject) {
							if (!previousNode) {
								mActiveList.SetHead(node->mNext);
							} else {
								previousNode->Next() = node->mNext; // remove from linked list
							}
							FreeNode(node);
							break;
						}
						previousNode = node;
					}

					// dispose the request node
					FreeNode(event);
				} break;
				case EventType::Clear: {
					Node* next{};
					for (Node* node = mActiveList.head(); node != nullptr;) {
						next = node->mNext;
						FreeNode(node);
						node = next;
					}
					FreeNode(event);

					if (mActiveList.head()) {
						mActiveList.SetHead(nullptr);
					}
				} break;
				default:
					AUSDK_LogError_RT("Unknown AUThreadSafeList event type");
					break;
				}
			}
		}
	}

	iterator begin() const noexcept { return iterator(mActiveList.head()); }
	iterator end() const noexcept { return iterator(nullptr); }

private:
	Node* AllocNode()
	{
		Node* node = mFreeList.PopAtomic();
		if (node == nullptr)
			node = new Node();
		return node;
	}

	void FreeNode(Node* node) { mFreeList.PushAtomic(node); }
	static void FreeAll(AUAtomicStack<Node>& stack)
	{
		Node* node{};
		while ((node = stack.PopNonAtomic()) != nullptr) {
			delete node;
		}
	}

	NodeStack mActiveList;  // what's actually in the container - only accessed on one thread
	NodeStack mPendingList; // add or remove requests - threadsafe
	NodeStack mFreeList;    // free nodes for reuse - threadsafe
};

AUSDK_END_NO_RT_WARNINGS

} // namespace ausdk

#endif // AudioUnitSDK_AUThreadSafeList_h


================================================
FILE: include/AudioUnitSDK/AUUtility.h
================================================
/*!
	@file		AudioUnitSDK/AUUtility.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_AUUtility_h
#define AudioUnitSDK_AUUtility_h

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on

// OS
#include <CoreFoundation/CFByteOrder.h>

#if AUSDK_HAVE_MACH_TIME
#include <mach/mach_time.h>
#endif

// std
#include <bitset>
#include <climits>
#include <cstdlib>
#include <cstring>
#include <expected>
#include <memory>
#include <mutex>
#include <span>
#include <stdexcept>
#include <string>
#include <system_error>
#include <type_traits>
#include <utility>
#include <vector>

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark Error-handling macros

#ifndef AUSDK_LOG_OBJECT
#define AUSDK_LOG_OBJECT OS_LOG_DEFAULT // NOLINT macro
#endif                                  // AUSDK_LOG_OBJECT

#ifdef AUSDK_NO_LOGGING
#define AUSDK_LogError(...) /* NOLINT macro */
#else
#include <os/log.h>
#include <syslog.h>
#define AUSDK_LogError(...) /* NOLINT macro */                                                     \
	if (__builtin_available(macOS 10.11, *)) {                                                     \
		os_log_error(AUSDK_LOG_OBJECT, __VA_ARGS__);                                               \
	} else {                                                                                       \
		syslog(LOG_ERR, __VA_ARGS__);                                                              \
	}
#endif

// logging from realtime thread
#define AUSDK_LogError_RT(...) AUSDK_RT_UNSAFE(AUSDK_LogError(__VA_ARGS__)) /* NOLINT macro */

#define AUSDK_Catch(result) /* NOLINT(cppcoreguidelines-macro-usage) */                            \
	catch (const ausdk::AUException& exc) { (result) = exc.mError; }                               \
	catch (const std::bad_alloc&) { (result) = kAudio_MemFullError; }                              \
	catch (const OSStatus& catch_err) { (result) = catch_err; }                                    \
	catch (const std::system_error& exc) { (result) = exc.code().value(); }                        \
	catch (...) { (result) = -1; }

#define AUSDK_Require(expr, error) /* NOLINT(cppcoreguidelines-macro-usage) */                     \
	do {                                                                                           \
		if (!(expr)) {                                                                             \
			return error;                                                                          \
		}                                                                                          \
	} while (0) /* NOLINT */

// Check an expected; if it holds an error, return that error.
#define AUSDK_RequireExpected(exp) /* NOLINT(cppcoreguidelines-macro-usage) */                     \
	AUSDK_Require(exp, exp.error())

// Evaluate an expression resulting in an Expected<T>. If the Expected contains an error, return
// the error. Otherwise, unwrap the Expected.
#define AUSDK_UnwrapOrReturnError(_expression)                                                     \
	*({                                                                                            \
		const auto e = (_expression);                                                              \
		if (!e) [[unlikely]]                                                                       \
			return e.error();                                                                      \
		e;                                                                                         \
	})

// TODO: deprecate this macro because it swallows the error
#define AUSDK_UnwrapOrReturnVoid(_expression)                                                      \
	*({                                                                                            \
		const auto e = (_expression);                                                              \
		if (!e) [[unlikely]]                                                                       \
			return;                                                                                \
		e;                                                                                         \
	})

#define AUSDK_CheckReturnError(_expression)                                                        \
	({                                                                                             \
		const auto e = (_expression);                                                              \
		if (!e) [[unlikely]]                                                                       \
			return e.error();                                                                      \
	})

// Evaluate an expression resulting in an Expected<T>. If the Expected contains an error, return
// the error as an Unexpected. Otherwise, unwrap the Expected.
#define AUSDK_UnwrapOrReturnUnexpected(_expression)                                                \
	*({                                                                                            \
		const auto e = (_expression);                                                              \
		if (!e) [[unlikely]]                                                                       \
			return ausdk::Unexpected{ e.error() };                                                 \
		e;                                                                                         \
	})

#define AUSDK_Require_noerr(_expression) /* NOLINT(cppcoreguidelines-macro-usage) */               \
	do {                                                                                           \
		const auto status_tmp_macro_detail_ = (_expression);                                       \
		if (status_tmp_macro_detail_ != noErr) [[unlikely]] {                                      \
			return status_tmp_macro_detail_;                                                       \
		}                                                                                          \
	} while (0)

#define AUSDK_Assert(_expression)                                                                  \
	({                                                                                             \
		const auto e = (_expression);                                                              \
		if (!e) [[unlikely]]                                                                       \
			std::abort();                                                                          \
	})


// clang-format off

// The "loose" realtime-safety contract: exceptions are allowed.
#ifndef AUSDK_LOOSE_RT_SAFETY
	#define AUSDK_LOOSE_RT_SAFETY 1
#endif

// AUSDK adopts `noexcept` independently of `[[clang::nonblocking]]`; suppress diagnostics.
#define AUSDK_BEGIN_NO_RT_NOEXCEPT_WARNINGS \
	_Pragma("clang diagnostic push")                                           \
	_Pragma("clang diagnostic ignored \"-Wunknown-warning-option\"")           \
	_Pragma("clang diagnostic ignored \"-Wperf-constraint-implies-noexcept\"")
#define AUSDK_END_NO_RT_NOEXCEPT_WARNINGS  \
	_Pragma("clang diagnostic pop")

//  ASAN inserts blocking function calls in otherwise nonblocking functions.
#if defined(__has_feature) && __has_feature(address_sanitizer)
#define AUSDK_BEGIN_NO_RT_WARNINGS                                              \
    AUSDK_BEGIN_NO_RT_NOEXCEPT_WARNINGS                                         \
    _Pragma("clang diagnostic ignored \"-Wfunction-effects\"")
#else
#define AUSDK_BEGIN_NO_RT_WARNINGS                                              \
    AUSDK_BEGIN_NO_RT_NOEXCEPT_WARNINGS
#endif

#define AUSDK_END_NO_RT_WARNINGS                                                \
    AUSDK_END_NO_RT_NOEXCEPT_WARNINGS

/*!
	@macro	AUSDK_RTSAFE_TYPE
	@brief	A function type which is guaranteed / required to be realtime safe.
*/
#if defined(__has_attribute) && __has_attribute(nonblocking)
#  ifdef __cplusplus
#    define AUSDK_RTSAFE_TYPE [[clang::nonblocking]]
#  else
#    define AUSDK_RTSAFE_TYPE __attribute__((nonblocking))
#  endif
#else
#    define AUSDK_RTSAFE_TYPE
#endif

#ifndef AUSDK_RTSAFE_SECTION
#  define AUSDK_RTSAFE_SECTION
#endif

/*!
	@macro	AUSDK_RTSAFE
	@brief	Declares a function as `nonblocking`, with a section attribute.
	
	Example placement:
		`void func(int param) AUSDK_RTSAFE;`
*/
#define AUSDK_RTSAFE AUSDK_RTSAFE_TYPE AUSDK_RTSAFE_SECTION

#if AUSDK_LOOSE_RT_SAFETY
	#define AUSDK_RTSAFE_LOOSE AUSDK_RTSAFE
#else
	#define AUSDK_RTSAFE_LOOSE
#endif

/*!
	@macro	AUSDK_RTSAFE_LAMBDA
	@brief	Declares a lambda as `nonblocking`, with a section attribute.
	
	Example placement:
		`auto lambda = [captures](int param) AUSDK_RTSAFE_LAMBDA -> int { ... };`
	
	Note: It's weird and annoying that this has to be different from `AUSDK_RTSAFE`.
*/
#define AUSDK_RTSAFE_LAMBDA AUSDK_RTSAFE_SECTION AUSDK_RTSAFE_TYPE

/*!
	@macro	AUSDK_RT_UNSAFE_BEGIN
	@brief	Begins a region of code as exempt from nonblocking checks.

	N.B. Every use of this is a maintenance and safety liability; use as a last resort.
*/
#define AUSDK_RT_UNSAFE_BEGIN(reason)                                \
	_Pragma("clang diagnostic push")                                 \
	_Pragma("clang diagnostic ignored \"-Wunknown-warning-option\"") \
	_Pragma("clang diagnostic ignored \"-Wfunction-effects\"")

/*!
	@macro	AUSDK_RT_UNSAFE_END
	@brief	Ends a region of code which is exempt from nonblocking checks.
*/
#define AUSDK_RT_UNSAFE_END \
	_Pragma("clang diagnostic pop")

/*!
	@macro	AUSDK_RT_UNSAFE_END
	@brief	Disables nonblocking checks during the evaluation of the expression.

	N.B. Every use of this is a maintenance and safety liability; use as a last resort.
*/
#define AUSDK_RT_UNSAFE(...)                                         \
	_Pragma("clang diagnostic push")                                 \
	_Pragma("clang diagnostic ignored \"-Wunknown-warning-option\"") \
	_Pragma("clang diagnostic ignored \"-Wfunction-effects\"")       \
	__VA_ARGS__                                                      \
	_Pragma("clang diagnostic pop")

// clang-format on

#pragma mark -

// -------------------------------------------------------------------------------------------------

namespace ausdk {

// -------------------------------------------------------------------------------------------------

/// A wrapper to preserve the nonblocking attribute on a function pointer. Copied from the
/// nonblocking proposal.
template <typename>
class RTSafeFP;

template <typename R, typename... Args>
class RTSafeFP<R(Args...)> {
public:
	using impl_t = R (*)(Args...) AUSDK_RTSAFE_TYPE;

private:
	impl_t mImpl;

public:
	RTSafeFP(impl_t f) : mImpl{ f } {}

	R operator()(Args... args) const { return mImpl(std::forward<Args>(args)...); }
};

// deduction guide (copied from std::function)
template <class R, class... ArgTypes>
RTSafeFP(R (*)(ArgTypes...)) -> RTSafeFP<R(ArgTypes...)>;

// -------------------------------------------------------------------------------------------------

/// A subclass of std::runtime_error that holds an OSStatus error.
class AUException : public std::runtime_error {
public:
	explicit AUException(OSStatus err)
		: std::runtime_error{ std::string("OSStatus ") + std::to_string(err) }, mError{ err }
	{
	}

	const OSStatus mError;
};

AUSDK_BEGIN_NO_RT_NOEXCEPT_WARNINGS
[[noreturn]] inline void Throw(OSStatus err) AUSDK_RTSAFE_LOOSE
{
	AUSDK_RT_UNSAFE_BEGIN("Can only log and throw under loose contract")
	AUSDK_LogError("throwing %d", static_cast<int>(err));
	throw AUException{ err };
	AUSDK_RT_UNSAFE_END
}
AUSDK_END_NO_RT_NOEXCEPT_WARNINGS

inline void ThrowExceptionIf(bool condition, OSStatus err)
{
	if (condition) [[unlikely]] {
		Throw(err);
	}
}

AUSDK_BEGIN_NO_RT_NOEXCEPT_WARNINGS
[[noreturn]] inline void ThrowQuiet(OSStatus err) AUSDK_RTSAFE_LOOSE
{
	AUSDK_RT_UNSAFE_BEGIN("Can only throw under loose realtime contract")
	throw AUException{ err };
	AUSDK_RT_UNSAFE_END
}
AUSDK_END_NO_RT_NOEXCEPT_WARNINGS

inline void ThrowQuietIf(bool condition, OSStatus err)
{
	if (condition) [[unlikely]] {
		ThrowQuiet(err);
	}
}

// -------------------------------------------------------------------------------------------------

/// Wrap a std::recursive_mutex in a C++ Mutex (named requirement). Methods are virtual to support
/// customization.
class AUMutex {
public:
	AUMutex() = default;
	virtual ~AUMutex() = default;

	AUMutex(const AUMutex&) = delete;
	AUMutex(AUMutex&&) = delete;
	AUMutex& operator=(const AUMutex&) = delete;
	AUMutex& operator=(AUMutex&&) = delete;

	virtual void lock() { mImpl.lock(); }
	virtual void unlock() noexcept { mImpl.unlock(); }
	virtual bool try_lock() noexcept { return mImpl.try_lock(); }

private:
	std::recursive_mutex mImpl;
};

// -------------------------------------------------------------------------------------------------

/// Implement optional locking at AudioUnit non-realtime entry points (required only for a small
/// number of plug-ins which must synchronize against external entry points).
class AUEntryGuard {
public:
	explicit AUEntryGuard(AUMutex* maybeMutex) : mMutex{ maybeMutex }
	{
		if (mMutex != nullptr) {
			mMutex->lock();
		}
	}

	~AUEntryGuard() noexcept
	{
		if (mMutex != nullptr) {
			mMutex->unlock();
		}
	}

	AUEntryGuard(const AUEntryGuard&) = delete;
	AUEntryGuard(AUEntryGuard&&) = delete;
	AUEntryGuard& operator=(const AUEntryGuard&) = delete;
	AUEntryGuard& operator=(AUEntryGuard&&) = delete;

private:
	AUMutex* mMutex;
};

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark ASBD

/// Utility functions relating to AudioStreamBasicDescription.
namespace ASBD {

constexpr bool IsInterleaved(const AudioStreamBasicDescription& format) noexcept
{
	return (format.mFormatFlags & kLinearPCMFormatFlagIsNonInterleaved) == 0u;
}

constexpr UInt32 NumberInterleavedChannels(const AudioStreamBasicDescription& format) noexcept
{
	return IsInterleaved(format) ? format.mChannelsPerFrame : 1;
}

constexpr UInt32 NumberChannelStreams(const AudioStreamBasicDescription& format) noexcept
{
	return IsInterleaved(format) ? 1 : format.mChannelsPerFrame;
}

constexpr bool IsCommonFloat32(const AudioStreamBasicDescription& format) noexcept
{
	return (
		format.mFormatID == kAudioFormatLinearPCM && format.mFramesPerPacket == 1 &&
		format.mBytesPerPacket == format.mBytesPerFrame
		// so far, it's a valid PCM format
		&& (format.mFormatFlags & kLinearPCMFormatFlagIsFloat) != 0 &&
		(format.mChannelsPerFrame == 1 ||
			(format.mFormatFlags & kAudioFormatFlagIsNonInterleaved) != 0) &&
		((format.mFormatFlags & kAudioFormatFlagIsBigEndian) == kAudioFormatFlagsNativeEndian) &&
		format.mBitsPerChannel == 32 // NOLINT
		&& format.mBytesPerFrame == NumberInterleavedChannels(format) * sizeof(float));
}

constexpr AudioStreamBasicDescription CreateCommonFloat32(
	Float64 sampleRate, UInt32 numChannels, bool interleaved = false) noexcept
{
	constexpr auto sampleSize = sizeof(Float32);

	AudioStreamBasicDescription asbd{};
	asbd.mFormatID = kAudioFormatLinearPCM;
	asbd.mFormatFlags = kAudioFormatFlagIsFloat |
						static_cast<AudioFormatFlags>(kAudioFormatFlagsNativeEndian) |
						kAudioFormatFlagIsPacked;
	asbd.mBitsPerChannel = 8 * sampleSize; // NOLINT magic number
	asbd.mChannelsPerFrame = numChannels;
	asbd.mFramesPerPacket = 1;
	asbd.mSampleRate = sampleRate;
	if (interleaved) {
		asbd.mBytesPerPacket = asbd.mBytesPerFrame = numChannels * sampleSize;
	} else {
		asbd.mBytesPerPacket = asbd.mBytesPerFrame = sampleSize;
		asbd.mFormatFlags |= kAudioFormatFlagIsNonInterleaved;
	}
	return asbd;
}

constexpr bool MinimalSafetyCheck(const AudioStreamBasicDescription& x) noexcept
{
	// This function returns false if there are sufficiently unreasonable values in any field.
	// It is very conservative so even some very unlikely values will pass.
	// This is just meant to catch the case where the data from a file is corrupted.

	return (x.mSampleRate >= 0.) && (x.mSampleRate < 3e6) // NOLINT SACD sample rate is 2.8224 MHz
		   && (x.mBytesPerPacket < 1000000)               // NOLINT
		   && (x.mFramesPerPacket < 1000000)              // NOLINT
		   && (x.mBytesPerFrame < 1000000)                // NOLINT
		   && (x.mChannelsPerFrame > 0) && (x.mChannelsPerFrame <= 1024) // NOLINT
		   && (x.mBitsPerChannel <= 1024)                                // NOLINT
		   && (x.mFormatID != 0) &&
		   !(x.mFormatID == kAudioFormatLinearPCM &&
			   (x.mFramesPerPacket != 1 || x.mBytesPerPacket != x.mBytesPerFrame));
}

inline bool IsEqual(
	const AudioStreamBasicDescription& lhs, const AudioStreamBasicDescription& rhs) noexcept
{
	return memcmp(&lhs, &rhs, sizeof(AudioStreamBasicDescription)) == 0;
}

} // namespace ASBD

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark ACL

/// Utility functions relating to AudioChannelLayout.
namespace ACL {

constexpr bool operator==(const AudioChannelLayout& lhs, const AudioChannelLayout& rhs) noexcept
{
	if (lhs.mChannelLayoutTag != rhs.mChannelLayoutTag) {
		return false;
	}
	if (lhs.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) {
		return lhs.mChannelBitmap == rhs.mChannelBitmap;
	}
	if (lhs.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) {
		if (lhs.mNumberChannelDescriptions != rhs.mNumberChannelDescriptions) {
			return false;
		}
		for (UInt32 i = 0; i < lhs.mNumberChannelDescriptions; ++i) {
			const auto& lhdesc = lhs.mChannelDescriptions[i]; // NOLINT array subscript
			const auto& rhdesc = rhs.mChannelDescriptions[i]; // NOLINT array subscript

			if (lhdesc.mChannelLabel != rhdesc.mChannelLabel) {
				return false;
			}
			if (lhdesc.mChannelLabel == kAudioChannelLabel_UseCoordinates) {
				if (memcmp(&lhdesc, &rhdesc, sizeof(AudioChannelDescription)) != 0) {
					return false;
				}
			}
		}
	}
	return true;
}

} // namespace ACL

// -------------------------------------------------------------------------------------------------

/// Utility wrapper for the variably-sized AudioChannelLayout struct.
class AUChannelLayout {
public:
	AUChannelLayout() : AUChannelLayout(0, kAudioChannelLayoutTag_UseChannelDescriptions, 0) {}

	/// Can construct from a layout tag.
	explicit AUChannelLayout(AudioChannelLayoutTag inTag) : AUChannelLayout(0, inTag, 0) {}

	AUChannelLayout(uint32_t inNumberChannelDescriptions, AudioChannelLayoutTag inChannelLayoutTag,
		AudioChannelBitmap inChannelBitMap)
		: mStorage(ObjectCountForByteSize(DataByteSize(inNumberChannelDescriptions)))
	{
		auto& acl = mStorage.front();
		acl.mChannelLayoutTag = inChannelLayoutTag;
		acl.mChannelBitmap = inChannelBitMap;
		acl.mNumberChannelDescriptions = inNumberChannelDescriptions;
	}

	/// Implicit conversion from AudioChannelLayout& is allowed.
	AUChannelLayout(const AudioChannelLayout& acl) // NOLINT
		: mStorage(ObjectCountForByteSize(DataByteSize(acl.mNumberChannelDescriptions)))
	{
		std::memcpy(mStorage.data(), &acl, DataByteSize(acl.mNumberChannelDescriptions));
	}

	~AUChannelLayout() noexcept = default;
	AUChannelLayout(AUChannelLayout&&) noexcept = default;
	AUChannelLayout& operator=(AUChannelLayout&&) noexcept = default;

	// copy overloads required because AudioChannelLayout deletes them
	AUChannelLayout(const AUChannelLayout& other) { CopyStorage(other); }

	AUChannelLayout& operator=(const AUChannelLayout& other)
	{
		CopyStorage(other);
		return *this;
	}

	bool operator==(const AUChannelLayout& other) const noexcept
	{
		return ACL::operator==(Layout(), other.Layout());
	}

	bool operator!=(const AUChannelLayout& other) const noexcept { return !(*this == other); }

	[[nodiscard]] bool IsValid() const noexcept { return NumberChannels() > 0; }

	[[nodiscard]] const AudioChannelLayout& Layout() const noexcept { return mStorage.front(); }

	[[nodiscard]] const AudioChannelLayout* LayoutPtr() const noexcept { return mStorage.data(); }

	/// After default construction, this method will return
	/// kAudioChannelLayoutTag_UseChannelDescriptions with 0 channel descriptions.
	[[nodiscard]] AudioChannelLayoutTag Tag() const noexcept { return Layout().mChannelLayoutTag; }

	[[nodiscard]] uint32_t NumberChannels() const noexcept { return NumberChannels(Layout()); }

	[[nodiscard]] uint32_t Size() const noexcept
	{
		return static_cast<uint32_t>(DataByteSize(Layout().mNumberChannelDescriptions));
	}

	static uint32_t NumberChannels(const AudioChannelLayout& inLayout) noexcept
	{
		if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelDescriptions) {
			return inLayout.mNumberChannelDescriptions;
		}
		if (inLayout.mChannelLayoutTag == kAudioChannelLayoutTag_UseChannelBitmap) {
			constexpr size_t bitWidth = sizeof(inLayout.mChannelBitmap) * CHAR_BIT;
			return static_cast<uint32_t>(std::bitset<bitWidth>(inLayout.mChannelBitmap).count());
		}
		return AudioChannelLayoutTag_GetNumberOfChannels(inLayout.mChannelLayoutTag);
	}

	static constexpr size_t DataByteSize(uint32_t inNumberChannelDescriptions) noexcept
	{
		constexpr size_t headerSize = offsetof(AudioChannelLayout, mChannelDescriptions);
		return headerSize + (inNumberChannelDescriptions * sizeof(AudioChannelDescription));
	}

private:
	// number of contiguous ACL objects required to accommodate a specific storage size
	static constexpr size_t ObjectCountForByteSize(size_t inDataByteSize) noexcept
	{
		const size_t padding = ((inDataByteSize % sizeof(AudioChannelLayout)) > 0) ? 1 : 0;
		return (inDataByteSize / sizeof(AudioChannelLayout)) + padding;
	}

	void CopyStorage(const AUChannelLayout& inSource)
	{
		mStorage = decltype(mStorage)(inSource.mStorage.size());
		std::memcpy(
			mStorage.data(), inSource.mStorage.data(), std::span(inSource.mStorage).size_bytes());
	}

	// the data representation is not literally an array of these entire objects, however using it
	// as the underlying storage data type ensures object lifetime and alignment of the data pointer
	std::vector<AudioChannelLayout> mStorage;
};

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark AudioBufferList

/// Utility functions relating to AudioBufferList.
namespace ABL {

// if the return result is odd, there was a null buffer.
constexpr uint32_t IsBogusAudioBufferList(const AudioBufferList& abl)
{
	const AudioBuffer *buf = abl.mBuffers, *const bufEnd = buf + abl.mNumberBuffers;
	uint32_t sum =
		0; // defeat attempts by the compiler to optimize away the code that touches the buffers
	uint32_t anyNull = 0;
	for (; buf < bufEnd; ++buf) {
		const uint32_t* const p = static_cast<const uint32_t*>(buf->mData);
		if (p == nullptr) {
			anyNull = 1;
			continue;
		}
		const auto dataSize = buf->mDataByteSize;
		if (dataSize >= sizeof(*p)) {
			const size_t frameCount = dataSize / sizeof(*p);
			sum += p[0];
			sum += p[frameCount - 1];
		}
	}
	return anyNull | (sum & ~1u);
}

} // namespace ABL

// -------------------------------------------------------------------------------------------------
#pragma mark -
#pragma mark HostTime

#if AUSDK_HAVE_MACH_TIME
AUSDK_BEGIN_NO_RT_WARNINGS

/// Utility functions relating to Mach absolute time.
namespace HostTime {

/// Returns the current host time
inline uint64_t Current() AUSDK_RTSAFE { return AUSDK_RT_UNSAFE(mach_absolute_time()); }

/// Returns the frequency of the host timebase, in ticks per second.
inline double Frequency()
{
	struct mach_timebase_info timeBaseInfo {}; // NOLINT
	mach_timebase_info(&timeBaseInfo);
	//	the frequency of that clock is: (sToNanosDenominator / sToNanosNumerator) * 10^9
	return static_cast<double>(timeBaseInfo.denom) / static_cast<double>(timeBaseInfo.numer) *
		   1.0e9; // NOLINT
}

} // namespace HostTime
AUSDK_END_NO_RT_WARNINGS
#endif // AUSDK_HAVE_MACH_TIME

// -------------------------------------------------------------------------------------------------
#pragma mark -

/// Basic RAII wrapper for CoreFoundation types
template <typename T>
	requires std::is_pointer_v<T>
class Owned {
	explicit Owned(T obj, bool fromget) noexcept : mImpl{ obj }
	{
		if (fromget) {
			retainRef();
		}
	}

public:
	static Owned from_get(T obj) noexcept { return Owned{ obj, true }; }

	static Owned from_create(T obj) noexcept { return Owned{ obj, false }; }
	static Owned from_copy(T obj) noexcept { return Owned{ obj, false }; }

	Owned() noexcept = default;
	~Owned() noexcept { releaseRef(); }

	Owned(const Owned& other) noexcept : mImpl{ other.mImpl } { retainRef(); }

	Owned(Owned&& other) noexcept : mImpl{ std::exchange(other.mImpl, nullptr) } {}

	Owned& operator=(const Owned& other) noexcept
	{
		if (this != &other) {
			releaseRef();
			mImpl = other.mImpl;
			retainRef();
		}
		return *this;
	}

	Owned& operator=(Owned&& other) noexcept
	{
		std::swap(mImpl, other.mImpl);
		return *this;
	}

	T operator*() const noexcept { return get(); }
	T get() const noexcept { return mImpl; }

	/// As with `unique_ptr<T>::release()`, releases ownership of the reference to the caller (not
	/// to be confused with decrementing the reference count as with `CFRelease()`).
	T release() noexcept { return std::exchange(mImpl, nullptr); }

	/// This is a from_get operation.
	Owned& operator=(T cfobj) noexcept
	{
		if (mImpl != cfobj) {
			releaseRef();
			mImpl = cfobj;
			retainRef();
		}
		return *this;
	}

private:
	void retainRef() noexcept
	{
		if (mImpl != nullptr) {
			CFRetain(mImpl);
		}
	}

	void releaseRef() noexcept
	{
		if (mImpl != nullptr) {
			CFRelease(mImpl);
		}
	}

	T mImpl{ nullptr };
};

// -------------------------------------------------------------------------------------------------
#pragma mark -

template <typename T>
concept TriviallyCopySerializable = std::is_trivially_copyable_v<T> && std::is_standard_layout_v<T>;

// copy object data to arbitrary memory address that may not share object alignment
void Serialize(const TriviallyCopySerializable auto& inValue, void* outData) noexcept
{
	std::memcpy(outData, std::addressof(inValue), sizeof(inValue));
}

template <TriviallyCopySerializable T, std::size_t Extent>
void Serialize(std::span<T, Extent> inValues, void* outData) noexcept
{
	std::memcpy(outData, inValues.data(), inValues.size_bytes());
}

// ensure object lifetime and alignment of object data from opaque pointer
template <TriviallyCopySerializable T>
	requires std::is_nothrow_default_constructible_v<T> && (!std::is_const_v<T>)
T Deserialize(const void* inData) noexcept
{
	T result{};
	std::memcpy(std::addressof(result), inData, sizeof(result));
	return result;
}

template <TriviallyCopySerializable T>
	requires std::is_default_constructible_v<T> && (!std::is_const_v<T>)
std::vector<T> DeserializeArray(const void* inData, size_t inSizeBytes)
{
	std::vector<T> result(inSizeBytes / sizeof(T));
	std::memcpy(result.data(), inData, std::span(result).size_bytes());
	return result;
}

inline UInt32 DeserializeBigUInt32AndAdvance(const UInt8*& ioData) noexcept
{
	const auto value = Deserialize<UInt32>(ioData);
	ioData += sizeof(value); // NOLINT
	return CFSwapInt32BigToHost(value);
}

inline std::string MakeStringFrom4CC(uint32_t in4CC)
{
	in4CC = CFSwapInt32HostToBig(in4CC);

	constexpr auto safeIsPrint = [](char character) {
		return (character >= ' ') && (character <= '~');
	};

	char* const string = reinterpret_cast<char*>(&in4CC); // NOLINT
	for (size_t i = 0; i < sizeof(in4CC); ++i) {
		if (!safeIsPrint(string[i])) { // NOLINT
			string[i] = '.';           // NOLINT
		}
	}
	return std::string{ string, sizeof(in4CC) };
}

using Unexpected = std::unexpected<OSStatus>;

template <typename T>
using Expected = std::expected<T, OSStatus>;

// expected<reference_wrapper<T>> is unweildy.
// Instead, extend expected<T*> (with a guarantee that the pointer is non-null).
template <typename T>
class [[nodiscard]] ExpectedPtr : public std::expected<T*, OSStatus> {
public:
	using Base = std::expected<T*, OSStatus>;

	// Caution: default-constructed to null ptr.
	ExpectedPtr() = default;

	// Construct with a reference, to enforce non-null guarantee (unless default-constructed).
	ExpectedPtr(T& ref) : Base{ &ref } {} // NOLINT implicit OK

	ExpectedPtr(Unexpected&& u) : Base{ u } {} // NOLINT implicit OK

	// unchecked (parallel to expected::operator*); use operator bool to verify
	T* operator->() const { return Base::operator*(); }
	T* get() const { return Base::operator*(); }
	T& operator*() const { return *get(); }
};

template <typename T>
inline void ThrowExceptionIfUnexpected(const Expected<T>& e)
{
	if (!e) [[unlikely]] {
		Throw(e.error());
	}
}

} // namespace ausdk

#endif // AudioUnitSDK_AUUtility_h


================================================
FILE: include/AudioUnitSDK/AudioUnitSDK.h
================================================
/*!
	@file		AudioUnitSDK/AudioUnitSDK.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_h
#define AudioUnitSDK_h

// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUBase.h>
#include <AudioUnitSDK/AUBuffer.h>
#include <AudioUnitSDK/AUEffectBase.h>
#include <AudioUnitSDK/AUInputElement.h>
#if AUSDK_HAVE_MIDI
#include <AudioUnitSDK/AUMIDIBase.h>
#include <AudioUnitSDK/AUMIDIEffectBase.h>
#endif // AUSDK_HAVE_MIDI
#include <AudioUnitSDK/AUOutputElement.h>
#include <AudioUnitSDK/AUPlugInDispatch.h>
#include <AudioUnitSDK/AUScopeElement.h>
#include <AudioUnitSDK/AUSilentTimeout.h>
#include <AudioUnitSDK/AUUtility.h>
#include <AudioUnitSDK/ComponentBase.h>
#if AUSDK_HAVE_MUSIC_DEVICE
#include <AudioUnitSDK/MusicDeviceBase.h>
#endif // AUSDK_HAVE_MUSIC_DEVICE

#endif /* AudioUnitSDK_h */


================================================
FILE: include/AudioUnitSDK/ComponentBase.h
================================================
/*!
	@file		AudioUnitSDK/ComponentBase.h
	@copyright	© 2000-2025 Apple Inc. All rights reserved.
*/
#ifndef AudioUnitSDK_ComponentBase_h
#define AudioUnitSDK_ComponentBase_h

// module
// clang-format off
#include <AudioUnitSDK/AUConfig.h> // must come first
// clang-format on
#include <AudioUnitSDK/AUUtility.h>

// OS
#include <AudioToolbox/AudioComponent.h>

// std
#include <array>
#include <mutex>
#include <new>

namespace ausdk {

/*!
	@class	ComponentBase
	@brief	Base class for implementing an `AudioComponentInstance`.
*/
class ComponentBase {
public:
	/// Construct given an AudioComponentInstance, typically from APFactory::Constuct.
	explicit ComponentBase(AudioComponentInstance inInstance);

	virtual ~ComponentBase() = default;

	ComponentBase(const ComponentBase&) = delete;
	ComponentBase(ComponentBase&&) = delete;
	ComponentBase& operator=(const ComponentBase&) = delete;
	ComponentBase& operator=(ComponentBase&&) = delete;

	/// Called from dispatchers after constructing an instance.
	void DoPostConstructor();

	/// Called from dispatchers before destroying an instance.
	void DoPreDestructor();

	/// Obtain the wrapped `AudioComponentInstance` (underlying type of `AudioUnit`, `AudioCodec`,
	/// and others).
	[[nodiscard]] AudioComponentInstance GetComponentInstance() const noexcept
	{
		return mComponentInstance;
	}

	/// Return the instance's `AudioComponentDescription`.
	[[nodiscard]] AudioComponentDescription GetComponentDescription() const;

	/// Component dispatch method.
	static OSStatus AP_Open(void* self, AudioComponentInstance compInstance);

	/// Component dispatch method.
	static OSStatus AP_Close(void* self);

	/// A mutex which is held during `Open`, since some AU's and the Component Manager itself
	/// are not thread-safe against globals.
	static std::recursive_mutex& InitializationMutex();

protected:
	// subclasses are free to to override these methods to add functionality
	virtual void PostConstructor() {}
	virtual void PreDestructor() {}
	// these methods, however, are reserved for override only within this SDK
	virtual void PostConstructorInternal() {}
	virtual void PreDestructorInternal() {}

private:
	AudioComponentInstance mComponentInstance;
};

/*!
	@class	AudioComponentPlugInInstance
	@brief	Object which implements an AudioComponentPlugInInterface for the framework, and
			which holds the C++ implementation object.
*/
struct AudioComponentPlugInInstance {
	// The AudioComponentPlugInInterface must remain first
	AudioComponentPlugInInterface mPlugInInterface{};

	void* (*mConstruct)(void* memory, AudioComponentInstance ci){ nullptr };

	void (*mDestruct)(void* memory){ nullptr };

	std::array<void*, 2> mPad{}; // pad to a 16-byte boundary (in either 32 or 64 bit mode)
	// the ACI implementation object is constructed into this memory
	// (this member is just a placeholder. it is aligned to a 16-byte boundary)
	UInt32 mInstanceStorage{ 0 };
};

/*!
	@class	APFactory
	@tparam	APMethodLookup	A class (e.g. AUBaseLookup) which provides a method selector lookup
							function.
	@tparam	Implementor		The class which implements the full plug-in (AudioUnit) interface.
	@brief	Provides an AudioComponentFactoryFunction and a convenience wrapper for
			AudioComponentRegister.
*/
template <class APMethodLookup, class Implementor>
class APFactory {
public:
	static void* Construct(void* memory, AudioComponentInstance compInstance)
	{
		return new (memory) Implementor(compInstance); // NOLINT manual memory management
	}

	static void Destruct(void* memory) { static_cast<Implementor*>(memory)->~Implementor(); }

	// This is the AudioComponentFactoryFunction. It returns an AudioComponentPlugInInstance.
	// The actual implementation object is not created until Open().
	static AudioComponentPlugInInterface* Factory(const AudioComponentDescription* /* inDesc */)
	{
		auto* const acpi =                                     // NOLINT owning memory
			static_cast<AudioComponentPlugInInstance*>(malloc( // NOLINT manual memory management
				offsetof(AudioComponentPlugInInstance, mInstanceStorage) + sizeof(Implementor)));
		acpi->mPlugInInterface.Open = ComponentBase::AP_Open;
		acpi->mPlugInInterface.Close = ComponentBase::AP_Close;
		acpi->mPlugInInterface.Lookup = APMethodLookup::Lookup;
		acpi->mPlugInInterface.reserved = nullptr;
		acpi->mConstruct = Construct;
		acpi->mDestruct = Destruct;
		acpi->mPad.fill(nullptr);
		return &acpi->mPlugInInterface;
	}

	// This is for runtime registration (not for plug-ins loaded from bundles).
	static AudioComponent Register(
		UInt32 type, UInt32 subtype, UInt32 manuf, CFStringRef name, UInt32 vers, UInt32 flags = 0)
	{
		const AudioComponentDescription desc = { type, subtype, manuf, flags, 0 };
		return AudioComponentRegister(&desc, name, vers, Factory);
	}
};

#ifndef AUSDK_EXPORT
#if __GNUC__
#define AUSDK_EXPORT __attribute__((visibility("default"))) // NOLINT
#else
#warning export?
#endif
#endif


/// Macro to generate the factory function for the specified Audio Component. Factory is an
/// APFactory such as AUBaseFactory. Class is the name of the final ComponentBas
Download .txt
gitextract_ldpfski0/

├── .github/
│   └── pull_request_template.md
├── .gitignore
├── AudioUnitSDK.xcodeproj/
│   ├── project.pbxproj
│   └── xcshareddata/
│       └── xcschemes/
│           ├── AudioUnitSDK.xcscheme
│           ├── EmptyPlugIns.xcscheme
│           └── Tests.xcscheme
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── _clang-format
├── _clang-tidy
├── demos/
│   └── EmptyPlugIns/
│       ├── EmptyPlugIns.cpp
│       └── Info.plist
├── hooks/
│   ├── install.sh
│   └── pre-commit
├── include/
│   └── AudioUnitSDK/
│       ├── AUBase.h
│       ├── AUBuffer.h
│       ├── AUConfig.h
│       ├── AUEffectBase.h
│       ├── AUInputElement.h
│       ├── AUMIDIBase.h
│       ├── AUMIDIEffectBase.h
│       ├── AUMIDIUtility.h
│       ├── AUOutputElement.h
│       ├── AUPlugInDispatch.h
│       ├── AUScopeElement.h
│       ├── AUSilentTimeout.h
│       ├── AUThreadSafeList.h
│       ├── AUUtility.h
│       ├── AudioUnitSDK.h
│       ├── ComponentBase.h
│       └── MusicDeviceBase.h
├── readme.md
├── src/
│   └── AudioUnitSDK/
│       ├── AUBase.cpp
│       ├── AUBuffer.cpp
│       ├── AUBufferAllocator.cpp
│       ├── AUEffectBase.cpp
│       ├── AUInputElement.cpp
│       ├── AUMIDIBase.cpp
│       ├── AUMIDIEffectBase.cpp
│       ├── AUOutputElement.cpp
│       ├── AUPlugInDispatch.cpp
│       ├── AUScopeElement.cpp
│       ├── ComponentBase.cpp
│       └── MusicDeviceBase.cpp
├── tests/
│   ├── AUThreadSafeListTests.mm
│   ├── Info.plist
│   └── Tests.mm
└── tools/
    ├── FindUB.sh
    └── build.sh
Download .txt
SYMBOL INDEX (288 symbols across 27 files)

FILE: demos/EmptyPlugIns/EmptyPlugIns.cpp
  class AUBase_Derived (line 11) | class AUBase_Derived : public ausdk::AUBase {
    method AUBase_Derived (line 15) | explicit AUBase_Derived(AudioComponentInstance ci) : Base{ ci, 1, 1 } {}
    method StreamFormatWritable (line 17) | bool StreamFormatWritable(AudioUnitScope, AudioUnitElement) override {...
    method AUSDK_RTSAFE (line 19) | AUSDK_RTSAFE override { return false; }
  class AUEffectBase_Derived (line 26) | class AUEffectBase_Derived : public ausdk::AUEffectBase {
    method AUEffectBase_Derived (line 30) | explicit AUEffectBase_Derived(AudioComponentInstance ci) : Base{ ci, t...
  class MusicDeviceBase_Derived (line 37) | class MusicDeviceBase_Derived : public ausdk::MusicDeviceBase {
    method MusicDeviceBase_Derived (line 41) | explicit MusicDeviceBase_Derived(AudioComponentInstance ci) : Base{ ci...
    method StreamFormatWritable (line 43) | bool StreamFormatWritable(AudioUnitScope, AudioUnitElement) override {...
    method AUSDK_RTSAFE (line 45) | AUSDK_RTSAFE override { return false; }

FILE: include/AudioUnitSDK/AUBase.h
  function namespace (line 44) | namespace ausdk {
  function HasInput (line 474) | bool HasInput(AudioUnitElement inElement)
  function OSStatus (line 489) | OSStatus CallHostBeatAndTempo(Float64* outCurrentBeat, Float64* outCurre...
  function OSStatus (line 497) | OSStatus CallHostMusicalTimeLocation(UInt32* outDeltaSampleOffsetToNextB...
  function OSStatus (line 508) | OSStatus CallHostTransportState(Boolean* outIsPlaying, Boolean* outTrans...
  function AUMutex (line 521) | AUMutex* GetMutex() noexcept { return mAUMutex; }
  function SetMutex (line 525) | void SetMutex(AUMutex* mutex) noexcept { mAUMutex = mutex; }
  function virtual (line 533) | virtual OSStatus Start() { return kAudio_UnimplementedError; }
  function virtual (line 535) | virtual OSStatus Stop() { return kAudio_UnimplementedError; }
  function virtual (line 544) | virtual OSStatus MIDIEvent(UInt32 /*inStatus*/, UInt32 /*inData1*/, UInt...
  function virtual (line 550) | virtual OSStatus SysEx(const UInt8* /*inData*/, UInt32 /*inLength*/) AUS...
  function virtual (line 556) | virtual OSStatus MIDIEventList(
  function virtual (line 564) | virtual OSStatus StartNote(MusicDeviceInstrumentID /*inInstrument*/,
  function virtual (line 571) | virtual OSStatus StopNote(MusicDeviceGroupID /*inGroupID*/, NoteInstance...
  function OSStatus (line 578) | static OSStatus PrepareInstrument(MusicDeviceInstrumentID /*inInstrument*/)
  function OSStatus (line 584) | static OSStatus ReleaseInstrument(MusicDeviceInstrumentID /*inInstrument*/)
  function PostConstructorInternal (line 597) | void PostConstructorInternal() final;
  function HasClump (line 617) | static void HasClump(AudioUnitParameterInfo& ioInfo, UInt32 inClumpID) n...
  function virtual (line 625) | [[nodiscard]] virtual OSStatus CanSetMaxFrames() const;
  type PropertyListener (line 642) | struct PropertyListener {
  function AudioUnitPropertyListenerProc (line 644) | AudioUnitPropertyListenerProc listenerProc{ nullptr };
  function AudioTimeStamp (line 798) | AudioTimeStamp mCurrentRenderTime{}
  function UInt32 (line 799) | UInt32 mMaxFramesPerSlice{ 0 }
  function mLastTimeMessagePrinted (line 805) | uint64_t mLastTimeMessagePrinted{ 0 }
  function mBuffersAllocated (line 812) | bool mBuffersAllocated{ false };

FILE: include/AudioUnitSDK/AUBuffer.h
  function AUSDK_BEGIN_NO_RT_WARNINGS (line 19) | AUSDK_BEGIN_NO_RT_WARNINGS
  function class (line 60) | class BufferAllocator {
  function class (line 84) | class AUBufferList {

FILE: include/AudioUnitSDK/AUEffectBase.h
  function namespace (line 17) | namespace ausdk {
  function virtual (line 73) | virtual std::unique_ptr<AUKernelBase> NewKernel() { return {}; }
  function Float64 (line 79) | Float64 GetSampleRate() AUSDK_RTSAFE { return GetOutput0().GetStreamForm...
  function UInt32 (line 80) | UInt32 GetNumberOfChannels() AUSDK_RTSAFE
  function SetParameter (line 90) | void SetParameter(AudioUnitParameterID paramID, AudioUnitParameterValue ...
  function AudioUnitParameterValue (line 97) | AudioUnitParameterValue GetParameter(AudioUnitParameterID paramID) AUSDK...
  function CanScheduleParameters (line 102) | [[nodiscard]] bool CanScheduleParameters() const AUSDK_RTSAFE override {...
  function virtual (line 107) | virtual void SetBypassEffect(bool inFlag) { mBypassEffect = inFlag; }
  function SetParamHasSampleRateDependency (line 109) | void SetParamHasSampleRateDependency(bool inFlag) noexcept { mParamSRDep...
  function GetParamHasSampleRateDependency (line 110) | [[nodiscard]] bool GetParamHasSampleRateDependency() const noexcept { re...
  function SetProcessesInPlace (line 123) | void SetProcessesInPlace(bool inProcessesInPlace) noexcept
  function virtual (line 135) | virtual bool ShouldBypassEffect() AUSDK_RTSAFE { return IsBypassEffect(); }
  function AUKernelBase (line 137) | [[nodiscard]] AUKernelBase* GetKernel(UInt32 index) const
  function KernelList (line 141) | [[nodiscard]] const KernelList& GetKernelList() const noexcept { return ...
  function SetOnlyOneKernel (line 155) | void SetOnlyOneKernel(bool inUseOnlyOneKernel) noexcept
  function mParamSRDep (line 164) | bool mParamSRDep{ false };

FILE: include/AudioUnitSDK/AUInputElement.h
  function NeedsBufferSpace (line 33) | [[nodiscard]] bool NeedsBufferSpace() const override { return IsCallback...
  type class (line 57) | enum class
  function AURenderCallback (line 61) | AURenderCallback mInputProc{ nullptr };

FILE: include/AudioUnitSDK/AUMIDIBase.h
  function class (line 29) | class AUMIDIMapper {

FILE: include/AudioUnitSDK/AUMIDIEffectBase.h
  function namespace (line 14) | namespace ausdk {

FILE: include/AudioUnitSDK/AUOutputElement.h
  function namespace (line 15) | namespace ausdk {

FILE: include/AudioUnitSDK/AUPlugInDispatch.h
  function namespace (line 13) | namespace ausdk {

FILE: include/AudioUnitSDK/AUScopeElement.h
  function namespace (line 26) | namespace ausdk {
  function keyless (line 80) | static bool keyless(const KVPair& item, Key k) AUSDK_RTSAFE { return k >...
  function iterator (line 92) | iterator begin() noexcept { return mImpl.begin(); }
  function iterator (line 93) | iterator end() noexcept { return mImpl.end(); }
  function const_iterator (line 94) | const_iterator cbegin() noexcept { return mImpl.cbegin(); }
  function const_iterator (line 95) | const_iterator cend() noexcept { return mImpl.cend(); }
  function const_iterator (line 97) | [[nodiscard]] const_iterator lower_bound(Key k) const
  function iterator (line 102) | iterator lower_bound(Key k)
  function const_iterator (line 107) | [[nodiscard]] const_iterator find(Key k) const
  function iterator (line 118) | iterator find(Key k)
  function class (line 129) | class ItemProxy {
  function ItemProxy (line 158) | ItemProxy operator[](Key k) { return ItemProxy{ *this, k }; }
  function class (line 166) | class AUElement {
  function noexcept (line 239) | const noexcept { return mAudioUnit; }
  function noexcept (line 244) | const noexcept { return mElementName; }
  function SetName (line 245) | void SetName(CFStringRef inName) noexcept { mElementName = inName; }
  function HasName (line 247) | [[nodiscard]] bool HasName() const noexcept { return *mElementName != nu...
  function class (line 269) | class AUIOElement : public AUElement {
  function SetBuffer (line 336) | void SetBuffer(UInt32 index, AudioBuffer& ab) { mIOBuffer.SetBuffer(inde...
  function InvalidateBufferList (line 343) | void InvalidateBufferList() { mIOBuffer.InvalidateBufferList(); }
  function AUSDK_RTSAFE (line 347) | const AUSDK_RTSAFE
  function CopyBufferListTo (line 374) | void CopyBufferListTo(AudioBufferList& abl) const { mIOBuffer.CopyBuffer...
  function CopyBufferContentsTo (line 375) | void CopyBufferContentsTo(AudioBufferList& abl) const { mIOBuffer.CopyBu...
  function AUSDK_RTSAFE (line 377) | const AUSDK_RTSAFE
  function AUSDK_RTSAFE (line 381) | const AUSDK_RTSAFE
  function IsInterleaved (line 386) | [[nodiscard]] bool IsInterleaved() const noexcept { return ASBD::IsInter...
  function UInt32 (line 388) | [[nodiscard]] UInt32 NumberInterleavedChannels() const noexcept
  function ForceSetAudioChannelLayout (line 407) | void ForceSetAudioChannelLayout(const AudioChannelLayout& inLayout)
  function AUChannelLayout (line 414) | AUChannelLayout mChannelLayout{}
  function mWillAllocate (line 417) | bool mWillAllocate{ false };
  function class (line 428) | class AUScopeDelegate {
  function AudioUnitScope (line 455) | AudioUnitScope mScope{ 0 };
  function class (line 464) | class AUScope {
  function HasElementWithName (line 541) | [[nodiscard]] bool HasElementWithName() const;
  function AUBase (line 556) | AUBase* mCreator{ nullptr };

FILE: include/AudioUnitSDK/AUSilentTimeout.h
  function namespace (line 16) | namespace ausdk {

FILE: include/AudioUnitSDK/AUThreadSafeList.h
  function namespace (line 19) | namespace ausdk {

FILE: include/AudioUnitSDK/AUUtility.h
  function namespace (line 238) | namespace ausdk {
  function class (line 268) | class AUException : public std::runtime_error {
  function AUSDK_BEGIN_NO_RT_NOEXCEPT_WARNINGS (line 278) | AUSDK_BEGIN_NO_RT_NOEXCEPT_WARNINGS
  function class (line 487) | class AUChannelLayout {
  function mStorage (line 505) | AUChannelLayout(const AudioChannelLayout& acl) // NOLINT
  function IsValid (line 531) | [[nodiscard]] bool IsValid() const noexcept { return NumberChannels() > ...
  function AudioChannelLayout (line 535) | [[nodiscard]] const AudioChannelLayout* LayoutPtr() const noexcept { ret...
  function AudioChannelLayoutTag (line 539) | [[nodiscard]] AudioChannelLayoutTag Tag() const noexcept { return Layout...
  function NumberChannels (line 548) | static uint32_t NumberChannels(const AudioChannelLayout& inLayout) noexcept
  function DataByteSize (line 560) | static constexpr size_t DataByteSize(uint32_t inNumberChannelDescription...
  function CopyStorage (line 574) | void CopyStorage(const AUChannelLayout& inSource)
  function namespace (line 591) | namespace ABL {
  function AUSDK_BEGIN_NO_RT_WARNINGS (line 623) | AUSDK_BEGIN_NO_RT_WARNINGS
  function explicit (line 652) | explicit Owned(T obj, bool fromget) noexcept : mImpl{ obj }
  function noexcept (line 668) | Owned(const Owned& other) noexcept : mImpl{ other.mImpl }
  function T (line 688) | T operator*() const noexcept { return get(); }
  function T (line 693) | T release() noexcept { return std::exchange(mImpl, nullptr); }
  function releaseRef (line 714) | void releaseRef() noexcept
  function T (line 721) | T mImpl{ nullptr };
  function Serialize (line 731) | void Serialize(const TriviallyCopySerializable auto& inValue, void* outD...
  function T (line 747) | T result{}
  function safeIsPrint (line 772) | constexpr auto safeIsPrint = [](char character) {
  function T (line 807) | T* get() const { return Base::operator*(); }

FILE: include/AudioUnitSDK/ComponentBase.h
  function namespace (line 22) | namespace ausdk {
  function Destruct (line 113) | static void Destruct(void* memory) { static_cast<Implementor*>(memory)->...
  function AudioComponentPlugInInterface (line 117) | static AudioComponentPlugInInterface* Factory(const AudioComponentDescri...

FILE: include/AudioUnitSDK/MusicDeviceBase.h
  function namespace (line 16) | namespace ausdk {

FILE: src/AudioUnitSDK/AUBase.cpp
  type ausdk (line 22) | namespace ausdk {
    class DenormalDisabler (line 28) | class DenormalDisabler {
      method DenormalDisabler (line 30) | DenormalDisabler() noexcept : mSavedMXCSR(GetCSR()) { SetCSR(mSavedM...
      method DenormalDisabler (line 32) | DenormalDisabler(const DenormalDisabler&) = delete;
      method DenormalDisabler (line 33) | DenormalDisabler(DenormalDisabler&&) = delete;
      method DenormalDisabler (line 34) | DenormalDisabler& operator=(const DenormalDisabler&) = delete;
      method DenormalDisabler (line 35) | DenormalDisabler& operator=(DenormalDisabler&&) = delete;
      method GetCSR (line 41) | static unsigned GetCSR() noexcept { return _mm_getcsr(); }
      method SetCSR (line 42) | static void SetCSR(unsigned x) noexcept { _mm_setcsr(x); }
      method GetCSR (line 45) | static unsigned GetCSR() noexcept
      method SetCSR (line 51) | static void SetCSR(unsigned a) noexcept
      method DenormalDisabler (line 65) | DenormalDisabler() = default;
    class DenormalDisabler (line 63) | class DenormalDisabler {
      method DenormalDisabler (line 30) | DenormalDisabler() noexcept : mSavedMXCSR(GetCSR()) { SetCSR(mSavedM...
      method DenormalDisabler (line 32) | DenormalDisabler(const DenormalDisabler&) = delete;
      method DenormalDisabler (line 33) | DenormalDisabler(DenormalDisabler&&) = delete;
      method DenormalDisabler (line 34) | DenormalDisabler& operator=(const DenormalDisabler&) = delete;
      method DenormalDisabler (line 35) | DenormalDisabler& operator=(DenormalDisabler&&) = delete;
      method GetCSR (line 41) | static unsigned GetCSR() noexcept { return _mm_getcsr(); }
      method SetCSR (line 42) | static void SetCSR(unsigned x) noexcept { _mm_setcsr(x); }
      method GetCSR (line 45) | static unsigned GetCSR() noexcept
      method SetCSR (line 51) | static void SetCSR(unsigned a) noexcept
      method DenormalDisabler (line 65) | DenormalDisabler() = default;
    function CFStringRef (line 69) | static CFStringRef GetPresetDefaultName() noexcept
    function OSStatus (line 154) | OSStatus AUBase::CanSetMaxFrames() const
    function OSStatus (line 197) | OSStatus AUBase::DoInitialize()
    function OSStatus (line 215) | OSStatus AUBase::Initialize() { return noErr; }
    function OSStatus (line 238) | OSStatus AUBase::DoReset(AudioUnitScope inScope, AudioUnitElement inEl...
    function OSStatus (line 246) | OSStatus AUBase::Reset(AudioUnitScope inScope, AudioUnitElement inElem...
    function OSStatus (line 253) | OSStatus AUBase::DispatchGetPropertyInfo(AudioUnitPropertyID inID, Aud...
    function OSStatus (line 461) | OSStatus AUBase::DispatchGetProperty(
    function OSStatus (line 668) | OSStatus AUBase::DispatchSetProperty(AudioUnitPropertyID inID, AudioUn...
    function OSStatus (line 864) | OSStatus AUBase::DispatchRemovePropertyValue(
    function OSStatus (line 909) | OSStatus AUBase::GetPropertyInfo(AudioUnitPropertyID /*inID*/, AudioUn...
    function OSStatus (line 918) | OSStatus AUBase::GetProperty(AudioUnitPropertyID /*inID*/, AudioUnitSc...
    function OSStatus (line 927) | OSStatus AUBase::SetProperty(AudioUnitPropertyID /*inID*/, AudioUnitSc...
    function OSStatus (line 935) | OSStatus AUBase::RemovePropertyValue(
    function OSStatus (line 943) | OSStatus AUBase::AddPropertyListener(
    function OSStatus (line 960) | OSStatus AUBase::RemovePropertyListener(AudioUnitPropertyID inID,
    function OSStatus (line 984) | OSStatus AUBase::SetRenderNotification(AURenderCallback inProc, void* ...
    function OSStatus (line 998) | OSStatus AUBase::RemoveRenderNotification(AURenderCallback inProc, voi...
    function OSStatus (line 1006) | OSStatus AUBase::GetParameter(AudioUnitParameterID inID, AudioUnitScop...
    function OSStatus (line 1017) | OSStatus AUBase::SetParameter(AudioUnitParameterID inID, AudioUnitScop...
    function OSStatus (line 1028) | OSStatus AUBase::ScheduleParameter(
    function ParameterEventListSortPredicate (line 1051) | constexpr bool ParameterEventListSortPredicate(
    function OSStatus (line 1066) | OSStatus AUBase::ProcessForScheduledParams(
    function OSStatus (line 1184) | OSStatus AUBase::DoRender(AudioUnitRenderActionFlags& ioActionFlags,
    function catch (line 1392) | catch (const OSStatus& err) {
    function catch (line 1394) | catch (...) {
  function catch (line 1539) | catch (const OSStatus& err) {
  function catch (line 1541) | catch (...) {
  function OSStatus (line 1551) | OSStatus AUBase::SetInputCallback(
  function OSStatus (line 1565) | OSStatus AUBase::SetConnection(const AudioUnitConnection& inConnection)
  function UInt32 (line 1589) | UInt32 AUBase::SupportedNumChannels(const AUChannelInfo** /*outInfo*/) {...
  function AudioStreamBasicDescription (line 1626) | AudioStreamBasicDescription AUBase::GetStreamFormat(
  function OSStatus (line 1648) | OSStatus AUBase::SetBusCount(AudioUnitScope inScope, UInt32 inCount)
  function OSStatus (line 1658) | OSStatus AUBase::ChangeStreamFormat(AudioUnitScope inScope, AudioUnitEle...
  function UInt32 (line 1692) | UInt32 AUBase::GetAudioChannelLayout(AudioUnitScope inScope, AudioUnitEl...
  function OSStatus (line 1699) | OSStatus AUBase::RemoveAudioChannelLayout(AudioUnitScope inScope, AudioU...
  function OSStatus (line 1709) | OSStatus AUBase::SetAudioChannelLayout(
  function AddNumToDictionary (line 1732) | static void AddNumToDictionary(CFMutableDictionaryRef dict, CFStringRef ...
  function OSStatus (line 1740) | OSStatus AUBase::SaveState(CFPropertyListRef* outData)
  function OSStatus (line 1815) | OSStatus AUBase::RestoreState(CFPropertyListRef plist)
  function OSStatus (line 1919) | OSStatus AUBase::GetPresets(CFArrayRef* /*outData*/) const { return kAud...
  function OSStatus (line 1921) | OSStatus AUBase::NewFactoryPresetSet(const AUPreset& /*inNewFactoryPrese...
  function OSStatus (line 1926) | OSStatus AUBase::NewCustomPresetSet(const AUPreset& inNewCustomPreset)
  function CFURLRef (line 1960) | CFURLRef AUBase::CopyIconLocation() { return nullptr; }
  function OSStatus (line 1965) | OSStatus AUBase::GetParameterList(
  function OSStatus (line 1992) | OSStatus AUBase::GetParameterInfo(AudioUnitScope /*inScope*/,
  function OSStatus (line 2000) | OSStatus AUBase::GetParameterValueStrings(
  function OSStatus (line 2008) | OSStatus AUBase::GetParameterHistoryInfo(AudioUnitScope /*inScope*/,
  function OSStatus (line 2018) | OSStatus AUBase::CopyClumpName(AudioUnitScope /*inScope*/, UInt32 /*inCl...

FILE: src/AudioUnitSDK/AUBuffer.cpp
  type ausdk (line 13) | namespace ausdk {
    function AUSDK_BEGIN_NO_RT_WARNINGS (line 15) | AUSDK_BEGIN_NO_RT_WARNINGS
    function RoundUpToMultipleOfPowerOf2 (line 24) | constexpr uint32_t RoundUpToMultipleOfPowerOf2(uint32_t x, uint32_t y)...
    function UInt32 (line 34) | static UInt32 SafeMultiplyAddUInt32(UInt32 a, UInt32 b, UInt32 c)
    function AllocatedBuffer (line 47) | AllocatedBuffer* BufferAllocator::Allocate(

FILE: src/AudioUnitSDK/AUBufferAllocator.cpp
  type ausdk (line 7) | namespace ausdk {
    function BufferAllocator (line 9) | BufferAllocator& BufferAllocator::instance()

FILE: src/AudioUnitSDK/AUEffectBase.cpp
  type ausdk (line 18) | namespace ausdk {
    function AUSDK_BEGIN_NO_RT_WARNINGS (line 20) | AUSDK_BEGIN_NO_RT_WARNINGS
    function OSStatus (line 46) | OSStatus AUEffectBase::Initialize()
    function OSStatus (line 109) | OSStatus AUEffectBase::Reset(AudioUnitScope inScope, AudioUnitElement ...
    function OSStatus (line 120) | OSStatus AUEffectBase::GetPropertyInfo(AudioUnitPropertyID inID, Audio...
    function OSStatus (line 138) | OSStatus AUEffectBase::GetProperty(
    function OSStatus (line 157) | OSStatus AUEffectBase::SetProperty(AudioUnitPropertyID inID, AudioUnit...
    function OSStatus (line 219) | OSStatus AUEffectBase::ChangeStreamFormat(AudioUnitScope inScope, Audi...
    function OSStatus (line 242) | OSStatus AUEffectBase::ProcessScheduledSlice(void* inUserData, UInt32 ...
    function OSStatus (line 286) | OSStatus AUEffectBase::Render(AudioUnitRenderActionFlags& ioActionFlags,
    function OSStatus (line 362) | OSStatus AUEffectBase::ProcessBufferLists(AudioUnitRenderActionFlags& ...

FILE: src/AudioUnitSDK/AUInputElement.cpp
  type ausdk (line 8) | namespace ausdk {
    function AUSDK_BEGIN_NO_RT_WARNINGS (line 10) | AUSDK_BEGIN_NO_RT_WARNINGS
    function OSStatus (line 63) | OSStatus AUInputElement::SetStreamFormat(const AudioStreamBasicDescrip...
    function OSStatus (line 72) | OSStatus AUInputElement::PullInput(AudioUnitRenderActionFlags& ioActio...

FILE: src/AudioUnitSDK/AUMIDIBase.cpp
  type ausdk (line 14) | namespace ausdk {
    function OSStatus (line 23) | OSStatus AUMIDIBase::DelegateGetPropertyInfo(AudioUnitPropertyID inID,...
    function OSStatus (line 67) | OSStatus AUMIDIBase::DelegateGetProperty(
    function OSStatus (line 113) | OSStatus AUMIDIBase::DelegateSetProperty(AudioUnitPropertyID inID, Aud...
    function MIDIStatusNibbleValue (line 182) | constexpr uint8_t MIDIStatusNibbleValue(uint8_t status) noexcept { ret...
    function OSStatus (line 188) | OSStatus AUMIDIBase::HandleMIDIEvent(
    function OSStatus (line 225) | OSStatus AUMIDIBase::HandleNonNoteEvent(
    function OSStatus (line 262) | OSStatus AUMIDIBase::SysEx(const UInt8* inData, UInt32 inLength) AUSDK...

FILE: src/AudioUnitSDK/AUMIDIEffectBase.cpp
  type ausdk (line 7) | namespace ausdk {
    function OSStatus (line 14) | OSStatus AUMIDIEffectBase::GetPropertyInfo(AudioUnitPropertyID inID, A...
    function OSStatus (line 28) | OSStatus AUMIDIEffectBase::GetProperty(
    function OSStatus (line 40) | OSStatus AUMIDIEffectBase::SetProperty(AudioUnitPropertyID inID, Audio...

FILE: src/AudioUnitSDK/AUOutputElement.cpp
  type ausdk (line 9) | namespace ausdk {
    function OSStatus (line 19) | OSStatus AUOutputElement::SetStreamFormat(const AudioStreamBasicDescri...

FILE: src/AudioUnitSDK/AUPlugInDispatch.cpp
  type ausdk (line 27) | namespace ausdk {
    function AUSDK_BEGIN_NO_RT_WARNINGS (line 29) | AUSDK_BEGIN_NO_RT_WARNINGS
    class AUInstanceGuard (line 39) | class AUInstanceGuard {
      method AUInstanceGuard (line 41) | explicit AUInstanceGuard(void* self) : mGuard(AUInstance(self)->GetM...
    function IsValidParameterValue (line 48) | static bool IsValidParameterValue(AudioUnitParameterValue value) { ret...
    function AreValidParameterEvents (line 50) | static bool AreValidParameterEvents(const AudioUnitParameterEvent* eve...
    function OSStatus (line 83) | static OSStatus AUMethodInitialize(void* self)
    function OSStatus (line 94) | static OSStatus AUMethodUninitialize(void* self)
    function OSStatus (line 105) | static OSStatus AUMethodGetPropertyInfo(void* self, AudioUnitPropertyI...
    function OSStatus (line 127) | static OSStatus AUMethodGetProperty(void* self, AudioUnitPropertyID in...
    function OSStatus (line 184) | static OSStatus AUMethodSetProperty(void* self, AudioUnitPropertyID in...
    function OSStatus (line 213) | static OSStatus AUMethodAddPropertyListener(
    function OSStatus (line 225) | static OSStatus AUMethodRemovePropertyListener(
    function OSStatus (line 237) | static OSStatus AUMethodRemovePropertyListenerWithUserData(
    function OSStatus (line 249) | static OSStatus AUMethodAddRenderNotify(void* self, AURenderCallback p...
    function OSStatus (line 260) | static OSStatus AUMethodRemoveRenderNotify(void* self, AURenderCallbac...
    function OSStatus (line 271) | static OSStatus AUMethodGetParameter(void* self, AudioUnitParameterID ...
    function OSStatus (line 284) | static OSStatus AUMethodSetParameter(void* self, AudioUnitParameterID ...
    function OSStatus (line 298) | static OSStatus AUMethodScheduleParameters(
    function OSStatus (line 313) | static OSStatus AUMethodRender(void* self, AudioUnitRenderActionFlags*...
    function OSStatus (line 337) | static OSStatus AUMethodComplexRender(void* self, AudioUnitRenderActio...
    function OSStatus (line 365) | static OSStatus AUMethodReset(void* self, AudioUnitScope scope, AudioU...
    function OSStatus (line 377) | static OSStatus AUMethodProcess(void* self, AudioUnitRenderActionFlags...
    function OSStatus (line 407) | static OSStatus AUMethodProcessMultiple(void* self, AudioUnitRenderAct...
    function OSStatus (line 442) | static OSStatus AUMethodStart(void* self)
    function OSStatus (line 453) | static OSStatus AUMethodStop(void* self)
    function OSStatus (line 469) | static OSStatus AUMethodMIDIEvent(
    function OSStatus (line 481) | static OSStatus AUMethodSysEx(void* self, const UInt8* inData, UInt32 ...
    function OSStatus (line 494) | static OSStatus AUMethodMIDIEventList(
    function OSStatus (line 516) | static OSStatus AUMethodStartNote(void* self, MusicDeviceInstrumentID ...
    function OSStatus (line 534) | static OSStatus AUMethodStopNote(void* self, MusicDeviceGroupID inGrou...
    function OSStatus (line 548) | static OSStatus AUMethodPrepareInstrument(void* self, MusicDeviceInstr...
    function OSStatus (line 559) | static OSStatus AUMethodReleaseInstrument(void* self, MusicDeviceInstr...
    function AudioComponentMethod (line 576) | AudioComponentMethod AUBaseLookup::Lookup(SInt16 selector)
    function AudioComponentMethod (line 615) | AudioComponentMethod AUOutputLookup::Lookup(SInt16 selector)
    function AudioComponentMethod (line 635) | AudioComponentMethod AUComplexOutputLookup::Lookup(SInt16 selector)
    function AudioComponentMethod (line 653) | AudioComponentMethod AUBaseProcessLookup::Lookup(SInt16 selector)
    function AudioComponentMethod (line 667) | AudioComponentMethod AUBaseProcessMultipleLookup::Lookup(SInt16 selector)
    function AudioComponentMethod (line 681) | AudioComponentMethod AUBaseProcessAndMultipleLookup::Lookup(SInt16 sel...
    function AudioComponentMethod (line 702) | inline AudioComponentMethod MIDI_Lookup(SInt16 selector)
    function AudioComponentMethod (line 719) | AudioComponentMethod AUMIDILookup::Lookup(SInt16 selector)
    function AudioComponentMethod (line 729) | AudioComponentMethod AUMIDIProcessLookup::Lookup(SInt16 selector)
    function AudioComponentMethod (line 741) | AudioComponentMethod AUMusicLookup::Lookup(SInt16 selector)

FILE: src/AudioUnitSDK/AUScopeElement.cpp
  type ausdk (line 20) | namespace ausdk {
    function AUSDK_BEGIN_NO_RT_WARNINGS (line 22) | AUSDK_BEGIN_NO_RT_WARNINGS
    function OSStatus (line 112) | OSStatus AUElement::SetScheduledEvent(AudioUnitParameterID paramID,
    function AppendBytes (line 142) | static void AppendBytes(CFMutableDataRef data, const TriviallyCopySeri...
    function UInt8 (line 199) | const UInt8* AUElement::RestoreState(const UInt8* state)
    function OSStatus (line 232) | OSStatus AUIOElement::SetStreamFormat(const AudioStreamBasicDescriptio...
    function UInt32 (line 271) | UInt32 AUIOElement::GetAudioChannelLayout(AudioChannelLayout* outLayou...
    function OSStatus (line 286) | OSStatus AUIOElement::SetAudioChannelLayout(const AudioChannelLayout& ...
    function OSStatus (line 299) | OSStatus AUIOElement::RemoveAudioChannelLayout()
    function UInt8 (line 412) | const UInt8* AUScope::RestoreState(const UInt8* state) const

FILE: src/AudioUnitSDK/ComponentBase.cpp
  type ausdk (line 12) | namespace ausdk {
    function OSStatus (line 40) | OSStatus ComponentBase::AP_Open(void* self, AudioComponentInstance com...
    function OSStatus (line 60) | OSStatus ComponentBase::AP_Close(void* self)
    function AudioComponentDescription (line 76) | AudioComponentDescription ComponentBase::GetComponentDescription() const
    function OSStatus (line 87) | static OSStatus CB_GetComponentDescription(

FILE: src/AudioUnitSDK/MusicDeviceBase.cpp
  type ausdk (line 14) | namespace ausdk {
    function OSStatus (line 24) | OSStatus MusicDeviceBase::GetPropertyInfo(AudioUnitPropertyID inID, Au...
    function OSStatus (line 45) | OSStatus MusicDeviceBase::GetProperty(
    function OSStatus (line 68) | OSStatus MusicDeviceBase::SetProperty(AudioUnitPropertyID inID, AudioU...
    function OSStatus (line 84) | OSStatus MusicDeviceBase::GetInstrumentCount(UInt32& outInstCount) const
    function OSStatus (line 90) | OSStatus MusicDeviceBase::HandleNoteOn(
    function OSStatus (line 103) | OSStatus MusicDeviceBase::HandleNoteOff(
Condensed preview — 50 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (388K chars).
[
  {
    "path": ".github/pull_request_template.md",
    "chars": 758,
    "preview": "NOTE: - While you can open new pull requests WE ADVISE AGAINST IT and as such our response may be limited.\n\nThis project"
  },
  {
    "path": ".gitignore",
    "chars": 30,
    "preview": ".DS_Store\n.cache/\nxcuserdata/\n"
  },
  {
    "path": "AudioUnitSDK.xcodeproj/project.pbxproj",
    "chars": 36881,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "AudioUnitSDK.xcodeproj/xcshareddata/xcschemes/AudioUnitSDK.xcscheme",
    "chars": 2477,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1200\"\n   version = \"1.7\">\n   <BuildAction\n      "
  },
  {
    "path": "AudioUnitSDK.xcodeproj/xcshareddata/xcschemes/EmptyPlugIns.xcscheme",
    "chars": 2481,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1200\"\n   version = \"1.7\">\n   <BuildAction\n      "
  },
  {
    "path": "AudioUnitSDK.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme",
    "chars": 2940,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1200\"\n   version = \"1.7\">\n   <BuildAction\n      "
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 3357,
    "preview": "# Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 1178,
    "preview": "# Contribution Guide\n\nThank you for your interest in contributing to the AudioUnit SDK! While this is an open-source pro"
  },
  {
    "path": "LICENSE.txt",
    "chars": 11358,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "_clang-format",
    "chars": 1978,
    "preview": "---\n# BasedOnStyle:  LLVM\nAccessModifierOffset: -4\nAlignAfterOpenBracket: DontAlign\nAlignConsecutiveAssignments: false\nA"
  },
  {
    "path": "_clang-tidy",
    "chars": 865,
    "preview": "---\nChecks:\n'\n*,\nclang-diagnostic-*,\nclang-analyzer-*,\n-clang-diagnostic-pragma-once-outside-header,\n-llvm-header-guard,"
  },
  {
    "path": "demos/EmptyPlugIns/EmptyPlugIns.cpp",
    "chars": 1622,
    "preview": "/*!\n    @file        EmptyPlugIns.cpp\n    @copyright    © 2000-2025 Apple Inc. All rights reserved.\n*/\n#include <AudioUn"
  },
  {
    "path": "demos/EmptyPlugIns/Info.plist",
    "chars": 775,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "hooks/install.sh",
    "chars": 411,
    "preview": "#! /bin/sh\n\ngit rev-parse 2> /dev/null\nif [ $? != 0 ]; then\n\techo \"not currently working in a git repository, therefore "
  },
  {
    "path": "hooks/pre-commit",
    "chars": 959,
    "preview": "#! /bin/zsh\n# This pre-commit hook uses clang-format to format the staged changes.\n\nif ! git rev-parse --verify HEAD >/d"
  },
  {
    "path": "include/AudioUnitSDK/AUBase.h",
    "chars": 31658,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUBase.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n\n#ifndef AudioUnitSDK_AUBas"
  },
  {
    "path": "include/AudioUnitSDK/AUBuffer.h",
    "chars": 7597,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUBuffer.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitSDK_AUBu"
  },
  {
    "path": "include/AudioUnitSDK/AUConfig.h",
    "chars": 3244,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUConfig.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n\n#ifndef AudioUnitSDK_AUC"
  },
  {
    "path": "include/AudioUnitSDK/AUEffectBase.h",
    "chars": 7612,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUEffectBase.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitSDK_"
  },
  {
    "path": "include/AudioUnitSDK/AUInputElement.h",
    "chars": 3213,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUInputElement.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitSD"
  },
  {
    "path": "include/AudioUnitSDK/AUMIDIBase.h",
    "chars": 5969,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUMIDIBase.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitSDK_AU"
  },
  {
    "path": "include/AudioUnitSDK/AUMIDIEffectBase.h",
    "chars": 1571,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUMIDIEffectBase.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnit"
  },
  {
    "path": "include/AudioUnitSDK/AUMIDIUtility.h",
    "chars": 395,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUMIDIUtility.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitSDK"
  },
  {
    "path": "include/AudioUnitSDK/AUOutputElement.h",
    "chars": 1047,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUOutputElement.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitS"
  },
  {
    "path": "include/AudioUnitSDK/AUPlugInDispatch.h",
    "chars": 3917,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUPlugInDispatch.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnit"
  },
  {
    "path": "include/AudioUnitSDK/AUScopeElement.h",
    "chars": 17415,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUScopeElement.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitSD"
  },
  {
    "path": "include/AudioUnitSDK/AUSilentTimeout.h",
    "chars": 1182,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUSilentTimeout.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitS"
  },
  {
    "path": "include/AudioUnitSDK/AUThreadSafeList.h",
    "chars": 8038,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUThreadSafeList.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnit"
  },
  {
    "path": "include/AudioUnitSDK/AUUtility.h",
    "chars": 28749,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUUtility.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitSDK_AUU"
  },
  {
    "path": "include/AudioUnitSDK/AudioUnitSDK.h",
    "chars": 890,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AudioUnitSDK.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitSDK_"
  },
  {
    "path": "include/AudioUnitSDK/ComponentBase.h",
    "chars": 5821,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/ComponentBase.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitSDK"
  },
  {
    "path": "include/AudioUnitSDK/MusicDeviceBase.h",
    "chars": 2179,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/MusicDeviceBase.h\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#ifndef AudioUnitS"
  },
  {
    "path": "readme.md",
    "chars": 2129,
    "preview": "# AudioUnitSDK\n\n## Overview\nThe AudioUnitSDK contains a set of base classes as well as utility sources required for Audi"
  },
  {
    "path": "src/AudioUnitSDK/AUBase.cpp",
    "chars": 69947,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUBase.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n// clang-format off\n#incl"
  },
  {
    "path": "src/AudioUnitSDK/AUBuffer.cpp",
    "chars": 5934,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUBuffer.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#include <AudioUnitSDK/"
  },
  {
    "path": "src/AudioUnitSDK/AUBufferAllocator.cpp",
    "chars": 308,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUBufferAllocator.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#include <Audi"
  },
  {
    "path": "src/AudioUnitSDK/AUEffectBase.cpp",
    "chars": 13471,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUEffectBase.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#include <AudioUnit"
  },
  {
    "path": "src/AudioUnitSDK/AUInputElement.cpp",
    "chars": 2438,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUInputElement.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#include <AudioUn"
  },
  {
    "path": "src/AudioUnitSDK/AUMIDIBase.cpp",
    "chars": 9392,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUMIDIBase.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#include <AudioUnitSD"
  },
  {
    "path": "src/AudioUnitSDK/AUMIDIEffectBase.cpp",
    "chars": 1603,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUMIDIEffectBase.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#include <Audio"
  },
  {
    "path": "src/AudioUnitSDK/AUOutputElement.cpp",
    "chars": 704,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUOutputElement.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#include <AudioU"
  },
  {
    "path": "src/AudioUnitSDK/AUPlugInDispatch.cpp",
    "chars": 22088,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUPlugInDispatch.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n// clang-format"
  },
  {
    "path": "src/AudioUnitSDK/AUScopeElement.cpp",
    "chars": 14700,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/AUScopeElement.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#include <AudioUn"
  },
  {
    "path": "src/AudioUnitSDK/ComponentBase.cpp",
    "chars": 2373,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/ComponentBase.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n// self\n#include <"
  },
  {
    "path": "src/AudioUnitSDK/MusicDeviceBase.cpp",
    "chars": 3463,
    "preview": "/*!\n\t@file\t\tAudioUnitSDK/MusicDeviceBase.cpp\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#include <AudioU"
  },
  {
    "path": "tests/AUThreadSafeListTests.mm",
    "chars": 5334,
    "preview": "/*!\n\t@file\t\tAUThreadSafeListTests.mm\n\t@copyright\t© 2000-2025 Apple Inc. All rights reserved.\n*/\n#import <XCTest/XCTest.h"
  },
  {
    "path": "tests/Info.plist",
    "chars": 727,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "tests/Tests.mm",
    "chars": 6718,
    "preview": "/*!\n\t@file\t\tTests.mm\n\t@copyright\t© 2020-2025 Apple Inc. All rights reserved.\n*/\n\n#import <XCTest/XCTest.h>\n\n#import <Aud"
  },
  {
    "path": "tools/FindUB.sh",
    "chars": 467,
    "preview": "#! /bin/sh\n\n# Certain types can only safely be accessed through pointers, not C++ references.\n# This is due to their bei"
  },
  {
    "path": "tools/build.sh",
    "chars": 238,
    "preview": "#! /bin/sh\n\n# Assumes the root of the project is the current directory\n\nSDK=$1\nDEST=\"$2\"\n\nif [ -z \"$DEST\" ] ; then\n\techo"
  }
]

About this extraction

This page contains the full source code of the apple/AudioUnitSDK GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 50 files (352.1 KB), approximately 95.0k tokens, and a symbol index with 288 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!