00001 #ifndef H_SDLPP_SOUND
00002 #define H_SDLPP_SOUND
00003
00004 #include "sdlpp_common.h"
00005 #include "sdlpp_io.h"
00006
00007 class MP3Decoder;
00008
00009 namespace SDLPP {
00010
00011 const int SOUND_BUFFER_SIZE = 1024;
00012
00014
00015
00016
00017
00018
00019
00021
00022
00023
00024
00025
00026
00027
00028
00029
00038 class SoundClip : public RefCount
00039 {
00040 public:
00042 SoundClip(const xstring& filename="", ResourceFile* rf=0);
00044 SoundClip(std::istream* is);
00045 virtual ~SoundClip();
00046 SoundClip(const SoundClip& rhs);
00047 SoundClip& operator= (const SoundClip& rhs);
00048
00050 void play(bool loop=false);
00051 protected:
00052 void destroy();
00053 private:
00054 void load_from_rwop(SDL_RWops* rwops, const char* name);
00055 void load(const xstring& filename);
00056 void load(std::istream* is);
00057 friend class SoundManager;
00058 Uint8* m_Buffer;
00059 Uint32 m_Length;
00060 bool m_Converted;
00061 };
00062
00071 class SoundStream : public RefCount
00072 {
00073 public:
00075 SoundStream(const xstring& filename="");
00077 SoundStream(std::istream* is);
00079 SoundStream(ResourceFile& rf, const xstring& name);
00080 virtual ~SoundStream();
00081 SoundStream(const SoundStream& rhs);
00082 SoundStream& operator= (const SoundStream& rhs);
00083
00085 void play();
00086
00088 void stop();
00089 protected:
00090 void destroy();
00091
00092 virtual Uint8* get_frame(int bytes);
00093 private:
00094 void load_from_rwop(SDL_RWops* rwops, const char* name);
00095 void load(const xstring& filename);
00096 void load(std::istream* is);
00097 friend class SoundManager;
00098 friend struct SoundStream_Thread;
00099
00100 int frames_available();
00101 int frames_to_fill();
00102
00103 int decode_thread();
00104
00105 struct Data
00106 {
00107 Data(int size)
00108 : m_DataStream(0),
00109 m_Source(0),
00110 m_Decoder(0),
00111 m_Buffer(new Uint8[size]),
00112 m_Start(0),
00113 m_Stop(0),
00114 m_DecodeThread(0),
00115 m_Semaphore(0),
00116 m_Finished(false),
00117 m_ThreadDone(false)
00118 {}
00119 std::istream* m_DataStream;
00120 SDL_RWops* m_Source;
00121
00122 MP3Decoder* m_Decoder;
00123 std::vector<Uint8> m_EncodedStream;
00124 Uint8* m_Buffer;
00125 int m_Start,m_Stop;
00126 SDL_Thread* m_DecodeThread;
00127 SDL_sem* m_Semaphore;
00128 bool m_Finished;
00129 bool m_ThreadDone;
00130 } *m_Data;
00131 };
00132
00137 class SoundManager : public Singleton
00138 {
00139 struct SoundClipState
00140 {
00141 SoundClipState(SoundClip c, bool l) : clip(c), pos(0), loop(l) {}
00142 SoundClip clip;
00143 int pos;
00144 bool loop;
00145 };
00146
00147 typedef std::list<SoundClipState> clip_seq;
00148 typedef std::list<SoundStream> stream_seq;
00149 clip_seq m_Clips;
00150 stream_seq m_Streams;
00151 double m_Gain,m_dGain;
00152 bool m_Fading;
00153
00154 void cleanup();
00155 void AudioCallback(Uint8 *stream, int len);
00156 static void AudioCallback(void *userdata, Uint8 *stream, int len);
00157 static Accumulator<int> s_MixingBuffer;
00158 public:
00160 static SoundManager* instance(bool destroy=false)
00161 {
00162 static SoundManager* ptr=0;
00163 if (!ptr && !destroy) ptr=new SoundManager;
00164 else
00165 if (ptr && destroy) { delete ptr; ptr=0; }
00166 return ptr;
00167 }
00168
00171 virtual void shutdown();
00172
00175 void initialize(int freq, bool stereo);
00176
00178 void pause(bool state=true);
00179
00182 void clear(int duration=0);
00183
00188 int get_freq() const { return m_Spec.freq; }
00189 bool is_stereo() const { return m_Spec.channels==2; }
00190
00192 void play(SoundClip clip, bool loop);
00193
00195 void play(SoundStream stream);
00196
00197 SDL_AudioSpec* get_audio_spec() { return &m_Spec; }
00198 private:
00199 friend class std::auto_ptr<SoundManager>;
00200 SoundManager() : m_Fading(false), m_Gain(1.0), m_dGain(0.0) {}
00201 ~SoundManager()
00202 {
00203 SDL_CloseAudio();
00204 }
00205 SoundManager(const SoundManager&) {}
00206
00207 SDL_AudioSpec m_Spec;
00208 };
00209
00210
00211 }
00212
00213
00214 #endif // H_SDLPP_SOUND
00215
00216