From da144ab5edb5bb629a8300c2cbf93c7f87947a83 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Thu, 17 Feb 2011 16:43:55 +0000 Subject: [PATCH] more progress on speakers/vbap etc. etc (still a work in progress) git-svn-id: svn://localhost/ardour2/branches/3.0@8887 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/speaker_dialog.cc | 37 ++++++++++++++------------ gtk2_ardour/speaker_dialog.h | 6 +++-- libs/ardour/ardour/panner.h | 3 +-- libs/ardour/ardour/session.h | 4 +-- libs/ardour/ardour/speakers.h | 1 + libs/ardour/panner.cc | 2 ++ libs/ardour/panner_shell.cc | 13 ++++++++- libs/ardour/session.cc | 5 ++-- libs/ardour/session_state.cc | 4 +-- libs/panners/1in2out/panner_1in2out.cc | 2 +- libs/panners/1in2out/panner_1in2out.h | 8 +----- libs/panners/2in2out/panner_2in2out.cc | 2 +- libs/panners/2in2out/panner_2in2out.h | 2 +- libs/panners/vbap/vbap.cc | 24 ++++++++--------- libs/panners/vbap/vbap.h | 6 ++--- libs/panners/vbap/vbap_speakers.cc | 19 +++---------- libs/panners/vbap/vbap_speakers.h | 7 ++--- 17 files changed, 70 insertions(+), 75 deletions(-) diff --git a/gtk2_ardour/speaker_dialog.cc b/gtk2_ardour/speaker_dialog.cc index 33200e99e0..8cdac45a45 100644 --- a/gtk2_ardour/speaker_dialog.cc +++ b/gtk2_ardour/speaker_dialog.cc @@ -33,13 +33,13 @@ using namespace Gtkmm2ext; SpeakerDialog::SpeakerDialog () : ArdourDialog (_("Speaker Configuration")) + , aspect_frame ("", 0.5, 0.5, 1.0, false) , azimuth_adjustment (0, 0.0, 360.0, 10.0, 1.0) , azimuth_spinner (azimuth_adjustment) , add_speaker_button (_("Add Speaker")) , use_system_button (_("Use System")) { - set_size_request (400, 200); side_vbox.set_homogeneous (false); side_vbox.set_border_width (9); @@ -48,14 +48,20 @@ SpeakerDialog::SpeakerDialog () side_vbox.pack_start (add_speaker_button, false, false); side_vbox.pack_start (use_system_button, false, false); + aspect_frame.set_size_request (200, 200); + aspect_frame.set_shadow_type (SHADOW_NONE); + aspect_frame.add (darea); + hbox.set_spacing (6); hbox.set_border_width (6); - hbox.pack_start (darea, true, true); + hbox.pack_start (aspect_frame, true, true); hbox.pack_start (side_vbox, false, false); get_vbox()->pack_start (hbox); get_vbox()->show_all (); + darea.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK); + darea.signal_size_allocate().connect (sigc::mem_fun (*this, &SpeakerDialog::darea_size_allocate)); darea.signal_expose_event().connect (sigc::mem_fun (*this, &SpeakerDialog::darea_expose_event)); darea.signal_button_press_event().connect (sigc::mem_fun (*this, &SpeakerDialog::darea_button_press_event)); @@ -66,9 +72,9 @@ SpeakerDialog::SpeakerDialog () } void -SpeakerDialog::set_speakers (const Speakers& s) +SpeakerDialog::set_speakers (boost::shared_ptr s) { - speakers = s; + speakers = *s; } Speakers @@ -226,7 +232,7 @@ SpeakerDialog::darea_button_press_event (GdkEventButton *ev) switch (ev->button) { case 1: case 2: - find_closest_object (ev->x, ev->y, drag_index); + drag_index = find_closest_object (ev->x, ev->y); drag_x = (int) floor (ev->x); drag_y = (int) floor (ev->y); state = (GdkModifierType) ev->state; @@ -288,39 +294,36 @@ SpeakerDialog::darea_button_release_event (GdkEventButton *ev) } int -SpeakerDialog::find_closest_object (gdouble x, gdouble y, int& which) +SpeakerDialog::find_closest_object (gdouble x, gdouble y) { float distance; float best_distance = FLT_MAX; - int pwhich = -1; + int n = 0; + int which = -1; - which = 0; - pwhich = 0; - - for (vector::iterator i = speakers.speakers().begin(); i != speakers.speakers().end(); ++i, ++pwhich) { + for (vector::iterator i = speakers.speakers().begin(); i != speakers.speakers().end(); ++i, ++n) { Speaker& candidate (*i); - CartesianVector c; - + candidate.angles().cartesian (c); cart_to_gtk (c); distance = sqrt ((c.x - x) * (c.x - x) + (c.y - y) * (c.y - y)); + if (distance < best_distance) { best_distance = distance; - which = pwhich; + which = n; } } - if (best_distance > 20) { // arbitrary - return 0; + return -1; } - return 1; + return which; } bool diff --git a/gtk2_ardour/speaker_dialog.h b/gtk2_ardour/speaker_dialog.h index 9a04896e7f..0ce99ac8d7 100644 --- a/gtk2_ardour/speaker_dialog.h +++ b/gtk2_ardour/speaker_dialog.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "ardour/speakers.h" @@ -35,12 +36,13 @@ class SpeakerDialog : public ArdourDialog SpeakerDialog (); ARDOUR::Speakers get_speakers() const; - void set_speakers (const ARDOUR::Speakers&); + void set_speakers (boost::shared_ptr); private: ARDOUR::Speakers speakers; Gtk::HBox hbox; Gtk::VBox side_vbox; + Gtk::AspectFrame aspect_frame; Gtk::DrawingArea darea; Gtk::Adjustment azimuth_adjustment; Gtk::SpinButton azimuth_spinner; @@ -63,7 +65,7 @@ class SpeakerDialog : public ArdourDialog void clamp_to_circle (double& x, double& y); void gtk_to_cart (PBD::CartesianVector& c) const; void cart_to_gtk (PBD::CartesianVector& c) const; - int find_closest_object (gdouble x, gdouble y, int& which); + int find_closest_object (gdouble x, gdouble y); }; #endif /* __ardour_gtk_speaker_dialog_h__ */ diff --git a/libs/ardour/ardour/panner.h b/libs/ardour/ardour/panner.h index 5e0ed991d6..75f9ea598c 100644 --- a/libs/ardour/ardour/panner.h +++ b/libs/ardour/ardour/panner.h @@ -162,7 +162,6 @@ class Panner : public PBD::Stateful, public PBD::ScopedConnectionList 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, framepos_t start, framepos_t end, pframes_t nframes, @@ -176,7 +175,7 @@ extern "C" { std::string name; int32_t in; int32_t out; - ARDOUR::Panner* (*factory)(boost::shared_ptr, ARDOUR::Speakers&); + ARDOUR::Panner* (*factory)(boost::shared_ptr, boost::shared_ptr); }; } diff --git a/libs/ardour/ardour/session.h b/libs/ardour/ardour/session.h index 25b7b72fe4..dfa09fd357 100644 --- a/libs/ardour/ardour/session.h +++ b/libs/ardour/ardour/session.h @@ -716,7 +716,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi /* Speakers */ - Speakers& get_speakers (); + boost::shared_ptr get_speakers (); /* Controllables */ @@ -1478,7 +1478,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi void start_time_changed (framepos_t); void end_time_changed (framepos_t); - Speakers* _speakers; + boost::shared_ptr _speakers; }; } // namespace ARDOUR diff --git a/libs/ardour/ardour/speakers.h b/libs/ardour/ardour/speakers.h index 0bee66af07..2bbfdadfa7 100644 --- a/libs/ardour/ardour/speakers.h +++ b/libs/ardour/ardour/speakers.h @@ -43,6 +43,7 @@ public: virtual void remove_speaker (int id); virtual void move_speaker (int id, const PBD::AngularVector& new_position); virtual void clear_speakers (); + uint32_t size() const { return _speakers.size(); } void setup_default_speakers (uint32_t nspeakers); diff --git a/libs/ardour/panner.cc b/libs/ardour/panner.cc index 6498c2777a..26009e1a64 100644 --- a/libs/ardour/panner.cc +++ b/libs/ardour/panner.cc @@ -25,6 +25,8 @@ #include "ardour/session.h" #include "ardour/utils.h" +#include "pbd/stacktrace.h" + using namespace std; using namespace ARDOUR; diff --git a/libs/ardour/panner_shell.cc b/libs/ardour/panner_shell.cc index ecf7adf990..d67925ed5c 100644 --- a/libs/ardour/panner_shell.cc +++ b/libs/ardour/panner_shell.cc @@ -104,7 +104,18 @@ PannerShell::configure_io (ChanCount in, ChanCount out) abort (); } - Panner* p = pi->descriptor.factory (_pannable, _session.get_speakers()); + boost::shared_ptr speakers = _session.get_speakers (); + + if (nouts != speakers->size()) { + /* hmm, output count doesn't match session speaker count so + create a new speaker set. + */ + Speakers* s = new Speakers (); + s->setup_default_speakers (nouts); + speakers.reset (s); + } + + Panner* p = pi->descriptor.factory (_pannable, speakers); boost_debug_shared_ptr_mark_interesting (p, "Panner"); _panner.reset (p); _panner->configure_io (in, out); diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index 4c25989c0a..39f6fc4ff7 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -323,7 +323,6 @@ Session::destroy () playlists.reset (); delete _locations; - delete _speakers; DEBUG_TRACE (DEBUG::Destruction, "Session::destroy() done\n"); @@ -4175,10 +4174,10 @@ Session::ensure_search_path_includes (const string& path, DataType type) } } -Speakers& +boost::shared_ptr Session::get_speakers() { - return *_speakers; + return _speakers; } list diff --git a/libs/ardour/session_state.cc b/libs/ardour/session_state.cc index 9a359e1b05..b925e9416e 100644 --- a/libs/ardour/session_state.cc +++ b/libs/ardour/session_state.cc @@ -221,7 +221,7 @@ Session::first_stage_init (string fullpath, string snapshot_name) midi_control_ui = 0; _step_editors = 0; no_questions_about_missing_files = false; - _speakers = new Speakers; + _speakers.reset (new Speakers); AudioDiskstream::allocate_working_buffers(); @@ -1186,9 +1186,7 @@ Session::state(bool full_state) } node->add_child_nocopy (_speakers->get_state()); - node->add_child_nocopy (_tempo_map->get_state()); - node->add_child_nocopy (get_control_protocol_state()); if (_extra_xml) { diff --git a/libs/panners/1in2out/panner_1in2out.cc b/libs/panners/1in2out/panner_1in2out.cc index cce2ec9b71..6c002c1591 100644 --- a/libs/panners/1in2out/panner_1in2out.cc +++ b/libs/panners/1in2out/panner_1in2out.cc @@ -317,7 +317,7 @@ Panner1in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, Panner* -Panner1in2out::factory (boost::shared_ptr p, Speakers& /* ignored */) +Panner1in2out::factory (boost::shared_ptr p, boost::shared_ptr /* ignored */) { return new Panner1in2out (p); } diff --git a/libs/panners/1in2out/panner_1in2out.h b/libs/panners/1in2out/panner_1in2out.h index ffc67ac54d..c36e3e87c7 100644 --- a/libs/panners/1in2out/panner_1in2out.h +++ b/libs/panners/1in2out/panner_1in2out.h @@ -51,13 +51,7 @@ class Panner1in2out : public Panner std::set what_can_be_automated() const; - /* this class just leaves the pan law itself to be defined - by the update(), do_distribute_automated() - methods. derived classes also need a factory method - and a type name. See EqualPowerStereoPanner as an example. - */ - - static Panner* factory (boost::shared_ptr, Speakers&); + static Panner* factory (boost::shared_ptr, boost::shared_ptr); std::string describe_parameter (Evoral::Parameter); std::string value_as_string (boost::shared_ptr) const; diff --git a/libs/panners/2in2out/panner_2in2out.cc b/libs/panners/2in2out/panner_2in2out.cc index 8667fd5f54..df859a1eff 100644 --- a/libs/panners/2in2out/panner_2in2out.cc +++ b/libs/panners/2in2out/panner_2in2out.cc @@ -426,7 +426,7 @@ Panner2in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, } Panner* -Panner2in2out::factory (boost::shared_ptr p, Speakers& /* ignored */) +Panner2in2out::factory (boost::shared_ptr p, boost::shared_ptr /* ignored */) { return new Panner2in2out (p); } diff --git a/libs/panners/2in2out/panner_2in2out.h b/libs/panners/2in2out/panner_2in2out.h index 2014bb032e..b9b9a73dfb 100644 --- a/libs/panners/2in2out/panner_2in2out.h +++ b/libs/panners/2in2out/panner_2in2out.h @@ -57,7 +57,7 @@ class Panner2in2out : public Panner std::set what_can_be_automated() const; - static Panner* factory (boost::shared_ptr, Speakers&); + static Panner* factory (boost::shared_ptr, boost::shared_ptr); std::string describe_parameter (Evoral::Parameter); std::string value_as_string (boost::shared_ptr) const; diff --git a/libs/panners/vbap/vbap.cc b/libs/panners/vbap/vbap.cc index 239a253f19..e563952efd 100644 --- a/libs/panners/vbap/vbap.cc +++ b/libs/panners/vbap/vbap.cc @@ -37,9 +37,9 @@ VBAPanner::Signal::Signal (Session& session, VBAPanner& p, uint32_t n) desired_outputs[0] = desired_outputs[1] = desired_outputs[2] = -1; }; -VBAPanner::VBAPanner (boost::shared_ptr p, Speakers& s) +VBAPanner::VBAPanner (boost::shared_ptr p, boost::shared_ptr s) : Panner (p) - , _speakers (VBAPSpeakers::instance (s)) + , _speakers (new VBAPSpeakers (s)) { _pannable->pan_azimuth_control->Changed.connect_same_thread (*this, boost::bind (&VBAPanner::update, this)); _pannable->pan_width_control->Changed.connect_same_thread (*this, boost::bind (&VBAPanner::update, this)); @@ -138,16 +138,16 @@ VBAPanner::compute_gains (double gains[3], int speaker_ids[3], int azi, int ele) gains[0] = gains[1] = gains[2] = 0; speaker_ids[0] = speaker_ids[1] = speaker_ids[2] = 0; - for (i = 0; i < _speakers.n_tuples(); i++) { + for (i = 0; i < _speakers->n_tuples(); i++) { small_g = 10000000.0; - for (j = 0; j < _speakers.dimension(); j++) { + for (j = 0; j < _speakers->dimension(); j++) { gtmp[j] = 0.0; - for (k = 0; k < _speakers.dimension(); k++) { - gtmp[j] += cartdir[k] * _speakers.matrix(i)[j*_speakers.dimension()+k]; + for (k = 0; k < _speakers->dimension(); k++) { + gtmp[j] += cartdir[k] * _speakers->matrix(i)[j*_speakers->dimension()+k]; } if (gtmp[j] < small_g) { @@ -162,12 +162,12 @@ VBAPanner::compute_gains (double gains[3], int speaker_ids[3], int azi, int ele) gains[0] = gtmp[0]; gains[1] = gtmp[1]; - speaker_ids[0] = _speakers.speaker_for_tuple (i, 0); - speaker_ids[1] = _speakers.speaker_for_tuple (i, 1); + speaker_ids[0] = _speakers->speaker_for_tuple (i, 0); + speaker_ids[1] = _speakers->speaker_for_tuple (i, 1); - if (_speakers.dimension() == 3) { + if (_speakers->dimension() == 3) { gains[2] = gtmp[2]; - speaker_ids[2] = _speakers.speaker_for_tuple (i, 2); + speaker_ids[2] = _speakers->speaker_for_tuple (i, 2); } else { gains[2] = 0.0; speaker_ids[2] = -1; @@ -275,7 +275,7 @@ VBAPanner::set_state (const XMLNode& node, int /*version*/) } Panner* -VBAPanner::factory (boost::shared_ptr p, Speakers& s) +VBAPanner::factory (boost::shared_ptr p, boost::shared_ptr s) { return new VBAPanner (p, s); } @@ -289,7 +289,7 @@ VBAPanner::in() const ChanCount VBAPanner::out() const { - return ChanCount (DataType::AUDIO, _speakers.n_speakers()); + return ChanCount (DataType::AUDIO, _speakers->n_speakers()); } std::set diff --git a/libs/panners/vbap/vbap.h b/libs/panners/vbap/vbap.h index cf010cc331..937199194f 100644 --- a/libs/panners/vbap/vbap.h +++ b/libs/panners/vbap/vbap.h @@ -37,7 +37,7 @@ class Pannable; class VBAPanner : public Panner { public: - VBAPanner (boost::shared_ptr, Speakers& s); + VBAPanner (boost::shared_ptr, boost::shared_ptr); ~VBAPanner (); void configure_io (ChanCount in, ChanCount /* ignored - we use Speakers */); @@ -46,7 +46,7 @@ public: std::set what_can_be_automated() const; - static Panner* factory (boost::shared_ptr, Speakers& s); + static Panner* factory (boost::shared_ptr, boost::shared_ptr); void distribute (BufferSet& ibufs, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes); @@ -72,7 +72,7 @@ private: }; std::vector _signals; - VBAPSpeakers& _speakers; + boost::shared_ptr _speakers; void compute_gains (double g[3], int ls[3], int azi, int ele); void update (); diff --git a/libs/panners/vbap/vbap_speakers.cc b/libs/panners/vbap/vbap_speakers.cc index 7e70e5df66..506ad4a25b 100644 --- a/libs/panners/vbap/vbap_speakers.cc +++ b/libs/panners/vbap/vbap_speakers.cc @@ -43,23 +43,12 @@ using namespace ARDOUR; using namespace PBD; using namespace std; -VBAPSpeakers* VBAPSpeakers::_instance = 0; - -VBAPSpeakers& -VBAPSpeakers::instance (Speakers& s) -{ - if (_instance == 0) { - _instance = new VBAPSpeakers (s); - } - - return *_instance; -} - -VBAPSpeakers::VBAPSpeakers (Speakers& s) +VBAPSpeakers::VBAPSpeakers (boost::shared_ptr s) : _dimension (2) - , _speakers (s.speakers()) + , _speakers (s->speakers()) { - s.Changed.connect_same_thread (speaker_connection, boost::bind (&VBAPSpeakers::update, this)); + // s.Changed.connect_same_thread (speaker_connection, boost::bind (&VBAPSpeakers::update, this)); + update (); } VBAPSpeakers::~VBAPSpeakers () diff --git a/libs/panners/vbap/vbap_speakers.h b/libs/panners/vbap/vbap_speakers.h index 8fe006ea1c..3bd298ba3d 100644 --- a/libs/panners/vbap/vbap_speakers.h +++ b/libs/panners/vbap/vbap_speakers.h @@ -43,20 +43,17 @@ public: int n_tuples () const { return _matrices.size(); } int dimension() const { return _dimension; } - static VBAPSpeakers& instance (Speakers&); + VBAPSpeakers (boost::shared_ptr); uint32_t n_speakers() const { return _speakers.size(); } ~VBAPSpeakers (); private: - static VBAPSpeakers* _instance; static const double MIN_VOL_P_SIDE_LGTH = 0.01; int _dimension; - std::vector& _speakers; + std::vector _speakers; PBD::ScopedConnection speaker_connection; - VBAPSpeakers (Speakers&); - struct azimuth_sorter { bool operator() (const Speaker& s1, const Speaker& s2) { return s1.angles().azi < s2.angles().azi;