Leaked source code of windows server 2003
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.

318 lines
7.7 KiB

  1. // Mixf.cpp
  2. // Copyright (c) Microsoft Corporation 1996-1999
  3. // Filtered Mix Engine
  4. #include "simple.h"
  5. #include <mmsystem.h>
  6. #include "synth.h"
  7. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  8. #pragma message ("Programer note: property hack")
  9. //#define DEBUG_DUMP_FILE
  10. #pragma warning(disable : 4101 4102 4146)
  11. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  12. #ifdef DEBUG_DUMP_FILE
  13. DWORD dmp_bufsize = 4000000;
  14. DWORD dmp_samplesrecorded;
  15. DWORD dmp_buffercount;
  16. short dmp_soundbuffer[4000000];
  17. #endif
  18. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  19. DWORD CDigitalAudio::Mix16Filtered(
  20. short **ppBuffers,
  21. DWORD *pdwChannels,
  22. DWORD dwBufferCount,
  23. DWORD dwLength,
  24. DWORD dwDeltaPeriod,
  25. VFRACT vfDeltaLVolume,
  26. VFRACT vfDeltaRVolume,
  27. PFRACT pfDeltaPitch,
  28. PFRACT pfSampleLength,
  29. PFRACT pfLoopLength,
  30. COEFFDELTA cfdK,
  31. COEFFDELTA cfdB1,
  32. COEFFDELTA cfdB2)
  33. {
  34. DWORD dwI;
  35. DWORD dwIndex;
  36. DWORD dwPosition;
  37. long lA;
  38. long lM;
  39. DWORD dwIncDelta = dwDeltaPeriod;
  40. VFRACT dwFract;
  41. short * pcWave = m_pnWave;
  42. PFRACT pfSamplePos = m_pfLastSample;
  43. VFRACT vfLVolume = m_vfLastLVolume;
  44. VFRACT vfRVolume = m_vfLastRVolume;
  45. PFRACT pfPitch = m_pfLastPitch;
  46. PFRACT pfPFract = pfPitch << 8;
  47. VFRACT vfLVFract = vfLVolume << 8;
  48. VFRACT vfRVFract = vfRVolume << 8;
  49. COEFF cfK = m_cfLastK;
  50. COEFF cfB1 = m_cfLastB1;
  51. COEFF cfB2 = m_cfLastB2;
  52. for (dwI = 0; dwI < dwLength;)
  53. {
  54. if (pfSamplePos >= pfSampleLength)
  55. {
  56. if (pfLoopLength)
  57. {
  58. pfSamplePos -= pfLoopLength;
  59. }
  60. else
  61. break;
  62. }
  63. dwIncDelta--;
  64. if (!dwIncDelta)
  65. {
  66. dwIncDelta = dwDeltaPeriod;
  67. pfPFract += pfDeltaPitch;
  68. pfPitch = pfPFract >> 8;
  69. vfLVFract += vfDeltaLVolume;
  70. vfLVolume = vfLVFract >> 8;
  71. vfRVFract += vfDeltaRVolume;
  72. vfRVolume = vfRVFract >> 8;
  73. cfK += cfdK;
  74. cfB1 += cfdB1;
  75. cfB2 += cfdB2;
  76. }
  77. dwPosition = pfSamplePos >> 12;
  78. dwFract = pfSamplePos & 0xFFF;
  79. pfSamplePos += pfPitch;
  80. // Interpolate
  81. lA = (long)pcWave[dwPosition];
  82. lM = (((pcWave[dwPosition+1] - lA) * dwFract) >> 12) + lA;
  83. //
  84. // Filter
  85. //
  86. // z = k*s - b1*z1 - b2*b2
  87. // >>>> We store the negative of b1 in the table, so we flip the sign again by
  88. // >>>> adding here
  89. // >>>> Lookinto simply using a float here, it may just be faster, save a div
  90. //
  91. lM = MulDiv(lM, cfK, (1 << 30))
  92. + MulDiv(m_lPrevSample, cfB1, (1 << 30))
  93. - MulDiv(m_lPrevPrevSample, cfB2, (1 << 30));
  94. //
  95. //
  96. //
  97. m_lPrevPrevSample = m_lPrevSample;
  98. m_lPrevSample = lM;
  99. //
  100. //
  101. //
  102. lA = lM;
  103. lA *= vfLVolume;
  104. lA >>= 13; // Signal bumps up to 15 bits.
  105. lM *= vfRVolume;
  106. lM >>= 13;
  107. dwIndex = 0;
  108. while ( dwIndex < dwBufferCount )
  109. {
  110. short *pBuffer = &ppBuffers[dwIndex][dwI];
  111. if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_LEFT )
  112. {
  113. // Keep this around so we can use it to generate new assembly code (see below...)
  114. *pBuffer += (short) lA;
  115. _asm{jno no_oflowl}
  116. *pBuffer = 0x7fff;
  117. _asm{js no_oflowl}
  118. *pBuffer = (short) 0x8000;
  119. }
  120. no_oflowl:
  121. if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_RIGHT )
  122. {
  123. // Keep this around so we can use it to generate new assembly code (see below...)
  124. *pBuffer += (short) lM;
  125. _asm{jno no_oflowr}
  126. *pBuffer = 0x7fff;
  127. _asm{js no_oflowr}
  128. *pBuffer = (short) 0x8000;
  129. }
  130. no_oflowr:
  131. dwIndex++;
  132. }
  133. #ifdef DEBUG_DUMP_FILE
  134. dmp_soundbuffer[dmp_samplesrecorded] = pBuffer[dwI];
  135. if (dmp_samplesrecorded < dmp_bufsize)
  136. dmp_samplesrecorded++ ;
  137. #endif
  138. dwI++;
  139. }
  140. m_vfLastLVolume = vfLVolume;
  141. m_vfLastRVolume = vfRVolume;
  142. m_pfLastPitch = pfPitch;
  143. m_pfLastSample = pfSamplePos;
  144. m_cfLastK = cfK;
  145. m_cfLastB1 = cfB1;
  146. m_cfLastB2 = cfB2;
  147. return (dwI);
  148. }
  149. DWORD CDigitalAudio::Mix16FilteredInterleaved(
  150. short **ppBuffers,
  151. DWORD *pdwChannels,
  152. DWORD dwBufferCount,
  153. DWORD dwLength,
  154. DWORD dwDeltaPeriod,
  155. VFRACT vfDeltaLVolume,
  156. VFRACT vfDeltaRVolume,
  157. PFRACT pfDeltaPitch,
  158. PFRACT pfSampleLength,
  159. PFRACT pfLoopLength,
  160. COEFFDELTA cfdK,
  161. COEFFDELTA cfdB1,
  162. COEFFDELTA cfdB2)
  163. {
  164. DWORD dwI;
  165. DWORD dwIndex;
  166. DWORD dwPosition;
  167. long lA;
  168. long lM;
  169. DWORD dwIncDelta = dwDeltaPeriod;
  170. VFRACT dwFract;
  171. short * pcWave = m_pnWave;
  172. PFRACT pfSamplePos = m_pfLastSample;
  173. VFRACT vfLVolume = m_vfLastLVolume;
  174. VFRACT vfRVolume = m_vfLastRVolume;
  175. PFRACT pfPitch = m_pfLastPitch;
  176. PFRACT pfPFract = pfPitch << 8;
  177. VFRACT vfLVFract = vfLVolume << 8;
  178. VFRACT vfRVFract = vfRVolume << 8;
  179. COEFF cfK = m_cfLastK;
  180. COEFF cfB1 = m_cfLastB1;
  181. COEFF cfB2 = m_cfLastB2;
  182. dwLength <<= 1;
  183. for (dwI = 0; dwI < dwLength;)
  184. {
  185. if (pfSamplePos >= pfSampleLength)
  186. {
  187. if (pfLoopLength)
  188. {
  189. pfSamplePos -= pfLoopLength;
  190. }
  191. else
  192. break;
  193. }
  194. dwIncDelta--;
  195. if (!dwIncDelta)
  196. {
  197. dwIncDelta = dwDeltaPeriod;
  198. pfPFract += pfDeltaPitch;
  199. pfPitch = pfPFract >> 8;
  200. vfLVFract += vfDeltaLVolume;
  201. vfLVolume = vfLVFract >> 8;
  202. vfRVFract += vfDeltaRVolume;
  203. vfRVolume = vfRVFract >> 8;
  204. cfK += cfdK;
  205. cfB1 += cfdB1;
  206. cfB2 += cfdB2;
  207. }
  208. dwPosition = pfSamplePos >> 12;
  209. dwFract = pfSamplePos & 0xFFF;
  210. pfSamplePos += pfPitch;
  211. // Interpolate
  212. lA = (long)pcWave[dwPosition];
  213. lM = (((pcWave[dwPosition+1] - lA) * dwFract) >> 12) + lA;
  214. //
  215. // Filter
  216. //
  217. // z = k*s - b1*z1 - b2*b2
  218. // >>>> We store the negative of b1 in the table, so we flip the sign again by
  219. // >>>> adding here
  220. // >>>> Lookinto simply using a float here, it may just be faster, save a div
  221. //
  222. lM = MulDiv(lM, cfK, (1 << 30))
  223. + MulDiv(m_lPrevSample, cfB1, (1 << 30))
  224. - MulDiv(m_lPrevPrevSample, cfB2, (1 << 30));
  225. //
  226. //
  227. //
  228. m_lPrevPrevSample = m_lPrevSample;
  229. m_lPrevSample = lM;
  230. //
  231. //
  232. //
  233. lA = lM;
  234. lA *= vfLVolume;
  235. lA >>= 13; // Signal bumps up to 15 bits.
  236. lM *= vfRVolume;
  237. lM >>= 13;
  238. dwIndex = 0;
  239. while ( dwIndex < dwBufferCount )
  240. {
  241. short *pBuffer = &ppBuffers[dwIndex][dwI];
  242. if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_LEFT )
  243. {
  244. // Keep this around so we can use it to generate new assembly code (see below...)
  245. *pBuffer += (short) lA;
  246. _asm{jno no_oflowl}
  247. *pBuffer = 0x7fff;
  248. _asm{js no_oflowl}
  249. *pBuffer = (short) 0x8000;
  250. }
  251. no_oflowl:
  252. if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_RIGHT )
  253. {
  254. // Keep this around so we can use it to generate new assembly code (see below...)
  255. pBuffer++;
  256. *pBuffer += (short) lM;
  257. _asm{jno no_oflowr}
  258. *pBuffer = 0x7fff;
  259. _asm{js no_oflowr}
  260. *pBuffer = (short) 0x8000;
  261. }
  262. no_oflowr:
  263. dwIndex++;
  264. }
  265. #ifdef DEBUG_DUMP_FILE
  266. dmp_soundbuffer[dmp_samplesrecorded] = pBuffer[dwI];
  267. if (dmp_samplesrecorded < dmp_bufsize)
  268. dmp_samplesrecorded++ ;
  269. #endif
  270. dwI += 2;
  271. }
  272. m_vfLastLVolume = vfLVolume;
  273. m_vfLastRVolume = vfRVolume;
  274. m_pfLastPitch = pfPitch;
  275. m_pfLastSample = pfSamplePos;
  276. m_cfLastK = cfK;
  277. m_cfLastB1 = cfB1;
  278. m_cfLastB2 = cfB2;
  279. return (dwI >> 1);
  280. }