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.

1724 lines
54 KiB

  1. //
  2. // Copyright (c) 1996-2001 Microsoft Corporation
  3. // Instrument.cpp
  4. //
  5. #ifdef DMSYNTH_MINIPORT
  6. #include "common.h"
  7. #else
  8. #include "simple.h"
  9. #include <mmsystem.h>
  10. #include <dmerror.h>
  11. #include "synth.h"
  12. #include "math.h"
  13. #include "debug.h"
  14. // @@BEGIN_DDKSPLIT -- This section will be removed in the DDK sample. See ddkreadme.txt for more info.
  15. #include "..\shared\validate.h"
  16. #if 0 // The following section will only take affect in the DDK sample.
  17. // @@END_DDKSPLIT
  18. #include "validate.h"
  19. // @@BEGIN_DDKSPLIT -- This section will be removed in the DDK sample.
  20. #endif
  21. // @@END_DDKSPLIT
  22. #endif
  23. void MemDump(char * prompt);
  24. //#include <windowsx.h>
  25. CSourceLFO::CSourceLFO()
  26. {
  27. m_pfFrequency = 3804; // f = (256*4096*16*5hz)/(samplerate)
  28. m_stDelay = 0;
  29. m_prMWPitchScale = 0;
  30. m_vrMWVolumeScale = 0;
  31. m_vrVolumeScale = 0;
  32. m_prPitchScale = 0;
  33. m_prCPPitchScale = 0;
  34. m_vrCPVolumeScale = 0;
  35. m_prCutoffScale = 0;
  36. m_prMWCutoffScale = 0;
  37. m_prCPCutoffScale = 0;
  38. }
  39. void CSourceLFO::Init(DWORD dwSampleRate)
  40. {
  41. m_pfFrequency = (256 * 4096 * 16 * 5) / dwSampleRate;
  42. m_stDelay = 0;
  43. m_prMWPitchScale = 0;
  44. m_vrMWVolumeScale = 0;
  45. m_vrVolumeScale = 0;
  46. m_prPitchScale = 0;
  47. m_prCPPitchScale = 0;
  48. m_vrCPVolumeScale = 0;
  49. m_prCutoffScale = 0;
  50. m_prMWCutoffScale = 0;
  51. m_prCPCutoffScale = 0;
  52. }
  53. void CSourceLFO::SetSampleRate(long lChange)
  54. {
  55. if (lChange > 0)
  56. {
  57. m_stDelay <<= lChange;
  58. m_pfFrequency <<= lChange;
  59. }
  60. else
  61. {
  62. m_stDelay >>= -lChange;
  63. m_pfFrequency >>= -lChange;
  64. }
  65. }
  66. void CSourceLFO::Verify()
  67. {
  68. FORCEBOUNDS(m_pfFrequency,64,7600);
  69. FORCEBOUNDS(m_stDelay,0,441000);
  70. FORCEBOUNDS(m_vrVolumeScale,-1200,1200);
  71. FORCEBOUNDS(m_vrMWVolumeScale,-1200,1200);
  72. FORCEBOUNDS(m_prPitchScale,-1200,1200);
  73. FORCEBOUNDS(m_prMWPitchScale,-1200,1200);
  74. FORCEBOUNDS(m_prCPPitchScale,-1200,1200);
  75. FORCEBOUNDS(m_vrCPVolumeScale,-1200,1200);
  76. FORCEBOUNDS(m_prCutoffScale, -12800, 12800);
  77. FORCEBOUNDS(m_prMWCutoffScale, -12800, 12800);
  78. FORCEBOUNDS(m_prCPCutoffScale, -12800, 12800);
  79. }
  80. CSourceEG::CSourceEG()
  81. {
  82. Init();
  83. }
  84. void CSourceEG::Init()
  85. {
  86. m_stAttack = 0;
  87. m_stDecay = 0;
  88. m_pcSustain = 1000;
  89. m_stRelease = 0;
  90. m_trVelAttackScale = 0;
  91. m_trKeyDecayScale = 0;
  92. m_sScale = 0;
  93. m_stDelay = 0;
  94. m_stHold = 0;
  95. m_prCutoffScale = 0;
  96. }
  97. void CSourceEG::SetSampleRate(long lChange)
  98. {
  99. if (lChange > 0)
  100. {
  101. m_stAttack <<= lChange;
  102. m_stDecay <<= lChange;
  103. m_stRelease <<= lChange;
  104. }
  105. else
  106. {
  107. m_stAttack >>= -lChange;
  108. m_stDecay >>= -lChange;
  109. m_stRelease >>= -lChange;
  110. }
  111. }
  112. void CSourceEG::Verify()
  113. {
  114. FORCEBOUNDS(m_stAttack,0,1764000);
  115. FORCEBOUNDS(m_stDecay,0,1764000);
  116. FORCEBOUNDS(m_pcSustain,0,1000);
  117. FORCEBOUNDS(m_stRelease,0,1764000);
  118. FORCEBOUNDS(m_sScale,-1200,1200);
  119. FORCEBOUNDS(m_trKeyDecayScale,-12000,12000);
  120. FORCEBOUNDS(m_trVelAttackScale,-12000,12000);
  121. FORCEBOUNDS(m_trKeyHoldScale,-12000,12000);
  122. FORCEBOUNDS(m_prCutoffScale,-12800,12800);
  123. }
  124. CSourceFilter::CSourceFilter()
  125. {
  126. Init(22050);
  127. }
  128. void CSourceFilter::Init(DWORD dwSampleRate)
  129. {
  130. // First, calculate the playback samplerate in pitch rels.
  131. // The reference frequency is a440, which is midi note 69.
  132. // So, calculate the ratio of the sample rate to 440 and
  133. // convert into prels (1200 per octave), then add the
  134. // offset of 6900.
  135. double fSampleRate = (double)dwSampleRate;
  136. fSampleRate /= 440.0;
  137. fSampleRate = log(fSampleRate) / log(2.0);
  138. fSampleRate *= 1200.0;
  139. fSampleRate += 6900.0;
  140. m_prSampleRate = (PRELS)fSampleRate;
  141. m_prCutoff = (PRELS)0x7FFF;
  142. m_vrQ = (VRELS)0;
  143. m_prVelScale = (PRELS)0;
  144. m_prCutoffSRAdjust = 0;
  145. m_iQIndex = 0;
  146. }
  147. void CSourceFilter::SetSampleRate(LONG lChange)
  148. {
  149. // lChange == 1 -> doubles -> add 1200 cents
  150. // lChange == 2 -> quad -> add 2400 cents
  151. // lChange == -1 -> halves -> sub 1200 cents
  152. // lChange == -2 -> 1/4ths -> sub 2400 cents
  153. //
  154. if (lChange > 0)
  155. {
  156. m_prSampleRate += (1200 << (lChange - 1));
  157. }
  158. else
  159. {
  160. m_prSampleRate -= (1200 << ((-lChange) - 1));
  161. }
  162. m_prCutoffSRAdjust = FILTER_FREQ_RANGE - m_prSampleRate + m_prCutoff;
  163. }
  164. void CSourceFilter::Verify()
  165. {
  166. if ( m_prCutoff == 0x7FFF )
  167. {
  168. m_vrQ = 0;
  169. m_prVelScale = 0;
  170. }
  171. else
  172. {
  173. FORCEBOUNDS(m_prCutoff, 5535, 11921);
  174. FORCEBOUNDS(m_vrQ, 0, 225);
  175. FORCEBOUNDS(m_prVelScale, -12800, 12800);
  176. }
  177. }
  178. CSourceArticulation::CSourceArticulation()
  179. {
  180. // m_sVelToVolScale = -9600;
  181. m_wUsageCount = 0;
  182. m_sDefaultPan = 0;
  183. m_dwSampleRate = 22050;
  184. m_PitchEG.m_sScale = 0; // pitch envelope defaults to off
  185. }
  186. void CSourceArticulation::Init(DWORD dwSampleRate)
  187. {
  188. m_dwSampleRate = dwSampleRate;
  189. m_LFO.Init(dwSampleRate); // Set to default values.
  190. m_PitchEG.Init();
  191. m_VolumeEG.Init();
  192. m_LFO2.Init(dwSampleRate);
  193. m_Filter.Init(dwSampleRate);
  194. }
  195. void CSourceArticulation::SetSampleRate(DWORD dwSampleRate)
  196. {
  197. if (dwSampleRate != m_dwSampleRate)
  198. {
  199. long lChange;
  200. if (dwSampleRate > (m_dwSampleRate * 2))
  201. {
  202. lChange = 2; // going from 11 to 44.
  203. }
  204. else if (dwSampleRate > m_dwSampleRate)
  205. {
  206. lChange = 1; // must be doubling
  207. }
  208. else if ((dwSampleRate * 2) < m_dwSampleRate)
  209. {
  210. lChange = -2; // going from 44 to 11
  211. }
  212. else
  213. {
  214. lChange = -1; // that leaves halving.
  215. }
  216. m_dwSampleRate = dwSampleRate;
  217. m_LFO.SetSampleRate(lChange);
  218. m_PitchEG.SetSampleRate(lChange);
  219. m_VolumeEG.SetSampleRate(lChange);
  220. m_LFO2.SetSampleRate(lChange);
  221. m_Filter.SetSampleRate(lChange);
  222. }
  223. }
  224. void CSourceArticulation::Verify()
  225. {
  226. m_LFO.Verify();
  227. m_PitchEG.Verify();
  228. m_VolumeEG.Verify();
  229. m_LFO2.Verify();
  230. m_Filter.Verify();
  231. }
  232. void CSourceArticulation::AddRef()
  233. {
  234. m_wUsageCount++;
  235. }
  236. void CSourceArticulation::Release()
  237. {
  238. m_wUsageCount--;
  239. if (m_wUsageCount == 0)
  240. {
  241. delete this;
  242. }
  243. }
  244. CSourceSample::CSourceSample()
  245. {
  246. m_pWave = NULL;
  247. m_dwLoopStart = 0;
  248. m_dwLoopEnd = 1;
  249. m_dwLoopType = WLOOP_TYPE_FORWARD;
  250. m_dwSampleLength = 0;
  251. m_prFineTune = 0;
  252. m_dwSampleRate = 22050;
  253. m_bMIDIRootKey = 60;
  254. m_bOneShot = TRUE;
  255. m_bSampleType = 0;
  256. }
  257. CSourceSample::~CSourceSample()
  258. {
  259. if (m_pWave != NULL)
  260. {
  261. m_pWave->Release();
  262. }
  263. }
  264. void CSourceSample::Verify()
  265. {
  266. if (m_pWave != NULL)
  267. {
  268. FORCEBOUNDS(m_dwSampleLength,0,m_pWave->m_dwSampleLength);
  269. FORCEBOUNDS(m_dwLoopEnd,1,m_dwSampleLength);
  270. FORCEBOUNDS(m_dwLoopStart,0,m_dwLoopEnd);
  271. if ((m_dwLoopEnd - m_dwLoopStart) < 6)
  272. {
  273. m_bOneShot = TRUE;
  274. }
  275. }
  276. FORCEBOUNDS(m_dwSampleRate,3000,200000);
  277. FORCEBOUNDS(m_bMIDIRootKey,0,127);
  278. FORCEBOUNDS(m_prFineTune,-1200,1200);
  279. }
  280. BOOL CSourceSample::CopyFromWave()
  281. {
  282. if (m_pWave == NULL)
  283. {
  284. return FALSE;
  285. }
  286. m_dwSampleLength = m_pWave->m_dwSampleLength;
  287. m_dwSampleRate = m_pWave->m_dwSampleRate;
  288. m_bSampleType = m_pWave->m_bSampleType;
  289. if (m_bOneShot)
  290. {
  291. m_dwSampleLength--;
  292. if (m_pWave->m_bSampleType & SFORMAT_16)
  293. {
  294. m_pWave->m_pnWave[m_dwSampleLength] = 0;
  295. }
  296. else
  297. {
  298. char *pBuffer = (char *) m_pWave->m_pnWave;
  299. pBuffer[m_dwSampleLength] = 0;
  300. }
  301. }
  302. else
  303. {
  304. if (m_dwLoopStart >= m_dwSampleLength)
  305. {
  306. m_dwLoopStart = 0;
  307. }
  308. if (m_pWave->m_bSampleType & SFORMAT_16)
  309. {
  310. m_pWave->m_pnWave[m_dwSampleLength-1] =
  311. m_pWave->m_pnWave[m_dwLoopStart];
  312. }
  313. else
  314. {
  315. char *pBuffer = (char *) m_pWave->m_pnWave;
  316. pBuffer[m_dwSampleLength-1] =
  317. pBuffer[m_dwLoopStart];
  318. }
  319. }
  320. Verify();
  321. return (TRUE);
  322. }
  323. CWave::CWave()
  324. {
  325. m_hUserData = NULL;
  326. m_lpFreeHandle = NULL;
  327. m_pnWave = NULL;
  328. m_dwSampleRate = 22050;
  329. m_bSampleType = SFORMAT_16;
  330. m_dwSampleLength = 0;
  331. m_wUsageCount = 0;
  332. m_dwID = 0;
  333. m_wPlayCount = 0;
  334. m_bStream = FALSE;
  335. m_bActive = FALSE;
  336. m_bLastSampleInit = FALSE;
  337. m_bValid = FALSE;
  338. }
  339. CWave::~CWave()
  340. {
  341. if (m_pnWave && m_lpFreeHandle)
  342. {
  343. m_lpFreeHandle((HANDLE) this,m_hUserData);
  344. }
  345. }
  346. void CWave::Verify()
  347. {
  348. FORCEBOUNDS(m_dwSampleRate,3000,200000);
  349. }
  350. void CWave::PlayOn()
  351. {
  352. m_wPlayCount++;
  353. AddRef();
  354. }
  355. void CWave::PlayOff()
  356. {
  357. m_wPlayCount--;
  358. Release();
  359. }
  360. BOOL CWave::IsPlaying()
  361. {
  362. return (m_wPlayCount);
  363. }
  364. void CWave::AddRef()
  365. {
  366. m_wUsageCount++;
  367. }
  368. void CWave::Release()
  369. {
  370. m_wUsageCount--;
  371. if (m_wUsageCount == 0)
  372. {
  373. delete this;
  374. }
  375. }
  376. CWaveArt::CWaveArt()
  377. {
  378. m_wUsageCount = 1;
  379. m_dwID = 0;
  380. m_bSampleType = 0;
  381. m_bStream = FALSE;
  382. memset(&m_WaveArtDl,0,sizeof(DMUS_WAVEARTDL));
  383. memset(&m_WaveformatEx,0,sizeof(WAVEFORMATEX));
  384. }
  385. CWaveArt::~CWaveArt()
  386. {
  387. //>>>>>>>>>> clear list
  388. while(!m_pWaves.IsEmpty())
  389. {
  390. CWaveBuffer* pWaveBuffer = m_pWaves.RemoveHead();
  391. if(pWaveBuffer)
  392. {
  393. pWaveBuffer->m_pWave->Release();
  394. pWaveBuffer->m_pWave = NULL;
  395. delete pWaveBuffer;
  396. }
  397. }
  398. }
  399. void CWaveArt::AddRef()
  400. {
  401. m_wUsageCount++;
  402. }
  403. void CWaveArt::Release()
  404. {
  405. m_wUsageCount--;
  406. if (m_wUsageCount == 0)
  407. {
  408. delete this;
  409. }
  410. }
  411. void CWaveArt::Verify()
  412. {
  413. }
  414. CSourceRegion::CSourceRegion()
  415. {
  416. m_pArticulation = NULL;
  417. m_vrAttenuation = 0;
  418. m_prTuning = 0;
  419. m_bKeyHigh = 127;
  420. m_bKeyLow = 0;
  421. m_bGroup = 0;
  422. m_bAllowOverlap = FALSE;
  423. m_bVelocityHigh = 127;
  424. m_bVelocityLow = 0;
  425. m_dwChannel = 0;
  426. m_sWaveLinkOptions = 0;
  427. }
  428. CSourceRegion::~CSourceRegion()
  429. {
  430. if (m_pArticulation)
  431. {
  432. m_pArticulation->Release();
  433. }
  434. }
  435. void CSourceRegion::SetSampleRate(DWORD dwSampleRate)
  436. {
  437. if (m_pArticulation != NULL)
  438. {
  439. m_pArticulation->SetSampleRate(dwSampleRate);
  440. }
  441. }
  442. void CSourceRegion::Verify()
  443. {
  444. FORCEBOUNDS(m_bKeyHigh,0,127);
  445. FORCEBOUNDS(m_bKeyLow,0,127);
  446. FORCEBOUNDS(m_prTuning,-12000,12000);
  447. FORCEBOUNDS(m_vrAttenuation,-9600,0);
  448. m_Sample.Verify();
  449. if (m_pArticulation != NULL)
  450. {
  451. m_pArticulation->Verify();
  452. }
  453. }
  454. CInstrument::CInstrument()
  455. {
  456. m_dwProgram = 0;
  457. }
  458. CInstrument::~CInstrument()
  459. {
  460. while (!m_RegionList.IsEmpty())
  461. {
  462. CSourceRegion *pRegion = m_RegionList.RemoveHead();
  463. delete pRegion;
  464. }
  465. }
  466. void CInstrument::Verify()
  467. {
  468. CSourceRegion *pRegion = m_RegionList.GetHead();
  469. CSourceArticulation *pArticulation = NULL;
  470. for (;pRegion != NULL;pRegion = pRegion->GetNext())
  471. {
  472. if (pRegion->m_pArticulation != NULL)
  473. {
  474. pArticulation = pRegion->m_pArticulation;
  475. }
  476. pRegion->Verify();
  477. }
  478. pRegion = m_RegionList.GetHead();
  479. for (;pRegion != NULL;pRegion = pRegion->GetNext())
  480. {
  481. if (pRegion->m_pArticulation == NULL && pArticulation)
  482. {
  483. pRegion->m_pArticulation = pArticulation;
  484. pArticulation->AddRef();
  485. }
  486. }
  487. }
  488. void CInstrument::SetSampleRate(DWORD dwSampleRate)
  489. {
  490. CSourceRegion *pRegion = m_RegionList.GetHead();
  491. for (;pRegion;pRegion = pRegion->GetNext())
  492. {
  493. pRegion->SetSampleRate(dwSampleRate);
  494. }
  495. }
  496. CSourceRegion * CInstrument::ScanForRegion(DWORD dwNoteValue, DWORD dwVelocity, CSourceRegion *pRegion)
  497. {
  498. if ( pRegion == NULL )
  499. pRegion = m_RegionList.GetHead(); // Starting search
  500. else
  501. pRegion = pRegion->GetNext(); // Continuing search through the rest of the regions
  502. for (;pRegion;pRegion = pRegion->GetNext())
  503. {
  504. if (dwNoteValue >= pRegion->m_bKeyLow &&
  505. dwNoteValue <= pRegion->m_bKeyHigh &&
  506. dwVelocity >= pRegion->m_bVelocityLow &&
  507. dwVelocity <= pRegion->m_bVelocityHigh )
  508. {
  509. break ;
  510. }
  511. }
  512. return pRegion;
  513. }
  514. void CInstManager::SetSampleRate(DWORD dwSampleRate)
  515. {
  516. DWORD dwIndex;
  517. m_dwSampleRate = dwSampleRate;
  518. EnterCriticalSection(&m_CriticalSection);
  519. for (dwIndex = 0; dwIndex < INSTRUMENT_HASH_SIZE; dwIndex++)
  520. {
  521. CInstrument *pInstrument = m_InstrumentList[dwIndex].GetHead();
  522. for (;pInstrument != NULL; pInstrument = pInstrument->GetNext())
  523. {
  524. pInstrument->SetSampleRate(dwSampleRate);
  525. }
  526. }
  527. LeaveCriticalSection(&m_CriticalSection);
  528. }
  529. CInstManager::CInstManager()
  530. {
  531. m_dwSampleRate = 22050;
  532. m_fCSInitialized = FALSE;
  533. InitializeCriticalSection(&m_CriticalSection);
  534. // Note: on pre-Blackcomb OS's, this call can raise an exception; if it
  535. // ever pops in stress, we can add an exception handler and retry loop.
  536. m_fCSInitialized = TRUE;
  537. m_dwSynthMemUse = 0;
  538. }
  539. CInstManager::~CInstManager()
  540. {
  541. if (m_fCSInitialized)
  542. {
  543. DWORD dwIndex;
  544. for (dwIndex = 0; dwIndex < INSTRUMENT_HASH_SIZE; dwIndex++)
  545. {
  546. while (!m_InstrumentList[dwIndex].IsEmpty())
  547. {
  548. CInstrument *pInstrument = m_InstrumentList[dwIndex].RemoveHead();
  549. delete pInstrument;
  550. }
  551. }
  552. for (dwIndex = 0; dwIndex < WAVE_HASH_SIZE; dwIndex++)
  553. {
  554. while (!m_WavePool[dwIndex].IsEmpty())
  555. {
  556. CWave *pWave = m_WavePool[dwIndex].RemoveHead();
  557. pWave->Release();
  558. }
  559. }
  560. while (!m_FreeWavePool.IsEmpty())
  561. {
  562. CWave *pWave = m_FreeWavePool.RemoveHead();
  563. pWave->Release();
  564. }
  565. for(int nCount = 0; nCount < WAVEART_HASH_SIZE; nCount++)
  566. {
  567. while(!m_WaveArtList[nCount].IsEmpty())
  568. {
  569. CWaveArt* pWaveArt = m_WaveArtList[nCount].RemoveHead();
  570. if(pWaveArt)
  571. {
  572. pWaveArt->Release();
  573. }
  574. }
  575. }
  576. DeleteCriticalSection(&m_CriticalSection);
  577. }
  578. }
  579. void CInstManager::Verify()
  580. {
  581. DWORD dwIndex;
  582. EnterCriticalSection(&m_CriticalSection);
  583. for (dwIndex = 0;dwIndex < INSTRUMENT_HASH_SIZE; dwIndex++)
  584. {
  585. CInstrument *pInstrument = m_InstrumentList[dwIndex].GetHead();
  586. for (;pInstrument != NULL;pInstrument = pInstrument->GetNext())
  587. {
  588. pInstrument->Verify();
  589. }
  590. }
  591. LeaveCriticalSection(&m_CriticalSection);
  592. }
  593. CInstrument * CInstManager::GetInstrument(DWORD dwProgram, DWORD dwKey, DWORD dwVelocity)
  594. {
  595. EnterCriticalSection(&m_CriticalSection);
  596. CInstrument *pInstrument = m_InstrumentList[dwProgram % INSTRUMENT_HASH_SIZE].GetHead();
  597. for (;pInstrument != NULL; pInstrument = pInstrument->GetNext())
  598. {
  599. if (pInstrument->m_dwProgram == dwProgram)
  600. {
  601. if (pInstrument->ScanForRegion(dwKey, dwVelocity, NULL) != NULL)
  602. {
  603. break;
  604. }
  605. else
  606. {
  607. Trace(2,"Warning: No region was found in instrument # %lx that matched note %ld\n",
  608. dwProgram,dwKey);
  609. }
  610. }
  611. }
  612. LeaveCriticalSection(&m_CriticalSection);
  613. return (pInstrument);
  614. }
  615. DWORD TimeCents2Samples(long tcTime, DWORD dwSampleRate)
  616. {
  617. if (tcTime == 0x80000000) return (0);
  618. double flTemp = tcTime;
  619. flTemp /= (65536 * 1200);
  620. flTemp = pow(2.0,flTemp);
  621. flTemp *= dwSampleRate;
  622. return (DWORD) flTemp;
  623. }
  624. DWORD PitchCents2PitchFract(long pcRate,DWORD dwSampleRate)
  625. {
  626. double fTemp = pcRate;
  627. fTemp /= 65536;
  628. fTemp -= 6900;
  629. fTemp /= 1200;
  630. fTemp = pow(2.0,fTemp);
  631. fTemp *= 7381975040.0; // (440*256*16*4096);
  632. fTemp /= dwSampleRate;
  633. return (DWORD) (fTemp);
  634. }
  635. HRESULT CSourceArticulation::Download(DMUS_DOWNLOADINFO * pInfo,
  636. void * pvOffsetTable[],
  637. DWORD dwIndex,
  638. DWORD dwSampleRate,
  639. BOOL fNewFormat)
  640. {
  641. if (fNewFormat)
  642. {
  643. DMUS_ARTICULATION2 * pdmArtic =
  644. (DMUS_ARTICULATION2 *) pvOffsetTable[dwIndex];
  645. while (pdmArtic)
  646. {
  647. if (pdmArtic->ulArtIdx)
  648. {
  649. if (pdmArtic->ulArtIdx >= pInfo->dwNumOffsetTableEntries)
  650. {
  651. Trace(1,"Error: Download failed because articulation chunk has an error.\n");
  652. return DMUS_E_BADARTICULATION;
  653. }
  654. DWORD dwPosition;
  655. void *pData = pvOffsetTable[pdmArtic->ulArtIdx];
  656. CONNECTIONLIST * pConnectionList =
  657. (CONNECTIONLIST *) pData;
  658. CONNECTION *pConnection;
  659. dwPosition = sizeof(CONNECTIONLIST);
  660. for (dwIndex = 0; dwIndex < pConnectionList->cConnections; dwIndex++)
  661. {
  662. pConnection = (CONNECTION *) ((BYTE *)pData + dwPosition);
  663. dwPosition += sizeof(CONNECTION);
  664. switch (pConnection->usSource)
  665. {
  666. case CONN_SRC_NONE :
  667. switch (pConnection->usDestination)
  668. {
  669. case CONN_DST_LFO_FREQUENCY :
  670. m_LFO.m_pfFrequency = PitchCents2PitchFract(
  671. pConnection->lScale,dwSampleRate);
  672. break;
  673. case CONN_DST_LFO_STARTDELAY :
  674. m_LFO.m_stDelay = TimeCents2Samples(
  675. (TCENT) pConnection->lScale,dwSampleRate);
  676. break;
  677. case CONN_DST_EG1_ATTACKTIME :
  678. m_VolumeEG.m_stAttack = TimeCents2Samples(
  679. (TCENT) pConnection->lScale,dwSampleRate);
  680. break;
  681. case CONN_DST_EG1_DECAYTIME :
  682. m_VolumeEG.m_stDecay = TimeCents2Samples(
  683. (TCENT) pConnection->lScale,dwSampleRate);
  684. break;
  685. case CONN_DST_EG1_SUSTAINLEVEL :
  686. m_VolumeEG.m_pcSustain =
  687. (SPERCENT) ((long) (pConnection->lScale >> 16));
  688. break;
  689. case CONN_DST_EG1_RELEASETIME :
  690. m_VolumeEG.m_stRelease = TimeCents2Samples(
  691. (TCENT) pConnection->lScale,dwSampleRate);
  692. break;
  693. case CONN_DST_EG2_ATTACKTIME :
  694. m_PitchEG.m_stAttack = TimeCents2Samples(
  695. (TCENT) pConnection->lScale,dwSampleRate);
  696. break;
  697. case CONN_DST_EG2_DECAYTIME :
  698. m_PitchEG.m_stDecay = TimeCents2Samples(
  699. (TCENT) pConnection->lScale,dwSampleRate);
  700. break;
  701. case CONN_DST_EG2_SUSTAINLEVEL :
  702. m_PitchEG.m_pcSustain =
  703. (SPERCENT) ((long) (pConnection->lScale >> 16));
  704. break;
  705. case CONN_DST_EG2_RELEASETIME :
  706. m_PitchEG.m_stRelease = TimeCents2Samples(
  707. (TCENT) pConnection->lScale,dwSampleRate);
  708. break;
  709. case CONN_DST_PAN :
  710. m_sDefaultPan = (short)
  711. ((long) ((long) pConnection->lScale >> 12) / 125);
  712. break;
  713. /* DLS2 */
  714. case CONN_DST_EG1_DELAYTIME:
  715. m_VolumeEG.m_stDelay = TimeCents2Samples(
  716. (TCENT) pConnection->lScale,dwSampleRate);
  717. break;
  718. case CONN_DST_EG1_HOLDTIME:
  719. m_VolumeEG.m_stHold = TimeCents2Samples(
  720. (TCENT) pConnection->lScale,dwSampleRate);
  721. break;
  722. case CONN_DST_EG2_DELAYTIME:
  723. m_PitchEG.m_stDelay = TimeCents2Samples(
  724. (TCENT) pConnection->lScale,dwSampleRate);
  725. break;
  726. case CONN_DST_EG2_HOLDTIME:
  727. m_PitchEG.m_stHold = TimeCents2Samples(
  728. (TCENT) pConnection->lScale,dwSampleRate);
  729. break;
  730. case CONN_DST_VIB_FREQUENCY :
  731. m_LFO2.m_pfFrequency = PitchCents2PitchFract(
  732. pConnection->lScale,dwSampleRate);
  733. break;
  734. case CONN_DST_VIB_STARTDELAY :
  735. m_LFO2.m_stDelay = TimeCents2Samples(
  736. (TCENT) pConnection->lScale,dwSampleRate);
  737. break;
  738. case CONN_DST_FILTER_CUTOFF:
  739. // First, get the filter cutoff frequency, which is relative to a440.
  740. m_Filter.m_prCutoff = (PRELS)
  741. (pConnection->lScale >> 16);
  742. // Then, calculate the resulting prel, taking into consideration
  743. // the sample rate and the base of the filter coefficient lookup
  744. // table, relative to the sample rate (FILTER_FREQ_RANGE).
  745. // This number can then be used directly look up the coefficients in the
  746. // filter table.
  747. m_Filter.m_prCutoffSRAdjust = (PRELS)
  748. FILTER_FREQ_RANGE - m_Filter.m_prSampleRate + m_Filter.m_prCutoff;
  749. break;
  750. case CONN_DST_FILTER_Q:
  751. m_Filter.m_vrQ = (VRELS)
  752. (pConnection->lScale >> 16); //>>>>>>>> not really VRELS, but 1/10th's
  753. m_Filter.m_iQIndex = (DWORD)
  754. ((m_Filter.m_vrQ / 15.0f) + 0.5f);
  755. break;
  756. }
  757. break;
  758. case CONN_SRC_LFO :
  759. switch (pConnection->usControl)
  760. {
  761. case CONN_SRC_NONE :
  762. switch (pConnection->usDestination)
  763. {
  764. case CONN_DST_ATTENUATION :
  765. m_LFO.m_vrVolumeScale = (VRELS)
  766. ((long) ((pConnection->lScale * 10) >> 16));
  767. break;
  768. case CONN_DST_PITCH :
  769. m_LFO.m_prPitchScale = (PRELS)
  770. ((long) (pConnection->lScale >> 16));
  771. break;
  772. /* DLS2 */
  773. case CONN_DST_FILTER_CUTOFF:
  774. m_LFO.m_prCutoffScale = (PRELS)
  775. (pConnection->lScale >> 16);
  776. break;
  777. }
  778. break;
  779. case CONN_SRC_CC1 :
  780. switch (pConnection->usDestination)
  781. {
  782. case CONN_DST_ATTENUATION :
  783. m_LFO.m_vrMWVolumeScale = (VRELS)
  784. ((long) ((pConnection->lScale * 10) >> 16));
  785. break;
  786. case CONN_DST_PITCH :
  787. m_LFO.m_prMWPitchScale = (PRELS)
  788. ((long) (pConnection->lScale >> 16));
  789. break;
  790. /* DLS2 */
  791. case CONN_DST_FILTER_CUTOFF:
  792. m_LFO.m_prMWCutoffScale = (PRELS)
  793. ((long) (pConnection->lScale >> 16));
  794. break;
  795. }
  796. break;
  797. /* DLS2 */
  798. case CONN_SRC_CHANNELPRESSURE :
  799. switch (pConnection->usDestination)
  800. {
  801. case CONN_DST_ATTENUATION :
  802. m_LFO.m_vrCPVolumeScale = (VRELS)
  803. ((long) (pConnection->lScale >> 16));
  804. break;
  805. case CONN_DST_PITCH :
  806. m_LFO.m_prCPPitchScale = (PRELS)
  807. ((long) (pConnection->lScale >> 16));
  808. break;
  809. /* DLS2 */
  810. case CONN_DST_FILTER_CUTOFF:
  811. m_LFO.m_prCPCutoffScale = (PRELS)
  812. ((long) (pConnection->lScale >> 16));
  813. break;
  814. }
  815. break;
  816. }
  817. break;
  818. case CONN_SRC_KEYONVELOCITY :
  819. switch (pConnection->usDestination)
  820. {
  821. case CONN_DST_EG1_ATTACKTIME :
  822. m_VolumeEG.m_trVelAttackScale = (TRELS)
  823. ((long) (pConnection->lScale >> 16));
  824. break;
  825. case CONN_DST_EG2_ATTACKTIME :
  826. m_PitchEG.m_trVelAttackScale = (TRELS)
  827. ((long) (pConnection->lScale >> 16));
  828. break;
  829. /* DLS2 */
  830. case CONN_DST_FILTER_CUTOFF:
  831. m_Filter.m_prVelScale = (PRELS)
  832. ((long) (pConnection->lScale >> 16));
  833. break;
  834. }
  835. break;
  836. case CONN_SRC_KEYNUMBER :
  837. switch (pConnection->usDestination)
  838. {
  839. case CONN_DST_EG1_DECAYTIME :
  840. m_VolumeEG.m_trKeyDecayScale = (TRELS)
  841. ((long) (pConnection->lScale >> 16));
  842. break;
  843. case CONN_DST_EG2_DECAYTIME :
  844. m_PitchEG.m_trKeyDecayScale = (TRELS)
  845. ((long) (pConnection->lScale >> 16));
  846. break;
  847. /* DLS2 */
  848. case CONN_DST_EG1_HOLDTIME :
  849. m_PitchEG.m_trKeyDecayScale = (TRELS)
  850. ((long) (pConnection->lScale >> 16));
  851. break;
  852. case CONN_DST_EG2_HOLDTIME :
  853. m_PitchEG.m_trKeyDecayScale = (TRELS)
  854. ((long) (pConnection->lScale >> 16));
  855. case CONN_DST_FILTER_CUTOFF :
  856. m_Filter.m_prKeyScale = (PRELS)
  857. ((long) (pConnection->lScale >> 16));
  858. break;
  859. }
  860. break;
  861. case CONN_SRC_EG2 :
  862. switch (pConnection->usDestination)
  863. {
  864. case CONN_DST_PITCH :
  865. m_PitchEG.m_sScale = (short)
  866. ((long) (pConnection->lScale >> 16));
  867. break;
  868. /* DLS2 */
  869. case CONN_DST_FILTER_CUTOFF:
  870. m_PitchEG.m_prCutoffScale = (PRELS)
  871. ((long) (pConnection->lScale >> 16));
  872. break;
  873. }
  874. break;
  875. /* DLS2 */
  876. case CONN_SRC_VIBRATO :
  877. switch (pConnection->usControl)
  878. {
  879. case CONN_SRC_NONE :
  880. switch (pConnection->usDestination)
  881. {
  882. case CONN_DST_PITCH :
  883. m_LFO2.m_prPitchScale = (PRELS)
  884. ((long) (pConnection->lScale >> 16));
  885. break;
  886. }
  887. break;
  888. case CONN_SRC_CC1 :
  889. switch (pConnection->usDestination)
  890. {
  891. case CONN_DST_PITCH :
  892. m_LFO2.m_prMWPitchScale = (PRELS)
  893. ((long) (pConnection->lScale >> 16));
  894. break;
  895. }
  896. break;
  897. case CONN_SRC_CHANNELPRESSURE :
  898. switch (pConnection->usDestination)
  899. {
  900. case CONN_DST_PITCH :
  901. m_LFO2.m_prCPPitchScale = (PRELS)
  902. ((long) (pConnection->lScale >> 16));
  903. break;
  904. }
  905. break;
  906. }
  907. break;
  908. }
  909. }
  910. }
  911. if (pdmArtic->ulNextArtIdx)
  912. {
  913. if (pdmArtic->ulNextArtIdx >= pInfo->dwNumOffsetTableEntries)
  914. {
  915. Trace(1,"Error: Download failed because articulation chunk has an error.\n");
  916. return DMUS_E_BADARTICULATION;
  917. }
  918. pdmArtic = (DMUS_ARTICULATION2 *) pvOffsetTable[pdmArtic->ulNextArtIdx];
  919. }
  920. else
  921. {
  922. pdmArtic = NULL;
  923. }
  924. }
  925. }
  926. else
  927. {
  928. DMUS_ARTICULATION * pdmArtic =
  929. (DMUS_ARTICULATION *) pvOffsetTable[dwIndex];
  930. if (pdmArtic->ulArt1Idx)
  931. {
  932. if (pdmArtic->ulArt1Idx >= pInfo->dwNumOffsetTableEntries)
  933. {
  934. Trace(1,"Error: Download failed because articulation chunk has an error.\n");
  935. return DMUS_E_BADARTICULATION;
  936. }
  937. DMUS_ARTICPARAMS * pdmArticParams =
  938. (DMUS_ARTICPARAMS *) pvOffsetTable[pdmArtic->ulArt1Idx];
  939. m_LFO.m_pfFrequency = PitchCents2PitchFract(
  940. pdmArticParams->LFO.pcFrequency,dwSampleRate);
  941. m_LFO.m_stDelay = TimeCents2Samples(
  942. (TCENT) pdmArticParams->LFO.tcDelay,dwSampleRate);
  943. m_LFO.m_vrVolumeScale = (VRELS)
  944. ((long) ((pdmArticParams->LFO.gcVolumeScale * 10) >> 16));
  945. m_LFO.m_prPitchScale = (PRELS)
  946. ((long) (pdmArticParams->LFO.pcPitchScale >> 16));
  947. m_LFO.m_vrMWVolumeScale = (VRELS)
  948. ((long) ((pdmArticParams->LFO.gcMWToVolume * 10) >> 16));
  949. m_LFO.m_prMWPitchScale = (PRELS)
  950. ((long) (pdmArticParams->LFO.pcMWToPitch >> 16));
  951. m_VolumeEG.m_stAttack = TimeCents2Samples(
  952. (TCENT) pdmArticParams->VolEG.tcAttack,dwSampleRate);
  953. m_VolumeEG.m_stDecay = TimeCents2Samples(
  954. (TCENT) pdmArticParams->VolEG.tcDecay,dwSampleRate);
  955. m_VolumeEG.m_pcSustain =
  956. (SPERCENT) ((long) (pdmArticParams->VolEG.ptSustain >> 16));
  957. m_VolumeEG.m_stRelease = TimeCents2Samples(
  958. (TCENT) pdmArticParams->VolEG.tcRelease,dwSampleRate);
  959. m_VolumeEG.m_trVelAttackScale = (TRELS)
  960. ((long) (pdmArticParams->VolEG.tcVel2Attack >> 16));
  961. m_VolumeEG.m_trKeyDecayScale = (TRELS)
  962. ((long) (pdmArticParams->VolEG.tcKey2Decay >> 16));
  963. m_PitchEG.m_trKeyDecayScale = (TRELS)
  964. ((long) (pdmArticParams->PitchEG.tcKey2Decay >> 16));
  965. m_PitchEG.m_sScale = (short)
  966. ((long) (pdmArticParams->PitchEG.pcRange >> 16));
  967. m_PitchEG.m_trVelAttackScale = (TRELS)
  968. ((long) (pdmArticParams->PitchEG.tcVel2Attack >> 16));
  969. m_PitchEG.m_stAttack = TimeCents2Samples(
  970. (TCENT) pdmArticParams->PitchEG.tcAttack,dwSampleRate);
  971. m_PitchEG.m_stDecay = TimeCents2Samples(
  972. (TCENT) pdmArticParams->PitchEG.tcDecay,dwSampleRate);
  973. m_PitchEG.m_pcSustain =
  974. (SPERCENT) ((long) (pdmArticParams->PitchEG.ptSustain >> 16));
  975. m_PitchEG.m_stRelease = TimeCents2Samples(
  976. (TCENT) pdmArticParams->PitchEG.tcRelease,dwSampleRate);
  977. m_sDefaultPan = (short)
  978. ((long) ((long) pdmArticParams->Misc.ptDefaultPan >> 12) / 125);
  979. }
  980. }
  981. Verify(); // Make sure all parameters are legal.
  982. return S_OK;
  983. }
  984. HRESULT CSourceRegion::Download(DMUS_DOWNLOADINFO * pInfo,
  985. void * pvOffsetTable[],
  986. DWORD *pdwRegionIX,
  987. DWORD dwSampleRate,
  988. BOOL fNewFormat)
  989. {
  990. DMUS_REGION * pdmRegion = (DMUS_REGION *) pvOffsetTable[*pdwRegionIX];
  991. *pdwRegionIX = pdmRegion->ulNextRegionIdx; // Clear to avoid loops.
  992. pdmRegion->ulNextRegionIdx = 0;
  993. // Read the Region chunk...
  994. m_bKeyHigh = (BYTE) pdmRegion->RangeKey.usHigh;
  995. m_bKeyLow = (BYTE) pdmRegion->RangeKey.usLow;
  996. m_bVelocityHigh = (BYTE) pdmRegion->RangeVelocity.usHigh;
  997. m_bVelocityLow = (BYTE) pdmRegion->RangeVelocity.usLow;
  998. //
  999. // Fix DLS Designer bug
  1000. // Designer was putting velocity ranges that fail
  1001. // on DLS2 synths
  1002. //
  1003. if ( m_bVelocityHigh == 0 && m_bVelocityLow == 0 )
  1004. m_bVelocityHigh = 127;
  1005. if (pdmRegion->fusOptions & F_RGN_OPTION_SELFNONEXCLUSIVE)
  1006. {
  1007. m_bAllowOverlap = TRUE;
  1008. }
  1009. else
  1010. {
  1011. m_bAllowOverlap = FALSE;
  1012. }
  1013. m_bGroup = (BYTE) pdmRegion->usKeyGroup;
  1014. // Now, the WSMP and WLOOP chunks...
  1015. m_vrAttenuation = (short) ((long) ((pdmRegion->WSMP.lAttenuation) * 10) >> 16);
  1016. m_Sample.m_prFineTune = pdmRegion->WSMP.sFineTune;
  1017. m_Sample.m_bMIDIRootKey = (BYTE) pdmRegion->WSMP.usUnityNote;
  1018. if (pdmRegion->WSMP.cSampleLoops == 0)
  1019. {
  1020. m_Sample.m_bOneShot = TRUE;
  1021. }
  1022. else
  1023. {
  1024. m_Sample.m_dwLoopStart = pdmRegion->WLOOP[0].ulStart;
  1025. m_Sample.m_dwLoopEnd = m_Sample.m_dwLoopStart + pdmRegion->WLOOP[0].ulLength;
  1026. m_Sample.m_bOneShot = FALSE;
  1027. m_Sample.m_dwLoopType = pdmRegion->WLOOP[0].ulType;
  1028. }
  1029. m_Sample.m_dwSampleRate = dwSampleRate;
  1030. m_sWaveLinkOptions = pdmRegion->WaveLink.fusOptions;
  1031. m_dwChannel = pdmRegion->WaveLink.ulChannel;
  1032. if ( (m_dwChannel != WAVELINK_CHANNEL_LEFT) && !IsMultiChannel() )
  1033. {
  1034. Trace(1, "Download failed: Attempt to use a non-mono channel without setting the multichannel flag.\n");
  1035. return DMUS_E_NOTMONO;
  1036. }
  1037. m_Sample.m_dwID = (DWORD) pdmRegion->WaveLink.ulTableIndex;
  1038. // Does it have its own articulation?
  1039. //
  1040. if (pdmRegion->ulRegionArtIdx )
  1041. {
  1042. if (pdmRegion->ulRegionArtIdx >= pInfo->dwNumOffsetTableEntries)
  1043. {
  1044. Trace(1,"Error: Download failed because articulation chunk has an error.\n");
  1045. return DMUS_E_BADARTICULATION;
  1046. }
  1047. CSourceArticulation *pArticulation = new CSourceArticulation;
  1048. if (pArticulation)
  1049. {
  1050. pArticulation->Init(dwSampleRate);
  1051. HRESULT hr = pArticulation->Download(pInfo, pvOffsetTable,
  1052. pdmRegion->ulRegionArtIdx, dwSampleRate, fNewFormat);
  1053. if (FAILED(hr))
  1054. {
  1055. delete pArticulation;
  1056. return hr;
  1057. }
  1058. m_pArticulation = pArticulation;
  1059. m_pArticulation->AddRef();
  1060. }
  1061. else
  1062. {
  1063. return E_OUTOFMEMORY;
  1064. }
  1065. }
  1066. return S_OK;
  1067. }
  1068. HRESULT CInstManager::DownloadInstrument(LPHANDLE phDownload,
  1069. DMUS_DOWNLOADINFO *pInfo,
  1070. void *pvOffsetTable[],
  1071. void *pvData,
  1072. BOOL fNewFormat)
  1073. {
  1074. DMUS_INSTRUMENT *pdmInstrument = (DMUS_INSTRUMENT *) pvData;
  1075. CInstrument *pInstrument = new CInstrument;
  1076. if (pInstrument)
  1077. {
  1078. Trace(3,"Downloading instrument %lx\n",pdmInstrument->ulPatch);
  1079. pInstrument->m_dwProgram = pdmInstrument->ulPatch;
  1080. DWORD dwRegionIX = pdmInstrument->ulFirstRegionIdx;
  1081. pdmInstrument->ulFirstRegionIdx = 0; // Clear to avoid loops.
  1082. while (dwRegionIX)
  1083. {
  1084. if (dwRegionIX >= pInfo->dwNumOffsetTableEntries)
  1085. {
  1086. Trace(1,"Error: Download failed because instrument has error in region list.\n");
  1087. delete pInstrument;
  1088. return DMUS_E_BADINSTRUMENT;
  1089. }
  1090. CSourceRegion *pRegion = new CSourceRegion;
  1091. if (!pRegion)
  1092. {
  1093. delete pInstrument;
  1094. return E_OUTOFMEMORY;
  1095. }
  1096. pInstrument->m_RegionList.AddHead(pRegion);
  1097. HRESULT hr = pRegion->Download(pInfo, pvOffsetTable, &dwRegionIX, m_dwSampleRate, fNewFormat);
  1098. if (FAILED(hr))
  1099. {
  1100. delete pInstrument;
  1101. return hr;
  1102. }
  1103. EnterCriticalSection(&m_CriticalSection);
  1104. CWave *pWave = m_WavePool[pRegion->m_Sample.m_dwID % WAVE_HASH_SIZE].GetHead();
  1105. for (;pWave;pWave = pWave->GetNext())
  1106. {
  1107. if (pRegion->m_Sample.m_dwID == pWave->m_dwID)
  1108. {
  1109. pRegion->m_Sample.m_pWave = pWave;
  1110. pWave->AddRef();
  1111. pRegion->m_Sample.CopyFromWave();
  1112. break;
  1113. }
  1114. }
  1115. LeaveCriticalSection(&m_CriticalSection);
  1116. }
  1117. if (pdmInstrument->ulGlobalArtIdx)
  1118. {
  1119. if (pdmInstrument->ulGlobalArtIdx >= pInfo->dwNumOffsetTableEntries)
  1120. {
  1121. Trace(1,"Error: Download failed because of out of range articulation chunk.\n");
  1122. delete pInstrument;
  1123. return DMUS_E_BADARTICULATION;
  1124. }
  1125. CSourceArticulation *pArticulation = new CSourceArticulation;
  1126. if (pArticulation)
  1127. {
  1128. pArticulation->Init(m_dwSampleRate);
  1129. HRESULT hr = pArticulation->Download(pInfo, pvOffsetTable,
  1130. pdmInstrument->ulGlobalArtIdx, m_dwSampleRate, fNewFormat);
  1131. if (FAILED(hr))
  1132. {
  1133. delete pInstrument;
  1134. delete pArticulation;
  1135. return hr;
  1136. }
  1137. for (CSourceRegion *pr = pInstrument->m_RegionList.GetHead();
  1138. pr != NULL;
  1139. pr = pr->GetNext())
  1140. {
  1141. if (pr->m_pArticulation == NULL)
  1142. {
  1143. pr->m_pArticulation = pArticulation;
  1144. pArticulation->AddRef();
  1145. }
  1146. }
  1147. if (!pArticulation->m_wUsageCount)
  1148. {
  1149. delete pArticulation;
  1150. }
  1151. }
  1152. else
  1153. {
  1154. delete pInstrument;
  1155. return E_OUTOFMEMORY;
  1156. }
  1157. }
  1158. else
  1159. {
  1160. for (CSourceRegion *pr = pInstrument->m_RegionList.GetHead();
  1161. pr != NULL;
  1162. pr = pr->GetNext())
  1163. {
  1164. if (pr->m_pArticulation == NULL)
  1165. {
  1166. Trace(1,"Error: Download failed because region has no articulation.\n");
  1167. delete pInstrument;
  1168. return DMUS_E_NOARTICULATION;
  1169. }
  1170. }
  1171. }
  1172. EnterCriticalSection(&m_CriticalSection);
  1173. if (pdmInstrument->ulFlags & DMUS_INSTRUMENT_GM_INSTRUMENT)
  1174. {
  1175. pInstrument->SetNext(NULL);
  1176. m_InstrumentList[pInstrument->m_dwProgram % INSTRUMENT_HASH_SIZE].AddTail(pInstrument);
  1177. }
  1178. else
  1179. {
  1180. m_InstrumentList[pInstrument->m_dwProgram % INSTRUMENT_HASH_SIZE].AddHead(pInstrument);
  1181. }
  1182. LeaveCriticalSection(&m_CriticalSection);
  1183. *phDownload = (HANDLE) pInstrument;
  1184. return S_OK;
  1185. }
  1186. return E_OUTOFMEMORY;
  1187. }
  1188. HRESULT CInstManager::DownloadWave(LPHANDLE phDownload,
  1189. DMUS_DOWNLOADINFO *pInfo,
  1190. void *pvOffsetTable[],
  1191. void *pvData)
  1192. {
  1193. DMUS_WAVE *pdmWave = (DMUS_WAVE *) pvData;
  1194. if (pdmWave->WaveformatEx.wFormatTag != WAVE_FORMAT_PCM)
  1195. {
  1196. Trace(1,"Error: Download failed because wave data is not PCM format.\n");
  1197. return DMUS_E_NOTPCM;
  1198. }
  1199. if (pdmWave->WaveformatEx.nChannels != 1)
  1200. {
  1201. Trace(1,"Error: Download failed because wave data is not mono.\n");
  1202. return DMUS_E_NOTMONO;
  1203. }
  1204. if (pdmWave->ulWaveDataIdx >= pInfo->dwNumOffsetTableEntries)
  1205. {
  1206. Trace(1,"Error: Download failed because wave data is at invalid location.\n");
  1207. return DMUS_E_BADWAVE;
  1208. }
  1209. CWave *pWave = new CWave;
  1210. if (pWave)
  1211. {
  1212. DMUS_WAVEDATA *pdmWaveData= (DMUS_WAVEDATA *)
  1213. pvOffsetTable[pdmWave->ulWaveDataIdx];
  1214. pWave->m_dwID = pInfo->dwDLId;
  1215. pWave->m_hUserData = NULL;
  1216. pWave->m_lpFreeHandle = NULL;
  1217. pWave->m_dwSampleLength = pdmWaveData->cbSize;
  1218. pWave->m_pnWave = (short *) &pdmWaveData->byData[0];
  1219. pWave->m_dwSampleRate = pdmWave->WaveformatEx.nSamplesPerSec;
  1220. if (pdmWave->WaveformatEx.wBitsPerSample == 8)
  1221. {
  1222. pWave->m_bSampleType = SFORMAT_8;
  1223. DWORD dwX;
  1224. char *pData = (char *) &pdmWaveData->byData[0];
  1225. for (dwX = 0; dwX < pWave->m_dwSampleLength; dwX++)
  1226. {
  1227. pData[dwX] -= (char) 128;
  1228. }
  1229. }
  1230. else if (pdmWave->WaveformatEx.wBitsPerSample == 16)
  1231. {
  1232. pWave->m_dwSampleLength >>= 1;
  1233. pWave->m_bSampleType = SFORMAT_16;
  1234. }
  1235. else
  1236. {
  1237. Trace(1,"Error: Downloading wave %ld, bad wave format.\n",pInfo->dwDLId);
  1238. delete pWave;
  1239. return DMUS_E_BADWAVE;
  1240. }
  1241. pWave->m_dwSampleLength++; // We always add one sample to the end for interpolation.
  1242. EnterCriticalSection(&m_CriticalSection);
  1243. m_WavePool[pWave->m_dwID % WAVE_HASH_SIZE].AddHead(pWave);
  1244. LeaveCriticalSection(&m_CriticalSection);
  1245. *phDownload = (HANDLE) pWave;
  1246. pWave->AddRef();
  1247. // Track memory usage
  1248. m_dwSynthMemUse += (pWave->m_bSampleType == SFORMAT_16)?pWave->m_dwSampleLength << 1: pWave->m_dwSampleLength;
  1249. Trace(3,"Downloading wave %ld memory usage %ld\n",pInfo->dwDLId,m_dwSynthMemUse);
  1250. return S_OK;
  1251. }
  1252. return E_OUTOFMEMORY;
  1253. }
  1254. HRESULT CInstManager::Download(LPHANDLE phDownload,
  1255. void * pvData,
  1256. LPBOOL pbFree)
  1257. {
  1258. V_INAME(IDirectMusicSynth::Download);
  1259. V_BUFPTR_READ(pvData,sizeof(DMUS_DOWNLOADINFO));
  1260. HRESULT hr = DMUS_E_UNKNOWNDOWNLOAD;
  1261. void ** ppvOffsetTable; // Array of pointers to chunks in data.
  1262. DMUS_DOWNLOADINFO * pInfo = (DMUS_DOWNLOADINFO *) pvData;
  1263. DMUS_OFFSETTABLE* pOffsetTable = (DMUS_OFFSETTABLE *)(((BYTE*)pvData) + sizeof(DMUS_DOWNLOADINFO));
  1264. char *pcData = (char *) pvData;
  1265. V_BUFPTR_READ(pvData,pInfo->cbSize);
  1266. // Code fails if pInfo->dwNumOffsetTableEntries == 0
  1267. // Sanity check here for debug
  1268. assert(pInfo->dwNumOffsetTableEntries);
  1269. ppvOffsetTable = new void *[pInfo->dwNumOffsetTableEntries];
  1270. if (ppvOffsetTable) // Create the pointer array and validate.
  1271. {
  1272. DWORD dwIndex;
  1273. for (dwIndex = 0; dwIndex < pInfo->dwNumOffsetTableEntries; dwIndex++)
  1274. {
  1275. if (pOffsetTable->ulOffsetTable[dwIndex] >= pInfo->cbSize)
  1276. {
  1277. delete[] ppvOffsetTable;
  1278. Trace(1,"Error: Download failed because of corrupt download tables.\n");
  1279. return DMUS_E_BADOFFSETTABLE; // Bad!
  1280. }
  1281. ppvOffsetTable[dwIndex] = (void *) &pcData[pOffsetTable->ulOffsetTable[dwIndex]];
  1282. }
  1283. if (pInfo->dwDLType == DMUS_DOWNLOADINFO_INSTRUMENT) // Instrument.
  1284. {
  1285. *pbFree = TRUE;
  1286. hr = DownloadInstrument(phDownload, pInfo, ppvOffsetTable, ppvOffsetTable[0],FALSE);
  1287. }
  1288. else if (pInfo->dwDLType == DMUS_DOWNLOADINFO_INSTRUMENT2) // New instrument format.
  1289. {
  1290. *pbFree = TRUE;
  1291. hr = DownloadInstrument(phDownload, pInfo, ppvOffsetTable, ppvOffsetTable[0],TRUE);
  1292. }
  1293. else if (pInfo->dwDLType == DMUS_DOWNLOADINFO_WAVE) // Wave.
  1294. {
  1295. *pbFree = FALSE;
  1296. hr = DownloadWave(phDownload, pInfo, ppvOffsetTable, ppvOffsetTable[0]);
  1297. }
  1298. else if (pInfo->dwDLType == DMUS_DOWNLOADINFO_WAVEARTICULATION) // Wave onshot & streaming
  1299. {
  1300. *pbFree = TRUE;
  1301. hr = DownloadWaveArticulation(phDownload, pInfo, ppvOffsetTable, ppvOffsetTable[0]);
  1302. }
  1303. else if (pInfo->dwDLType == DMUS_DOWNLOADINFO_STREAMINGWAVE) // Streaming
  1304. {
  1305. *pbFree = FALSE;
  1306. hr = DownloadWaveRaw(phDownload, pInfo, ppvOffsetTable, ppvOffsetTable[0]);
  1307. }
  1308. else if (pInfo->dwDLType == DMUS_DOWNLOADINFO_ONESHOTWAVE) // Wave onshot
  1309. {
  1310. *pbFree = FALSE;
  1311. hr = DownloadWaveRaw(phDownload, pInfo, ppvOffsetTable, ppvOffsetTable[0]);
  1312. }
  1313. delete[] ppvOffsetTable;
  1314. }
  1315. else
  1316. {
  1317. hr = E_OUTOFMEMORY;
  1318. }
  1319. return hr;
  1320. }
  1321. HRESULT CInstManager::Unload(HANDLE hDownload,
  1322. HRESULT ( CALLBACK *lpFreeHandle)(HANDLE,HANDLE),
  1323. HANDLE hUserData)
  1324. {
  1325. DWORD dwIndex;
  1326. EnterCriticalSection(&m_CriticalSection);
  1327. for (dwIndex = 0; dwIndex < INSTRUMENT_HASH_SIZE; dwIndex++)
  1328. {
  1329. CInstrument *pInstrument = m_InstrumentList[dwIndex].GetHead();
  1330. for (;pInstrument != NULL; pInstrument = pInstrument->GetNext())
  1331. {
  1332. if (pInstrument == (CInstrument *) hDownload)
  1333. {
  1334. Trace(3,"Unloading instrument %lx\n",pInstrument->m_dwProgram);
  1335. m_InstrumentList[dwIndex].Remove(pInstrument);
  1336. delete pInstrument;
  1337. LeaveCriticalSection(&m_CriticalSection);
  1338. return S_OK;
  1339. }
  1340. }
  1341. }
  1342. for (dwIndex = 0; dwIndex < WAVE_HASH_SIZE; dwIndex++)
  1343. {
  1344. CWave *pWave = m_WavePool[dwIndex].GetHead();
  1345. for (;pWave != NULL;pWave = pWave->GetNext())
  1346. {
  1347. if (pWave == (CWave *) hDownload)
  1348. {
  1349. // Track memory usage
  1350. m_dwSynthMemUse -= (pWave->m_bSampleType == SFORMAT_16)?pWave->m_dwSampleLength << 1: pWave->m_dwSampleLength;
  1351. Trace(3,"Unloading wave %ld memory usage %ld\n",pWave->m_dwID,m_dwSynthMemUse);
  1352. m_WavePool[dwIndex].Remove(pWave);
  1353. pWave->m_hUserData = hUserData;
  1354. pWave->m_lpFreeHandle = lpFreeHandle;
  1355. pWave->Release();
  1356. LeaveCriticalSection(&m_CriticalSection);
  1357. return S_OK;
  1358. }
  1359. }
  1360. }
  1361. for (dwIndex = 0; dwIndex < WAVE_HASH_SIZE; dwIndex++)
  1362. {
  1363. CWaveArt* pWaveArt = m_WaveArtList[dwIndex].GetHead();
  1364. for (;pWaveArt != NULL;pWaveArt = pWaveArt->GetNext())
  1365. {
  1366. if (pWaveArt == (CWaveArt *) hDownload)
  1367. {
  1368. Trace(3,"Unloading wave articulation %ld\n",pWaveArt->m_dwID,m_dwSynthMemUse);
  1369. m_WaveArtList[dwIndex].Remove(pWaveArt);
  1370. pWaveArt->Release();
  1371. LeaveCriticalSection(&m_CriticalSection);
  1372. return S_OK;
  1373. }
  1374. }
  1375. }
  1376. LeaveCriticalSection(&m_CriticalSection);
  1377. Trace(1,"Error: Unload failed - downloaded object not found.\n");
  1378. return E_FAIL;
  1379. }
  1380. //////////////////////////////////////////////////////////
  1381. // Directx8 Methods
  1382. CWave * CInstManager::GetWave(DWORD dwDLId)
  1383. {
  1384. EnterCriticalSection(&m_CriticalSection);
  1385. CWave *pWave = m_WavePool[dwDLId % WAVE_HASH_SIZE].GetHead();
  1386. for (;pWave;pWave = pWave->GetNext())
  1387. {
  1388. if (dwDLId == pWave->m_dwID)
  1389. {
  1390. break;
  1391. }
  1392. }
  1393. LeaveCriticalSection(&m_CriticalSection);
  1394. return pWave;
  1395. }
  1396. CWaveArt * CInstManager::GetWaveArt(DWORD dwDLId)
  1397. {
  1398. EnterCriticalSection(&m_CriticalSection);
  1399. CWaveArt *pWaveArt = m_WaveArtList[dwDLId % WAVEART_HASH_SIZE].GetHead();
  1400. for (;pWaveArt;pWaveArt = pWaveArt->GetNext())
  1401. {
  1402. if (dwDLId == pWaveArt->m_dwID)
  1403. {
  1404. break;
  1405. }
  1406. }
  1407. LeaveCriticalSection(&m_CriticalSection);
  1408. return pWaveArt;
  1409. }
  1410. HRESULT CInstManager::DownloadWaveArticulation(LPHANDLE phDownload,
  1411. DMUS_DOWNLOADINFO *pInfo,
  1412. void *pvOffsetTable[],
  1413. void *pvData)
  1414. {
  1415. DMUS_WAVEARTDL* pWaveArtDl = (DMUS_WAVEARTDL*)pvData;
  1416. WAVEFORMATEX *pWaveformatEx = (WAVEFORMATEX *) pvOffsetTable[1];
  1417. DWORD *dwDlId = (DWORD*)pvOffsetTable[2];
  1418. DWORD i;
  1419. CWaveArt* pWaveArt = new CWaveArt();
  1420. if ( pWaveArt )
  1421. {
  1422. pWaveArt->m_dwID = pInfo->dwDLId;
  1423. pWaveArt->m_WaveArtDl = *pWaveArtDl;;
  1424. pWaveArt->m_WaveformatEx = *pWaveformatEx;
  1425. if (pWaveformatEx->wBitsPerSample == 8)
  1426. {
  1427. pWaveArt->m_bSampleType = SFORMAT_8;
  1428. }
  1429. else if (pWaveformatEx->wBitsPerSample == 16)
  1430. {
  1431. pWaveArt->m_bSampleType = SFORMAT_16;
  1432. }
  1433. else
  1434. {
  1435. Trace(1,"Error: Download failed because wave data is %ld bits instead of 8 or 16.\n",(long) pWaveformatEx->wBitsPerSample);
  1436. delete pWaveArt;
  1437. return DMUS_E_BADWAVE;
  1438. }
  1439. for ( i = 0; i < pWaveArtDl->ulBuffers; i++ )
  1440. {
  1441. // Get wave buffer and fill header with waveformat data
  1442. CWave *pWave = GetWave(dwDlId[i]);
  1443. assert(pWave);
  1444. if (!pWave)
  1445. {
  1446. delete pWaveArt;
  1447. return E_POINTER;
  1448. }
  1449. pWave->m_dwSampleRate = pWaveformatEx->nSamplesPerSec;
  1450. if (pWaveformatEx->wBitsPerSample == 8)
  1451. {
  1452. DWORD dwX;
  1453. char *pData = (char *) pWave->m_pnWave;
  1454. for (dwX = 0; dwX < pWave->m_dwSampleLength; dwX++)
  1455. {
  1456. pData[dwX] -= (char) 128;
  1457. }
  1458. pWave->m_bSampleType = SFORMAT_8;
  1459. }
  1460. else if (pWaveformatEx->wBitsPerSample == 16)
  1461. {
  1462. pWave->m_dwSampleLength >>= 1;
  1463. pWave->m_bSampleType = SFORMAT_16;
  1464. }
  1465. else
  1466. {
  1467. Trace(1,"Error: Download failed because wave data is %ld bits instead of 8 or 16.\n",(long) pWaveformatEx->wBitsPerSample);
  1468. delete pWaveArt;
  1469. return DMUS_E_BADWAVE;
  1470. }
  1471. pWave->m_dwSampleLength++; // We always add one sample to the end for interpolation.
  1472. // Default is to duplicate last sample. This will be overrwritten for
  1473. // streaming waves.
  1474. //
  1475. if (pWave->m_dwSampleLength > 1)
  1476. {
  1477. if (pWave->m_bSampleType == SFORMAT_8)
  1478. {
  1479. char* pb = (char*)pWave->m_pnWave;
  1480. pb[pWave->m_dwSampleLength - 1] = pb[pWave->m_dwSampleLength - 2];
  1481. }
  1482. else
  1483. {
  1484. short *pn = pWave->m_pnWave;
  1485. pn[pWave->m_dwSampleLength - 1] = pn[pWave->m_dwSampleLength - 2];
  1486. }
  1487. }
  1488. // Create a WaveBuffer listitem and save the wave in and add it to the circular buffer list
  1489. CWaveBuffer* pWavBuf = new CWaveBuffer();
  1490. if ( pWavBuf == NULL )
  1491. {
  1492. delete pWaveArt;
  1493. return E_OUTOFMEMORY;
  1494. }
  1495. pWavBuf->m_pWave = pWave;
  1496. // This Articulation will be handling streaming data
  1497. if ( pWave->m_bStream )
  1498. pWaveArt->m_bStream = TRUE;
  1499. pWaveArt->m_pWaves.AddTail(pWavBuf);
  1500. }
  1501. EnterCriticalSection(&m_CriticalSection);
  1502. if (pWaveArt)
  1503. {
  1504. CWaveBuffer* pCurrentBuffer = pWaveArt->m_pWaves.GetHead();
  1505. for (; pCurrentBuffer; pCurrentBuffer = pCurrentBuffer->GetNext() )
  1506. {
  1507. if (pCurrentBuffer->m_pWave)
  1508. {
  1509. pCurrentBuffer->m_pWave->AddRef();
  1510. }
  1511. }
  1512. }
  1513. m_WaveArtList[pWaveArt->m_dwID % WAVEART_HASH_SIZE].AddHead(pWaveArt);
  1514. LeaveCriticalSection(&m_CriticalSection);
  1515. *phDownload = (HANDLE) pWaveArt;
  1516. return S_OK;
  1517. }
  1518. return E_OUTOFMEMORY;
  1519. }
  1520. HRESULT CInstManager::DownloadWaveRaw(LPHANDLE phDownload,
  1521. DMUS_DOWNLOADINFO *pInfo,
  1522. void *pvOffsetTable[],
  1523. void *pvData)
  1524. {
  1525. CWave *pWave = new CWave;
  1526. if (pWave)
  1527. {
  1528. DMUS_WAVEDATA *pdmWaveData= (DMUS_WAVEDATA *)pvData;
  1529. Trace(3,"Downloading raw wave data%ld\n",pInfo->dwDLId);
  1530. pWave->m_dwID = pInfo->dwDLId;
  1531. pWave->m_hUserData = NULL;
  1532. pWave->m_lpFreeHandle = NULL;
  1533. pWave->m_dwSampleLength = pdmWaveData->cbSize;
  1534. pWave->m_pnWave = (short *) &pdmWaveData->byData[0];
  1535. if ( pInfo->dwDLType == DMUS_DOWNLOADINFO_STREAMINGWAVE )
  1536. {
  1537. pWave->m_bStream = TRUE;
  1538. pWave->m_bValid = TRUE;
  1539. }
  1540. EnterCriticalSection(&m_CriticalSection);
  1541. m_WavePool[pWave->m_dwID % WAVE_HASH_SIZE].AddHead(pWave);
  1542. LeaveCriticalSection(&m_CriticalSection);
  1543. *phDownload = (HANDLE) pWave;
  1544. pWave->AddRef();
  1545. m_dwSynthMemUse += pWave->m_dwSampleLength;
  1546. return S_OK;
  1547. }
  1548. return E_OUTOFMEMORY;
  1549. }