summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorSampo Savolainen <v2@iki.fi>2008-11-01 20:10:56 +0000
committerSampo Savolainen <v2@iki.fi>2008-11-01 20:10:56 +0000
commit43d868cde8bea9932fc828dfd2461b0296bb9135 (patch)
tree0596dd4549c56eb78ba6d6fccb8fa5cf41f5ba13 /libs
parent3043b68bfbcd70ba13d132c8b833cdf3ba199266 (diff)
Wiimote control surface. Bind one wiimote by pressing 1+2 after the surface module is loaded. You need to bind every time you start ardour:
A Toggle play/stop D-pad: Up/Down: scroll tracks in the editor Left/Right: move playhead (nudge) +/- Zoom 1 Arm selected track(s) for recording 2 Toggle recording As an extra, if you press down B and then A to stopp recording pass, Ardour scraps the recorded audio. This is a work in progress. Please test. git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@4079 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/surfaces/wiimote/SConscript60
-rw-r--r--libs/surfaces/wiimote/interface.cc73
-rw-r--r--libs/surfaces/wiimote/wiimote.cc200
-rw-r--r--libs/surfaces/wiimote/wiimote.h43
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 */
+