| @@ -107,6 +107,8 @@ JuceDemoPluginAudioProcessorEditor::JuceDemoPluginAudioProcessorEditor (JuceDemo | |||||
| setSize (owner.lastUIWidth, | setSize (owner.lastUIWidth, | ||||
| owner.lastUIHeight); | owner.lastUIHeight); | ||||
| updateTrackProperties(); | |||||
| // start a timer which will keep our timecode display updated | // start a timer which will keep our timecode display updated | ||||
| startTimerHz (30); | startTimerHz (30); | ||||
| } | } | ||||
| @@ -118,7 +120,7 @@ JuceDemoPluginAudioProcessorEditor::~JuceDemoPluginAudioProcessorEditor() | |||||
| //============================================================================== | //============================================================================== | ||||
| void JuceDemoPluginAudioProcessorEditor::paint (Graphics& g) | void JuceDemoPluginAudioProcessorEditor::paint (Graphics& g) | ||||
| { | { | ||||
| g.setColour (getLookAndFeel().findColour (ResizableWindow::backgroundColourId)); | |||||
| g.setColour (backgroundColour); | |||||
| g.fillAll(); | g.fillAll(); | ||||
| } | } | ||||
| @@ -151,6 +153,16 @@ void JuceDemoPluginAudioProcessorEditor::hostMIDIControllerIsAvailable (bool con | |||||
| midiKeyboard.setVisible (! controllerIsAvailable); | midiKeyboard.setVisible (! controllerIsAvailable); | ||||
| } | } | ||||
| void JuceDemoPluginAudioProcessorEditor::updateTrackProperties () | |||||
| { | |||||
| auto trackColour = getProcessor().trackProperties.colour; | |||||
| auto& lf = getLookAndFeel(); | |||||
| backgroundColour = (trackColour == Colour() ? lf.findColour (ResizableWindow::backgroundColourId) | |||||
| : trackColour.withAlpha (1.0f).withBrightness (0.266f)); | |||||
| repaint(); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| // quick-and-dirty function to format a timecode string | // quick-and-dirty function to format a timecode string | ||||
| static String timeToTimecodeString (double seconds) | static String timeToTimecodeString (double seconds) | ||||
| @@ -45,6 +45,7 @@ public: | |||||
| void resized() override; | void resized() override; | ||||
| void timerCallback() override; | void timerCallback() override; | ||||
| void hostMIDIControllerIsAvailable (bool) override; | void hostMIDIControllerIsAvailable (bool) override; | ||||
| void updateTrackProperties(); | |||||
| private: | private: | ||||
| class ParameterSlider; | class ParameterSlider; | ||||
| @@ -52,6 +53,7 @@ private: | |||||
| MidiKeyboardComponent midiKeyboard; | MidiKeyboardComponent midiKeyboard; | ||||
| Label timecodeDisplayLabel, gainLabel, delayLabel; | Label timecodeDisplayLabel, gainLabel, delayLabel; | ||||
| ScopedPointer<ParameterSlider> gainSlider, delaySlider; | ScopedPointer<ParameterSlider> gainSlider, delaySlider; | ||||
| Colour backgroundColour; | |||||
| //============================================================================== | //============================================================================== | ||||
| JuceDemoPluginAudioProcessor& getProcessor() const | JuceDemoPluginAudioProcessor& getProcessor() const | ||||
| @@ -390,6 +390,14 @@ void JuceDemoPluginAudioProcessor::setStateInformation (const void* data, int si | |||||
| } | } | ||||
| } | } | ||||
| void JuceDemoPluginAudioProcessor::updateTrackProperties (const TrackProperties& properties) | |||||
| { | |||||
| trackProperties = properties; | |||||
| if (auto* editor = dynamic_cast<JuceDemoPluginAudioProcessorEditor*> (getActiveEditor())) | |||||
| editor->updateTrackProperties (); | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| // This creates new instances of the plugin.. | // This creates new instances of the plugin.. | ||||
| AudioProcessor* JUCE_CALLTYPE createPluginFilter() | AudioProcessor* JUCE_CALLTYPE createPluginFilter() | ||||
| @@ -82,6 +82,9 @@ public: | |||||
| void getStateInformation (MemoryBlock&) override; | void getStateInformation (MemoryBlock&) override; | ||||
| void setStateInformation (const void* data, int sizeInBytes) override; | void setStateInformation (const void* data, int sizeInBytes) override; | ||||
| //============================================================================== | |||||
| void updateTrackProperties (const TrackProperties& properties) override; | |||||
| //============================================================================== | //============================================================================== | ||||
| // These properties are public so that our editor component can access them | // These properties are public so that our editor component can access them | ||||
| // A bit of a hacky way to do it, but it's only a demo! Obviously in your own | // A bit of a hacky way to do it, but it's only a demo! Obviously in your own | ||||
| @@ -104,6 +107,9 @@ public: | |||||
| AudioParameterFloat* gainParam = nullptr; | AudioParameterFloat* gainParam = nullptr; | ||||
| AudioParameterFloat* delayParam = nullptr; | AudioParameterFloat* delayParam = nullptr; | ||||
| // Current track colour and name | |||||
| TrackProperties trackProperties; | |||||
| private: | private: | ||||
| //============================================================================== | //============================================================================== | ||||
| template <typename FloatType> | template <typename FloatType> | ||||
| @@ -942,6 +942,13 @@ namespace AAXClasses | |||||
| { | { | ||||
| if (type == AAX_eNotificationEvent_EnteringOfflineMode) pluginInstance->setNonRealtime (true); | if (type == AAX_eNotificationEvent_EnteringOfflineMode) pluginInstance->setNonRealtime (true); | ||||
| if (type == AAX_eNotificationEvent_ExitingOfflineMode) pluginInstance->setNonRealtime (false); | if (type == AAX_eNotificationEvent_ExitingOfflineMode) pluginInstance->setNonRealtime (false); | ||||
| if (type == AAX_eNotificationEvent_TrackNameChanged && data != nullptr) | |||||
| { | |||||
| AudioProcessor::TrackProperties props; | |||||
| props.name = static_cast<const AAX_IString*> (data)->Get(); | |||||
| pluginInstance->updateTrackProperties (props); | |||||
| } | |||||
| return AAX_CEffectParameters::NotificationReceived (type, data, size); | return AAX_CEffectParameters::NotificationReceived (type, data, size); | ||||
| } | } | ||||
| @@ -147,6 +147,8 @@ public: | |||||
| channelInfo = AudioUnitHelpers::getAUChannelInfo (*juceFilter); | channelInfo = AudioUnitHelpers::getAUChannelInfo (*juceFilter); | ||||
| #endif | #endif | ||||
| AddPropertyListener (kAudioUnitProperty_ContextName, auPropertyListenerDispatcher, this); | |||||
| totalInChannels = juceFilter->getTotalNumInputChannels(); | totalInChannels = juceFilter->getTotalNumInputChannels(); | ||||
| totalOutChannels = juceFilter->getTotalNumOutputChannels(); | totalOutChannels = juceFilter->getTotalNumOutputChannels(); | ||||
| @@ -1956,6 +1958,25 @@ private: | |||||
| return (getHostType().isLogic() ? 8 : 64); | return (getHostType().isLogic() ? 8 : 64); | ||||
| } | } | ||||
| //============================================================================== | |||||
| void auPropertyListener (AudioUnitPropertyID propId, AudioUnitScope scope, AudioUnitElement) | |||||
| { | |||||
| if (scope == kAudioUnitScope_Global && propId == kAudioUnitProperty_ContextName | |||||
| && juceFilter != nullptr && mContextName != nullptr) | |||||
| { | |||||
| AudioProcessor::TrackProperties props; | |||||
| props.name = String::fromCFString (mContextName); | |||||
| juceFilter->updateTrackProperties (props); | |||||
| } | |||||
| } | |||||
| static void auPropertyListenerDispatcher (void* inRefCon, AudioUnit, AudioUnitPropertyID propId, | |||||
| AudioUnitScope scope, AudioUnitElement element) | |||||
| { | |||||
| static_cast<JuceAU*> (inRefCon)->auPropertyListener (propId, scope, element); | |||||
| } | |||||
| JUCE_DECLARE_NON_COPYABLE (JuceAU) | JUCE_DECLARE_NON_COPYABLE (JuceAU) | ||||
| }; | }; | ||||
| @@ -195,6 +195,10 @@ public: | |||||
| virtual bool getRenderingOffline() = 0; | virtual bool getRenderingOffline() = 0; | ||||
| virtual void setRenderingOffline (bool offline) = 0; | virtual void setRenderingOffline (bool offline) = 0; | ||||
| //============================================================================== | |||||
| virtual NSString* getContextName() const = 0; | |||||
| virtual void setContextName (NSString*) = 0; | |||||
| virtual bool allocateRenderResourcesAndReturnError (NSError **outError) | virtual bool allocateRenderResourcesAndReturnError (NSError **outError) | ||||
| { | { | ||||
| objc_super s = { getAudioUnit(), [AUAudioUnit class] }; | objc_super s = { getAudioUnit(), [AUAudioUnit class] }; | ||||
| @@ -273,6 +277,10 @@ private: | |||||
| addMethod (@selector (allocateRenderResourcesAndReturnError:), allocateRenderResourcesAndReturnError, "B@:^@"); | addMethod (@selector (allocateRenderResourcesAndReturnError:), allocateRenderResourcesAndReturnError, "B@:^@"); | ||||
| addMethod (@selector (deallocateRenderResources), deallocateRenderResources, "v@:"); | addMethod (@selector (deallocateRenderResources), deallocateRenderResources, "v@:"); | ||||
| //============================================================================== | |||||
| addMethod (@selector (contextName), getContextName, "@@:"); | |||||
| addMethod (@selector (setContextName:), setContextName, "v@:@"); | |||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_AUV3_VIEW_CONFIG_SUPPORTED | #if JUCE_AUV3_VIEW_CONFIG_SUPPORTED | ||||
| addMethod (@selector (supportedViewConfigurations:), getSupportedViewConfigurations, "@@:@"); | addMethod (@selector (supportedViewConfigurations:), getSupportedViewConfigurations, "@@:@"); | ||||
| @@ -351,6 +359,10 @@ private: | |||||
| static BOOL allocateRenderResourcesAndReturnError (id self, SEL, NSError** error) { return _this (self)->allocateRenderResourcesAndReturnError (error) ? YES : NO; } | static BOOL allocateRenderResourcesAndReturnError (id self, SEL, NSError** error) { return _this (self)->allocateRenderResourcesAndReturnError (error) ? YES : NO; } | ||||
| static void deallocateRenderResources (id self, SEL) { _this (self)->deallocateRenderResources(); } | static void deallocateRenderResources (id self, SEL) { _this (self)->deallocateRenderResources(); } | ||||
| //============================================================================== | |||||
| static NSString* getContextName (id self, SEL) { return _this (self)->getContextName(); } | |||||
| static void setContextName (id self, SEL, NSString* str) { return _this (self)->setContextName (str); } | |||||
| //============================================================================== | //============================================================================== | ||||
| #if JUCE_AUV3_VIEW_CONFIG_SUPPORTED | #if JUCE_AUV3_VIEW_CONFIG_SUPPORTED | ||||
| static NSIndexSet* getSupportedViewConfigurations (id self, SEL, NSArray<AUAudioUnitViewConfiguration*>* configs) { return _this (self)->getSupportedViewConfigurations (configs); } | static NSIndexSet* getSupportedViewConfigurations (id self, SEL, NSArray<AUAudioUnitViewConfiguration*>* configs) { return _this (self)->getSupportedViewConfigurations (configs); } | ||||
| @@ -679,6 +691,20 @@ public: | |||||
| bool getRenderingOffline() override { return getAudioProcessor().isNonRealtime(); } | bool getRenderingOffline() override { return getAudioProcessor().isNonRealtime(); } | ||||
| void setRenderingOffline (bool offline) override { getAudioProcessor().setNonRealtime (offline); } | void setRenderingOffline (bool offline) override { getAudioProcessor().setNonRealtime (offline); } | ||||
| //============================================================================== | |||||
| NSString* getContextName() const override { return juceStringToNS (contextName); } | |||||
| void setContextName (NSString* str) override | |||||
| { | |||||
| if (str != nullptr) | |||||
| { | |||||
| AudioProcessor::TrackProperties props; | |||||
| props.name = nsStringToJuce (str); | |||||
| getAudioProcessor().updateTrackProperties (props); | |||||
| } | |||||
| } | |||||
| //============================================================================== | |||||
| bool allocateRenderResourcesAndReturnError (NSError **outError) override | bool allocateRenderResourcesAndReturnError (NSError **outError) override | ||||
| { | { | ||||
| AudioProcessor& processor = getAudioProcessor(); | AudioProcessor& processor = getAudioProcessor(); | ||||
| @@ -1436,6 +1462,8 @@ private: | |||||
| AudioTimeStamp lastTimeStamp; | AudioTimeStamp lastTimeStamp; | ||||
| CurrentPositionInfo lastAudioHead; | CurrentPositionInfo lastAudioHead; | ||||
| String contextName; | |||||
| }; | }; | ||||
| const double JuceAudioUnitv3::kDefaultSampleRate = 44100.0; | const double JuceAudioUnitv3::kDefaultSampleRate = 44100.0; | ||||
| @@ -115,6 +115,7 @@ class JuceVST3Component; | |||||
| //============================================================================== | //============================================================================== | ||||
| class JuceVST3EditController : public Vst::EditController, | class JuceVST3EditController : public Vst::EditController, | ||||
| public Vst::IMidiMapping, | public Vst::IMidiMapping, | ||||
| public Vst::ChannelContext::IInfoListener, | |||||
| public AudioProcessorListener | public AudioProcessorListener | ||||
| { | { | ||||
| public: | public: | ||||
| @@ -147,6 +148,7 @@ public: | |||||
| TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IEditController2) | TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IEditController2) | ||||
| TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IConnectionPoint) | TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IConnectionPoint) | ||||
| TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IMidiMapping) | TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IMidiMapping) | ||||
| TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::ChannelContext::IInfoListener) | |||||
| TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, IPluginBase, Vst::IEditController) | TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, IPluginBase, Vst::IEditController) | ||||
| TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, IDependent, Vst::IEditController) | TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, IDependent, Vst::IEditController) | ||||
| TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, FUnknown, Vst::IEditController) | TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, FUnknown, Vst::IEditController) | ||||
| @@ -429,6 +431,41 @@ public: | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramChangeParameter) | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ProgramChangeParameter) | ||||
| }; | }; | ||||
| //============================================================================== | |||||
| tresult PLUGIN_API setChannelContextInfos (Vst::IAttributeList* list) override | |||||
| { | |||||
| if (auto* instance = getPluginInstance()) | |||||
| { | |||||
| if (list != nullptr) | |||||
| { | |||||
| AudioProcessor::TrackProperties trackProperties; | |||||
| { | |||||
| Vst::String128 channelName; | |||||
| if (list->getString (Vst::ChannelContext::kChannelNameKey, channelName, sizeof (channelName)) == kResultTrue) | |||||
| trackProperties.name = toString (channelName); | |||||
| } | |||||
| { | |||||
| int64 colour; | |||||
| if (list->getInt (Vst::ChannelContext::kChannelColorKey, colour) == kResultTrue) | |||||
| trackProperties.colour = Colour (Vst::ChannelContext::GetRed ((uint32) colour), Vst::ChannelContext::GetGreen ((uint32) colour), | |||||
| Vst::ChannelContext::GetBlue ((uint32) colour), Vst::ChannelContext::GetAlpha ((uint32) colour)); | |||||
| } | |||||
| if (MessageManager::getInstance()->isThisTheMessageThread()) | |||||
| instance->updateTrackProperties (trackProperties); | |||||
| else | |||||
| MessageManager::callAsync ([trackProperties, instance] () | |||||
| { instance->updateTrackProperties (trackProperties); }); | |||||
| } | |||||
| } | |||||
| return kResultOk; | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| tresult PLUGIN_API setComponentState (IBStream* stream) override | tresult PLUGIN_API setComponentState (IBStream* stream) override | ||||
| { | { | ||||
| @@ -1120,6 +1157,7 @@ public: | |||||
| TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IAudioProcessor) | TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IAudioProcessor) | ||||
| TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IUnitInfo) | TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IUnitInfo) | ||||
| TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IConnectionPoint) | TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::IConnectionPoint) | ||||
| TEST_FOR_AND_RETURN_IF_VALID (targetIID, Vst::ChannelContext::IInfoListener) | |||||
| TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, FUnknown, Vst::IComponent) | TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (targetIID, FUnknown, Vst::IComponent) | ||||
| if (doUIDsMatch (targetIID, JuceAudioProcessor::iid)) | if (doUIDsMatch (targetIID, JuceAudioProcessor::iid)) | ||||
| @@ -1065,6 +1065,19 @@ public: | |||||
| jassertfalse; // xxx not implemented! | jassertfalse; // xxx not implemented! | ||||
| } | } | ||||
| //============================================================================== | |||||
| void updateTrackProperties (const TrackProperties& properties) override | |||||
| { | |||||
| if (properties.name.isNotEmpty()) | |||||
| { | |||||
| CFStringRef contextName = properties.name.toCFString(); | |||||
| AudioUnitSetProperty (audioUnit, kAudioUnitProperty_ContextName, kAudioUnitScope_Global, | |||||
| 0, &contextName, sizeof (CFStringRef)); | |||||
| CFRelease (contextName); | |||||
| } | |||||
| } | |||||
| //============================================================================== | //============================================================================== | ||||
| void getStateInformation (MemoryBlock& destData) override | void getStateInformation (MemoryBlock& destData) override | ||||
| { | { | ||||
| @@ -84,6 +84,7 @@ | |||||
| #include <pluginterfaces/vst/vsttypes.h> | #include <pluginterfaces/vst/vsttypes.h> | ||||
| #include <pluginterfaces/vst/ivstunits.h> | #include <pluginterfaces/vst/ivstunits.h> | ||||
| #include <pluginterfaces/vst/ivstmidicontrollers.h> | #include <pluginterfaces/vst/ivstmidicontrollers.h> | ||||
| #include <pluginterfaces/vst/ivstchannelcontextinfo.h> | |||||
| #include <public.sdk/source/common/memorystream.h> | #include <public.sdk/source/common/memorystream.h> | ||||
| #include <public.sdk/source/vst/vsteditcontroller.h> | #include <public.sdk/source/vst/vsteditcontroller.h> | ||||
| #else | #else | ||||
| @@ -102,6 +103,7 @@ | |||||
| #include <pluginterfaces/gui/iplugview.h> | #include <pluginterfaces/gui/iplugview.h> | ||||
| #include <pluginterfaces/gui/iplugviewcontentscalesupport.h> | #include <pluginterfaces/gui/iplugviewcontentscalesupport.h> | ||||
| #include <pluginterfaces/vst/ivstmidicontrollers.h> | #include <pluginterfaces/vst/ivstmidicontrollers.h> | ||||
| #include <pluginterfaces/vst/ivstchannelcontextinfo.h> | |||||
| #include <public.sdk/source/common/memorystream.cpp> | #include <public.sdk/source/common/memorystream.cpp> | ||||
| #include <public.sdk/source/common/pluginview.cpp> | #include <public.sdk/source/common/pluginview.cpp> | ||||
| #include <public.sdk/source/vst/vsteditcontroller.cpp> | #include <public.sdk/source/vst/vsteditcontroller.cpp> | ||||
| @@ -2100,6 +2100,67 @@ struct VST3PluginInstance : public AudioPluginInstance | |||||
| return result; | return result; | ||||
| } | } | ||||
| //============================================================================== | |||||
| void updateTrackProperties (const TrackProperties& properties) override | |||||
| { | |||||
| if (trackInfoListener != nullptr) | |||||
| { | |||||
| ComSmartPtr<Vst::IAttributeList> l (new TrackPropertiesAttributeList (properties)); | |||||
| trackInfoListener->setChannelContextInfos (l); | |||||
| } | |||||
| } | |||||
| struct TrackPropertiesAttributeList : public Vst::IAttributeList | |||||
| { | |||||
| TrackPropertiesAttributeList (const TrackProperties& properties) : props (properties) {} | |||||
| virtual ~TrackPropertiesAttributeList() {} | |||||
| JUCE_DECLARE_VST3_COM_REF_METHODS | |||||
| tresult PLUGIN_API queryInterface (const TUID iid, void** obj) override | |||||
| { | |||||
| TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IAttributeList) | |||||
| TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (iid, FUnknown, Vst::IAttributeList) | |||||
| *obj = nullptr; | |||||
| return kNotImplemented; | |||||
| } | |||||
| tresult PLUGIN_API setInt (AttrID, int64) override { return kOutOfMemory; } | |||||
| tresult PLUGIN_API setFloat (AttrID, double) override { return kOutOfMemory; } | |||||
| tresult PLUGIN_API setString (AttrID, const Vst::TChar*) override { return kOutOfMemory; } | |||||
| tresult PLUGIN_API setBinary (AttrID, const void*, uint32) override { return kOutOfMemory; } | |||||
| tresult PLUGIN_API getFloat (AttrID, double&) override { return kResultFalse; } | |||||
| tresult PLUGIN_API getBinary (AttrID, const void*&, uint32&) override { return kResultFalse; } | |||||
| tresult PLUGIN_API getString (AttrID id, Vst::TChar* string, uint32 size) override | |||||
| { | |||||
| if (! std::strcmp (id, Vst::ChannelContext::kChannelNameKey)) | |||||
| { | |||||
| Steinberg::String str (props.name.toRawUTF8()); | |||||
| str.copyTo (string, 0, (Steinberg::int32) jmin (size, (Steinberg::uint32) std::numeric_limits<Steinberg::int32>::max())); | |||||
| return kResultTrue; | |||||
| } | |||||
| return kResultFalse; | |||||
| } | |||||
| tresult PLUGIN_API getInt (AttrID id, int64& value) override | |||||
| { | |||||
| if (! std::strcmp (Vst::ChannelContext::kChannelNameLengthKey, id)) value = props.name.length(); | |||||
| else if (! std::strcmp (Vst::ChannelContext::kChannelColorKey, id)) value = static_cast<int64> (props.colour.getARGB()); | |||||
| else return kResultFalse; | |||||
| return kResultTrue; | |||||
| } | |||||
| Atomic<int> refCount; | |||||
| TrackProperties props; | |||||
| JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TrackPropertiesAttributeList) | |||||
| }; | |||||
| //============================================================================== | //============================================================================== | ||||
| String getChannelName (int channelIndex, bool forInput, bool forAudioChannel) const | String getChannelName (int channelIndex, bool forInput, bool forAudioChannel) const | ||||
| { | { | ||||
| @@ -2449,6 +2510,7 @@ private: | |||||
| ComSmartPtr<Vst::IUnitData> unitData; | ComSmartPtr<Vst::IUnitData> unitData; | ||||
| ComSmartPtr<Vst::IProgramListData> programListData; | ComSmartPtr<Vst::IProgramListData> programListData; | ||||
| ComSmartPtr<Vst::IConnectionPoint> componentConnection, editControllerConnection; | ComSmartPtr<Vst::IConnectionPoint> componentConnection, editControllerConnection; | ||||
| ComSmartPtr<Vst::ChannelContext::IInfoListener> trackInfoListener; | |||||
| /** The number of IO buses MUST match that of the plugin, | /** The number of IO buses MUST match that of the plugin, | ||||
| even if there aren't enough channels to process, | even if there aren't enough channels to process, | ||||
| @@ -2533,6 +2595,7 @@ private: | |||||
| editController2.loadFrom (holder->component); | editController2.loadFrom (holder->component); | ||||
| componentHandler.loadFrom (holder->component); | componentHandler.loadFrom (holder->component); | ||||
| componentHandler2.loadFrom (holder->component); | componentHandler2.loadFrom (holder->component); | ||||
| trackInfoListener.loadFrom (holder->component); | |||||
| if (processor == nullptr) processor.loadFrom (editController); | if (processor == nullptr) processor.loadFrom (editController); | ||||
| if (unitInfo == nullptr) unitInfo.loadFrom (editController); | if (unitInfo == nullptr) unitInfo.loadFrom (editController); | ||||
| @@ -2541,6 +2604,7 @@ private: | |||||
| if (editController2 == nullptr) editController2.loadFrom (editController); | if (editController2 == nullptr) editController2.loadFrom (editController); | ||||
| if (componentHandler == nullptr) componentHandler.loadFrom (editController); | if (componentHandler == nullptr) componentHandler.loadFrom (editController); | ||||
| if (componentHandler2 == nullptr) componentHandler2.loadFrom (editController); | if (componentHandler2 == nullptr) componentHandler2.loadFrom (editController); | ||||
| if (trackInfoListener == nullptr) trackInfoListener.loadFrom (editController); | |||||
| } | } | ||||
| void setStateForAllMidiBuses (bool newState) | void setStateForAllMidiBuses (bool newState) | ||||
| @@ -1025,6 +1025,9 @@ void AudioProcessor::setCurrentProgramStateInformation (const void* data, int si | |||||
| setStateInformation (data, sizeInBytes); | setStateInformation (data, sizeInBytes); | ||||
| } | } | ||||
| //============================================================================== | |||||
| void AudioProcessor::updateTrackProperties (const AudioProcessor::TrackProperties&) {} | |||||
| //============================================================================== | //============================================================================== | ||||
| // magic number to identify memory blocks that we've stored as XML | // magic number to identify memory blocks that we've stored as XML | ||||
| const uint32 magicXmlNumber = 0x21324356; | const uint32 magicXmlNumber = 0x21324356; | ||||
| @@ -1310,6 +1310,32 @@ public: | |||||
| */ | */ | ||||
| WrapperType wrapperType; | WrapperType wrapperType; | ||||
| /** A struct containing information about the DAW track inside which your | |||||
| AudioProcessor is loaded. */ | |||||
| struct TrackProperties | |||||
| { | |||||
| String name; // The name of the track - this will be empty if the track name is not known | |||||
| Colour colour; // The colour of the track - this will be transparentBlack if the colour is not known | |||||
| // other properties may be added in the future | |||||
| }; | |||||
| /** Informs the AudioProcessor that track properties such as the track's name or | |||||
| colour has been changed. | |||||
| If you are hosting this AudioProcessor then use this method to inform the | |||||
| AudioProcessor about which track the AudioProcessor is loaded on. This method | |||||
| may only be called on the message thread. | |||||
| If you are implemeting an AudioProcessor then you can override this callback | |||||
| to do something useful with the track properties such as changing the colour | |||||
| of your AudioProcessor's editor. It's entirely up to the host when and how | |||||
| often this callback will be called. | |||||
| The default implementation of this callback will do nothing. | |||||
| */ | |||||
| virtual void updateTrackProperties (const TrackProperties& properties); | |||||
| //============================================================================== | //============================================================================== | ||||
| #ifndef DOXYGEN | #ifndef DOXYGEN | ||||
| /** Deprecated: use getTotalNumInputChannels instead. */ | /** Deprecated: use getTotalNumInputChannels instead. */ | ||||