33 #include "util/base/exception.h"
34 #include "util/log/logger.h"
35 #include "loaders/native/audio/ogg_loader.h"
37 #include "soundclip.h"
40 static Logger _log(LM_AUDIO);
42 SoundClip::SoundClip(IResourceLoader* loader) :
43 IResource(createUniqueClipName(), loader),
46 m_deletedecoder(
false) {
50 SoundClip::SoundClip(
const std::string& name, IResourceLoader* loader) :
51 IResource(name, loader),
54 m_deletedecoder(
false) {
58 void SoundClip::load(){
63 if(m_name.find(
".ogg", m_name.size() - 4) != std::string::npos) {
67 FL_WARN(_log,
LMsg() <<
"No audio-decoder available for file \"" << m_name <<
"\"!");
68 throw InvalidFormat(
"Error: Ogg loader can't load files without ogg extension");
74 m_isstream = m_decoder->needsStreaming();
79 SoundBufferEntry* ptr =
new SoundBufferEntry();
82 for (int32_t i = 0; i < BUFFER_NUM; i++) {
84 if (m_decoder->decode(BUFFER_LEN)) {
90 alGenBuffers(1, &ptr->buffers[i]);
92 alBufferData(ptr->buffers[i], m_decoder->getALFormat(), m_decoder->getBuffer(),
93 m_decoder->getBufferSize(), m_decoder->getSampleRate());
95 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR,
"error copying data to buffers")
100 m_decoder->releaseBuffer();
103 m_buffervec.push_back(ptr);
107 m_state = IResource::RES_LOADED;
110 void SoundClip::free(){
111 if (m_state == IResource::RES_LOADED) {
114 std::vector<SoundBufferEntry*>::iterator it;
116 for (it = m_buffervec.begin(); it != m_buffervec.end(); ++it) {
117 if ((*it)->buffers[0] != 0) {
118 alDeleteBuffers(BUFFER_NUM, (*it)->buffers);
126 SoundBufferEntry* ptr = m_buffervec.at(0);
128 for(uint32_t i = 0; i < ptr->usedbufs; i++) {
129 alDeleteBuffers(1, &ptr->buffers[i]);
133 m_state = IResource::RES_NOT_LOADED;
138 SoundBufferEntry* ptr =
new SoundBufferEntry();
140 alGenBuffers(BUFFER_NUM, ptr->buffers);
142 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR,
"error creating streaming-buffers")
144 m_buffervec.push_back(ptr);
146 return m_buffervec.size()-1;
155 pos =
static_cast<uint64_t
>(value);
158 value *= m_decoder->getSampleRate();
160 pos =
static_cast<uint64_t
>((m_decoder->getBitResolution() / 8) * (m_decoder->isStereo() ? 2 : 1) * value);
164 if (pos > m_decoder->getDecodedLength()) {
170 m_buffervec.at(streamid)->deccursor = pos;
175 uint64_t pos = m_buffervec.at(streamid)->deccursor;
180 return pos / (m_decoder->getBitResolution() / 8 * (m_decoder->isStereo() ? 2 : 1));
182 return pos / (m_decoder->getBitResolution() / 8 * (m_decoder->isStereo() ? 2 : 1) * m_decoder->getSampleRate());
189 SoundBufferEntry* ptr = m_buffervec.at(streamid);
191 for (int32_t i = 0; i < BUFFER_NUM; i++) {
198 SoundBufferEntry* ptr = m_buffervec.at(streamid);
200 if (ptr->deccursor >= m_decoder->getDecodedLength()) {
206 m_decoder->setCursor(ptr->deccursor);
209 if (m_decoder->decode(BUFFER_LEN)) {
210 throw Exception(
"error while reading from audio file");
214 alBufferData(buffer, m_decoder->getALFormat(),
215 m_decoder->getBuffer(), m_decoder->getBufferSize(), m_decoder->getSampleRate());
217 m_decoder->releaseBuffer();
220 ptr->deccursor += BUFFER_LEN;
222 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR,
"error catching stream")
229 SoundBufferEntry* ptr = m_buffervec.at(streamid);
230 alDeleteBuffers(BUFFER_NUM, ptr->buffers);
234 SoundClip::~SoundClip() {
238 if (m_deletedecoder && m_decoder != NULL) {
243 std::string SoundClip::createUniqueClipName() {
245 static uint32_t uniqueNumber = 0;
246 static std::string baseName =
"soundclip";
248 std::ostringstream oss;
249 oss << uniqueNumber <<
"_" << baseName;
251 const std::string name = oss.str();
bool getStream(uint32_t streamid, ALuint buffer)
void acquireStream(uint32_t streamid)
float getStreamPos(uint32_t streamid, SoundPositionType type) const
void quitStreaming(uint32_t streamid)
bool setStreamPos(uint32_t streamid, SoundPositionType type, float value)
uint32_t beginStreaming()
credit to phoku for his NodeDisplay example which the visitor code is adapted from ( he coded the qua...