1 /*
2  * DSFML - The Simple and Fast Multimedia Library for D
3  *
4  * Copyright (c) 2013 - 2018 Jeremy DeHaan (dehaan.jeremiah@gmail.com)
5  *
6  * This software is provided 'as-is', without any express or implied warranty.
7  * In no event will the authors be held liable for any damages arising from the
8  * use of this software.
9  *
10  * Permission is granted to anyone to use this software for any purpose,
11  * including commercial applications, and to alter it and redistribute it
12  * freely, subject to the following restrictions:
13  *
14  * 1. The origin of this software must not be misrepresented; you must not claim
15  * that you wrote the original software. If you use this software in a product,
16  * an acknowledgment in the product documentation would be appreciated but is
17  * not required.
18  *
19  * 2. Altered source versions must be plainly marked as such, and must not be
20  * misrepresented as being the original software.
21  *
22  * 3. This notice may not be removed or altered from any source distribution
23  *
24  *
25  * DSFML is based on SFML (Copyright Laurent Gomila)
26  */
27 
28 /**
29  * The audio listener defines the global properties of the audio environment, it
30  * defines where and how sounds and musics are heard.
31  *
32  * If $(VIEW_LINK) is the eyes of the user, then
33  * $(U Listener) is his ears (by the way, they are often linked together – same
34  * position, orientation, etc.).
35  *
36  * $(U Listener) is a simple interface, which allows to setup the listener in
37  * the 3D audio environment (position and direction), and to adjust the global
38  * volume.
39  *
40  * Because the listener is unique in the scene, $(U Listener) only contains
41  * static functions and doesn't have to be instanciated.
42  *
43  * Example:
44  * ---
45  * // Move the listener to the position (1, 0, -5)
46  * Listener.position = Vector3f(1, 0, -5);
47  *
48  * // Make it face the right axis (1, 0, 0)
49  * Listener.direction = Vector3f(1, 0, 0);
50  *
51  * // Reduce the global volume
52  * Listener.globalVolume = 50;
53  * ---
54  */
55 module dsfml.audio.listener;
56 
57 import dsfml.system.vector3;
58 
59 /**
60  * The audio listener is the point in the scene from where all the sounds are
61  * heard.
62  */
63 final abstract class Listener
64 {
65     @property
66     {
67         /**
68          * The orientation of the listener in the scene.
69          *
70          * The orientation defines the 3D axes of the listener (left, up, front)
71          * in the scene. The orientation vector doesn't have to be normalized.
72          *
73          * The default listener's orientation is (0, 0, -1).
74          */
75         static void direction(Vector3f orientation)
76         {
77             sfListener_setDirection(orientation.x, orientation.y,
78                                     orientation.z);
79         }
80 
81         /// ditto
82         static Vector3f direction()
83         {
84             Vector3f temp;
85 
86             sfListener_getDirection(&temp.x, &temp.y, &temp.z);
87 
88             return temp;
89         }
90     }
91 
92     @property
93     {
94         /**
95          * The upward vector of the listener in the scene.
96          *
97          * The upward vector defines the 3D axes of the listener (left, up,
98          * front) in the scene. The upward vector doesn't have to be normalized.
99          *
100          * The default listener's upward vector is (0, 1, 0).
101          */
102         static void upVector(Vector3f orientation)
103         {
104             sfListener_setUpVector(orientation.x, orientation.y, orientation.z);
105         }
106 
107         /// ditto
108         static Vector3f upVector()
109         {
110             Vector3f temp;
111 
112             sfListener_getUpVector(&temp.x, &temp.y, &temp.z);
113 
114             return temp;
115         }
116     }
117 
118     @property
119     {
120         /**
121          * The global volume of all the sounds and musics.
122          *
123          * The volume is a number between 0 and 100; it is combined with the
124          * individual volume of each sound / music.
125          *
126          * The default value for the volume is 100 (maximum).
127          */
128         static void globalVolume(float volume)
129         {
130             sfListener_setGlobalVolume(volume);
131         }
132 
133         /// ditto
134         static float globalVolume()
135         {
136             return sfListener_getGlobalVolume();
137         }
138     }
139 
140     @property
141     {
142         /**
143          * The position of the listener in the scene.
144          *
145          * The default listener's position is (0, 0, 0).
146          */
147         static void position(Vector3f pos)
148         {
149             sfListener_setPosition(pos.x, pos.y, pos.z);
150         }
151 
152         /// ditto
153         static Vector3f position()
154         {
155             Vector3f temp;
156 
157             sfListener_getPosition(&temp.x, &temp.y, &temp.z);
158 
159             return temp;
160         }
161     }
162 
163     deprecated("Use the 'direction' property instead.")
164     @property
165     {
166         /**
167          * The orientation of the listener in the scene.
168          *
169          * The orientation defines the 3D axes of the listener (left, up, front)
170          * in the scene. The orientation vector doesn't have to be normalized.
171          *
172          * The default listener's orientation is (0, 0, -1).
173          *
174          * Deprecated: Use the 'direction' property instead.
175          */
176         static void Direction(Vector3f orientation)
177         {
178             sfListener_setDirection(orientation.x, orientation.y,
179                                     orientation.z);
180         }
181 
182         /// ditto
183         static Vector3f Direction()
184         {
185             Vector3f temp;
186 
187             sfListener_getDirection(&temp.x, &temp.y, &temp.z);
188 
189             return temp;
190         }
191     }
192 
193     deprecated("Use the 'upVector' property instead.")
194     @property
195     {
196         /**
197          * The upward vector of the listener in the scene.
198          *
199          * The upward vector defines the 3D axes of the listener (left, up,
200          * front) in the scene. The upward vector doesn't have to be normalized.
201          *
202          * The default listener's upward vector is (0, 1, 0).
203          *
204          * Deprecated: Use the 'upVector' property instead.
205          */
206         static void UpVector(Vector3f orientation)
207         {
208             sfListener_setUpVector(orientation.x, orientation.y, orientation.z);
209         }
210 
211         /// ditto
212         static Vector3f UpVector()
213         {
214             Vector3f temp;
215 
216             sfListener_getUpVector(&temp.x, &temp.y, &temp.z);
217 
218             return temp;
219         }
220     }
221 
222     deprecated("Use the 'globalVolume' property instead.")
223     @property
224     {
225         /**
226          * The global volume of all the sounds and musics. The volume is a
227          * number between 0 and 100; it is combined with the individual volume
228          * of each sound / music.
229          *
230          * The default value for the volume is 100 (maximum).
231          *
232          * Deprecated: Use the 'globalVolume' property instead.
233          */
234         static void GlobalVolume(float volume)
235         {
236             sfListener_setGlobalVolume(volume);
237         }
238 
239         /// ditto
240         static float GlobalVolume()
241         {
242             return sfListener_getGlobalVolume();
243         }
244     }
245 
246     deprecated("Use the 'position' property instead.")
247     @property
248     {
249         /**
250          * The position of the listener in the scene.
251          *
252          * The default listener's position is (0, 0, 0).
253          *
254          * Deprecated: Use the 'position' property instead.
255          */
256         static void Position(Vector3f position)
257         {
258             sfListener_setPosition(position.x, position.y, position.z);
259         }
260 
261         /// ditto
262         static Vector3f Position()
263         {
264             Vector3f temp;
265 
266             sfListener_getPosition(&temp.x, &temp.y, &temp.z);
267 
268             return temp;
269         }
270     }
271 }
272 
273 unittest
274 {
275     version (DSFML_Unittest_Audio)
276     {
277         import std.stdio;
278 
279         writeln("Unit test for Listener");
280 
281         float volume = Listener.GlobalVolume;
282         volume -= 10;
283         Listener.GlobalVolume = volume;
284 
285         Vector3f pos = Listener.Position;
286         pos.x += 10;
287         pos.y -= 10;
288         pos.z *= 3;
289         Listener.Position = pos;
290 
291         Vector3f dir = Listener.Direction;
292         dir.x += 10;
293         dir.y -= 10;
294         dir.z *= 3;
295         Listener.Direction = dir;
296         writeln("Unit tests pass!");
297         writeln();
298     }
299 }
300 
301 private extern (C):
302 
303 void sfListener_setGlobalVolume(float volume);
304 
305 float sfListener_getGlobalVolume();
306 
307 void sfListener_setPosition(float x, float y, float z);
308 
309 void sfListener_getPosition(float* x, float* y, float* z);
310 
311 void sfListener_setDirection(float x, float y, float z);
312 
313 void sfListener_getDirection(float* x, float* y, float* z);
314 
315 void sfListener_setUpVector(float x, float y, float z);
316 
317 void sfListener_getUpVector(float* x, float* y, float* z);