diff options
author | Paul Davis <paul@linuxaudiosystems.com> | 2006-05-23 19:54:52 +0000 |
---|---|---|
committer | Paul Davis <paul@linuxaudiosystems.com> | 2006-05-23 19:54:52 +0000 |
commit | 2fba6d0925307abd11be9d8f7a8d2722a2b6ccbd (patch) | |
tree | 485eed909963636b010d5f1e24527a6a4b377a42 /libs/surfaces/control_protocol | |
parent | a222c19737fa2d3fce3971350c1a18906635e29a (diff) |
breakout control protocol code into LGPL library; fix panner buttons even more than nick did, plus some other bits and pieces
git-svn-id: svn://localhost/trunk/ardour2@522 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/surfaces/control_protocol')
-rw-r--r-- | libs/surfaces/control_protocol/SConscript | 54 | ||||
-rw-r--r-- | libs/surfaces/control_protocol/basic_ui.cc | 273 | ||||
-rw-r--r-- | libs/surfaces/control_protocol/basic_ui.h | 98 | ||||
-rw-r--r-- | libs/surfaces/control_protocol/control_protocol.cc | 333 | ||||
-rw-r--r-- | libs/surfaces/control_protocol/control_protocol.h | 121 |
5 files changed, 879 insertions, 0 deletions
diff --git a/libs/surfaces/control_protocol/SConscript b/libs/surfaces/control_protocol/SConscript new file mode 100644 index 0000000000..e3927fa7ac --- /dev/null +++ b/libs/surfaces/control_protocol/SConscript @@ -0,0 +1,54 @@ +# -*- python -*- + +import os +import os.path +import glob + +Import('env final_prefix install_prefix final_config_prefix libraries i18n') + +cp = env.Copy() + +# +# this defines the version number of libardour_cp +# + +domain = 'ardour_cp' + +cp.Append(DOMAIN = domain, MAJOR = 1, MINOR = 0, MICRO = 0) +cp.Append(CXXFLAGS = "-DPACKAGE=\\\"" + domain + "\\\"") +cp.Append(CXXFLAGS="-DLIBSIGC_DISABLE_DEPRECATED") +cp.Append(PACKAGE = domain) +cp.Append(POTFILE = domain + '.pot') + +cp_files=Split(""" +basic_ui.cc +control_protocol.cc +""") + +cp.Append(CCFLAGS="-D_REENTRANT -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE") +cp.Append(CXXFLAGS="-DDATA_DIR=\\\""+final_prefix+"/share\\\"") +cp.Append(CXXFLAGS="-DCONFIG_DIR=\\\""+final_config_prefix+"\\\"") +cp.Append(CXXFLAGS="-DLOCALEDIR=\\\""+final_prefix+"/share/locale\\\"") + +cp.Merge ([ + libraries['ardour'], + libraries['sigc2'], + libraries['pbd3'], + libraries['midi++2'], + libraries['xml'], + libraries['usb'] + ]) + +libardour_cp = cp.SharedLibrary('ardour_cp', cp_files) + +Default(libardour_cp) + +if env['NLS']: + i18n (cp, cp_files, env) + +env.Alias('install', env.Install(os.path.join(install_prefix, 'lib/ardour2/surfaces'), libardour_cp)) + +env.Alias('tarball', env.Distribute (env['DISTTREE'], + [ 'SConscript', 'i18n.h', 'gettext.h' ] + + cp_files + + glob.glob('po/*.po') + glob.glob('*.h'))) diff --git a/libs/surfaces/control_protocol/basic_ui.cc b/libs/surfaces/control_protocol/basic_ui.cc new file mode 100644 index 0000000000..4519eb2781 --- /dev/null +++ b/libs/surfaces/control_protocol/basic_ui.cc @@ -0,0 +1,273 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser + 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. + + $Id$ +*/ + +#include <ardour/session.h> +#include <ardour/location.h> + +#include "basic_ui.h" +#include "i18n.h" + +using namespace ARDOUR; + +BasicUI::BasicUI (Session& s) + : session (&s) +{ +} + +BasicUI::BasicUI () + : session (0) +{ +} + +BasicUI::~BasicUI () +{ + +} + +void +BasicUI::loop_toggle () +{ + if (session->get_auto_loop()) { + session->request_auto_loop (false); + } else { + session->request_auto_loop (true); + if (!session->transport_rolling()) { + session->request_transport_speed (1.0); + } + } +} + +void +BasicUI::goto_start () +{ + session->goto_start (); +} + +void +BasicUI::goto_end () +{ + session->goto_end (); +} + +void +BasicUI::add_marker () +{ + jack_nframes_t when = session->audible_frame(); + session->locations()->add (new Location (when, when, _("unnamed"), Location::IsMark)); +} + +void +BasicUI::rewind () +{ + session->request_transport_speed (-2.0f); +} + +void +BasicUI::ffwd () +{ + session->request_transport_speed (2.0f); +} + +void +BasicUI::transport_stop () +{ + session->request_transport_speed (0.0); +} + +void +BasicUI::transport_play (bool from_last_start) +{ + bool rolling = session->transport_rolling (); + + if (session->get_auto_loop()) { + session->request_auto_loop (false); + } + + if (session->get_play_range ()) { + session->request_play_range (false); + } + + if (from_last_start && rolling) { + session->request_locate (session->last_transport_start(), true); + + } + + session->request_transport_speed (1.0f); +} + +void +BasicUI::rec_enable_toggle () +{ + switch (session->record_status()) { + case Session::Disabled: + if (session->ntracks() == 0) { + // string txt = _("Please create 1 or more track\nbefore trying to record.\nCheck the Session menu."); + // MessageDialog msg (*editor, txt); + // msg.run (); + return; + } + session->maybe_enable_record (); + break; + case Session::Recording: + case Session::Enabled: + session->disable_record (true); + } +} + +void +BasicUI::save_state () +{ + session->save_state (""); +} + +void +BasicUI::prev_marker () +{ + Location *location = session->locations()->first_location_before (session->transport_frame()); + + if (location) { + session->request_locate (location->start(), session->transport_rolling()); + } else { + session->goto_start (); + } +} + +void +BasicUI::next_marker () +{ + Location *location = session->locations()->first_location_after (session->transport_frame()); + + if (location) { + session->request_locate (location->start(), session->transport_rolling()); + } else { + session->request_locate (session->current_end_frame()); + } +} + +void +BasicUI::set_transport_speed (float speed) +{ + session->request_transport_speed (speed); +} + +float +BasicUI::get_transport_speed () +{ + return session->transport_speed (); +} + +void +BasicUI::undo () +{ + session->undo (1); +} + +void +BasicUI::redo () +{ + session->redo (1); +} + +void +BasicUI::toggle_all_rec_enables () +{ + if (session->get_record_enabled()) { + session->record_disenable_all (); + } else { + session->record_enable_all (); + } +} + +void +BasicUI::toggle_punch_in () +{ + session->set_punch_in (!session->get_punch_in()); +} + +void +BasicUI::toggle_punch_out () +{ + session->set_punch_out (!session->get_punch_out()); +} + +bool +BasicUI::get_record_enabled () +{ + return session->get_record_enabled(); +} + +void +BasicUI::set_record_enable (bool yn) +{ + if (yn) { + session->maybe_enable_record (); + } else { + session->disable_record (false, true); + } +} + +jack_nframes_t +BasicUI::transport_frame () +{ + return session->transport_frame(); +} + +void +BasicUI::locate (jack_nframes_t where, bool roll_after_locate) +{ + session->request_locate (where, roll_after_locate); +} + +bool +BasicUI::locating () +{ + return session->locate_pending(); +} + +bool +BasicUI::locked () +{ + return session->transport_locked (); +} + +jack_nframes_t +BasicUI::smpte_frames_per_hour () +{ + return session->smpte_frames_per_hour (); +} + +void +BasicUI::smpte_time (jack_nframes_t where, SMPTE_t& smpte) +{ + session->smpte_time (where, *((SMPTE_Time *) &smpte)); +} + +void +BasicUI::smpte_to_sample (SMPTE_t& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes) const +{ + session->smpte_to_sample (*((SMPTE_Time*)&smpte), sample, use_offset, use_subframes); +} + +void +BasicUI::sample_to_smpte (jack_nframes_t sample, SMPTE_t& smpte, bool use_offset, bool use_subframes) const +{ + session->sample_to_smpte (sample, *((SMPTE_Time*)&smpte), use_offset, use_subframes); +} diff --git a/libs/surfaces/control_protocol/basic_ui.h b/libs/surfaces/control_protocol/basic_ui.h new file mode 100644 index 0000000000..2db19685b1 --- /dev/null +++ b/libs/surfaces/control_protocol/basic_ui.h @@ -0,0 +1,98 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser + 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. + + $Id$ +*/ + +#ifndef __ardour_basic_ui_h__ +#define __ardour_basic_ui_h__ + +#include <jack/types.h> + +namespace ARDOUR { + class Session; +} + +class BasicUI { + public: + BasicUI (ARDOUR::Session&); + virtual ~BasicUI (); + + void add_marker (); + + /* transport control */ + + void loop_toggle (); + void goto_start (); + void goto_end (); + void rewind (); + void ffwd (); + void transport_stop (); + void transport_play (bool jump_back = true); + void set_transport_speed (float speed); + float get_transport_speed (); + + jack_nframes_t transport_frame (); + void locate (jack_nframes_t frame, bool play = false); + bool locating (); + bool locked (); + + void save_state (); + void prev_marker (); + void next_marker (); + void undo (); + void redo (); + void toggle_punch_in (); + void toggle_punch_out (); + + void set_record_enable (bool yn); + bool get_record_enabled (); + + void rec_enable_toggle (); + void toggle_all_rec_enables (); + + jack_nframes_t smpte_frames_per_hour (); + + struct SMPTE_t { + bool negative; + uint32_t hours; + uint32_t minutes; + uint32_t seconds; + uint32_t frames; + uint32_t subframes; // mostly not used + + SMPTE_t () { + negative = false; + hours = 0; + minutes = 0; + seconds = 0; + frames = 0; + subframes = 0; + } + }; + + void smpte_time (jack_nframes_t where, SMPTE_t&); + void smpte_to_sample (SMPTE_t& smpte, jack_nframes_t& sample, bool use_offset, bool use_subframes) const; + void sample_to_smpte (jack_nframes_t sample, SMPTE_t& smpte, bool use_offset, bool use_subframes) const; + + protected: + BasicUI (); + ARDOUR::Session* session; +}; + +#endif /* __ardour_basic_ui_h__ */ diff --git a/libs/surfaces/control_protocol/control_protocol.cc b/libs/surfaces/control_protocol/control_protocol.cc new file mode 100644 index 0000000000..6407c64385 --- /dev/null +++ b/libs/surfaces/control_protocol/control_protocol.cc @@ -0,0 +1,333 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser + 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. + + $Id$ +*/ + +#include <ardour/session.h> +#include <ardour/route.h> +#include <ardour/audio_track.h> + +#include "control_protocol.h" + +using namespace ARDOUR; +using namespace std; + +sigc::signal<void> ControlProtocol::ZoomToSession; +sigc::signal<void> ControlProtocol::ZoomOut; +sigc::signal<void> ControlProtocol::ZoomIn; +sigc::signal<void> ControlProtocol::Enter; +sigc::signal<void,float> ControlProtocol::ScrollTimeline; + +ControlProtocol::ControlProtocol (Session& s, string str) + : BasicUI (s), + _name (str) +{ + _active = false; +} + +ControlProtocol::~ControlProtocol () +{ +} + +void +ControlProtocol::next_track (uint32_t initial_id) +{ + uint32_t limit = session->nroutes(); + Route* cr = route_table[0]; + uint32_t id; + + if (cr) { + id = cr->remote_control_id (); + } else { + id = 0; + } + + if (id == limit) { + id = 0; + } else { + id++; + } + + while (id < limit) { + if ((cr = session->route_by_remote_id (id)) != 0) { + break; + } + id++; + } + + if (id == limit) { + id = 0; + while (id != initial_id) { + if ((cr = session->route_by_remote_id (id)) != 0) { + break; + } + id++; + } + } + + route_table[0] = cr; +} + +void +ControlProtocol::prev_track (uint32_t initial_id) +{ + uint32_t limit = session->nroutes() - 1; + Route* cr = route_table[0]; + uint32_t id; + + if (cr) { + id = cr->remote_control_id (); + } else { + id = 0; + } + + if (id == 0) { + id = session->nroutes() - 1; + } else { + id--; + } + + while (id >= 0) { + if ((cr = session->route_by_remote_id (id)) != 0) { + break; + } + id--; + } + + if (id < 0) { + id = limit; + while (id > initial_id) { + if ((cr = session->route_by_remote_id (id)) != 0) { + break; + } + id--; + } + } + + route_table[0] = cr; +} + + +void +ControlProtocol::set_route_table_size (uint32_t size) +{ + while (route_table.size() < size) { + route_table.push_back (0); + } +} + +void +ControlProtocol::set_route_table (uint32_t table_index, ARDOUR::Route*) +{ +} + +bool +ControlProtocol::set_route_table (uint32_t table_index, uint32_t remote_control_id) +{ + if (table_index >= route_table.size()) { + return false; + } + + Route* r = session->route_by_remote_id (remote_control_id); + + if (!r) { + return false; + } + + route_table[table_index] = r; + + return true; +} + +void +ControlProtocol::route_set_rec_enable (uint32_t table_index, bool yn) +{ + if (table_index > route_table.size()) { + return; + } + + Route* r = route_table[table_index]; + + AudioTrack* at = dynamic_cast<AudioTrack*>(r); + + if (at) { + at->set_record_enable (yn, this); + } +} + +bool +ControlProtocol::route_get_rec_enable (uint32_t table_index) +{ + if (table_index > route_table.size()) { + return false; + } + + Route* r = route_table[table_index]; + + AudioTrack* at = dynamic_cast<AudioTrack*>(r); + + if (at) { + return at->record_enabled (); + } + + return false; +} + + +float +ControlProtocol::route_get_gain (uint32_t table_index) +{ + if (table_index > route_table.size()) { + return 0.0f; + } + + Route* r = route_table[table_index]; + + if (r == 0) { + return 0.0f; + } + + return r->gain (); +} + +void +ControlProtocol::route_set_gain (uint32_t table_index, float gain) +{ + if (table_index > route_table.size()) { + return; + } + + Route* r = route_table[table_index]; + + if (r != 0) { + r->set_gain (gain, this); + } +} + +float +ControlProtocol::route_get_effective_gain (uint32_t table_index) +{ + if (table_index > route_table.size()) { + return 0.0f; + } + + Route* r = route_table[table_index]; + + if (r == 0) { + return 0.0f; + } + + return r->effective_gain (); +} + + +float +ControlProtocol::route_get_peak_input_power (uint32_t table_index, uint32_t which_input) +{ + if (table_index > route_table.size()) { + return 0.0f; + } + + Route* r = route_table[table_index]; + + if (r == 0) { + return 0.0f; + } + + return r->peak_input_power (which_input); +} + + +bool +ControlProtocol::route_get_muted (uint32_t table_index) +{ + if (table_index > route_table.size()) { + return false; + } + + Route* r = route_table[table_index]; + + if (r == 0) { + return false; + } + + return r->muted (); +} + +void +ControlProtocol::route_set_muted (uint32_t table_index, bool yn) +{ + if (table_index > route_table.size()) { + return; + } + + Route* r = route_table[table_index]; + + if (r != 0) { + r->set_mute (yn, this); + } +} + + +bool +ControlProtocol::route_get_soloed (uint32_t table_index) +{ + if (table_index > route_table.size()) { + return false; + } + + Route* r = route_table[table_index]; + + if (r == 0) { + return false; + } + + return r->soloed (); +} + +void +ControlProtocol::route_set_soloed (uint32_t table_index, bool yn) +{ + if (table_index > route_table.size()) { + return; + } + + Route* r = route_table[table_index]; + + if (r != 0) { + r->set_solo (yn, this); + } +} + +string +ControlProtocol:: route_get_name (uint32_t table_index) +{ + if (table_index > route_table.size()) { + return ""; + } + + Route* r = route_table[table_index]; + + if (r == 0) { + return ""; + } + + return r->name(); +} + diff --git a/libs/surfaces/control_protocol/control_protocol.h b/libs/surfaces/control_protocol/control_protocol.h new file mode 100644 index 0000000000..720188c666 --- /dev/null +++ b/libs/surfaces/control_protocol/control_protocol.h @@ -0,0 +1,121 @@ +/* + Copyright (C) 2006 Paul Davis + + This program is free software; you can redistribute it + and/or modify it under the terms of the GNU Lesser + 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. + + $Id$ +*/ + +#ifndef ardour_control_protocols_h +#define ardour_control_protocols_h + +#include <string> +#include <vector> +#include <list> +#include <sigc++/sigc++.h> + +#include "basic_ui.h" + +namespace ARDOUR { + +class Route; +class Session; + +class ControlProtocol : public sigc::trackable, public BasicUI { + public: + ControlProtocol (Session&, std::string name); + virtual ~ControlProtocol(); + + std::string name() const { return _name; } + + virtual int set_active (bool yn) = 0; + bool get_active() const { return _active; } + + sigc::signal<void> ActiveChanged; + + /* signals that a control protocol can emit and other (presumably graphical) + user interfaces can respond to + */ + + static sigc::signal<void> ZoomToSession; + static sigc::signal<void> ZoomIn; + static sigc::signal<void> ZoomOut; + static sigc::signal<void> Enter; + static sigc::signal<void,float> ScrollTimeline; + + /* the model here is as follows: + + we imagine most control surfaces being able to control + from 1 to N tracks at a time, with a session that may + contain 1 to M tracks, where M may be smaller, larger or + equal to N. + + the control surface has a fixed set of physical controllers + which can potentially be mapped onto different tracks/busses + via some mechanism. + + therefore, the control protocol object maintains + a table that reflects the current mapping between + the controls and route object. + */ + + void set_route_table_size (uint32_t size); + void set_route_table (uint32_t table_index, ARDOUR::Route*); + bool set_route_table (uint32_t table_index, uint32_t remote_control_id); + + void route_set_rec_enable (uint32_t table_index, bool yn); + bool route_get_rec_enable (uint32_t table_index); + + float route_get_gain (uint32_t table_index); + void route_set_gain (uint32_t table_index, float); + float route_get_effective_gain (uint32_t table_index); + + float route_get_peak_input_power (uint32_t table_index, uint32_t which_input); + + bool route_get_muted (uint32_t table_index); + void route_set_muted (uint32_t table_index, bool); + + bool route_get_soloed (uint32_t table_index); + void route_set_soloed (uint32_t table_index, bool); + + std::string route_get_name (uint32_t table_index); + + protected: + std::vector<ARDOUR::Route*> route_table; + std::string _name; + bool _active; + + void next_track (uint32_t initial_id); + void prev_track (uint32_t initial_id); +}; + +extern "C" { + struct ControlProtocolDescriptor { + const char* name; /* descriptive */ + const char* id; /* unique and version-specific */ + void* ptr; /* protocol can store a value here */ + void* module; /* not for public access */ + int mandatory; /* if non-zero, always load and do not make optional */ + bool (*probe)(ControlProtocolDescriptor*); + ControlProtocol* (*initialize)(ControlProtocolDescriptor*,Session*); + void (*destroy)(ControlProtocolDescriptor*,ControlProtocol*); + + }; +} + +} + +#endif // ardour_control_protocols_h |