R³ – VST Integration in Audiocube: Feasibility and Implementation

By Audiocube.app and Noah Feasey-Kemp (2025)

Introduction

Audiocube is a Unity-based 3D Digital Audio Workstation (DAW) that enables musicians and sound designers to create and manipulate sound in a virtual three-dimensional space. By leveraging spatial audio, custom acoustic simulations, and an intuitive 3D interface, Audiocube provides novel workflows beyond traditional 2D DAWs. However, one significant feature that Audiocube currently lacks is support for third-party audio plugins, specifically VST (Virtual Studio Technology) plugins. VST plugins—ranging from software synthesizers (VSTi) to audio effects—are the backbone of modern music production, with thousands of instruments and effects available on the market. Integrating VST support into Audiocube could greatly expand its capabilities by allowing users to incorporate their favorite virtual instruments and effects into the 3D environment, bridging Audiocube with established music production workflows.

Significance of VST Integration: For Audiocube’s users, VST integration means access to a vast ecosystem of sounds and processing tools developed over decades. Most producers rely on a palette of VST instruments (like synthesizers and samplers) and effects (like EQs, reverbs, compressors) to craft their music. By supporting VSTs, Audiocube can interoperate with industry-standard tools, making it easier for customers to adopt it alongside or in place of traditional DAWs. For investors and stakeholders, VST support signals that Audiocube is evolving into a full-featured production platform, increasing its competitive edge and market appeal. It addresses a frequent user request – as noted by Audiocube’s developer, many have asked for the ability to use Audiocube in tandem with other DAWs or to load plugins directly. In essence, VST integration can transform Audiocube from a standalone niche application into a versatile hub in a producer’s workflow.

Scope of this White Paper: This document explores the feasibility and implementation strategy of adding VST plugin support to Audiocube. We begin with an overview of VST technology and why it’s important. Then we examine Unity’s current audio capabilities and limitations in the context of hosting VSTs. Various approaches to achieve VST integration are analyzed – including using the JUCE framework and alternative methods such as Unity’s native audio plugin SDK or third-party audio middleware. We discuss technical challenges (from performance and latency to plugin UI integration and cross-platform issues) and potential solutions. A step-by-step conceptual implementation plan is outlined, with considerations for user interface and experience in controlling VSTs within Audiocube. Throughout, we balance technical depth (suitable for Audiocube’s development team) with clarity and context (so that customers and non-developers can understand the benefits and challenges). Finally, we present recommendations on the best path forward for Audiocube’s VST integration and the next steps towards making it a reality, backed by references to relevant research and industry practices.

By the end of this white paper, the reader should have a comprehensive understanding of what it takes to integrate VST plugins into a Unity-based 3D DAW, why it matters, and a clear direction for implementing this feature in Audiocube. The goal is to provide a roadmap that can guide development and also communicate to stakeholders the complexity and value of this undertaking.

2. Understanding VST Technology

What is a VST? Virtual Studio Technology (VST) is an audio plugin standard introduced by Steinberg in 1996 that revolutionized digital music production. In essence, a VST plugin is a software component that can be loaded into a host application (typically a DAW) to either generate audio (instruments) or process audio (effects). VSTs allow producers to extend a host application with new synths and effects much like hardware racks in a physical studio. Being an open and widely adopted standard, VST created a rich third-party developer ecosystem; over the past two decades, thousands of virtual instruments and effects have been released in VST format. This includes everything from analog-modeling synthesizers and samplers to advanced effects like convolution reverbs and spectral processors.

Types of VST Plugins: There are three general categories of VST plugins:

  • VST Instruments (VSTi): These generate audio output, often via MIDI input. They include virtual synthesizers, samplers, drum machines, and other sound generators. For example, popular VSTi synths like Native Instruments Massive or Arturia’s analog emulations take MIDI notes as input and produce audio signals. VST instruments often emulate hardware synthesizers or create entirely new digital sounds.

  • VST Effects: These plugins process incoming audio and output the modified audio. They behave like studio effects units (equalizers, compressors, reverbs, delays, distortion pedals, etc.). You can insert multiple VST effects in series on an audio signal (creating an “effects chain”). Some effects are also “audio analyzers” that don’t alter sound but display information (spectrum analyzers, meters).

  • VST MIDI Effects: These less-common plugins process MIDI data rather than audio (for instance, an arpeggiator or a MIDI chord generator). They sit between a MIDI source and a VST instrument, transforming the MIDI messages.

In typical DAWs, users can load any number of VST instruments and effects on their tracks to build complex projects. A VST host is the environment or application that loads the plugins and connects them to the overall audio/MIDI routing. Hosts provide the infrastructure for: scanning and loading plugin files, instantiating them, delivering audio/MIDI to them, and exposing their user interfaces for parameter control.

How VST Plugins Work: From a technical perspective, a VST plugin is a dynamically-loaded library (a .dll on Windows, .vst3 bundle or .component (AU) on macOS) that adheres to Steinberg’s VST API. The host (e.g., Ableton Live, Steinberg Cubase, or potentially Audiocube) loads this library at runtime and uses predefined API calls to initialize the plugin and process audio. The basic flow is: the host provides the plugin with chunks of audio data and timing information, and the plugin returns the processed audio for output. Audio is typically processed in small blocks of samples (e.g., 64, 128, 512 samples at a time) for efficiency. The host controls the block size and manages the audio stream, calling the plugin’s processing callback for each block. In the case of instruments, the host also sends MIDI events (note on, note off, control change, etc.) into the plugin. The VST instrument synthesizes audio (often in the same process callback) and outputs it to the host.

From the host's point of view, a VST plugin is a black box that receives input (audio and/or MIDI) and produces output (audio and/or MIDI). The host doesn’t need to know the plugin’s internal DSP (Digital Signal Processing) details; it simply calls into the plugin at the right times. This modular approach means a DAW can support any number of third-party plugins without custom code for each, as long as they all follow the VST interface.

VST 2 vs VST 3: There have been multiple versions of the VST standard. VST 2.4 (introduced in 2006) became the long-lived workhorse standard through the 2000s, supporting 32-bit and 64-bit processing and MIDI handling. VST 3 (introduced in 2008) is the modern standard with improved features: it adds support for audio input on instruments, multiple MIDI I/O, dynamic parameter management, and other enhancements. Notably, Steinberg discontinued maintenance and distribution of the VST 2 SDK after 2013, encouraging developers and hosts to transition to VST 3. Today, new hosts (especially commercial products) implement VST 3 for plugin support, as it is actively maintained and comes with a more permissive license (Steinberg provides the VST 3 SDK for free, with an option for open-source GPLv3 licensing as of version 3.6.7). For Audiocube, this implies that VST3 is the target format for integration, ensuring compatibility with current and future plugins. (Support for VST2 could be considered for legacy compatibility, but it entails legal/licensing complexity since Steinberg’s VST2 SDK is no longer officially available. VST3 support will cover most modern plugins and can be backward-compatible if plugin developers have provided VST3 versions.)

Use Cases and Benefits of VST Plugins:

  • Expanding Sound Palette: VST instruments allow Audiocube users to introduce virtually any sound – from grand piano emulations to futuristic synth textures – into their 3D projects. Instead of being limited to imported audio samples, users could play and sequence notes for VSTi plugins, hearing those instruments in Audiocube’s spatial environment.

  • Advanced Audio Processing: With VST effects, users can apply professional-grade processing to their audio within Audiocube. For example, they might use a renowned reverb plugin to enhance spatialization, or a mastering compressor to gel the final mix. This could complement Audiocube’s built-in effects with the user’s preferred tools.

  • Workflow Integration: Many producers have established workflows revolving around certain plugins. VST support lets Audiocube slot into these workflows. A sound designer could, for instance, use Audiocube to spatialize sounds and then insert a favorite VST EQ and limiter on the output for final tuning, all within Audiocube.

  • Community and Support: By aligning with the VST standard, Audiocube can tap into the collective knowledge base of audio developers and users. Tutorials, forums, and support resources for “using plugins” would become relevant, lowering the learning curve for new Audiocube users who are already familiar with plugins in other DAWs.

In summary, VST technology is a cornerstone of modern audio production, offering a standardized way to extend an audio workstation’s capabilities. For Audiocube, understanding how VST works and what it enables is the first step in assessing integration feasibility. The next step is to evaluate how Unity (the engine behind Audiocube) can accommodate this plugin paradigm.

3. Unity’s Audio Capabilities

Unity is well known as a game engine, but it also provides a suite of audio features for interactive applications. Understanding what Unity’s audio subsystem offers (and where it falls short for DAW use-cases) is crucial to plan VST integration. Here we outline Unity’s built-in audio strengths and limitations, especially in the context of Audiocube as a 3D DAW.

