merge r1449 from surfaces branch to include mackie surface and tranzport updates...
[ardour.git] / libs / surfaces / tranzport / wheel.cc
1 /*
2  *   Copyright (C) 2006 Paul Davis 
3  *   Copyright (C) 2007 Michael Taht
4  *
5  *   This program is free software; you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *   GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program; if not, write to the Free Software
17  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *  
19  *   */
20
21 #include <iostream>
22 #include <algorithm>
23 #include <cmath>
24
25 #define __STDC_FORMAT_MACROS
26 #include <inttypes.h>
27 #include <float.h>
28 #include <sys/time.h>
29 #include <errno.h>
30 #include <ardour/route.h>
31 #include <ardour/audio_track.h>
32 #include <ardour/session.h>
33 #include <ardour/location.h>
34 #include <ardour/dB.h>
35
36 using namespace ARDOUR;
37 using namespace std;
38 using namespace sigc;
39 using namespace PBD;
40
41 #include "i18n.h"
42
43 #include <pbd/abstract_ui.cc>
44
45 BaseUI::RequestType LEDChange = BaseUI::new_request_type ();
46 BaseUI::RequestType Print = BaseUI::new_request_type ();
47 BaseUI::RequestType SetCurrentTrack = BaseUI::new_request_type ();
48
49
50 #include <tranzport_control_protocol.h>
51
52 void
53 TranzportControlProtocol::datawheel ()
54 {
55         if ((buttonmask & ButtonTrackRight) || (buttonmask & ButtonTrackLeft)) {
56
57                 /* track scrolling */
58                 
59                 if (_datawheel < WheelDirectionThreshold) {
60                         next_track ();
61                 } else {
62                         prev_track ();
63                 }
64
65                 timerclear (&last_wheel_motion);
66                 
67         } else if ((buttonmask & ButtonPrev) || (buttonmask & ButtonNext)) {
68
69                 if (_datawheel < WheelDirectionThreshold) {
70                         next_marker ();
71                 } else {
72                         prev_marker ();
73                 }
74                 
75                 timerclear (&last_wheel_motion);
76                 
77         } else if (buttonmask & ButtonShift) {
78                 
79                 /* parameter control */
80                 
81                 if (route_table[0]) {
82                         switch (wheel_shift_mode) {
83                         case WheelShiftGain:
84                                 if (_datawheel < WheelDirectionThreshold) {
85                                         step_gain_up ();
86                                 } else {
87                                         step_gain_down ();
88                                 }
89                                 break;
90                         case WheelShiftPan:
91                                 if (_datawheel < WheelDirectionThreshold) {
92                                         step_pan_right ();
93                                 } else {
94                                         step_pan_left ();
95                                 }
96                                 break;
97                                 
98                         case WheelShiftMarker:
99                                 break;
100                                 
101                         case WheelShiftMaster:
102                                 break;
103                                 
104                         }
105                 }
106                 
107                 timerclear (&last_wheel_motion);
108                 
109         } else {
110                 
111                 switch (wheel_mode) {
112                 case WheelTimeline:
113                         scroll ();
114                         break;
115                         
116                 case WheelScrub:
117                         scrub ();
118                         break;
119                         
120                 case WheelShuttle:
121                         shuttle ();
122                         break;
123                 }
124         }
125 }
126
127 void
128 TranzportControlProtocol::scroll ()
129 {
130         float m = 1.0;
131         if (_datawheel < WheelDirectionThreshold) {
132                 m = 1.0;
133         } else {
134                 m = -1.0;
135         }
136         switch(wheel_increment) {
137         case WheelIncrScreen: ScrollTimeline (0.2*m); break;
138         case WheelIncrSlave:
139         case WheelIncrSample:
140         case WheelIncrBeat:
141         case WheelIncrBar:
142         case WheelIncrSecond:
143         case WheelIncrMinute:
144         default: break; // other modes unimplemented as yet
145         }
146 }
147
148 void
149 TranzportControlProtocol::scrub ()
150 {
151         float speed;
152         struct timeval now;
153         struct timeval delta;
154         int dir;
155         
156         gettimeofday (&now, 0);
157         
158         if (_datawheel < WheelDirectionThreshold) {
159                 dir = 1;
160         } else {
161                 dir = -1;
162         }
163         
164         if (dir != last_wheel_dir) {
165                 /* changed direction, start over */
166                 speed = 0.1f;
167         } else {
168                 if (timerisset (&last_wheel_motion)) {
169
170                         timersub (&now, &last_wheel_motion, &delta);
171                         
172                         /* 10 clicks per second => speed == 1.0 */
173                         
174                         speed = 100000.0f / (delta.tv_sec * 1000000 + delta.tv_usec);
175                         
176                 } else {
177                         
178                         /* start at half-speed and see where we go from there */
179                         
180                         speed = 0.5f;
181                 }
182         }
183         
184         last_wheel_motion = now;
185         last_wheel_dir = dir;
186         
187         set_transport_speed (speed * dir);
188 }
189
190 void
191 TranzportControlProtocol::shuttle ()
192 {
193         if (_datawheel < WheelDirectionThreshold) {
194                 if (session->transport_speed() < 0) {
195                         session->request_transport_speed (1.0);
196                 } else {
197                         session->request_transport_speed (session->transport_speed() + 0.1);
198                 }
199         } else {
200                 if (session->transport_speed() > 0) {
201                         session->request_transport_speed (-1.0);
202                 } else {
203                         session->request_transport_speed (session->transport_speed() - 0.1);
204                 }
205         }
206 }