diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/surfaces/wiimote/SConscript | 60 | ||||
-rw-r--r-- | libs/surfaces/wiimote/interface.cc | 73 | ||||
-rw-r--r-- | libs/surfaces/wiimote/wiimote.cc | 200 | ||||
-rw-r--r-- | libs/surfaces/wiimote/wiimote.h | 43 |
4 files changed, 376 insertions, 0 deletions
diff --git a/libs/surfaces/wiimote/SConscript b/libs/surfaces/wiimote/SConscript new file mode 100644 index 0000000000..abfd40e534 --- /dev/null +++ b/libs/surfaces/wiimote/SConscript @@ -0,0 +1,60 @@ +# -*- python -*- + +import os +import os.path +import glob + +Import('env final_prefix install_prefix final_config_prefix libraries i18n') + +wiimote = env.Clone() + +# +# this defines the version number of libardour_wiimote +# + +domain = 'ardour_wiimote' + +wiimote.Append(DOMAIN = domain, MAJOR = 1, MINOR = 0, MICRO = 0) +wiimote.Append(CXXFLAGS = "-DPACKAGE=\\\"" + domain + "\\\"") +wiimote.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED") +wiimote.Append(PACKAGE = domain) +wiimote.Append(POTFILE = domain + '.pot') + +wiimote_files=Split(""" +wiimote.cc +interface.cc +""") + +wiimote.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE") +wiimote.Append(CXXFLAGS="-DDATA_DIR=\\\""+final_prefix+"/share\\\"") +wiimote.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"") +wiimote.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"") +wiimote.Append(LINKFLAGS="-lcwiid") +#wiimote.Append(CPPPATH = libraries['jack'].get('CPPPATH', [])) + +wiimote.Merge ([ + libraries['ardour'], + libraries['ardour_cp'], + libraries['sndfile-ardour'], + libraries['midi++2'], + libraries['pbd'], + libraries['sigc2'], + libraries['usb'], + libraries['xml'], + libraries['glib2'], + libraries['glibmm2'] + ]) + +libardour_wiimote = wiimote.SharedLibrary('ardour_wiimote', wiimote_files) + +Default(libardour_wiimote) + +if env['NLS']: + i18n (wiimote, wiimote_files, env) + +env.Alias('install', env.Install(os.path.join(install_prefix, env['LIBDIR'], 'ardour2', 'surfaces'), libardour_wiimote)) + +env.Alias('tarball', env.Distribute (env['DISTTREE'], + [ 'SConscript' ] + + wiimote_files + + glob.glob('po/*.po') + glob.glob('*.h'))) diff --git a/libs/surfaces/wiimote/interface.cc b/libs/surfaces/wiimote/interface.cc new file mode 100644 index 0000000000..0ef301dd6c --- /dev/null +++ b/libs/surfaces/wiimote/interface.cc @@ -0,0 +1,73 @@ +#include <pbd/failed_constructor.h> + +#include <control_protocol/control_protocol.h> +#include "wiimote.h" + +#include <ardour/session.h> + +using namespace ARDOUR; + +static WiimoteControlProtocol *foo; + +ControlProtocol* +new_wiimote_protocol (ControlProtocolDescriptor* descriptor, Session* s) +{ + WiimoteControlProtocol* wmcp; + + try { + wmcp = new WiimoteControlProtocol (*s); + } catch (failed_constructor& err) { + return 0; + } + + if (wmcp-> set_active (true)) { + delete wmcp; + return 0; + } + + foo = wmcp; + + return wmcp; +} + +void +wiimote_control_protocol_cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count, union cwiid_mesg mesg[], struct timespec *t) +{ + assert(foo != 0); + + foo->wiimote_callback(wiimote,mesg_count,mesg,t); +} + +void +delete_wiimote_protocol (ControlProtocolDescriptor* descriptor, ControlProtocol* cp) +{ + foo = 0; + delete cp; +} + +bool +probe_wiimote_protocol (ControlProtocolDescriptor* descriptor) +{ + return WiimoteControlProtocol::probe (); +} + +static ControlProtocolDescriptor wiimote_descriptor = { + name : "Wiimote", + id : "uri://ardour.org/surfaces/wiimote:0", + ptr : 0, + module : 0, + mandatory : 0, + supports_feedback : false, + probe : probe_wiimote_protocol, + initialize : new_wiimote_protocol, + destroy : delete_wiimote_protocol +}; + + +extern "C" { +ControlProtocolDescriptor* +protocol_descriptor () { + return &wiimote_descriptor; +} +} + diff --git a/libs/surfaces/wiimote/wiimote.cc b/libs/surfaces/wiimote/wiimote.cc new file mode 100644 index 0000000000..8b48d7378f --- /dev/null +++ b/libs/surfaces/wiimote/wiimote.cc @@ -0,0 +1,200 @@ +#include "wiimote.h" + +#include <iostream> +#include <sigc++/bind.h> + +#include <pbd/xml++.h> +#include <ardour/session.h> + +#include "i18n.h" + + +using namespace ARDOUR; +using namespace PBD; + +void wiimote_control_protocol_cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count, union cwiid_mesg mesg[], struct timespec *t); + +uint16_t WiimoteControlProtocol::button_state = 0; + +WiimoteControlProtocol::WiimoteControlProtocol ( Session & session) + : ControlProtocol ( session, "Wiimote"), + thread_quit (false), + thread_registered_for_ardour (false) +{ + std::cerr << "WiimoteControlProtocol()" << std::endl; + thread = Glib::Thread::create( sigc::mem_fun(*this, &WiimoteControlProtocol::main_thread), true); +} + +WiimoteControlProtocol::~WiimoteControlProtocol() +{ + thread_quit = true; + thread->join(); + // TODO: you con't delete the thread, but is join() still enough? + std::cerr << "~WiimoteControlProtocol()" << std::endl; +} + + +bool +WiimoteControlProtocol::probe() +{ + return true; +} + +void +WiimoteControlProtocol::wiimote_callback(cwiid_wiimote_t *wiimote, int mesg_count, union cwiid_mesg mesg[], struct timespec *t) +{ + int i; + uint16_t b; + + if (!thread_registered_for_ardour) { + register_thread("Wiimote Control Protocol"); + thread_registered_for_ardour = true; + } + + for (i=0; i < mesg_count; i++) + { + if (mesg[i].type != CWIID_MESG_BTN) continue; + + b = (mesg[i].btn_mesg.buttons ^ button_state) & mesg[i].btn_mesg.buttons; + + button_state = mesg[i].btn_mesg.buttons; + + if (b & CWIID_BTN_2) { + rec_enable_toggle(); + //std::cerr << "2" << std::endl; + } + if (b & CWIID_BTN_1) { + access_action("Editor/track-record-enable-toggle"); + //std::cerr << "1" << std::endl; + } + if (b & CWIID_BTN_B) { + transport_stop(); + //std::cerr << "B" << std::endl; + } + if (b & CWIID_BTN_A && button_state & CWIID_BTN_B) { + // B pressed down and then A + access_action("Transport/ToggleRollForgetCapture"); + //std::cerr << "B+A" << std::endl; + } + + if (b & CWIID_BTN_A && !(button_state & CWIID_BTN_B)) { + // Just A pressed + access_action("Transport/ToggleRoll"); + //std::cerr << "A" << std::endl; + } + if (b & CWIID_BTN_MINUS) { + access_action("Editor/temporal-zoom-out"); + //std::cerr << "-" << std::endl; + } + if (b & CWIID_BTN_HOME) { + //std::cerr << "home" << std::endl; + } + if (b & CWIID_BTN_LEFT) { + access_action("Editor/nudge-playhead-backward"); + //std::cerr << "<" << std::endl; + } + if (b & CWIID_BTN_RIGHT) { + access_action("Editor/nudge-playhead-forward"); + //std::cerr << ">" << std::endl; + } + if (b & CWIID_BTN_DOWN) { + access_action("Editor/select-next-route"); + //std::cerr << "_" << std::endl; + } + if (b & CWIID_BTN_UP) { + access_action("Editor/select-prev-route"); + //std::cerr << "^" << std::endl; + } + if (b & CWIID_BTN_PLUS) { + access_action("Editor/temporal-zoom-in"); + //std::cerr << "+" << std::endl; + } + + } +} + +void +WiimoteControlProtocol::main_thread() +{ + cwiid_wiimote_t *wiimote_handle = 0; + bdaddr_t bdaddr; + unsigned char rpt_mode = 0; + + std::cerr << "wiimote: discovering, press 1+2" << std::endl; + + while (!wiimote_handle && !thread_quit) { + bdaddr = *BDADDR_ANY; + wiimote_handle = cwiid_open(&bdaddr, 0); + + if (!wiimote_handle) { + sleep(1); + // We don't know whether the issue was a timeout or a configuration + // issue + } + } + + if (thread_quit) { + // The corner case where the wiimote is bound at the same time as + // the control protocol is destroyed + if (wiimote_handle) { + cwiid_close(wiimote_handle); + } + std::cerr << "Wiimote Control Protocol stopped before connected to a wiimote" << std::endl; + return; + } + + std::cerr << "Wiimote: connected" << std::endl; + WiimoteControlProtocol::button_state = 0; + + if (cwiid_enable(wiimote_handle, CWIID_FLAG_REPEAT_BTN)) { + std::cerr << "cwiid_enable(), error" << std::endl; + cwiid_close(wiimote_handle); + return; + } + if (cwiid_set_mesg_callback(wiimote_handle, wiimote_control_protocol_cwiid_callback)) { + std::cerr << "cwiid_set_mesg_callback(), couldn't connect callback" << std::endl; + cwiid_close(wiimote_handle); + return; + } + if (cwiid_command(wiimote_handle, CWIID_CMD_RPT_MODE, CWIID_RPT_BTN)) { + std::cerr << "cwiid_command(), RPT_MODE error" << std::endl; + cwiid_close(wiimote_handle); + return; + } + + rpt_mode |= CWIID_RPT_BTN; + cwiid_enable(wiimote_handle, CWIID_FLAG_MESG_IFC); + cwiid_set_rpt_mode(wiimote_handle, rpt_mode); + + while (!thread_quit) { + sleep(1); + } + + cwiid_close(wiimote_handle); + std::cerr << "Wiimote: stopped" << std::endl; +} + + +int +WiimoteControlProtocol::set_active (bool yn) +{ + // Let's not care about this just yet + return 0; + +} + +XMLNode& +WiimoteControlProtocol::get_state() +{ + XMLNode *node = new XMLNode ("Protocol"); + node->add_property (X_("name"), _name); + node->add_property (X_("feedback"), "0"); + + return *node; +} + +int +WiimoteControlProtocol::set_state(const XMLNode& node) +{ + return 0; +} diff --git a/libs/surfaces/wiimote/wiimote.h b/libs/surfaces/wiimote/wiimote.h new file mode 100644 index 0000000000..7b0dcc6094 --- /dev/null +++ b/libs/surfaces/wiimote/wiimote.h @@ -0,0 +1,43 @@ +#ifndef ardour_wiimote_control_protocol_h +#define ardour_wiimote_control_protocol_h + +#include <ardour/types.h> +#include <control_protocol/control_protocol.h> + +#include <glibmm/thread.h> + +#include <cwiid.h> + + +namespace ARDOUR { + class Session; +} + +class WiimoteControlProtocol : public ARDOUR::ControlProtocol { + public: + WiimoteControlProtocol (ARDOUR::Session &); + virtual ~WiimoteControlProtocol (); + + static bool probe(); + + int set_active (bool yn); + XMLNode& get_state(); + int set_state(const XMLNode&); + + void wiimote_callback(cwiid_wiimote_t *, int, union cwiid_mesg [], + struct timespec *); + + private: + + void main_thread(); + + bool thread_quit; + bool thread_registered_for_ardour; + + Glib::Thread *thread; + static uint16_t button_state; +}; + + +#endif /* ardour_wiimote_control_protocol_h */ + |