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.

2134 lines
43 KiB

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