CUGL 2.1
Cornell University Game Library
|
#include <CUAudioOutput.h>
Public Member Functions | |
AudioOutput () | |
~AudioOutput () | |
const SDL_AudioDeviceID | getAUID () const |
const std::string & | getDevice () const |
bool | isDefault () const |
Uint16 | getCapacity () const |
size_t | getBitRate () const |
bool | attach (const std::shared_ptr< AudioNode > &node) |
std::shared_ptr< AudioNode > | detach () |
std::shared_ptr< AudioNode > | getInput () |
virtual bool | pause () override |
virtual bool | resume () override |
virtual bool | completed () override |
virtual Uint32 | read (float *buffer, Uint32 frames) override |
Uint32 | poll (Uint8 *stream, int len) |
void | reboot () |
Uint64 | getOverhead () const |
virtual bool | mark () override |
virtual bool | unmark () override |
virtual bool | reset () override |
virtual Sint64 | advance (Uint32 frames) override |
virtual Sint64 | getPosition () const override |
virtual Sint64 | setPosition (Uint32 position) override |
virtual double | getElapsed () const override |
virtual double | setElapsed (double time) override |
virtual double | getRemaining () const override |
virtual double | setRemaining (double time) override |
Public Member Functions inherited from cugl::audio::AudioNode | |
AudioNode () | |
virtual | ~AudioNode () |
Uint8 | getChannels () const |
Uint32 | getRate () const |
float | getGain () |
virtual void | setGain (float gain) |
const std::string & | getClassName () const |
const std::string & | getName () const |
void | setName (const std::string name) |
Sint32 | getTag () const |
void | setTag (Sint32 tag) |
virtual std::string | toString (bool verbose=false) const |
operator std::string () const | |
Callback | getCallback () |
void | setCallback (Callback callback) |
virtual bool | isPaused () |
Friends | |
class | cugl::AudioDevices |
Additional Inherited Members | |
Public Types inherited from cugl::audio::AudioNode | |
enum | Action : int { COMPLETE = 0, INTERRUPT = 1, FADE_OUT = 2, FADE_IN = 3, FADE_DIP = 4, LOOPBACK = 5 } |
typedef std::function< void(const std::shared_ptr< AudioNode > &node, Action type)> | Callback |
Static Public Attributes inherited from cugl::audio::AudioNode | |
const static Uint32 | DEFAULT_CHANNELS |
const static Uint32 | DEFAULT_SAMPLING |
Protected Member Functions inherited from cugl::audio::AudioNode | |
void | notify (const std::shared_ptr< AudioNode > &node, Action action) |
Protected Attributes inherited from cugl::audio::AudioNode | |
Uint8 | _channels |
Uint32 | _sampling |
bool | _booted |
std::atomic< float > | _ndgain |
std::atomic< bool > | _paused |
std::atomic< bool > | _polling |
Callback | _callback |
std::atomic< bool > | _calling |
Sint32 | _tag |
std::string | _localname |
std::string | _classname |
size_t | _hashOfName |
This class provides a graph node interface for an audio playback device.
This audio node provides a modern, graph-based approach to sound design. Unlike other audio engines, this output node does not have a dedicated mixer. Instead, you attach the single terminal node of the audio graph to this output device node. The output channels of that node must match with those of this output device.
This method has no public initializers or non-degenerate constructors. That is because all output nodes should be created by the factory methods in AudioDevices. That way, the AudioDevices can properly handle device conflicts as they may arise.
Audio devices in SDL are identified by name. If you have two devices with the same name, SDL will add a distinguishing index to the name. You can see the list of all available devices with the AudioDevices#devices() method. In addition, the empty string may be used to refer to the default devices. Instances of AudioOutput attached to a default device will roll over (if possible) whenever the default device changes.
When deciding on the number of channels, SDL supports 1 (mono), 2 (stereo), 4 (quadrophonic), 6 (5.1 surround), or 8 (7.1 surround) channels for playback. Stereo and quadraphonic are arranged left-right, front-back. For 5.1 surround, they are arranged in the following order.
For 7.1 surround, they are arranged in the same order with the following additional channels.
The audio graph should only be accessed in the main thread. In addition, no methods marked as AUDIO THREAD ONLY should ever be accessed by the user.
This class does not support any actions for the AudioNode#setCallback.
cugl::audio::AudioOutput::AudioOutput | ( | ) |
Creates a degenerate audio output node.
The node has not been initialized, so it is not active. The node must be initialized to be used.
NEVER USE A CONSTRUCTOR WITH NEW. If you want to allocate a node on the heap, use the factory in AudioDevices.
cugl::audio::AudioOutput::~AudioOutput | ( | ) |
Deletes the audio output node, disposing of all resources
|
overridevirtual |
Advances the stream by the given number of frames.
DELEGATED METHOD: This method delegates its call to the input node. It returns -1 if there is no input node or if this method is unsupported in that node
This method only advances the read position, it does not actually read data into a buffer. This method is generally not supported for nodes with real-time input like AudioInput.
frames | The number of frames to advace |
Reimplemented from cugl::audio::AudioNode.
bool cugl::audio::AudioOutput::attach | ( | const std::shared_ptr< AudioNode > & | node | ) |
Attaches an audio graph to this output node.
This method will fail if the channels of the audio graph do not agree with the number of the channels of this node.
node | The terminal node of the audio graph |
|
overridevirtual |
Returns true if this audio node has no more data.
An audio node is typically completed if it return 0 (no frames read) on subsequent calls to read(). However, for infinite-running audio threads, it is possible for this method to return true even when data can still be read; in that case the node is notifying that it should be shut down.
Reimplemented from cugl::audio::AudioNode.
std::shared_ptr<AudioNode> cugl::audio::AudioOutput::detach | ( | ) |
Detaches an audio graph from this output node.
If the method succeeds, it returns the terminal node of the audio graph.
|
inline |
Returns the audio device identifier associated with this audio output.
|
inline |
Returns the native bit rate of this device.
The bit rate is the number of bits per sample. By default, the audio graph assumes 32 bits (for float-sized samples). However, some devices (paricularly Android devices) have a smaller bit rate. This value is used by the internal resampler to convert to the proper rate on output.
|
inline |
Returns the buffer size of this output node.
The buffer value is the number of samples collected at each poll. Smaller buffers clearly tax the CPU, as the node is collecting data at a higher rate. Furthermore, if the value is too small, the time to collect the data may be larger than the time to play it. This will result in pops and crackles in the audio.
However, larger values increase the audio lag. For example, a buffer of 1024 for a sample rate of 48000 Hz corresponds to 21 milliseconds. This is the delay between when sound is gathered and it is played. But this gathering process is also buffered, so this means that any sound effect generated at the same time that the output node executes must wait 42 milliseconds before it can play. A value of 512 is the perferred value for 60 fps framerate. With that said, many devices cannot handle this rate and need a buffer size of 1024 instead.
const std::string& cugl::audio::AudioOutput::getDevice | ( | ) | const |
Returns the device associated with this output node.
|
overridevirtual |
Returns the elapsed time in seconds.
DELEGATED METHOD: This method delegates its call to the input node. It returns -1 if there is no input node or if this method is unsupported in that node
In some nodes like AudioInput, this method is only supported if mark() is set. In that case, the times will be the number of seconds since the mark. Other nodes like AudioPlayer measure from the start of the stream.
Reimplemented from cugl::audio::AudioNode.
|
inline |
Returns the terminal node of the audio graph
Uint64 cugl::audio::AudioOutput::getOverhead | ( | ) | const |
Returns the number of microseconds needed to render the last audio frame.
This method is primarily for debugging.
|
overridevirtual |
Returns the current frame position of this audio node
DELEGATED METHOD: This method delegates its call to the input node. It returns -1 if there is no input node or if this method is unsupported in that node
In some nodes like AudioInput, this method is only supported if mark() is set. In that case, the position will be the number of frames since the mark. Other nodes like AudioPlayer measure from the start of the stream.
Reimplemented from cugl::audio::AudioNode.
|
overridevirtual |
Returns the remaining time in seconds.
DELEGATED METHOD: This method delegates its call to the input node. It returns -1 if there is no input node or if this method is unsupported in that node
In some nodes like AudioInput, this method is only supported if setRemaining() has been called. In that case, the node will be marked as completed after the given number of seconds. This may or may not actually move the read head. For example, in AudioPlayer it will skip to the end of the sample. However, in AudioInput it will simply time out after the given time.
Reimplemented from cugl::audio::AudioNode.
|
inline |
Returns true if this output node is associated with the default device
A graph on the default device will switch devices whenever the default device changes.
|
overridevirtual |
Marks the current read position in the audio steam.
DELEGATED METHOD: This method delegates its call to the input node. It returns false if there is no input node or if this method is unsupported in that node
This method is typically used by reset() to determine where to restore the read position. For some nodes (like AudioInput), this method may start recording data to a buffer, which will continue until reset() is called.
It is possible for reset() to be supported even if this method is not.
Reimplemented from cugl::audio::AudioNode.
|
overridevirtual |
Pauses this node, preventing any data from being read.
If the node is already paused, this method has no effect. Pausing will not go into effect until the next render call in the audio thread.
Reimplemented from cugl::audio::AudioNode.
Uint32 cugl::audio::AudioOutput::poll | ( | Uint8 * | stream, |
int | len | ||
) |
Reads up to the specified number of bytes into the given buffer
AUDIO THREAD ONLY: Users should never access this method directly. The only exception is when the user needs to create a custom subclass of this AudioOutput.
This method is used by the SDL audio interface to process the audio graph. It should never be called by the developer.
stream | The read buffer to store the results |
len | The maximum number of bytes to read |
|
overridevirtual |
Reads up to the specified number of frames into the given buffer
AUDIO THREAD ONLY: Users should never access this method directly. The only exception is when the user needs to create a custom subclass of this AudioOutput.
The buffer should have enough room to store frames * channels elements. The channels are interleaved into the output buffer.
This method will always forward the read position.
buffer | The read buffer to store the results |
frames | The maximum number of frames to read |
Reimplemented from cugl::audio::AudioNode.
void cugl::audio::AudioOutput::reboot | ( | ) |
Reboots the audio output node without interrupting any active polling.
AUDIO THREAD ONLY: Users should never access this method directly. The only exception is when the user needs to create a custom subclass of this AudioNode.
This method will close and reopen the associated audio device. It is primarily used when an node on the default device needs to migrate between devices.
|
overridevirtual |
Resets the read position to the marked position of the audio stream.
DELEGATED METHOD: This method delegates its call to the input node. It returns false if there is no input node or if this method is unsupported in that node
When no mark() is set, the result of this method is node dependent. Some nodes (such as AudioPlayer) will reset to the beginning of the stream, while others (like AudioInput) only support a rest when a mark is set. Pay attention to the return value of this method to see if the call is successful.
Reimplemented from cugl::audio::AudioNode.
|
overridevirtual |
Resumes this previously paused node, allowing data to be read.
If the node is not paused, this method has no effect. It is possible to resume an node that is not yet activated by AudioDevices. When that happens, data will be read as soon as the node becomes active.
Reimplemented from cugl::audio::AudioNode.
|
overridevirtual |
Sets the read position to the elapsed time in seconds.
DELEGATED METHOD: This method delegates its call to the input node. It returns -1 if there is no input node or if this method is unsupported in that node
In some nodes like AudioInput, this method is only supported if mark() is set. In that case, the new time will be meaured from the mark. Other nodes like AudioPlayer measure from the start of the stream.
time | The elapsed time in seconds. |
Reimplemented from cugl::audio::AudioNode.
|
overridevirtual |
Sets the current frame position of this audio node.
DELEGATED METHOD: This method delegates its call to the input node. It returns -1 if there is no input node or if this method is unsupported in that node
In some nodes like AudioInput, this method is only supported if mark() is set. In that case, the position will be the number of frames since the mark. Other nodes like AudioPlayer measure from the start of the stream.
position | the current frame position of this audio node. |
Reimplemented from cugl::audio::AudioNode.
|
overridevirtual |
Sets the remaining time in seconds.
DELEGATED METHOD: This method delegates its call to the input node. It returns -1 if there is no input node or if this method is unsupported in that node
If this method is supported, then the node will be marked as completed after the given number of seconds. This may or may not actually move the read head. For example, in AudioPlayer it will skip to the end of the sample. However, in AudioInput it will simply time out after the given time.
time | The remaining time in seconds. |
Reimplemented from cugl::audio::AudioNode.
|
overridevirtual |
Clears the current marked position.
DELEGATED METHOD: This method delegates its call to the input node. It returns false if there is no input node or if this method is unsupported in that node
If the method mark() started recording to a buffer (such as with AudioInput), this method will stop recording and release the buffer. When the mark is cleared, reset() may or may not work depending upon the specific node.
Reimplemented from cugl::audio::AudioNode.
|
friend |
Allow AudioManager to access intializers