Mercurial > fife-parpg
diff engine/core/audio/soundclip.cpp @ 0:4a0efb7baf70
* Datasets becomes the new trunk and retires after that :-)
author | mvbarracuda@33b003aa-7bff-0310-803a-e67f0ece8222 |
---|---|
date | Sun, 29 Jun 2008 18:44:17 +0000 |
parents | |
children | 90005975cdbb |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/engine/core/audio/soundclip.cpp Sun Jun 29 18:44:17 2008 +0000 @@ -0,0 +1,198 @@ +/*************************************************************************** + * 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 General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program 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 General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin St, 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_location(ResourceLocation("")), 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) { + 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; + } + } +}