Call function from AudioProcessor in SynthesiserVoice?

Hello!

I am developing a synth called Polymento for my bachelors project and I’m getting stuck on a C2653-error. In my projects PolymentoAudioProcessor I’ve made a private MidiKeyboardState-object along with a getClosestNote() function that I was hoping to be able to use in the SynthesiserVoice class, to retrieve the closest currently pressed note when a new note is pressed.

I’ve been following along with “The Audio Programmer”'s JUCE tutorials for building a synth, and have the same file structure as him (plugineditor.cpp + .h, pluginprocessor.cpp + .h, synthsound.h and synthvoice.h). synthVoice.h has my SynthesiserVoice-class, and is included in pluginProcessor.h. In the AudioProcessor-class 8 new synthVoices are added to the synth object.

In the synthVoice class I am for example able to call MidiMessage::getMidiNoteInHertz without any issues, but I’m not able to call PolymentoAudioProcessor::getClosestNote(midiNoteNumber) without errors.

I’ve tried many different solutions, but it doesn’t seem like a way to make this work. Is there anything I’m failing to see, or another solution that would give me the same result?

Posting some actual code is helpful to those trying to assist you. :slight_smile:

Oh, of course!

class PolymentoAudioProcessor : public AudioProcessor {
public: 

[…]

int getClosesNote(int midiNoteNumber)

[…]

private: 
MidiKeyboardState keyboard;

And then in the synthVoice.h:

class SynthVoice : public SynthesiserVoice {
public: 
void startNote(int midiNoteNumber, float velocity, SynthesiserSound* sound, int currentPitchWheelPosition) {
startFreq = MidiMessage::getMidiNoteInHertz(PolymentoAudioProcessor::getClosestNote(midiNoteNumber));

[…]

private:
double startFreq;

and I’m using the startFreq during the renderNextBlock function in synthVoice

This syntax will only work if you declare getClosestNote static. Static member functions are functions that are logically related to the class they are declared in but that don’t have access to a certain instance of that class. Therefore you don’t use the

Class myClassInstance;
myClassInstance.function();

syntax for static functions, but

Class::function();

instead. Note that you obviously can’t access any member variables and non-static member function inside static member functions.

1 Like

Ok, so I guess this approach wouldn’t work then if I can’t access member variables. Would there be any other way to get updated information about which notes are currently being held to the synthVoice-class?

Would it work if I instead of having the synthVoice.h, i place it’s content within the pluginProcessor.h, and set the MidiKeyboardState keyboard; as a public member variable within PolymentoAudioProcessor?

I realize this won’t work. I’m trying to figure out now if I can use the AudioProcessorValueTreeState to relay the value

Found out the solution was much simpler than I was thinking. I just created a member variable in SynthVoice, and a void-function to set this variable, and called the function from the AudioProcessor

I tried using your suggested syntax for a static function in PluginProcessor, which I also need to access in my SynthVoice, but I am getting some strange errors. FYI the function is a distortion which I would like to be able to apply either on a unison or voice level within SynthVoice, or in PluginProcessor on a Tone Generator (all voices) or Global level (all tone generators). My code looks this, first PluginProcessor.h (Note I do not use SynthSound at all);

#include "../JuceLibraryCode/JuceHeader.h"
//#include "SynthSound.h"
#include "SynthVoice.h"

//==============================================================================
/**
*/
class MutineerAudioProcessor  : public AudioProcessor
{
public:
    //==============================================================================
    MutineerAudioProcessor();
    ~MutineerAudioProcessor();

    // All the normal processor functions
    static void distortion ();

Then in PluginProcessor.cpp I got;

#include "PluginProcessor.h"
#include "PluginEditor.h"

#include "Common.h"
#include "WaveTables.h"

//==============================================================================
MutineerAudioProcessor::MutineerAudioProcessor ()
#ifndef JucePlugin_PreferredChannelConfigurations
	: AudioProcessor (BusesProperties ()
#if ! JucePlugin_IsMidiEffect
#if ! JucePlugin_IsSynth
		.withInput ("Input", AudioChannelSet::stereo (), true)
#endif
		.withOutput ("Output", AudioChannelSet::stereo (), true)
#endif
	)
#endif
{
	// Initializing stuff
}

MutineerAudioProcessor::~MutineerAudioProcessor ()
{
	mutineer.clearSounds ();
	mutineer.clearVoices ();
}

void MutineerAudioProcessor::distortion ()
{
	// To do
}

Then in SynthVoice.h I got;

#include "../JuceLibraryCode/JuceHeader.h"
#include "SynthSound.h"
#include "gbEditorVoice.h"
#include "WaveTables.h"
#include "PluginProcessor.h"

class SynthVoice : public SynthesiserVoice {
public:
	SynthVoice ()
	{
            // Initializing variables
        }

void renderNextBlock (AudioBuffer<float>& outputBuffer, int startSample, int numSamples)
	{
      // Usual suspects here

      // Just calling to check if I can
      MutineerAudioProcessor::distortion ();

      // Usual suspects here
    }

VS 2019 editor shows no errors, until I try to compile, and then I get;

Build started…
1>------ Build started: Project: Mutineer_SharedCode, Configuration: Debug x64 ------
1>RandomToneGenerator.cpp
1>CloneToneGenerator.cpp
1>StripEffects.cpp
1>StripToneGenerators.cpp
1>PluginProcessor.cpp
1>PluginEditor.cpp
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,3): error C2653: ‘MutineerAudioProcessor’: is not a class or namespace name (compiling source file …\Source\PluginProcessor.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,3): error C2653: ‘MutineerAudioProcessor’: is not a class or namespace name (compiling source file …\Source\StripToneGenerators.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,3): error C2653: ‘MutineerAudioProcessor’: is not a class or namespace name (compiling source file …\Source\RandomToneGenerator.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,3): error C2653: ‘MutineerAudioProcessor’: is not a class or namespace name (compiling source file …\Source\CloneToneGenerator.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,27): error C3861: ‘distortion’: identifier not found (compiling source file …\Source\StripToneGenerators.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,27): error C3861: ‘distortion’: identifier not found (compiling source file …\Source\CloneToneGenerator.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,27): error C3861: ‘distortion’: identifier not found (compiling source file …\Source\RandomToneGenerator.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,27): error C3861: ‘distortion’: identifier not found (compiling source file …\Source\PluginProcessor.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,3): error C2653: ‘MutineerAudioProcessor’: is not a class or namespace name (compiling source file …\Source\StripEffects.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,27): error C3861: ‘distortion’: identifier not found (compiling source file …\Source\StripEffects.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,3): error C2653: ‘MutineerAudioProcessor’: is not a class or namespace name (compiling source file …\Source\PluginEditor.cpp)
1>C:\JUCE\Mutineer\Source\SynthVoice.h(83,27): error C3861: ‘distortion’: identifier not found (compiling source file …\Source\PluginEditor.cpp)
1>Done building project “Mutineer_SharedCode.vcxproj” – FAILED.
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

So obviously I am doing something wrong somewhere. If I can’t solve it by having the shared function in PluginProcessor, I guess I could create a new pair of class (h and cpp) file, which I can then include in PluginProcessor and SynthVoice.