audio.h

Go to the documentation of this file.
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

Generated Fri Jul 28 19:22:59 2006.
Copyright © 1998-2003 by the respective authors.

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.