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.audio; 23 24 import blocksound.core; 25 import blocksound.backend.types; 26 27 public import blocksound.backend.types : Source, Sound, StreamingSource, StreamedSound; 28 29 version(blocksound_ALBackend) { 30 import blocksound.backend.openal; 31 } 32 33 /++ 34 Loads a Sound from a file. 35 36 Params: 37 file = The file where the sound is stored. 38 39 Returns: A Sound instance loaded from the specified file. 40 +/ 41 Sound loadSoundFile(in string file) @trusted { 42 version(blocksound_ALBackend) { 43 import blocksound.backend.openal : ALSound; 44 45 return ALSound.loadSound(file); 46 } else { 47 throw new Exception("No backend avaliable! (Try compiling with version \"blocksound_ALBackend\" enabled)"); 48 } 49 } 50 51 /++ 52 Loads a Sound from a file for streaming. 53 54 Params: 55 file = The file where the sound is stored. 56 57 Returns: A StreamedSound instance loaded from the specified file. 58 +/ 59 StreamedSound loadStreamingSoundFile(in string file, in size_t numBuffers = 4) @trusted { 60 version(blocksound_ALBackend) { 61 import blocksound.backend.openal : ALStreamedSound; 62 import derelict.openal.al : ALuint; 63 64 return ALStreamedSound.loadSound(file, cast(ALuint) numBuffers); 65 } else { 66 throw new Exception("No backend avaliable! (Try compiling with version \"blocksound_ALBackend\" enabled)"); 67 } 68 } 69 70 /// Manages the Audio. 71 class AudioManager { 72 private Vec3 _listenerLocation; 73 private float _gain; 74 75 private AudioBackend backend; 76 private shared ArrayList!Source sources; 77 78 /// The location where the listener is. 79 @property Vec3 listenerLocation() @safe nothrow { return _listenerLocation; } 80 /// The location where the listener is. 81 @property void listenerLocation(Vec3 loc) @safe { 82 _listenerLocation = loc; 83 backend.setListenerLocation(loc); 84 } 85 86 /// The listener's gain or volume. 87 @property float gain() @safe nothrow { return _gain; } 88 /// The listener's gain or volume. 89 @property void gain(float gain) @safe { 90 _gain = gain; 91 backend.setListenerGain(gain); 92 } 93 94 /++ 95 Initializes the AudioManager and it's backend. 96 Backend is decided at compile-time. 97 +/ 98 this() @trusted { 99 import std.exception : enforce; 100 101 enforce(INIT, new Exception("BlockSound has not been initialized!")); 102 103 version(blocksound_ALBackend) { 104 backend = new ALAudioBackend(); 105 } else { 106 throw new Exception("No backend avaliable! (Try compiling with version \"blocksound_ALBackend\" enabled)"); 107 } 108 109 sources = new ArrayList!Source(); 110 } 111 112 /++ 113 Create a a new Source at the specified 114 location. The Source is also added to this AudioManager. 115 116 Params: 117 location = The location of the Source. 118 119 Returns: A new Source. 120 +/ 121 Source createSource(Vec3 location) @trusted { 122 Source source = backend_createSource(location); 123 sources.add(source); 124 return source; 125 } 126 127 /++ 128 Create a a new StreamingSource at the specified 129 location. The Source is also added to this AudioManager. 130 This is for Streaming sounds. 131 132 Params: 133 location = The location of the Source. 134 135 Returns: A new Source. 136 +/ 137 StreamingSource createStreamingSource(Vec3 location) @trusted { 138 StreamingSource source = backend_createStreamingSource(location); 139 sources.add(source); 140 return source; 141 } 142 143 /++ 144 Deletes a Source, frees it's resources, 145 and removes it from the AudioManager. 146 147 Params: 148 source = The source to be deleted. 149 +/ 150 void deleteSource(Source source) @trusted { 151 sources.remove(source); 152 source.cleanup(); 153 } 154 155 /// Cleanup any resources used by the backend. 156 void cleanup() @trusted { 157 backend.cleanup(); 158 } 159 }