From 81ef56fba962ff7b16658cc2831720947aacc8b5 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 28 Jan 2006 13:33:54 +0000 Subject: [PATCH] fix (mostly) measure lines and click box text and meter markings git-svn-id: svn://localhost/trunk/ardour2@300 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardour2_ui.rc | 2 +- gtk2_ardour/canvas-simpleline.c | 7 +- gtk2_ardour/editor.cc | 24 +++- gtk2_ardour/editor_actions.cc | 6 +- gtk2_ardour/editor_mouse.cc | 5 + gtk2_ardour/editor_tempodisplay.cc | 11 +- gtk2_ardour/gain_meter.cc | 17 +-- libs/ardour/ardour/destructive_filesource.h | 14 ++- libs/ardour/audiofilter.cc | 2 +- libs/ardour/destructive_filesource.cc | 128 +++++++++++++++++++- libs/ardour/session_timefx.cc | 2 +- libs/gtkmm2ext/click_box.cc | 48 +++++--- libs/gtkmm2ext/gtkmm2ext/click_box.h | 4 + libs/midi++2/mmc.cc | 40 +++++- 14 files changed, 262 insertions(+), 48 deletions(-) diff --git a/gtk2_ardour/ardour2_ui.rc b/gtk2_ardour/ardour2_ui.rc index 92a9cbb19a..90ecf53717 100644 --- a/gtk2_ardour/ardour2_ui.rc +++ b/gtk2_ardour/ardour2_ui.rc @@ -1709,7 +1709,7 @@ widget "*cTempoMarker" style "cTempoMarker" style "cMeasureLineBeat" { - fg[NORMAL] = { 0.51, 0.59, 0.51 } + fg[NORMAL] = { 0.51, 0.59, 0.87 } fg[ACTIVE] = { 0.98, 0, 0 } } widget "*cMeasureLineBeat" style "cMeasureLineBeat" diff --git a/gtk2_ardour/canvas-simpleline.c b/gtk2_ardour/canvas-simpleline.c index 3aeee4b32a..4ba3d6bc76 100644 --- a/gtk2_ardour/canvas-simpleline.c +++ b/gtk2_ardour/canvas-simpleline.c @@ -287,6 +287,7 @@ gnome_canvas_simpleline_set_property (GObject *object, case PROP_COLOR_RGBA: if (simpleline->color != g_value_get_uint(value)) { simpleline->color = g_value_get_uint(value); + UINT_TO_RGBA (simpleline->color, &simpleline->r, &simpleline->g, &simpleline->b, &simpleline->a); update = TRUE; } break; @@ -377,8 +378,8 @@ gnome_canvas_simpleline_render (GnomeCanvasItem *item, buf->is_bg = FALSE; } - // begin = MAX(simpleline->bbox_ulx,buf->rect.x0); - // end = MIN(simpleline->bbox_lrx,buf->rect.x1); + //begin = MAX(simpleline->bbox_ulx,buf->rect.x0); + //end = MIN(simpleline->bbox_lrx,buf->rect.x1); begin = simpleline->bbox_ulx; end = simpleline->bbox_lrx; @@ -388,7 +389,7 @@ gnome_canvas_simpleline_render (GnomeCanvasItem *item, PAINT_HORIZA(buf, simpleline->r, simpleline->g, simpleline->b, simpleline->a, begin, end, simpleline->bbox_uly); } else { - PAINT_VERTA(buf, simpleline->r, simpleline->g, simpleline->b, simpleline->a, + PAINT_VERTA(buf, simpleline->r, simpleline->g, simpleline->b, simpleline->a, begin, simpleline->bbox_uly, simpleline->bbox_lry); } } diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 5800888d0c..d6b9f5b278 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2121,19 +2121,37 @@ Editor::set_state (const XMLNode& node) if ((prop = node.property ("show-waveforms"))) { bool yn = (prop->value() == "yes"); _show_waveforms = !yn; - set_show_waveforms (yn); + RefPtr act = ActionManager::get_action (X_("Editor"), X_("ToggleWaveformVisibility")); + if (act) { + RefPtr tact = RefPtr::cast_dynamic(act); + /* do it twice to force the change */ + tact->set_active (!yn); + tact->set_active (yn); + } } if ((prop = node.property ("show-waveforms-recording"))) { bool yn = (prop->value() == "yes"); _show_waveforms_recording = !yn; - set_show_waveforms_recording (yn); + RefPtr act = ActionManager::get_action (X_("Editor"), X_("ToggleWaveformsWhileRecording")); + if (act) { + RefPtr tact = RefPtr::cast_dynamic(act); + /* do it twice to force the change */ + tact->set_active (!yn); + tact->set_active (yn); + } } if ((prop = node.property ("show-measures"))) { bool yn = (prop->value() == "yes"); _show_measures = !yn; - set_show_measures (yn); + RefPtr act = ActionManager::get_action (X_("Editor"), X_("ToggleMeasureVisibility")); + if (act) { + RefPtr tact = RefPtr::cast_dynamic(act); + /* do it twice to force the change */ + tact->set_active (!yn); + tact->set_active (yn); + } } if ((prop = node.property ("follow-playhead"))) { diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index 5f92c62bd7..e3dcfac15a 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -324,8 +324,8 @@ Editor::register_actions () ActionManager::register_toggle_action (editor_actions, X_("ToggleWaveformVisibility"), _("show waveforms"), mem_fun (*this, &Editor::toggle_waveform_visibility)); ActionManager::register_toggle_action (editor_actions, X_("ToggleWaveformsWhileRecording"), _("show waveforms while recording"), mem_fun (*this, &Editor::toggle_waveforms_while_recording)); - ActionManager::register_toggle_action (editor_actions, X_("ToggleMeasureVisibility"), _("show measures"), mem_fun (*this, &Editor::toggle_measure_visibility)); - + act = ActionManager::register_toggle_action (editor_actions, X_("ToggleMeasureVisibility"), _("show measures"), mem_fun (*this, &Editor::toggle_measure_visibility)); + RadioAction::Group meter_falloff_group; RadioAction::Group meter_hold_group; @@ -377,7 +377,7 @@ Editor::toggle_waveforms_while_recording () void Editor::toggle_measure_visibility () { - Glib::RefPtr act = ActionManager::get_action (X_("Editor"), X_("ToggleWaveformVisibility")); + Glib::RefPtr act = ActionManager::get_action (X_("Editor"), X_("ToggleMeasureVisibility")); if (act) { Glib::RefPtr tact = Glib::RefPtr::cast_dynamic(act); set_show_measures (tact->get_active()); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 02271e2467..75a026f92b 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -94,6 +94,11 @@ Editor::event_frame (GdkEvent* event, double* pcx, double* pcy) case GDK_LEAVE_NOTIFY: track_canvas.w2c(event->crossing.x, event->crossing.y, *pcx, *pcy); break; + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + cerr << "here\n"; + // track_canvas.w2c(event->key.x, event->key.y, *pcx, *pcy); + break; default: warning << string_compose (_("Editor::event_frame() used on unhandled event type %1"), event->type) << endmsg; break; diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index d7e35caa20..70c92dfcdd 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -135,7 +135,6 @@ Editor::get_time_line () if (free_measure_lines.empty()) { line = new ArdourCanvas::SimpleLine (*time_line_group); - // cerr << "measure line @ " << line << endl; used_measure_lines.push_back (line); } else { line = free_measure_lines.front(); @@ -182,7 +181,7 @@ Editor::draw_measures () break; case TempoMap::Beat: - xpos = p.frame / (gdouble) frames_per_unit; + xpos = frame_to_unit (p.frame); if (last_beat < xpos) { beat_spacing = xpos - last_beat; } @@ -199,8 +198,8 @@ Editor::draw_measures () break; case TempoMap::Beat: - xpos = p.frame / (gdouble) frames_per_unit; - + xpos = frame_to_unit (p.frame); + if (p.beat == 1) { color = color_map[cMeasureLineBeat]; } else { @@ -214,12 +213,12 @@ Editor::draw_measures () break; } } - + if (cnt == 0 || xpos - last_xpos > 4.0) { line = get_time_line (); line->property_x1() = xpos; line->property_x2() = xpos; - line->property_y2() = canvas_height; + line->property_y2() = 1000; line->property_color_rgba() = color; line->raise_to_top(); line->show(); diff --git a/gtk2_ardour/gain_meter.cc b/gtk2_ardour/gain_meter.cc index 4368bf809f..a696bbfbb1 100644 --- a/gtk2_ardour/gain_meter.cc +++ b/gtk2_ardour/gain_meter.cc @@ -223,11 +223,9 @@ GainMeter::meter_metrics_expose (GdkEventExpose *ev) /* XXX optimize this so that it doesn't do it all everytime */ double fraction; - Glib::RefPtr win (meter_metric_area.get_window()); Glib::RefPtr fg_gc (meter_metric_area.get_style()->get_fg_gc (Gtk::STATE_NORMAL)); Glib::RefPtr bg_gc (meter_metric_area.get_style()->get_bg_gc (Gtk::STATE_NORMAL)); - Pango::FontDescription font (meter_metric_area.get_style()->get_font()); gint x, y, width, height, depth; gint pos; int db_points[] = { -50, -10, -3, 0, 6 }; @@ -235,6 +233,8 @@ GainMeter::meter_metrics_expose (GdkEventExpose *ev) char buf[32]; GdkRectangle base_rect; GdkRectangle draw_rect; + int theight; + int twidth; win->get_geometry (x, y, width, height, depth); @@ -246,18 +246,22 @@ GainMeter::meter_metrics_expose (GdkEventExpose *ev) gdk_rectangle_intersect (&ev->area, &base_rect, &draw_rect); win->draw_rectangle (bg_gc, true, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height); + Glib::RefPtr layout = meter_metric_area.create_pango_layout(""); + for (i = 0; i < sizeof (db_points)/sizeof (db_points[0]); ++i) { + fraction = log_meter (db_points[i]); pos = height - (gint) floor (height * fraction); snprintf (buf, sizeof (buf), "%d", db_points[i]); - Glib::RefPtr Layout = meter_metric_area.create_pango_layout(buf); - // GTK2FIX - how to get twidth, ascent - win->draw_layout(fg_gc, width /* - twidth */, pos /* + ascent */, Layout); + layout->set_text (buf); + layout->get_pixel_size (twidth, theight); + + win->draw_layout (fg_gc, width - twidth, pos + theight, layout); } - return TRUE; + return true; } GainMeter::~GainMeter () @@ -281,7 +285,6 @@ GainMeter::update_meters () uint32_t n; float peak; char buf[32]; - for (n = 0, i = meters.begin(); i != meters.end(); ++i, ++n) { if ((*i).packed) { diff --git a/libs/ardour/ardour/destructive_filesource.h b/libs/ardour/ardour/destructive_filesource.h index 7f816a9e6b..0663d7f034 100644 --- a/libs/ardour/ardour/destructive_filesource.h +++ b/libs/ardour/ardour/destructive_filesource.h @@ -43,8 +43,18 @@ class DestructiveFileSource : public FileSource { jack_nframes_t write (Sample *src, jack_nframes_t cnt); private: - bool _capture_start; - bool _capture_end; + static jack_nframes_t xfade_frames; + static gain_t* out_coefficient; + static gain_t* in_coefficient; + static void setup_standard_crossfades (jack_nframes_t sample_rate); + + bool _capture_start; + bool _capture_end; + jack_nframes_t file_pos; + Sample* xfade_buf; + + jack_nframes_t crossfade (Sample* data, jack_nframes_t cnt, int dir); + }; } diff --git a/libs/ardour/audiofilter.cc b/libs/ardour/audiofilter.cc index 6145ef9c83..ce3a103e28 100644 --- a/libs/ardour/audiofilter.cc +++ b/libs/ardour/audiofilter.cc @@ -73,7 +73,7 @@ AudioFilter::finish (AudioRegion& region, AudioRegion::SourceList& nsrcs) now = localtime (&xnow); for (AudioRegion::SourceList::iterator si = nsrcs.begin(); si != nsrcs.end(); ++si) { - dynamic_cast((*si))->update_header (session.transport_frame(), *now, xnow); + dynamic_cast((*si))->update_header (region.position(), *now, xnow); } /* create a new region */ diff --git a/libs/ardour/destructive_filesource.cc b/libs/ardour/destructive_filesource.cc index f0813f61dc..186166e08c 100644 --- a/libs/ardour/destructive_filesource.cc +++ b/libs/ardour/destructive_filesource.cc @@ -51,6 +51,7 @@ typedef off_t off64_t; #endif #include +#include #include #include @@ -60,9 +61,19 @@ typedef off_t off64_t; using namespace std; using namespace ARDOUR; +gain_t* DestructiveFileSource::out_coefficient = 0; +gain_t* DestructiveFileSource::in_coefficient = 0; +jack_nframes_t DestructiveFileSource::xfade_frames = 64; + DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, bool repair_first) : FileSource (path, rate, repair_first) { + if (out_coefficient == 0) { + setup_standard_crossfades (rate); + } + + xfade_buf = new Sample[xfade_frames]; + _capture_start = false; _capture_end = false; } @@ -70,17 +81,42 @@ DestructiveFileSource::DestructiveFileSource (string path, jack_nframes_t rate, DestructiveFileSource::DestructiveFileSource (const XMLNode& node, jack_nframes_t rate) : FileSource (node, rate) { + if (out_coefficient == 0) { + setup_standard_crossfades (rate); + } + + xfade_buf = new Sample[xfade_frames]; + _capture_start = false; _capture_end = false; } DestructiveFileSource::~DestructiveFileSource() { + delete xfade_buf; +} + +void +DestructiveFileSource::setup_standard_crossfades (jack_nframes_t rate) +{ + xfade_frames = (jack_nframes_t) floor ((/*Config->get_destructive_crossfade_msecs()*/ 64 / 1000.0) * rate); + + out_coefficient = new gain_t[xfade_frames]; + in_coefficient = new gain_t[xfade_frames]; + + for (jack_nframes_t n = 0; n < xfade_frames; ++n) { + + /* XXXX THIS IS NOT THE RIGHT XFADE CURVE: USE A PROPER VOLUMETRIC EQUAL POWER CURVE */ + + out_coefficient[n] = n/(gain_t) xfade_frames; + in_coefficient[n] = 1.0 - out_coefficient[n]; + } } int DestructiveFileSource::seek (jack_nframes_t frame) { + file_pos = data_offset + (sizeof (Sample) * frame); return 0; } @@ -103,6 +139,72 @@ DestructiveFileSource::clear_capture_marks () _capture_end = false; } +jack_nframes_t +DestructiveFileSource::crossfade (Sample* data, jack_nframes_t cnt, int dir) +{ + jack_nframes_t xfade = min (xfade_frames, cnt); + jack_nframes_t xfade_bytes = xfade * sizeof (Sample); + + if (::pread64 (fd, (char *) xfade_buf, xfade_bytes, file_pos) != (off64_t) xfade_bytes) { + error << string_compose(_("FileSource: \"%1\" bad read (%2)"), _path, strerror (errno)) << endmsg; + return 0; + } + + if (xfade == xfade_frames) { + + /* use the standard xfade curve */ + + if (dir) { + + /* fade new material in */ + + for (jack_nframes_t n = 0; n < xfade; ++n) { + xfade_buf[n] = (xfade_buf[n] * out_coefficient[n]) + (data[n] * in_coefficient[n]); + } + } else { + + /* fade new material out */ + + + for (jack_nframes_t n = 0; n < xfade; ++n) { + xfade_buf[n] = (xfade_buf[n] * in_coefficient[n]) + (data[n] * out_coefficient[n]); + } + } + + + } else { + + /* short xfade, compute custom curve */ + + for (jack_nframes_t n = 0; n < xfade; ++n) { + xfade_buf[n] = (xfade_buf[n] * out_coefficient[n]) + (data[n] * in_coefficient[n]); + } + } + + if (::pwrite64 (fd, (char *) xfade_buf, xfade, file_pos) != (off64_t) xfade_bytes) { + error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; + return 0; + } + + /* don't advance file_pos here; if the write fails, we want it left where it was before the overall + write, not in the middle of it. + */ + + if (xfade < cnt) { + jack_nframes_t remaining = (cnt - xfade); + int32_t bytes = remaining * sizeof (Sample); + + if (::pwrite64 (fd, (char *) data + remaining, bytes, file_pos) != (off64_t) bytes) { + error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; + return 0; + } + } + + file_pos += cnt; + + return cnt; +} + jack_nframes_t DestructiveFileSource::write (Sample* data, jack_nframes_t cnt) { @@ -110,17 +212,31 @@ DestructiveFileSource::write (Sample* data, jack_nframes_t cnt) LockMonitor lm (_lock, __LINE__, __FILE__); int32_t byte_cnt = cnt * sizeof (Sample); - int32_t byte_pos = data_offset + (_length * sizeof (Sample)); jack_nframes_t oldlen; - if (::pwrite64 (fd, (char *) data, byte_cnt, byte_pos) != (off64_t) byte_cnt) { - error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; - return 0; + if (_capture_start) { + _capture_start = false; + if (crossfade (data, cnt, 1) != cnt) { + return 0; + } + } else if (_capture_end) { + _capture_end = false; + if (crossfade (data, cnt, 0) != cnt) { + return 0; + } + } else { + if (::pwrite64 (fd, (char *) data, byte_cnt, file_pos) != (off64_t) byte_cnt) { + error << string_compose(_("FileSource: \"%1\" bad write (%2)"), _path, strerror (errno)) << endmsg; + return 0; + } } - oldlen = _length; - _length += cnt; + oldlen = file_pos; + if (file_pos + cnt > _length) { + _length += cnt; + } _write_data_count = byte_cnt; + file_pos += byte_cnt; if (_build_peakfiles) { PeakBuildRecord *pbr = 0; diff --git a/libs/ardour/session_timefx.cc b/libs/ardour/session_timefx.cc index e8c5a54349..b8f0068a91 100644 --- a/libs/ardour/session_timefx.cc +++ b/libs/ardour/session_timefx.cc @@ -149,7 +149,7 @@ Session::tempoize_region (TimeStretchRequest& tsr) xnow = localtime (&now); for (it = sources.begin(); it != sources.end(); ++it) { - dynamic_cast(*it)->update_header (0, *xnow, now); + dynamic_cast(*it)->update_header (tsr.region->position(), *xnow, now); } region_name = tsr.region->name() + X_(".t"); diff --git a/libs/gtkmm2ext/click_box.cc b/libs/gtkmm2ext/click_box.cc index ca8d7f725f..efce988c29 100644 --- a/libs/gtkmm2ext/click_box.cc +++ b/libs/gtkmm2ext/click_box.cc @@ -34,6 +34,9 @@ ClickBox::ClickBox (Gtk::Adjustment *adjp, const string &name, bool round_to_ste { print_func = default_printer; print_arg = 0; + layout = create_pango_layout (""); + twidth = 0; + theight = 0; set_name (name); add_events (Gdk::BUTTON_RELEASE_MASK| @@ -85,6 +88,17 @@ ClickBox::default_printer (char buf[32], Gtk::Adjustment &adj, void ClickBox::set_label () { + if (!print_func) { + return; + } + + char buf[32]; + + print_func (buf, get_adjustment(), print_arg); + + layout->set_text (buf); + layout->get_pixel_size (twidth, theight); + queue_draw (); } @@ -102,21 +116,27 @@ ClickBox::on_expose_event (GdkEventExpose *ev) if (print_func) { - char buf[32]; - Glib::RefPtr style (get_style()); - - print_func (buf, get_adjustment(), print_arg); - - Glib::RefPtr win (get_window()); - win->draw_rectangle (style->get_bg_gc(get_state()), - TRUE, 0, 0, -1, -1); - - { - int width = 0; - int height = 0; - create_pango_layout(buf)->get_pixel_size(width, height); - set_size_request(width, height); + Glib::RefPtr fg_gc (style->get_fg_gc (Gtk::STATE_NORMAL)); + Glib::RefPtr bg_gc (style->get_bg_gc (Gtk::STATE_NORMAL)); + Glib::RefPtr win (get_window()); + + GdkRectangle base_rect; + GdkRectangle draw_rect; + gint x, y, width, height, depth; + + win->get_geometry (x, y, width, height, depth); + + base_rect.width = width; + base_rect.height = height; + base_rect.x = 0; + base_rect.y = 0; + + gdk_rectangle_intersect (&ev->area, &base_rect, &draw_rect); + win->draw_rectangle (bg_gc, true, draw_rect.x, draw_rect.y, draw_rect.width, draw_rect.height); + + if (twidth && theight) { + win->draw_layout (fg_gc, width - (twidth + 2), (height - theight) + 2, layout); } } diff --git a/libs/gtkmm2ext/gtkmm2ext/click_box.h b/libs/gtkmm2ext/gtkmm2ext/click_box.h index 4f1ef5ca6b..c6f2922f3f 100644 --- a/libs/gtkmm2ext/gtkmm2ext/click_box.h +++ b/libs/gtkmm2ext/gtkmm2ext/click_box.h @@ -49,6 +49,10 @@ class ClickBox : public Gtk::DrawingArea, public AutoSpin void (*print_func) (char buf[32], Gtk::Adjustment &, void *); void *print_arg; + Glib::RefPtr layout; + int twidth; + int theight; + void set_label (); bool button_press_handler (GdkEventButton *); bool button_release_handler (GdkEventButton *); diff --git a/libs/midi++2/mmc.cc b/libs/midi++2/mmc.cc index a0de774329..a7501664f2 100644 --- a/libs/midi++2/mmc.cc +++ b/libs/midi++2/mmc.cc @@ -485,10 +485,48 @@ MachineControl::write_track_record_ready (byte *msg, size_t len) bit 3: aux track a bit 4: aux track b + the format of the message (its an MMC Masked Write) is: + + 0x41 Command Code + byte count of following data + byte value of the field being written + byte number of target byte in the + bitmap being written to + ones in the mask indicate which bits will be changed + new data for the byte being written + + by the time this code is executing, msg[0] is the + byte number of the target byte. if its zero, we + are writing to a special byte in the standard + track bitmap, in which the first 5 bits are + special. hence the bits for tracks 1 + 2 are bits + 5 and 6 of the first byte of the track + bitmap. so: + + change track 1: msg[0] = 0; << first byte of track bitmap + msg[1] = 0100000; << binary: bit 5 set + + change track 2: msg[0] = 0; << first byte of track bitmap + msg[1] = 1000000; << binary: bit 6 set + + change track 3: msg[0] = 1; << second byte of track bitmap + msg[1] = 0000001; << binary: bit 0 set + + the (msg[0] * 7) - 5 computation is an attempt to + extract the value of the first track: ie. the one + that would be indicated by bit 0 being set. + + so, if msg[0] = 0, msg[1] = 0100000 (binary), + what happens is that base_track = -5, but by the + time we check the correct bit, n = 5, and so the + computed track for the status change is 0 (first + track). + + if msg[0] = 1, then the base track for any change is 2 (the third track), and so on. */ /* XXX check needed to make sure we don't go outside the - support number of tracks. + supported number of tracks. */ base_track = (msg[0] * 7) - 5; -- 2.30.2