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::OpenALStreamingSound Class Reference

#include <OpenALStreamingSound.h>

Inheritance diagram for Audio::OpenALStreamingSound:
Audio::SimpleSound Audio::Sound

Public Member Functions

 OpenALStreamingSound (const std::string &name, VSFileSystem::VSFileType type=VSFileSystem::UnknownFile, unsigned int bufferSamples=0) throw ()
 
virtual ~OpenALStreamingSound ()
 
ALBufferHandle readAndFlip () throw (Exception)
 
void unqueueBuffer (ALBufferHandle buffer) throw (Exception)
 
void flushBuffers () throw ()
 
Timestamp getTimeBase () const throw ()
 
void seek (double position) throw (Exception)
 
- Public Member Functions inherited from Audio::SimpleSound
virtual ~SimpleSound ()
 
VSFileSystem::VSFileType getType () const
 
- Public Member Functions inherited from Audio::Sound
virtual ~Sound ()
 
const std::string & getName () const throw ()
 
const FormatgetFormat () const throw ()
 
bool isLoaded () const throw ()
 
bool isLoading () const throw ()
 
bool isStreaming () const throw ()
 
void load (bool wait=true) throw (Exception)
 
void unload () throw ()
 

Protected Member Functions

virtual void loadImpl (bool wait) throw (Exception)
 
virtual void unloadImpl () throw ()
 
- Protected Member Functions inherited from Audio::SimpleSound
 SimpleSound (const std::string &name, VSFileSystem::VSFileType type=VSFileSystem::UnknownFile, bool streaming=false) throw ()
 
bool isStreamLoaded () const
 
void loadStream () throw (Exception)
 
void closeStream () throw (ResourceNotLoadedException)
 
SharedPtr< StreamgetStream () const throw (ResourceNotLoadedException)
 
void readBuffer (SoundBuffer &buffer) throw (Exception)
 
virtual void abortLoad () throw ()
 
- Protected Member Functions inherited from Audio::Sound
 Sound (const std::string &name, bool streaming) throw ()
 
FormatgetFormat () throw ()
 
virtual void onLoaded (bool success) throw ()
 
virtual void waitLoad () throw (Exception)
 

Additional Inherited Members

- Protected Attributes inherited from Audio::Sound
struct Audio::Sound::Flags flags
 

Detailed Description

OpenAL Streaming Sound implementation class

Remarks
This class implements streaming OpenAL sounds. This will load the sound in chunks into OpenAL buffers, with double-buffering to make certain there's something to be played while the application is loading the next.

A package-private function is called to fill buffers for a configurable amount of buffer time - whenever a source is playing this sound, this has to happen regularly.

See Also
Sound, SimpleSound

Definition at line 34 of file OpenALStreamingSound.h.

Constructor & Destructor Documentation

Audio::OpenALStreamingSound::OpenALStreamingSound ( const std::string &  name,
VSFileSystem::VSFileType  type = VSFileSystem::UnknownFile,
unsigned int  bufferSamples = 0 
)
throw (
)

Internal constructor used by derived classes

Parameters
namethe resource's name
typethe resource's type
bufferSampleshow many samples a single buffer should hold. remember double buffering is used, so this holds the number of samples below which a read would be triggered.

Definition at line 29 of file OpenALStreamingSound.cpp.

References AL_NULL_BUFFER, i, and NUM_BUFFERS.

31  :
32  SimpleSound(name, type, true),
33  bufferSamples(_bufferSamples)
34  {
35  for (size_t i=0; i < NUM_BUFFERS; ++i)
36  bufferHandles[i] = AL_NULL_BUFFER;
37  }
Audio::OpenALStreamingSound::~OpenALStreamingSound ( )
virtual

Definition at line 39 of file OpenALStreamingSound.cpp.

40  {
41  }

Member Function Documentation

void Audio::OpenALStreamingSound::flushBuffers ( )
throw (
)

Reset the buffer queue

Definition at line 94 of file OpenALStreamingSound.cpp.

References NUM_BUFFERS.

96  {
97  // Mark as detached, so that readAndFlip() knows to initialize the source
98  // and streaming indices
99  readBufferIndex = 0;
100 
101  // Mark the playBufferIndex as uninitialized, by setting it to NUM_BUFFERS
102  // readAndFlip will initialize it later.
103  playBufferIndex = NUM_BUFFERS;
104  }
Timestamp Audio::OpenALStreamingSound::getTimeBase ( ) const
throw (
)

Get the time base of the stream

Returns
The timestamp of the first unreturned buffer's starting point.

Definition at line 166 of file OpenALStreamingSound.cpp.

168  {
169  return bufferStarts[playBufferIndex];
170  }
void Audio::OpenALStreamingSound::loadImpl ( bool  wait)
throw (Exception
)
protectedvirtual

Load the resource

Note
Assume it is unloaded and not loading

Implements Audio::Sound.

Definition at line 43 of file OpenALStreamingSound.cpp.

References buffer, checkAlError, clearAlError, e, max(), and NUM_BUFFERS.

