1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-09-16 16:20:50 +02:00

Made the original peak/rms meter design selectable as suggested by Gale.

It can be selected in the meter preferences.
This commit is contained in:
lllucius 2014-10-04 09:47:48 +00:00
parent 62e3467b7d
commit 96417b912e
2 changed files with 198 additions and 90 deletions

View File

@ -225,6 +225,7 @@ Meter::Meter(wxWindow* parent, wxWindowID id,
mWidth(size.x), mHeight(size.y), mWidth(size.x), mHeight(size.y),
mIsInput(isInput), mIsInput(isInput),
mStyle(style), mStyle(style),
mGradient(true),
mDB(true), mDB(true),
mDBRange(ENV_DB_RANGE), mDBRange(ENV_DB_RANGE),
mDecay(true), mDecay(true),
@ -353,6 +354,7 @@ void Meter::UpdatePrefs()
mStyle = gPrefs->Read(wxT("/Meter/MeterStyle"), wxT("HorizontalStereo")) == wxT("HorizontalStereo") ? mStyle = gPrefs->Read(wxT("/Meter/MeterStyle"), wxT("HorizontalStereo")) == wxT("HorizontalStereo") ?
HorizontalStereo : HorizontalStereo :
VerticalStereo; VerticalStereo;
mGradient = gPrefs->Read(wxT("/Meter/MeterBars"), wxT("Gradient")) == wxT("Gradient");
mDB = gPrefs->Read(wxT("/Meter/MeterType"), wxT("dB")) == wxT("dB"); mDB = gPrefs->Read(wxT("/Meter/MeterType"), wxT("dB")) == wxT("dB");
if (mIsInput) if (mIsInput)
@ -875,9 +877,9 @@ void Meter::HandleLayout(wxDC &dc)
} }
mRuler.SetOrientation(wxVERTICAL); mRuler.SetOrientation(wxVERTICAL);
mRuler.SetBounds(mBar[1].r.x + mBar[1].r.width + 1, mRuler.SetBounds(mBar[1].r.x + mBar[1].r.width + 1,
mBar[1].r.y, mBar[1].r.y + 1,
mBar[1].r.x + width, mBar[1].r.x + width,
mBar[1].r.y + mBar[1].r.height); mBar[1].r.y + mBar[1].r.height - 1);
if (mDB) { if (mDB) {
mRuler.SetRange(0, -mDBRange); mRuler.SetRange(0, -mDBRange);
mRuler.SetFormat(Ruler::LinearDBFormat); mRuler.SetFormat(Ruler::LinearDBFormat);
@ -1051,54 +1053,57 @@ void Meter::HandlePaint(wxDC &destDC)
// Cache bar rect // Cache bar rect
wxRect r = mBar[i].r; wxRect r = mBar[i].r;
// Calculate the size of the two gradiant segments of the meter if (mGradient)
double gradw;
double gradh;
if (mDB)
{ {
gradw = (double) r.GetWidth() / mDBRange * 6.0; // Calculate the size of the two gradiant segments of the meter
gradh = (double) r.GetHeight() / mDBRange * 6.0; double gradw;
} double gradh;
else if (mDB)
{ {
gradw = (double) r.GetWidth() / 100 * 25; gradw = (double) r.GetWidth() / mDBRange * 6.0;
gradh = (double) r.GetHeight() / 100 * 25; gradh = (double) r.GetHeight() / mDBRange * 6.0;
} }
else
{
gradw = (double) r.GetWidth() / 100 * 25;
gradh = (double) r.GetHeight() / 100 * 25;
}
if (mBar[i].vert) if (mBar[i].vert)
{ {
// Draw the "critical" segment (starts at top of meter and works down) // Draw the "critical" segment (starts at top of meter and works down)
r.SetHeight(gradh); r.SetHeight(gradh);
dc.GradientFillLinear(r, red, yellow, wxSOUTH); dc.GradientFillLinear(r, red, yellow, wxSOUTH);
// Draw the "warning" segment // Draw the "warning" segment
r.SetTop(r.GetBottom()); r.SetTop(r.GetBottom());
dc.GradientFillLinear(r, yellow, green, wxSOUTH); dc.GradientFillLinear(r, yellow, green, wxSOUTH);
// Draw the "safe" segment // Draw the "safe" segment
r.SetTop(r.GetBottom()); r.SetTop(r.GetBottom());
r.SetBottom(mBar[i].r.GetBottom()); r.SetBottom(mBar[i].r.GetBottom());
dc.SetPen(*wxTRANSPARENT_PEN); dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(green); dc.SetBrush(green);
dc.DrawRectangle(r); dc.DrawRectangle(r);
} }
else else
{ {
// Draw the "safe" segment // Draw the "safe" segment
r.SetWidth(r.GetWidth() - (int) (gradw + gradw + 0.5)); r.SetWidth(r.GetWidth() - (int) (gradw + gradw + 0.5));
dc.SetPen(*wxTRANSPARENT_PEN); dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(green); dc.SetBrush(green);
dc.DrawRectangle(r); dc.DrawRectangle(r);
// Draw the "warning" segment // Draw the "warning" segment
r.SetLeft(r.GetRight() + 1); r.SetLeft(r.GetRight() + 1);
r.SetWidth(floor(gradw)); r.SetWidth(floor(gradw));
dc.GradientFillLinear(r, green, yellow); dc.GradientFillLinear(r, green, yellow);
// Draw the "critical" segment // Draw the "critical" segment
r.SetLeft(r.GetRight() + 1); r.SetLeft(r.GetRight() + 1);
r.SetRight(mBar[i].r.GetRight()); r.SetRight(mBar[i].r.GetRight());
dc.GradientFillLinear(r, yellow, red); dc.GradientFillLinear(r, yellow, red);
}
} }
// Give it a recessed look // Give it a recessed look
@ -1133,12 +1138,12 @@ void Meter::RepaintBarsNow()
void Meter::DrawMeterBar(wxDC &dc, MeterBar *meterBar) void Meter::DrawMeterBar(wxDC &dc, MeterBar *meterBar)
{ {
// Cache some metrics // Cache some metrics (and adjust to be inside the bevel)
wxRect r = meterBar->r; wxRect r = meterBar->r;
wxCoord x = r.GetLeft(); wxCoord x = r.GetLeft() + 1;
wxCoord y = r.GetTop(); wxCoord y = r.GetTop() + 1;
wxCoord w = r.GetWidth(); wxCoord w = r.GetWidth() - 1;
wxCoord h = r.GetHeight(); wxCoord h = r.GetHeight() - 1;
// Map the predrawn bitmap into the source DC // Map the predrawn bitmap into the source DC
wxMemoryDC srcDC; wxMemoryDC srcDC;
@ -1148,52 +1153,135 @@ void Meter::DrawMeterBar(wxDC &dc, MeterBar *meterBar)
dc.SetPen(*wxTRANSPARENT_PEN); dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(mBkgndBrush); dc.SetBrush(mBkgndBrush);
if (meterBar->vert) int ht;
int wd;
if (mGradient)
{ {
// Copy as much of the predrawn meter bar as is required for the if (meterBar->vert)
// current peak.
int ht = (int)(meterBar->peak * h + 0.5);
dc.Blit(x, y + h - ht, w, ht, &srcDC, x, y + h - ht);
// Blank out the rest
dc.DrawRectangle(x + 1, y, w - 1, y + h - ht);
// Draw the "recent" peak hold line using the predrawn meter bar so that
// it will be the same color as the original level.
ht = (int)(meterBar->peakHold * h + 0.5);
dc.Blit(x, y + h - ht, w, 2, &srcDC, x, y + h - ht);
// Draw the "maximum" peak hold line using a themed color.
dc.SetPen(mPeakPeakPen);
ht = (int)(meterBar->peakPeakHold * r.height + 0.5);
AColor::Line(dc, x + 1, y + h - ht, x + w - 1, y + h - ht);
if (ht > 1)
{ {
AColor::Line(dc, x + 1, y + h - ht + 1, x + w - 1, y + h - ht + 1); // Copy as much of the predrawn meter bar as is required for the
// current peak.
ht = (int)(meterBar->peak * h + 0.5);
dc.Blit(x, y + h - ht, w, ht, &srcDC, x, y + h - ht);
// Blank out the rest
dc.DrawRectangle(x, y, w, y + h - ht);
// Draw the "recent" peak hold line using the predrawn meter bar so that
// it will be the same color as the original level.
ht = (int)(meterBar->peakHold * h + 0.5);
dc.Blit(x, y + h - ht - 1, w, 2, &srcDC, x, y + h - ht - 1);
// Draw the "maximum" peak hold line
dc.SetPen(mPeakPeakPen);
ht = (int)(meterBar->peakPeakHold * h + 0.5);
AColor::Line(dc, x, y + h - ht - 1, x + w - 1, y + h - ht - 1);
if (ht > 1)
{
AColor::Line(dc, x, y + h - ht, x + w - 1, y + h - ht);
}
}
else
{
// Copy as much of the predrawn meter bar as is required for the
// current peak.
wd = (int)(meterBar->peak * w + 0.5);
dc.Blit(x, y, wd, h, &srcDC, x, y);
// Blank out the rest
dc.DrawRectangle(x + wd, y, w - wd, h);
// Draw the "recent" peak hold line using the predrawn meter bar so that
// it will be the same color as the original level.
wd = (int)(meterBar->peakHold * w + 0.5);
dc.Blit(wd, y, 2, h, &srcDC, wd, y);
// Draw the "maximum" peak hold line using a themed color.
dc.SetPen(mPeakPeakPen);
wd = (int)(meterBar->peakPeakHold * w + 0.5);
AColor::Line(dc, x + wd, y, x + wd, y + h - 1);
if (wd > 1)
{
AColor::Line(dc, x + wd - 1, y, x + wd - 1, y + h - 1);
}
} }
} }
else { else
// Copy as much of the predrawn meter bar as is required for the {
// current peak. wxRect rRMS;
int wd = (int)(meterBar->peak * w + 0.5);
dc.Blit(x, y, wd, h, &srcDC, x, y);
// Blank out the rest if (meterBar->vert)
dc.DrawRectangle(x + wd, y + 1, w - wd, h - 1);
// Draw the "recent" peak hold line using the predrawn meter bar so that
// it will be the same color as the original level.
wd = (int)(meterBar->peakHold * w + 0.5);
dc.Blit(wd, y + 1, 2, h, &srcDC, wd, y + 1);
// Draw the "maximum" peak hold line using a themed color.
dc.SetPen(mPeakPeakPen);
wd = (int)(meterBar->peakPeakHold * w + 0.5);
AColor::Line(dc, x + wd, y + 1, x + wd, y + h - 1);
if (wd > 1)
{ {
AColor::Line(dc, x + wd - 1, y + 1, x + wd - 1, y + h - 1); // Calculate the peak and rms rectangles
// (+1 and -1 to not overlay the bevel)
ht = (int)(meterBar->peak * h + 0.5);
r = wxRect(x, y + h - ht, w, ht);
ht = (int)(meterBar->rms * h + 0.5);
rRMS = wxRect(x, y + h - ht, w, ht);
// Blank out the rest
dc.DrawRectangle(x, y, w, y + h - ht);
// Reset the colors
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.SetPen(mPen);
// Draw the "recent" peak hold line
int ht = (int)(meterBar->peakHold * h + 0.5);
AColor::Line(dc, x, y + h - ht - 1, x + w - 1, y + h - ht - 1);
if (ht > 1)
{
AColor::Line(dc, x, y + h - ht - 1, x + w - 1, y + h - ht);
}
// Draw the "maximum" peak hold line
dc.SetPen(mPeakPeakPen);
ht = (int)(meterBar->peakPeakHold * h + 0.5);
AColor::Line(dc, x, y + h - ht - 1, x + w - 1, y + h - ht - 1);
if (ht > 1)
{
AColor::Line(dc, x, y + h - ht, x + w - 1, y + h - ht);
}
} }
else
{
// Calculate the peak and rms rectangles
wd = (int)(meterBar->peak * w + 0.5);
r = wxRect(x, y, wd, h);
wd = (int)(meterBar->rms * w + 0.5);
rRMS = wxRect(x, y, wd, h);
// Blank out the rest
dc.DrawRectangle(x + wd, y, w, h);
// Reset the colors
dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.SetPen(mPen);
// Draw the "recent" peak hold line
wd = (int)(meterBar->peakHold * w + 0.5);
AColor::Line(dc, x + wd, y, x + wd, y + h - 1);
if (wd > 1)
{
AColor::Line(dc, x + wd - 1, y, x + wd - 1, y + h - 1);
}
// Draw the "maximum" peak hold line using a themed color
dc.SetPen(mPeakPeakPen);
wd = (int)(meterBar->peakPeakHold * w + 0.5);
AColor::Line(dc, x + wd, y, x + wd, y + h - 1);
if (wd > 1)
{
AColor::Line(dc, x + wd - 1, y, x + wd - 1, y + h - 1);
}
}
// Draw the peak and rms levels
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(mBrush);
dc.DrawRectangle(r);
dc.SetBrush(mRMSBrush);
dc.DrawRectangle(rRMS);
} }
// If meter had a clipping indicator, draw or erase it // If meter had a clipping indicator, draw or erase it
@ -1374,6 +1462,8 @@ void Meter::OnFloat(wxCommandEvent & WXUNUSED(event))
void Meter::OnPreferences(wxCommandEvent & WXUNUSED(event)) void Meter::OnPreferences(wxCommandEvent & WXUNUSED(event))
{ {
wxTextCtrl *rate; wxTextCtrl *rate;
wxRadioButton *gradient;
wxRadioButton *rms;
wxRadioButton *db; wxRadioButton *db;
wxRadioButton *linear; wxRadioButton *linear;
wxRadioButton *horizontal; wxRadioButton *horizontal;
@ -1383,7 +1473,7 @@ void Meter::OnPreferences(wxCommandEvent & WXUNUSED(event))
ShuttleGui S(&dlg, eIsCreating); ShuttleGui S(&dlg, eIsCreating);
S.StartVerticalLay(); S.StartVerticalLay();
{ {
S.StartStatic(_("Refresh Rate"), 1); S.StartStatic(_("Refresh Rate"), 0);
{ {
S.AddFixedText(_("Higher refresh rates make the meter show more frequent\nchanges. A rate of 30 per second or less should prevent\nthe meter affecting audio quality on slower machines.")); S.AddFixedText(_("Higher refresh rates make the meter show more frequent\nchanges. A rate of 30 per second or less should prevent\nthe meter affecting audio quality on slower machines."));
S.StartHorizontalLay(); S.StartHorizontalLay();
@ -1400,7 +1490,23 @@ void Meter::OnPreferences(wxCommandEvent & WXUNUSED(event))
} }
S.EndStatic(); S.EndStatic();
S.StartStatic(_("Meter Style"), 1); S.StartStatic(_("Meter Style"), 0);
{
S.StartVerticalLay();
{
gradient = S.AddRadioButton(_("Gradient"));
gradient->SetName(_("Gradient"));
gradient->SetValue(mGradient);
rms = S.AddRadioButtonToGroup(_("RMS"));
rms->SetName(_("RMS"));
rms->SetValue(!mGradient);
}
S.EndVerticalLay();
}
S.EndStatic();
S.StartStatic(_("Meter Type"), 0);
{ {
S.StartVerticalLay(); S.StartVerticalLay();
{ {
@ -1442,6 +1548,7 @@ void Meter::OnPreferences(wxCommandEvent & WXUNUSED(event))
{ {
gPrefs->Write(wxT("/Meter/MeterRefreshRate"), mMeterRefreshRate); gPrefs->Write(wxT("/Meter/MeterRefreshRate"), mMeterRefreshRate);
gPrefs->Write(wxT("/Meter/MeterStyle"), horizontal->GetValue() ? wxT("HorizontalStereo") : wxT("VerticalStereo")); gPrefs->Write(wxT("/Meter/MeterStyle"), horizontal->GetValue() ? wxT("HorizontalStereo") : wxT("VerticalStereo"));
gPrefs->Write(wxT("/Meter/MeterBars"), gradient->GetValue() ? wxT("Gradient") : wxT("RMS"));
gPrefs->Write(wxT("/Meter/MeterType"), db->GetValue() ? wxT("dB") : wxT("Linear")); gPrefs->Write(wxT("/Meter/MeterType"), db->GetValue() ? wxT("dB") : wxT("Linear"));
gPrefs->Flush(); gPrefs->Flush();

View File

@ -219,6 +219,7 @@ class Meter : public wxPanel
bool mIsInput; bool mIsInput;
Style mStyle, mSavedStyle; Style mStyle, mSavedStyle;
bool mGradient;
bool mDB; bool mDB;
int mDBRange; int mDBRange;
bool mDecay; bool mDecay;