Source.cpp 26 KB

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