Built-in Audio Features in Unity: Unity’s audio engine is designed to handle common game sound tasks with ease. Key capabilities include:

  • Audio Playback and Import: Unity can import most standard audio file formats (WAV, MP3, OGG, etc.) and play them back via AudioSource components. Each AudioSource can play a clip (sound file) either in 2D (stereo) or 3D space.

  • 3D Spatial Sound: Unity natively supports positioning sounds in 3D. An AudioSource in the scene emits sound that is heard by an AudioListener (typically attached to the camera or player). Unity applies distance attenuation (volume fades with distance) and panning (sound comes from the correct direction) automatically. It also can simulate Doppler effect for moving sources. These features align well with Audiocube’s core idea of spatial audio.

  • Audio Effects and Mixer: Unity provides a set of built-in audio filters and effects (e.g., low-pass filters, echoes, reverbs). These can be added to AudioSources or global mixer groups to modify sound. Additionally, Unity’s Audio Mixer allows developers to route AudioSources into mixer channels, apply effects, and control volumes much like a small mixing console.

  • Microphone Input: Unity can record from system microphones and use that audio in real-time or store it. This is useful for interactive or music applications that involve live input.

  • Native Audio Plugin API: For more advanced use, Unity provides a C++ plugin SDK to create custom audio effects or generators that integrate with the Unity mixer. This allows developers to write DSP code that Unity’s audio system will call, enabling custom filters or even synths beyond the built-in offerings.

Unity’s Audio Strengths: In Audiocube’s context, Unity’s audio engine provides a strong foundation for spatial audio. It handles multiple sound sources in 3D, spatialization, and basic mixing out of the box, which Audiocube leverages to let users place sounds in space and hear them with positional cues. Unity’s engine is also cross-platform, ensuring Audiocube runs on both Windows and macOS with consistent audio behavior (and even other platforms like mobile or VR should they be needed in the future). For most game and VR applications, Unity’s audio is sufficient and conveniently integrated with the editor and scripting.

However, Unity was not originally designed as a DAW. There are important limitations and differences compared to professional audio workstations:

  • Latency and Real-Time Performance: DAWs typically prioritize low latency audio processing, often using specialized drivers (ASIO on Windows, CoreAudio on macOS) to achieve minimal delay between input, processing, and output. Unity’s audio, being tailored for games, often tolerates higher latency (to avoid CPU hiccups). By default, Unity might use a buffer size that results in ~20-30ms or more of latency, which is fine for sound effects but could feel sluggish for real-time music interaction. Unity does offer settings for “Best Latency” which reduce buffer sizes, but achieving sub-5ms latencies (common in pro audio) can be challenging. In fact, Audiocube’s developer opted to bypass Unity’s native audio pipeline and implement a custom audio engine specifically to reduce latency and add features Unity didn’t have (Show HN: Audiocube – A 3D DAW for Spatial Audio | Hacker News). This custom engine achieves very low latency (on the order of 20 samples of buffer, i.e. <0.5ms at 48kHz) as mentioned in forum discussions, far below Unity’s typical out-of-the-box performance.

  • Limited Polyphony and Voice Management: Unity historically had a default limit (around 32) on the number of simultaneous audio sources (voices) that could play reliably. While newer versions and the DSPGraph system may extend this, game audio engines often aren’t tested against scenarios with hundreds of voices that a music project might entail. A dense music session with many notes and layered instruments could push Unity’s audio beyond its intended use, requiring careful management or a custom solution.

  • Lack of MIDI and Sequencing: Unlike a DAW, Unity has no native concept of MIDI tracks, piano rolls, or sequencers for musical data. Unity can detect keyboard input or use external scripts to read MIDI devices via C# libraries, but it doesn’t inherently understand “musical time” (bars, beats, tempo) or provide tools to arrange notes. Audiocube currently focuses on audio clips and spatial positioning, not MIDI sequencing. Full VST instrument support would require adding or integrating a MIDI sequencing capability to trigger those instruments. This is a non-trivial addition, essentially implementing a core DAW feature from scratch (and was cited by Audiocube’s creator as one reason plugin support is deferred).

  • Plugin Hosting Support: Unity’s audio system does not natively load VST or Audio Unit plugins. The built-in Native Audio Plugin API is different – it allows custom DSP coded specifically for Unity, compiled as Unity-compatible libraries. This is great for writing new effects, but it’s not designed to load an arbitrary VST plugin file. As Unity’s documentation notes, bridging other plugin formats like VST into Unity requires additional work to map their interfaces to Unity’s plugin API. Unity doesn’t ship with a VST host or a generic plugin loader; any such functionality must be implemented by the developer of the Unity application or via third-party SDK.

  • Audio Engine Flexibility: Traditional DAWs often have very flexible routing – you can send audio from any track to any other, create side-chains, group buses, etc. Unity’s mixer is more rigid (structured in hierarchies defined in the editor) and might not accommodate complex, dynamic routing easily. For example, if a VST instrument plugin wants to send its audio to multiple outputs or if a side-chain input is needed for a compressor plugin, Unity’s audio might need extensions.

  • GUI and Editor Integration for Audio: In DAWs, when you load a plugin, the host will open the plugin’s custom GUI for user tweaking. Unity’s UI system is separate from its audio engine and doesn’t have a built-in mechanism to display a plugin’s GUI (which is usually written in Win32 or macOS GUI code). In Unity, any interactive audio parameter control would have to be explicitly programmed in the Unity UI (e.g., using sliders in an Editor window or game UI). As a result, hosting a VST’s own interface is challenging (we will discuss this in the technical roadblocks section). A known limitation from a Unity VST hosting experiment was that no GUI was shown – instead, all plugin parameters were exposed generically in the Unity Inspector. This is far from ideal for user experience, as it loses the custom controls and visuals that plugin designers created.

In summary, Unity provides a capable audio foundation for games and spatial sound, which Audiocube leverages for 3D positioning and basic effects. However, to transform Unity into a host for VST plugins, we run into areas that Unity doesn’t natively cover (MIDI, plugin loading, low-latency pro audio performance, plugin GUIs). Audiocube’s existing implementation already works around some Unity limitations by using a custom audio engine for spatialization (Show HN: Audiocube – A 3D DAW for Spatial Audio | Hacker News). That custom engine will likely serve as the backbone for handling the audio stream from VST plugins as well, since it’s tuned for low latency and advanced features.

The next section explores how we can integrate VST support into this Unity/Audiocube context. We will look at possible approaches – using frameworks or writing our own integration layer – to bridge the gap between VST plugins and the Unity environment.

4. Approaches to VST Integration

