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 #include <SDL/SDL_events.h> 00022 00023 #include <boost/assign/list_of.hpp> 00024 00025 #include "sdlevent.h" 00026 #include "sdlmixer.h" 00027 00028 #include <wt/trace.h> 00029 #include <wt/application.h> 00030 #include <wt/audio.h> 00031 00032 namespace Wt { 00033 00034 Factory<Audio, NullAudio> NullAudio::factory; 00035 00036 Audio::FactoryList Audio::factories= boost::assign::list_of<AudioBaseFactory *> 00037 (&SDLMixer::factory) 00038 (&NullAudio::factory); 00039 00040 Audio::FadingType::Member Audio::FadingType::None = 0; 00041 Audio::FadingType::Member Audio::FadingType::Out; 00042 Audio::FadingType::Member Audio::FadingType::In; 00043 00044 Audio::MusicType::Member Audio::MusicType::None = 0; 00045 Audio::MusicType::Member Audio::MusicType::Cmd; 00046 Audio::MusicType::Member Audio::MusicType::WAV; 00047 Audio::MusicType::Member Audio::MusicType::MOD; 00048 Audio::MusicType::Member Audio::MusicType::MID; 00049 Audio::MusicType::Member Audio::MusicType::OGG; 00050 Audio::MusicType::Member Audio::MusicType::MP3; 00051 00052 Audio::Audio() 00053 : Singleton<Audio>(this), 00054 musicLoops(1) { 00055 SDLEvent& sdlevent = *SDLEvent::instance(); 00056 sdlevent[SDLEvent::Audio] = &handleAudioEvent; 00057 } 00058 00059 Audio::~Audio() { 00060 trace("audio", "Entering Destructor for Audio\n"); 00061 } 00062 00063 Audio* Audio::load() { 00064 //this code never runs if we are initialized 00065 FactoryList::iterator it = factories.begin(), end = factories.end(); 00066 Audio *audio; 00067 00068 trace("audio", "Audio initialization...\n"); 00069 do { 00070 audio = (*it)->instance(); 00071 ++it; 00072 } while (!audio && it != end); 00073 00074 trace("audio", "Audio driver %p\n", instance_); 00075 return audio; 00076 } 00077 00078 Audio::Chunk* Audio::loadChunk(const std::string&) const { 00079 return 0; 00080 } 00081 00082 int Audio::numChannels() const { 00083 return channels.size(); 00084 } 00085 00086 Audio::Channel *Audio::operator[](int i) const { 00087 return channels[i]; 00088 } 00089 00090 int Audio::allocateChannels(int) { 00091 return channels.size(); 00092 } 00093 00094 /// pause all channels 00095 void Audio::pause() {} 00096 00097 /// resume all channels 00098 void Audio::resume() {} 00099 00100 /// stop all channels 00101 void Audio::stop(int) {} 00102 00103 void Audio::fadeOut(int) {} 00104 00105 int Audio::playingChannels() const { 00106 return 0; 00107 } 00108 00109 int Audio::pausedChannels() const { 00110 return 0; 00111 } 00112 00113 bool Audio::isAvailable() const { 00114 return false; 00115 } 00116 00117 // ************* music ***************** 00118 Audio::Music *Audio::loadMusic(const std::string&) { 00119 return new Music; 00120 } 00121 00122 Audio::Music::Music() {} 00123 Audio::Music::~Music() {} 00124 00125 void Audio::playMusic(Music&) { 00126 trace("audio", "Audio::playMusic() called\n"); 00127 } 00128 00129 void Audio::fadeInMusic(Music&, int) {} 00130 00131 void Audio::fadeOutMusic(int) {} 00132 00133 void Audio::setMusicVolume(int) {} 00134 00135 void Audio::pauseMusic() {} 00136 00137 void Audio::rewindMusic() {} 00138 00139 bool Audio::setMusicPosition(double) { 00140 return false; 00141 } 00142 00143 void Audio::stopMusic() {} 00144 00145 bool Audio::playingMusic() const { 00146 return false; 00147 } 00148 00149 bool Audio::pausedMusic() const { 00150 return false; 00151 } 00152 00153 int Audio::musicFading() const { 00154 return 0; 00155 } 00156 00157 int Audio::Music::type() const { 00158 return 0; 00159 } 00160 00161 int Audio::minHWVolume() const { 00162 return 0; 00163 } 00164 00165 int Audio::maxHWVolume() const { 00166 return 1; 00167 } 00168 00169 int Audio::HWVolume(int volume) const { 00170 return (maxHWVolume() - minHWVolume()) * volume / 00171 (maxVolume - minVolume); 00172 } 00173 00174 /*! posts a SDL type event (SDLEvent::Audio) 00175 in the SDL event queue. By the time the event 00176 it is dispatched all SDL actions are allowed. 00177 */ 00178 void Audio::onChannelFinish(int channel_id) { 00179 Audio& self = *instance(); 00180 Channel *channel = self.channels[channel_id]; 00181 Chunk *chunk = channel->chunk(); 00182 00183 SDL_Event event; 00184 00185 event.type = SDLEvent::Audio; 00186 event.user.code = 0; 00187 event.user.data1 = new Event(channel, chunk); 00188 event.user.data2 = 0; 00189 00190 trace("audio", "channelFinished callback called %d\n", channel_id); 00191 SDLEvent::push(&event); 00192 } 00193 00194 /*! posts a SDL type event (SDLEvent::Audio) 00195 in the SDL event queue. By the time the event 00196 it is dispatched all SDL actions are allowed. 00197 */ 00198 void Audio::onMusicFinish() { 00199 SDL_Event event; 00200 00201 event.type = SDLEvent::Audio; 00202 event.user.code = 0; 00203 event.user.data1 = new Event(0, 0); 00204 event.user.data2 = 0; 00205 00206 trace("audio", "musicFinished callback called\n"); 00207 00208 SDLEvent::push(&event); 00209 } 00210 00211 /// SDLEvent::Audio handler 00212 /*! it emits the required signal to all interested parties */ 00213 void Audio::handleAudioEvent(const SDL_Event *event) { 00214 trace("audio", "audio event delivered\n"); 00215 Event *sdl_audio_event = static_cast<Event *>(event->user.data1); 00216 Chunk *chunk = sdl_audio_event->chunk(); 00217 Channel *channel = sdl_audio_event->channel(); 00218 if (chunk && channel) { 00219 chunk->finished(chunk); 00220 channel->finished(channel); 00221 instance()->finished(channel); 00222 } else { 00223 instance()->musicFinished(); 00224 } 00225 delete sdl_audio_event; 00226 } 00227 00228 // ********* Audio::Chunk *************** 00229 00230 Audio::Chunk::Chunk() 00231 : loops(1) {} 00232 00233 Audio::Chunk::~Chunk() { 00234 stop(); 00235 } 00236 00237 void Audio::Chunk::setVolume(int) {} 00238 00239 void Audio::Chunk::play(int) {} 00240 00241 void Audio::Chunk::fadeIn(int, int) {} 00242 00243 void Audio::Chunk::fadeOut(int) {} 00244 00245 /// pause chunk 00246 void Audio::Chunk::pause() {} 00247 00248 /// resume chunk 00249 void Audio::Chunk::resume() {} 00250 00251 /// stop chunk 00252 void Audio::Chunk::stop(int) {} 00253 00254 bool Audio::Chunk::playing() const { 00255 return false; 00256 } 00257 00258 bool Audio::Chunk::paused() const { 00259 return false; 00260 } 00261 00262 Audio::Channel *Audio::Chunk::channel() const { 00263 return 0; 00264 } 00265 00266 Audio::Chunk *Audio::Chunk::clone() const { 00267 return 0; 00268 } 00269 00270 void Audio::Chunk::detach() {} 00271 00272 // ********* Audio::Channel *************** 00273 00274 Audio::Channel::Channel() : 00275 loops(1) {} 00276 00277 Audio::Channel::~Channel() {} 00278 00279 void Audio::Channel::setVolume(int) {} 00280 00281 void Audio::Channel::play(Chunk&, int) { 00282 trace("audio", "Audio::Channel::play()\n"); 00283 } 00284 00285 void Audio::Channel::fadeIn(Chunk&, int, int) {} 00286 00287 void Audio::Channel::fadeOut(int) {} 00288 00289 /// pause channel 00290 void Audio::Channel::pause() {} 00291 00292 /// resume channel 00293 void Audio::Channel::resume() {} 00294 00295 /// stop channel 00296 void Audio::Channel::stop(int) {} 00297 00298 bool Audio::Channel::playing() const { 00299 return false; 00300 } 00301 00302 bool Audio::Channel::paused() const { 00303 return false; 00304 } 00305 00306 int Audio::Channel::fading() const { 00307 return 0; 00308 } 00309 00310 Audio::Chunk *Audio::Channel::chunk() const { 00311 return 0; 00312 } 00313 00314 // ********* NullAudio *************** 00315 00316 NullAudio::NullAudio() { 00317 // allocate one channel so we don't crash 00318 adjustAllocatedChannels<NullAudio>(0, 1); 00319 } 00320 00321 NullAudio::~NullAudio() { 00322 allocateChannels(0); 00323 } 00324 00325 Audio* NullAudio::load() { 00326 trace("audio", "NullAudio initialization...ok\n"); 00327 return new NullAudio; 00328 } 00329 00330 Audio::Chunk* NullAudio::loadChunk(const std::string&) const { 00331 return new Chunk; 00332 } 00333 00334 // ********* NullAudio::Chunk *************** 00335 00336 NullAudio::Chunk::Chunk() : Audio::Chunk() {} 00337 00338 Audio::Channel *NullAudio::Chunk::channel() const { 00339 // we go through this to avoid protections 00340 NullAudio& self = * static_cast<NullAudio *>(instance()); 00341 return static_cast<NullAudio::Channel *>(self.channels[0]); 00342 } 00343 00344 void NullAudio::Chunk::play(int duration) { 00345 trace("audio", "NullAudio::Chunk::play()\n"); 00346 Audio::Chunk::channel<NullAudio>()->play(*this, duration); 00347 } 00348 00349 void NullAudio::Chunk::fadeIn(int ms, int duration) { 00350 trace("audio", "NullAudio::Chunk::fadeIn()\n"); 00351 Audio::Chunk::channel<NullAudio>()->fadeIn(*this, ms, duration); 00352 } 00353 00354 Audio::Chunk *NullAudio::Chunk::clone() const { 00355 return new Chunk; 00356 } 00357 00358 void NullAudio::Chunk::detach() {} 00359 00360 // ********* NullAudio::Channel *************** 00361 00362 NullAudio::Channel::Channel(int) : Audio::Channel() {} 00363 00364 void NullAudio::Channel::play(Audio::Chunk& chunk, int) { 00365 trace("audio", "NullAudio::Channel::play()\n"); 00366 chunk_p = &chunk; 00367 onChannelFinish(0); 00368 } 00369 00370 void NullAudio::Channel::fadeIn(Audio::Chunk& chunk, int, int) { 00371 trace("audio", "NullAudio::Channel::fadeIn()\n"); 00372 chunk_p = &chunk; 00373 onChannelFinish(0); 00374 } 00375 00376 Audio::Chunk *NullAudio::Channel::chunk() const { 00377 return chunk_p; 00378 } 00379 00380 void NullAudio::playMusic(Music&) { 00381 trace("audio", "NullAudio::playMusic() called\n"); 00382 onMusicFinish(); 00383 } 00384 00385 void NullAudio::fadeInMusic(Music&, int) { 00386 onMusicFinish(); 00387 } 00388 00389 } // namespace Wt
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.