CUGL 2.0
Cornell University Game Library
Public Member Functions | Friends | List of all members
cugl::AudioQueue Class Reference

#include <CUAudioQueue.h>

Public Member Functions

 AudioQueue ()
 
 ~AudioQueue ()
 
void play (const std::shared_ptr< Sound > &music, bool loop=false, float volume=1.0f, float fade=0.0f)
 
void play (const std::shared_ptr< audio::AudioNode > &graph, bool loop=false, float volume=1.0f, float fade=0.0f)
 
const std::string current () const
 
AudioEngine::State getState () const
 
bool isLoop () const
 
void setLoop (bool loop)
 
float getVolume () const
 
void setVolume (float volume)
 
float getPanFactor () const
 
void setPanFactor (float pan)
 
float getDuration () const
 
float getTimeElapsed () const
 
void setTimeElapsed (float time)
 
float getTimeRemaining () const
 
void setTimeRemaining (float time)
 
void clear (float fade=DEFAULT_FADE)
 
void pause (float fade=DEFAULT_FADE)
 
void resume ()
 
void setListener (std::function< void(const std::string, bool)> callback)
 
std::function< void(const std::string, bool)> getMusicListener () const
 
void enqueue (const std::shared_ptr< Sound > &music, bool loop=false, float volume=1.0f, float fade=0.0f)
 
void enqueue (const std::shared_ptr< audio::AudioNode > &graph, bool loop=false, float volume=1.0f, float fade=0.0f)
 
const std::vector< std::string > getElements () const
 
size_t getPending () const
 
float getOverlap () const
 
void setOverlap (float time)
 
void advance (unsigned int steps=0, float fade=DEFAULT_FADE)
 
void clearPending ()
 

Friends

class AudioEngine
 

Detailed Description

Creates a queue for seamless audio playback.

Unless your game music consists of a single audio loop, you want to be able to dynamically switch up your audio on the fly. But this is not possible in the default AudioEngine. That engine is optimized for playing sounds simultaneously. Its design does not allow you to stop one sound and start another immediately. Either the two sounds will overlap a little bit or there will be a noticeable gap in-between.

To manage seamless playback, you have to use a queue. This is true even in legacy audio engines like OpenAL. The queue guarantees that the next sample in the queue will be played sequentially with no break in audio. The queue provides some minor crossfade support via setOverlap for loops that do not align perfectly.

The primary difference between this class and an OpenAL style audio queue is that it is not limited to sample playback. As with AudioEngine, you can add any audio node graphs to the queue for playback. However, be careful with this, as any infinite-playing node can stall the queue. Fortunately, the method advance allows the programmer to manually progress through the queue.

IMPORTANT: Like the OpenGL context, this class is not thread-safe. It is only safe to access this class in the main application thread. This means it should never be called in a call-back function as those are typically executed in the host thread. If you need to access the an audio queue in a callback function, you should use the Application#schedule method to delay until the main thread is next available.

Constructor & Destructor Documentation

◆ AudioQueue()

cugl::AudioQueue::AudioQueue ( )

Creates, but does not initialize an audio queue.

The queue must be initialized before is can be used.

◆ ~AudioQueue()

cugl::AudioQueue::~AudioQueue ( )
inline

Disposes of the singleton audio engine.

This destructor releases all of the resources associated with this audio queue.

Member Function Documentation

◆ advance()

void cugl::AudioQueue::advance ( unsigned int  steps = 0,
float  fade = DEFAULT_FADE 
)

Advances ahead in the music queue.

The value fade is the number of seconds to fade out the currently The value step is the number of songs to skip over. A value of 0 will simply skip over the active music to the next element of the queue. Each value above 0 will skip over one more element in the queue. If this skipping empties the queue, no music will play.

The value fade is the number of seconds to fade out the currently playing music assets (if any). This is to ensure a smooth transition to the next song. If the music ends naturally, before this time, the fadeout will not carry over to later entries in the queue.

Parameters
fadeThe number of seconds to fade out the current asset
stepsThe number of elements to skip in the queue

◆ clear()

void cugl::AudioQueue::clear ( float  fade = DEFAULT_FADE)

Clears the entire queue, stopping the background music

