| 
							- /*
 -   ==============================================================================
 - 
 -    This file is part of the JUCE library.
 -    Copyright (c) 2022 - Raw Material Software Limited
 - 
 -    JUCE is an open source library subject to commercial or open-source
 -    licensing.
 - 
 -    By using JUCE, you agree to the terms of both the JUCE 7 End-User License
 -    Agreement and JUCE Privacy Policy.
 - 
 -    End User License Agreement: www.juce.com/juce-7-licence
 -    Privacy Policy: www.juce.com/juce-privacy-policy
 - 
 -    Or: You may also use this code under the terms of the GPL v3 (see
 -    www.gnu.org/licenses).
 - 
 -    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
 -    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
 -    DISCLAIMED.
 - 
 -   ==============================================================================
 - */
 - 
 - #pragma once
 - 
 - #include <juce_core/system/juce_TargetPlatform.h>
 - 
 - #if JUCE_PLUGINHOST_ARA && (JUCE_MAC || JUCE_WINDOWS || JUCE_LINUX)
 - 
 - #include <JuceHeader.h>
 - 
 - #include <ARA_API/ARAInterface.h>
 - #include <ARA_Library/Dispatch/ARAHostDispatch.h>
 - 
 - class FileAudioSource
 - {
 -     auto getAudioSourceProperties() const
 -     {
 -         auto properties = ARAHostModel::AudioSource::getEmptyProperties();
 -         properties.name = formatReader->getFile().getFullPathName().toRawUTF8();
 -         properties.persistentID = formatReader->getFile().getFullPathName().toRawUTF8();
 -         properties.sampleCount = formatReader->lengthInSamples;
 -         properties.sampleRate = formatReader->sampleRate;
 -         properties.channelCount = (int) formatReader->numChannels;
 -         properties.merits64BitSamples = false;
 -         return properties;
 -     }
 - 
 - public:
 -     FileAudioSource (ARA::Host::DocumentController& dc, const juce::File& file)
 -         : formatReader ([&file]
 -           {
 -               auto result = rawToUniquePtr (WavAudioFormat().createMemoryMappedReader (file));
 -               result->mapEntireFile();
 -               return result;
 -           }()),
 -           audioSource (Converter::toHostRef (this), dc, getAudioSourceProperties())
 -     {
 -         audioSource.enableAudioSourceSamplesAccess (true);
 -     }
 - 
 -     bool readAudioSamples (float* const* buffers, int64 startSample, int64 numSamples)
 -     {
 -         // TODO: the ARA interface defines numSamples as int64. We should do multiple reads if necessary with the reader.
 -         if (numSamples > std::numeric_limits<int>::max())
 -             return false;
 - 
 -         return formatReader->read (buffers, (int) formatReader->numChannels, startSample, (int) (numSamples));
 -     }
 - 
 -     bool readAudioSamples (double* const* buffers, int64 startSample, int64 numSamples)
 -     {
 -         ignoreUnused (buffers, startSample, numSamples);
 -         return false;
 -     }
 - 
 -     MemoryMappedAudioFormatReader& getFormatReader() const { return *formatReader; }
 - 
 -     auto getPluginRef() const { return audioSource.getPluginRef(); }
 - 
 -     auto& getSource() { return audioSource; }
 - 
 -     using Converter = ARAHostModel::ConversionFunctions<FileAudioSource*, ARA::ARAAudioSourceHostRef>;
 - 
 - private:
 -     std::unique_ptr<MemoryMappedAudioFormatReader> formatReader;
 -     ARAHostModel::AudioSource audioSource;
 - };
 - 
 - //==============================================================================
 - class MusicalContext
 - {
 -     auto getMusicalContextProperties() const
 -     {
 -         auto properties = ARAHostModel::MusicalContext::getEmptyProperties();
 -         properties.name = "MusicalContext";
 -         properties.orderIndex = 0;
 -         properties.color = nullptr;
 -         return properties;
 -     }
 - 
 - public:
 -     MusicalContext (ARA::Host::DocumentController& dc)
 -         : context (Converter::toHostRef (this), dc, getMusicalContextProperties())
 -     {
 -     }
 - 
 -     auto getPluginRef() const { return context.getPluginRef(); }
 - 
 - private:
 -     using Converter = ARAHostModel::ConversionFunctions<MusicalContext*, ARA::ARAMusicalContextHostRef>;
 - 
 -     ARAHostModel::MusicalContext context;
 - };
 - 
 - //==============================================================================
 - class RegionSequence
 - {
 -     auto getRegionSequenceProperties() const
 -     {
 -         auto properties = ARAHostModel::RegionSequence::getEmptyProperties();
 -         properties.name = name.toRawUTF8();
 -         properties.orderIndex = 0;
 -         properties.musicalContextRef = context.getPluginRef();
 -         properties.color = nullptr;
 -         return properties;
 -     }
 - 
 - public:
 -     RegionSequence (ARA::Host::DocumentController& dc, MusicalContext& contextIn, String nameIn)
 -         : context (contextIn),
 -           name (std::move (nameIn)),
 -           sequence (Converter::toHostRef (this), dc, getRegionSequenceProperties())
 -     {
 -     }
 - 
 -     auto& getMusicalContext() const { return context; }
 -     auto getPluginRef() const { return sequence.getPluginRef(); }
 - 
 - private:
 -     using Converter = ARAHostModel::ConversionFunctions<RegionSequence*, ARA::ARARegionSequenceHostRef>;
 - 
 -     MusicalContext& context;
 -     String name;
 -     ARAHostModel::RegionSequence sequence;
 - };
 - 
 - class AudioModification
 - {
 -     auto getProperties() const
 -     {
 -         auto properties = ARAHostModel::AudioModification::getEmptyProperties();
 -         properties.persistentID = "x";
 -         return properties;
 -     }
 - 
 - public:
 -     AudioModification (ARA::Host::DocumentController& dc, FileAudioSource& source)
 -         : modification (Converter::toHostRef (this), dc, source.getSource(), getProperties())
 -     {
 -     }
 - 
 -     auto& getModification() { return modification; }
 - 
 - private:
 -     using Converter = ARAHostModel::ConversionFunctions<AudioModification*, ARA::ARAAudioModificationHostRef>;
 - 
 -     ARAHostModel::AudioModification modification;
 - };
 - 
 - //==============================================================================
 - class PlaybackRegion
 - {
 -     auto getPlaybackRegionProperties() const
 -     {
 -         auto properties = ARAHostModel::PlaybackRegion::getEmptyProperties();
 -         properties.transformationFlags = ARA::kARAPlaybackTransformationNoChanges;
 -         properties.startInModificationTime = 0.0;
 -         const auto& formatReader = audioSource.getFormatReader();
 -         properties.durationInModificationTime = (double) formatReader.lengthInSamples / formatReader.sampleRate;
 -         properties.startInPlaybackTime = 0.0;
 -         properties.durationInPlaybackTime = properties.durationInModificationTime;
 -         properties.musicalContextRef = sequence.getMusicalContext().getPluginRef();
 -         properties.regionSequenceRef = sequence.getPluginRef();
 - 
 -         properties.name = nullptr;
 -         properties.color = nullptr;
 -         return properties;
 -     }
 - 
 - public:
 -     PlaybackRegion (ARA::Host::DocumentController& dc,
 -                     RegionSequence& s,
 -                     AudioModification& m,
 -                     FileAudioSource& source)
 -         : sequence (s),
 -           audioSource (source),
 -           region (Converter::toHostRef (this), dc, m.getModification(), getPlaybackRegionProperties())
 -     {
 -         jassert (source.getPluginRef() == m.getModification().getAudioSource().getPluginRef());
 -     }
 - 
 -     auto& getPlaybackRegion() { return region; }
 - 
 - private:
 -     using Converter = ARAHostModel::ConversionFunctions<PlaybackRegion*, ARA::ARAPlaybackRegionHostRef>;
 - 
 -     RegionSequence& sequence;
 -     FileAudioSource& audioSource;
 -     ARAHostModel::PlaybackRegion region;
 - };
 - 
 - //==============================================================================
 - class AudioAccessController final : public ARA::Host::AudioAccessControllerInterface
 - {
 - public:
 -     ARA::ARAAudioReaderHostRef createAudioReaderForSource (ARA::ARAAudioSourceHostRef audioSourceHostRef,
 -                                                            bool use64BitSamples) noexcept override
 -     {
 -         auto audioReader = std::make_unique<AudioReader> (audioSourceHostRef, use64BitSamples);
 -         auto audioReaderHostRef = Converter::toHostRef (audioReader.get());
 -         auto* readerPtr = audioReader.get();
 -         audioReaders.emplace (readerPtr, std::move (audioReader));
 -         return audioReaderHostRef;
 -     }
 - 
 -     bool readAudioSamples (ARA::ARAAudioReaderHostRef readerRef,
 -                            ARA::ARASamplePosition samplePosition,
 -                            ARA::ARASampleCount samplesPerChannel,
 -                            void* const* buffers) noexcept override
 -     {
 -         const auto use64BitSamples = Converter::fromHostRef (readerRef)->use64Bit;
 -         auto* audioSource = FileAudioSource::Converter::fromHostRef (Converter::fromHostRef (readerRef)->sourceHostRef);
 - 
 -         if (use64BitSamples)
 -             return audioSource->readAudioSamples (
 -                 reinterpret_cast<double* const*> (buffers), samplePosition, samplesPerChannel);
 - 
 -         return audioSource->readAudioSamples (
 -             reinterpret_cast<float* const*> (buffers), samplePosition, samplesPerChannel);
 -     }
 - 
 -     void destroyAudioReader (ARA::ARAAudioReaderHostRef readerRef) noexcept override
 -     {
 -         audioReaders.erase (Converter::fromHostRef (readerRef));
 -     }
 - 
 - private:
 -     struct AudioReader
 -     {
 -         AudioReader (ARA::ARAAudioSourceHostRef source, bool use64BitSamples)
 -             : sourceHostRef (source), use64Bit (use64BitSamples)
 -         {
 -         }
 - 
 -         ARA::ARAAudioSourceHostRef sourceHostRef;
 -         bool use64Bit;
 -     };
 - 
 -     using Converter = ARAHostModel::ConversionFunctions<AudioReader*, ARA::ARAAudioReaderHostRef>;
 - 
 -     std::map<AudioReader*, std::unique_ptr<AudioReader>> audioReaders;
 - };
 - 
 - class ArchivingController final : public ARA::Host::ArchivingControllerInterface
 - {
 - public:
 -     using ReaderConverter = ARAHostModel::ConversionFunctions<MemoryBlock*, ARA::ARAArchiveReaderHostRef>;
 -     using WriterConverter = ARAHostModel::ConversionFunctions<MemoryOutputStream*, ARA::ARAArchiveWriterHostRef>;
 - 
 -     ARA::ARASize getArchiveSize (ARA::ARAArchiveReaderHostRef archiveReaderHostRef) noexcept override
 -     {
 -         return (ARA::ARASize) ReaderConverter::fromHostRef (archiveReaderHostRef)->getSize();
 -     }
 - 
 -     bool readBytesFromArchive (ARA::ARAArchiveReaderHostRef archiveReaderHostRef,
 -                                ARA::ARASize position,
 -                                ARA::ARASize length,
 -                                ARA::ARAByte* buffer) noexcept override
 -     {
 -         auto* archiveReader = ReaderConverter::fromHostRef (archiveReaderHostRef);
 - 
 -         if ((position + length) <= archiveReader->getSize())
 -         {
 -             std::memcpy (buffer, addBytesToPointer (archiveReader->getData(), position), length);
 -             return true;
 -         }
 - 
 -         return false;
 -     }
 - 
 -     bool writeBytesToArchive (ARA::ARAArchiveWriterHostRef archiveWriterHostRef,
 -                               ARA::ARASize position,
 -                               ARA::ARASize length,
 -                               const ARA::ARAByte* buffer) noexcept override
 -     {
 -         auto* archiveWriter = WriterConverter::fromHostRef (archiveWriterHostRef);
 - 
 -         if (archiveWriter->setPosition ((int64) position) && archiveWriter->write (buffer, length))
 -             return true;
 - 
 -         return false;
 -     }
 - 
 -     void notifyDocumentArchivingProgress (float value) noexcept override { ignoreUnused (value); }
 - 
 -     void notifyDocumentUnarchivingProgress (float value) noexcept override { ignoreUnused (value); }
 - 
 -     ARA::ARAPersistentID getDocumentArchiveID (ARA::ARAArchiveReaderHostRef archiveReaderHostRef) noexcept override
 -     {
 -         ignoreUnused (archiveReaderHostRef);
 - 
 -         return nullptr;
 -     }
 - };
 - 
 - class ContentAccessController final : public ARA::Host::ContentAccessControllerInterface
 - {
 - public:
 -     using Converter = ARAHostModel::ConversionFunctions<ARA::ARAContentType, ARA::ARAContentReaderHostRef>;
 - 
 -     bool isMusicalContextContentAvailable (ARA::ARAMusicalContextHostRef musicalContextHostRef,
 -                                            ARA::ARAContentType type) noexcept override
 -     {
 -         ignoreUnused (musicalContextHostRef);
 - 
 -         return (type == ARA::kARAContentTypeTempoEntries || type == ARA::kARAContentTypeBarSignatures);
 -     }
 - 
 -     ARA::ARAContentGrade getMusicalContextContentGrade (ARA::ARAMusicalContextHostRef musicalContextHostRef,
 -                                                         ARA::ARAContentType type) noexcept override
 -     {
 -         ignoreUnused (musicalContextHostRef, type);
 - 
 -         return ARA::kARAContentGradeInitial;
 -     }
 - 
 -     ARA::ARAContentReaderHostRef
 -         createMusicalContextContentReader (ARA::ARAMusicalContextHostRef musicalContextHostRef,
 -                                            ARA::ARAContentType type,
 -                                            const ARA::ARAContentTimeRange* range) noexcept override
 -     {
 -         ignoreUnused (musicalContextHostRef, range);
 - 
 -         return Converter::toHostRef (type);
 -     }
 - 
 -     bool isAudioSourceContentAvailable (ARA::ARAAudioSourceHostRef audioSourceHostRef,
 -                                         ARA::ARAContentType type) noexcept override
 -     {
 -         ignoreUnused (audioSourceHostRef, type);
 - 
 -         return false;
 -     }
 - 
 -     ARA::ARAContentGrade getAudioSourceContentGrade (ARA::ARAAudioSourceHostRef audioSourceHostRef,
 -                                                      ARA::ARAContentType type) noexcept override
 -     {
 -         ignoreUnused (audioSourceHostRef, type);
 - 
 -         return 0;
 -     }
 - 
 -     ARA::ARAContentReaderHostRef
 -         createAudioSourceContentReader (ARA::ARAAudioSourceHostRef audioSourceHostRef,
 -                                         ARA::ARAContentType type,
 -                                         const ARA::ARAContentTimeRange* range) noexcept override
 -     {
 -         ignoreUnused (audioSourceHostRef, type, range);
 - 
 -         return nullptr;
 -     }
 - 
 -     ARA::ARAInt32 getContentReaderEventCount (ARA::ARAContentReaderHostRef contentReaderHostRef) noexcept override
 -     {
 -         const auto contentType = Converter::fromHostRef (contentReaderHostRef);
 - 
 -         if (contentType == ARA::kARAContentTypeTempoEntries || contentType == ARA::kARAContentTypeBarSignatures)
 -             return 2;
 - 
 -         return 0;
 -     }
 - 
 -     const void* getContentReaderDataForEvent (ARA::ARAContentReaderHostRef contentReaderHostRef,
 -                                               ARA::ARAInt32 eventIndex) noexcept override
 -     {
 -         if (Converter::fromHostRef (contentReaderHostRef) == ARA::kARAContentTypeTempoEntries)
 -         {
 -             if (eventIndex == 0)
 -             {
 -                 tempoEntry.timePosition = 0.0;
 -                 tempoEntry.quarterPosition = 0.0;
 -             }
 -             else if (eventIndex == 1)
 -             {
 -                 tempoEntry.timePosition = 2.0;
 -                 tempoEntry.quarterPosition = 4.0;
 -             }
 - 
 -             return &tempoEntry;
 -         }
 -         else if (Converter::fromHostRef (contentReaderHostRef) == ARA::kARAContentTypeBarSignatures)
 -         {
 -             if (eventIndex == 0)
 -             {
 -                 barSignature.position = 0.0;
 -                 barSignature.numerator = 4;
 -                 barSignature.denominator = 4;
 -             }
 - 
 -             if (eventIndex == 1)
 -             {
 -                 barSignature.position = 1.0;
 -                 barSignature.numerator = 4;
 -                 barSignature.denominator = 4;
 -             }
 - 
 -             return &barSignature;
 -         }
 - 
 -         jassertfalse;
 -         return nullptr;
 -     }
 - 
 -     void destroyContentReader (ARA::ARAContentReaderHostRef contentReaderHostRef) noexcept override
 -     {
 -         ignoreUnused (contentReaderHostRef);
 -     }
 - 
 -     ARA::ARAContentTempoEntry tempoEntry;
 -     ARA::ARAContentBarSignature barSignature;
 - };
 - 
 - class ModelUpdateController final : public ARA::Host::ModelUpdateControllerInterface
 - {
 - public:
 -     void notifyAudioSourceAnalysisProgress (ARA::ARAAudioSourceHostRef audioSourceHostRef,
 -                                             ARA::ARAAnalysisProgressState state,
 -                                             float value) noexcept override
 -     {
 -         ignoreUnused (audioSourceHostRef, state, value);
 -     }
 - 
 -     void notifyAudioSourceContentChanged (ARA::ARAAudioSourceHostRef audioSourceHostRef,
 -                                           const ARA::ARAContentTimeRange* range,
 -                                           ARA::ContentUpdateScopes scopeFlags) noexcept override
 -     {
 -         ignoreUnused (audioSourceHostRef, range, scopeFlags);
 -     }
 - 
 -     void notifyAudioModificationContentChanged (ARA::ARAAudioModificationHostRef audioModificationHostRef,
 -                                                 const ARA::ARAContentTimeRange* range,
 -                                                 ARA::ContentUpdateScopes scopeFlags) noexcept override
 -     {
 -         ignoreUnused (audioModificationHostRef, range, scopeFlags);
 -     }
 - 
 -     void notifyPlaybackRegionContentChanged (ARA::ARAPlaybackRegionHostRef playbackRegionHostRef,
 -                                              const ARA::ARAContentTimeRange* range,
 -                                              ARA::ContentUpdateScopes scopeFlags) noexcept override
 -     {
 -         ignoreUnused (playbackRegionHostRef, range, scopeFlags);
 -     }
 - };
 - 
 - class PlaybackController final : public ARA::Host::PlaybackControllerInterface
 - {
 - public:
 -     void requestStartPlayback() noexcept override {}
 -     void requestStopPlayback() noexcept override {}
 - 
 -     void requestSetPlaybackPosition (ARA::ARATimePosition timePosition) noexcept override
 -     {
 -         ignoreUnused (timePosition);
 -     }
 - 
 -     void requestSetCycleRange (ARA::ARATimePosition startTime, ARA::ARATimeDuration duration) noexcept override
 -     {
 -         ignoreUnused (startTime, duration);
 -     }
 - 
 -     void requestEnableCycle (bool enable) noexcept override { ignoreUnused (enable); }
 - };
 - 
 - struct SimplePlayHead final : public juce::AudioPlayHead
 - {
 -     Optional<PositionInfo> getPosition() const override
 -     {
 -         PositionInfo result;
 -         result.setTimeInSamples (timeInSamples.load());
 -         result.setIsPlaying (isPlaying.load());
 -         return result;
 -     }
 - 
 -     std::atomic<int64_t> timeInSamples { 0 };
 -     std::atomic<bool> isPlaying { false };
 - };
 - 
 - struct HostPlaybackController
 - {
 -     virtual ~HostPlaybackController() = default;
 - 
 -     virtual void setPlaying (bool isPlaying) = 0;
 -     virtual void goToStart() = 0;
 -     virtual File getAudioSource() const = 0;
 -     virtual void setAudioSource (File audioSourceFile) = 0;
 -     virtual void clearAudioSource() = 0;
 - };
 - 
 - class AudioSourceComponent final : public Component,
 -                                    public FileDragAndDropTarget,
 -                                    public ChangeListener
 - {
 - public:
 -     explicit AudioSourceComponent (HostPlaybackController& controller, juce::ChangeBroadcaster& bc)
 -         : hostPlaybackController (controller),
 -           broadcaster (bc),
 -           waveformComponent (*this)
 -     {
 -         audioSourceLabel.setText ("You can drag and drop .wav files here", NotificationType::dontSendNotification);
 - 
 -         addAndMakeVisible (audioSourceLabel);
 -         addAndMakeVisible (waveformComponent);
 - 
 -         playButton.setButtonText ("Play / Pause");
 -         playButton.onClick = [this]
 -         {
 -             isPlaying = ! isPlaying;
 -             hostPlaybackController.setPlaying (isPlaying);
 -         };
 - 
 -         goToStartButton.setButtonText ("Go to start");
 -         goToStartButton.onClick = [this] { hostPlaybackController.goToStart(); };
 - 
 -         addAndMakeVisible (goToStartButton);
 -         addAndMakeVisible (playButton);
 - 
 -         broadcaster.addChangeListener (this);
 - 
 -         update();
 -     }
 - 
 -     ~AudioSourceComponent() override
 -     {
 -         broadcaster.removeChangeListener (this);
 -     }
 - 
 -     void changeListenerCallback (ChangeBroadcaster*) override
 -     {
 -         update();
 -     }
 - 
 -     void resized() override
 -     {
 -         auto localBounds = getLocalBounds();
 -         auto buttonsArea = localBounds.removeFromBottom (40).reduced (5);
 -         auto waveformArea = localBounds.removeFromBottom (150).reduced (5);
 - 
 -         juce::FlexBox fb;
 -         fb.justifyContent = juce::FlexBox::JustifyContent::center;
 -         fb.alignContent = juce::FlexBox::AlignContent::center;
 - 
 -         fb.items = { juce::FlexItem (goToStartButton).withMinWidth (100.0f).withMinHeight ((float) buttonsArea.getHeight()),
 -                      juce::FlexItem (playButton).withMinWidth (100.0f).withMinHeight ((float) buttonsArea.getHeight()) };
 - 
 -         fb.performLayout (buttonsArea);
 - 
 -         waveformComponent.setBounds (waveformArea);
 - 
 -         audioSourceLabel.setBounds (localBounds);
 -     }
 - 
 -     bool isInterestedInFileDrag (const StringArray& files) override
 -     {
 -         if (files.size() != 1)
 -             return false;
 - 
 -         if (files.getReference (0).endsWithIgnoreCase (".wav"))
 -             return true;
 - 
 -         return false;
 -     }
 - 
 -     void update()
 -     {
 -         const auto currentAudioSource = hostPlaybackController.getAudioSource();
 - 
 -         if (currentAudioSource.existsAsFile())
 -         {
 -             waveformComponent.setSource (currentAudioSource);
 -             audioSourceLabel.setText (currentAudioSource.getFullPathName(),
 -                                       NotificationType::dontSendNotification);
 -         }
 -         else
 -         {
 -             waveformComponent.clearSource();
 -             audioSourceLabel.setText ("You can drag and drop .wav files here", NotificationType::dontSendNotification);
 -         }
 -     }
 - 
 -     void filesDropped (const StringArray& files, int, int) override
 -     {
 -         hostPlaybackController.setAudioSource (files.getReference (0));
 -         update();
 -     }
 - 
 - private:
 -     class WaveformComponent final : public Component,
 -                                     public ChangeListener
 -     {
 -     public:
 -         WaveformComponent (AudioSourceComponent& p)
 -             : parent (p),
 -               thumbCache (7),
 -               audioThumb (128, formatManager, thumbCache)
 -         {
 -             setWantsKeyboardFocus (true);
 -             formatManager.registerBasicFormats();
 -             audioThumb.addChangeListener (this);
 -         }
 - 
 -         ~WaveformComponent() override
 -         {
 -             audioThumb.removeChangeListener (this);
 -         }
 - 
 -         void mouseDown (const MouseEvent&) override
 -         {
 -             isSelected = true;
 -             repaint();
 -         }
 - 
 -         void changeListenerCallback (ChangeBroadcaster*) override
 -         {
 -             repaint();
 -         }
 - 
 -         void paint (juce::Graphics& g) override
 -         {
 -             if (! isEmpty)
 -             {
 -                 auto rect = getLocalBounds();
 - 
 -                 const auto waveformColour = Colours::cadetblue;
 - 
 -                 if (rect.getWidth() > 2)
 -                 {
 -                     g.setColour (isSelected ? juce::Colours::yellow : juce::Colours::black);
 -                     g.drawRect (rect);
 -                     rect.reduce (1, 1);
 -                     g.setColour (waveformColour.darker (1.0f));
 -                     g.fillRect (rect);
 -                 }
 - 
 -                 g.setColour (Colours::cadetblue);
 -                 audioThumb.drawChannels (g, rect, 0.0, audioThumb.getTotalLength(), 1.0f);
 -             }
 -         }
 - 
 -         void setSource (const File& source)
 -         {
 -             isEmpty = false;
 -             audioThumb.setSource (new FileInputSource (source));
 -         }
 - 
 -         void clearSource()
 -         {
 -             isEmpty = true;
 -             isSelected = false;
 -             audioThumb.clear();
 -         }
 - 
 -         bool keyPressed (const KeyPress& key) override
 -         {
 -             if (isSelected && key == KeyPress::deleteKey)
 -             {
 -                 parent.hostPlaybackController.clearAudioSource();
 -                 return true;
 -             }
 - 
 -             return false;
 -         }
 - 
 -     private:
 -         AudioSourceComponent& parent;
 - 
 -         bool isEmpty = true;
 -         bool isSelected = false;
 -         AudioFormatManager formatManager;
 -         AudioThumbnailCache thumbCache;
 -         AudioThumbnail audioThumb;
 -     };
 - 
 -     HostPlaybackController& hostPlaybackController;
 -     juce::ChangeBroadcaster& broadcaster;
 -     Label audioSourceLabel;
 -     WaveformComponent waveformComponent;
 -     bool isPlaying { false };
 -     TextButton playButton, goToStartButton;
 - };
 - 
 - class ARAPluginInstanceWrapper final : public AudioPluginInstance
 - {
 - public:
 -     class ARATestHost final : public HostPlaybackController,
 -                               public juce::ChangeBroadcaster
 -     {
 -     public:
 -         class Editor final : public AudioProcessorEditor
 -         {
 -         public:
 -             explicit Editor (ARATestHost& araTestHost)
 -                 : AudioProcessorEditor (araTestHost.getAudioPluginInstance()),
 -                   audioSourceComponent (araTestHost, araTestHost)
 -             {
 -                 audioSourceComponent.update();
 -                 addAndMakeVisible (audioSourceComponent);
 -                 setSize (512, 220);
 -             }
 - 
 -             ~Editor() override { getAudioProcessor()->editorBeingDeleted (this); }
 - 
 -             void resized() override { audioSourceComponent.setBounds (getLocalBounds()); }
 - 
 -         private:
 -             AudioSourceComponent audioSourceComponent;
 -         };
 - 
 -         explicit ARATestHost (ARAPluginInstanceWrapper& instanceIn)
 -             : instance (instanceIn)
 -         {
 -             if (instance.inner->getPluginDescription().hasARAExtension)
 -             {
 -                 instance.inner->setPlayHead (&playHead);
 - 
 -                 createARAFactoryAsync (*instance.inner, [this] (ARAFactoryWrapper araFactory)
 -                                                         {
 -                                                             init (std::move (araFactory));
 -                                                         });
 -             }
 -         }
 - 
 -         void init (ARAFactoryWrapper araFactory)
 -         {
 -             if (araFactory.get() != nullptr)
 -             {
 -                 documentController = ARAHostDocumentController::create (std::move (araFactory),
 -                                                                         "AudioPluginHostDocument",
 -                                                                         std::make_unique<AudioAccessController>(),
 -                                                                         std::make_unique<ArchivingController>(),
 -                                                                         std::make_unique<ContentAccessController>(),
 -                                                                         std::make_unique<ModelUpdateController>(),
 -                                                                         std::make_unique<PlaybackController>());
 - 
 -                 if (documentController != nullptr)
 -                 {
 -                     const auto allRoles = ARA::kARAPlaybackRendererRole | ARA::kARAEditorRendererRole | ARA::kARAEditorViewRole;
 -                     const auto plugInExtensionInstance = documentController->bindDocumentToPluginInstance (*instance.inner,
 -                                                                                                            allRoles,
 -                                                                                                            allRoles);
 -                     playbackRenderer = plugInExtensionInstance.getPlaybackRendererInterface();
 -                     editorRenderer   = plugInExtensionInstance.getEditorRendererInterface();
 -                     synchronizeStateWithDocumentController();
 -                 }
 -                 else
 -                     jassertfalse;
 -             }
 -             else
 -                 jassertfalse;
 -         }
 - 
 -         void getStateInformation (juce::MemoryBlock& b)
 -         {
 -             std::lock_guard<std::mutex> configurationLock (instance.innerMutex);
 - 
 -             if (context != nullptr)
 -                 context->getStateInformation (b);
 -         }
 - 
 -         void setStateInformation (const void* d, int s)
 -         {
 -             {
 -                 std::lock_guard<std::mutex> lock { contextUpdateSourceMutex };
 -                 contextUpdateSource = ContextUpdateSource { d, s };
 -             }
 - 
 -             synchronise();
 -         }
 - 
 -         ~ARATestHost() override { instance.inner->releaseResources(); }
 - 
 -         void afterProcessBlock (int numSamples)
 -         {
 -             const auto isPlayingNow = isPlaying.load();
 -             playHead.isPlaying.store (isPlayingNow);
 - 
 -             if (isPlayingNow)
 -             {
 -                 const auto currentAudioSourceLength = audioSourceLength.load();
 -                 const auto currentPlayHeadPosition = playHead.timeInSamples.load();
 - 
 -                 // Rudimentary attempt to not seek beyond our sample data, assuming a fairly stable numSamples
 -                 // value. We should gain control over calling the AudioProcessorGraph's processBlock() calls so
 -                 // that we can do sample precise looping.
 -                 if (currentAudioSourceLength - currentPlayHeadPosition < numSamples)
 -                     playHead.timeInSamples.store (0);
 -                 else
 -                     playHead.timeInSamples.fetch_add (numSamples);
 -             }
 - 
 -             if (goToStartSignal.exchange (false))
 -                 playHead.timeInSamples.store (0);
 -         }
 - 
 -         File getAudioSource() const override
 -         {
 -             std::lock_guard<std::mutex> lock { instance.innerMutex };
 - 
 -             if (context != nullptr)
 -                 return context->audioFile;
 - 
 -             return {};
 -         }
 - 
 -         void setAudioSource (File audioSourceFile) override
 -         {
 -             if (audioSourceFile.existsAsFile())
 -             {
 -                 {
 -                     std::lock_guard<std::mutex> lock { contextUpdateSourceMutex };
 -                     contextUpdateSource = ContextUpdateSource (std::move (audioSourceFile));
 -                 }
 - 
 -                 synchronise();
 -             }
 -         }
 - 
 -         void clearAudioSource() override
 -         {
 -             {
 -                 std::lock_guard<std::mutex> lock { contextUpdateSourceMutex };
 -                 contextUpdateSource = ContextUpdateSource (ContextUpdateSource::Type::reset);
 -             }
 - 
 -             synchronise();
 -         }
 - 
 -         void setPlaying (bool isPlayingIn) override { isPlaying.store (isPlayingIn); }
 - 
 -         void goToStart() override { goToStartSignal.store (true); }
 - 
 -         Editor* createEditor() { return new Editor (*this); }
 - 
 -         AudioPluginInstance& getAudioPluginInstance() { return instance; }
 - 
 -     private:
 -         /**  Use this to put the plugin in an unprepared state for the duration of adding and removing PlaybackRegions
 -              to and from Renderers.
 -         */
 -         class ScopedPluginDeactivator
 -         {
 -         public:
 -             explicit ScopedPluginDeactivator (ARAPluginInstanceWrapper& inst) : instance (inst)
 -             {
 -                 if (instance.prepareToPlayParams.isValid)
 -                     instance.inner->releaseResources();
 -             }
 - 
 -             ~ScopedPluginDeactivator()
 -             {
 -                 if (instance.prepareToPlayParams.isValid)
 -                     instance.inner->prepareToPlay (instance.prepareToPlayParams.sampleRate,
 -                                                    instance.prepareToPlayParams.samplesPerBlock);
 -             }
 - 
 -         private:
 -             ARAPluginInstanceWrapper& instance;
 - 
 -             JUCE_DECLARE_NON_COPYABLE (ScopedPluginDeactivator)
 -         };
 - 
 -         class ContextUpdateSource
 -         {
 -         public:
 -             enum class Type
 -             {
 -                 empty,
 -                 audioSourceFile,
 -                 stateInformation,
 -                 reset
 -             };
 - 
 -             ContextUpdateSource() = default;
 - 
 -             explicit ContextUpdateSource (const File& file)
 -                 : type (Type::audioSourceFile),
 -                   audioSourceFile (file)
 -             {
 -             }
 - 
 -             ContextUpdateSource (const void* d, int s)
 -                 : type (Type::stateInformation),
 -                   stateInformation (d, (size_t) s)
 -             {
 -             }
 - 
 -             ContextUpdateSource (Type t) : type (t)
 -             {
 -                 jassert (t == Type::reset);
 -             }
 - 
 -             Type getType() const { return type; }
 - 
 -             const File& getAudioSourceFile() const
 -             {
 -                 jassert (type == Type::audioSourceFile);
 - 
 -                 return audioSourceFile;
 -             }
 - 
 -             const MemoryBlock& getStateInformation() const
 -             {
 -                 jassert (type == Type::stateInformation);
 - 
 -                 return stateInformation;
 -             }
 - 
 -         private:
 -             Type type = Type::empty;
 - 
 -             File audioSourceFile;
 -             MemoryBlock stateInformation;
 -         };
 - 
 -         void synchronise()
 -         {
 -             const SpinLock::ScopedLockType scope (instance.innerProcessBlockFlag);
 -             std::lock_guard<std::mutex> configurationLock (instance.innerMutex);
 -             synchronizeStateWithDocumentController();
 -         }
 - 
 -         void synchronizeStateWithDocumentController()
 -         {
 -             bool resetContext = false;
 - 
 -             auto newContext = [&]() -> std::unique_ptr<Context>
 -             {
 -                 std::lock_guard<std::mutex> lock { contextUpdateSourceMutex };
 - 
 -                 switch (contextUpdateSource.getType())
 -                 {
 -                     case ContextUpdateSource::Type::empty:
 -                         return {};
 - 
 -                     case ContextUpdateSource::Type::audioSourceFile:
 -                         if (! (contextUpdateSource.getAudioSourceFile().existsAsFile()))
 -                             return {};
 - 
 -                         {
 -                             const ARAEditGuard editGuard (documentController->getDocumentController());
 -                             return std::make_unique<Context> (documentController->getDocumentController(),
 -                                                               contextUpdateSource.getAudioSourceFile());
 -                         }
 - 
 -                     case ContextUpdateSource::Type::stateInformation:
 -                         jassert (contextUpdateSource.getStateInformation().getSize() <= std::numeric_limits<int>::max());
 - 
 -                         return Context::createFromStateInformation (documentController->getDocumentController(),
 -                                                                     contextUpdateSource.getStateInformation().getData(),
 -                                                                     (int) contextUpdateSource.getStateInformation().getSize());
 - 
 -                     case ContextUpdateSource::Type::reset:
 -                         resetContext = true;
 -                         return {};
 -                 }
 - 
 -                 jassertfalse;
 -                 return {};
 -             }();
 - 
 -             if (newContext != nullptr)
 -             {
 -                 {
 -                     ScopedPluginDeactivator deactivator (instance);
 - 
 -                     context = std::move (newContext);
 -                     audioSourceLength.store (context->fileAudioSource.getFormatReader().lengthInSamples);
 - 
 -                     auto& region = context->playbackRegion.getPlaybackRegion();
 -                     playbackRenderer.add (region);
 -                     editorRenderer.add (region);
 -                 }
 - 
 -                 sendChangeMessage();
 -             }
 - 
 -             if (resetContext)
 -             {
 -                 {
 -                     ScopedPluginDeactivator deactivator (instance);
 - 
 -                     context.reset();
 -                     audioSourceLength.store (0);
 -                 }
 - 
 -                 sendChangeMessage();
 -             }
 -         }
 - 
 -         struct Context
 -         {
 -             Context (ARA::Host::DocumentController& dc, const File& audioFileIn)
 -                 : audioFile (audioFileIn),
 -                   musicalContext    (dc),
 -                   regionSequence    (dc, musicalContext, "track 1"),
 -                   fileAudioSource   (dc, audioFile),
 -                   audioModification (dc, fileAudioSource),
 -                   playbackRegion    (dc, regionSequence, audioModification, fileAudioSource)
 -             {
 -             }
 - 
 -             static std::unique_ptr<Context> createFromStateInformation (ARA::Host::DocumentController& dc, const void* d, int s)
 -             {
 -                 if (auto xml = getXmlFromBinary (d, s))
 -                 {
 -                     if (xml->hasTagName (xmlRootTag))
 -                     {
 -                         File file { xml->getStringAttribute (xmlAudioFileAttrib) };
 - 
 -                         if (file.existsAsFile())
 -                             return std::make_unique<Context> (dc, std::move (file));
 -                     }
 -                 }
 - 
 -                 return {};
 -             }
 - 
 -             void getStateInformation (juce::MemoryBlock& b)
 -             {
 -                 XmlElement root { xmlRootTag };
 -                 root.setAttribute (xmlAudioFileAttrib, audioFile.getFullPathName());
 -                 copyXmlToBinary (root, b);
 -             }
 - 
 -             const static Identifier xmlRootTag;
 -             const static Identifier xmlAudioFileAttrib;
 - 
 -             File audioFile;
 - 
 -             MusicalContext musicalContext;
 -             RegionSequence regionSequence;
 -             FileAudioSource fileAudioSource;
 -             AudioModification audioModification;
 -             PlaybackRegion playbackRegion;
 -         };
 - 
 -         SimplePlayHead playHead;
 -         ARAPluginInstanceWrapper& instance;
 - 
 -         std::unique_ptr<ARAHostDocumentController> documentController;
 -         ARAHostModel::PlaybackRendererInterface playbackRenderer;
 -         ARAHostModel::EditorRendererInterface editorRenderer;
 - 
 -         std::unique_ptr<Context> context;
 - 
 -         mutable std::mutex contextUpdateSourceMutex;
 -         ContextUpdateSource contextUpdateSource;
 - 
 -         std::atomic<bool> isPlaying { false };
 -         std::atomic<bool> goToStartSignal { false };
 -         std::atomic<int64> audioSourceLength { 0 };
 -     };
 - 
 -     explicit ARAPluginInstanceWrapper (std::unique_ptr<AudioPluginInstance> innerIn)
 -         : inner (std::move (innerIn)), araHost (*this)
 -     {
 -         jassert (inner != nullptr);
 - 
 -         for (auto isInput : { true, false })
 -             matchBuses (isInput);
 - 
 -         setBusesLayout (inner->getBusesLayout());
 -     }
 - 
 -     //==============================================================================
 -     AudioProcessorEditor* createARAHostEditor() { return araHost.createEditor(); }
 - 
 -     //==============================================================================
 -     const String getName() const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->getName();
 -     }
 - 
 -     StringArray getAlternateDisplayNames() const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->getAlternateDisplayNames();
 -     }
 - 
 -     double getTailLengthSeconds() const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->getTailLengthSeconds();
 -     }
 - 
 -     bool acceptsMidi() const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->acceptsMidi();
 -     }
 - 
 -     bool producesMidi() const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->producesMidi();
 -     }
 - 
 -     AudioProcessorEditor* createEditor() override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->createEditorIfNeeded();
 -     }
 - 
 -     bool hasEditor() const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->hasEditor();
 -     }
 - 
 -     int getNumPrograms() override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->getNumPrograms();
 -     }
 - 
 -     int getCurrentProgram() override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->getCurrentProgram();
 -     }
 - 
 -     void setCurrentProgram (int i) override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->setCurrentProgram (i);
 -     }
 - 
 -     const String getProgramName (int i) override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->getProgramName (i);
 -     }
 - 
 -     void changeProgramName (int i, const String& n) override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->changeProgramName (i, n);
 -     }
 - 
 -     void getStateInformation (juce::MemoryBlock& b) override
 -     {
 -         XmlElement state ("ARAPluginInstanceWrapperState");
 - 
 -         {
 -             MemoryBlock m;
 -             araHost.getStateInformation (m);
 -             state.createNewChildElement ("host")->addTextElement (m.toBase64Encoding());
 -         }
 - 
 -         {
 -             std::lock_guard<std::mutex> lock (innerMutex);
 - 
 -             MemoryBlock m;
 -             inner->getStateInformation (m);
 -             state.createNewChildElement ("plugin")->addTextElement (m.toBase64Encoding());
 -         }
 - 
 -         copyXmlToBinary (state, b);
 -     }
 - 
 -     void setStateInformation (const void* d, int s) override
 -     {
 -         if (auto xml = getXmlFromBinary (d, s))
 -         {
 -             if (xml->hasTagName ("ARAPluginInstanceWrapperState"))
 -             {
 -                 if (auto* hostState = xml->getChildByName ("host"))
 -                 {
 -                     MemoryBlock m;
 -                     m.fromBase64Encoding (hostState->getAllSubText());
 -                     jassert (m.getSize() <= std::numeric_limits<int>::max());
 -                     araHost.setStateInformation (m.getData(), (int) m.getSize());
 -                 }
 - 
 -                 if (auto* pluginState = xml->getChildByName ("plugin"))
 -                 {
 -                     std::lock_guard<std::mutex> lock (innerMutex);
 - 
 -                     MemoryBlock m;
 -                     m.fromBase64Encoding (pluginState->getAllSubText());
 -                     jassert (m.getSize() <= std::numeric_limits<int>::max());
 -                     inner->setStateInformation (m.getData(), (int) m.getSize());
 -                 }
 -             }
 -         }
 -     }
 - 
 -     void getCurrentProgramStateInformation (juce::MemoryBlock& b) override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->getCurrentProgramStateInformation (b);
 -     }
 - 
 -     void setCurrentProgramStateInformation (const void* d, int s) override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->setCurrentProgramStateInformation (d, s);
 -     }
 - 
 -     void prepareToPlay (double sr, int bs) override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->setRateAndBufferSizeDetails (sr, bs);
 -         inner->prepareToPlay (sr, bs);
 -         prepareToPlayParams = { sr, bs };
 -     }
 - 
 -     void releaseResources() override { inner->releaseResources(); }
 - 
 -     void memoryWarningReceived() override { inner->memoryWarningReceived(); }
 - 
 -     void processBlock (AudioBuffer<float>& a, MidiBuffer& m) override
 -     {
 -         const SpinLock::ScopedTryLockType scope (innerProcessBlockFlag);
 - 
 -         if (! scope.isLocked())
 -             return;
 - 
 -         inner->processBlock (a, m);
 -         araHost.afterProcessBlock (a.getNumSamples());
 -     }
 - 
 -     void processBlock (AudioBuffer<double>& a, MidiBuffer& m) override
 -     {
 -         const SpinLock::ScopedTryLockType scope (innerProcessBlockFlag);
 - 
 -         if (! scope.isLocked())
 -             return;
 - 
 -         inner->processBlock (a, m);
 -         araHost.afterProcessBlock (a.getNumSamples());
 -     }
 - 
 -     void processBlockBypassed (AudioBuffer<float>& a, MidiBuffer& m) override
 -     {
 -         const SpinLock::ScopedTryLockType scope (innerProcessBlockFlag);
 - 
 -         if (! scope.isLocked())
 -             return;
 - 
 -         inner->processBlockBypassed (a, m);
 -         araHost.afterProcessBlock (a.getNumSamples());
 -     }
 - 
 -     void processBlockBypassed (AudioBuffer<double>& a, MidiBuffer& m) override
 -     {
 -         const SpinLock::ScopedTryLockType scope (innerProcessBlockFlag);
 - 
 -         if (! scope.isLocked())
 -             return;
 - 
 -         inner->processBlockBypassed (a, m);
 -         araHost.afterProcessBlock (a.getNumSamples());
 -     }
 - 
 -     bool supportsDoublePrecisionProcessing() const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->supportsDoublePrecisionProcessing();
 -     }
 - 
 -     bool supportsMPE() const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->supportsMPE();
 -     }
 - 
 -     bool isMidiEffect() const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->isMidiEffect();
 -     }
 - 
 -     void reset() override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->reset();
 -     }
 - 
 -     void setNonRealtime (bool b) noexcept override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->setNonRealtime (b);
 -     }
 - 
 -     void refreshParameterList() override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->refreshParameterList();
 -     }
 - 
 -     void numChannelsChanged() override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->numChannelsChanged();
 -     }
 - 
 -     void numBusesChanged() override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->numBusesChanged();
 -     }
 - 
 -     void processorLayoutsChanged() override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->processorLayoutsChanged();
 -     }
 - 
 -     void setPlayHead (AudioPlayHead* p) override { ignoreUnused (p); }
 - 
 -     void updateTrackProperties (const TrackProperties& p) override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         inner->updateTrackProperties (p);
 -     }
 - 
 -     bool isBusesLayoutSupported (const BusesLayout& layout) const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return inner->checkBusesLayoutSupported (layout);
 -     }
 - 
 -     bool canAddBus (bool) const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return true;
 -     }
 -     bool canRemoveBus (bool) const override
 -     {
 -         std::lock_guard<std::mutex> lock (innerMutex);
 -         return true;
 -     }
 - 
 -     //==============================================================================
 -     void fillInPluginDescription (PluginDescription& description) const override
 -     {
 -         return inner->fillInPluginDescription (description);
 -     }
 - 
 - private:
 -     void matchBuses (bool isInput)
 -     {
 -         const auto inBuses = inner->getBusCount (isInput);
 - 
 -         while (getBusCount (isInput) < inBuses)
 -             addBus (isInput);
 - 
 -         while (inBuses < getBusCount (isInput))
 -             removeBus (isInput);
 -     }
 - 
 -     // Used for mutual exclusion between the audio and other threads
 -     SpinLock innerProcessBlockFlag;
 - 
 -     // Used for mutual exclusion on non-audio threads
 -     mutable std::mutex innerMutex;
 - 
 -     std::unique_ptr<AudioPluginInstance> inner;
 - 
 -     ARATestHost araHost;
 - 
 -     struct PrepareToPlayParams
 -     {
 -         PrepareToPlayParams() : isValid (false) {}
 - 
 -         PrepareToPlayParams (double sampleRateIn, int samplesPerBlockIn)
 -             : isValid (true), sampleRate (sampleRateIn), samplesPerBlock (samplesPerBlockIn)
 -         {
 -         }
 - 
 -         bool isValid;
 -         double sampleRate;
 -         int samplesPerBlock;
 -     };
 - 
 -     PrepareToPlayParams prepareToPlayParams;
 - 
 -     //==============================================================================
 -     JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ARAPluginInstanceWrapper)
 - };
 - #endif
 
 
  |