The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

99 lines
2.3KB

  1. /*!
  2. @file AudioUnitSDK/ComponentBase.cpp
  3. @copyright © 2000-2021 Apple Inc. All rights reserved.
  4. */
  5. // self
  6. #include <AudioUnitSDK/AUUtility.h>
  7. #include <AudioUnitSDK/ComponentBase.h>
  8. // std
  9. #include <mutex>
  10. namespace ausdk {
  11. static OSStatus CB_GetComponentDescription(
  12. AudioComponentInstance inInstance, AudioComponentDescription* outDesc);
  13. std::recursive_mutex& ComponentBase::InitializationMutex()
  14. {
  15. __attribute__((no_destroy)) static std::recursive_mutex global;
  16. return global;
  17. }
  18. ComponentBase::ComponentBase(AudioComponentInstance inInstance) : mComponentInstance(inInstance)
  19. {
  20. (void)GetComponentDescription();
  21. }
  22. void ComponentBase::DoPostConstructor()
  23. {
  24. PostConstructorInternal();
  25. PostConstructor();
  26. }
  27. void ComponentBase::DoPreDestructor()
  28. {
  29. PreDestructor();
  30. PreDestructorInternal();
  31. }
  32. OSStatus ComponentBase::AP_Open(void* self, AudioComponentInstance compInstance)
  33. {
  34. OSStatus result = noErr;
  35. const auto acpi = static_cast<AudioComponentPlugInInstance*>(self);
  36. try {
  37. const std::lock_guard guard{ InitializationMutex() };
  38. auto* const cb =
  39. static_cast<ComponentBase*>((*acpi->mConstruct)(&acpi->mInstanceStorage, compInstance));
  40. cb->DoPostConstructor(); // allows base class to do additional initialization
  41. // once the derived class is fully constructed
  42. result = noErr;
  43. }
  44. AUSDK_Catch(result)
  45. if (result != noErr) {
  46. delete acpi; // NOLINT
  47. }
  48. return result;
  49. }
  50. OSStatus ComponentBase::AP_Close(void* self)
  51. {
  52. OSStatus result = noErr;
  53. try {
  54. const auto acpi = static_cast<AudioComponentPlugInInstance*>(self);
  55. if (const auto acImp =
  56. reinterpret_cast<ComponentBase*>(&acpi->mInstanceStorage)) { // NOLINT
  57. acImp->DoPreDestructor();
  58. (*acpi->mDestruct)(&acpi->mInstanceStorage);
  59. free(self); // NOLINT manual memory management
  60. }
  61. }
  62. AUSDK_Catch(result)
  63. return result;
  64. }
  65. AudioComponentDescription ComponentBase::GetComponentDescription() const
  66. {
  67. AudioComponentDescription desc = {};
  68. if (CB_GetComponentDescription(mComponentInstance, &desc) == noErr) {
  69. return desc;
  70. }
  71. return {};
  72. }
  73. static OSStatus CB_GetComponentDescription(
  74. AudioComponentInstance inInstance, AudioComponentDescription* outDesc)
  75. {
  76. const AudioComponent comp = AudioComponentInstanceGetComponent(inInstance);
  77. if (comp != nullptr) {
  78. return AudioComponentGetDescription(comp, outDesc);
  79. }
  80. return kAudio_ParamError;
  81. }
  82. } // namespace ausdk