1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2012 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdsound_lowlevel.h"
22 #include "nel/sound/driver/source.h"
24 using namespace NLMISC
;
29 // common method used only with OptionManualRolloff. return the volume in 1/100th DB ( = mB) modified
30 sint32
ISource::computeManualRollOff(sint32 volumeMB
, sint32 mbMin
, sint32 mbMax
, double alpha
, float sqrdist
, float distMin
, float distMax
)
32 if (sqrdist
< distMin
* distMin
)
37 else if (sqrdist
> distMax
* distMax
)
44 double dist
= (double) sqrt(sqrdist
);
46 // linearly descending volume on a dB scale
47 double db1
= mbMin
* (dist
- distMin
) / (distMax
- distMin
);
50 volumeMB
+= (sint32
) db1
;
52 } else if (alpha
> 0.0) {
53 double amp2
= 0.0001 + 0.9999 * (distMax
- dist
) / (distMax
- distMin
); // linear amp between 0.00001 and 1.0
54 double db2
= 2000.0 * log10(amp2
); // convert to 1/100th decibels
55 volumeMB
+= (sint32
) ((1.0 - alpha
) * db1
+ alpha
* db2
);
57 } else if (alpha
< 0.0) {
58 double amp3
= distMin
/ dist
; // linear amplitude is 1/distance
59 double db3
= 2000.0 * log10(amp3
); // convert to 1/100th decibels
60 volumeMB
+= (sint32
) ((1.0 + alpha
) * db1
- alpha
* db3
);
63 clamp(volumeMB
, mbMin
, mbMax
);
68 // common method used only with OptionManualRolloff. return the rolloff in amplitude ratio (gain)
69 float ISource::computeManualRolloff(double alpha
, float sqrdist
, float distMin
, float distMax
)
71 /*static const sint mbMin = -10000;
72 static const sint mbMax = 0;
73 sint32 rolloffMb = ISource::computeManualRollOff(mbMax, mbMin, mbMax, alpha, sqrdist, distMin, distMax);
74 float rolloffGain = (float)pow(10.0, (double)rolloffMb / 2000.0);
75 clamp(rolloffGain, 0.0f, 1.0f);
78 static const double mbMin
= -10000;
79 static const double mbMax
= 0;
81 if (sqrdist
< distMin
* distMin
)
90 double dist
= (double)sqrt(sqrdist
);
91 // inverse distance rolloff
92 float rolloff
= distMin
/ dist
;
93 if (alpha
<= -1.0f
) return rolloff
;
97 // full attenuation of mbrolloff
98 return (-alpha
* rolloff
);
102 double mb
= mbMin
* (dist
- distMin
) / (distMax
- distMin
);
103 float mbrolloff
= (float)pow(10.0, (double)mb
/ 2000.0);
104 return ((1.0 + alpha
) * mbrolloff
- alpha
* rolloff
);
109 if (sqrdist
> distMax
* distMax
)
114 double dist
= (double)sqrt(sqrdist
);
117 // linearly descending volume on a dB scale
118 double mb
= mbMin
* (dist
- distMin
) / (distMax
- distMin
);
119 return (float)pow(10.0, (double)mb
/ 2000.0);
121 else // if (alpha > 0.0f)
123 // linear distance rolloff
124 float rolloff
= (distMax
- dist
) / (distMax
- distMin
);
125 if (alpha
>= 1.0f
) return rolloff
;
127 double mb
= mbMin
* (dist
- distMin
) / (distMax
- distMin
);
128 float mbrolloff
= (float)pow(10.0, (double)mb
/ 2000.0);
129 return ((1.0 - alpha
) * mbrolloff
+ alpha
* rolloff
);