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.

1891 lines
35 KiB

  1. //
  2. // Copyright (c) 1996-2000 Microsoft Corporation. All rights reserved.
  3. // Mix.cpp
  4. // Mix engines for MSSynth
  5. #include "common.h"
  6. #define STR_MODULENAME "DDKSynth.sys:Mix: "
  7. #pragma warning(disable : 4101 4102 4146)
  8. #ifdef _ALPHA_
  9. extern "C" {
  10. int __ADAWI(short, short *);
  11. };
  12. #pragma intrinsic(__ADAWI)
  13. #define ALPHA_OVERFLOW 2
  14. #define ALPHA_NEGATIVE 8
  15. #else // !_ALPHA_
  16. // TODO -- overflow detection for ia64? (+ axp64?)
  17. #endif // !_ALPHA_
  18. #pragma code_seg()
  19. /*****************************************************************************
  20. * CDigitalAudio::Mix8()
  21. *****************************************************************************
  22. * Implement a stereo eight-bit mix.
  23. * Heavily optimized for x86 non-MMX, plus C code for non-x86.
  24. */
  25. DWORD CDigitalAudio::Mix8(short * pBuffer, DWORD dwLength,
  26. DWORD dwDeltaPeriod, VFRACT vfDeltaLVolume,
  27. VFRACT vfDeltaRVolume,PFRACT pfDeltaPitch,
  28. PFRACT pfSampleLength,PFRACT pfLoopLength)
  29. {
  30. DWORD dwI;
  31. DWORD dwPosition;
  32. long lM, lLM;
  33. DWORD dwIncDelta = dwDeltaPeriod;
  34. VFRACT dwFract;
  35. char * pcWave = (char *) m_pnWave;
  36. PFRACT pfSamplePos = m_pfLastSample;
  37. VFRACT vfLVolume = m_vfLastLVolume;
  38. VFRACT vfRVolume = m_vfLastRVolume;
  39. PFRACT pfPitch = m_pfLastPitch;
  40. PFRACT pfPFract = pfPitch << 8;
  41. VFRACT vfLVFract = vfLVolume << 8; // Keep high res version around.
  42. VFRACT vfRVFract = vfRVolume << 8;
  43. dwLength <<= 1;
  44. #ifndef _X86_
  45. for (dwI = 0; dwI < dwLength; )
  46. {
  47. if (pfSamplePos >= pfSampleLength)
  48. {
  49. if (pfLoopLength)
  50. pfSamplePos -= pfLoopLength;
  51. else
  52. break;
  53. }
  54. dwIncDelta--;
  55. if (!dwIncDelta)
  56. {
  57. dwIncDelta = dwDeltaPeriod;
  58. pfPFract += pfDeltaPitch;
  59. pfPitch = pfPFract >> 8;
  60. vfLVFract += vfDeltaLVolume;
  61. vfLVolume = vfLVFract >> 8;
  62. vfRVFract += vfDeltaRVolume;
  63. vfRVolume = vfRVFract >> 8;
  64. }
  65. dwPosition = pfSamplePos >> 12;
  66. dwFract = pfSamplePos & 0xFFF;
  67. pfSamplePos += pfPitch;
  68. lLM = pcWave[dwPosition];
  69. lM = ((pcWave[dwPosition + 1] - lLM) * dwFract) >> 12;
  70. lM += lLM;
  71. lLM = lM;
  72. lLM *= vfLVolume;
  73. lLM >>= 5; // Signal bumps up to 15 bits.
  74. lM *= vfRVolume;
  75. lM >>= 5;
  76. #ifndef _X86_
  77. #ifdef _ALPHA_
  78. int nBitmask;
  79. if( ALPHA_OVERFLOW & (nBitmask = __ADAWI( (short) lLM, &pBuffer[dwI] )) ) {
  80. if( ALPHA_NEGATIVE & nBitmask ) {
  81. pBuffer[dwI] = 0x7FFF;
  82. }
  83. else pBuffer[dwI] = (short) 0x8000;
  84. }
  85. if( ALPHA_OVERFLOW & (nBitmask = __ADAWI( (short) lM, &pBuffer[dwI+1] )) ) {
  86. if( ALPHA_NEGATIVE & nBitmask ) {
  87. pBuffer[dwI+1] = 0x7FFF;
  88. }
  89. else pBuffer[dwI+1] = (short) 0x8000;
  90. }
  91. #else // !_ALPHA_
  92. // TODO -- overflow detection on ia64 (+ axp64?)
  93. #endif // !_ALPHA_
  94. #else // _X86_ (dead code)
  95. // Keep this around so we can use it to generate new assembly code (see below...)
  96. pBuffer[dwI] += (short) lLM;
  97. _asm{jno no_oflowl}
  98. pBuffer[dwI] = 0x7fff;
  99. _asm{js no_oflowl}
  100. pBuffer[dwI] = (short) 0x8000;
  101. no_oflowl:
  102. pBuffer[dwI+1] += (short) lM;
  103. _asm{jno no_oflowr}
  104. pBuffer[dwI+1] = 0x7fff;
  105. _asm{js no_oflowr}
  106. pBuffer[dwI+1] = (short) 0x8000;
  107. no_oflowr:
  108. #endif // _X86_ (dead code)
  109. dwI += 2;
  110. }
  111. #else // _X86_
  112. int i, a, b, c, total;
  113. short * pBuf = pBuffer + dwLength, *pBufX;
  114. dwI = - dwLength;
  115. _asm {
  116. ; 979 : for (dwI = 0; dwI < dwLength; )
  117. // Induction variables.
  118. mov edi, dwI
  119. mov ebx, DWORD PTR pfSamplePos
  120. // Previously set up.
  121. cmp DWORD PTR dwLength, 0
  122. mov edx, pfPFract
  123. mov ecx, DWORD PTR pfPitch
  124. je $L30539
  125. $L30536:
  126. cmp ebx, DWORD PTR pfSampleLength
  127. ; 981 : if (pfSamplePos >= pfSampleLength)
  128. mov esi, DWORD PTR dwIncDelta
  129. jge SHORT $L30540_
  130. $L30540:
  131. ; 987 : else
  132. ; 988 : break;
  133. ; 990 : dwIncDelta--;
  134. dec esi
  135. mov DWORD PTR dwIncDelta, esi
  136. ; 991 : if (!dwIncDelta)
  137. je SHORT $L30541_
  138. $L30541:
  139. // esi, edx, edi esi == dwIncDelta
  140. mov DWORD PTR i, 0
  141. ; 1010 : b = dwIncDelta;
  142. // esi = b == dwIncDelta
  143. ; 1011 : c = (pfSampleLength - pfSamplePos) / pfPitch;
  144. ; 1009 : a = (dwLength - dwI) / 2; // Remaining span.
  145. mov edx, edi
  146. neg edx
  147. shr edx, 1 // edx = a
  148. ; 1017 : if (b < a && b < c)
  149. cmp esi, edx
  150. jge try_ax
  151. mov eax, ecx
  152. imul eax, esi
  153. add eax, ebx
  154. cmp eax, DWORD PTR pfSampleLength
  155. jge try_c
  156. ; 1019 : i = b;
  157. cmp esi, 3
  158. jl got_it
  159. mov DWORD PTR i, esi
  160. jmp SHORT got_it
  161. ; 1013 : if (a < b && a < c)
  162. try_a:
  163. cmp edx, esi
  164. jge try_c
  165. try_ax:
  166. mov eax, edx
  167. imul eax, ecx
  168. add eax, ebx
  169. cmp eax, DWORD PTR pfSampleLength
  170. jge try_c
  171. ; 1015 : i = a;
  172. cmp edx, 3
  173. jl got_it
  174. mov DWORD PTR i, edx
  175. jmp SHORT got_it
  176. ; 1021 : else if (c < a && c < b)
  177. try_c:
  178. push edx
  179. mov eax, DWORD PTR pfSampleLength
  180. sub eax, ebx
  181. cdq
  182. idiv ecx // eax == c
  183. pop edx
  184. cmp eax, edx
  185. jge got_it
  186. try_cx:
  187. cmp eax, esi
  188. jge got_it
  189. ; 1023 : i = c;
  190. cmp eax, 3
  191. jl $L30543
  192. mov DWORD PTR i, eax
  193. got_it:
  194. mov edx, DWORD PTR i
  195. mov eax, DWORD PTR pBuf
  196. dec edx
  197. jl $L30543
  198. sub DWORD PTR dwIncDelta, edx
  199. ; 1093 : return (dwI >> 1);
  200. ; 1094 : }
  201. lea edx, [edx*2+2] // Current span.
  202. lea eax, [eax+edi*2] // Starting position.
  203. add edi, edx // Remaining span.
  204. lea eax, [eax+edx*2] // New ending position.
  205. push edi
  206. mov edi, edx // Current span.
  207. mov DWORD PTR pBufX, eax
  208. neg edi
  209. $L30797:
  210. ; 1005 : do
  211. ; 1010 : dwPosition = pfSamplePos >> 12;
  212. ; 1011 : dwFract = pfSamplePos & 0xFFF;
  213. mov edx, ebx
  214. mov esi, ebx
  215. add ebx, ecx
  216. mov ecx, DWORD PTR pcWave
  217. ; 1012 : pfSamplePos += pfPitch;
  218. sar edx, 12 ; 0000000cH
  219. and esi, 4095 ; 00000fffH
  220. ; 1013 :
  221. ; 1014 : lLM = (long) pcWave[dwPosition];
  222. movsx eax, BYTE PTR [ecx+edx]
  223. ; 1015 : lM = ((pcWave[dwPosition+1] - lLM) * dwFract);
  224. ; 1016 : lM >>= 12;
  225. ; 1017 : lM += lLM;
  226. movsx edx, BYTE PTR [ecx+edx+1]
  227. ; 1018 : lLM = lM;
  228. ; 1019 : lLM *= vfLVolume;
  229. ; 1020 : lLM >>= 5; // Signal bumps up to 15 bits.
  230. ; 1022 : pBuffer[dwI] += (short) lLM;
  231. ; 1028 : lM *= vfRVolume;
  232. ; 1029 : lM >>= 5;
  233. ; 1030 : pBuffer[dwI+1] += (short) lM;
  234. ; 1036 :
  235. ; 1037 : dwI += 2;
  236. sub edx, eax
  237. imul edx, esi
  238. sar edx, 12 ; 0000000cH
  239. mov esi, DWORD PTR vfLVolume
  240. add edx, eax
  241. imul esi, edx
  242. sar esi, 5 ; 00000005H
  243. mov eax, DWORD PTR pBufX
  244. add WORD PTR [eax+edi*2], si
  245. mov esi, DWORD PTR vfRVolume
  246. jo overflow_lx
  247. no_oflowlx:
  248. imul esi, edx
  249. ; 1038 : } while (--dwIncDelta);
  250. sar esi, 5 ; 00000005H
  251. mov ecx, DWORD PTR pfPitch
  252. add WORD PTR [eax+edi*2+2], si
  253. jo overflow_rx
  254. no_oflowrx:
  255. add edi, 2
  256. jne SHORT $L30797
  257. pop edi
  258. ; 1039 : ++dwIncDelta;
  259. ; 1040 : continue;
  260. mov edx, DWORD PTR pfPFract
  261. cmp edi, 0
  262. jl SHORT $L30536
  263. jmp SHORT $L30539
  264. $L30540_:
  265. ; 982 : {
  266. ; 983 : if (pfLoopLength)
  267. cmp DWORD PTR pfLoopLength, 0
  268. je $L30539
  269. ; 984 : {
  270. ; 985 : pfSamplePos -= pfLoopLength;
  271. sub ebx, DWORD PTR pfLoopLength
  272. jmp $L30540
  273. $L30541_:
  274. ; 994 : pfPFract += pfDeltaPitch;
  275. mov ecx, DWORD PTR pfDeltaPitch
  276. mov esi, DWORD PTR vfDeltaLVolume
  277. add ecx, edx
  278. mov edx, DWORD PTR vfLVFract
  279. ; 995 : pfPitch = pfPFract >> 8;
  280. ; 996 : vfLVFract += vfDeltaLVolume;
  281. mov DWORD PTR pfPFract, ecx
  282. add edx, esi
  283. ; 997 : vfLVolume = vfLVFract >> 8;
  284. ; 998 : vfRVFract += vfDeltaRVolume;
  285. sar ecx, 8
  286. mov DWORD PTR vfLVFract, edx
  287. sar edx, 8
  288. mov esi, DWORD PTR vfDeltaRVolume
  289. mov DWORD PTR vfLVolume, edx
  290. mov edx, DWORD PTR vfRVFract
  291. add edx, esi
  292. mov DWORD PTR pfPitch, ecx
  293. mov DWORD PTR vfRVFract, edx
  294. mov esi, DWORD PTR dwDeltaPeriod
  295. ; 999 : vfRVolume = vfRVFract >> 8;
  296. sar edx, 8
  297. mov DWORD PTR dwIncDelta, esi
  298. ; 993 : dwIncDelta = dwDeltaPeriod;
  299. mov DWORD PTR vfRVolume, edx
  300. jmp $L30541
  301. // Handle truncation.
  302. overflow_l:
  303. mov WORD PTR [eax+edi*2], 0x7fff
  304. js no_oflowl
  305. mov WORD PTR [eax+edi*2], 0x8000
  306. jmp no_oflowl
  307. overflow_r:
  308. mov WORD PTR [eax+edi*2+2], 0x7fff
  309. js no_oflowr
  310. mov WORD PTR [eax+edi*2+2], 0x8000
  311. jmp no_oflowr
  312. overflow_lx:
  313. mov WORD PTR [eax+edi*2], 0x7fff
  314. js no_oflowlx
  315. mov WORD PTR [eax+edi*2], 0x8000
  316. jmp no_oflowlx
  317. overflow_rx:
  318. mov WORD PTR [eax+edi*2+2], 0x7fff
  319. js no_oflowrx
  320. mov WORD PTR [eax+edi*2+2], 0x8000
  321. jmp no_oflowrx
  322. $L30543:
  323. ; 1041 : }
  324. ; 1044 : dwPosition = pfSamplePos >> 12;
  325. mov edx, ebx
  326. mov ecx, DWORD PTR pfPitch
  327. ; 1045 : dwFract = pfSamplePos & 0xFFF;
  328. sar edx, 12 ; 0000000cH
  329. mov esi, ebx
  330. add ebx, ecx
  331. and esi, 4095 ; 00000fffH
  332. ; 1046 : pfSamplePos += pfPitch;
  333. mov ecx, DWORD PTR pcWave
  334. ; 1047 :
  335. ; 1048 : lLM = (long) pcWave[dwPosition];
  336. movsx eax, BYTE PTR [ecx+edx]
  337. ; 1049 : lM = ((pcWave[dwPosition+1] - lLM) * dwFract);
  338. ; 1050 : lM >>= 12;
  339. ; 1051 : lM += lLM;
  340. movsx edx, BYTE PTR [ecx+edx+1]
  341. sub edx, eax
  342. imul edx, esi
  343. ; 1052 : lLM = lM;
  344. ; 1053 : lLM *= vfLVolume;
  345. ; 1054 : lLM >>= 5; // Signal bumps up to 15 bits.
  346. sar edx, 12 ; 0000000cH
  347. mov esi, DWORD PTR vfLVolume
  348. add edx, eax
  349. ; 1072 : pBuffer[dwI] += (short) lLM;
  350. imul esi, edx
  351. sar esi, 5 ; 00000005H
  352. mov eax, DWORD PTR pBuf
  353. add WORD PTR [eax+edi*2], si
  354. mov esi, DWORD PTR vfRVolume
  355. jo overflow_l
  356. no_oflowl:
  357. ; 1078 : lM *= vfRVolume;
  358. ; 1079 : lM >>= 5;
  359. imul esi, edx
  360. ; 1080 : pBuffer[dwI+1] += (short) lM;
  361. ; 1085 : no_oflowr:
  362. ; 1087 : dwI += 2;
  363. sar esi, 5 ; 00000005H
  364. mov ecx, DWORD PTR pfPitch
  365. add WORD PTR [eax+edi*2+2], si
  366. mov edx, DWORD PTR pfPFract
  367. jo overflow_r
  368. no_oflowr:
  369. ; 978 :
  370. ; 979 : for (dwI = 0; dwI < dwLength; )
  371. add edi, 2
  372. jl $L30536
  373. $L30539:
  374. mov DWORD PTR dwI, edi
  375. mov DWORD PTR pfSamplePos, ebx
  376. }
  377. dwI += dwLength;
  378. #endif // _X86_
  379. m_vfLastLVolume = vfLVolume;
  380. m_vfLastRVolume = vfRVolume;
  381. m_pfLastPitch = pfPitch;
  382. m_pfLastSample = pfSamplePos;
  383. return (dwI >> 1);
  384. }
  385. /*****************************************************************************
  386. * CDigitalAudio::MixMono8()
  387. *****************************************************************************
  388. * Implement a mono eight-bit mix.
  389. * Heavily optimized for x86 non-MMX, plus C code for non-x86.
  390. */
  391. DWORD CDigitalAudio::MixMono8(short * pBuffer, DWORD dwLength,
  392. DWORD dwDeltaPeriod,VFRACT vfDeltaVolume,
  393. PFRACT pfDeltaPitch,PFRACT pfSampleLength,
  394. PFRACT pfLoopLength)
  395. {
  396. DWORD dwI;
  397. DWORD dwPosition;
  398. long lM;
  399. DWORD dwIncDelta = dwDeltaPeriod;
  400. VFRACT dwFract;
  401. char * pcWave = (char *) m_pnWave;
  402. PFRACT pfSamplePos = m_pfLastSample;
  403. VFRACT vfVolume = m_vfLastLVolume;
  404. PFRACT pfPitch = m_pfLastPitch;
  405. PFRACT pfPFract = pfPitch << 8;
  406. VFRACT vfVFract = vfVolume << 8; // Keep high res version around.
  407. #ifndef _X86_
  408. for (dwI = 0; dwI < dwLength; )
  409. {
  410. if (pfSamplePos >= pfSampleLength)
  411. {
  412. if (pfLoopLength)
  413. pfSamplePos -= pfLoopLength;
  414. else
  415. break;
  416. }
  417. dwIncDelta--;
  418. if (!dwIncDelta)
  419. {
  420. dwIncDelta = dwDeltaPeriod;
  421. pfPFract += pfDeltaPitch;
  422. pfPitch = pfPFract >> 8;
  423. vfVFract += vfDeltaVolume;
  424. vfVolume = vfVFract >> 8;
  425. }
  426. dwPosition = pfSamplePos >> 12;
  427. dwFract = pfSamplePos & 0xFFF;
  428. pfSamplePos += pfPitch;
  429. lM = pcWave[dwPosition];
  430. lM += ((pcWave[dwPosition + 1] - lM) * dwFract) >> 12;
  431. lM *= vfVolume;
  432. lM >>= 5;
  433. #ifndef _X86_
  434. #ifdef _ALPHA_
  435. int nBitmask;
  436. if( ALPHA_OVERFLOW & (nBitmask = __ADAWI( (short) lM, &pBuffer[dwI] )) ) {
  437. if( ALPHA_NEGATIVE & nBitmask ) {
  438. pBuffer[dwI] = 0x7FFF;
  439. }
  440. else pBuffer[dwI] = (short) 0x8000;
  441. }
  442. #else // !_ALPHA_
  443. // TODO -- overflow code on ia64 (+ axp64?)
  444. #endif // !_ALPHA_
  445. #else // _X86_ (dead code)
  446. // Keep this around so we can use it to generate new assembly code (see below...)
  447. pBuffer[dwI] += (short) lM;
  448. _asm{jno no_oflow}
  449. pBuffer[dwI] = 0x7fff;
  450. _asm{js no_oflow}
  451. pBuffer[dwI] = (short) 0x8000;
  452. no_oflow:
  453. #endif // _X86_ (dead code)
  454. dwI++;
  455. }
  456. #else // _X86_
  457. int i, a, b, c, total;
  458. short * pBuf = pBuffer + dwLength, *pBufX;
  459. dwI = - dwLength;
  460. _asm {
  461. ; 979 : for (dwI = 0; dwI < dwLength; )
  462. // Induction variables.
  463. mov edi, dwI
  464. mov ebx, DWORD PTR pfSamplePos
  465. // Previously set up.
  466. cmp DWORD PTR dwLength, 0
  467. mov edx, pfPFract
  468. mov ecx, DWORD PTR pfPitch
  469. je $L30539
  470. $L30536:
  471. cmp ebx, DWORD PTR pfSampleLength
  472. ; 981 : if (pfSamplePos >= pfSampleLength)
  473. mov esi, DWORD PTR dwIncDelta
  474. jge SHORT $L30540_
  475. $L30540:
  476. ; 987 : else
  477. ; 988 : break;
  478. ; 990 : dwIncDelta--;
  479. dec esi
  480. mov DWORD PTR dwIncDelta, esi
  481. ; 991 : if (!dwIncDelta)
  482. je SHORT $L30541_
  483. $L30541:
  484. // esi, edx, edi esi == dwIncDelta
  485. mov DWORD PTR i, 0
  486. ; 1010 : b = dwIncDelta;
  487. // esi = b == dwIncDelta
  488. ; 1011 : c = (pfSampleLength - pfSamplePos) / pfPitch;
  489. ; 1009 : a = dwLength - dwI; // Remaining span.
  490. mov edx, edi
  491. neg edx
  492. ; 1017 : if (b < a && b < c)
  493. cmp esi, edx
  494. jge try_ax
  495. mov eax, ecx
  496. imul eax, esi
  497. add eax, ebx
  498. cmp eax, DWORD PTR pfSampleLength
  499. jge try_c
  500. ; 1019 : i = b;
  501. cmp esi, 3
  502. jl got_it
  503. mov DWORD PTR i, esi
  504. jmp SHORT got_it
  505. ; 1013 : if (a < b && a < c)
  506. try_a:
  507. cmp edx, esi
  508. jge try_c
  509. try_ax:
  510. mov eax, edx
  511. imul eax, ecx
  512. add eax, ebx
  513. cmp eax, DWORD PTR pfSampleLength
  514. jge try_c
  515. ; 1015 : i = a;
  516. cmp edx, 3
  517. jl got_it
  518. mov DWORD PTR i, edx
  519. jmp SHORT got_it
  520. ; 1021 : else if (c < a && c < b)
  521. try_c:
  522. push edx
  523. mov eax, DWORD PTR pfSampleLength
  524. sub eax, ebx
  525. cdq
  526. idiv ecx // eax == c
  527. pop edx
  528. cmp eax, edx
  529. jge got_it
  530. try_cx:
  531. cmp eax, esi
  532. jge got_it
  533. ; 1023 : i = c;
  534. cmp eax, 3
  535. jl $L30543
  536. mov DWORD PTR i, eax
  537. got_it:
  538. mov edx, DWORD PTR i
  539. mov eax, DWORD PTR pBuf
  540. dec edx
  541. jl $L30543
  542. sub DWORD PTR dwIncDelta, edx
  543. ; 1093 : return (dwI);
  544. ; 1094 : }
  545. lea edx, [edx+1] // Current span.
  546. lea eax, [eax+edi*2] // Starting position.
  547. add edi, edx // Remaining span.
  548. lea eax, [eax+edx*2] // New ending position.
  549. push edi
  550. mov edi, edx // Current span.
  551. mov DWORD PTR pBufX, eax
  552. neg edi
  553. $L30797:
  554. ; 1005 : do
  555. ; 1010 : dwPosition = pfSamplePos >> 12;
  556. ; 1011 : dwFract = pfSamplePos & 0xFFF;
  557. mov edx, ebx
  558. mov esi, ebx
  559. add ebx, ecx
  560. mov ecx, DWORD PTR pcWave
  561. ; 1012 : pfSamplePos += pfPitch;
  562. sar edx, 12 ; 0000000cH
  563. and esi, 4095 ; 00000fffH
  564. ; 1013 :
  565. ; 1014 : lLM = (long) pcWave[dwPosition];
  566. movsx eax, BYTE PTR [ecx+edx]
  567. ; 1015 : lM = ((pcWave[dwPosition+1] - lLM) * dwFract);
  568. ; 1016 : lM >>= 12;
  569. ; 1017 : lM += lLM;
  570. movsx edx, BYTE PTR [ecx+edx+1]
  571. sub edx, eax
  572. ; 1018 : lLM = lM;
  573. ; 1019 : lLM *= vfLVolume;
  574. ; 1020 : lLM >>= 5; // Signal bumps up to 15 bits.
  575. ; 1022 : pBuffer[dwI] += (short) lLM;
  576. ; 1027 : no_oflowx:
  577. ; 1037 : ++dwI;
  578. imul edx, esi
  579. sar edx, 12 ; 0000000cH
  580. mov esi, DWORD PTR vfVolume
  581. mov ecx, DWORD PTR pfPitch
  582. add edx, eax
  583. imul esi, edx
  584. sar esi, 5 ; 00000005H
  585. mov eax, DWORD PTR pBufX
  586. add WORD PTR [eax+edi*2], si
  587. jo overflow_x
  588. no_oflowx:
  589. inc edi
  590. jne SHORT $L30797
  591. pop edi
  592. ; 1039 : ++dwIncDelta;
  593. ; 1040 : continue;
  594. mov edx, DWORD PTR pfPFract
  595. cmp edi, 0
  596. jl SHORT $L30536
  597. jmp SHORT $L30539
  598. $L30540_:
  599. ; 982 : {
  600. ; 983 : if (pfLoopLength)
  601. cmp DWORD PTR pfLoopLength, 0
  602. je $L30539
  603. ; 984 : {
  604. ; 985 : pfSamplePos -= pfLoopLength;
  605. sub ebx, DWORD PTR pfLoopLength
  606. jmp $L30540
  607. $L30541_:
  608. ; 994 : pfPFract += pfDeltaPitch;
  609. mov ecx, DWORD PTR pfDeltaPitch
  610. mov esi, DWORD PTR vfDeltaVolume
  611. add ecx, edx
  612. mov edx, DWORD PTR vfVFract
  613. ; 995 : pfPitch = pfPFract >> 8;
  614. ; 996 : vfVFract += vfDeltaVolume;
  615. mov DWORD PTR pfPFract, ecx
  616. add edx, esi
  617. ; 997 : vfLVolume = vfLVFract >> 8;
  618. sar ecx, 8
  619. mov DWORD PTR vfVFract, edx
  620. sar edx, 8
  621. mov esi, DWORD PTR dwDeltaPeriod
  622. mov DWORD PTR vfVolume, edx
  623. mov DWORD PTR pfPitch, ecx
  624. mov DWORD PTR dwIncDelta, esi
  625. ; 993 : dwIncDelta = dwDeltaPeriod;
  626. jmp $L30541
  627. // Handle truncation.
  628. overflow_:
  629. mov WORD PTR [eax+edi*2], 0x7fff
  630. js no_oflow
  631. mov WORD PTR [eax+edi*2], 0x8000
  632. jmp no_oflow
  633. overflow_x:
  634. mov WORD PTR [eax+edi*2], 0x7fff
  635. js no_oflowx
  636. mov WORD PTR [eax+edi*2], 0x8000
  637. jmp no_oflowx
  638. $L30543:
  639. ; 1044 : dwPosition = pfSamplePos >> 12;
  640. mov edx, ebx
  641. mov ecx, DWORD PTR pfPitch
  642. ; 1045 : dwFract = pfSamplePos & 0xFFF;
  643. sar edx, 12 ; 0000000cH
  644. mov esi, ebx
  645. add ebx, ecx
  646. and esi, 4095 ; 00000fffH
  647. ; 1046 : pfSamplePos += pfPitch;
  648. mov ecx, DWORD PTR pcWave
  649. ; 1047 :
  650. ; 1048 : lLM = (long) pcWave[dwPosition];
  651. movsx eax, BYTE PTR [ecx+edx]
  652. ; 1049 : lM = ((pcWave[dwPosition+1] - lLM) * dwFract);
  653. ; 1050 : lM >>= 12;
  654. ; 1051 : lM += lLM;
  655. movsx edx, BYTE PTR [ecx+edx+1]
  656. sub edx, eax
  657. imul edx, esi
  658. ; 1052 : lLM = lM;
  659. ; 1053 : lLM *= vfLVolume;
  660. ; 1054 : lLM >>= 5; // Signal bumps up to 15 bits.
  661. sar edx, 12 ; 0000000cH
  662. mov esi, DWORD PTR vfVolume
  663. add edx, eax
  664. ; 1072 : pBuffer[dwI] += (short) lLM;
  665. imul esi, edx
  666. sar esi, 5 ; 00000005H
  667. mov eax, DWORD PTR pBuf
  668. add WORD PTR [eax+edi*2], si
  669. jo overflow_
  670. no_oflow:
  671. inc edi
  672. mov edx, DWORD PTR pfPFract
  673. ; 979 : for (dwI = 0; dwI < dwLength; )
  674. mov ecx, DWORD PTR pfPitch
  675. jl $L30536
  676. $L30539:
  677. mov DWORD PTR dwI, edi
  678. mov DWORD PTR pfSamplePos, ebx
  679. }
  680. dwI += dwLength;
  681. #endif // _X86_
  682. m_vfLastLVolume = vfVolume;
  683. m_vfLastRVolume = vfVolume; // !!! is this right?
  684. m_pfLastPitch = pfPitch;
  685. m_pfLastSample = pfSamplePos;
  686. return (dwI);
  687. }
  688. /*****************************************************************************
  689. * CDigitalAudio::Mix16()
  690. *****************************************************************************
  691. * Implement a stereo sixteen-bit mix.
  692. * Heavily optimized for x86 non-MMX, plus C code for non-x86.
  693. */
  694. DWORD CDigitalAudio::Mix16(short * pBuffer, DWORD dwLength,
  695. DWORD dwDeltaPeriod, VFRACT vfDeltaLVolume,
  696. VFRACT vfDeltaRVolume,PFRACT pfDeltaPitch,
  697. PFRACT pfSampleLength,PFRACT pfLoopLength)
  698. {
  699. DWORD dwI;
  700. DWORD dwPosition;
  701. long lA;
  702. long lM;
  703. DWORD dwIncDelta = dwDeltaPeriod;
  704. VFRACT dwFract;
  705. short * pcWave = m_pnWave;
  706. PFRACT pfSamplePos = m_pfLastSample;
  707. VFRACT vfLVolume = m_vfLastLVolume;
  708. VFRACT vfRVolume = m_vfLastRVolume;
  709. PFRACT pfPitch = m_pfLastPitch;
  710. PFRACT pfPFract = pfPitch << 8;
  711. VFRACT vfLVFract = vfLVolume << 8; // Keep high res version around.
  712. VFRACT vfRVFract = vfRVolume << 8;
  713. dwLength <<= 1;
  714. #ifndef _X86_
  715. for (dwI = 0; dwI < dwLength; )
  716. {
  717. if (pfSamplePos >= pfSampleLength)
  718. {
  719. if (pfLoopLength)
  720. {
  721. pfSamplePos -= pfLoopLength;
  722. }
  723. else
  724. break;
  725. }
  726. dwIncDelta--;
  727. if (!dwIncDelta)
  728. {
  729. dwIncDelta = dwDeltaPeriod;
  730. pfPFract += pfDeltaPitch;
  731. pfPitch = pfPFract >> 8;
  732. vfLVFract += vfDeltaLVolume;
  733. vfLVolume = vfLVFract >> 8;
  734. vfRVFract += vfDeltaRVolume;
  735. vfRVolume = vfRVFract >> 8;
  736. }
  737. dwPosition = pfSamplePos >> 12;
  738. dwFract = pfSamplePos & 0xFFF;
  739. pfSamplePos += pfPitch;
  740. lA = (long) pcWave[dwPosition];
  741. lM = ((pcWave[dwPosition+1] - lA) * dwFract);
  742. lM >>= 12;
  743. lM += lA;
  744. lA = lM;
  745. lA *= vfLVolume;
  746. lA >>= 13; // Signal bumps up to 15 bits.
  747. lM *= vfRVolume;
  748. lM >>= 13;
  749. #ifndef _X86_
  750. #ifdef _ALPHA_
  751. int nBitmask;
  752. if( ALPHA_OVERFLOW & (nBitmask = __ADAWI( (short) lA, &pBuffer[dwI] )) ) {
  753. if( ALPHA_NEGATIVE & nBitmask ) {
  754. pBuffer[dwI] = 0x7FFF;
  755. }
  756. else pBuffer[dwI] = (short) 0x8000;
  757. }
  758. if( ALPHA_OVERFLOW & (nBitmask = __ADAWI( (short) lM, &pBuffer[dwI+1] )) ) {
  759. if( ALPHA_NEGATIVE & nBitmask ) {
  760. pBuffer[dwI+1] = 0x7FFF;
  761. }
  762. else pBuffer[dwI+1] = (short) 0x8000;
  763. }
  764. #else // !_ALPHA_
  765. // TODO -- overflow detection on ia64 (+ axp64?)
  766. #endif // !_ALPHA_
  767. #else // _X86_ (dead code)
  768. // Keep this around so we can use it to generate new assembly code (see below...)
  769. pBuffer[dwI] += (short) lA;
  770. _asm{jno no_oflowl}
  771. pBuffer[dwI] = 0x7fff;
  772. _asm{js no_oflowl}
  773. pBuffer[dwI] = (short) 0x8000;
  774. no_oflowl:
  775. pBuffer[dwI+1] += (short) lM;
  776. _asm{jno no_oflowr}
  777. pBuffer[dwI+1] = 0x7fff;
  778. _asm{js no_oflowr}
  779. pBuffer[dwI+1] = (short) 0x8000;
  780. no_oflowr:
  781. #endif // _X86_ (dead code)
  782. dwI += 2;
  783. }
  784. #else // _X86_
  785. int i, a, b, c, total;
  786. short * pBuf = pBuffer + dwLength, *pBufX;
  787. dwI = - dwLength;
  788. _asm {
  789. ; 979 : for (dwI = 0; dwI < dwLength; )
  790. // Induction variables.
  791. mov edi, dwI
  792. mov ebx, DWORD PTR pfSamplePos
  793. // Previously set up.
  794. cmp DWORD PTR dwLength, 0
  795. mov edx, pfPFract
  796. mov ecx, DWORD PTR pfPitch
  797. je $L30539
  798. $L30536:
  799. cmp ebx, DWORD PTR pfSampleLength
  800. ; 981 : if (pfSamplePos >= pfSampleLength)
  801. mov esi, DWORD PTR dwIncDelta
  802. jge SHORT $L30540_
  803. $L30540:
  804. ; 987 : else
  805. ; 988 : break;
  806. ; 990 : dwIncDelta--;
  807. dec esi
  808. mov DWORD PTR dwIncDelta, esi
  809. ; 991 : if (!dwIncDelta)
  810. je SHORT $L30541_
  811. $L30541:
  812. // esi, edx, edi esi == dwIncDelta
  813. mov DWORD PTR i, 0
  814. ; 1010 : b = dwIncDelta;
  815. // esi = b == dwIncDelta
  816. ; 1011 : c = (pfSampleLength - pfSamplePos) / pfPitch;
  817. ; 1009 : a = (dwLength - dwI) / 2; // Remaining span.
  818. mov edx, edi
  819. neg edx
  820. shr edx, 1 // edx = a
  821. ; 1017 : if (b < a && b < c)
  822. cmp esi, edx
  823. jge try_ax
  824. mov eax, ecx
  825. imul eax, esi
  826. add eax, ebx
  827. cmp eax, DWORD PTR pfSampleLength
  828. jge try_c
  829. ; 1019 : i = b;
  830. cmp esi, 3
  831. jl got_it
  832. mov DWORD PTR i, esi
  833. jmp SHORT got_it
  834. ; 1013 : if (a < b && a < c)
  835. try_a:
  836. cmp edx, esi
  837. jge try_c
  838. try_ax:
  839. mov eax, edx
  840. imul eax, ecx
  841. add eax, ebx
  842. cmp eax, DWORD PTR pfSampleLength
  843. jge try_c
  844. ; 1015 : i = a;
  845. cmp edx, 3
  846. jl got_it
  847. mov DWORD PTR i, edx
  848. jmp SHORT got_it
  849. ; 1021 : else if (c < a && c < b)
  850. try_c:
  851. push edx
  852. mov eax, DWORD PTR pfSampleLength
  853. sub eax, ebx
  854. cdq
  855. idiv ecx // eax == c
  856. pop edx
  857. cmp eax, edx
  858. jge got_it
  859. try_cx:
  860. cmp eax, esi
  861. jge got_it
  862. ; 1023 : i = c;
  863. cmp eax, 3
  864. jl $L30543
  865. mov DWORD PTR i, eax
  866. got_it:
  867. mov edx, DWORD PTR i
  868. mov eax, DWORD PTR pBuf
  869. dec edx
  870. jl $L30543
  871. sub DWORD PTR dwIncDelta, edx
  872. ; 1093 : return (dwI >> 1);
  873. ; 1094 : }
  874. lea edx, [edx*2+2] // Current span.
  875. lea eax, [eax+edi*2] // Starting position.
  876. add edi, edx // Remaining span.
  877. lea eax, [eax+edx*2] // New ending position.
  878. push edi
  879. mov edi, edx // Current span.
  880. mov DWORD PTR pBufX, eax
  881. neg edi
  882. $L30797:
  883. ; 1005 : do
  884. ; 1010 : dwPosition = pfSamplePos >> 12;
  885. ; 1011 : dwFract = pfSamplePos & 0xFFF;
  886. mov edx, ebx
  887. mov esi, ebx
  888. add ebx, ecx
  889. mov ecx, DWORD PTR pcWave
  890. ; 1012 : pfSamplePos += pfPitch;
  891. sar edx, 12 ; 0000000cH
  892. and esi, 4095 ; 00000fffH
  893. ; 1014 : lA = (long) pcWave[dwPosition];
  894. movsx eax, WORD PTR [ecx+edx*2]
  895. ; 1015 : lM = ((pcWave[dwPosition+1] - lA) * dwFract);
  896. ; 1016 : lM >>= 12;
  897. ; 1017 : lM += lA;
  898. movsx edx, WORD PTR [ecx+edx*2+2]
  899. sub edx, eax
  900. ; 1018 : lA = lM;
  901. ; 1019 : lA *= vfLVolume;
  902. ; 1020 : lA >>= 13; // Signal bumps up to 15 bits.
  903. ; 1022 : pBuffer[dwI] += (short) lA;
  904. ; 1027 : no_oflowlx:
  905. ; 1028 : lM *= vfRVolume;
  906. ; 1029 : lM >>= 13;
  907. ; 1030 : pBuffer[dwI+1] += (short) lM;
  908. ; 1035 : no_oflowrx:
  909. ; 1037 : dwI += 2;
  910. imul edx, esi
  911. sar edx, 12 ; 0000000cH
  912. mov esi, DWORD PTR vfLVolume
  913. add edx, eax
  914. mov eax, DWORD PTR pBufX
  915. imul esi, edx
  916. sar esi, 13 ; 0000000dH
  917. add WORD PTR [eax+edi*2], si
  918. mov esi, DWORD PTR vfRVolume
  919. jo overflow_lx
  920. no_oflowlx:
  921. imul esi, edx
  922. ; 1038 : } while (--dwIncDelta);
  923. sar esi, 13 ; 0000000dH
  924. mov ecx, DWORD PTR pfPitch
  925. add WORD PTR [eax+edi*2+2], si
  926. jo overflow_rx
  927. no_oflowrx:
  928. add edi, 2
  929. jne SHORT $L30797
  930. pop edi
  931. ; 1039 : ++dwIncDelta;
  932. ; 1040 : continue;
  933. mov edx, DWORD PTR pfPFract
  934. cmp edi, 0
  935. jl SHORT $L30536
  936. jmp SHORT $L30539
  937. $L30540_:
  938. ; 982 : {
  939. ; 983 : if (pfLoopLength)
  940. cmp DWORD PTR pfLoopLength, 0
  941. je $L30539
  942. ; 985 : pfSamplePos -= pfLoopLength;
  943. sub ebx, DWORD PTR pfLoopLength
  944. jmp $L30540
  945. $L30541_:
  946. ; 994 : pfPFract += pfDeltaPitch;
  947. mov ecx, DWORD PTR pfDeltaPitch
  948. mov esi, DWORD PTR vfDeltaLVolume
  949. add ecx, edx
  950. mov edx, DWORD PTR vfLVFract
  951. ; 995 : pfPitch = pfPFract >> 8;
  952. ; 996 : vfLVFract += vfDeltaLVolume;
  953. mov DWORD PTR pfPFract, ecx
  954. add edx, esi
  955. ; 997 : vfLVolume = vfLVFract >> 8;
  956. ; 998 : vfRVFract += vfDeltaRVolume;
  957. sar ecx, 8
  958. mov DWORD PTR vfLVFract, edx
  959. sar edx, 8
  960. mov esi, DWORD PTR vfDeltaRVolume
  961. mov DWORD PTR vfLVolume, edx
  962. mov edx, DWORD PTR vfRVFract
  963. add edx, esi
  964. mov DWORD PTR pfPitch, ecx
  965. mov DWORD PTR vfRVFract, edx
  966. mov esi, DWORD PTR dwDeltaPeriod
  967. ; 999 : vfRVolume = vfRVFract >> 8;
  968. sar edx, 8
  969. mov DWORD PTR dwIncDelta, esi
  970. ; 993 : dwIncDelta = dwDeltaPeriod;
  971. mov DWORD PTR vfRVolume, edx
  972. jmp $L30541
  973. // Handle truncation.
  974. overflow_l:
  975. mov WORD PTR [eax+edi*2], 0x7fff
  976. js no_oflowl
  977. mov WORD PTR [eax+edi*2], 0x8000
  978. jmp no_oflowl
  979. overflow_r:
  980. mov WORD PTR [eax+edi*2+2], 0x7fff
  981. js no_oflowr
  982. mov WORD PTR [eax+edi*2+2], 0x8000
  983. jmp no_oflowr
  984. overflow_lx:
  985. mov WORD PTR [eax+edi*2], 0x7fff
  986. js no_oflowlx
  987. mov WORD PTR [eax+edi*2], 0x8000
  988. jmp no_oflowlx
  989. overflow_rx:
  990. mov WORD PTR [eax+edi*2+2], 0x7fff
  991. js no_oflowrx
  992. mov WORD PTR [eax+edi*2+2], 0x8000
  993. jmp no_oflowrx
  994. $L30543:
  995. ; 1044 : dwPosition = pfSamplePos >> 12;
  996. mov edx, ebx
  997. mov ecx, DWORD PTR pfPitch
  998. ; 1045 : dwFract = pfSamplePos & 0xFFF;
  999. sar edx, 12 ; 0000000cH
  1000. mov esi, ebx
  1001. and esi, 4095 ; 00000fffH
  1002. add ebx, ecx
  1003. ; 1046 : pfSamplePos += pfPitch;
  1004. mov ecx, DWORD PTR pcWave
  1005. ; 1047 :
  1006. ; 1048 : lA = (long) pcWave[dwPosition];
  1007. movsx eax, WORD PTR [ecx+edx*2]
  1008. ; 1049 : lM = ((pcWave[dwPosition+1] - lA) * dwFract);
  1009. ; 1050 : lM >>= 12;
  1010. ; 1051 : lM += lA;
  1011. movsx edx, WORD PTR [ecx+edx*2+2]
  1012. sub edx, eax
  1013. imul edx, esi
  1014. ; 1052 : lA = lM;
  1015. ; 1053 : lA *= vfLVolume;
  1016. ; 1054 : lA >>= 13; // Signal bumps up to 15 bits.
  1017. sar edx, 12 ; 0000000cH
  1018. mov esi, DWORD PTR vfLVolume
  1019. add edx, eax
  1020. ; 1072 : pBuffer[dwI] += (short) lA;
  1021. imul esi, edx
  1022. sar esi, 13 ; 0000000dH
  1023. mov eax, DWORD PTR pBuf
  1024. add WORD PTR [eax+edi*2], si
  1025. mov esi, DWORD PTR vfRVolume
  1026. jo overflow_l
  1027. no_oflowl:
  1028. ; 1077 : no_oflowl:
  1029. ; 1078 : lM *= vfRVolume;
  1030. ; 1079 : lM >>= 13;
  1031. imul esi, edx
  1032. ; 1080 : pBuffer[dwI+1] += (short) lM;
  1033. ; 1085 : no_oflowr:
  1034. ; 1086 : #endif /* _ALPHA */
  1035. ; 1087 : dwI += 2;
  1036. sar esi, 13 ; 0000000dH
  1037. mov ecx, DWORD PTR pfPitch
  1038. add WORD PTR [eax+edi*2+2], si
  1039. mov edx, DWORD PTR pfPFract
  1040. jo overflow_r
  1041. no_oflowr:
  1042. add edi, 2
  1043. ; 978 :
  1044. ; 979 : for (dwI = 0; dwI < dwLength; )
  1045. jl $L30536
  1046. $L30539:
  1047. mov DWORD PTR dwI, edi
  1048. mov DWORD PTR pfSamplePos, ebx
  1049. }
  1050. dwI += dwLength;
  1051. #endif // _X86_
  1052. m_vfLastLVolume = vfLVolume;
  1053. m_vfLastRVolume = vfRVolume;
  1054. m_pfLastPitch = pfPitch;
  1055. m_pfLastSample = pfSamplePos;
  1056. return (dwI >> 1);
  1057. }
  1058. /*****************************************************************************
  1059. * CDigitalAudio::MixMono16()
  1060. *****************************************************************************
  1061. * Implement a mono sixteen-bit mix.
  1062. * Heavily optimized for x86 non-MMX, plus C code for non-x86.
  1063. */
  1064. DWORD CDigitalAudio::MixMono16(short * pBuffer, DWORD dwLength,
  1065. DWORD dwDeltaPeriod,VFRACT vfDeltaVolume,
  1066. PFRACT pfDeltaPitch,PFRACT pfSampleLength,
  1067. PFRACT pfLoopLength)
  1068. {
  1069. DWORD dwI;
  1070. DWORD dwPosition;
  1071. long lA;//, lB;
  1072. long lM;
  1073. DWORD dwIncDelta = dwDeltaPeriod;
  1074. VFRACT dwFract;
  1075. short * pcWave = m_pnWave;
  1076. PFRACT pfSamplePos = m_pfLastSample;
  1077. VFRACT vfVolume = m_vfLastLVolume;
  1078. PFRACT pfPitch = m_pfLastPitch;
  1079. PFRACT pfPFract = pfPitch << 8;
  1080. VFRACT vfVFract = vfVolume << 8; // Keep high res version around.
  1081. #ifndef _X86_
  1082. for (dwI = 0; dwI < dwLength;)
  1083. {
  1084. if (pfSamplePos >= pfSampleLength)
  1085. {
  1086. if (pfLoopLength)
  1087. pfSamplePos -= pfLoopLength;
  1088. else
  1089. break;
  1090. }
  1091. dwIncDelta--;
  1092. if (!dwIncDelta)
  1093. {
  1094. dwIncDelta = dwDeltaPeriod;
  1095. pfPFract += pfDeltaPitch;
  1096. pfPitch = pfPFract >> 8;
  1097. vfVFract += vfDeltaVolume;
  1098. vfVolume = vfVFract >> 8;
  1099. }
  1100. dwPosition = pfSamplePos >> 12;
  1101. dwFract = pfSamplePos & 0xFFF;
  1102. pfSamplePos += pfPitch;
  1103. lA = (long) pcWave[dwPosition];
  1104. lM = (((pcWave[dwPosition+1] - lA) * dwFract) >> 12) + lA;
  1105. lM *= vfVolume;
  1106. lM >>= 13; // Signal bumps up to 12 bits.
  1107. #ifndef _X86_
  1108. #ifdef _ALPHA_
  1109. int nBitmask;
  1110. if( ALPHA_OVERFLOW & (nBitmask = __ADAWI( (short) lM, &pBuffer[dwI] )) ) {
  1111. if( ALPHA_NEGATIVE & nBitmask ) {
  1112. pBuffer[dwI] = 0x7FFF;
  1113. }
  1114. else pBuffer[dwI] = (short) 0x8000;
  1115. }
  1116. #else // !_ALPHA_
  1117. // TODO -- overflow detection for ia64 (+ axp64?)
  1118. #endif // !_ALPHA_
  1119. #else // _X86_ (dead code)
  1120. // Keep this around so we can use it to generate new assembly code (see below...)
  1121. pBuffer[dwI] += (short) lM;
  1122. _asm{jno no_oflow}
  1123. pBuffer[dwI] = 0x7fff;
  1124. _asm{js no_oflow}
  1125. pBuffer[dwI] = (short) 0x8000;
  1126. no_oflow:
  1127. #endif // _X86 (dead code)
  1128. dwI++;
  1129. }
  1130. #else // _X86_
  1131. int i, a, b, c, total;
  1132. short * pBuf = pBuffer + dwLength, *pBufX;
  1133. dwI = - dwLength;
  1134. _asm {
  1135. ; 979 : for (dwI = 0; dwI < dwLength; )
  1136. // Induction variables.
  1137. mov edi, dwI
  1138. mov ebx, DWORD PTR pfSamplePos
  1139. // Previously set up.
  1140. cmp DWORD PTR dwLength, 0
  1141. mov edx, pfPFract
  1142. mov ecx, DWORD PTR pfPitch
  1143. je $L30539
  1144. $L30536:
  1145. cmp ebx, DWORD PTR pfSampleLength
  1146. ; 981 : if (pfSamplePos >= pfSampleLength)
  1147. mov esi, DWORD PTR dwIncDelta
  1148. jge SHORT $L30540_
  1149. $L30540:
  1150. ; 987 : else
  1151. ; 988 : break;
  1152. ; 990 : dwIncDelta--;
  1153. dec esi
  1154. mov DWORD PTR dwIncDelta, esi
  1155. ; 991 : if (!dwIncDelta)
  1156. je SHORT $L30541_
  1157. $L30541:
  1158. // esi, edx, edi esi == dwIncDelta
  1159. mov DWORD PTR i, 0
  1160. ; 1010 : b = dwIncDelta;
  1161. // esi = b == dwIncDelta
  1162. ; 1011 : c = (pfSampleLength - pfSamplePos) / pfPitch;
  1163. ; 1009 : a = dwLength - dwI; // Remaining span.
  1164. mov edx, edi
  1165. neg edx
  1166. ; 1017 : if (b < a && b < c)
  1167. cmp esi, edx
  1168. jge try_ax
  1169. mov eax, ecx
  1170. imul eax, esi
  1171. add eax, ebx
  1172. cmp eax, DWORD PTR pfSampleLength
  1173. jge try_c
  1174. ; 1019 : i = b;
  1175. cmp esi, 3
  1176. jl got_it
  1177. mov DWORD PTR i, esi
  1178. jmp SHORT got_it
  1179. ; 1013 : if (a < b && a < c)
  1180. try_a:
  1181. cmp edx, esi
  1182. jge try_c
  1183. try_ax:
  1184. mov eax, edx
  1185. imul eax, ecx
  1186. add eax, ebx
  1187. cmp eax, DWORD PTR pfSampleLength
  1188. jge try_c
  1189. ; 1015 : i = a;
  1190. cmp edx, 3
  1191. jl got_it
  1192. mov DWORD PTR i, edx
  1193. jmp SHORT got_it
  1194. ; 1021 : else if (c < a && c < b)
  1195. try_c:
  1196. push edx
  1197. mov eax, DWORD PTR pfSampleLength
  1198. sub eax, ebx
  1199. cdq
  1200. idiv ecx // eax == c
  1201. pop edx
  1202. cmp eax, edx
  1203. jge got_it
  1204. try_cx:
  1205. cmp eax, esi
  1206. jge got_it
  1207. ; 1023 : i = c;
  1208. cmp eax, 3
  1209. jl $L30543
  1210. mov DWORD PTR i, eax
  1211. got_it:
  1212. mov edx, DWORD PTR i
  1213. mov eax, DWORD PTR pBuf
  1214. dec edx
  1215. jl $L30543
  1216. sub DWORD PTR dwIncDelta, edx
  1217. ; 1093 : return (dwI);
  1218. ; 1094 : }
  1219. lea edx, [edx+1] // Current span.
  1220. lea eax, [eax+edi*2] // Starting position.
  1221. add edi, edx // Remaining span.
  1222. lea eax, [eax+edx*2] // New ending position.
  1223. push edi
  1224. mov edi, edx // Current span.
  1225. mov DWORD PTR pBufX, eax
  1226. neg edi
  1227. $L30797:
  1228. ; 1005 : do
  1229. ; 1010 : dwPosition = pfSamplePos >> 12;
  1230. ; 1011 : dwFract = pfSamplePos & 0xFFF;
  1231. mov edx, ebx
  1232. mov esi, ebx
  1233. add ebx, ecx
  1234. mov ecx, DWORD PTR pcWave
  1235. ; 1012 : pfSamplePos += pfPitch;
  1236. sar edx, 12 ; 0000000cH
  1237. and esi, 4095 ; 00000fffH
  1238. ; 1013 :
  1239. ; 1014 : lA = (long) pcWave[dwPosition];
  1240. movsx eax, WORD PTR [ecx+edx*2]
  1241. ; 1015 : lM = ((pcWave[dwPosition+1] - lA) * dwFract);
  1242. ; 1016 : lM >>= 12;
  1243. ; 1017 : lM += lA;
  1244. movsx edx, WORD PTR [ecx+edx*2+2]
  1245. sub edx, eax
  1246. ; 1018 : lA = lM;
  1247. ; 1019 : lA *= vfLVolume;
  1248. ; 1020 : lA >>= 13; // Signal bumps up to 15 bits.
  1249. ; 1022 : pBuffer[dwI] += (short) lA;
  1250. ; 1027 : no_oflowx:
  1251. ; 1037 : ++dwI;
  1252. imul edx, esi
  1253. sar edx, 12 ; 0000000cH
  1254. mov esi, DWORD PTR vfVolume
  1255. add edx, eax
  1256. mov ecx, DWORD PTR pfPitch
  1257. imul esi, edx
  1258. sar esi, 13 ; 0000000dH
  1259. mov eax, DWORD PTR pBufX
  1260. add WORD PTR [eax+edi*2], si
  1261. jo overflow_x
  1262. no_oflowx:
  1263. ; 1038 : } while (--dwIncDelta);
  1264. inc edi
  1265. jne SHORT $L30797
  1266. pop edi
  1267. ; 1039 : ++dwIncDelta;
  1268. ; 1040 : continue;
  1269. mov edx, DWORD PTR pfPFract
  1270. cmp edi, 0
  1271. jl SHORT $L30536
  1272. jmp SHORT $L30539
  1273. $L30540_:
  1274. ; 983 : if (pfLoopLength)
  1275. cmp DWORD PTR pfLoopLength, 0
  1276. je $L30539
  1277. ; 985 : pfSamplePos -= pfLoopLength;
  1278. sub ebx, DWORD PTR pfLoopLength
  1279. jmp $L30540
  1280. $L30541_:
  1281. ; 994 : pfPFract += pfDeltaPitch;
  1282. mov ecx, DWORD PTR pfDeltaPitch
  1283. mov esi, DWORD PTR vfDeltaVolume
  1284. add ecx, edx
  1285. mov edx, DWORD PTR vfVFract
  1286. ; 995 : pfPitch = pfPFract >> 8;
  1287. ; 996 : vfVFract += vfDeltaVolume;
  1288. mov DWORD PTR pfPFract, ecx
  1289. add edx, esi
  1290. ; 997 : vfVolume = vfVFract >> 8;
  1291. sar ecx, 8
  1292. mov DWORD PTR vfVFract, edx
  1293. sar edx, 8
  1294. mov esi, DWORD PTR dwDeltaPeriod
  1295. mov DWORD PTR vfVolume, edx
  1296. mov DWORD PTR pfPitch, ecx
  1297. mov DWORD PTR dwIncDelta, esi
  1298. ; 993 : dwIncDelta = dwDeltaPeriod;
  1299. jmp $L30541
  1300. // Handle truncation.
  1301. overflow_:
  1302. mov WORD PTR [eax+edi*2], 0x7fff
  1303. js no_oflow
  1304. mov WORD PTR [eax+edi*2], 0x8000
  1305. jmp no_oflow
  1306. overflow_x:
  1307. mov WORD PTR [eax+edi*2], 0x7fff
  1308. js no_oflowx
  1309. mov WORD PTR [eax+edi*2], 0x8000
  1310. jmp no_oflowx
  1311. $L30543:
  1312. ; 1044 : dwPosition = pfSamplePos >> 12;
  1313. mov edx, ebx
  1314. mov ecx, DWORD PTR pfPitch
  1315. ; 1045 : dwFract = pfSamplePos & 0xFFF;
  1316. sar edx, 12 ; 0000000cH
  1317. mov esi, ebx
  1318. and esi, 4095 ; 00000fffH
  1319. add ebx, ecx
  1320. ; 1046 : pfSamplePos += pfPitch;
  1321. mov ecx, DWORD PTR pcWave
  1322. ; 1047 :
  1323. ; 1048 : lA = (long) pcWave[dwPosition];
  1324. movsx eax, WORD PTR [ecx+edx*2]
  1325. ; 1049 : lM = ((pcWave[dwPosition+1] - lA) * dwFract);
  1326. ; 1050 : lM >>= 12;
  1327. ; 1051 : lM += lA;
  1328. movsx edx, WORD PTR [ecx+edx*2+2]
  1329. sub edx, eax
  1330. imul edx, esi
  1331. ; 1052 : lA = lM;
  1332. ; 1053 : lA *= vfVolume;
  1333. ; 1054 : lA >>= 13; // Signal bumps up to 15 bits.
  1334. sar edx, 12 ; 0000000cH
  1335. mov esi, DWORD PTR vfVolume
  1336. add edx, eax
  1337. ; 1072 : pBuffer[dwI] += (short) lA;
  1338. imul esi, edx
  1339. sar esi, 13 ; 0000000dH
  1340. mov eax, DWORD PTR pBuf
  1341. add WORD PTR [eax+edi*2], si
  1342. jo overflow_
  1343. no_oflow:
  1344. ; 1077 : no_oflowl:
  1345. ; 1087 : ++dwI;
  1346. inc edi
  1347. mov edx, DWORD PTR pfPFract
  1348. ; 979 : for (dwI = 0; dwI < dwLength; )
  1349. mov ecx, DWORD PTR pfPitch
  1350. jl $L30536
  1351. $L30539:
  1352. mov DWORD PTR dwI, edi
  1353. mov DWORD PTR pfSamplePos, ebx
  1354. }
  1355. dwI += dwLength;
  1356. #endif // _X86_
  1357. m_vfLastLVolume = vfVolume;
  1358. m_vfLastRVolume = vfVolume; // !!! is this right?
  1359. m_pfLastPitch = pfPitch;
  1360. m_pfLastSample = pfSamplePos;
  1361. return (dwI);
  1362. }