FIFE  2008.0
 All Classes Namespaces Functions Variables Enumerations Enumerator
soundclip.cpp
00001 /***************************************************************************
00002  *   Copyright (C) 2005-2008 by the FIFE team                              *
00003  *   http://www.fifengine.de                                               *
00004  *   This file is part of FIFE.                                            *
00005  *                                                                         *
00006  *   FIFE is free software; you can redistribute it and/or                 *
00007  *   modify it under the terms of the GNU Lesser General Public            *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2.1 of the License, or (at your option) any later version.    *
00010  *                                                                         *
00011  *   This library is distributed in the hope that it will be useful,       *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00014  *   Lesser General Public License for more details.                       *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Lesser General Public      *
00017  *   License along with this library; if not, write to the                 *
00018  *   Free Software Foundation, Inc.,                                       *
00019  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
00020  ***************************************************************************/
00021 
00022 // Standard C++ library includes
00023 
00024 // Platform specific includes
00025 
00026 // 3rd party library includes
00027 
00028 // FIFE includes
00029 // These includes are split up in two parts, separated by one empty line
00030 // First block: files included from the FIFE root src directory
00031 // Second block: files included from the same folder
00032 #include "util/base/exception.h"
00033 #include "util/log/logger.h"
00034 
00035 #include "soundclip.h"
00036 
00037 namespace FIFE {
00038     static Logger _log(LM_AUDIO);
00039 
00040     SoundClip::SoundClip(SoundDecoder* decptr, bool deletedecoder) : m_isstream(decptr->needsStreaming()), m_decoder(decptr), m_deletedecoder(deletedecoder) {
00041         if (!m_isstream) {
00042             
00043             // only for non-streaming buffers
00044             SoundBufferEntry* ptr = new SoundBufferEntry();
00045             
00046             // iterate the bufs and fill them with data
00047             for (int i = 0; i < BUFFER_NUM; i++) {
00048                 
00049                 if (m_decoder->decode(BUFFER_LEN)) {
00050                     // EOF or error
00051                     break;
00052                 }
00053                 
00054                 // generate buffer and fill it with data
00055                 alGenBuffers(1, &ptr->buffers[i]);
00056                 
00057                 alBufferData(ptr->buffers[i], m_decoder->getALFormat(), m_decoder->getBuffer(),
00058                     m_decoder->getBufferSize(), m_decoder->getSampleRate());
00059                 
00060                 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error copying data to buffers")
00061                     
00062                 ptr->usedbufs++;
00063             }
00064             
00065             m_decoder->releaseBuffer();
00066             
00067             // push the buffer information to the vector
00068             m_buffervec.push_back(ptr);
00069             
00070         }
00071     }
00072     
00073     unsigned int SoundClip::beginStreaming() {
00074         // create new sound buffer entry
00075         SoundBufferEntry* ptr = new SoundBufferEntry();
00076         ptr->usedbufs=0;
00077         alGenBuffers(BUFFER_NUM, ptr->buffers);
00078 
00079         CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error creating streaming-buffers")
00080         
00081         m_buffervec.push_back(ptr);
00082         
00083         return m_buffervec.size()-1;
00084     }
00085     
00086     bool SoundClip::setStreamPos(unsigned int streamid, SoundPositionType type, float value) {
00087         unsigned long pos = 0;
00088         
00089         // convert position to bytes
00090         switch (type) {
00091             case SD_BYTE_POS:
00092                 pos = static_cast<unsigned long>(value);
00093                 break;
00094             case SD_TIME_POS:
00095                 value *= m_decoder->getSampleRate();
00096             case SD_SAMPLE_POS:
00097                 pos = static_cast<unsigned long>((m_decoder->getBitResolution() / 8) * (m_decoder->isStereo() ? 2 : 1) * value);
00098                 break;
00099         }
00100         
00101         if (pos > m_decoder->getDecodedLength()) {
00102             // EOF!
00103             return true;
00104         }
00105         
00106         // set cursor position
00107         m_buffervec.at(streamid)->deccursor = pos;
00108         return false;
00109     }
00110     
00111     float SoundClip::getStreamPos(unsigned int streamid, SoundPositionType type) const{
00112         unsigned long pos = m_buffervec.at(streamid)->deccursor;
00113         switch(type) {
00114             case SD_BYTE_POS:
00115                 return pos;
00116             case SD_SAMPLE_POS:
00117                 return pos / (m_decoder->getBitResolution() / 8 * (m_decoder->isStereo() ? 2 : 1));
00118             case SD_TIME_POS:
00119                 return pos / (m_decoder->getBitResolution() / 8 * (m_decoder->isStereo() ? 2 : 1) * m_decoder->getSampleRate());
00120         }
00121         return 0.0f;
00122     }
00123     
00124     void SoundClip::acquireStream(unsigned int streamid) {
00125         
00126         SoundBufferEntry* ptr = m_buffervec.at(streamid);
00127         
00128         for (int i = 0; i < BUFFER_NUM; i++) {
00129             getStream(streamid, ptr->buffers[i]);
00130         }
00131     }
00132     
00133     bool SoundClip::getStream(unsigned int streamid, ALuint buffer) {
00134         
00135         SoundBufferEntry* ptr = m_buffervec.at(streamid);
00136         
00137         if (ptr->deccursor >= m_decoder->getDecodedLength()) {
00138             // EOF!
00139             return true;
00140         }
00141         
00142         // set cursor of decoder
00143         m_decoder->setCursor(ptr->deccursor);
00144 
00145         // Error while decoding file?
00146         if (m_decoder->decode(BUFFER_LEN)) {
00147             throw Exception("error while reading from audio file");
00148         }
00149 
00150         // fill the buffer with data
00151         alBufferData(buffer, m_decoder->getALFormat(),
00152             m_decoder->getBuffer(), m_decoder->getBufferSize(), m_decoder->getSampleRate());
00153             
00154         m_decoder->releaseBuffer();
00155             
00156         // update cursor
00157         ptr->deccursor += BUFFER_LEN;
00158 
00159         CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error catching stream")
00160         
00161         return false;
00162     }
00163     
00164     void SoundClip::quitStreaming(unsigned int streamid) {
00165         // release the buffers
00166         SoundBufferEntry* ptr = m_buffervec.at(streamid);
00167         alDeleteBuffers(BUFFER_NUM, ptr->buffers);
00168         ptr->buffers[0] = 0;
00169     }
00170     
00171     SoundClip::~SoundClip() {
00172         if (m_isstream) {
00173             // erase all elements from the list
00174             std::vector<SoundBufferEntry*>::iterator it;
00175         
00176             for (it = m_buffervec.begin(); it != m_buffervec.end(); ++it) {
00177                 if ((*it)->buffers[0] != 0) {
00178                     alDeleteBuffers(BUFFER_NUM, (*it)->buffers);
00179                 }
00180                 delete (*it);
00181             }
00182             m_buffervec.clear();
00183         }
00184         else {
00185             // for non-streaming soundclips
00186             SoundBufferEntry* ptr = m_buffervec.at(0);
00187             
00188             for(unsigned int i = 0; i < ptr->usedbufs; i++) {
00189                 alDeleteBuffers(1, &ptr->buffers[i]);
00190             }
00191         }
00192 
00193         // delete decoder
00194         if (m_deletedecoder && m_decoder != NULL) {
00195             delete m_decoder;
00196         }
00197     }
00198 }