



Hello everyone,
I have always had trouble with this, but it seems like such a trivial thing that I almost feel bad for posting this question.
I would like to simply have a meter for Peak and RMS with a label underneath each which reflects the value of said meter.
I.e. State 1 : Peak = -17.1 dB, RMS = -21.0 dB
State 2 : Peak = 3.1 dB, RMS = -0.2 dB
Obviously the unit text dB can be added. I have tried using AudioDetectors or just straight linking the output audio for each channel but this just hasn't worked for me thus far. As I have been exploring custom views and the advanced GUI section I noticed some custom options for the meters in the code files so I was wondering if what I want to do requires something custom.. but I feel like I am just being stupid and over complicating things but I can't seem to get the results I am after.
C.


There must be something quite fundamental I am missing. I am using the medanalogvumeter with the 0dB frame set as 52 / 80 and the custom view set as the default AnalogMeterView_H65_Z52.
It appears that the 0dB mark is actually hitting at the end of the meter @3dB. I have attached an image :
https://drive.google.com/file/d/1sMvYzrX0wnc9Bo9Cj30atXoWJovkD_gU/view?usp=sharing
I am just exploring a way to display peak as per above. I was starting to look into writing custom stuff under the advanced GUI stuff to create a label for this but thought it should be as simple as linking a meter to the text label. This led me to this scenario in which I MUST be doing something stupidly wrong.
Any suggestions would be appreciated, I cannot find anything in the book or online that uses this.
C.


This is literally all I would like to achieve. I thought that using an audio detector in DB linked to a label would work.
https://drive.google.com/file/d/1Fqwgbt8sys_0CUPRAwtX6f0FtuMGYahR/view?usp=sharing


Hey Chaes,
You can get this functionality using the CVUMeter base class. I think it's the only GUI component (apart from Will's custom WaveViews) which updates on each screen refresh.
To do this though you'll need to create a new inherited class that overrides the draw functionality of that object.
Achieving that may require a separate thread.
Off the bat though you could try directly commenting out the code in Will's CVUMeterEx in customcontrols.cpp and replacing for this;
UTF8String s; // declares a string named s
s = toString( getValue()) + "db"; // gets the value - clipped to 0-1 unfortunately, appends to the string the letters db
CRect r = (getViewSize()); //declares a rectangle the size of the view
CFontRef fntt = new CFontDesc("Arial", 12); /// since the meter has no font select in the VSTGUI interface we manually choose it
pContext->setFillColor(kBlackCColor); // checkout the CColor object for more control
float t = s.length()*.25f; // compensates the text length
float h = fntt->getSize(); // compensates the font height
CGraphicsTransform transf; // declares a transform. The only way to reposition text from (0,0)
transf.translate(r.getCenter().x - (h*t), r.getBottomCenter().y - (h)); // calls the transforms translate function to center the text within the view
CDrawContext::Transform transp(*pContext, transf); // actually applies the centering
pContext->drawGraphicsPath(pContext->createTextPath(fntt, s), CDrawContext::kPathFilled); // draws it up
setDirty(false);
best luck


Thanks Jim, I will look into this! I don't like the look of the clipped to 0-1 haha. as I need to show -60 to 60 dB... But if this is the case can this be applied as a custom view to a label? Because ignoring the fact the analog seems a bit iffy on my computer. Its the labels which are giving me the biggest issue.


Yo, + 60db has a peak to peak value of 1000.0 which is pretty extreme, but you can simply scale down the input and rescale the output up by 1000 if that's the case.
Look into gain factor conversions if you haven't already done so volume in db's = 20 * log10( gain ratio ).
A label won't refresh it's state without GUI interaction as far as I'm aware. Otherwise that previous code I posted would work for this purpose.
The code above rewrites the meter view to have pretty much all of the functionality of the label view minus the menu based font selection.
The strategy would be to create this as an overwritten meter object ready to use whenever you just want a real-time readout.
You can use ENVELOPE_DETECT_MODE_NONE and kLinearMeter in the piParam section, if you want to do all your own math on the readout for potential other use.
Cheers




So the bottom line is that I cannot simply create a Label, make an audio detector set to Log mode (dB) and set its output to the label so that it measures the level of the outgoing audio as a dB value -60db to + whatever dB.
It requires a custom class / view? Seems crazy to me that a label cannot take the reading of the non normalised meter reading! I will have to look into the inheritance and CPP more!
I am going to look at the dirty led project and see if that can help me make my label work in db levels.
If it needs to be connected to a meter.. in theory it makes sense to me to connect it to a AnalogMeter as it should go above 0, which is seen in rackafx, but this doesnt seem to be the case for me when I put the class in.....


Has anyone been able to get the Analog Meters working for ASPiK or inside RACKAFX like the ones on the side of rackafx? It actually going over 0 db accurately etc? I have followed over the documentation multiple times and experimented and it always acts the same as bar meter, 0 dB being at the top?


