2 * Copyright (C) 2006 Paul Davis
3 * Copyright (C) 2007 Michael Taht
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.
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.
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.
21 #include <tranzport_common.h>
22 #include <tranzport_control_protocol.h>
24 using namespace ARDOUR;
31 #include <pbd/abstract_ui.cc>
32 // HA, I don't need this anymore
33 #include <slider_gain.h>
35 // FIXME, flash recording light when recording and transport is moving
36 int TranzportControlProtocol::lights_show_recording()
38 return lights_show_normal();
41 void TranzportControlProtocol::show_bling() {
46 void TranzportControlProtocol::notify(const char *msg) {
48 if(strlen(msg) < 21) {
49 strcpy(last_notify_msg,msg);
51 strncpy(last_notify_msg,msg,16);
52 last_notify_msg[16] = '\n';
56 void TranzportControlProtocol::show_notify() {
57 // FIXME: Get width of the notify area somehow
63 print(1,0,last_notify_msg);
70 int TranzportControlProtocol::lights_show_bling()
74 case BlingKit: break; // rotate rec/mute/solo/any solo back and forth
75 case BlingRotating: break; // switch between lights
76 case BlingPairs: break; // Show pairs of lights
77 case BlingRows: break; // light each row in sequence
78 case BlingFlashAll: break; // Flash everything randomly
79 case BlingEnter: lights_on(); // Show intro
87 int TranzportControlProtocol::screen_show_bling()
91 case BlingKit: break; // rotate rec/mute/solo/any solo back and forth
92 case BlingRotating: break; // switch between lights
93 case BlingPairs: break; // Show pairs of lights
94 case BlingRows: break; // light each row in sequence
95 case BlingFlashAll: break; // Flash everything randomly
96 case BlingEnter: // Show intro
97 print(0,0,"!!Welcome to Ardour!");
98 print(1,0,"Peace through Music!");
106 int TranzportControlProtocol::lights_show_normal()
110 if (route_table[0]) {
111 boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack> (route_table[0]);
112 lights_pending[LightTrackrec] = at && at->record_enabled();
113 lights_pending[LightTrackmute] = route_get_muted(0);
114 lights_pending[LightTracksolo] = route_get_soloed(0);
116 lights_pending[LightTrackrec] = false;
117 lights_pending[LightTracksolo] = false;
118 lights_pending[LightTrackmute] = false;
121 /* Global settings */
123 lights_pending[LightLoop] = session->get_play_loop();
124 lights_pending[LightPunch] = session->config.get_punch_in() || session->config.get_punch_out();
125 lights_pending[LightRecord] = session->get_record_enabled();
126 lights_pending[LightAnysolo] = session->soloing();
131 int TranzportControlProtocol::lights_show_tempo()
133 // someday soon fiddle with the lights more sanely based on the tempo
134 return lights_show_normal();
138 TranzportControlProtocol::update_state ()
140 /* do the text and light updates */
142 switch (display_mode) {
143 case DisplayBigMeter:
149 lights_show_normal();
156 case DisplayRecording:
157 lights_show_recording();
161 case DisplayRecordingMeter:
162 lights_show_recording();
170 case DisplayBlingMeter:
182 TranzportControlProtocol::prev_marker ()
184 Location *location = session->locations()->first_location_before (session->transport_frame());
187 session->request_locate (location->start(), session->transport_rolling());
188 notify(location->name().c_str());
190 session->goto_start ();
197 TranzportControlProtocol::next_marker ()
199 Location *location = session->locations()->first_location_after (session->transport_frame());
202 session->request_locate (location->start(), session->transport_rolling());
203 notify(location->name().c_str());
205 session->request_locate (session->current_end_frame());
212 TranzportControlProtocol::show_current_track ()
217 if (route_table[0] == 0) {
218 print (0, 0, "---------------");
219 last_track_gain = FLT_MAX;
222 v = (char *)route_get_name (0).substr (0, 14).c_str();
223 if((len = strlen(v)) > 0) {
224 strncpy(pad,(char *)v,len);
233 TranzportControlProtocol::step_gain (float increment)
235 // FIXME: buttonstop is used elsewhere
236 if (buttonmask & ButtonStop) {
237 gain_fraction += 0.001*increment;
239 gain_fraction += 0.01*increment;
242 if (fabsf(gain_fraction) > 2.0) {
243 gain_fraction = 2.0*sign(gain_fraction);
246 route_set_gain (0, slider_position_to_gain (gain_fraction));
251 TranzportControlProtocol::step_gain_up ()
253 if (buttonmask & ButtonStop) {
254 gain_fraction += 0.001;
256 gain_fraction += 0.01;
259 if (gain_fraction > 2.0) {
263 route_set_gain (0, slider_position_to_gain (gain_fraction));
267 TranzportControlProtocol::step_gain_down ()
269 if (buttonmask & ButtonStop) {
270 gain_fraction -= 0.001;
272 gain_fraction -= 0.01;
275 if (gain_fraction < 0.0) {
279 route_set_gain (0, slider_position_to_gain (gain_fraction));
284 TranzportControlProtocol::next_track ()
286 ControlProtocol::next_track (current_track_id);
287 gain_fraction = gain_to_slider_position (route_get_effective_gain (0));
288 // notify("NextTrak"); // not needed til we have more modes
292 TranzportControlProtocol::prev_track ()
294 ControlProtocol::prev_track (current_track_id);
295 gain_fraction = gain_to_slider_position (route_get_effective_gain (0));
296 // notify("PrevTrak");
299 // This should kind of switch to using notify
301 // Was going to keep state around saying to retry or not
302 // haven't got to it yet, still not sure it's a good idea
305 TranzportControlProtocol::print (int row, int col, const char *text) {
306 print_noretry(row,col,text);
311 // count of bit set on damage?
314 TranzportControlProtocol::print_noretry (int row, int col, const char *text)
316 uint32_t length = strlen (text);
317 if (row*COLUMNS+col+length > (ROWS*COLUMNS)) {
320 // FIXME - be able to print the whole screen at a go.
322 std::bitset<ROWS*COLUMNS> mask(screen_invalid);
323 for(r = row, c = col, t = 0 ; t < length; c++,t++) {
324 screen_pending[r][c] = text[t];
325 mask[r*COLUMNS+c] = (screen_current[r][c] != screen_pending[r][c]);
327 screen_invalid = mask;
330 void TranzportControlProtocol::invalidate()
332 lcd_damage(); lights_invalidate(); screen_invalidate(); // one of these days lcds can be fine but screens not