diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index b1f6a0d2cf..1a44041f73 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -158,6 +158,20 @@ show_me_the_size (Requisition* r, const char* what) cerr << "size of " << what << " = " << r->width << " x " << r->height << endl; } +void +check_adjustment (Gtk::Adjustment* adj) +{ + cerr << "CHANGE adj = " + << adj->get_lower () << ' ' + << adj->get_upper () << ' ' + << adj->get_value () << ' ' + << adj->get_step_increment () << ' ' + << adj->get_page_increment () << ' ' + << adj->get_page_size () << ' ' + << endl; + +} + Editor::Editor (AudioEngine& eng) : engine (eng), @@ -179,8 +193,8 @@ Editor::Editor (AudioEngine& eng) reset them as needed. */ - vertical_adjustment (0.0, 0.0, 400.0, 10), - horizontal_adjustment (0.0, 0.0, 1200.0, 20), + vertical_adjustment (0.0, 0.0, 10.0, 400.0), + horizontal_adjustment (0.0, 0.0, 20.0, 1200.0), /* tool bar related */ @@ -321,6 +335,8 @@ Editor::Editor (AudioEngine& eng) set_mouse_mode (MouseObject, true); frames_per_unit = 2048; /* too early to use set_frames_per_unit */ + reset_hscrollbar_stepping (); + zoom_focus = ZoomFocusLeft; zoom_range_clock.ValueChanged.connect (mem_fun(*this, &Editor::zoom_adjustment_changed)); @@ -862,10 +878,6 @@ Editor::set_frames_per_unit (double fpu) which will do the same updates. */ - if (session && !no_zoom_repos_update) { - horizontal_adjustment.set_upper (session->current_end_frame() / frames_per_unit); - } - if (!no_zoom_repos_update) { horizontal_adjustment.set_value (leftmost_frame/frames_per_unit); update_fixed_rulers (); @@ -886,6 +898,9 @@ Editor::set_frames_per_unit (double fpu) ZoomChanged (); /* EMIT_SIGNAL */ + reset_hscrollbar_stepping (); + reset_scrolling_region (); + if (edit_cursor) edit_cursor->set_position (edit_cursor->current_frame); if (playhead_cursor) playhead_cursor->set_position (playhead_cursor->current_frame); @@ -912,10 +927,6 @@ Editor::reposition_x_origin (jack_nframes_t frame) { if (frame != leftmost_frame) { leftmost_frame = frame; - double pixel = frame_to_pixel (frame); - if (pixel >= horizontal_adjustment.get_upper()) { - horizontal_adjustment.set_upper (frame_to_pixel (frame + (current_page_frames()))); - } horizontal_adjustment.set_value (frame/frames_per_unit); } } @@ -1152,7 +1163,7 @@ Editor::handle_new_duration () reset_scrolling_region (); if (session) { - horizontal_adjustment.set_upper (session->current_end_frame() / frames_per_unit); + cerr << "Set upper #2 to " << horizontal_adjustment.get_upper () << endl; horizontal_adjustment.set_value (leftmost_frame/frames_per_unit); } } @@ -1342,7 +1353,6 @@ Editor::connect_to_session (Session *t) leftmost_frame = 0; - horizontal_adjustment.set_upper (session->current_end_frame() / frames_per_unit); horizontal_adjustment.set_value (0); restore_ruler_visibility (); @@ -3971,7 +3981,7 @@ void Editor::end_location_changed (Location* location) { ENSURE_GUI_THREAD (bind (mem_fun(*this, &Editor::end_location_changed), location)); - horizontal_adjustment.set_upper (location->end() / frames_per_unit); + reset_scrolling_region (); } int diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 1b0a1a4811..3e080415c0 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -691,6 +691,8 @@ class Editor : public PublicEditor Gtk::HScrollbar edit_hscrollbar; bool edit_hscroll_dragging; + + void reset_hscrollbar_stepping (); bool hscrollbar_button_press (GdkEventButton*); bool hscrollbar_button_release (GdkEventButton*); diff --git a/gtk2_ardour/editor_canvas.cc b/gtk2_ardour/editor_canvas.cc index 92844124bd..73e6e22668 100644 --- a/gtk2_ardour/editor_canvas.cc +++ b/gtk2_ardour/editor_canvas.cc @@ -312,6 +312,7 @@ Editor::track_canvas_allocate (Gtk::Allocation alloc) edit_cursor->set_position (edit_cursor->current_frame); playhead_cursor->set_position (playhead_cursor->current_frame); + reset_hscrollbar_stepping (); reset_scrolling_region (); if (edit_cursor) edit_cursor->set_length (canvas_height); @@ -374,14 +375,22 @@ Editor::reset_scrolling_region (Gtk::Allocation* alloc) } } - double last_canvas_unit = ceil ((double) max_frames / frames_per_unit); + // old: ceil ((double) max_frames / frames_per_unit); + + double last_canvas_unit; + + if (session) { + last_canvas_unit = (session->get_maximum_extent() + (current_page_frames() * 0.10f)) / frames_per_unit; + } else { + last_canvas_unit = 0; + } + track_canvas.set_scroll_region (0.0, 0.0, max (last_canvas_unit, canvas_width), pos); // XXX what is the correct height value for the time canvas ? this overstates it time_canvas.set_scroll_region ( 0.0, 0.0, max (last_canvas_unit, canvas_width), canvas_height); controls_layout.queue_resize(); - } void @@ -522,3 +531,4 @@ Editor::drop_regions (const RefPtr& context, context->drag_finish (true, false, time); } + diff --git a/gtk2_ardour/editor_hscroller.cc b/gtk2_ardour/editor_hscroller.cc index 049f19b85f..5b2da7dc83 100644 --- a/gtk2_ardour/editor_hscroller.cc +++ b/gtk2_ardour/editor_hscroller.cc @@ -28,10 +28,6 @@ using namespace ARDOUR; void Editor::hscrollbar_allocate (Gtk::Allocation &alloc) { - if (session) { - horizontal_adjustment.set_upper (session->current_end_frame() / frames_per_unit); - } - } bool @@ -55,3 +51,9 @@ Editor::hscrollbar_button_release (GdkEventButton *ev) return true; } +void +Editor::reset_hscrollbar_stepping () +{ + horizontal_adjustment.set_step_increment ((current_page_frames() / 5)/frames_per_unit); /* 5 clicks to scroll the entire page */ + horizontal_adjustment.set_page_increment (current_page_frames()/frames_per_unit); +} diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 201cc48ada..924a482936 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -365,6 +365,7 @@ class Session : public sigc::trackable, public Stateful int remove_region_from_region_list (Region&); + jack_nframes_t get_maximum_extent () const; jack_nframes_t current_end_frame() const { return end_location->start(); } jack_nframes_t current_start_frame() const { return start_location->start(); } jack_nframes_t frame_rate() const { return _current_frame_rate; } diff --git a/libs/ardour/control_protocol.cc b/libs/ardour/control_protocol.cc index 2a28921d53..1e4bd8efc9 100644 --- a/libs/ardour/control_protocol.cc +++ b/libs/ardour/control_protocol.cc @@ -153,6 +153,8 @@ ControlProtocol::thread_work () struct sched_param rtparam; int err; + cerr << _name << " receiver thread running\n"; + memset (&rtparam, 0, sizeof (rtparam)); rtparam.sched_priority = 3; /* XXX should be relative to audio (JACK) thread */ @@ -238,15 +240,12 @@ ControlProtocol::thread_work () continue; } - if (send()) { - - if (send_route_feedback ()) { - list routes = session.get_routes(); /* copies the routes */ - send_route_feedback (routes); - } - - send_global_feedback (); + if (send_route_feedback ()) { + list routes = session.get_routes(); /* copies the routes */ + send_route_feedback (routes); } + + send_global_feedback (); } return 0; diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 216517e668..125e0387f3 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -2227,24 +2227,12 @@ Session::route_by_remote_id (uint32_t id) void Session::find_current_end () { - jack_nframes_t max = 0; - jack_nframes_t me; - if (_state_of_the_state & Loading) { return; } - /* Don't take the diskstream lock. Caller must have other ways to - ensure atomicity. - */ + jack_nframes_t max = get_maximum_extent (); - for (DiskStreamList::iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { - Playlist* pl = (*i)->playlist(); - if ((me = pl->get_maximum_extent()) > max) { - max = me; - } - } - if (max > end_location->end()) { end_location->set_end (max); set_dirty(); @@ -2252,6 +2240,26 @@ Session::find_current_end () } } +jack_nframes_t +Session::get_maximum_extent () const +{ + jack_nframes_t max = 0; + jack_nframes_t me; + + /* Don't take the diskstream lock. Caller must have other ways to + ensure atomicity. + */ + + for (DiskStreamList::const_iterator i = diskstreams.begin(); i != diskstreams.end(); ++i) { + Playlist* pl = (*i)->playlist(); + if ((me = pl->get_maximum_extent()) > max) { + max = me; + } + } + + return max; +} + DiskStream * Session::diskstream_by_name (string name) { diff --git a/libs/surfaces/tranzport/tranzport_control_protocol.cc b/libs/surfaces/tranzport/tranzport_control_protocol.cc index 34ba54c8b6..6760caac63 100644 --- a/libs/surfaces/tranzport/tranzport_control_protocol.cc +++ b/libs/surfaces/tranzport/tranzport_control_protocol.cc @@ -49,8 +49,8 @@ TranzportControlProtocol::TranzportControlProtocol (Session& s) TranzportControlProtocol::~TranzportControlProtocol () { if (udev) { - lcd_clear (); pthread_cancel_one (thread); + lcd_clear (); close (); } } @@ -63,9 +63,7 @@ TranzportControlProtocol::init () } lcd_clear (); - - print (0, 0, "Welcome to"); - print (1, 0, "Ardour"); + lights_off (); show_wheel_mode(); next_track (); @@ -77,7 +75,7 @@ TranzportControlProtocol::init () /* inbound thread */ - pthread_create_and_store (X_("tranzport monitor"), &thread, 0, _thread_work, this); + pthread_create_and_store (X_("tranzport monitor"), &thread, 0, _monitor_work, this); return 0; } @@ -126,8 +124,6 @@ TranzportControlProtocol::send_global_feedback () void TranzportControlProtocol::next_display_mode () { - cerr << "Next display mode\n"; - switch (display_mode) { case DisplayNormal: requested_display_mode = DisplayBigMeter; @@ -144,6 +140,7 @@ TranzportControlProtocol::enter_big_meter_mode () { lcd_clear (); lights_off (); + last_meter_fill = 0; display_mode = DisplayBigMeter; } @@ -154,6 +151,7 @@ TranzportControlProtocol::enter_normal_display_mode () lights_off (); show_current_track (); show_wheel_mode (); + last_where += 1; /* force time redisplay */ show_transport_time (); display_mode = DisplayNormal; } @@ -199,17 +197,51 @@ TranzportControlProtocol::show_meter () float level = current_route->peak_input_power (0); float fraction = log_meter (level); - int fill = (int) floor (fraction * 20); + + /* we draw using a choice of a sort of double colon-like character ("::") or a single, left-aligned ":". + the screen is 20 chars wide, so we can display 40 different levels. compute the level, + then figure out how many "::" to fill. if the answer is odd, make the last one a ":" + */ + + uint32_t fill = (uint32_t) floor (fraction * 40); char buf[21]; int i; + if (fill == last_meter_fill) { + /* nothing to do */ + return; + } + + last_meter_fill = fill; + + bool add_single_level = (fill % 2 != 0); + fill /= 2; + + if (fraction > 0.98) { + light_on (LightAnysolo); + } + + /* add all full steps */ + for (i = 0; i < fill; ++i) { - buf[i] = 0x70; /* tranzport special code for 4 quadrant LCD block */ + buf[i] = 0x07; /* tranzport special code for 4 quadrant LCD block */ } + + /* add a possible half-step */ + + if (i < 20 && add_single_level) { + buf[i] = 0x03; /* tranzport special code for 2 left quadrant LCD block */ + ++i; + } + + /* fill rest with space */ + for (; i < 20; ++i) { buf[i] = ' '; } + /* print() requires this */ + buf[21] = '\0'; print (0, 0, buf); @@ -249,13 +281,13 @@ TranzportControlProtocol::show_transport_time () } void* -TranzportControlProtocol::_thread_work (void* arg) +TranzportControlProtocol::_monitor_work (void* arg) { - return static_cast(arg)->thread_work (); + return static_cast(arg)->monitor_work (); } void* -TranzportControlProtocol::thread_work () +TranzportControlProtocol::monitor_work () { PBD::ThreadCreated (pthread_self(), X_("tranzport monitor")); @@ -678,8 +710,15 @@ void TranzportControlProtocol::track_gain_changed (void* ignored) { char buf[8]; - snprintf (buf, sizeof (buf), "%.1fdB", coefficient_to_dB (current_route->gain())); - print (0, 9, buf); + + switch (display_mode) { + case DisplayNormal: + snprintf (buf, sizeof (buf), "%.1fdB", coefficient_to_dB (current_route->gain())); + print (0, 9, buf); + break; + default: + break; + } } void @@ -793,6 +832,11 @@ TranzportControlProtocol::button_event_trackmute_release (bool shifted) void TranzportControlProtocol::button_event_tracksolo_press (bool shifted) { + if (display_mode == DisplayBigMeter) { + light_off (LightAnysolo); + return; + } + if (shifted) { session.set_all_solo (!session.soloing()); } else { @@ -1353,7 +1397,7 @@ TranzportControlProtocol::print (int row, int col, const char *text) /* copy current cell contents into tmp */ memcpy (tmp, ¤t_screen[row][base_col], 4); - + /* overwrite with new text */ uint32_t tocopy = min ((4U - offset), left); diff --git a/libs/surfaces/tranzport/tranzport_control_protocol.h b/libs/surfaces/tranzport/tranzport_control_protocol.h index d460a6c74a..925ac72e2a 100644 --- a/libs/surfaces/tranzport/tranzport_control_protocol.h +++ b/libs/surfaces/tranzport/tranzport_control_protocol.h @@ -99,6 +99,7 @@ class TranzportControlProtocol : public ControlProtocol { int last_wheel_dir; DisplayMode display_mode; DisplayMode requested_display_mode; + uint32_t last_meter_fill; std::vector track_connections; @@ -159,8 +160,8 @@ class TranzportControlProtocol : public ControlProtocol { void step_pan_right (); void step_pan_left (); - static void* _thread_work (void* arg); - void* thread_work (); + static void* _monitor_work (void* arg); + void* monitor_work (); void button_event_battery_press (bool shifted); void button_event_battery_release (bool shifted);