Beginner Question: updating the editor with data from the processor?

Hello everyone,

I'm working on making a meter. I have the component class for it all fleshed out but am having trouble getting data to the actually meter.

bassically the meter has a buffer that is supposed to store data from the processor's audio buffer, and then use that to calculate which image to change to. That is all well and good. However i cant figure out how to constantly send data to the meter through it's addToBuffer(float num) method so that it can update the image.

 

I would really appreciate any help with this. This is a big stepping stone for me in learning how to work with GUIs in JUCE

Thanks in advance for your time!

 

Here are the files from my meter class:


class Meter1  : public Component
{
public:
    //==============================================================================
    Meter1 ();
    ~Meter1();
    //==============================================================================
    //[UserMethods]     -- You can add your own custom methods in this section.
    //[/UserMethods]


    void addToBuffer(float num);
    void changeImage(float num);


    void paint (Graphics& g);
    void resized();


    // Binary resources:
    static const char* meter_0_png;
    static const int meter_0_pngSize;
    static const char* meter_1_png;
    static const int meter_1_pngSize;
    static const char* meter_2_png;
    static const int meter_2_pngSize;
    static const char* meter_3_png;
    static const int meter_3_pngSize;
    static const char* meter_4_png;
    static const int meter_4_pngSize;
    static const char* meter_5_png;
    static const int meter_5_pngSize;
    static const char* meter_6_png;
    static const int meter_6_pngSize;
    static const char* meter_7_png;
    static const int meter_7_pngSize;
    static const char* meter_8_png;
    static const int meter_8_pngSize;
    static const char* meter_9_png;
    static const int meter_9_pngSize;
    static const char* meter_10_png;
    static const int meter_10_pngSize;
    static const char* meter_11_png;
    static const int meter_11_pngSize;
    static const char* meter_12_png;
    static const int meter_12_pngSize;
    static const char* meter_13_png;
    static const int meter_13_pngSize;
    static const char* meter_14_png;
    static const int meter_14_pngSize;
    static const char* meter_15_png;
    static const int meter_15_pngSize;
    static const char* meter_16_png;
    static const int meter_16_pngSize;
    static const char* meter_17_png;
    static const int meter_17_pngSize;
    static const char* meter_18_png;
    static const int meter_18_pngSize;
    static const char* meter_19_png;
    static const int meter_19_pngSize;

private:
    //[UserVariables]   -- You can add your own custom variables in this section.
    //[/UserVariables]
    //The main component
    ImageComponent *meter;
    std::vector<float> buffer;
    //Store all of the binary resources in a usable form
    Image image0, image1, image2, image3, image4, image5, image6, image7, image8, image9, image10;
    Image image11, image12, image13, image14, image15, image16, image17, image18, image19;
    //==============================================================================

    //==============================================================================
    JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Meter1)
};
 

 

#include "Meter1.h"


//[MiscUserDefs] You can add your own user definitions and misc code here...
//[/MiscUserDefs]

//==============================================================================
Meter1::Meter1 ()
{
    image0 = ImageCache::getFromMemory(meter_0_png, meter_0_pngSize);
    image1 = ImageCache::getFromMemory(meter_1_png, meter_1_pngSize);
    image2 = ImageCache::getFromMemory(meter_2_png, meter_2_pngSize);
    image3 = ImageCache::getFromMemory(meter_3_png, meter_3_pngSize);
    image4 = ImageCache::getFromMemory(meter_4_png, meter_4_pngSize);
    image5 = ImageCache::getFromMemory(meter_5_png, meter_5_pngSize);
    image6 = ImageCache::getFromMemory(meter_6_png, meter_6_pngSize);
    image7 = ImageCache::getFromMemory(meter_7_png, meter_7_pngSize);
    image8 = ImageCache::getFromMemory(meter_8_png, meter_8_pngSize);
    image9 = ImageCache::getFromMemory(meter_9_png, meter_9_pngSize);
    image10 = ImageCache::getFromMemory(meter_10_png, meter_10_pngSize);
    image11 = ImageCache::getFromMemory(meter_11_png, meter_11_pngSize);
    image12 = ImageCache::getFromMemory(meter_12_png, meter_12_pngSize);
    image13 = ImageCache::getFromMemory(meter_13_png, meter_13_pngSize);
    image14 = ImageCache::getFromMemory(meter_14_png, meter_14_pngSize);
    image15 = ImageCache::getFromMemory(meter_15_png, meter_15_pngSize);
    image16 = ImageCache::getFromMemory(meter_16_png, meter_16_pngSize);
    image17 = ImageCache::getFromMemory(meter_17_png, meter_17_pngSize);
    image18 = ImageCache::getFromMemory(meter_18_png, meter_18_pngSize);
    image19 = ImageCache::getFromMemory(meter_19_png, meter_19_pngSize);
    
    //[UserPreSize]
    //[/UserPreSize]
    meter = new ImageComponent();
    meter->setImage(image0);

    addAndMakeVisible(meter);
    setSize (100, 450);


    //[Constructor] You can add your own custom stuff here..
    //[/Constructor]
}

void Meter1::addToBuffer(float num){
    float avg = 0;
    int size = buffer.size();
    buffer.push_back(num);
    if (buffer.size() > 100){
        while(!buffer.empty()){
            avg = avg + buffer.back();
            buffer.pop_back();
        }
        avg = avg / size;
        changeImage(num);
    }

}

void Meter1::changeImage(float num){
    int newNum = num * 20;
    if (newNum > 20){
        newNum = 20;
    }

    switch (newNum){
    case 0: meter->setImage(image0);
        break;
    case 2: meter->setImage(image2);
        break;
    case 3: meter->setImage(image3);
        break;
    case 4: meter->setImage(image4);
        break;
    case 5: meter->setImage(image5);
        break;
    case 6: meter->setImage(image6);
        break;
    case 7: meter->setImage(image7);
        break;
    case 8: meter->setImage(image8);
        break;
    case 9: meter->setImage(image9);
        break;
    case 10: meter->setImage(image10);
        break;
    case 11: meter->setImage(image11);
        break;
    case 12: meter->setImage(image12);
        break;
    case 13: meter->setImage(image13);
        break;
    case 14: meter->setImage(image14);
        break;
    case 15: meter->setImage(image15);
        break;
    case 16: meter->setImage(image16);
        break;
    case 17: meter->setImage(image17);
        break;
    case 18: meter->setImage(image18);
        break;
    case 19: meter->setImage(image19);
        break;

    }
}

What kind of meter do you want? 
I've made a gain meter which only takes a single value.

A sub class of my signal processor sums up a number of samples and calculates a gain value over these values. So I have a gain value which gets updated every few milliseconds. (I set the number of samples I wan't to use for the value)
I've then created a timer in my editor which takes the gain value from the processor (just use a public function) and repaints an image based on the value. (Instead of swtich you could use an array of image pointers, I think this is more convenient.)

This approach works well because the actuall calculation is done in the processor the the value the editor takes is always a legit value. 

If you want to create an oscilloskop or a spectrum, things will get more complicated...

Thanks for the reply!

After reading your post, I looked into the timer class and looked over the plugin example. I realized it was exactly what I needed. The meter is now working exactly how I wanted it to. It's not perfect, but i'm sure a little tweaking can fix that. Also i'm going to look into your idea of using an array of image pointers.  I appreciatte the feedback!

1 Like