abort if configuration fails
[ardour.git] / libs / ardour / speakers.cc
index 4229e77c658d1e6ca945f6d2dad9c6380ea30a42..7c7b02f0cc796ab4bbda3b637d8f186aac1e289e 100644 (file)
@@ -35,26 +35,65 @@ Speaker::Speaker (int i, const AngularVector& position)
        move (position);
 }
 
+Speaker::Speaker (Speaker const & o)
+       : id (o.id)
+       , _coords (o._coords)
+       , _angles (o._angles)
+{
+
+}
+
+Speaker &
+Speaker::operator= (Speaker const & o)
+{
+       if (&o == this) {
+               return *this;
+       }
+
+       id = o.id;
+       _coords = o._coords;
+       _angles = o._angles;
+
+       return *this;
+}
+
 void
 Speaker::move (const AngularVector& new_position)
 {
        _angles = new_position;
        _angles.cartesian (_coords);
+
+       PositionChanged (); /* EMIT SIGNAL */
 }
 
 Speakers::Speakers ()
 {
 }
 
+Speakers::Speakers (const Speakers& s)
+       : Stateful ()
+{
+        _speakers = s._speakers;
+}
+
 Speakers::~Speakers ()
 {
 }
 
+Speakers&
+Speakers::operator= (const Speakers& s)
+{
+        if (&s != this) {
+                _speakers = s._speakers;
+        }
+        return *this;
+}
+
 void
 Speakers::dump_speakers (ostream& o)
 {
        for (vector<Speaker>::iterator i = _speakers.begin(); i != _speakers.end(); ++i) {
-               o << "Speaker " << (*i).id << " @ " 
+               o << "Speaker " << (*i).id << " @ "
                  << (*i).coords().x << ", " << (*i).coords().y << ", " << (*i).coords().z
                  << " azimuth " << (*i).angles().azi
                  << " elevation " << (*i).angles().ele
@@ -70,31 +109,28 @@ Speakers::clear_speakers ()
        update ();
 }
 
-int 
+int
 Speakers::add_speaker (const AngularVector& position)
 {
        int id = _speakers.size();
 
-       cerr << "Added speaker " << id << " at " << position.azi << " /= " << position.ele << endl;
-
        _speakers.push_back (Speaker (id, position));
        update ();
 
-       dump_speakers (cerr);
        Changed ();
 
        return id;
-}        
+}
 
 void
 Speakers::remove_speaker (int id)
 {
-       for (vector<Speaker>::iterator i = _speakers.begin(); i != _speakers.end(); ) {
-               if ((*i).id == id) {
+       for (vector<Speaker>::iterator i = _speakers.begin(); i != _speakers.end(); ++i) {
+               if (i->id == id) {
                        i = _speakers.erase (i);
                        update ();
                        break;
-               } 
+               }
        }
 }
 
@@ -113,35 +149,76 @@ Speakers::move_speaker (int id, const AngularVector& new_position)
 void
 Speakers::setup_default_speakers (uint32_t n)
 {
+       double o = 180.0;
+
         /* default assignment of speaker position for n speakers */
 
         assert (n>0);
 
        switch (n) {
         case 1:
-                add_speaker (AngularVector (0.0, 0.0));
+                add_speaker (AngularVector (o   +0.0, 0.0));
                 break;
 
         case 2:
-                add_speaker (AngularVector (0.0, 0.0));
-                add_speaker (AngularVector (180.0, 0,0));
+                add_speaker (AngularVector (o  +60.0, 0.0));
+                add_speaker (AngularVector (o  -60.0, 0.0));
                 break;
 
        case 3:
-               /* top, bottom kind-of-left & bottom kind-of-right */
-                add_speaker (AngularVector (90.0, 0.0));
-                add_speaker (AngularVector (215.0, 0,0));
-                add_speaker (AngularVector (335.0, 0,0));
+                add_speaker (AngularVector (o  +60.0, 0.0));
+                add_speaker (AngularVector (o  -60.0, 0.0));
+                add_speaker (AngularVector (o +180.0, 0.0));
                break;
        case 4:
-               /* clockwise from top left */
-                add_speaker (AngularVector (135.0, 0.0));
-                add_speaker (AngularVector (45.0, 0.0));
-                add_speaker (AngularVector (335.0, 0.0));
-                add_speaker (AngularVector (215.0, 0.0));
+               /* 4.0 with regular spacing */
+                add_speaker (AngularVector (o  +45.0, 0.0));
+                add_speaker (AngularVector (o  -45.0, 0.0));
+                add_speaker (AngularVector (o +135.0, 0.0));
+                add_speaker (AngularVector (o -135.0, 0.0));
+               break;
+       case 5:
+               /* 5.0 with regular spacing */
+                add_speaker (AngularVector (o  +72.0, 0.0));
+                add_speaker (AngularVector (o  -72.0, 0.0));
+                add_speaker (AngularVector (o   +0.0, 0.0));
+                add_speaker (AngularVector (o +144.0, 0.0));
+                add_speaker (AngularVector (o -144.0, 0.0));
+               break;
+       case 6:
+               /* 6.0 with regular spacing */
+                add_speaker (AngularVector (o  +60.0, 0.0));
+                add_speaker (AngularVector (o  -60.0, 0.0));
+                add_speaker (AngularVector (o   +0.0, 0.0));
+                add_speaker (AngularVector (o +120.0, 0.0));
+                add_speaker (AngularVector (o -120.0, 0.0));
+                add_speaker (AngularVector (o +180.0, 0.0));
+               break;
+       case 7:
+               /* 7.0 with regular front spacing */
+                add_speaker (AngularVector (o  +45.0, 0.0));
+                add_speaker (AngularVector (o  -45.0, 0.0));
+                add_speaker (AngularVector (o   +0.0, 0.0));
+                add_speaker (AngularVector (o  +90.0, 0.0));
+                add_speaker (AngularVector (o  -90.0, 0.0));
+                add_speaker (AngularVector (o +150.0, 0.0));
+                add_speaker (AngularVector (o -150.0, 0.0));
+               break;
+       case 10:
+               /* 5+4 with 45°/90° spacing */
+                add_speaker (AngularVector (o  +45.0, 0.0));
+                add_speaker (AngularVector (o  -45.0, 0.0));
+                add_speaker (AngularVector (o   +0.0, 0.0));
+                add_speaker (AngularVector (o +135.0, 0.0));
+                add_speaker (AngularVector (o -135.0, 0.0));
+                add_speaker (AngularVector (o  +45.0, 60.0));
+                add_speaker (AngularVector (o  -45.0, 60.0));
+                add_speaker (AngularVector (o +135.0, 60.0));
+                add_speaker (AngularVector (o -135.0, 60.0));
+                add_speaker (AngularVector (o   +0.0, 90.0));
                break;
 
-       default: 
+       default:
        {
                double degree_step = 360.0 / n;
                double deg;
@@ -152,23 +229,23 @@ Speakers::setup_default_speakers (uint32_t n)
                */
 
                if (n % 2) {
-                       deg = 90.0 - degree_step;
+                       deg = 360 + o + degree_step;
                } else {
-                       deg = 90.0;
+                       deg = 360 + o;
                }
-               for (i = 0; i < n; ++i, deg += degree_step) {
-                       add_speaker (AngularVector (deg, 0.0));
+               for (i = 0; i < n; ++i, deg -= degree_step) {
+                       add_speaker (AngularVector (fmod(deg, 360), 0.0));
                }
        }
         }
 }
-        
+
 XMLNode&
 Speakers::get_state ()
 {
         XMLNode* node = new XMLNode (X_("Speakers"));
         char buf[32];
-        LocaleGuard lg (X_("POSIX"));
+        LocaleGuard lg (X_("C"));
 
         for (vector<Speaker>::const_iterator i = _speakers.begin(); i != _speakers.end(); ++i) {
                 XMLNode* speaker = new XMLNode (X_("Speaker"));
@@ -182,7 +259,7 @@ Speakers::get_state ()
 
                 node->add_child_nocopy (*speaker);
         }
-        
+
         return *node;
 }
 
@@ -192,7 +269,7 @@ Speakers::set_state (const XMLNode& node, int /*version*/)
         XMLNodeConstIterator i;
         const XMLProperty* prop;
         double a, e, d;
-        LocaleGuard lg (X_("POSIX"));
+        LocaleGuard lg (X_("C"));
         int n = 0;
 
         _speakers.clear ();
@@ -210,7 +287,7 @@ Speakers::set_state (const XMLNode& node, int /*version*/)
                                 continue;
                         }
                         e = atof (prop->value());
-                                            
+
                         if ((prop = (*i)->property (X_("distance"))) == 0) {
                                 warning << _("Speaker information is missing distance - speaker ignored") << endmsg;
                                 continue;
@@ -222,6 +299,6 @@ Speakers::set_state (const XMLNode& node, int /*version*/)
         }
 
         update ();
-        
+
         return 0;
 }