Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Audio::OpenALRenderableStreamingSource Class Reference

#include <OpenALRenderableStreamingSource.h>

Inheritance diagram for Audio::OpenALRenderableStreamingSource:
Audio::RenderableSource Audio::UserData

Public Member Functions

 OpenALRenderableStreamingSource (Source *source)
 
virtual ~OpenALRenderableStreamingSource ()
 
bool shouldBePlaying () const
 
- Public Member Functions inherited from Audio::RenderableSource
virtual ~RenderableSource ()
 
void startPlaying (Timestamp start=0) throw (Exception)
 
void stopPlaying () throw ()
 
bool isPlaying () const throw ()
 
Timestamp getPlayingTime () const throw (Exception)
 
SourcegetSource () const throw ()
 
void seek (Timestamp time) throw (Exception)
 
void update (int flags, const Listener &sceneListener) throw ()
 
- Public Member Functions inherited from Audio::UserData
virtual ~UserData ()
 

Protected Member Functions

virtual void startPlayingImpl (Timestamp start) throw (Exception)
 
virtual void stopPlayingImpl () throw (Exception)
 
virtual bool isPlayingImpl () const throw (Exception)
 
virtual Timestamp getPlayingTimeImpl () const throw (Exception)
 
virtual void updateImpl (int flags, const Listener &sceneListener) throw (Exception)
 
virtual void seekImpl (Timestamp time) throw (Exception)
 
ALuint getALSource () const
 
void queueALBuffers () throw (Exception)
 
- Protected Member Functions inherited from Audio::RenderableSource
 RenderableSource (Source *source) throw ()
 

Additional Inherited Members

- Public Types inherited from Audio::RenderableSource
enum  UpdateFlags {
  UPDATE_ALL = 0x0F, UPDATE_LOCATION = 0x01, UPDATE_ATTRIBUTES = 0x02, UPDATE_EFFECTS = 0x04,
  UPDATE_GAIN = 0x08
}
 

Detailed Description

OpenAL Renderable Source class

Remarks
This class implements the RenderableSource interface for the OpenAL renderer.

Definition at line 23 of file OpenALRenderableStreamingSource.h.

Constructor & Destructor Documentation

Audio::OpenALRenderableStreamingSource::OpenALRenderableStreamingSource ( Source source)

Definition at line 28 of file OpenALRenderableStreamingSource.cpp.

29  : RenderableSource(source)
30  , alSource(0)
31  , atEos(false)
32  , shouldPlay(false)
33  , buffering(false)
34  {
35  alGenSources(1,&alSource);
36  }
Audio::OpenALRenderableStreamingSource::~OpenALRenderableStreamingSource ( )
virtual

Definition at line 38 of file OpenALRenderableStreamingSource.cpp.

39  {
40  alDeleteSources(1,&alSource);
41  }

Member Function Documentation

ALuint Audio::OpenALRenderableStreamingSource::getALSource ( ) const
inlineprotected

Derived classes may use the underlying AL source handle to set additional attributes

Definition at line 63 of file OpenALRenderableStreamingSource.h.

Referenced by getPlayingTimeImpl(), isPlayingImpl(), and queueALBuffers().

63 { return alSource; }
Timestamp Audio::OpenALRenderableStreamingSource::getPlayingTimeImpl ( ) const
throw (Exception
)
protectedvirtual
See Also
RenderableSource::getPlayingTimeImpl.

Implements Audio::RenderableSource.

Definition at line 88 of file OpenALRenderableStreamingSource.cpp.

References AL_SEC_OFFSET, f, getALSource(), Audio::Source::getSound(), and Audio::RenderableSource::getSource().

90  {
91  ALfloat offs = -1.f;
92  alGetSourcef(getALSource(), AL_SEC_OFFSET, &offs);
93 
94  if (offs < 0.f)
95  throw NotImplementedException("getPlayingTimeImpl");
96 
97  Timestamp base = dynamic_cast<OpenALStreamingSound*>(getSource()->getSound().get())
98  ->getTimeBase();
99 
100  return Timestamp(offs) + base;
101  }
bool Audio::OpenALRenderableStreamingSource::isPlayingImpl ( ) const
throw (Exception
)
protectedvirtual
See Also
RenderableSource::isPlayingImpl.

Implements Audio::RenderableSource.

Definition at line 80 of file OpenALRenderableStreamingSource.cpp.

References getALSource().

82  {
83  ALint state = 0;
84  alGetSourcei(getALSource(), AL_SOURCE_STATE, &state);
85  return (state == AL_PLAYING);
86  }
void Audio::OpenALRenderableStreamingSource::queueALBuffers ( )
throw (Exception
)
protected

