VirtualDJ Rust SDK
A complete Rust binding for the VirtualDJ Plugin SDK, enabling developers to write VirtualDJ plugins entirely in Rust while maintaining full compatibility with the C++ ABI.
Architecture
This SDK consists of three layers:
┌─────────────────────────────────────────────┐
│ User Rust Plugin (Pure Rust) │
│ - Implements plugin traits │
│ - No C++ knowledge required │
└────────────────┬────────────────────────────┘
│ (Safe abstraction)
┌────────────────▼────────────────────────────┐
│ Rust Safe API (rs_core/lib.rs) │
│ - Trait definitions (DspPlugin, etc) │
│ - Error handling (PluginError) │
│ - High-level abstractions │
└────────────────┬────────────────────────────┘
│ (FFI bindings)
┌────────────────▼────────────────────────────┐
│ Rust FFI Layer (rs_core/ffi.rs) │
│ - Raw C function declarations │
│ - Direct mapping to C ABI │
└────────────────┬────────────────────────────┘
│ (C linkage)
┌────────────────▼────────────────────────────┐
│ C ABI Layer (abi/vdj_plugin_abi.h) │
│ - C-compatible function signatures │
│ - Opaque handles (VdjPlugin, etc) │
│ - Callback structures │
└────────────────┬────────────────────────────┘
│ (C++ implementation)
┌────────────────▼────────────────────────────┐
│ C++ Shim Layer (vdj_plugin_shim/*.cpp) │
│ - Wraps C++ classes from VirtualDJ SDK │
│ - Implements C ABI functions │
│ - Bridges C++ and C/FFI worlds │
└────────────────┬────────────────────────────┘
│ (C++ classes)
┌────────────────▼────────────────────────────┐
│ VirtualDJ C++ SDK Headers (header_ref/) │
│ - IVdjPlugin8 (base plugin interface) │
│ - IVdjPluginDsp8 (audio effects) │
│ - IVdjPluginVideoFx8 (video effects) │
│ - IVdjPluginOnlineSource (online sources) │
└─────────────────────────────────────────────┘
How It Works
- User writes Rust code implementing trait methods (e.g.,
DspPlugin::on_process_samples) - Safe API trait provides default implementations and type safety
- Rust FFI bindings call into C ABI functions (extern "C" declarations)
- C ABI layer defines function signatures that work with C calling conventions
- C++ shim implements those C functions by wrapping the C++ classes from VirtualDJ
- VirtualDJ C++ SDK provides the actual plugin infrastructure
Building
The build script (build.rs) automatically:
- Compiles the C++ shim layer using the
cccrate - Links the compiled C++ code with your Rust code
- Monitors file changes for incremental builds
Creating a Plugin
1. Basic DSP Plugin Template
use ;
2. Available Plugin Types
DspPlugin- Real-time audio effectsBufferDspPlugin- Buffer manipulation (e.g., time-stretching)PositionDspPlugin- Position/playback controlVideoFxPlugin- Video effectsVideoTransitionPlugin- Video transitionsOnlineSourcePlugin- Online music sources/streaming
3. Querying VirtualDJ State
The PluginContext provides safe access to VirtualDJ state information like track metadata, position, BPM, and cue information. This is useful for plugins that need to react to VirtualDJ events or query the current state.
use ;
PluginContext Methods
-
get_info_string(command)- Query string values from VirtualDJ- Examples:
"deck 1 get_title","get_activedeck","deck 1 cue_name 1" - Returns:
Result<String>
- Examples:
-
get_info_double(command)- Query numeric/floating-point values- Examples:
"deck 1 get_position","deck 1 get_bpm","deck 1 cue_pos 1" - Returns:
Result<f64>
- Examples:
-
send_command(command)- Send commands to VirtualDJ- Examples:
"deck 1 play","deck 2 pause","mixer master volume 50" - Returns:
Result<()>
- Examples:
Example: Monitoring Cues
Here's a practical example of monitoring cues across multiple decks:
use PluginContext;
Key Features
✅ 100% Rust - Write plugins in pure Rust, no C++ needed
✅ Type Safe - Leverages Rust's type system for safety
✅ Error Handling - Rust's Result type for error propagation
✅ ABI Compatible - Fully compatible with VirtualDJ's C++ ABI
✅ Zero Overhead - Direct FFI calls, minimal abstraction cost
✅ Cross-Platform - Works with Windows, macOS implementations
Project Structure
VirtualDJRustSDK/
├── abi/
│ └── vdj_plugin_abi.h # C ABI interface definitions
├── header_ref/
│ ├── vdjPlugin8.h # VirtualDJ base plugin header
│ ├── vdjDsp8.h # DSP plugin header
│ ├── vdjVideo8.h # Video plugin header
│ └── vdjOnlineSource.h # Online source plugin header
├── vdj_plugin_shim/
│ └── basic_plugin_shim.cpp # C++ shim implementation
├── rs_core/
│ ├── lib.rs # Safe Rust API and trait definitions
│ └── ffi.rs # Raw FFI bindings to C ABI
├── examples/
│ └── simple_dsp.rs # Example DSP plugin
├── build.rs # Build script for C++ compilation
├── Cargo.toml # Rust package manifest
└── README.md # This file
Development Workflow
1. Create a new plugin library
2. Add SDK as a dependency
# Cargo.toml
[]
= { = "../VirtualDJRustSDK" }
3. Implement the plugin trait
use DspPlugin;
4. Build your plugin
Error Handling
The SDK provides a PluginError type for error handling:
use ;
FFI Bindings Reference
The low-level FFI bindings are available in rs_core::ffi for advanced use cases:
use *;
// Direct C function calls
unsafe
Note: Direct FFI usage requires unsafe blocks and is not recommended for typical use.
Constants and Flags
Common plugin flags and parameter types are available:
use *;
// Plugin flags
const VDJFLAG_PROCESSFIRST: u32 = 0x4;
const VDJFLAG_PROCESSLAST: u32 = 0x8;
// Parameter types
const VDJPARAM_SLIDER: i32 = 1;
const VDJPARAM_BUTTON: i32 = 0;
Testing
The SDK includes test support for plugin logic:
Run tests with:
Performance Considerations
- Buffer Processing: Buffers are passed as
&mut [f32]slices for zero-copy access - Sample Rates: Typically 44.1kHz or 48kHz (access via
sample_rate()method) - Stereo Format: Audio samples are interleaved (L, R, L, R, ...)
- Real-time: Minimize allocations in
on_process_samples()for best performance
Troubleshooting
Compilation errors with C++
Ensure you have:
- A C++ compiler installed (MSVC on Windows)
- The
cccrate dependency (automatically downloaded)
Symbol resolution errors
The C++ shim must be properly compiled. Check that vdj_plugin_shim/basic_plugin_shim.cpp includes all necessary VirtualDJ headers.
Contributing
Contributions are welcome! Areas for improvement:
- Additional plugin type examples
- Performance optimizations
- Cross-platform testing
- Extended trait methods
License
This project is provided under the MIT or Apache 2.0 license.