1 /*
2  *  zlib License
3  *  
4  *  (C) 2016 jython234
5  *  
6  *  This software is provided 'as-is', without any express or implied
7  *  warranty.  In no event will the authors be held liable for any damages
8  *  arising from the 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
15  *     claim that you wrote the original software. If you use this software
16  *     in a product, an acknowledgment in the product documentation would be
17  *     appreciated but is not required.
18  *  2. Altered source versions must be plainly marked as such, and must not be
19  *     misrepresented as being the original software.
20  *  3. This notice may not be removed or altered from any source distribution.
21 */
22 module blocksound.backend.types;
23 
24 import blocksound.core;
25 
26 debug(blocksound_verbose) {
27     package void notifyLoadLib(string lib) @safe {
28         import std.stdio : writeln;
29         writeln("[BlockSound]: Loaded ", lib);
30     }
31 }
32 
33 version(blocksound_ALBackend) {
34     /// Name of the backend used for blocksound.
35     immutable string BACKEND = "OpenAL";
36 } else {
37     /// Name of the backend used for blocksound.
38     immutable string BACKEND = "None";
39 }
40 
41 /// Used by AudioManager to create a source.
42 Source backend_createSource(Vec3 loc) @system {
43     version(blocksound_ALBackend) {
44         import blocksound.backend.openal : ALSource;
45 
46         Source source = new ALSource();
47         source.location = loc;
48         return source;
49     } else {
50         throw new Exception("No backend avaliable! (Try compiling with version \"blocksound_ALBackend\" enabled)");
51     }
52 }
53 
54 /// Base class for the audio backend.
55 abstract class AudioBackend {
56     
57     abstract void setListenerLocation(in Vec3 loc) @trusted;
58 
59     abstract void setListenerGain(in float gain) @trusted;
60 
61     abstract void cleanup() @trusted;
62 }
63 
64 /// Represents a source that emits audio.
65 abstract class Source {
66     protected Vec3 _location;
67     protected Sound sound;
68 
69     /// The location of the source.
70     @property Vec3 location() @safe nothrow { return _location; }
71     /// The location of the source.
72     @property void location(Vec3 loc) @safe nothrow {
73         _location = loc;
74     }
75 
76     /++
77         Create a new source. The backend class will automatically be
78         determined.
79 
80         Returns: A new Source instance.
81     +/
82     deprecated("Use AudioManager.createSource()") 
83     static Source newSource(Vec3 location) {
84         version(blocksound_ALBackend) {
85             import blocksound.backend.openal : ALSource;
86 
87             Source source = new ALSource();
88             source.location = location;
89             return source;
90         } else {
91             throw new Exception("No backend avaliable! (Try compiling with version \"blocksound_ALBackend\" enabled)");
92         }
93     }
94     
95     /++
96         Set the Sound that this Source plays.
97 
98         Params:
99                 sound =     The Sound that the Source plays.
100     +/
101     final void setSound(Sound sound) @trusted {
102         this.sound = sound;
103         _setSound(sound);
104     }
105 
106     protected abstract void _setSound(Sound sound) @trusted;
107 
108     /++
109         Set if the Source should loop the Sound.
110 
111         Params:
112                 loop =  If the Source should loop it's Sound.
113     +/
114     abstract void setLooping(in bool loop) @trusted;
115 
116     /// Plays the Sound that belongs to this Source.
117     abstract void play() @trusted;
118 
119     /// Pause the Sound that is playing.
120     abstract void pause() @trusted;
121 
122     /// Stops playing the Sound.
123     abstract void stop() @trusted;
124 
125     /++
126         Returns: If the Source has stopped playing it's Sound.
127     +/
128     abstract bool hasFinishedPlaying() @trusted;
129 
130     /// Cleans up the resources used by the Source.
131     final void cleanup() @trusted {
132         sound.cleanup();
133         _cleanup();
134     }
135 
136     abstract protected void _cleanup();
137 }
138 
139 /++
140     Represents a sound, loaded in memory. For
141     larger sounds, consider using streaming instead.
142 
143     TODO: STREAMING
144 +/
145 interface Sound {
146 
147     /// Frees resources used by the sound.
148     void cleanup() @trusted;
149 }