audio.cpp

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 #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

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.