Queue AL buffers from the source's AL sound stream.

Note
It will fail with an assertion if the attached sound isn't a streaming OpenAL sound
It will not throw an EndOfStream exception, even if the sound reaches the end and it's not a looping source.

Definition at line 193 of file OpenALRenderableStreamingSource.cpp.

References AL_NULL_BUFFER, buffer, e, fprintf, getALSource(), Audio::Source::getSound(), Audio::RenderableSource::getSource(), i, Audio::Source::isLooping(), Audio::OpenALStreamingSound::readAndFlip(), Audio::OpenALStreamingSound::seek(), and Audio::OpenALStreamingSound::unqueueBuffer().

195  {
196  SharedPtr<Sound> sound = getSource()->getSound();
197 
198  if (!sound->isLoaded())
199  sound->load();
200 
201  assert(sound->isStreaming() && "OpenALRenderableStreamingSource can only handle streaming sounds");
202 
203  buffering = true;
204 
205  OpenALStreamingSound *streamingSound = dynamic_cast<OpenALStreamingSound*>(sound.get());
206  Source *source = getSource();
207  ALSourceHandle als = getALSource();
208  ALint buffersProcessed = 0;
209 
210  // Unqueue any buffers the AL is done with,
211  // returning them to the streaming sound
212  alGetSourcei(als, AL_BUFFERS_PROCESSED, &buffersProcessed);
213 
214  while (buffersProcessed > 0) {
215  ALBufferHandle buffers[2];
216  ALsizei nbuffers = (buffersProcessed > 2) ? 2 : (ALsizei)buffersProcessed;
217  alSourceUnqueueBuffers(als, nbuffers, buffers);
218 
219  for (ALsizei i=0; i<nbuffers; ++i)
220  streamingSound->unqueueBuffer(buffers[i]);
221 
222  buffersProcessed -= nbuffers;
223  }
224 
225  // Get buffers from the streaming sound and queue them
226  // until the streaming sound says Basta!
228  do {
229  try {
230  buffer = streamingSound->readAndFlip();
231  } catch(EndOfStreamException e) {
232  fprintf(stderr, "EOS!\n");
233  if (source->isLooping()) {
234  streamingSound->seek(0);
235  buffer = streamingSound->readAndFlip();
236  } else {
237  atEos = true;
238  buffer = AL_NULL_BUFFER;
239  }
240  }
241  if (buffer != AL_NULL_BUFFER)
242  alSourceQueueBuffers(als, 1, &buffer);
243  } while (buffer != AL_NULL_BUFFER);
244  }
void Audio::OpenALRenderableStreamingSource::seekImpl ( Timestamp  time)
throw (Exception
)
protectedvirtual
See Also
RenderableSource::seekImpl.

Implements Audio::RenderableSource.

Definition at line 103 of file OpenALRenderableStreamingSource.cpp.

105  {
106  // Seek the stream to the specified position
107  atEos = false;
108  dynamic_cast<OpenALStreamingSound*>(getSource()->getSound().get())
109  ->seek(time);
110  }
bool Audio::OpenALRenderableStreamingSource::shouldBePlaying ( ) const
inline

Returns whether this stream should be playing

Remarks
Streaming sources may halt due to buffer underruns. By keeping track of the desired state, rather than querying the underlying AL source, we can overcome this problem.

Definition at line 41 of file OpenALRenderableStreamingSource.h.

41 { return shouldPlay && !atEos; }
void Audio::OpenALRenderableStreamingSource::startPlayingImpl ( Timestamp  start)
throw (Exception
)
protectedvirtual
See Also
RenderableSource::startPlayingImpl.

Implements Audio::RenderableSource.

Definition at line 43 of file OpenALRenderableStreamingSource.cpp.

References checkAlError, clearAlError, and start.

45  {
46  if (!isPlayingImpl()) {
47  SharedPtr<Sound> sound = getSource()->getSound();
48 
49  assert(sound->isStreaming() && "OpenALRenderableStreamingSource can only handle streaming sounds");
50 
51  if (!sound->isLoaded())
52  sound->load();
53  else if (!buffering)
54  dynamic_cast<OpenALStreamingSound*>(sound.get())->flushBuffers();
55 
56  // Seek the stream to the specified position
57  atEos = false;
58  shouldPlay = true;
59  dynamic_cast<OpenALStreamingSound*>(sound.get())->seek(start);
60 
61  // Make sure we have some starting buffers queued
63 
64  // Tell the AL to start playing
65  clearAlError();
66  ALuint als = getALSource();
67  alSourcePlay(als);
68  checkAlError();
69  }
70  }
void Audio::OpenALRenderableStreamingSource::stopPlayingImpl ( )
throw (Exception
)
protectedvirtual
See Also
RenderableSource::stopPlayingImpl.

