Jamoma API  0.6.0.a19
Source.cpp
1 // Source.cpp
2 
3 /***************************************************/
4 /*! \class Source
5  \brief Sound source class
6 
7  This class implements a sound source, which consists
8  of a 1d signal and its own
9  directivity pattern and 3-d position properties.
10 
11  by Tristan Matthews and Nils Peters, 2007-2008.
12  */
13 /***************************************************/
14 
15 #include "Source.h"
16 #include "Room.h"
17 #include "Mirror.h"
18 #include "Moveable.h"
19 #include "ext.h"
20 
21 
22 extern bool globWarningFlag;
23 extern bool globReportFlag;
24 
25 // default constructor
26 Source::Source(Room &room, Mirror *mirrors) :
27  Moveable(), owner_(room), mirrors_(mirrors)
28 {
29  init();
30 }
31 
32 void Source::init()
33 {
34  aziAngle_ = 0;
35  directivityFlag_ = false;
36 
37  directivityTbl_.resize(361, 1.0f); // reserve space for all degrees
38 }
39 
40 void Source::updateDirectivity(long **tbl)
41 {
42  int n = 0;
43  for (std::vector<double>::iterator iter = directivityTbl_.begin(); iter != directivityTbl_.end(); iter++, n++)
44  {
45  *iter = (*((*tbl) + n)) * 0.0001; // retrieve the nth element from the table, and divide by 10000
46  if (globReportFlag)
47  post("directTbl[%d]: %f", n, *iter);
48  }
49 
50  flag(true);
51 }
52 
53 double Source::directivityAt(long angle) const
54 {
55  if (angle >= 0 && angle < 361) // index 361 gives us the average source directivity
56  {
57  return directivityTbl_[angle];
58  }
59  else // out of bounds
60  {
61  if (globWarningFlag)
62  error("Angle out of bounds for directivity table.");
63 
64  return 1.0;
65  }
66 }
67 
68 void Source::aziAngle(long angle)
69 {
70  if (angle >= 0 && angle < 360)
71  {
72  aziAngle_ = angle;
73 
74  // update mirrors azi angles accordingly
75  mirrors_[0].aziAngle(aziAngle_);
76 
77  /* if (owner_.reflOrder() > 0)
78  {
79  mirrors_[LEFT].aziAngle((aziAngle_ + 270) % 360);
80  mirrors_[RIGHT].aziAngle((aziAngle_ + 90) % 360);
81  mirrors_[FRONT].aziAngle(aziAngle_);
82  mirrors_[REAR].aziAngle((aziAngle_ + 180) % 360);
83  mirrors_[FLOOR].aziAngle(360); // at angle 360, we look at the mean for the directivity table.
84  mirrors_[CEILING].aziAngle(360);
85  }
86 
87  if (owner_.reflOrder() > 1)
88  {
89  mirrors_[LEFT_FRONT].aziAngle(mirrors_[LEFT].aziAngle());
90  mirrors_[RIGHT_FRONT].aziAngle(mirrors_[RIGHT].aziAngle());
91  mirrors_[LEFT_REAR].aziAngle(mirrors_[LEFT].aziAngle());
92  mirrors_[RIGHT_REAR].aziAngle(mirrors_[RIGHT].aziAngle());
93  mirrors_[LEFT_FLOOR].aziAngle(mirrors_[LEFT].aziAngle());
94  mirrors_[RIGHT_FLOOR].aziAngle(mirrors_[RIGHT].aziAngle());
95  mirrors_[LEFT_CEILING].aziAngle(mirrors_[LEFT].aziAngle());
96  mirrors_[RIGHT_CEILING].aziAngle(mirrors_[RIGHT].aziAngle());
97  mirrors_[FRONT_FLOOR].aziAngle(mirrors_[FRONT].aziAngle());
98  mirrors_[REAR_FLOOR].aziAngle(mirrors_[REAR].aziAngle());
99  mirrors_[FRONT_CEILING].aziAngle(mirrors_[FRONT].aziAngle());
100  mirrors_[REAR_CEILING].aziAngle(mirrors_[REAR].aziAngle());
101  }
102  */
103  flag(true);
104  }
105  else if (globWarningFlag)
106  post("Source angle must be between 0 and 360.");
107 }
108 
109 long Source::aziAngle() const
110 {
111  return aziAngle_;
112 }
113 
114 void Source::printPos() const
115 {
116  post("SourcePos= X: %f,Y: %f,Z: %f,Orientation: %ld", xPos(), yPos(), zPos(), aziAngle_);
117 }
118 
119 void Source::xPosAbs(double newXPos)
120 {
121  if (newXPos < owner_.halfWidth() && newXPos > -owner_.halfWidth())
122  {
123  xPos(newXPos);
124  notifyRoom();
125  }
126  else if (globWarningFlag)
127  post("source exceeds room");
128 }
129 
130 void Source::yPosAbs(double newYPos)
131 {
132  if (newYPos < owner_.halfDepth() && newYPos > -owner_.halfDepth())
133  {
134  yPos(newYPos);
135  notifyRoom();
136  }
137  else if (globWarningFlag)
138  post("source exceeds room");
139 }
140 
141 void Source::zPosAbs(double newZPos)
142 {
143  if (newZPos < owner_.halfHeight() && newZPos > -owner_.halfHeight())
144  {
145  zPos(newZPos);
146  notifyRoom();
147  }
148  else if (globWarningFlag)
149  post("source exceeds room");
150 }
151 
152 void Source::xPosRel(double newXPos)
153 {
154  if (newXPos < 1 && newXPos > -1)
155  {
156  xPos(newXPos * owner_.halfWidth());
157  notifyRoom();
158  }
159  else if (globWarningFlag)
160  post("source exceeds room");
161 }
162 
163 void Source::yPosRel(double newYPos)
164 {
165  if (newYPos < 1 && newYPos > -1)
166  {
167  yPos(newYPos * owner_.halfDepth());
168  notifyRoom();
169  }
170  else if (globWarningFlag)
171  post("source exceeds room");
172 }
173 
174 void Source::zPosRel(double newZPos)
175 {
176  if (newZPos < 1 && newZPos > -1)
177  {
178  zPos(newZPos * owner_.halfHeight());
179  notifyRoom();
180  }
181  else if (globWarningFlag)
182  post("source exceeds room");
183 }
184 
185 // let Room know that this source has changed
186 void Source::notifyRoom()
187 {
188  owner_.sourceChanged();
189 }
190 
191 
193 {
194  return directivityFlag_;
195 }
196 
197 void Source::directivityFlag(bool newFlag)
198 {
199  directivityFlag_ = newFlag;
200  this->flag(true);
201 }
202 
203 // vim:sw=4:et:cindent:
void updateDirectivity(long **tbl)
Set directivity table to values obtained from the Max patch.
Definition: Source.cpp:40
long aziAngle() const
Get azimuth angle.
Definition: Source.cpp:109
bool directivityFlag() const
True if the source's directivity is to be taken into account, false otherwise.
Definition: Source.cpp:192
virtual void printPos() const
Post xyz position.
Definition: Source.cpp:114
void sourceChanged()
Allows source to notify mirror that it has changed.
Definition: Room.cpp:128
double xPos() const
Get x position.
Definition: Moveable.cpp:26
double halfWidth() const
Get half width.
Definition: Room.cpp:194
void yPosAbs(double yPos)
Set y position in meters.
Definition: Source.cpp:130
Source(Room &room, Mirror *mirrors)
Class constructor, taking the Room to which the source belongs, as well as a pointer to the acoustic ...
Definition: Source.cpp:26
bool flag() const
True if object has moved.
Definition: Moveable.cpp:65
double directivityAt(long angle) const
Retrieve directivity gain for a given angle.
Definition: Source.cpp:53
void xPosAbs(double xPos)
Set x position in meters.
Definition: Source.cpp:119
double zPos() const
Get z position.
Definition: Moveable.cpp:52
void yPosRel(double yPos)
Set y position relative to room depth (0.0 to 1.0).
Definition: Source.cpp:163
double halfDepth() const
Get half depth.
Definition: Room.cpp:199
Moveable class.
Definition: Moveable.h:18
void aziAngle(long angle)
Set azimuth angle.
Definition: Mirror.cpp:46
void zPosRel(double zPos)
Set z position relative to room height (0.0 to 1.0).
Definition: Source.cpp:174
Sound mirror class.
Definition: Mirror.h:19
double yPos() const
Get y position.
Definition: Moveable.cpp:39
double halfHeight() const
Get half height.
Definition: Room.cpp:204
void zPosAbs(double zPos)
Set z position in meters.
Definition: Source.cpp:141
Room class.
Definition: Room.h:25
void xPosRel(double xPos)
Set x position relative to room width (0.0 to 1.0).
Definition: Source.cpp:152