more progress on speakers/vbap etc. etc (still a work in progress)
authorPaul Davis <paul@linuxaudiosystems.com>
Thu, 17 Feb 2011 16:43:55 +0000 (16:43 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Thu, 17 Feb 2011 16:43:55 +0000 (16:43 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@8887 d708f5d6-7413-0410-9779-e7cbd77b26cf

17 files changed:
gtk2_ardour/speaker_dialog.cc
gtk2_ardour/speaker_dialog.h
libs/ardour/ardour/panner.h
libs/ardour/ardour/session.h
libs/ardour/ardour/speakers.h
libs/ardour/panner.cc
libs/ardour/panner_shell.cc
libs/ardour/session.cc
libs/ardour/session_state.cc
libs/panners/1in2out/panner_1in2out.cc
libs/panners/1in2out/panner_1in2out.h
libs/panners/2in2out/panner_2in2out.cc
libs/panners/2in2out/panner_2in2out.h
libs/panners/vbap/vbap.cc
libs/panners/vbap/vbap.h
libs/panners/vbap/vbap_speakers.cc
libs/panners/vbap/vbap_speakers.h

index 33200e99e07bfe42ee4e20d94a256ed7650cf5d4..8cdac45a45690ac0017b6f91d8c19d53149bbe19 100644 (file)
@@ -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<Speakers> 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<Speaker>::iterator i = speakers.speakers().begin(); i != speakers.speakers().end(); ++i, ++pwhich) {
+       for (vector<Speaker>::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
index 9a04896e7f47372a14e0de6e8a2f181e4062baf6..0ce99ac8d7f320b55bb51005bcdaed9ce56f18f9 100644 (file)
@@ -24,6 +24,7 @@
 #include <gtkmm/spinbutton.h>
 #include <gtkmm/box.h>
 #include <gtkmm/adjustment.h>
+#include <gtkmm/aspectframe.h>
 
 #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<ARDOUR::Speakers>);
 
   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__ */
index 5e0ed991d6592314a77436f9b6fe07af123abdf0..75f9ea598c9b9f3aee1ccaf83556e01c6a36970e 100644 (file)
@@ -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::Pannable>, ARDOUR::Speakers&);
+            ARDOUR::Panner* (*factory)(boost::shared_ptr<ARDOUR::Pannable>, boost::shared_ptr<ARDOUR::Speakers>);
         };
 }
 
index 25b7b72fe4278b6cc5ed961de08e710d22c14b59..dfa09fd3577e8d0286a0b8a9e56040920147838e 100644 (file)
@@ -716,7 +716,7 @@ class Session : public PBD::StatefulDestructible, public PBD::ScopedConnectionLi
 
        /* Speakers */
 
-       Speakers& get_speakers ();
+        boost::shared_ptr<Speakers> 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> _speakers; 
 };
 
 } // namespace ARDOUR
index 0bee66af07079c434540cac0cc380917939a675c..2bbfdadfa7b3c8aca7092fab728abcd4f4dbc0fe 100644 (file)
@@ -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);
 
index 6498c2777aa0067aced09201d15d120a4956b452..26009e1a646bd7ec2689fafdfd5f8b70dec5280f 100644 (file)
@@ -25,6 +25,8 @@
 #include "ardour/session.h"
 #include "ardour/utils.h"
 
+#include "pbd/stacktrace.h"
+
 using namespace std;
 using namespace ARDOUR;
 
index ecf7adf990cf8c0f896f84df425f75268fb29541..d67925ed5c1b0f7fc658ad5eae2a8ed6d8dfbdf9 100644 (file)
@@ -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> 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);
index 4c25989c0ae8acbb7360244b685a6d4c3b44edd7..39f6fc4ff7218a05d3d67e70ce3a521f29276369 100644 (file)
@@ -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<Speakers>
 Session::get_speakers() 
 {
-        return *_speakers;
+        return _speakers;
 }
 
 list<string>
