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