add non-functional meta-controls for 2in/2out panning, to control direction+width. support exists in OSC and MIDI maps. no GUI elements yet

git-svn-id: svn://localhost/ardour2/branches/3.0@8121 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
Paul Davis 2010-11-28 21:28:54 +00:00
parent ad4e0cd2d1
commit c7df5f5271
8 changed files with 145 additions and 15 deletions

View File

@ -279,6 +279,17 @@ public:
return automation_control (Evoral::Parameter (PanAutomation, chan, id));
}
boost::shared_ptr<AutomationControl> direction_control () {
return automation_control (Evoral::Parameter (PanAutomation, 0, 100));
}
boost::shared_ptr<AutomationControl> width_control () {
return automation_control (Evoral::Parameter (PanAutomation, 0, 200));
}
void set_stereo_position (double);
void set_stereo_width (double);
static std::string value_as_string (double);
private:
@ -297,7 +308,8 @@ public:
static float current_automation_version_number;
void setup_speakers (uint32_t nouts);
void setup_meta_controls ();
/* old school automation handling */
std::string automation_path;

View File

@ -101,7 +101,19 @@ StreamPanner::set_mono (bool yn)
void
StreamPanner::PanControllable::set_value (double val)
{
streampanner.set_position (AngularVector (direct_control_to_stereo_pan (val), 0.0));
switch (parameter().id()) {
case 100:
/* position */
streampanner.get_parent().set_stereo_position (val);
break;
case 200:
/* width */
streampanner.get_parent().set_stereo_width (val);
break;
default:
streampanner.set_position (AngularVector (direct_control_to_stereo_pan (val), 0.0));
}
AutomationControl::set_value(val);
}
@ -746,6 +758,8 @@ Panner::reset (uint32_t nouts, uint32_t npans)
(*x)->update ();
}
setup_meta_controls ();
/* must emit Changed here, otherwise the changes to the pan_control below raise further
signals which the GUI is not prepared for until it has seen the Changed here.
*/
@ -997,13 +1011,12 @@ Panner::set_state (const XMLNode& node, int version)
if (sp->set_state (**niter, version) == 0) {
_streampanners.push_back (sp);
}
}
break;
}
}
if (!pan_plugins[i].factory) {
error << string_compose (_("Unknown panner plugin \"%1\" found in pan state - ignored"),
prop->value())
@ -1019,7 +1032,10 @@ Panner::set_state (const XMLNode& node, int version)
}
}
setup_meta_controls ();
reset (outputs.size (), num_panners);
/* don't try to do old-school automation loading if it wasn't marked as existing */
if ((prop = node.property (X_("automation")))) {
@ -1029,14 +1045,12 @@ Panner::set_state (const XMLNode& node, int version)
automation_path = Glib::build_filename(_session.automation_dir(), prop->value ());
}
#ifdef MUST_FIX_PANNER_AUTOMATION
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
if ((*niter)->name() == X_("Automation")) {
set_automation_xml_state (**niter, Evoral::Parameter (PanAutomation));
}
}
#endif
return 0;
}
@ -1378,3 +1392,42 @@ Panner::setup_speakers (uint32_t nouts)
speakers.add_speaker ((*o).position);
}
}
void
Panner::set_stereo_width (double val)
{
cerr << "Set stereo width to " << val << endl;
}
void
Panner::set_stereo_position (double val)
{
cerr << "Set stereo position to " << val << endl;
}
void
Panner::setup_meta_controls ()
{
if (_streampanners.size() != 2 || outputs.size() != 2) {
return;
}
/* 2 signals to 2 outputs: provide "classic" controls for easier manipulation.
The ID numbers used here don't really matter that much, because Parameters are scoped by owner,
but they keep us out of the ordinary range of pan-related parameters.
*/
Evoral::Parameter lr_param (PanAutomation, 0, 100);
Evoral::Parameter width_param (PanAutomation, 0, 200);
if (!automation_control (lr_param)) {
boost::shared_ptr<AutomationControl> c (new StreamPanner::PanControllable (_session, _("lr"), *_streampanners.front(), lr_param));
add_control (c);
}
if (!automation_control (width_param)) {
boost::shared_ptr<AutomationControl> c (new StreamPanner::PanControllable (_session, _("width"), *_streampanners.front(), width_param));
add_control (c);
}
}

View File

