### Example Implementation of prepareToPlay Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/visualizers.md An example demonstrating how to set the sample rate and size a FIFO buffer based on the expected block size. ```cpp void prepareToPlay(double sr, int blockSize) override { sampleRate = sr; fifo.setSize(1, blockSize * 4); // 4 blocks of buffer } ``` -------------------------------- ### Example: Getting Style Properties Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/stylesheet.md Demonstrates how to retrieve 'background-color' and 'width' properties using getStyleProperty. The second example also shows how to capture the ValueTree node where the 'width' property was defined. ```cpp auto bgColor = stylesheet.getStyleProperty( juce::Identifier("background-color"), node); juce::ValueTree definedAt; auto width = stylesheet.getStyleProperty( juce::Identifier("width"), node, true, &definedAt); ``` -------------------------------- ### Adding Example Subdirectories Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/Examples/CMakeLists.txt Includes various example subdirectories into the build. Each subdirectory likely contains specific code examples or components for demonstration purposes. ```cmake add_subdirectory(APVTS_Tutorial) add_subdirectory(EqualizerExample) add_subdirectory(ExtendingExample) add_subdirectory(FoleysSynth) add_subdirectory(SignalGenerator) add_subdirectory(Vanilla) add_subdirectory(PlayerExample) ``` -------------------------------- ### Convenience Setup with MagicProcessor Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/architecture-overview.md Utilize the MagicProcessor class for a simplified setup. It automatically creates the MagicProcessorState and MagicPluginEditor, and handles state serialization. ```cpp class MyPlugin : public foleys::MagicProcessor { // MagicProcessorState magicState is created automatically // MagicPluginEditor is created automatically // State serialization is handled automatically }; ``` -------------------------------- ### Example Implementation of createPlotPaths Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/visualizers.md An example showing how to populate a juce::Path with line segments based on audio data within specified bounds. ```cpp void createPlotPaths(juce::Path& path, juce::Path& filledPath, juce::Rectangle bounds, MagicPlotComponent& component) override { path.startNewSubPath(bounds.getX(), bounds.getCentreY()); // Add points to the path for visualization for (size_t i = 0; i < data.size(); ++i) { float x = bounds.getX() + (i * bounds.getWidth() / data.size()); float y = bounds.getBottom() - (data[i] * bounds.getHeight()); path.lineTo(x, y); } } ``` -------------------------------- ### Complete Plugin Example with Visualizers Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/visualizers.md A full example of a JUCE plugin that registers and uses MagicAnalyser and MagicOscilloscope visualizers. It demonstrates how to create, prepare, and push samples to these visualizers within the plugin's lifecycle. ```cpp class SpectrumAnalyzerPlugin : public foleys::MagicProcessor { public: SpectrumAnalyzerPlugin() : MagicProcessor(juce::BusesProperties() .withInput("Input", juce::AudioChannelSet::stereo()) .withOutput("Output", juce::AudioChannelSet::stereo())) { FOLEYS_SET_SOURCE_PATH(__FILE__); // Register visualizers magicState.createAndAddObject("spectrum"); magicState.createAndAddObject("waveform"); } void prepareToPlay(double sampleRate, int samplesPerBlockExpected) override { // Prepare visualizers if (auto analyser = magicState.getObjectWithType("spectrum")) { analyser->prepareToPlay(sampleRate, samplesPerBlockExpected); } if (auto scope = magicState.getObjectWithType("waveform")) { scope->prepareToPlay(sampleRate, samplesPerBlockExpected); } } void processBlock(juce::AudioBuffer& buffer, juce::MidiBuffer&) override { // Send to visualizers if (auto analyser = magicState.getObjectWithType("spectrum")) { analyser->pushSamples(buffer); } if (auto scope = magicState.getObjectWithType("waveform")) { scope->pushSamples(buffer); } // Audio processing... } private: juce::ValueTree createGuiValueTree() override { juce::String xml(BinaryData::magic_xml, BinaryData::magic_xmlSize); return juce::ValueTree::fromXml(xml); } }; ``` -------------------------------- ### CMakeLists.txt Configuration Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/README.md Shows compile-time configuration options for Foley's GUI Magic using CMake. ```cmake FOLEYS_SHOW_GUI_EDITOR_PALLETTE=1 # WYSWYG editor FOLEYS_ENABLE_BINARY_DATA=1 # BinaryData support FOLEYS_ENABLE_OPEN_GL_CONTEXT=1 # OpenGL rendering ``` -------------------------------- ### Load GUI from BinaryData and File Examples Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Demonstrates loading the GUI structure from embedded BinaryData or an external XML file. ```cpp // Load from BinaryData (embedded in plugin) magicState.setGuiValueTree(BinaryData::magic_xml, BinaryData::magic_xmlSize); // Or load from file (useful during development) magicState.setGuiValueTree(juce::File::getSpecialLocation( juce::File::currentApplicationFile).getChildFile("magic.xml")); ``` -------------------------------- ### C++ API Runtime Configuration Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/README.md Demonstrates runtime configuration of the GUI state using the C++ API. ```cpp magicState.setGuiValueTree(xml); magicState.setApplicationSettingsFile(path); magicState.createAndAddObject("id"); ``` -------------------------------- ### Listen to Property Changes Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Demonstrates how to retrieve a property by path and attach a listener to observe its changes. ```cpp auto darkModeValue = magicState.getPropertyAsValue("settings:theme:darkMode"); darkModeValue.addListener(this); // Listen for changes ``` -------------------------------- ### XML Properties Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/README.md Provides examples of XML properties used for configuring GUI elements like sliders and plots. ```xml ``` -------------------------------- ### Example Implementation of getBackgroundJob Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/visualizers.md This example shows how to return a pointer to a processing job object that will be executed on a worker thread. ```cpp juce::TimeSliceClient* getBackgroundJob() override { return &processingJob; // Worker thread will call useTimeSlice() repeatedly } ``` -------------------------------- ### Common Settings File Locations Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/configuration.md Examples of common directory locations for storing application settings. ```cpp // User application data directory juce::File::getSpecialLocation(juce::File::userApplicationDataDirectory) ``` ```cpp // User documents juce::File::getSpecialLocation(juce::File::userDocumentsDirectory) ``` ```cpp // Current executable directory juce::File::getSpecialLocation(juce::File::currentApplicationFile) ``` -------------------------------- ### Setup and Save Application Settings Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/GUIDE.md Configure the file path for application settings using 'setApplicationSettingsFile'. Then, retrieve the settings ValueTree and set properties to save them. ```cpp // Setup path magicState.setApplicationSettingsFile( juce::File::getSpecialLocation(juce::File::userApplicationDataDirectory) .getChildFile("MyCompany") .getChildFile("MyPlugin.settings")); // Save setting juce::ValueTree& settings = magicState.getSettings(); settings.getOrCreateChildWithName("preferences", nullptr) .setProperty("theme", "dark", nullptr); ``` -------------------------------- ### Manage Application Settings and Presets Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Example demonstrating how to set the application settings file and then store and retrieve custom settings, such as preset information, within the global settings tree. ```cpp magicState.setApplicationSettingsFile( juce::File::getSpecialLocation(juce::File::userApplicationDataDirectory) .getChildFile("MyCompany") .getChildFile("MyPlugin.settings")); // Store and retrieve settings juce::ValueTree presets = magicState.getSettings() .getOrCreateChildWithName("presets", nullptr); presets.setProperty("lastUsedPreset", "Default", nullptr); ``` -------------------------------- ### Layout Property Examples Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/configuration.md Examples of layout properties like layout, flex-direction, justify-content, align-items, x, and y. Used for arranging elements. ```XML layout="flex" flex-direction="column" justify-content="center" align-items="center" x="10" y="10" ``` -------------------------------- ### Conditional Property Examples Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/configuration.md Examples of conditional properties using 'when-width' and 'when-height' attributes to apply styles based on GUI dimensions. ```XML ``` -------------------------------- ### Complete GUI Configuration Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/configuration.md This XML snippet demonstrates a full configuration for a GUI, including stylesheet definitions for colors, component types, classes, IDs, and conditional styling, as well as the GUI's DOM structure. ```xml ``` -------------------------------- ### String Property Examples Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/configuration.md Examples of string properties including text, id, parameter, source, and class. These are used for labels, identifiers, and styling. ```XML text="Button Label" id="myButton" parameter="volumeParam" source="spectrum" class="large" ``` -------------------------------- ### Numeric Property Examples Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/configuration.md Examples of numeric properties like width, height, font-size, and border. Values can be in pixels or percentages. ```XML width="100" height="200" min="0" max="100" font-size="16" border="2" border-radius="5" margin="10" padding="5" gap="10" flex="1" ``` -------------------------------- ### Define GUI Layout with XML Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/GUIDE.md Create an XML file to define the plugin's graphical user interface. This example includes stylesheet for colors and a view with a spectrum plot and a volume slider. ```xml ``` -------------------------------- ### Property Tree Structure Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md Illustrates the hierarchical organization of properties within a ValueTree, showing nested parameters, settings, and visualizers. ```cpp ValueTree root; ├─ "parameters" │ ├─ "volume" → Value: 0.5 │ ├─ "frequency" → Value: 500.0 │ └─ ... ├─ "settings" │ ├─ "theme" → Value: "dark" │ ├─ "presets" │ │ ├─ "Preset1" → Value: {...} │ │ └─ "Preset2" → Value: {...} │ └─ ... ├─ "visualizers" │ ├─ "spectrum" → Object: MagicAnalyser* │ ├─ "waveform" → Object: MagicOscilloscope* │ └─ ... └─ ... ``` -------------------------------- ### Conditional Styling Example (XML) Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/architecture-overview.md Illustrates conditional styling using media query syntax within the XML configuration to apply styles based on GUI dimensions. ```xml ``` -------------------------------- ### Get Main Configuration Tree Reference Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Returns a reference to the root configuration tree that holds properties, state, and settings. ```cpp juce::ValueTree& getValueTree() ``` -------------------------------- ### Get Magic Toolbox Instance Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Returns the WYSWYG editor toolbox instance. ```cpp ToolBox& getMagicToolBox() ``` -------------------------------- ### Manual Foleys GUI State and Builder Setup Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/architecture-overview.md Manually set up the Foleys GUI state and builder by creating a MagicGUIState instance, loading the GUI structure, and then initializing a MagicGUIBuilder. Register JUCE factories and look-and-feels before building the GUI. ```cpp // Create state foleys::MagicGUIState magicState; magicState.setGuiValueTree(xmlData); // Create builder foleys::MagicGUIBuilder builder(magicState); builder.registerJUCEFactories(); builder.registerJUCELookAndFeels(); // Build GUI builder.createGUI(parentComponent); ``` -------------------------------- ### Markdown Documentation Format Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/README.md Illustrates the standard markdown format for documenting classes, including sections for constructor, methods, and related classes. ```markdown # Class Name Location: `path/to/header.h` One-sentence class purpose. ## Constructor ```cpp ClassName(parameters) ``` Parameter table | Return type | Description ## Methods Group by functionality with: - Full signature - Parameter tables - Return type - Description - Usage examples - Cross-references ## Related Classes - [[ClassName]] — Short description ``` -------------------------------- ### Implementing JUCE ValueTree Listener Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md Provides an example of a class inheriting from `juce::ValueTree::Listener` to handle various ValueTree change events. ```cpp class MyListener : public juce::ValueTree::Listener { void valueTreePropertyChanged(juce::ValueTree& tree, const juce::Identifier& property) override; void valueTreeChildAdded(juce::ValueTree& parent, juce::ValueTree& child) override; void valueTreeChildRemoved(juce::ValueTree& parent, juce::ValueTree& child, int index) override; void valueTreeChildOrderChanged(juce::ValueTree& parent, int oldIndex, int newIndex) override; void valueTreeParentChanged(juce::ValueTree& tree) override; }; // Use with stylesheet.addListener(&myListener); ``` -------------------------------- ### prepareToPlay Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/visualizers.md Initializes or re-initializes buffers and processing state based on audio setup changes. This method is called when the sample rate or expected block size changes. ```APIDOC ## prepareToPlay ### Description Called when audio setup changes (sample rate or block size). Use this to initialize buffers and processing state. ### Method ```cpp virtual void prepareToPlay(double sampleRate, int samplesPerBlockExpected) = 0 ``` ### Parameters #### Path Parameters - **sampleRate** (`double`) - Description: Sample rate in Hz - **samplesPerBlockExpected** (`int`) - Description: Expected block size ### Request Example ```cpp void prepareToPlay(double sr, int blockSize) override { sampleRate = sr; fifo.setSize(1, blockSize * 4); // 4 blocks of buffer } ``` ``` -------------------------------- ### Flex-Box Layout Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/GUIDE.md Shows how to use flex-box properties within XML to create responsive layouts. Items can grow, shrink, or have fixed dimensions based on their flex properties. ```xml ``` -------------------------------- ### Typical EqualizerPlugin Configuration Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/configuration.md A complete example of setting up an EqualizerPlugin using Foleys::MagicProcessor. It configures audio buses, sets the source path for auto-saving, defines a custom application settings file, and adds visualizer components. ```cpp // MyAudioProcessor.cpp class EqualizerPlugin : public foleys::MagicProcessor { public: EqualizerPlugin() : MagicProcessor(juce::BusesProperties() .withInput("Input", juce::AudioChannelSet::stereo()) .withOutput("Output", juce::AudioChannelSet::stereo())) { // Set source directory for auto-save FOLEYS_SET_SOURCE_PATH(__FILE__); // Set global settings file magicState.setApplicationSettingsFile( juce::File::getSpecialLocation(juce::File::userApplicationDataDirectory) .getChildFile("FoleysFinestAudio") .getChildFile("Equalizer.settings")); // Create visualizers magicState.createAndAddObject("spectrum"); magicState.createAndAddObject("output"); } void initialiseBuilder(foleys::MagicGUIBuilder& builder) override { // Enable standard components builder.registerJUCEFactories(); builder.registerJUCELookAndFeels(); } juce::ValueTree createGuiValueTree() override { // Load GUI from embedded binary data juce::String xml(BinaryData::equalizer_xml, BinaryData::equalizer_xmlSize); return juce::ValueTree::fromXml(xml); } }; ``` -------------------------------- ### Register and Use Triggers for Actions Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Example showing how to register trigger callbacks for actions like saving or loading presets. These triggers can then be invoked from GUI elements. ```cpp magicState.addTrigger(juce::Identifier("savePreset"), [this]() { // Save current preset }); magicState.addTrigger(juce::Identifier("loadPreset"), [this]() { // Load preset dialog }); ``` -------------------------------- ### Process MIDI Buffer in MidiLearnComponent Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/widgets.md Example of integrating MidiLearnComponent's MIDI processing within the audio processor's processBlock. Ensure the magicState is properly initialized. ```cpp // MIDI learn is typically integrated with the processor's processMidiBuffer void processBlock(juce::AudioBuffer& buffer, juce::MidiBuffer& midi) override { magicState.processMidiBuffer(midi, buffer.getNumSamples()); // ... } ``` -------------------------------- ### Example: Handling Layout Recalculation After Media Size Change Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/stylesheet.md Demonstrates how to check if the media size change necessitates a layout update. Call builder.updateLayout if the stylesheet indicates a potential change in active style classes. ```cpp bool changed = stylesheet.setMediaSize(800, 600); if (!changed) { builder.updateLayout(getLocalBounds()); } ``` -------------------------------- ### Create and Add MagicAnalyser to State Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor.md Example of creating and adding a MagicAnalyser object to the magicState, which can then be used for spectrum analysis. ```cpp analyser = magicState.createAndAddObject("spectrum"); ``` -------------------------------- ### Output Folder Setup Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/Examples/CMakeLists.txt Sets the output folder for build artifacts based on the operating system. It uses a specific path within the project for macOS and Windows builds. ```cmake if (APPLE) set(COPY_FOLDER ${CMAKE_SOURCE_DIR}/Builds/MacOSX) elseif(WIN32) set(COPY_FOLDER ${CMAKE_SOURCE_DIR}/Builds/VisualStudio2019) endif() ``` -------------------------------- ### Processor Constructor with Resource Path Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor.md Example of how to use the FOLEYS_SET_SOURCE_PATH macro within the processor's constructor to specify the resource folder and enable auto-save functionality. ```cpp MyAudioProcessor::MyAudioProcessor() { FOLEYS_SET_SOURCE_PATH(__FILE__); } ``` -------------------------------- ### Get Current Time in Milliseconds and Seconds Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md Utilize juce::Time for time-related utilities. This example demonstrates fetching the current time in milliseconds and calculating seconds since the epoch. ```cpp juce::int64 currentMs = juce::Time::currentTimeMillis(); double secondsSinceEpoch = juce::Time::getMillisecondCounter() / 1000.0; ``` -------------------------------- ### JUCE Plugin Target Setup Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/Examples/APVTS_Tutorial/CMakeLists.txt Adds the plugin target using juce_add_plugin, specifying various plugin properties like version, company details, formats, and categories. ```cmake juce_add_plugin(${PROJECT_NAME} VERSION "${version}" COMPANY_NAME "Foleys Finest Audio" PLUGIN_MANUFACTURER_CODE "FFAU" PLUGIN_CODE "PgmV" FORMATS ${FORMATS} VST3_CATEGORIES "Fx" AAX_CATEGORY "AAX_ePlugInCategory_EQ" AU_MAIN_TYPE "kAudioUnitType_Effect" COMPANY_WEBSITE "https://foleysfinest.com" COMPANY_EMAIL "info@foleysfinest.com" BUNDLE_ID "com.foleysfinest.APVTS-Tutorial" PLUGIN_NAME "PGM-APVTS-Tutorial" PRODUCT_NAME "PGM-APVTS-Tutorial") ``` -------------------------------- ### GuiItem getWrappedComponent Override Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/gui-item.md Example of overriding the getWrappedComponent method to return a custom JUCE slider component. ```cpp class MySliderItem : public GuiItem { std::unique_ptr slider; juce::Component* getWrappedComponent() override { return slider.get(); } }; ``` -------------------------------- ### Access juce::AudioBuffer Data Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md Demonstrates how to get the number of channels, samples, and access individual channel data or samples from a juce::AudioBuffer. ```cpp const juce::AudioBuffer& buffer int numChannels = buffer.getNumChannels(); int numSamples = buffer.getNumSamples(); float* channelData = buffer.getReadPointer(channel); float sample = buffer.getSample(channel, sampleIndex); ``` -------------------------------- ### Color Property Examples Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/configuration.md Examples of color properties such as background-color, text-color, and border-color. Values can be in hex format or predefined variables. ```XML background-color="#FF6B35" text-color="$text" border-color="#333333" track-color="$primary" thumb-color="$text" ``` -------------------------------- ### Register Custom Component Factory Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md Example of registering a custom component factory with the MagicGUIBuilder. This allows the builder to create instances of your custom GUI items. ```cpp builder.registerFactory(juce::Identifier("MyComponent"), [](foleys::MagicGUIBuilder& b, const juce::ValueTree& node) { return std::make_unique(b, node); }); ``` -------------------------------- ### Flex-Box Layout Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/architecture-overview.md Defines a View container using flex-box layout with a column direction. Child components grow and shrink based on their flex properties. ```xml ``` -------------------------------- ### ValueTree Hierarchy Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/GUIDE.md Illustrates the hierarchical structure of the GUI in Foley's GUI Magic, where nodes represent components or styles, and properties store configuration values. This structure is similar to a file system hierarchy. ```text root ├─ View (container) │ ├─ Slider (parameter control) │ └─ Plot (visualization) └─ Stylesheet ├─ Type (rules for component types) ├─ Class (reusable style rules) └─ Colours (color palette) ``` -------------------------------- ### GuiItem update Override Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/gui-item.md Example of overriding the update method to apply properties from the ValueTree to a JUCE slider component, such as setting its range. ```cpp void update() override { if (auto slider = dynamic_cast(getWrappedComponent())) { double minVal = magicBuilder.getStyleProperty(juce::Identifier("min"), configNode); double maxVal = magicBuilder.getStyleProperty(juce::Identifier("max"), configNode); slider->setRange(minVal, maxVal); } } ``` -------------------------------- ### Pure Virtual prepareToPlay Method Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/visualizers.md This method is called when audio settings change and should be used to initialize or re-initialize buffers and internal state based on the new sample rate and expected block size. ```cpp virtual void prepareToPlay(double sampleRate, int samplesPerBlockExpected) = 0 ``` -------------------------------- ### Create MagicAnalyser Instances Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/visualizers.md Demonstrates how to create MagicAnalyser objects for different audio channels. Use -1 to analyze the sum of all channels. ```cpp auto leftAnalyser = magicState.createAndAddObject("left", 0); auto rightAnalyser = magicState.createAndAddObject("right", 1); auto sumAnalyser = magicState.createAndAddObject("stereo", -1); ``` -------------------------------- ### Get and Calculate Time Differences with juce::int64 Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md Use juce::int64 for timestamp values. This snippet shows how to get the last update time, the current time in milliseconds, and calculate the elapsed time. ```cpp juce::int64 lastUpdate = source->getLastDataUpdate(); juce::int64 now = juce::Time::currentTimeMillis(); juce::int64 elapsed = now - lastUpdate; ``` -------------------------------- ### Create a Basic Plugin Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/00-START-HERE.md Subclass MagicProcessor to create a new plugin. Implement createGuiValueTree to load your GUI from an XML definition. Ensure your CMakeLists.txt links against foleys_gui_magic. ```cpp // 1. Subclass MagicProcessor class MyPlugin : public foleys::MagicProcessor { juce::ValueTree createGuiValueTree() override { juce::String xml(BinaryData::magic_xml, BinaryData::magic_xmlSize); return juce::ValueTree::fromXml(xml); } }; // 2. Load GUI from XML (create magic.xml) // // // // // // 3. Build with CMake (link foleys_gui_magic) ``` -------------------------------- ### Get Property Default Value Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Looks up the default value for a property. ```cpp juce::var getPropertyDefaultValue(juce::Identifier property) const ``` -------------------------------- ### Get Magic GUI State Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Returns the MagicGUIState this builder is associated with. ```cpp MagicGUIState& getMagicState() ``` -------------------------------- ### Implement Plugin Processor and GUI Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/GUIDE.md Implement the plugin's constructor to set up audio buses, enable auto-save with FOLEYS_SOURCE_PATH, and add GUI components like MagicAnalyser. Load GUI layout from binary data and override processBlock to send audio data to visualizers. ```cpp // MyAudioProcessor.cpp MyAudioProcessor::MyAudioProcessor() : MagicProcessor(juce::BusesProperties() .withInput("Input", juce::AudioChannelSet::stereo()) .withOutput("Output", juce::AudioChannelSet::stereo())) { FOLEYS_SET_SOURCE_PATH(__FILE__); // Enable auto-save // Add visualizers magicState.createAndAddObject("spectrum"); } juce::ValueTree MyAudioProcessor::createGuiValueTree() { // Load from embedded binary data juce::String xml(BinaryData::magic_xml, BinaryData::magic_xmlSize); return juce::ValueTree::fromXml(xml); } // Don't forget to override processBlock: void processBlock(juce::AudioBuffer& buffer, juce::MidiBuffer& midi) override { // Send audio to visualizers if (auto analyser = magicState.getObjectWithType("spectrum")) { analyser->pushSamples(buffer); } // Your audio processing... } ``` -------------------------------- ### Get Undo Manager Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Returns the UndoManager for tracking edits in edit mode. ```cpp juce::UndoManager& getUndoManager() ``` -------------------------------- ### Configure juce::FlexBox for Layout Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md Shows how to set up a juce::FlexBox container with properties like direction, justification, and alignment, and then perform layout. ```cpp juce::FlexBox flexBox; flexBox.flexDirection = juce::FlexBox::Direction::column; flexBox.justifyContent = juce::FlexBox::JustifyContent::center; flexBox.alignItems = juce::FlexBox::AlignItems::center; flexBox.items.add(item1); flexBox.items.add(item2); flexBox.performLayout(bounds); ``` -------------------------------- ### Get Currently Selected Node Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Returns the currently selected node in edit mode. ```cpp const juce::ValueTree& getSelectedNode() const ``` -------------------------------- ### Load GUI from Different Sources Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/configuration.md Demonstrates how to load the GUI definition for MagicState from embedded binary data, a disk file, or an XML string. Choose the method that best suits your project's asset management. ```cpp // From embedded BinaryData magicState.setGuiValueTree(BinaryData::magic_xml, BinaryData::magic_xmlSize); // From disk file magicState.setGuiValueTree(juce::File("path/to/gui.xml")); // From XML string juce::String xmlText = "..."; magicState.setGuiValueTree(juce::ValueTree::fromXml(xmlText)); ``` -------------------------------- ### Create Parameter Menu Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Generates a popup menu containing all available AudioProcessor parameters. The default implementation returns an empty menu. ```cpp virtual juce::PopupMenu createParameterMenu() const ``` -------------------------------- ### Get Registered Factory Names Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Retrieves the identifiers of all available component types that have registered factories. ```cpp juce::StringArray getFactoryNames() const ``` -------------------------------- ### Prepare Oscilloscope for Playback Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/Examples/SignalGenerator/README.md Call prepareToPlay on magicState from the processor's prepareToPlay method to initialize the oscilloscope. ```cpp void SignalGeneratorAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock) { // ... magicState.prepareToPlay (sampleRate, samplesPerBlock); } ``` -------------------------------- ### Get Radio Button Manager Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Returns the radio button manager that coordinates mutually-exclusive button groups. ```cpp RadioButtonManager& getRadioButtonManager() ``` -------------------------------- ### Get Customizable Colour Names Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Returns an array of names for colors that can be customized for a specific component type. ```cpp juce::StringArray getColourNames(juce::Identifier type) ``` -------------------------------- ### Runtime API Configuration for GUI Building Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/INDEX.md Configures the GUI at runtime by registering JUCE factories and custom components, setting stylesheet colors, and specifying application settings files. ```cpp // Enable component types builder.registerJUCEFactories(); // Register custom components builder.registerFactory(juce::Identifier("MyComponent"), factory); // Set colors stylesheet.addPaletteEntry("$primary", juce::Colours::red, false); // Store global settings magicState.setApplicationSettingsFile(path); ``` -------------------------------- ### createGUI Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Main method to build the GUI. Creates all components from the GUI ValueTree and adds them to the parent component. This triggers building of the stylesheet and all child components. ```APIDOC ## Method createGUI ### Description Main method to build the GUI. Creates all components from the GUI ValueTree and adds them to the parent component. This triggers building of the stylesheet and all child components. ### Parameters #### Path Parameters - **parent** (`juce::Component&`) - Required - Parent component to add GUI elements to ### Request Example ```cpp juce::Component editorPanel; builder.createGUI(editorPanel); ``` ``` -------------------------------- ### Project and Source Configuration Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/Examples/APVTS_Tutorial/CMakeLists.txt Sets the minimum CMake version and project name, then defines the source files for the plugin. ```cmake cmake_minimum_required(VERSION 3.15.0) project("apvtsTutorial" VERSION ${FGM_VERSION}) ``` ```cmake set(${PROJECT_NAME}_sources Source/PluginProcessor.cpp) ``` -------------------------------- ### Get LookAndFeel for Node Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/stylesheet.md Returns the LookAndFeel assigned to a specific GUI node. Returns nullptr if no LookAndFeel is assigned. ```cpp juce::LookAndFeel* getLookAndFeel(const juce::ValueTree& node) const ``` -------------------------------- ### Get Property Root Node Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Returns the root node of the property tree, used for exposing values to the GUI. ```cpp juce::ValueTree getPropertyRoot() ``` ```cpp juce::ValueTree getPropertyRoot() const ``` -------------------------------- ### Iterate Through juce::StringArray Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md juce::StringArray is used for lists of strings. This example shows how to retrieve parameter names and iterate over them. ```cpp juce::StringArray names = magicState.getParameterNames(); for (const auto& name : names) { // Process each name } ``` -------------------------------- ### Create Popup Menu from Asset Files Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Constructs and returns a JUCE PopupMenu populated with available asset file paths. ```cpp juce::PopupMenu createAssetFilesMenu() const ``` -------------------------------- ### MagicProcessor Constructors Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor.md Instantiate MagicProcessor with default or custom I/O layouts. The parameterless constructor is suitable for default mono/stereo setups. ```cpp MagicProcessor() MagicProcessor(const juce::BusesProperties& ioLayouts) MagicProcessor(const std::initializer_list& channelLayoutList) ``` ```cpp class MyAudioProcessor : public foleys::MagicProcessor { public: MyAudioProcessor() : MagicProcessor(BusesProperties() .withInput("Input", juce::AudioChannelSet::stereo()) .withOutput("Output", juce::AudioChannelSet::stereo())) { FOLEYS_SET_SOURCE_PATH(__FILE__); } }; ``` -------------------------------- ### Get Parameter Names Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Retrieves the IDs of all available AudioProcessorParameters. Subclasses typically override this to provide their specific parameter IDs. ```cpp virtual juce::StringArray getParameterNames() const ``` -------------------------------- ### Create and Use MagicLevelMeter Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/widgets.md First, create a MagicLevelSource object in your audio processor. Then, in your GUI XML, define a LevelMeter component to display the audio levels. ```cpp // Create a level source auto levelSource = magicState.createAndAddObject("input"); // In GUI XML // ``` -------------------------------- ### Get Background Image Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/stylesheet.md Retrieves the background image for a node. This function requires FOLEYS_ENABLE_BINARY_DATA to be enabled and images to be present in BinaryData. ```cpp juce::Image getBackgroundImage(const juce::ValueTree& node) const ``` -------------------------------- ### Get Colour from Stylesheet Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/stylesheet.md Looks up a color from the palette. Names can use the $ variable syntax. Returns black if the color is not found. ```cpp juce::Colour getColour(const juce::String& name) const ``` ```cpp auto primaryColor = stylesheet.getColour("$primary"); auto accentColor = stylesheet.getColour("$accent"); ``` -------------------------------- ### createAssetFilesMenu Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Creates a popup menu of available asset files. ```APIDOC ## createAssetFilesMenu ### Description Creates a popup menu of available asset files. ### Return Type `juce::PopupMenu` — A popup menu of available asset files ### Method Signature ```cpp juce::PopupMenu createAssetFilesMenu() const ``` ``` -------------------------------- ### Get Parameter Names Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor-state.md Returns a StringArray containing the IDs of all parameters available in the AudioProcessor. This overrides the base class method. ```cpp juce::StringArray getParameterNames() const override ``` -------------------------------- ### Stylesheet Constructor Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/stylesheet.md Creates a new stylesheet instance, attaching it to a MagicGUIBuilder. ```APIDOC ## Stylesheet Constructor ### Description Creates a new stylesheet attached to a builder. ### Signature ```cpp Stylesheet(MagicGUIBuilder& builder) ``` ### Parameters #### Path Parameters - **builder** (`MagicGUIBuilder&`) - Required - The builder that owns this stylesheet ``` -------------------------------- ### Example Usage of getLastDataUpdate Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/visualizers.md Demonstrates how to check if a plot source is outdated by comparing the current time with the last data update timestamp. ```cpp bool isOutdated = (juce::Time::currentTimeMillis() - source->getLastDataUpdate()) > 50; ``` -------------------------------- ### Get Playhead Information Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md Retrieves playhead information such as BPM, PPQ position, and playback status from the DAW via juce::AudioPlayHead. ```cpp auto optionalPlayHead = getPlayHead(); if (optionalPlayHead != nullptr) { if (auto posInfo = optionalPlayHead->getPosition()) { double bpm = posInfo->getBpm().orFallback(120.0); double ppqPosition = posInfo->getPpqPosition().orFallback(0.0); bool isPlaying = posInfo->getIsPlaying(); } } ``` -------------------------------- ### Get Root GUI Node Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Returns the top-level ValueTree node representing the root of the GUI structure, usually a '' element. ```cpp juce::ValueTree guiRoot = builder.getGuiRootNode(); ``` -------------------------------- ### Create GUI from ValueTree Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-builder.md Builds the entire GUI by creating components from the GUI ValueTree and attaching them to a parent component. This method also triggers stylesheet and child component building. ```cpp juce::Component editorPanel; builder.createGUI(editorPanel); ``` -------------------------------- ### Set GUI Structure from File Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Loads the GUI structure from an XML file on disk. Useful during development. ```cpp void setGuiValueTree(const juce::File& file) ``` -------------------------------- ### Get Specific Parameter Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Retrieves a pointer to a specific AudioProcessorParameter by its ID. Returns nullptr if the parameter is not found. Subclasses usually override this. ```cpp virtual juce::RangedAudioParameter* getParameter(const juce::String& paramID) ``` -------------------------------- ### Implementing MagicGUIBuilder Listener Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md Demonstrates how to implement the `foleys::MagicGUIBuilder::Listener` interface to receive callbacks for item selection and component dropping during GUI editing. ```cpp class MyBuilderListener : public foleys::MagicGUIBuilder::Listener { void selectedItem(const juce::ValueTree& node) override { // Called when user selects a component in edit mode } void guiItemDropped(const juce::ValueTree& node, juce::ValueTree& droppedOnto) override { // Called when user drops a component in edit mode } }; builder.addListener(&myBuilderListener); ``` -------------------------------- ### Get Last Editor Size Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor-state.md Retrieves the previously stored editor dimensions. Returns true if a size was found, false otherwise. ```cpp bool getLastEditorSize(int& width, int& height) ``` ```cpp int w = 800, h = 600; if (magicState.getLastEditorSize(w, h)) { setSize(w, h); } ``` -------------------------------- ### Create Parameter Menu Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor-state.md Generates a juce::PopupMenu containing all parameters, organized hierarchically based on the AudioProcessor's parameter tree structure. This overrides the base class method. ```cpp juce::PopupMenu createParameterMenu() const override ``` -------------------------------- ### Get Property as JUCE Value Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Retrieves a property by its colon-separated hierarchical path and returns a JUCE Value object that can be listened to for changes. ```cpp juce::Value getPropertyAsValue(const juce::String& pathToProperty) ``` -------------------------------- ### Create Popup Menu from Properties Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Constructs and returns a JUCE PopupMenu containing all available property paths, using a given ComboBox for building. ```cpp juce::PopupMenu createPropertiesMenu(juce::ComboBox& combo) const ``` -------------------------------- ### Add Visualisations to Plugin Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/README.md Add visualisations like Analysers or Oscilloscopes by creating and adding them as objects to your magicState in the constructor. Prepare them in prepareToPlay and push samples in processBlock. ```cpp // Member: foleys::MagicPlotSource* analyser = nullptr; // Constructor analyser = magicState.createAndAddObject("input"); // prepareToPlay analyser->prepareToPlay (sampleRate, samplesPerBlockExpected); // e.g. in processBlock send the samples to the analyser: analyser->pushSamples (buffer); ``` -------------------------------- ### Get the current style ValueTree Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/stylesheet.md Retrieves the currently active style node as a juce::ValueTree. This is useful for inspecting or modifying the active stylesheet. ```cpp juce::ValueTree getCurrentStyle() const ``` -------------------------------- ### Get Audio Processor Instance Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor-state.md Returns a pointer to the AudioProcessor this state is managing. This is useful for accessing processor-specific functionality from the state management context. ```cpp juce::AudioProcessor* getProcessor() override ``` -------------------------------- ### Create and Use Parameter Menu Lambda Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/types-and-interfaces.md Demonstrates creating a menu lambda and assigning it to a ComboBox's onChange event. The lambda is used to populate the ComboBox. ```cpp auto parameterMenu = builder.createParameterMenuLambda(); // Now parameterMenu can populate a ComboBox comboBox.onChange = [&, parameterMenu] { parameterMenu(comboBox); }; ``` -------------------------------- ### Get Last Moved MIDI Controller Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor-state.md Retrieves the MIDI CC number of the most recently moved controller. Returns -1 if no controller has been moved. ```cpp int getLastController() const ``` -------------------------------- ### Get Mutable GUI Tree Reference Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-gui-state.md Returns a mutable reference to the GUI DOM structure, allowing runtime modification and change listening. ```cpp juce::ValueTree& getGuiTree() ``` -------------------------------- ### Typical MagicAnalyser Usage in a MagicProcessor Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/visualizers.md Shows how to integrate MagicAnalyser into a custom MagicProcessor. Ensure to register the analyser and prepare it for audio playback before processing blocks. ```cpp class MyAudioProcessor : public foleys::MagicProcessor { public: MyAudioProcessor() { // Register analysers for the GUI spectrum = magicState.createAndAddObject("spectrum"); // Prepare audio processing spectrum->prepareToPlay(44100.0, 512); } private: foleys::MagicAnalyser* spectrum = nullptr; }; // In processBlock: void processBlock(juce::AudioBuffer& buffer, juce::MidiBuffer&) override { spectrum->pushSamples(buffer); // ... rest of processing } ``` -------------------------------- ### createParameterMenu Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor-state.md Creates a popup menu with all parameters organized hierarchically according to the AudioProcessor's parameter tree structure (including parameter groups). Overrides the base class method. ```APIDOC ## createParameterMenu ### Description Creates a popup menu with all parameters organized hierarchically. ### Method ```cpp juce::PopupMenu createParameterMenu() const override ``` ### Return Type `juce::PopupMenu` — Hierarchical menu of AudioProcessor parameters ``` -------------------------------- ### Get Tail Length in Seconds Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor.md Specifies the tail length of the audio processor. Overridden by subclasses if the processor has a tail; otherwise, returns 0.0. ```cpp double getTailLengthSeconds() const override ``` -------------------------------- ### Get Processor State Information Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/magic-processor.md Serializes the current state of the audio processor, including parameters and GUI state, into a memory block for saving. ```cpp void getStateInformation(juce::MemoryBlock& destData) override ``` -------------------------------- ### Create and Use MagicLevelSource Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/api-reference/visualizers.md Instantiate a MagicLevelSource to track RMS and peak levels. This is typically done via a MagicLevelMeter widget, but can be created directly. Ensure to prepare it for playback and push audio samples for level measurement. ```cpp // Create a level source auto levelSource = magicState.createAndAddObject("inputLevel"); levelSource->prepareToPlay(sampleRate, blockSize); // Push samples to measure levels if (auto level = magicState.getObjectWithType("inputLevel")) { level->pushSamples(buffer); } ``` -------------------------------- ### Absolute Positioning Layout Example Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/architecture-overview.md Defines a View container using absolute positioning. Child components are placed using explicit x and y coordinates. ```xml ``` -------------------------------- ### Create and Register MagicAnalyser Source: https://github.com/ffaudio/foleys_gui_magic/blob/main/_autodocs/GUIDE.md Instantiate a MagicAnalyser object with the ID 'spectrum' and prepare it for audio processing by providing the sample rate and block size. ```cpp auto analyser = magicState.createAndAddObject("spectrum"); analyser->prepareToPlay(sampleRate, blockSize); ```