00001 /* 00002 libwt - Vassilis Virvilis Toolkit - a widget library 00003 Copyright (C) 2006 Vassilis Virvilis <vasvir2@fastmail.fm> 00004 00005 This library is free software; you can redistribute it and/or 00006 modify it under the terms of the GNU Lesser General Public 00007 License as published by the Free Software Foundation; either 00008 version 2.1 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Lesser General Public License for more details. 00014 00015 You should have received a copy of the GNU Lesser General Public 00016 License along with this library; if not, write to the 00017 Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, SA. 00019 */ 00020 00021 #ifndef WT_AUDIO_H 00022 #define WT_AUDIO_H 00023 00024 #include <list> 00025 #include <vector> 00026 00027 #include <wt/wvar.h> 00028 #include <wt/enum.h> 00029 #include <wt/singleton.h> 00030 00031 union SDL_Event; 00032 00033 namespace Wt { 00034 00035 template <class BT> 00036 class BaseFactory { 00037 public: 00038 BaseFactory() {} 00039 virtual ~BaseFactory() {} 00040 virtual BT *instance() = 0; 00041 }; 00042 00043 template <class BT, class ST> 00044 class Factory : public BaseFactory<BT> { 00045 public: 00046 Factory() {} 00047 virtual ~Factory() {} 00048 virtual BT *instance() { 00049 return BT::template instance<ST> 00050 (); 00051 } 00052 }; 00053 00054 /// wrapper class around different audio driver 00055 /// implementations e.g. NullAudio, SDLMixer etc 00056 /*! 00057 It is not possible to use the curiously reccuring 00058 pattern this time from (Audio to Driver) because 00059 then the different drivers wouldn't be pointer 00060 compatible since they would inherit from different 00061 objects. 00062 */ 00063 class Audio : public Singleton<Audio> { 00064 // The Singleton part 00065 friend class Singleton<Audio>; 00066 00067 public: 00068 class FadingType : public Enum<FadingType> { 00069 public: 00070 static Member None; 00071 static Member Out; 00072 static Member In; 00073 }; 00074 00075 class MusicType : public Enum<MusicType> { 00076 public: 00077 static Member None; 00078 static Member Cmd; 00079 static Member WAV; 00080 static Member MOD; 00081 static Member MID; 00082 static Member OGG; 00083 static Member MP3; 00084 }; 00085 00086 typedef BaseFactory<Audio> AudioBaseFactory; 00087 static Factory<Audio, Audio> factory; 00088 00089 //forward declaration needed 00090 class Channel; 00091 /// Audio::Chunk base abstract class 00092 class Chunk { 00093 friend class Audio; 00094 public: 00095 virtual void setVolume(int); 00096 virtual void play(int duration = -1); 00097 virtual void fadeIn(int, int duration = -1); 00098 virtual void fadeOut(int ms); 00099 00100 /// pause chunk 00101 virtual void pause(); 00102 /// resume chunk 00103 virtual void resume(); 00104 /// stop chunk 00105 virtual void stop(int ms = 0); 00106 virtual bool playing() const; 00107 virtual bool paused() const; 00108 00109 //overrides still need to return the base class 00110 //since C++ does not allow to forward declare 00111 //that the Dirver::Channel is a child of Audio::Channel 00112 virtual Channel *channel() const; 00113 template<typename CHILD> 00114 typename CHILD::Channel *channel() const { 00115 return static_cast<typename CHILD::Channel *>(channel()); 00116 } 00117 00118 Signal01<void, Chunk *> finished; 00119 WVar<int> loops; 00120 00121 virtual Chunk *clone() const; 00122 virtual void detach(); 00123 00124 // stops at deletion 00125 virtual ~Chunk(); 00126 00127 protected: 00128 Chunk(); 00129 }; 00130 00131 class Channel { 00132 friend class Audio; 00133 public: 00134 virtual void setVolume(int); 00135 virtual void play(Chunk&, int duration = -1); 00136 virtual void fadeIn(Chunk&, int, int duration = -1); 00137 virtual void fadeOut(int ms); 00138 00139 /// pause channel 00140 virtual void pause(); 00141 /// resume channel 00142 virtual void resume(); 00143 /// stop channel 00144 virtual void stop(int ms = 0); 00145 00146 virtual bool playing() const; 00147 virtual bool paused() const; 00148 virtual int fading() const; 00149 virtual Chunk *chunk() const; 00150 00151 Signal01<void, Channel *> finished; 00152 WVar<int> loops; 00153 00154 virtual ~Channel(); 00155 00156 protected: 00157 Channel(); 00158 }; 00159 00160 virtual Chunk* loadChunk(const std::string&) const; 00161 00162 int numChannels() const; 00163 Channel *operator[](int i) const; 00164 virtual int allocateChannels(int num_channels); 00165 00166 /// pause all channels 00167 virtual void pause(); 00168 /// resume all channels 00169 virtual void resume(); 00170 /// stop all channels 00171 virtual void stop(int ms = 0); 00172 virtual void fadeOut(int); 00173 00174 virtual int playingChannels() const; 00175 virtual int pausedChannels() const; 00176 00177 virtual bool isAvailable() const; 00178 00179 class Event { 00180 public: 00181 Event(Channel *channel, Chunk *chunk) : 00182 channel_(channel), 00183 chunk_(chunk) {} 00184 00185 Channel *channel() const { 00186 return channel_; 00187 } 00188 00189 Chunk* chunk() const { 00190 return chunk_; 00191 } 00192 00193 private: 00194 Channel *channel_; 00195 Chunk* chunk_; 00196 }; 00197 00198 Signal01<void, Channel *> finished; 00199 00200 //music 00201 class Music { 00202 friend class Audio; 00203 protected: 00204 Music(); 00205 public: 00206 virtual ~Music(); 00207 virtual int type() const; 00208 private: 00209 }; 00210 00211 virtual Music *loadMusic(const std::string& filename); 00212 virtual void playMusic(Music&); 00213 virtual void fadeInMusic(Music&, int ms); 00214 virtual void fadeOutMusic(int ms); 00215 virtual void setMusicVolume(int volume); 00216 virtual void pauseMusic(); 00217 virtual void rewindMusic(); 00218 virtual bool setMusicPosition(double start_sec); 00219 virtual void stopMusic(); 00220 virtual bool playingMusic() const; 00221 virtual bool pausedMusic() const; 00222 virtual int musicFading() const; 00223 00224 WVar<int> musicLoops; 00225 00226 sigc::signal<void> musicFinished; 00227 00228 protected: 00229 Audio(); 00230 virtual ~Audio(); 00231 static Audio* load(); 00232 00233 virtual int minHWVolume() const; 00234 virtual int maxHWVolume() const; 00235 int HWVolume(int volume) const; 00236 00237 static const int minVolume = 0; 00238 static const int maxVolume = 1000; 00239 00240 template<typename CHILD> 00241 void adjustAllocatedChannels(int oldnum, int newnum) { 00242 if (oldnum < newnum) { 00243 for (int i = oldnum; i < newnum; i++) { 00244 channels.push_back(new typename CHILD::Channel(i)); 00245 } 00246 } else { // newnum < oldnum 00247 Audio& self = *this; 00248 for (int i = newnum; i < oldnum; i++) { 00249 delete self[i]; 00250 } 00251 self.channels.resize(newnum); 00252 } 00253 } 00254 00255 /// callback called when a channel finishes 00256 static void onChannelFinish(int channel_id); 00257 static void onMusicFinish(); 00258 static void handleAudioEvent(const SDL_Event *event); 00259 00260 std::vector<Channel *> channels; 00261 00262 private: 00263 typedef std::list<AudioBaseFactory *> FactoryList; 00264 static FactoryList factories; 00265 }; 00266 00267 class NullAudio : public Audio { 00268 friend class Singleton<Audio>; 00269 public: 00270 static Factory<Audio, NullAudio> factory; 00271 00272 class Chunk : public Audio::Chunk { 00273 friend class NullAudio; 00274 public: 00275 virtual void play(int duration = -1); 00276 virtual void fadeIn(int, int duration = -1); 00277 virtual Audio::Channel *channel() const; 00278 00279 virtual Audio::Chunk *clone() const; 00280 virtual void detach(); 00281 protected: 00282 Chunk(); 00283 }; 00284 00285 class Channel : public Audio::Channel { 00286 friend class Audio; 00287 friend class NullAudio; 00288 public: 00289 virtual void play(Audio::Chunk&, int duration = -1); 00290 virtual void fadeIn(Audio::Chunk&, int, int duration = -1); 00291 virtual Audio::Chunk *chunk() const; 00292 protected: 00293 Channel(int id = 0); 00294 private: 00295 Audio::Chunk *chunk_p; 00296 }; 00297 00298 virtual Audio::Chunk* loadChunk(const std::string&) const; 00299 00300 virtual void playMusic(Music&); 00301 virtual void fadeInMusic(Music&, int ms); 00302 00303 ~NullAudio(); 00304 00305 protected: 00306 NullAudio(); 00307 static Audio* load(); 00308 private: 00309 }; 00310 00311 } // namespace Wt 00312 00313 #endif // WT_AUDIO_H
This document is licensed under the terms of the GNU Free Documentation License and may be freely distributed under the conditions given by this license.