Mercurial > fife-parpg
view engine/core/audio/soundclip.cpp @ 392:fa77b6927d3d
More complete changelog for 0.3.0 release
author | cheesesucker@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sun, 24 Jan 2010 16:07:10 +0000 |
parents | 64738befdf3b |
children |
line wrap: on
line source
/*************************************************************************** * Copyright (C) 2005-2008 by the FIFE team * * http://www.fifengine.de * * This file is part of FIFE. * * * * FIFE is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with this library; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * ***************************************************************************/ // Standard C++ library includes // Platform specific includes // 3rd party library includes // FIFE includes // These includes are split up in two parts, separated by one empty line // First block: files included from the FIFE root src directory // Second block: files included from the same folder #include "util/base/exception.h" #include "util/log/logger.h" #include "soundclip.h" namespace FIFE { static Logger _log(LM_AUDIO); SoundClip::SoundClip(SoundDecoder* decptr, bool deletedecoder) : m_isstream(decptr->needsStreaming()), m_decoder(decptr), m_deletedecoder(deletedecoder) { if (!m_isstream) { // only for non-streaming buffers SoundBufferEntry* ptr = new SoundBufferEntry(); // iterate the bufs and fill them with data for (int i = 0; i < BUFFER_NUM; i++) { if (m_decoder->decode(BUFFER_LEN)) { // EOF or error break; } // generate buffer and fill it with data alGenBuffers(1, &ptr->buffers[i]); alBufferData(ptr->buffers[i], m_decoder->getALFormat(), m_decoder->getBuffer(), m_decoder->getBufferSize(), m_decoder->getSampleRate()); CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error copying data to buffers") ptr->usedbufs++; } m_decoder->releaseBuffer(); // push the buffer information to the vector m_buffervec.push_back(ptr); } } unsigned int SoundClip::beginStreaming() { // create new sound buffer entry SoundBufferEntry* ptr = new SoundBufferEntry(); ptr->usedbufs=0; alGenBuffers(BUFFER_NUM, ptr->buffers); CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error creating streaming-buffers") m_buffervec.push_back(ptr); return m_buffervec.size()-1; } bool SoundClip::setStreamPos(unsigned int streamid, SoundPositionType type, float value) { unsigned long pos = 0; // convert position to bytes switch (type) { case SD_BYTE_POS: pos = static_cast<unsigned long>(value); break; case SD_TIME_POS: value *= m_decoder->getSampleRate(); case SD_SAMPLE_POS: pos = static_cast<unsigned long>((m_decoder->getBitResolution() / 8) * (m_decoder->isStereo() ? 2 : 1) * value); break; } if (pos > m_decoder->getDecodedLength()) { // EOF! return true; } // set cursor position m_buffervec.at(streamid)->deccursor = pos; return false; } float SoundClip::getStreamPos(unsigned int streamid, SoundPositionType type) const{ unsigned long pos = m_buffervec.at(streamid)->deccursor; switch(type) { case SD_BYTE_POS: return pos; case SD_SAMPLE_POS: return pos / (m_decoder->getBitResolution() / 8 * (m_decoder->isStereo() ? 2 : 1)); case SD_TIME_POS: return pos / (m_decoder->getBitResolution() / 8 * (m_decoder->isStereo() ? 2 : 1) * m_decoder->getSampleRate()); } return 0.0f; } void SoundClip::acquireStream(unsigned int streamid) { SoundBufferEntry* ptr = m_buffervec.at(streamid); for (int i = 0; i < BUFFER_NUM; i++) { getStream(streamid, ptr->buffers[i]); } } bool SoundClip::getStream(unsigned int streamid, ALuint buffer) { SoundBufferEntry* ptr = m_buffervec.at(streamid); if (ptr->deccursor >= m_decoder->getDecodedLength()) { // EOF! return true; } // set cursor of decoder m_decoder->setCursor(ptr->deccursor); // Error while decoding file? if (m_decoder->decode(BUFFER_LEN)) { throw Exception("error while reading from audio file"); } // fill the buffer with data alBufferData(buffer, m_decoder->getALFormat(), m_decoder->getBuffer(), m_decoder->getBufferSize(), m_decoder->getSampleRate()); m_decoder->releaseBuffer(); // update cursor ptr->deccursor += BUFFER_LEN; CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error catching stream") return false; } void SoundClip::quitStreaming(unsigned int streamid) { // release the buffers SoundBufferEntry* ptr = m_buffervec.at(streamid); alDeleteBuffers(BUFFER_NUM, ptr->buffers); ptr->buffers[0] = 0; } SoundClip::~SoundClip() { if (m_isstream) { // erase all elements from the list std::vector<SoundBufferEntry*>::iterator it; for (it = m_buffervec.begin(); it != m_buffervec.end(); ++it) { if ((*it)->buffers[0] != 0) { alDeleteBuffers(BUFFER_NUM, (*it)->buffers); } delete (*it); } m_buffervec.clear(); } else { // for non-streaming soundclips SoundBufferEntry* ptr = m_buffervec.at(0); for(unsigned int i = 0; i < ptr->usedbufs; i++) { alDeleteBuffers(1, &ptr->buffers[i]); } } // delete decoder if (m_deletedecoder && m_decoder != NULL) { delete m_decoder; } } }