So taking what Jim said;
I have for now replaced the draw function inside the VuMeterEx inside 'Customcontrols.cpp'
UTF8String s; // declares a string named s
float xt = getValue();
//--- convert to dB
float yt = 20 * log10(xt * 100);
//--- perform 00.00 String instead of 00.00000000000
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << yt;
s = stream.str();
CRect r = (getViewSize()); //declares a rectangle the size of the view
CFontRef fntt = new CFontDesc("Arial", 12); /// since the meter has no font select in the VSTGUI interface we manually choose it
_pContext->setFillColor(kBlackCColor); // checkout the CColor object for more control
float t = s.length() * .25f; // compensates the text length
float h = fntt->getSize(); // compensates the font height
CGraphicsTransform transf; // declares a transform. The only way to reposition text from (0,0)
transf.translate(r.getCenter().x - (h * t), r.getBottomCenter().y - (h)); // calls the transforms translate function to center the text within the view
CDrawContext::Transform transp(*_pContext, transf); // actually applies the centering
_pContext->drawGraphicsPath(_pContext->createTextPath(fntt, s), CDrawContext::kPathFilled); // draws it up
setDirty(false);
Which gives me a readout yay. I scale up the input then convert to db.
Next:
I scaled out output into the meter inside 'Plugincore.cpp', I scaled it by 100.
// --- VU metering
leftVUMeterIn = processFrameInfo.audioInputFrame[0]/100;
leftVUMeterOut = processFrameInfo.audioOutputFrame[0]/100;
The next thing I need to do is figure out how to display the generally highest level over a certain time. I currently cant read the output as it changes so fast as it oscillates. I next have to figure out how to add ballistics. I am not sure if I need to add something extra in 'plugingui.cpp' to do stuff there like thew others under custom views line 1945 and below.
I think for the RMS and even the Peak I need something like this;
float* channelData = buffer.getWritePointer(0); < replace this for buffer
float sum = 0.0;
float totalSum = 0.0;
for (int i = 0; i < buffer.getNumSamples(); i++) < number of samples inside the buffer
{
float sample = channelData[i];
sum += sample * sample;
}
for (int i = 0; i < 100; i++)
{
if (i < 99) {
sumVector[i] = sumVector[i + 1];
}
else {
sumVector[99] = sum;
}
totalSum += sumVector[i];
}
rmsLevel = std::sqrt(totalSum / (buffer.getNumSamples() * 100));
I think the ideal way to call this would be to call it in the post buffer and perform the RMS calculation on all of the samples in that buffer. For peak it would be a matter of performing some form of max, min either side of the 0 dB mark, (+-), but I am unsure how cpp/buffers completely work atm.
The last thing I need to figure out is how to create this as something I can add to meters as and when I need to and to provide a custom font / sizing for each instance.
I will update this post as I discover more. I am surprised this has not come up before!
C.




Hi Chaes,
I'm really glad you've got things working out there. Great work. Customizing views is the definitely way to go. I've also been updating all my views to be drawn in vector graphics rather than .bmp's, its pretty fun/way cooler.
Anyway I have to apologise for giving you some pretty shoddy code earlier by not deleting the new pointer instance.
I'd highly recommend removing these four lines;
CGraphicsTransform transf; // declares a transform. The only way to reposition text from (0,0)
transf.translate(r.getCenter().x - (h*t), r.getBottomCenter().y - (h)); // calls the transforms translate function to center the text within the view
CDrawContext::Transform transp(*pContext, transf); // actually applies the centering
pContext->drawGraphicsPath(pContext->createTextPath(fntt, s), CDrawContext::kPathFilled); // draws it up
and replacing with these three
const CPoint pnt(r.getCenter().x - .5*t , r.getCenter().y - .5*h); // point to draw the text
pContext->drawString(g, pnt, true); //draws the string
delete fntt; // because of the new command
Still probably not doing that right but at least this doesn't have the potential to crash out your compy.
Cheers,
James


//--- convert to dB
float yt = 20 * log10(getMaxPeak() * 100);
I used this but for some reason it is centred on the mac, but is clipped off the top on windows. Anyone know if you can shift a font down? Im using CTextButton for this..
//--- perform 00.00 String instead of 00.00000000000
std::stringstream stream;
stream << std::fixed << std::setprecision(1) << yt;
s = stream.str():
bool highlight = value > 0.5 ? true : false;
context->setDrawMode(kAntiAliasing);
context->setLineWidth(frameWidth);
CRect r = (getViewSize()); //declares a rectangle the size of the view
//float t = s.length() *.25f; // compensates the text length
//float h = getFont()->getSize(); // compensates the font height
CBitmap* iconToDraw = highlight ? (iconHighlighted ? iconHighlighted : icon) : (icon ? icon : iconHighlighted);
CDrawMethods::drawIconAndText(context, iconToDraw, iconPosition, getTextAlignment(), getTextMargin(), r, s, getFont(), highlight ? getTextColorHighlighted() : getTextColor());
setDirty(false);
Most Users Ever Online: 152
Currently Online:
6 Guest(s)
Currently Browsing this Page:
1 Guest(s)
Top Posters:
Chaes: 49
Skyler: 48
Derek: 46
Frodson: 45
Peter: 43
TheSmile: 43
clau_ste: 39
jim: 34
JimmyM: 33
Gwen: 32
Member Stats:
Guest Posters: 1
Members: 677
Moderators: 1
Admins: 5
Forum Stats:
Groups: 13
Forums: 41
Topics: 740
Posts: 2835
Newest Members:
bmarx, Tom Helvey, Ludovic, Mihir Shah, Mina, robbie, Matteo Desantis, jacobwotson, Nowhk, reynaldo_fmModerators: W Pirkle: 550
Administrators: Tom: 74, JD Young: 80, Will Pirkle: 0, W Pirkle: 550, VariableCook: 3