[SOLVED] Custom standalone and inputs

Hi guys,

I’m still having troubles making my custom standalone work. What I do is:

(copied from another thread… same steps)

  • Copy the juce_StandaloneFilterApp.cpp and juce_StandaloneFilterWindow.h files to my own folder
  • In MyStandaloneApp.cpp
    • Comment out the includes and add #include "../JuceLibraryCode/JuceHeader.h"
    • Change #include "juce_StandaloneFilterWindow.h" to use my file #include "MyStandaloneWindow.h"
    • Rename the class StandaloneFilterApp to MyStandaloneFilterApp
    • Comment out the #if ! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP line and it’s matching #endif
    • Add START_JUCE_APPLICATION(MyStandaloneFilterApp) to the end of the file
  • In MyStandloneWindow.h
    • Rename StandaloneFilterHolder to MyStandaloneFilterHolder
    • Rename StandaloneFilterWindow to MyStandaloneFilterWindow
  • In PluginEditor.cpp
    • Add #include “MyStandaloneApp.cpp”
  • Add JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP=1 to the Projucer Preprocessor Definitions field

When I build, I get a duplicate symbol for ‘juce_createApplication()’.

I also need to get a way to have mono input selection, since these will be standalone version of guitar effect plugins. I know that’s possibile, since there are competitors using JUCE and doing that:

Any advice will be greatly appreciated.
Thanks!

1 Like

What is the full text of the linker error? It should tell you in which translation unit the other symbol is defined. If the duplicate symbol is in juce_audio_plugin_client_Standalone.cpp, that would suggest that the JUCE_USE_CUSTOM_PLUGIN_STANDALONE_APP definition isn’t active in that file, and you should check that you re-exported the Projucer project after adding that definition. If the duplicate symbol is in one of your files, then that might mean that you have several entry points in your code, or are mistakenly compiling a file twice (perhaps including a .cpp in another .cpp, but also building both .cpp files individually).

Thanks, reuk. The full error is:

duplicate symbol 'juce_CreateApplication()' in:
    /.../Builds/MacOSX/build/Debug/libL12X Solid State Amplifier.a(LC_StandaloneFilterApp.o)
    /.../Builds/MacOSX/build/Debug/libL12X Solid State Amplifier.a(PluginEditor.o)
ld: 1 duplicate symbol for architecture x86_64

In PluginEditor, I just have the include for LC_StandaloneFilterApp.cpp" along with inclusions for PluginProcessor.h and PluginEditor.h

Thanks

The error is saying that the duplicate function is defined both in LC_StandaloneFilterApp.cpp and PluginEditor.cpp.

You should either include LC_StandaloneFilterApp.cpp in PluginEditor.cpp, or add it as a separate translation unit in the Projucer. Don’t do both. Each .cpp should only be built/included once in the final project.

The cpp file is added in Projucer as any other file in the project. Then I just include it in PluginEditor.cpp. AFAIK this shouldn’t be a problem.

No, that is the problem. You need to do one or the other.

that worked, thanks. So is it the macro that actually “includes” that cpp file during compilation?

Update for other users that wants to select just a mono input and not a stereo pair:

in your StandaloneFilterWindow.h, around line 415:

deviceSelector (deviceManagerToUse,
0, maxAudioInputChannels,
0, maxAudioOutputChannels,
true,
(pluginHolder.processor.get() != nullptr && pluginHolder.processor->producesMidi()),
true, false)

Change the highlighted bool from true to false and you will be able to select single channels instead of stereo pairs.

No, the macro just defines the juce_CreateApplication function.

When you build the program, you’ll end up with one copy of this function in LC_StandaloneFilterApp.cpp (because that’s where the macro is expanded), and a second copy in PluginEditor.cpp (because that file includes LC_StandaloneFilterApp.cpp, which contains the macro).

It’s an error to define the same (non-inline) function in multiple translation units. To ensure that the function is only defined once, you need to ensure that the macro is only used in a single translation unit. In this case, that’s achieved by either removing the include from PluginEditor.cpp (the only macro expansion will be in the StandaloneFilterApp TU), or avoiding adding the StandaloneFilterApp as a TU altogether (the macro expansion will happen in the PluginEditor.cpp, as this file includes StandaloneFilterApp.cpp).

Outside of a JUCE module, it’s a bad idea to include .cpp files inside other .cpp files as it’s very easy to end up with these duplicate symbol errors, so I’d recommend that removing the LC_StandaloneFilterApp.cpp include is the better solution.

2 Likes

Thanks for the info, reuk.

1 Like

Hey, question related to allowing different input configs.

I am trying to give the Standalone Plugin app the ability to select more than 2 channels from the input device.

The purpose is to allow 4/6/8/etc channels of processing in the standalone version of the plugin.

This can be done with AudioPluginHost.
I’m trying to avoid having to deep dive into the APH code and figure out where this happens and am hoping it is a relatively simple fix for the Standalone Plugin target.

Has anyone got this working?

Is this still the only way to do that? It’s very strange that you need to rewrite all the Standalone app code just to change one very simple option, but of course I would like to avoid to change JUCE library code!

1 Like

I have just opened an issue on GitHub related to this topic:

[Bug]: StandaloneFilterWindow doesn’t reference “Plugin MIDI Input” jucer option when creating AudioDeviceSelectorComponent

Adding a few notes that might help future custom-standalone-app’ers

All of the OP instructions plus

  • I simply added MyStandaloneApp.cpp to my plugin build files to be built as a separate .cpp - no need to include in editor
  • Important: after copying of the contents of juce_StandaloneFilterApp.cpp to MyStandaloneApp.cpp, remove these lines in MyStandaloneApp.cpp:

#if ! JUCE_USE_CUSTOM_PLUGIN_STANDALONE_ENTRYPOINT
JUCE_MAIN_FUNCTION_DEFINITION
#endif

(i.e. let juce_StandaloneFilterApp.cpp continue to do those lines and create the main entry point)

Seems like this could be the fix for OP’s duplicate symbol problem as well.

1 Like