3 #include "ardour/session.h"
5 #include "mackie_jog_wheel.h"
6 #include "mackie_control_protocol.h"
7 #include "surface_port.h"
13 using namespace Mackie;
15 JogWheel::JogWheel (MackieControlProtocol & mcp)
17 , _transport_speed (4.0)
18 , _transport_direction (0)
19 , _shuttle_speed (0.0)
23 JogWheel::State JogWheel::jog_wheel_state() const
25 if (!_jog_wheel_states.empty())
26 return _jog_wheel_states.top();
31 void JogWheel::zoom_event (SurfacePort &, Control &, const ControlState &)
35 void JogWheel::scrub_event (SurfacePort &, Control &, const ControlState &)
39 void JogWheel::speed_event (SurfacePort &, Control &, const ControlState &)
43 void JogWheel::scroll_event (SurfacePort &, Control &, const ControlState &)
47 void JogWheel::jog_event (SurfacePort &, Control &, float delta)
49 // TODO use current snap-to setting?
50 switch (jog_wheel_state())
53 _mcp.ScrollTimeline (delta);
58 // TODO implement something similar to ScrollTimeline which
59 // ends up in Editor::control_scroll for smoother zooming.
61 for (unsigned int i = 0; i < fabs (delta); ++i) {
65 for (unsigned int i = 0; i < fabs (delta); ++i) {
72 // locally, _transport_speed is an positive value
73 _transport_speed += _mcp.surfaces.front()->scaled_delta (delta, _mcp.get_session().transport_speed());
75 // make sure no weirdness gets to the session
76 if (_transport_speed < 0 || isnan (_transport_speed))
78 _transport_speed = 0.0;
81 // translate _transport_speed speed to a signed transport velocity
82 _mcp.get_session().request_transport_speed_nonzero (transport_speed() * transport_direction());
88 add_scrub_interval (_scrub_timer.restart());
89 // x clicks per second => speed == 1.0
90 float speed = _mcp.surfaces.front()->scrub_scaling_factor() / average_scrub_interval() * delta;
91 _mcp.get_session().request_transport_speed_nonzero (speed);
95 // we have a stop event
102 _shuttle_speed = _mcp.get_session().transport_speed();
103 _shuttle_speed += _mcp.surfaces.front()->scaled_delta (delta, _mcp.get_session().transport_speed());
104 _mcp.get_session().request_transport_speed_nonzero (_shuttle_speed);
108 std::cout << "JogWheel select not implemented" << std::endl;
113 void JogWheel::check_scrubbing()
115 // if the last elapsed is greater than the average + std deviation, then stop
116 if (!_scrub_intervals.empty() && _scrub_timer.elapsed() > average_scrub_interval() + std_dev_scrub_interval())
118 _mcp.get_session().request_transport_speed (0.0);
119 _scrub_intervals.clear();
123 void JogWheel::push (State state)
125 _jog_wheel_states.push (state);
130 if (_jog_wheel_states.size() > 0)
132 _jog_wheel_states.pop();
136 void JogWheel::zoom_state_toggle()
138 if (jog_wheel_state() == zoom)
144 JogWheel::State JogWheel::scrub_state_cycle()
146 State top = jog_wheel_state();
149 // stop scrubbing and go to shuttle
152 _shuttle_speed = 0.0;
154 else if (top == shuttle)
156 // default to scroll, or the last selected
165 return jog_wheel_state();
168 void JogWheel::add_scrub_interval (unsigned long elapsed)
170 if (_scrub_intervals.size() > 5)
172 _scrub_intervals.pop_front();
174 _scrub_intervals.push_back (elapsed);
177 float JogWheel::average_scrub_interval()
180 for (std::deque<unsigned long>::iterator it = _scrub_intervals.begin(); it != _scrub_intervals.end(); ++it)
184 return sum / _scrub_intervals.size();
187 float JogWheel::std_dev_scrub_interval()
189 float average = average_scrub_interval();
191 // calculate standard deviation
193 for (std::deque<unsigned long>::iterator it = _scrub_intervals.begin(); it != _scrub_intervals.end(); ++it)
195 sum += pow (*it - average, 2);
197 return sqrt (sum / _scrub_intervals.size() -1);