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 }