SndFx.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2016 RWS Inc, All Rights Reserved
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of version 2 of the GNU General Public License as published by
  7. // the Free Software Foundation
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License along
  15. // with this program; if not, write to the Free Software Foundation, Inc.,
  16. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. //
  18. ///////////////////////////////////////////////////////////////////////////////
  19. //
  20. // SndFx.cpp
  21. //
  22. // History:
  23. // 09/06/96 JMI Started.
  24. //
  25. // 09/10/96 JMI Now uses a precalculated table (generated by a call to
  26. // SetFadeAccuracy()) to do fades.
  27. //
  28. // 09/10/96 JMI Now effects can optionally have a destination other than
  29. // the source.
  30. //
  31. // 09/11/96 JMI Fade outs for 8 bit were sending the fade in variables
  32. // to the decimate unsigned template.
  33. //
  34. // 09/24/96 MJR Added <stdlib.h> so it would compile on Mac.
  35. //
  36. // 10/30/96 JMI Changed:
  37. // Old label: New label:
  38. // ========= =========
  39. // CSndFx RSndFx
  40. // MAX_BITSPERSAMPLE RSP_SNDFX_MAX_BITSPERSAMPLE
  41. // NUM_FADE_INTERVALS RSP_SNDFX_NUM_FADE_INTERVALS
  42. // SNDFX_* * Macros changed to enum/typedef.
  43. // m_fx m_fx
  44. //
  45. //////////////////////////////////////////////////////////////////////////////
  46. //
  47. // Implements sound effects on PCM data.
  48. //
  49. //////////////////////////////////////////////////////////////////////////////
  50. #include <stdlib.h>
  51. #include "Blue.h"
  52. #ifdef PATHS_IN_INCLUDES
  53. #include "GREEN/SndFx/SndFx.h"
  54. #else
  55. #include "SndFx.h"
  56. #endif // PATHS_IN_INCLUDES
  57. //////////////////////////////////////////////////////////////////////////////
  58. // Initialize static member variables.
  59. //////////////////////////////////////////////////////////////////////////////
  60. RSndFx::PCMINFO RSndFx::ms_apcminfo[RSP_SNDFX_MAX_BITSPERSAMPLE + 1] = // Stores info
  61. // particular to each
  62. // PCM type.
  63. {
  64. { 0x00000000, 0x00000000 }, // 0 Bit.
  65. { 0x00000000, 0x00000001 }, // 1 Bit.
  66. { 0x00000000, 0x00000003 }, // 2 Bit.
  67. { 0x00000000, 0x00000007 }, // 3 Bit.
  68. { 0x00000000, 0x0000000F }, // 4 Bit.
  69. { 0x00000000, 0x0000001F }, // 5 Bit.
  70. { 0x00000000, 0x0000003F }, // 6 Bit.
  71. { 0x00000000, 0x0000007F }, // 7 Bit.
  72. { 0x00000000, 0x000000FF }, // 8 Bit.
  73. { 0x00000080, 0x000000FF }, // 9 Bit.
  74. { 0x00000100, 0x000001FF }, // 10 Bit.
  75. { 0x00000200, 0x000003FF }, // 11 Bit.
  76. { 0x00000400, 0x000007FF }, // 12 Bit.
  77. { 0x00000800, 0x00000FFF }, // 13 Bit.
  78. { 0x00001000, 0x00001FFF }, // 14 Bit.
  79. { 0x00002000, 0x00003FFF }, // 15 Bit.
  80. { -32768, 32767 }, // 16 Bit.
  81. { 0x00008000, 0x0000FFFF }, // 17 Bit.
  82. { 0x00010000, 0x0001FFFF }, // 18 Bit.
  83. { 0x00020000, 0x0003FFFF }, // 19 Bit.
  84. { 0x00040000, 0x0007FFFF }, // 20 Bit.
  85. { 0x00080000, 0x000FFFFF }, // 21 Bit.
  86. { 0x00100000, 0x001FFFFF }, // 22 Bit.
  87. { 0x00200000, 0x003FFFFF }, // 23 Bit.
  88. { 0x00400000, 0x007FFFFF }, // 24 Bit.
  89. { 0x00800000, 0x00FFFFFF }, // 25 Bit.
  90. { 0x01000000, 0x01FFFFFF }, // 26 Bit.
  91. { 0x02000000, 0x03FFFFFF }, // 27 Bit.
  92. { 0x04000000, 0x07FFFFFF }, // 28 Bit.
  93. { 0x08000000, 0x0FFFFFFF }, // 29 Bit.
  94. { 0x10000000, 0x1FFFFFFF }, // 30 Bit.
  95. { 0x20000000, 0x3FFFFFFF }, // 31 Bit.
  96. { 0x40000000, 0x7FFFFFFF }, // 32 Bit.
  97. };
  98. U8* RSndFx::ms_pu8Fade = NULL; // Unsigned 8 bit output
  99. // fade table.
  100. S16* RSndFx::ms_ps16Fade = NULL; // Signed 16 bit output
  101. // fade table.
  102. short RSndFx::ms_sNumFadeSteps = 0; // Number of fade steps.
  103. long RSndFx::ms_lSamplesPerSec = 0; // Samples per second.
  104. long RSndFx::ms_lBitsPerSample = 0; // Bits per sample.
  105. long RSndFx::ms_lNumChannels = 0; // Number of channels.
  106. long RSndFx::ms_lBitsPerSec = 0; // Number of bits per second.
  107. // Can be used to convert bytes to milliseconds
  108. // and convert milliseconds into bytes. See
  109. // macros BYTES2MS and MS2BYTES in SndFx.CPP.
  110. //////////////////////////////////////////////////////////////////////////////
  111. // Macros.
  112. //////////////////////////////////////////////////////////////////////////////
  113. // Converts bytes into milliseconds using a pre calculated variable.
  114. // 8000L consists of 8 (for bytes to bits) and 1000 (for seconds
  115. // to milliseconds).
  116. #define BYTES2MS(bytes) (((bytes) * 8000L) / ms_lBitsPerSec)
  117. // Converts milliseconds into bytes using a pre calculated variable.
  118. // 8000L consists of 8 (for bits to bytes) and 1000 (for milliseconds
  119. // to seconds).
  120. #define MS2BYTES(ms) (((ms) * ms_lBitsPerSec) / 8000L)
  121. #define PCM8_SILENCE 0x7F // 0x80 will not work for unsigned algorithm.
  122. #define PCM16_SILENCE 0x0000
  123. #define FIXED_POINT_DEPTH 1000 // Depth of fixed point notation (e.g.,
  124. // 1000 == depth of 1/1000).
  125. //////////////////////////////////////////////////////////////////////////////
  126. // Functions.
  127. //////////////////////////////////////////////////////////////////////////////
  128. //////////////////////////////////////////////////////////////////////////////
  129. //
  130. // Default Constructor.
  131. // Returns nothing.
  132. // (public)
  133. //
  134. //////////////////////////////////////////////////////////////////////////////
  135. RSndFx::RSndFx()
  136. {
  137. // Initializes members.
  138. Init();
  139. }
  140. //////////////////////////////////////////////////////////////////////////////
  141. //
  142. // Destructor.
  143. // Returns nothing.
  144. // (public)
  145. //
  146. //////////////////////////////////////////////////////////////////////////////
  147. RSndFx::~RSndFx()
  148. {
  149. // Clear and free.
  150. Clear();
  151. }
  152. //////////////////////////////////////////////////////////////////////////////
  153. //
  154. // Initialize instantiable members.
  155. // Returns nothing.
  156. // (public)
  157. //
  158. //////////////////////////////////////////////////////////////////////////////
  159. void RSndFx::Init(void)
  160. {
  161. // Initialize members.
  162. m_fx = NoFX; // Currently active effects.
  163. ///////////////// Fade In /////////////////////////////////////////
  164. m_lFadeInMillisecondsDuration = 0; // Original duration.
  165. m_lFadeInBytesDurationAffected = 0; // Amount left to fade.
  166. ///////////////// Fade Out ////////////////////////////////////////
  167. m_lFadeOutMillisecondsDuration = 0; // Original duration.
  168. m_lFadeOutBytesDurationRemaining = 0; // Amount left to fade.
  169. }
  170. ///////////////////////////////////////////////////////////////////////////////
  171. //
  172. // Release any dynamic memory and reset variables.
  173. // Clears all effects.
  174. // (public)
  175. //
  176. ///////////////////////////////////////////////////////////////////////////////
  177. void RSndFx::Clear(void)
  178. {
  179. Init();
  180. }
  181. ///////////////////////////////////////////////////////////////////////////////
  182. //
  183. // Release any dynamic memory referenced by static members.
  184. // (static/public)
  185. //
  186. ///////////////////////////////////////////////////////////////////////////////
  187. void RSndFx::CleanUp(void)
  188. {
  189. if (ms_pu8Fade != NULL)
  190. {
  191. free(ms_pu8Fade);
  192. ms_pu8Fade = NULL;
  193. }
  194. if (ms_ps16Fade != NULL)
  195. {
  196. free(ms_ps16Fade);
  197. ms_ps16Fade = NULL;
  198. }
  199. }
  200. ///////////////////////////////////////////////////////////////////////////////
  201. //
  202. // Reset effects to start over.
  203. //
  204. ///////////////////////////////////////////////////////////////////////////////
  205. void RSndFx::Reset(void)
  206. {
  207. ///////////////// Fade In /////////////////////////////////////////////////
  208. SetUpFadeIn(m_lFadeInMillisecondsDuration);
  209. ///////////////// Fade Out ////////////////////////////////////////////////
  210. SetUpFadeOut(m_lFadeOutMillisecondsDuration);
  211. }
  212. //////////////////////////////////////////////////////////////////////////////
  213. //
  214. // Sets the fade accuracy (i.e., the number of steps to perform a fade).
  215. // This costs sNumStemps * 256 * bits per sample / 8 bytes of memory.
  216. // This function should only be called after the bits per sample have
  217. // been set via a call to SetDataType().
  218. //
  219. //
  220. //
  221. // Power A
  222. // Power difference in dB = 10 log -------
  223. // Power B
  224. //
  225. // Every 3dB, the audible loudness doubles.
  226. // For acoustics, 0dB often means the threshold of hearing, 0.0002ubar
  227. // (Microbars: a bar is the "normal" pressure of air).
  228. // (static).
  229. //
  230. //////////////////////////////////////////////////////////////////////////////
  231. short RSndFx::SetFadeAccuracy( // Returns 0 on success.
  232. short sNumSteps) // Number of steps to fades; see above.
  233. {
  234. short sRes = 0; // Assume success.
  235. if (ms_lBitsPerSec != 0)
  236. {
  237. // Clean up any existing memory.
  238. CleanUp();
  239. // If bits per sample is value that indicates signage . . .
  240. switch (ms_lBitsPerSample)
  241. {
  242. case 8:
  243. {
  244. ms_pu8Fade = (U8*)malloc((long)sNumSteps * 256L * sizeof(S16));
  245. if (ms_pu8Fade != NULL)
  246. {
  247. short sStep;
  248. short sSample;
  249. float fStep = 1.0F / (float)sNumSteps;
  250. float fCurDecimation = fStep;
  251. U8* pu8 = ms_pu8Fade;
  252. for (sStep = 0; sStep < sNumSteps; sStep++)
  253. {
  254. for (sSample = 0; sSample < 256; sSample++)
  255. {
  256. *pu8++ = (U8)( (float)(sSample - 0x80) * fCurDecimation) + 0x80;
  257. }
  258. fCurDecimation += fStep;
  259. }
  260. // Success.
  261. ms_sNumFadeSteps = sNumSteps;
  262. static short sSetUpAtExit = FALSE; // Remember if we already did this.
  263. // If we haven't already set up the at exit function . . .
  264. if (sSetUpAtExit == FALSE)
  265. {
  266. // Set up atexit to deallocate memory.
  267. atexit(CleanUp);
  268. sSetUpAtExit = TRUE;
  269. }
  270. }
  271. else
  272. {
  273. TRACE("SetFadeAccuracy(): Failed to allocate fade lookup table.\n");
  274. sRes = -1;
  275. }
  276. break;
  277. }
  278. case 16:
  279. {
  280. ms_ps16Fade = (S16*)malloc((long)sNumSteps * 256L * sizeof(S16));
  281. if (ms_ps16Fade != NULL)
  282. {
  283. short sStep;
  284. short sSample;
  285. float fStep = 1.0F / (float)sNumSteps;
  286. float fCurDecimation = fStep;
  287. S16* ps16 = ms_ps16Fade;
  288. for (sStep = 0; sStep < sNumSteps; sStep++)
  289. {
  290. for (sSample = 0; sSample < 256; sSample++)
  291. {
  292. *ps16++ = (S16)( (float)((sSample - 128) << 8) * fCurDecimation);
  293. }
  294. fCurDecimation += fStep;
  295. }
  296. // Success.
  297. ms_sNumFadeSteps = sNumSteps;
  298. static short sSetUpAtExit = FALSE; // Remember if we already did this.
  299. // If we haven't already set up the at exit function . . .
  300. if (sSetUpAtExit == FALSE)
  301. {
  302. // Set up atexit to deallocate memory.
  303. atexit(CleanUp);
  304. sSetUpAtExit = TRUE;
  305. }
  306. }
  307. else
  308. {
  309. TRACE("SetFadeAccuracy(): Failed to allocate fade lookup table.\n");
  310. sRes = -1;
  311. }
  312. break;
  313. }
  314. default:
  315. TRACE("SetFadeAccuracy(): %ld bits per sample not supported.\n", ms_lBitsPerSample);
  316. break;
  317. }
  318. }
  319. else
  320. {
  321. TRACE("SetFadeAccuracy(): No data type set. Use SetDataType().\n");
  322. sRes = 1;
  323. }
  324. return sRes;
  325. }
  326. //////////////////////////////////////////////////////////////////////////////
  327. //
  328. // Set type of PCM data in use. This will reset all effects.
  329. // (static).
  330. //
  331. //////////////////////////////////////////////////////////////////////////////
  332. void RSndFx::SetDataType( // Returns nothing.
  333. long lSamplesPerSec, // Samples per second.
  334. long lBitsPerSample, // Bits per sample.
  335. long lNumChannels) // Number of channels.
  336. {
  337. ms_lSamplesPerSec = lSamplesPerSec;
  338. ms_lBitsPerSample = lBitsPerSample;
  339. ms_lNumChannels = lNumChannels;
  340. // Precalculate bits per second to aid in computation time.
  341. ms_lBitsPerSec = lSamplesPerSec * lBitsPerSample * lNumChannels;
  342. }
  343. /////////////////////////////////////////////////////////////////////////
  344. //
  345. // Fades in lNumBytes of pnData for signed TYPE.
  346. //
  347. /////////////////////////////////////////////////////////////////////////
  348. template <
  349. class TYPE> // Data type, signed.
  350. inline void Decimate( // Returns nothing.
  351. TYPE* psnSrcData, // Data buffer to decimate.
  352. TYPE* psnDstData, // Decimation destination.
  353. long lNumBytes, // Number of bytes in buffer.
  354. TYPE* psnTable) // Attenuation table.
  355. {
  356. long lNumSamples = lNumBytes / sizeof(TYPE);
  357. while (lNumSamples-- > 0)
  358. {
  359. *psnDstData++ = psnTable[((*psnSrcData++ + 0x0080) >> 8) + 128];
  360. }
  361. }
  362. /////////////////////////////////////////////////////////////////////////
  363. //
  364. // Fades in lNumBytes of punData for unsigned UTYPE.
  365. //
  366. /////////////////////////////////////////////////////////////////////////
  367. template <
  368. class UTYPE> // Data type, unsigned.
  369. inline void UnsignedDecimate( // Returns nothing.
  370. UTYPE* punSrcData, // Data buffer to decimate.
  371. UTYPE* punDstData, // Decimation destination.
  372. long lNumBytes, // Number of bytes in buffer.
  373. UTYPE* punTable) // Attenuation table.
  374. {
  375. long lNumSamples = lNumBytes / sizeof(UTYPE);
  376. while (lNumSamples-- > 0)
  377. {
  378. *punDstData++ = punTable[*punSrcData++];
  379. }
  380. }
  381. /////////////////////////////////////////////////////////////////////////
  382. //
  383. // Implements the effect on the provided buffer.
  384. //
  385. /////////////////////////////////////////////////////////////////////////
  386. void RSndFx::Do( // Returns nothing.
  387. UCHAR* pucSrcData, // Data to affect.
  388. long lBufSize, // Amount of data.
  389. UCHAR* pucDstData /*= NULL*/) // Destination for data, defaults
  390. // to same as source.
  391. {
  392. if (ms_lBitsPerSec > 0)
  393. {
  394. // If any active effects . . .
  395. if (m_fx != 0)
  396. {
  397. // If there is no destination . . .
  398. if (pucDstData == NULL)
  399. {
  400. pucDstData = pucSrcData;
  401. }
  402. if (m_fx & FadeIn)
  403. {
  404. if (m_lFadeInBytesDurationAffected < m_lFadeInBytesDuration)
  405. {
  406. switch (ms_lBitsPerSample)
  407. {
  408. case 8:
  409. {
  410. UnsignedDecimate( // Returns nothing.
  411. (U8*)pucSrcData, // Data buffer to fade.
  412. (U8*)pucDstData, // Dest data buffer.
  413. lBufSize, // Number of bytes in buffer.
  414. ms_pu8Fade + (m_lFadeInBytesDurationAffected / m_lFadeInRate) * 256 ); // Attenuation Table.
  415. break;
  416. }
  417. case 16:
  418. {
  419. Decimate( // Returns nothing.
  420. (S16*)pucSrcData, // Data buffer to fade.
  421. (S16*)pucDstData, // Dest data buffer.
  422. lBufSize, // Number of bytes in buffer.
  423. ms_ps16Fade + (m_lFadeInBytesDurationAffected / m_lFadeInRate) * 256 ); // Attenuation Table.
  424. break;
  425. }
  426. default:
  427. {
  428. TRACE("Do(): Unsupported bits per sample.\n");
  429. break;
  430. }
  431. }
  432. m_lFadeInBytesDurationAffected += lBufSize;
  433. }
  434. else
  435. {
  436. // Done.
  437. ActivateFadeIn(FALSE);
  438. }
  439. }
  440. else
  441. {
  442. if (m_fx & FadeOut)
  443. {
  444. if (m_lFadeOutBytesDurationRemaining > 0)
  445. {
  446. switch (ms_lBitsPerSample)
  447. {
  448. case 8:
  449. {
  450. UnsignedDecimate( // Returns nothing.
  451. (U8*)pucSrcData, // Data buffer to fade.
  452. (U8*)pucDstData, // Dest data buffer.
  453. lBufSize, // Number of bytes in buffer.
  454. ms_pu8Fade + (m_lFadeOutBytesDurationRemaining / m_lFadeOutRate) * 256 ); // Attenuation Table.
  455. break;
  456. }
  457. case 16:
  458. {
  459. Decimate( // Returns nothing.
  460. (S16*)pucSrcData, // Data buffer to fade.
  461. (S16*)pucDstData, // Dest data buffer.
  462. lBufSize, // Number of bytes in buffer.
  463. ms_ps16Fade + (m_lFadeOutBytesDurationRemaining / m_lFadeOutRate) * 256 ); // Attenuation table.
  464. break;
  465. }
  466. default:
  467. {
  468. TRACE("Do(): Unsupported bits per sample.\n");
  469. break;
  470. }
  471. }
  472. m_lFadeOutBytesDurationRemaining -= lBufSize;
  473. }
  474. else
  475. {
  476. // Done.
  477. ActivateFadeOut(FALSE);
  478. }
  479. }
  480. }
  481. }
  482. }
  483. else
  484. {
  485. TRACE("Do(): Called, but no data format set. Use SetDataType().\n");
  486. }
  487. }
  488. /////////////////////////////////////////////////////////////////////////
  489. // Various FX.
  490. /////////////////////////////////////////////////////////////////////////
  491. //////////////////////////// Fade In ////////////////////////////////////
  492. /////////////////////////////////////////////////////////////////////////
  493. //
  494. // Set up a fade in.
  495. //
  496. /////////////////////////////////////////////////////////////////////////
  497. short RSndFx::SetUpFadeIn( // Returns 0 on success.
  498. long lDuration) // Duration until silence in milliseconds.
  499. {
  500. short sRes = 0; // Assume success.
  501. // Must set data type before setting up effect . . .
  502. if (ms_lBitsPerSec > 0)
  503. {
  504. if (lDuration > 0)
  505. {
  506. m_lFadeInMillisecondsDuration = lDuration;
  507. m_lFadeInBytesDurationAffected = 0;
  508. m_lFadeInBytesDuration = MS2BYTES(m_lFadeInMillisecondsDuration);
  509. // Determine the number of bytes per table index.
  510. m_lFadeInRate = m_lFadeInBytesDuration / ms_sNumFadeSteps;
  511. }
  512. }
  513. else
  514. {
  515. TRACE("FadeIn(): Data type not set. Use SetDataType().\n");
  516. sRes = 1;
  517. }
  518. return sRes;
  519. }
  520. /////////////////////////////////////////////////////////////////////////
  521. //
  522. // Activate/Deactivate fade in.
  523. //
  524. /////////////////////////////////////////////////////////////////////////
  525. void RSndFx::ActivateFadeIn( // Returns nothing.
  526. short sActivate) // TRUE to activate, FALSE to deactivate.
  527. {
  528. if (sActivate == FALSE)
  529. {
  530. m_fx = (FX)(m_fx & (~FadeIn));
  531. }
  532. else
  533. {
  534. m_fx = (FX)(m_fx | FadeIn);
  535. }
  536. }
  537. /////////////////////// Fade Out ////////////////////////////////////////
  538. /////////////////////////////////////////////////////////////////////////
  539. //
  540. // Set up a fade out.
  541. //
  542. /////////////////////////////////////////////////////////////////////////
  543. short RSndFx::SetUpFadeOut( // Returns 0 on success.
  544. long lDuration) // Duration until full volume in milliseconds.
  545. {
  546. short sRes = 0; // Assume success.
  547. // Must set data type before setting up effect . . .
  548. if (ms_lBitsPerSec > 0)
  549. {
  550. if (lDuration > 0)
  551. {
  552. m_lFadeOutMillisecondsDuration = lDuration;
  553. m_lFadeOutBytesDurationRemaining = MS2BYTES(m_lFadeOutMillisecondsDuration);
  554. m_lFadeOutBytesDuration = m_lFadeOutBytesDurationRemaining;
  555. // Determine the number of bytes per table index.
  556. m_lFadeOutRate = m_lFadeOutBytesDuration / ms_sNumFadeSteps;
  557. }
  558. }
  559. else
  560. {
  561. TRACE("FadeOut(): Data type not set. Use SetDataType().\n");
  562. sRes = 1;
  563. }
  564. return sRes;
  565. }
  566. /////////////////////////////////////////////////////////////////////////
  567. //
  568. // Activate/Deactivate fade out.
  569. //
  570. /////////////////////////////////////////////////////////////////////////
  571. void RSndFx::ActivateFadeOut( // Returns nothing.
  572. short sActivate) // TRUE to activate, FALSE to deactivate.
  573. {
  574. if (sActivate != FALSE)
  575. {
  576. // Deactivates fade ins.
  577. ActivateFadeIn(FALSE);
  578. m_fx = (FX)(m_fx | FadeOut);
  579. }
  580. else
  581. {
  582. m_fx = (FX)(m_fx & (~FadeOut));
  583. }
  584. }
  585. //////////////////////////////////////////////////////////////////////////////
  586. // EOF
  587. //////////////////////////////////////////////////////////////////////////////