Unsure How to Call Editor Component Method Inside Processor

So I’ve instantiated a waveform viewer class inside my editor which, for obvious reasons is necessary to paint and place the object in the editor. The class itself also has functions which require access to the processor’s buffer so that it can display the correct waveform in the buffer to the editor. I’m just wondering how you would go about this? I’ll post some code for reference.

editor.h

class Ring_modulatorAudioProcessorEditor  : public AudioProcessorEditor, public Slider::Listener, public ComboBox::Listener
 {
 public:
     Ring_modulatorAudioProcessorEditor (Ring_modulatorAudioProcessor&);
     ~Ring_modulatorAudioProcessorEditor();
     //==============================================================================
     void paint (Graphics& g) override;
     void resized() override;
     void sliderValueChanged (Slider* slider) override;
 
 void comboBoxChanged(juce::ComboBox* comboBox) override;
 
 Component* getComponent() { return this; };
 
 std::unique_ptr<KrotosWaveformViewer> m_waveformViewer; //instantiated waveViewer class as pointer     
 private:

processor.cpp

 void Ring_modulatorAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
 {
     const int totalNumOutputChannels = buffer.getNumChannels();

             for (int sampleNum = 0; sampleNum < buffer.getNumSamples(); ++sampleNum)
             {
                 
                 for (int channel = 0; channel < totalNumOutputChannels; ++channel)
                 {
                     ......
                     ......
                     ......
                     m_waveformViewer->updateWaveformThumbnail(buffer.getReadPointer(0));
                                     
                 }
             }

waveformViewer.cpp

void WaveformViewer::updateWaveformThumbnail(juce::AudioSampleBuffer& monoAudioBuffer)
 {
     m_waveformThumbnail->reset(1, m_wavReader->sampleRate, monoAudioBuffer.getNumSamples());
     m_waveformThumbnail->addBlock(0, monoAudioBuffer, 0, monoAudioBuffer.getNumSamples());
     
     m_currentBuffer = monoAudioBuffer;
 }
1 Like

I am having the same problem in the same place.
getActiveEditor()->
Even with this, I can only call methods within the processor editor type and not the original custom class.

There are plenty of ways to get the processor from the editor,
I too would like to know the opposite.

You can cast the pointer returned from getActiveEditor to your actual editor class:

auto* editor = dynamic_cast<Ring_modulatorAudioProcessorEditor*>(getActiveEditor());

editor->m_waveformViewer->...;

The AudioThumbnail::addBlock method accepts an AudioSampleBuffer, you don’t need to pass in the raw pointer.

Though be aware that you should avoid that at all cost.

  • There is no guarantee that getActiveEditor() is the one and only editor. The API allows multiple editors
  • There is no guarantee that the editor is not being deleted while you are working on it (unless you use the MessageManager and/or a MessageManagerLock)

The better design is to store what needs to be processed in the processor and only let the editor look at it.
If you need to signal the editor, you can use ChangeBroadcaster and ChangeListener.

2 Likes

This is my way of pushing audio buffers to the editor:

In your processor declare these guys:

AudioBuffer<float> displayBuffer;
CriticalSection displayBufferLock;

Next, add these methods

void copyFromDisplayBuffer(AudioBuffer<float>& copyToBuffer)
{
ScopedLock sl(displayBufferLock);
copyToBuffer.makeCopyOf(displayBuffer);
}

void copyToDisplayBuffer(AudioBuffer<float>& bufferToCopy)
{
ScopedLock sl(displayBufferLock);
displayBuffer.makeCopyOf(bufferToCopy);
}

In processBlock you call
copyToDisplayBuffer(buffer);

and in your editor run a timer:

void timerCallback()
{
AudioBuffer<float> displayBufferCopy;
audioProcessor.copyFromDisplayBuffer(displayBufferCopy);
audioVisualiserComponent.pushBuffer(displayBufferCopy);
}

Yes, I am using locks on the audio thread which is a no-no, but in this case I really know they will only be held for a short time and only perform simple copy operations.

Not only locks but also allocations in makeCopyOf…

The only good approach is a FIFO where you push the last audio samples into and read the last n samples from the FIFO for displaying from a timer.

1 Like

Yes, FIFO is always the best way. Not the easiest one to setup though.