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.

2385 lines
71 KiB

  1. //
  2. // Voice.cpp
  3. // Copyright (c) 1996-2001 Microsoft Corporation
  4. //
  5. #ifdef DMSYNTH_MINIPORT
  6. #include "common.h"
  7. #include <math.h>
  8. #include "muldiv32.h"
  9. #else
  10. #include "debug.h"
  11. #include "simple.h"
  12. #include <mmsystem.h>
  13. #include <dmusicc.h>
  14. #include <dmusics.h>
  15. #include "synth.h"
  16. #include <math.h>
  17. #include <stdio.h>
  18. #include "csynth.h"
  19. #endif
  20. #include "fparms.h" // Generated filter parameter arrays
  21. #ifdef _X86_
  22. #define MMX_ENABLED 1
  23. #endif
  24. #ifdef DBG
  25. extern DWORD sdwDebugLevel;
  26. #endif
  27. CVoiceLFO::CVoiceLFO()
  28. {
  29. m_pModWheelIn = NULL;
  30. m_pPressureIn = NULL;
  31. m_bEnable = TRUE;
  32. }
  33. short CVoiceLFO::m_snSineTable[256];
  34. void CVoiceLFO::Init()
  35. {
  36. double flTemp;
  37. long lIndex;
  38. for (lIndex = 0;lIndex < 256;lIndex++)
  39. {
  40. flTemp = lIndex;
  41. flTemp *= 6.283185307;
  42. flTemp /= 256.0;
  43. flTemp = sin(flTemp);
  44. flTemp *= 100.0;
  45. m_snSineTable[lIndex] = (short) flTemp;
  46. }
  47. }
  48. STIME CVoiceLFO::StartVoice(CSourceLFO *pSource,
  49. STIME stStartTime, CModWheelIn * pModWheelIn, CPressureIn * pPressureIn)
  50. {
  51. m_bEnable = TRUE;
  52. m_pModWheelIn = pModWheelIn;
  53. m_pPressureIn = pPressureIn;
  54. m_Source = *pSource;
  55. m_stStartTime = stStartTime;
  56. if ((m_Source.m_prMWPitchScale == 0) && (m_Source.m_vrMWVolumeScale == 0) &&
  57. (m_Source.m_prPitchScale == 0) && (m_Source.m_vrVolumeScale == 0))
  58. {
  59. m_stRepeatTime = 44100;
  60. }
  61. else
  62. {
  63. m_stRepeatTime = 2097152 / m_Source.m_pfFrequency; // (1/8 * 256 * 4096 * 16)
  64. }
  65. return (m_stRepeatTime);
  66. }
  67. long CVoiceLFO::GetLevel(STIME stTime, STIME *pstNextTime)
  68. {
  69. if ( !m_bEnable )
  70. return 0;
  71. stTime -= (m_stStartTime + m_Source.m_stDelay);
  72. if (stTime < 0)
  73. {
  74. *pstNextTime = -stTime;
  75. return (0);
  76. }
  77. *pstNextTime = m_stRepeatTime;
  78. stTime *= m_Source.m_pfFrequency;
  79. stTime = stTime >> (12 + 4); // We've added 4 extra bits of resolution...
  80. return (m_snSineTable[stTime & 0xFF]);
  81. }
  82. VREL CVoiceLFO::GetVolume(STIME stTime, STIME *pstNextTime)
  83. {
  84. VREL vrVolume;
  85. VREL vrCPVolume;
  86. VREL vrMWVolume;
  87. if ( !m_bEnable )
  88. return 0;
  89. vrCPVolume = m_pPressureIn->GetPressure(stTime);
  90. vrCPVolume *= m_Source.m_vrCPVolumeScale;
  91. vrCPVolume /= 127;
  92. vrMWVolume = m_pModWheelIn->GetModulation(stTime);
  93. vrMWVolume *= m_Source.m_vrMWVolumeScale;
  94. vrMWVolume /= 127;
  95. vrVolume = vrMWVolume;
  96. vrVolume += vrCPVolume;
  97. vrVolume += m_Source.m_vrVolumeScale;
  98. vrVolume *= GetLevel(stTime, pstNextTime);
  99. vrVolume /= 100;
  100. return (vrVolume);
  101. }
  102. PREL CVoiceLFO::GetPitch(STIME stTime, STIME *pstNextTime)
  103. {
  104. PREL prPitch;
  105. PREL prCPPitch;
  106. PREL prMWPitch;
  107. if ( !m_bEnable )
  108. return 0;
  109. prCPPitch = m_pPressureIn->GetPressure(stTime);
  110. prCPPitch *= m_Source.m_prCPPitchScale;
  111. prCPPitch /= 127;
  112. prMWPitch = m_pModWheelIn->GetModulation(stTime);
  113. prMWPitch *= m_Source.m_prMWPitchScale;
  114. prMWPitch /= 127;
  115. prPitch = prMWPitch;
  116. prPitch += prCPPitch;
  117. prPitch += m_Source.m_prPitchScale;
  118. prPitch *= GetLevel(stTime, pstNextTime);
  119. prPitch /= 100;
  120. return (prPitch);
  121. }
  122. PREL CVoiceLFO::GetCutoff(STIME stTime)
  123. {
  124. PREL prPitch;
  125. PREL prCPPitch;
  126. PREL prMWPitch;
  127. STIME stNextTime;
  128. if ( !m_bEnable )
  129. return 0;
  130. prCPPitch = m_pPressureIn->GetPressure(stTime);
  131. prCPPitch *= m_Source.m_prCPCutoffScale;
  132. prCPPitch /= 127;
  133. prMWPitch = m_pModWheelIn->GetModulation(stTime);
  134. prMWPitch *= m_Source.m_prMWCutoffScale;
  135. prMWPitch /= 127;
  136. prPitch = prMWPitch;
  137. prPitch += prCPPitch;
  138. prPitch += m_Source.m_prCutoffScale;
  139. prPitch *= GetLevel(stTime, &stNextTime);
  140. prPitch /= 100;
  141. return (prPitch);
  142. }
  143. CVoiceEG::CVoiceEG()
  144. {
  145. m_stStopTime = 0;
  146. m_bEnable = TRUE;
  147. }
  148. short CVoiceEG::m_snAttackTable[201];
  149. void CVoiceEG::Init()
  150. {
  151. double flTemp;
  152. long lV;
  153. m_snAttackTable[0] = 0;
  154. for (lV = 1;lV <= 200; lV++)
  155. {
  156. flTemp = lV;
  157. flTemp /= 200.0;
  158. flTemp *= flTemp;
  159. flTemp = log10(flTemp);
  160. flTemp *= 10000.0;
  161. flTemp /= 96.0;
  162. flTemp += 1000.0;
  163. m_snAttackTable[lV] = (short) flTemp;
  164. }
  165. }
  166. void CVoiceEG::StopVoice(STIME stTime)
  167. {
  168. if ( m_bEnable )
  169. {
  170. m_Source.m_stRelease *= GetLevel(stTime, &m_stStopTime, TRUE); // Adjust for current sustain level.
  171. m_Source.m_stRelease /= 1000;
  172. }
  173. m_stStopTime = stTime;
  174. }
  175. void CVoiceEG::QuickStopVoice(STIME stTime, DWORD dwSampleRate)
  176. {
  177. if ( m_bEnable )
  178. {
  179. m_Source.m_stRelease *= GetLevel(stTime, &m_stStopTime, TRUE); // Adjust for current sustain level.
  180. m_Source.m_stRelease /= 1000;
  181. dwSampleRate /= 70;
  182. if (m_Source.m_stRelease > (long) dwSampleRate)
  183. {
  184. m_Source.m_stRelease = dwSampleRate;
  185. }
  186. }
  187. m_stStopTime = stTime;
  188. }
  189. STIME CVoiceEG::StartVoice(CSourceEG *pSource, STIME stStartTime,
  190. WORD nKey, WORD nVelocity, STIME stMinAttack)
  191. {
  192. m_bEnable = TRUE;
  193. m_stStartTime = stStartTime;
  194. m_stStopTime = 0x7fffffffffffffff; // set to indefinite future
  195. m_Source = *pSource;
  196. if (m_Source.m_stAttack < stMinAttack)
  197. {
  198. m_Source.m_stAttack = stMinAttack;
  199. }
  200. if (m_Source.m_stRelease < stMinAttack)
  201. {
  202. m_Source.m_stRelease = stMinAttack;
  203. }
  204. // apply velocity to attack length scaling here
  205. m_Source.m_stAttack *= CDigitalAudio::PRELToPFRACT(nVelocity * m_Source.m_trVelAttackScale / 127);
  206. m_Source.m_stAttack /= 4096;
  207. m_Source.m_stHold *= CDigitalAudio::PRELToPFRACT(nKey * m_Source.m_trKeyDecayScale / 127);
  208. m_Source.m_stHold /= 4096;
  209. m_Source.m_stDecay *= CDigitalAudio::PRELToPFRACT(nKey * m_Source.m_trKeyDecayScale / 127);
  210. m_Source.m_stDecay /= 4096;
  211. m_Source.m_stDecay *= (1000 - m_Source.m_pcSustain);
  212. m_Source.m_stDecay /= 1000;
  213. if ( m_Source.m_stDelay )
  214. return ((STIME)m_Source.m_stDelay);
  215. else
  216. return ((STIME)m_Source.m_stAttack);
  217. }
  218. //note: appears to not be in use
  219. BOOL CVoiceEG::InAttack(STIME st)
  220. {
  221. if ( !m_bEnable )
  222. return FALSE;
  223. // has note been released?
  224. if (st >= m_stStopTime)
  225. return FALSE;
  226. // past length of attack?
  227. if (st >= m_stStartTime + m_Source.m_stDelay + m_Source.m_stAttack)
  228. return FALSE;
  229. return TRUE;
  230. }
  231. BOOL CVoiceEG::InRelease(STIME st)
  232. {
  233. if ( !m_bEnable )
  234. return FALSE;
  235. // has note been released?
  236. if (st > m_stStopTime)
  237. return TRUE;
  238. return FALSE;
  239. }
  240. long CVoiceEG::GetLevel(STIME stEnd, STIME *pstNext, BOOL fVolume)
  241. {
  242. long lLevel = 0;
  243. if (stEnd <= m_stStopTime)
  244. {
  245. stEnd -= m_stStartTime;
  246. if (stEnd < m_Source.m_stDelay )
  247. {
  248. lLevel = 0;
  249. *pstNext = m_Source.m_stDelay - stEnd;
  250. }
  251. else
  252. {
  253. stEnd -= m_Source.m_stDelay;
  254. if (stEnd < m_Source.m_stAttack )
  255. {
  256. // still in attack
  257. lLevel = 1000 * (long) stEnd;
  258. if (m_Source.m_stAttack)
  259. {
  260. lLevel /= (long) m_Source.m_stAttack;
  261. }
  262. else // This should never happen, but it does...
  263. {
  264. lLevel = 0;
  265. }
  266. *pstNext = m_Source.m_stAttack - stEnd;
  267. if (lLevel < 0) lLevel = 0;
  268. if (lLevel > 1000) lLevel = 1000;
  269. if (fVolume)
  270. {
  271. lLevel = m_snAttackTable[lLevel / 5];
  272. }
  273. }
  274. else
  275. {
  276. stEnd -= m_Source.m_stAttack;
  277. if ( stEnd < m_Source.m_stHold )
  278. {
  279. lLevel = 1000;
  280. *pstNext = m_Source.m_stHold - stEnd;
  281. if (fVolume)
  282. {
  283. lLevel = m_snAttackTable[lLevel / 5];
  284. }
  285. }
  286. else
  287. {
  288. stEnd -= m_Source.m_stHold;
  289. if (stEnd < m_Source.m_stDecay)
  290. {
  291. // still in decay
  292. lLevel = (1000 - m_Source.m_pcSustain) * (long) stEnd;
  293. lLevel /= (long) m_Source.m_stDecay;
  294. lLevel = 1000 - lLevel;
  295. // To improve the decay curve, set the next point to be 1/4, 1/2, or end of slope.
  296. // To avoid close duplicates, fudge an extra 100 samples.
  297. if (stEnd < ((m_Source.m_stDecay >> 2) - 100))
  298. {
  299. *pstNext = (m_Source.m_stDecay >> 2) - stEnd;
  300. }
  301. else if (stEnd < ((m_Source.m_stDecay >> 1) - 100))
  302. {
  303. *pstNext = (m_Source.m_stDecay >> 1) - stEnd;
  304. }
  305. else
  306. {
  307. *pstNext = m_Source.m_stDecay - stEnd; // Next is end of decay.
  308. }
  309. }
  310. else
  311. {
  312. // in sustain
  313. lLevel = m_Source.m_pcSustain;
  314. *pstNext = 44100;
  315. }
  316. }
  317. }
  318. }
  319. }
  320. else
  321. {
  322. STIME stBogus;
  323. // in release
  324. stEnd -= m_stStopTime;
  325. if (stEnd < m_Source.m_stRelease)
  326. {
  327. lLevel = GetLevel(m_stStopTime, &stBogus, fVolume) * (long) (m_Source.m_stRelease - stEnd);
  328. lLevel /= (long) m_Source.m_stRelease;
  329. if (stEnd < ((m_Source.m_stRelease >> 2) - 100))
  330. {
  331. *pstNext = (m_Source.m_stRelease >> 2) - stEnd;
  332. }
  333. else if (stEnd < ((m_Source.m_stRelease >> 1) - 100))
  334. {
  335. *pstNext = (m_Source.m_stRelease >> 1) - stEnd;
  336. }
  337. else
  338. {
  339. *pstNext = m_Source.m_stRelease - stEnd; // Next is end of decay.
  340. }
  341. }
  342. else
  343. {
  344. lLevel = 0; // !!! off
  345. *pstNext = 0x7FFFFFFFFFFFFFFF;
  346. }
  347. }
  348. return lLevel;
  349. }
  350. VREL CVoiceEG::GetVolume(STIME stTime, STIME *pstNextTime)
  351. {
  352. if ( !m_bEnable )
  353. return 0;
  354. VREL vrLevel = GetLevel(stTime, pstNextTime, TRUE) * 96;
  355. vrLevel /= 10;
  356. vrLevel = vrLevel - 9600;
  357. return vrLevel;
  358. }
  359. PREL CVoiceEG::GetPitch(STIME stTime, STIME *pstNextTime)
  360. {
  361. if ( !m_bEnable )
  362. return 0;
  363. PREL prLevel;
  364. if (m_Source.m_sScale != 0)
  365. {
  366. prLevel = GetLevel(stTime, pstNextTime, FALSE);
  367. prLevel *= m_Source.m_sScale;
  368. prLevel /= 1000;
  369. }
  370. else
  371. {
  372. *pstNextTime = 44100;
  373. prLevel = 0;
  374. }
  375. return prLevel;
  376. }
  377. PREL CVoiceEG::GetCutoff(STIME stTime)
  378. {
  379. if ( !m_bEnable )
  380. return 0;
  381. PREL prLevel;
  382. STIME pstNextTime; // not used
  383. if (m_Source.m_prCutoffScale != 0)
  384. {
  385. prLevel = GetLevel(stTime, &pstNextTime, FALSE);
  386. prLevel *= m_Source.m_prCutoffScale;
  387. prLevel /= 1000;
  388. }
  389. else
  390. {
  391. prLevel = 0;
  392. }
  393. return prLevel;
  394. }
  395. void CVoiceFilter::StartVoice(CSourceFilter *pSource, CVoiceLFO *pLFO, CVoiceEG *pEG, WORD nKey, WORD nVelocity)
  396. {
  397. m_Source = *pSource;
  398. m_pLFO = pLFO;
  399. m_pEG = pEG;
  400. m_prVelScale = (nVelocity * m_Source.m_prVelScale) / 127;
  401. m_prKeyScale = (nKey * m_Source.m_prKeyScale) / 127;
  402. }
  403. /////////////////////////////////////////////////////////////////////////////////
  404. // DLS2 Lowpass Filter Filter
  405. /*
  406. >>>>> finish low pass filter comment
  407. b1 = -2.0 * r * cos(theta);
  408. b2 = r * r;
  409. K = (1.0 + b1 + b2) * pow(10.0, -qIndex * 0.0375);
  410. The Filter :
  411. z = (K * sample[i]) - (b1 * z1) - (b2 * z2)
  412. z2 = z1
  413. z1 = z
  414. >>> B1 negation turned to positive then used as an add instead of subtraction.
  415. Resonance : Q
  416. GainUnits
  417. -qIndex * 0.0375
  418. 0.0375 = 1.5/40 in db's
  419. Values
  420. Q min/max Values are 0db to 22.5db
  421. Q min/max Values are 0 to 225 in 1/10th db's
  422. Cutoff Fequency : Fc
  423. Pitch absolute values
  424. Absolute Pitch = ((1200 * log2(F/440)) + 6900)
  425. Values
  426. Initial Fc min/max Values are 200Hz to 7998Hz
  427. Initial Fc min/max Values are 5535 to 11921 in abosolute pitch cents
  428. Table Indexs
  429. 65 - entries in the table
  430. Hertz Pitch
  431. --------------------------------------
  432. Max Sample Rate -> 48000Hz (15023) ---|
  433. 44100Hz (14877) |
  434. 22050Hz (13676) |
  435. ....... 9488
  436. Max Cutoff Freq -> 7999Hz (11921) |
  437. ....... |
  438. Min Cutoff Freq -> 200Hz (5535) ---|
  439. More Acurately .....
  440. 48KHz 15023.26448623030034519401770744100
  441. 200Hz - 5534.99577150007811000514765931632
  442. =====================================
  443. Feq Range 9488.26871473022223518887004812496
  444. Feq Range/1200 = 7.906890596 is the Feq Range in octaves
  445. Feq Range/100 = 94.882687147 is the Feq Range in setimtones
  446. Behavoir of Fc to indexes according to ouput Sample Rate
  447. SampleRate of 48k (15023)
  448. Fc < 5535 (200Hz) -> fIndex = 0
  449. Fc = 11921 (7999Hz) -> fIndex = 63.86
  450. Fc > 11935 (8064Hz) -> fIndex = 64
  451. SampleRate of 41k (14877)
  452. Fc = 5535 (200Hz) -> fIndex = 0
  453. Fc < 5389 (200Hz) -> fIndex = 0
  454. Fc > 11789 (7411Hz) -> fIndex = 64
  455. Fc = 11921 (7999Hz) -> fIndex = 65.32
  456. SampleRate of 22k (13676)
  457. Fc < 4188 (92Hz) -> fIndex = 0
  458. Fc = 5535 (200Hz) -> fIndex = 13.44
  459. 10574 (3675Hz) -> spec min of 1/6th the sample rate
  460. Fc > 10588 (3704Hz) -> fIndex = 64
  461. 11276 (5510Hz) -> filter fails one octave bellow Nyquist
  462. Fc = 11921 (7999Hz) -> fIndex = 77.33
  463. 12476 (11025Hz) -> nyquist
  464. Precision
  465. 0.01 - minimal acuracy for interpolation
  466. 9488.2687
  467. 0.00025 +/- error
  468. m_aB1[0][63] = 0x33ea24fb = 0.811166044148771133412393865559
  469. m_aB1[0][64] = - 0x2fa8ebf5 = 0.744685163483661751713288716704
  470. ============
  471. 0x04413906 = 0.066480880665109381699105148854
  472. fIndex's fractional constant = 0.002687147302222351888700481249
  473. interpolation of
  474. m_aB1[0][63] + constant = 0.810987400229642518622447868604
  475. difference = 0.000178643919128614789945996955
  476. One 2.30 fixpoint bit = 0.000000000931322575482840254421
  477. 9488.2687147
  478. 7.906890596 * 1200 = 9488.2687152 <-- precision error
  479. 1-bit lossed when going to intger math
  480. */
  481. //
  482. void CVoiceFilter::GetCoeff(STIME stTime, PREL prFreqIn, COEFF& cfK, COEFF& cfB1, COEFF& cfB2)
  483. {
  484. PREL prCutoff;
  485. DWORD dwFract;
  486. int iQIndex;
  487. int iIndex;
  488. //
  489. // Check if filter is disabled
  490. //
  491. if (m_Source.m_prCutoff == 0x7FFF)
  492. {
  493. cfK = 0x40000000; // is unity in 2.30 fixpoint
  494. cfB1 = 0;
  495. cfB2 = 0;
  496. return;
  497. }
  498. //
  499. // Accumulate the current Cutoff Frequency
  500. //
  501. prCutoff = m_Source.m_prCutoffSRAdjust;
  502. prCutoff += m_pLFO->GetCutoff(stTime);
  503. prCutoff += m_pEG->GetCutoff(stTime);
  504. prCutoff += m_prVelScale;
  505. prCutoff += prFreqIn;
  506. //
  507. // Set the Resonance Q index
  508. //
  509. iQIndex = m_Source.m_iQIndex;
  510. //
  511. // Set the cutoff frequency index, and retrive
  512. // the fractional part for interpolation
  513. //
  514. iIndex = prCutoff;
  515. if ( iIndex >= 0 )
  516. {
  517. dwFract = iIndex % 100;
  518. iIndex /= 100;
  519. }
  520. else
  521. {
  522. dwFract = 0;
  523. iIndex = -1;
  524. }
  525. if (iIndex < 0) // Cutoff fequency is less than 100Hz (at 48k Fs)
  526. {
  527. cfK = m_aK[iQIndex][0];
  528. cfB1 = m_aB1[iQIndex][0];
  529. cfB2 = m_aB2[iQIndex][0];
  530. }
  531. else if (iIndex >= FILTER_PARMS_DIM_FC - 1)
  532. {
  533. cfK = m_aK[iQIndex][FILTER_PARMS_DIM_FC - 1];
  534. cfB1 = m_aB1[iQIndex][FILTER_PARMS_DIM_FC - 1];
  535. cfB2 = m_aB2[iQIndex][FILTER_PARMS_DIM_FC - 1];
  536. }
  537. else if (iIndex >= FILTER_PARMS_DIM_FC - 5)
  538. {
  539. //
  540. // Not enough headroom to handle the calculation,
  541. // shift the range douwn by half
  542. //
  543. cfK = m_aK[iQIndex][iIndex] + (((( m_aK[iQIndex][iIndex+1] - m_aK[iQIndex][iIndex]) >> 1) * dwFract)/50);
  544. cfB1 = m_aB1[iQIndex][iIndex] - ((((m_aB1[iQIndex][iIndex] - m_aB1[iQIndex][iIndex+1]) >> 1) * dwFract)/50);
  545. cfB2 = m_aB2[iQIndex][iIndex] - ((((m_aB2[iQIndex][iIndex] - m_aB2[iQIndex][iIndex+1]) >> 1) * dwFract)/50);
  546. }
  547. else
  548. {
  549. cfK = m_aK[iQIndex][iIndex] + (((( m_aK[iQIndex][iIndex+1] - m_aK[iQIndex][iIndex])) * dwFract)/100);
  550. cfB1 = m_aB1[iQIndex][iIndex] - ((((m_aB1[iQIndex][iIndex] - m_aB1[iQIndex][iIndex+1])) * dwFract)/100);
  551. cfB2 = m_aB2[iQIndex][iIndex] - ((((m_aB2[iQIndex][iIndex] - m_aB2[iQIndex][iIndex+1])) * dwFract)/100);
  552. }
  553. }
  554. //------------------------------------------------------------------------------------
  555. // Reference Filter
  556. // Note: This code is used only for testing or to understance the derivation
  557. // of the above filter code. It was the original source for the current implementation
  558. // aboce was optimized
  559. //------------------------------------------------------------------------------------
  560. /*void CVoiceFilter::GetCoeffRef(STIME stTime, COEFF &cfK, COEFF &cfB1, COEFF &cfB2)
  561. {
  562. PREL prCutoff;
  563. int iQIndex;
  564. int iIndex;
  565. double fIndex;
  566. double fIntrp;
  567. //
  568. // Check if filter is disabled
  569. //
  570. if (m_Source.m_prCutoff == 0x7FFF)
  571. {
  572. cfK = 0x40000000; // unity in 2.30 fixpoint
  573. cfB1 = 0;
  574. cfB2 = 0;
  575. return;
  576. }
  577. //
  578. // Accumulate the current Cutoff Frequency
  579. //
  580. prCutoff = m_Source.m_prCutoff;
  581. prCutoff += m_pLFO->GetCutoff(stTime);
  582. prCutoff += m_pEG->GetCutoff(stTime);
  583. prCutoff += m_prVelScale;
  584. //
  585. // There are 16 resonance values spaced 1.5db arpart
  586. // DLS2's has a minimum 1.5db error tolerance
  587. // Range of values it 0db to 22.5db
  588. // m_Source.m_vrQ are in 1/10 db's
  589. // The 15.0 represents the 1.5db'in 1/10 db's
  590. // with the 0.5 for rounding to the nearest index
  591. //
  592. iQIndex = (int)((m_Source.m_vrQ / 15.0f) + 0.5f);
  593. if (iQIndex < 0)
  594. iQIndex = 0;
  595. if (iQIndex > FILTER_PARMS_DIM_Q-1) // FILTER_PARMS_DIM_Q = 16
  596. iQIndex = FILTER_PARMS_DIM_Q-1;
  597. // >>>>> docdoc
  598. //
  599. //
  600. fIndex = 12.0 * (((prCutoff - m_Source.m_prSampleRate) / 1200.0 ) + 7.906890596);
  601. iIndex = (int)fIndex;
  602. fIntrp = fIndex - iIndex;
  603. if (iIndex < 0)
  604. {
  605. cfK = m_aK [iQIndex][0];
  606. cfB1 = m_aB1[iQIndex][0];
  607. cfB2 = m_aB2[iQIndex][0];
  608. }
  609. else if (iIndex >= FILTER_PARMS_DIM_FC - 1)
  610. {
  611. cfK = m_aK [iQIndex][FILTER_PARMS_DIM_FC - 1];
  612. cfB1 = m_aB1[iQIndex][FILTER_PARMS_DIM_FC - 1];
  613. cfB2 = m_aB2[iQIndex][FILTER_PARMS_DIM_FC - 1];
  614. }
  615. else
  616. {
  617. //
  618. // Linearly interpolate the fractional part of the index
  619. // accross two values of the coeficient table
  620. //
  621. cfK = (COEFF)(m_aK[iQIndex][iIndex] * (1.0 - fIntrp) +
  622. m_aK[iQIndex][iIndex+1] * fIntrp);
  623. cfB1 = (COEFF)(m_aB1[iQIndex][iIndex] * (1.0 - fIntrp) +
  624. m_aB1[iQIndex][iIndex+1] * fIntrp);
  625. cfB2 = (COEFF)(m_aB2[iQIndex][iIndex] * (1.0 - fIntrp) +
  626. m_aB2[iQIndex][iIndex+1] * fIntrp);
  627. }
  628. }*/
  629. BOOL CVoiceFilter::IsFiltered()
  630. {
  631. return (m_Source.m_prCutoff != 0x7FFF);
  632. }
  633. CDigitalAudio::CDigitalAudio()
  634. {
  635. m_pfBasePitch = 0;
  636. m_pfLastPitch = 0;
  637. m_pfLastSample = 0;
  638. m_pfLoopEnd = 0;
  639. m_pfLoopStart = 0;
  640. m_pfSampleLength = 0;
  641. m_prLastPitch = 0;
  642. m_ullLastSample = 0;
  643. m_ullLoopStart = 0;
  644. m_ullLoopEnd = 0;
  645. m_ullSampleLength = 0;
  646. m_fElGrande = FALSE;
  647. m_pCurrentBuffer = NULL;
  648. m_pWaveArt = NULL;
  649. m_ullSamplesSoFar = 0;
  650. m_lPrevSample = 0;
  651. m_lPrevPrevSample = 0;
  652. };
  653. CDigitalAudio::~CDigitalAudio()
  654. {
  655. if (m_pWaveArt)
  656. {
  657. m_pWaveArt->Release();
  658. }
  659. }
  660. PFRACT CDigitalAudio::m_spfCents[201];
  661. PFRACT CDigitalAudio::m_spfSemiTones[97];
  662. VFRACT CDigitalAudio::m_svfDbToVolume[(MAXDB - MINDB) * 10 + 1];
  663. BOOL CDigitalAudio::m_sfMMXEnabled = FALSE;
  664. #ifdef MMX_ENABLED
  665. BOOL MultiMediaInstructionsSupported();
  666. #endif
  667. #pragma optimize("", off) // Optimize causes crash! Argh!
  668. void CDigitalAudio::Init()
  669. {
  670. double flTemp;
  671. VREL vrdB;
  672. #ifdef MMX_ENABLED
  673. m_sfMMXEnabled = MultiMediaInstructionsSupported();
  674. #endif // MMX_ENABLED
  675. for (vrdB = MINDB * 10;vrdB <= MAXDB * 10;vrdB++)
  676. {
  677. flTemp = vrdB;
  678. flTemp /= 100.0;
  679. flTemp = pow(10.0, flTemp);
  680. flTemp = pow(flTemp, 0.5); // square root.
  681. flTemp *= 4095.0; // 2^12th, but avoid overflow...
  682. m_svfDbToVolume[vrdB - (MINDB * 10)] = (long) flTemp;
  683. }
  684. PREL prRatio;
  685. for (prRatio = -100;prRatio <= 100;prRatio++)
  686. {
  687. flTemp = prRatio;
  688. flTemp /= 1200.0;
  689. flTemp = pow(2.0, flTemp);
  690. flTemp *= 4096.0;
  691. m_spfCents[prRatio + 100] = (long) flTemp;
  692. }
  693. for (prRatio = -48;prRatio <= 48;prRatio++)
  694. {
  695. flTemp = prRatio;
  696. flTemp /= 12.0;
  697. flTemp = pow(2.0, flTemp);
  698. flTemp *= 4096.0;
  699. m_spfSemiTones[prRatio + 48] = (long) flTemp;
  700. }
  701. }
  702. #pragma optimize("", on)
  703. VFRACT CDigitalAudio::VRELToVFRACT(VREL vrVolume)
  704. {
  705. vrVolume /= 10;
  706. if (vrVolume < MINDB * 10)
  707. vrVolume = MINDB * 10;
  708. else if (vrVolume >= MAXDB * 10)
  709. vrVolume = MAXDB * 10;
  710. return (m_svfDbToVolume[vrVolume - MINDB * 10]);
  711. }
  712. PFRACT CDigitalAudio::PRELToPFRACT(PREL prPitch)
  713. {
  714. PFRACT pfPitch = 0;
  715. PREL prOctave;
  716. if (prPitch > 100)
  717. {
  718. if (prPitch > 4800)
  719. {
  720. prPitch = 4800;
  721. }
  722. prOctave = prPitch / 100;
  723. prPitch = prPitch % 100;
  724. pfPitch = m_spfCents[prPitch + 100];
  725. pfPitch <<= prOctave / 12;
  726. prOctave = prOctave % 12;
  727. pfPitch *= m_spfSemiTones[prOctave + 48];
  728. pfPitch >>= 12;
  729. }
  730. else if (prPitch < -100)
  731. {
  732. if (prPitch < -4800)
  733. {
  734. prPitch = -4800;
  735. }
  736. prOctave = prPitch / 100;
  737. prPitch = (-prPitch) % 100;
  738. pfPitch = m_spfCents[100 - prPitch];
  739. pfPitch >>= ((-prOctave) / 12);
  740. prOctave = (-prOctave) % 12;
  741. pfPitch *= m_spfSemiTones[48 - prOctave];
  742. pfPitch >>= 12;
  743. }
  744. else
  745. {
  746. pfPitch = m_spfCents[prPitch + 100];
  747. }
  748. return (pfPitch);
  749. }
  750. void CDigitalAudio::ClearVoice()
  751. {
  752. if (m_Source.m_pWave != NULL)
  753. {
  754. m_Source.m_pWave->PlayOff();
  755. m_Source.m_pWave->Release(); // Releases wave structure.
  756. m_Source.m_pWave = NULL;
  757. }
  758. if (m_pWaveArt)
  759. {
  760. m_pWaveArt->Release();
  761. m_pWaveArt = NULL;
  762. }
  763. }
  764. STIME CDigitalAudio::StartVoice(CSynth *pSynth,
  765. CSourceSample *pSample,
  766. PREL prBasePitch,
  767. long lKey)
  768. {
  769. m_prLastPitch = 0;
  770. m_lPrevSample = 0;
  771. m_lPrevPrevSample = 0;
  772. m_cfLastK = 0;
  773. m_cfLastB1 = 0;
  774. m_cfLastB2 = 0;
  775. m_Source = *pSample;
  776. m_pnWave = pSample->m_pWave->m_pnWave;
  777. m_pSynth = pSynth;
  778. m_bOneShot = m_Source.m_bOneShot;
  779. pSample->m_pWave->AddRef(); // Keeps track of Wave usage.
  780. pSample->m_pWave->PlayOn();
  781. // Set initial pitch
  782. prBasePitch += pSample->m_prFineTune;
  783. prBasePitch += ((lKey - pSample->m_bMIDIRootKey) * 100);
  784. m_pfBasePitch = PRELToPFRACT(prBasePitch);
  785. m_pfBasePitch *= pSample->m_dwSampleRate;
  786. m_pfBasePitch /= pSynth->m_dwSampleRate;
  787. m_pfLastPitch = m_pfBasePitch;
  788. m_fElGrande = pSample->m_dwSampleLength >= 0x80000; // Greater than 512k.
  789. if ((pSample->m_dwLoopEnd - pSample->m_dwLoopStart) >= 0x80000)
  790. { // We can't handle loops greater than 1 meg!
  791. m_bOneShot = TRUE;
  792. }
  793. m_ullLastSample = 0;
  794. m_ullLoopStart = pSample->m_dwLoopStart;
  795. m_ullLoopStart = m_ullLoopStart << 12;
  796. m_ullLoopEnd = pSample->m_dwLoopEnd;
  797. m_ullLoopEnd = m_ullLoopEnd << 12;
  798. m_ullSampleLength = pSample->m_dwSampleLength;
  799. m_ullSampleLength = m_ullSampleLength << 12;
  800. m_pfLastSample = 0;
  801. m_pfLoopStart = (long) m_ullLoopStart;
  802. m_pfLoopEnd = (long) m_ullLoopEnd;
  803. if (m_ullLoopEnd <= m_ullLoopStart) // Should never happen, but death if it does!
  804. {
  805. m_bOneShot = TRUE;
  806. }
  807. if (m_fElGrande)
  808. {
  809. m_pfSampleLength = 0x7FFFFFFF;
  810. }
  811. else
  812. {
  813. m_pfSampleLength = (long) m_ullSampleLength;
  814. }
  815. m_pCurrentBuffer = NULL; // Used by wave playing must be null for standard sample
  816. m_pWaveArt = NULL;
  817. m_ullSamplesSoFar = 0;
  818. return (0); // !!! what is this return value?
  819. }
  820. STIME CDigitalAudio::StartWave(CSynth *pSynth,
  821. CWaveArt *pWaveArt,
  822. PREL prBasePitch,
  823. SAMPLE_TIME stVoiceStart,
  824. SAMPLE_TIME stLoopStart,
  825. SAMPLE_TIME stLoopEnd)
  826. {
  827. m_pSynth = pSynth; // Save Synth
  828. if (pWaveArt)
  829. {
  830. pWaveArt->AddRef();
  831. }
  832. if (m_pWaveArt)
  833. {
  834. m_pWaveArt->Release();
  835. }
  836. m_pWaveArt = pWaveArt; // Save Wave articulation
  837. // Reset all wave buffer flags
  838. CWaveBuffer* pWavBuf = pWaveArt->m_pWaves.GetHead();
  839. while ( pWavBuf )
  840. {
  841. pWavBuf->m_pWave->m_bActive = FALSE;
  842. pWavBuf = pWavBuf->GetNext();
  843. }
  844. // Initialize the current play buffer
  845. m_pCurrentBuffer = pWaveArt->m_pWaves.GetHead();;
  846. //if m_pCurrentBuffer is NULL the articulation contains
  847. //no samples... this shouldn't be possible.
  848. assert(m_pCurrentBuffer);
  849. m_pCurrentBuffer->m_pWave->m_bActive = TRUE;
  850. m_pCurrentBuffer->m_pWave->AddRef(); // Keeps track of Wave usage.
  851. m_pCurrentBuffer->m_pWave->PlayOn();
  852. // Fill CSourceSample class with CWave Defaults
  853. m_Source.m_pWave = m_pCurrentBuffer->m_pWave;
  854. m_Source.m_dwSampleLength = m_pCurrentBuffer->m_pWave->m_dwSampleLength;
  855. m_Source.m_dwSampleRate = m_pCurrentBuffer->m_pWave->m_dwSampleRate;
  856. m_Source.m_bSampleType = m_pCurrentBuffer->m_pWave->m_bSampleType;
  857. m_Source.m_dwID = m_pCurrentBuffer->m_pWave->m_dwID;
  858. m_Source.m_dwLoopStart = 0;
  859. m_Source.m_dwLoopEnd = m_pCurrentBuffer->m_pWave->m_dwSampleLength;
  860. m_Source.m_bMIDIRootKey = 0;
  861. m_Source.m_prFineTune = 0;
  862. m_bOneShot = TRUE;
  863. // The the current sample pointer
  864. m_pnWave = m_pCurrentBuffer->m_pWave->m_pnWave;
  865. // Set initial pitch
  866. m_pfBasePitch = PRELToPFRACT(prBasePitch);
  867. m_pfBasePitch *= m_Source.m_dwSampleRate;
  868. m_pfBasePitch /= pSynth->m_dwSampleRate;
  869. m_pfLastPitch = m_pfBasePitch;
  870. m_prLastPitch = 0;
  871. m_fElGrande = m_Source.m_dwSampleLength >= 0x80000; // Greater than 512k.
  872. m_ullLastSample = stVoiceStart;
  873. m_ullLastSample = m_ullLastSample << 12;
  874. m_ullSamplesSoFar = 0;
  875. m_ullLoopStart = m_Source.m_dwLoopStart;
  876. m_ullLoopStart = m_ullLoopStart << 12;
  877. m_ullLoopEnd = m_Source.m_dwLoopEnd;
  878. m_ullLoopEnd = m_ullLoopEnd << 12;
  879. m_ullSampleLength = m_Source.m_dwSampleLength;
  880. m_ullSampleLength = m_ullSampleLength << 12;
  881. m_pfLastSample = (long) m_ullLastSample;
  882. m_pfLoopStart = (long) m_ullLoopStart;
  883. m_pfLoopEnd = (long) m_ullLoopEnd;
  884. if (stLoopStart || stLoopEnd)
  885. {
  886. m_bOneShot = FALSE;
  887. m_ullLoopStart = stLoopStart;
  888. m_ullLoopStart = m_ullLoopStart << 12;
  889. m_ullLoopEnd = stLoopEnd;
  890. m_ullLoopEnd = m_ullLoopEnd << 12;
  891. m_pfLoopStart = (long) m_ullLoopStart;
  892. m_pfLoopEnd = (long) m_ullLoopEnd;
  893. }
  894. if ((stLoopEnd - stLoopStart) >= 0x80000)
  895. {
  896. m_bOneShot = TRUE;
  897. }
  898. // This could be WAY beyond the actual wave data range
  899. // So find out the sample we want to start at
  900. if(stVoiceStart > stLoopStart)
  901. {
  902. SAMPLE_TIME stLoopLen = stLoopEnd - stLoopStart;
  903. if(m_bOneShot == FALSE && stLoopLen != 0)
  904. {
  905. m_ullLastSample = stVoiceStart - stLoopStart;
  906. m_ullLastSample = m_ullLastSample - (stLoopLen * (m_ullLastSample / stLoopLen));
  907. m_ullLastSample = stLoopStart + m_ullLastSample;
  908. m_ullLastSample = m_ullLastSample << 12;
  909. m_pfLastSample = (long) (m_ullLastSample);
  910. }
  911. // Must be a wave with an start offset?
  912. // In any case we need to correct this or else we crash
  913. if(m_bOneShot && stVoiceStart > m_Source.m_dwSampleLength)
  914. {
  915. m_ullLastSample = 0;
  916. m_pfLastSample = 0;
  917. }
  918. }
  919. if(m_fElGrande)
  920. {
  921. m_pfSampleLength = 0x7FFFFFFF;
  922. }
  923. else
  924. {
  925. m_pfSampleLength = (long) m_ullSampleLength;
  926. }
  927. return (0);
  928. }
  929. /* If the wave is bigger than one meg, the index can overflow.
  930. Solve this by assuming no mix session will ever be as great
  931. as one meg AND loops are never that long. We keep all our
  932. fractional indexes in two variables. In one case, m_pfLastSample,
  933. is the normal mode where the lower 12 bits are the fraction and
  934. the upper 20 bits are the index. And, m_ullLastSample
  935. is a LONGLONG with an extra 32 bits of index. The mix engine
  936. does not want the LONGLONGs, so we need to track the variables
  937. in the LONGLONGs and prepare them for the mixer as follows:
  938. Prior to mixing,
  939. if the sample is large (m_fElGrande is set), BeforeSampleMix()
  940. is called. This finds the starting point for the mix, which
  941. is either the current position or the start of the loop,
  942. whichever is earlier. It subtracts this starting point from
  943. the LONGLONG variables and stores an offset in m_dwAddressUpper.
  944. It also adjusts the pointer to the wave data appropriately.
  945. AfterSampleMix() does the inverse, reconstructing the the LONGLONG
  946. indeces and returning everthing back to normal.
  947. */
  948. void CDigitalAudio::BeforeBigSampleMix()
  949. {
  950. if (m_fElGrande)
  951. {
  952. ULONGLONG ullBase = 0;
  953. DWORD dwBase;
  954. if (m_bOneShot)
  955. {
  956. ullBase = m_ullLastSample;
  957. }
  958. else
  959. {
  960. if (m_ullLastSample < m_ullLoopStart)
  961. {
  962. ullBase = m_ullLastSample;
  963. }
  964. else
  965. {
  966. ullBase = m_ullLoopStart;
  967. }
  968. }
  969. // Keep the value as we want to offset into the wave buffer
  970. ULONGLONG ullWaveOffset = ullBase;
  971. ullBase >>= 12;
  972. dwBase = (DWORD) ullBase & 0xFFFFFFFE; // Clear bottom bit so 8 bit pointer aligns with short.
  973. ullBase = dwBase;
  974. ullBase <<= 12;
  975. m_dwAddressUpper = dwBase;
  976. m_pfLastSample = (long) (m_ullLastSample - ullBase);
  977. if ((m_ullLoopEnd - ullBase) < 0x7FFFFFFF)
  978. {
  979. m_pfLoopStart = (long) (m_ullLoopStart - ullBase);
  980. m_pfLoopEnd = (long) (m_ullLoopEnd - ullBase);
  981. }
  982. else
  983. {
  984. m_pfLoopStart = 0;
  985. m_pfLoopEnd = 0x7FFFFFFF;
  986. }
  987. ullBase = m_ullSampleLength - ullBase;
  988. dwBase = (DWORD)(ullWaveOffset >> 12);
  989. if (ullBase > 0x7FFFFFFF)
  990. {
  991. m_pfSampleLength = 0x7FFFFFFF;
  992. }
  993. else
  994. {
  995. m_pfSampleLength = (long) ullBase;
  996. }
  997. if (m_Source.m_bSampleType & SFORMAT_8)
  998. {
  999. dwBase >>= 1;
  1000. }
  1001. m_pnWave = &m_Source.m_pWave->m_pnWave[dwBase];
  1002. }
  1003. }
  1004. void CDigitalAudio::AfterBigSampleMix()
  1005. {
  1006. m_pnWave = m_Source.m_pWave->m_pnWave;
  1007. if (m_fElGrande)
  1008. {
  1009. ULONGLONG ullBase = m_dwAddressUpper;
  1010. m_ullLastSample = m_pfLastSample;
  1011. m_ullLastSample += (ullBase << 12);
  1012. m_dwAddressUpper = 0;
  1013. }
  1014. }
  1015. BOOL CDigitalAudio::Mix(short **ppBuffers, // Array of mix buffers
  1016. DWORD dwBufferCount, // Number of mix buffers
  1017. DWORD dwInterleaved, // Are the buffers interleaved data?
  1018. DWORD dwLength, // Length to mix, in samples
  1019. VREL vrMaxVolumeDelta, // Maximum volume accross all buses
  1020. VFRACT vfNewVolume[],
  1021. VFRACT vfLastVolume[],
  1022. PREL prPitch, // Pitch to play the sample too
  1023. DWORD dwIsFiltered, // Is the mix filtered
  1024. COEFF cfK, // filter coeficients
  1025. COEFF cfB1,
  1026. COEFF cfB2)
  1027. {
  1028. DWORD i;
  1029. PFRACT pfDeltaPitch;
  1030. PFRACT pfEnd;
  1031. PFRACT pfLoopLen;
  1032. PFRACT pfNewPitch;
  1033. VFRACT vfDeltaVolume[MAX_DAUD_CHAN];
  1034. DWORD dwPeriod = 64;
  1035. DWORD dwSoFar;
  1036. DWORD dwStart; // position in WORDs
  1037. DWORD dwMixChoice = 0;
  1038. DWORD dwBuffers;
  1039. PFRACT pfPreMix;
  1040. COEFFDELTA cfdK = 0;
  1041. COEFFDELTA cfdB1 = 0;
  1042. COEFFDELTA cfdB2 = 0;
  1043. if (dwLength == 0) // Attack was instant.
  1044. {
  1045. m_pfLastPitch = (m_pfBasePitch * PRELToPFRACT(prPitch)) >> 12;
  1046. m_prLastPitch = prPitch;
  1047. m_cfLastK = cfK;
  1048. m_cfLastB1 = cfB1;
  1049. m_cfLastB2 = cfB2;
  1050. return TRUE;
  1051. }
  1052. if ( m_pWaveArt ) // Playing a wave or Streaming
  1053. {
  1054. if ( m_pWaveArt->m_bStream )
  1055. {
  1056. // Check if the buffer is valid yet
  1057. if ( !m_pCurrentBuffer->m_pWave->m_bValid )
  1058. {
  1059. Trace(3, "Warning: Synth starting mix with invalid streaming wave buffer\n\r");
  1060. return TRUE; // not valid yet, get out of here
  1061. }
  1062. m_pCurrentBuffer->m_pWave->m_bActive = TRUE;
  1063. if ( m_pCurrentBuffer->m_pWave->m_bLastSampleInit == FALSE )
  1064. {
  1065. CWaveBuffer* pnextbuffer = m_pCurrentBuffer->GetNextLoop();
  1066. if ( pnextbuffer->m_pWave->m_bValid )
  1067. {
  1068. DWORD dwSampleLength = m_pCurrentBuffer->m_pWave->m_dwSampleLength; // Length of sample.
  1069. if ( m_Source.m_bSampleType == SFORMAT_8 )
  1070. {
  1071. ((BYTE*)m_pCurrentBuffer->m_pWave->m_pnWave)[dwSampleLength-1] = ((BYTE*)pnextbuffer->m_pWave->m_pnWave)[0];
  1072. }
  1073. else
  1074. {
  1075. m_pCurrentBuffer->m_pWave->m_pnWave[dwSampleLength-1] = pnextbuffer->m_pWave->m_pnWave[0];
  1076. }
  1077. m_pCurrentBuffer->m_pWave->m_bLastSampleInit = TRUE;
  1078. }
  1079. }
  1080. }
  1081. }
  1082. if ((m_Source.m_pWave == NULL) || (m_Source.m_pWave->m_pnWave == NULL))
  1083. {
  1084. return FALSE;
  1085. }
  1086. DWORD dwMax = max(vrMaxVolumeDelta, abs(prPitch - m_prLastPitch) << 1);
  1087. dwMax >>= 1;
  1088. m_prLastPitch = prPitch;
  1089. if (dwMax > 0)
  1090. {
  1091. dwPeriod = (dwLength << 3) / dwMax;
  1092. if (dwPeriod > 512)
  1093. {
  1094. dwPeriod = 512;
  1095. }
  1096. else if (dwPeriod < 1)
  1097. {
  1098. dwPeriod = 1;
  1099. }
  1100. }
  1101. else
  1102. {
  1103. dwPeriod = 512; // Make it happen anyway.
  1104. }
  1105. // This makes MMX sound a little better (MMX bug will be fixed)
  1106. dwPeriod += 3;
  1107. dwPeriod &= 0xFFFFFFFC;
  1108. pfNewPitch = m_pfBasePitch * PRELToPFRACT(prPitch);
  1109. pfNewPitch >>= 12;
  1110. pfDeltaPitch = MulDiv(pfNewPitch - m_pfLastPitch, dwPeriod << 8, dwLength);
  1111. if ( dwInterleaved )
  1112. {
  1113. vfDeltaVolume[0] = MulDiv(vfNewVolume[0] - vfLastVolume[0], dwPeriod << 8, dwLength);
  1114. vfDeltaVolume[1] = MulDiv(vfNewVolume[1] - vfLastVolume[1], dwPeriod << 8, dwLength);
  1115. }
  1116. else
  1117. {
  1118. for (dwBuffers = 0; dwBuffers < dwBufferCount; dwBuffers++)
  1119. {
  1120. vfDeltaVolume[dwBuffers] = MulDiv(vfNewVolume[dwBuffers] - vfLastVolume[dwBuffers], dwPeriod << 8, dwLength);
  1121. }
  1122. }
  1123. if ( dwInterleaved )
  1124. {
  1125. dwMixChoice |= SPLAY_INTERLEAVED;
  1126. }
  1127. if (m_sfMMXEnabled && (dwLength > 8))
  1128. {
  1129. dwMixChoice |= SPLAY_MMX;
  1130. }
  1131. dwMixChoice |= m_Source.m_bSampleType;
  1132. dwStart = 0;
  1133. if (dwIsFiltered)
  1134. {
  1135. dwMixChoice |= SPLAY_FILTERED;
  1136. //
  1137. // The coeficients have been stored as DWORD's to gain an additional
  1138. // bit of presision when calculating the interpolation between
  1139. // coefiecients in the table. Since these calcutlations always
  1140. // result in positive coefiecients no greater the 1.9999,
  1141. // we can safely cast to a signed int, from which negative deltas
  1142. // can be correctly determined.
  1143. //
  1144. cfdK = MulDiv((LONG)cfK - (LONG)m_cfLastK, dwPeriod, dwLength);
  1145. cfdB1 = MulDiv((LONG)cfB1 - (LONG)m_cfLastB1, dwPeriod, dwLength);
  1146. cfdB2 = MulDiv((LONG)cfB2 - (LONG)m_cfLastB2, dwPeriod, dwLength);
  1147. }
  1148. for (;;)
  1149. {
  1150. if (dwLength <= 8)
  1151. {
  1152. dwMixChoice &= ~SPLAY_MMX;
  1153. }
  1154. if (m_fElGrande)
  1155. {
  1156. BeforeBigSampleMix();
  1157. }
  1158. if (m_bOneShot)
  1159. {
  1160. pfEnd = m_pfSampleLength;
  1161. if(m_pCurrentBuffer && m_pCurrentBuffer->m_pWave)
  1162. {
  1163. // We grow the buffers by one sample for interpolation so we can transition smoothly
  1164. // between the multiple streaming buffers. This will cause a click at the end of the
  1165. // buffer if the wave is ending as there's no valid nex tbuffer. So we check for that
  1166. // and adjust the length of the buffer so that the mix engine doesn't try to interpolate
  1167. // the additional (last) sample. If it's NOT the last buffer then we proceed as planned.
  1168. if((pfEnd >> 12) >= (long)(m_pCurrentBuffer->m_pWave->m_dwSampleLength - 1))
  1169. {
  1170. CWaveBuffer* pnextbuffer = m_pCurrentBuffer->GetNextLoop();
  1171. if(pnextbuffer == NULL || pnextbuffer->m_pWave->m_bValid == FALSE)
  1172. {
  1173. pfEnd = (m_pCurrentBuffer->m_pWave->m_dwSampleLength - 2) << 12;
  1174. }
  1175. else
  1176. {
  1177. pfEnd = (m_pCurrentBuffer->m_pWave->m_dwSampleLength - 1) << 12;
  1178. }
  1179. }
  1180. }
  1181. pfLoopLen = 0;
  1182. pfPreMix = m_pfLastSample; // save off last sample pos
  1183. }
  1184. else
  1185. {
  1186. pfEnd = m_pfLoopEnd;
  1187. pfLoopLen = m_pfLoopEnd - m_pfLoopStart;
  1188. pfPreMix = 0;
  1189. if (pfLoopLen <= pfNewPitch)
  1190. {
  1191. return FALSE;
  1192. }
  1193. if(pfLoopLen > m_pfSampleLength)
  1194. {
  1195. return FALSE;
  1196. }
  1197. }
  1198. switch (dwMixChoice)
  1199. {
  1200. case SFORMAT_8 | SPLAY_INTERLEAVED :
  1201. dwSoFar = Mix8(ppBuffers[0], dwLength, dwPeriod,
  1202. vfDeltaVolume[0], vfDeltaVolume[1],
  1203. vfLastVolume,
  1204. pfDeltaPitch,
  1205. pfEnd, pfLoopLen);
  1206. break;
  1207. case SFORMAT_16 | SPLAY_INTERLEAVED :
  1208. dwSoFar = Mix16(ppBuffers[0], dwLength, dwPeriod,
  1209. vfDeltaVolume[0], vfDeltaVolume[1],
  1210. vfLastVolume,
  1211. pfDeltaPitch,
  1212. pfEnd, pfLoopLen);
  1213. break;
  1214. case SFORMAT_8 | SPLAY_INTERLEAVED | SPLAY_FILTERED | SPLAY_MMX :
  1215. case SFORMAT_8 | SPLAY_INTERLEAVED | SPLAY_FILTERED :
  1216. dwSoFar = Mix8Filter(ppBuffers[0],dwLength,dwPeriod,
  1217. vfDeltaVolume[0], vfDeltaVolume[1],
  1218. vfLastVolume,
  1219. pfDeltaPitch,
  1220. pfEnd, pfLoopLen,
  1221. cfdK, cfdB1, cfdB2);
  1222. break;
  1223. case SFORMAT_16 | SPLAY_INTERLEAVED | SPLAY_FILTERED | SPLAY_MMX :
  1224. case SFORMAT_16 | SPLAY_INTERLEAVED | SPLAY_FILTERED :
  1225. dwSoFar = Mix16Filter(ppBuffers[0],dwLength,dwPeriod,
  1226. vfDeltaVolume[0], vfDeltaVolume[1],
  1227. vfLastVolume,
  1228. pfDeltaPitch,
  1229. pfEnd, pfLoopLen,
  1230. cfdK, cfdB1, cfdB2);
  1231. break;
  1232. #ifdef MMX_ENABLED
  1233. case SFORMAT_8 | SPLAY_MMX | SPLAY_INTERLEAVED :
  1234. dwSoFar = Mix8X(ppBuffers[0], dwLength, dwPeriod,
  1235. vfDeltaVolume[0], vfDeltaVolume[1],
  1236. vfLastVolume,
  1237. pfDeltaPitch,
  1238. pfEnd, pfLoopLen);
  1239. break;
  1240. case SFORMAT_16 | SPLAY_MMX | SPLAY_INTERLEAVED :
  1241. dwSoFar = Mix16X(ppBuffers[0], dwLength, dwPeriod,
  1242. vfDeltaVolume[0], vfDeltaVolume[1],
  1243. vfLastVolume,
  1244. pfDeltaPitch,
  1245. pfEnd, pfLoopLen);
  1246. break;
  1247. #endif
  1248. case SFORMAT_8 :
  1249. case SFORMAT_8 | SPLAY_MMX :
  1250. dwSoFar = MixMulti8(ppBuffers, dwBufferCount,
  1251. dwLength, dwPeriod,
  1252. vfDeltaVolume,
  1253. vfLastVolume,
  1254. pfDeltaPitch,
  1255. pfEnd, pfLoopLen);
  1256. break;
  1257. case SFORMAT_8 | SPLAY_FILTERED :
  1258. case SFORMAT_8 | SPLAY_FILTERED | SPLAY_MMX :
  1259. dwSoFar = MixMulti8Filter(ppBuffers, dwBufferCount,
  1260. dwLength, dwPeriod,
  1261. vfDeltaVolume,
  1262. vfLastVolume,
  1263. pfDeltaPitch,
  1264. pfEnd, pfLoopLen,
  1265. cfdK, cfdB1, cfdB2);
  1266. break;
  1267. case SFORMAT_16 :
  1268. case SFORMAT_16 | SPLAY_MMX :
  1269. dwSoFar = MixMulti16(ppBuffers, dwBufferCount,
  1270. dwLength, dwPeriod,
  1271. vfDeltaVolume,
  1272. vfLastVolume,
  1273. pfDeltaPitch,
  1274. pfEnd, pfLoopLen);
  1275. break;
  1276. case SFORMAT_16 | SPLAY_FILTERED :
  1277. case SFORMAT_16 | SPLAY_FILTERED | SPLAY_MMX :
  1278. dwSoFar = MixMulti16Filter(ppBuffers, dwBufferCount,
  1279. dwLength, dwPeriod,
  1280. vfDeltaVolume,
  1281. vfLastVolume,
  1282. pfDeltaPitch,
  1283. pfEnd, pfLoopLen,
  1284. cfdK, cfdB1, cfdB2);
  1285. break;
  1286. default :
  1287. return (FALSE);
  1288. }
  1289. if (m_fElGrande)
  1290. {
  1291. AfterBigSampleMix();
  1292. }
  1293. if (m_bOneShot)
  1294. {
  1295. // have mixed all we needed at this time to break
  1296. if (dwSoFar >= dwLength)
  1297. {
  1298. m_ullSamplesSoFar += (m_pfLastSample - pfPreMix)>>12;
  1299. break;
  1300. }
  1301. // the mix engine reached the end of the source data
  1302. m_ullSamplesSoFar += ((m_pfLastSample - pfPreMix)>>12)-1;
  1303. if ( m_pWaveArt ) // Playing or Streaming a Wave
  1304. {
  1305. if ( !m_pWaveArt->m_bStream ) // we must be at the end of the buffer
  1306. return FALSE;
  1307. // Set completion flags
  1308. m_pCurrentBuffer->m_pWave->m_bActive = FALSE;
  1309. m_pCurrentBuffer->m_pWave->m_bValid = FALSE;
  1310. m_pCurrentBuffer->m_pWave->m_bLastSampleInit = FALSE;
  1311. // Get next buffer
  1312. m_pCurrentBuffer = m_pCurrentBuffer->GetNextLoop();
  1313. // Set new wave pointer to play out of
  1314. m_pnWave = m_pCurrentBuffer->m_pWave->m_pnWave;
  1315. // Check if the buffer is valid yet
  1316. if ( !m_pCurrentBuffer->m_pWave->m_bValid )
  1317. {
  1318. Trace(2, "Warning: Synth attempting to start invalid streaming wave buffer\n\r");
  1319. break; // nothing to play yet, get out of here
  1320. }
  1321. m_pCurrentBuffer->m_pWave->m_bActive = TRUE;
  1322. CWaveBuffer* pnextbuffer = m_pCurrentBuffer->GetNextLoop();
  1323. if ( pnextbuffer->m_pWave->m_bValid )
  1324. {
  1325. DWORD dwSampleLength = m_pCurrentBuffer->m_pWave->m_dwSampleLength; // Length of sample.
  1326. if ( m_Source.m_bSampleType == SFORMAT_8 )
  1327. {
  1328. ((BYTE*)m_pCurrentBuffer->m_pWave->m_pnWave)[dwSampleLength-1] = ((BYTE*)pnextbuffer->m_pWave->m_pnWave)[0];
  1329. }
  1330. else
  1331. {
  1332. m_pCurrentBuffer->m_pWave->m_pnWave[dwSampleLength-1] = pnextbuffer->m_pWave->m_pnWave[0];
  1333. }
  1334. m_pCurrentBuffer->m_pWave->m_bLastSampleInit = TRUE;
  1335. }
  1336. //>>>>>>>>>> CHECK FOR LOOP POINT, IF SO NOT TRY AGAIN HERE
  1337. dwStart += dwSoFar << dwInterleaved;
  1338. dwLength -= dwSoFar;
  1339. m_pfLastSample = 0;
  1340. //>>>>>>>>>> CHECK INTERLEAVED FLAG FOR CORRECT DISTANCE ????????
  1341. // Move buffer pointers since we are mixing more samples
  1342. for ( i = 0; i < dwBufferCount; i++ )
  1343. ppBuffers[i] += dwStart;
  1344. continue; // keep playing
  1345. }
  1346. else
  1347. return FALSE; // Playing a standard one shot, we hit the end of the buffer
  1348. }
  1349. else
  1350. {
  1351. if (dwSoFar >= dwLength)
  1352. break;
  1353. // Loops are handled in the mix engine, however
  1354. // when you reach the end of source data you will
  1355. // reach this code.
  1356. dwStart += dwSoFar << dwInterleaved;
  1357. dwLength -= dwSoFar;
  1358. m_pfLastSample -= (m_pfLoopEnd - m_pfLoopStart);
  1359. // Move buffer pointers since we are mixing more samples
  1360. for ( i = 0; i < dwBufferCount; i++ )
  1361. ppBuffers[i] += dwStart;
  1362. }
  1363. }
  1364. m_pfLastPitch = pfNewPitch;
  1365. m_cfLastK = cfK;
  1366. m_cfLastB1 = cfB1;
  1367. m_cfLastB2 = cfB2;
  1368. return (TRUE);
  1369. }
  1370. CVoice::CVoice()
  1371. {
  1372. m_pControl = NULL;
  1373. m_pPitchBendIn = NULL;
  1374. m_pExpressionIn = NULL;
  1375. m_dwPriority = 0;
  1376. m_nPart = 0;
  1377. m_nKey = 0;
  1378. m_fInUse = FALSE;
  1379. m_fSustainOn = FALSE;
  1380. m_fNoteOn = FALSE;
  1381. m_fTag = FALSE;
  1382. m_stStartTime = 0;
  1383. m_stStopTime = 0x7fffffffffffffff;
  1384. m_stWaveStopTime = 0;
  1385. m_vrVolume = 0;
  1386. m_fAllowOverlap = FALSE;
  1387. m_pRegion = NULL;
  1388. m_pReverbSend = NULL;
  1389. m_pChorusSend = NULL;
  1390. m_dwLoopType = 0;
  1391. for ( int i = 0; i < MAX_DAUD_CHAN; i++ )
  1392. {
  1393. m_vfLastVolume[i] = 0;
  1394. m_vrLastVolume[i] = 0;
  1395. }
  1396. }
  1397. VREL CVoice::m_svrPanToVREL[128];
  1398. void CVoice::Init()
  1399. {
  1400. static BOOL fBeenHereBefore = FALSE;
  1401. if (fBeenHereBefore) return;
  1402. fBeenHereBefore = TRUE;
  1403. CVoiceLFO::Init();
  1404. CVoiceEG::Init();
  1405. CDigitalAudio::Init();
  1406. WORD nI;
  1407. for (nI = 1; nI < 128; nI++)
  1408. {
  1409. double flTemp;
  1410. flTemp = nI;
  1411. flTemp /= 127.0;
  1412. flTemp = log10(flTemp);
  1413. flTemp *= 1000.0;
  1414. m_svrPanToVREL[nI] = (long) flTemp;
  1415. }
  1416. m_svrPanToVREL[0] = -2500;
  1417. }
  1418. void CVoice::StopVoice(STIME stTime)
  1419. {
  1420. if (m_fNoteOn)
  1421. {
  1422. if (stTime <= m_stStartTime) stTime = m_stStartTime + 1;
  1423. m_PitchEG.StopVoice(stTime);
  1424. m_VolumeEG.StopVoice(stTime);
  1425. m_fNoteOn = FALSE;
  1426. m_fSustainOn = FALSE;
  1427. m_stStopTime = stTime;
  1428. m_stWaveStopTime = 0;
  1429. if (m_dwLoopType == WLOOP_TYPE_RELEASE)
  1430. {
  1431. m_DigitalAudio.BreakLoop();
  1432. }
  1433. }
  1434. }
  1435. void CVoice::QuickStopVoice(STIME stTime)
  1436. {
  1437. m_fTag = TRUE;
  1438. if (m_fNoteOn || m_fSustainOn)
  1439. {
  1440. if (stTime <= m_stStartTime) stTime = m_stStartTime + 1;
  1441. m_PitchEG.StopVoice(stTime);
  1442. m_VolumeEG.QuickStopVoice(stTime, m_pSynth->m_dwSampleRate);
  1443. m_fNoteOn = FALSE;
  1444. m_fSustainOn = FALSE;
  1445. m_stStopTime = stTime;
  1446. }
  1447. else
  1448. {
  1449. m_VolumeEG.QuickStopVoice(m_stStopTime, m_pSynth->m_dwSampleRate);
  1450. }
  1451. }
  1452. BOOL CVoice::StartVoice(CSynth *pSynth,
  1453. CSourceRegion *pRegion,
  1454. STIME stStartTime,
  1455. CModWheelIn * pModWheelIn,
  1456. CPitchBendIn * pPitchBendIn,
  1457. CExpressionIn * pExpressionIn,
  1458. CVolumeIn * pVolumeIn,
  1459. CPanIn * pPanIn,
  1460. CPressureIn * pPressureIn,
  1461. CReverbIn * pReverbSend,
  1462. CChorusIn * pChorusSend,
  1463. CCutOffFreqIn * pCCutOffFreqIn,
  1464. CBusIds * pBusIds,
  1465. WORD nKey,
  1466. WORD nVelocity,
  1467. VREL vrVolume,
  1468. PREL prPitch)
  1469. {
  1470. m_pSynth = pSynth;
  1471. CSourceArticulation * pArticulation = pRegion->m_pArticulation;
  1472. if (pArticulation == NULL)
  1473. {
  1474. return FALSE;
  1475. }
  1476. m_dwLoopType = pRegion->m_Sample.m_dwLoopType;
  1477. // if we're going to handle volume later, don't read it now.
  1478. if (!pSynth->m_fAllowVolumeChangeWhilePlayingNote)
  1479. vrVolume += pVolumeIn->GetVolume(stStartTime);
  1480. prPitch += pRegion->m_prTuning;
  1481. m_dwGroup = pRegion->m_bGroup;
  1482. m_fAllowOverlap = pRegion->m_bAllowOverlap;
  1483. vrVolume += CMIDIRecorder::VelocityToVolume(nVelocity);
  1484. vrVolume += pRegion->m_vrAttenuation;
  1485. m_lDefaultPan = pRegion->m_pArticulation->m_sDefaultPan;
  1486. // ignore pan here if allowing pan to vary after note starts
  1487. // or if the source is multichannel or the dest is mono
  1488. //
  1489. m_fIgnorePan = pRegion->IsMultiChannel();
  1490. if (pBusIds->m_dwBusCount == 1)
  1491. {
  1492. DWORD dwFunctionID;
  1493. if (m_pSynth->BusIDToFunctionID(pBusIds->m_dwBusIds[0], &dwFunctionID, NULL, NULL))
  1494. {
  1495. if (dwFunctionID == DSBUSID_LEFT)
  1496. {
  1497. m_fIgnorePan = TRUE;
  1498. }
  1499. }
  1500. }
  1501. VREL vrVolumeL;
  1502. VREL vrVolumeR;
  1503. if ( pSynth->m_dwStereo &&
  1504. !pSynth->m_fAllowPanWhilePlayingNote &&
  1505. !m_fIgnorePan)
  1506. {
  1507. long lPan = pPanIn->GetPan(stStartTime) + m_lDefaultPan;
  1508. if (lPan < 0)
  1509. lPan = 0;
  1510. if (lPan > 127)
  1511. lPan = 127;
  1512. vrVolumeL = m_svrPanToVREL[127 - lPan] + vrVolume;
  1513. vrVolumeR = m_svrPanToVREL[lPan] + vrVolume;
  1514. }
  1515. else
  1516. {
  1517. vrVolumeL = vrVolume;
  1518. vrVolumeR = vrVolume;
  1519. }
  1520. VREL vrVolumeReverb = vrVolume;
  1521. VREL vrVolumeChorus = vrVolume;
  1522. PREL prBusPitchBend = 0; // This gets a pitch offset that is set by DSound in response to SetFrequency and Doppler commands.
  1523. // When this is applied to multiple buses, only one of the values can be used, so we always give
  1524. // preference to the buffer that has DSBUSID_DYNAMIC_0 for the functional id, since that
  1525. // would most likely be a 3D sound effect.
  1526. BOOL fDynamic = false;
  1527. for( DWORD i = 0; i < pBusIds->m_dwBusCount; i++ )
  1528. {
  1529. DWORD dwFunctionID;
  1530. PREL prGetPitch = 0;
  1531. if (m_pSynth->BusIDToFunctionID(pBusIds->m_dwBusIds[i], &dwFunctionID, &prGetPitch, NULL))
  1532. {
  1533. if (!fDynamic)
  1534. {
  1535. // If no previous bus was dynamic, get this value.
  1536. prBusPitchBend = prGetPitch;
  1537. }
  1538. m_vrBaseVolume[i] = MIN_VOLUME;
  1539. if (DSBUSID_IS_SPKR_LOC(dwFunctionID))
  1540. {
  1541. if (pRegion->IsMultiChannel())
  1542. {
  1543. // Explicit channel assignment with no pan. For every bus
  1544. // that matches a bit in the channel mask, turn it on.
  1545. //
  1546. if (pRegion->m_dwChannel & (1 << dwFunctionID))
  1547. {
  1548. m_vrBaseVolume[i] = vrVolume;
  1549. }
  1550. }
  1551. else
  1552. {
  1553. switch(dwFunctionID)
  1554. {
  1555. case DSBUSID_LEFT:
  1556. m_vrBaseVolume[i] = vrVolumeL;
  1557. break;
  1558. case DSBUSID_RIGHT:
  1559. m_vrBaseVolume[i] = vrVolumeR;
  1560. break;
  1561. }
  1562. }
  1563. }
  1564. else
  1565. {
  1566. // Not a speaker location, a send or a 3D buffer.
  1567. //
  1568. switch(dwFunctionID)
  1569. {
  1570. case DSBUSID_REVERB_SEND:
  1571. m_vrBaseVolume[i] = vrVolumeReverb;
  1572. break;
  1573. case DSBUSID_CHORUS_SEND:
  1574. m_vrBaseVolume[i] = vrVolumeChorus;
  1575. break;
  1576. case DSBUSID_NULL:
  1577. m_vrBaseVolume[i] = MIN_VOLUME;
  1578. break;
  1579. case DSBUSID_DYNAMIC_0:
  1580. fDynamic = true;
  1581. default:
  1582. m_vrBaseVolume[i] = vrVolume;
  1583. }
  1584. }
  1585. m_vrLastVolume[i] = MIN_VOLUME;
  1586. m_vfLastVolume[i] = m_DigitalAudio.VRELToVFRACT(MIN_VOLUME);
  1587. }
  1588. }
  1589. m_stMixTime = m_LFO.StartVoice(&pArticulation->m_LFO,
  1590. stStartTime, pModWheelIn, pPressureIn);
  1591. STIME stMixTime = m_LFO2.StartVoice(&pArticulation->m_LFO2,
  1592. stStartTime, pModWheelIn, pPressureIn);
  1593. if (stMixTime < m_stMixTime)
  1594. {
  1595. m_stMixTime = stMixTime;
  1596. }
  1597. stMixTime = m_PitchEG.StartVoice(&pArticulation->m_PitchEG,
  1598. stStartTime, nKey, nVelocity, 0);
  1599. if (stMixTime < m_stMixTime)
  1600. {
  1601. m_stMixTime = stMixTime;
  1602. }
  1603. // Force attack to never be shorter than a millisecond.
  1604. stMixTime = m_VolumeEG.StartVoice(&pArticulation->m_VolumeEG,
  1605. stStartTime, nKey, nVelocity, pSynth->m_dwSampleRate/1000);
  1606. if (stMixTime < m_stMixTime)
  1607. {
  1608. m_stMixTime = stMixTime;
  1609. }
  1610. if (m_stMixTime > pSynth->m_stMaxSpan)
  1611. {
  1612. m_stMixTime = pSynth->m_stMaxSpan;
  1613. }
  1614. m_Filter.StartVoice(&pArticulation->m_Filter,
  1615. &m_LFO, &m_PitchEG, nKey, nVelocity);
  1616. // Make sure we have a pointer to the wave ready:
  1617. if ((pRegion->m_Sample.m_pWave == NULL) || (pRegion->m_Sample.m_pWave->m_pnWave == NULL))
  1618. {
  1619. return (FALSE); // Do nothing if no sample.
  1620. }
  1621. m_DigitalAudio.StartVoice(pSynth,
  1622. &pRegion->m_Sample,
  1623. prPitch,
  1624. (long)nKey);
  1625. m_pPitchBendIn = pPitchBendIn;
  1626. m_pExpressionIn = pExpressionIn;
  1627. m_pPanIn = pPanIn;
  1628. m_pReverbSend = pReverbSend;
  1629. m_pChorusSend = pChorusSend;
  1630. m_CCutOffFreqIn = pCCutOffFreqIn;
  1631. m_pVolumeIn = pVolumeIn;
  1632. m_BusIds = *pBusIds;
  1633. m_fNoteOn = TRUE;
  1634. m_fTag = FALSE;
  1635. m_fSustainOn = FALSE;
  1636. m_stStartTime = stStartTime;
  1637. m_stLastMix = stStartTime - 1;
  1638. m_stStopTime = 0x7fffffffffffffff;
  1639. m_stWaveStopTime = 0;
  1640. //
  1641. // Zero length attack,
  1642. // be sure initial settings aren't missed....
  1643. //
  1644. if (m_stMixTime == 0)
  1645. {
  1646. PREL prNewPitch;
  1647. COEFF cfK, cfB1, cfB2;
  1648. GetNewPitch(stStartTime, prNewPitch);
  1649. GetNewCoeff(stStartTime, m_prLastCutOff, cfK, cfB1, cfB2);
  1650. m_DigitalAudio.Mix(NULL,
  1651. 0,
  1652. 0,
  1653. 0,
  1654. 0,
  1655. NULL,
  1656. NULL,
  1657. prNewPitch + prBusPitchBend,
  1658. m_Filter.IsFiltered(),
  1659. cfK, cfB1, cfB2);
  1660. }
  1661. m_vrVolume = MAX_VOLUME;
  1662. return (TRUE);
  1663. }
  1664. BOOL CVoice::StartWave(CSynth *pSynth,
  1665. CWaveArt *pWaveArt,
  1666. DWORD dwVoiceId,
  1667. STIME stStartTime,
  1668. CPitchBendIn * pPitchBendIn,
  1669. CExpressionIn * pExpressionIn,
  1670. CVolumeIn * pVolumeIn,
  1671. CPanIn * pPanIn,
  1672. CReverbIn * pReverbSend,
  1673. CChorusIn * pChorusSend,
  1674. CCutOffFreqIn * pCCutOffFreqIn,
  1675. CBusIds * pBusIds,
  1676. VREL vrVolume,
  1677. PREL prPitch,
  1678. SAMPLE_TIME stVoiceStart,
  1679. SAMPLE_TIME stLoopStart,
  1680. SAMPLE_TIME stLoopEnd
  1681. )
  1682. {
  1683. m_pSynth = pSynth;
  1684. DWORD dwFuncId = pWaveArt->m_WaveArtDl.ulBus;
  1685. VREL vrVolumeReverb = vrVolume;
  1686. VREL vrVolumeChorus = vrVolume;
  1687. m_fIgnorePan = (BOOL)(DSBUSID_IS_SPKR_LOC(dwFuncId) && (pWaveArt->m_WaveArtDl.usOptions & F_WAVELINK_MULTICHANNEL));
  1688. if (pBusIds->m_dwBusCount == 1)
  1689. {
  1690. DWORD dwFunctionID;
  1691. if (m_pSynth->BusIDToFunctionID(pBusIds->m_dwBusIds[0], &dwFunctionID, NULL, NULL))
  1692. {
  1693. if (dwFunctionID == DSBUSID_LEFT)
  1694. {
  1695. m_fIgnorePan = TRUE;
  1696. }
  1697. }
  1698. }
  1699. for( DWORD i = 0; i < pBusIds->m_dwBusCount; i++ )
  1700. {
  1701. m_vrBaseVolume[i] = MIN_VOLUME;
  1702. DWORD dwFunctionID;
  1703. if (m_pSynth->BusIDToFunctionID(pBusIds->m_dwBusIds[i], &dwFunctionID, NULL, NULL))
  1704. {
  1705. // If this bus is a speaker location
  1706. //
  1707. if (DSBUSID_IS_SPKR_LOC(dwFunctionID))
  1708. {
  1709. if (pWaveArt->m_WaveArtDl.usOptions & F_WAVELINK_MULTICHANNEL)
  1710. {
  1711. if (dwFuncId == dwFunctionID)
  1712. {
  1713. m_vrBaseVolume[i] = vrVolume;
  1714. }
  1715. }
  1716. else
  1717. {
  1718. if (dwFunctionID == DSBUSID_LEFT || dwFunctionID == DSBUSID_RIGHT)
  1719. {
  1720. m_vrBaseVolume[i] = vrVolume;
  1721. }
  1722. }
  1723. }
  1724. else switch (dwFunctionID)
  1725. {
  1726. case DSBUSID_REVERB_SEND:
  1727. m_vrBaseVolume[i] = vrVolumeReverb;
  1728. break;
  1729. case DSBUSID_CHORUS_SEND:
  1730. m_vrBaseVolume[i] = vrVolumeChorus;
  1731. break;
  1732. case DSBUSID_NULL:
  1733. m_vrBaseVolume[i] = MIN_VOLUME;
  1734. break;
  1735. default:
  1736. m_vrBaseVolume[i] = vrVolume;
  1737. }
  1738. m_vrLastVolume[i] = MIN_VOLUME;
  1739. m_vfLastVolume[i] = m_DigitalAudio.VRELToVFRACT(MIN_VOLUME);
  1740. }
  1741. }
  1742. // Initialize an envelope for wave playing
  1743. //
  1744. CSourceEG WaveVolumeEG;
  1745. WaveVolumeEG.Init();
  1746. WaveVolumeEG.m_pcSustain = 1000;
  1747. // Force the envelope attack and release to be no smaller than 4ms. This ensures we won't get
  1748. // clicks if we start and stop at non-zero crossings.
  1749. m_stMixTime = m_VolumeEG.StartVoice(&WaveVolumeEG, stStartTime, 0, 0, pSynth->m_dwSampleRate/250);
  1750. if (m_stMixTime > pSynth->m_stMaxSpan)
  1751. {
  1752. m_stMixTime = pSynth->m_stMaxSpan;
  1753. }
  1754. m_pPitchBendIn = pPitchBendIn;
  1755. m_pExpressionIn = pExpressionIn;
  1756. m_pPanIn = pPanIn;
  1757. m_pReverbSend = pReverbSend;
  1758. m_pChorusSend = pChorusSend;
  1759. m_CCutOffFreqIn = pCCutOffFreqIn;
  1760. m_pVolumeIn = pVolumeIn;
  1761. m_BusIds = *pBusIds;
  1762. m_fNoteOn = TRUE;
  1763. m_fTag = FALSE;
  1764. m_stStartTime = stStartTime;
  1765. m_stLastMix = stStartTime - 1;
  1766. m_stStopTime = 0x7fffffffffffffff;
  1767. m_stWaveStopTime = 0;
  1768. m_dwGroup = 0;
  1769. m_lDefaultPan = 0;
  1770. m_vrVolume = 0;
  1771. m_fAllowOverlap = FALSE;
  1772. m_fSustainOn = FALSE;
  1773. m_dwVoiceId = dwVoiceId;
  1774. m_LFO.Enable(FALSE); // Disable LFO.
  1775. m_LFO2.Enable(FALSE); // Disable LFO2.
  1776. m_PitchEG.Enable(FALSE); // Disable Pitch Envelope.
  1777. m_Filter.m_Source.m_prCutoff = 0x7FFF;
  1778. m_DigitalAudio.StartWave(pSynth,
  1779. pWaveArt,
  1780. prPitch,
  1781. stVoiceStart,
  1782. stLoopStart,
  1783. stLoopEnd);
  1784. return (TRUE);
  1785. }
  1786. SAMPLE_POSITION CVoice::GetCurrentPos()
  1787. {
  1788. return m_DigitalAudio.GetCurrentPos();
  1789. }
  1790. void CVoice::ClearVoice()
  1791. {
  1792. m_fInUse = FALSE;
  1793. m_DigitalAudio.ClearVoice();
  1794. }
  1795. // return the volume delta at time <stTime>.
  1796. // volume is sum of volume envelope, LFO, expression, optionally the
  1797. // channel volume if we're allowing it to change, and optionally the current
  1798. // pan if we're allowing that to change.
  1799. // This will be added to the base volume calculated in CVoice::StartVoice().
  1800. inline void CVoice::GetNewVolume(STIME stTime, VREL& vrVolume, VREL& vrVolumeL, VREL& vrVolumeR, VREL& vrVolumeReverb, VREL& vrVolumeChorus)
  1801. {
  1802. STIME stMixTime = m_stMixTime;
  1803. //
  1804. // the evelope volume is used by code that detects whether this note is off
  1805. // and for voice stealing
  1806. //
  1807. m_vrVolume = m_VolumeEG.GetVolume(stTime, &stMixTime);
  1808. if (stMixTime < m_stMixTime)
  1809. m_stMixTime = stMixTime;
  1810. vrVolume = m_vrVolume;
  1811. vrVolume += m_LFO.GetVolume(stTime, &stMixTime);
  1812. if (stMixTime < m_stMixTime)
  1813. m_stMixTime = stMixTime;
  1814. vrVolume += m_pExpressionIn->GetVolume(stTime);
  1815. if (m_pSynth->m_fAllowVolumeChangeWhilePlayingNote)
  1816. vrVolume += m_pVolumeIn->GetVolume(stTime);
  1817. vrVolume += m_pSynth->m_vrGainAdjust;
  1818. // handle pan here if allowing pan to vary after note starts
  1819. vrVolumeL = vrVolume;
  1820. vrVolumeR = vrVolume;
  1821. if (m_pSynth->m_dwStereo && m_pSynth->m_fAllowPanWhilePlayingNote && !m_fIgnorePan)
  1822. {
  1823. // add current pan & instrument default pan
  1824. LONG lPan;
  1825. if (m_pPanIn)
  1826. {
  1827. lPan = m_pPanIn->GetPan(stTime) + m_lDefaultPan;
  1828. }
  1829. else
  1830. {
  1831. lPan = 63;
  1832. }
  1833. // don't go off either end....
  1834. if (lPan < 0) lPan = 0;
  1835. if (lPan > 127) lPan = 127;
  1836. vrVolumeL += m_svrPanToVREL[127 - lPan];
  1837. vrVolumeR += m_svrPanToVREL[lPan];
  1838. }
  1839. // Get Reverb Send volume
  1840. vrVolumeReverb = vrVolume + m_pReverbSend->GetVolume(stTime);
  1841. // Get Chorus Send volume
  1842. vrVolumeChorus = vrVolume + m_pChorusSend->GetVolume(stTime);
  1843. }
  1844. // Returns the current pitch for time <stTime>.
  1845. // Pitch is the sum of the pitch LFO, the pitch envelope, and the current
  1846. // pitch bend.
  1847. inline void CVoice::GetNewPitch(STIME stTime, PREL& prPitch)
  1848. {
  1849. STIME stMixTime = m_stMixTime;
  1850. prPitch = m_LFO.GetPitch(stTime, &stMixTime);
  1851. if (m_stMixTime > stMixTime) m_stMixTime = stMixTime;
  1852. prPitch += m_LFO2.GetPitch(stTime, &stMixTime);
  1853. if (m_stMixTime > stMixTime) m_stMixTime = stMixTime;
  1854. prPitch += m_PitchEG.GetPitch(stTime, &stMixTime);
  1855. if (m_stMixTime > stMixTime) m_stMixTime = stMixTime;
  1856. prPitch += m_pPitchBendIn->GetPitch(stTime);
  1857. }
  1858. // Returns the current cutoff frequency for time <stTime>.
  1859. // cutoff frequency is the sum of the pitch LFO, the pitch envelope, and the current
  1860. // MIDI filter CC control.
  1861. inline void CVoice::GetNewCoeff(STIME stTime, PREL& prCutOff, COEFF& cfK, COEFF& cfB1, COEFF& cfB2)
  1862. {
  1863. DWORD dwfreq;
  1864. // returned frequency is in semitones, where 64 is the mid range
  1865. dwfreq = m_CCutOffFreqIn->GetFrequency(stTime);
  1866. prCutOff = (dwfreq - 64)*100; // convert to PREL's
  1867. m_Filter.GetCoeff(stTime, prCutOff, cfK, cfB1, cfB2);
  1868. }
  1869. DWORD CVoice::Mix(short **ppvBuffer,
  1870. DWORD dwBufferFlags,
  1871. DWORD dwLength,
  1872. STIME stStart,
  1873. STIME stEnd)
  1874. {
  1875. BOOL fInUse = TRUE;
  1876. BOOL fFullMix = TRUE;
  1877. STIME stEndMix = stStart;
  1878. STIME stStartMix = m_stStartTime;
  1879. COEFF cfK, cfB1, cfB2;
  1880. PREL prPitch;
  1881. PREL prCutOff;
  1882. VREL vrVolume, vrVolumeL, vrVolumeR;
  1883. VREL vrVolumeReverb, vrVolumeChorus;
  1884. VREL vrMaxVolumeDelta;
  1885. VFRACT vfNewVolume[MAX_DAUD_CHAN];
  1886. VFRACT vfLastVolume[MAX_DAUD_CHAN];
  1887. short *ppsMixBuffers[MAX_DAUD_CHAN];
  1888. if (stStartMix < stStart)
  1889. {
  1890. stStartMix = stStart;
  1891. }
  1892. if (m_stLastMix >= stEnd)
  1893. {
  1894. return (0);
  1895. }
  1896. if (m_stLastMix >= stStartMix)
  1897. {
  1898. stStartMix = m_stLastMix;
  1899. }
  1900. while (stStartMix < stEnd && fInUse)
  1901. {
  1902. stEndMix = stStartMix + m_stMixTime;
  1903. if (stEndMix > stEnd)
  1904. {
  1905. stEndMix = stEnd;
  1906. }
  1907. m_stMixTime = m_pSynth->m_stMaxSpan;
  1908. if ((m_stLastMix < m_stStopTime) && (m_stStopTime < stEnd))
  1909. {
  1910. if (m_stMixTime > (m_stStopTime - m_stLastMix))
  1911. {
  1912. m_stMixTime = m_stStopTime - m_stLastMix;
  1913. }
  1914. }
  1915. //
  1916. // Get the new pitch
  1917. //
  1918. GetNewPitch(stEndMix, prPitch);
  1919. //
  1920. // Get the new volume
  1921. //
  1922. GetNewVolume(stEndMix, vrVolume, vrVolumeL, vrVolumeR, vrVolumeReverb, vrVolumeChorus);
  1923. //
  1924. // Get the new filter coeficients
  1925. //
  1926. GetNewCoeff(stEndMix, prCutOff, cfK, cfB1, cfB2);
  1927. //
  1928. // Check to see if the volume is precievable, if not kill voice
  1929. //
  1930. if (m_VolumeEG.InRelease(stEndMix))
  1931. {
  1932. if (m_vrVolume < PERCEIVED_MIN_VOLUME) // End of release slope
  1933. {
  1934. // Breaking the loop ensures that the mixmulti functions don't mix any more samples
  1935. // for looped wave Without this the mix engine will mix a few more samples for
  1936. // looped waves resulting in a pop at the end of the wave.
  1937. m_DigitalAudio.BreakLoop();
  1938. fInUse = FALSE;
  1939. }
  1940. }
  1941. vrMaxVolumeDelta = 0;
  1942. vfNewVolume[0] = 0;
  1943. ppsMixBuffers[0] = NULL;
  1944. DWORD dwMixBufferCount = 0;
  1945. PREL prBusPitchBend = 0; // This gets a pitch offset that is set by DSound in response to SetFrequency and Doppler commands.
  1946. // When this is applied to multiple buses, only one of the values can be used, so we always give
  1947. // preference to the buffer that has DSBUSID_DYNAMIC_0 for the functional id, since that
  1948. // would most likely be a 3D sound effect.
  1949. BOOL fDynamic = false;
  1950. if (dwBufferFlags & BUFFERFLAG_MULTIBUFFER)
  1951. {
  1952. // Iterate through each bus id in the voice, assigning a sink bus to each one.
  1953. for ( DWORD nBusID = 0; nBusID < m_BusIds.m_dwBusCount; nBusID++ )
  1954. {
  1955. DWORD dwFunctionalID;
  1956. DWORD dwBusIndex;
  1957. PREL prGetPitch;
  1958. if (m_pSynth->BusIDToFunctionID(m_BusIds.m_dwBusIds[nBusID], &dwFunctionalID, &prGetPitch, &dwBusIndex))
  1959. {
  1960. if (!fDynamic)
  1961. {
  1962. // If no previous bus was dynamic, get this value.
  1963. prBusPitchBend = prGetPitch;
  1964. }
  1965. // Default to original volume (before pan, reverb or chorus modifiers.)
  1966. VREL vrTemp = vrVolume;
  1967. // Replace for any of the other cases (left, right, reverb, chorus.)
  1968. if ( dwFunctionalID == DSBUSID_NULL )
  1969. {
  1970. continue;
  1971. }
  1972. if ( dwFunctionalID == DSBUSID_LEFT )
  1973. {
  1974. vrTemp = vrVolumeL;
  1975. }
  1976. if ( dwFunctionalID == DSBUSID_RIGHT )
  1977. {
  1978. vrTemp = vrVolumeR;
  1979. }
  1980. else if ( dwFunctionalID == DSBUSID_REVERB_SEND )
  1981. {
  1982. vrTemp = vrVolumeReverb;
  1983. }
  1984. else if ( dwFunctionalID == DSBUSID_CHORUS_SEND )
  1985. {
  1986. vrTemp = vrVolumeChorus;
  1987. }
  1988. else if ( dwFunctionalID == DSBUSID_DYNAMIC_0 )
  1989. {
  1990. fDynamic = true;
  1991. }
  1992. vrMaxVolumeDelta = max((long)vrMaxVolumeDelta, abs(vrTemp - m_vrLastVolume[nBusID]));
  1993. m_vrLastVolume[nBusID] = vrTemp;
  1994. vrTemp += m_vrBaseVolume[nBusID];
  1995. vfNewVolume[dwMixBufferCount] = m_DigitalAudio.VRELToVFRACT(vrTemp);
  1996. vfLastVolume[dwMixBufferCount] = m_vfLastVolume[nBusID];
  1997. m_vfLastVolume[nBusID] = vfNewVolume[dwMixBufferCount];
  1998. ppsMixBuffers[dwMixBufferCount] = &ppvBuffer[dwBusIndex][(stStartMix - stStart)];
  1999. dwMixBufferCount++;
  2000. }
  2001. }
  2002. }
  2003. else
  2004. {
  2005. // This is the DX7 compatibility case.
  2006. vrMaxVolumeDelta = max((long)vrMaxVolumeDelta, abs(vrVolumeL - m_vrLastVolume[0]));
  2007. m_vrLastVolume[0] = vrVolumeL;
  2008. vfNewVolume[0] = m_DigitalAudio.VRELToVFRACT(m_vrBaseVolume[0] + vrVolumeL);
  2009. vfLastVolume[0] = m_vfLastVolume[0];
  2010. m_vfLastVolume[0] = vfNewVolume[0];
  2011. dwMixBufferCount = 1;
  2012. if ( dwBufferFlags & BUFFERFLAG_INTERLEAVED ) // Is this a stereo buffer?
  2013. {
  2014. vrMaxVolumeDelta = max((long)vrMaxVolumeDelta, abs(vrVolumeR - m_vrLastVolume[1]));
  2015. m_vrLastVolume[1] = vrVolumeR;
  2016. vfNewVolume[1] = m_DigitalAudio.VRELToVFRACT(m_vrBaseVolume[1] + vrVolumeR);
  2017. vfLastVolume[1] = m_vfLastVolume[1];
  2018. m_vfLastVolume[1] = vfNewVolume[1];
  2019. ppsMixBuffers[0] = &ppvBuffer[0][(stStartMix - stStart) << 1];
  2020. }
  2021. else // Or mono?
  2022. {
  2023. ppsMixBuffers[0] = &ppvBuffer[0][(stStartMix - stStart)];
  2024. }
  2025. }
  2026. // If dwMixBufferCount is 0, this indicates there is no buffer available to play into.
  2027. // This is caused by a buffer being deactivated. Under such circumstances, the
  2028. // voice should not continue playing, or it will hold until the buffer reactivates, which
  2029. // doesn't make sense. So, set fInUse to FALSE.
  2030. if (dwMixBufferCount)
  2031. {
  2032. DWORD dwIsFiltered = m_Filter.IsFiltered();
  2033. if (dwIsFiltered)
  2034. {
  2035. vrMaxVolumeDelta = max((long)vrMaxVolumeDelta, abs(prCutOff - m_prLastCutOff));
  2036. m_prLastCutOff = prCutOff;
  2037. }
  2038. //
  2039. // note: mix will in some cases modify the pointers found ppsMixBuffers array
  2040. //
  2041. fFullMix = m_DigitalAudio.Mix(ppsMixBuffers, // Array of mix buffers
  2042. dwMixBufferCount, // Number of mix buffers
  2043. (dwBufferFlags & BUFFERFLAG_INTERLEAVED), // Are the buffers interleaved data?
  2044. (DWORD) (stEndMix - stStartMix), // Length to mix in Samples
  2045. vrMaxVolumeDelta, //
  2046. vfNewVolume,
  2047. vfLastVolume,
  2048. prPitch + prBusPitchBend, // Pitch to play the sample too
  2049. dwIsFiltered, // Is the mix filtered
  2050. cfK, cfB1, cfB2);
  2051. stStartMix = stEndMix;
  2052. }
  2053. else
  2054. {
  2055. fInUse = FALSE;
  2056. }
  2057. }
  2058. m_fInUse = fInUse && fFullMix;
  2059. if (!m_fInUse)
  2060. {
  2061. ClearVoice();
  2062. m_stStopTime = stEndMix; // For measurement purposes.
  2063. }
  2064. m_stLastMix = stEndMix;
  2065. return (dwLength);
  2066. }