@ -191,7 +191,7 @@ PluginInsert::set_automatable ()
Evoral::Parameter param(*i);
_plugins.front()->get_parameter_descriptor(i->id(), desc);
/* the Parameter belonging to the actual plugin doesn't have its range set
but we want the Controllable related to this Parameter to have those limits.
*/
@ -915,8 +915,9 @@ PluginInsert::set_parameter_state_2X (const XMLNode& node, int version)
string
PluginInsert::describe_parameter (Evoral::Parameter param)
{
if (param.type() != PluginAutomation)
if (param.type() != PluginAutomation) {
return Automatable::describe_parameter(param);
}
return _plugins[0]->describe_parameter (param);
}

View File

@ -74,6 +74,7 @@
#include "ardour/audioplaylist.h"
#include "ardour/audioregion.h"
#include "ardour/auditioner.h"
#include "ardour/automation_control.h"
#include "ardour/buffer.h"
#include "ardour/butler.h"
#include "ardour/configuration.h"
@ -91,6 +92,7 @@
#include "ardour/midi_source.h"
#include "ardour/midi_track.h"
#include "ardour/named_selection.h"
#include "ardour/panner.h"
#include "ardour/processor.h"
#include "ardour/port.h"
#include "ardour/region_factory.h"
@ -2978,9 +2980,27 @@ Session::controllable_by_descriptor (const ControllableDescriptor& desc)
break;
}
case ControllableDescriptor::Pan:
/* XXX pan control */
case ControllableDescriptor::PanDirection:
{
boost::shared_ptr<Panner> p = r->panner();
cerr << "Looking at panner for " << r->name() << endl;
if (p) {
c = p->direction_control();
cerr << "PAN DIRECTION Bound TO " << c << endl;
}
break;
}
case ControllableDescriptor::PanWidth:
{
boost::shared_ptr<Panner> p = r->panner();
cerr << "Looking at panner for " << r->name() << endl;
if (p) {
c = p->width_control();
cerr << "PAN WIDTH Bound TO " << c << endl;
}
break;
}
case ControllableDescriptor::Balance:
/* XXX simple pan control */

View File

@ -84,9 +84,11 @@ ControllableDescriptor::set (const std::string& str)
} else if (path[1] == "balance") {
_subtype = Balance;
} else if (path[1] == "pan") {
_subtype = Pan;
_target.push_back (atoi (rest[1]));
} else if (path[1] == "panwidth") {
_subtype = PanWidth;
} else if (path[1] == "pandirection") {
_subtype = PanDirection;
} else if (path[1] == "plugin") {
if (path.size() == 3 && rest.size() == 3) {

View File

@ -37,7 +37,8 @@ public:
Solo,
Mute,
Recenable,
Pan,
PanDirection,
PanWidth,
Balance,
SendGain,
PluginParameter

View File

@ -42,6 +42,7 @@
#include "ardour/midi_track.h"
#include "ardour/dB.h"
#include "ardour/filesystem_paths.h"
#include "ardour/panner.h"
#include "osc.h"
#include "osc_controllable.h"
@ -781,6 +782,42 @@ OSC::route_set_gain_dB (int rid, float dB)
return 0;
}
int
OSC::route_set_pan_stereo_position (int rid, float pos)
{
if (!session) return -1;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
if (r) {
boost::shared_ptr<Panner> panner = r->panner();
if (panner) {
panner->set_stereo_position (pos);
}
}
return 0;
}
int
OSC::route_set_pan_stereo_width (int rid, float pos)
{
if (!session) return -1;
boost::shared_ptr<Route> r = session->route_by_remote_id (rid);
if (r) {
boost::shared_ptr<Panner> panner = r->panner();
if (panner) {
panner->set_stereo_width (pos);
}
}
return 0;
}
XMLNode&
OSC::get_state ()
{

View File

@ -173,12 +173,16 @@ class OSC : public ARDOUR::ControlProtocol, public AbstractUI<OSCUIRequest>
PATH_CALLBACK2(route_recenable,i,i);
PATH_CALLBACK2(route_set_gain_abs,i,f);
PATH_CALLBACK2(route_set_gain_dB,i,f);
PATH_CALLBACK2(route_set_pan_stereo_position,i,f);
PATH_CALLBACK2(route_set_pan_stereo_width,i,f);
int route_mute (int rid, int yn);
int route_solo (int rid, int yn);
int route_recenable (int rid, int yn);
int route_set_gain_abs (int rid, float level);
int route_set_gain_dB (int rid, float dB);
int route_set_pan_stereo_position (int rid, float left_right_fraction);
int route_set_pan_stereo_width (int rid, float percent);
void listen_to_route (boost::shared_ptr<ARDOUR::Route>, lo_address);
void end_listen (boost::shared_ptr<ARDOUR::Route>, lo_address);