emilib
al_lib.hpp
1 // By Emil Ernerfeldt 2012-2016
2 // LICENSE:
3 // This software is dual-licensed to the public domain and under the following
4 // license: you are granted a perpetual, irrevocable license to copy, modify,
5 // publish, and distribute this file as you see fit.
6 // Wrapper around OpenAL, a library for playing sounds.
7 
8 #pragma once
9 
10 #include <string>
11 #include <unordered_map>
12 #include <vector>
13 
14 #include "al_lib_fwd.hpp"
15 
16 using ALCdevice = struct ALCdevice_struct;
17 using ALCcontext = struct ALCcontext_struct;
18 
19 namespace al {
20 
21 // ----------------------------------------------------------------------------
22 
23 struct Vec3f { float data[3]; };
24 
25 void check_for_al_error();
26 
27 // ----------------------------------------------------------------------------
28 
30 class Sound
31 {
32 public:
33  static Sound load_wav(const char* path);
34 
35  Sound(Sound&& o) noexcept : _debug_name(o._debug_name), _buffer_id(o._buffer_id), _size_bytes(o._size_bytes) { o._buffer_id = 0; o._size_bytes = 0; }
36  ~Sound();
37 
39  unsigned size_bytes() const { return _size_bytes; }
40 
41 private:
42  friend class Source;
43  Sound(const Sound&) = delete;
44  Sound& operator=(const Sound&) = delete;
45 
46  Sound(const char* debug_name, unsigned buffer_id, unsigned size_bytes);
47 
48  const char* _debug_name;
49  unsigned _buffer_id;
50  unsigned _size_bytes;
51 };
52 
53 // ----------------------------------------------------------------------------
54 
56 class Source
57 {
58 public:
59  enum State
60  {
61  INITIAL,
62  PLAYING,
63  PAUSED,
64  STOPPED,
65  };
66 
68  static int max_sources();
69 
70  Source();
71  ~Source();
72 
73  void set_state(State arg);
74  State state() const;
75 
76  void play();
77  void pause();
78  void stop();
79  void rewind();
80 
81  void set_sound(Sound_SP sound);
82  const Sound_SP& sound() const;
83 
85  void set_gain(float gain);
86  float gain() const;
87 
89  void set_pitch(float pitch);
91  float pitch() const;
92 
93  void set_pos(Vec3f);
94  Vec3f pos() const;
95 
96  void set_vel(Vec3f);
97  Vec3f vel() const;
98 
99  void set_direction(Vec3f);
100  Vec3f direction() const;
101 
107  void set_max_distance(float arg);
108  float max_distance() const;
109 
111  void set_rolloff_factor(float arg);
112  float rolloff_factor() const;
113 
119  void set_reference_distance(float arg);
120  float reference_distance() const;
121 
122  void set_min_gain(float arg);
123  float min_gain() const;
124 
125  void set_max_gain(float arg);
126  float max_gain() const;
127 
128  void set_cone_outer_gain(float arg);
129  float cone_outer_gain() const;
130 
131  void set_cone_inner_angle(float arg);
132  float cone_inner_angle() const;
133 
134  void set_cone_outer_angle(float arg);
135  float cone_outer_angle() const;
136 
138  void set_relative_to_listener(bool arg);
139  bool relative_to_listener() const;
140 
141  void set_looping(bool);
142  bool looping() const;
143 
144 private:
145  Source(const Source&) = delete;
146  Source& operator=(const Source&) = delete;
147 
148  unsigned _source;
149  Sound_SP _sound;
150  float _gain = 1;
151 };
152 
153 // ----------------------------------------------------------------------------
154 
157 class Listener
158 {
159 public:
160  void set_pos(Vec3f);
161  Vec3f pos() const;
162 
163  void set_vel(Vec3f);
164  Vec3f vel() const;
165 
166  void set_orientation(const Vec3f& forward, const Vec3f& up);
167 
168  Vec3f direction() const;
169  Vec3f up() const;
170 
171  void set_gain(float);
172  float gain() const;
173 };
174 
175 // ----------------------------------------------------------------------------
176 
179 {
180 public:
182  explicit SoundMngr(const std::string& sfx_dir);
183  ~SoundMngr();
184 
185  //------------------------------------------------------------------------------
186 
188  void prefetch(const std::string& sound_name);
189 
191  void prefetch_all(const std::string& sub_folder = "");
192 
195  Source_SP play(const std::string& sound_name);
196 
197  //------------------------------------------------------------------------------
198  // Global settings
199 
200  bool is_working() const;
201 
202  Listener* listener() { return &_listener; }
203 
204  enum DistanceModel
205  {
206  NONE,
207  INVERSE_DISTANCE,
208  INVERSE_DISTANCE_CLAMPED,
209  };
210 
212  void set_doppler_vel(float vel);
214  float doppler_vel();
215 
217  void set_doppler_factor(float factor);
219  float doppler_factor();
220 
222  void set_distance_model(DistanceModel model);
224  DistanceModel distance_model();
225 
226  const char* vendor();
227  const char* version();
228  const char* renderer();
229  const char* extensions();
230 
231  //------------------------------------------------------------------------------
232 
233  void print_memory_usage() const;
234 
235 private:
236  Sound_SP load_sound(const std::string& sound_name, bool is_hot);
237  Source_SP get_source();
238 
239  using SoundMap = std::unordered_map<std::string, Sound_SP>;
240  using SourceList = std::vector<Source_SP>;
241 
242  std::string _sfx_dir;
243  ALCdevice* _device = nullptr;
244  ALCcontext* _context = nullptr;
245  Listener _listener;
246 
247  SoundMap _map;
248  SourceList _sources;
249 };
250 
251 } // namespace al
Definition: al_lib.hpp:157
A sound source. Has position, and a sound to play.
Definition: al_lib.hpp:56
Definition: al_lib.hpp:19
Definition: al_lib.hpp:23
A loaded sound. Can be played via Source. Many Source:s can play the same Sound at the same...
Definition: al_lib.hpp:30
You should have only one of these.
Definition: al_lib.hpp:178
unsigned size_bytes() const
Memory usage.
Definition: al_lib.hpp:39