| @@ -23,15 +23,18 @@ | |||
| ============================================================================== | |||
| */ | |||
| #include "../JuceLibraryCode/JuceHeader.h" | |||
| #include "GraphEditorPanel.h" | |||
| #include "InternalFilters.h" | |||
| #include "MainHostWindow.h" | |||
| #include "FilterIOConfiguration.h" | |||
| //============================================================================== | |||
| class NumberedBoxes : public TableListBox, private TableListBoxModel, private Button::Listener | |||
| class NumberedBoxes : public TableListBox, | |||
| private TableListBoxModel, | |||
| private Button::Listener | |||
| { | |||
| public: | |||
| struct Listener | |||
| @@ -56,21 +59,19 @@ public: | |||
| canAddColumn (canCurrentlyAddColumn), | |||
| canRemoveColumn (canCurrentlyRemoveColumn) | |||
| { | |||
| TableHeaderComponent& tableHeader = getHeader(); | |||
| auto& tableHeader = getHeader(); | |||
| for (int i = 0; i < 16; ++i) | |||
| tableHeader.addColumn (String (i + 1), i + 1, 40); | |||
| setHeaderHeight (0); | |||
| setRowHeight (40); | |||
| if (ScrollBar* scrollbar = getHorizontalScrollBar()) | |||
| scrollbar->setAutoHide (false); | |||
| getHorizontalScrollBar().setAutoHide (false); | |||
| } | |||
| void setSelected (int columnId) | |||
| { | |||
| if (TextButton* button = dynamic_cast<TextButton*> (getCellComponent (columnId, 0))) | |||
| if (auto* button = dynamic_cast<TextButton*> (getCellComponent (columnId, 0))) | |||
| button->setToggleState (true, NotificationType::dontSendNotification); | |||
| } | |||
| @@ -80,7 +81,7 @@ public: | |||
| { | |||
| canAddColumn = canCurrentlyAdd; | |||
| if (TextButton* button = dynamic_cast<TextButton*> (getCellComponent (plusButtonColumnId, 0))) | |||
| if (auto* button = dynamic_cast<TextButton*> (getCellComponent (plusButtonColumnId, 0))) | |||
| button->setEnabled (true); | |||
| } | |||
| } | |||
| @@ -91,7 +92,7 @@ public: | |||
| { | |||
| canRemoveColumn = canCurrentlyRemove; | |||
| if (TextButton* button = dynamic_cast<TextButton*> (getCellComponent (minusButtonColumnId, 0))) | |||
| if (auto* button = dynamic_cast<TextButton*> (getCellComponent (minusButtonColumnId, 0))) | |||
| button->setEnabled (true); | |||
| } | |||
| } | |||
| @@ -105,9 +106,10 @@ private: | |||
| Component* refreshComponentForCell (int, int columnId, bool, | |||
| Component* existingComponentToUpdate) override | |||
| { | |||
| TextButton* textButton = dynamic_cast<TextButton*> (existingComponentToUpdate); | |||
| auto* textButton = dynamic_cast<TextButton*> (existingComponentToUpdate); | |||
| if (textButton == nullptr) | |||
| textButton = new TextButton (""); | |||
| textButton = new TextButton(); | |||
| textButton->setButtonText (getButtonName (columnId)); | |||
| textButton->setConnectedEdges (Button::ConnectedOnLeft | Button::ConnectedOnRight | | |||
| @@ -124,7 +126,7 @@ private: | |||
| textButton->setRadioGroupId (1, NotificationType::dontSendNotification); | |||
| textButton->setClickingTogglesState (true); | |||
| Colour busColour = Colours::green.withRotatedHue (static_cast<float> (columnId) / 5.0f); | |||
| auto busColour = Colours::green.withRotatedHue (static_cast<float> (columnId) / 5.0f); | |||
| textButton->setColour (TextButton::buttonColourId, busColour); | |||
| textButton->setColour (TextButton::buttonOnColourId, busColour.withMultipliedBrightness (2.0f)); | |||
| } | |||
| @@ -145,17 +147,18 @@ private: | |||
| void buttonClicked (Button* btn) override | |||
| { | |||
| const String& text = btn->getButtonText(); | |||
| auto text = btn->getButtonText(); | |||
| if (text == "+") listener.addColumn(); | |||
| else if (text == "-") listener.removeColumn(); | |||
| if (text == "+") listener.addColumn(); | |||
| if (text == "-") listener.removeColumn(); | |||
| } | |||
| void buttonStateChanged (Button* btn) override | |||
| { | |||
| const String& text = btn->getButtonText(); | |||
| auto text = btn->getButtonText(); | |||
| if (text == "+" || text == "-") return; | |||
| if (text == "+" || text == "-") | |||
| return; | |||
| if (btn->getToggleState()) | |||
| listener.columnSelected (text.getIntValue()); | |||
| @@ -167,8 +170,10 @@ private: | |||
| }; | |||
| //============================================================================== | |||
| class FilterIOConfigurationWindow::InputOutputConfig | |||
| : public Component, private ComboBox::Listener, private Button::Listener, private NumberedBoxes::Listener | |||
| class FilterIOConfigurationWindow::InputOutputConfig : public Component, | |||
| private ComboBox::Listener, | |||
| private Button::Listener, | |||
| private NumberedBoxes::Listener | |||
| { | |||
| public: | |||
| InputOutputConfig (FilterIOConfigurationWindow& parent, bool direction) | |||
| @@ -208,7 +213,7 @@ public: | |||
| void resized() override | |||
| { | |||
| Rectangle<int> r = getLocalBounds().reduced (10); | |||
| auto r = getLocalBounds().reduced (10); | |||
| ioTitle.setBounds (r.removeFromTop (14)); | |||
| r.reduce (10, 0); | |||
| @@ -217,7 +222,7 @@ public: | |||
| ioBuses.setBounds (r.removeFromTop (60)); | |||
| { | |||
| Rectangle<int> label = r.removeFromTop (24); | |||
| auto label = r.removeFromTop (24); | |||
| nameLabel.setBounds (label.removeFromLeft (100)); | |||
| enabledToggle.setBounds (label.removeFromRight (80)); | |||
| @@ -225,7 +230,7 @@ public: | |||
| } | |||
| { | |||
| Rectangle<int> label = r.removeFromTop (24); | |||
| auto label = r.removeFromTop (24); | |||
| layoutLabel.setBounds (label.removeFromLeft (100)); | |||
| layouts.setBounds (label); | |||
| @@ -235,12 +240,13 @@ public: | |||
| private: | |||
| void updateBusButtons() | |||
| { | |||
| if (AudioProcessor* filter = owner.getAudioProcessor()) | |||
| if (auto* filter = owner.getAudioProcessor()) | |||
| { | |||
| TableHeaderComponent& header = ioBuses.getHeader(); | |||
| auto& header = ioBuses.getHeader(); | |||
| header.removeAllColumns(); | |||
| const int n = filter->getBusCount (isInput); | |||
| for (int i = 0; i < n; ++i) | |||
| header.addColumn ("", i + 1, 40); | |||
| @@ -256,14 +262,13 @@ private: | |||
| void updateBusLayout() | |||
| { | |||
| if (AudioProcessor* filter = owner.getAudioProcessor()) | |||
| if (auto* filter = owner.getAudioProcessor()) | |||
| { | |||
| if (AudioProcessor::Bus* bus = filter->getBus (isInput, currentBus)) | |||
| if (auto* bus = filter->getBus (isInput, currentBus)) | |||
| { | |||
| name.setText (bus->getName(), NotificationType::dontSendNotification); | |||
| int i; | |||
| for (i = 1; i < AudioChannelSet::maxChannelsOfNamedLayout; ++i) | |||
| if ((layouts.indexOfItemId(i) == -1) != bus->supportedLayoutWithChannels (i).isDisabled()) | |||
| break; | |||
| @@ -275,7 +280,8 @@ private: | |||
| for (i = 1; i < AudioChannelSet::maxChannelsOfNamedLayout; ++i) | |||
| { | |||
| AudioChannelSet set = bus->supportedLayoutWithChannels (i); | |||
| auto set = bus->supportedLayoutWithChannels (i); | |||
| if (! set.isDisabled()) | |||
| layouts.addItem (set.getDescription(), i); | |||
| } | |||
| @@ -298,18 +304,18 @@ private: | |||
| { | |||
| if (combo == &layouts) | |||
| { | |||
| if (AudioProcessor* filter = owner.getAudioProcessor()) | |||
| if (auto* processor = owner.getAudioProcessor()) | |||
| { | |||
| if (AudioProcessor::Bus* bus = filter->getBus (isInput, currentBus)) | |||
| if (auto* bus = processor->getBus (isInput, currentBus)) | |||
| { | |||
| const int selectedNumChannels = layouts.getSelectedId(); | |||
| auto selectedNumChannels = layouts.getSelectedId(); | |||
| if (selectedNumChannels != bus->getLastEnabledLayout().size()) | |||
| { | |||
| if (isPositiveAndBelow (selectedNumChannels, (int) AudioChannelSet::maxChannelsOfNamedLayout) | |||
| && bus->setCurrentLayoutWithoutEnabling (bus->supportedLayoutWithChannels (selectedNumChannels))) | |||
| && bus->setCurrentLayoutWithoutEnabling (bus->supportedLayoutWithChannels (selectedNumChannels))) | |||
| { | |||
| if (InputOutputConfig* config = owner.getConfig (! isInput)) | |||
| if (auto* config = owner.getConfig (! isInput)) | |||
| config->updateBusLayout(); | |||
| owner.update(); | |||
| @@ -326,9 +332,9 @@ private: | |||
| { | |||
| if (btn == &enabledToggle && enabledToggle.isEnabled()) | |||
| { | |||
| if (AudioProcessor* filter = owner.getAudioProcessor()) | |||
| if (auto* processor = owner.getAudioProcessor()) | |||
| { | |||
| if (AudioProcessor::Bus* bus = filter->getBus (isInput, currentBus)) | |||
| if (auto* bus = processor->getBus (isInput, currentBus)) | |||
| { | |||
| if (bus->isEnabled() != enabledToggle.getToggleState()) | |||
| { | |||
| @@ -362,16 +368,16 @@ private: | |||
| //============================================================================== | |||
| void addColumn() override | |||
| { | |||
| if (AudioProcessor* filter = owner.getAudioProcessor()) | |||
| if (auto* processor = owner.getAudioProcessor()) | |||
| { | |||
| if (filter->canAddBus (isInput)) | |||
| if (processor->canAddBus (isInput)) | |||
| { | |||
| if (filter->addBus (isInput)) | |||
| if (processor->addBus (isInput)) | |||
| { | |||
| updateBusButtons(); | |||
| updateBusLayout(); | |||
| if (InputOutputConfig* config = owner.getConfig (! isInput)) | |||
| if (auto* config = owner.getConfig (! isInput)) | |||
| { | |||
| config->updateBusButtons(); | |||
| config->updateBusLayout(); | |||
| @@ -385,18 +391,18 @@ private: | |||
| void removeColumn() override | |||
| { | |||
| if (AudioProcessor* filter = owner.getAudioProcessor()) | |||
| if (auto* processor = owner.getAudioProcessor()) | |||
| { | |||
| if (filter->getBusCount (isInput) > 1 && filter->canRemoveBus (isInput)) | |||
| if (processor->getBusCount (isInput) > 1 && processor->canRemoveBus (isInput)) | |||
| { | |||
| if (filter->removeBus (isInput)) | |||
| if (processor->removeBus (isInput)) | |||
| { | |||
| currentBus = jmin (filter->getBusCount (isInput) - 1, currentBus); | |||
| currentBus = jmin (processor->getBusCount (isInput) - 1, currentBus); | |||
| updateBusButtons(); | |||
| updateBusLayout(); | |||
| if (InputOutputConfig* config = owner.getConfig (! isInput)) | |||
| if (auto* config = owner.getConfig (! isInput)) | |||
| { | |||
| config->updateBusButtons(); | |||
| config->updateBusLayout(); | |||
| @@ -411,6 +417,7 @@ private: | |||
| void columnSelected (int columnId) override | |||
| { | |||
| const int newBus = columnId - 1; | |||
| if (currentBus != newBus) | |||
| { | |||
| currentBus = newBus; | |||
| @@ -460,9 +467,9 @@ FilterIOConfigurationWindow::FilterIOConfigurationWindow (AudioProcessor* const | |||
| FilterIOConfigurationWindow::~FilterIOConfigurationWindow() | |||
| { | |||
| if (AudioProcessorGraph* graph = getGraph()) | |||
| if (auto* graph = getGraph()) | |||
| { | |||
| if (AudioProcessor* p = getAudioProcessor()) | |||
| if (auto* p = getAudioProcessor()) | |||
| { | |||
| ScopedLock renderLock (graph->getCallbackLock()); | |||
| @@ -485,7 +492,7 @@ void FilterIOConfigurationWindow::paint (Graphics& g) | |||
| void FilterIOConfigurationWindow::resized() | |||
| { | |||
| Rectangle<int> r = getLocalBounds().reduced (10); | |||
| auto r = getLocalBounds().reduced (10); | |||
| title.setBounds (r.removeFromTop (14)); | |||
| r.reduce (10, 0); | |||
| @@ -499,25 +506,25 @@ void FilterIOConfigurationWindow::resized() | |||
| void FilterIOConfigurationWindow::update() | |||
| { | |||
| const int32 nodeId = getNodeId(); | |||
| auto nodeId = getNodeId(); | |||
| if (AudioProcessorGraph* graph = getGraph()) | |||
| if (auto* graph = getGraph()) | |||
| if (nodeId != -1) | |||
| graph->disconnectNode (static_cast<uint32> (nodeId)); | |||
| if (GraphDocumentComponent* graphEditor = getGraphEditor()) | |||
| if (GraphEditorPanel* panel = graphEditor->graphPanel) | |||
| if (auto* graphEditor = getGraphEditor()) | |||
| if (auto* panel = graphEditor->graphPanel) | |||
| panel->updateComponents(); | |||
| } | |||
| int32 FilterIOConfigurationWindow::getNodeId() const | |||
| { | |||
| if (AudioProcessorGraph* graph = getGraph()) | |||
| if (auto* graph = getGraph()) | |||
| { | |||
| const int n = graph->getNumNodes(); | |||
| for (int i = 0; i < n; ++i) | |||
| if (AudioProcessorGraph::Node* node = graph->getNode (i)) | |||
| if (auto* node = graph->getNode (i)) | |||
| if (node->getProcessor() == getAudioProcessor()) | |||
| return static_cast<int32> (node->nodeId); | |||
| } | |||
| @@ -530,7 +537,7 @@ MainHostWindow* FilterIOConfigurationWindow::getMainWindow() const | |||
| Component* comp; | |||
| for (int idx = 0; (comp = Desktop::getInstance().getComponent(idx)) != nullptr; ++idx) | |||
| if (MainHostWindow* mainWindow = dynamic_cast<MainHostWindow*> (comp)) | |||
| if (auto* mainWindow = dynamic_cast<MainHostWindow*> (comp)) | |||
| return mainWindow; | |||
| return nullptr; | |||
| @@ -538,20 +545,18 @@ MainHostWindow* FilterIOConfigurationWindow::getMainWindow() const | |||
| GraphDocumentComponent* FilterIOConfigurationWindow::getGraphEditor() const | |||
| { | |||
| if (MainHostWindow* mainWindow = getMainWindow()) | |||
| { | |||
| if (GraphDocumentComponent* graphEditor = mainWindow->getGraphEditor()) | |||
| if (auto* mainWindow = getMainWindow()) | |||
| if (auto* graphEditor = mainWindow->getGraphEditor()) | |||
| return graphEditor; | |||
| } | |||
| return nullptr; | |||
| } | |||
| AudioProcessorGraph* FilterIOConfigurationWindow::getGraph() const | |||
| { | |||
| if (GraphDocumentComponent* graphEditor = getGraphEditor()) | |||
| if (FilterGraph* filterGraph = graphEditor->graph) | |||
| return &filterGraph->getGraph(); | |||
| if (auto* graphEditor = getGraphEditor()) | |||
| if (auto* graph = graphEditor->graph.get()) | |||
| return &graph->getGraph(); | |||
| return nullptr; | |||
| } | |||
| @@ -529,6 +529,13 @@ public: | |||
| : "NDEBUG;%(PreprocessorDefinitions)"); | |||
| } | |||
| const String externalLibraries (getExternalLibraries (config, getOwner().getExternalLibrariesString())); | |||
| const auto additionalDependencies = externalLibraries.isNotEmpty() ? getOwner().replacePreprocessorTokens (config, externalLibraries).trim() + ";%(AdditionalDependencies)" | |||
| : String(); | |||
| const StringArray librarySearchPaths (config.getLibrarySearchPaths()); | |||
| const auto additionalLibraryDirs = librarySearchPaths.size() > 0 ? getOwner().replacePreprocessorTokens (config, librarySearchPaths.joinIntoString (";")) + ";%(AdditionalLibraryDirectories)" | |||
| : String(); | |||
| { | |||
| XmlElement* link = group->createNewChildElement ("Link"); | |||
| link->createNewChildElement ("OutputFile")->addTextElement (getOutputFilePath (config)); | |||
| @@ -551,17 +558,13 @@ public: | |||
| link->createNewChildElement ("EnableCOMDATFolding")->addTextElement ("true"); | |||
| } | |||
| const StringArray librarySearchPaths (config.getLibrarySearchPaths()); | |||
| if (librarySearchPaths.size() > 0) | |||
| link->createNewChildElement ("AdditionalLibraryDirectories")->addTextElement (getOwner().replacePreprocessorTokens (config, librarySearchPaths.joinIntoString (";")) | |||
| + ";%(AdditionalLibraryDirectories)"); | |||
| if (additionalLibraryDirs.isNotEmpty()) | |||
| link->createNewChildElement ("AdditionalLibraryDirectories")->addTextElement (additionalLibraryDirs); | |||
| link->createNewChildElement ("LargeAddressAware")->addTextElement ("true"); | |||
| const String externalLibraries (getExternalLibraries (config, getOwner().getExternalLibrariesString())); | |||
| if (externalLibraries.isNotEmpty()) | |||
| link->createNewChildElement ("AdditionalDependencies")->addTextElement (getOwner().replacePreprocessorTokens (config, externalLibraries).trim() | |||
| + ";%(AdditionalDependencies)"); | |||
| if (additionalDependencies.isNotEmpty()) | |||
| link->createNewChildElement ("AdditionalDependencies")->addTextElement (additionalDependencies); | |||
| String extraLinkerOptions (getOwner().getExtraLinkerFlagsString()); | |||
| if (extraLinkerOptions.isNotEmpty()) | |||
| @@ -584,6 +587,16 @@ public: | |||
| bsc->createNewChildElement ("OutputFile")->addTextElement (getOwner().getIntDirFile (config, config.getOutputFilename (".bsc", true))); | |||
| } | |||
| { | |||
| XmlElement* lib = group->createNewChildElement ("Lib"); | |||
| if (additionalDependencies.isNotEmpty()) | |||
| lib->createNewChildElement ("AdditionalDependencies")->addTextElement (additionalDependencies); | |||
| if (additionalLibraryDirs.isNotEmpty()) | |||
| lib->createNewChildElement ("AdditionalLibraryDirectories")->addTextElement (additionalLibraryDirs); | |||
| } | |||
| const RelativePath& manifestFile = getOwner().getManifestPath(); | |||
| if (manifestFile.getRoot() != RelativePath::unknown) | |||
| { | |||
| @@ -24,12 +24,20 @@ | |||
| ============================================================================== | |||
| */ | |||
| class ModuleItem : public ConfigTreeItemBase | |||
| class ModuleItem : public ConfigTreeItemBase, | |||
| private Value::Listener | |||
| { | |||
| public: | |||
| ModuleItem (Project& p, const String& modID) | |||
| : project (p), moduleID (modID) | |||
| { | |||
| missingDependencies = project.getModules().getExtraDependenciesNeeded (moduleID).size() > 0; | |||
| cppStandardHigherThanProject = project.getModules().doesModuleHaveHigherCppStandardThanProject (moduleID); | |||
| projectCppStandardValue.referTo (project.getCppStandardValue()); | |||
| projectCppStandardValue.addListener (this); | |||
| moduleInfo = project.getModules().getModuleInfo (moduleID); | |||
| } | |||
| bool canBeSelected() const override { return true; } | |||
| @@ -38,8 +46,8 @@ public: | |||
| String getDisplayName() const override { return moduleID; } | |||
| String getRenamingName() const override { return getDisplayName(); } | |||
| void setName (const String&) override {} | |||
| bool isMissing() const override { return hasMissingDependencies(); } | |||
| bool hasWarnings() const override { return hasHigherCppStandardThanProject(); } | |||
| bool isMissing() const override { return missingDependencies; } | |||
| bool hasWarnings() const override { return cppStandardHigherThanProject; } | |||
| void showDocument() override | |||
| { | |||
| @@ -59,12 +67,11 @@ public: | |||
| if (! isSelected()) | |||
| { | |||
| auto info = project.getModules().getModuleInfo (moduleID); | |||
| if (info.isValid() && info.getVendor() == "juce") | |||
| if (moduleInfo.isValid() && moduleInfo.getVendor() == "juce") | |||
| { | |||
| if (info.getLicense() == "ISC") | |||
| if (moduleInfo.getLicense() == "ISC") | |||
| iconColour = Colours::lightblue; | |||
| else if (info.getLicense() == "GPL/Commercial") | |||
| else if (moduleInfo.getLicense() == "GPL/Commercial") | |||
| iconColour = Colours::orange; | |||
| } | |||
| } | |||
| @@ -89,14 +96,28 @@ public: | |||
| String moduleID; | |||
| private: | |||
| bool hasMissingDependencies() const | |||
| { | |||
| return project.getModules().getExtraDependenciesNeeded (moduleID).size() > 0; | |||
| } | |||
| ModuleDescription moduleInfo; | |||
| bool missingDependencies = false; | |||
| bool cppStandardHigherThanProject = false; | |||
| Value projectCppStandardValue; | |||
| bool hasHigherCppStandardThanProject() const | |||
| //============================================================================== | |||
| void valueChanged (Value& v) override | |||
| { | |||
| return project.getModules().doesModuleHaveHigherCppStandardThanProject (moduleID); | |||
| if (v == projectCppStandardValue) | |||
| { | |||
| auto oldVal = cppStandardHigherThanProject; | |||
| cppStandardHigherThanProject = project.getModules().doesModuleHaveHigherCppStandardThanProject (moduleID); | |||
| if (oldVal != cppStandardHigherThanProject) | |||
| { | |||
| if (auto* parent = dynamic_cast<EnabledModulesItem*> (getParentItem())) | |||
| { | |||
| parent->refreshSubItems(); | |||
| return; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //============================================================================== | |||
| @@ -244,8 +265,8 @@ private: | |||
| } | |||
| } | |||
| if (auto* moduleInfo = dynamic_cast<ModuleInfoComponent*> (group.properties.getUnchecked (0))) | |||
| moduleInfo->refresh(); | |||
| if (auto* infoComponent = dynamic_cast<ModuleInfoComponent*> (group.properties.getUnchecked (0))) | |||
| infoComponent->refresh(); | |||
| } | |||
| //============================================================================== | |||
| @@ -68,6 +68,8 @@ String AudioChannelSet::getChannelTypeName (AudioChannelSet::ChannelType type) | |||
| case ambisonicX: return NEEDS_TRANS("Ambisonic X"); | |||
| case ambisonicY: return NEEDS_TRANS("Ambisonic Y"); | |||
| case ambisonicZ: return NEEDS_TRANS("Ambisonic Z"); | |||
| case topSideLeft: return NEEDS_TRANS("Top Side Left"); | |||
| case topSideRight: return NEEDS_TRANS("Top Side Right"); | |||
| default: break; | |||
| } | |||
| @@ -108,6 +110,8 @@ String AudioChannelSet::getAbbreviatedChannelTypeName (AudioChannelSet::ChannelT | |||
| case ambisonicX: return "X"; | |||
| case ambisonicY: return "Y"; | |||
| case ambisonicZ: return "Z"; | |||
| case topSideLeft: return "Tsl"; | |||
| case topSideRight: return "Tsr"; | |||
| default: break; | |||
| } | |||
| @@ -147,6 +151,8 @@ AudioChannelSet::ChannelType AudioChannelSet::getChannelTypeFromAbbreviation (co | |||
| if (abbr == "X") return ambisonicX; | |||
| if (abbr == "Y") return ambisonicY; | |||
| if (abbr == "Z") return ambisonicZ; | |||
| if (abbr == "Tsl") return topSideLeft; | |||
| if (abbr == "Tsr") return topSideRight; | |||
| return unknown; | |||
| } | |||
| @@ -192,16 +198,18 @@ String AudioChannelSet::getDescription() const | |||
| if (*this == createLRS()) return "LRS"; | |||
| if (*this == createLCRS()) return "LCRS"; | |||
| if (*this == create5point0()) return "5.0 Surround"; | |||
| if (*this == create5point1()) return "5.1 Surround"; | |||
| if (*this == create6point0()) return "6.0 Surround"; | |||
| if (*this == create6point1()) return "6.1 Surround"; | |||
| if (*this == create6point0Music()) return "6.0 (Music) Surround"; | |||
| if (*this == create6point1Music()) return "6.1 (Music) Surround"; | |||
| if (*this == create7point0()) return "7.0 Surround"; | |||
| if (*this == create7point1()) return "7.1 Surround"; | |||
| if (*this == create7point0SDDS()) return "7.0 Surround SDDS"; | |||
| if (*this == create7point1SDDS()) return "7.1 Surround SDDS"; | |||
| if (*this == create5point0()) return "5.0 Surround"; | |||
| if (*this == create5point1()) return "5.1 Surround"; | |||
| if (*this == create6point0()) return "6.0 Surround"; | |||
| if (*this == create6point1()) return "6.1 Surround"; | |||
| if (*this == create6point0Music()) return "6.0 (Music) Surround"; | |||
| if (*this == create6point1Music()) return "6.1 (Music) Surround"; | |||
| if (*this == create7point0()) return "7.0 Surround"; | |||
| if (*this == create7point1()) return "7.1 Surround"; | |||
| if (*this == create7point0SDDS()) return "7.0 Surround SDDS"; | |||
| if (*this == create7point1SDDS()) return "7.1 Surround SDDS"; | |||
| if (*this == create7point0point2()) return "7.0.2 Surround"; | |||
| if (*this == create7point1point2()) return "7.1.2 Surround"; | |||
| if (*this == quadraphonic()) return "Quadraphonic"; | |||
| if (*this == pentagonal()) return "Pentagonal"; | |||
| @@ -215,7 +223,7 @@ String AudioChannelSet::getDescription() const | |||
| bool AudioChannelSet::isDiscreteLayout() const noexcept | |||
| { | |||
| for (auto& speaker : getChannelTypes()) | |||
| if (speaker <= ambisonicZ) | |||
| if (speaker <= topSideRight) | |||
| return false; | |||
| return true; | |||
| @@ -275,27 +283,29 @@ void AudioChannelSet::removeChannel (ChannelType newChannel) | |||
| channels.clearBit (bit); | |||
| } | |||
| AudioChannelSet AudioChannelSet::disabled() { return {}; } | |||
| AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (1u << centre); } | |||
| AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); } | |||
| AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); } | |||
| AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surround)); } | |||
| AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); } | |||
| AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround)); } | |||
| AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround)); } | |||
| AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); } | |||
| AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); } | |||
| AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); } | |||
| AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); } | |||
| AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } | |||
| AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } | |||
| AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); } | |||
| AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); } | |||
| AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << centreSurround) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); } | |||
| AudioChannelSet AudioChannelSet::disabled() { return {}; } | |||
| AudioChannelSet AudioChannelSet::mono() { return AudioChannelSet (1u << centre); } | |||
| AudioChannelSet AudioChannelSet::stereo() { return AudioChannelSet ((1u << left) | (1u << right)); } | |||
| AudioChannelSet AudioChannelSet::createLCR() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre)); } | |||
| AudioChannelSet AudioChannelSet::createLRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << surround)); } | |||
| AudioChannelSet AudioChannelSet::createLCRS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << surround)); } | |||
| AudioChannelSet AudioChannelSet::create5point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround)); } | |||
| AudioChannelSet AudioChannelSet::create5point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround)); } | |||
| AudioChannelSet AudioChannelSet::create6point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); } | |||
| AudioChannelSet AudioChannelSet::create6point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround)); } | |||
| AudioChannelSet AudioChannelSet::create6point0Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); } | |||
| AudioChannelSet AudioChannelSet::create6point1Music() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftSurroundSide) | (1u << rightSurroundSide)); } | |||
| AudioChannelSet AudioChannelSet::create7point0() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| AudioChannelSet AudioChannelSet::create7point0SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } | |||
| AudioChannelSet AudioChannelSet::create7point1() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| AudioChannelSet AudioChannelSet::create7point1SDDS() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurround) | (1u << rightSurround) | (1u << leftCentre) | (1u << rightCentre)); } | |||
| AudioChannelSet AudioChannelSet::ambisonic() { return AudioChannelSet ((1u << ambisonicW) | (1u << ambisonicX) | (1u << ambisonicY) | (1u << ambisonicZ)); } | |||
| AudioChannelSet AudioChannelSet::quadraphonic() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << leftSurround) | (1u << rightSurround)); } | |||
| AudioChannelSet AudioChannelSet::pentagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| AudioChannelSet AudioChannelSet::hexagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << centreSurround) | (1u << leftSurroundRear) | (1u << rightSurroundRear)); } | |||
| AudioChannelSet AudioChannelSet::octagonal() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurround) | (1u << rightSurround) | (1u << centreSurround) | (1u << wideLeft) | (1u << wideRight)); } | |||
| AudioChannelSet AudioChannelSet::create7point0point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); } | |||
| AudioChannelSet AudioChannelSet::create7point1point2() { return AudioChannelSet ((1u << left) | (1u << right) | (1u << centre) | (1u << LFE) | (1u << leftSurroundSide) | (1u << rightSurroundSide) | (1u << leftSurroundRear) | (1u << rightSurroundRear) | (1u << topSideLeft) | (1u << topSideRight)); } | |||
| AudioChannelSet AudioChannelSet::discreteChannels (int numChannels) | |||
| @@ -194,6 +194,18 @@ public: | |||
| */ | |||
| static AudioChannelSet JUCE_CALLTYPE create7point1SDDS(); | |||
| /** Creates a set for Dolby Atmos 7.0.2 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, topSideLeft, topSideRight). | |||
| Is equivalent to: n/a (VST), AAX_eStemFormat_7_0_2 (AAX), n/a (CoreAudio) | |||
| */ | |||
| static AudioChannelSet JUCE_CALLTYPE create7point0point2(); | |||
| /** Creates a set for Dolby Atmos 7.1.2 surround setup (left, right, centre, leftSurroundSide, rightSurroundSide, leftSurroundRear, rightSurroundRear, LFE, topSideLeft, topSideRight). | |||
| Is equivalent to: k71_2 (VST), AAX_eStemFormat_7_1_2 (AAX), n/a (CoreAudio) | |||
| */ | |||
| static AudioChannelSet JUCE_CALLTYPE create7point1point2(); | |||
| //============================================================================== | |||
| /** Creates a set for ambisonic surround setups (ambisonicW, ambisonicX, ambisonicY, ambisonicZ). | |||
| @@ -289,6 +301,10 @@ public: | |||
| ambisonicY = 26, | |||
| ambisonicZ = 27, | |||
| // Used by Dolby Atmos 7.0.2 and 7.1.2 | |||
| topSideLeft = 28, // Lts (AAX), Tsl (VST) | |||
| topSideRight = 29, // Rts (AAX), Tsr (VST) | |||
| discreteChannel0 = 64 /**< Non-typed individual channels are indexed upwards from this value. */ | |||
| }; | |||
| @@ -305,7 +321,7 @@ public: | |||
| //============================================================================== | |||
| enum | |||
| { | |||
| maxChannelsOfNamedLayout = 8 | |||
| maxChannelsOfNamedLayout = 10 | |||
| }; | |||
| /** Adds a channel to the set. */ | |||
| @@ -33,7 +33,6 @@ namespace juce | |||
| METHOD (release, "release", "()V") \ | |||
| METHOD (flush, "flush", "()V") \ | |||
| METHOD (write, "write", "([SII)I") \ | |||
| METHOD (getUnderrunCount, "getUnderrunCount", "()I") \ | |||
| DECLARE_JNI_CLASS (AudioTrack, "android/media/AudioTrack"); | |||
| #undef JNI_CLASS_MEMBERS | |||
| @@ -51,6 +50,13 @@ DECLARE_JNI_CLASS (AudioTrack, "android/media/AudioTrack"); | |||
| DECLARE_JNI_CLASS (AudioRecord, "android/media/AudioRecord"); | |||
| #undef JNI_CLASS_MEMBERS | |||
| //============================================================================== | |||
| #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ | |||
| STATICFIELD (SDK_INT, "SDK_INT", "I") \ | |||
| DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION"); | |||
| #undef JNI_CLASS_MEMBERS | |||
| //============================================================================== | |||
| enum | |||
| { | |||
| @@ -196,6 +202,9 @@ public: | |||
| STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT, | |||
| (jint) (minBufferSizeOut * numDeviceOutputChannels * static_cast<int> (sizeof (int16))), MODE_STREAM)); | |||
| const bool supportsUnderrunCount = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24); | |||
| getUnderrunCount = supportsUnderrunCount ? env->GetMethodID (AudioTrack, "getUnderrunCount", "()I") : 0; | |||
| int outputDeviceState = env->CallIntMethod (outputDevice, AudioTrack.getState); | |||
| if (outputDeviceState > 0) | |||
| { | |||
| @@ -284,8 +293,8 @@ public: | |||
| int getXRunCount() const noexcept override | |||
| { | |||
| if (outputDevice != nullptr) | |||
| return getEnv()->CallIntMethod (outputDevice, AudioTrack.getUnderrunCount); | |||
| if (outputDevice != nullptr && getUnderrunCount != 0) | |||
| return getEnv()->CallIntMethod (outputDevice, getUnderrunCount); | |||
| return -1; | |||
| } | |||
| @@ -415,6 +424,7 @@ private: | |||
| BigInteger activeOutputChans, activeInputChans; | |||
| GlobalRef outputDevice, inputDevice; | |||
| AudioSampleBuffer inputChannelBuffer, outputChannelBuffer; | |||
| jmethodID getUnderrunCount = 0; | |||
| void closeDevices() | |||
| { | |||
| @@ -23,12 +23,6 @@ | |||
| namespace juce | |||
| { | |||
| #define JNI_CLASS_MEMBERS(METHOD, STATICMETHOD, FIELD, STATICFIELD) \ | |||
| STATICFIELD (SDK_INT, "SDK_INT", "I") \ | |||
| DECLARE_JNI_CLASS (AndroidBuildVersion, "android/os/Build$VERSION"); | |||
| #undef JNI_CLASS_MEMBERS | |||
| //============================================================================== | |||
| #ifndef SL_ANDROID_DATAFORMAT_PCM_EX | |||
| #define SL_ANDROID_DATAFORMAT_PCM_EX ((SLuint32) 0x00000004) | |||
| @@ -306,15 +300,22 @@ public: | |||
| if (runner == nullptr) | |||
| return false; | |||
| // may return nullptr on some platforms - that's ok | |||
| config = SlRef<SLAndroidConfigurationItf_>::cast (runner); | |||
| if (config != nullptr) | |||
| const bool supportsJavaProxy = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24); | |||
| if (supportsJavaProxy) | |||
| { | |||
| jobject audioRoutingJni; | |||
| auto status = (*config)->AcquireJavaProxy (config, SL_ANDROID_JAVA_PROXY_ROUTING, &audioRoutingJni); | |||
| // may return nullptr on some platforms - that's ok | |||
| config = SlRef<SLAndroidConfigurationItf_>::cast (runner); | |||
| if (status == SL_RESULT_SUCCESS && audioRoutingJni != 0) | |||
| javaProxy = GlobalRef (audioRoutingJni); | |||
| if (config != nullptr) | |||
| { | |||
| jobject audioRoutingJni; | |||
| auto status = (*config)->AcquireJavaProxy (config, SL_ANDROID_JAVA_PROXY_ROUTING, | |||
| &audioRoutingJni); | |||
| if (status == SL_RESULT_SUCCESS && audioRoutingJni != 0) | |||
| javaProxy = GlobalRef (audioRoutingJni); | |||
| } | |||
| } | |||
| queue = SlRef<SLAndroidSimpleBufferQueueItf_>::cast (runner); | |||
| @@ -634,6 +635,9 @@ public: | |||
| player = nullptr; | |||
| return; | |||
| } | |||
| const bool supportsUnderrunCount = (getEnv()->GetStaticIntField (AndroidBuildVersion, AndroidBuildVersion.SDK_INT) >= 24); | |||
| getUnderrunCount = supportsUnderrunCount ? getEnv()->GetMethodID (AudioTrack, "getUnderrunCount", "()I") : 0; | |||
| } | |||
| } | |||
| } | |||
| @@ -698,8 +702,8 @@ public: | |||
| int getXRunCount() const noexcept override | |||
| { | |||
| if (player != nullptr && player->javaProxy != nullptr) | |||
| return getEnv()->CallIntMethod (player->javaProxy, AudioTrack.getUnderrunCount); | |||
| if (player != nullptr && player->javaProxy != nullptr && getUnderrunCount != 0) | |||
| return getEnv()->CallIntMethod (player->javaProxy, getUnderrunCount); | |||
| return -1; | |||
| } | |||
| @@ -754,6 +758,7 @@ public: | |||
| ScopedPointer<OpenSLQueueRunnerPlayer<T> > player; | |||
| ScopedPointer<OpenSLQueueRunnerRecorder<T> > recorder; | |||
| Atomic<int> guard; | |||
| jmethodID getUnderrunCount = 0; | |||
| }; | |||
| //============================================================================== | |||
| @@ -46,6 +46,10 @@ | |||
| #pragma warning (disable : 4127 4512) | |||
| #endif | |||
| #include <AAX_Version.h> | |||
| static_assert (AAX_SDK_CURRENT_REVISION >= AAX_SDK_2p3p0_REVISION, "JUCE requires AAX SDK version 2.3.0 or higher"); | |||
| #include <AAX_Exports.cpp> | |||
| #include <AAX_ICollection.h> | |||
| #include <AAX_IComponentDescriptor.h> | |||
| @@ -63,6 +67,9 @@ | |||
| #include <AAX_IMIDINode.h> | |||
| #include <AAX_UtilsNative.h> | |||
| #include <AAX_Enums.h> | |||
| #include <AAX_IDescriptionHost.h> | |||
| #include <AAX_IFeatureInfo.h> | |||
| #include <AAX_UIDs.h> | |||
| #ifdef _MSC_VER | |||
| #pragma warning (pop) | |||
| @@ -134,25 +141,27 @@ namespace AAXClasses | |||
| struct AAXChannelStreamOrder | |||
| { | |||
| AAX_EStemFormat aaxStemFormat; | |||
| AudioChannelSet::ChannelType speakerOrder[8]; | |||
| AudioChannelSet::ChannelType speakerOrder[10]; | |||
| }; | |||
| static AAXChannelStreamOrder aaxChannelOrder[] = | |||
| { | |||
| {AAX_eStemFormat_Mono, {AudioChannelSet::centre, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_Stereo, {AudioChannelSet::left, AudioChannelSet::right, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_LCR, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_LCRS, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::centreSurround, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_Quad, {AudioChannelSet::left, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::rightSurround, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_5_0, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::rightSurround, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_5_1, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::rightSurround, AudioChannelSet::LFE, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_6_0, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::centreSurround, AudioChannelSet::rightSurround, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_6_1, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::centreSurround, AudioChannelSet::rightSurround, AudioChannelSet::LFE, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_7_0_SDDS, {AudioChannelSet::left, AudioChannelSet::leftCentre, AudioChannelSet::centre, AudioChannelSet::rightCentre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::rightSurround, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_7_0_DTS, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide, AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_7_1_SDDS, {AudioChannelSet::left, AudioChannelSet::leftCentre, AudioChannelSet::centre, AudioChannelSet::rightCentre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::rightSurround, AudioChannelSet::LFE}}, | |||
| {AAX_eStemFormat_7_1_DTS, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide, AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::LFE}}, | |||
| {AAX_eStemFormat_None, {AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_Mono, {AudioChannelSet::centre, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_Stereo, {AudioChannelSet::left, AudioChannelSet::right, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_LCR, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_LCRS, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::centreSurround, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_Quad, {AudioChannelSet::left, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::rightSurround, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_5_0, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::rightSurround, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_5_1, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::rightSurround, AudioChannelSet::LFE, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_6_0, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::centreSurround, AudioChannelSet::rightSurround, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_6_1, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::centreSurround, AudioChannelSet::rightSurround, AudioChannelSet::LFE, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_7_0_SDDS, {AudioChannelSet::left, AudioChannelSet::leftCentre, AudioChannelSet::centre, AudioChannelSet::rightCentre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::rightSurround, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_7_0_DTS, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide, AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_7_1_SDDS, {AudioChannelSet::left, AudioChannelSet::leftCentre, AudioChannelSet::centre, AudioChannelSet::rightCentre, AudioChannelSet::right, AudioChannelSet::leftSurround, AudioChannelSet::rightSurround, AudioChannelSet::LFE, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_7_1_DTS, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide, AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::LFE, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_7_0_2, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide, AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::topSideLeft, AudioChannelSet::topSideRight, AudioChannelSet::unknown}}, | |||
| {AAX_eStemFormat_7_1_2, {AudioChannelSet::left, AudioChannelSet::centre, AudioChannelSet::right, AudioChannelSet::leftSurroundSide, AudioChannelSet::rightSurroundSide, AudioChannelSet::leftSurroundRear, AudioChannelSet::rightSurroundRear, AudioChannelSet::LFE, AudioChannelSet::topSideLeft, AudioChannelSet::topSideRight}}, | |||
| {AAX_eStemFormat_None, {AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown, AudioChannelSet::unknown}}, | |||
| }; | |||
| static AAX_EStemFormat aaxFormats[] = | |||
| @@ -169,7 +178,9 @@ namespace AAXClasses | |||
| AAX_eStemFormat_7_0_SDDS, | |||
| AAX_eStemFormat_7_1_SDDS, | |||
| AAX_eStemFormat_7_0_DTS, | |||
| AAX_eStemFormat_7_1_DTS | |||
| AAX_eStemFormat_7_1_DTS, | |||
| AAX_eStemFormat_7_0_2, | |||
| AAX_eStemFormat_7_1_2 | |||
| }; | |||
| static AAX_EStemFormat getFormatForAudioChannelSet (const AudioChannelSet& set, bool ignoreLayout) noexcept | |||
| @@ -179,15 +190,17 @@ namespace AAXClasses | |||
| { | |||
| switch (set.size()) | |||
| { | |||
| case 0: return AAX_eStemFormat_None; | |||
| case 1: return AAX_eStemFormat_Mono; | |||
| case 2: return AAX_eStemFormat_Stereo; | |||
| case 3: return AAX_eStemFormat_LCR; | |||
| case 4: return AAX_eStemFormat_Quad; | |||
| case 5: return AAX_eStemFormat_5_0; | |||
| case 6: return AAX_eStemFormat_5_1; | |||
| case 7: return AAX_eStemFormat_7_0_DTS; | |||
| case 8: return AAX_eStemFormat_7_1_DTS; | |||
| case 0: return AAX_eStemFormat_None; | |||
| case 1: return AAX_eStemFormat_Mono; | |||
| case 2: return AAX_eStemFormat_Stereo; | |||
| case 3: return AAX_eStemFormat_LCR; | |||
| case 4: return AAX_eStemFormat_Quad; | |||
| case 5: return AAX_eStemFormat_5_0; | |||
| case 6: return AAX_eStemFormat_5_1; | |||
| case 7: return AAX_eStemFormat_7_0_DTS; | |||
| case 8: return AAX_eStemFormat_7_1_DTS; | |||
| case 9: return AAX_eStemFormat_7_0_2; | |||
| case 10: return AAX_eStemFormat_7_1_2; | |||
| default: | |||
| break; | |||
| } | |||
| @@ -195,20 +208,22 @@ namespace AAXClasses | |||
| return AAX_eStemFormat_INT32_MAX; | |||
| } | |||
| if (set == AudioChannelSet::disabled()) return AAX_eStemFormat_None; | |||
| if (set == AudioChannelSet::mono()) return AAX_eStemFormat_Mono; | |||
| if (set == AudioChannelSet::stereo()) return AAX_eStemFormat_Stereo; | |||
| if (set == AudioChannelSet::createLCR()) return AAX_eStemFormat_LCR; | |||
| if (set == AudioChannelSet::createLCRS()) return AAX_eStemFormat_LCRS; | |||
| if (set == AudioChannelSet::quadraphonic()) return AAX_eStemFormat_Quad; | |||
| if (set == AudioChannelSet::create5point0()) return AAX_eStemFormat_5_0; | |||
| if (set == AudioChannelSet::create5point1()) return AAX_eStemFormat_5_1; | |||
| if (set == AudioChannelSet::create6point0()) return AAX_eStemFormat_6_0; | |||
| if (set == AudioChannelSet::create6point1()) return AAX_eStemFormat_6_1; | |||
| if (set == AudioChannelSet::create7point0()) return AAX_eStemFormat_7_0_DTS; | |||
| if (set == AudioChannelSet::create7point1()) return AAX_eStemFormat_7_1_DTS; | |||
| if (set == AudioChannelSet::create7point0SDDS()) return AAX_eStemFormat_7_0_SDDS; | |||
| if (set == AudioChannelSet::create7point1SDDS()) return AAX_eStemFormat_7_1_SDDS; | |||
| if (set == AudioChannelSet::disabled()) return AAX_eStemFormat_None; | |||
| if (set == AudioChannelSet::mono()) return AAX_eStemFormat_Mono; | |||
| if (set == AudioChannelSet::stereo()) return AAX_eStemFormat_Stereo; | |||
| if (set == AudioChannelSet::createLCR()) return AAX_eStemFormat_LCR; | |||
| if (set == AudioChannelSet::createLCRS()) return AAX_eStemFormat_LCRS; | |||
| if (set == AudioChannelSet::quadraphonic()) return AAX_eStemFormat_Quad; | |||
| if (set == AudioChannelSet::create5point0()) return AAX_eStemFormat_5_0; | |||
| if (set == AudioChannelSet::create5point1()) return AAX_eStemFormat_5_1; | |||
| if (set == AudioChannelSet::create6point0()) return AAX_eStemFormat_6_0; | |||
| if (set == AudioChannelSet::create6point1()) return AAX_eStemFormat_6_1; | |||
| if (set == AudioChannelSet::create7point0()) return AAX_eStemFormat_7_0_DTS; | |||
| if (set == AudioChannelSet::create7point1()) return AAX_eStemFormat_7_1_DTS; | |||
| if (set == AudioChannelSet::create7point0SDDS()) return AAX_eStemFormat_7_0_SDDS; | |||
| if (set == AudioChannelSet::create7point1SDDS()) return AAX_eStemFormat_7_1_SDDS; | |||
| if (set == AudioChannelSet::create7point0point2()) return AAX_eStemFormat_7_0_2; | |||
| if (set == AudioChannelSet::create7point1point2()) return AAX_eStemFormat_7_1_2; | |||
| return AAX_eStemFormat_INT32_MAX; | |||
| } | |||
| @@ -233,6 +248,8 @@ namespace AAXClasses | |||
| case AAX_eStemFormat_7_0_DTS: return AudioChannelSet::create7point0(); | |||
| case AAX_eStemFormat_7_1_SDDS: return AudioChannelSet::create7point1SDDS(); | |||
| case AAX_eStemFormat_7_1_DTS: return AudioChannelSet::create7point1(); | |||
| case AAX_eStemFormat_7_0_2: return AudioChannelSet::create7point0point2(); | |||
| case AAX_eStemFormat_7_1_2: return AudioChannelSet::create7point1point2(); | |||
| default: | |||
| break; | |||
| } | |||
| @@ -267,8 +284,9 @@ namespace AAXClasses | |||
| const AAXChannelStreamOrder& channelOrder = aaxChannelOrder[layoutIndex]; | |||
| const AudioChannelSet::ChannelType channelType = channelSet.getTypeOfChannel (static_cast<int> (juceIndex)); | |||
| auto numSpeakers = numElementsInArray (channelOrder.speakerOrder); | |||
| for (int i = 0; i < 8 && channelOrder.speakerOrder[i] != 0; ++i) | |||
| for (int i = 0; i < numSpeakers && channelOrder.speakerOrder[i] != 0; ++i) | |||
| if (channelOrder.speakerOrder[i] == channelType) | |||
| return i; | |||
| @@ -1893,7 +1911,25 @@ namespace AAXClasses | |||
| check (desc.AddProcessProc_Native (algorithmProcessCallback, properties)); | |||
| } | |||
| static void getPlugInDescription (AAX_IEffectDescriptor& descriptor) | |||
| static bool hostSupportsStemFormat (AAX_EStemFormat stemFormat, const AAX_IFeatureInfo* featureInfo) | |||
| { | |||
| if (featureInfo != nullptr) | |||
| { | |||
| AAX_ESupportLevel supportLevel; | |||
| if (featureInfo->SupportLevel (supportLevel) == AAX_SUCCESS && supportLevel == AAX_eSupportLevel_ByProperty) | |||
| { | |||
| ScopedPointer<const AAX_IPropertyMap> props (featureInfo->AcquireProperties()); | |||
| if (props != nullptr && props->GetProperty ((AAX_EProperty) stemFormat, (AAX_CPropertyValue*) &supportLevel) != 0) | |||
| return (supportLevel == AAX_eSupportLevel_Supported); | |||
| } | |||
| } | |||
| return (AAX_STEM_FORMAT_INDEX (stemFormat) <= 12); | |||
| } | |||
| static void getPlugInDescription (AAX_IEffectDescriptor& descriptor, const AAX_IFeatureInfo* featureInfo) | |||
| { | |||
| PluginHostType::jucePlugInClientCurrentWrapperType = AudioProcessor::wrapperType_AAX; | |||
| ScopedPointer<AudioProcessor> plugin = createPluginFilterOfType (AudioProcessor::wrapperType_AAX); | |||
| @@ -1949,14 +1985,17 @@ namespace AAXClasses | |||
| AAX_EStemFormat aaxOutFormat = numOuts > 0 ? aaxFormats[outIdx] : AAX_eStemFormat_None; | |||
| AudioChannelSet outLayout = channelSetFromStemFormat (aaxOutFormat, false); | |||
| AudioProcessor::BusesLayout fullLayout; | |||
| if (! JuceAAX_Processor::fullBusesLayoutFromMainLayout (*plugin, inLayout, outLayout, fullLayout)) | |||
| continue; | |||
| if (AAX_IComponentDescriptor* const desc = descriptor.NewComponentDescriptor()) | |||
| if (hostSupportsStemFormat (aaxInFormat, featureInfo) && hostSupportsStemFormat (aaxOutFormat, featureInfo)) | |||
| { | |||
| createDescriptor (*desc, fullLayout, *plugin, pluginIds, numMeters); | |||
| check (descriptor.AddComponent (desc)); | |||
| AudioProcessor::BusesLayout fullLayout; | |||
| if (! JuceAAX_Processor::fullBusesLayoutFromMainLayout (*plugin, inLayout, outLayout, fullLayout)) | |||
| continue; | |||
| if (AAX_IComponentDescriptor* const desc = descriptor.NewComponentDescriptor()) | |||
| { | |||
| createDescriptor (*desc, fullLayout, *plugin, pluginIds, numMeters); | |||
| check (descriptor.AddComponent (desc)); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1972,15 +2011,22 @@ void AAX_CALLBACK AAXClasses::algorithmProcessCallback (JUCEAlgorithmContext* co | |||
| AAXClasses::JuceAAX_Processor::algorithmCallback (instancesBegin, instancesEnd); | |||
| } | |||
| //============================================================================== | |||
| //============================================================================== | |||
| AAX_Result JUCE_CDECL GetEffectDescriptions (AAX_ICollection*); | |||
| AAX_Result JUCE_CDECL GetEffectDescriptions (AAX_ICollection* collection) | |||
| { | |||
| ScopedJuceInitialiser_GUI libraryInitialiser; | |||
| ScopedPointer<const AAX_IFeatureInfo> stemFormatFeatureInfo; | |||
| if (const auto* hostDescription = collection->DescriptionHost()) | |||
| stemFormatFeatureInfo = hostDescription->AcquireFeatureProperties (AAXATTR_ClientFeature_StemFormat); | |||
| if (AAX_IEffectDescriptor* const descriptor = collection->NewDescriptor()) | |||
| { | |||
| AAXClasses::getPlugInDescription (*descriptor); | |||
| AAXClasses::getPlugInDescription (*descriptor, stemFormatFeatureInfo); | |||
| collection->AddEffect (JUCE_STRINGIFY (JucePlugin_AAXIdentifier), descriptor); | |||
| collection->SetManufacturerName (JucePlugin_Manufacturer); | |||
| @@ -173,6 +173,8 @@ static inline Steinberg::Vst::Speaker getSpeakerType (const AudioChannelSet& set | |||
| case AudioChannelSet::ambisonicX: return (1 << 21); /* kSpeakerX */ | |||
| case AudioChannelSet::ambisonicY: return (1 << 22); /* kSpeakerY */ | |||
| case AudioChannelSet::ambisonicZ: return (1 << 23); /* kSpeakerZ */ | |||
| case AudioChannelSet::topSideLeft: return (1 << 24); /* kSpeakerTsl */ | |||
| case AudioChannelSet::topSideRight: return (1 << 25); /* kSpeakerTsr */ | |||
| case AudioChannelSet::discreteChannel0: return kSpeakerM; | |||
| default: | |||
| @@ -182,8 +184,6 @@ static inline Steinberg::Vst::Speaker getSpeakerType (const AudioChannelSet& set | |||
| switch (static_cast<int> (type)) | |||
| { | |||
| case (int) AudioChannelSet::discreteChannel0 + 1: return (1 << 24); /* kSpeakerTsl */ | |||
| case (int) AudioChannelSet::discreteChannel0 + 2: return (1 << 25); /* kSpeakerTsr */ | |||
| case (int) AudioChannelSet::discreteChannel0 + 3: return (1 << 28); /* kSpeakerBfl */ | |||
| case (int) AudioChannelSet::discreteChannel0 + 4: return (1 << 29); /* kSpeakerBfc */ | |||
| case (int) AudioChannelSet::discreteChannel0 + 5: return (1 << 30); /* kSpeakerBfr */ | |||
| @@ -225,8 +225,8 @@ static inline AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::Speak | |||
| case (1 << 21): return AudioChannelSet::ambisonicX; /* kSpeakerX */ | |||
| case (1 << 22): return AudioChannelSet::ambisonicY; /* kSpeakerY */ | |||
| case (1 << 23): return AudioChannelSet::ambisonicZ; /* kSpeakerZ */ | |||
| case (1 << 24): return static_cast<AudioChannelSet::ChannelType> ((int)AudioChannelSet::discreteChannel0 + 1); /* kSpeakerTsl */ | |||
| case (1 << 25): return static_cast<AudioChannelSet::ChannelType> ((int)AudioChannelSet::discreteChannel0 + 2); /* kSpeakerTsr */ | |||
| case (1 << 24): return AudioChannelSet::topSideLeft; /* kSpeakerTsl */ | |||
| case (1 << 25): return AudioChannelSet::topSideRight; /* kSpeakerTsr */ | |||
| case (1 << 26): return AudioChannelSet::leftSurroundSide; /* kSpeakerLcs */ | |||
| case (1 << 27): return AudioChannelSet::rightSurroundSide; /* kSpeakerRcs */ | |||
| case (1 << 28): return static_cast<AudioChannelSet::ChannelType> ((int)AudioChannelSet::discreteChannel0 + 3); /* kSpeakerBfl */ | |||
| @@ -247,24 +247,28 @@ static inline AudioChannelSet::ChannelType getChannelType (Steinberg::Vst::Speak | |||
| static inline Steinberg::Vst::SpeakerArrangement getVst3SpeakerArrangement (const AudioChannelSet& channels) noexcept | |||
| { | |||
| if (channels == AudioChannelSet::disabled()) return Steinberg::Vst::SpeakerArr::kEmpty; | |||
| else if (channels == AudioChannelSet::mono()) return Steinberg::Vst::SpeakerArr::kMono; | |||
| else if (channels == AudioChannelSet::stereo()) return Steinberg::Vst::SpeakerArr::kStereo; | |||
| else if (channels == AudioChannelSet::createLCR()) return Steinberg::Vst::SpeakerArr::k30Cine; | |||
| else if (channels == AudioChannelSet::createLRS()) return Steinberg::Vst::SpeakerArr::k30Music; | |||
| else if (channels == AudioChannelSet::createLCRS()) return Steinberg::Vst::SpeakerArr::k40Cine; | |||
| else if (channels == AudioChannelSet::create5point0()) return Steinberg::Vst::SpeakerArr::k50; | |||
| else if (channels == AudioChannelSet::create5point1()) return Steinberg::Vst::SpeakerArr::k51; | |||
| else if (channels == AudioChannelSet::create6point0()) return Steinberg::Vst::SpeakerArr::k60Cine; | |||
| else if (channels == AudioChannelSet::create6point1()) return Steinberg::Vst::SpeakerArr::k61Cine; | |||
| else if (channels == AudioChannelSet::create6point0Music()) return Steinberg::Vst::SpeakerArr::k60Music; | |||
| else if (channels == AudioChannelSet::create6point1Music()) return Steinberg::Vst::SpeakerArr::k61Music; | |||
| else if (channels == AudioChannelSet::create7point0()) return Steinberg::Vst::SpeakerArr::k70Music; | |||
| else if (channels == AudioChannelSet::create7point0SDDS()) return Steinberg::Vst::SpeakerArr::k70Cine; | |||
| else if (channels == AudioChannelSet::create7point1()) return Steinberg::Vst::SpeakerArr::k71CineSideFill; | |||
| else if (channels == AudioChannelSet::create7point1SDDS()) return Steinberg::Vst::SpeakerArr::k71Cine; | |||
| else if (channels == AudioChannelSet::ambisonic()) return Steinberg::Vst::SpeakerArr::kBFormat; | |||
| else if (channels == AudioChannelSet::quadraphonic()) return Steinberg::Vst::SpeakerArr::k40Music; | |||
| using namespace Steinberg::Vst::SpeakerArr; | |||
| if (channels == AudioChannelSet::disabled()) return kEmpty; | |||
| else if (channels == AudioChannelSet::mono()) return kMono; | |||
| else if (channels == AudioChannelSet::stereo()) return kStereo; | |||
| else if (channels == AudioChannelSet::createLCR()) return k30Cine; | |||
| else if (channels == AudioChannelSet::createLRS()) return k30Music; | |||
| else if (channels == AudioChannelSet::createLCRS()) return k40Cine; | |||
| else if (channels == AudioChannelSet::create5point0()) return k50; | |||
| else if (channels == AudioChannelSet::create5point1()) return k51; | |||
| else if (channels == AudioChannelSet::create6point0()) return k60Cine; | |||
| else if (channels == AudioChannelSet::create6point1()) return k61Cine; | |||
| else if (channels == AudioChannelSet::create6point0Music()) return k60Music; | |||
| else if (channels == AudioChannelSet::create6point1Music()) return k61Music; | |||
| else if (channels == AudioChannelSet::create7point0()) return k70Music; | |||
| else if (channels == AudioChannelSet::create7point0SDDS()) return k70Cine; | |||
| else if (channels == AudioChannelSet::create7point1()) return k71CineSideFill; | |||
| else if (channels == AudioChannelSet::create7point1SDDS()) return k71Cine; | |||
| else if (channels == AudioChannelSet::ambisonic()) return kBFormat; | |||
| else if (channels == AudioChannelSet::quadraphonic()) return k40Music; | |||
| else if (channels == AudioChannelSet::create7point0point2()) return k71_2 & ~(Steinberg::Vst::kSpeakerLfe); | |||
| else if (channels == AudioChannelSet::create7point1point2()) return k71_2; | |||
| Steinberg::Vst::SpeakerArrangement result = 0; | |||
| @@ -278,24 +282,28 @@ static inline Steinberg::Vst::SpeakerArrangement getVst3SpeakerArrangement (cons | |||
| static inline AudioChannelSet getChannelSetForSpeakerArrangement (Steinberg::Vst::SpeakerArrangement arr) noexcept | |||
| { | |||
| if (arr == Steinberg::Vst::SpeakerArr::kEmpty) return AudioChannelSet::disabled(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::kMono) return AudioChannelSet::mono(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::kStereo) return AudioChannelSet::stereo(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k30Cine) return AudioChannelSet::createLCR(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k30Music) return AudioChannelSet::createLRS(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k40Cine) return AudioChannelSet::createLCRS(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k50) return AudioChannelSet::create5point0(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k51) return AudioChannelSet::create5point1(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k60Cine) return AudioChannelSet::create6point0(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k61Cine) return AudioChannelSet::create6point1(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k60Music) return AudioChannelSet::create6point0Music(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k61Music) return AudioChannelSet::create6point1Music(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k70Music) return AudioChannelSet::create7point0(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k70Cine) return AudioChannelSet::create7point0SDDS(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k71CineSideFill) return AudioChannelSet::create7point1(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k71Cine) return AudioChannelSet::create7point1SDDS(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::kBFormat) return AudioChannelSet::ambisonic(); | |||
| else if (arr == Steinberg::Vst::SpeakerArr::k40Music) return AudioChannelSet::quadraphonic(); | |||
| using namespace Steinberg::Vst::SpeakerArr; | |||
| if (arr == kEmpty) return AudioChannelSet::disabled(); | |||
| else if (arr == kMono) return AudioChannelSet::mono(); | |||
| else if (arr == kStereo) return AudioChannelSet::stereo(); | |||
| else if (arr == k30Cine) return AudioChannelSet::createLCR(); | |||
| else if (arr == k30Music) return AudioChannelSet::createLRS(); | |||
| else if (arr == k40Cine) return AudioChannelSet::createLCRS(); | |||
| else if (arr == k50) return AudioChannelSet::create5point0(); | |||
| else if (arr == k51) return AudioChannelSet::create5point1(); | |||
| else if (arr == k60Cine) return AudioChannelSet::create6point0(); | |||
| else if (arr == k61Cine) return AudioChannelSet::create6point1(); | |||
| else if (arr == k60Music) return AudioChannelSet::create6point0Music(); | |||
| else if (arr == k61Music) return AudioChannelSet::create6point1Music(); | |||
| else if (arr == k70Music) return AudioChannelSet::create7point0(); | |||
| else if (arr == k70Cine) return AudioChannelSet::create7point0SDDS(); | |||
| else if (arr == k71CineSideFill) return AudioChannelSet::create7point1(); | |||
| else if (arr == k71Cine) return AudioChannelSet::create7point1SDDS(); | |||
| else if (arr == kBFormat) return AudioChannelSet::ambisonic(); | |||
| else if (arr == k40Music) return AudioChannelSet::quadraphonic(); | |||
| else if (arr == k71_2) return AudioChannelSet::create7point1point2(); | |||
| else if (arr == (k71_2 & ~(Steinberg::Vst::kSpeakerLfe))) return AudioChannelSet::create7point0point2(); | |||
| AudioChannelSet result; | |||
| @@ -1353,20 +1353,22 @@ int32 AudioProcessor::getAAXPluginIDForMainBusConfig (const AudioChannelSet& mai | |||
| const AudioChannelSet& set = (isInput ? mainInputLayout : mainOutputLayout); | |||
| int aaxFormatIndex = 0; | |||
| if (set == AudioChannelSet::disabled()) aaxFormatIndex = 0; | |||
| else if (set == AudioChannelSet::mono()) aaxFormatIndex = 1; | |||
| else if (set == AudioChannelSet::stereo()) aaxFormatIndex = 2; | |||
| else if (set == AudioChannelSet::createLCR()) aaxFormatIndex = 3; | |||
| else if (set == AudioChannelSet::createLCRS()) aaxFormatIndex = 4; | |||
| else if (set == AudioChannelSet::quadraphonic()) aaxFormatIndex = 5; | |||
| else if (set == AudioChannelSet::create5point0()) aaxFormatIndex = 6; | |||
| else if (set == AudioChannelSet::create5point1()) aaxFormatIndex = 7; | |||
| else if (set == AudioChannelSet::create6point0()) aaxFormatIndex = 8; | |||
| else if (set == AudioChannelSet::create6point1()) aaxFormatIndex = 9; | |||
| else if (set == AudioChannelSet::create7point0()) aaxFormatIndex = 10; | |||
| else if (set == AudioChannelSet::create7point1()) aaxFormatIndex = 11; | |||
| else if (set == AudioChannelSet::create7point0SDDS()) aaxFormatIndex = 12; | |||
| else if (set == AudioChannelSet::create7point1SDDS()) aaxFormatIndex = 13; | |||
| if (set == AudioChannelSet::disabled()) aaxFormatIndex = 0; | |||
| else if (set == AudioChannelSet::mono()) aaxFormatIndex = 1; | |||
| else if (set == AudioChannelSet::stereo()) aaxFormatIndex = 2; | |||
| else if (set == AudioChannelSet::createLCR()) aaxFormatIndex = 3; | |||
| else if (set == AudioChannelSet::createLCRS()) aaxFormatIndex = 4; | |||
| else if (set == AudioChannelSet::quadraphonic()) aaxFormatIndex = 5; | |||
| else if (set == AudioChannelSet::create5point0()) aaxFormatIndex = 6; | |||
| else if (set == AudioChannelSet::create5point1()) aaxFormatIndex = 7; | |||
| else if (set == AudioChannelSet::create6point0()) aaxFormatIndex = 8; | |||
| else if (set == AudioChannelSet::create6point1()) aaxFormatIndex = 9; | |||
| else if (set == AudioChannelSet::create7point0()) aaxFormatIndex = 10; | |||
| else if (set == AudioChannelSet::create7point1()) aaxFormatIndex = 11; | |||
| else if (set == AudioChannelSet::create7point0SDDS()) aaxFormatIndex = 12; | |||
| else if (set == AudioChannelSet::create7point1SDDS()) aaxFormatIndex = 13; | |||
| else if (set == AudioChannelSet::create7point0point2()) aaxFormatIndex = 14; | |||
| else if (set == AudioChannelSet::create7point1point2()) aaxFormatIndex = 15; | |||
| else | |||
| { | |||
| // AAX does not support this format and the wrapper should not have | |||
| @@ -47,7 +47,7 @@ | |||
| #define JUCE_COMPILER_SUPPORTS_THREAD_LOCAL 1 | |||
| #endif | |||
| #if __cpp_constexpr >= 201304 | |||
| #if (__GNUC__ * 100 + __GNUC_MINOR__) >= 500 | |||
| #define JUCE_HAS_CONSTEXPR 1 | |||
| #endif | |||
| @@ -61,7 +61,7 @@ void FileListComponent::deselectAllFiles() | |||
| void FileListComponent::scrollToTop() | |||
| { | |||
| getVerticalScrollBar()->setCurrentRangeStart (0); | |||
| getVerticalScrollBar().setCurrentRangeStart (0); | |||
| } | |||
| void FileListComponent::setSelectedFile (const File& f) | |||
| @@ -91,7 +91,7 @@ public: | |||
| { | |||
| jassert (parentContentsList != nullptr); | |||
| DirectoryContentsList* const l = new DirectoryContentsList (parentContentsList->getFilter(), thread); | |||
| auto l = new DirectoryContentsList (parentContentsList->getFilter(), thread); | |||
| l->setDirectory (file, | |||
| parentContentsList->isFindingDirectories(), | |||
| @@ -299,7 +299,7 @@ void FileTreeComponent::deselectAllFiles() | |||
| void FileTreeComponent::scrollToTop() | |||
| { | |||
| getViewport()->getVerticalScrollBar()->setCurrentRangeStart (0); | |||
| getViewport()->getVerticalScrollBar().setCurrentRangeStart (0); | |||
| } | |||
| void FileTreeComponent::setDragAndDropDescription (const String& description) | |||
| @@ -35,11 +35,11 @@ Viewport::Viewport (const String& name) : Component (name) | |||
| scrollBarThickness = getLookAndFeel().getDefaultScrollbarWidth(); | |||
| addChildComponent (verticalScrollBar); | |||
| addChildComponent (horizontalScrollBar); | |||
| addChildComponent (verticalScrollBar = createScrollBarComponent (true)); | |||
| addChildComponent (horizontalScrollBar = createScrollBarComponent (false)); | |||
| verticalScrollBar.addListener (this); | |||
| horizontalScrollBar.addListener (this); | |||
| getVerticalScrollBar().addListener (this); | |||
| getHorizontalScrollBar().addListener (this); | |||
| setInterceptsMouseClicks (false, true); | |||
| setWantsKeyboardFocus (true); | |||
| @@ -140,7 +140,7 @@ bool Viewport::autoScroll (const int mouseX, const int mouseY, const int activeB | |||
| { | |||
| int dx = 0, dy = 0; | |||
| if (horizontalScrollBar.isVisible() || canScrollHorizontally()) | |||
| if (getHorizontalScrollBar().isVisible() || canScrollHorizontally()) | |||
| { | |||
| if (mouseX < activeBorderThickness) | |||
| dx = activeBorderThickness - mouseX; | |||
| @@ -153,7 +153,7 @@ bool Viewport::autoScroll (const int mouseX, const int mouseY, const int activeB | |||
| dx = jmin (dx, maximumSpeed, -contentComp->getX()); | |||
| } | |||
| if (verticalScrollBar.isVisible() || canScrollVertically()) | |||
| if (getVerticalScrollBar().isVisible() || canScrollVertically()) | |||
| { | |||
| if (mouseY < activeBorderThickness) | |||
| dy = activeBorderThickness - mouseY; | |||
| @@ -223,7 +223,7 @@ struct Viewport::DragToScrollListener : private MouseListener, | |||
| { | |||
| if (numTouches == 1 && ! isViewportDragBlocked) | |||
| { | |||
| Point<float> totalOffset = e.getOffsetFromDragStart().toFloat(); | |||
| auto totalOffset = e.getOffsetFromDragStart().toFloat(); | |||
| if (! isDragging && totalOffset.getDistanceFromOrigin() > 8.0f) | |||
| { | |||
| @@ -326,8 +326,8 @@ void Viewport::updateVisibleArea() | |||
| for (int i = 3; --i >= 0;) | |||
| { | |||
| hBarVisible = canShowHBar && ! horizontalScrollBar.autoHides(); | |||
| vBarVisible = canShowVBar && ! verticalScrollBar.autoHides(); | |||
| hBarVisible = canShowHBar && ! getHorizontalScrollBar().autoHides(); | |||
| vBarVisible = canShowVBar && ! getVerticalScrollBar().autoHides(); | |||
| contentArea = getLocalBounds(); | |||
| if (contentComp != nullptr && ! contentArea.contains (contentComp->getBounds())) | |||
| @@ -371,27 +371,30 @@ void Viewport::updateVisibleArea() | |||
| auto visibleOrigin = -contentBounds.getPosition(); | |||
| horizontalScrollBar.setBounds (0, contentArea.getHeight(), contentArea.getWidth(), scrollbarWidth); | |||
| horizontalScrollBar.setRangeLimits (0.0, contentBounds.getWidth()); | |||
| horizontalScrollBar.setCurrentRange (visibleOrigin.x, contentArea.getWidth()); | |||
| horizontalScrollBar.setSingleStepSize (singleStepX); | |||
| horizontalScrollBar.cancelPendingUpdate(); | |||
| auto& hbar = getHorizontalScrollBar(); | |||
| auto& vbar = getVerticalScrollBar(); | |||
| hbar.setBounds (0, contentArea.getHeight(), contentArea.getWidth(), scrollbarWidth); | |||
| hbar.setRangeLimits (0.0, contentBounds.getWidth()); | |||
| hbar.setCurrentRange (visibleOrigin.x, contentArea.getWidth()); | |||
| hbar.setSingleStepSize (singleStepX); | |||
| hbar.cancelPendingUpdate(); | |||
| if (canShowHBar && ! hBarVisible) | |||
| visibleOrigin.setX (0); | |||
| verticalScrollBar.setBounds (contentArea.getWidth(), 0, scrollbarWidth, contentArea.getHeight()); | |||
| verticalScrollBar.setRangeLimits (0.0, contentBounds.getHeight()); | |||
| verticalScrollBar.setCurrentRange (visibleOrigin.y, contentArea.getHeight()); | |||
| verticalScrollBar.setSingleStepSize (singleStepY); | |||
| verticalScrollBar.cancelPendingUpdate(); | |||
| vbar.setBounds (contentArea.getWidth(), 0, scrollbarWidth, contentArea.getHeight()); | |||
| vbar.setRangeLimits (0.0, contentBounds.getHeight()); | |||
| vbar.setCurrentRange (visibleOrigin.y, contentArea.getHeight()); | |||
| vbar.setSingleStepSize (singleStepY); | |||
| vbar.cancelPendingUpdate(); | |||
| if (canShowVBar && ! vBarVisible) | |||
| visibleOrigin.setY (0); | |||
| // Force the visibility *after* setting the ranges to avoid flicker caused by edge conditions in the numbers. | |||
| horizontalScrollBar.setVisible (hBarVisible); | |||
| verticalScrollBar.setVisible (vBarVisible); | |||
| hbar.setVisible (hBarVisible); | |||
| vbar.setVisible (vBarVisible); | |||
| if (contentComp != nullptr) | |||
| { | |||
| @@ -414,8 +417,8 @@ void Viewport::updateVisibleArea() | |||
| visibleAreaChanged (visibleArea); | |||
| } | |||
| horizontalScrollBar.handleUpdateNowIfNeeded(); | |||
| verticalScrollBar.handleUpdateNowIfNeeded(); | |||
| hbar.handleUpdateNowIfNeeded(); | |||
| vbar.handleUpdateNowIfNeeded(); | |||
| } | |||
| //============================================================================== | |||
| @@ -480,11 +483,11 @@ void Viewport::scrollBarMoved (ScrollBar* scrollBarThatHasMoved, double newRange | |||
| { | |||
| const int newRangeStartInt = roundToInt (newRangeStart); | |||
| if (scrollBarThatHasMoved == &horizontalScrollBar) | |||
| if (scrollBarThatHasMoved == horizontalScrollBar) | |||
| { | |||
| setViewPosition (newRangeStartInt, getViewPositionY()); | |||
| } | |||
| else if (scrollBarThatHasMoved == &verticalScrollBar) | |||
| else if (scrollBarThatHasMoved == verticalScrollBar) | |||
| { | |||
| setViewPosition (getViewPositionX(), newRangeStartInt); | |||
| } | |||
| @@ -511,8 +514,8 @@ bool Viewport::useMouseWheelMoveIfNeeded (const MouseEvent& e, const MouseWheelD | |||
| { | |||
| if (! (e.mods.isAltDown() || e.mods.isCtrlDown() || e.mods.isCommandDown())) | |||
| { | |||
| const bool canScrollVert = (allowScrollingWithoutScrollbarV || verticalScrollBar.isVisible()); | |||
| const bool canScrollHorz = (allowScrollingWithoutScrollbarH || horizontalScrollBar.isVisible()); | |||
| const bool canScrollVert = (allowScrollingWithoutScrollbarV || getVerticalScrollBar().isVisible()); | |||
| const bool canScrollHorz = (allowScrollingWithoutScrollbarH || getHorizontalScrollBar().isVisible()); | |||
| if (canScrollHorz || canScrollVert) | |||
| { | |||
| @@ -566,13 +569,13 @@ bool Viewport::keyPressed (const KeyPress& key) | |||
| { | |||
| const bool isUpDownKey = isUpDownKeyPress (key); | |||
| if (verticalScrollBar.isVisible() && isUpDownKey) | |||
| return verticalScrollBar.keyPressed (key); | |||
| if (getVerticalScrollBar().isVisible() && isUpDownKey) | |||
| return getVerticalScrollBar().keyPressed (key); | |||
| const bool isLeftRightKey = isLeftRightKeyPress (key); | |||
| if (horizontalScrollBar.isVisible() && (isUpDownKey || isLeftRightKey)) | |||
| return horizontalScrollBar.keyPressed (key); | |||
| if (getHorizontalScrollBar().isVisible() && (isUpDownKey || isLeftRightKey)) | |||
| return getHorizontalScrollBar().keyPressed (key); | |||
| return false; | |||
| } | |||
| @@ -582,4 +585,9 @@ bool Viewport::respondsToKey (const KeyPress& key) | |||
| return isUpDownKeyPress (key) || isLeftRightKeyPress (key); | |||
| } | |||
| ScrollBar* Viewport::createScrollBarComponent (bool isVertical) | |||
| { | |||
| return new ScrollBar (isVertical); | |||
| } | |||
| } // namespace juce | |||
| @@ -231,12 +231,12 @@ public: | |||
| /** Returns a pointer to the scrollbar component being used. | |||
| Handy if you need to customise the bar somehow. | |||
| */ | |||
| ScrollBar* getVerticalScrollBar() noexcept { return &verticalScrollBar; } | |||
| ScrollBar& getVerticalScrollBar() noexcept { return *verticalScrollBar; } | |||
| /** Returns a pointer to the scrollbar component being used. | |||
| Handy if you need to customise the bar somehow. | |||
| */ | |||
| ScrollBar* getHorizontalScrollBar() noexcept { return &horizontalScrollBar; } | |||
| ScrollBar& getHorizontalScrollBar() noexcept { return *horizontalScrollBar; } | |||
| /** True if there's any off-screen content that could be scrolled vertically, | |||
| or false if everything is currently visible. | |||
| @@ -277,9 +277,16 @@ public: | |||
| /** @internal */ | |||
| static bool respondsToKey (const KeyPress&); | |||
| protected: | |||
| //============================================================================== | |||
| /** Creates the Scrollbar components that will be added to the Viewport. | |||
| Subclasses can override this if they need to customise the scrollbars in some way. | |||
| */ | |||
| virtual ScrollBar* createScrollBarComponent (bool isVertical); | |||
| private: | |||
| //============================================================================== | |||
| ScrollBar verticalScrollBar { true }, horizontalScrollBar { false }; | |||
| ScopedPointer<ScrollBar> verticalScrollBar, horizontalScrollBar; | |||
| Component contentHolder; | |||
| WeakReference<Component> contentComp; | |||
| Rectangle<int> lastVisibleArea; | |||
| @@ -1494,7 +1494,7 @@ class LookAndFeel_V2::SliderLabelComp : public Label | |||
| public: | |||
| SliderLabelComp() : Label ({}, {}) {} | |||
| void mouseWheelMove (const MouseEvent&, const MouseWheelDetails&) {} | |||
| void mouseWheelMove (const MouseEvent&, const MouseWheelDetails&) override {} | |||
| }; | |||
| Label* LookAndFeel_V2::createSliderTextBox (Slider& slider) | |||
| @@ -791,16 +791,16 @@ void ListBox::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& whee | |||
| { | |||
| bool eventWasUsed = false; | |||
| if (wheel.deltaX != 0.0f && viewport->getHorizontalScrollBar()->isVisible()) | |||
| if (wheel.deltaX != 0.0f && getHorizontalScrollBar().isVisible()) | |||
| { | |||
| eventWasUsed = true; | |||
| viewport->getHorizontalScrollBar()->mouseWheelMove (e, wheel); | |||
| getHorizontalScrollBar().mouseWheelMove (e, wheel); | |||
| } | |||
| if (wheel.deltaY != 0.0f && viewport->getVerticalScrollBar()->isVisible()) | |||
| if (wheel.deltaY != 0.0f && getVerticalScrollBar().isVisible()) | |||
| { | |||
| eventWasUsed = true; | |||
| viewport->getVerticalScrollBar()->mouseWheelMove (e, wheel); | |||
| getVerticalScrollBar().mouseWheelMove (e, wheel); | |||
| } | |||
| if (! eventWasUsed) | |||
| @@ -834,8 +834,8 @@ void ListBox::setMinimumContentWidth (const int newMinimumWidth) | |||
| int ListBox::getVisibleContentWidth() const noexcept { return viewport->getMaximumVisibleWidth(); } | |||
| ScrollBar* ListBox::getVerticalScrollBar() const noexcept { return viewport->getVerticalScrollBar(); } | |||
| ScrollBar* ListBox::getHorizontalScrollBar() const noexcept { return viewport->getHorizontalScrollBar(); } | |||
| ScrollBar& ListBox::getVerticalScrollBar() const noexcept { return viewport->getVerticalScrollBar(); } | |||
| ScrollBar& ListBox::getHorizontalScrollBar() const noexcept { return viewport->getHorizontalScrollBar(); } | |||
| void ListBox::colourChanged() | |||
| { | |||
| @@ -379,11 +379,11 @@ public: | |||
| /** Scrolls if necessary to make sure that a particular row is visible. */ | |||
| void scrollToEnsureRowIsOnscreen (int row); | |||
| /** Returns a pointer to the vertical scrollbar. */ | |||
| ScrollBar* getVerticalScrollBar() const noexcept; | |||
| /** Returns a reference to the vertical scrollbar. */ | |||
| ScrollBar& getVerticalScrollBar() const noexcept; | |||
| /** Returns a pointer to the horizontal scrollbar. */ | |||
| ScrollBar* getHorizontalScrollBar() const noexcept; | |||
| /** Returns a reference to the horizontal scrollbar. */ | |||
| ScrollBar& getHorizontalScrollBar() const noexcept; | |||
| /** Finds the row index that contains a given x,y position. | |||
| The position is relative to the ListBox's top-left. | |||
| @@ -357,20 +357,18 @@ Component* TableListBox::getCellComponent (int columnId, int rowNumber) const | |||
| void TableListBox::scrollToEnsureColumnIsOnscreen (int columnId) | |||
| { | |||
| if (auto* scrollbar = getHorizontalScrollBar()) | |||
| { | |||
| auto pos = header->getColumnPosition (header->getIndexOfColumnId (columnId, true)); | |||
| auto& scrollbar = getHorizontalScrollBar(); | |||
| auto pos = header->getColumnPosition (header->getIndexOfColumnId (columnId, true)); | |||
| auto x = scrollbar->getCurrentRangeStart(); | |||
| auto w = scrollbar->getCurrentRangeSize(); | |||
| auto x = scrollbar.getCurrentRangeStart(); | |||
| auto w = scrollbar.getCurrentRangeSize(); | |||
| if (pos.getX() < x) | |||
| x = pos.getX(); | |||
| else if (pos.getRight() > x + w) | |||
| x += jmax (0.0, pos.getRight() - (x + w)); | |||
| if (pos.getX() < x) | |||
| x = pos.getX(); | |||
| else if (pos.getRight() > x + w) | |||
| x += jmax (0.0, pos.getRight() - (x + w)); | |||
| scrollbar->setCurrentRangeStart (x); | |||
| } | |||
| scrollbar.setCurrentRangeStart (x); | |||
| } | |||
| int TableListBox::getNumRows() | |||
| @@ -1869,8 +1869,7 @@ bool TextEditor::pageDown (bool selecting) | |||
| void TextEditor::scrollByLines (int deltaLines) | |||
| { | |||
| if (auto* scrollbar = viewport->getVerticalScrollBar()) | |||
| scrollbar->moveScrollbarInSteps (deltaLines); | |||
| viewport->getVerticalScrollBar().moveScrollbarInSteps (deltaLines); | |||
| } | |||
| bool TextEditor::scrollDown() | |||
| @@ -74,18 +74,7 @@ public: | |||
| CachedImage (OpenGLContext& c, Component& comp, | |||
| const OpenGLPixelFormat& pixFormat, void* contextToShare) | |||
| : ThreadPoolJob ("OpenGL Rendering"), | |||
| context (c), component (comp), | |||
| scale (1.0), | |||
| #if JUCE_OPENGL3 | |||
| vertexArrayObject (0), | |||
| #endif | |||
| #if JUCE_OPENGL_ES | |||
| shadersAvailable (true), | |||
| #else | |||
| shadersAvailable (false), | |||
| #endif | |||
| hasInitialised (false), | |||
| needsUpdate (1), lastMMLockReleaseTime (0) | |||
| context (c), component (comp) | |||
| { | |||
| nativeContext = new NativeContext (component, pixFormat, contextToShare, | |||
| c.useMultisampling, c.versionRequired); | |||
| @@ -180,8 +169,8 @@ public: | |||
| //============================================================================== | |||
| bool ensureFrameBufferSize() | |||
| { | |||
| const int fbW = cachedImageFrameBuffer.getWidth(); | |||
| const int fbH = cachedImageFrameBuffer.getHeight(); | |||
| auto fbW = cachedImageFrameBuffer.getWidth(); | |||
| auto fbH = cachedImageFrameBuffer.getHeight(); | |||
| if (fbW != viewportArea.getWidth() || fbH != viewportArea.getHeight() || ! cachedImageFrameBuffer.isValid()) | |||
| { | |||
| @@ -200,9 +189,9 @@ public: | |||
| glClearColor (0, 0, 0, 0); | |||
| glEnable (GL_SCISSOR_TEST); | |||
| const GLuint previousFrameBufferTarget = OpenGLFrameBuffer::getCurrentFrameBufferTarget(); | |||
| auto previousFrameBufferTarget = OpenGLFrameBuffer::getCurrentFrameBufferTarget(); | |||
| cachedImageFrameBuffer.makeCurrentRenderingTarget(); | |||
| const int imageH = cachedImageFrameBuffer.getHeight(); | |||
| auto imageH = cachedImageFrameBuffer.getHeight(); | |||
| for (auto& r : list) | |||
| { | |||
| @@ -280,16 +269,16 @@ public: | |||
| void updateViewportSize (bool canTriggerUpdate) | |||
| { | |||
| if (ComponentPeer* peer = component.getPeer()) | |||
| if (auto* peer = component.getPeer()) | |||
| { | |||
| lastScreenBounds = component.getTopLevelComponent()->getScreenBounds(); | |||
| const double newScale = Desktop::getInstance().getDisplays() | |||
| .getDisplayContaining (lastScreenBounds.getCentre()).scale; | |||
| auto newScale = Desktop::getInstance().getDisplays() | |||
| .getDisplayContaining (lastScreenBounds.getCentre()).scale; | |||
| Rectangle<int> newArea (peer->getComponent().getLocalArea (&component, component.getLocalBounds()) | |||
| .withZeroOrigin() | |||
| * newScale); | |||
| auto newArea = peer->getComponent().getLocalArea (&component, component.getLocalBounds()) | |||
| .withZeroOrigin() | |||
| * newScale; | |||
| if (scale != newScale || viewportArea != newArea) | |||
| { | |||
| @@ -312,7 +301,7 @@ public: | |||
| void checkViewportBounds() | |||
| { | |||
| const Rectangle<int> screenBounds (component.getTopLevelComponent()->getScreenBounds()); | |||
| auto screenBounds = component.getTopLevelComponent()->getScreenBounds(); | |||
| if (lastScreenBounds != screenBounds) | |||
| updateViewportSize (true); | |||
| @@ -524,7 +513,7 @@ public: | |||
| } | |||
| //============================================================================== | |||
| struct MessageLockWorker : MessageManagerLock::BailOutChecker | |||
| struct MessageLockWorker : public MessageManagerLock::BailOutChecker | |||
| { | |||
| MessageLockWorker (CachedImage& cachedImageRequestingLock) | |||
| : owner (cachedImageRequestingLock) | |||
| @@ -534,11 +523,11 @@ public: | |||
| bool shouldAbortAcquiringLock() override { return owner.doWorkWhileWaitingForLock (false); } | |||
| CachedImage& owner; | |||
| JUCE_DECLARE_NON_COPYABLE(MessageLockWorker) | |||
| JUCE_DECLARE_NON_COPYABLE (MessageLockWorker) | |||
| }; | |||
| //============================================================================== | |||
| struct BlockingWorker : OpenGLContext::AsyncWorker | |||
| struct BlockingWorker : public OpenGLContext::AsyncWorker | |||
| { | |||
| BlockingWorker (OpenGLContext::AsyncWorker::Ptr && workerToUse) | |||
| : originalWorker (static_cast<OpenGLContext::AsyncWorker::Ptr&&> (workerToUse)) | |||
| @@ -552,7 +541,7 @@ public: | |||
| finishedSignal.signal(); | |||
| } | |||
| void block() { finishedSignal.wait(); } | |||
| void block() noexcept { finishedSignal.wait(); } | |||
| OpenGLContext::AsyncWorker::Ptr originalWorker; | |||
| WaitableEvent finishedSignal; | |||
| @@ -599,7 +588,9 @@ public: | |||
| blocker->block(); | |||
| } | |||
| else | |||
| { | |||
| jassertfalse; // you called execute AFTER you detached your openglcontext | |||
| } | |||
| } | |||
| //============================================================================== | |||
| @@ -610,7 +601,7 @@ public: | |||
| //============================================================================== | |||
| // used to push no work on to the gl thread to easily block | |||
| struct DoNothingWorker : OpenGLContext::AsyncWorker | |||
| struct DoNothingWorker : public OpenGLContext::AsyncWorker | |||
| { | |||
| DoNothingWorker() {} | |||
| void operator() (OpenGLContext&) override {} | |||
| @@ -625,18 +616,23 @@ public: | |||
| OpenGLFrameBuffer cachedImageFrameBuffer; | |||
| RectangleList<int> validArea; | |||
| Rectangle<int> viewportArea, lastScreenBounds; | |||
| double scale; | |||
| double scale = 1.0; | |||
| #if JUCE_OPENGL3 | |||
| GLuint vertexArrayObject; | |||
| GLuint vertexArrayObject = 0; | |||
| #endif | |||
| StringArray associatedObjectNames; | |||
| ReferenceCountedArray<ReferenceCountedObject> associatedObjects; | |||
| WaitableEvent canPaintNowFlag, finishedPaintingFlag, repaintEvent; | |||
| bool shadersAvailable, hasInitialised; | |||
| Atomic<int> needsUpdate, destroying; | |||
| uint32 lastMMLockReleaseTime; | |||
| #if JUCE_OPENGL_ES | |||
| bool shadersAvailable = true; | |||
| #else | |||
| bool shadersAvailable = false; | |||
| #endif | |||
| bool hasInitialised = false; | |||
| Atomic<int> needsUpdate { 1 }, destroying; | |||
| uint32 lastMMLockReleaseTime = 0; | |||
| ScopedPointer<ThreadPool> renderThread; | |||
| ReferenceCountedArray<OpenGLContext::AsyncWorker, CriticalSection> workQueue; | |||
| @@ -667,17 +663,15 @@ public: | |||
| void detach() | |||
| { | |||
| Component& comp = *getComponent(); | |||
| auto& comp = *getComponent(); | |||
| stop(); | |||
| comp.setCachedComponentImage (nullptr); | |||
| context.nativeContext = nullptr; | |||
| } | |||
| void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override | |||
| { | |||
| Component& comp = *getComponent(); | |||
| auto& comp = *getComponent(); | |||
| if (isAttached (comp) != canBeAttached (comp)) | |||
| componentVisibilityChanged(); | |||
| @@ -685,10 +679,10 @@ public: | |||
| if (comp.getWidth() > 0 && comp.getHeight() > 0 | |||
| && context.nativeContext != nullptr) | |||
| { | |||
| if (CachedImage* const c = CachedImage::get (comp)) | |||
| if (auto* c = CachedImage::get (comp)) | |||
| c->handleResize(); | |||
| if (ComponentPeer* peer = comp.getTopLevelComponent()->getPeer()) | |||
| if (auto* peer = comp.getTopLevelComponent()->getPeer()) | |||
| context.nativeContext->updateWindowPosition (peer->getAreaCoveredBy (comp)); | |||
| } | |||
| } | |||
| @@ -701,7 +695,7 @@ public: | |||
| void componentVisibilityChanged() override | |||
| { | |||
| Component& comp = *getComponent(); | |||
| auto& comp = *getComponent(); | |||
| if (canBeAttached (comp)) | |||
| { | |||
| @@ -730,7 +724,7 @@ public: | |||
| void update() | |||
| { | |||
| Component& comp = *getComponent(); | |||
| auto& comp = *getComponent(); | |||
| if (canBeAttached (comp)) | |||
| start(); | |||
| @@ -751,7 +745,7 @@ private: | |||
| if (! c.isVisible()) | |||
| return false; | |||
| if (Component* p = c.getParentComponent()) | |||
| if (auto* p = c.getParentComponent()) | |||
| return isShowingOrMinimised (*p); | |||
| return c.getPeer() != nullptr; | |||
| @@ -764,10 +758,10 @@ private: | |||
| void attach() | |||
| { | |||
| Component& comp = *getComponent(); | |||
| CachedImage* const newCachedImage = new CachedImage (context, comp, | |||
| context.openGLPixelFormat, | |||
| context.contextToShareWith); | |||
| auto& comp = *getComponent(); | |||
| auto* newCachedImage = new CachedImage (context, comp, | |||
| context.openGLPixelFormat, | |||
| context.contextToShareWith); | |||
| comp.setCachedComponentImage (newCachedImage); | |||
| start(); | |||
| @@ -777,21 +771,21 @@ private: | |||
| { | |||
| stopTimer(); | |||
| Component& comp = *getComponent(); | |||
| auto& comp = *getComponent(); | |||
| #if JUCE_MAC | |||
| [[(NSView*) comp.getWindowHandle() window] disableScreenUpdatesUntilFlush]; | |||
| #endif | |||
| if (CachedImage* const oldCachedImage = CachedImage::get (comp)) | |||
| if (auto* oldCachedImage = CachedImage::get (comp)) | |||
| oldCachedImage->stop(); // (must stop this before detaching it from the component) | |||
| } | |||
| void start() | |||
| { | |||
| Component& comp = *getComponent(); | |||
| auto& comp = *getComponent(); | |||
| if (CachedImage* const cachedImage = CachedImage::get (comp)) | |||
| if (auto* cachedImage = CachedImage::get (comp)) | |||
| { | |||
| cachedImage->start(); // (must wait until this is attached before starting its thread) | |||
| cachedImage->updateViewportSize (true); | |||
| @@ -802,21 +796,13 @@ private: | |||
| void timerCallback() override | |||
| { | |||
| if (CachedImage* const cachedImage = CachedImage::get (*getComponent())) | |||
| if (auto* cachedImage = CachedImage::get (*getComponent())) | |||
| cachedImage->checkViewportBounds(); | |||
| } | |||
| }; | |||
| //============================================================================== | |||
| OpenGLContext::OpenGLContext() | |||
| : nativeContext (nullptr), renderer (nullptr), | |||
| currentRenderScale (1.0), contextToShareWith (nullptr), | |||
| versionRequired (OpenGLContext::defaultGLVersion), | |||
| imageCacheMaxSize (8 * 1024 * 1024), | |||
| renderComponents (true), | |||
| useMultisampling (false), | |||
| continuousRepaint (false), | |||
| overrideCanAttach (false) | |||
| { | |||
| } | |||
| @@ -894,7 +880,7 @@ void OpenGLContext::attachTo (Component& component) | |||
| void OpenGLContext::detach() | |||
| { | |||
| if (Attachment* a = attachment) | |||
| if (auto* a = attachment.get()) | |||
| { | |||
| a->detach(); // must detach before nulling our pointer | |||
| attachment = nullptr; | |||
| @@ -915,7 +901,7 @@ Component* OpenGLContext::getTargetComponent() const noexcept | |||
| OpenGLContext* OpenGLContext::getContextAttachedTo (Component& c) noexcept | |||
| { | |||
| if (CachedImage* const ci = CachedImage::get (c)) | |||
| if (auto* ci = CachedImage::get (c)) | |||
| return &(ci->context); | |||
| return nullptr; | |||
| @@ -930,7 +916,7 @@ OpenGLContext* OpenGLContext::getCurrentContext() | |||
| bool OpenGLContext::makeActive() const noexcept | |||
| { | |||
| OpenGLContext*& current = currentThreadActiveContext.get(); | |||
| auto& current = currentThreadActiveContext.get(); | |||
| if (nativeContext != nullptr && nativeContext->makeActive()) | |||
| { | |||
| @@ -955,7 +941,7 @@ void OpenGLContext::deactivateCurrentContext() | |||
| void OpenGLContext::triggerRepaint() | |||
| { | |||
| if (CachedImage* const cachedImage = getCachedImage()) | |||
| if (auto* cachedImage = getCachedImage()) | |||
| cachedImage->triggerRepaint(); | |||
| } | |||
| @@ -987,7 +973,7 @@ void* OpenGLContext::getRawContext() const noexcept | |||
| OpenGLContext::CachedImage* OpenGLContext::getCachedImage() const noexcept | |||
| { | |||
| if (Component* const comp = getTargetComponent()) | |||
| if (auto* comp = getTargetComponent()) | |||
| return CachedImage::get (*comp); | |||
| return nullptr; | |||
| @@ -995,7 +981,7 @@ OpenGLContext::CachedImage* OpenGLContext::getCachedImage() const noexcept | |||
| bool OpenGLContext::areShadersAvailable() const | |||
| { | |||
| CachedImage* const c = getCachedImage(); | |||
| auto* c = getCachedImage(); | |||
| return c != nullptr && c->shadersAvailable; | |||
| } | |||
| @@ -1003,7 +989,7 @@ ReferenceCountedObject* OpenGLContext::getAssociatedObject (const char* name) co | |||
| { | |||
| jassert (name != nullptr); | |||
| CachedImage* const c = getCachedImage(); | |||
| auto* c = getCachedImage(); | |||
| // This method must only be called from an openGL rendering callback. | |||
| jassert (c != nullptr && nativeContext != nullptr); | |||
| @@ -1017,7 +1003,7 @@ void OpenGLContext::setAssociatedObject (const char* name, ReferenceCountedObjec | |||
| { | |||
| jassert (name != nullptr); | |||
| if (CachedImage* const c = getCachedImage()) | |||
| if (auto* c = getCachedImage()) | |||
| { | |||
| // This method must only be called from an openGL rendering callback. | |||
| jassert (nativeContext != nullptr); | |||
| @@ -1050,7 +1036,7 @@ size_t OpenGLContext::getImageCacheSize() const noexcept { return ima | |||
| void OpenGLContext::execute (OpenGLContext::AsyncWorker::Ptr workerToUse, bool shouldBlock) | |||
| { | |||
| if (CachedImage* const c = getCachedImage()) | |||
| if (auto* c = getCachedImage()) | |||
| c->execute (static_cast<OpenGLContext::AsyncWorker::Ptr&&> (workerToUse), shouldBlock); | |||
| else | |||
| jassertfalse; // You must have attached the context to a component | |||
| @@ -1062,7 +1048,7 @@ void OpenGLContext::overrideCanBeAttached (bool newCanAttach) | |||
| { | |||
| overrideCanAttach = newCanAttach; | |||
| if (Attachment* a = attachment) | |||
| if (auto* a = attachment.get()) | |||
| a->update(); | |||
| } | |||
| } | |||
| @@ -1185,13 +1171,13 @@ void OpenGLContext::copyTexture (const Rectangle<int>& targetClipArea, | |||
| Params params; | |||
| }; | |||
| const GLshort left = (GLshort) targetClipArea.getX(); | |||
| const GLshort top = (GLshort) targetClipArea.getY(); | |||
| const GLshort right = (GLshort) targetClipArea.getRight(); | |||
| const GLshort bottom = (GLshort) targetClipArea.getBottom(); | |||
| auto left = (GLshort) targetClipArea.getX(); | |||
| auto top = (GLshort) targetClipArea.getY(); | |||
| auto right = (GLshort) targetClipArea.getRight(); | |||
| auto bottom = (GLshort) targetClipArea.getBottom(); | |||
| const GLshort vertices[] = { left, bottom, right, bottom, left, top, right, top }; | |||
| const OverlayShaderProgram& program = OverlayShaderProgram::select (*this); | |||
| auto& program = OverlayShaderProgram::select (*this); | |||
| program.params.set ((float) contextWidth, (float) contextHeight, anchorPosAndTextureSize.toFloat(), flippedVertically); | |||
| GLuint vertexBuffer = 0; | |||
| @@ -1199,7 +1185,7 @@ void OpenGLContext::copyTexture (const Rectangle<int>& targetClipArea, | |||
| extensions.glBindBuffer (GL_ARRAY_BUFFER, vertexBuffer); | |||
| extensions.glBufferData (GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW); | |||
| const GLuint index = (GLuint) program.params.positionAttribute.attributeID; | |||
| auto index = (GLuint) program.params.positionAttribute.attributeID; | |||
| extensions.glVertexAttribPointer (index, 2, GL_SHORT, GL_FALSE, 4, 0); | |||
| extensions.glEnableVertexAttribArray (index); | |||
| JUCE_CHECK_OPENGL_ERROR | |||
| @@ -300,30 +300,30 @@ public: | |||
| private: | |||
| class CachedImage; | |||
| class Attachment; | |||
| NativeContext* nativeContext; | |||
| OpenGLRenderer* renderer; | |||
| double currentRenderScale; | |||
| NativeContext* nativeContext = nullptr; | |||
| OpenGLRenderer* renderer = nullptr; | |||
| double currentRenderScale = 1.0; | |||
| ScopedPointer<Attachment> attachment; | |||
| OpenGLPixelFormat openGLPixelFormat; | |||
| void* contextToShareWith; | |||
| OpenGLVersion versionRequired; | |||
| size_t imageCacheMaxSize; | |||
| bool renderComponents, useMultisampling, continuousRepaint, overrideCanAttach; | |||
| void* contextToShareWith = nullptr; | |||
| OpenGLVersion versionRequired = defaultGLVersion; | |||
| size_t imageCacheMaxSize = 8 * 1024 * 1024; | |||
| bool renderComponents = true, useMultisampling = false, continuousRepaint = false, overrideCanAttach = false; | |||
| //============================================================================== | |||
| struct AsyncWorker : ReferenceCountedObject | |||
| struct AsyncWorker : public ReferenceCountedObject | |||
| { | |||
| typedef ReferenceCountedObjectPtr<AsyncWorker> Ptr; | |||
| virtual void operator() (OpenGLContext&) = 0; | |||
| virtual ~AsyncWorker() {} | |||
| }; | |||
| template <typename T> | |||
| struct AsyncWorkerFunctor : AsyncWorker | |||
| template <typename FunctionType> | |||
| struct AsyncWorkerFunctor : public AsyncWorker | |||
| { | |||
| AsyncWorkerFunctor (T functorToUse) : functor (functorToUse) {} | |||
| AsyncWorkerFunctor (FunctionType functorToUse) : functor (functorToUse) {} | |||
| void operator() (OpenGLContext& callerContext) override { functor (callerContext); } | |||
| T functor; | |||
| FunctionType functor; | |||
| JUCE_DECLARE_NON_COPYABLE (AsyncWorkerFunctor) | |||
| }; | |||
| @@ -341,8 +341,8 @@ private: | |||
| //============================================================================== | |||
| #ifndef DOXYGEN | |||
| template <typename T> | |||
| void OpenGLContext::executeOnGLThread (T&& f, bool shouldBlock) { execute (new AsyncWorkerFunctor<T> (f), shouldBlock); } | |||
| template <typename FunctionType> | |||
| void OpenGLContext::executeOnGLThread (FunctionType&& f, bool shouldBlock) { execute (new AsyncWorkerFunctor<FunctionType> (f), shouldBlock); } | |||
| #endif | |||
| } // namespace juce | |||