index 9a359e1b05aae04be1b97bd14bd4844c71218b4a..b925e9416ecf495eb82a9ee9d1c0272b68b08980 100644 (file)
@@ -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) {
index cce2ec9b715237ca53741cb66c547004384f5076..6c002c159125ad454a93a6a651fad3a21167e722 100644 (file)
@@ -317,7 +317,7 @@ Panner1in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs,
 
 
 Panner*
-Panner1in2out::factory (boost::shared_ptr<Pannable> p, Speakers& /* ignored */)
+Panner1in2out::factory (boost::shared_ptr<Pannable> p, boost::shared_ptr<Speakers> /* ignored */)
 {
        return new Panner1in2out (p);
 }
index ffc67ac54dfeecc8e11a1154370cfa73b2e81b37..c36e3e87c7636cc096a4931460c5cb5edda33741 100644 (file)
@@ -51,13 +51,7 @@ class Panner1in2out : public Panner
 
         std::set<Evoral::Parameter> 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<Pannable>, Speakers&);
+        static Panner* factory (boost::shared_ptr<Pannable>, boost::shared_ptr<Speakers>);
 
         std::string describe_parameter (Evoral::Parameter);
         std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
index 8667fd5f5414de1da0318dc3c83929aa20dcf7f8..df859a1eff67e7967e32886e07891b4b185e666d 100644 (file)
@@ -426,7 +426,7 @@ Panner2in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs,
 }
 
 Panner*
-Panner2in2out::factory (boost::shared_ptr<Pannable> p, Speakers& /* ignored */)
+Panner2in2out::factory (boost::shared_ptr<Pannable> p, boost::shared_ptr<Speakers> /* ignored */)
 {
        return new Panner2in2out (p);
 }
index 2014bb032e4e3c429bd9ad3e00353127bc658c22..b9b9a73dfb45c29c4559e62a71dfe92acc3d49e3 100644 (file)
@@ -57,7 +57,7 @@ class Panner2in2out : public Panner
 
        std::set<Evoral::Parameter> what_can_be_automated() const;
 
-       static Panner* factory (boost::shared_ptr<Pannable>, Speakers&);
+       static Panner* factory (boost::shared_ptr<Pannable>, boost::shared_ptr<Speakers>);
 
         std::string describe_parameter (Evoral::Parameter);
         std::string value_as_string (boost::shared_ptr<AutomationControl>) const;
index 239a253f19f560468bcdc1e2890aaacdbdb75b09..e563952efd30f822f52c1b54360210eecdc509c6 100644 (file)
@@ -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<Pannable> p, Speakers& s)
+VBAPanner::VBAPanner (boost::shared_ptr<Pannable> p, boost::shared_ptr<Speakers> 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<Pannable> p, Speakers& s)
+VBAPanner::factory (boost::shared_ptr<Pannable> p, boost::shared_ptr<Speakers> 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<Evoral::Parameter> 
index cf010cc33190a486771429848f3f5c462cd8bf14..937199194f873d95c4a12368774d3c2752b0ffa3 100644 (file)
@@ -37,7 +37,7 @@ class Pannable;
 class VBAPanner : public Panner 
 { 
 public:
-       VBAPanner (boost::shared_ptr<Pannable>, Speakers& s);
+       VBAPanner (boost::shared_ptr<Pannable>, boost::shared_ptr<Speakers>);
        ~VBAPanner ();
 
         void configure_io (ChanCount in, ChanCount /* ignored - we use Speakers */);
@@ -46,7 +46,7 @@ public:
 
         std::set<Evoral::Parameter> what_can_be_automated() const;
 
-       static Panner* factory (boost::shared_ptr<Pannable>, Speakers& s);
+       static Panner* factory (boost::shared_ptr<Pannable>, boost::shared_ptr<Speakers>);
 
        void distribute (BufferSet& ibufs, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes);
 
@@ -72,7 +72,7 @@ private:
         };
 
         std::vector<Signal*> _signals;
-        VBAPSpeakers&       _speakers;
+        boost::shared_ptr<VBAPSpeakers>  _speakers;
         
        void compute_gains (double g[3], int ls[3], int azi, int ele);
         void update ();
index 7e70e5df66b6d3d8fb7f0c35849d3c74b428208d..506ad4a25bbd0d00cd650e92b2394756fea56200 100644 (file)
@@ -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<Speakers> 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 ()
index 8fe006ea1cefdb4602cb5c6cef2f7963e144dae6..3bd298ba3d4be194dae514e594880d19f197e57a 100644 (file)
@@ -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<Speakers>);
         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<Speaker>& _speakers;
+       std::vector<Speaker> _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;