AudioDeviceManager level metering

Hello,

I would like to add output level metering (for each output channal separately) to the AudioDeviceManager. There is a build in inputLevelMeasurement, but no output level metering.

What would the best/clean way of achieving this?

I'm using the AudioDeviceManager like in the juce example project PluginHost).

Gilles

 

Hello,

I see that this is an old topic but I don’t want to add more and more topics. I read the docs for the Input and Output Level Meter from the juce docs and I don’t really understand how it is supposed to work with more than one channel?
Is it intended to be used for metering? I also don’t see if it’s peak or rms? Sorry once again I just have ??? in my head and don’t really understand how to get a level meter working for each of my in and output channels in my audio app.

Thanks in advance,

LAzzle

Hey,

just one more time, can somebody point me in the right direction here? I think I’ll go with buffers and get the level by that but I’m passing around my deviceManager also already, so I thought it could safe me some lines if I could use the deviceManager to get the level of the out or inputs of the selected soundcard.

Greetings,

Lazlo

It was mentioned somewhere else, that this LevelMeter was never intended to be used outside the AudioDeviceSelectorComponent.

I am afraid you have to write your own LevelMeter, or you could use my open source project

I haven’t worked on it for ages, but I think it still does the job.

1 Like

Thank you @daniel. I already draw a meter but I’m struggeling a bit to get the rmsLvl into my component. Maybe I didn’t made that clear. I felt it is so complicated to pass a copybuffer of the current audio channel into each of my meter components but I reasearched now pretty long and it appears that there is no other way than that. I thought the deviceManager could have access to the lvls of my Ins/Outs of the soundcard but as far as I collected informations it is not really possible. So I guess I will create copybuffers for each in and output from the bufferToFill and pass them to the lvl component. I just feel it is so much buffers and so much lines of code that I thought I’ll try investigating for a smarter approach.

You may calculate the RMS level in the processor and store them in std::atomic<float>. After that, the component can get those values without any thread-safety issues.
Furthermore, you may enable/disable RMS calculation in the editor constructor/destructor to avoid RMS calculation when editor is not open.

2 Likes

That sounds much easier! Thank you for the hint :slight_smile:
I already have in mind that I could use also my value tree to pass around the atomic to the appropriate meter. Will try that immediatly.

FWIW that’s exactly how the LevelMeter works I linked above :wink:

The LevelMeterSource holds a vector of ChannelDatas for each channel.

No need for a ValueTree IMHO.

Oh sorry @daniel I should have taken a closer look on your level meter.

But even if I use your lvl meter I have to pass in the floats from my audiobuffer somehow. I separated my frontend from my audio processing backend and I can’t access my components directly from my audio processing. Since I write an Audio App and not a plugin, I use the maincomponent as my Controller which takes care of the audio and components. I have a global valuetree to sync states eg user interaction or responses from the audiothread like transportsource finished playing etc…

My first intention was though to get the lvls right away from the devicemanager in a way that I only pass in the channel number and receive eg rms lvl or any lvl from which I can create the desired lvl meter.
But I understand now that this is not possible.

So my alternative approach is, that I have to pass either the buffer to the meter and to call then getRMSlvl() on the buffer for example or maybe get the lvl in my audioprocessing logic and pass that to the lvl meter component.
In my code the easiest would be to make use of the valuetree and just sync the lvl through the valuetree to the component.
So far that’s how I would try to solve the issue to pass the lvl to the meter.
But since you hinted me twice to your lvl meter I’m thinking maybe I’m going a wrong path to achieve what I want in my code. Is you’re lvl meter intended to use differently? Is there another approach I can go for?

No worries :slight_smile:

That is a great approach, best to keep things organised. That’s also why the module I linked has a LevelMeterSource (which gets fed the AudioBuffer in the procesBlock or getNextAudioBlock) and the LevelMeter, which is a Component and which needs a reference to the LevelMeterSource. That’s it.

It is totally fine to write your own, so you learn the most of it. Most likely you will end up with somehting very similar.

The usage is explained in the README:

Ahhhh that brings light into the dark !! Thank you so much! I’m a bit under preasure to show results and I have a selfwritten meter component so I just took a look at the source code and didn’t understand it completly. I’m so sorry that I didn’t get it right away. I should have really taken a closer look. My bad.

I never implemented code from somebody else but I think if I leave everything as it’s in github, with the license text, I should be fine isn’t? Just want to make it the right way :slight_smile:

Yes, license is as written there, in this case BSD v3.

But I don’t care too much about how it is used, I should maybe switch to MIT or even ISC.

Just copy and do what you want with it.

I added it as a module to my project in projucer. Now will play around with it. Thank you :slight_smile:

Now I also learned how to add third party modules to juce.

1 Like