Before the music is stopped, this method gives the user an option to fade out the music. If the argument is 0, it will halt the music immediately. Otherwise it will fade to completion over the given number of seconds (or until the end of the song). Only by fading can you guarantee no audible clicks.

This method also clears the queue of any further music.

Parameters
fadeThe number of seconds to fade out

◆ clearPending()

void cugl::AudioQueue::clearPending ( )

Clears the music queue, but does not release any other resources.

This method does not stop the current background music from playing. It only clears pending music assets from the queue.

◆ current()

const std::string cugl::AudioQueue::current ( ) const

Returns the identifier for the track currently playing

If the current playing track is an Sound asset, then the identifier is the file name. Otherwise, it is the name of the root of the audio graph. See audio::AudioNode#getName.

Returns
the identifier for the track currently playing

◆ enqueue() [1/2]

void cugl::AudioQueue::enqueue ( const std::shared_ptr< audio::AudioNode > &  graph,
bool  loop = false,
float  volume = 1.0f,
float  fade = 0.0f 
)

Plays given audio graph as a background track.

This alternate version of play allows the programmer to construct custom composite audio graphs and play them as music tracks. Looping behavior is supported if the audio node has a finite duration.

If the queue is empty and there is no active music, this method will play the music immediately. Otherwise, it will add the music to the queue, and it will play as soon as it is removed from the queue.

When the begins playing, the music will start at full volume unless you provide a number of seconds to fade in. However, any cross-fade value set in setOverlap will be applied independently of the the fade-in value.

Note that looping a song will cause it to block the queue indefinitely until you turn off looping for that asset {

See also
setLoop}. This can be desired behavior, as it gives you a way to control the speed of the queue processing.
Parameters
graphThe audio node to play
loopWhether to loop the music continuously
volumeThe music volume (relative to the default instance volume)
fadeThe number of seconds to fade in

◆ enqueue() [2/2]

void cugl::AudioQueue::enqueue ( const std::shared_ptr< Sound > &  music,
bool  loop = false,
float  volume = 1.0f,
float  fade = 0.0f 
)

Adds the given music asset to the background music queue

Music is handled differently from sound effects. You can only play one music asset at a time. However, it is possible to queue music assets for immediate playback once the active asset is finished. Proper queue management is the keep for smooth, uninterrupted playback that responds to the user's actions.

If the queue is empty and there is no active music, this method will play the music immediately. Otherwise, it will add the music to the queue, and it will play as soon as it is removed from the queue.

When the begins playing, the music will start at full volume unless you provide a number of seconds to fade in. However, any cross-fade value set in setOverlap will be applied independently of the the fade-in value.

Note that looping a song will cause it to block the queue indefinitely until you turn off looping for that asset {

See also
setLoop}. This can be desired behavior, as it gives you a way to control the speed of the queue processing.
Parameters
musicThe music asset to queue
loopWhether to loop the music continuously
volumeThe music volume (relative to the default instance volume)
fadeThe number of seconds to fade in

◆ getDuration()

float cugl::AudioQueue::getDuration ( ) const

Returns the length of background music, in seconds.

This is only the duration of the active background music track. All other music in the queue is ignored. If there is no active background music, this method will return 0. If the current asset is an audio node with undefined duration, this method will return -1.

Returns
the length of background music, in seconds.

◆ getElements()

const std::vector<std::string> cugl::AudioQueue::getElements ( ) const

Returns the list of asset identifiers for the music queue

For each music track, the identifer is either a file name (if it is a sound sample) or the name of the root node of the sound instance.

This list only includes the pending elements in queue, and does not include the asset currently playing.

Returns
the list of asset identifiers for the music queue

◆ getMusicListener()

std::function<void(const std::string,bool)> cugl::AudioQueue::getMusicListener ( ) const
inline

Returns the callback for background music

This callback function is called whenever a background music track completes. It is called whether or not the music completed normally or if it was terminated manually. However, the second parameter can be used to distinguish the two cases.

Returns
the callback for background music

◆ getOverlap()

float cugl::AudioQueue::getOverlap ( ) const

Returns the overlap time in seconds.

The overlap time is the amount of time to cross-fade between a music asset and the next. It does not apply to looped music; music assets can never cross-fade with themselves.

