CUGL 1.3
Cornell University Game Library
CUAudioChannels.h
1 //
2 // CUAudioEngine.h
3 // Cornell University Game Library (CUGL)
4 //
5 // This module is a singleton providing a legacy (2000-era) audio engine. Like
6 // all engines of this era, it provides a flat channel structure for playing
7 // sounds as well as a single channel for background music. This is much
8 // more primitive than modern sound engines, with the advantage that it is
9 // simpler to use.
10 //
11 // Because this is a singleton, there are no publicly accessible constructors
12 // or intializers. Use the static methods instead. This singleton should be
13 // used instead of AudioManager, and not used at the same time as it.
14 //
15 // This engine has been refactored to take advantage of our more modern audio
16 // graph backend. However, we have kept the legacy API for backwards
17 // compatibility with older versions of CUGL. The mixer graph behind the
18 // scenes is a little complicated because we make heavy use of AudioFader.
19 // This is to prevent the audible "clicking" that comes when sound is stopped
20 // or paused, and was a major problem with OpenAL.
21 //
22 // CUGL MIT License:
23 //
24 // This software is provided 'as-is', without any express or implied
25 // warranty. In no event will the authors be held liable for any damages
26 // arising from the use of this software.
27 //
28 // Permission is granted to anyone to use this software for any purpose,
29 // including commercial applications, and to alter it and redistribute it
30 // freely, subject to the following restrictions:
31 //
32 // 1. The origin of this software must not be misrepresented; you must not
33 // claim that you wrote the original software. If you use this software
34 // in a product, an acknowledgment in the product documentation would be
35 // appreciated but is not required.
36 //
37 // 2. Altered source versions must be plainly marked as such, and must not
38 // be misrepresented as being the original software.
39 //
40 // 3. This notice may not be removed or altered from any source distribution.
41 //
42 // Author: Walker White
43 // Version: 12/20/18
44 //
45 #ifndef __CU_AUDIO_CHANNELS_H__
46 #define __CU_AUDIO_CHANNELS_H__
47 #include <cugl/audio/CUAudioManager.h>
48 #include <cugl/audio/CUSound.h>
49 #include <cugl/util/CUTimestamp.h>
50 #include <unordered_map>
51 #include <functional>
52 #include <vector>
53 #include <deque>
54 #include <queue>
55 
57 #define DEFAULT_FADE 0.015
58 
59 namespace cugl {
61  namespace audio {
62  class AudioOutput;
63  class AudioScheduler;
64  class AudioMixer;
65  class AudioFader;
66  class AudioPanner;
67  }
115 #pragma mark Sound State
116 public:
120  enum class State {
122  INACTIVE,
124  PLAYING,
126  PAUSED
127  };
128 
129 private:
131  static AudioChannels* _gEngine;
132 
134  unsigned int _capacity;
136  std::unordered_map<std::string,std::shared_ptr<audio::AudioFader>> _effects;
138  std::deque<std::string> _equeue;
140  //std::deque<std::string,> _equeue;
141 
143  std::shared_ptr<audio::AudioOutput> _output;
145  std::shared_ptr<audio::AudioMixer> _mixer;
147  std::vector<std::shared_ptr<audio::AudioScheduler>> _channel;
149  std::vector<std::shared_ptr<audio::AudioFader>> _chfader;
150 
152  std::deque<std::shared_ptr<audio::AudioFader>> _fadePool;
154  std::deque<std::shared_ptr<audio::AudioPanner>> _pan1Pool;
156  std::deque<std::shared_ptr<audio::AudioPanner>> _pan2Pool;
157 
169  std::function<void(Sound* asset, bool status)> _musicCB;
170 
182  std::function<void(const std::string& key , bool status)> _soundCB;
183 
184 #pragma mark -
185 #pragma mark Constructors (Private)
186 
191  AudioChannels();
192 
199  ~AudioChannels() { dispose(); }
200 
210  bool init();
211 
223  bool init(Uint32 slots);
224 
231  void dispose();
232 
233 
234 #pragma mark -
235 #pragma mark Internal Helpers
236 
244  void removeKey(std::string key);
245 
258  std::shared_ptr<audio::AudioFader> wrapInstance(const std::shared_ptr<Sound>& asset);
259 
272  std::shared_ptr<Sound> accessInstance(const std::shared_ptr<audio::AudioNode>& node) const;
273 
286  std::shared_ptr<Sound> disposeInstance(const std::shared_ptr<audio::AudioNode>& node);
287 
299  void gcMusic(const std::shared_ptr<audio::AudioNode>& sound, bool status);
300 
314  void gcEffect(const std::shared_ptr<audio::AudioNode>& sound, bool status);
315 
316 #pragma mark -
317 #pragma mark Static Accessors
318 public:
327  static AudioChannels* get() { return _gEngine; }
328 
357  static void start(Uint32 slots);
358 
388  static void start(Uint32 channels, Uint32 buffer);
389 
397  static void stop();
398 
399 
400 #pragma mark -
401 #pragma mark Music Playback
402 
426  void playMusic(const std::shared_ptr<Sound>& music, bool loop=false,
427  float volume=-1.0f, float fade=0.0f);
428 
436  const Sound* currentMusic() const;
437 
443  State getMusicState() const;
444 
452  bool isMusicLoop() const;
453 
465  void setMusicLoop(bool loop);
466 
475  float getMusicVolume() const;
476 
485  void setMusicVolume(float volume);
486 
501  float getMusicPan() const;
502 
517  void setMusicPan(float pan);
518 
531  float getMusicDuration() const;
532 
548  float getMusicElapsed() const;
549 
566  float getMusicRemaining() const;
567 
584  void setMusicElapsed(float time);
585 
603  void setMusicRemaining(float time);
604 
618  void stopMusic(float fade=DEFAULT_FADE);
619 
633  void pauseMusic(float fade=DEFAULT_FADE);
634 
640  void resumeMusic();
641 
652  void setMusicListener(std::function<void(Sound*,bool)> callback) {
653  _musicCB = callback;
654  }
655 
666  std::function<void(Sound*,bool)> getMusicListener() const {
667  return _musicCB;
668  }
669 
670 #pragma mark -
671 #pragma mark Music Queue Management
672 
696  void queueMusic(const std::shared_ptr<Sound>& music, bool loop=false,
697  float volume=-1.0f, float fade=0.0f);
698 
704  const std::vector<Sound*> getMusicQueue() const;
705 
711  size_t getMusicPending() const;
712 
728  float getOverlap() const;
729 
745  void setOverlap(double time);
746 
763  void advanceMusicQueue(float fade=DEFAULT_FADE,unsigned int steps=0);
764 
771  void clearMusicQueue();
772 
773 
774 #pragma mark -
775 #pragma mark Sound Effect Management
776 
800  bool playEffect(const std::string& key, const std::shared_ptr<Sound>& sound,
801  bool loop=false, float volume=-1.0f, bool force=false);
802 
827  bool playEffect(const char* key, const std::shared_ptr<Sound>& sound,
828  bool loop=false, float volume=1.0f, bool force=false) {
829  return playEffect(std::string(key),sound,loop,volume,force);
830  }
831 
842  size_t getAvailableChannels() const {
843  return (size_t)_capacity-_effects.size();
844  }
845 
856  State getEffectState(const std::string& key) const;
857 
868  State getEffectState(const char* key) const {
869  return getEffectState(std::string(key));
870  }
871 
879  bool isActiveEffect(const std::string& key) const {
880  return _effects.find(key) != _effects.end();
881  }
882 
890  bool isActiveEffect(const char* key) const {
891  return isActiveEffect(std::string(key));
892  }
893 
904  const Sound* currentEffect(const std::string& key) const;
905 
916  const Sound* currentEffect(const char* key) const {
917  return currentEffect(std::string(key));
918  }
919 
929  bool isEffectLoop(const std::string& key) const;
930 
940  bool isEffectLoop(const char* key) const {
941  return isEffectLoop(std::string(key));
942  }
943 
952  void setEffectLoop(const std::string& key, bool loop);
953 
962  void setEffectLoop(const char* key, bool loop) {
963  setEffectLoop(std::string(key),loop);
964  }
965 
976  float getEffectVolume(const std::string& key) const;
977 
988  float getEffectVolume(const char* key) const {
989  return getEffectVolume(std::string(key));
990  }
991 
1002  void setEffectVolume(const std::string& key, float volume);
1003 
1014  void setEffectVolume(const char* key, float volume) {
1015  setEffectVolume(std::string(key),volume);
1016  }
1017 
1036  float getEffectPan(const std::string& key) const;
1037 
1056  float getEffectPan(const char* key) const {
1057  return getEffectPan(std::string(key));
1058  }
1059 
1077  void setEffectPan(const std::string& key, float pan);
1078 
1096  void setEffectPan(const char* key, float pan) {
1097  setEffectPan(std::string(key),pan);
1098  }
1099 
1112  float getEffectDuration(const std::string& key) const;
1113 
1126  float getEffectDuration(const char* key) const {
1127  return getEffectDuration(std::string(key));
1128  }
1129 
1144  float getEffectElapsed(const std::string& key) const;
1145 
1160  float getEffectElapsed(const char* key) const {
1161  return getEffectElapsed(std::string(key));
1162  }
1163 
1177  void setEffectElapsed(const std::string& key, float time);
1178 
1192  void setEffectElapsed(const char* key, float time) {
1193  setEffectElapsed(std::string(key),time);
1194  }
1195 
1210  float getEffectRemaining(const std::string& key) const;
1211 
1226  float getEffectRemaining(const char* key) const {
1227  return getEffectRemaining(std::string(key));
1228  }
1229 
1243  void setEffectRemaining(const std::string& key, float time);
1244 
1258  void setEffectRemaining(const char* key, float time) {
1259  setEffectRemaining(std::string(key),time);
1260  }
1261 
1279  void stopEffect(const std::string& key,float fade=DEFAULT_FADE);
1280 
1298  void stopEffect(const char* key,float fade=DEFAULT_FADE) {
1299  stopEffect(std::string(key));
1300  }
1301 
1316  void pauseEffect(const std::string& key,float fade=DEFAULT_FADE);
1317 
1332  void pauseEffect(const char* key,float fade=DEFAULT_FADE) {
1333  pauseEffect(std::string(key));
1334  }
1335 
1343  void resumeEffect(std::string key);
1344 
1352  void resumeEffect(const char* key) {
1353  resumeEffect(std::string(key));
1354  }
1355 
1369  void stopAllEffects(float fade=DEFAULT_FADE);
1370 
1384  void pauseAllEffects(float fade=DEFAULT_FADE);
1385 
1389  void resumeAllEffects();
1390 
1401  void setEffectListener(std::function<void(const std::string& key,bool)> callback) {
1402  _soundCB = callback;
1403  }
1404 
1415  std::function<void(const std::string& key,bool)> getEffectListener() const {
1416  return _soundCB;
1417  }
1418 
1419 #pragma mark -
1420 #pragma mark Global Management
1421 
1434  void stopAll(float fade=DEFAULT_FADE);
1435 
1450  void pauseAll(float fade=DEFAULT_FADE);
1451 
1458  void resumeAll();
1459 };
1460 
1461 }
1462 
1463 
1464 #endif /* __CU_AUDIO_CHANNELS_H__ */
cugl::AudioChannels::stop
static void stop()
cugl::AudioChannels::getEffectDuration
float getEffectDuration(const char *key) const
Definition: CUAudioChannels.h:1126
cugl::AudioChannels::pauseAll
void pauseAll(float fade=DEFAULT_FADE)
cugl::AudioChannels::stopEffect
void stopEffect(const char *key, float fade=DEFAULT_FADE)
Definition: CUAudioChannels.h:1298
cugl::AudioChannels::resumeEffect
void resumeEffect(std::string key)
cugl::AudioChannels::getMusicRemaining
float getMusicRemaining() const
cugl::AudioChannels::getEffectVolume
float getEffectVolume(const char *key) const
Definition: CUAudioChannels.h:988
cugl::AudioChannels::playEffect
bool playEffect(const char *key, const std::shared_ptr< Sound > &sound, bool loop=false, float volume=1.0f, bool force=false)
Definition: CUAudioChannels.h:827
cugl::AudioChannels::setEffectRemaining
void setEffectRemaining(const char *key, float time)
Definition: CUAudioChannels.h:1258
cugl::AudioChannels::setMusicVolume
void setMusicVolume(float volume)
cugl::AudioChannels::setEffectRemaining
void setEffectRemaining(const std::string &key, float time)
cugl::AudioChannels::getEffectVolume
float getEffectVolume(const std::string &key) const
cugl::AudioChannels::getEffectElapsed
float getEffectElapsed(const std::string &key) const
cugl::AudioChannels::resumeMusic
void resumeMusic()
cugl::AudioChannels::get
static AudioChannels * get()
Definition: CUAudioChannels.h:327
cugl::AudioChannels::setEffectLoop
void setEffectLoop(const char *key, bool loop)
Definition: CUAudioChannels.h:962
cugl::AudioChannels::State::INACTIVE
cugl::AudioChannels
Definition: CUAudioChannels.h:114
cugl::AudioChannels::getMusicQueue
const std::vector< Sound * > getMusicQueue() const
cugl::AudioChannels::getMusicPan
float getMusicPan() const
cugl::AudioChannels::currentEffect
const Sound * currentEffect(const std::string &key) const
cugl::AudioChannels::resumeAllEffects
void resumeAllEffects()
cugl::AudioChannels::getEffectListener
std::function< void(const std::string &key, bool)> getEffectListener() const
Definition: CUAudioChannels.h:1415
cugl::AudioChannels::setMusicElapsed
void setMusicElapsed(float time)
cugl::AudioChannels::getAvailableChannels
size_t getAvailableChannels() const
Definition: CUAudioChannels.h:842
cugl::AudioChannels::playMusic
void playMusic(const std::shared_ptr< Sound > &music, bool loop=false, float volume=-1.0f, float fade=0.0f)
cugl::AudioChannels::currentMusic
const Sound * currentMusic() const
cugl::AudioChannels::pauseEffect
void pauseEffect(const std::string &key, float fade=DEFAULT_FADE)
cugl::AudioChannels::isEffectLoop
bool isEffectLoop(const std::string &key) const
cugl::AudioChannels::getEffectState
State getEffectState(const std::string &key) const
cugl::AudioChannels::setEffectPan
void setEffectPan(const std::string &key, float pan)
cugl::AudioChannels::setMusicLoop
void setMusicLoop(bool loop)
cugl::AudioChannels::resumeAll
void resumeAll()
cugl::AudioChannels::getEffectRemaining
float getEffectRemaining(const std::string &key) const
cugl::AudioChannels::getMusicState
State getMusicState() const
cugl::AudioChannels::getEffectPan
float getEffectPan(const std::string &key) const
cugl::AudioChannels::getMusicDuration
float getMusicDuration() const
cugl::AudioChannels::isEffectLoop
bool isEffectLoop(const char *key) const
Definition: CUAudioChannels.h:940
cugl::AudioChannels::stopAllEffects
void stopAllEffects(float fade=DEFAULT_FADE)
cugl::Sound
Definition: CUSound.h:69
cugl::AudioChannels::setEffectLoop
void setEffectLoop(const std::string &key, bool loop)
cugl::AudioChannels::setEffectElapsed
void setEffectElapsed(const std::string &key, float time)
cugl::AudioChannels::State::PLAYING
cugl::AudioChannels::setOverlap
void setOverlap(double time)
cugl::AudioChannels::State
State
Definition: CUAudioChannels.h:120
cugl::AudioChannels::stopEffect
void stopEffect(const std::string &key, float fade=DEFAULT_FADE)
cugl::AudioChannels::setMusicRemaining
void setMusicRemaining(float time)
cugl::AudioChannels::getEffectState
State getEffectState(const char *key) const
Definition: CUAudioChannels.h:868
cugl::AudioChannels::getOverlap
float getOverlap() const
cugl::AudioChannels::stopMusic
void stopMusic(float fade=DEFAULT_FADE)
cugl::AudioChannels::pauseEffect
void pauseEffect(const char *key, float fade=DEFAULT_FADE)
Definition: CUAudioChannels.h:1332
cugl::AudioChannels::setEffectPan
void setEffectPan(const char *key, float pan)
Definition: CUAudioChannels.h:1096
cugl::AudioChannels::playEffect
bool playEffect(const std::string &key, const std::shared_ptr< Sound > &sound, bool loop=false, float volume=-1.0f, bool force=false)
cugl::AudioChannels::queueMusic
void queueMusic(const std::shared_ptr< Sound > &music, bool loop=false, float volume=-1.0f, float fade=0.0f)
cugl::AudioChannels::setEffectElapsed
void setEffectElapsed(const char *key, float time)
Definition: CUAudioChannels.h:1192
cugl::AudioChannels::getMusicVolume
float getMusicVolume() const
cugl::AudioChannels::State::PAUSED
cugl::AudioChannels::resumeEffect
void resumeEffect(const char *key)
Definition: CUAudioChannels.h:1352
cugl::AudioChannels::setMusicPan
void setMusicPan(float pan)
cugl::AudioChannels::isActiveEffect
bool isActiveEffect(const std::string &key) const
Definition: CUAudioChannels.h:879
cugl::AudioChannels::getEffectElapsed
float getEffectElapsed(const char *key) const
Definition: CUAudioChannels.h:1160
cugl::AudioChannels::getMusicListener
std::function< void(Sound *, bool)> getMusicListener() const
Definition: CUAudioChannels.h:666
cugl::AudioChannels::pauseAllEffects
void pauseAllEffects(float fade=DEFAULT_FADE)
cugl::AudioChannels::currentEffect
const Sound * currentEffect(const char *key) const
Definition: CUAudioChannels.h:916
cugl::AudioChannels::isActiveEffect
bool isActiveEffect(const char *key) const
Definition: CUAudioChannels.h:890
cugl::AudioChannels::clearMusicQueue
void clearMusicQueue()
cugl::AudioChannels::getMusicElapsed
float getMusicElapsed() const
cugl::AudioChannels::getEffectRemaining
float getEffectRemaining(const char *key) const
Definition: CUAudioChannels.h:1226
cugl::AudioChannels::getEffectPan
float getEffectPan(const char *key) const
Definition: CUAudioChannels.h:1056
cugl::AudioChannels::isMusicLoop
bool isMusicLoop() const
cugl::AudioChannels::setEffectListener
void setEffectListener(std::function< void(const std::string &key, bool)> callback)
Definition: CUAudioChannels.h:1401
cugl::AudioChannels::pauseMusic
void pauseMusic(float fade=DEFAULT_FADE)
cugl::AudioChannels::start
static void start(Uint32 slots)
cugl::AudioChannels::advanceMusicQueue
void advanceMusicQueue(float fade=DEFAULT_FADE, unsigned int steps=0)
cugl::AudioChannels::setEffectVolume
void setEffectVolume(const char *key, float volume)
Definition: CUAudioChannels.h:1014
cugl::AudioChannels::setEffectVolume
void setEffectVolume(const std::string &key, float volume)
cugl::AudioChannels::getMusicPending
size_t getMusicPending() const
cugl::AudioChannels::setMusicListener
void setMusicListener(std::function< void(Sound *, bool)> callback)
Definition: CUAudioChannels.h:652
cugl::AudioChannels::getEffectDuration
float getEffectDuration(const std::string &key) const
cugl::AudioChannels::stopAll
void stopAll(float fade=DEFAULT_FADE)