Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include "pbd/error.h"
+
#include "ardour/speaker.h"
#include "ardour/speakers.h"
+#include "pbd/i18n.h"
+
using namespace ARDOUR;
using namespace PBD;
using namespace std;
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
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;
- }
+ }
}
}
}
}
}
+
+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 (o +0.0, 0.0));
+ break;
+
+ case 2:
+ add_speaker (AngularVector (o +60.0, 0.0));
+ add_speaker (AngularVector (o -60.0, 0.0));
+ break;
+
+ case 3:
+ 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:
+ /* 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:
+ {
+ double degree_step = 360.0 / n;
+ double deg;
+ uint32_t i;
+
+ /* even number of speakers? make sure the top two are either side of "top".
+ otherwise, just start at the "top" (90.0 degrees) and rotate around
+ */
+
+ if (n % 2) {
+ deg = 360 + o + degree_step;
+ } else {
+ deg = 360 + o;
+ }
+ 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"));
+
+ for (vector<Speaker>::const_iterator i = _speakers.begin(); i != _speakers.end(); ++i) {
+ XMLNode* speaker = new XMLNode (X_("Speaker"));
+
+ speaker->set_property (X_("azimuth"), (*i).angles().azi);
+ speaker->set_property (X_("elevation"), (*i).angles().ele);
+ speaker->set_property (X_("distance"), (*i).angles().length);
+
+ node->add_child_nocopy (*speaker);
+ }
+
+ return *node;
+}
+
+int
+Speakers::set_state (const XMLNode& node, int /*version*/)
+{
+ XMLNodeConstIterator i;
+
+ _speakers.clear ();
+
+ for (i = node.children().begin(); i != node.children().end(); ++i) {
+ if ((*i)->name() == X_("Speaker")) {
+ double a, e, d;
+ if (!(*i)->get_property (X_("azimuth"), a) ||
+ !(*i)->get_property (X_("elevation"), e) ||
+ !(*i)->get_property (X_("distance"), d)) {
+ warning << _("Speaker information is missing - speaker ignored") << endmsg;
+ continue;
+ }
+
+ add_speaker (AngularVector (a, e, d));
+ }
+ }
+
+ update ();
+
+ return 0;
+}