By default, this value is 0. Assets play sequentially but do not overlap. However, you may get smoother transitions between musical segments if you adjust this value. The overlap should be chosen with care. If the play length of an asset is less than the overlap, the results are undefined.

Returns
the overlap time in seconds.

◆ getPanFactor()

float cugl::AudioQueue::getPanFactor ( ) const

Returns the stereo pan of the background music

This audio engine provides limited (e.g. not full 3D) stereo panning for simple effects. The pan value is a float from -1 to 1. A value of 0 (default) plays to both channels (regardless of whether the current effect is mono or stereo). A value of -1 will play to the left channel only, while the right will play to the right channel only. Channels beyond the first two are unaffected.

In the case of stereo assets, panning to the left or right will mix the audio feed; this process will never lose audio.

Returns
the stereo pan of the background music

◆ getPending()

size_t cugl::AudioQueue::getPending ( ) const

Returns the size of the music queue

Returns
the size of the music queue

◆ getState()

AudioEngine::State cugl::AudioQueue::getState ( ) const

Returns the current state of the background music

Returns
the current state of the background music

◆ getTimeElapsed()

float cugl::AudioQueue::getTimeElapsed ( ) const

Returns the elapsed time of the background music, in seconds

The elapsed time is the current position of the music from the beginning. It does not include any time spent on a continuous loop. If there is no active background music, this method will return 0. Given that the queue processes streaming data in PCM format, the result of this method is reasonably accurate, though it is affected by device latency.

If the current asset is an audio node with undefined duration, this method will return -1.

Returns
the elapsed time of the background music, in seconds

◆ getTimeRemaining()

float cugl::AudioQueue::getTimeRemaining ( ) const

Returns the time remaining for the background music, in seconds

The elapsed time is the current position of the music from the beginning. It does not include any time spent on a continuous loop. If there is no active background music, this method will return 0. Given that the queue processes streaming data in PCM format, the result of this method is reasonably accurate, though it is affected by device latency.

If the current asset is an audio node with undefined duration, this method will return -1.

Returns
the time remaining for the background music, in seconds

◆ getVolume()

float cugl::AudioQueue::getVolume ( ) const

Returns the volume of the background music

The volume is a value 0 to 1, where 1 is maximum volume and 0 is complete silence. If there is no active background music, this method will return 0.

Note that this is the playback volume. If the asset or audio graph had its own initial volume setting, this is independent of this setting. Indeed, this value can be though of as the percentage of the default volume.

Returns
the volume of the background music

◆ isLoop()

bool cugl::AudioQueue::isLoop ( ) const

Returns true if the background music is in a continuous loop.

If there is no active background music, this method will return false.

Returns
true if the background music is in a continuous loop.

◆ pause()

void cugl::AudioQueue::pause ( float  fade = DEFAULT_FADE)

Pauses the background music, allowing it to be resumed later.

Before the music is stopped, this method gives the user an option to fade out the music. If the argument is 0, it will pause the music immediately. Otherwise it will fade to completion over the given number of seconds (or until the end of the song). Only by fading can you guarantee no audible clicks.

This method has no effect on the music queue.

Parameters
fadeThe number of seconds to fade out

◆ play() [1/2]

void cugl::AudioQueue::play ( const std::shared_ptr< audio::AudioNode > &  graph,
bool  loop = false,
float  volume = 1.0f,
float  fade = 0.0f 
)

Plays given audio graph as a background track.

This alternate version of play allows the programmer to construct custom composite audio graphs and play them as music tracks. Looping behavior is supported if the audio node has a finite duration.

This method immediately plays the provided asset. Hence it overrides and clears the music queue (though any cross fade setting is honored). To safely play an asset without affecting the music queue, use the method enqueue instead.

When it begins playing, the music will start at full volume unless you provide a number of seconds to fade in. Note that looping a audio graph, or providing audio graph with infinite duration will cause it to block the queue indefinitely. You will need to turn off looping {

See also
setLoop} and/or manually advance the queue to progress further.
Parameters
graphThe audio node to play
loopWhether to loop the music continuously
volumeThe music volume (relative to the default instance volume)
fadeThe number of seconds to fade in

◆ play() [2/2]

void cugl::AudioQueue::play ( const std::shared_ptr< Sound > &  music,
bool  loop = false,
float  volume = 1.0f,
float  fade = 0.0f 
)

