CUGL 1.3
Cornell University Game Library
Public Member Functions | Friends | List of all members
cugl::audio::AudioOutput Class Reference

#include <CUAudioOutput.h>

Inheritance diagram for cugl::audio::AudioOutput:
cugl::audio::AudioNode

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< AudioNodedetach ()
 
std::shared_ptr< AudioNodegetInput ()
 
virtual bool pause () override
 
virtual bool resume () override
 
virtual bool completed () override
 
virtual Uint32 read (float *buffer, Uint32 frames) override
 
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 & getName () const
 
void setName (const std::string &name)
 
void setName (const char *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::AudioManager
 

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
 
- Public Attributes inherited from cugl::audio::AudioNode
std::string _classname
 
- 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
 
size_t _hashOfName
 

Detailed Description

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 AudioManager. That way, the AudioManager 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 AudioManager#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.

  1. front-left
  2. front-right
  3. center
  4. subwoofer/low-frequency
  5. rear left
  6. rear right

For 7.1 surround, they are arranged in the same order with the following additional channels.

  1. side left
  2. side right

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.

Constructor & Destructor Documentation

◆ AudioOutput()

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 AudioManager.

◆ ~AudioOutput()

cugl::audio::AudioOutput::~AudioOutput ( )

Deletes the audio output node, disposing of all resources

Member Function Documentation

◆ advance()

virtual Sint64 cugl::audio::AudioOutput::advance ( Uint32  frames)
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.

Parameters
framesThe number of frames to advace
Returns
the actual number of frames advanced; -1 if not supported

Reimplemented from cugl::audio::AudioNode.

◆ attach()

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.

Parameters
nodeThe terminal node of the audio graph
Returns
true if the attachment was successful

◆ completed()

virtual bool cugl::audio::AudioOutput::completed ( )
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.

Returns
true if this audio node has no more data.

Reimplemented from cugl::audio::AudioNode.

◆ detach()

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.

Returns
the terminal node of the audio graph (or null if failed)

◆ getAUID()

const SDL_AudioDeviceID cugl::audio::AudioOutput::getAUID ( ) const
inline

Returns the audio device identifier associated with this audio output.

Returns
the audio device identifier associated with this audio output.

◆ getBitRate()

size_t cugl::audio::AudioOutput::getBitRate ( ) const
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.

Returns
the native bit rate of this device.

◆ getCapacity()

Uint16 cugl::audio::AudioOutput::getCapacity ( ) const
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.

Returns
the buffer size of this output node.

◆ getDevice()

const std::string& cugl::audio::AudioOutput::getDevice ( ) const

Returns the device associated with this output node.

Returns
the device associated with this output node.

◆ getElapsed()

virtual double cugl::audio::AudioOutput::getElapsed ( ) const
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.

Returns
the elapsed time in seconds.

Reimplemented from cugl::audio::AudioNode.

◆ getInput()

std::shared_ptr<AudioNode> cugl::audio::AudioOutput::getInput ( )
inline

Returns the terminal node of the audio graph

Returns
the terminal node of the audio graph

◆ getOverhead()

Uint64 cugl::audio::AudioOutput::getOverhead ( ) const

Returns the number of microseconds needed to render the last audio frame.

This method is primarily for debugging.

Returns
the number of microseconds needed to render the last audio frame.

◆ getPosition()

virtual Sint64 cugl::audio::AudioOutput::getPosition ( ) const
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.

Returns
the current frame position of this audio node.

Reimplemented from cugl::audio::AudioNode.

◆ getRemaining()

virtual double cugl::audio::AudioOutput::getRemaining ( ) const
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.

Returns
the remaining time in seconds.

Reimplemented from cugl::audio::AudioNode.

◆ isDefault()

bool cugl::audio::AudioOutput::isDefault ( ) const
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.

Returns
true if this audio graph is associated with the default device

◆ mark()

virtual bool cugl::audio::AudioOutput::mark ( )
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.

Returns
true if the read position was marked.

Reimplemented from cugl::audio::AudioNode.

◆ pause()

virtual bool cugl::audio::AudioOutput::pause ( )
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.

Returns
true if the node was successfully paused

Reimplemented from cugl::audio::AudioNode.

◆ read()

virtual Uint32 cugl::audio::AudioOutput::read ( float *  buffer,
Uint32  frames 
)
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.

Parameters
bufferThe read buffer to store the results
framesThe maximum number of frames to read
Returns
the actual number of frames read

Reimplemented from cugl::audio::AudioNode.

◆ reboot()

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.

◆ reset()

virtual bool cugl::audio::AudioOutput::reset ( )
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.

Returns
true if the read position was moved.

Reimplemented from cugl::audio::AudioNode.

◆ resume()

virtual bool cugl::audio::AudioOutput::resume ( )
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 AudioManager. When that happens, data will be read as soon as the node becomes active.

Returns
true if the node was successfully resumed

Reimplemented from cugl::audio::AudioNode.

◆ setElapsed()

virtual double cugl::audio::AudioOutput::setElapsed ( double  time)
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.

Parameters
timeThe elapsed time in seconds.
Returns
the new elapsed time in seconds.

Reimplemented from cugl::audio::AudioNode.

◆ setPosition()

virtual Sint64 cugl::audio::AudioOutput::setPosition ( Uint32  position)
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.

Parameters
positionthe current frame position of this audio node.
Returns
the new frame position of this audio node.

Reimplemented from cugl::audio::AudioNode.

◆ setRemaining()

virtual double cugl::audio::AudioOutput::setRemaining ( double  time)
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.

Parameters
timeThe remaining time in seconds.
Returns
the new remaining time in seconds.

Reimplemented from cugl::audio::AudioNode.

◆ unmark()

virtual bool cugl::audio::AudioOutput::unmark ( )
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.

Returns
true if the read position was marked.

Reimplemented from cugl::audio::AudioNode.

Friends And Related Function Documentation

◆ cugl::AudioManager

friend class cugl::AudioManager
friend

Allow AudioManager to access intializers


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