FIFE
2008.0
|
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 }