# HISE AU Multi-Output Support for Logic Pro ## Overview This document describes the modifications required to enable HISE-exported AU plugins to appear in Logic Pro with multi-output instantiation options, similar to professional instruments like Kontakt. ### Problem Statement By default, HISE AU plugins only appear in Logic Pro with a single "Stereo" option, even when configured with multiple output buses. Logic Pro does not show "Multi-Output" instantiation options, preventing users from accessing individual instrument outputs as separate aux channels. ### Solution Modify JUCE's AU wrapper to advertise specific channel configurations that Logic Pro recognizes for multi-output support. When `HISE_NUM_PLUGIN_CHANNELS > 2`, the AU will advertise both stereo (2 channels) and multi-output (N channels) configurations. --- ## Code Changes Required ### File to Modify **Path:** `JUCE/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm` **Location:** Inside the `JuceAU` constructor, around line 139 ### Original Code ```cpp #ifdef JucePlugin_PreferredChannelConfigurations short configs[][2] = {JucePlugin_PreferredChannelConfigurations}; const int numConfigs = sizeof (configs) / sizeof (short[2]); jassert (numConfigs > 0 && (configs[0][0] > 0 || configs[0][1] > 0)); juceFilter->setPlayConfigDetails (configs[0][0], configs[0][1], 44100.0, 1024); for (int i = 0; i < numConfigs; ++i) { AUChannelInfo info; info.inChannels = configs[i][0]; info.outChannels = configs[i][1]; channelInfo.add (info); } #else channelInfo = AudioUnitHelpers::getAUChannelInfo (*juceFilter); #endif ``` ### Modified Code ```cpp // HISE multi-output AU support: Advertise specific supported configurations #if defined(HISE_NUM_PLUGIN_CHANNELS) && HISE_NUM_PLUGIN_CHANNELS > 2 { AUChannelInfo info; // Advertise stereo configuration (main bus only) info.inChannels = 0; info.outChannels = 2; channelInfo.add (info); // Advertise full multi-output configuration (all buses) // This shows in Logic as "Multi-Output" option info.outChannels = HISE_NUM_PLUGIN_CHANNELS; channelInfo.add (info); } #elif defined(JucePlugin_PreferredChannelConfigurations) short configs[][2] = {JucePlugin_PreferredChannelConfigurations}; const int numConfigs = sizeof (configs) / sizeof (short[2]); jassert (numConfigs > 0 && (configs[0][0] > 0 || configs[0][1] > 0)); juceFilter->setPlayConfigDetails (configs[0][0], configs[0][1], 44100.0, 1024); for (int i = 0; i < numConfigs; ++i) { AUChannelInfo info; info.inChannels = configs[i][0]; info.outChannels = configs[i][1]; channelInfo.add (info); } #else channelInfo = AudioUnitHelpers::getAUChannelInfo (*juceFilter); #endif ``` --- ## How It Works ### Channel Configuration Advertising The AU uses the `kAudioUnitProperty_SupportedNumChannels` property to advertise supported channel configurations to Logic Pro. **For HISE plugins with `HISE_NUM_PLUGIN_CHANNELS > 2`:** 1. **Stereo Configuration** `[0, 2]` - 0 input channels, 2 output channels - Represents main stereo bus only - Shows in Logic as "YourPlugin (Stereo)" 2. **Multi-Output Configuration** `[0, N]` - 0 input channels, N output channels (e.g., 10 for 5 stereo buses) - Represents all output buses combined - Shows in Logic as "YourPlugin (Multi-Output)" **For HISE plugins with `HISE_NUM_PLUGIN_CHANNELS ≤ 2`:** - Falls back to standard JUCE behavior - No changes to existing workflow ### Alternative: Flexible Configuration To enable **all** Logic Pro configuration options (Mono, 5.1, 7.1, etc.), use a **negative** value: ```cpp // Instead of: info.outChannels = HISE_NUM_PLUGIN_CHANNELS; // Use: info.outChannels = -HISE_NUM_PLUGIN_CHANNELS; // Negative = flexible ``` **Negative Value Behavior:** - `-N` means "flexible configuration up to N channels" - Logic shows: Mono, Stereo, 5.1, 7.1, Multi-Output, and any configuration ≤ N - Similar to how Kontakt advertises `[0, -64]` **Recommendation:** Use positive values for cleaner menu (Stereo + Multi-Output only) --- ## Complete Setup Instructions ### 1. Configure HISE for Multi-Channel Output **Edit:** `hi_core/LibConfig.h` ```cpp // Set the maximum number of plugin channels // Example: 10 channels = 5 stereo buses #ifndef HISE_NUM_PLUGIN_CHANNELS #define HISE_NUM_PLUGIN_CHANNELS 10 #endif ``` ### 2. Rebuild HISE ```bash cd HISE/projects/standalone # Build using your platform's build system (Projucer/Xcode/Visual Studio) ``` **Why rebuild?** The HISE application needs to support the channel count in its routing matrix and DSP engine. ### 3. Modify the AU Wrapper **Edit:** `JUCE/modules/juce_audio_plugin_client/AU/juce_AU_Wrapper.mm` Apply the code change shown above (around line 139 in the `JuceAU` constructor). **Note:** You do NOT need to rebuild HISE after this change - only exported plugins are affected. ### 4. Configure Your Plugin in HISE 1. Launch the rebuilt HISE 2. Open/create your plugin project 3. **Configure Routing Matrix:** - Open the routing matrix editor - Set up multiple output channels (e.g., 5 stereo pairs = 10 channels) - Assign each instrument/sound generator to its own output pair **Example 5-instrument setup:** - Instrument 1 → Channels 1-2 - Instrument 2 → Channels 3-4 - Instrument 3 → Channels 5-6 - Instrument 4 → Channels 7-8 - Instrument 5 → Channels 9-10 ### 5. Export the Plugin 1. In HISE: File → Export → Export as AU/VST/Standalone 2. The exporter automatically writes `HISE_NUM_PLUGIN_CHANNELS=10` to the generated project 3. Export location: `YourProject/Binaries/` ### 6. Build the Exported AU **macOS:** ```bash cd YourProject/Binaries/Builds/MacOSX xcodebuild -project "YourPlugin.xcodeproj" \ -target "YourPlugin - AU" \ -configuration Release ``` **Result:** `build/Release/YourPlugin.component` ### 7. Install the AU ```bash # Remove old version rm -rf ~/Library/Audio/Plug-Ins/Components/YourPlugin.component # Install new version cp -R build/Release/YourPlugin.component \ ~/Library/Audio/Plug-Ins/Components/ # Clear AU cache killall -9 AudioComponentRegistrar ``` ### 8. Test in Logic Pro 1. **Clear Logic's cache:** ```bash rm -rf ~/Library/Caches/AudioUnitCache ``` 2. **Launch Logic Pro** 3. **Rescan plugin:** - Logic Pro → Settings → Plug-In Manager - Find "YourPlugin" - Click "Reset & Rescan Selection" 4. **Create new Software Instrument track** 5. **Check instrument menu:** - You should see: "YourPlugin (Stereo)" - And: "YourPlugin (Multi-Output)" or similar 6. **Select Multi-Output** and verify all buses appear as aux channels in Logic's mixer --- ## Verification with auval You can verify the AU is correctly advertising configurations using Apple's `auval` tool: ```bash # Find your plugin's identifiers auval -a | grep "YourPlugin" # Validate the AU (example identifiers) auval -v aumu YrPl YrCo # Look for this section in output: # Reported Channel Capabilities (explicit): # [0, 2] [0, 10] ``` **Expected output:** - `[0, 2]` - Stereo configuration - `[0, 10]` - Multi-output configuration (for 10 channels) **If using negative value:** - `[0, 2]` - Stereo configuration - `[0, -10]` - Flexible up to 10 channels --- ## Troubleshooting ### Logic Only Shows Stereo Option **Causes:** 1. AU wasn't rebuilt after code changes 2. Logic is caching old plugin version 3. `HISE_NUM_PLUGIN_CHANNELS` wasn't set correctly during export **Solutions:** ```bash # Verify export has correct channel count grep "HISE_NUM_PLUGIN_CHANNELS" \ YourProject/Binaries/AutogeneratedProject.jucer # Should show: HISE_NUM_PLUGIN_CHANNELS=10 (or your value) # Rebuild the AU cd YourProject/Binaries/Builds/MacOSX xcodebuild clean xcodebuild -target "YourPlugin - AU" -configuration Release # Complete cache clear rm -rf ~/Library/Caches/AudioUnitCache killall -9 AudioComponentRegistrar # Force Logic rescan ``` ### Logic Shows Unwanted Options (Mono, 5.1, etc.) **Cause:** Using negative value for flexible configuration **Solution:** Change code to use positive value: ```cpp info.outChannels = HISE_NUM_PLUGIN_CHANNELS; // Positive = specific config ``` Then rebuild and reinstall the AU. ### AU Validation Fails **Common errors:** 1. **"Dynamic Configuration" error:** - This is expected and doesn't prevent Logic functionality - Related to bus count not being dynamically changeable 2. **Format not supported errors:** - Check that HISE's routing matrix matches advertised channel count - Verify all buses are properly configured in HISE 3. **Component won't load:** - Check code signing (may need to disable Gatekeeper during testing) - Verify AU is in correct location: `~/Library/Audio/Plug-Ins/Components/` --- ## Technical Details ### AUChannelInfo Structure ```cpp struct AUChannelInfo { SInt16 inChannels; // Input channel count (0 for instruments) SInt16 outChannels; // Output channel count }; ``` **Special values:** - Positive number: Exact channel count - `-1`: Any number of channels - `-2`: Any number matching other side (input/output) - Negative number: Flexible up to abs(value) channels ### Why This Works 1. **Logic Pro checks `kAudioUnitProperty_SupportedNumChannels`** to determine available instantiation options 2. **JUCE's AU wrapper** returns the `channelInfo` array via the `SupportedNumChannels()` method 3. **Our modification** populates this array with HISE-specific configurations when `HISE_NUM_PLUGIN_CHANNELS > 2` 4. **Logic displays menu options** based on the advertised configurations ### Multi-Bus Architecture HISE uses true multi-bus architecture: - Each output pair is a separate AU bus - Example: 5 stereo buses = 5 separate `AUAudioUnitBus` objects - Each bus is named (e.g., "Channel 1+2", "Channel 3+4", etc.) - Logic maps these buses to aux channels in the mixer --- ## Compatibility Notes ### HISE Versions - Tested with HISE as of December 2024 - Should work with any HISE version using the included JUCE ### Logic Pro Versions - Confirmed working with Logic Pro 10.8+ - Should work with any version supporting multi-output AU ### Other DAWs This modification specifically targets Logic Pro's AU implementation. Other DAWs may: - Already show multi-output options without changes - Use different mechanisms to detect multi-output support - Require additional modifications --- ## Advanced Configuration ### Custom Channel Counts To advertise intermediate configurations (e.g., 2, 4, 6, 10 channels): ```cpp #if defined(HISE_NUM_PLUGIN_CHANNELS) && HISE_NUM_PLUGIN_CHANNELS > 2 { AUChannelInfo info; info.inChannels = 0; // Stereo info.outChannels = 2; channelInfo.add (info); // 4 channels info.outChannels = 4; channelInfo.add (info); // 6 channels info.outChannels = 6; channelInfo.add (info); // Full multi-output info.outChannels = HISE_NUM_PLUGIN_CHANNELS; channelInfo.add (info); } #elif defined(JucePlugin_PreferredChannelConfigurations) ``` This gives Logic more granular options for how many outputs to enable. ### Per-Project Override If you need different channel counts for different projects without rebuilding HISE: 1. HISE allows manual override via project settings 2. Set in project: `Extra Definitions` → `HISE_NUM_PLUGIN_CHANNELS=N` 3. This overrides the compiled default 4. Re-export and rebuild the plugin --- ## Summary **One-time setup:** 1. Set `HISE_NUM_PLUGIN_CHANNELS` in `LibConfig.h` 2. Rebuild HISE 3. Modify `juce_AU_Wrapper.mm` with multi-output code **Per-plugin workflow:** 1. Configure routing matrix in HISE 2. Export plugin (writes channel count to .jucer) 3. Build exported AU 4. Install and test in Logic Pro **Result:** - Clean menu with Stereo and Multi-Output options - All output buses accessible as separate aux channels - Professional multi-output workflow like Kontakt --- ## Credits This solution was developed through analysis of: - JUCE AU wrapper implementation - Apple's Audio Unit specification - Logic Pro's multi-output AU requirements - Comparison with reference implementations (Kontakt) **Date:** December 2024 **HISE Version:** Compatible with current JUCE-based builds **Platform:** macOS (AU format) --- ## License This modification follows HISE's GPL v3 license. The modified JUCE code remains under JUCE's licensing terms.