Channel.cpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "Audio.h"
  25. #include "Channel.h"
  26. #include "Sound.h"
  27. #include <cstring>
  28. #include "DebugNew.h"
  29. #define INC_POS_LOOPED() \
  30. pos += intAdd; \
  31. fractPos += fractAdd; \
  32. if (fractPos > 65535) \
  33. { \
  34. fractPos &= 65535; \
  35. ++pos; \
  36. } \
  37. while (pos >= end) \
  38. pos -= (end - repeat); \
  39. #define INC_POS_ONESHOT() \
  40. pos += intAdd; \
  41. fractPos += fractAdd; \
  42. if (fractPos > 65535) \
  43. { \
  44. fractPos &= 65535; \
  45. ++pos; \
  46. } \
  47. if (pos >= end) \
  48. { \
  49. pos = 0; \
  50. break; \
  51. } \
  52. #define INC_POS_STEREO_LOOPED() \
  53. pos += (intAdd << 1); \
  54. fractPos += fractAdd; \
  55. if (fractPos > 65535) \
  56. { \
  57. fractPos &= 65535; \
  58. pos += 2; \
  59. } \
  60. while (pos >= end) \
  61. pos -= (end - repeat); \
  62. #define INC_POS_STEREO_ONESHOT() \
  63. pos += (intAdd << 1); \
  64. fractPos += fractAdd; \
  65. if (fractPos > 65535) \
  66. { \
  67. fractPos &= 65535; \
  68. pos += 2; \
  69. } \
  70. if (pos >= end) \
  71. { \
  72. pos = 0; \
  73. break; \
  74. } \
  75. #define GET_IP_SAMPLE() (((((int)pos[1] - (int)pos[0]) * fractPos) / 65536) + (int)pos[0])
  76. #define GET_IP_SAMPLE_LEFT() (((((int)pos[2] - (int)pos[0]) * fractPos) / 65536) + (int)pos[0])
  77. #define GET_IP_SAMPLE_RIGHT() (((((int)pos[3] - (int)pos[1]) * fractPos) / 65536) + (int)pos[1])
  78. // Compressed audio decode buffer length in milliseconds
  79. static const int DECODE_BUFFER_LENGTH = 100;
  80. Channel::Channel(Audio* audio) :
  81. mAudio(audio),
  82. mPos(0),
  83. mFractPos(0),
  84. mTimePos(0.0f),
  85. mChannelType(CHANNEL_EFFECT),
  86. mFrequency(0.0f),
  87. mGain(1.0f),
  88. mAttenuation(1.0f),
  89. mPanning(0.0f),
  90. mDecoder(0),
  91. mDecodePos(0)
  92. {
  93. if (mAudio)
  94. mAudio->addChannel(this);
  95. }
  96. Channel::~Channel()
  97. {
  98. if (mAudio)
  99. mAudio->removeChannel(this);
  100. freeDecoder();
  101. }
  102. void Channel::play(Sound* sound)
  103. {
  104. if (!mAudio)
  105. return;
  106. // If channel is currently playing, have to lock the audio mutex
  107. if (mPos)
  108. {
  109. MutexLock lock(mAudio->getMutex());
  110. playLockless(sound);
  111. }
  112. else
  113. playLockless(sound);
  114. }
  115. void Channel::play(Sound* sound, float frequency)
  116. {
  117. setFrequency(frequency);
  118. play(sound);
  119. }
  120. void Channel::play(Sound* sound, float frequency, float gain)
  121. {
  122. setFrequency(frequency);
  123. setGain(gain);
  124. play(sound);
  125. }
  126. void Channel::play(Sound* sound, float frequency, float gain, float panning)
  127. {
  128. setFrequency(frequency);
  129. setGain(gain);
  130. setPanning(panning);
  131. play(sound);
  132. }
  133. void Channel::stop()
  134. {
  135. if (!mAudio)
  136. return;
  137. // If channel is currently playing, have to lock the audio mutex
  138. if (mPos)
  139. {
  140. MutexLock lock(mAudio->getMutex());
  141. stopLockless();
  142. }
  143. // Free the compressed sound decoder now if any
  144. freeDecoder();
  145. mSound.reset();
  146. }
  147. void Channel::setChannelType(ChannelType type)
  148. {
  149. if ((type == CHANNEL_MASTER) || (type >= MAX_CHANNEL_TYPES))
  150. return;
  151. mChannelType = type;
  152. }
  153. void Channel::setFrequency(float frequency)
  154. {
  155. mFrequency = clamp(frequency, 0.0f, 535232.0f);
  156. }
  157. void Channel::setGain(float gain)
  158. {
  159. mGain = max(gain, 0.0f);
  160. }
  161. void Channel::setAttenuation(float attenuation)
  162. {
  163. mAttenuation = clamp(attenuation, 0.0f, 1.0f);
  164. }
  165. void Channel::setPanning(float panning)
  166. {
  167. mPanning = clamp(panning, -1.0f, 1.0f);
  168. }
  169. void Channel::setIntFrequency(unsigned frequency)
  170. {
  171. mFrequency = clamp((float)frequency, 0.0f, 535232.0f);
  172. }
  173. void Channel::setIntVolume(int volume)
  174. {
  175. mGain = max((float)volume / 64.0f, 0.0f);
  176. }
  177. void Channel::setIntPanning(int panning)
  178. {
  179. mPanning = clamp(((float)panning / 255.0f) * 2.0f - 1.0f, -1.0f, 1.0f);
  180. }
  181. bool Channel::isPlaying() const
  182. {
  183. return mSound.getPtr() != 0;
  184. }
  185. void Channel::setPlayPosition(signed char* pos)
  186. {
  187. if ((!mAudio) || (!mSound))
  188. return;
  189. MutexLock lock(mAudio->getMutex());
  190. setPlayPositionLockless(pos);
  191. }
  192. void Channel::playLockless(Sound* sound)
  193. {
  194. // Reset the time position in any case
  195. mTimePos = 0.0f;
  196. if (sound)
  197. {
  198. if (!sound->isCompressed())
  199. {
  200. // Uncompressed sound start
  201. signed char* start = sound->getStart();
  202. if (start)
  203. {
  204. // Free decoder in case previous sound was compressed
  205. freeDecoder();
  206. mSound = sound;
  207. mPos = start;
  208. mFractPos = 0;
  209. return;
  210. }
  211. }
  212. else
  213. {
  214. // Compressed sound start
  215. if (sound == mSound)
  216. {
  217. // If same compressed sound is already playing, rewind the decoder
  218. mSound->rewindDecoder(mDecoder);
  219. return;
  220. }
  221. else
  222. {
  223. // Else just set the new sound with a dummy start position. The mixing routine will allocate the new decoder
  224. freeDecoder();
  225. mSound = sound;
  226. mPos = sound->getStart();
  227. return;
  228. }
  229. }
  230. }
  231. // If sound pointer is null or if sound has no data, stop playback
  232. freeDecoder();
  233. mSound.reset();
  234. mPos = 0;
  235. }
  236. void Channel::stopLockless()
  237. {
  238. mPos = 0;
  239. mTimePos = 0.0f;
  240. }
  241. void Channel::setPlayPositionLockless(signed char* pos)
  242. {
  243. // Setting position on a compressed sound is not supported
  244. if ((!mSound) || (mSound->isCompressed()))
  245. return;
  246. signed char* start = mSound->getStart();
  247. signed char* end = mSound->getEnd();
  248. if (pos < start)
  249. pos = start;
  250. if ((mSound->isSixteenBit()) && ((pos - start) & 1))
  251. ++pos;
  252. if (pos > end)
  253. pos = end;
  254. mPos = pos;
  255. mTimePos = (float)((int)pos - (int)mSound->getStart()) / (mSound->getSampleSize() * mSound->getFrequency());
  256. }
  257. void Channel::update(float timeStep)
  258. {
  259. if (!mAudio)
  260. return;
  261. // If there is no actual audio output, perform fake mixing into a nonexistent buffer to check stopping/looping
  262. if (!mAudio->hasBuffer())
  263. mixNull(timeStep);
  264. // Free the sound if playback has stopped
  265. if ((mSound) && (!mPos))
  266. {
  267. freeDecoder();
  268. mSound.reset();
  269. }
  270. }
  271. void Channel::mix(int* dest, unsigned samples, int mixRate, bool stereo, bool interpolate)
  272. {
  273. if ((!mPos) || (!mSound))
  274. return;
  275. if (mSound->isCompressed())
  276. {
  277. if (mDecoder)
  278. {
  279. // If decoder already exists, decode new compressed audio
  280. bool eof = false;
  281. unsigned currentPos = mPos - mDecodeBuffer->getStart();
  282. if (currentPos != mDecodePos)
  283. {
  284. // If buffer has wrapped, decode first to the end
  285. if (currentPos < mDecodePos)
  286. {
  287. unsigned bytes = mDecodeBuffer->getDataSize() - mDecodePos;
  288. unsigned outBytes = mSound->decode(mDecoder, mDecodeBuffer->getStart() + mDecodePos, bytes);
  289. // If produced less output, end of sound encountered. Fill rest with zero
  290. if (outBytes < bytes)
  291. {
  292. memset(mDecodeBuffer->getStart() + mDecodePos + outBytes, 0, bytes - outBytes);
  293. eof = true;
  294. }
  295. mDecodePos = 0;
  296. }
  297. if (currentPos > mDecodePos)
  298. {
  299. unsigned bytes = currentPos - mDecodePos;
  300. unsigned outBytes = mSound->decode(mDecoder, mDecodeBuffer->getStart() + mDecodePos, bytes);
  301. // If produced less output, end of sound encountered. Fill rest with zero
  302. if (outBytes < bytes)
  303. {
  304. memset(mDecodeBuffer->getStart() + mDecodePos + outBytes, 0, bytes - outBytes);
  305. if (mSound->isLooped())
  306. eof = true;
  307. }
  308. // If wrote to buffer start, correct interpolation wraparound
  309. if (!mDecodePos)
  310. mDecodeBuffer->fixInterpolation();
  311. }
  312. }
  313. // If end of stream encountered, check whether we should rewind or stop
  314. if (eof)
  315. {
  316. if (mSound->isLooped())
  317. {
  318. mSound->rewindDecoder(mDecoder);
  319. mTimePos = 0.0f;
  320. }
  321. else
  322. mDecodeBuffer->setOneshot(); // Stop after the current decode buffer has been played
  323. }
  324. mDecodePos = currentPos;
  325. }
  326. else
  327. {
  328. // Setup the decoder and decode buffer
  329. mDecoder = mSound->allocateDecoder();
  330. unsigned sampleSize = mSound->getSampleSize();
  331. unsigned decodeBufferSize = sampleSize * mSound->getIntFrequency() * DECODE_BUFFER_LENGTH / 1000;
  332. mDecodeBuffer = new Sound();
  333. mDecodeBuffer->setSize(decodeBufferSize);
  334. mDecodeBuffer->setFormat(mSound->getIntFrequency(), true, mSound->isStereo());
  335. // Clear the decode buffer, then fill with initial audio data and set it to loop
  336. memset(mDecodeBuffer->getStart(), 0, decodeBufferSize);
  337. mSound->decode(mDecoder, mDecodeBuffer->getStart(), decodeBufferSize);
  338. mDecodeBuffer->setLooped();
  339. mDecodePos = 0;
  340. // Start playing the decode buffer
  341. mPos = mDecodeBuffer->getStart();
  342. mFractPos = 0;
  343. }
  344. }
  345. // If compressed, play the decode buffer. Otherwise play the original sound
  346. Sound* sound = mSound->isCompressed() ? mDecodeBuffer : mSound;
  347. if (!sound)
  348. return;
  349. // Choose the correct mixing routine
  350. if (!sound->isStereo())
  351. {
  352. if (interpolate)
  353. {
  354. if (stereo)
  355. mixMonoToStereoIP(sound, dest, samples, mixRate);
  356. else
  357. mixMonoToMonoIP(sound, dest, samples, mixRate);
  358. }
  359. else
  360. {
  361. if (stereo)
  362. mixMonoToStereo(sound, dest, samples, mixRate);
  363. else
  364. mixMonoToMono(sound, dest, samples, mixRate);
  365. }
  366. }
  367. else
  368. {
  369. if (interpolate)
  370. {
  371. if (stereo)
  372. mixStereoToStereoIP(sound, dest, samples, mixRate);
  373. else
  374. mixStereoToMonoIP(sound, dest, samples, mixRate);
  375. }
  376. else
  377. {
  378. if (stereo)
  379. mixStereoToStereo(sound, dest, samples, mixRate);
  380. else
  381. mixStereoToMono(sound, dest, samples, mixRate);
  382. }
  383. }
  384. // Update the time position
  385. if (!mSound->isCompressed())
  386. mTimePos = (float)((int)mPos - (int)mSound->getStart()) / (mSound->getSampleSize() * mSound->getFrequency());
  387. else
  388. mTimePos += ((float)samples / (float)mixRate) * mFrequency / mSound->getFrequency();
  389. }
  390. void Channel::mixMonoToMono(Sound* sound, int* dest, unsigned samples, int mixRate)
  391. {
  392. float totalGain = mAudio->getChannelMasterGain(mChannelType) * mAttenuation * mGain;
  393. int vol = (int)(256.0f * totalGain + 0.5f);
  394. if (!vol)
  395. {
  396. mixZeroVolume(sound, samples, mixRate);
  397. return;
  398. }
  399. float add = mFrequency / (float)mixRate;
  400. int intAdd = (int)add;
  401. int fractAdd = (int)((add - floorf(add)) * 65536.0f);
  402. int fractPos = mFractPos;
  403. if (sound->isSixteenBit())
  404. {
  405. short* pos = (short*)mPos;
  406. short* end = (short*)sound->getEnd();
  407. short* repeat = (short*)sound->getRepeat();
  408. if (sound->isLooped())
  409. {
  410. while (samples--)
  411. {
  412. *dest = *dest + (*pos * vol) / 256;
  413. ++dest;
  414. INC_POS_LOOPED();
  415. }
  416. mPos = (signed char*)pos;
  417. }
  418. else
  419. {
  420. while (samples--)
  421. {
  422. *dest = *dest + (*pos * vol) / 256;
  423. ++dest;
  424. INC_POS_ONESHOT();
  425. }
  426. mPos = (signed char*)pos;
  427. }
  428. }
  429. else
  430. {
  431. signed char* pos = (signed char*)mPos;
  432. signed char* end = sound->getEnd();
  433. signed char* repeat = sound->getRepeat();
  434. if (sound->isLooped())
  435. {
  436. while (samples--)
  437. {
  438. *dest = *dest + *pos * vol;
  439. ++dest;
  440. INC_POS_LOOPED();
  441. }
  442. mPos = pos;
  443. }
  444. else
  445. {
  446. while (samples--)
  447. {
  448. *dest = *dest + *pos * vol;
  449. ++dest;
  450. INC_POS_ONESHOT();
  451. }
  452. mPos = pos;
  453. }
  454. }
  455. mFractPos = fractPos;
  456. }
  457. void Channel::mixMonoToStereo(Sound* sound, int* dest, unsigned samples, int mixRate)
  458. {
  459. float totalGain = mAudio->getChannelMasterGain(mChannelType) * mAttenuation * mGain;
  460. int leftVol = (int)((-mPanning + 1.0f) * (256.0f * totalGain + 0.5f));
  461. int rightVol = (int)((mPanning + 1.0f) * (256.0f * totalGain + 0.5f));
  462. if ((!leftVol) && (!rightVol))
  463. {
  464. mixZeroVolume(sound, samples, mixRate);
  465. return;
  466. }
  467. float add = mFrequency / (float)mixRate;
  468. int intAdd = (int)add;
  469. int fractAdd = (int)((add - floorf(add)) * 65536.0f);
  470. int fractPos = mFractPos;
  471. if (sound->isSixteenBit())
  472. {
  473. short* pos = (short*)mPos;
  474. short* end = (short*)sound->getEnd();
  475. short* repeat = (short*)sound->getRepeat();
  476. if (sound->isLooped())
  477. {
  478. while (samples--)
  479. {
  480. *dest = *dest + (*pos * leftVol) / 256;
  481. ++dest;
  482. *dest = *dest + (*pos * rightVol) / 256;
  483. ++dest;
  484. INC_POS_LOOPED();
  485. }
  486. mPos = (signed char*)pos;
  487. }
  488. else
  489. {
  490. while (samples--)
  491. {
  492. *dest = *dest + (*pos * leftVol) / 256;
  493. ++dest;
  494. *dest = *dest + (*pos * rightVol) / 256;
  495. ++dest;
  496. INC_POS_ONESHOT();
  497. }
  498. mPos = (signed char*)pos;
  499. }
  500. }
  501. else
  502. {
  503. signed char* pos = (signed char*)mPos;
  504. signed char* end = sound->getEnd();
  505. signed char* repeat = sound->getRepeat();
  506. if (sound->isLooped())
  507. {
  508. while (samples--)
  509. {
  510. *dest = *dest + *pos * leftVol;
  511. ++dest;
  512. *dest = *dest + *pos * rightVol;
  513. ++dest;
  514. INC_POS_LOOPED();
  515. }
  516. mPos = pos;
  517. }
  518. else
  519. {
  520. while (samples--)
  521. {
  522. *dest = *dest + *pos * leftVol;
  523. ++dest;
  524. *dest = *dest + *pos * rightVol;
  525. ++dest;
  526. INC_POS_ONESHOT();
  527. }
  528. mPos = pos;
  529. }
  530. }
  531. mFractPos = fractPos;
  532. }
  533. void Channel::mixMonoToMonoIP(Sound* sound, int* dest, unsigned samples, int mixRate)
  534. {
  535. float totalGain = mAudio->getChannelMasterGain(mChannelType) * mAttenuation * mGain;
  536. int vol = (int)(256.0f * totalGain + 0.5f);
  537. if (!vol)
  538. {
  539. mixZeroVolume(sound, samples, mixRate);
  540. return;
  541. }
  542. float add = mFrequency / (float)mixRate;
  543. int intAdd = (int)add;
  544. int fractAdd = (int)((add - floorf(add)) * 65536.0f);
  545. int fractPos = mFractPos;
  546. if (sound->isSixteenBit())
  547. {
  548. short* pos = (short*)mPos;
  549. short* end = (short*)sound->getEnd();
  550. short* repeat = (short*)sound->getRepeat();
  551. if (sound->isLooped())
  552. {
  553. while (samples--)
  554. {
  555. *dest = *dest + (GET_IP_SAMPLE() * vol) / 256;
  556. ++dest;
  557. INC_POS_LOOPED();
  558. }
  559. mPos = (signed char*)pos;
  560. }
  561. else
  562. {
  563. while (samples--)
  564. {
  565. *dest = *dest + (GET_IP_SAMPLE() * vol) / 256;
  566. ++dest;
  567. INC_POS_ONESHOT();
  568. }
  569. mPos = (signed char*)pos;
  570. }
  571. }
  572. else
  573. {
  574. signed char* pos = (signed char*)mPos;
  575. signed char* end = sound->getEnd();
  576. signed char* repeat = sound->getRepeat();
  577. if (sound->isLooped())
  578. {
  579. while (samples--)
  580. {
  581. *dest = *dest + GET_IP_SAMPLE() * vol;
  582. ++dest;
  583. INC_POS_LOOPED();
  584. }
  585. mPos = pos;
  586. }
  587. else
  588. {
  589. while (samples--)
  590. {
  591. *dest = *dest + GET_IP_SAMPLE() * vol;
  592. ++dest;
  593. INC_POS_ONESHOT();
  594. }
  595. mPos = pos;
  596. }
  597. }
  598. mFractPos = fractPos;
  599. }
  600. void Channel::mixMonoToStereoIP(Sound* sound, int* dest, unsigned samples, int mixRate)
  601. {
  602. float totalGain = mAudio->getChannelMasterGain(mChannelType) * mAttenuation * mGain;
  603. int leftVol = (int)((-mPanning + 1.0f) * (256.0f * totalGain + 0.5f));
  604. int rightVol = (int)((mPanning + 1.0f) * (256.0f * totalGain + 0.5f));
  605. if ((!leftVol) && (!rightVol))
  606. {
  607. mixZeroVolume(sound, samples, mixRate);
  608. return;
  609. }
  610. float add = mFrequency / (float)mixRate;
  611. int intAdd = (int)add;
  612. int fractAdd = (int)((add - floorf(add)) * 65536.0f);
  613. int fractPos = mFractPos;
  614. if (sound->isSixteenBit())
  615. {
  616. short* pos = (short*)mPos;
  617. short* end = (short*)sound->getEnd();
  618. short* repeat = (short*)sound->getRepeat();
  619. if (sound->isLooped())
  620. {
  621. while (samples--)
  622. {
  623. int s = GET_IP_SAMPLE();
  624. *dest = *dest + (s * leftVol) / 256;
  625. ++dest;
  626. *dest = *dest + (s * rightVol) / 256;
  627. ++dest;
  628. INC_POS_LOOPED();
  629. }
  630. mPos = (signed char*)pos;
  631. }
  632. else
  633. {
  634. while (samples--)
  635. {
  636. int s = GET_IP_SAMPLE();
  637. *dest = *dest + (s * leftVol) / 256;
  638. ++dest;
  639. *dest = *dest + (s * rightVol) / 256;
  640. ++dest;
  641. INC_POS_ONESHOT();
  642. }
  643. mPos = (signed char*)pos;
  644. }
  645. }
  646. else
  647. {
  648. signed char* pos = (signed char*)mPos;
  649. signed char* end = sound->getEnd();
  650. signed char* repeat = sound->getRepeat();
  651. if (sound->isLooped())
  652. {
  653. while (samples--)
  654. {
  655. int s = GET_IP_SAMPLE();
  656. *dest = *dest + s * leftVol;
  657. ++dest;
  658. *dest = *dest + s * rightVol;
  659. ++dest;
  660. INC_POS_LOOPED();
  661. }
  662. mPos = pos;
  663. }
  664. else
  665. {
  666. while (samples--)
  667. {
  668. int s = GET_IP_SAMPLE();
  669. *dest = *dest + s * leftVol;
  670. ++dest;
  671. *dest = *dest + s * rightVol;
  672. ++dest;
  673. INC_POS_ONESHOT();
  674. }
  675. mPos = pos;
  676. }
  677. }
  678. mFractPos = fractPos;
  679. }
  680. void Channel::mixStereoToMono(Sound* sound, int* dest, unsigned samples, int mixRate)
  681. {
  682. float totalGain = mAudio->getChannelMasterGain(mChannelType) * mAttenuation * mGain;
  683. int vol = (int)(256.0f * totalGain + 0.5f);
  684. if (!vol)
  685. {
  686. mixZeroVolume(sound, samples, mixRate);
  687. return;
  688. }
  689. float add = mFrequency / (float)mixRate;
  690. int intAdd = (int)add;
  691. int fractAdd = (int)((add - floorf(add)) * 65536.0f);
  692. int fractPos = mFractPos;
  693. if (sound->isSixteenBit())
  694. {
  695. short* pos = (short*)mPos;
  696. short* end = (short*)sound->getEnd();
  697. short* repeat = (short*)sound->getRepeat();
  698. if (sound->isLooped())
  699. {
  700. while (samples--)
  701. {
  702. int s = ((int)pos[0] + (int)pos[1]) / 2;
  703. *dest = *dest + (s * vol) / 256;
  704. ++dest;
  705. INC_POS_STEREO_LOOPED();
  706. }
  707. mPos = (signed char*)pos;
  708. }
  709. else
  710. {
  711. while (samples--)
  712. {
  713. int s = ((int)pos[0] + (int)pos[1]) / 2;
  714. *dest = *dest + (s * vol) / 256;
  715. ++dest;
  716. INC_POS_STEREO_ONESHOT();
  717. }
  718. mPos = (signed char*)pos;
  719. }
  720. }
  721. else
  722. {
  723. signed char* pos = (signed char*)mPos;
  724. signed char* end = sound->getEnd();
  725. signed char* repeat = sound->getRepeat();
  726. if (sound->isLooped())
  727. {
  728. while (samples--)
  729. {
  730. int s = ((int)pos[0] + (int)pos[1]) / 2;
  731. *dest = *dest + s * vol;
  732. ++dest;
  733. INC_POS_STEREO_LOOPED();
  734. }
  735. mPos = pos;
  736. }
  737. else
  738. {
  739. while (samples--)
  740. {
  741. int s = ((int)pos[0] + (int)pos[1]) / 2;
  742. *dest = *dest + s * vol;
  743. ++dest;
  744. INC_POS_STEREO_ONESHOT();
  745. }
  746. mPos = pos;
  747. }
  748. }
  749. mFractPos = fractPos;
  750. }
  751. void Channel::mixStereoToStereo(Sound* sound, int* dest, unsigned samples, int mixRate)
  752. {
  753. float totalGain = mAudio->getChannelMasterGain(mChannelType) * mAttenuation * mGain;
  754. int vol = (int)(256.0f * totalGain + 0.5f);
  755. if (!vol)
  756. {
  757. mixZeroVolume(sound, samples, mixRate);
  758. return;
  759. }
  760. float add = mFrequency / (float)mixRate;
  761. int intAdd = (int)add;
  762. int fractAdd = (int)((add - floorf(add)) * 65536.0f);
  763. int fractPos = mFractPos;
  764. if (sound->isSixteenBit())
  765. {
  766. short* pos = (short*)mPos;
  767. short* end = (short*)sound->getEnd();
  768. short* repeat = (short*)sound->getRepeat();
  769. if (sound->isLooped())
  770. {
  771. while (samples--)
  772. {
  773. *dest = *dest + (pos[0] * vol) / 256;
  774. ++dest;
  775. *dest = *dest + (pos[1] * vol) / 256;
  776. ++dest;
  777. INC_POS_STEREO_LOOPED();
  778. }
  779. mPos = (signed char*)pos;
  780. }
  781. else
  782. {
  783. while (samples--)
  784. {
  785. *dest = *dest + (pos[0] * vol) / 256;
  786. ++dest;
  787. *dest = *dest + (pos[1] * vol) / 256;
  788. ++dest;
  789. INC_POS_STEREO_ONESHOT();
  790. }
  791. mPos = (signed char*)pos;
  792. }
  793. }
  794. else
  795. {
  796. signed char* pos = (signed char*)mPos;
  797. signed char* end = sound->getEnd();
  798. signed char* repeat = sound->getRepeat();
  799. if (sound->isLooped())
  800. {
  801. while (samples--)
  802. {
  803. *dest = *dest + pos[0] * vol;
  804. ++dest;
  805. *dest = *dest + pos[1] * vol;
  806. ++dest;
  807. INC_POS_STEREO_LOOPED();
  808. }
  809. mPos = pos;
  810. }
  811. else
  812. {
  813. while (samples--)
  814. {
  815. *dest = *dest + pos[0] * vol;
  816. ++dest;
  817. *dest = *dest + pos[1] * vol;
  818. ++dest;
  819. INC_POS_STEREO_ONESHOT();
  820. }
  821. mPos = pos;
  822. }
  823. }
  824. mFractPos = fractPos;
  825. }
  826. void Channel::mixStereoToMonoIP(Sound* sound, int* dest, unsigned samples, int mixRate)
  827. {
  828. float totalGain = mAudio->getChannelMasterGain(mChannelType) * mAttenuation * mGain;
  829. int vol = (int)(256.0f * totalGain + 0.5f);
  830. if (!vol)
  831. {
  832. mixZeroVolume(sound, samples, mixRate);
  833. return;
  834. }
  835. float add = mFrequency / (float)mixRate;
  836. int intAdd = (int)add;
  837. int fractAdd = (int)((add - floorf(add)) * 65536.0f);
  838. int fractPos = mFractPos;
  839. if (sound->isSixteenBit())
  840. {
  841. short* pos = (short*)mPos;
  842. short* end = (short*)sound->getEnd();
  843. short* repeat = (short*)sound->getRepeat();
  844. if (sound->isLooped())
  845. {
  846. while (samples--)
  847. {
  848. int s = (GET_IP_SAMPLE_LEFT() + GET_IP_SAMPLE_RIGHT()) / 2;
  849. *dest = *dest + (s * vol) / 256;
  850. ++dest;
  851. INC_POS_STEREO_LOOPED();
  852. }
  853. mPos = (signed char*)pos;
  854. }
  855. else
  856. {
  857. while (samples--)
  858. {
  859. int s = (GET_IP_SAMPLE_LEFT() + GET_IP_SAMPLE_RIGHT()) / 2;
  860. *dest = *dest + (s * vol) / 256;
  861. ++dest;
  862. INC_POS_STEREO_ONESHOT();
  863. }
  864. mPos = (signed char*)pos;
  865. }
  866. }
  867. else
  868. {
  869. signed char* pos = (signed char*)mPos;
  870. signed char* end = sound->getEnd();
  871. signed char* repeat = sound->getRepeat();
  872. if (sound->isLooped())
  873. {
  874. while (samples--)
  875. {
  876. int s = (GET_IP_SAMPLE_LEFT() + GET_IP_SAMPLE_RIGHT()) / 2;
  877. *dest = *dest + s * vol;
  878. ++dest;
  879. INC_POS_STEREO_LOOPED();
  880. }
  881. mPos = pos;
  882. }
  883. else
  884. {
  885. while (samples--)
  886. {
  887. int s = (GET_IP_SAMPLE_LEFT() + GET_IP_SAMPLE_RIGHT()) / 2;
  888. *dest = *dest + s * vol;
  889. ++dest;
  890. INC_POS_STEREO_ONESHOT();
  891. }
  892. mPos = pos;
  893. }
  894. }
  895. mFractPos = fractPos;
  896. }
  897. void Channel::mixStereoToStereoIP(Sound* sound, int* dest, unsigned samples, int mixRate)
  898. {
  899. float totalGain = mAudio->getChannelMasterGain(mChannelType) * mAttenuation * mGain;
  900. int vol = (int)(256.0f * totalGain + 0.5f);
  901. if (!vol)
  902. {
  903. mixZeroVolume(sound, samples, mixRate);
  904. return;
  905. }
  906. float add = mFrequency / (float)mixRate;
  907. int intAdd = (int)add;
  908. int fractAdd = (int)((add - floorf(add)) * 65536.0f);
  909. int fractPos = mFractPos;
  910. if (sound->isSixteenBit())
  911. {
  912. short* pos = (short*)mPos;
  913. short* end = (short*)sound->getEnd();
  914. short* repeat = (short*)sound->getRepeat();
  915. if (sound->isLooped())
  916. {
  917. while (samples--)
  918. {
  919. *dest = *dest + (GET_IP_SAMPLE_LEFT() * vol) / 256;
  920. ++dest;
  921. *dest = *dest + (GET_IP_SAMPLE_RIGHT() * vol) / 256;
  922. ++dest;
  923. INC_POS_STEREO_LOOPED();
  924. }
  925. mPos = (signed char*)pos;
  926. }
  927. else
  928. {
  929. while (samples--)
  930. {
  931. *dest = *dest + (GET_IP_SAMPLE_LEFT() * vol) / 256;
  932. ++dest;
  933. *dest = *dest + (GET_IP_SAMPLE_RIGHT() * vol) / 256;
  934. ++dest;
  935. INC_POS_STEREO_ONESHOT();
  936. }
  937. mPos = (signed char*)pos;
  938. }
  939. }
  940. else
  941. {
  942. signed char* pos = (signed char*)mPos;
  943. signed char* end = sound->getEnd();
  944. signed char* repeat = sound->getRepeat();
  945. if (sound->isLooped())
  946. {
  947. while (samples--)
  948. {
  949. *dest = *dest + GET_IP_SAMPLE_LEFT() * vol;
  950. ++dest;
  951. *dest = *dest + GET_IP_SAMPLE_RIGHT() * vol;
  952. ++dest;
  953. INC_POS_STEREO_LOOPED();
  954. }
  955. mPos = pos;
  956. }
  957. else
  958. {
  959. while (samples--)
  960. {
  961. *dest = *dest + GET_IP_SAMPLE_LEFT() * vol;
  962. ++dest;
  963. *dest = *dest + GET_IP_SAMPLE_RIGHT() * vol;
  964. ++dest;
  965. INC_POS_STEREO_ONESHOT();
  966. }
  967. mPos = pos;
  968. }
  969. }
  970. mFractPos = fractPos;
  971. }
  972. void Channel::mixZeroVolume(Sound* sound, unsigned samples, int mixRate)
  973. {
  974. float add = mFrequency * (float)samples / (float)mixRate;
  975. int intAdd = (int)add;
  976. int fractAdd = (int)((add - floorf(add)) * 65536.0f);
  977. unsigned sampleSize = sound->getSampleSize();
  978. mFractPos += fractAdd;
  979. if (mFractPos > 65535)
  980. {
  981. mFractPos &= 65535;
  982. mPos += sampleSize;
  983. }
  984. mPos += intAdd * sampleSize;
  985. if (mPos > sound->getEnd())
  986. {
  987. if (sound->isLooped())
  988. {
  989. while (mPos >= sound->getEnd())
  990. {
  991. mPos -= (sound->getEnd() - sound->getRepeat());
  992. }
  993. }
  994. else
  995. mPos = 0;
  996. }
  997. }
  998. void Channel::mixNull(float timeStep)
  999. {
  1000. if ((!mPos) || (!mSound))
  1001. return;
  1002. // Advance only the time position
  1003. mTimePos += timeStep * mFrequency / mSound->getFrequency();
  1004. if (mSound->isLooped())
  1005. {
  1006. // For simulated playback, simply reset the time position to zero when the sound loops
  1007. if (mTimePos >= mSound->getLength())
  1008. mTimePos -= mSound->getLength();
  1009. }
  1010. else
  1011. {
  1012. if (mTimePos >= mSound->getLength())
  1013. {
  1014. mPos = 0;
  1015. mTimePos = 0.0f;
  1016. }
  1017. }
  1018. }
  1019. void Channel::freeDecoder()
  1020. {
  1021. if ((mSound) && (mDecoder))
  1022. {
  1023. mSound->freeDecoder(mDecoder);
  1024. mDecoder = 0;
  1025. }
  1026. mDecodeBuffer.reset();
  1027. }