comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:4a0efb7baf70
1 /***************************************************************************
2 * Copyright (C) 2005-2008 by the FIFE Team *
3 * http://www.fifengine.de *
4 * This file is part of FIFE. *
5 * *
6 * FIFE is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *
20 ***************************************************************************/
21
22 // Standard C++ library includes
23
24 // Platform specific includes
25
26 // 3rd party library includes
27
28 // FIFE includes
29 // These includes are split up in two parts, separated by one empty line
30 // First block: files included from the FIFE root src directory
31 // Second block: files included from the same folder
32 #include "util/base/exception.h"
33 #include "util/log/logger.h"
34
35 #include "soundclip.h"
36
37 namespace FIFE {
38 static Logger _log(LM_AUDIO);
39
40 SoundClip::SoundClip(SoundDecoder* decptr, bool deletedecoder) : m_location(ResourceLocation("")), m_isstream(decptr->needsStreaming()), m_decoder(decptr), m_deletedecoder(deletedecoder) {
41 if (!m_isstream) {
42
43 // only for non-streaming buffers
44 SoundBufferEntry* ptr = new SoundBufferEntry();
45
46 // iterate the bufs and fill them with data
47 for (int i = 0; i < BUFFER_NUM; i++) {
48
49 if (m_decoder->decode(BUFFER_LEN)) {
50 // EOF or error
51 break;
52 }
53
54 // generate buffer and fill it with data
55 alGenBuffers(1, &ptr->buffers[i]);
56
57 alBufferData(ptr->buffers[i], m_decoder->getALFormat(), m_decoder->getBuffer(),
58 m_decoder->getBufferSize(), m_decoder->getSampleRate());
59
60 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error copying data to buffers")
61
62 ptr->usedbufs++;
63 }
64
65 m_decoder->releaseBuffer();
66
67 // push the buffer information to the vector
68 m_buffervec.push_back(ptr);
69
70 }
71 }
72
73 unsigned int SoundClip::beginStreaming() {
74 // create new sound buffer entry
75 SoundBufferEntry* ptr = new SoundBufferEntry();
76 ptr->usedbufs=0;
77 alGenBuffers(BUFFER_NUM, ptr->buffers);
78
79 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error creating streaming-buffers")
80
81 m_buffervec.push_back(ptr);
82
83 return m_buffervec.size()-1;
84 }
85
86 bool SoundClip::setStreamPos(unsigned int streamid, SoundPositionType type, float value) {
87 unsigned long pos = 0;
88
89 // convert position to bytes
90 switch (type) {
91 case SD_BYTE_POS:
92 pos = static_cast<unsigned long>(value);
93 break;
94 case SD_TIME_POS:
95 value *= m_decoder->getSampleRate();
96 case SD_SAMPLE_POS:
97 pos = static_cast<unsigned long>((m_decoder->getBitResolution() / 8) * (m_decoder->isStereo() ? 2 : 1) * value);
98 break;
99 }
100
101 if (pos > m_decoder->getDecodedLength()) {
102 // EOF!
103 return true;
104 }
105
106 // set cursor position
107 m_buffervec.at(streamid)->deccursor = pos;
108 return false;
109 }
110
111 float SoundClip::getStreamPos(unsigned int streamid, SoundPositionType type) {
112 unsigned long pos = m_buffervec.at(streamid)->deccursor;
113 switch(type) {
114 case SD_BYTE_POS:
115 return pos;
116 case SD_SAMPLE_POS:
117 return pos / (m_decoder->getBitResolution() / 8 * (m_decoder->isStereo() ? 2 : 1));
118 case SD_TIME_POS:
119 return pos / (m_decoder->getBitResolution() / 8 * (m_decoder->isStereo() ? 2 : 1) * m_decoder->getSampleRate());
120 }
121 return 0.0f;
122 }
123
124 void SoundClip::acquireStream(unsigned int streamid) {
125
126 SoundBufferEntry* ptr = m_buffervec.at(streamid);
127
128 for (int i = 0; i < BUFFER_NUM; i++) {
129 getStream(streamid, ptr->buffers[i]);
130 }
131 }
132
133 bool SoundClip::getStream(unsigned int streamid, ALuint buffer) {
134
135 SoundBufferEntry* ptr = m_buffervec.at(streamid);
136
137 if (ptr->deccursor >= m_decoder->getDecodedLength()) {
138 // EOF!
139 return true;
140 }
141
142 // set cursor of decoder
143 m_decoder->setCursor(ptr->deccursor);
144
145 // Error while decoding file?
146 if (m_decoder->decode(BUFFER_LEN)) {
147 throw Exception("error while reading from audio file");
148 }
149
150 // fill the buffer with data
151 alBufferData(buffer, m_decoder->getALFormat(),
152 m_decoder->getBuffer(), m_decoder->getBufferSize(), m_decoder->getSampleRate());
153
154 m_decoder->releaseBuffer();
155
156 // update cursor
157 ptr->deccursor += BUFFER_LEN;
158
159 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error catching stream")
160
161 return false;
162 }
163
164 void SoundClip::quitStreaming(unsigned int streamid) {
165 // release the buffers
166 SoundBufferEntry* ptr = m_buffervec.at(streamid);
167 alDeleteBuffers(BUFFER_NUM, ptr->buffers);
168 ptr->buffers[0] = 0;
169 }
170
171 SoundClip::~SoundClip() {
172 if (m_isstream) {
173 // erase all elements from the list
174 std::vector<SoundBufferEntry*>::iterator it;
175
176 for (it = m_buffervec.begin(); it != m_buffervec.end(); ++it) {
177 if ((*it)->buffers[0] != 0) {
178 alDeleteBuffers(BUFFER_NUM, (*it)->buffers);
179 }
180 delete (*it);
181 }
182 m_buffervec.clear();
183 }
184 else {
185 // for non-streaming soundclips
186 SoundBufferEntry* ptr = m_buffervec.at(0);
187
188 for(unsigned int i = 0; i < ptr->usedbufs; i++) {
189 alDeleteBuffers(1, &ptr->buffers[i]);
190 }
191 }
192
193 // delete decoder
194 if (m_deletedecoder && m_decoder != NULL) {
195 delete m_decoder;
196 }
197 }
198 }