Mercurial > fife-parpg
comparison engine/core/audio/soundemitter.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/log/logger.h" | |
33 #include "util/time/timemanager.h" | |
34 #include "util/base/exception.h" | |
35 #include "soundemitter.h" | |
36 #include "soundmanager.h" | |
37 #include "soundclippool.h" | |
38 | |
39 namespace FIFE { | |
40 static Logger _log(LM_AUDIO); | |
41 | |
42 SoundEmitter::SoundEmitter(SoundManager* manager, SoundClipPool* pool, unsigned int uid) : m_manager(manager), m_pool(pool), m_source(0), m_soundclip(NULL), m_soundclipid(0), m_streamid(0), | |
43 m_emitterid(uid), m_loop(false) { | |
44 if (!m_manager->isActive()) { | |
45 return; | |
46 } | |
47 | |
48 TimeManager::instance()->registerEvent(this); | |
49 setPeriod(-1); | |
50 alGenSources(1, &m_source); | |
51 | |
52 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error creating source") | |
53 } | |
54 | |
55 SoundEmitter::~SoundEmitter() { | |
56 if (!m_manager->isActive()) { | |
57 return; | |
58 } | |
59 | |
60 setPeriod(-1); | |
61 TimeManager::instance()->unregisterEvent(this); | |
62 reset(); | |
63 alDeleteSources(1, &m_source); | |
64 } | |
65 | |
66 void SoundEmitter::reset(bool defaultall) { | |
67 if (m_soundclip != NULL) { | |
68 | |
69 setPeriod(-1); | |
70 alSourceStop(m_source); | |
71 | |
72 // Release all buffers | |
73 alSourcei(m_source, AL_BUFFER, AL_NONE); | |
74 alGetError(); | |
75 | |
76 if (m_soundclip->isStream()) { | |
77 m_soundclip->quitStreaming(m_streamid); | |
78 } | |
79 | |
80 // release the soundclip | |
81 m_pool->release(m_soundclipid, true); | |
82 m_soundclip = NULL; | |
83 | |
84 // default source properties | |
85 if (defaultall) { | |
86 setPosition(0.0f, 0.0f, 0.0f); | |
87 setVelocity(0.0f, 0.0f, 0.0f); | |
88 setGain(1.0f); | |
89 setPositioning(false); | |
90 alSourcei(m_source, AL_LOOPING, AL_FALSE); | |
91 } | |
92 } | |
93 } | |
94 | |
95 void SoundEmitter::release() { | |
96 m_manager->releaseEmitter(m_emitterid); | |
97 } | |
98 | |
99 void SoundEmitter::setSoundClip(unsigned int sound_id) { | |
100 m_soundclipid = sound_id; | |
101 m_soundclip = &(m_pool->getSoundClip(m_soundclipid)); | |
102 m_soundclip->addRef(); | |
103 | |
104 attachSoundClip(); | |
105 } | |
106 | |
107 void SoundEmitter::attachSoundClip() { | |
108 if (!m_soundclip->isStream()) { | |
109 // non-streaming | |
110 alSourceQueueBuffers(m_source, m_soundclip->countBuffers(), m_soundclip->getBuffers()); | |
111 alSourcei(m_source, AL_LOOPING, m_loop ? AL_TRUE : AL_FALSE); | |
112 | |
113 } else { | |
114 // streaming | |
115 m_streamid = m_soundclip->beginStreaming(); | |
116 m_soundclip->acquireStream(m_streamid); | |
117 | |
118 // queue initial buffers | |
119 alSourceQueueBuffers(m_source, BUFFER_NUM, m_soundclip->getBuffers(m_streamid)); | |
120 alSourcei(m_source, AL_LOOPING, AL_FALSE); | |
121 } | |
122 | |
123 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error attaching sound clip") | |
124 } | |
125 | |
126 void SoundEmitter::updateEvent(unsigned long time) { | |
127 ALint procs; | |
128 ALint bufs; | |
129 ALuint buffer; | |
130 | |
131 alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &procs); | |
132 | |
133 while (procs--) { | |
134 alSourceUnqueueBuffers(m_source, 1, &buffer); | |
135 | |
136 if (m_soundclip->getStream(m_streamid, buffer)) { | |
137 // EOF! | |
138 if (m_loop) { | |
139 // play again from the beginning | |
140 m_soundclip->setStreamPos(m_streamid, SD_BYTE_POS, 0); | |
141 m_soundclip->getStream(m_streamid, buffer); | |
142 } else { | |
143 | |
144 // check if the playback has been finished | |
145 alGetSourcei(m_source, AL_BUFFERS_QUEUED, &bufs); | |
146 if (bufs == 0) { | |
147 setPeriod(-1); | |
148 alSourceStop(m_source); | |
149 } | |
150 continue; | |
151 } | |
152 } | |
153 alSourceQueueBuffers(m_source, 1, &buffer); | |
154 } | |
155 | |
156 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error while streaming") | |
157 } | |
158 | |
159 void SoundEmitter::setLooping(bool loop) { | |
160 if (m_soundclip) { | |
161 if (!m_soundclip->isStream()) { | |
162 alSourcei(m_source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE); | |
163 } else { | |
164 alSourcei(m_source, AL_LOOPING, AL_FALSE); | |
165 } | |
166 } | |
167 m_loop = loop; | |
168 } | |
169 | |
170 void SoundEmitter::play() { | |
171 if (m_soundclip) { | |
172 alSourcePlay(m_source); | |
173 if (m_soundclip->isStream()) { | |
174 setPeriod(5000); | |
175 } | |
176 } | |
177 } | |
178 | |
179 void SoundEmitter::stop() { | |
180 if (m_soundclip) { | |
181 alSourceStop(m_source); | |
182 | |
183 if (m_soundclip->isStream()) { | |
184 setPeriod(-1); | |
185 setCursor(SD_BYTE_POS, 0); | |
186 } else { | |
187 alSourceRewind(m_source); | |
188 } | |
189 } | |
190 } | |
191 | |
192 void SoundEmitter::setCursor(SoundPositionType type, float value) { | |
193 if (!m_soundclip) { | |
194 return; | |
195 } | |
196 | |
197 ALint state = 0; | |
198 | |
199 if (!m_soundclip->isStream()) { | |
200 switch(type) { | |
201 case SD_BYTE_POS: | |
202 alSourcef(m_source, AL_BYTE_OFFSET, value); | |
203 break; | |
204 case SD_SAMPLE_POS: | |
205 alSourcef(m_source, AL_SAMPLE_OFFSET, value); | |
206 break; | |
207 case SD_TIME_POS: | |
208 alSourcef(m_source, AL_SEC_OFFSET, value); | |
209 break; | |
210 } | |
211 | |
212 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error setting cursor position") | |
213 } | |
214 else { | |
215 alGetSourcei(m_source, AL_SOURCE_STATE, &state); | |
216 | |
217 if (state == AL_PLAYING || AL_PAUSED) { | |
218 setPeriod(-1); | |
219 alSourceStop(m_source); | |
220 } | |
221 | |
222 m_soundclip->setStreamPos(m_streamid, type, value); | |
223 | |
224 // detach all buffers | |
225 alSourcei(m_source, AL_BUFFER, 0); | |
226 | |
227 // queue the buffers with new data | |
228 m_soundclip->acquireStream(m_streamid); | |
229 alSourceQueueBuffers(m_source, BUFFER_NUM, m_soundclip->getBuffers(m_streamid)); | |
230 | |
231 if (state == AL_PLAYING) { | |
232 setPeriod(5000); | |
233 alSourcePlay(m_source); | |
234 } | |
235 | |
236 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error setting stream cursor position") | |
237 } | |
238 } | |
239 | |
240 float SoundEmitter::getCursor(SoundPositionType type) { | |
241 if (!m_soundclip) { | |
242 return 0.0f; | |
243 } | |
244 | |
245 ALfloat pos = 0.0f; | |
246 | |
247 switch(type) { | |
248 case SD_BYTE_POS: | |
249 alGetSourcef(m_source, AL_BYTE_OFFSET, &pos); | |
250 break; | |
251 case SD_SAMPLE_POS: | |
252 alGetSourcef(m_source, AL_SAMPLE_OFFSET, &pos); | |
253 break; | |
254 case SD_TIME_POS: | |
255 alGetSourcef(m_source, AL_SEC_OFFSET, &pos); | |
256 break; | |
257 } | |
258 | |
259 if (m_soundclip->isStream()) { | |
260 pos += m_soundclip->getStreamPos(m_streamid, type); | |
261 } | |
262 | |
263 CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error getting cursor") | |
264 | |
265 return pos; | |
266 } | |
267 } |