Integrating VST plugins into a Unity-based application like Audiocube can be approached in several ways. Broadly, the challenge is to create a VST host within the Unity application. There are both established frameworks to assist with this and more custom, low-level methods. This section examines a few key approaches:

  • Using JUCE, a popular C++ audio development framework, which now supports building Unity plugins.

  • Developing custom integration via Unity’s native audio plugin SDK or other audio libraries.

  • Utilizing third-party middleware (such as audio engines or libraries that can host VSTs).

  • Considering other frameworks or languages (e.g., VST.NET for C#) as an alternative.

Each approach will be analyzed for its capabilities and how feasible it is to implement in Audiocube, considering factors like cross-platform support, performance, and development effort.

4.1 JUCE Framework Integration

What is JUCE? JUCE (Jules’ Utility Class Extensions) is a widely-used open-source C++ framework for audio application and plugin development. It provides high-level APIs to create audio signal processing modules, handle MIDI, design plugin GUIs, and more. Many VST plugins and even some DAWs are built with JUCE. For our purposes, two features of JUCE stand out:

  • JUCE can host VST plugins using its plugin hosting classes.

  • JUCE can also build audio plugins for various formats (VST2, VST3, AU, AAX). Notably, since JUCE 5.4.0, it added support to export audio plugins as Unity native plugins.

JUCE Unity Plug-in Support: In 2018, JUCE 5.4 introduced the ability to create a Unity-compatible audio plugin. This effectively means a developer can write a plugin in JUCE and compile it as a native library that Unity’s audio engine can load (similar to how one would write a native audio effect for Unity). An article on the JUCE site highlighted this feature, indicating it’s possible to deliver high-performance audio code into Unity easily. This opens an interesting pathway: Audiocube’s team could develop a “plugin hosting plugin” using JUCE. In simpler terms, use JUCE to create a Unity native plugin whose job is to load and run VST plugins internally.

How It Might Work: The Unity native plugin created via JUCE would integrate with Unity’s audio pipeline (through the Native Audio Plugin interface). Inside that plugin’s code, we could use JUCE’s VST hosting capabilities (such as AudioPluginFormatManager and AudioPluginInstance classes) to scan for and load an actual VST instrument or effect from disk. Once loaded, the JUCE code can receive audio/MIDI from Unity, pass it through the VST, and return the output to Unity. Essentially, JUCE would act as a bridge between Unity and the VST.

For instance, one could design a JUCE-based Unity plugin that exposes a certain number of audio input/output channels and perhaps a fixed number of parameter slots to Unity. When attached to an Audio Mixer or Audio Source in Unity, it will call the underlying VST’s process function each audio block. A developer at Playful Tones demonstrated this concept: he exported a JUCE synthesizer as a Unity plugin and then wrote a C# script to send note events to it, effectively playing a synth in Unity. The article noted that Unity’s plugin API is primarily geared towards effects, and getting instruments (synths) to work required some extra native code for handling MIDI notes. They solved it by creating a small wrapper so that from Unity’s side (C#), they could call into the plugin to trigger note on/off events in the synth.

Feasibility for Audiocube: JUCE offers a high level of abstraction and a lot of the heavy lifting done already:

  • Cross-Platform: JUCE’s code is cross-platform, and it supports VST3 hosting on both Windows and macOS. This aligns with Audiocube’s needs to run on both platforms.

  • MIDI and Audio Handling: JUCE has built-in MIDI message classes, synth frameworks, and can deal with multiple audio channels. This can compensate for Unity’s lack of MIDI: e.g., JUCE can manage a virtual MIDI keyboard or sequencer internally, which Unity could feed from its UI side.

  • Development Speed: Using JUCE could significantly speed up implementation. Instead of writing a VST host from scratch, Audiocube’s developer can use JUCE’s well-tested libraries. There is an active community and many examples (JUCE even comes with a Plugin Host example application) which can be a reference for how to scan for plugins and load them.

  • UI Considerations: One challenge is the plugin’s own UI. JUCE can create UIs for plugins (it’s often used for plugin development), but in a Unity context, it might not be straightforward to show a JUCE GUI. If Audiocube were to use JUCE solely on the audio thread and expose parameters to Unity, it might forego the plugin’s custom GUI and instead rely on Unity’s interface. Alternatively, Audiocube could use JUCE to create its own GUI for controlling the plugin parameters (for instance, generating sliders dynamically for each parameter, similar to how UnityVSTHost populated the Inspector). A hybrid approach could also be considered: have Audiocube pop out a separate window for the plugin UI using JUCE’s windowing, though integrating that with Unity’s game window might be complex.

In summary, JUCE appears to be a promising route for VST integration:

  • It’s feasible (others have done Unity plugin hosting with JUCE).

  • It abstracts away low-level details of VST handling.

  • It ensures high-performance DSP code (C++ level, avoiding C# for processing).

  • It comes with the baggage of adding a C++ codebase to the project, which means compiling and maintaining platform-specific binaries, and possibly needing a JUCE commercial license (if Audiocube is closed-source, JUCE GPL might not be suitable).

4.2 Native Unity Audio Plugin or Custom DSP Engine

Another approach is to build the VST support with Unity’s native audio plugin API or a custom audio engine, essentially “from the ground up” without a high-level framework like JUCE. This could mean writing C++ code that directly uses Steinberg’s VST SDK (especially the VST3 SDK) to load plugins and integrate with Unity’s audio callback system.

Unity Native Audio Plugin SDK: Unity allows developers to write native audio plugins in C/C++ that implement certain callback functions (create, process, release, etc.) and compile into a DLL (Windows) or bundle (macOS) which Unity loads at runtime. These callbacks include UnityAudioEffect_ProcessCallback, which Unity calls to process a block of audio through the plugin. Typically, one would hardcode the DSP effect in such a plugin. But Unity’s docs hint that it’s possible to create “bridge plugins” that map external plugin formats like VST or AudioUnits into Unity’s interface. The idea is that the Unity plugin could dynamically load a VST plugin (using VST SDK calls) and simply forward Unity’s audio buffers to that plugin’s processing function.

To implement this:

  • The plugin’s CreateCallback could open a specified .vst3 file using the Steinberg API, instantiate the plugin class, and initialize it.

  • The ProcessCallback would call the loaded plugin’s process() method, feeding it the inbuffer and outbuffer that Unity supplies.

  • Parameter setting functions in the Unity plugin would be mapped to setting the VST’s parameters.

  • This approach essentially results in a generic VST-hosting Unity plugin. It’s similar to the JUCE approach but done manually.

Challenges of Custom Approach: Writing this from scratch is non-trivial. Some considerations:

  • Using VST SDK: Steinberg’s VST3 SDK is C++ and quite complex for hosting. It involves component and controller classes, threading considerations, etc. A developer would need to have good knowledge of the SDK to integrate it reliably. Alternatively, one could try to embed an existing simple host code (like JUCE’s modules or something like VSTSDK’s validator host example).

  • GUI: As with JUCE, a custom solution would have to forego the plugin’s native GUI or implement a way to show it (which might involve platform-specific window handling outside of Unity’s control).

  • MIDI: Unity’s plugin API by default deals with audio buffers. To feed MIDI to an instrument, the Unity plugin might need a custom entry point. For example, the plugin could expose a function via DllImport that Unity C# calls when a note needs to be played. The UnityVSTHost project on GitHub followed a pattern where they used Unity’s OnAudioFilterRead to push audio through the plugin and separate calls to send parameter changes, albeit they did not handle MIDI input at the time.

  • Platform differences: The plugin would need conditional code for Windows vs Mac (loading .dll vs .vst3, dealing with OS-specific aspects of the VST GUI if attempted, etc.). Steinberg’s SDK supports both, but testing on both is required.

  • Stability: Writing a host means dealing with potentially buggy third-party plugins. A poorly written plugin could crash the Unity application if not isolated. Some DAWs implement plugin sandboxing (running plugins out-of-process to prevent crashes from bringing down the whole app). Implementing such protection in Audiocube is beyond initial scope, but it's worth noting that a custom host runs plugins in-process, so careful handling is needed (for example, catching exceptions in the native plugin if possible, or at least documenting that only stable plugins should be used to avoid crashes).

Custom DSP Engine (Outside Unity’s Mixer): It’s worth mentioning that Audiocube’s developer already built a custom “spatializer and acoustic engine” that bypasses Unity’s built-in audio simulation (Show HN: Audiocube – A 3D DAW for Spatial Audio | Hacker News). This implies Audiocube might be running an audio thread of its own (using, say, the C# Job System with DSPGraph, or native code) to handle things like reflections and occlusion. It’s conceivable to integrate VST hosting into that same engine rather than Unity’s mixer. For example, the app could open an audio stream (via an API like PortAudio, RtAudio, or Unity’s lower-level audio interface) and manage audio processing timeline itself. The VST would then be just another element in the processing chain of that engine. The final output would still go to Unity’s sound output or an external audio device. This approach gives maximum flexibility (we’re not constrained by Unity’s audio pipeline at all), but it also means essentially treating Audiocube like a self-contained audio application that just happens to use Unity for visuals/interaction.

Pros of a fully custom engine approach:

  • Can achieve extremely low latency (tuning audio thread priorities, using ASIO on Windows, etc.).

  • Total control over audio routing, scheduling, etc., similar to writing a mini-DAW engine.

  • No need to fit into Unity’s plugin interface quirks (like fixed parameter definitions or stereo-only channels, etc.).

Cons:

  • Reinventing a lot of wheels: would need to manage audio drivers, buffer callbacks, etc. Unity’s audio output can be bypassed but then how to combine with any Unity-based audio is a question. Maybe Audiocube already outputs directly to the OS audio rather than Unity AudioSource – unclear from outside.

  • Much more development and maintenance effort – effectively building a host from scratch or integrating with an existing audio backend like JACK or ASIO.

  • Might complicate deployment (drivers, or requiring users to select audio devices, which game devs normally don’t do).

Given these, a balanced approach might be: use Unity’s plugin system (or the existing custom engine) but leverage a library or framework to handle the VST part, which leads us back to frameworks like JUCE or others rather than fully manual coding.

4.3 Alternative Frameworks and Middleware

Beyond JUCE, there are other tools and libraries that could assist with VST integration:

  • VST.NET (for C#): VST.NET is an open-source project that wraps the VST2 API for .NET languages. It allows developers to both create VST plugins in C# and host VST plugins using C#. One could theoretically use VST.NET inside Unity (which uses C#) to load a VST and process audio. There is a Stack Overflow discussion where a developer attempted this in Unity. The main hurdle was Unity’s environment not playing nicely with the unmanaged interop DLL required by VST.NET. The consensus was that it’s tricky to get working, and indeed the official VST.NET documentation emphasizes Windows-only and no comprehensive hosting framework provided. VST.NET might work for a Windows-only solution, but Audiocube also supports macOS, and VST.NET does not host VST3 or Audio Units. Therefore, while VST.NET demonstrates the concept of hosting via C#, it’s likely not the best route for Audiocube due to limited platform support and the fact that it targets the deprecated VST2 standard.

  • Audio Middleware (FMOD, Wwise): These are professional audio engines used in game development. FMOD Studio and Audiokinetic Wwise allow integration of complex audio logic into Unity (replacing or augmenting Unity’s audio). They are not designed as music production tools, but FMOD does have a feature where it can load certain VST plugins as effects in its system. For example, FMOD’s API System::loadPlugin can load a VST2 effect by path, making it available as a DSP effect in the game’s audio chain. This is primarily meant for applying third-party effects (like a special EQ or reverb) in a game. However, FMOD does not serve as a VST instrument host, and integrating it would mean incorporating another layer (the user would design audio events in FMOD Studio tool, etc., which is likely too cumbersome and not in line with Audiocube’s real-time creative workflow). Wwise, on the other hand, uses its own plugin format and does not host VSTs directly. Given these, audio middleware might not be a suitable solution for broad VST support, though if Audiocube wanted just to allow a specific VST effect globally (like a particular spatializer), FMOD could handle that. But generally, this path adds complexity and licensing (FMOD/Wwise have their own license models) and would divert from Audiocube’s integrated environment.

  • Custom DSP Libraries: Instead of hosting actual third-party plugins, an alternate approach is to re-implement or include specific DSP algorithms that are needed. For instance, if the goal is to get a certain type of effect, one could code it directly or use libraries like DSPFilters, etc. However, this doesn’t truly address “VST integration” – it just extends Audiocube’s native capabilities. The advantage of true VST support is giving users access to all their existing plugins, not just a predetermined set of effects. So while Audiocube could expand its internal effects, that’s not a substitute for general plugin hosting.

  • Other Plugin Formats: It’s worth mentioning Audio Unit (AU) plugins on macOS and AAX plugins for Pro Tools. If Audiocube aims to support external plugins on macOS, using AUs is an option since those are native to that platform. However, modern macOS DAWs (except Logic which uses AU exclusively) support VST3 as well, and many plugin developers ship both VST3 and AU. A possible approach is to adopt a cross-format host (some hosts use wrappers that can load both VST and AU). JUCE, for example, can host both VST and AU if needed. But to keep scope manageable, focusing on VST3 ensures a single consistent interface across Win/Mac. If needed, later expansions could add AU support for any AU-only plugins. AAX is proprietary to Pro Tools and not relevant outside that ecosystem, so it’s not in consideration for Audiocube.

  • Emerging Standards (CLAP): Recently, a new open-source plugin standard called CLAP (CLever Audio Plugin) has been introduced by developers of Bitwig Studio and others. It’s designed to be more open and flexible than VST3. While promising, CLAP is still new and not widely adopted yet by third-party plugins compared to VST. Audiocube might keep an eye on it for future, but initially VST remains the priority due to sheer number of available plugins.

Comparison of Approaches:
To weigh these options, consider the following criteria:

  • Development Effort: JUCE provides a lot out-of-the-box, whereas a custom solution (native plugin or custom engine) requires substantial low-level coding. VST.NET is easier in C# but limited. Middleware integration is heavy and not tailored for this use-case.

  • Performance: C++ based solutions (JUCE or custom) will operate at native speed and can use real-time threads effectively. A pure C# approach might face garbage collection or threading issues for real-time audio (unless carefully handled). Unity’s Burst compiler and DSPGraph could be another angle if writing a host in C#, but that’s an unexplored territory for VST loading.

  • Cross-Platform: JUCE and custom C++ with VST3 SDK can be cross-platform. VST.NET fails here (Win only). Middleware are cross-platform but add external dependencies.

  • Community & Support: JUCE is backed by a community of audio developers, with documentation and forums (and examples like the Playful Tones blog). Rolling a custom host means debugging obscure VST compatibility issues largely alone, unless leveraging open-source projects for reference. For example, one could look at open-source DAWs or hosts (like Jeskola Buzz, Carla, etc.) for inspiration if doing it from scratch.

  • Licensing: Steinberg’s VST3 SDK is free to use but requires agreeing to their license. JUCE is open-source (GPLv3) or commercial license; Audiocube likely would need a commercial JUCE license to avoid disclosing source. This is a cost to factor in. If Audiocube sells well, that cost may be justified by faster development. Middleware like FMOD has its own licensing (free up to certain limit, then paid). VST.NET is LGPL which is okay to use but again only VST2.

Considering all, the JUCE approach stands out as a balanced solution that provides cross-platform plugin hosting with relatively lower development effort and high performance. The main downsides are managing the C++ integration within a Unity project and handling the plugin GUI (which is a common challenge across all approaches).

In the next section, we delve deeper into the technical feasibility and roadblocks of implementing VST support, assuming we choose an approach like JUCE or a custom integration. We will highlight specific challenges (like GUI, MIDI timing, performance, etc.) and discuss how to overcome them.

5. Technical Feasibility & Roadblocks

Implementing VST integration in Audiocube presents several technical challenges. In this section, we identify the key roadblocks and discuss potential solutions or workarounds for each. These cover both high-level feasibility concerns and low-level implementation details:

5.1 Performance and Latency

Challenge: Achieving stable, low-latency audio processing with VSTs in Unity. VST plugins are real-time DSP components; they need to receive and output audio buffers on a strict timing schedule (e.g., every 2-3 ms for a 128-sample buffer at 48 kHz). If the host (Audiocube) fails to deliver buffers in time (due to frame drops or CPU spikes), audible glitches (clicks, pops) or dropouts occur. Unity’s typical frame loop and garbage-collected environment can be at odds with the strict timing of audio threads.

Potential Solutions:

  • Dedicated Audio Thread: Ensure that VST processing occurs on a dedicated high-priority audio thread, not the main Unity thread. Unity’s native audio plugin mechanism already runs plugins on the audio thread provided by Unity’s engine (which can be separate from the game thread). If Audiocube’s custom engine is used, it should spawn a real-time thread (using Thread.Priority = Highest in C#, or better, using native thread with real-time scheduling if possible). The VST processing should happen there, minimizing interaction with Unity’s update loop except for parameter changes.

  • Buffer Size Management: Allow the user (or internally configure) to choose a suitable buffer size for VST processing. For instance, a buffer of 256 samples might be a compromise that yields ~5.3 ms latency at 48 kHz, which is decent. For more responsive playability (for live MIDI input), 128 or 64 samples might be used, though CPU usage rises as buffer size drops. Audiocube can provide settings for “Audio Latency” similar to how DAWs offer buffer settings.

  • Optimized DSP and DSPGraph: Unity’s new DSPGraph (an evolution using the C# Job System) could potentially be leveraged to schedule audio tasks across multiple CPU cores. If Audiocube’s custom engine uses DSPGraph, VST integration would mean creating a DSP node that calls into the VST. The Job System approach can improve performance by parallelizing audio tasks, but integrating an external API call (VST processing) might limit that parallelism (most VSTs aren’t thread-safe for simultaneous calls; they expect sequential buffer processing).

  • Profiling and Limits: It may be prudent to limit how many VST plugins a user can load initially, or at least give guidelines. For example, running 10 heavy synthesizers in a dense 3D scene with physics might tax the CPU. Audiocube could monitor audio CPU usage and provide warnings if the load is too high, to maintain real-time performance.

  • Bypassing Unity Overhead: If Unity’s own audio update imposes overhead, the custom engine might interface directly with audio drivers (ASIO/CoreAudio). This is a complex route but could yield the lowest latency. It means Audiocube handles output to the sound device itself. Considering the developer already wrote a custom spatializer, he might have some infrastructure for this. However, it complicates Unity build (would need native plugins for driver handling). A hybrid approach might be: use Unity’s audio out but keep buffers short and optimize within.

Audiocube’s developer managed to get extremely low latency by custom means, which suggests the feasibility is there. The main overhead comes from adding VST plugin processing, but modern CPUs can handle a number of plugins, and many VSTs have internal optimizations (idle processing, etc.).

5.2 MIDI and Sequencing

Challenge: Feeding MIDI notes and automation data to VST instruments within Audiocube. As discussed, Unity has no concept of MIDI timeline or piano roll.

Potential Solutions:

  • MIDI Input Device Support: Implement or integrate a MIDI device reader in Audiocube. This could be done via existing C# MIDI libraries or platform APIs. On Windows, the WinMM API or Microsoft’s MIDI API can be called via C# to get MIDI messages from connected keyboards; on macOS, CoreMIDI can be accessed. There are Unity plugins and C# packages (like DryWetMIDI or Sanford Midi library) that could help. This would allow a user to play notes on a MIDI keyboard and Audiocube to send those to a VST instrument in real time, turning Audiocube into an instrument host for live performance.

  • Sequencer/Timeline: For programmed MIDI (not just live input), Audiocube will need a UI for sequencing notes. This is arguably as large a project as the VST integration itself (it means making a piano roll editor, tempo management, etc.). A minimal approach might be to allow users to import a MIDI file or record live MIDI into a simple sequence, then loop or play it. Alternatively, Audiocube could expose its audio output as a sync-able source to another DAW (for instance, via ReWire or a virtual audio cable) and let the user use that DAW for MIDI sequencing. But a more integrated approach is likely desired eventually. Perhaps in the first iteration, focus on live MIDI input and basic triggering (which is simpler), then expand to a full sequencer in the future.

  • Mapping Unity Events to MIDI: If building a timeline is not immediate, Audiocube might use its existing logic blocks or visual scripting (if any) to trigger sounds. For example, an object collision in the scene could trigger a MIDI note on a loaded VST instrument, purely within the 3D logic context. This would use Audiocube’s strengths (3D interactions) to generate music in a more procedural way. It’s a creative angle different from a piano roll but could still showcase instrument plugins.

  • MIDI Timing: Ensuring MIDI notes align properly with audio processing buffer boundaries is important. If a user plays a note, the command should be enqueued and delivered to the VST at the start of the next buffer to avoid timing jitter. JUCE’s Unity plugin approach did this by letting the Unity C# side call into the plugin’s note-on function at the right moment. In a custom integration, we might maintain a thread-safe queue of MIDI events that the audio thread checks each block.

5.3 Plugin User Interface (GUI)

Challenge: Displaying and interacting with the VST plugin’s own GUI within Audiocube. VST GUIs are traditionally implemented in native UI frameworks (Win32/GDI or WPF on Windows, Cocoa on Mac). Unity’s rendering is separate (DirectX/OpenGL/Vulkan context for the game). Embedding one into the other is extremely challenging.

Potential Solutions:

  • Generic Parameter UI in Unity: Easiest to implement, though not as user-friendly, is to present the plugin’s parameters using Unity’s own UI system. The VST standard allows the host to query a list of parameters (each with an ID, name, default value, range, etc.). Audiocube could retrieve all parameters from the plugin and auto-create sliders, knobs, or numeric fields in its interface for each. This is what the UnityVSTHost example did: it simply listed all parameters in the Unity Inspector for the user to tweak. Audiocube can make this more user-friendly by grouping parameters (if the plugin provides grouping information, VST3 supports categories for parameters), maybe showing a few key ones by default and advanced on demand. The benefit is that this works uniformly for all plugins and fits in Audiocube’s style. The downside is it ignores the custom GUI design of the plugin, which often includes visual feedback, custom controls, or even unique workflows (for example, a synthesizer might have an on-screen piano or a modulation matrix that doesn’t translate to a simple list of knobs).

  • External Window for Plugin GUI: Another approach is to open the plugin’s editor in a separate window outside of the Unity game view. Many plugin hosts (even DAWs) open plugins as independent windows (in Windows, these would be additional top-level windows owned by the application process). If using JUCE or the VST SDK directly, one can call editor->open() on the plugin, which typically returns a platform-specific window handle or uses one provided. Unity itself might not manage this window, but the OS will display it. The user would then adjust the plugin UI in that window. The host (Audiocube) continues running and processing audio in the background. This approach preserves the full plugin GUI, but it introduces complexity:

    • Need to manage window lifetime and threading. VST GUIs often assume they run on the main thread of the application. Unity’s main thread is busy with the game; perhaps one can schedule calls to plugin GUI on it, or have to risk running on another thread (which some plugins won’t like).

    • The GUI window will float above the Unity application. In a standalone build, this might be okay (Audiocube could be a desktop app that spawns sub-windows). In a game or fullscreen scenario, it’s not ideal. But Audiocube as a creative tool could allow windowed mode usage.

    • Cross-platform differences: On Mac, you’d be dealing with NSView/NSWindow for AU/VST3, on Windows an HWND for the editor. JUCE can abstract some of this if it hosts the plugin GUI in a JUCE window.

  • Render Plugin GUI to Texture: An experimental idea is to render the plugin’s interface into a Unity texture. This would involve capturing the plugin GUI drawing commands or its window surface and transferring it to Unity. There have been attempts at this in other contexts, but it’s complicated. It might involve off-screen rendering techniques or remote desktop-like capture of the GUI. Given the time and complexity, this is likely not feasible for a first implementation, but in future it could be a flashy feature (imagine seeing the synth’s knob movements on a panel within the 3D world). This would require deep OS-specific hacking or cooperation from the plugin (which is generally not present, as plugins expect a normal window).

  • Hybrid approach: Initially, Audiocube might implement the simple route (generic UI controls) to ensure functionality, and later add the ability to launch the plugin’s own GUI if the user needs fine control or visualization. Documentation could state that “basic plugin parameters can be controlled in-app; for advanced editing, open the plugin UI in an external window.” This at least gives an option. Some plugin hosts (like certain live performance hosts) do exactly this: provide a generic UI but allow popping open the real GUI if needed.

5.4 Plugin Discovery and Management

Challenge: Finding and loading the plugin files on the user’s system. DAWs typically let users configure plugin directories or use standard locations.

Potential Solutions:

  • Standard Paths: On Windows, VST2 plugins are often in C:\Program Files\Steinberg\VSTPlugins\ or user-specified paths, and VST3 plugins are in %PROGRAMFILES%\Common Files\VST3\. On macOS, VST2s go in /Library/Audio/Plug-Ins/VST/ and VST3 in /Library/Audio/Plug-Ins/VST3/ (plus user library equivalents). Audiocube could by default scan these standard directories for plugins. Scanning means searching for files with .dll (for VST2) or .vst3 extension and perhaps verifying they are valid plugins (attempting to load them in a safe way or using a known plugin list).

  • User Configuration: Provide a settings panel where users can add additional directories to scan (much like any DAW’s plugin manager). This ensures if someone installs plugins in a custom folder, Audiocube can find them.

  • Plugin List and Cache: Scanning every startup can be slow if dozens of plugins are installed. Audiocube can implement a caching mechanism: scan once (or on demand), store the list of found plugins (name, type, path, maybe unique ID). On next run, use the cache unless the user triggers a rescan (e.g., after installing new plugins).

  • Validating Plugins: When loading a plugin for the first time, it might be wise to do it in a sandbox or at least catch errors. A crash during scan can be frustrating (some DAWs have “bad plugin lists” to skip known problematic ones). For stability, Audiocube could attempt to load each plugin in a separate process to test if it initializes without crashing, then proceed. This is advanced; a simpler approach is to try/catch around plugin loading (in native C++, a try/catch might not catch a segfault though). It might rely on user to manage their plugins (in a professional environment, users generally know which plugins are stable).

  • 32-bit vs 64-bit: Ensure Audiocube only tries to load plugins matching its own architecture. Unity builds are 64-bit, so 32-bit VST plugins will not load in-process. Many modern plugins are 64-bit only now, but if a user has older 32-bit only plugins, Audiocube should either ignore them or warn that those aren’t supported. Some hosts use “bridges” to run 32-bit plugins in 64-bit hosts via separate process (JBridge, etc.), but that’s likely beyond our scope initially.

5.5 Cross-Platform Differences

Challenge: Handling differences between Windows and macOS plugin systems.

Solutions/Considerations:

  • As discussed, prefer VST3 which is uniform across platforms. On macOS, some popular plugins might be AU only (like Apple’s own units or some older products), but most provide VST as well. If needed, on macOS the integration layer can check for AU in absence of VST. JUCE would automatically handle AUs if told to scan them.

  • File paths and extensions differ, so maintain separate configurations and scanning logic for each OS.

  • Testing on both platforms is essential as there are subtle differences (threading, graphics, file permissions for scanning plugin folders, etc.).

  • Apple Silicon (ARM64) vs Intel: Ensure any native integration (JUCE or custom) compiles for both architectures. Many plugins now ship as Universal Binary on macOS (containing both Intel and ARM code). Steinberg’s VST3 SDK supports ARM compilation. Unity can build Universal or separate builds for Mac. This should be planned so that Audiocube on Apple Silicon can load ARM VSTs; if only x64 is supported, users would run in Rosetta mode which is not ideal.

  • For Windows, just 64-bit (x86-64) is the target.

5.6 Licensing and Legal

Challenge: The legal aspects of using VST technology.

Considerations:

  • Steinberg’s VST3 SDK is free to use but requires the developer to agree to the license agreement. Audiocube’s developer would need to download the SDK from Steinberg and likely register as a VST developer (which is a standard process).

  • If including JUCE: JUCE’s license must be accounted for. The GPL option would force Audiocube’s source to be open, which likely isn’t desired for a commercial product. The alternative is a paid JUCE license (which can be a few thousand dollars for a company license, allowing closed-source usage).

  • If any part of integration uses other libraries (e.g., VST.NET or FMOD), their licenses must be compatible. VST.NET is LGPL – linking that into Unity (which is closed source) might be problematic unless used as a separate DLL.

  • On the user side, loading VSTs assumes the user has properly licensed those plugins. Audiocube as a host is not responsible for plugin licenses (just like Ableton isn’t responsible for ensuring you bought Massive – the plugin itself will enforce its copy protection). So that side is straightforward: Audiocube just loads whatever is installed, and if a plugin requires authorization, it will usually show its authorization GUI to the user (which we need to support GUI for that to happen, or handle headlessly if possible). In any case, that's similar to any host environment.

5.7 Scope Management

Challenge: Avoiding feature creep and maintaining Audiocube’s core identity while adding VST support.

Considerations:
Audiocube’s strength is its 3D spatial audio paradigm and intuitive visual environment, not necessarily to become a full conventional DAW. The developer has expressed focusing on that unique aspect instead of re-implementing every DAW feature. Therefore, when integrating VST, it should be done in a way that complements the 3D workflow rather than turning Audiocube into a clone of existing DAWs. For example:

  • Perhaps limit the number of instrument plugins or encourage using Audiocube as a “spatial effect rack” where you send sounds from other DAWs into it, process in 3D, and send back (that audio bridge concept). This is slightly different – it implies Audiocube itself could be a VST plugin to other DAWs, but that’s another side of integration that could be tackled later (making Audiocube a VST or ReWire device).

  • Ensure that user interface doesn’t become cluttered: maybe have a dedicated “Plugin Rack” panel in Audiocube for managing VSTs, separate from the main 3D view. Users who don’t care about VSTs can ignore it and just use built-in features.

  • Performance-wise, if Audiocube projects become heavy with VST usage, provide ways to freeze or bounce tracks (render VST instrument output to an audio clip in Audiocube, then disable the plugin to save CPU). This is a common DAW feature to manage load. It might not be implemented in first version, but planning for it is wise.

Feasibility Verdict: Despite the challenges listed, none are insurmountable. Many existing applications prove that hosting VSTs in various environments is possible – from traditional DAWs to lighter hosts and even game engines in research projects. Unity, while not built for this, can accommodate it with the approaches discussed (especially leveraging C++ plugins). The biggest lifts are development effort and ensuring stability across the unpredictable variety of plugins.

Having covered the potential roadblocks and mitigation strategies, we can now outline how to actually implement VST integration in Audiocube in a step-by-step manner, bringing together the chosen approaches and solving the challenges as we go.

6. Implementation Process

Integrating VST support in Audiocube will involve coordinated development across the audio engine, user interface, and system integration. Below is a conceptual implementation plan that Audiocube’s development team could follow, broken into stages. This plan assumes we take advantage of the JUCE framework for the core VST hosting functionality, combined with Unity’s plugin system for integration. (Even if JUCE is not used, the overall steps would be similar, but more low-level coding would be needed.)

6.1 Plugin Hosting Engine Setup

a. Include VST Hosting Framework: Begin by setting up the environment to use JUCE (or an alternative) in the Unity project. This likely means creating a C++ project (a DLL for Windows, a bundle for Mac) that uses JUCE’s AudioPlugin module. For example, create a JUCE project named AudioCubeVSTHost. Configure it to build as a “Unity plug-in”. This will ensure the produced plugin implements Unity’s required entry points so it can be loaded into the Unity audio pipeline.

b. Initialize VST SDK: Within this plugin code, initialize the VST plugin hosting system. In JUCE, this would involve creating an AudioPluginFormatManager and adding VST3PluginFormat (and possibly VSTPluginFormat for VST2 if needed) to it. Then call its scanPaths or similar function to scan known plugin directories. Alternatively, scanning can be triggered from the C# side, passing directory paths into the plugin.

c. Manage Loaded Plugin Instances: Design the plugin such that it can load a specific VST when instructed. One approach is to allow only one VST to be loaded per plugin instance (so if the user wants two VSTs simultaneously, Unity would instantiate two instances of our host plugin). The Unity audio plugin API could allow multiple instances. Thus, our plugin needs a way to differentiate which VST to load. A simple plan: after adding the plugin component in Audiocube, the user selects a VST by name, then the C# script calls a function like LoadPlugin("PluginName") into the native plugin. The plugin then uses the earlier format manager to create an AudioPluginInstance. This instance is stored.

d. Audio Processing Callback: Implement the Unity audio processing callback to route audio through the VST. If the VST is an effect, Unity will be feeding audio into our plugin – simply pass that into the plugin instance’s process block. If the VST is an instrument, Unity’s input buffer might be silent (no input); in that case the plugin instance still needs to be run to produce sound. We fill Unity’s outbuffer with the plugin’s output each callback. For example pseudocode in C++:

AudioPluginInstance* pluginInstance = nullptr;  // our loaded VST


UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK ProcessCallback(UnityAudioEffectState* state, float* inbuffer, float* outbuffer,

                                                              unsigned int length, int inchannels, int outchannels) {

    if(pluginInstance == nullptr) {

        // No plugin loaded, just bypass

        if(outbuffer != inbuffer) {

            memcpy(outbuffer, inbuffer, length * outchannels * sizeof(float));

        }

        return UNITY_AUDIODSP_OK;

    }

    pluginInstance->processBlock( AudioBuffer<float>(inbuffer, inchannels, length),

                                  AudioBuffer<float>(outbuffer, outchannels, length) );

    return UNITY_AUDIODSP_OK;

}


This assumes the plugin instance has been prepared with the correct channel layout. VST instruments might ignore input buffer and only use outbuffer. The code must handle differences in channel count (some VSTs might be stereo only, etc., we may need to configure Unity to use stereo channels for the plugin or handle mono to stereo conversions). The above pseudocode calls a JUCE-like processBlock with input and output audio buffers.

e. MIDI and Event Handling: The plugin instance also needs to receive MIDI notes. We won’t get those from Unity’s audio callback (Unity doesn’t know about MIDI), so we need a mechanism to send MIDI to the plugin. We can implement additional native entry points in our plugin DLL using extern "C" functions that Unity can call from C#. For example:

extern "C" {

    UNITY_AUDIODSP_EXPORT void SendMidiNoteOn(int note, int velocity) {

        if(pluginInstance != nullptr) {

            // create a MIDI message (using JUCE's MidiMessage or VST3 API directly)

            MidiMessage m = MidiMessage::noteOn(1, note, (uint8)velocity);

            midiBuffer.addEvent(m, 0); // add to a MidiBuffer for next block

        }

    }

}


We maintain a MidiBuffer midiBuffer; that the ProcessCallback will consume each time before calling processBlock. This way, when C# triggers a note, it’s queued and will be sent on the upcoming audio processing call. Similarly, we might have SendMidiNoteOff, and possibly SetParameter(int index, float value) extern functions to allow automation or UI to tweak plugin parameters from Unity side.

f. Parameter Management: To allow Unity to get/set plugin parameters (for automation or UI display), we can expose functions to enumerate parameters and to change them. For example: GetParameterCount(), GetParameterInfo(index), SetParameterValue(index, value). Using the VST3 API or JUCE’s wrapper, we can implement these to query plugin’s parameter list. Unity could call these and then present UI accordingly.

g. Memory and Thread Safety: Ensure that shared data (like the MIDI buffer or plugin pointer) is handled safely between Unity’s main thread (making LoadPlugin or SendMidi calls) and the audio thread (ProcessCallback). Simple locking or using atomic operations around these will be necessary to avoid race conditions (e.g., if a note is sent while process is reading the buffer). Ideally, double buffering of MIDI events per block or lock-free FIFOs can be used to minimize any wait in the audio thread.

6.2 Unity Integration and UI Development

a. Unity Plugin Import: After building the native plugin, include it in the Unity project under Assets/Plugins (with appropriate subfolders for platforms if needed). Unity should recognize it as an audio plugin, and it can then be added to the Audio Mixer or an AudioSource. Alternatively, we might design it to work on an AudioSource via the AudioFilter mechanism. (Unity allows adding a script with OnAudioFilterRead to route audio, but using the native plugin directly is cleaner and more efficient.)

b. Audiocube UI – Plugin Manager: Create a user interface within Audiocube for managing VST plugins. This likely includes:

  • A Plugin Browser window or panel, listing available plugins (scanned from the system as done in 6.1b). This list can be categorized by instruments vs effects, possibly with a search function. Each entry might show the plugin name and maybe the vendor or type.

  • A Load/Insert mechanism: In a traditional DAW, to use a plugin you either create an instrument track or insert an effect on an existing track. In Audiocube’s spatial paradigm, a similar concept can apply:

    • To use a VST instrument, the user could create a new “Virtual Instrument Object” in the scene. This object doesn’t have an audio clip, instead it houses a plugin that generates sound. The position of this object in 3D space would position the instrument’s output in the virtual environment. (Imagine a virtual synthesizer placed in the 3D room.)

    • To use a VST effect, perhaps allow adding it to an Audio Source or to the master output. For example, an imported sound in Audiocube could have an effects chain which now supports adding VST effects in addition to built-in ones. The UI could present a “+ Add Effect” menu that includes VSTs.

  • If using Unity’s Audio Mixer, we could also attach the plugin at the mixer group level (e.g., a reverb plugin on a send bus). But Audiocube’s current architecture might not expose the mixer directly to users, so integrating at the object level might be more straightforward.

c. Plugin UI (in Unity): Develop the interface to control plugin parameters:

  • When a user selects an object that has a plugin, show a panel with the plugin’s name and a list of its parameters (slider for each, possibly grouped in collapsible sections).

  • Allow user to adjust these sliders; on change, call the SetParameterValue in the native plugin. Also, ideally reflect any changes from the plugin side (some plugins have internal modulators that change parameters, or presets that set multiple params). Polling plugin parameters every few frames could catch those updates, or require user to refresh UI after loading a preset.

  • Provide an “Open GUI” button if we implement external window display. Clicking it would call an exported function like OpenEditor() in the native plugin, which triggers the plugin’s own GUI to open. The user can then interact and close it when done.

  • If it’s an instrument plugin, also show controls for MIDI input: maybe an on-screen keyboard to test sounds, and a record button to capture MIDI from a device.

  • If Audiocube has a timeline or intends to add one: incorporate the instrument in the timeline so it can sequence notes like an audio clip but for MIDI.

d. Preset Management: (Optional for first version) Many plugins have presets. It might be complex to integrate fully, but at least exposing the ability to load a preset file or select next/prev if the plugin supports a program list can be nice. JUCE’s hosting can often load .vstpreset or the plugin’s internal programs.

e. Testing with Real Plugins: It’s crucial to test the implementation with a variety of VSTs:

  • A simple free synthesizer (like Surge XT or Dexed) to verify instrument hosting and MIDI.

  • A sampler or drum machine (to test polyphony, multi-out maybe).

  • A simple effect (like the MDA plugins or Voxengo SPAN analyzer) to test effect routing.

  • A heavy plugin (like Omnisphere or Kontakt if available) to test performance and memory.

  • Both VST2 and VST3 versions if possible (depending on what we choose to support).

  • Test unusual cases: plugins with multi-channel IO, plugins that spawn their own windows (like iZotope’s authorizer, etc.), plugins that have large GUIs.

f. UI/UX Considerations: The user experience should be as seamless as possible:

  • Feedback: If a plugin fails to load or crashes, catch that and inform the user (e.g., “Plugin XYZ failed to load. It may not be supported.”). Don’t just fail silently.

  • Multiple Instances: Show in the UI which objects or slots have which plugin. Possibly provide a central “Plugin Manager” that lists all currently loaded plugins in the project, with ability to disable or remove them.

  • Saving/Loading Projects: Ensure that when an Audiocube project is saved, it stores enough information to recall the plugin state. This means saving the plugin’s name/ID, its parameter values, and perhaps its internal preset state. VST plugins allow the host to get a binary “state” (often called a plugin chunk) representing all its settings. Audiocube should capture this (via a call like getStateInformation in VST) and serialize it into the project file. On loading a project, Audiocube should instantiate the same plugin and give it that state to restore the user’s sound exactly (this is analogous to how DAWs remember your plugin settings in sessions).

  • Resource Management: Provide a way to unload a plugin instance when not needed (e.g., removing an effect should free it from memory). And potentially flush/reset the audio engine if needed when making big changes (some hosts stop audio processing when adding/removing plugins to avoid glitches).

6.3 Pseudocode Example for Unity–Plugin Interaction

To illustrate the interaction between Unity’s C# side and the native plugin host, consider a simplified pseudocode scenario where we load a VST instrument and play a note:

C# side (Unity):

public class VSTInstrumentPlayer : MonoBehaviour {

    [DllImport("AudioCubeVSTHost")]

    private static extern bool LoadPlugin([MarshalAs(UnmanagedType.LPWStr)] string pluginName);

    [DllImport("AudioCubeVSTHost")]

    private static extern void SendMidiNoteOn(byte note, byte velocity);

    [DllImport("AudioCubeVSTHost")]

    private static extern void SendMidiNoteOff(byte note);

    [DllImport("AudioCubeVSTHost")]

    private static extern float GetParameterValue(int index);

    [DllImport("AudioCubeVSTHost")]

    private static extern void SetParameterValue(int index, float value);

    

    void Start() {

        // Load the plugin by name (must match something the native side recognizes)

        bool success = LoadPlugin("Virtual Analog Synth");

        if(!success) {

            Debug.LogError("Failed to load plugin.");

        }

    }

    void Update() {

        // Example: play a middle C note when space key is pressed

        if(Input.GetKeyDown(KeyCode.Space)) {

            SendMidiNoteOn(60, 127); // note number 60 (C4), max velocity

        }

        if(Input.GetKeyUp(KeyCode.Space)) {

            SendMidiNoteOff(60);

        }

    }

    // Additional code for UI sliders that call SetParameterValue(index, newValue) on change.

}


C++ side (inside AudioCubeVSTHost plugin):

AudioPluginInstance* pluginInstance = nullptr;

MidiBuffer incomingMidi;


extern "C" bool UNITY_AUDIODSP_CALLBACK LoadPlugin(const wchar_t* pluginName) {

    // Find plugin by name from scanned list (for simplicity, assume name->file mapping known)

    File pluginFile = findPluginFileByName(pluginName);

    if(pluginFile.exists()) {

        pluginInstance = formatManager.createPluginInstance(pluginFile);

        if(pluginInstance) {

            pluginInstance->prepareToPlay(sampleRate, blockSize); // initialize

            return true;

        }

    }

    return false;

}


extern "C" void UNITY_AUDIODSP_CALLBACK SendMidiNoteOn(unsigned char note, unsigned char velocity) {

    if(pluginInstance) {

        MidiMessage m = MidiMessage::noteOn(1, note, (uint8)velocity);

        std::lock_guard<std::mutex> lock(midiMutex);

        incomingMidi.addEvent(m, 0);

    }

}

extern "C" void UNITY_AUDIODSP_CALLBACK SendMidiNoteOff(unsigned char note) {

    if(pluginInstance) {

        MidiMessage m = MidiMessage::noteOff(1, note);

        std::lock_guard<std::mutex> lock(midiMutex);

        incomingMidi.addEvent(m, 0);

    }

}


extern "C" void UNITY_AUDIODSP_CALLBACK SetParameterValue(int index, float value) {

    if(pluginInstance) {

        pluginInstance->setParameter(index, value);

    }

}


UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK ProcessCallback(UnityAudioEffectState* state,

                                     float* inbuffer, float* outbuffer,

                                     unsigned int length, int inchannels, int outchannels) {

    if(pluginInstance == nullptr) {

        // pass through audio

        memcpy(outbuffer, inbuffer, length * outchannels * sizeof(float));

        return UNITY_AUDIODSP_OK;

    }

    // Lock MIDI buffer and swap out the events

    midiMutex.lock();

    MidiBuffer midiThisBlock;

    midiThisBlock.swapWith(incomingMidi);

    midiMutex.unlock();

    // process audio through plugin

    AudioBuffer<float> audioIn(inbuffer, inchannels, length);

    AudioBuffer<float> audioOut(outbuffer, outchannels, length);

    pluginInstance->processBlock(audioIn, audioOut, midiThisBlock);

    return UNITY_AUDIODSP_OK;

}


Explanation: The C# Update() in this example listens for a keypress and sends a MIDI note on/off to the native plugin. The native side queues those events in a thread-safe way. In the audio callback, it takes all queued MIDI events (incomingMidi) and processes one block of audio through the plugin. The plugin was loaded and prepared with the system’s sample rate and block size. This pseudocode omits error checking and many details (like handling parameter queries, multiple channels, etc.), but it illustrates the core communication pattern.

6.4 Iterative Development and Testing

Given the complexity, implementing VST support should be done iteratively:

  1. Prototype Stage: Get a basic instrument plugin working end-to-end with manual triggering (as in pseudocode). Test that audio is produced and there are no crashes.

  2. Effect Plugins: Then test with an effect plugin on an existing audio source (feed audio in, get processed audio out).

  3. Multiple Instances: Try two different plugins at once (e.g., a synth and an effect) to ensure isolation (one should not affect the other’s state).

  4. UI Integration: Build out the Unity UI once the backend is stable, and ensure user interactions map correctly to plugin changes.

  5. Project Save/Load: Implement state saving last, once you’re confident in loading and controlling plugins.

  6. Optimization: Profile CPU usage with a few typical scenarios. Use Unity’s Profiler and any audio-specific metrics (maybe measure how much time the ProcessCallback takes vs budget). Optimize by adjusting thread priorities, reducing lock contention, etc. Use release builds of the native plugin for true performance measures (debug builds might be slower).

Throughout development, maintain a focus on stability. If a particular plugin causes a crash, it may be necessary to catch that at load and skip it, rather than let it bring down the whole Audiocube application. Over time, building a list of incompatible plugins or certain features to avoid (like certain plugins’ GUIs might not work with external window method) will be valuable.

7. Final Recommendations

After examining the technical details and possible methods, here are the key recommendations for achieving VST integration in Audiocube:

1. Leverage JUCE for Efficiency: Using the JUCE framework to build the VST hosting layer is recommended due to its cross-platform support and existing functionality for both Unity integration and VST hosting. This will significantly cut down development time and provide a robust foundation. The Audiocube team should acquire a JUCE commercial license (to keep Audiocube closed-source) and start by prototyping a Unity audio plugin through JUCE that can host a simple VST. The investment in JUCE will pay off with cleaner code and community support. As a backup or complement, keep Steinberg’s VST3 SDK at hand for any low-level needs not covered directly by JUCE.

2. Focus on VST3 Support (Cross-Platform): Aim to host VST3 plugins primarily, as it’s the current standard and is supported on both Windows and Mac. VST2 can be considered if there’s high demand, but it requires the discontinued SDK. Many plugin developers have migrated to VST3, and those that haven’t often still offer Audio Unit on Mac. If needed, host Audio Units on Mac via the same framework (JUCE can do this) to cover AU-only plugins. Ensure the architecture is 64-bit only, consistent with modern plugin builds and Unity’s requirements.

3. Implement a Basic but Functional UI for Plugins: Initially, implement a generic parameter control interface within Audiocube for loaded plugins. This guarantees that users can tweak any parameter of the plugin. Supplement this with an option to open the plugin’s native GUI in a separate window for more complex editing – this caters to power users who need the full plugin interface (for example, to manage presets or visualize an EQ curve). Clear instructions should be provided on how to use the external window, noting any limitations (e.g., “Keep the plugin window open only when needed to reduce strain,” or “On macOS, click the Audiocube icon to return to the main app after closing the plugin window.”). Over time, if feasible, improve the integration of plugin GUIs, but for the first release, a basic solution is acceptable given the complexity.

4. Start with Effects, Then Instruments: If prioritization is necessary, adding support for VST effects might be simpler and can be delivered first. Effects don’t require MIDI or sequencer integration – they only need audio routing. Audiocube could benefit from immediate use of popular spatial effects (like advanced reverbs or analyzers) inside the 3D environment. Once effect hosting is stable, proceed to implement instrument hosting, which will bring along the need for MIDI input and sequencing. This two-phase approach gets a usable feature out sooner and lets the team gather feedback (e.g., users might report on performance or stability with their plugin suite) before the more complex instrument integration is rolled out.

5. Integrate MIDI Input and a Basic Sequencer: For VST instruments, enable MIDI device input so users can play notes live on their keyboard through Audiocube. In the UI, display a virtual keyboard or allow mapping of computer keyboard to notes for those without external controllers. In parallel, plan a simple step sequencer or piano roll interface in Audiocube. It doesn’t need to rival Ableton’s or Logic’s editors initially; even a basic recording and playback of MIDI notes on a timeline per instrument would suffice. This could be presented as a “MIDI Clip” object in the scene or a separate timeline view. The key is to integrate it such that spatial movements and MIDI notes can be coordinated (e.g., a synth moves through space while playing a melody). If developing a full sequencer is too resource-intensive right now, consider providing synchronization so that Audiocube can be used with an external DAW for sequencing (for example, through Ableton Link for tempo sync, or ReWire/ReaRoute to pipe audio/MIDI between applications). However, a built-in sequencer will ultimately give Audiocube more standalone power.

6. Ensure Robustness and Sandbox Where Possible: Plugin crashes and misbehavior can degrade user experience. Take measures to handle these gracefully. For instance, if a plugin fails to load or crashes during scanning, flag it and continue scanning the rest. Possibly maintain a “blacklist” of plugins that caused crashes and skip them on future loads until the user re-enables them. While full out-of-process sandboxing (like Bitwig’s “plugin crash protection”) might be out of scope initially, at least isolate issues and prevent data loss. Encourage beta testers to use a variety of plugins and report any that cause instability, then test those specifically. Over time, stability will improve as edge cases are handled.

7. UI/UX: Keep it User-Friendly: Balance the new complexity with Audiocube’s generally intuitive design. The addition of plugin support will introduce some traditional DAW complexity, so design the UX carefully:

  • The plugin selection and insertion process should be as simple as drag-and-drop or a right-click “Add Effect…” menu on objects.

  • Use terminology familiar to musicians: e.g., call them “Plugins” or “Instruments/Effects” rather than technical terms like “VST instances” in the UI.

  • Provide tooltips or a quick tutorial for new users explaining how to use plugins in Audiocube (e.g., “To add a virtual instrument, go to Plugins panel, choose an instrument and place it in your 3D scene. Use a MIDI keyboard or the onscreen keys to play notes.”).

  • For investors or demos, emphasize how this integration allows Audiocube to leverage the best of both worlds: innovative 3D audio and the vast library of existing sounds/effects.

8. Documentation and Support: Update Audiocube’s documentation to include a section on VST plugin support. Cover how to install plugins (for novices), how to add them in Audiocube, any known limitations (like “no support for synths with multiple audio outputs yet” or “plugin GUIs open externally”). Also outline troubleshooting tips, such as what to do if a plugin isn’t showing up (e.g., ensure it’s a VST3 in the correct folder, rescan plugins from settings, etc.). Good documentation will reduce support burden and increase customer confidence in using the new feature.

9. Long-Term Vision – Audio Bridges and Exports: After implementing in-host VST support, Audiocube could explore the reverse: providing a VST/AU plugin of its own to be loaded in other DAWs. This would allow Audiocube to act as a spatial audio plugin where the DAW sends in tracks, they’re positioned in Audiocube’s 3D space, and then Audiocube returns a processed spatial mix. The HN discussion shows interest in using Audiocube with DAWs in real-time. While this is a separate development, it complements the strategy of interoperability. Also, consider an export feature: e.g., exporting Audiocube’s 3D scene as an Ambisonic audio file or stems that can be loaded into other software. These features would further solidify Audiocube’s place in a modern production workflow.

10. Proceed in Stages and Gather Feedback: VST integration is a major undertaking; doing it iteratively ensures that each piece (effects, instruments, GUI, sequencer) can be tested by a subset of users. Possibly release an early version to a small group or as a beta feature for power users to try out, then refine it. Pay attention to user feedback especially on performance and usability. The integration should ultimately feel like a natural extension of Audiocube, not a bolted-on tech demo. Given user enthusiasm (the HN thread had multiple people asking about plugin support (Nuxt HN | Show HN: Audiocube – A 3D DAW for Spatial Audio)), delivering this feature can significantly boost Audiocube’s adoption and utility.

In conclusion, adding VST support to Audiocube is technically feasible and highly beneficial. By using the right tools and carefully addressing the challenges, Audiocube can evolve from a standalone 3D audio playground into a more fully-fledged production environment that complements existing workflows. Customers will enjoy the freedom to bring their beloved instruments and effects into Audiocube’s 3D space, opening up creative possibilities (imagine playing a synthesizer in a virtual concert hall or applying a familiar guitar amp simulation to a 3D-located sound source). Investors will see this as Audiocube tapping into a large and growing market of audio plugins and professional users, thus expanding its market potential.

Audiocube’s unique value proposition—spatial audio creativity—combined with VST’s expansive ecosystem could position it as a revolutionary tool in music and sound design. With a solid implementation plan and focused development effort, VST integration can be the bridge that connects Audiocube’s innovative 3D audio world with the rich history and capabilities of modern music production software.

8. References

  1. Audiocube Official Website – “Create sound in 3 dimensions. Explore new dimensions of sound design in a virtual 3D environment.” Audiocube features page.

  2. Attack Magazine – The plugin market is massive. Over 20.6k individual products (plugins, instruments, etc.) listed on KVR Audio, reflecting the huge ecosystem of VSTs.

  3. Steinberg Developer – What is VST? Steinberg’s introduction to VST: established in 1996 as the leading standard for virtual instruments/effects.

  4. Steinberg VST 3 SDK Documentation – Technical perspective: A VST plug-in is a black box audio processor; the host feeds it audio/MIDI blocks which it processes and returns.

  5. Wikipedia – Types of VST plugins: VST instruments generate audio; VST effects process audio; VST MIDI effects process MIDI – all integrated into host applications.

  6. Wikipedia – History of VST standard: Steinberg discontinued VST2 SDK in 2013, moving focus to VST3 (with an open-source GPLv3 licensing option introduced in 2017).

  7. Unity Manual – Audio Overview: Unity’s audio engine supports 3D spatial sound, effects like echo and filtering, and basic mixing, but doesn't automatically handle advanced acoustics.

  8. Hacker News (Audiocube post) – Unity’s native audio vs custom: Audiocube’s app is built in Unity but uses a custom spatializer and acoustic engine instead of Unity’s native audio, to achieve reflections, occlusion, etc., not available in Unity by default (Show HN: Audiocube – A 3D DAW for Spatial Audio | Hacker News).

  9. Playful Tones Blog – JUCE and Unity: Integrating JUCE audio plugins into Unity is now easier thanks to JUCE’s support for exporting Unity plugins, though Unity’s plugin API is geared toward effects, making synth integration non-trivial (needing native code for note handling).

  10. Cabbage Audio Forum – JUCE 5.4.0 adds Unity native plug-in support: Announcement that JUCE can now build Unity-compatible plugins, enabling new possibilities for audio in Unity.

  11. UnityVSTHost (GitHub) – VST host in Unity (research project): A limited Unity implementation supporting 64-bit VST2 on Windows. Uses Unity’s OnAudioFilterRead to process audio through loaded plugins, and exposes parameters in the Unity inspector (no custom GUI).

  12. FMOD Forum – Using VST plugins in games: FMOD’s API can load VST (2) effects via System::loadPlugin and create DSP from it, allowing game developers to use certain VST effects in-game.

  13. Hacker News – User interest in Audiocube plugin support: Discussion suggesting that if Audiocube had VST/ReWire support, it could offload traditional DAW tasks to existing tools and integrate better (chaining DAWs together).

  14. ObiwanJacobi VST.NET GitHub – VST.NET overview: .NET library for building VST2 plugins and host applications in C#. It allows loading and communicating with unmanaged VST plugins, but is Windows-only and VST2-specific.

  15. Unity Documentation – Native audio plugin SDK: Notes that bridging other plugin formats (VST, AudioUnits) to Unity’s audio interface is possible but requires dynamic setup of parameters at load time (a hint toward creating a plugin bridge).

  16. Hacker News (Audiocube) – Latency discussion: Audiocube’s developer achieved an audio buffer of 20 samples (~0.4ms at 48kHz) in his custom engine for low latency, whereas another dev noted Unity’s audio system added too much latency for VR instrument use (Show HN: Audiocube – A 3D DAW for Spatial Audio | Hacker News).

  17. Bay Eight Studios Blog – What are music plugins (VST/AU/AAX)? Overview explaining how plugins integrate with DAWs to create or modify sound, analogous to guitar pedals for a guitarist.

  18. Unity Forum (C# scripting) – MIDI in Unity: Developers discuss sending MIDI from Unity to external sources or using MIDI in Unity (no direct citation given above, but context for MIDI handling).

  19. Bitwig Studio – Plugin sandboxing: Modern hosts like Bitwig run plugins in separate processes or sandboxes to prevent crashes from bringing down the DAW. Audiocube may not implement this immediately but should be aware of the practice for future stability improvements.



Previous
Previous

R³ – Real-Time Audio Bridging Between Audiocube and External DAWs

Next
Next

R³ - Implementing Multi-Channel Audio Output in Audiocube