FIFE
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
soundemitter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2013 by the FIFE team *
3  * http://www.fifengine.net *
4  * This file is part of FIFE. *
5  * *
6  * FIFE is free software; you can redistribute it and/or *
7  * modify it under the terms of the GNU Lesser General Public *
8  * License as published by the Free Software Foundation; either *
9  * version 2.1 of the License, or (at your option) any later version. *
10  * *
11  * This library 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 GNU *
14  * Lesser General Public License for more details. *
15  * *
16  * You should have received a copy of the GNU Lesser General Public *
17  * License along with this library; if not, write to the *
18  * Free Software Foundation, Inc., *
19  * 51 Franklin Street, 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 "soundclipmanager.h"
38 
39 namespace FIFE {
40  static Logger _log(LM_AUDIO);
41 
42  SoundEmitter::SoundEmitter(SoundManager* manager, uint32_t uid) : m_manager(manager), m_source(0), m_soundclip(), m_soundclipid(0), m_streamid(0),
43  m_emitterid(uid), m_loop(false) {
44  if (!m_manager->isActive()) {
45  return;
46  }
47 
49  setPeriod(-1);
50  alGenSources(1, &m_source);
51  CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error creating source")
52  }
53 
55  if (!m_manager->isActive()) {
56  return;
57  }
58 
59  setPeriod(-1);
61  reset();
62  alDeleteSources(1, &m_source);
63  }
64 
65  void SoundEmitter::reset(bool defaultall) {
66  if (m_soundclip) {
67 
68  setPeriod(-1);
69  alSourceStop(m_source);
70 
71  // Release all buffers
72  alSourcei(m_source, AL_BUFFER, AL_NONE);
73  alGetError();
74 
75  if (m_soundclip->isStream()) {
77  }
78 
79  // release the soundclip
80  //SoundClipManager::instance()->free(m_soundclipid);
82 
83  // default source properties
84  if (defaultall) {
85  setPosition(0.0f, 0.0f, 0.0f);
86  setVelocity(0.0f, 0.0f, 0.0f);
87  setGain(1.0f);
88  setPositioning(false);
89  alSourcei(m_source, AL_LOOPING, AL_FALSE);
90  }
91  }
92  }
93 
96  }
97 
99  m_soundclipid = soundclip->getHandle();
100  m_soundclip = soundclip;
101 
102  attachSoundClip();
103  }
104 
106  m_callback = cb;
107  }
108 
110  if (!m_soundclip->isStream()) {
111  // non-streaming
112  alSourceQueueBuffers(m_source, m_soundclip->countBuffers(), m_soundclip->getBuffers());
113  alSourcei(m_source, AL_LOOPING, m_loop ? AL_TRUE : AL_FALSE);
114 
115  } else {
116  // streaming
119 
120  // queue initial buffers
121  alSourceQueueBuffers(m_source, BUFFER_NUM, m_soundclip->getBuffers(m_streamid));
122  alSourcei(m_source, AL_LOOPING, AL_FALSE);
123  }
124 
125  CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error attaching sound clip")
126  }
127 
129  ALint procs;
130  ALint bufs;
131  ALuint buffer;
132 
133  alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &procs);
134 
135  while (procs--) {
136  alSourceUnqueueBuffers(m_source, 1, &buffer);
137 
138  if (m_soundclip->getStream(m_streamid, buffer)) {
139  // EOF!
140  if (m_loop) {
141  // play again from the beginning
143  m_soundclip->getStream(m_streamid, buffer);
144  } else {
145 
146  // check if the playback has been finished
147  alGetSourcei(m_source, AL_BUFFERS_QUEUED, &bufs);
148  if (bufs == 0) {
149  setPeriod(-1);
150  alSourceStop(m_source);
151  if(m_callback) {
152  m_callback();
153  }
154  }
155  continue;
156  }
157  }
158  alSourceQueueBuffers(m_source, 1, &buffer);
159  }
160 
161  CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error while streaming")
162  }
163 
164  void SoundEmitter::setLooping(bool loop) {
165  if (m_soundclip) {
166  if (!m_soundclip->isStream()) {
167  alSourcei(m_source, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
168  } else {
169  alSourcei(m_source, AL_LOOPING, AL_FALSE);
170  }
171  }
172  m_loop = loop;
173  }
174 
176  if (m_soundclip) {
177  alSourcePlay(m_source);
178  if (m_soundclip->isStream()) {
179  setPeriod(5000);
180  }
181  }
182  }
183 
185  if (m_soundclip) {
186  alSourceStop(m_source);
187 
188  if (m_soundclip->isStream()) {
189  setPeriod(-1);
191  } else {
192  alSourceRewind(m_source);
193  }
194  }
195  }
196 
197  void SoundEmitter::setCursor(SoundPositionType type, float value) {
198  if (!m_soundclip) {
199  return;
200  }
201 
202  ALint state = 0;
203 
204  if (!m_soundclip->isStream()) {
205  switch(type) {
206  case SD_BYTE_POS:
207  alSourcef(m_source, AL_BYTE_OFFSET, value);
208  break;
209  case SD_SAMPLE_POS:
210  alSourcef(m_source, AL_SAMPLE_OFFSET, value);
211  break;
212  case SD_TIME_POS:
213  alSourcef(m_source, AL_SEC_OFFSET, value);
214  break;
215  }
216 
217  CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error setting cursor position")
218  }
219  else {
220  alGetSourcei(m_source, AL_SOURCE_STATE, &state);
221 
222  if (state == AL_PLAYING || AL_PAUSED) {
223  setPeriod(-1);
224  alSourceStop(m_source);
225  }
226 
227  m_soundclip->setStreamPos(m_streamid, type, value);
228 
229  // detach all buffers
230  alSourcei(m_source, AL_BUFFER, 0);
231 
232  // queue the buffers with new data
234  alSourceQueueBuffers(m_source, BUFFER_NUM, m_soundclip->getBuffers(m_streamid));
235 
236  if (state == AL_PLAYING) {
237  setPeriod(5000);
238  alSourcePlay(m_source);
239  }
240 
241  CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error setting stream cursor position")
242  }
243  }
244 
246  if (!m_soundclip) {
247  return 0.0f;
248  }
249 
250  ALfloat pos = 0.0f;
251 
252  switch(type) {
253  case SD_BYTE_POS:
254  alGetSourcef(m_source, AL_BYTE_OFFSET, &pos);
255  break;
256  case SD_SAMPLE_POS:
257  alGetSourcef(m_source, AL_SAMPLE_OFFSET, &pos);
258  break;
259  case SD_TIME_POS:
260  alGetSourcef(m_source, AL_SEC_OFFSET, &pos);
261  break;
262  }
263 
264  if (m_soundclip->isStream()) {
265  pos += m_soundclip->getStreamPos(m_streamid, type);
266  }
267 
268  CHECK_OPENAL_LOG(_log, LogManager::LEVEL_ERROR, "error getting cursor")
269 
270  return pos;
271  }
272 }
bool getStream(uint32_t streamid, ALuint buffer)
Refill a processed buffer with new data.
Definition: soundclip.cpp:196
void setGain(float gain)
Sets the gain of the emitter.
Definition: soundemitter.h:128
void registerEvent(TimeEvent *event)
Adds a TimeEvent.
Definition: timemanager.cpp:84
void reset(bool defaultall=false)
Reset the emitter, free all internal buffers.
void reset(T *ptr=0)
reset this pointer to a null shared pointer this can be used to lower the reference count of the shar...
Definition: sharedptr.h:164
void setCallback(const type_callback &cb)
Sets the callback to use when the STREAM has finished being played.
uint32_t m_soundclipid
Definition: soundemitter.h:228
static Logger _log(LM_AUDIO)
#define CHECK_OPENAL_LOG(logger, level, msg)
Definition: fife_openal.h:61
bool isStream() const
Does this SoundClip require a streaming mechanism?
Definition: soundclip.h:70
bool isActive() const
Returns true if audio module is active.
Definition: soundmanager.h:121
static TimeManager * instance()
Definition: singleton.h:84
boost::function0< void > type_callback
Definition: soundemitter.h:48
void release()
Releases the emitter.
void setCursor(SoundPositionType type, float value)
Sets the cursor position in the audio file.
void unregisterEvent(TimeEvent *event)
Removes a TimeEvent.
Definition: timemanager.cpp:89
void acquireStream(uint32_t streamid)
Fills the streaming-buffers with initial data.
Definition: soundclip.cpp:187
void setSoundClip(SoundClipPtr soundclip)
Sets the sound clip to be used by this emitter.
SoundPositionType
Different types of audio-file positions.
Definition: soundclip.h:44
void attachSoundClip()
Internal function to attach a soundclip to the source.
void setPosition(float x, float y, float z)
Sets the position of the SoundEmitter in the virtual audio space.
Definition: soundemitter.h:206
void play()
Plays the associated audio file.
type_callback m_callback
Definition: soundemitter.h:232
float getCursor(SoundPositionType type)
Returns the cursor position in the audio file.
float getStreamPos(uint32_t streamid, SoundPositionType type) const
Gets the stream position.
Definition: soundclip.cpp:174
SoundClipPtr m_soundclip
Definition: soundemitter.h:227
void setLooping(bool loop)
Sets the playing mode.
virtual void updateEvent(uint32_t time)
Implementation of the pure virtual function from TimeEvent to update streaming.
void setVelocity(float x, float y, float z)
Sets the velocity of the SoundEmitter in the virtual audio space.
Definition: soundemitter.h:212
void setPeriod(int32_t period)
Set the period of the event.
Definition: timeevent.cpp:56
void quitStreaming(uint32_t streamid)
Quits Streaming.
Definition: soundclip.cpp:227
void setPositioning(bool relative)
Sets Positioning-Type Default is false.
Definition: soundemitter.h:65
ALuint * getBuffers(uint32_t streamid=0) const
Returns the array of buffers for queuing.
Definition: soundclip.h:86
uint32_t countBuffers() const
Returns the number of buffers used by the SoundClip (only for non-streaming sound clips) ...
Definition: soundclip.h:79
SoundEmitter(SoundManager *manager, uint32_t uid)
const int16_t BUFFER_NUM
Definition: soundconfig.h:43
SoundManager * m_manager
Definition: soundemitter.h:225
void stop()
Stops playing the audio file and rewinds to the beginning.
unsigned int uint32_t
Definition: core.h:40
ResourceHandle getHandle()
Definition: resource.h:68
bool setStreamPos(uint32_t streamid, SoundPositionType type, float value)
Sets the stream position.
Definition: soundclip.cpp:149
uint32_t beginStreaming()
Starts streaming the soundclip.
Definition: soundclip.cpp:136
void releaseEmitter(uint32_t emitterid)
Release an emitter-instance given by emitter-id.