Source.cpp 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222
  1. /**
  2. * Copyright (c) 2006-2016 LOVE Development Team
  3. *
  4. * This software is provided 'as-is', without any express or implied
  5. * warranty. In no event will the authors be held liable for any damages
  6. * arising from the use of this software.
  7. *
  8. * Permission is granted to anyone to use this software for any purpose,
  9. * including commercial applications, and to alter it and redistribute it
  10. * freely, subject to the following restrictions:
  11. *
  12. * 1. The origin of this software must not be misrepresented; you must not
  13. * claim that you wrote the original software. If you use this software
  14. * in a product, an acknowledgment in the product documentation would be
  15. * appreciated but is not required.
  16. * 2. Altered source versions must be plainly marked as such, and must not be
  17. * misrepresented as being the original software.
  18. * 3. This notice may not be removed or altered from any source distribution.
  19. **/
  20. #include "Source.h"
  21. #include "Pool.h"
  22. #include "common/math.h"
  23. // STD
  24. #include <iostream>
  25. #include <algorithm>
  26. namespace love
  27. {
  28. namespace audio
  29. {
  30. namespace openal
  31. {
  32. class InvalidFormatException : public love::Exception
  33. {
  34. public:
  35. InvalidFormatException(int channels, int bitdepth)
  36. : Exception("%d-channel Sources with %d bits per sample are not supported.", channels, bitdepth)
  37. {
  38. }
  39. };
  40. class SpatialSupportException : public love::Exception
  41. {
  42. public:
  43. SpatialSupportException()
  44. : Exception("This spatial audio functionality is only available for mono Sources. \
  45. Ensure the Source is not multi-channel before calling this function.")
  46. {
  47. }
  48. };
  49. class QueueFormatMismatchException : public love::Exception
  50. {
  51. public:
  52. QueueFormatMismatchException()
  53. : Exception("Queued sound data must have same format as sound Source.")
  54. {
  55. }
  56. };
  57. class QueueTypeMismatchException : public love::Exception
  58. {
  59. public:
  60. QueueTypeMismatchException()
  61. : Exception("Only queueable Sources can be queued with sound data.")
  62. {
  63. }
  64. };
  65. class QueueMalformedLengthException : public love::Exception
  66. {
  67. public:
  68. QueueMalformedLengthException(int bytes)
  69. : Exception("Data length must be a multiple of sample size (%d bytes).", bytes)
  70. {
  71. }
  72. };
  73. class QueueLoopingException : public love::Exception
  74. {
  75. public:
  76. QueueLoopingException()
  77. : Exception("Queueable Sources can not be looped.")
  78. {
  79. }
  80. };
  81. StaticDataBuffer::StaticDataBuffer(ALenum format, const ALvoid *data, ALsizei size, ALsizei freq)
  82. : size(size)
  83. {
  84. alGenBuffers(1, &buffer);
  85. alBufferData(buffer, format, data, size, freq);
  86. }
  87. StaticDataBuffer::~StaticDataBuffer()
  88. {
  89. alDeleteBuffers(1, &buffer);
  90. }
  91. Source::Source(Pool *pool, love::sound::SoundData *soundData)
  92. : love::audio::Source(Source::TYPE_STATIC)
  93. , pool(pool)
  94. , sampleRate(soundData->getSampleRate())
  95. , channels(soundData->getChannels())
  96. , bitDepth(soundData->getBitDepth())
  97. {
  98. ALenum fmt = getFormat(soundData->getChannels(), soundData->getBitDepth());
  99. if (fmt == 0)
  100. throw InvalidFormatException(soundData->getChannels(), soundData->getBitDepth());
  101. staticBuffer.set(new StaticDataBuffer(fmt, soundData->getData(), (ALsizei) soundData->getSize(), sampleRate), Acquire::NORETAIN);
  102. float z[3] = {0, 0, 0};
  103. setFloatv(position, z);
  104. setFloatv(velocity, z);
  105. setFloatv(direction, z);
  106. }
  107. Source::Source(Pool *pool, love::sound::Decoder *decoder)
  108. : love::audio::Source(Source::TYPE_STREAM)
  109. , pool(pool)
  110. , sampleRate(decoder->getSampleRate())
  111. , channels(decoder->getChannels())
  112. , bitDepth(decoder->getBitDepth())
  113. , decoder(decoder)
  114. , unusedBufferTop(MAX_BUFFERS - 1)
  115. {
  116. if (getFormat(decoder->getChannels(), decoder->getBitDepth()) == 0)
  117. throw InvalidFormatException(decoder->getChannels(), decoder->getBitDepth());
  118. alGenBuffers(MAX_BUFFERS, streamBuffers);
  119. for (unsigned int i = 0; i < MAX_BUFFERS; i++)
  120. unusedBuffers[i] = streamBuffers[i];
  121. float z[3] = {0, 0, 0};
  122. setFloatv(position, z);
  123. setFloatv(velocity, z);
  124. setFloatv(direction, z);
  125. }
  126. Source::Source(Pool *pool, int sampleRate, int bitDepth, int channels)
  127. : love::audio::Source(Source::TYPE_QUEUE)
  128. , pool(pool)
  129. , sampleRate(sampleRate)
  130. , channels(channels)
  131. , bitDepth(bitDepth)
  132. {
  133. ALenum fmt = getFormat(channels, bitDepth);
  134. if (fmt == 0)
  135. throw InvalidFormatException(channels, bitDepth);
  136. alGenBuffers(MAX_BUFFERS, streamBuffers);
  137. for (unsigned int i = 0; i < MAX_BUFFERS; i++)
  138. unusedBuffers[i] = streamBuffers[i];
  139. float z[3] = {0, 0, 0};
  140. setFloatv(position, z);
  141. setFloatv(velocity, z);
  142. setFloatv(direction, z);
  143. }
  144. Source::Source(const Source &s)
  145. : love::audio::Source(s.type)
  146. , pool(s.pool)
  147. , valid(false)
  148. , staticBuffer(s.staticBuffer)
  149. , pitch(s.pitch)
  150. , volume(s.volume)
  151. , relative(s.relative)
  152. , looping(s.looping)
  153. , minVolume(s.minVolume)
  154. , maxVolume(s.maxVolume)
  155. , referenceDistance(s.referenceDistance)
  156. , rolloffFactor(s.rolloffFactor)
  157. , maxDistance(s.maxDistance)
  158. , cone(s.cone)
  159. , offsetSamples(0)
  160. , offsetSeconds(0)
  161. , sampleRate(s.sampleRate)
  162. , channels(s.channels)
  163. , bitDepth(s.bitDepth)
  164. , decoder(nullptr)
  165. , toLoop(0)
  166. , unusedBufferTop(s.type == TYPE_STREAM ? MAX_BUFFERS - 1 : -1)
  167. {
  168. if (type == TYPE_STREAM)
  169. {
  170. if (s.decoder.get())
  171. decoder.set(s.decoder->clone(), Acquire::NORETAIN);
  172. }
  173. if (type != TYPE_STATIC)
  174. {
  175. alGenBuffers(MAX_BUFFERS, streamBuffers);
  176. for (unsigned int i = 0; i < MAX_BUFFERS; i++)
  177. unusedBuffers[i] = streamBuffers[i];
  178. }
  179. setFloatv(position, s.position);
  180. setFloatv(velocity, s.velocity);
  181. setFloatv(direction, s.direction);
  182. }
  183. Source::~Source()
  184. {
  185. if (valid)
  186. pool->stop(this);
  187. if (type != TYPE_STATIC)
  188. alDeleteBuffers(MAX_BUFFERS, streamBuffers);
  189. }
  190. love::audio::Source *Source::clone()
  191. {
  192. return new Source(*this);
  193. }
  194. bool Source::play()
  195. {
  196. valid = pool->play(this);
  197. return valid;
  198. }
  199. void Source::stop()
  200. {
  201. if (valid)
  202. pool->stop(this);
  203. }
  204. void Source::pause()
  205. {
  206. pool->pause(this);
  207. }
  208. bool Source::isPlaying() const
  209. {
  210. if (!valid)
  211. return false;
  212. ALenum state;
  213. alGetSourcei(source, AL_SOURCE_STATE, &state);
  214. return state == AL_PLAYING;
  215. }
  216. bool Source::isFinished() const
  217. {
  218. if (!valid)
  219. return false;
  220. if (type == TYPE_STREAM && (isLooping() || !decoder->isFinished()))
  221. return false;
  222. ALenum state;
  223. alGetSourcei(source, AL_SOURCE_STATE, &state);
  224. return state == AL_STOPPED;
  225. }
  226. bool Source::update()
  227. {
  228. if (!valid)
  229. return false;
  230. switch (type)
  231. {
  232. case TYPE_STATIC:
  233. {
  234. // Looping mode could have changed.
  235. // FIXME: make looping mode change atomically so this is not needed
  236. alSourcei(source, AL_LOOPING, isLooping() ? AL_TRUE : AL_FALSE);
  237. return !isFinished();
  238. }
  239. case TYPE_STREAM:
  240. if (!isFinished())
  241. {
  242. ALint processed;
  243. ALuint buffers[MAX_BUFFERS];
  244. float curOffsetSamples, curOffsetSecs, newOffsetSamples, newOffsetSecs;
  245. int freq = decoder->getSampleRate();
  246. alGetSourcef(source, AL_SAMPLE_OFFSET, &curOffsetSamples);
  247. curOffsetSecs = curOffsetSamples / freq;
  248. alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
  249. alSourceUnqueueBuffers(source, processed, buffers);
  250. alGetSourcef(source, AL_SAMPLE_OFFSET, &newOffsetSamples);
  251. newOffsetSecs = newOffsetSamples / freq;
  252. offsetSamples += (curOffsetSamples - newOffsetSamples);
  253. offsetSeconds += (curOffsetSecs - newOffsetSecs);
  254. for (unsigned int i = 0; i < (unsigned int)processed; i++)
  255. unusedBufferPush(buffers[i]);
  256. while (unusedBufferPeek() != AL_NONE)
  257. {
  258. if(streamAtomic(unusedBufferPeek(), decoder.get()) > 0)
  259. alSourceQueueBuffers(source, 1, unusedBufferPop());
  260. else
  261. break;
  262. }
  263. return true;
  264. }
  265. return false;
  266. case TYPE_QUEUE:
  267. {
  268. ALint processed;
  269. ALuint buffers[MAX_BUFFERS];
  270. alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
  271. alSourceUnqueueBuffers(source, processed, buffers);
  272. for (unsigned int i = 0; i < (unsigned int)processed; i++)
  273. {
  274. ALint size;
  275. alGetBufferi(buffers[i], AL_SIZE, &size);
  276. bufferedBytes -= size;
  277. unusedBufferPush(buffers[i]);
  278. }
  279. return !isFinished();
  280. }
  281. case TYPE_MAX_ENUM:
  282. break;
  283. }
  284. return false;
  285. }
  286. void Source::setPitch(float pitch)
  287. {
  288. if (valid)
  289. alSourcef(source, AL_PITCH, pitch);
  290. this->pitch = pitch;
  291. }
  292. float Source::getPitch() const
  293. {
  294. if (valid)
  295. {
  296. ALfloat f;
  297. alGetSourcef(source, AL_PITCH, &f);
  298. return f;
  299. }
  300. // In case the Source isn't playing.
  301. return pitch;
  302. }
  303. void Source::setVolume(float volume)
  304. {
  305. if (valid)
  306. alSourcef(source, AL_GAIN, volume);
  307. this->volume = volume;
  308. }
  309. float Source::getVolume() const
  310. {
  311. if (valid)
  312. {
  313. ALfloat f;
  314. alGetSourcef(source, AL_GAIN, &f);
  315. return f;
  316. }
  317. // In case the Source isn't playing.
  318. return volume;
  319. }
  320. void Source::seekAtomic(float offset, void *unit)
  321. {
  322. float offsetSamples, offsetSeconds;
  323. switch (*((Source::Unit *) unit))
  324. {
  325. case Source::UNIT_SAMPLES:
  326. offsetSamples = offset;
  327. offsetSeconds = offset / sampleRate;
  328. break;
  329. case Source::UNIT_SECONDS:
  330. default:
  331. offsetSeconds = offset;
  332. offsetSamples = offset * sampleRate;
  333. break;
  334. }
  335. bool wasPlaying = isPlaying();
  336. switch (type)
  337. {
  338. case TYPE_STATIC:
  339. if (valid)
  340. {
  341. alSourcef(source, AL_SAMPLE_OFFSET, offsetSamples);
  342. offsetSamples = offsetSeconds = 0;
  343. }
  344. break;
  345. case TYPE_STREAM:
  346. {
  347. // To drain all buffers
  348. if (valid)
  349. stop();
  350. decoder->seek(offsetSeconds);
  351. if (wasPlaying)
  352. play();
  353. break;
  354. }
  355. case TYPE_QUEUE:
  356. if (valid)
  357. {
  358. alSourcef(source, AL_SAMPLE_OFFSET, offsetSamples);
  359. offsetSamples = offsetSeconds = 0;
  360. }
  361. else
  362. {
  363. ALint size;
  364. ALuint buffer = unusedBufferPeek();
  365. //emulate AL behavior, discarding buffer once playback head is past one
  366. while (buffer != AL_NONE)
  367. {
  368. alGetBufferi(buffer, AL_SIZE, &size);
  369. if (offsetSamples < size / (bitDepth / 8 * channels))
  370. break;
  371. unusedBufferPop();
  372. buffer = unusedBufferPeek();
  373. bufferedBytes -= size;
  374. offsetSamples -= size / (bitDepth / 8 * channels);
  375. }
  376. if (buffer == AL_NONE)
  377. offsetSamples = 0;
  378. offsetSeconds = offsetSamples / sampleRate;
  379. }
  380. break;
  381. case TYPE_MAX_ENUM:
  382. break;
  383. }
  384. if (wasPlaying && (alGetError() == AL_INVALID_VALUE || (type == TYPE_STREAM && !isPlaying())))
  385. {
  386. stop();
  387. if (isLooping())
  388. play();
  389. return;
  390. }
  391. this->offsetSamples = offsetSamples;
  392. this->offsetSeconds = offsetSeconds;
  393. }
  394. void Source::seek(float offset, Source::Unit unit)
  395. {
  396. return pool->seek(this, offset, &unit);
  397. }
  398. float Source::tellAtomic(void *unit) const
  399. {
  400. float offset = 0.0f;
  401. switch (*((Source::Unit *) unit))
  402. {
  403. case Source::UNIT_SAMPLES:
  404. if (valid)
  405. alGetSourcef(source, AL_SAMPLE_OFFSET, &offset);
  406. offset += offsetSamples;
  407. break;
  408. case Source::UNIT_SECONDS:
  409. default:
  410. if (valid)
  411. alGetSourcef(source, AL_SEC_OFFSET, &offset);
  412. offset += offsetSeconds;
  413. break;
  414. }
  415. return offset;
  416. }
  417. float Source::tell(Source::Unit unit)
  418. {
  419. return pool->tell(this, &unit);
  420. }
  421. double Source::getDurationAtomic(void *vunit)
  422. {
  423. Unit unit = *(Unit *) vunit;
  424. switch (type)
  425. {
  426. case TYPE_STATIC:
  427. {
  428. ALsizei size = staticBuffer->getSize();
  429. ALsizei samples = (size / channels) / (bitDepth / 8);
  430. if (unit == UNIT_SAMPLES)
  431. return (double) samples;
  432. else
  433. return (double) samples / (double) sampleRate;
  434. }
  435. case TYPE_STREAM:
  436. {
  437. double seconds = decoder->getDuration();
  438. if (unit == UNIT_SECONDS)
  439. return seconds;
  440. else
  441. return seconds * decoder->getSampleRate();
  442. }
  443. case TYPE_QUEUE:
  444. {
  445. ALsizei samples = (bufferedBytes / channels) / (bitDepth / 8);
  446. if (unit == UNIT_SAMPLES)
  447. return (double)samples;
  448. else
  449. return (double)samples / (double)sampleRate;
  450. }
  451. case TYPE_MAX_ENUM:
  452. return 0.0;
  453. }
  454. return 0.0;
  455. }
  456. double Source::getDuration(Unit unit)
  457. {
  458. return pool->getDuration(this, &unit);
  459. }
  460. void Source::setPosition(float *v)
  461. {
  462. if (channels > 1)
  463. throw SpatialSupportException();
  464. if (valid)
  465. alSourcefv(source, AL_POSITION, v);
  466. setFloatv(position, v);
  467. }
  468. void Source::getPosition(float *v) const
  469. {
  470. if (channels > 1)
  471. throw SpatialSupportException();
  472. if (valid)
  473. alGetSourcefv(source, AL_POSITION, v);
  474. else
  475. setFloatv(v, position);
  476. }
  477. void Source::setVelocity(float *v)
  478. {
  479. if (channels > 1)
  480. throw SpatialSupportException();
  481. if (valid)
  482. alSourcefv(source, AL_VELOCITY, v);
  483. setFloatv(velocity, v);
  484. }
  485. void Source::getVelocity(float *v) const
  486. {
  487. if (channels > 1)
  488. throw SpatialSupportException();
  489. if (valid)
  490. alGetSourcefv(source, AL_VELOCITY, v);
  491. else
  492. setFloatv(v, velocity);
  493. }
  494. void Source::setDirection(float *v)
  495. {
  496. if (channels > 1)
  497. throw SpatialSupportException();
  498. if (valid)
  499. alSourcefv(source, AL_DIRECTION, v);
  500. else
  501. setFloatv(direction, v);
  502. }
  503. void Source::getDirection(float *v) const
  504. {
  505. if (channels > 1)
  506. throw SpatialSupportException();
  507. if (valid)
  508. alGetSourcefv(source, AL_DIRECTION, v);
  509. else
  510. setFloatv(v, direction);
  511. }
  512. void Source::setCone(float innerAngle, float outerAngle, float outerVolume)
  513. {
  514. if (channels > 1)
  515. throw SpatialSupportException();
  516. cone.innerAngle = (int) LOVE_TODEG(innerAngle);
  517. cone.outerAngle = (int) LOVE_TODEG(outerAngle);
  518. cone.outerVolume = outerVolume;
  519. if (valid)
  520. {
  521. alSourcei(source, AL_CONE_INNER_ANGLE, cone.innerAngle);
  522. alSourcei(source, AL_CONE_OUTER_ANGLE, cone.outerAngle);
  523. alSourcef(source, AL_CONE_OUTER_GAIN, cone.outerVolume);
  524. }
  525. }
  526. void Source::getCone(float &innerAngle, float &outerAngle, float &outerVolume) const
  527. {
  528. if (channels > 1)
  529. throw SpatialSupportException();
  530. innerAngle = LOVE_TORAD(cone.innerAngle);
  531. outerAngle = LOVE_TORAD(cone.outerAngle);
  532. outerVolume = cone.outerVolume;
  533. }
  534. void Source::setRelative(bool enable)
  535. {
  536. if (channels > 1)
  537. throw SpatialSupportException();
  538. if (valid)
  539. alSourcei(source, AL_SOURCE_RELATIVE, enable ? AL_TRUE : AL_FALSE);
  540. relative = enable;
  541. }
  542. bool Source::isRelative() const
  543. {
  544. if (channels > 1)
  545. throw SpatialSupportException();
  546. return relative;
  547. }
  548. void Source::setLooping(bool enable)
  549. {
  550. if (type == TYPE_QUEUE)
  551. throw QueueLoopingException();
  552. if (valid && type == TYPE_STATIC)
  553. alSourcei(source, AL_LOOPING, enable ? AL_TRUE : AL_FALSE);
  554. looping = enable;
  555. }
  556. bool Source::isLooping() const
  557. {
  558. return looping;
  559. }
  560. bool Source::queue(void *data, size_t length, int dataSampleRate, int dataBitDepth, int dataChannels)
  561. {
  562. if (type != TYPE_QUEUE)
  563. throw QueueTypeMismatchException();
  564. if (dataSampleRate != sampleRate || dataBitDepth != bitDepth || dataChannels != channels )
  565. throw QueueFormatMismatchException();
  566. if (length % (bitDepth / 8 * channels) != 0)
  567. throw QueueMalformedLengthException(bitDepth / 8 * channels);
  568. if (length == 0)
  569. return true;
  570. return pool->queue(this, data, (ALsizei)length);
  571. }
  572. bool Source::queueAtomic(void *data, ALsizei length)
  573. {
  574. if (valid)
  575. {
  576. ALuint buffer = unusedBufferPeek();
  577. if (buffer == AL_NONE)
  578. return false;
  579. alBufferData(buffer, getFormat(channels, bitDepth), data, length, sampleRate);
  580. alSourceQueueBuffers(source, 1, &buffer);
  581. unusedBufferPop();
  582. }
  583. else
  584. {
  585. ALuint buffer = unusedBufferPeekNext();
  586. if (buffer == AL_NONE)
  587. return false;
  588. //stack acts as queue while stopped
  589. alBufferData(buffer, getFormat(channels, bitDepth), data, length, sampleRate);
  590. unusedBufferQueue(buffer);
  591. }
  592. bufferedBytes += length;
  593. return true;
  594. }
  595. int Source::getFreeBufferCount() const
  596. {
  597. switch (type) //why not :^)
  598. {
  599. case TYPE_STATIC:
  600. return 0;
  601. case TYPE_STREAM:
  602. return unusedBufferTop + 1;
  603. case TYPE_QUEUE:
  604. return valid ? unusedBufferTop + 1 : (int)MAX_BUFFERS - unusedBufferTop - 1;
  605. case TYPE_MAX_ENUM:
  606. return 0;
  607. }
  608. return 0;
  609. }
  610. void Source::prepareAtomic()
  611. {
  612. // This Source may now be associated with an OpenAL source that still has
  613. // the properties of another love Source. Let's reset it to the settings
  614. // of the new one.
  615. reset();
  616. switch (type)
  617. {
  618. case TYPE_STATIC:
  619. alSourcei(source, AL_BUFFER, staticBuffer->getBuffer());
  620. break;
  621. case TYPE_STREAM:
  622. while (unusedBufferPeek() != AL_NONE)
  623. {
  624. if(streamAtomic(unusedBufferPeek(), decoder.get()) == 0)
  625. break;
  626. alSourceQueueBuffers(source, 1, unusedBufferPop());
  627. if (decoder->isFinished())
  628. break;
  629. }
  630. break;
  631. case TYPE_QUEUE:
  632. {
  633. int top = unusedBufferTop;
  634. //when queue source is stopped, loaded buffers are stored in unused buffers stack
  635. while (unusedBufferPeek() != AL_NONE)
  636. alSourceQueueBuffers(source, 1, unusedBufferPop());
  637. //construct a stack of unused buffers (beyond the end of stack)
  638. for (unsigned int i = top + 1; i < MAX_BUFFERS; i++)
  639. unusedBufferPush(unusedBuffers[i]);
  640. break;
  641. }
  642. case TYPE_MAX_ENUM:
  643. break;
  644. }
  645. }
  646. void Source::teardownAtomic()
  647. {
  648. switch (type)
  649. {
  650. case TYPE_STATIC:
  651. break;
  652. case TYPE_STREAM:
  653. {
  654. ALint queued;
  655. ALuint buffer;
  656. decoder->seek(0);
  657. // drain buffers
  658. //since we only unqueue 1 buffer, it's OK to use singular variable pointer instead of array
  659. alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
  660. for (unsigned int i = 0; i < (unsigned int)queued; i++)
  661. alSourceUnqueueBuffers(source, 1, &buffer);
  662. // generate unused buffers list
  663. for (unsigned int i = 0; i < MAX_BUFFERS; i++)
  664. unusedBuffers[i] = streamBuffers[i];
  665. unusedBufferTop = MAX_BUFFERS - 1;
  666. break;
  667. }
  668. case TYPE_QUEUE:
  669. {
  670. ALint queued;
  671. ALuint buffer;
  672. alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
  673. for (unsigned int i = (unsigned int)queued; i > 0; i--)
  674. alSourceUnqueueBuffers(source, 1, &buffer);
  675. // generate unused buffers list
  676. for (unsigned int i = 0; i < MAX_BUFFERS; i++)
  677. unusedBuffers[i] = streamBuffers[i];
  678. unusedBufferTop = -1;
  679. break;
  680. }
  681. case TYPE_MAX_ENUM:
  682. break;
  683. }
  684. alSourcei(source, AL_BUFFER, AL_NONE);
  685. toLoop = 0;
  686. valid = false;
  687. offsetSamples = offsetSeconds = 0;
  688. }
  689. bool Source::playAtomic(ALuint source)
  690. {
  691. this->source = source;
  692. prepareAtomic();
  693. // Clear errors.
  694. alGetError();
  695. alSourcePlay(source);
  696. bool success = alGetError() == AL_NO_ERROR;
  697. if (type == TYPE_STREAM)
  698. {
  699. valid = true; //isPlaying() needs source to be valid
  700. if (!isPlaying())
  701. success = false;
  702. }
  703. else if (success)
  704. {
  705. alSourcef(source, AL_SAMPLE_OFFSET, offsetSamples);
  706. success = alGetError() == AL_NO_ERROR;
  707. }
  708. if (!success)
  709. {
  710. valid = true; //stop() needs source to be valid
  711. stop();
  712. }
  713. else if (type != TYPE_STREAM)
  714. offsetSamples = offsetSeconds = 0;
  715. //this is set to success state afterwards anyway, but setting it here
  716. //to true preemptively avoids race condition with update bug
  717. valid = true;
  718. return success;
  719. }
  720. void Source::stopAtomic()
  721. {
  722. if (!valid)
  723. return;
  724. alSourceStop(source);
  725. teardownAtomic();
  726. }
  727. void Source::pauseAtomic()
  728. {
  729. if (valid)
  730. alSourcePause(source);
  731. }
  732. void Source::resumeAtomic()
  733. {
  734. if (valid && !isPlaying())
  735. {
  736. alSourcePlay(source);
  737. if (alGetError() == AL_INVALID_VALUE || (type == TYPE_STREAM && unusedBufferTop == MAX_BUFFERS - 1))
  738. stop();
  739. }
  740. }
  741. bool Source::playAtomic(const std::vector<love::audio::Source*> &sources, const std::vector<ALuint> &ids, const std::vector<char> &wasPlaying)
  742. {
  743. if (sources.size() == 0)
  744. return true;
  745. std::vector<ALuint> toPlay;
  746. toPlay.reserve(sources.size());
  747. for (size_t i = 0; i < sources.size(); i++)
  748. {
  749. if (wasPlaying[i])
  750. continue;
  751. Source *source = (Source*) sources[i];
  752. source->source = ids[i];
  753. source->prepareAtomic();
  754. toPlay.push_back(ids[i]);
  755. }
  756. alGetError();
  757. alSourcePlayv((ALsizei) toPlay.size(), &toPlay[0]);
  758. bool success = alGetError() == AL_NO_ERROR;
  759. for (auto &_source : sources)
  760. {
  761. Source *source = (Source*) _source;
  762. source->valid = source->valid || success;
  763. if (success && source->type != TYPE_STREAM)
  764. source->offsetSamples = source->offsetSeconds = 0;
  765. }
  766. return success;
  767. }
  768. void Source::stopAtomic(const std::vector<love::audio::Source*> &sources)
  769. {
  770. if (sources.size() == 0)
  771. return;
  772. std::vector<ALuint> sourceIds;
  773. sourceIds.reserve(sources.size());
  774. for (auto &_source : sources)
  775. {
  776. Source *source = (Source*) _source;
  777. if (source->valid)
  778. sourceIds.push_back(source->source);
  779. }
  780. alSourceStopv((ALsizei) sources.size(), &sourceIds[0]);
  781. for (auto &_source : sources)
  782. {
  783. Source *source = (Source*) _source;
  784. if (source->valid)
  785. source->teardownAtomic();
  786. }
  787. }
  788. void Source::pauseAtomic(const std::vector<love::audio::Source*> &sources)
  789. {
  790. if (sources.size() == 0)
  791. return;
  792. std::vector<ALuint> sourceIds;
  793. sourceIds.reserve(sources.size());
  794. for (auto &_source : sources)
  795. {
  796. Source *source = (Source*) _source;
  797. if (source->valid)
  798. sourceIds.push_back(source->source);
  799. }
  800. alSourcePausev((ALsizei) sources.size(), &sourceIds[0]);
  801. }
  802. void Source::reset()
  803. {
  804. alSourcei(source, AL_BUFFER, AL_NONE);
  805. alSourcefv(source, AL_POSITION, position);
  806. alSourcefv(source, AL_VELOCITY, velocity);
  807. alSourcefv(source, AL_DIRECTION, direction);
  808. alSourcef(source, AL_PITCH, pitch);
  809. alSourcef(source, AL_GAIN, volume);
  810. alSourcef(source, AL_MIN_GAIN, minVolume);
  811. alSourcef(source, AL_MAX_GAIN, maxVolume);
  812. alSourcef(source, AL_REFERENCE_DISTANCE, referenceDistance);
  813. alSourcef(source, AL_ROLLOFF_FACTOR, rolloffFactor);
  814. alSourcef(source, AL_MAX_DISTANCE, maxDistance);
  815. alSourcei(source, AL_LOOPING, (type == TYPE_STATIC) && isLooping() ? AL_TRUE : AL_FALSE);
  816. alSourcei(source, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE);
  817. alSourcei(source, AL_CONE_INNER_ANGLE, cone.innerAngle);
  818. alSourcei(source, AL_CONE_OUTER_ANGLE, cone.outerAngle);
  819. alSourcef(source, AL_CONE_OUTER_GAIN, cone.outerVolume);
  820. }
  821. void Source::setFloatv(float *dst, const float *src) const
  822. {
  823. dst[0] = src[0];
  824. dst[1] = src[1];
  825. dst[2] = src[2];
  826. }
  827. ALenum Source::getFormat(int channels, int bitDepth) const
  828. {
  829. if (channels == 1 && bitDepth == 8)
  830. return AL_FORMAT_MONO8;
  831. else if (channels == 1 && bitDepth == 16)
  832. return AL_FORMAT_MONO16;
  833. else if (channels == 2 && bitDepth == 8)
  834. return AL_FORMAT_STEREO8;
  835. else if (channels == 2 && bitDepth == 16)
  836. return AL_FORMAT_STEREO16;
  837. #ifdef AL_EXT_MCFORMATS
  838. if (alIsExtensionPresent("AL_EXT_MCFORMATS"))
  839. {
  840. if (channels == 6 && bitDepth == 8)
  841. return AL_FORMAT_51CHN8;
  842. else if (channels == 6 && bitDepth == 16)
  843. return AL_FORMAT_51CHN16;
  844. else if (channels == 8 && bitDepth == 8)
  845. return AL_FORMAT_71CHN8;
  846. else if (channels == 8 && bitDepth == 16)
  847. return AL_FORMAT_71CHN16;
  848. }
  849. #endif
  850. return 0;
  851. }
  852. ALuint Source::unusedBufferPeek()
  853. {
  854. return (unusedBufferTop < 0) ? AL_NONE : unusedBuffers[unusedBufferTop];
  855. }
  856. ALuint Source::unusedBufferPeekNext()
  857. {
  858. return (unusedBufferTop >= (int)MAX_BUFFERS - 1) ? AL_NONE : unusedBuffers[unusedBufferTop + 1];
  859. }
  860. ALuint *Source::unusedBufferPop()
  861. {
  862. return &unusedBuffers[unusedBufferTop--];
  863. }
  864. void Source::unusedBufferPush(ALuint buffer)
  865. {
  866. unusedBuffers[++unusedBufferTop] = buffer;
  867. }
  868. void Source::unusedBufferQueue(ALuint buffer)
  869. {
  870. for (unsigned int i = ++unusedBufferTop; i > 0; i--)
  871. unusedBuffers[i] = unusedBuffers[i - 1];
  872. unusedBuffers[0] = buffer;
  873. }
  874. int Source::streamAtomic(ALuint buffer, love::sound::Decoder *d)
  875. {
  876. // Get more sound data.
  877. int decoded = std::max(d->decode(), 0);
  878. // OpenAL implementations are allowed to ignore 0-size alBufferData calls.
  879. if (decoded > 0)
  880. {
  881. int fmt = getFormat(d->getChannels(), d->getBitDepth());
  882. if (fmt != 0)
  883. alBufferData(buffer, fmt, d->getBuffer(), decoded, d->getSampleRate());
  884. else
  885. decoded = 0;
  886. }
  887. if (decoder->isFinished() && isLooping())
  888. {
  889. int queued, processed;
  890. alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
  891. alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
  892. if (queued > processed)
  893. toLoop = queued-processed;
  894. else
  895. toLoop = MAX_BUFFERS-processed;
  896. d->rewind();
  897. }
  898. if (toLoop > 0)
  899. {
  900. if (--toLoop == 0)
  901. {
  902. offsetSamples = 0;
  903. offsetSeconds = 0;
  904. }
  905. }
  906. return decoded;
  907. }
  908. void Source::setMinVolume(float volume)
  909. {
  910. if (valid)
  911. alSourcef(source, AL_MIN_GAIN, volume);
  912. minVolume = volume;
  913. }
  914. float Source::getMinVolume() const
  915. {
  916. if (valid)
  917. {
  918. ALfloat f;
  919. alGetSourcef(source, AL_MIN_GAIN, &f);
  920. return f;
  921. }
  922. // In case the Source isn't playing.
  923. return this->minVolume;
  924. }
  925. void Source::setMaxVolume(float volume)
  926. {
  927. if (valid)
  928. alSourcef(source, AL_MAX_GAIN, volume);
  929. maxVolume = volume;
  930. }
  931. float Source::getMaxVolume() const
  932. {
  933. if (valid)
  934. {
  935. ALfloat f;
  936. alGetSourcef(source, AL_MAX_GAIN, &f);
  937. return f;
  938. }
  939. // In case the Source isn't playing.
  940. return maxVolume;
  941. }
  942. void Source::setReferenceDistance(float distance)
  943. {
  944. if (channels > 1)
  945. throw SpatialSupportException();
  946. if (valid)
  947. alSourcef(source, AL_REFERENCE_DISTANCE, distance);
  948. referenceDistance = distance;
  949. }
  950. float Source::getReferenceDistance() const
  951. {
  952. if (channels > 1)
  953. throw SpatialSupportException();
  954. if (valid)
  955. {
  956. ALfloat f;
  957. alGetSourcef(source, AL_REFERENCE_DISTANCE, &f);
  958. return f;
  959. }
  960. // In case the Source isn't playing.
  961. return referenceDistance;
  962. }
  963. void Source::setRolloffFactor(float factor)
  964. {
  965. if (channels > 1)
  966. throw SpatialSupportException();
  967. if (valid)
  968. alSourcef(source, AL_ROLLOFF_FACTOR, factor);
  969. rolloffFactor = factor;
  970. }
  971. float Source::getRolloffFactor() const
  972. {
  973. if (channels > 1)
  974. throw SpatialSupportException();
  975. if (valid)
  976. {
  977. ALfloat f;
  978. alGetSourcef(source, AL_ROLLOFF_FACTOR, &f);
  979. return f;
  980. }
  981. // In case the Source isn't playing.
  982. return rolloffFactor;
  983. }
  984. void Source::setMaxDistance(float distance)
  985. {
  986. if (channels > 1)
  987. throw SpatialSupportException();
  988. distance = std::min(distance, MAX_ATTENUATION_DISTANCE);
  989. if (valid)
  990. alSourcef(source, AL_MAX_DISTANCE, distance);
  991. maxDistance = distance;
  992. }
  993. float Source::getMaxDistance() const
  994. {
  995. if (channels > 1)
  996. throw SpatialSupportException();
  997. if (valid)
  998. {
  999. ALfloat f;
  1000. alGetSourcef(source, AL_MAX_DISTANCE, &f);
  1001. return f;
  1002. }
  1003. // In case the Source isn't playing.
  1004. return maxDistance;
  1005. }
  1006. int Source::getChannels() const
  1007. {
  1008. return channels;
  1009. }
  1010. } // openal
  1011. } // audio
  1012. } // love