Implements Audio::RenderableSource.

Definition at line 72 of file OpenALRenderableStreamingSource.cpp.

74  {
75  shouldPlay = false;
76  buffering = false;
77  alSourceStop(alSource);
78  }
void Audio::OpenALRenderableStreamingSource::updateImpl ( int  flags,
const Listener sceneListener 
)
throw (Exception
)
protectedvirtual
See Also
RenderableSource::updateImpl.

Implements Audio::RenderableSource.

Definition at line 112 of file OpenALRenderableStreamingSource.cpp.

References Audio::alSource3f(), checkAlError, clearAlError, f, Audio::Source::getAngleRange(), Audio::Source::getDirection(), Audio::Source::getGain(), Audio::Source::getPosition(), Audio::Source::getRadius(), Audio::Source::getSound(), Audio::Source::getVelocity(), Audio::Source::isAttenuated(), Audio::Source::isLooping(), Audio::Source::isRelative(), M_1_PI, Audio::Range< T >::max, and Audio::Range< T >::min.

114  {
115  Source *source = getSource();
116  ALSourceHandle als = getALSource();
117 
118  // Restart playing in case of a buffer underrun,
119  // else just fill buffers
120  if (shouldBePlaying() && !isPlayingImpl()) {
121  // startPlayingImpl(source->getWouldbePlayingTime());
122  // NOTE: Cannot use startPlaying because it stresses the buggy seek method
123  // Must fix that
124 
125  SharedPtr<Sound> sound = source->getSound();
126 
127  if (!sound->isLoaded())
128  sound->load();
129  else if (!buffering)
130  dynamic_cast<OpenALStreamingSound*>(sound.get())->flushBuffers();
131 
132  // Make sure we have some starting buffers queued
133  queueALBuffers();
134 
135  // Tell the AL to start playing
136  clearAlError();
137  ALuint als = getALSource();
138  alSourcePlay(als);
139  checkAlError();
140  } else {
141  queueALBuffers();
142  }
143 
144  // Update various attributes if required
145  clearAlError();
146 
147  if (flags & UPDATE_ATTRIBUTES) {
148  // Distance attenuation
149  if (source->isAttenuated()) {
150  alSourcef(als, AL_REFERENCE_DISTANCE, source->getRadius());
151  alSourcef(als, AL_ROLLOFF_FACTOR, 1.f / source->getRadius());
152  } else {
153  alSourcef(als, AL_ROLLOFF_FACTOR, 0.f);
154  }
155  // Cone
156  {
157  Range<Scalar> angleRange = source->getAngleRange();
158  alSourcef(als, AL_CONE_INNER_ANGLE, float(angleRange.min) * M_1_PI * 360.f);
159  alSourcef(als, AL_CONE_OUTER_ANGLE, float(angleRange.max) * M_1_PI * 360.f);
160  alSourcef(als, AL_CONE_OUTER_GAIN , 0.f);
161  }
162  // Relativity
163  alSourcei(als, AL_SOURCE_RELATIVE, source->isRelative() ? AL_TRUE : AL_FALSE);
164  // Looping
165  alSourcei(als, AL_LOOPING, source->isLooping() ? AL_TRUE : AL_FALSE);
166  }
167  if (flags & UPDATE_GAIN) {
168  // Gain
169  alSourcef(als, AL_GAIN, source->getGain());
170  }
171  if (flags & UPDATE_LOCATION) {
172  if (source->isRelative()) {
173  alSource3f(als, AL_POSITION, source->getPosition());
174  alSource3f(als, AL_VELOCITY, source->getVelocity());
175  alSource3f(als, AL_DIRECTION, source->getDirection());
176  } else {
177  alSource3f(als, AL_POSITION,
178  source->getPosition() - sceneListener.getPosition() );
179  alSource3f(als, AL_VELOCITY,
180  sceneListener.toLocalDirection(
181  source->getVelocity() - sceneListener.getVelocity()
182  ) );
183  alSource3f(als, AL_DIRECTION,
184  sceneListener.toLocalDirection(
185  source->getDirection()
186  ) );
187  }
188  }
189 
190  checkAlError();
191  }

The documentation for this class was generated from the following files: