VolCtrl.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include "VolCtrl.h"
  2. #include <cmath>
  3. static double lin2log_vol(double v)
  4. {
  5. return v>0 ? 20.0*log10(v) : -100.0;
  6. }
  7. static double log2lin_vol(double v)
  8. {
  9. return v<=-100.0 ? 0 : pow(10.0,v/20.0);
  10. }
  11. static double lin2log_pan(double p)
  12. {
  13. if (p==0) return 0;
  14. else return lin2log_vol(1.0-fabs(p)) * (p>0 ? -1 : 1);
  15. }
  16. static double log2lin_pan(double p)
  17. {
  18. if (p==0) return 0;
  19. else return (1.0-log2lin_vol(-fabs(p))) * (p>0 ? 1 :-1);
  20. }
  21. void DsVolCtrl::MapVol(double Vol,double Pan,double &OutNewVol,double &OutNewPan)
  22. {
  23. DestVolHack=Vol;
  24. DestPanHack=Pan;
  25. double NewVol = 0.0;
  26. double NewPan = 0.0;
  27. switch(VolMode)
  28. {
  29. case 0:
  30. NewVol=lin2log_vol(Vol);
  31. NewPan=lin2log_pan(Pan);
  32. NewVol=Vol>0 ? 20*log10(Vol) : -100.0;//in negative db
  33. if (Pan==0) NewPan=0;
  34. else
  35. {
  36. double d= 1.0 - fabs(Pan);
  37. d = d>0 ? 20*log10(d) : -1000.0;
  38. if (Pan>0) d=-d;
  39. NewPan=d;
  40. }
  41. break;
  42. case 1:
  43. {
  44. double left,right;
  45. NewVol=left=right=(double)LogVolMin * (Vol-1.0);
  46. left+=lin2log_vol(sqrt(0.5-0.5*Pan));
  47. right+=lin2log_vol(sqrt(0.5+0.5*Pan));
  48. //NewVol=left>right ? left : right;
  49. NewPan=right-left;
  50. }
  51. break;
  52. case 2:
  53. {
  54. double left,right;
  55. NewVol=left=right=100.0 * (pow(Vol,0.25)-1.0);
  56. left+=lin2log_vol(sqrt(0.5-0.5*Pan));
  57. right+=lin2log_vol(sqrt(0.5+0.5*Pan));
  58. //NewVol=left>right ? left : right;
  59. NewPan=right-left;
  60. }
  61. break;
  62. }
  63. if (NewVol<-100.0) NewVol=-100.0;
  64. else if (NewVol>0) NewVol=0;
  65. if (NewPan<-100.0) NewPan=-100.0;
  66. else if (NewPan>100.0) NewPan=100.0;
  67. OutNewVol=NewVol;
  68. OutNewPan=NewPan;
  69. }
  70. DsVolCtrl::DsVolCtrl(int _VolMode,double _LogVolMin,bool _LogFades)
  71. {
  72. IsFading=0;
  73. LogFades=_LogFades;
  74. VolMode=_VolMode;
  75. LogVolMin=_LogVolMin;
  76. FadeSrcTime=FadeDstTime=-1;
  77. CurTime=0;
  78. CurVol=1;
  79. LastVol=0;
  80. CurPan=0;
  81. LastPan=0;
  82. DestPanHack = 0;
  83. DestVolHack = 0;
  84. FadeDstPan = 0;
  85. FadeDstVol = 0;
  86. FadeSrcPan = 0;
  87. FadeSrcVol = 0;
  88. }
  89. void DsVolCtrl::SetFade(__int64 duration,double destvol,double destpan)
  90. {
  91. FadeSrcTime=CurTime;
  92. FadeDstTime=CurTime+duration;
  93. FadeSrcVol=CurVol;
  94. FadeSrcPan=CurPan;
  95. IsFading=1;
  96. MapVol(destvol,destpan,FadeDstVol,FadeDstPan);
  97. }
  98. void DsVolCtrl::SetTime(__int64 time)
  99. {
  100. CurTime=time;
  101. }
  102. void DsVolCtrl::SetVolume(double vol)
  103. {
  104. if (Fading()) SetFade(FadeDstTime-CurTime,vol,DestPanHack);
  105. else MapVol(vol,DestPanHack,CurVol,CurPan);
  106. }
  107. void DsVolCtrl::SetPan(double pan)
  108. {
  109. if (Fading()) SetFade(FadeDstTime-CurTime,DestVolHack,pan);
  110. else MapVol(DestVolHack,pan,CurVol,CurPan);
  111. }
  112. void DsVolCtrl::Apply(IDirectSoundBuffer * pDSB)
  113. {
  114. if (Fading())
  115. {
  116. if (LogFades)
  117. {
  118. CurVol= FadeSrcVol + (FadeDstVol-FadeSrcVol) * (double)(CurTime-FadeSrcTime) / (double)(FadeDstTime-FadeSrcTime);
  119. CurPan= FadeSrcPan + (FadeDstPan-FadeSrcPan) * (double)(CurTime-FadeSrcTime) / (double)(FadeDstTime-FadeSrcTime);
  120. }
  121. else
  122. {
  123. double SrcVol=log2lin_vol(FadeSrcVol);
  124. double DstVol=log2lin_vol(FadeDstVol);
  125. double SrcPan=log2lin_pan(FadeSrcPan);
  126. double DstPan=log2lin_pan(FadeDstPan);
  127. CurVol=lin2log_vol( SrcVol + (DstVol-SrcVol) * (double)(CurTime-FadeSrcTime) / (double)(FadeDstTime-FadeSrcTime) );
  128. CurPan=lin2log_pan( SrcPan + (DstPan-SrcPan) * (double)(CurTime-FadeSrcTime) / (double)(FadeDstTime-FadeSrcTime) );
  129. }
  130. }
  131. else if (FadeDstTime>=0)
  132. {
  133. CurVol=FadeDstVol;
  134. CurPan=FadeDstPan;
  135. FadeDstTime=-1;
  136. IsFading=0;
  137. }
  138. if (CurVol!=LastVol)
  139. {
  140. LastVol=CurVol;
  141. pDSB->SetVolume((long)(CurVol*100.0));
  142. }
  143. if (CurPan!=LastPan)
  144. {
  145. LastPan=CurPan;
  146. pDSB->SetPan((long)(CurPan*100.0));
  147. }
  148. }
  149. bool DsVolCtrl::Fading()
  150. {
  151. return IsFading && CurTime<FadeDstTime;
  152. }
  153. __int64 DsVolCtrl::RelFade(__int64 max,double destvol)
  154. {
  155. return (__int64)(fabs(destvol-DestVolHack)*(double)max);
  156. }
  157. double DsVolCtrl::Stat_GetVolLeft()
  158. {
  159. return CurPan<0 ? CurVol : CurVol - CurPan;
  160. }
  161. double DsVolCtrl::Stat_GetVolRight()
  162. {
  163. return CurPan>0 ? CurVol : CurVol + CurPan;
  164. }