+
+void
+ExportReport::on_logscale_toggled (Gtk::ToggleButton* b)
+{
+ bool en = b->get_active ();
+ for (std::list<CimgWaveArea*>::iterator i = waves.begin (); i != waves.end (); ++i) {
+ (*i)->set_logscale (en);
+ }
+}
+
+void
+ExportReport::on_rectivied_toggled (Gtk::ToggleButton* b)
+{
+ bool en = b->get_active ();
+ for (std::list<CimgWaveArea*>::iterator i = waves.begin (); i != waves.end (); ++i) {
+ (*i)->set_rectified (en);
+ }
+}
+
+void
+ExportReport::draw_waveform (Cairo::RefPtr<Cairo::ImageSurface>& wave, ExportAnalysisPtr p, uint32_t c, int m_l, size_t width, int anw, int height_2, bool log, bool rect)
+{
+ int w, h;
+ Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create (get_pango_context ());
+ const float ht = 2.f * height_2;
+
+ std::vector<double> dashes;
+ dashes.push_back (3.0);
+ dashes.push_back (5.0);
+
+ wave = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, m_l + width, ht);
+ Cairo::RefPtr<Cairo::Context> cr = Cairo::Context::create (wave);
+ cr->set_operator (Cairo::OPERATOR_SOURCE);
+ cr->rectangle (0, 0, m_l, ht);
+ cr->set_source_rgba (0, 0, 0, 0);
+ cr->fill ();
+ cr->rectangle (m_l, 0, width, ht);
+ cr->set_source_rgba (0, 0, 0, 1.0);
+ cr->fill ();
+ cr->set_operator (Cairo::OPERATOR_OVER);
+
+ cr->set_source_rgba (.7, .7, .7, 1.0);
+ cr->set_line_width (1.0);
+
+ // -1dB range
+ float clip_top;
+ float clip_bot;
+
+ if (rect) {
+ clip_bot = ht;
+
+ if (log) {
+ clip_top = ht * (1.f - alt_log_meter (-1));
+ for (size_t x = 0 ; x < width; ++x) {
+ const float v = alt_log_meter (fast_coefficient_to_dB (std::max (fabsf (p->peaks[c][x].max), fabsf (p->peaks[c][x].min))));
+ cr->move_to (m_l + x - .5, ht - ht * v);
+ cr->line_to (m_l + x - .5, ht);
+ }
+ cr->stroke ();
+ } else {
+ clip_top = ht * (1.f - dB_to_coefficient (-1));
+ for (size_t x = 0 ; x < width; ++x) {
+ const float v = std::max (fabsf (p->peaks[c][x].max), fabsf (p->peaks[c][x].min));
+ cr->move_to (m_l + x - .5, ht - ht * v);
+ cr->line_to (m_l + x - .5, ht);
+ }
+ cr->stroke ();
+ }
+ } else {
+ if (log) {
+ clip_top = height_2 - height_2 * alt_log_meter (-1);
+ clip_bot = height_2 + height_2 * alt_log_meter (-1);
+ for (size_t x = 0 ; x < width; ++x) {
+ float pmax, pmin;
+ if (p->peaks[c][x].max > 0) {
+ pmax = alt_log_meter (fast_coefficient_to_dB (p->peaks[c][x].max));
+ } else {
+ pmax = -alt_log_meter (fast_coefficient_to_dB (-p->peaks[c][x].max));
+ }
+
+ if (p->peaks[c][x].min > 0) {
+ pmin = alt_log_meter (fast_coefficient_to_dB (p->peaks[c][x].min));
+ } else {
+ pmin = -alt_log_meter (fast_coefficient_to_dB (-p->peaks[c][x].min));
+ }
+ cr->move_to (m_l + x - .5, height_2 - height_2 * pmax);
+ cr->line_to (m_l + x - .5, height_2 - height_2 * pmin);
+ }
+ cr->stroke ();
+ } else {
+ clip_top = height_2 - height_2 * dB_to_coefficient (-1);
+ clip_bot = height_2 + height_2 * dB_to_coefficient (-1);
+ for (size_t x = 0 ; x < width; ++x) {
+ cr->move_to (m_l + x - .5, height_2 - height_2 * p->peaks[c][x].max);
+ cr->line_to (m_l + x - .5, height_2 - height_2 * p->peaks[c][x].min);
+ }
+ cr->stroke ();
+ }
+ }
+
+ // >= 0dBFS
+ cr->set_source_rgba (1.0, 0, 0, 1.0);
+ for (size_t x = 0 ; x < width; ++x) {
+ if (p->peaks[c][x].max >= 1.0) {
+ cr->move_to (m_l + x - .5, 0);
+ cr->line_to (m_l + x - .5, clip_top);
+ }
+ if (p->peaks[c][x].min <= -1.0) {
+ cr->move_to (m_l + x - .5, clip_bot);
+ cr->line_to (m_l + x - .5, ht);
+ }
+ }
+ cr->stroke ();
+
+ // >= -1dBTP (coeff >= .89125, libs/vamp-plugins/TruePeak.cpp)
+ cr->set_source_rgba (1.0, 0.7, 0, 0.7);
+ for (std::set<framepos_t>::const_iterator i = p->truepeakpos[c].begin (); i != p->truepeakpos[c].end (); ++i) {
+ cr->move_to (m_l + (*i) - .5, clip_top);
+ cr->line_to (m_l + (*i) - .5, clip_bot);
+ cr->stroke ();
+ }
+
+ if (!rect) {
+ // zero line
+ cr->set_source_rgba (.3, .3, .3, 0.7);
+ cr->move_to (m_l + 0, height_2 - .5);
+ cr->line_to (m_l + width, height_2 - .5);
+ cr->stroke ();
+ }
+
+ // Unit
+ layout->set_font_description (UIConfiguration::instance ().get_SmallerFont ());
+ layout->set_alignment (Pango::ALIGN_LEFT);
+ layout->set_text (_("dBFS"));
+ layout->get_pixel_size (w, h);
+ cr->move_to (rint (m_l - h - anw - 10), rint (height_2 + w * .5));
+ cr->set_source_rgba (.9, .9, .9, 1.0);
+ cr->save ();
+ cr->rotate (M_PI / -2.0);
+ layout->show_in_cairo_context (cr);
+ cr->restore ();
+
+ // x-Axis
+ cr->set_line_width (1.0);
+ cr->set_dash (dashes, 2.0);
+ cr->set_line_cap (Cairo::LINE_CAP_ROUND);
+
+ layout->set_font_description (UIConfiguration::instance ().get_SmallMonospaceFont ());
+
+ if (rect) {
+ if (log) {
+ XAXISLABEL ((ht - ht * alt_log_meter (-36)), _("-36"));
+ XAXISLABEL ((ht - ht * alt_log_meter (-18)), _("-18"));
+ XAXISLABEL ((ht - ht * alt_log_meter (-9)), _("-9"));
+ XAXISLABEL ((ht - ht * alt_log_meter (-3)), _("-3"));
+ } else {
+ XAXISLABEL ((ht - ht * .1259), _("-18"));
+ XAXISLABEL ((ht - ht * .3548), _("-9"));
+ XAXISLABEL ((ht - ht * .7079), _("-3"));
+ }
+ } else {
+ if (log) {
+ XAXISLABEL ((height_2 - height_2 * alt_log_meter (-18)), _("-18"));
+ XAXISLABEL ((height_2 - height_2 * alt_log_meter (-9)), _("-9"));
+ XAXISLABEL ((height_2 - height_2 * alt_log_meter (-3)), _("-3"));
+ XAXISLABEL ((height_2 + height_2 * alt_log_meter (-18)), _("-18"));
+ XAXISLABEL ((height_2 + height_2 * alt_log_meter (-9)), _("-9"));
+ XAXISLABEL ((height_2 + height_2 * alt_log_meter (-3)), _("-3"));
+ } else {
+ XAXISLABEL (height_2 * 0.6452, _("-9"));
+ XAXISLABEL (height_2 * 1.3548, _("-9"));
+ XAXISLABEL (height_2 * 0.2921, _("-3"));
+ XAXISLABEL (height_2 * 1.7079, _("-3"));
+ }
+ }
+ wave->flush ();
+}