ge211  2021.5.1
A student game engine
ge211_audio.hxx
1 #pragma once
2 
3 #include "ge211_forward.hxx"
4 #include "ge211_error.hxx"
5 #include "ge211_time.hxx"
6 #include "ge211_util.hxx"
7 
8 #include <memory>
9 #include <vector>
10 
11 namespace ge211 {
12 
24 namespace audio {
25 
29 {
30  friend Music_track; // derived class
31  friend Sound_effect; // derived class
32 
33 public:
35  bool empty() const { return real_empty_(); }
36 
39  explicit operator bool() const { return !real_empty_(); }
40 
45  void load(const std::string&, const Mixer&);
46 
52  bool try_load(const std::string&, const Mixer&);
53 
55  void clear();
56 
57  virtual ~Audio_clip() = default;
58 
59 private:
60  Audio_clip();
61 
64  virtual bool real_try_load_(const std::string& filename, const Mixer&) = 0;
65 
68  virtual void real_clear_() = 0;
69 
72  virtual bool real_empty_() const = 0;
73 };
74 
86 class Music_track : public Audio_clip
87 {
88  friend Mixer;
89 
90 public:
103  Music_track(const std::string& filename, const Mixer&);
104 
107 
108 private:
109  bool real_try_load_(const std::string&, const Mixer&) override;
110  void real_clear_() override;
111  bool real_empty_() const override;
112 
114 };
115 
124 class Sound_effect : public Audio_clip
125 {
126  friend Mixer;
127 
128 public:
138  Sound_effect(const std::string& filename, const Mixer&);
139 
142 
143 private:
144  bool real_try_load_(const std::string&, const Mixer&) override;
145  void real_clear_() override;
146  bool real_empty_() const override;
147 
149 };
150 
190 class Mixer
191 {
192  // This calls default constructor...
193  friend Abstract_game;
194  // ...via this:
195  friend class detail::lazy_ptr<Mixer>;
196 
197 public:
199  enum class State
200  {
203  detached,
205  playing,
208  fading_out,
210  paused,
211  };
212 
215  bool is_enabled() const
216  { return enabled_; }
217 
220 
231  void play_music(Music_track, bool forever = false);
232 
241 
250  void resume_music(Duration fade_in = Duration(0), bool forever = false);
251 
257  void pause_music(Duration fade_out = Duration(0));
258 
264  void rewind_music();
265 
267  const Music_track& get_music() const
268  {
269  return current_music_;
270  }
271 
291  {
292  return music_state_;
293  }
294 
298  double get_music_volume() const;
299 
301  void set_music_volume(double unit_value);
302 
304 
307 
311  int available_effect_channels() const;
312 
322  play_effect(Sound_effect effect, double volume = 1.0);
323 
330  try_play_effect(Sound_effect effect, double volume = 1.0);
331 
333  void pause_all_effects();
334 
336  void resume_all_effects();
337 
339 
342 
344  Mixer(const Mixer&) = delete;
346  Mixer(const Mixer&&) = delete;
348  Mixer& operator=(const Mixer&) = delete;
350  Mixer& operator=(const Mixer&&) = delete;
351 
353  ~Mixer();
354 
356 
357 private:
360  Mixer();
361 
363  void poll_channels_();
364  friend class detail::Engine; // calls poll_channels_().
365 
368  int find_empty_channel_() const;
369 
372  register_effect_(int channel, Sound_effect effect);
373 
375  void unregister_effect_(int channel);
376  friend Sound_effect_handle; // calls unregister_effect_(int).
377 
378 private:
379  Music_track current_music_;
380  State music_state_{State::detached};
381  Pausable_timer music_position_{true};
382 
383  bool enabled_;
385  int available_effect_channels_;
386 };
387 
392 {
393 public:
401 
403  bool empty() const;
404 
407  explicit operator bool() const;
408 
415  void pause();
416 
423  void resume();
424 
431  void stop();
432 
437  const Sound_effect& get_effect() const;
438 
447  Mixer::State get_state() const;
448 
451  double get_volume() const;
452 
455  void set_volume(double unit_value);
456 
457 private:
458  friend Mixer;
459 
460  struct Impl_
461  {
462  Impl_(Mixer& m, Sound_effect e, int c)
463  : mixer(m)
464  , effect(std::move(e))
465  , channel(c)
466  , state(Mixer::State::playing)
467  { }
468 
469  Mixer& mixer;
470  Sound_effect effect;
471  int channel;
472  Mixer::State state;
473  };
474 
475  Sound_effect_handle(Mixer&, Sound_effect, int channel);
476 
478 };
479 
480 } // end namespace audio
481 
482 } // end namespace ge211
ge211::audio::Music_track
A music track, which can be attached to the Mixer and played.
Definition: ge211_audio.hxx:87
ge211::audio::Sound_effect_handle
Used to control a Sound_effect after it is started playing on a Mixer.
Definition: ge211_audio.hxx:392
std::string
std::shared_ptr< Mix_Music >
ge211::time::Duration
A length of time.
Definition: ge211_time.hxx:31
ge211::audio::Audio_clip::load
void load(const std::string &, const Mixer &)
Loads audio from a resource file into this audio clip instance.
Definition: ge211_audio.cxx:37
ge211::audio::Mixer::get_music
const Music_track & get_music() const
Gets the Music_track currently attached to this Mixer, if any.
Definition: ge211_audio.hxx:267
std::vector
ge211::audio::Sound_effect_handle::get_effect
const Sound_effect & get_effect() const
Gets the Sound_effect being played by this handle.
Definition: ge211_audio.cxx:239
ge211::audio::Mixer::pause_all_effects
void pause_all_effects()
Pauses all currently-playing effects.
Definition: ge211_audio.cxx:380
ge211::audio::Mixer::State::playing
@ playing
Actively playing.
ge211::audio::Sound_effect_handle::empty
bool empty() const
Recognizes the empty sound effect handle.
Definition: ge211_audio.cxx:432
ge211::audio::Mixer::operator=
Mixer & operator=(const Mixer &)=delete
The mixer cannot be copied.
ge211::audio::Sound_effect_handle::pause
void pause()
Pauses the effect.
Definition: ge211_audio.cxx:339
ge211
The game engine namespace.
Definition: ge211.hxx:4
ge211::audio::Mixer::State::fading_out
@ fading_out
In the process of fading out from playing to paused (for music) or to halted and detached (for sound ...
ge211::audio::Mixer::is_enabled
bool is_enabled() const
Returns whether the mixer is enabled.
Definition: ge211_audio.hxx:215
ge211::audio::Sound_effect_handle::stop
void stop()
Stops the effect from playing and detaches it.
Definition: ge211_audio.cxx:359
ge211::audio::Audio_clip
Common interface to classes that load audio data, Music_track and Sound_effect.
Definition: ge211_audio.hxx:29
ge211::audio::Mixer::resume_music
void resume_music(Duration fade_in=Duration(0), bool forever=false)
Plays the currently attached music from the current saved position.
Definition: ge211_audio.cxx:173
ge211::audio::Sound_effect::Sound_effect
Sound_effect()
Default-constructs the empty sound effect track.
Definition: ge211_audio.hxx:141
ge211::audio::Mixer::pause_music
void pause_music(Duration fade_out=Duration(0))
Pauses the currently attached music, fading out if requested.
Definition: ge211_audio.cxx:198
ge211::audio::Mixer::attach_music
void attach_music(Music_track)
Attaches the given music track to this mixer.
Definition: ge211_audio.cxx:150
ge211::audio::Sound_effect_handle::resume
void resume()
Unpauses the effect.
Definition: ge211_audio.cxx:319
ge211::audio::Mixer::operator=
Mixer & operator=(const Mixer &&)=delete
The mixer cannot be moved.
ge211::audio::Audio_clip::empty
bool empty() const
Returns true if this audio clip is empty.
Definition: ge211_audio.hxx:35
ge211::audio::Mixer::get_music_volume
double get_music_volume() const
Returns the music volume as a number from 0.0 to 1.0.
Definition: ge211_audio.cxx:422
ge211::audio::Mixer::~Mixer
~Mixer()
Destructor, to clean up the mixer's resources.
Definition: ge211_audio.cxx:135
ge211::time::Pausable_timer
A class for timing intervals while supporting pausing.
Definition: ge211_time.hxx:317
ge211::audio::Mixer::State::paused
@ paused
Attached but not playing.
ge211::audio::Audio_clip::clear
void clear()
Unloads any audio data, leaving this Audio_clip empty.
Definition: ge211_audio.cxx:43
ge211::audio::Audio_clip::try_load
bool try_load(const std::string &, const Mixer &)
Attempts to load audio from a resource file into this Audio_clip instance.
Definition: ge211_audio.cxx:32
ge211::audio::Sound_effect_handle::get_state
Mixer::State get_state() const
Gets the state of this effect.
Definition: ge211_audio.cxx:244
ge211::audio::Mixer::try_play_effect
Sound_effect_handle try_play_effect(Sound_effect effect, double volume=1.0)
Attempts to play the given effect track on this mixer, returning an empty Sound_effect_handle if no e...
Definition: ge211_audio.cxx:306
ge211::audio::Mixer::State
State
The state of an audio channel.
Definition: ge211_audio.hxx:200
ge211::audio::Mixer::State::detached
@ detached
No track is attached to the channel, or no channel is attached to the handle.
ge211::audio::Sound_effect_handle::set_volume
void set_volume(double unit_value)
Sets the playing sound effect's volume as a number from 0.0 to 1.0.
Definition: ge211_audio.cxx:456
ge211::audio::Music_track::Music_track
Music_track()
Default-constructs the empty music track.
Definition: ge211_audio.hxx:106
ge211::audio::Mixer
The entity that coordinates playing all audio tracks.
Definition: ge211_audio.hxx:191
ge211::audio::Sound_effect
A sound effect track, which can be attached to a Mixer channel and played.
Definition: ge211_audio.hxx:125
ge211::audio::Mixer::set_music_volume
void set_music_volume(double unit_value)
Sets the music volume, on a scale from 0.0 to 1.0.
Definition: ge211_audio.cxx:427
ge211::audio::Mixer::resume_all_effects
void resume_all_effects()
Unpauses all currently-paused effects.
Definition: ge211_audio.cxx:390
ge211::audio::Mixer::get_music_state
State get_music_state() const
Returns the current state of the attached music, if any.
Definition: ge211_audio.hxx:290
ge211::audio::Mixer::Mixer
Mixer(const Mixer &&)=delete
The mixer cannot be moved.
ge211::audio::Mixer::play_effect
Sound_effect_handle play_effect(Sound_effect effect, double volume=1.0)
Plays the given effect track on this mixer, at the specified volume.
Definition: ge211_audio.cxx:295
ge211::audio::Mixer::play_music
void play_music(Music_track, bool forever=false)
Attaches the given music track to this mixer and starts it playing.
Definition: ge211_audio.cxx:144
ge211::audio::Mixer::rewind_music
void rewind_music()
Rewinds the music to the beginning.
Definition: ge211_audio.cxx:224
ge211::audio::Sound_effect_handle::get_volume
double get_volume() const
Returns the playing sound effect's volume as a number from 0.0 to 1.0.
Definition: ge211_audio.cxx:448
ge211::audio::Mixer::available_effect_channels
int available_effect_channels() const
How many effect channels are currently unused? If this is positive, then we can play an additional so...
Definition: ge211_audio.cxx:400
ge211::Abstract_game
This is the abstract base class for deriving games.
Definition: ge211_base.hxx:131
ge211::audio::Mixer::Mixer
Mixer(const Mixer &)=delete
The mixer cannot be copied.
ge211::audio::Sound_effect_handle::Sound_effect_handle
Sound_effect_handle()
Default-constructs the empty sound effect handle.
Definition: ge211_audio.hxx:400