diff -Naur -x '*.os' -x '*.so' -x '*~' ardour-2.5.virgin/libs/surfaces/control_protocol/control_protocol.cc ardour-2.5/libs/surfaces/control_protocol/control_protocol.cc --- ardour-2.5.virgin/libs/surfaces/control_protocol/control_protocol.cc 2008-07-25 04:55:23.000000000 -0500 +++ ardour-2.5/libs/surfaces/control_protocol/control_protocol.cc 2008-07-25 04:21:00.000000000 -0500 @@ -63,21 +63,21 @@ } else { id = 0; } - + if (id == limit) { id = 0; } else { id++; } - - while (id < limit) { + + while (id <= limit) { if ((cr = session->route_by_remote_id (id)) != 0) { break; } id++; } - - if (id == limit) { + + if (id > limit) { id = 0; while (id != initial_id) { if ((cr = session->route_by_remote_id (id)) != 0) { @@ -86,14 +86,14 @@ id++; } } - + route_table[0] = cr; } void ControlProtocol::prev_track (uint32_t initial_id) { - uint32_t limit = session->nroutes() - 1; + uint32_t limit = session->nroutes(); boost::shared_ptr cr = route_table[0]; uint32_t id; @@ -104,19 +104,19 @@ } if (id == 0) { - id = session->nroutes() - 1; + id = session->nroutes(); } else { id--; } - while (id >= 0) { + while (id > 0) { if ((cr = session->route_by_remote_id (id)) != 0) { break; } id--; } - if (id < 0) { + if (id <= 0) { id = limit; while (id > initial_id) { if ((cr = session->route_by_remote_id (id)) != 0) { diff -Naur -x '*.os' -x '*.so' -x '*~' ardour-2.5.virgin/libs/surfaces/tranzport/SConscript ardour-2.5/libs/surfaces/tranzport/SConscript --- ardour-2.5.virgin/libs/surfaces/tranzport/SConscript 2008-07-25 04:55:23.000000000 -0500 +++ ardour-2.5/libs/surfaces/tranzport/SConscript 2008-07-25 02:02:29.000000000 -0500 @@ -25,6 +25,7 @@ buttons.cc io.cc io_usb.cc +io_kernel.cc panner.cc lights.cc screen.cc @@ -44,12 +45,16 @@ #io_midi.cc #io_kernel.cc +#Should eventually go into some sort of config, but if you're applying +# this patch you probably want it... +env['HAVE_TRANZPORT_KERNEL_DRIVER']=1 + tranzport.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE") tranzport.Append(CXXFLAGS="-DDATA_DIR=\\\""+final_prefix+"/share\\\"") tranzport.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"") tranzport.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"") -#if env['HAVE_TRANZPORT_KERNEL_DRIVER']: -# tranzport.Append(CXXFLAGS="-DHAVE_TRANZPORT_KERNEL_DRIVER=1") +if env['HAVE_TRANZPORT_KERNEL_DRIVER']: + tranzport.Append(CXXFLAGS="-DHAVE_TRANZPORT_KERNEL_DRIVER=1") #merge more into tranzport files for the right io lib diff -Naur -x '*.os' -x '*.so' -x '*~' ardour-2.5.virgin/libs/surfaces/tranzport/general.cc ardour-2.5/libs/surfaces/tranzport/general.cc --- ardour-2.5.virgin/libs/surfaces/tranzport/general.cc 2008-07-25 04:55:23.000000000 -0500 +++ ardour-2.5/libs/surfaces/tranzport/general.cc 2008-07-25 04:59:49.000000000 -0500 @@ -284,6 +284,7 @@ TranzportControlProtocol::next_track () { ControlProtocol::next_track (current_track_id); + current_track_id = route_table[0]->remote_control_id(); gain_fraction = gain_to_slider_position (route_get_effective_gain (0)); // notify("NextTrak"); // not needed til we have more modes } @@ -292,6 +293,7 @@ TranzportControlProtocol::prev_track () { ControlProtocol::prev_track (current_track_id); + current_track_id = route_table[0]->remote_control_id(); gain_fraction = gain_to_slider_position (route_get_effective_gain (0)); // notify("PrevTrak"); } diff -Naur -x '*.os' -x '*.so' -x '*~' ardour-2.5.virgin/libs/surfaces/tranzport/init.cc ardour-2.5/libs/surfaces/tranzport/init.cc --- ardour-2.5.virgin/libs/surfaces/tranzport/init.cc 2008-07-25 04:55:23.000000000 -0500 +++ ardour-2.5/libs/surfaces/tranzport/init.cc 2008-07-25 05:11:06.000000000 -0500 @@ -141,7 +141,7 @@ _datawheel = 0; _device_status = STATUS_OFFLINE; udev = 0; - current_track_id = 0; + current_track_id = 1; last_where = max_frames; wheel_mode = WheelTimeline; wheel_shift_mode = WheelShiftGain; @@ -150,18 +150,24 @@ last_notify_msg[0] = '\0'; last_notify = 0; timerclear (&last_wheel_motion); + last_speed = 0.0f; last_wheel_dir = 1; last_track_gain = FLT_MAX; last_write_error = 0; last_read_error = 0; - display_mode = DisplayBling; + display_mode = DisplayNormal; gain_fraction = 0.0; + session->route_by_remote_id (1); + route_table[0] = session->route_by_remote_id (1); + + invalidate(); screen_init(); lights_init(); // FIXME: Wait til device comes online somewhere // About 3 reads is enough // enter_bling_mode(); + } @@ -181,6 +187,8 @@ //int intro = 20; // wait for the device to come online + display_mode = DisplayNormal; + invalidate(); screen_init(); lights_init(); @@ -199,7 +207,6 @@ // lights_on(); // while(flush()!=0) ; // lights_off(); - display_mode = DisplayNormal; while (true) { @@ -215,6 +222,7 @@ } else { offline = 0; // hate writing this } + unsigned int s = (last_write_error == 0) | ((last_read_error == 0) << 1); switch (s) { case 0: val = read(buf,DEFAULT_USB_TIMEOUT); break; @@ -223,7 +231,7 @@ case 3: val = read(buf,DEFAULT_USB_TIMEOUT*2); break; // Hoo, boy, we're in trouble default: break; // not reached } - + #if DEBUG_TRANZPORT_BITS > 9 if(_device_status != STATUS_OFFLINE && _device_status != STATUS_ONLINE && _device_status != STATUS_OK) { printf("The device has more status bits than off or online: %d\n",_device_status); @@ -307,6 +315,7 @@ } } } + // pending = 0; } return (void*) 0; diff -Naur -x '*.os' -x '*.so' -x '*~' ardour-2.5.virgin/libs/surfaces/tranzport/io_kernel.cc ardour-2.5/libs/surfaces/tranzport/io_kernel.cc --- ardour-2.5.virgin/libs/surfaces/tranzport/io_kernel.cc 1969-12-31 18:00:00.000000000 -0600 +++ ardour-2.5/libs/surfaces/tranzport/io_kernel.cc 2008-07-25 03:33:15.000000000 -0500 @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2006 Paul Davis + * 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. + * + * */ + +#include + +#define __STDC_FORMAT_MACROS +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#if HAVE_TRANZPORT_KERNEL_DRIVER +using namespace ARDOUR; +using namespace std; +using namespace sigc; +using namespace PBD; + +#include "i18n.h" + +#include + +// I note that these usb specific open, close, probe, read routines are basically +// pure boilerplate and could easily be abstracted elsewhere + +bool +TranzportControlProtocol::probe () +{ + struct stat buf; + + // This is about as simple as it gets. + // FIXME real probing? Does the kernel driver create a + // tranzport0 even if your tranzport isn't plugged in? + // multiple tranzports? + // I am far too lazy to dig around behind my DAW and unplug it -- + // this will have to do. + + if (!stat(TRANZPORT_DEVICE, &buf)) + return true; + + return false; +} + +int +TranzportControlProtocol::open () +{ + // not sure if this is what the 'udev' var was intended + // for but I'm gonna use it anyway. + udev = ::open((const char *)TRANZPORT_DEVICE, O_RDWR); + + if (udev > 0) { + return 0; + } + + cerr << _("Tranzport: no device detected") << endmsg; + return -1; +} + + +int +TranzportControlProtocol::close () +{ + int ret = 0; + + if (udev <= 0) { + return 0; + } + + return ::close(udev); +} + +int TranzportControlProtocol::read(uint8_t *buf, uint32_t timeout_override) +{ + fd_set rfds; + struct timeval tv; + + // dirty but it'll do + + FD_ZERO(&rfds); + FD_SET(udev, &rfds); + + tv.tv_sec = 0; + tv.tv_usec = 10000; + + if (!select(udev+1, &rfds, NULL, NULL, &tv)) { + // yawn + return 0; + } + + + last_read_error = ::read(udev, (char *) buf, 8); + + switch(last_read_error) { + case -ENOENT: + case -ENXIO: + case -ECONNRESET: + case -ESHUTDOWN: + case -ENODEV: + cerr << "Tranzport disconnected, errno: " << last_read_error; + set_active(false); + case -ETIMEDOUT: // This is normal + break; + default: +#if 0 + cerr << "Got an unknown error on read:" << last_read_error << "\n"; +#endif + break; + } + + return last_read_error; +} + + +int +TranzportControlProtocol::write_noretry (uint8_t* cmd, uint32_t timeout_override) +{ + // nobody appears to actually use this + return 0; +} + +int +TranzportControlProtocol::write (uint8_t* cmd, uint32_t timeout_override) +{ + int val; + int retry = 0; +// if(inflight > MAX_TRANZPORT_INFLIGHT) { printf("Too many inflight\n"); return (-1); } + + while(((val = ::write(udev, (char*) cmd, 8)) != 8) && retry++ < MAX_RETRY) { + printf("Tranzport write failed, retrying\n"); + } + + if (retry == MAX_RETRY) { + printf("Too many retries on a tranzport write, aborting\n"); + } + + if (val < 0) { + printf("Tranzport write failed: %d\n", val); + return val; + } + if (val != 8) { + printf("usb_interrupt_write failed: %d\n", val); + return -1; + } +// ++inflight; + return 0; +} + +#endif diff -Naur -x '*.os' -x '*.so' -x '*~' ardour-2.5.virgin/libs/surfaces/tranzport/screen.cc ardour-2.5/libs/surfaces/tranzport/screen.cc --- ardour-2.5.virgin/libs/surfaces/tranzport/screen.cc 2008-07-25 04:55:23.000000000 -0500 +++ ardour-2.5/libs/surfaces/tranzport/screen.cc 2008-07-25 04:58:16.000000000 -0500 @@ -19,6 +19,7 @@ * */ #include +#include void TranzportControlProtocol::screen_clear () diff -Naur -x '*.os' -x '*.so' -x '*~' ardour-2.5.virgin/libs/surfaces/tranzport/show.cc ardour-2.5/libs/surfaces/tranzport/show.cc --- ardour-2.5.virgin/libs/surfaces/tranzport/show.cc 2008-07-25 04:55:23.000000000 -0500 +++ ardour-2.5/libs/surfaces/tranzport/show.cc 2008-07-25 05:10:32.000000000 -0500 @@ -148,7 +148,7 @@ if (route_table[0] == 0) { // Principle of least surprise - print (1, 0, "NoAUDIO "); + print (1, 0, "NoAUDIO "); return; } @@ -286,7 +286,7 @@ void TranzportControlProtocol::show_bbt (nframes_t where) { - if (where != last_where) { + if (where != last_where || session->transport_speed() != last_speed) { char buf[16]; BBT_Time bbt; @@ -300,6 +300,7 @@ last_beats = bbt.beats; last_ticks = bbt.ticks; last_where = where; + last_speed = session->transport_speed(); float speed = fabsf(session->transport_speed()); diff -Naur -x '*.os' -x '*.so' -x '*~' ardour-2.5.virgin/libs/surfaces/tranzport/tranzport_control_protocol.h ardour-2.5/libs/surfaces/tranzport/tranzport_control_protocol.h --- ardour-2.5.virgin/libs/surfaces/tranzport/tranzport_control_protocol.h 2008-04-18 08:54:21.000000000 -0500 +++ ardour-2.5/libs/surfaces/tranzport/tranzport_control_protocol.h 2008-07-25 05:10:51.000000000 -0500 @@ -200,6 +200,8 @@ uint32_t last_secs; uint32_t last_frames; nframes_t last_where; + float last_speed; + ARDOUR::gain_t last_track_gain; uint32_t last_meter_fill; struct timeval last_wheel_motion;