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
This commit is contained in:
Paul Davis
2006-05-23 19:54:52 +00:00
parent a222c19737
commit 2fba6d0925
25 changed files with 414 additions and 142 deletions

View File

@@ -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')))

View File

@@ -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);
}

View File

@@ -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__ */

View File

@@ -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();
}

View File

@@ -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