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.

228 lines
5.2 KiB

  1. // Mixc.cpp
  2. // Copyright (c) Microsoft Corporation 1996-1999
  3. // C version of the Mix Engine
  4. #include "simple.h"
  5. #include <mmsystem.h>
  6. #include "synth.h"
  7. #pragma warning(disable : 4101 4102 4146)
  8. DWORD CDigitalAudio::Mix16(
  9. short **ppBuffers,
  10. DWORD *pdwChannels,
  11. DWORD dwBufferCount,
  12. DWORD dwLength,
  13. DWORD dwDeltaPeriod,
  14. VFRACT vfDeltaLVolume,
  15. VFRACT vfDeltaRVolume,
  16. PFRACT pfDeltaPitch,
  17. PFRACT pfSampleLength,
  18. PFRACT pfLoopLength)
  19. {
  20. DWORD dwI;
  21. DWORD dwIndex;
  22. DWORD dwPosition;
  23. long lA;
  24. long lM;
  25. DWORD dwIncDelta = dwDeltaPeriod;
  26. VFRACT dwFract;
  27. short * pcWave = m_pnWave;
  28. PFRACT pfSamplePos = m_pfLastSample;
  29. VFRACT vfLVolume = m_vfLastLVolume;
  30. VFRACT vfRVolume = m_vfLastRVolume;
  31. PFRACT pfPitch = m_pfLastPitch;
  32. PFRACT pfPFract = pfPitch << 8;
  33. VFRACT vfLVFract = vfLVolume << 8;
  34. VFRACT vfRVFract = vfRVolume << 8;
  35. for (dwI = 0; dwI < dwLength;)
  36. {
  37. if (pfSamplePos >= pfSampleLength)
  38. {
  39. if (pfLoopLength)
  40. {
  41. pfSamplePos -= pfLoopLength;
  42. }
  43. else
  44. break;
  45. }
  46. dwIncDelta--;
  47. if (!dwIncDelta)
  48. {
  49. dwIncDelta = dwDeltaPeriod;
  50. pfPFract += pfDeltaPitch;
  51. pfPitch = pfPFract >> 8;
  52. vfLVFract += vfDeltaLVolume;
  53. vfLVolume = vfLVFract >> 8;
  54. vfRVFract += vfDeltaRVolume;
  55. vfRVolume = vfRVFract >> 8;
  56. }
  57. dwPosition = pfSamplePos >> 12;
  58. dwFract = pfSamplePos & 0xFFF;
  59. pfSamplePos += pfPitch;
  60. // Interpolate
  61. lA = (long)pcWave[dwPosition];
  62. lM = (((pcWave[dwPosition+1] - lA) * dwFract) >> 12) + lA;
  63. lA = lM;
  64. lA *= vfLVolume;
  65. lA >>= 13; // Signal bumps up to 15 bits.
  66. lM *= vfRVolume;
  67. lM >>= 13;
  68. dwIndex = 0;
  69. while ( dwIndex < dwBufferCount )
  70. {
  71. short *pBuffer = &ppBuffers[dwIndex][dwI];
  72. if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_LEFT )
  73. {
  74. // Keep this around so we can use it to generate new assembly code (see below...)
  75. *pBuffer += (short) lA;
  76. _asm{jno no_oflowl}
  77. *pBuffer = 0x7fff;
  78. _asm{js no_oflowl}
  79. *pBuffer = (short) 0x8000;
  80. }
  81. no_oflowl:
  82. if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_RIGHT )
  83. {
  84. // Keep this around so we can use it to generate new assembly code (see below...)
  85. *pBuffer += (short) lM;
  86. _asm{jno no_oflowr}
  87. *pBuffer = 0x7fff;
  88. _asm{js no_oflowr}
  89. *pBuffer = (short) 0x8000;
  90. }
  91. no_oflowr:
  92. dwIndex++;
  93. }
  94. dwI++;
  95. }
  96. m_vfLastLVolume = vfLVolume;
  97. m_vfLastRVolume = vfRVolume;
  98. m_pfLastPitch = pfPitch;
  99. m_pfLastSample = pfSamplePos;
  100. return (dwI);
  101. }
  102. DWORD CDigitalAudio::Mix16InterLeaved(
  103. short **ppBuffers,
  104. DWORD *pdwChannels,
  105. DWORD dwBufferCount,
  106. DWORD dwLength,
  107. DWORD dwDeltaPeriod,
  108. VFRACT vfDeltaLVolume,
  109. VFRACT vfDeltaRVolume,
  110. PFRACT pfDeltaPitch,
  111. PFRACT pfSampleLength,
  112. PFRACT pfLoopLength)
  113. {
  114. DWORD dwI;
  115. DWORD dwIndex;
  116. DWORD dwPosition;
  117. long lA;
  118. long lM;
  119. DWORD dwIncDelta = dwDeltaPeriod;
  120. VFRACT dwFract;
  121. short * pcWave = m_pnWave;
  122. PFRACT pfSamplePos = m_pfLastSample;
  123. VFRACT vfLVolume = m_vfLastLVolume;
  124. VFRACT vfRVolume = m_vfLastRVolume;
  125. PFRACT pfPitch = m_pfLastPitch;
  126. PFRACT pfPFract = pfPitch << 8;
  127. VFRACT vfLVFract = vfLVolume << 8;
  128. VFRACT vfRVFract = vfRVolume << 8;
  129. dwLength <<= 1;
  130. for (dwI = 0; dwI < dwLength;)
  131. {
  132. if (pfSamplePos >= pfSampleLength)
  133. {
  134. if (pfLoopLength)
  135. {
  136. pfSamplePos -= pfLoopLength;
  137. }
  138. else
  139. break;
  140. }
  141. dwIncDelta--;
  142. if (!dwIncDelta)
  143. {
  144. dwIncDelta = dwDeltaPeriod;
  145. pfPFract += pfDeltaPitch;
  146. pfPitch = pfPFract >> 8;
  147. vfLVFract += vfDeltaLVolume;
  148. vfLVolume = vfLVFract >> 8;
  149. vfRVFract += vfDeltaRVolume;
  150. vfRVolume = vfRVFract >> 8;
  151. }
  152. dwPosition = pfSamplePos >> 12;
  153. dwFract = pfSamplePos & 0xFFF;
  154. pfSamplePos += pfPitch;
  155. // Interpolate
  156. lA = (long)pcWave[dwPosition];
  157. lM = (((pcWave[dwPosition+1] - lA) * dwFract) >> 12) + lA;
  158. lA = lM;
  159. lA *= vfLVolume;
  160. lA >>= 13; // Signal bumps up to 15 bits.
  161. lM *= vfRVolume;
  162. lM >>= 13;
  163. dwIndex = 0;
  164. while ( dwIndex < dwBufferCount )
  165. {
  166. short *pBuffer = &ppBuffers[dwIndex][dwI];
  167. if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_LEFT )
  168. {
  169. // Keep this around so we can use it to generate new assembly code (see below...)
  170. *pBuffer += (short) lA;
  171. _asm{jno no_oflowl}
  172. *pBuffer = 0x7fff;
  173. _asm{js no_oflowl}
  174. *pBuffer = (short) 0x8000;
  175. }
  176. no_oflowl:
  177. if ( pdwChannels[dwIndex] & WAVELINK_CHANNEL_RIGHT )
  178. {
  179. // Keep this around so we can use it to generate new assembly code (see below...)
  180. pBuffer++;
  181. *pBuffer += (short) lM;
  182. _asm{jno no_oflowr}
  183. *pBuffer = 0x7fff;
  184. _asm{js no_oflowr}
  185. *pBuffer = (short) 0x8000;
  186. }
  187. no_oflowr:
  188. dwIndex++;
  189. }
  190. dwI += 2;
  191. }
  192. m_vfLastLVolume = vfLVolume;
  193. m_vfLastRVolume = vfRVolume;
  194. m_pfLastPitch = pfPitch;
  195. m_pfLastSample = pfSamplePos;
  196. return (dwI >> 1);
  197. }