Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1181 lines
34 KiB

  1. /***********************************************************
  2. Copyrights : ksWaves Ltd. 1998.
  3. Provided to Microsoft under contract between ksWaves and Microsoft.
  4. ************************************************************/
  5. /***********************************************************
  6. General description :
  7. The functions in this file provides for any apoplication to process audio data
  8. with the SVerb algorithm.
  9. In order to do so the application should :
  10. 1. Allocate two chunks of memory for 'Coefs' and 'States' with sizes as returned
  11. by the functions 'GetCoefsSize' and 'GetStatesSize' accordingly.
  12. 2. Initialize these memory chunks using the functions : 'InitSVerb' and 'InitSVerbStates'
  13. accordingly.
  14. 3. Change the settings of the SVerb sound using the function 'SetSVerb'.
  15. 4. Call one of the process functions according to the input/output data format:
  16. SVerbMonoToMonoShort
  17. SVerbMonoToStereoShort
  18. SVerbStereoToStereoShort
  19. SVerbMonoToMonoFloat
  20. SVerbMonoToStereoFloat
  21. SVerbStereoToStereoFloat
  22. The input/output are always the same data type (i.e. both input and output are short integer
  23. or both are 32bits floats).
  24. Stereo data format is always'interlaced' left,right samples.
  25. The 'coefs' and 'states' memory should be passed to the process functions.
  26. 5. Many coefs structures can be initialized each for different SVerb settings. Passing a different
  27. coefs structure will cause a real time change of sound quality.
  28. As long as sound continuity should be maintained the states structure should not be changes or
  29. re-initialized. Only when a completly new audio sequence is desired should the states be re-initialized.
  30. 6. Note that the coefs are valid per sampling rate.
  31. 7. Althaugh provisions for coefs compatibility for future versions are provided, it should be avoided to save coefs
  32. structures to files as-is and re-use them later. Rather the application should save the 'real-world'
  33. settings of the reverb - namely the parameters passed to 'SetSVerb'. These 'real-world' settings
  34. will always be valid for future versions, as well as if other sampling rates are used. The coefs
  35. structur(es) should be re-initialized in run time using the real-world settings and call to
  36. 'SetSverb'.
  37. ************************************************************/
  38. #include <windows.h>
  39. #include <String.h>
  40. #include <math.h>
  41. #include "SVerb.h"
  42. #pragma optimize( "ty", on )
  43. /****************************************************************************
  44. Function Name : GetCoefsSize
  45. Input Arguments : None
  46. Return Value : The size of memory in bytes, to be allocated in order to hold coefficients.
  47. Description :
  48. This function must be called before any calls to other functions that uses the coefs structure.
  49. The calling app must than allocate the returned size of memory and initialize it using 'InitSVerb()'
  50. and 'SetSVerb()'.
  51. The caller should not be botherred by the internals of the coefs structure, rather only konw it's size
  52. and than allocate enough memory to hold it.
  53. The structure allocated can be used in a very flexible way in order to allow for real-time, pre-computed
  54. changes in Reverb Sound.
  55. *****************************************************************************/
  56. long GetCoefsSize(void)
  57. {
  58. return sizeof(sCoefsStruct);
  59. };
  60. /****************************************************************************
  61. Function Name : GetStatesSize
  62. Input Arguments : None
  63. Return Value : The size of memory in bytes, to be allocated in order to hold states.
  64. Description :
  65. This function must be called before any calls to other functions that uses the states structure.
  66. The calling app must than allocate the returned size of memory and initialize it using 'InitSVerbStates()'.
  67. The states allocated are valid in run-time only, and sould be re-initialized only when a complete
  68. new input is to be processed by the SVerb.
  69. When changing the settings of revevreb in real time while audio is playing, the states should not
  70. be re-initialized, rather the same passed states must be passed to the process functions in order
  71. to maintain sound continuity.
  72. *****************************************************************************/
  73. long GetStatesSize(void)
  74. {
  75. return sizeof(long)*(BASE_REV_DELAY+2*BASE_DSPS_DELAY+2);
  76. };
  77. /****************************************************************************
  78. Function Name : GetSVerbVersion
  79. Input Arguments : None
  80. Return Value : Version of SVerb implementation - for future compatibility.
  81. Description :
  82. Since the caller do not know about the internals of the coefs structure, this function,
  83. together with 'VerifyVersion' function provides a way to verify if a coefs structure
  84. match the version of the reverb used.
  85. This should be needed only if one is using a coefs structure that was saved to file, and
  86. being used later.
  87. NOTE : In normal operation, this way of usage should be avoided... and only real-world reverb
  88. settings should be saved to files, and re-initialize the coefs in run time.
  89. *****************************************************************************/
  90. long GetSVerbVersion(void)
  91. {
  92. return 0x1;
  93. };
  94. /****************************************************************************
  95. Function Name : VerifySampleRate
  96. Input Arguments :
  97. void *pC : The pointer to the coefs memory.
  98. Return Value : The sample rate for which this coefs are valid.
  99. Description :
  100. When an application uses different sampling rates, and re-uses same coefs structures,
  101. it should verify that the coefs match the audio sampling rate.
  102. *****************************************************************************/
  103. float VerifySampleRate(void *pC) {
  104. return ((sCoefsStruct *)pC)->SampleRate;
  105. };
  106. /****************************************************************************
  107. Function Name : VerifyVersion
  108. Input Arguments :
  109. void *pC : The pointer to the coefs memory.
  110. Return Value : The version of this coefs structure.
  111. Description :
  112. When initialized, each coefs structure is 'stamped' with it's version.
  113. The location of this variable in the structure is fixed, and thus all future versions of
  114. SVerb will know to read it.
  115. Note : as explained above, in normal uses coefs should not be saved to files, rather the
  116. 'real-world' settings should be saved and coefs re-initialized in run-time.
  117. *****************************************************************************/
  118. long VerifyVersion(void *pC) {
  119. return ((sCoefsStruct *)pC)->myVersion;
  120. };
  121. /****************************************************************************
  122. Function Name : VerifySize
  123. Input Arguments :
  124. void *pC : The pointer to the coefs memory.
  125. Return Value : The size of this coefs structure.
  126. Description :
  127. When initialized, each coefs structure is 'stamped' with it's size.
  128. The location of this variable in the structure is fixed, and thus all future versions of
  129. SVerb will know to read it.
  130. Note : as explained above, in normal uses coefs should not be saved to files, rather the
  131. 'real-world' settings should be saved and coefs re-initialized in run-time.
  132. *****************************************************************************/
  133. long VerifySize(void *pC) {
  134. return ((sCoefsStruct *)pC)->mySize;
  135. };
  136. /****************************************************************************
  137. Function Name : InitSVerbStates
  138. Input Arguments :
  139. float *pStates : The pointer to the states memory.
  140. Return Value : none.
  141. Description :
  142. After allocating memory for the states, according to thge size returned by 'GetStatesSize'
  143. The application MUST initialize the states using this function.
  144. Note : in future versions this may be more complex than simply memset to 0...
  145. *****************************************************************************/
  146. void InitSVerbStates( long *pStates )
  147. {
  148. memset( pStates, 0, GetStatesSize() ) ;
  149. }
  150. /****************************************************************************
  151. Function Name : DToF16
  152. Input Arguments :
  153. float SampleRate : The sampling rate.
  154. void *pC : The pointer to the coefs memory.
  155. Return Value : none.
  156. Description :
  157. Converts a float number between -1.0 .. 1.0 to a 16bits integer
  158. fixed point representation.
  159. This allows for fix point arithmetics, where two 16bits integers are multiplied to
  160. a 32bits integer, and we than take the upper 16 bits of the result.
  161. *****************************************************************************/
  162. long DToF16( float dbl )
  163. {
  164. dbl *= MAX_16;
  165. dbl = max(-MAX_16,min(MAX_16-(float)1.0,dbl+(float)0.5));
  166. return (long)(dbl);
  167. }
  168. /****************************************************************************
  169. Function Name : ConvertCoefsToFix
  170. Input Arguments :
  171. void *pC : The pointer to the coefs memory.
  172. Return Value : none.
  173. Description : converts coefficients to longs, as fixed point numbers
  174. *****************************************************************************/
  175. void ConvertCoefsToFix( void *pC )
  176. {
  177. sCoefsStruct *pCoefs = ((sCoefsStruct *)pC);
  178. // float directGain;
  179. pCoefs->l_directGain = DToF16(pCoefs->directGain);
  180. // float revGain;
  181. pCoefs->l_revGain = DToF16(pCoefs->revGain);
  182. // float dDsps;
  183. pCoefs->l_dDsps = DToF16(pCoefs->dDsps);
  184. // float dDG1;
  185. pCoefs->l_dDG1 = DToF16(pCoefs->dDG1);
  186. // float dDG2;
  187. pCoefs->l_dDG2 = DToF16(pCoefs->dDG2);
  188. // float dFB11;
  189. pCoefs->l_dFB11 = DToF16(pCoefs->dFB11);
  190. // float dFB12;
  191. pCoefs->l_dFB12 = DToF16(pCoefs->dFB12);
  192. // float dFB21;
  193. pCoefs->l_dFB21 = DToF16(pCoefs->dFB21);
  194. // float dFB22;
  195. pCoefs->l_dFB22 = DToF16(pCoefs->dFB22);
  196. // float dFB31;
  197. pCoefs->l_dFB31 = DToF16(pCoefs->dFB31);
  198. // float dFB32;
  199. pCoefs->l_dFB32 = DToF16(pCoefs->dFB32);
  200. // float dFB41;
  201. pCoefs->l_dFB41 = DToF16(pCoefs->dFB41);
  202. // float dFB42;
  203. pCoefs->l_dFB42 = DToF16(pCoefs->dFB42);
  204. // float dDamp;
  205. pCoefs->l_dDamp = DToF16(pCoefs->dDamp);
  206. }
  207. /****************************************************************************
  208. Function Name : InitSVerb
  209. Input Arguments :
  210. float SampleRate : The sampling rate.
  211. void *pC : The pointer to the coefs memory.
  212. Return Value : none.
  213. Description :
  214. After allocating memory for the coefs, according to thge size returned by 'GetCoefsSize'
  215. The application MUST initialize the coefs using this function.
  216. The initialization takes the sampling rate as an argument, ans thus is valid per this
  217. sampling rate only.
  218. It is possible to find out what is the sampling rate a coefs structure is valid for by calling
  219. the function 'VerifySampleRate'.
  220. This function initialises the SVerb to so reasonable default setting by calling 'SetSVerb' with
  221. the following real-world settings :
  222. InGain = -3.0dB (to avoid output overflows)
  223. dRevMix = -6.0dB (a reasonable reverb mix)
  224. dRevTime = 1000.0ms (one second global reverb time)
  225. dHighFreqRTRatio = 0.001 (the ratio of the high frequencies to the global reverb time)
  226. *****************************************************************************/
  227. void InitSVerb( float SampleRate, void *pC)
  228. {
  229. sCoefsStruct *pCoefs = ((sCoefsStruct *)pC);
  230. //Magic numbers ...
  231. long lRefD;
  232. float dRatio = (float)1.189207115003;
  233. float dD2MRatio = (float)0.2309333333;
  234. pCoefs->mySize = sizeof(sCoefsStruct);
  235. pCoefs->myVersion = 0x1;
  236. pCoefs->dDsps = (float)0.6180339887499;
  237. pCoefs->SampleRate = SampleRate;
  238. lRefD = (long)( 0.5 + 0.045 * pCoefs->SampleRate ) ;
  239. pCoefs->lDelay1 = lRefD;
  240. pCoefs->lDelay3 = (long)(0.5 + dRatio * (float)pCoefs->lDelay1);
  241. pCoefs->lDelay2 = (long)(0.5 + dRatio * (float)pCoefs->lDelay3);
  242. pCoefs->lDelay4 = (long)(0.5 + dRatio * (float)pCoefs->lDelay2);
  243. pCoefs->lDDly1 = (long)(0.5 + 0.5 * dD2MRatio * (float)(pCoefs->lDelay1+pCoefs->lDelay2));
  244. pCoefs->lDDly2 = (long)(0.5 + 0.5 * dD2MRatio * (float)(pCoefs->lDelay3+pCoefs->lDelay4));
  245. pCoefs->lDelay1 -= pCoefs->lDDly1 ;
  246. pCoefs->lDelay2 -= pCoefs->lDDly1 ;
  247. pCoefs->lDelay3 -= pCoefs->lDDly2 ;
  248. pCoefs->lDelay4 -= pCoefs->lDDly2 ;
  249. pCoefs->lDelay1 <<= 2;
  250. pCoefs->lDelay2 <<= 2;
  251. pCoefs->lDelay3 <<= 2;
  252. pCoefs->lDelay4 <<= 2;
  253. pCoefs->lDDly1 <<= 1;
  254. pCoefs->lDDly2 <<= 1;
  255. SetSVerb( (float)0.0, (float)-10.0, (float)1000.0, (float)0.001, pC );
  256. }
  257. /****************************************************************************
  258. Function Name : SetSVerb
  259. Input Arguments :
  260. InGain : input gain in dB (to avoid output overflows)
  261. dRevMix : Reverb mix in dB. 0dB means 100% wet reverb (no direct signal)
  262. Negative values gives less wet signal.
  263. The coeficients are calculated so that the overall output level stays
  264. (approximately) constant regardless of the ammount of reverb mix.
  265. dRevTime : The global reverb time (decay time) in milliseconds.
  266. dHighFreqRTRatio : The ratio of the high frequencies to the global reverb time.
  267. Unless very 'splashy-bright' reverbs are wanted, this should be set to
  268. a value < 1.0.
  269. For example if dRevTime==1000ms and dHighFreqRTRatio=0.1 than the
  270. decay time for high frequencies will be 100ms.
  271. void *pC : The pointer to the coefs memory.
  272. Return Value : none.
  273. Description :
  274. This function accepts the 'real world' settings or SVerb and computes the corresponding
  275. coefs structure.
  276. The coefs pointer passed to it MUST have been initialized first by InitSVerb.
  277. In normal uses one coefs structure is allocated, initialized, and than as the user changes
  278. SVerb settings this function should be called repeatedly with the same coefs pointer and the
  279. new 'real world' settings.
  280. And the coefs structure passed to the process function in the next buffer to process.
  281. Also few coefs structures can be pre allocated, and initialized, and than different 'presets'
  282. can be pre-computed into each of them, and switched in real time.
  283. The coefs structures should not be saved to files by the application for future uses, rather
  284. the 'real world' settings them selvs. This way future compatibility is guaranteed.
  285. *****************************************************************************/
  286. void SetSVerb( float InGain, float dRevMix,
  287. float dRevTime, float dHighFreqRTRatio, void *pC )
  288. {
  289. sCoefsStruct *pCoefs = ((sCoefsStruct *)pC);
  290. float dD,dTmp,dInGain,dRevGain;
  291. float dHfR;
  292. float dAPS;
  293. if (dHighFreqRTRatio > (float) 0.999)
  294. {
  295. dHighFreqRTRatio = (float) 0.999;
  296. }
  297. if (dHighFreqRTRatio <= (float) 0.0)
  298. {
  299. dHighFreqRTRatio = (float) 0.001;
  300. }
  301. dHfR = ( (float)1.0/dHighFreqRTRatio - (float)1.0);
  302. if (dRevTime < (float) 0.001)
  303. {
  304. dRevTime = (float) 0.001;
  305. }
  306. if (InGain > (float) 0.0)
  307. {
  308. InGain = (float) 0.0;
  309. }
  310. if (dRevMix > (float) 0.0)
  311. {
  312. dRevMix = (float) 0.0;
  313. }
  314. if (pCoefs->SampleRate < (float) 1.0)
  315. {
  316. pCoefs->SampleRate = (float) 22050.0;
  317. }
  318. dAPS = (float)(-3000.0) / (pCoefs->SampleRate * dRevTime);
  319. pCoefs->dDamp = 0.0;
  320. pCoefs->dDG1 = (float)pow((float)10.0,(float)(pCoefs->lDDly1>>1)*dAPS);
  321. pCoefs->dDG2 = (float)pow((float)10.0,(float)(pCoefs->lDDly2>>1)*dAPS);
  322. //////////////////////////////
  323. pCoefs->dFB11 = (float)pow((float)10.0,(float)(pCoefs->lDelay1>>2)*dAPS);
  324. dD = pCoefs->dFB11 * pCoefs->dDG1;
  325. dD = (float)1.0+dD*((float)1.0+dD*((float)1.0+dD*((float)1.0 + dD)));
  326. pCoefs->dDamp += dD *dD;
  327. dTmp = (float)pow((float)10.0,(float)((pCoefs->lDDly1>>1)+(pCoefs->lDelay1>>2))*dAPS*dHfR);
  328. dTmp = ((float)1.0 - dTmp)*(float)0.5;
  329. pCoefs->dFB12 = pCoefs->dFB11 * dTmp;
  330. pCoefs->dFB11 *= ((float)1.0-dTmp);
  331. ///////////////////////////////
  332. pCoefs->dFB21 = (float)pow((float)10.0,(float)(pCoefs->lDelay2>>2)*dAPS);
  333. dD = pCoefs->dFB21 * pCoefs->dDG1;
  334. dD = (float)1.0+dD*((float)1.0+dD*((float)1.0+dD*((float)1.0 + dD)));
  335. pCoefs->dDamp += dD *dD;
  336. dTmp = (float)pow((float)10.0,(float)((pCoefs->lDDly1>>1)+(pCoefs->lDelay2>>2))*dAPS*dHfR);
  337. dTmp = ((float)1.0 - dTmp)*(float)0.5;
  338. pCoefs->dFB22 = pCoefs->dFB21 * dTmp;
  339. pCoefs->dFB21 *= ((float)1.0-dTmp);
  340. ////////////////////////////////
  341. pCoefs->dFB31 = (float)pow((float)10.0,(float)(pCoefs->lDelay3>>2)*dAPS);
  342. dD = pCoefs->dFB31 * pCoefs->dDG2;
  343. dD = (float)1.0+dD*((float)1.0+dD*((float)1.0+dD*((float)1.0 + dD)));
  344. pCoefs->dDamp += dD *dD;
  345. dTmp = (float)pow((float)10.0,(float)((pCoefs->lDDly2>>1)+(pCoefs->lDelay3>>2))*dAPS*dHfR);
  346. dTmp = ((float)1.0 - dTmp)*(float)0.5;
  347. pCoefs->dFB32 = pCoefs->dFB31 * dTmp;
  348. pCoefs->dFB31 *= ((float)1.0-dTmp);
  349. //////////////////////////////
  350. pCoefs->dFB41 = (float)pow((float)10.0,(float)(pCoefs->lDelay4>>2)*dAPS);
  351. dD = pCoefs->dFB41 * pCoefs->dDG2;
  352. dD = (float)1.0+dD*((float)1.0+dD*((float)1.0+dD*((float)1.0 + dD)));
  353. pCoefs->dDamp += dD *dD;
  354. dTmp = (float)pow((float)10.0,(float)((pCoefs->lDDly2>>1)+(pCoefs->lDelay4>>2))*dAPS*dHfR);
  355. dTmp = ((float)1.0 - dTmp)*(float)0.5;
  356. pCoefs->dFB42 = pCoefs->dFB41 * dTmp;
  357. pCoefs->dFB41 *= ((float)1.0-dTmp);
  358. pCoefs->dDamp = (float)sqrt(pCoefs->dDamp);
  359. dInGain = (float)pow((float)10.0, (float)0.05*InGain ) ;
  360. dRevMix = (float)pow((float)10.0,(float)0.1*dRevMix);
  361. dRevGain = (float)4.0 / pCoefs->dDamp * dInGain;
  362. //in the DSP we used -
  363. pCoefs->directGain = dInGain * (float)sqrt((float)1.0-dRevMix);
  364. pCoefs->revGain = dRevGain * (float)sqrt(dRevMix);
  365. ConvertCoefsToFix( pC );
  366. }
  367. ///////////////////////////////////////////////////////////////////////////////////////
  368. /**************************************************************************************/
  369. /**************************************************************************************/
  370. /**************************************************************************************/
  371. /**************************************************************************************/
  372. /* Process functions */
  373. /**************************************************************************************/
  374. /**************************************************************************************/
  375. /**************************************************************************************/
  376. /**********************************************************************************
  377. Bellow are 6 different process functions.
  378. The difference between the functions is only in the input/output data formats.
  379. 3 functions support short samples input/output.
  380. 3 other functions support float samples input/output.
  381. Per each of the data types there are 3 functions :
  382. Mono-Mono
  383. Mono-Stereo
  384. Stereo-Stereo
  385. The names of the functions are clear to which format they apply.
  386. Stereo data is always interlaced left,right samples.
  387. All process functions have basically the same format namely :
  388. SVerbXXXXXX(long NumInFrames, short *pInShort, short *pOutShort,
  389. void *pC, float *pStates)
  390. Input arguments :
  391. long NumInFrames : Number of input frames
  392. short *pInXXX : Pointer to input buffer.
  393. Each function expects the data format suggested by it's name in terms of
  394. data type (short or float) and mono/stereo.
  395. short *pOutXXX : Pointer to output buffer.
  396. Each function expects the data format suggested by it's name in terms of
  397. data type (short or float) and mono/stereo.
  398. void *pC : The coefs structure allocated and initialized as explained above.
  399. float *pStates : The states structure allocated and initialized as explained above.
  400. *******************************************************************************************/
  401. void SVerbMonoToMonoShort(long NumInFrames, short *pInShort, short *pOutShort,
  402. void *pC, long *pStates)
  403. {
  404. sCoefsStruct *pCoefs = ((sCoefsStruct *)pC);
  405. long n_sample;
  406. long In1, In2, Out1, Out2;
  407. long Indx1,Indx2,Indx3,Indx4;
  408. long *pNewDll1, *pNewDll2, *pNewDll3, *pNewDll4;
  409. long *pPrevDll1, *pPrevDll2, *pPrevDll3, *pPrevDll4, *pDelayIn;
  410. long *pDelay = pStates+2;
  411. long *pDD1 = pDelay+0x4000;
  412. long *pDD2 = pDD1+0x800;
  413. long Indx = ((long *)pStates)[0];
  414. long DIndx = ((long *)pStates)[1] ;
  415. Indx1 = (Indx+4+pCoefs->lDelay1) & REV_MASK;
  416. Indx2 = (Indx+4+pCoefs->lDelay2) & REV_MASK;
  417. Indx3 = (Indx+4+pCoefs->lDelay3) & REV_MASK;
  418. Indx4 = (Indx+4+pCoefs->lDelay4) & REV_MASK;
  419. pPrevDll1 = pDelay+Indx1;
  420. pPrevDll2 = pDelay+Indx2+1;
  421. pPrevDll3 = pDelay+Indx3+2;
  422. pPrevDll4 = pDelay+Indx4+3;
  423. Indx1 = (Indx1-4)&REV_MASK;
  424. Indx2 = (Indx2-4)&REV_MASK;
  425. Indx3 = (Indx3-4)&REV_MASK;
  426. Indx4 = (Indx4-4)&REV_MASK;
  427. for (n_sample = 0;n_sample < NumInFrames;n_sample++)
  428. {
  429. In1 = In2 = (long)(*pInShort++)>>1;
  430. Out1 = (In1 * pCoefs->l_directGain)>>15;
  431. Out2 = (In2 * pCoefs->l_directGain)>>15;
  432. In1 = (In1 * pCoefs->l_revGain)>>15;
  433. In2 = (In2 * pCoefs->l_revGain)>>15;
  434. pNewDll1 = pDelay+Indx1;
  435. pNewDll2 = pDelay+Indx2+1;
  436. pNewDll3 = pDelay+Indx3+2;
  437. pNewDll4 = pDelay+Indx4+3;
  438. dspsL( pDD1, DIndx, pCoefs->lDDly1, pCoefs->l_dDG1, pCoefs->l_dDsps, pNewDll1, pNewDll2 );
  439. dspsL( pDD2, DIndx, pCoefs->lDDly2, pCoefs->l_dDG2, pCoefs->l_dDsps, pNewDll3, pNewDll4 );
  440. Out1 += *pNewDll1 + *pNewDll3;
  441. Out2 += *pNewDll2 + *pNewDll4;
  442. pDelayIn = pDelay + Indx;
  443. *pDelayIn++ = In1 + ((*pNewDll1*pCoefs->l_dFB11 + *pPrevDll1*pCoefs->l_dFB12)>>15);
  444. pPrevDll1 = pNewDll1;
  445. Indx1 = (Indx1 - 4) & REV_MASK;
  446. *pDelayIn++ = In2 + ((*pNewDll2*pCoefs->l_dFB21 + *pPrevDll2*pCoefs->l_dFB22)>>15);
  447. pPrevDll2 = pNewDll2;
  448. Indx2 = (Indx2 - 4) & REV_MASK;
  449. *pDelayIn++ = -In2 + ((*pNewDll3*pCoefs->l_dFB31 + *pPrevDll3*pCoefs->l_dFB32)>>15);
  450. pPrevDll3 = pNewDll3;
  451. Indx3 = (Indx3 - 4) & REV_MASK;
  452. *pDelayIn++ = In1 + ((*pNewDll4*pCoefs->l_dFB41 + *pPrevDll4*pCoefs->l_dFB42)>>15);
  453. pPrevDll4 = pNewDll4;
  454. Indx4 = (Indx4 - 4) & REV_MASK;
  455. Indx = (Indx - 4) & REV_MASK;
  456. DIndx = (DIndx - 2) & DSPS_MASK;
  457. Out1 += Out2;
  458. CLIP_SHORT_TO_SHORT(Out1)
  459. *pOutShort++ = (short)(Out1);
  460. }
  461. ((long *)pStates)[0] = Indx ;
  462. ((long *)pStates)[1] = DIndx ;
  463. }
  464. #ifdef USE_ALL_VERBS
  465. void SVerbMonoToStereoShort(long NumInFrames, short *pInShort, short *pOutShort,
  466. void *pC, long *pStates)
  467. {
  468. sCoefsStruct *pCoefs = ((sCoefsStruct *)pC);
  469. long n_sample;
  470. long In1, In2, Out1, Out2;
  471. long Indx1,Indx2,Indx3,Indx4;
  472. long *pNewDll1, *pNewDll2, *pNewDll3, *pNewDll4;
  473. long *pPrevDll1, *pPrevDll2, *pPrevDll3, *pPrevDll4, *pDelayIn;
  474. long *pDelay = pStates+2;
  475. long *pDD1 = pDelay+0x4000;
  476. long *pDD2 = pDD1+0x800;
  477. long Indx = ((long *)pStates)[0];
  478. long DIndx = ((long *)pStates)[1] ;
  479. Indx1 = (Indx+4+pCoefs->lDelay1) & REV_MASK;
  480. Indx2 = (Indx+4+pCoefs->lDelay2) & REV_MASK;
  481. Indx3 = (Indx+4+pCoefs->lDelay3) & REV_MASK;
  482. Indx4 = (Indx+4+pCoefs->lDelay4) & REV_MASK;
  483. pPrevDll1 = pDelay+Indx1;
  484. pPrevDll2 = pDelay+Indx2+1;
  485. pPrevDll3 = pDelay+Indx3+2;
  486. pPrevDll4 = pDelay+Indx4+3;
  487. Indx1 = (Indx1-4)&REV_MASK;
  488. Indx2 = (Indx2-4)&REV_MASK;
  489. Indx3 = (Indx3-4)&REV_MASK;
  490. Indx4 = (Indx4-4)&REV_MASK;
  491. for (n_sample = 0;n_sample < NumInFrames;n_sample++)
  492. {
  493. In1 = (long)(*pInShort++);
  494. In1 += (In1>>1) - (In1>>2);
  495. In2 = In1;
  496. Out1 = (In1 * pCoefs->l_directGain)>>15;
  497. Out2 = (In2 * pCoefs->l_directGain)>>15;
  498. In1 = (In1 * pCoefs->l_revGain)>>15;
  499. In2 = (In2 * pCoefs->l_revGain)>>15;
  500. pNewDll1 = pDelay+Indx1;
  501. pNewDll2 = pDelay+Indx2+1;
  502. pNewDll3 = pDelay+Indx3+2;
  503. pNewDll4 = pDelay+Indx4+3;
  504. dspsL( pDD1, DIndx, pCoefs->lDDly1, pCoefs->l_dDG1, pCoefs->l_dDsps, pNewDll1, pNewDll2 );
  505. dspsL( pDD2, DIndx, pCoefs->lDDly2, pCoefs->l_dDG2, pCoefs->l_dDsps, pNewDll3, pNewDll4 );
  506. Out1 += *pNewDll1 + *pNewDll3;
  507. Out2 += *pNewDll2 + *pNewDll4;
  508. pDelayIn = pDelay + Indx;
  509. *pDelayIn++ = In1 + ((*pNewDll1*pCoefs->l_dFB11 + *pPrevDll1*pCoefs->l_dFB12)>>15);
  510. pPrevDll1 = pNewDll1;
  511. Indx1 = (Indx1 - 4) & REV_MASK;
  512. *pDelayIn++ = In2 + ((*pNewDll2*pCoefs->l_dFB21 + *pPrevDll2*pCoefs->l_dFB22)>>15);
  513. pPrevDll2 = pNewDll2;
  514. Indx2 = (Indx2 - 4) & REV_MASK;
  515. *pDelayIn++ = -In2 + ((*pNewDll3*pCoefs->l_dFB31 + *pPrevDll3*pCoefs->l_dFB32)>>15);
  516. pPrevDll3 = pNewDll3;
  517. Indx3 = (Indx3 - 4) & REV_MASK;
  518. *pDelayIn++ = In1 + ((*pNewDll4*pCoefs->l_dFB41 + *pPrevDll4*pCoefs->l_dFB42)>>15);
  519. pPrevDll4 = pNewDll4;
  520. Indx4 = (Indx4 - 4) & REV_MASK;
  521. Indx = (Indx - 4) & REV_MASK;
  522. DIndx = (DIndx - 2) & DSPS_MASK;
  523. CLIP_SHORT_TO_SHORT(Out1)
  524. CLIP_SHORT_TO_SHORT(Out2)
  525. *pOutShort++ = (short)(Out1);
  526. *pOutShort++ = (short)(Out2);
  527. }
  528. ((long *)pStates)[0] = Indx ;
  529. ((long *)pStates)[1] = DIndx ;
  530. }
  531. #endif
  532. void SVerbStereoToStereoShort(long NumInFrames, short *pInShort, short *pOutShort,
  533. void *pC, long *pStates)
  534. {
  535. sCoefsStruct *pCoefs = ((sCoefsStruct *)pC);
  536. long n_sample;
  537. long In1, In2, Out1, Out2;
  538. long Indx1,Indx2,Indx3,Indx4;
  539. long *pNewDll1, *pNewDll2, *pNewDll3, *pNewDll4;
  540. long *pPrevDll1, *pPrevDll2, *pPrevDll3, *pPrevDll4, *pDelayIn;
  541. long *pDelay = pStates+2;
  542. long *pDD1 = pDelay+0x4000;
  543. long *pDD2 = pDD1+0x800;
  544. long Indx = ((long *)pStates)[0];
  545. long DIndx = ((long *)pStates)[1] ;
  546. Indx1 = (Indx+4+pCoefs->lDelay1) & REV_MASK;
  547. Indx2 = (Indx+4+pCoefs->lDelay2) & REV_MASK;
  548. Indx3 = (Indx+4+pCoefs->lDelay3) & REV_MASK;
  549. Indx4 = (Indx+4+pCoefs->lDelay4) & REV_MASK;
  550. pPrevDll1 = pDelay+Indx1;
  551. pPrevDll2 = pDelay+Indx2+1;
  552. pPrevDll3 = pDelay+Indx3+2;
  553. pPrevDll4 = pDelay+Indx4+3;
  554. Indx1 = (Indx1-4)&REV_MASK;
  555. Indx2 = (Indx2-4)&REV_MASK;
  556. Indx3 = (Indx3-4)&REV_MASK;
  557. Indx4 = (Indx4-4)&REV_MASK;
  558. for (n_sample = 0;n_sample < NumInFrames;n_sample++)
  559. {
  560. In1 = (long)(*pInShort++);
  561. In2 = (long)(*pInShort++);
  562. Out1 = (In1 * pCoefs->l_directGain)>>15;
  563. Out2 = (In2 * pCoefs->l_directGain)>>15;
  564. In1 = (In1 * pCoefs->l_revGain)>>15;
  565. In2 = (In2 * pCoefs->l_revGain)>>15;
  566. pNewDll1 = pDelay+Indx1;
  567. pNewDll2 = pDelay+Indx2+1;
  568. pNewDll3 = pDelay+Indx3+2;
  569. pNewDll4 = pDelay+Indx4+3;
  570. dspsL( pDD1, DIndx, pCoefs->lDDly1, pCoefs->l_dDG1, pCoefs->l_dDsps, pNewDll1, pNewDll2 );
  571. dspsL( pDD2, DIndx, pCoefs->lDDly2, pCoefs->l_dDG2, pCoefs->l_dDsps, pNewDll3, pNewDll4 );
  572. Out1 += *pNewDll1 + *pNewDll3;
  573. Out2 += *pNewDll2 + *pNewDll4;
  574. pDelayIn = pDelay + Indx;
  575. *pDelayIn++ = In1 + ((*pNewDll1*pCoefs->l_dFB11 + *pPrevDll1*pCoefs->l_dFB12)>>15);
  576. pPrevDll1 = pNewDll1;
  577. Indx1 = (Indx1 - 4) & REV_MASK;
  578. *pDelayIn++ = In2 + ((*pNewDll2*pCoefs->l_dFB21 + *pPrevDll2*pCoefs->l_dFB22)>>15);
  579. pPrevDll2 = pNewDll2;
  580. Indx2 = (Indx2 - 4) & REV_MASK;
  581. *pDelayIn++ = -In2 + ((*pNewDll3*pCoefs->l_dFB31 + *pPrevDll3*pCoefs->l_dFB32)>>15);
  582. pPrevDll3 = pNewDll3;
  583. Indx3 = (Indx3 - 4) & REV_MASK;
  584. *pDelayIn++ = In1 + ((*pNewDll4*pCoefs->l_dFB41 + *pPrevDll4*pCoefs->l_dFB42)>>15);
  585. pPrevDll4 = pNewDll4;
  586. Indx4 = (Indx4 - 4) & REV_MASK;
  587. Indx = (Indx - 4) & REV_MASK;
  588. DIndx = (DIndx - 2) & DSPS_MASK;
  589. CLIP_SHORT_TO_SHORT(Out1)
  590. CLIP_SHORT_TO_SHORT(Out2)
  591. *pOutShort++ = (short)(Out1);
  592. *pOutShort++ = (short)(Out2);
  593. }
  594. ((long *)pStates)[0] = Indx ;
  595. ((long *)pStates)[1] = DIndx ;
  596. }
  597. #ifdef USE_ALL_VERBS
  598. void SVerbMonoToMonoFloat(long NumInFrames, float *pInFloat, float *pOutFloat,
  599. void *pC, float *pStates)
  600. {
  601. sCoefsStruct *pCoefs = ((sCoefsStruct *)pC);
  602. long n_sample;
  603. float In1, In2, Out1, Out2;
  604. long Indx1,Indx2,Indx3,Indx4;
  605. float *pNewDll1, *pNewDll2, *pNewDll3, *pNewDll4;
  606. float *pPrevDll1, *pPrevDll2, *pPrevDll3, *pPrevDll4, *pDelayIn;
  607. float *pDelay = pStates+2;
  608. float *pDD1 = pDelay+0x4000;
  609. float *pDD2 = pDD1+0x800;
  610. long Indx = ((long *)pStates)[0];
  611. long DIndx = ((long *)pStates)[1] ;
  612. Indx1 = (Indx+4+pCoefs->lDelay1) & REV_MASK;
  613. Indx2 = (Indx+4+pCoefs->lDelay2) & REV_MASK;
  614. Indx3 = (Indx+4+pCoefs->lDelay3) & REV_MASK;
  615. Indx4 = (Indx+4+pCoefs->lDelay4) & REV_MASK;
  616. pPrevDll1 = pDelay+Indx1;
  617. pPrevDll2 = pDelay+Indx2+1;
  618. pPrevDll3 = pDelay+Indx3+2;
  619. pPrevDll4 = pDelay+Indx4+3;
  620. Indx1 = (Indx1-4)&REV_MASK;
  621. Indx2 = (Indx2-4)&REV_MASK;
  622. Indx3 = (Indx3-4)&REV_MASK;
  623. Indx4 = (Indx4-4)&REV_MASK;
  624. for (n_sample = 0;n_sample < NumInFrames;n_sample++)
  625. {
  626. In1 = In2 = (float)0.5 * (*pInFloat++) + FPU_DENORM_OFFS;
  627. Out1 = In1 * pCoefs->directGain;
  628. Out2 = In2 * pCoefs->directGain;
  629. In1 *= pCoefs->revGain;
  630. In2 *= pCoefs->revGain;
  631. pNewDll1 = pDelay+Indx1;
  632. pNewDll2 = pDelay+Indx2+1;
  633. pNewDll3 = pDelay+Indx3+2;
  634. pNewDll4 = pDelay+Indx4+3;
  635. dsps( pDD1, DIndx, pCoefs->lDDly1, pCoefs->dDG1, pCoefs->dDsps, pNewDll1, pNewDll2 );
  636. dsps( pDD2, DIndx, pCoefs->lDDly2, pCoefs->dDG2, pCoefs->dDsps, pNewDll3, pNewDll4 );
  637. Out1 += *pNewDll1 + *pNewDll3;
  638. Out2 += *pNewDll2 + *pNewDll4;
  639. pDelayIn = pDelay + Indx;
  640. *pDelayIn++ = In1 + *pNewDll1*pCoefs->dFB11 + *pPrevDll1*pCoefs->dFB12;
  641. pPrevDll1 = pNewDll1;
  642. Indx1 = (Indx1 - 4) & REV_MASK;
  643. *pDelayIn++ = In2 + *pNewDll2*pCoefs->dFB21 + *pPrevDll2*pCoefs->dFB22;
  644. pPrevDll2 = pNewDll2;
  645. Indx2 = (Indx2 - 4) & REV_MASK;
  646. *pDelayIn++ = -In2 + *pNewDll3*pCoefs->dFB31 + *pPrevDll3*pCoefs->dFB32;
  647. pPrevDll3 = pNewDll3;
  648. Indx3 = (Indx3 - 4) & REV_MASK;
  649. *pDelayIn++ = In1 + *pNewDll4*pCoefs->dFB41 + *pPrevDll4*pCoefs->dFB42;
  650. pPrevDll4 = pNewDll4;
  651. Indx4 = (Indx4 - 4) & REV_MASK;
  652. Indx = (Indx - 4) & REV_MASK;
  653. DIndx = (DIndx - 2) & DSPS_MASK;
  654. *pOutFloat++ = Out1+Out2;
  655. }
  656. ((long *)pStates)[0] = Indx ;
  657. ((long *)pStates)[1] = DIndx ;
  658. }
  659. void SVerbMonoToStereoFloat(long NumInFrames, float *pInFloat, float *pOutFloat,
  660. void *pC, float *pStates)
  661. {
  662. sCoefsStruct *pCoefs = ((sCoefsStruct *)pC);
  663. long n_sample;
  664. float In1, In2, Out1, Out2;
  665. long Indx1,Indx2,Indx3,Indx4;
  666. float *pNewDll1, *pNewDll2, *pNewDll3, *pNewDll4;
  667. float *pPrevDll1, *pPrevDll2, *pPrevDll3, *pPrevDll4, *pDelayIn;
  668. float *pDelay = pStates+2;
  669. float *pDD1 = pDelay+0x4000;
  670. float *pDD2 = pDD1+0x800;
  671. long Indx = ((long *)pStates)[0];
  672. long DIndx = ((long *)pStates)[1] ;
  673. Indx1 = (Indx+4+pCoefs->lDelay1) & REV_MASK;
  674. Indx2 = (Indx+4+pCoefs->lDelay2) & REV_MASK;
  675. Indx3 = (Indx+4+pCoefs->lDelay3) & REV_MASK;
  676. Indx4 = (Indx+4+pCoefs->lDelay4) & REV_MASK;
  677. pPrevDll1 = pDelay+Indx1;
  678. pPrevDll2 = pDelay+Indx2+1;
  679. pPrevDll3 = pDelay+Indx3+2;
  680. pPrevDll4 = pDelay+Indx4+3;
  681. Indx1 = (Indx1-4)&REV_MASK;
  682. Indx2 = (Indx2-4)&REV_MASK;
  683. Indx3 = (Indx3-4)&REV_MASK;
  684. Indx4 = (Indx4-4)&REV_MASK;
  685. for (n_sample = 0;n_sample < NumInFrames;n_sample++)
  686. {
  687. In1 = In2 = (float)0.7071 * (*pInFloat++) + FPU_DENORM_OFFS;
  688. Out1 = In1 * pCoefs->directGain;
  689. Out2 = In2 * pCoefs->directGain;
  690. In1 *= pCoefs->revGain;
  691. In2 *= pCoefs->revGain;
  692. pNewDll1 = pDelay+Indx1;
  693. pNewDll2 = pDelay+Indx2+1;
  694. pNewDll3 = pDelay+Indx3+2;
  695. pNewDll4 = pDelay+Indx4+3;
  696. dsps( pDD1, DIndx, pCoefs->lDDly1, pCoefs->dDG1, pCoefs->dDsps, pNewDll1, pNewDll2 );
  697. dsps( pDD2, DIndx, pCoefs->lDDly2, pCoefs->dDG2, pCoefs->dDsps, pNewDll3, pNewDll4 );
  698. Out1 += *pNewDll1 + *pNewDll3;
  699. Out2 += *pNewDll2 + *pNewDll4;
  700. pDelayIn = pDelay + Indx;
  701. *pDelayIn++ = In1 + *pNewDll1*pCoefs->dFB11 + *pPrevDll1*pCoefs->dFB12;
  702. pPrevDll1 = pNewDll1;
  703. Indx1 = (Indx1 - 4) & REV_MASK;
  704. *pDelayIn++ = In2 + *pNewDll2*pCoefs->dFB21 + *pPrevDll2*pCoefs->dFB22;
  705. pPrevDll2 = pNewDll2;
  706. Indx2 = (Indx2 - 4) & REV_MASK;
  707. *pDelayIn++ = -In2 + *pNewDll3*pCoefs->dFB31 + *pPrevDll3*pCoefs->dFB32;
  708. pPrevDll3 = pNewDll3;
  709. Indx3 = (Indx3 - 4) & REV_MASK;
  710. *pDelayIn++ = In1 + *pNewDll4*pCoefs->dFB41 + *pPrevDll4*pCoefs->dFB42;
  711. pPrevDll4 = pNewDll4;
  712. Indx4 = (Indx4 - 4) & REV_MASK;
  713. Indx = (Indx - 4) & REV_MASK;
  714. DIndx = (DIndx - 2) & DSPS_MASK;
  715. *pOutFloat++ = Out1;
  716. *pOutFloat++ = Out2;
  717. }
  718. ((long *)pStates)[0] = Indx ;
  719. ((long *)pStates)[1] = DIndx ;
  720. }
  721. void SVerbStereoToStereoFloat(long NumInFrames, float *pInFloat, float *pOutFloat,
  722. void *pC, float *pStates)
  723. {
  724. sCoefsStruct *pCoefs = ((sCoefsStruct *)pC);
  725. long n_sample;
  726. float In1, In2, Out1, Out2;
  727. long Indx1,Indx2,Indx3,Indx4;
  728. float *pNewDll1, *pNewDll2, *pNewDll3, *pNewDll4;
  729. float *pPrevDll1, *pPrevDll2, *pPrevDll3, *pPrevDll4, *pDelayIn;
  730. float *pDelay = pStates+2;
  731. float *pDD1 = pDelay+0x4000;
  732. float *pDD2 = pDD1+0x800;
  733. long Indx = ((long *)pStates)[0];
  734. long DIndx = ((long *)pStates)[1] ;
  735. Indx1 = (Indx+4+pCoefs->lDelay1) & REV_MASK;
  736. Indx2 = (Indx+4+pCoefs->lDelay2) & REV_MASK;
  737. Indx3 = (Indx+4+pCoefs->lDelay3) & REV_MASK;
  738. Indx4 = (Indx+4+pCoefs->lDelay4) & REV_MASK;
  739. pPrevDll1 = pDelay+Indx1;
  740. pPrevDll2 = pDelay+Indx2+1;
  741. pPrevDll3 = pDelay+Indx3+2;
  742. pPrevDll4 = pDelay+Indx4+3;
  743. Indx1 = (Indx1-4)&REV_MASK;
  744. Indx2 = (Indx2-4)&REV_MASK;
  745. Indx3 = (Indx3-4)&REV_MASK;
  746. Indx4 = (Indx4-4)&REV_MASK;
  747. for (n_sample = 0;n_sample < NumInFrames;n_sample++)
  748. {
  749. In1 = (*pInFloat++) + FPU_DENORM_OFFS;
  750. In2 = (*pInFloat++) + FPU_DENORM_OFFS;
  751. Out1 = In1 * pCoefs->directGain;
  752. Out2 = In2 * pCoefs->directGain;
  753. In1 *= pCoefs->revGain;
  754. In2 *= pCoefs->revGain;
  755. pNewDll1 = pDelay+Indx1;
  756. pNewDll2 = pDelay+Indx2+1;
  757. pNewDll3 = pDelay+Indx3+2;
  758. pNewDll4 = pDelay+Indx4+3;
  759. dsps( pDD1, DIndx, pCoefs->lDDly1, pCoefs->dDG1, pCoefs->dDsps, pNewDll1, pNewDll2 );
  760. dsps( pDD2, DIndx, pCoefs->lDDly2, pCoefs->dDG2, pCoefs->dDsps, pNewDll3, pNewDll4 );
  761. Out1 += *pNewDll1 + *pNewDll3;
  762. Out2 += *pNewDll2 + *pNewDll4;
  763. pDelayIn = pDelay + Indx;
  764. *pDelayIn++ = In1 + *pNewDll1*pCoefs->dFB11 + *pPrevDll1*pCoefs->dFB12;
  765. pPrevDll1 = pNewDll1;
  766. Indx1 = (Indx1 - 4) & REV_MASK;
  767. *pDelayIn++ = In2 + *pNewDll2*pCoefs->dFB21 + *pPrevDll2*pCoefs->dFB22;
  768. pPrevDll2 = pNewDll2;
  769. Indx2 = (Indx2 - 4) & REV_MASK;
  770. *pDelayIn++ = -In2 + *pNewDll3*pCoefs->dFB31 + *pPrevDll3*pCoefs->dFB32;
  771. pPrevDll3 = pNewDll3;
  772. Indx3 = (Indx3 - 4) & REV_MASK;
  773. *pDelayIn++ = In1 + *pNewDll4*pCoefs->dFB41 + *pPrevDll4*pCoefs->dFB42;
  774. pPrevDll4 = pNewDll4;
  775. Indx4 = (Indx4 - 4) & REV_MASK;
  776. Indx = (Indx - 4) & REV_MASK;
  777. DIndx = (DIndx - 2) & DSPS_MASK;
  778. *pOutFloat++ = Out1;
  779. *pOutFloat++ = Out2;
  780. }
  781. ((long *)pStates)[0] = Indx ;
  782. ((long *)pStates)[1] = DIndx ;
  783. }
  784. __inline void dsps( float *pDly, long ref, long delay, float dDG1, float dDsps, float *inL, float *inR )
  785. {
  786. float outL, outR;
  787. float *pDlyOut;
  788. pDlyOut = pDly + ((ref+delay) & DSPS_MASK);
  789. pDly += (ref & DSPS_MASK);
  790. outL = dDG1 * (*pDlyOut++) + *inR * dDsps;
  791. outR = dDG1 * (*pDlyOut) - *inL * dDsps ;
  792. // here we feed back the output.
  793. *pDly++ = *inL + dDsps * outR ;
  794. *pDly = *inR - dDsps * outL ;
  795. *inL = outL;
  796. *inR = outR;
  797. }
  798. #endif
  799. __inline void dspsL( long *pDly, long ref, long delay, long dDG1, long dDsps, long *inL, long *inR )
  800. {
  801. long outL, outR;
  802. long *pDlyOut;
  803. pDlyOut = pDly + ((ref+delay) & DSPS_MASK);
  804. pDly += (ref & DSPS_MASK);
  805. outL = (dDG1 * (*pDlyOut++) + *inR * dDsps)>>15;
  806. outR = (dDG1 * (*pDlyOut) - *inL * dDsps)>>15;
  807. // here we feed back the output.
  808. *pDly++ = *inL + ((dDsps * outR)>>15) ;
  809. *pDly = *inR - ((dDsps * outL)>>15) ;
  810. *inL = outL;
  811. *inR = outR;
  812. }
  813. #pragma optimize( "ty", off )