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.

92 lines
2.9KB

  1. /*!
  2. @file AudioUnitSDK/AUInputElement.h
  3. @copyright © 2000-2021 Apple Inc. All rights reserved.
  4. */
  5. #ifndef AudioUnitSDK_AUInputElement_h
  6. #define AudioUnitSDK_AUInputElement_h
  7. #include <AudioUnitSDK/AUBuffer.h>
  8. #include <AudioUnitSDK/AUScopeElement.h>
  9. namespace ausdk {
  10. /*!
  11. @class AUInputElement
  12. @brief Implements an audio unit input element, managing the source of input from a callback
  13. or connection.
  14. */
  15. class AUInputElement : public AUIOElement {
  16. public:
  17. using AUIOElement::AUIOElement;
  18. // AUElement override
  19. OSStatus SetStreamFormat(const AudioStreamBasicDescription& fmt) override;
  20. [[nodiscard]] bool NeedsBufferSpace() const override { return IsCallback(); }
  21. void SetConnection(const AudioUnitConnection& conn);
  22. void SetInputCallback(AURenderCallback proc, void* refCon);
  23. [[nodiscard]] bool IsActive() const noexcept { return mInputType != EInputType::NoInput; }
  24. [[nodiscard]] bool IsCallback() const noexcept
  25. {
  26. return mInputType == EInputType::FromCallback;
  27. }
  28. [[nodiscard]] bool HasConnection() const noexcept
  29. {
  30. return mInputType == EInputType::FromConnection;
  31. }
  32. OSStatus PullInput(AudioUnitRenderActionFlags& ioActionFlags, const AudioTimeStamp& inTimeStamp,
  33. AudioUnitElement inElement, UInt32 nFrames);
  34. OSStatus PullInputWithBufferList(AudioUnitRenderActionFlags& ioActionFlags,
  35. const AudioTimeStamp& inTimeStamp, AudioUnitElement inElement, UInt32 nFrames,
  36. AudioBufferList& inBufferList);
  37. protected:
  38. void Disconnect();
  39. private:
  40. enum class EInputType { NoInput, FromConnection, FromCallback };
  41. EInputType mInputType{ EInputType::NoInput };
  42. // if from callback:
  43. AURenderCallback mInputProc{ nullptr };
  44. void* mInputProcRefCon{ nullptr };
  45. // if from connection:
  46. AudioUnitConnection mConnection{};
  47. };
  48. inline OSStatus AUInputElement::PullInputWithBufferList(AudioUnitRenderActionFlags& ioActionFlags,
  49. const AudioTimeStamp& inTimeStamp, AudioUnitElement inElement, UInt32 nFrames,
  50. AudioBufferList& inBufferList)
  51. {
  52. OSStatus theResult = noErr;
  53. if (HasConnection()) {
  54. // only support connections for V2 audio units
  55. theResult = AudioUnitRender(mConnection.sourceAudioUnit, &ioActionFlags, &inTimeStamp,
  56. mConnection.sourceOutputNumber, nFrames, &inBufferList);
  57. } else {
  58. // kFromCallback:
  59. theResult = (mInputProc)(mInputProcRefCon, &ioActionFlags, &inTimeStamp, inElement, nFrames,
  60. &inBufferList);
  61. }
  62. if (mInputType == EInputType::NoInput) { // defense: the guy upstream could have disconnected
  63. // it's a horrible thing to do, but may happen!
  64. return kAudioUnitErr_NoConnection;
  65. }
  66. #if !TARGET_OS_IPHONE || DEBUG
  67. if (theResult == noErr) { // if there's already an error, there's no point (and maybe some harm)
  68. // in validating.
  69. if (ABL::IsBogusAudioBufferList(inBufferList) & 1) {
  70. return kAudioUnitErr_InvalidPropertyValue;
  71. }
  72. }
  73. #endif
  74. return theResult;
  75. }
  76. } // namespace ausdk
  77. #endif // AudioUnitSDK_AUInputElement_h