2008-06-02 17:41:35 -04:00
|
|
|
/*
|
2015-10-04 14:51:05 -04:00
|
|
|
* Copyright (C) 2006 Paul Davis
|
2008-06-02 17:41:35 -04:00
|
|
|
* Copyright (C) 2007 Michael Taht
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
2015-10-04 14:51:05 -04:00
|
|
|
*
|
2008-06-02 17:41:35 -04:00
|
|
|
* */
|
|
|
|
|
|
|
|
#include <tranzport_common.h>
|
|
|
|
#include <tranzport_control_protocol.h>
|
|
|
|
|
|
|
|
using namespace ARDOUR;
|
|
|
|
using namespace std;
|
|
|
|
using namespace sigc;
|
|
|
|
using namespace PBD;
|
|
|
|
|
|
|
|
#include "i18n.h"
|
|
|
|
|
|
|
|
#include <pbd/abstract_ui.cc>
|
|
|
|
// HA, I don't need this anymore
|
|
|
|
#include <slider_gain.h>
|
|
|
|
|
|
|
|
// FIXME, flash recording light when recording and transport is moving
|
2015-10-04 14:51:05 -04:00
|
|
|
int TranzportControlProtocol::lights_show_recording()
|
2008-06-02 17:41:35 -04:00
|
|
|
{
|
|
|
|
return lights_show_normal();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TranzportControlProtocol::show_bling() {
|
|
|
|
lights_show_bling();
|
|
|
|
screen_show_bling();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TranzportControlProtocol::notify(const char *msg) {
|
|
|
|
last_notify=100;
|
|
|
|
if(strlen(msg) < 21) {
|
|
|
|
strcpy(last_notify_msg,msg);
|
|
|
|
} else {
|
|
|
|
strncpy(last_notify_msg,msg,16);
|
|
|
|
last_notify_msg[16] = '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TranzportControlProtocol::show_notify() {
|
|
|
|
// FIXME: Get width of the notify area somehow
|
|
|
|
if(last_notify==0) {
|
|
|
|
print(1,0," ");
|
|
|
|
last_notify=-1;
|
|
|
|
}
|
|
|
|
if(last_notify > 0) {
|
|
|
|
print(1,0,last_notify_msg);
|
|
|
|
--last_notify;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Need more bling!
|
|
|
|
|
2015-10-04 14:51:05 -04:00
|
|
|
int TranzportControlProtocol::lights_show_bling()
|
2008-06-02 17:41:35 -04:00
|
|
|
{
|
|
|
|
switch (bling_mode) {
|
|
|
|
case BlingOff: break;
|
|
|
|
case BlingKit: break; // rotate rec/mute/solo/any solo back and forth
|
|
|
|
case BlingRotating: break; // switch between lights
|
|
|
|
case BlingPairs: break; // Show pairs of lights
|
|
|
|
case BlingRows: break; // light each row in sequence
|
|
|
|
case BlingFlashAll: break; // Flash everything randomly
|
|
|
|
case BlingEnter: lights_on(); // Show intro
|
2015-10-04 14:51:05 -04:00
|
|
|
case BlingExit:
|
2008-06-02 17:41:35 -04:00
|
|
|
lights_off();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-10-04 14:51:05 -04:00
|
|
|
int TranzportControlProtocol::screen_show_bling()
|
2008-06-02 17:41:35 -04:00
|
|
|
{
|
|
|
|
switch (bling_mode) {
|
|
|
|
case BlingOff: break;
|
|
|
|
case BlingKit: break; // rotate rec/mute/solo/any solo back and forth
|
|
|
|
case BlingRotating: break; // switch between lights
|
|
|
|
case BlingPairs: break; // Show pairs of lights
|
|
|
|
case BlingRows: break; // light each row in sequence
|
|
|
|
case BlingFlashAll: break; // Flash everything randomly
|
|
|
|
case BlingEnter: // Show intro
|
|
|
|
print(0,0,"!!Welcome to Ardour!");
|
|
|
|
print(1,0,"Peace through Music!");
|
|
|
|
break;
|
2015-10-04 14:51:05 -04:00
|
|
|
case BlingExit:
|
2008-06-02 17:41:35 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-10-04 14:51:05 -04:00
|
|
|
int TranzportControlProtocol::lights_show_normal()
|
2008-06-02 17:41:35 -04:00
|
|
|
{
|
|
|
|
/* Track only */
|
|
|
|
|
|
|
|
if (route_table[0]) {
|
|
|
|
boost::shared_ptr<AudioTrack> at = boost::dynamic_pointer_cast<AudioTrack> (route_table[0]);
|
|
|
|
lights_pending[LightTrackrec] = at && at->record_enabled();
|
2015-10-04 14:51:05 -04:00
|
|
|
lights_pending[LightTrackmute] = route_get_muted(0);
|
2008-06-02 17:41:35 -04:00
|
|
|
lights_pending[LightTracksolo] = route_get_soloed(0);
|
|
|
|
} else {
|
|
|
|
lights_pending[LightTrackrec] = false;
|
|
|
|
lights_pending[LightTracksolo] = false;
|
|
|
|
lights_pending[LightTrackmute] = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Global settings */
|
|
|
|
|
2015-10-04 14:51:05 -04:00
|
|
|
lights_pending[LightLoop] = session->get_play_loop();
|
2009-06-08 19:58:46 -04:00
|
|
|
lights_pending[LightPunch] = session->config.get_punch_in() || session->config.get_punch_out();
|
2008-06-02 17:41:35 -04:00
|
|
|
lights_pending[LightRecord] = session->get_record_enabled();
|
|
|
|
lights_pending[LightAnysolo] = session->soloing();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-10-04 14:51:05 -04:00
|
|
|
int TranzportControlProtocol::lights_show_tempo()
|
2008-06-02 17:41:35 -04:00
|
|
|
{
|
2015-10-04 14:51:05 -04:00
|
|
|
// someday soon fiddle with the lights more sanely based on the tempo
|
2008-06-02 17:41:35 -04:00
|
|
|
return lights_show_normal();
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
TranzportControlProtocol::update_state ()
|
|
|
|
{
|
|
|
|
/* do the text and light updates */
|
|
|
|
|
|
|
|
switch (display_mode) {
|
|
|
|
case DisplayBigMeter:
|
|
|
|
lights_show_tempo();
|
|
|
|
show_meter ();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DisplayNormal:
|
|
|
|
lights_show_normal();
|
|
|
|
normal_update();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DisplayConfig:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DisplayRecording:
|
|
|
|
lights_show_recording();
|
|
|
|
normal_update();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DisplayRecordingMeter:
|
|
|
|
lights_show_recording();
|
2015-10-04 14:51:05 -04:00
|
|
|
show_meter();
|
2008-06-02 17:41:35 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case DisplayBling:
|
|
|
|
show_bling();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case DisplayBlingMeter:
|
|
|
|
lights_show_bling();
|
|
|
|
show_meter();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
show_notify();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TranzportControlProtocol::prev_marker ()
|
|
|
|
{
|
|
|
|
Location *location = session->locations()->first_location_before (session->transport_frame());
|
|
|
|
|
|
|
|
if (location) {
|
|
|
|
session->request_locate (location->start(), session->transport_rolling());
|
|
|
|
notify(location->name().c_str());
|
|
|
|
} else {
|
|
|
|
session->goto_start ();
|
|
|
|
notify("START");
|
|
|
|
}
|
2015-10-04 14:51:05 -04:00
|
|
|
|
2008-06-02 17:41:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TranzportControlProtocol::next_marker ()
|
|
|
|
{
|
|
|
|
Location *location = session->locations()->first_location_after (session->transport_frame());
|
|
|
|
|
|
|
|
if (location) {
|
|
|
|
session->request_locate (location->start(), session->transport_rolling());
|
|
|
|
notify(location->name().c_str());
|
|
|
|
} else {
|
|
|
|
session->request_locate (session->current_end_frame());
|
|
|
|
notify("END ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
TranzportControlProtocol::show_current_track ()
|
|
|
|
{
|
|
|
|
char pad[COLUMNS];
|
|
|
|
char *v;
|
|
|
|
int len;
|
|
|
|
if (route_table[0] == 0) {
|
|
|
|
print (0, 0, "---------------");
|
|
|
|
last_track_gain = FLT_MAX;
|
|
|
|
} else {
|
|
|
|
strcpy(pad," ");
|
|
|
|
v = (char *)route_get_name (0).substr (0, 14).c_str();
|
|
|
|
if((len = strlen(v)) > 0) {
|
|
|
|
strncpy(pad,(char *)v,len);
|
|
|
|
}
|
|
|
|
print (0, 0, pad);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
void
|
|
|
|
TranzportControlProtocol::step_gain (float increment)
|
|
|
|
{
|
|
|
|
// FIXME: buttonstop is used elsewhere
|
|
|
|
if (buttonmask & ButtonStop) {
|
|
|
|
gain_fraction += 0.001*increment;
|
|
|
|
} else {
|
|
|
|
gain_fraction += 0.01*increment;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (fabsf(gain_fraction) > 2.0) {
|
|
|
|
gain_fraction = 2.0*sign(gain_fraction);
|
|
|
|
}
|
|
|
|
|
|
|
|
route_set_gain (0, slider_position_to_gain (gain_fraction));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
void
|
|
|
|
TranzportControlProtocol::step_gain_up ()
|
|
|
|
{
|
|
|
|
if (buttonmask & ButtonStop) {
|
|
|
|
gain_fraction += 0.001;
|
|
|
|
} else {
|
|
|
|
gain_fraction += 0.01;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gain_fraction > 2.0) {
|
|
|
|
gain_fraction = 2.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
route_set_gain (0, slider_position_to_gain (gain_fraction));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TranzportControlProtocol::step_gain_down ()
|
|
|
|
{
|
|
|
|
if (buttonmask & ButtonStop) {
|
|
|
|
gain_fraction -= 0.001;
|
|
|
|
} else {
|
|
|
|
gain_fraction -= 0.01;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gain_fraction < 0.0) {
|
|
|
|
gain_fraction = 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
route_set_gain (0, slider_position_to_gain (gain_fraction));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
TranzportControlProtocol::next_track ()
|
|
|
|
{
|
|
|
|
ControlProtocol::next_track (current_track_id);
|
|
|
|
gain_fraction = gain_to_slider_position (route_get_effective_gain (0));
|
|
|
|
// notify("NextTrak"); // not needed til we have more modes
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
TranzportControlProtocol::prev_track ()
|
|
|
|
{
|
|
|
|
ControlProtocol::prev_track (current_track_id);
|
|
|
|
gain_fraction = gain_to_slider_position (route_get_effective_gain (0));
|
|
|
|
// notify("PrevTrak");
|
|
|
|
}
|
|
|
|
|
|
|
|
// This should kind of switch to using notify
|
|
|
|
|
|
|
|
// Was going to keep state around saying to retry or not
|
|
|
|
// haven't got to it yet, still not sure it's a good idea
|
|
|
|
|
|
|
|
void
|
|
|
|
TranzportControlProtocol::print (int row, int col, const char *text) {
|
|
|
|
print_noretry(row,col,text);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -1 on failure
|
|
|
|
// 0 on no damage
|
|
|
|
// count of bit set on damage?
|
|
|
|
|
|
|
|
void
|
|
|
|
TranzportControlProtocol::print_noretry (int row, int col, const char *text)
|
|
|
|
{
|
|
|
|
uint32_t length = strlen (text);
|
|
|
|
if (row*COLUMNS+col+length > (ROWS*COLUMNS)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// FIXME - be able to print the whole screen at a go.
|
|
|
|
uint32_t t,r,c;
|
|
|
|
std::bitset<ROWS*COLUMNS> mask(screen_invalid);
|
|
|
|
for(r = row, c = col, t = 0 ; t < length; c++,t++) {
|
|
|
|
screen_pending[r][c] = text[t];
|
|
|
|
mask[r*COLUMNS+c] = (screen_current[r][c] != screen_pending[r][c]);
|
|
|
|
}
|
|
|
|
screen_invalid = mask;
|
|
|
|
}
|
|
|
|
|
2015-10-04 14:51:05 -04:00
|
|
|
void TranzportControlProtocol::invalidate()
|
2008-06-02 17:41:35 -04:00
|
|
|
{
|
|
|
|
lcd_damage(); lights_invalidate(); screen_invalidate(); // one of these days lcds can be fine but screens not
|
|
|
|
}
|