ramirezd42 / node-audio

Graph-based audio api for Node.js based on LabSound and JUCE
89 stars 7 forks source link

Hosting AudioUnit with PluginNode #9

Open eliot-akira opened 6 years ago

eliot-akira commented 6 years ago

Thank you for this project, I'm learning a lot from it.

In the documentation, it says: "It currently supports only VST3 plugins, but the host process is built with JUCE so adding support for other formats like VST and AudioUnit shouldn't be too much work."

I'm interested in loading AudioUnit via PluginNode. Would it be possible to provide some hints as to how I can achieve it?

From what I can understand, here's where it searches for and loads a VST plugin: https://github.com/ramirezd42/node-audio/blob/master/src/extended/PluginHostChildProcess/main.cc#L103

ramirezd42 commented 6 years ago

It looks like AudioPluginFormat has a findAllTypesForFile() function you can use to get at the PluginDescription there in a way that will work for types other than VST3. https://docs.juce.com/master/classAudioUnitPluginFormat.html

I expect there will also be some modifications to the build steps necessary. It might be as simple as adding the AudioUnit framework to the juce.gypi file.

{ 
  ...
  "conditions": [[ 
    'OS=="mac"', 
    { 
      'link_settings': { 
        'libraries': [ 
          '$(SDKROOT)/System/Library/Frameworks/AudioUnit.framework', 
          ...
        ] 
      }, 
      ...
    } 
  ]]
}
eliot-akira commented 6 years ago

Thanks for looking into it, that's a helpful pointer.

I was actually able to get AudioUnit effects to load, by modifying the line I mentioned above. I'm very new to C++, so the change is quite crude still..

AudioPluginInstance *instance;
OwnedArray<juce::PluginDescription> foundPlugins;

if (pluginPath.endsWith(".vst3")) {

  VST3PluginFormat formatVST;

  formatVST.findAllTypesForFile(foundPlugins, pluginPath);
  description = foundPlugins[0];
  instance = formatVST.createInstanceFromDescription(
    *description, setup.sampleRate, setup.bufferSize);

} else {

  AudioUnitPluginFormat formatAU;

  formatAU.findAllTypesForFile(foundPlugins, pluginPath);
  description = foundPlugins[0];
  instance = formatAU.createInstanceFromDescription(
    *description, setup.sampleRate, setup.bufferSize);
}

Aside from the probably unnecessary duplicated code, it looks like I'm not using findAllTypesForFile correctly, from your description of what it does. Well, I'll try to improve my knowledge of C++ and JUCE, and create a pull request when the code is better. :)