summaryrefslogtreecommitdiff
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
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
-rw-r--r--SConstruct14
-rw-r--r--gtk2_ardour/editor.cc2
-rw-r--r--gtk2_ardour/editor.h1
-rw-r--r--gtk2_ardour/editor_actions.cc3
-rw-r--r--gtk2_ardour/editor_ops.cc22
-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
9 files changed, 416 insertions, 2 deletions
diff --git a/SConstruct b/SConstruct
index dd91ed2f19..d841472956 100644
--- a/SConstruct
+++ b/SConstruct
@@ -50,6 +50,7 @@ opts.AddOptions(
BoolOption('NLS', 'Set to turn on i18n support', 1),
PathOption('PREFIX', 'Set the install "prefix"', '/usr/local'),
BoolOption('SURFACES', 'Build support for control surfaces', 1),
+ BoolOption('WIIMOTE', 'Build the wiimote control surface', 0),
BoolOption('SYSLIBS', 'USE AT YOUR OWN RISK: CANCELS ALL SUPPORT FROM ARDOUR AUTHORS: Use existing system versions of various libraries instead of internal ones', 0),
BoolOption('UNIVERSAL', 'Compile as universal binary. Requires that external libraries are already universal.', 0),
BoolOption('VERSIONED', 'Add revision information to ardour/gtk executable name inside the build directory', 0),
@@ -578,6 +579,12 @@ if env['LV2']:
else:
print 'LV2 support is not enabled. Build with \'scons LV2=1\' to enable.'
+if env['WIIMOTE']:
+ wiimote_surface = [ 'libs/surfaces/wiimote' ]
+else:
+ wiimote_surface = [ ]
+ print 'WIIMOTE support not enabled. Build with \'scons WIIMOTE=1\' to enale.'
+
libraries['jack'] = LibraryInfo()
libraries['jack'].ParseConfig('pkg-config --cflags --libs jack')
@@ -900,6 +907,12 @@ if conf.CheckHeader('linux/input.h'):
else:
have_linux_input = False
+# let's continue checking, check for libcwiid
+if not conf.CheckHeader('cwiid.h'):
+ if env['WIIMOTE']:
+ print 'WIIIMOTE configured but you are missing libcwiid!'
+ sys.exit(1)
+
libraries['usb'] = conf.Finish ()
#
@@ -1196,6 +1209,7 @@ surface_subdirs = [ 'libs/surfaces/control_protocol',
'libs/surfaces/mackie',
'libs/surfaces/powermate'
]
+surface_subdirs += wiimote_surface
if env['SURFACES']:
if have_libusb:
diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc
index 1bd85650e1..fc231ff30e 100644
--- a/gtk2_ardour/editor.cc
+++ b/gtk2_ardour/editor.cc
@@ -1047,8 +1047,6 @@ Editor::access_action (std::string action_group, std::string action_item)
ENSURE_GUI_THREAD (bind (mem_fun (*this, &Editor::access_action), action_group, action_item));
- cout<< "OSC: Recieved: "<< action_item << endl;
-
RefPtr<Action> act;
act = ActionManager::get_action( action_group.c_str(), action_item.c_str() );
diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h
index 3d3acffb29..7e0126bb04 100644
--- a/gtk2_ardour/editor.h
+++ b/gtk2_ardour/editor.h
@@ -1052,6 +1052,7 @@ class Editor : public PublicEditor
void toggle_region_mute ();
void toggle_region_lock ();
void toggle_region_opaque ();
+ void toggle_record_enable ();
void set_region_lock_style (ARDOUR::Region::PositionLockStyle);
void raise_region ();
void raise_region_to_top ();
diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc
index 1aea9364b9..5ecb529bdf 100644
--- a/gtk2_ardour/editor_actions.cc
+++ b/gtk2_ardour/editor_actions.cc
@@ -205,6 +205,9 @@ Editor::register_actions ()
act = ActionManager::register_action (editor_actions, "select-prev-route", _("Select Previous Track/Bus"), mem_fun(*this, &Editor::select_prev_route));
ActionManager::session_sensitive_actions.push_back (act);
+ act = ActionManager::register_action (editor_actions, "track-record-enable-toggle", _("Toggle Record Enable"), mem_fun(*this, &Editor::toggle_record_enable));
+ ActionManager::session_sensitive_actions.push_back (act);
+
act = ActionManager::register_action (editor_actions, "save-visual-state-1", _("Save View 1"), bind (mem_fun (*this, &Editor::start_visual_state_op), 0));
ActionManager::session_sensitive_actions.push_back (act);
diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc
index cc2622cd1c..43dd06780c 100644
--- a/gtk2_ardour/editor_ops.cc
+++ b/gtk2_ardour/editor_ops.cc
@@ -4642,6 +4642,28 @@ Editor::toggle_region_opaque ()
}
void
+Editor::toggle_record_enable ()
+{
+ bool new_state;
+ bool first = true;
+ for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) {
+ RouteTimeAxisView *rtav = dynamic_cast<RouteTimeAxisView *>(*i);
+ if (!rtav)
+ continue;
+ if (!rtav->is_track())
+ continue;
+
+ if (first) {
+ new_state = !rtav->track()->record_enabled();
+ first = false;
+ }
+
+ rtav->track()->set_record_enable(new_state, this);
+ }
+}
+
+
+void
Editor::set_fade_length (bool in)
{
RegionSelection rs;
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 */
+