ge211
ge211_audio.h
1 #pragma once
2 
3 #include "ge211_forward.h"
4 #include "ge211_time.h"
5 #include "ge211_util.h"
6 
7 #include <memory>
8 #include <vector>
9 
10 namespace ge211 {
11 
21 namespace audio {
22 
35 {
36 public:
45  Music_track(const std::string& filename, const Mixer&);
46 
49 
51  bool empty() const;
52 
55  operator bool() const;
56 
57 private:
58  // Friends
59  friend Mixer;
60 
61  // Private helper.
62  static std::shared_ptr<Mix_Music> load_(const std::string& filename);
63 
64  std::shared_ptr<Mix_Music> ptr_;
65 };
66 
77 {
78 public:
85  Sound_effect(const std::string& filename, const Mixer&);
86 
89 
91  bool empty() const;
92 
95  operator bool() const;
96 
97 private:
98  // Friends
99  friend Mixer;
100 
101  // Private static factory
102  static std::shared_ptr<Mix_Chunk> load_(const std::string& filename);
103 
104  std::shared_ptr<Mix_Chunk> ptr_;
105 };
106 
142 class Mixer
143 {
144 public:
146  enum class State
147  {
150  detached,
152  playing,
155  fading_out,
157  paused,
158  };
159 
162 
170  void play_music(Music_track);
171 
180 
187  void resume_music(Duration fade_in = Duration(0));
188 
194  void pause_music(Duration fade_out = Duration(0));
195 
201  void rewind_music();
202 
204  const Music_track& get_music() const
205  {
206  return current_music_;
207  }
208 
227  State get_music_state() const
228  {
229  return music_state_;
230  }
231 
235  double get_music_volume() const;
236 
238  void set_music_volume(double unit_value);
239 
241 
244 
248  int available_effect_channels() const;
249 
258  Sound_effect_handle
259  play_effect(Sound_effect effect, double volume = 1.0);
260 
262  void pause_all_effects();
263 
265  void resume_all_effects();
266 
268 
271 
273  Mixer(const Mixer&) = delete;
275  Mixer(const Mixer&&) = delete;
277  Mixer& operator=(const Mixer&) = delete;
279  Mixer& operator=(const Mixer&&) = delete;
280 
282  ~Mixer();
283 
285 
286 private:
288  static std::unique_ptr<Mixer> open_mixer();
289 
291  // (and if there is more than one Abstract_game at a time, we're in trouble.
292  Mixer();
293  friend Abstract_game; // constructs.
294 
296  void poll_channels_();
297  friend detail::Engine; // calls poll_channels_().
298 
300  int find_empty_channel_() const;
301 
303  Sound_effect_handle
304  register_effect_(int channel, Sound_effect effect);
305 
307  void unregister_effect_(int channel);
308  friend Sound_effect_handle; // calls unregister_effect_(int).
309 
310 private:
311  Music_track current_music_;
312  State music_state_{State::detached};
313  Pausable_timer music_position_{true};
314 
315  std::vector<Sound_effect_handle> channels_;
316  int available_effect_channels_;
317 };
318 
322 class Sound_effect_handle
323 {
324 public:
332 
334  bool empty() const;
335 
338  operator bool() const;
339 
346  void pause();
347 
354  void resume();
355 
362  void stop();
363 
368  const Sound_effect& get_effect() const;
369 
378  Mixer::State get_state() const;
379 
382  double get_volume() const;
383 
386  void set_volume(double unit_value);
387 
388 private:
389  friend Mixer;
390 
391  struct Impl_
392  {
393  Impl_(Mixer& m, Sound_effect e, int c)
394  : mixer(m)
395  , effect(std::move(e))
396  , channel(c)
397  , state(Mixer::State::playing)
398  { }
399 
400  Mixer& mixer;
401  Sound_effect effect;
402  int channel;
403  Mixer::State state;
404  };
405 
406  Sound_effect_handle(Mixer&, Sound_effect, int channel);
407 
408  std::shared_ptr<Impl_> ptr_;
409 };
410 
411 } // end namespace audio
412 
413 } // end namespace ge211
void rewind_music()
Rewinds the music to the beginning.
void resume_all_effects()
Unpauses all currently-paused effects.
Mixer::State get_state() const
Gets the state of this effect.
void pause_all_effects()
Pauses all currently-playing effects.
In the process of fading out from playing to paused (for music) or to halted and detached (for sound ...
Sound_effect_handle play_effect(Sound_effect effect, double volume=1.0)
Plays the given effect track on this mixer, at the specified volume.
void set_volume(double unit_value)
Sets the playing sound effect&#39;s volume as a number from 0.0 to 1.0.
The game engine namespace.
Definition: ge211.h:17
double get_music_volume() const
Returns the music volume as a number from 0.0 to 1.0.
bool empty() const
Recognizes the empty sound effect track.
Definition: ge211_audio.cpp:62
State get_music_state() const
Returns the current state of the attached music, if any.
Definition: ge211_audio.h:232
double get_volume() const
Returns the playing sound effect&#39;s volume as a number from 0.0 to 1.0.
A music track, which can be attached to the Mixer and played.
Definition: ge211_audio.h:34
A sound effect track, which can be attached to a Mixer channel and played.
Definition: ge211_audio.h:76
Sound_effect_handle()
Default-constructs the empty sound effect handle.
Definition: ge211_audio.h:337
void pause_music(Duration fade_out=Duration(0))
Pauses the currently attached music, fading out if requested.
void resume_music(Duration fade_in=Duration(0))
Plays the currently attached music from the current saved position, fading in if requested.
int available_effect_channels() const
How many effect channels are currently unused? If this is positive, then we can play an additional so...
void play_music(Music_track)
Attaches the given music track to this mixer and starts it playing.
The entity that coordinates playing all audio tracks.
Definition: ge211_audio.h:142
Mixer & operator=(const Mixer &)=delete
The mixer cannot be copied.
void set_music_volume(double unit_value)
Sets the music volume, on a scale from 0.0 to 1.0.
bool empty() const
Recognizes the empty music track.
Definition: ge211_audio.cpp:39
Attached but not playing.
const Sound_effect & get_effect() const
Gets the Sound_effect being played by this handle.
const Music_track & get_music() const
Gets the Music_track currently attached to this Mixer, if any.
Definition: ge211_audio.h:209
~Mixer()
Destructor, to clean up the mixer&#39;s resources.
State
The state of an audio channel.
Definition: ge211_audio.h:146
A length of time.
Definition: ge211_time.h:30
bool empty() const
Recognizes the empty sound effect handle.
void stop()
Stops the effect from playing and detaches it.
No track is attached to the channel, or no channel is attached to the handle.
Music_track()
Default-constructs the empty music track.
Definition: ge211_audio.h:48
Sound_effect()
Default-constructs the empty sound effect track.
Definition: ge211_audio.h:88
void resume()
Unpauses the effect.
void pause()
Pauses the effect.
void attach_music(Music_track)
Attaches the given music track to this mixer.