Ahoy, I finally tested my attempt. I'm slightly less than convinced that it works exactly as it should.
Ignore the pitch-related things in here, unless I put them somewhere obviously wrong.
Specifically, the volume seems to be the most non-working.
const double PI=3.14159265358979323846264;
void position_sound_3d(sound@ snd, vector listener_position, double theta, vector sound_position, double pan_step=1.0, double volume_step=1.0, double pitch_step=5.0, double behind_pitch_decrease=0.5, double behind_volume_decrease=5.0, double pitch_range=25) {
// We need distances:
double xd=listener_position.x-sound_position.x;
double yd=listener_position.y-sound_position.y;
double zd=listener_position.z-sound_position.z;
// double d=square_root((xd*xd)+(yd*yd)); // Ignores vertical for now.
vector v(xd, yd, zd); double d=v.length();
// Could just be the length of a vector...
double atheta; double rtheta;
if((xd==0)&&(yd==0)) atheta=-1;
if(xd>0) atheta=arc_tangent(yd/xd);
if(xd<0) atheta=arc_tangent(yd/xd)+PI;
atheta = (atheta * (180 / PI));
rtheta=atheta-theta;
double pan=cosine(rtheta*PI/180);
pan*=100.0*pan_step;
double volume=sine(rtheta*PI/180);
double tempvolume=-absolute((d*-100)/volume_step); //?
double pitch=100.0;
if(volume>0) {tempvolume-=behind_volume_decrease; pitch-=behind_pitch_decrease;}
// pitch_step indicates the maximum absolute value of pitch variation. So we multiply that by the vertical angle.
double phi=(
(d!=0) ? arc_tangent(zd/d) : (zd!=0) ? PI/2.0*absolute(zd)/zd : 0 ); // Prease?
double temppitch=-pitch_step*sine(phi);
if(temppitch<0) temppitch=math_max(temppitch, -pitch_range);
else temppitch=math_min(temppitch, pitch_range);
pitch +=temppitch;
snd.pan=pan; snd.volume=tempvolume; snd.pitch=pitch;
}// Position_sound_3d.
Is there anything wrong in there?
"If you want utopia but reality gives you Lovecraft, you don't give up, you carve your utopia out of the corpses of dead gods."
MaxAngor wrote:
George... Don't do that.