#include "pbd/error.h"
#include "pbd/cartesian.h"
#include "ardour/panner.h"
+#include "ardour/panner_shell.h"
#include "ardour/pannable.h"
#include "ardour/speakers.h"
text = txt;
}
-Panner2d::Panner2d (boost::shared_ptr<Panner> p, int32_t h)
- : panner (p)
+Panner2d::Panner2d (boost::shared_ptr<PannerShell> p, int32_t h)
+ : panner_shell (p)
, position (AngularVector (0.0, 0.0), "")
, width (0)
, height (h)
, last_width (0)
{
- panner->StateChanged.connect (connections, invalidator (*this), boost::bind (&Panner2d::handle_state_change, this), gui_context());
+ panner_shell->Changed.connect (connections, invalidator (*this), boost::bind (&Panner2d::handle_state_change, this), gui_context());
- panner->pannable()->pan_azimuth_control->Changed.connect (connections, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context());
- panner->pannable()->pan_width_control->Changed.connect (connections, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context());
+ panner_shell->pannable()->pan_azimuth_control->Changed.connect (connections, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context());
+ panner_shell->pannable()->pan_width_control->Changed.connect (connections, invalidator(*this), boost::bind (&Panner2d::handle_position_change, this), gui_context());
drag_target = 0;
set_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK);
void
Panner2d::reset (uint32_t n_inputs)
{
- uint32_t nouts = panner->out().n_audio();
+ uint32_t nouts = panner_shell->panner()->out().n_audio();
/* signals */
label_signals ();
for (uint32_t i = 0; i < n_inputs; ++i) {
- signals[i]->position = panner->signal_position (i);
+ signals[i]->position = panner_shell->panner()->signal_position (i);
}
/* add all outputs */
(*x)->visible = false;
}
- vector<Speaker>& the_speakers (panner->get_speakers()->speakers());
+ vector<Speaker>& the_speakers (panner_shell->panner()->get_speakers()->speakers());
for (uint32_t n = 0; n < nouts; ++n) {
char buf[16];
void
Panner2d::label_signals ()
{
- double w = panner->pannable()->pan_width_control->get_value();
+ double w = panner_shell->pannable()->pan_width_control->get_value();
uint32_t sz = signals.size();
switch (sz) {
Panner2d::handle_position_change ()
{
uint32_t n;
- double w = panner->pannable()->pan_width_control->get_value();
+ double w = panner_shell->pannable()->pan_width_control->get_value();
- position.position = AngularVector (panner->pannable()->pan_azimuth_control->get_value() * 360.0, 0.0);
+ position.position = AngularVector (panner_shell->pannable()->pan_azimuth_control->get_value() * 360.0, 0.0);
for (uint32_t i = 0; i < signals.size(); ++i) {
- signals[i]->position = panner->signal_position (i);
+ signals[i]->position = panner_shell->panner()->signal_position (i);
}
if (w * last_width <= 0) {
last_width = w;
- vector<Speaker>& the_speakers (panner->get_speakers()->speakers());
+ vector<Speaker>& the_speakers (panner_shell->panner()->get_speakers()->speakers());
for (n = 0; n < speakers.size(); ++n) {
speakers[n]->position = the_speakers[n].angles();
/* background */
cairo_rectangle (cr, event->area.x, event->area.y, event->area.width, event->area.height);
- if (!panner->bypassed()) {
+ if (!panner_shell->bypassed()) {
cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 1.0);
} else {
cairo_set_source_rgba (cr, 0.1, 0.1, 0.1, 0.2);
if (signals.size() > 1) {
/* arc to show "diffusion" */
- double width_angle = fabs (panner->pannable()->pan_width_control->get_value()) * 2 * M_PI;
- double position_angle = (2 * M_PI) - panner->pannable()->pan_azimuth_control->get_value() * 2 * M_PI;
+ double width_angle = fabs (panner_shell->pannable()->pan_width_control->get_value()) * 2 * M_PI;
+ double position_angle = (2 * M_PI) - panner_shell->pannable()->pan_azimuth_control->get_value() * 2 * M_PI;
cairo_save (cr);
cairo_translate (cr, radius, radius);
cairo_move_to (cr, 0, 0);
cairo_arc_negative (cr, 0, 0, radius, width_angle, 0.0);
cairo_close_path (cr);
- if (panner->pannable()->pan_width_control->get_value() >= 0.0) {
+ if (panner_shell->pannable()->pan_width_control->get_value() >= 0.0) {
/* normal width */
cairo_set_source_rgba (cr, 0.282, 0.517, 0.662, 0.45);
} else {
cairo_restore (cr);
}
- if (!panner->bypassed()) {
+ if (!panner_shell->bypassed()) {
double arc_radius;
if ((drag_target = find_closest_object (x, y, is_signal)) != 0) {
if (!is_signal) {
- panner->set_position (drag_target->position.azi/360.0);
+ panner_shell->panner()->set_position (drag_target->position.azi/360.0);
drag_target = 0;
} else {
drag_target->set_selected (true);
if (drag_target == &position) {
double degree_fract = av.azi / 360.0;
- panner->set_position (degree_fract);
+ panner_shell->panner()->set_position (degree_fract);
}
}
}
switch (ev->direction) {
case GDK_SCROLL_UP:
case GDK_SCROLL_RIGHT:
- panner->set_position (panner->pannable()->pan_azimuth_control->get_value() - 1.0/360.0);
+ panner_shell->panner()->set_position (panner_shell->pannable()->pan_azimuth_control->get_value() - 1.0/360.0);
break;
case GDK_SCROLL_DOWN:
case GDK_SCROLL_LEFT:
- panner->set_position (panner->pannable()->pan_azimuth_control->get_value() + 1.0/360.0);
+ panner_shell->panner()->set_position (panner_shell->pannable()->pan_azimuth_control->get_value() + 1.0/360.0);
break;
}
return true;
void
Panner2d::toggle_bypass ()
{
- panner->set_bypassed (!panner->bypassed());
+ panner_shell->set_bypassed (!panner_shell->bypassed());
}
-Panner2dWindow::Panner2dWindow (boost::shared_ptr<Panner> p, int32_t h, uint32_t inputs)
+Panner2dWindow::Panner2dWindow (boost::shared_ptr<PannerShell> p, int32_t h, uint32_t inputs)
: ArdourDialog (_("Panner (2D)"))
, widget (p, h)
, bypass_button (_("Bypass"))
Panner2dWindow::bypass_toggled ()
{
bool view = bypass_button.get_active ();
- bool model = widget.get_panner()->bypassed ();
+ bool model = widget.get_panner_shell()->bypassed ();
if (model != view) {
- widget.get_panner()->set_bypassed (view);
+ widget.get_panner_shell()->set_bypassed (view);
}
}
#include "ardour_dialog.h"
namespace ARDOUR {
- class Panner;
+ class PannerShell;
}
namespace Gtk {
class Panner2d : public Gtk::DrawingArea
{
public:
- Panner2d (boost::shared_ptr<ARDOUR::Panner>, int32_t height);
+ Panner2d (boost::shared_ptr<ARDOUR::PannerShell>, int32_t height);
~Panner2d ();
void allow_target_motion (bool);
void move_signal (int which, const PBD::AngularVector&);
void reset (uint32_t n_inputs);
- boost::shared_ptr<ARDOUR::Panner> get_panner() const { return panner; }
+ boost::shared_ptr<ARDOUR::PannerShell> get_panner_shell() const { return panner_shell; }
sigc::signal<void,int> PuckMoved;
sigc::signal<void,int> TargetMoved;
bool _selected;
};
- boost::shared_ptr<ARDOUR::Panner> panner;
+ boost::shared_ptr<ARDOUR::PannerShell> panner_shell;
Glib::RefPtr<Pango::Layout> layout;
typedef std::vector<Target*> Targets;
class Panner2dWindow : public ArdourDialog
{
public:
- Panner2dWindow (boost::shared_ptr<ARDOUR::Panner>, int32_t height, uint32_t inputs);
+ Panner2dWindow (boost::shared_ptr<ARDOUR::PannerShell>, int32_t height, uint32_t inputs);
void reset (uint32_t n_inputs);
}
_panshell->Changed.connect (connections, invalidator (*this), boost::bind (&PannerUI::panshell_changed, this), gui_context());
- _panner->StateChanged.connect (connections, invalidator (*this), boost::bind (&PannerUI::update_pan_state, this), gui_context());
/* new panner object, force complete reset of panner GUI
*/
setup_pan ();
}
-void
-PannerUI::update_pan_state ()
-{
- /* currently nothing to do */
-}
-
void
PannerUI::setup_pan ()
{
} else {
if (!twod_panner) {
- twod_panner = new Panner2d (_panner, 61);
+ twod_panner = new Panner2d (_panshell, 61);
twod_panner->set_name ("MixerPanZone");
twod_panner->show ();
twod_panner->signal_button_press_event().connect (sigc::mem_fun(*this, &PannerUI::pan_button_event), false);
case 1:
if (twod_panner && ev->type == GDK_2BUTTON_PRESS) {
if (!big_window) {
- big_window = new Panner2dWindow (_panner, 400, _panner->in().n_audio());
+ big_window = new Panner2dWindow (_panshell, 400, _panner->in().n_audio());
}
big_window->show ();
return true;
/* set state first, connect second */
- bypass_menu_item->set_active (_panner->bypassed());
+ bypass_menu_item->set_active (_panshell->bypassed());
bypass_menu_item->signal_toggled().connect (sigc::mem_fun(*this, &PannerUI::pan_bypass_toggle));
items.push_back (MenuElem (_("Reset"), sigc::mem_fun (*this, &PannerUI::pan_reset)));
void
PannerUI::pan_bypass_toggle ()
{
- if (bypass_menu_item && (_panner->bypassed() != bypass_menu_item->get_active())) {
- _panner->set_bypassed (!_panner->bypassed());
+ if (bypass_menu_item && (_panshell->bypassed() != bypass_menu_item->get_active())) {
+ _panshell->set_bypassed (!_panshell->bypassed());
}
}
std::vector<MonoPanner*> pan_bars;
void pan_value_changed (uint32_t which);
- void update_pan_state ();
void build_astate_menu ();
void build_astyle_menu ();
virtual void reset() {}
- virtual bool bypassed() const { return _bypassed; }
- virtual void set_bypassed (bool yn);
-
void set_automation_state (AutoState);
AutoState automation_state() const;
void set_automation_style (AutoStyle);
framepos_t start, framepos_t end, pframes_t nframes,
pan_t** buffers);
- PBD::Signal0<void> StateChanged;
-
int set_state (const XMLNode&, int version);
- virtual XMLNode& state (bool full_state) = 0;
-
+ XMLNode& get_state ();
+
boost::shared_ptr<Pannable> pannable() const { return _pannable; }
//virtual std::string describe_parameter (Evoral::Parameter);
protected:
boost::shared_ptr<Pannable> _pannable;
- bool _bypassed;
-
- XMLNode& get_state ();
virtual void distribute_one (AudioBuffer&, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes, uint32_t which) = 0;
virtual void distribute_one_automated (AudioBuffer&, BufferSet& obufs,
/// The fundamental Panner function
void run (BufferSet& src, BufferSet& dest, framepos_t start_frame, framepos_t end_frames, pframes_t nframes);
-
- XMLNode& get_state (void);
- XMLNode& state (bool full);
+ XMLNode& get_state ();
int set_state (const XMLNode&, int version);
- PBD::Signal0<void> Changed; /* panner and/or outputs count changed */
+ PBD::Signal0<void> Changed; /* panner and/or outputs count and/or bypass state changed */
boost::shared_ptr<Panner> panner() const { return _panner; }
boost::shared_ptr<Pannable> pannable() const { return _pannable; }
+ bool bypassed () const;
+ void set_bypassed (bool);
+
private:
void distribute_no_automation (BufferSet& src, BufferSet& dest, pframes_t nframes, gain_t gain_coeff);
boost::shared_ptr<Panner> _panner;
boost::shared_ptr<Pannable> _pannable;
+ bool _bypassed;
static float current_automation_version_number;
};
void
Delivery::run (BufferSet& bufs, framepos_t start_frame, framepos_t end_frame, pframes_t nframes, bool result_required)
{
- boost::shared_ptr<Panner> panner;
-
assert (_output);
PortSet& ports (_output->ports());
Amp::apply_simple_gain (bufs, nframes, tgain);
}
- if (_panshell) {
- panner = _panshell->panner();
- }
-
#if 0
if (_session.transport_rolling()) {
cerr << name() << " first value written : " << scnt << endl;
}
#endif
- if (panner && !panner->bypassed()) {
+ if (_panshell && !_panshell->bypassed()) {
// Use the panner to distribute audio to output port buffers
node.add_property("role", enum_2_string(_role));
if (_panshell) {
- node.add_child_nocopy (_panshell->state (full_state));
+ node.add_child_nocopy (_panshell->get_state ());
}
return node;
assert(mixbufs.available() >= bufs.count());
- boost::shared_ptr<Panner> panner;
-
- if (_panshell) {
- panner = _panshell->panner();
- }
-
- if (panner && !panner->bypassed()) {
+ if (_panshell && !_panshell->bypassed()) {
mixbufs.set_count (_send_to->n_outputs ());
_panshell->run (bufs, mixbufs, start_frame, end_frame, nframes);
} else {
void
InternalSend::set_can_pan (bool yn)
{
- boost::shared_ptr<Panner> panner;
-
if (_panshell) {
- panner = _panshell->panner ();
- }
-
- if (panner) {
- panner->set_bypassed (!yn);
+ _panshell->set_bypassed (!yn);
}
}
Panner::Panner (boost::shared_ptr<Pannable> p)
: _pannable (p)
- , _bypassed (false)
{
}
DEBUG_TRACE(PBD::DEBUG::Destruction, string_compose ("panner @ %1 destructor, pannable is %2\n", this, _pannable));
}
-void
-Panner::set_bypassed (bool yn)
-{
- if (yn != _bypassed) {
- _bypassed = yn;
- StateChanged ();
- }
-}
-
-int
-Panner::set_state (const XMLNode& node, int version)
-{
- const XMLProperty* prop;
-
- if ((prop = node.property (X_("bypassed"))) != 0) {
- set_bypassed (string_is_affirmative (prop->value()));
- }
-
- return 0;
-}
-
XMLNode&
Panner::get_state ()
{
- XMLNode* node = new XMLNode (X_("Panner"));
-
- node->add_property (X_("bypassed"), (bypassed() ? "yes" : "no"));
-
- return *node;
+ return *(new XMLNode (X_("Panner")));
}
void
{
return _pannable->value_as_string (ac);
}
+
+int
+Panner::set_state (XMLNode const &, int)
+{
+ return 0;
+}
PannerShell::PannerShell (string name, Session& s, boost::shared_ptr<Pannable> p)
: SessionObject (s, name)
, _pannable (p)
+ , _bypassed (false)
{
set_name (name);
}
}
XMLNode&
-PannerShell::get_state (void)
-{
- return state (true);
-}
-
-XMLNode&
-PannerShell::state (bool full)
+PannerShell::get_state ()
{
XMLNode* node = new XMLNode ("PannerShell");
+ node->add_property (X_("bypassed"), _bypassed ? X_("yes") : X_("no"));
+
if (_panner) {
- node->add_child_nocopy (_panner->state (full));
+ node->add_child_nocopy (_panner->get_state ());
}
return *node;
const XMLProperty *prop;
LocaleGuard lg (X_("POSIX"));
+ if ((prop = node.property (X_("bypassed"))) != 0) {
+ set_bypassed (string_is_affirmative (prop->value ()));
+ }
+
_panner.reset ();
for (niter = nlist.begin(); niter != nlist.end(); ++niter) {
}
}
+void
+PannerShell::set_bypassed (bool yn)
+{
+ if (yn == _bypassed) {
+ return;
+ }
+
+ _bypassed = yn;
+ Changed (); /* EMIT SIGNAL */
+}
+
+bool
+PannerShell::bypassed () const
+{
+ return _bypassed;
+}
}
XMLNode&
-Panner1in2out::get_state (void)
-{
- return state (true);
-}
-
-XMLNode&
-Panner1in2out::state (bool /*full_state*/)
+Panner1in2out::get_state ()
{
XMLNode& root (Panner::get_state ());
root.add_property (X_("type"), _descriptor.name);
return root;
}
-int
-Panner1in2out::set_state (const XMLNode& node, int version)
-{
- LocaleGuard lg (X_("POSIX"));
- Panner::set_state (node, version);
- return 0;
-}
std::set<Evoral::Parameter>
Panner1in2out::what_can_be_automated() const
std::string describe_parameter (Evoral::Parameter);
std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
- XMLNode& state (bool full_state);
- XMLNode& get_state (void);
- int set_state (const XMLNode&, int version);
+ XMLNode& get_state ();
protected:
float left;
}
XMLNode&
-Panner2in2out::get_state (void)
-{
- return state (true);
-}
-
-XMLNode&
-Panner2in2out::state (bool /*full_state*/)
+Panner2in2out::get_state ()
{
XMLNode& root (Panner::get_state ());
root.add_property (X_("type"), _descriptor.name);
return root;
}
-int
-Panner2in2out::set_state (const XMLNode& node, int version)
-{
- LocaleGuard lg (X_("POSIX"));
- Panner::set_state (node, version);
- return 0;
-}
-
std::set<Evoral::Parameter>
Panner2in2out::what_can_be_automated() const
{
std::string describe_parameter (Evoral::Parameter);
std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
- XMLNode& state (bool full_state);
- XMLNode& get_state (void);
- int set_state (const XMLNode&, int version);
+ XMLNode& get_state ();
void update ();
XMLNode&
VBAPanner::get_state ()
-{
- return state (true);
-}
-
-XMLNode&
-VBAPanner::state (bool full_state)
{
XMLNode& node (Panner::get_state());
node.add_property (X_("type"), _descriptor.name);
return node;
}
-int
-VBAPanner::set_state (const XMLNode& node, int /*version*/)
-{
- return 0;
-}
-
Panner*
VBAPanner::factory (boost::shared_ptr<Pannable> p, boost::shared_ptr<Speakers> s)
{
std::string describe_parameter (Evoral::Parameter);
std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
- XMLNode& state (bool full_state);
XMLNode& get_state ();
- int set_state (const XMLNode&, int version);
PBD::AngularVector signal_position (uint32_t n) const;
boost::shared_ptr<Speakers> get_speakers() const;