1 /* 2 ******************************************************************************************* 3 * Dgame (a D game framework) - Copyright (c) Randy Schütt 4 * 5 * This software is provided 'as-is', without any express or implied warranty. 6 * In no event will the authors be held liable for any damages arising from 7 * the use of this software. 8 * 9 * Permission is granted to anyone to use this software for any purpose, 10 * including commercial applications, and to alter it and redistribute it 11 * freely, subject to the following restrictions: 12 * 13 * 1. The origin of this software must not be misrepresented; you must not claim 14 * that you wrote the original software. If you use this software in a product, 15 * an acknowledgment in the product documentation would be appreciated but is 16 * not required. 17 * 18 * 2. Altered source versions must be plainly marked as such, and must not be 19 * misrepresented as being the original software. 20 * 21 * 3. This notice may not be removed or altered from any source distribution. 22 ******************************************************************************************* 23 */ 24 module Dgame.Audio.Music; 25 26 private: 27 28 import derelict.sdl2.mixer; 29 30 import Dgame.Internal.Error; 31 32 public: 33 34 /** 35 * Music represents the functionality to load and play music files. 36 * 37 * Note: Music is designed to load and play <b>larger</b> music files, e.g. background music 38 * If you just want to play short sounds, use Sound. 39 * 40 * Supported formats are .wav, .mp3, .vorbis, .ogg, .midi 41 * 42 * Author: Randy Schuett (rswhite4@googlemail.com) 43 */ 44 struct Music { 45 private: 46 Mix_Music* _music; 47 48 public: 49 /** 50 * CTor 51 */ 52 @nogc 53 this(string filename, ubyte volume = 128) nothrow { 54 this.loadFromFile(filename); 55 this.setVolume(volume); 56 } 57 58 /** 59 * Postblit is disabled 60 */ 61 @disable 62 this(this); 63 64 /** 65 * DTor 66 */ 67 @nogc 68 ~this() nothrow { 69 Mix_FreeMusic(_music); 70 } 71 72 /** 73 * Load the music file (filename). 74 * Returns if the loading was successful. 75 * If not, an error message is showed which describes what the problem is. 76 */ 77 @nogc 78 bool loadFromFile(string filename) nothrow { 79 _music = Mix_LoadMUS(filename.ptr); 80 if (!_music) { 81 print_fmt("Could not load file: %s\n", Mix_GetError()); 82 return false; 83 } 84 85 return true; 86 } 87 88 /** 89 * Set the volume, max. is 128, min. is 0 90 * If the value is above 128, the max. will be assumed. 91 * Returns the previous volume. 92 */ 93 @nogc 94 ubyte setVolume(ubyte volume) const nothrow { 95 return cast(ubyte) Mix_VolumeMusic(volume); 96 } 97 98 /** 99 * Returns the current volume 100 */ 101 @nogc 102 ubyte getVolume() const nothrow { 103 return cast(ubyte) Mix_VolumeMusic(-1); 104 } 105 106 /** 107 * Plays the music. 108 * loops describe how often the music shall be played. 109 * A value of -1 indicated, that the music plays forever, 110 * a value of 0 means, that the music plays zero times. 111 * delay is the time in ms to fade in. 112 * Any previous music will be halted. 113 */ 114 @nogc 115 void play(byte loops = 1, short delay = -1) nothrow { 116 if (_music) { 117 loops = loops > 0 ? cast(byte)(loops - 1) : loops; 118 Mix_FadeInMusic(_music, loops, delay); 119 } 120 } 121 122 /** 123 * Resume the music playback 124 * 125 * See: pause 126 * See: stop 127 */ 128 @nogc 129 void resume() const nothrow { 130 Mix_ResumeMusic(); 131 } 132 133 /** 134 * Stop/Halt the music playback 135 * 136 * See: resume 137 */ 138 @nogc 139 void stop() const nothrow { 140 Mix_HaltMusic(); 141 } 142 143 /** 144 * Pause the music playback 145 * 146 * See: resume 147 */ 148 @nogc 149 void pause() const nothrow { 150 Mix_PauseMusic(); 151 } 152 153 /** 154 * Rewind the music to the start 155 * 156 * Note: This function only works for .ogg, .vorbis, .mp3, .midi 157 */ 158 @nogc 159 void rewind() const nothrow { 160 Mix_RewindMusic(); 161 } 162 163 /** 164 * Fade out the music. The music will be stopped in ms milliseconds. 165 */ 166 @nogc 167 void fadeOut(ushort ms) nothrow { 168 Mix_FadeOutMusic(ms); 169 } 170 171 /** 172 * Set the position of the currently playing music. 173 * The position takes different meanings for different music sources. 174 * 175 * <b>.ogg / .vorbis:</b> 176 * Jumps to position seconds from the beginning of the song. 177 * <b>mp3:</b> 178 * Jumps to position seconds from the current position in the stream. 179 * So you may want to call rewind before. 180 * <b>Does not go in reverse: negative values do nothing.</b> 181 * 182 * Note: This only works for.ogg, .vorbis and .mp3 183 */ 184 @nogc 185 void setPosition(float seconds) const nothrow { 186 Mix_SetMusicPosition(seconds); 187 } 188 189 /** 190 * Returns if the music is currently playing 191 */ 192 @nogc 193 bool isPlaying() const nothrow { 194 return Mix_PlayingMusic() != 0; 195 } 196 197 /** 198 * Returns if the music is currently paused 199 */ 200 @nogc 201 bool isPaused() const nothrow { 202 return Mix_PausedMusic() != 0; 203 } 204 }