+void
+AmbientSound::update(float deltat)
+{
+ if (latency-- <= 0) {
+ float px,py;
+ float rx,ry;
+
+ if (!Sector::current() || !Sector::current()->camera) return;
+ // Camera position
+ px=Sector::current()->camera->get_center().x;
+ py=Sector::current()->camera->get_center().y;
+
+ // Relate to which point in the area
+ rx=px<position.x?position.x:
+ (px<position.x+dimension.x?px:position.x+dimension.x);
+ ry=py<position.y?position.y:
+ (py<position.y+dimension.y?py:position.y+dimension.y);
+
+ // calculate square of distance
+ float sqrdistance=(px-rx)*(px-rx)+(py-ry)*(py-ry);
+ sqrdistance-=distance_bias;
+
+ // inside the bias: full volume (distance 0)
+ if (sqrdistance<0)
+ sqrdistance=0;
+
+ // calculate target volume - will never become 0
+ targetvolume=1/(1+sqrdistance*distance_factor);
+ float rise=targetvolume/currentvolume;
+
+ // rise/fall half life?
+ currentvolume*=pow(rise,deltat*10);
+ currentvolume += 1e-6f; // volume is at least 1e-6 (0 would never rise)
+
+ if (sound_source != 0) {
+
+ // set the volume
+ sound_source->set_gain(currentvolume*maximumvolume);
+
+ if (sqrdistance>=silence_distance && currentvolume<1e-3)
+ stop_playing();
+ latency=0;
+ } else {
+ if (sqrdistance<silence_distance) {
+ start_playing();
+ latency=0;
+ }
+ else // set a reasonable latency
+ latency=(int)(0.001/distance_factor);
+ //(int)(10*((sqrdistance-silence_distance)/silence_distance));
+ }
+ }
+
+ // heuristically measured "good" latency maximum
+
+ // if (latency>0.001/distance_factor)
+ // latency=
+}