Can Anyone Explain to Me Why I Can't Implement Two Constructors When Calling my AudioProcessor Class?


#1

So I’m trying to implement C++ code produced from HEAVY in my JUCE project. I’ve decided to lift the functionality from the HEAVY code and try implement it directly into my JUCE project, taking the generator and calling it from the ‘processingBlock’.

The issue I’m having is that I need to call the constructor for “audioEffectX” in my main class which is “Animal_generator_krotosAudioProcessor”. There is a lot of stuff that has been auto-generated from HEAVY so it can be quite messy to work with. Can someone look at how I’m calling this constructor and explain why Xcode is complaining about it.

This is my .cpp file:

/*
  ==============================================================================
    This file was auto-generated!
    It contains the basic framework code for a JUCE plugin processor.
  ==============================================================================
*/
#include "PluginProcessor.h"
#include "PluginEditor.h"
#include "HeavyVst2_creatureSynthHL.h"
#include "HvUtils.h"
#define HV_VST2_NUM_PARAMETERS 5
//==============================================================================
Animal_generator_krotosAudioProcessor::Animal_generator_krotosAudioProcessor(audioMasterCallback amCallback)
#ifndef JucePlugin_PreferredChannelConfigurations
    : AudioProcessor (BusesProperties()
            #if ! JucePlugin_IsMidiEffect
                #if ! JucePlugin_IsSynth
                      .withInput  ("Input",  AudioChannelSet::stereo(), true)
                #endif
                      .withOutput ("Output", AudioChannelSet::stereo(), true)
            #endif
                      )
#endif
{
    //constructor
},
    AudioEffectX(amCallback, 0, HV_VST2_NUM_PARAMETERS) {
        setUniqueID(0x2FEC904B);
        setNumInputs(0);
        setNumOutputs(2);
        isSynth(true);
        canProcessReplacing(true);
        canDoubleReplacing(false);
        // initialise parameters with defaults
        _parameters[0] = 0.5f; // aggression
        _parameters[1] = 0.5f; // excitation
        _parameters[2] = 0.5f; // mouthScale
        _parameters[3] = 1.0f; // rippleScale
        _parameters[4] = 0.5f; // size
        _context = NULL;
        this->sampleRate = 0.0f; // initialise sample rate
        setSampleRate(44100.0f); // set sample rate to some default
    }
Animal_generator_krotosAudioProcessor::~Animal_generator_krotosAudioProcessor()
{
    if (_context != NULL) hv_creatureSynthHL_free(_context);
}

This is my .h file:

 /*
   ==============================================================================

     This file was auto-generated!

     It contains the basic framework code for a JUCE plugin processor.

   ==============================================================================
 */

 #ifndef PLUGINPROCESSOR_H_INCLUDED
 #define PLUGINPROCESSOR_H_INCLUDED

 #include "../JuceLibraryCode/JuceHeader.h"
 #include "Generator/vst2/audioeffectx.h"
 #include "Heavy_creatureSynthHL.h"


 //==============================================================================
 /**
 */
 class Animal_generator_krotosAudioProcessor  : public AudioProcessor, public AudioEffectX
 {
 public:
     //==============================================================================
     Animal_generator_krotosAudioProcessor(audioMasterCallback amCallback);
     ~Animal_generator_krotosAudioProcessor();

     //==============================================================================
     void prepareToPlay (double sampleRate, int samplesPerBlock) override;
     void releaseResources() override;

    #ifndef JucePlugin_PreferredChannelConfigurations
     bool isBusesLayoutSupported (const BusesLayout& layouts) const override;
    #endif

     void processBlock (AudioSampleBuffer&, MidiBuffer&) override;

     //==============================================================================
     AudioProcessorEditor* createEditor() override;
     bool hasEditor() const override;

     //==============================================================================
     const String getName() const override;

     bool acceptsMidi() const override;
     bool producesMidi() const override;
     double getTailLengthSeconds() const override;

     //==============================================================================
     int getNumPrograms() override;
     int getCurrentProgram() override;
     void setCurrentProgram (int index) override;
     const String getProgramName (int index) override;
     void changeProgramName (int index, const String& newName) override;

     //==============================================================================
     void getStateInformation (MemoryBlock& destData) override;
     void setStateInformation (const void* data, int sizeInBytes) override;
     

     //==============================================================================
     //From 'HeavyVst2_creatureSynthHL'
     void setSampleRate(float sampleRate) override;
     
     void setParameter(VstInt32 index, float value) override;
     float getParameter(VstInt32 index) override;
     
     void getParameterDisplay(VstInt32 index, char* text) override;
     void getParameterName(VstInt32 index, char* text) override;
     bool string2parameter(VstInt32 index, char* text) override;
     
     VstInt32 canDo(char *text) override;
     
     void processReplacing(float** inputs, float** outputs, VstInt32 sampleFrames) override;
     
     VstInt32 processEvents(VstEvents* events) override;
     
     bool getEffectName(char* name) override;
     bool getVendorString(char* text) override;
    
     VstInt32 getChunk(void** data, bool isPreset) override;
     VstInt32 setChunk(void* data, VstInt32 byteSize, bool isPreset) override;
     //===============================================================================

If someone can let me know where I’m going wrong here that would be great!


#2

This doesn’t seem to be valid C++.
Why is your processor inheriting from AudioEffectX? AudioProcessor should be the one handling VST aspects.
If you need to have AudioEffectX somewhere, don’t do it like that, use it (or more precisely its implementation) as a variable parameter (think of it as is “implemented in terms of”, instead of “is a”).

You actual issue is the two {} that should be after the call to the constructor.
But once again, change your hierarchy, it’s not currently done efficiently and properly.


#3

How do you refer to AudioEffectX as a variable parameter? What should I look at to understand this approach?


#4

You should put your implementation of AudioEffectX as another class, split the AudioProcessor implementation that actually deals with communicating with the DAW from the implementation of your process.
Look at a good architecture book (or some blogs) to understand the difference between IS A from HAS A (and IS IMPLEMENTED IN TERMS OF)
The fact that you derive from AudioEffectX is probably useless in your design, but you may require it if other parts of HEAVY uses that API, so split HEAVY from the AudioProcessor specifics.


#5

Cheers Matthieu, i’ll give it a shot and hopefully i’ll manage. I understand that what im doing is a bit ambitious but hopefully i can pull it off. Would be cool to get my pure data patch running as a JUCE generated VST with a nice GUI. This is pretty much what I’m trying to achieve. Just getting confused with all this HEAVY auto-generated code.


#6

To create a VST plugin, you don’t have to derive from AudioEffectX. And you don’t need to include any files of the VST SDK directly (read you should not).
The AudioProcessor class acts as wrapper. All different plugin formats is taken care of by juce, just by setting the right switches in the Projucer.

Also to publish parameters to the host, use the AudioParameterFloat classes, or even better the AudioProcessorValueTreeState.

HTH


#7

The issue is that the HEAVY generated code relies on AudioEffectX to produce audio output. I’m not sure how I would go about changing this dependancy so that it relies on the audioProcessor. I was almost thinking it might be possible to wrap a VST in a VST?


#8

Yes, that’s what I said. Wrap the class inside the Audio Processor as an independent class.