/*
- Copyright (C) 2013 Paul Davis
- Author: Robin Gareus
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
+ * Copyright (C) 2013-2019 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2014-2016 Paul Davis <paul@linuxaudiosystems.com>
+ * Copyright (C) 2015 Tim Mayberry <mojofunk@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <gtkmm/drawingarea.h>
#include <gtkmm2ext/cairo_widget.h>
#include <gtkmm2ext/gtk_ui.h>
#include <gtkmm2ext/utils.h>
#include <gtkmm2ext/rgb_macros.h>
+#include "ardour/logmeter.h"
#include <ardour/rc_configuration.h>
-#include "ardour_ui.h"
+
#include "utils.h"
-#include "logmeter.h"
#include "meter_patterns.h"
+#include "ui_config.h"
-#include "i18n.h"
+#include "pbd/i18n.h"
using namespace ARDOUR;
using namespace ARDOUR_UI_UTILS;
{
switch (mt) {
case MeterPeak:
- return _("Peak");
+ return _("Peak (+6dBFS)");
+ break;
+ case MeterPeak0dB:
+ return _("Peak (0dBFS)");
break;
case MeterKrms:
return _("RMS + Peak");
return _("IEC2/EBU");
break;
case MeterK20:
- return _("K20");
+ return _("K20/RMS");
break;
case MeterK14:
- return _("K14");
+ return _("K14/RMS");
break;
case MeterK12:
- return _("K12");
+ return _("K12/RMS");
break;
case MeterVU:
return _("VU");
break;
default:
+ assert(0);
return _("???");
break;
}
cairo_set_source_rgb (cr, c->get_red_p(), c->get_green_p(), c->get_blue_p());
}
break;
+ case MeterPeak0dB:
+ fraction = log_meter0dB (val);
+ if (val >= 0 || val == -9) {
+ cairo_set_source_rgb (cr,
+ UINT_RGBA_R_FLT(peakcolor),
+ UINT_RGBA_G_FLT(peakcolor),
+ UINT_RGBA_B_FLT(peakcolor));
+ } else {
+ cairo_set_source_rgb (cr, c->get_red_p(), c->get_green_p(), c->get_blue_p());
+ }
+ break;
case MeterIEC2BBC:
case MeterIEC2EBU:
fraction = meter_deflect_ppm(val);
cairo_fill (cr);
}
-static void set_bg_color(Gtk::Widget& w, cairo_t* cr, MeterType type) {
- float r,g,b;
+static void set_bg_color (Gtk::Widget& w, cairo_t* cr, MeterType type) {
+ double r,g,b,a;
switch(type) {
case MeterVU:
- if (rgba_p_from_style("meterstripVU", &r, &g, &b, "bg")) {
- cairo_set_source_rgb (cr, r, g, b);
- } else {
- cairo_set_source_rgb (cr, 1.0, 1.0, 0.85);
- }
+ Gtkmm2ext::color_to_rgba (UIConfiguration::instance().color ("meterstrip vu bg"), r, g, b, a);
break;
case MeterIEC1DIN:
case MeterIEC1NOR:
case MeterIEC2BBC:
case MeterIEC2EBU:
+ Gtkmm2ext::color_to_rgba (UIConfiguration::instance().color ("meterstrip ppm bg"), r, g, b, a);
+ break;
case MeterK12:
case MeterK14:
case MeterK20:
- if (rgba_p_from_style("meterstripPPM", &r, &g, &b, "bg")) {
- cairo_set_source_rgb (cr, r, g, b);
- } else {
- cairo_set_source_rgb (cr, 0.1, 0.1, 0.1);
- }
+ Gtkmm2ext::color_to_rgba (UIConfiguration::instance().color ("meterstrip dpm bg"), r, g, b, a);
break;
default:
{
Gdk::Color c = w.get_style()->get_bg (Gtk::STATE_ACTIVE);
- cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p());
+ r = c.get_red_p();
+ g = c.get_green_p();
+ b = c.get_blue_p();
}
break;
}
+ cairo_set_source_rgb (cr, r, g, b);
}
static void set_fg_color(Gtk::Widget&, MeterType type, Gdk::Color * c) {
- float r,g,b;
+ double r,g,b,a;
switch(type) {
case MeterVU:
- if (rgba_p_from_style("meterstripVU", &r, &g, &b)) {
- c->set_rgb_p(r, g, b);
- } else {
- c->set_rgb_p(0.0, 0.0, 0.0);
- }
+ Gtkmm2ext::color_to_rgba (UIConfiguration::instance().color ("meterstrip vu fg"), r, g, b, a);
+ break;
+ case MeterIEC1DIN:
+ case MeterIEC1NOR:
+ case MeterIEC2BBC:
+ case MeterIEC2EBU:
+ Gtkmm2ext::color_to_rgba (UIConfiguration::instance().color ("meterstrip ppm fg"), r, g, b, a);
break;
default:
- if (rgba_p_from_style("meterstripPPM", &r, &g, &b)) {
- c->set_rgb_p(r, g, b);
- } else {
- c->set_rgb_p(1.0, 1.0, 1.0);
- }
+ Gtkmm2ext::color_to_rgba (UIConfiguration::instance().color ("meterstrip dpm fg"), r, g, b, a);
break;
}
+ c->set_rgb_p (r, g, b);
}
static cairo_pattern_t*
float box_l=0;
float box_w=0;
+#define PX_SCALE(pxmin, dflt) rint(std::max((double)pxmin, (double)dflt * UIConfiguration::instance().get_ui_scale()))
if (tickleft) {
if (w.get_name().substr(0, 3) == "Bar") {
- box_l = width-2; box_w = 2;
+ box_w = PX_SCALE(2, 2);
+ box_l = width - box_w;
} else if (w.get_name().substr(0, 4) == "Mark") {
- box_l = width-2; box_w = 2;
+ box_w = PX_SCALE(2, 2);
+ box_l = width - box_w;
background = false;
}
} else if (tickright) {
if (w.get_name().substr(0, 3) == "Bar") {
- box_l = 0; box_w = 2;
+ box_l = 0; box_w = PX_SCALE(2, 2);
} else if (w.get_name().substr(0, 4) == "Mark") {
- box_l = 0; box_w = 2;
+ box_l = 0; box_w = PX_SCALE(2, 2);
background = false;
}
} else {
- box_l = 0; box_w = 3;
+ box_l = 0; box_w = width;
}
+#undef PX_SCALE
cairo_surface_t* surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
cairo_t* cr = cairo_create (surface);
cairo_fill (cr);
height = min(max_pattern_metric_size, height);
- uint32_t peakcolor = ARDOUR_UI::config()->color_by_name ("meterbridge peaklabel");
+ uint32_t peakcolor = UIConfiguration::instance().color ("meterbridge peaklabel");
for (vector<DataType>::const_iterator i = types.begin(); i != types.end(); ++i) {
break;
default:
+ points.insert (std::pair<float,float>( 0, 1.0));
+ points.insert (std::pair<float,float>( 1, 0.5));
+ points.insert (std::pair<float,float>( 2, 0.5));
+ points.insert (std::pair<float,float>( 3, 1.0));
+ points.insert (std::pair<float,float>( 4, 0.5));
+ points.insert (std::pair<float,float>( 5, 0.5));
+ /* fallthrough */
+ case MeterPeak0dB:
points.insert (std::pair<float,float>(-60, 0.5));
points.insert (std::pair<float,float>(-50, 1.0));
points.insert (std::pair<float,float>(-40, 1.0));
points.insert (std::pair<float,float>(-30, 1.0));
- if (Config->get_meter_line_up_level() == MeteringLineUp24) {
+ if (UIConfiguration::instance().get_meter_line_up_level() == MeteringLineUp24) {
points.insert (std::pair<float,float>(-24, 1.0));
} else {
points.insert (std::pair<float,float>(-25, 1.0));
points.insert (std::pair<float,float>( -3, 1.0));
points.insert (std::pair<float,float>( -2, 0.5));
points.insert (std::pair<float,float>( -1, 0.5));
-
- points.insert (std::pair<float,float>( 0, 1.0));
- points.insert (std::pair<float,float>( 1, 0.5));
- points.insert (std::pair<float,float>( 2, 0.5));
- points.insert (std::pair<float,float>( 3, 1.0));
- points.insert (std::pair<float,float>( 4, 0.5));
- points.insert (std::pair<float,float>( 5, 0.5));
break;
}
break;
pos = height - (gint) floor (height * fraction);
pos = max (pos, 1);
cairo_move_to(cr, 0, pos + .5);
- cairo_line_to(cr, 3, pos + .5);
+ cairo_line_to(cr, width, pos + .5);
cairo_stroke (cr);
break;
case DataType::MIDI:
pos = 1 + height - (gint) floor (height * fraction);
pos = min (pos, height);
cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p());
- cairo_arc(cr, 1.5, pos + .5, 1.0, 0, 2 * M_PI);
+ cairo_arc(cr, width * .5, pos + .5, 1.0, 0, 2 * M_PI);
cairo_fill(cr);
break;
}
tickright = true;
}
+#ifdef NO_OVERSAMPLE
cairo_surface_t* surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
cairo_t* cr = cairo_create (surface);
+#else
+ cairo_surface_t* surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width*2, height*2);
+ cairo_t* cr = cairo_create (surface);
+ cairo_scale(cr, 2.0, 2.0);
+#endif
Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create(w.get_pango_context());
Pango::AttrList audio_font_attributes;
Pango::AttrFontDesc* font_attr;
Pango::FontDescription font;
- font = Pango::FontDescription (ARDOUR_UI::config()->get_canvasvar_SmallMonospaceFont());
- double fixfontsize = 81920.0 / (double) ARDOUR::Config->get_font_scale();
+ font = Pango::FontDescription (UIConfiguration::instance().get_SmallMonospaceFont());
+#ifdef __APPLE__
+ const double fixfontsize = 1.0;
+#else
+ // counter-act global font-scaling.
+ const double fixfontsize = std::min(1.0, 0.9 / sqrtf(UIConfiguration::instance().get_ui_scale()));
+#endif
font.set_weight (Pango::WEIGHT_NORMAL);
- font.set_size (9.0 * PANGO_SCALE * fixfontsize);
+ font.set_size (8.0 * fixfontsize * PANGO_SCALE);
font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font));
audio_font_attributes.change (*font_attr);
delete font_attr;
font.set_weight (Pango::WEIGHT_ULTRALIGHT);
font.set_stretch (Pango::STRETCH_ULTRA_CONDENSED);
- font.set_size (8.0 * PANGO_SCALE * fixfontsize);
+ font.set_size (7.0 * fixfontsize * PANGO_SCALE);
font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font));
midi_font_attributes.change (*font_attr);
delete font_attr;
- font.set_size (6.0 * PANGO_SCALE * fixfontsize);
+ font.set_size (6.0 * fixfontsize * PANGO_SCALE);
font_attr = new Pango::AttrFontDesc (Pango::Attribute::create_attr_font_desc (font));
unit_font_attributes.change (*font_attr);
delete font_attr;
cairo_set_line_width (cr, 1.0);
height = min(max_pattern_metric_size, height);
- uint32_t peakcolor = ARDOUR_UI::config()->color_by_name ("meterbridge peaklabel");
+ uint32_t peakcolor = UIConfiguration::instance().color ("meterbridge peaklabel");
Gdk::Color c; // default text color
for (vector<DataType>::const_iterator i = types.begin(); i != types.end(); ++i) {
switch (*i) {
case DataType::AUDIO:
layout->set_attributes (audio_font_attributes);
+ if (type == MeterPeak0dB) {
+ overlay_midi = 4;
+ }
switch (type) {
case MeterK12:
overlay_midi = 0;
points.insert (std::pair<float,string>( -5.0f, "+15"));
points.insert (std::pair<float,string>( 0.0f, "+20"));
break;
- default:
case MeterPeak:
+ /* fallthrough */
case MeterKrms:
+ /* fallthrough */
+ default:
+ points.insert (std::pair<float,string>( 3.0f, "+3"));
+ /* fallthrough */
+ case MeterPeak0dB:
points.insert (std::pair<float,string>(-50.0f, "-50"));
points.insert (std::pair<float,string>(-40.0f, "-40"));
points.insert (std::pair<float,string>(-30.0f, "-30"));
points.insert (std::pair<float,string>(-20.0f, "-20"));
if (types.size() == 1) {
- if (Config->get_meter_line_up_level() == MeteringLineUp24) {
+ if (UIConfiguration::instance().get_meter_line_up_level() == MeteringLineUp24) {
points.insert (std::pair<float,string>(-24.0f, "-24"));
} else {
points.insert (std::pair<float,string>(-25.0f, "-25"));
points.insert (std::pair<float,string>( -5.0f, "-5"));
points.insert (std::pair<float,string>( -3.0f, "-3"));
points.insert (std::pair<float,string>( 0.0f, "+0"));
- points.insert (std::pair<float,string>( 3.0f, "+3"));
break;
case MeterIEC2EBU:
points.insert (std::pair<float,string>( 96, "96"));
points.insert (std::pair<float,string>(100, "100"));
points.insert (std::pair<float,string>(112, "112"));
+ points.insert (std::pair<float,string>(127, "127"));
} else {
switch (overlay_midi) {
case 1:
points.insert (std::pair<float,string>( 72, "72"));
points.insert (std::pair<float,string>(112, "112"));
points.insert (std::pair<float,string>(127, "127"));
+ break;
+ case 4:
+ /* labels that don't overlay with 0dBFS*/
+ points.insert (std::pair<float,string>( 0, "0"));
+ points.insert (std::pair<float,string>( 16, "16"));
+ points.insert (std::pair<float,string>( 48, "48"));
+ points.insert (std::pair<float,string>( 84, "84"));
+ points.insert (std::pair<float,string>(100, "100"));
default:
break;
}
cairo_stroke (cr);
}
break;
-
case DataType::MIDI:
align_center = false; // don't bleed into legend
fraction = (j->first) / 127.0;
pos = 1 + height - (gint) lrintf (height * fraction);
pos = min (pos, height);
- cairo_set_source_rgb (cr, c.get_red_p(), c.get_green_p(), c.get_blue_p());
- if (tickleft) {
- cairo_arc(cr, width - 2.0, pos + .5, 1.0, 0, 2 * M_PI);
- cairo_fill(cr);
- } else if (tickright) {
- cairo_arc(cr, 3, pos + .5, 1.0, 0, 2 * M_PI);
- cairo_fill(cr);
- }
break;
}
break;
default:
case MeterPeak:
+ case MeterPeak0dB:
case MeterKrms:
layout->set_text("dBFS");
break;
layout->set_text("mid");
layout->get_pixel_size(tw, th);
break;
+ default: // DataType::NIL;
+ layout->set_text("");
+ tw = th = 0;
+ assert (0); // not reached
+ break;
}
if (!background) {
c = w.get_style()->get_fg (Gtk::STATE_ACTIVE);
}
cairo_move_to (cr, 0, 0);
- cairo_set_source (cr, pattern);
gint width, height;
win->get_size (width, height);
-
+#ifdef NO_OVERSAMPLE
+ cairo_set_source (cr, pattern);
cairo_rectangle (cr, 0, 0, width, height);
+#else
+ cairo_scale(cr, 0.5, 0.5);
+ cairo_set_antialias(cr, CAIRO_ANTIALIAS_BEST);
+ cairo_set_source (cr, pattern);
+ cairo_rectangle (cr, 0, 0, width * 2., height * 2.);
+#endif
+
cairo_fill (cr);
cairo_destroy (cr);
++j;
}
}
- RedrawMetrics();
+ RedrawMetrics(); /* EMIT SIGNAL */
}