Plays given music asset as a background track.

Music is handled differently from sound effects. You can only play one music asset at a time. However, it is possible to queue music assets for immediate playback once the active asset is finished. Proper queue management is the keep for smooth, uninterrupted playback that responds to the user's actions.

This method immediately plays the provided asset. Hence it overrides and clears the music queue (though any cross fade setting is honored). To safely play an asset without affecting the music queue, use the method enqueue instead.

When it begins playing, the music will start at full volume unless you provide a number of seconds to fade in. Note that looping a song will cause it to block the queue indefinitely until you turn off looping for that asset {

See also
setLoop}. This can be desired behavior, as it gives you a way to control the speed of the queue processing
Parameters
musicThe music asset to play
loopWhether to loop the music continuously
volumeThe music volume (relative to the default asset volume)
fadeThe number of seconds to fade in

◆ resume()

void cugl::AudioQueue::resume ( )

Resumes the background music assuming that it was paused previously.

This method has no effect on the music queue.

◆ setListener()

void cugl::AudioQueue::setListener ( std::function< void(const std::string, bool)>  callback)
inline

Sets the callback for background music

This callback function is called whenever a background music track completes. It is called whether or not the music completed normally or if it was terminated manually. However, the second parameter can be used to distinguish the two cases.

Parameters
callbackThe callback for background music

◆ setLoop()

void cugl::AudioQueue::setLoop ( bool  loop)

Sets whether the background music is on a continuous loop.

If loop is true, this will block the queue until it is set to false again. This can be desired behavior, as it gives you a way to control the speed of the queue processing.

If there is no active background music, this method will do nothing.

Parameters
loopwhether the background music should be on a continuous loop

◆ setOverlap()

void cugl::AudioQueue::setOverlap ( float  time)

Sets the overlap time in seconds.

The overlap time is the amount of time to cross-fade between a music asset and the next. It does not apply to looped music; music assets can never cross-fade with themselves.

By default, this value is 0. Assets play sequentially but do not overlap. However, you may get smoother transitions between musical segments if you adjust this value. The overlap should be chosen with care. If the play length of an asset is less than the overlap, the results are undefined.

Parameters
timeThe overlap time in seconds.

◆ setPanFactor()

void cugl::AudioQueue::setPanFactor ( float  pan)

Sets the stereo pan of the background music

This audio engine provides limited (e.g. not full 3D) stereo panning for simple effects. The pan value is a float from -1 to 1. A value of 0 (default) plays to both channels (regardless of whether the current effect is mono or stereo). A value of -1 will play to the left channel only, while the right will play to the right channel only. Channels beyond the first two are unaffected.

In the case of stereo assets, panning to the left or right will mix the audio feed; this process will never lose audio.

Parameters
panThe stereo pan of the background music

◆ setTimeElapsed()

void cugl::AudioQueue::setTimeElapsed ( float  time)

Sets the elapsed time of the background music, in seconds

The elapsed time is the current position of the music from the beginning. It does not include any time spent on a continuous loop.

If there is no active background music, this method will have no effect.

Parameters
timethe new position of the background music

◆ setTimeRemaining()

void cugl::AudioQueue::setTimeRemaining ( float  time)

Sets the time remaining for the background music, in seconds

The time remaining is just duration-elapsed. It does not take into account whether the music is on a loop. It also does not include the duration of any music waiting in the queue.

This adjustment is not guaranteed to be accurate. Attempting to time the playback of streaming data (as opposed to a fully in-memory PCM buffer) is very difficult and not cross-platform. We have tried to be reasonably accurate, but from our tests we can only guarantee accuracy within a 10th of a second.

If there is no active background music, this method will have no effect.

Parameters
timethe new time remaining of the background music

◆ setVolume()

void cugl::AudioQueue::setVolume ( float  volume)

Sets the volume of the background music

The volume is a value 0 to 1, where 1 is maximum volume and 0 is complete silence. If there is no active background music, this method will have no effect.

Note that this is the playback volume. If the asset or audio graph had its own initial volume setting, this is independent of this setting. Indeed, this value can be though of as the percentage of the default volume.

Parameters
volumethe volume of the background music

Friends And Related Function Documentation

◆ AudioEngine

friend class AudioEngine
friend

Allow the audio engine access


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