45  {
46  // just in case
47  unloadImpl();
48 
49  try {
50 
51  flags.loading = 1;
52 
53  // load the stream
54  try {
55  loadStream();
56  } catch(ResourceAlreadyLoadedException e) {
57  // Weird...
58  getStream()->seek(0);
59  }
60  SharedPtr<Stream> stream = getStream();
61 
62  // setup formatted buffer
63  // if the format does not match an OpenAL built-in format, we must convert it.
64  targetFormat = stream->getFormat();
65  targetFormat.signedSamples = (targetFormat.bitsPerSample > 8);
66  targetFormat.nativeOrder = 1;
67  if (targetFormat.bitsPerSample > 8)
68  targetFormat.bitsPerSample = 16;
69  else
70  targetFormat.bitsPerSample = 8;
71 
72  // Set capacity to a quarter second or 16k samples, whatever's bigger
73  // TODO: make it configurable. But first, implement a central configuration repository.
74  bufferSamples = std::max( 16384U, targetFormat.sampleFrequency/4 );
75 
76  // Prepare a buffer, so we avoid repeated allocation/deallocation
77  buffer.reserve(bufferSamples, targetFormat);
78 
79  // Prepare AL buffers
80  clearAlError();
81  alGenBuffers(NUM_BUFFERS, bufferHandles);
82  checkAlError();
83 
84  // Initialize the buffer queue
85  flushBuffers();
86 
87  onLoaded(true);
88  } catch(Exception e) {
89  onLoaded(false);
90  throw e;
91  }
92  }
ALBufferHandle Audio::OpenALStreamingSound::readAndFlip ( )
throw (Exception
)

Keep buffers going.

Returns
An AL buffer handle that can be queued in an AL streaming source, or AL_NULL_BUFFER if there's no available buffer for the operation (which means the source should free some buffers)
Remarks
It will check the buffer queue, and if there are free buffers, it will free one with new data. Basically, if you call this function often enough, you'll keep the source playing.
Exceptions
EndOfStreamExceptionwhen there's no more data to feed from the stream. You may seek the stream and keep going, for instance, for a looping stream. Any other exception would be fatal.

Definition at line 115 of file OpenALStreamingSound.cpp.

References AL_NULL_BUFFER, Audio::__impl::OpenAL::asALFormat(), buffer, checkAlError, clearAlError, UnitUtil::getName(), and NUM_BUFFERS.

Referenced by Audio::OpenALRenderableStreamingSource::queueALBuffers().

117  {
118  if (!isLoaded())
119  throw ResourceNotLoadedException(getName());
120 
121  // Check for a full queue
122  if (playBufferIndex == readBufferIndex)
123  return AL_NULL_BUFFER;
124 
125  bufferStarts[readBufferIndex] = getStream()->getPosition();
126 
128 
129  // Break if there's no more data
130  if (buffer.getUsedBytes() == 0)
131  throw EndOfStreamException();
132 
133  ALBufferHandle bufferHandle = bufferHandles[readBufferIndex];
134 
135  clearAlError();
136  alBufferData(bufferHandle,
137  asALFormat(targetFormat),
138  buffer.getBuffer(), buffer.getUsedBytes(),
139  targetFormat.sampleFrequency);
140  checkAlError();
141 
142  if (playBufferIndex == NUM_BUFFERS)
143  playBufferIndex = readBufferIndex;
144 
145  readBufferIndex = (readBufferIndex + 1) % NUM_BUFFERS;
146  return bufferHandle;
147  }
void Audio::OpenALStreamingSound::seek ( double  position)
throw (Exception
)

Set the stream's position, in seconds

See Also
Stream::seek(double)

Definition at line 157 of file OpenALStreamingSound.cpp.

References UnitUtil::getName().

Referenced by Audio::OpenALRenderableStreamingSource::queueALBuffers().

159  {
160  if (!isLoaded())
161  throw ResourceNotLoadedException(getName());
162 
163  getStream()->seek(position);
164  }
void Audio::OpenALStreamingSound::unloadImpl ( )
throw (
)
protectedvirtual

Unload the resource.

Note
Assume it is loaded

Implements Audio::Sound.

Definition at line 106 of file OpenALStreamingSound.cpp.

References AL_NULL_BUFFER.

108  {
109  if (isStreamLoaded())
110  closeStream();
111  if (bufferHandles[0] != AL_NULL_BUFFER)
112  alDeleteBuffers(sizeof(bufferHandles)/sizeof(bufferHandles[0]), bufferHandles);
113  }
void Audio::OpenALStreamingSound::unqueueBuffer ( ALBufferHandle  buffer)
throw (Exception
)

Notify a dequeued buffer

Remarks
The function will not do anything, but it will mark the specified buffer as dequeued, allowing readAndFlip() to use it for new data. The caller is expected to have detached the buffer from the source.

Definition at line 149 of file OpenALStreamingSound.cpp.

References buffer, and NUM_BUFFERS.

Referenced by Audio::OpenALRenderableStreamingSource::queueALBuffers().

151  {
152  if (playBufferIndex < NUM_BUFFERS && buffer == bufferHandles[playBufferIndex]) {
153  playBufferIndex = (playBufferIndex + 1) % NUM_BUFFERS;
154  }
155  }

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